diff --git a/code/game/dna/genes/vg_powers.dm b/code/game/dna/genes/vg_powers.dm
index 073683fbb8a..9fe03b734aa 100644
--- a/code/game/dna/genes/vg_powers.dm
+++ b/code/game/dna/genes/vg_powers.dm
@@ -244,7 +244,7 @@ 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)]: [msg]")
+ 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
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/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm
index 2594d4ce5b8..ab03c19d18c 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm
@@ -36,6 +36,9 @@
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()
..()
@@ -77,6 +80,70 @@
if(world.time <= next_move)
return
A.attack_ghost(src)
+ if(ishuman(A) && in_range(src, A))
+ src.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(!in_range(src, target))
+ src << "You are not close enough to siphon [target]'s soul. The link has been broken."
+ draining = 0
+ return
+ 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"
+ draining = 0
+ return
/mob/living/simple_animal/revenant/say(message)
return 0 //Revenants cannot speak out loud.
@@ -123,6 +190,7 @@
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/revenant_defile
+ src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf
return 1
return 0
@@ -190,22 +258,32 @@
user << "Lost [essence_amt]E from [source]."
return 1
-/mob/living/simple_animal/revenant/proc/reveal(var/time, var/stun)
+/mob/living/simple_animal/revenant/proc/reveal(time)
var/mob/living/simple_animal/revenant/R = usr
if(!istype(usr) || !usr)
return
+ if(time <= 0)
+ return
R.revealed = 1
R.invisibility = 0
- if(stun)
- R.notransform = 1
- R << "You have been revealed[stun ? " and cannot move" : ""]."
+ R << "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" : ""]."
+ R << "You are once more concealed."
+/mob/living/simple_animal/revenant/proc/stun(time)
+ var/mob/living/simple_animal/revenant/R = usr
+ if(!istype(usr) || !usr)
+ return
+ if(time <= 0)
+ return
+ R.notransform = 1
+ R << "You cannot move!"
+ spawn(time)
+ R.notransform = 0
+ R << "You can move again!"
+
/datum/objective/revenant
var/targetAmount = 100
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 873d5dfa877..7f34835a0be 100644
--- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
+++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm
@@ -1,102 +1,28 @@
//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 = 1
- var/essence_drained = 0
- var/draining
- var/list/drained_mobs = list() //Cannot harvest the same mob twice
/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!"
- charge_counter = charge_max
- return
- if(target in drained_mobs)
- user << "[target]'s soul is dead and empty."
- charge_counter = charge_max
- return
- if(!target.stat)
- 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 = 2
- user << "You search for the soul of [target]."
- sleep(10)
- if(target.ckey)
- user << "Their soul burns with intelligence."
- essence_drained += 2
- if(target.stat != DEAD)
- user << "Their soul blazes with life!"
- essence_drained += 2
- else
- user << "Their soul is weak and faltering."
- 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."
- return //hey, wait a minute...
- user << "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..."
- user.icon_state = "revenant_draining"
- user.reveal(65,1)
- 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=60)
- 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."
- 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, "")
@@ -118,6 +44,8 @@
charge_max = 200
clothes_req = 0
range = 1
+ var/reveal = 80
+ var/stun = 10
var/locked = 1
/obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
@@ -129,7 +57,7 @@
name = "Overload Lights (20E)"
panel = "Revenant Abilities"
locked = 0
- range = 5
+ range = 6
charge_counter = charge_max
return
if(!user.castcheck(-20))
@@ -156,29 +84,31 @@
z.set_up(4, 1, M)
z.start()
playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1)
- user.reveal(80)
-
+ user.reveal(reveal)
+ user.stun(stun)
//Defile: Corrupts nearby stuff, unblesses floor tiles.
/obj/effect/proc_holder/spell/aoe_turf/revenant_defile
- name = "Defile (40E)"
- desc = "Twists and corrupts certain nearby objects. Also dispels holy auras on floors, but not salt lines."
+ 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 = 200
clothes_req = 0
range = 1
+ var/reveal = 100
+ var/stun = 10
var/locked = 1
/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(-40))
+ 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))
@@ -188,22 +118,70 @@
spawn(0)
if(T.flags & NOJAUNT)
T.flags -= NOJAUNT
- for(var/obj/machinery/bot/bot in T.contents)
- bot.locked = 0
- bot.open = 1
- bot.emagged = 2
- bot.Emag(null)
+ if(!istype(T, /turf/simulated/wall/cult) && istype(T, /turf/simulated/wall) && prob(30))
+ T.ChangeTurf(/turf/simulated/wall/cult)
+ if(!istype(T, /turf/simulated/floor/engine/cult) && istype(T, /turf/simulated/floor) && prob(30))
+ T.ChangeTurf(/turf/simulated/floor/engine/cult)
for(var/mob/living/carbon/human/human in T.contents)
human << "You suddenly feel tired."
- human.adjustStaminaLoss(50)
+ human.adjustStaminaLoss(35)
+ for(var/obj/structure/window/window in T.contents)
+ window.hit(rand(50,125))
+ for(var/obj/machinery/light/light in T.contents)
+ light.flicker() //spooky
+ 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/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'
robot.emp_act(2)
playsound(robot, 'sound/machines/warning-buzzer.ogg', 50, 1)
- for(var/obj/structure/window/window in T.contents)
- window.hit(rand(50,200))
- for(var/obj/machinery/light/light in T.contents)
- light.flicker() //spooky
- user.reveal(100)
+ for(var/mob/living/carbon/human/human in T.contents)
+ human << "You feel a burst of cold throughout your body..."
+ human.emp_act(2)
+ for(var/obj/machinery/mach in T.contents)
+ switch(rand(1,10))
+ if(1 to 3)
+ mach.emp_act(1)
+ if(4 to 9)
+ mach.emp_act(2)
+ if(10)
+ mach.emag_act(null)
+ user.reveal(reveal)
+ user.stun(stun)
diff --git a/code/modules/mob/living/simple_animal/slaughter/slaughter.dm b/code/modules/mob/living/simple_animal/slaughter/slaughter.dm
index c6457047530..764947115d3 100644
--- a/code/modules/mob/living/simple_animal/slaughter/slaughter.dm
+++ b/code/modules/mob/living/simple_animal/slaughter/slaughter.dm
@@ -120,11 +120,11 @@
var/msg = stripped_input(usr, "What do you wish to tell [M]?", null, "")
if(!(msg))
return
- log_say("Slaughter Demon Transmit: [key_name(usr)]->[key_name(M)]: [say]")
+ 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)]): [say]")
+ 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 a30d2de451e..3880e7fe2dc 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.")