diff --git a/code/game/asteroid.dm b/code/game/asteroid.dm
index 88ff95833ad..3753c888912 100644
--- a/code/game/asteroid.dm
+++ b/code/game/asteroid.dm
@@ -97,7 +97,7 @@ var/global/max_secret_rooms = 6
theme = "xenoden"
walltypes = list(/turf/simulated/mineral/random/high_chance=1)
floortypes = list(/turf/simulated/floor/plating/airless/asteroid, /turf/simulated/floor/beach/sand)
- treasureitems = list(/obj/item/clothing/mask/facehugger=1)
+ treasureitems = list(/obj/item/clothing/mask/facehugger=1,/obj/item/stack/sheet/animalhide/xeno=2,/obj/item/clothing/suit/xenos=2,/obj/item/clothing/head/xenos=2)
fluffitems = list(/obj/effect/decal/remains/human=1,/obj/effect/decal/cleanable/blood/xeno=5)
if("hitech")
diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm
index 616a2deb206..aec9b2580b5 100644
--- a/code/game/dna/genes/vg_powers.dm
+++ b/code/game/dna/genes/vg_powers.dm
@@ -224,8 +224,7 @@ Obviously, requires DNA2.
var/list/validtargets = new /list()
for(var/mob/M in living_mob_list)
if(M && M.mind)
- var/special_role = M.mind.special_role
- if (special_role == "Wizard" || special_role == "Ninja" || special_role == "Syndicate" || special_role == "Syndicate Commando" || special_role == "Vox Raider" || special_role == "Alien")
+ if(isAntag(M))
continue
validtargets += M
@@ -244,15 +243,14 @@ Obviously, requires DNA2.
var/say = strip_html(input("What do you wish to say"))
for(var/mob/living/target in targets)
+ log_say("Project Mind: [key_name(usr)]->[key_name(target)]: [say]")
if(REMOTE_TALK in target.mutations)
target.show_message("\blue You hear [usr.real_name]'s voice: [say]")
else
target.show_message("\blue You hear a voice that seems to echo around the room: [say]")
usr.show_message("\blue You project your mind into [target.real_name]: [say]")
for(var/mob/dead/observer/G in player_list)
- G.show_message("Telepathic message from [usr] to [target]: [say]")
-
-
+ G.show_message("Telepathic message from [usr] ([ghost_follow_link(usr, ghost=G)]) to [target] ([ghost_follow_link(target, ghost=G)]): [say]")
/datum/dna/gene/basic/grant_spell/remoteview
name="Remote Viewing"
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index c42c9cec293..3b7ca6d5b0e 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -558,12 +558,16 @@ var/list/sacrificed = list()
else
usr.whisper("[input]")
+ log_say("Cult Message: [key_name(usr)]: [input]")
for(var/datum/mind/H in ticker.mode.cult)
if (H.current)
H.current << "[cultName]: [input]"
for(var/mob/spirit/spirit in spirits)
spirit << "[displayName]: [input]"
+
+ for(var/mob/dead/observer/G in player_list)
+ G.show_message("[displayName] ([cultName]) ([ghost_follow_link(usr, ghost=G)]): [input]")
qdel(src)
return 1
diff --git a/code/game/gamemodes/events/holidays/Other.dm b/code/game/gamemodes/events/holidays/Other.dm
deleted file mode 100644
index 74b47506aaf..00000000000
--- a/code/game/gamemodes/events/holidays/Other.dm
+++ /dev/null
@@ -1,10 +0,0 @@
-/proc/GameOver()
- if(!hadevent)
- hadevent = 1
- message_admins("The apocalypse has begun! (this holiday event can be disabled by toggling events off within 60 seconds)")
- spawn(600)
- if(!config.allow_random_events) return
- Show2Group4Delay(ScreenText(null,"
GAME OVER"),null,150)
- for(var/i=1,i<=4,i++)
- spawn_dynamic_event()
- sleep(50)
\ No newline at end of file
diff --git a/code/game/gamemodes/game_mode.dm b/code/game/gamemodes/game_mode.dm
index 0d821a186fa..d0e2228162c 100644
--- a/code/game/gamemodes/game_mode.dm
+++ b/code/game/gamemodes/game_mode.dm
@@ -238,8 +238,7 @@
var/list/suspects = list()
for(var/mob/living/carbon/human/man in player_list) if(man.client && man.mind)
// NT relation option
- var/special_role = man.mind.special_role
- if (special_role == "Wizard" || special_role == "Ninja" || special_role == "Syndicate" || special_role == "Syndicate Commando" || special_role == "Vox Raider" || special_role == "Alien")
+ if(isAntag(man))
continue //NT intelligence ruled out possiblity that those are too classy to pretend to be a crew.
if(man.client.prefs.nanotrasen_relation == "Opposed" && prob(50) || \
man.client.prefs.nanotrasen_relation == "Skeptical" && prob(20))
diff --git a/code/game/machinery/alarm.dm b/code/game/machinery/alarm.dm
index b11edd5ae8d..f9f13d4f907 100644
--- a/code/game/machinery/alarm.dm
+++ b/code/game/machinery/alarm.dm
@@ -992,7 +992,8 @@
/obj/machinery/alarm/emag_act(mob/user)
if(!emagged)
src.emagged = 1
- user.visible_message("Sparks fly out of the [src]!", "You emag the [src], disabling its safeties.")
+ if(user)
+ user.visible_message("Sparks fly out of the [src]!", "You emag the [src], disabling its safeties.")
playsound(src.loc, 'sound/effects/sparks4.ogg', 50, 1)
return
diff --git a/code/game/machinery/portable_turret.dm b/code/game/machinery/portable_turret.dm
index 7bb074e03f4..0b7907eb88f 100644
--- a/code/game/machinery/portable_turret.dm
+++ b/code/game/machinery/portable_turret.dm
@@ -352,8 +352,9 @@ var/list/turret_icons
if(!emagged)
//Emagging the turret makes it go bonkers and stun everyone. It also makes
//the turret shoot much, much faster.
- user << "You short out [src]'s threat assessment circuits."
- visible_message("[src] hums oddly...")
+ if(user)
+ user << "You short out [src]'s threat assessment circuits."
+ visible_message("[src] hums oddly...")
emagged = 1
iconholder = 1
controllock = 1
diff --git a/code/modules/events/event_container.dm b/code/modules/events/event_container.dm
index f7924a83ed7..be2b3a0c075 100644
--- a/code/modules/events/event_container.dm
+++ b/code/modules/events/event_container.dm
@@ -9,6 +9,7 @@
#define ASSIGNMENT_SECURITY "Security"
var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT_LEVEL_MODERATE = "Moderate", EVENT_LEVEL_MAJOR = "Major")
+var/list/event_last_fired = list()
/datum/event_container
var/severity = -1
@@ -134,8 +135,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Vermin Infestation",/datum/event/infestation, 100, list(ASSIGNMENT_JANITOR = 100)),
new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Wallrot", /datum/event/wallrot, 0, list(ASSIGNMENT_ENGINEER = 30, ASSIGNMENT_GARDENER = 50)),
// NON-BAY EVENTS
- new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Cargo Bonus", /datum/event/cargo_bonus, 100),
- new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Revenant", /datum/event/revenant, 50)
+ new /datum/event_meta(EVENT_LEVEL_MUNDANE, "Cargo Bonus", /datum/event/cargo_bonus, 100)
)
/datum/event_container/moderate
@@ -158,7 +158,6 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Spider Infestation", /datum/event/spider_infestation, 100, list(ASSIGNMENT_SECURITY = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Ion Storm", /datum/event/ion_storm, 0, list(ASSIGNMENT_AI = 50, ASSIGNMENT_CYBORG = 50, ASSIGNMENT_ENGINEER = 15, ASSIGNMENT_SCIENTIST = 5)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Borer Infestation", /datum/event/borer_infestation, 20, list(ASSIGNMENT_SECURITY = 20), 1),
- new /datum/event_meta/alien(EVENT_LEVEL_MODERATE, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 15), 1),
//new /datum/event_meta/ninja(EVENT_LEVEL_MODERATE, "Space Ninja", /datum/event/space_ninja, 0, list(ASSIGNMENT_SECURITY = 15), 1),
// NON-BAY EVENTS
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Mass Hallucination", /datum/event/mass_hallucination, 300),
@@ -172,6 +171,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Bluespace Anomaly", /datum/event/anomaly/anomaly_bluespace, 50, list(ASSIGNMENT_ENGINEER = 25)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Flux Anomaly", /datum/event/anomaly/anomaly_flux, 50, list(ASSIGNMENT_ENGINEER = 50)),
new /datum/event_meta(EVENT_LEVEL_MODERATE, "Gravitational Anomaly", /datum/event/anomaly/anomaly_grav, 200),
+ new /datum/event_meta(EVENT_LEVEL_MODERATE, "Revenant", /datum/event/revenant, 150)
)
/datum/event_container/major
@@ -183,6 +183,7 @@ var/global/list/severity_to_string = list(EVENT_LEVEL_MUNDANE = "Mundane", EVENT
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Viral Infection", /datum/event/viral_infection, 0, list(ASSIGNMENT_MEDICAL = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Blob", /datum/event/blob, 0, list(ASSIGNMENT_ENGINEER = 30), 1),
new /datum/event_meta(EVENT_LEVEL_MAJOR, "Meteor Wave", /datum/event/meteor_wave, 0, list(ASSIGNMENT_ENGINEER = 3), 1),
+ new /datum/event_meta/alien(EVENT_LEVEL_MAJOR, "Alien Infestation", /datum/event/alien_infestation, 0, list(ASSIGNMENT_SECURITY = 30), 1),
)
diff --git a/code/modules/events/event_dynamic.dm b/code/modules/events/event_dynamic.dm
deleted file mode 100644
index 2a491a62b9d..00000000000
--- a/code/modules/events/event_dynamic.dm
+++ /dev/null
@@ -1,242 +0,0 @@
-
-/*
-/proc/start_events()
- //changed to a while(1) loop since they are more efficient.
- //Moved the spawn in here to allow it to be called with advance proc call if it crashes.
- //and also to stop spawn copying variables from the game ticker
- spawn(3000)
- while(1)
- /*if(prob(50))//Every 120 seconds and prob 50 2-4 weak spacedusts will hit the station
- spawn(1)
- dust_swarm("weak")*/
- if(!event)
- //CARN: checks to see if random events are enabled.
- if(config.allow_random_events)
- hadevent = event()
- else
- Holiday_Random_Event()
- else
- event = 0
- sleep(2400)
- */
-
-var/list/event_last_fired = list()
-
-//Always triggers an event when called, dynamically chooses events based on job population
-var/global/list/possibleEvents = list()
-/proc/spawn_dynamic_event()
- if(!config.allow_random_events)
- return
-
- var/minutes_passed = world.time/600
-
- var/list/active_with_role = number_active_with_role()
- //var/engineer_count = number_active_with_role("Engineer")
- //var/security_count = number_active_with_role("Security")
- //var/medical_count = number_active_with_role("Medical")
- //var/AI_count = number_active_with_role("AI")
- //var/janitor_count = number_active_with_role("Janitor")
-
- // Maps event names to event chances
- // For each chance, 100 represents "normal likelihood", anything below 100 is "reduced likelihood", anything above 100 is "increased likelihood"
- // Events have to be manually added to this proc to happen
-
- //see:
- // Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events.dm
- // Code/WorkInProgress/Cael_Aislinn/Economy/Economy_Events_Mundane.dm
-
- possibleEvents[/datum/event/economic_event] = 300
- possibleEvents[/datum/event/trivial_news] = 400
- possibleEvents[/datum/event/mundane_news] = 300
-
- possibleEvents[/datum/event/cargo_bonus] = 100
- possibleEvents[/datum/event/revenant] = 75
-
- possibleEvents[/datum/event/pda_spam] = max(min(25, player_list.len) * 4, 200)
- possibleEvents[/datum/event/money_lotto] = max(min(5, player_list.len), 50)
- if(account_hack_attempted)
- possibleEvents[/datum/event/money_hacker] = max(min(25, player_list.len) * 4, 200)
-
- possibleEvents[/datum/event/mass_hallucination] = 200
- possibleEvents[/datum/event/vent_clog] = 300
- possibleEvents[/datum/event/anomaly/anomaly_grav] = 200
-
- possibleEvents[/datum/event/wormholes] = 150
-
- possibleEvents[/datum/event/carp_migration] = 20 + 10 * active_with_role["Engineer"]
- possibleEvents[/datum/event/dust] = 50 + 50 * active_with_role["Engineer"]
- possibleEvents[/datum/event/dust/meaty] = 50 + 50 * active_with_role["Engineer"]
-
- possibleEvents[/datum/event/rogue_drone] = 5 + 25 * active_with_role["Engineer"] + 25 * active_with_role["Security"]
- possibleEvents[/datum/event/infestation] = 100 + 100 * active_with_role["Janitor"]
-
- possibleEvents[/datum/event/communications_blackout] = 50 + 25 * active_with_role["AI"] + active_with_role["Scientist"] * 25
- possibleEvents[/datum/event/ion_storm] = active_with_role["AI"] * 25 + active_with_role["Cyborg"] * 25 + active_with_role["Engineer"] * 10 + active_with_role["Scientist"] * 5
-// possibleEvents[/datum/event/grid_check] = 25 + 10 * active_with_role["Engineer"]
- possibleEvents[/datum/event/electrical_storm] = 15 * active_with_role["Janitor"] + 5 * active_with_role["Engineer"]
- possibleEvents[/datum/event/wallrot] = 30 * active_with_role["Engineer"] + 50 * active_with_role["Botanist"]
- possibleEvents[/datum/event/borer_infestation] = 50 + 15 * active_with_role["Security"]
-
- if(!spacevines_spawned)
- possibleEvents[/datum/event/spacevine] = 10 + 5 * active_with_role["Engineer"]
- if(minutes_passed >= 30) // Give engineers time to set up engine
- possibleEvents[/datum/event/brand_intelligence] = 50 + 25 * active_with_role["Engineer"]
- possibleEvents[/datum/event/anomaly/anomaly_pyro] = 100 + 60 * active_with_role["Engineer"]
- possibleEvents[/datum/event/anomaly/anomaly_vortex] = 50 + 25 * active_with_role["Engineer"]
- possibleEvents[/datum/event/anomaly/anomaly_bluespace] = 50 + 25 * active_with_role["Engineer"]
- possibleEvents[/datum/event/anomaly/anomaly_flux] = 50 + 50 * active_with_role["Engineer"]
-
- possibleEvents[/datum/event/meteor_wave] = 10 * active_with_role["Engineer"]
- possibleEvents[/datum/event/blob] = 10 * active_with_role["Engineer"]
-
- if(active_with_role["Medical"] > 0)
- possibleEvents[/datum/event/radiation_storm] = active_with_role["Medical"] * 10
- possibleEvents[/datum/event/viral_infection] = active_with_role["Medical"] * 10
-
- possibleEvents[/datum/event/prison_break] = active_with_role["Security"] * 50
- if(active_with_role["Security"] > 0)
- if(!sent_spiders_to_station)
- possibleEvents[/datum/event/spider_infestation] = max(active_with_role["Security"], 5) + 5
- if(aliens_allowed && !sent_aliens_to_station)
- possibleEvents[/datum/event/alien_infestation] = max(active_with_role["Security"], 5) + 2.5
- /*if(!sent_ninja_to_station && toggle_space_ninja)
- possibleEvents[/datum/event/space_ninja] = max(active_with_role["Security"], 5)*/
- possibleEvents[/datum/event/tear] = active_with_role["Security"] * 25
-
- for(var/event_type in event_last_fired) if(possibleEvents[event_type])
- var/time_passed = world.time - event_last_fired[event_type]
- var/full_recharge_after = 60 * 60 * 10 * 3 // 3 hours
- var/weight_modifier = max(0, (full_recharge_after - time_passed) / 300)
-
- possibleEvents[event_type] = max(possibleEvents[event_type] - weight_modifier, 0)
-
- var/picked_event = pickweight(possibleEvents)
- event_last_fired[picked_event] = world.time
-
- // Debug code below here, very useful for testing so don't delete please.
- var/debug_message = "Firing random event. "
- for(var/V in active_with_role)
- debug_message += "#[V]:[active_with_role[V]] "
- debug_message += "||| "
- for(var/V in possibleEvents)
- debug_message += "[V]:[possibleEvents[V]]"
- debug_message += "|||Picked:[picked_event]"
- log_debug(debug_message)
-
- if(!picked_event)
- return
-
- //The event will add itself to the MC's event list
- //and start working via the constructor.
- new picked_event
-
- //moved this to proc/check_event()
- /*var/chance = possibleEvents[picked_event]
- var/base_chance = 0.4
- switch(player_list.len)
- if(5 to 10)
- base_chance = 0.6
- if(11 to 15)
- base_chance = 0.7
- if(16 to 20)
- base_chance = 0.8
- if(21 to 25)
- base_chance = 0.9
- if(26 to 30)
- base_chance = 1.0
- if(30 to 100000)
- base_chance = 1.1
-
- // Trigger the event based on how likely it currently is.
- if(!prob(chance * eventchance * base_chance / 100))
- return 0*/
-
- /*switch(picked_event)
- if("Meteor")
- command_announcement.Announce("Meteors have been detected on collision course with the station.", "Meteor Alert", new_sound = 'sound/AI/meteors.ogg')
- spawn(100)
- meteor_wave(10)
- spawn_meteors()
- spawn(700)
- meteor_wave(10)
- spawn_meteors()
- if("Space Ninja")
- //Handled in space_ninja.dm. Doesn't announce arrival, all sneaky-like.
- space_ninja_arrival()
- if("Radiation")
- high_radiation_event()
- if("Virus")
- viral_outbreak()
- if("Alien")
- alien_infestation()
- if("Prison Break")
- prison_break()
- if("Carp")
- carp_migration()
- if("Lights")
- lightsout(1,2)
- if("Appendicitis")
- appendicitis()
- if("Ion Storm")
- IonStorm()
- if("Spacevine")
- spacevine_infestation()
- if("Communications")
- communications_blackout()
- if("Grid Check")
- grid_check()
- if("Meteor")
- meteor_shower()*/
-
- return 1
-
-// Returns how many characters are currently active(not logged out, not AFK for more than 10 minutes)
-// with a specific role.
-// Note that this isn't sorted by department, because e.g. having a roboticist shouldn't make meteors spawn.
-/proc/number_active_with_role()
- var/list/active_with_role = list()
- active_with_role["Engineer"] = 0
- active_with_role["Medical"] = 0
- active_with_role["Security"] = 0
- active_with_role["Scientist"] = 0
- active_with_role["AI"] = 0
- active_with_role["Cyborg"] = 0
- active_with_role["Janitor"] = 0
- active_with_role["Botanist"] = 0
- active_with_role["Any"] = player_list.len
-
- for(var/mob/M in player_list)
- if(!M.mind || !M.client || M.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive
- continue
-
- if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "engineering robot module")
- active_with_role["Engineer"]++
- if(M.mind.assigned_role in list("Chief Engineer", "Station Engineer"))
- active_with_role["Engineer"]++
-
- if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "medical robot module")
- active_with_role["Medical"]++
- if(M.mind.assigned_role in list("Chief Medical Officer", "Medical Doctor"))
- active_with_role["Medical"]++
-
- if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "security robot module")
- active_with_role["Security"]++
- if(M.mind.assigned_role in security_positions)
- active_with_role["Security"]++
-
- if(M.mind.assigned_role in list("Research Director", "Scientist"))
- active_with_role["Scientist"]++
-
- if(M.mind.assigned_role == "AI")
- active_with_role["AI"]++
-
- if(M.mind.assigned_role == "Cyborg")
- active_with_role["Cyborg"]++
-
- if(M.mind.assigned_role == "Janitor")
- active_with_role["Janitor"]++
-
- if(M.mind.assigned_role == "Botanist")
- active_with_role["Botanist"]++
-
- return active_with_role
diff --git a/code/modules/events/event_manager.dm b/code/modules/events/event_manager.dm
index 7982fc1debf..b5fec993420 100644
--- a/code/modules/events/event_manager.dm
+++ b/code/modules/events/event_manager.dm
@@ -361,3 +361,54 @@
if(P.client)
players++
return players
+
+// Returns how many characters are currently active(not logged out, not AFK for more than 10 minutes)
+// with a specific role.
+// Note that this isn't sorted by department, because e.g. having a roboticist shouldn't make meteors spawn.
+/proc/number_active_with_role()
+ var/list/active_with_role = list()
+ active_with_role["Engineer"] = 0
+ active_with_role["Medical"] = 0
+ active_with_role["Security"] = 0
+ active_with_role["Scientist"] = 0
+ active_with_role["AI"] = 0
+ active_with_role["Cyborg"] = 0
+ active_with_role["Janitor"] = 0
+ active_with_role["Botanist"] = 0
+ active_with_role["Any"] = player_list.len
+
+ for(var/mob/M in player_list)
+ if(!M.mind || !M.client || M.client.inactivity > 10 * 10 * 60) // longer than 10 minutes AFK counts them as inactive
+ continue
+
+ if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "engineering robot module")
+ active_with_role["Engineer"]++
+ if(M.mind.assigned_role in list("Chief Engineer", "Station Engineer"))
+ active_with_role["Engineer"]++
+
+ if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "medical robot module")
+ active_with_role["Medical"]++
+ if(M.mind.assigned_role in list("Chief Medical Officer", "Medical Doctor"))
+ active_with_role["Medical"]++
+
+ if(istype(M, /mob/living/silicon/robot) && M:module && M:module.name == "security robot module")
+ active_with_role["Security"]++
+ if(M.mind.assigned_role in security_positions)
+ active_with_role["Security"]++
+
+ if(M.mind.assigned_role in list("Research Director", "Scientist"))
+ active_with_role["Scientist"]++
+
+ if(M.mind.assigned_role == "AI")
+ active_with_role["AI"]++
+
+ if(M.mind.assigned_role == "Cyborg")
+ active_with_role["Cyborg"]++
+
+ if(M.mind.assigned_role == "Janitor")
+ active_with_role["Janitor"]++
+
+ if(M.mind.assigned_role == "Botanist")
+ active_with_role["Botanist"]++
+
+ return active_with_role
diff --git a/code/modules/events/tgevents/false_alarm.dm b/code/modules/events/tgevents/false_alarm.dm
index 5d29829eaa8..b91ceeebfbf 100644
--- a/code/modules/events/tgevents/false_alarm.dm
+++ b/code/modules/events/tgevents/false_alarm.dm
@@ -3,8 +3,10 @@
endWhen = 1
/datum/event/falsealarm/announce()
- var/datum/event/E = pick(possibleEvents)
- var/datum/event/Event = new E
- message_admins("False Alarm: [Event]")
- Event.announce() //just announce it like it's happening
- Event.kill() //do not process this event - no starts, no ticks, no ends
+ var/weight = pick(EVENT_LEVEL_MUNDANE,EVENT_LEVEL_MUNDANE,EVENT_LEVEL_MUNDANE,EVENT_LEVEL_MODERATE,EVENT_LEVEL_MODERATE,EVENT_LEVEL_MAJOR)
+ var/datum/event_container/container = event_manager.event_containers[weight]
+ var/datum/event/E = container.acquire_event()
+ var/datum/event/Event = new E
+ message_admins("False Alarm: [Event]")
+ Event.announce() //just announce it like it's happening
+ Event.kill() //do not process this event - no starts, no ticks, no ends
diff --git a/code/modules/karma/karma.dm b/code/modules/karma/karma.dm
index ed00a84e97c..6c3a5d35046 100644
--- a/code/modules/karma/karma.dm
+++ b/code/modules/karma/karma.dm
@@ -63,8 +63,7 @@ var/list/karma_spenders = list()
var/list/karma_list = list("Cancel")
for(var/mob/M in player_list) if(M.client && M.mind)
- var/special_role = M.mind.special_role
- if (special_role == "Wizard" || special_role == "Ninja" || special_role == "Syndicate" || special_role == "Syndicate Commando" || special_role == "Vox Raider" || special_role == "Alien") // Don't include special roles, because players use it to meta
+ if(isAntag(M)) // Don't include special roles, because players use it to meta
continue
karma_list += M
diff --git a/code/modules/mob/language.dm b/code/modules/mob/language.dm
index 4b5fc980d2c..e1cae9e3c66 100644
--- a/code/modules/mob/language.dm
+++ b/code/modules/mob/language.dm
@@ -97,7 +97,7 @@
return (copytext(message, length(message)) == "!") ? 2 : 1
/datum/language/proc/broadcast(var/mob/living/speaker,var/message,var/speaker_mask)
- log_say("[key_name(speaker)] : ([name]) [message]")
+ log_say("[key_name(speaker)]: ([name]) [message]")
if(!speaker_mask) speaker_mask = speaker.name
var/msg = "[name], [speaker_mask] [format_message(message, get_spoken_verb(message))]"
diff --git a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
index 4efc0c56dc6..3a60506ebe1 100644
--- a/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
+++ b/code/modules/mob/living/carbon/alien/humanoid/alien_powers.dm
@@ -43,9 +43,11 @@ Doesn't work on other aliens/AI.*/
adjustToxLoss(-10)
var/msg = sanitize(input("Message:", "Alien Whisper") as text|null)
if(msg)
- log_say("AlienWhisper: [key_name(src)]->[M.key] : [msg]")
+ log_say("Alien Whisper: [key_name(src)]->[key_name(M)]: [msg]")
M << "You hear a strange, alien voice in your head...[msg]"
- src << {"You said: "[msg]" to [M]"}
+ src << "You said: [msg] to [M]"
+ for(var/mob/dead/observer/G in player_list)
+ G.show_message("Alien message from [src] ([ghost_follow_link(src, ghost=G)]) to [M] ([ghost_follow_link(M, ghost=G)]): [msg]")
return
/mob/living/carbon/alien/humanoid/verb/transfer_plasma(mob/living/carbon/alien/M as mob in oview())
diff --git a/code/modules/mob/living/simple_animal/hostile/alien.dm b/code/modules/mob/living/simple_animal/hostile/alien.dm
index c2dc78c5377..3ec2633e2e9 100644
--- a/code/modules/mob/living/simple_animal/hostile/alien.dm
+++ b/code/modules/mob/living/simple_animal/hostile/alien.dm
@@ -30,7 +30,7 @@
min_n2 = 0
max_n2 = 0
var/dead = 0
- unsuitable_atoms_damage = 15
+ unsuitable_atmos_damage = 15
faction = list("alien")
status_flags = CANPUSH
minbodytemp = 0
diff --git a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
index 3a88146dfb0..285948e6073 100644
--- a/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
+++ b/code/modules/mob/living/simple_animal/hostile/mining_mobs.dm
@@ -8,7 +8,7 @@
max_co2 = 0
min_n2 = 0
max_n2 = 0
- unsuitable_atoms_damage = 15
+ unsuitable_atmos_damage = 15
faction = list("mining")
environment_smash = 2
minbodytemp = 0
diff --git a/code/modules/mob/living/simple_animal/hostile/pirate.dm b/code/modules/mob/living/simple_animal/hostile/pirate.dm
index b642c5c6dda..c519c2c62bc 100644
--- a/code/modules/mob/living/simple_animal/hostile/pirate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/pirate.dm
@@ -27,7 +27,7 @@
max_co2 = 5
min_n2 = 0
max_n2 = 0
- unsuitable_atoms_damage = 15
+ unsuitable_atmos_damage = 15
speak_emote = list("yarrs")
var/corpse = /obj/effect/landmark/mobcorpse/pirate
var/weapon1 = /obj/item/weapon/melee/energy/sword/pirate
diff --git a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
index d62a4ba976d..2635c97f9a1 100644
--- a/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
+++ b/code/modules/mob/living/simple_animal/hostile/retaliate/clown.dm
@@ -36,4 +36,4 @@
maxbodytemp = 370
heat_damage_per_tick = 15 //amount of damage applied if animal's body temperature is higher than maxbodytemp
cold_damage_per_tick = 10 //same as heat_damage_per_tick, only if the bodytemperature it's lower than minbodytemp
- unsuitable_atoms_damage = 10
+ unsuitable_atmos_damage = 10
diff --git a/code/modules/mob/living/simple_animal/hostile/russian.dm b/code/modules/mob/living/simple_animal/hostile/russian.dm
index d1140f38c5b..729ef2ad658 100644
--- a/code/modules/mob/living/simple_animal/hostile/russian.dm
+++ b/code/modules/mob/living/simple_animal/hostile/russian.dm
@@ -29,7 +29,7 @@
max_co2 = 5
min_n2 = 0
max_n2 = 0
- unsuitable_atoms_damage = 15
+ unsuitable_atmos_damage = 15
faction = list("russian")
status_flags = CANPUSH
diff --git a/code/modules/mob/living/simple_animal/hostile/syndicate.dm b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
index a83eddf5e84..6eb56766229 100644
--- a/code/modules/mob/living/simple_animal/hostile/syndicate.dm
+++ b/code/modules/mob/living/simple_animal/hostile/syndicate.dm
@@ -30,7 +30,7 @@
max_co2 = 5
min_n2 = 0
max_n2 = 0
- unsuitable_atoms_damage = 15
+ unsuitable_atmos_damage = 15
faction = list("syndicate")
status_flags = CANPUSH
diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm
index bad520aa326..1d83cbcc9d8 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm
@@ -12,47 +12,52 @@
invisibility = INVISIBILITY_OBSERVER
health = 25
maxHealth = 25
- see_in_dark = 255
see_invisible = SEE_INVISIBLE_OBSERVER
universal_understand = 1
response_help = "passes through"
response_disarm = "swings at"
response_harm = "punches"
+ unsuitable_atmos_damage = 0
minbodytemp = 0
maxbodytemp = INFINITY
- harm_intent_damage = 5
- speak_emote = list("hisses", "spits", "growls")
+ harm_intent_damage = 0
friendly = "touches"
status_flags = 0
wander = 0
density = 0
+ flying = 1
+ anchored = 1
- var/essence = 25 //The resource of revenants. Max health is equal to twice this amount
+ var/essence = 25 //The resource of revenants. Max health is equal to three times this amount
var/essence_regen_cap = 25 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount.
- var/essence_regen = 1 //If the revenant regenerates essence or not; 1 for yes, 0 for no
+ var/essence_regenerating = 1 //If the revenant regenerates essence or not; 1 for yes, 0 for no
+ var/essence_regen_amount = 2 //How much essence regenerates
var/essence_min = 1 //The minimum amount of essence a revenant can have; by default, it never drops below one
- var/strikes = 0 //How many times a revenant can die before dying for good
+ var/essence_accumulated = 0 //How much essence the revenant has stolen
var/revealed = 0 //If the revenant can take damage from normal sources.
var/inhibited = 0 //If the revenant's abilities are blocked by a chaplain's power.
+ var/essence_drained = 0 //How much essence the revenant has drained.
+ var/draining = 0 //If the revenant is draining someone.
+ var/list/drained_mobs = list() //Cannot harvest the same mob twice
/mob/living/simple_animal/revenant/Life()
..()
if(essence < essence_min)
essence = essence_min
- if(strikes > 0)
- strikes--
- src << "Your essence has dropped below critical levels. You barely manage to save yourself - [strikes ? "you can't keep this up!" : "next time, it's death."]"
- else if(strikes <= 0)
- Die()
- maxHealth = essence * 2
+ if(essence_regenerating && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate
+ essence += essence_regen_amount
+ if(essence > essence_regen_cap)
+ essence = essence_regen_cap
+ maxHealth = essence * 3
if(!revealed)
health = maxHealth //Heals to full when not revealed
- if(essence_regen && !inhibited && essence < essence_regen_cap) //While inhibited, essence will not regenerate
- essence++
/mob/living/simple_animal/revenant/ex_act(severity)
return 1 //Immune to the effects of explosions.
+/mob/living/simple_animal/revenant/blob_act()
+ return 1 //blah blah blobs aren't in tune with the spirit world, or something.
+
/mob/living/simple_animal/revenant/ClickOn(var/atom/A, var/params) //Copypaste from ghost code - revenants can't interact with the world directly.
if(client.buildmode)
build_click(src, client.buildmode, params, A)
@@ -75,6 +80,70 @@
if(world.time <= next_move)
return
A.attack_ghost(src)
+ if(ishuman(A) && in_range(src, A))
+ Harvest(A)
+
+/mob/living/simple_animal/revenant/proc/Harvest(mob/living/carbon/human/target)
+ if(!castcheck(0))
+ return
+ if(draining)
+ src << "You are already siphoning the essence of a soul!"
+ return
+ if(target in drained_mobs)
+ src << "[target]'s soul is dead and empty."
+ return
+ if(!target.stat)
+ src << "This being's soul is too strong to harvest."
+ if(prob(10))
+ target << "You feel as if you are being watched."
+ return
+ draining = 1
+ essence_drained = 2
+ src << "You search for the soul of [target]."
+ if(do_after(src, 10, 3, 0, target)) //did they get deleted in that second?
+ if(target.ckey)
+ src << "Their soul burns with intelligence."
+ essence_drained += 2
+ if(target.stat != DEAD)
+ src << "Their soul blazes with life!"
+ essence_drained += 2
+ else
+ src << "Their soul is weak and faltering."
+ if(do_after(src, 20, 6, 0, target)) //did they get deleted NOW?
+ switch(essence_drained)
+ if(1 to 2)
+ src << "[target] will not yield much essence. Still, every bit counts."
+ if(3 to 4)
+ src << "[target] will yield an average amount of essence."
+ if(5 to INFINITY)
+ src << "Such a feast! [target] will yield much essence to you."
+ if(do_after(src, 30, 9, 0, target)) //how about now
+ if(!target.stat)
+ src << "They are now powerful enough to fight off your draining."
+ target << "You feel something tugging across your body before subsiding."
+ draining = 0
+ return //hey, wait a minute...
+ src << "You begin siphoning essence from [target]'s soul."
+ if(target.stat != DEAD)
+ target << "You feel a horribly unpleasant draining sensation as your grip on life weakens..."
+ icon_state = "revenant_draining"
+ reveal(65)
+ stun(65)
+ target.visible_message("[target] suddenly rises slightly into the air, their skin turning an ashy gray.")
+ target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=60)
+ if(target) //As one cannot prove the existance of ghosts, ghosts cannot prove the existance of the target they were draining.
+ change_essence_amount(essence_drained * 5, 0, target)
+ src << "[target]'s soul has been considerably weakened and will yield no more essence for the time being."
+ target.visible_message("[target] gently slumps back onto the ground.")
+ drained_mobs.Add(target)
+ target.death(0)
+ icon_state = "revenant_idle"
+ else
+ src << "You are not close enough to siphon [target]'s soul. The link has been broken."
+ draining = 0
+ return
+ draining = 0
+ return
/mob/living/simple_animal/revenant/say(message)
return 0 //Revenants cannot speak out loud.
@@ -83,6 +152,7 @@
..()
if(statpanel("Status"))
stat(null, "Current essence: [essence]E")
+ stat(null, "Stolen essence: [essence_accumulated]E")
/mob/living/simple_animal/revenant/New()
..()
@@ -99,11 +169,11 @@
src << "You do not remember anything of your past lives, nor will you remember anything about this one after your death."
src << "Be sure to read the wiki page at http://nanotrasen.se/wiki/index.php/Revenant to learn more."
var/datum/objective/revenant/objective = new
- objective.owner = src
+ objective.owner = src.mind
src.mind.objectives += objective
src << "Objective #1: [objective.explanation_text]"
var/datum/objective/revenantFluff/objective2 = new
- objective2.owner = src
+ objective2.owner = src.mind
src.mind.objectives += objective2
src << "Objective #2: [objective2.explanation_text]"
ticker.mode.traitors |= src.mind //Necessary for announcing
@@ -119,13 +189,12 @@
src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_harvest
src.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/revenant_transmit
src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_light
- src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenantDefile
+ src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile
+ src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf
return 1
return 0
/mob/living/simple_animal/revenant/Die()
- if(strikes)
- return 0 //Impossible to die with strikes still active
..()
src << "NO! No... it's too late, you can feel yourself fading..."
notransform = 1
@@ -145,74 +214,78 @@
/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
- ..()
if(istype(W, /obj/item/weapon/nullrod))
visible_message("[src] violently flinches!", \
- "The null rod invokes agony in you! You feel your essence draining away!")
+ "As the null rod passes through you, you feel your essence draining away!")
essence -= 25 //hella effective
inhibited = 1
spawn(30)
inhibited = 0
+
+ ..()
-
-
-/mob/living/simple_animal/revenant/proc/castcheck(var/essence_cost)
- var/mob/living/simple_animal/revenant/user = usr
- if(!istype(user) || !user)
+/mob/living/simple_animal/revenant/proc/castcheck(essence_cost)
+ if(!src)
return
- var/turf/T = get_turf(usr)
+ var/turf/T = get_turf(src)
if(istype(T, /turf/simulated/wall))
- user << "You cannot use abilities from inside of a wall."
+ src << "You cannot use abilities from inside of a wall."
return 0
- if(!user.change_essence_amount(essence_cost, 1))
- user << "You lack the essence to use that ability."
+ if(src.inhibited)
+ src << "Your powers have been suppressed by nulling energy!"
return 0
- if(user.inhibited)
- user << "Your powers have been suppressed by holy energies!"
+ if(!src.change_essence_amount(essence_cost, 1))
+ src << "You lack the essence to use that ability."
return 0
return 1
-
-
-/mob/living/simple_animal/revenant/proc/change_essence_amount(var/essence_amt, var/silent = 0, var/source = null)
- var/mob/living/simple_animal/revenant/user = usr
- if(!istype(usr) || !usr)
+/mob/living/simple_animal/revenant/proc/change_essence_amount(essence_amt, silent = 0, source = null)
+ if(!src)
return
- if(user.essence + essence_amt <= 0)
+ if(essence + essence_amt <= 0)
return
- user.essence += essence_amt
- user.essence = Clamp(user.essence, 0, INFINITY)
+ essence += essence_amt
+ essence = max(0, essence)
+ if(essence_amt > 0)
+ essence_accumulated += essence_amt
+ essence_accumulated = max(0, essence_accumulated)
if(!silent)
if(essence_amt > 0)
- user << "Gained [essence_amt]E from [source]."
+ src << "Gained [essence_amt]E from [source]."
else
- user << "Lost [essence_amt]E from [source]."
+ src << "Lost [essence_amt]E from [source]."
return 1
-
-
-/mob/living/simple_animal/revenant/proc/reveal(var/time, var/stun)
- var/mob/living/simple_animal/revenant/R = usr
- if(!istype(usr) || !usr)
+/mob/living/simple_animal/revenant/proc/reveal(time)
+ if(!src)
return
- R.revealed = 1
- R.invisibility = 0
- if(stun)
- R.notransform = 1
- R << "You have been revealed [stun ? "and cannot move" : ""]."
+ if(time <= 0)
+ return
+ revealed = 1
+ invisibility = 0
+ src << "You have been revealed."
spawn(time)
- R.revealed = 0
- R.invisibility = INVISIBILITY_OBSERVER
- if(stun)
- R.notransform = 0
- R << "You are once more concealed [stun ? "and can move again" : ""]."
+ revealed = 0
+ invisibility = INVISIBILITY_OBSERVER
+ src << "You are once more concealed."
+/mob/living/simple_animal/revenant/proc/stun(time)
+ if(!src)
+ return
+ if(time <= 0)
+ return
+ notransform = 1
+ src << "You cannot move!"
+ spawn(time)
+ notransform = 0
+ src << "You can move again!"
+
/datum/objective/revenant
var/targetAmount = 100
/datum/objective/revenant/New()
targetAmount = rand(100,200)
- explanation_text = "Absorb [targetAmount] points of essence."
+ explanation_text = "Absorb [targetAmount] points of essence from humans."
..()
/datum/objective/revenant/check_completion()
@@ -221,8 +294,8 @@
var/mob/living/simple_animal/revenant/R = owner.current
if(!R || R.stat == DEAD)
return 0
- var/essenceAccumulated = R.essence
- if(essenceAccumulated < targetAmount)
+ var/essence_stolen = R.essence_accumulated
+ if(essence_stolen < targetAmount)
return 0
return 1
@@ -254,7 +327,7 @@
/obj/item/weapon/ectoplasm/revenant/New()
..()
reforming = 1
- spawn(1800) //3 minutes
+ spawn(600) //1 minutes
if(src && reforming)
return reform()
if(src && !reforming)
@@ -290,7 +363,7 @@
/obj/item/weapon/ectoplasm/revenant/proc/reform()
if(!reforming || !src)
return
- message_admins("Revenant ectoplasm was left undestroyed for 3 minutes and has reformed into a new revenant.")
+ message_admins("Revenant ectoplasm was left undestroyed for 1 minute and has reformed into a new revenant.")
loc = get_turf(src) //In case it's in a backpack or someone's hand
visible_message("[src] suddenly rises into the air before fading away.")
var/mob/living/simple_animal/revenant/R = new(get_turf(src))
diff --git a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
index 01f527f2e07..016b8171113 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
@@ -1,128 +1,66 @@
//Harvest Essence: The bread and butter of the revenant. The basic way of harvesting additional essence.
/obj/effect/proc_holder/spell/targeted/revenant_harvest
- name = "Harvest (0E)"
+ name = "Harvest"
desc = "Siphons the lingering spectral essence from a human, empowering yourself."
panel = "Revenant Abilities"
- charge_max = 100 //Short cooldown
+ charge_max = 0 //Short cooldown
clothes_req = 0
- range = 5
- var/essence_drained = 0
- var/draining
- var/list/drained_mobs = list() //Cannot harvest the same mob twice
+ range = 1
/obj/effect/proc_holder/spell/targeted/revenant_harvest/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(!user.castcheck(0))
- charge_counter = charge_max
- return
for(var/mob/living/carbon/human/target in targets)
spawn(0)
- if(draining)
- user << "You are already siphoning the essence of a soul!"
- return
- if(target in drained_mobs)
- user << "[target]'s soul is dead and empty."
- return
- if(target.stat != DEAD)
- user << "This being's soul is too strong to harvest."
- if(prob(10))
- target << "You feel as if you are being watched."
- return
- draining = 1
- essence_drained = 1
- user << "You search for the still-living soul of [target]."
- sleep(10)
- if(target.ckey)
- user << "Their soul burns with intelligence."
- essence_drained += 3
- sleep(20)
- switch(essence_drained)
- if(1 to 2)
- user << "[target] will not yield much essence. Still, every bit counts."
- if(3 to 4)
- user << "[target] will yield an average amount of essence."
- if(5 to INFINITY)
- user << "Such a feast! [target] will yield much essence to you."
- sleep(30)
- if(!in_range(user, target))
- user << "You are not close enough to siphon [target]'s soul. The link has been broken."
- draining = 0
- return
- if(!target.stat)
- user << "They are now powerful enough to fight off your draining."
- target << "You feel something tugging across your body before subsiding."
- user << "You begin siphoning essence from [target]'s soul. You can not move while this is happening."
- if(target.stat != DEAD)
- target << "You feel a horribly unpleasant draining sensation as your grip on life weakens..."
- user.icon_state = "revenant_draining"
- user.notransform = 1
- user.revealed = 1
- user.invisibility = 0
- target.visible_message("[target] suddenly rises slightly into the air, their skin turning an ashy gray.")
- target.Beam(user,icon_state="drain_life",icon='icons/effects/effects.dmi',time=80)
- target.death(0)
- target.visible_message("[target] gently slumps back onto the ground.")
- user.icon_state = "revenant_idle"
- user.change_essence_amount(essence_drained * 5, 0, target)
- user << "[target]'s soul has been considerably weakened and will yield no more essence for the time being."
- user.revealed = 0
- user.notransform = 0
- user.invisibility = INVISIBILITY_OBSERVER
- drained_mobs.Add(target)
- draining = 0
-
+ user.Harvest(target)
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob for 5E.
/obj/effect/proc_holder/spell/targeted/revenant_transmit
- name = "Transmit (5E)"
+ name = "Transmit"
desc = "Telepathically transmits a message to the target."
- panel = "Revenant Abilities (Locked)"
- charge_max = 50
+ panel = "Revenant Abilities"
+ charge_max = 0
clothes_req = 0
- range = -1
- include_user = 1
- var/locked = 1
+ range = 7
+ include_user = 0
/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(!user.castcheck(-5))
- charge_counter = charge_max
- return
- if(locked)
- usr << "You have unlocked Transmit!"
- locked = 0
- charge_counter = charge_max
- panel = "Revenant Abilities"
- range = 7
- include_user = 0
- return
for(var/mob/living/M in targets)
spawn(0)
var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
if(!msg)
charge_counter = charge_max
return
- usr << "You transmit to [M]: [msg]"
- M << "A strange voice resonates in your head... [msg]"
+ log_say("Revenant Transmit: [key_name(usr)]->[key_name(M)]: [msg]")
+ usr << "You transmit to [M]: [msg]"
+ M << "A strange voice resonates in your head... [msg]"
+ for(var/mob/dead/observer/G in player_list)
+ G.show_message("Revenant message from [usr] ([ghost_follow_link(usr, ghost=G)]) to [M] ([ghost_follow_link(M, ghost=G)]): [msg]")
//Overload Light: Breaks a light that's online and sends out lightning bolts to all nearby people.
/obj/effect/proc_holder/spell/aoe_turf/revenant_light
- name = "Overload Light (25E)"
- desc = "Directs a large amount of essence into an electrical light, causing an impressive light show."
+ name = "Overload Light (30E)"
+ desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby."
panel = "Revenant Abilities (Locked)"
- charge_max = 300
+ charge_max = 200
clothes_req = 0
range = 1
+ var/reveal = 80
+ var/stun = 20
var/locked = 1
/obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(!user.castcheck(-25))
- charge_counter = charge_max
- return
if(locked)
- user << "You have unlocked Overload Light!"
+ if(!user.castcheck(-30))
+ charge_counter = charge_max
+ return
+ user << "You have unlocked Overload Lights!"
+ name = "Overload Lights (20E)"
panel = "Revenant Abilities"
locked = 0
- range = 5
+ range = 6
+ charge_counter = charge_max
+ return
+ if(!user.castcheck(-20))
charge_counter = charge_max
return
for(var/turf/T in targets)
@@ -132,57 +70,106 @@
if(!L.on)
return
L.visible_message("\The [L] suddenly flares brightly and begins to spark!")
- sleep(20)
+ sleep(10)
+ var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread
+ s.set_up(4, 1, L)
+ s.start()
+ sleep(10)
for(var/mob/living/M in orange(4, L))
if(M == user)
return
M.Beam(L,icon_state="lightning",icon='icons/effects/effects.dmi',time=5)
M.electrocute_act(25, "[L.name]")
+ var/datum/effect/effect/system/spark_spread/z = new /datum/effect/effect/system/spark_spread
+ z.set_up(4, 1, M)
+ z.start()
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
- user.reveal(50, 1)
-
+ user.reveal(reveal)
+ user.stun(stun)
//Defile: Corrupts nearby stuff, unblesses floor tiles.
-/obj/effect/proc_holder/spell/aoe_turf/revenantDefile
- name = "Defile (30E)"
- desc = "Twists and corrupts certain nearby objects. Also dispels holy auras on floors, but not salt lines."
+/obj/effect/proc_holder/spell/aoe_turf/revenant_defile
+ name = "Defile (35E)"
+ desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors, but not salt lines."
panel = "Revenant Abilities (Locked)"
- charge_max = 300
+ charge_max = 200
clothes_req = 0
range = 1
+ var/reveal = 100
+ var/stun = 20
var/locked = 1
-/obj/effect/proc_holder/spell/aoe_turf/revenantDefile/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
- if(!user.castcheck(-30))
- charge_counter = charge_max
- return
+/obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
if(locked)
+ if(!user.castcheck(-35))
+ charge_counter = charge_max
+ return
user << "You have unlocked Defile!"
+ name = "Defile (20E)"
panel = "Revenant Abilities"
locked = 0
- range = 4
+ range = 3
+ charge_counter = charge_max
+ return
+ if(!user.castcheck(-20))
charge_counter = charge_max
return
for(var/turf/T in targets)
spawn(0)
if(T.flags & NOJAUNT)
T.flags -= NOJAUNT
- for(var/obj/machinery/bot/secbot/secbot in T.contents) //Not including ED-209
- secbot.emagged = 2
- secbot.Emag(null)
- for(var/obj/machinery/bot/cleanbot/cleanbot in T.contents)
- cleanbot.emagged = 2
- cleanbot.Emag(null)
+ if(!istype(T, /turf/simulated/wall/cult) && istype(T, /turf/simulated/wall) && prob(40))
+ T.ChangeTurf(/turf/simulated/wall/cult)
+ if(!istype(T, /turf/simulated/floor/engine/cult) && istype(T, /turf/simulated/floor) && prob(40))
+ T.ChangeTurf(/turf/simulated/floor/engine/cult)
for(var/mob/living/carbon/human/human in T.contents)
human << "You suddenly feel tired."
- human.adjustStaminaLoss(25)
- for(var/mob/living/silicon/robot/robot in T.contents)
- robot.visible_message("[robot] lets out an alarm!", \
- "01001111 01010110 01000101 01010010 01001100 01001111 01000001 01000100") //Translates to "OVERLOAD"
- robot << 'sound/misc/interference.ogg'
- playsound(robot, 'sound/machines/warning-buzzer.ogg', 50, 1)
+ human.adjustStaminaLoss(35)
for(var/obj/structure/window/window in T.contents)
- window.hit(rand(10,50))
+ window.hit(rand(50,125))
for(var/obj/machinery/light/light in T.contents)
light.flicker() //spooky
- user.reveal(30, 1)
+ user.reveal(reveal)
+ user.stun(stun)
+
+//Malfunction: Makes bad stuff happen to robots and machines.
+/obj/effect/proc_holder/spell/aoe_turf/revenant_malf
+ name = "Malfunction (50E)"
+ desc = "Corrupts and damages nearby machines and mechanical objects."
+ panel = "Revenant Abilities (Locked)"
+ charge_max = 150
+ clothes_req = 0
+ range = 1
+ var/reveal = 60
+ var/stun = 30
+ var/locked = 1
+
+/obj/effect/proc_holder/spell/aoe_turf/revenant_malf/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
+ if(locked)
+ if(!user.castcheck(-50))
+ charge_counter = charge_max
+ return
+ user << "You have unlocked Malfunction!"
+ name = "Malfunction (15E)"
+ panel = "Revenant Abilities"
+ locked = 0
+ range = 4
+ charge_counter = charge_max
+ return
+ if(!user.castcheck(-15))
+ charge_counter = charge_max
+ return
+ for(var/turf/T in targets)
+ spawn(0)
+ for(var/obj/machinery/bot/bot in T.contents)
+ if(!bot.emagged)
+ bot.locked = 0
+ bot.open = 1
+ bot.Emag(null)
+ for(var/obj/machinery/mach in T.contents)
+ if(prob(10))
+ mach.emag_act(null)
+
+ empulse(user.loc, 3, 5)
+ user.reveal(reveal)
+ user.stun(stun)
diff --git a/code/modules/mob/living/simple_animal/simple_animal.dm b/code/modules/mob/living/simple_animal/simple_animal.dm
index 7fd2dba5c90..dbd87107f1e 100644
--- a/code/modules/mob/living/simple_animal/simple_animal.dm
+++ b/code/modules/mob/living/simple_animal/simple_animal.dm
@@ -51,7 +51,7 @@
var/max_co2 = 5
var/min_n2 = 0
var/max_n2 = 0
- var/unsuitable_atoms_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
+ var/unsuitable_atmos_damage = 2 //This damage is taken when atmos doesn't fit all the requirements above
//LETTING SIMPLE ANIMALS ATTACK? WHAT COULD GO WRONG. Defaults to zero so Ian can still be cuddly
@@ -227,7 +227,7 @@
fire_alert = 0
if(!atmos_suitable)
- adjustBruteLoss(unsuitable_atoms_damage)
+ adjustBruteLoss(unsuitable_atmos_damage)
return 1
/mob/living/simple_animal/Bumped(AM as mob|obj)
diff --git a/code/modules/mob/living/simple_animal/slaughter/slaughter.dm b/code/modules/mob/living/simple_animal/slaughter/slaughter.dm
index a03b9b5173b..764947115d3 100644
--- a/code/modules/mob/living/simple_animal/slaughter/slaughter.dm
+++ b/code/modules/mob/living/simple_animal/slaughter/slaughter.dm
@@ -120,8 +120,12 @@
var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
if(!(msg))
return
- usr << "You whisper to [M]: [msg]"
- M << "Suddenly a strange,demonic,voice resonates in your head... [msg]"
+ log_say("Slaughter Demon Transmit: [key_name(usr)]->[key_name(M)]: [msg]")
+ usr << "You whisper to [M]: [msg]"
+ M << "Suddenly a strange, demonic voice resonates in your head... [msg]"
+ for(var/mob/dead/observer/G in player_list)
+ G.show_message("Demonic message from [usr] ([ghost_follow_link(usr, ghost=G)]) to [M] ([ghost_follow_link(M, ghost=G)]): [msg]")
+
//////////The Loot
diff --git a/code/modules/power/singularity/emitter.dm b/code/modules/power/singularity/emitter.dm
index 8f228eb30f4..4b2763c0d86 100644
--- a/code/modules/power/singularity/emitter.dm
+++ b/code/modules/power/singularity/emitter.dm
@@ -276,4 +276,5 @@
if(!emagged)
locked = 0
emagged = 1
- user.visible_message("[user.name] emags the [src.name].","\red You short out the lock.")
+ if(user)
+ user.visible_message("[user.name] emags the [src.name].","\red You short out the lock.")
diff --git a/icons/obj/power.dmi b/icons/obj/power.dmi
index ea42ac5b39d..19e56047c76 100644
Binary files a/icons/obj/power.dmi and b/icons/obj/power.dmi differ
diff --git a/paradise.dme b/paradise.dme
index a1748771fa1..2126b1b0b21 100644
--- a/paradise.dme
+++ b/paradise.dme
@@ -1111,7 +1111,6 @@
#include "code\modules\events\electrical_storm.dm"
#include "code\modules\events\event.dm"
#include "code\modules\events\event_container.dm"
-#include "code\modules\events\event_dynamic.dm"
#include "code\modules\events\event_manager.dm"
#include "code\modules\events\grid_check.dm"
#include "code\modules\events\infestation.dm"