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.
This commit is contained in:
Nerd Lord
2015-10-20 17:07:34 -04:00
parent 8a35115f1d
commit 7770c2071e
2 changed files with 132 additions and 106 deletions
@@ -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 << "<span class='boldnotice'>You are once more concealed.</span>"
if(stun_duration)
stun_duration --
if(stun_duration <= 0)
stun_duration = 0
notransform = 0
src << "<span class='boldnotice'>You can move again!</span>"
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 << "<span class='userdanger'>You have been revealed!</span>"
else
src << "<span class='warning'>You have been revealed!</span>"
reveal_duration += time
/mob/living/simple_animal/revenant/proc/stun(time)
if(!src)
return
if(time <= 0)
return
notransform = 1
if(!stun_duration)
src << "<span class='userdanger'>You cannot move!</span>"
else
src << "<span class='warning'>You cannot move!</span>"
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 << "<span class='userdanger'>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 << "<span class='notice'>You search for the soul of [target].</span>"
if(do_after(src, 10, 3, 0, target)) //did they get deleted in that second?
if(target.ckey)
src << "<span class='notice'>Their soul burns with intelligence.</span>"
essence_drained += 2
essence_drained += rand(20, 30)
if(target.stat != DEAD)
src << "<span class='notice'>Their soul blazes with life!</span>"
essence_drained += 2
essence_drained += rand(40, 50)
else
src << "<span class='notice'>Their soul is weak and faltering.</span>"
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 << "<span class='info'>[target] will not yield much essence. Still, every bit counts.</span>"
if(3 to 4)
if(30 to 70)
src << "<span class='info'>[target] will yield an average amount of essence.</span>"
if(5 to INFINITY)
if(70 to 95)
src << "<span class='info'>Such a feast! [target] will yield much essence to you.</span>"
if(95 to INFINITY)
src << "<span class='boldnotice'>Ah, the perfect soul. [target] will yield massive amounts of essence to you.</span>"
if(do_after(src, 30, 9, 0, target)) //how about now
if(!target.stat)
src << "<span class='warning'>They are now powerful enough to fight off your draining.</span>"
@@ -114,17 +162,24 @@
if(target.stat != DEAD)
target << "<span class='warning'>You feel a horribly unpleasant draining sensation as your grip on life weakens...</span>"
icon_state = "revenant_draining"
reveal(65)
stun(65)
reveal(3)
stun(3)
target.visible_message("<span class='warning'>[target] suddenly rises slightly into the air, their skin turning an ashy gray.</span>")
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 << "<span class='info'>The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap].</span>"
src << "<span class='info'>[target]'s soul has been considerably weakened and will yield no more essence for the time being.</span>"
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
"<span class='userdanger'>Violets lights, dancing in your vision, getting clo--</span>")
drained_mobs.Add(target)
target.death(0)
else
src << "<span class='warning'>[target] has been drawn out of your grasp. The link has been broken.</span>"
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
"<span class='userdanger'>Violets lights, dancing in your vision, receding--</span>")
icon_state = "revenant_idle"
else
src << "<span class='warning'>You are not close enough to siphon [target]'s soul. The link has been broken.</span>"
@@ -142,12 +197,14 @@
M << "<span class='deadsay'><b>REVENANT: [src]</b> 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 << "<span class='deadsay'><font size=3><b>You are a revenant.</b></font></span>"
src << "<b>Your formerly mundane spirit has been infused with alien energies and empowered into a revenant.</b>"
src << "<b>You are not dead, not alive, but somewhere in between. You are capable of limited interaction with both worlds.</b>"
src << "<b>You are invincible and invisible to everyone but other ghosts. Some abilities may change this.</b>"
src << "<b>To function, you are to drain the life essence from humans. This essence is a resource and will power all of your abilities.</b>"
src << "<b>You are invincible and invisible to everyone but other ghosts. Most abilities will reveal you, rendering you vulnerable.</b>"
src << "<b>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.</b>"
src << "<b><i>You do not remember anything of your past lives, nor will you remember anything about this one after your death.</i></b>"
src << "<b>Be sure to read the wiki page at https://tgstation13.org/wiki/Revenant to learn more.</b>"
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 << "<span class='userdanger'>NO! No... it's too late, you can feel yourself fading...</span>"
src << "<span class='userdanger'>NO! No... it's too late, you can feel your essence breaking apart...</span>"
notransform = 1
revealed = 1
invisibility = 0
@@ -203,13 +261,12 @@
if(istype(W, /obj/item/weapon/nullrod))
visible_message("<span class='warning'>[src] violently flinches!</span>", \
"<span class='userdanger'>As the null rod passes through you, you feel your essence draining away!</span>")
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 << "<span class='notice'>Gained [essence_amt]E from [source].</span>"
@@ -244,40 +297,12 @@
src << "<span class='danger'>Lost [essence_amt]E from [source].</span>"
return 1
/mob/living/simple_animal/revenant/proc/reveal(time)
if(!src)
return
if(time <= 0)
return
revealed = 1
invisibility = 0
src << "<span class='warning'>You have been revealed.</span>"
spawn(time)
revealed = 0
invisibility = INVISIBILITY_REVENANT
src << "<span class='notice'>You are once more concealed.</span>"
/mob/living/simple_animal/revenant/proc/stun(time)
if(!src)
return
if(time <= 0)
return
notransform = 1
src << "<span class='warning'>You cannot move!</span>"
spawn(time)
notransform = 0
src << "<span class='notice'>You can move again!</span>"
/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."
..()
@@ -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 << "<span class='info'>You have unlocked Overload Lights!</span>"
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("<span class='warning'><b>\The [L] suddenly flares brightly and begins to spark!</span>")
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 << "<span class='info'>You have unlocked Defile!</span>"
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 << "<span class='warning'>You suddenly feel tired.</span>"
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 << "<span class='info'>You have unlocked Malfunction!</span>"
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 << "<span class='warning'><b>ERROR $!(@ ERROR )#^! SENSORY OVERLOAD \[$(!@#</b></span>"
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)