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.")