From 7770c2071e1493ec5dc36ea856cf3628b9700bf8 Mon Sep 17 00:00:00 2001 From: Nerd Lord Date: Tue, 20 Oct 2015 17:07:34 -0400 Subject: [PATCH] Once again overhauls revenants: Instead of supporting health and essence, with health being three times essence, essence is tripled and now acts as revenant health. Draining a target is slightly shorter, but if the target is dragged away while you are draining, the drain will fail. If you get exceptionally lucky, you can gain a higher essence regen cap from draining - this requires the target mob to have a ckey, be alive, and for RNG to favor you. You can no longer abuse the spawns in reveal and stun to be invisible or move while draining a target(this is really awful I want a better way to do it) Overload lights now has a wider range, but only shocks people adjacent to lights. Defile damages windows slightly less and makes lights flicker for somewhat longer. Malfunction no longer disables bots after emagging them. --- .../living/simple_animal/revenant/revenant.dm | 161 ++++++++++-------- .../revenant/revenant_abilities.dm | 77 ++++----- 2 files changed, 132 insertions(+), 106 deletions(-) diff --git a/code/modules/mob/living/simple_animal/revenant/revenant.dm b/code/modules/mob/living/simple_animal/revenant/revenant.dm index 29996e19f01..154aab864d2 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant.dm @@ -12,8 +12,8 @@ icon_state = "revenant_idle" incorporeal_move = 3 invisibility = INVISIBILITY_REVENANT - health = 25 - maxHealth = 25 + health = INFINITY //Revenants don't use health, they use essence instead + maxHealth = INFINITY healable = 0 see_invisible = SEE_INVISIBLE_MINIMUM see_in_dark = 8 @@ -33,29 +33,65 @@ flying = 1 anchored = 1 - 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 = 75 //The resource, and health, of revenants. + var/essence_regen_cap = 75 //The regeneration cap of essence (go figure); regenerates every Life() tick up to this amount. 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/essence_regen_amount = 5 //How much essence regenerates var/essence_accumulated = 0 //How much essence the revenant has stolen var/revealed = 0 //If the revenant can take damage from normal sources. + var/reveal_duration = 0 //How long the revenant is revealed for, is about 2 seconds times this var. + var/stun_duration = 0 //How long the revenant is stunned for, is about 2 seconds times this var. 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/essence_drained = 0 //How much essence the revenant has drained from the corpse it's feasting on. 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(revealed && essence <= 0) + death() + if(reveal_duration) + reveal_duration -- + if(reveal_duration <= 0) + reveal_duration = 0 + revealed = 0 + invisibility = INVISIBILITY_REVENANT + src << "You are once more concealed." + if(stun_duration) + stun_duration -- + if(stun_duration <= 0) + stun_duration = 0 + notransform = 0 + src << "You can move again!" 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 + essence = min(essence_regen_cap, essence+essence_regen_amount) + + +/mob/living/simple_animal/revenant/proc/reveal(time) + if(!src) + return + if(time <= 0) + return + revealed = 1 + invisibility = 0 + if(!reveal_duration) + src << "You have been revealed!" + else + src << "You have been revealed!" + reveal_duration += time + +/mob/living/simple_animal/revenant/proc/stun(time) + if(!src) + return + if(time <= 0) + return + notransform = 1 + if(!stun_duration) + src << "You cannot move!" + else + src << "You cannot move!" + stun_duration += time + /mob/living/simple_animal/revenant/ex_act(severity, target) return 1 //Immune to the effects of explosions. @@ -63,13 +99,23 @@ /mob/living/simple_animal/revenant/blob_act() return //blah blah blobs aren't in tune with the spirit world, or something. +/mob/living/simple_animal/revenant/singularity_act() + return //don't walk into the singularity expecting to find corpses, okay? + +/mob/living/simple_animal/revenant/adjustBruteLoss(amount) + if(!revealed) + return + essence = max(0, essence-amount) + if(essence == 0) + src << "You feel your essence fraying!/span>" + + /mob/living/simple_animal/revenant/ClickOn(atom/A, params) //Copypaste from ghost code - revenants can't interact with the world directly. if(client.inquisitive_ghost) A.examine(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 @@ -85,25 +131,27 @@ target << "You feel as if you are being watched." return draining = 1 - essence_drained = 2 + essence_drained = rand(15, 20) 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 + essence_drained += rand(20, 30) if(target.stat != DEAD) src << "Their soul blazes with life!" - essence_drained += 2 + essence_drained += rand(40, 50) 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) + if(1 to 30) src << "[target] will not yield much essence. Still, every bit counts." - if(3 to 4) + if(30 to 70) src << "[target] will yield an average amount of essence." - if(5 to INFINITY) + if(70 to 95) src << "Such a feast! [target] will yield much essence to you." + if(95 to INFINITY) + src << "Ah, the perfect soul. [target] will yield massive amounts of 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." @@ -114,17 +162,24 @@ 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) + reveal(3) + stun(3) 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) + target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=30) + if(target && in_range(src, 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, 0, target) + if(essence_drained >= 95) + essence_regen_cap += 25 + src << "The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap]." src << "[target]'s soul has been considerably weakened and will yield no more essence for the time being." target.visible_message("[target] slumps onto the ground.", \ "Violets lights, dancing in your vision, getting clo--") drained_mobs.Add(target) target.death(0) + else + src << "[target] has been drawn out of your grasp. The link has been broken." + target.visible_message("[target] slumps onto the ground.", \ + "Violets lights, dancing in your vision, receding--") icon_state = "revenant_idle" else src << "You are not close enough to siphon [target]'s soul. The link has been broken." @@ -142,12 +197,14 @@ M << "REVENANT: [src] says, \"[message]\"" //Can commune with the dead return + /mob/living/simple_animal/revenant/Stat() ..() if(statpanel("Status")) stat(null, "Current essence: [essence]E") stat(null, "Stolen essence: [essence_accumulated]E") + /mob/living/simple_animal/revenant/New() ..() spawn(5) @@ -159,8 +216,8 @@ src << "You are a revenant." src << "Your formerly mundane spirit has been infused with alien energies and empowered into a revenant." src << "You are not dead, not alive, but somewhere in between. You are capable of limited interaction with both worlds." - src << "You are invincible and invisible to everyone but other ghosts. Some abilities may change this." - src << "To function, you are to drain the life essence from humans. This essence is a resource and will power all of your abilities." + src << "You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable." + src << "To function, you are to drain the life essence from humans. This essence is a resource, as well as your health, and will power all of your abilities." 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 https://tgstation13.org/wiki/Revenant to learn more." var/datum/objective/revenant/objective = new @@ -177,11 +234,12 @@ AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_defile(null)) AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf(null)) + /mob/living/simple_animal/revenant/death() if(!revealed) //Revenants cannot die if they aren't revealed return 0 ..(1) - src << "NO! No... it's too late, you can feel yourself fading..." + src << "NO! No... it's too late, you can feel your essence breaking apart..." notransform = 1 revealed = 1 invisibility = 0 @@ -203,13 +261,12 @@ if(istype(W, /obj/item/weapon/nullrod)) visible_message("[src] violently flinches!", \ "As the null rod passes through you, you feel your essence draining away!") - essence -= 25 //hella effective + adjustBruteLoss(25) //hella effective inhibited = 1 spawn(30) inhibited = 0 ..() - /mob/living/simple_animal/revenant/proc/castcheck(essence_cost) if(!src) return @@ -225,18 +282,14 @@ return 0 return 1 - - /mob/living/simple_animal/revenant/proc/change_essence_amount(essence_amt, silent = 0, source = null) if(!src) return if(essence + essence_amt <= 0) return - essence += essence_amt - essence = max(0, essence) + essence = max(0, essence+essence_amt) if(essence_amt > 0) - essence_accumulated += essence_amt - essence_accumulated = max(0, essence_accumulated) + essence_accumulated = max(0, essence_accumulated+essence_amt) if(!silent) if(essence_amt > 0) src << "Gained [essence_amt]E from [source]." @@ -244,40 +297,12 @@ src << "Lost [essence_amt]E from [source]." return 1 - - -/mob/living/simple_animal/revenant/proc/reveal(time) - if(!src) - return - if(time <= 0) - return - revealed = 1 - invisibility = 0 - src << "You have been revealed." - spawn(time) - revealed = 0 - invisibility = INVISIBILITY_REVENANT - 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 dangerrating = 10 var/targetAmount = 100 /datum/objective/revenant/New() - targetAmount = rand(100,200) + targetAmount = rand(200,500) explanation_text = "Absorb [targetAmount] points of essence from humans." ..() 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 0ed3e23e591..b71cff677a5 100644 --- a/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm +++ b/code/modules/mob/living/simple_animal/revenant/revenant_abilities.dm @@ -23,31 +23,33 @@ //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 Lights (30E)" + name = "Overload Lights (100E)" desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby." panel = "Revenant Abilities (Locked)" - charge_max = 200 + charge_max = 250 clothes_req = 0 range = 1 - var/reveal = 80 - var/stun = 20 + var/shock_range = 1 + var/shock_damage = 20 + var/reveal = 8 + var/stun = 2 var/locked = 1 action_icon_state = "overload_lights" action_background_icon_state = "bg_revenant" /obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(locked) - if(!user.castcheck(-30)) + if(!user.castcheck(-100)) charge_counter = charge_max return user << "You have unlocked Overload Lights!" - name = "Overload Lights (20E)" + name = "Overload Lights (50E)" panel = "Revenant Abilities" locked = 0 - range = 2 + range = 5 charge_counter = charge_max return - if(!user.castcheck(-20)) + if(!user.castcheck(-50)) charge_counter = charge_max return for(var/turf/T in targets) @@ -57,51 +59,52 @@ if(!L.on) return L.visible_message("\The [L] suddenly flares brightly and begins to spark!") - 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() + s.set_up(4, 0, L) sleep(10) - for(var/mob/living/M in range(4, L)) + s.start() + sleep(20) + for(var/mob/living/carbon/human/M in range(shock_range, 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) + spawn(0) + M.Beam(L,icon_state="lightning",icon='icons/effects/effects.dmi',time=5) + M.electrocute_act(shock_damage, "[L.name]", safety=1) + var/datum/effect/effect/system/spark_spread/z = new /datum/effect/effect/system/spark_spread + z.set_up(4, 0, M) + z.start() + playsound(M, 'sound/machines/defib_zap.ogg', 50, 1, -1) user.reveal(reveal) user.stun(stun) //Defile: Corrupts nearby stuff, unblesses floor tiles. /obj/effect/proc_holder/spell/aoe_turf/revenant_defile - name = "Defile (20E)" + name = "Defile (75E)" desc = "Twists and corrupts the nearby area. Also dispels holy auras on floors." panel = "Revenant Abilities (Locked)" charge_max = 200 clothes_req = 0 range = 1 - var/reveal = 100 - var/stun = 20 + var/reveal = 6 + var/stun = 2 var/locked = 1 action_icon_state = "defile" action_background_icon_state = "bg_revenant" /obj/effect/proc_holder/spell/aoe_turf/revenant_defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr) if(locked) - if(!user.castcheck(-35)) + if(!user.castcheck(-75)) charge_counter = charge_max return user << "You have unlocked Defile!" - name = "Defile (10E)" + name = "Defile (40E)" panel = "Revenant Abilities" locked = 0 range = 3 charge_counter = charge_max return - if(!user.castcheck(-20)) + if(!user.castcheck(-40)) charge_counter = charge_max return for(var/turf/T in targets) @@ -110,42 +113,42 @@ T.flags -= NOJAUNT for(var/mob/living/carbon/human/human in T.contents) human << "You suddenly feel tired." - human.adjustStaminaLoss(35) + human.adjustStaminaLoss(40) for(var/obj/structure/window/window in T.contents) - window.hit(rand(50,125)) + window.hit(rand(50,100)) for(var/obj/machinery/light/light in T.contents) - light.flicker() //spooky + light.flicker(30) //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)" + name = "Malfunction (150E)" desc = "Corrupts and damages nearby machines and mechanical objects." panel = "Revenant Abilities (Locked)" - charge_max = 150 + charge_max = 250 clothes_req = 0 range = 1 - var/reveal = 60 - var/stun = 30 + var/reveal = 4 + var/stun = 2 var/locked = 1 action_icon_state = "malfunction" action_background_icon_state = "bg_revenant" /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)) + if(!user.castcheck(-150)) charge_counter = charge_max return user << "You have unlocked Malfunction!" - name = "Malfunction (15E)" + name = "Malfunction (40E)" panel = "Revenant Abilities" locked = 0 range = 4 charge_counter = charge_max return - if(!user.castcheck(-15)) + if(!user.castcheck(-40)) charge_counter = charge_max return for(var/turf/T in targets) @@ -156,7 +159,7 @@ bot.open = 1 bot.Emag(null) for(var/obj/machinery/mach in T.contents) - if(istype(mach, /obj/machinery/dominator) || istype(mach, /obj/machinery/power/apc) || istype(mach, /obj/machinery/power/smes)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery + if(istype(mach, /obj/machinery/dominator) || istype(mach, /obj/machinery/power/apc) || istype(mach, /obj/machinery/power/smes) || istype(mach, /obj/machinery/bot)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery //Also doesn't work on bots so they can go do stuff faster(god this is so ugly) continue if(prob(10)) mach.emag_act(null) @@ -166,9 +169,7 @@ S << "ERROR $!(@ ERROR )#^! SENSORY OVERLOAD \[$(!@#" S << 'sound/misc/interference.ogg' playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1) - var/datum/effect/effect/system/spark_spread/sp = new /datum/effect/effect/system/spark_spread - sp.set_up(5, 1, S) - sp.start() + S.spark_system.start() S.Weaken(6) user.reveal(reveal) user.stun(stun) \ No newline at end of file