well this escalated quickly

This commit is contained in:
Aurorablade
2015-11-22 23:16:30 -05:00
parent d038dfeede
commit 677b38304d
9 changed files with 372 additions and 276 deletions
@@ -2,17 +2,22 @@
//"Ghosts" that are invisible and move like ghosts, cannot take damage while invsible
//Don't hear deadchat and are NOT normal ghosts
//Admin-spawn or random event
#define INVISIBILITY_REVENANT 50
/mob/living/simple_animal/revenant
name = "revenant"
desc = "A malevolent spirit."
icon = 'icons/mob/mob.dmi'
icon_state = "revenant_idle"
var/icon_idle = "revenant_idle"
var/icon_reveal = "revenant_revealed"
var/icon_stun = "revenant_stun"
var/icon_drain = "revenant_draining"
incorporeal_move = 3
invisibility = INVISIBILITY_OBSERVER
health = 25
maxHealth = 25
see_invisible = SEE_INVISIBLE_OBSERVER
invisibility = INVISIBILITY_REVENANT
health = INFINITY //Revenants don't use health, they use essence instead
maxHealth = INFINITY
see_invisible = INVISIBILITY_REVENANT
universal_understand = 1
response_help = "passes through"
response_disarm = "swings at"
@@ -23,16 +28,16 @@
harm_intent_damage = 0
friendly = "touches"
status_flags = 0
see_in_dark = 8
wander = 0
density = 0
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 of revenants. Max health is equal to three times this amount
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/unreveal_time = 0 //How long the revenant is revealed for, is about 2 seconds times this var.
@@ -41,27 +46,24 @@
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
var/perfectsouls = 0 //How many perfect, regen-cap increasing souls the revenant has.
var/image/ghostimage = null //Visible to ghost with darkness off
/mob/living/simple_animal/revenant/Life()
..()
if(essence < essence_min)
essence = essence_min
if(revealed && essence <= 0)
death()
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
essence = min(essence_regen_cap, essence+essence_regen_amount)
if(unreveal_time && world.time >= unreveal_time)
unreveal_time = 0
revealed = 0
invisibility = INVISIBILITY_OBSERVER
invisibility = INVISIBILITY_REVENANT
src << "<span class='revenboldnotice'>You are once more concealed.</span>"
if(unstun_time && world.time >= unstun_time)
unstun_time = 0
notransform = 0
src << "<span class='revenboldnotice'>You can move again!</span>"
if(!revealed)
health = maxHealth //Heals to full when not revealed
update_spooky_icon()
/mob/living/simple_animal/revenant/ex_act(severity)
@@ -70,6 +72,19 @@
/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/singularity_act()
return //don't walk into the singularity expecting to find corpses, okay?
/mob/living/simple_animal/revenant/narsie_act()
return //most humans will now be either bones or harvesters, but we're still un-alive.
/mob/living/simple_animal/revenant/adjustBruteLoss(amount)
if(!revealed)
return
essence = max(0, essence-amount)
if(essence == 0)
src << "<span class='revendanger'>You feel your essence fraying!</span>"
/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)
@@ -99,62 +114,78 @@
if(!castcheck(0))
return
if(draining)
src << "<span class='warning'>You are already siphoning the essence of a soul!</span>"
src << "<span class='revenwarning'>You are already siphoning the essence of a soul!</span>"
return
if(target in drained_mobs)
src << "<span class='warning'>[target]'s soul is dead and empty.</span>"
src << "<span class='revenwarning'>[target]'s soul is dead and empty.</span>"
return
if(!target.stat)
src << "<span class='notice'>This being's soul is too strong to harvest.</span>"
src << "<span class='revennotice'>This being's soul is too strong to harvest.</span>"
if(prob(10))
target << "You feel as if you are being watched."
return
draining = 1
essence_drained = 2
src << "<span class='notice'>You search for the soul of [target].</span>"
essence_drained = rand(15, 20)
src << "<span class='revennotice'>You search for the soul of [target].</span>"
if(do_after(src, 10, 3, 0, target = target)) //did they get deleted in that second?
if(target.ckey)
src << "<span class='notice'>Their soul burns with intelligence.</span>"
essence_drained += 2
src << "<span class='revennotice'>Their soul burns with intelligence.</span>"
essence_drained += rand(20, 30)
if(target.stat != DEAD)
src << "<span class='notice'>Their soul blazes with life!</span>"
essence_drained += 2
src << "<span class='revennotice'>Their soul blazes with life!</span>"
essence_drained += rand(40, 50)
else
src << "<span class='notice'>Their soul is weak and faltering.</span>"
src << "<span class='revennotice'>Their soul is weak and faltering.</span>"
if(do_after(src, 20, 6, 0, target = target)) //did they get deleted NOW?
switch(essence_drained)
if(1 to 2)
src << "<span class='info'>[target] will not yield much essence. Still, every bit counts.</span>"
if(3 to 4)
src << "<span class='info'>[target] will yield an average amount of essence.</span>"
if(5 to INFINITY)
src << "<span class='info'>Such a feast! [target] will yield much essence to you.</span>"
if(do_after(src, 30, 9, 0, target = target)) //how about now
if(1 to 30)
src << "<span class='revennotice'>[target] will not yield much essence. Still, every bit counts.</span>"
if(30 to 70)
src << "<span class='revennotice'>[target] will yield an average amount of essence.</span>"
if(70 to 90)
src << "<span class='revenboldnotice'>Such a feast! [target] will yield much essence to you.</span>"
if(90 to INFINITY)
src << "<span class='revenbignotice'>Ah, the perfect soul. [target] will yield massive amounts of essence to you.</span>"
if(do_after(src, 20, 6, 0, target = target)) //how about now
if(!target.stat)
src << "<span class='warning'>They are now powerful enough to fight off your draining.</span>"
src << "<span class='revenwarning'>They are now powerful enough to fight off your draining.</span>"
target << "<span class='boldannounce'>You feel something tugging across your body before subsiding.</span>"
draining = 0
return //hey, wait a minute...
src << "<span class='danger'>You begin siphoning essence from [target]'s soul.</span>"
src << "<span class='revenminor'>You begin siphoning essence from [target]'s soul.</span>"
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(27)
stun(27)
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)
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] gently slumps back onto the ground.</span>")
target.Beam(src,icon_state="drain_life",icon='icons/effects/effects.dmi',time=26)
if(do_after(src, 30, 9, 0, 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 > 90)
essence_regen_cap += 25
perfectsouls += 1
src << "<span class='revenboldnotice'>The perfection of [target]'s soul has increased your maximum essence level. Your new maximum essence is [essence_regen_cap].</span>"
src << "<span class='revennotice'>[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='revenwarning'>Violets lights, dancing in your vision, getting clo--</span>")
drained_mobs.Add(target)
target.death(0)
icon_state = "revenant_idle"
else
src << "<span class='revenwarning'>[target ? "[target] has":"They have"] been drawn out of your grasp. The link has been broken.</span>"
draining = 0
essence_drained = 0
if(target) //Wait, target is WHERE NOW?
target.visible_message("<span class='warning'>[target] slumps onto the ground.</span>", \
"<span class='revenwarning'>Violets lights, dancing in your vision, receding--</span>")
return
else
src << "<span class='warning'>You are not close enough to siphon [target]'s soul. The link has been broken.</span>"
src << "<span class='revenwarning'>You are not close enough to siphon [target ? "[target]'s":"their"] soul. The link has been broken.</span>"
draining = 0
essence_drained = 0
return
draining = 0
essence_drained = 0
return
/mob/living/simple_animal/revenant/say(message)
@@ -163,11 +194,17 @@
/mob/living/simple_animal/revenant/Stat()
..()
if(statpanel("Status"))
stat(null, "Current essence: [essence]E")
stat(null, "Current essence: [essence]/[essence_regen_cap]E")
stat(null, "Stolen essence: [essence_accumulated]E")
stat(null, "Stolen perfect souls: [perfectsouls]")
/mob/living/simple_animal/revenant/New()
..()
ghostimage = image(src.icon,src,src.icon_state)
ghost_darkness_images |= ghostimage
updateallghostimages()
spawn(5)
if(src.mind)
src.mind.wipe_memory()
@@ -176,8 +213,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 http://nanotrasen.se/wiki/index.php/Revenant to learn more.</b>"
var/datum/objective/revenant/objective = new
@@ -198,17 +235,21 @@
/mob/living/simple_animal/revenant/proc/giveSpells()
if(src.mind)
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/revenant_defile
src.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/revenant_malf
src.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/revenant_transmit(null))
src.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/overload(null))
src.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/defile(null))
src.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction(null))
return 1
return 0
/mob/living/simple_animal/revenant/death()
..()
src << "<span class='userdanger'><b>NO! No... it's too late, you can feel yourself fading...</b></span>"
if(!revealed) //Revenants cannot die if they aren't revealed
return
ghost_darkness_images -= ghostimage
updateallghostimages()
src << "<span class='revendanger'>NO! No... it's too late, you can feel your essence breaking apart...</span>"
notransform = 1
revealed = 1
invisibility = 0
@@ -218,8 +259,9 @@
for(var/i = alpha, i > 0, i -= 10)
sleep(0.1)
alpha = i
visible_message("<span class='danger'>[src]'s body breaks apart into blue dust.</span>")
new /obj/item/weapon/ectoplasm/revenant(get_turf(src))
visible_message("<span class='danger'>[src]'s body breaks apart into a fine pile of blue dust.</span>")
var/obj/item/weapon/ectoplasm/revenant/R = new (get_turf(src))
R.client_to_revive = src.client //If the essence reforms, the old revenant is put back in the body
ghostize()
qdel(src)
return
@@ -228,8 +270,8 @@
/mob/living/simple_animal/revenant/attackby(obj/item/W, mob/living/user, params)
if(istype(W, /obj/item/weapon/nullrod))
visible_message("<span class='warning'>[src] violently flinches!</span>", \
"<span class='boldannounce'>As the null rod passes through you, you feel your essence draining away!</span>")
essence -= 25 //hella effective
"<span class='revendanger'>As the null rod passes through you, you feel your essence draining away!</span>")
adjustBruteLoss(25) //hella effective
inhibited = 1
spawn(30)
inhibited = 0
@@ -241,13 +283,13 @@
return
var/turf/T = get_turf(src)
if(istype(T, /turf/simulated/wall))
src << "<span class='warning'>You cannot use abilities from inside of a wall.</span>"
src << "<span class='revenwarning'>You cannot use abilities from inside of a wall.</span>"
return 0
if(src.inhibited)
src << "<span class='warning'>Your powers have been suppressed by nulling energy!</span>"
src << "<span class='revenwarning'>Your powers have been suppressed by nulling energy!</span>"
return 0
if(!src.change_essence_amount(essence_cost, 1))
src << "<span class='warning'>You lack the essence to use that ability.</span>"
src << "<span class='revenwarning'>You lack the essence to use that ability.</span>"
return 0
return 1
@@ -256,16 +298,14 @@
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>"
src << "<span class='revennotice'>Gained [essence_amt]E from [source].</span>"
else
src << "<span class='danger'>Lost [essence_amt]E from [source].</span>"
src << "<span class='revenminor'>Lost [essence_amt]E from [source].</span>"
return 1
/mob/living/simple_animal/revenant/proc/reveal(time)
@@ -276,11 +316,12 @@
revealed = 1
invisibility = 0
if(!unreveal_time)
src << "<span class='revennotice'>You have been revealed!</span>"
src << "<span class='revendanger'>You have been revealed!</span>"
unreveal_time = world.time + time
else
src << "<span class='revenboldnotice'>You have been revealed!</span>"
src << "<span class='revenwarning'>You have been revealed!</span>"
unreveal_time = unreveal_time + time
update_spooky_icon()
/mob/living/simple_animal/revenant/proc/stun(time)
if(!src)
@@ -289,30 +330,30 @@
return
notransform = 1
if(!unstun_time)
src << "<span class='revennotice'>You cannot move!</span>"
src << "<span class='revendanger'>You cannot move!</span>"
unstun_time = world.time + time
else
src << "<span class='revenboldnotice'>You cannot move!</span>"
src << "<span class='revenwarning'>You cannot move!</span>"
unstun_time = unstun_time + time
update_spooky_icon()
/mob/living/simple_animal/revenant/proc/update_spooky_icon()
if(unreveal_time)
if(draining)
icon_state = "revenant_draining"
return
if(unstun_time)
icon_state = "revenant_stun"
return
icon_state = "revenant_revealed"
return
icon_state = "revenant_idle"
if(revealed)
if(notransform)
if(draining)
icon_state = icon_drain
else
icon_state = icon_stun
else
icon_state = icon_reveal
else
icon_state = icon_idle
/datum/objective/revenant
var/targetAmount = 100
/datum/objective/revenant/New()
targetAmount = rand(100,200)
targetAmount = rand(200,500)
explanation_text = "Absorb [targetAmount] points of essence from humans."
..()
@@ -349,27 +390,23 @@
icon = 'icons/effects/effects.dmi'
icon_state = "revenantEctoplasm"
w_class = 2
var/reforming = 0
var/reformed = 0
var/reforming = 1
var/inert = 0
var/client/client_to_revive
/obj/item/weapon/ectoplasm/revenant/New()
..()
reforming = 1
reforming = 0
spawn(600) //1 minutes
if(src && reforming)
return reform()
if(src && !reforming)
else
inert = 1
visible_message("<span class='warning'>[src] settles down and seems lifeless.</span>")
return
/obj/item/weapon/ectoplasm/revenant/attack_hand(mob/user)
if(reformed)
user << "<span class='warning'>[src] keeps slipping out of your hands, you can't get a hold on it!</span>"
return
..()
/obj/item/weapon/ectoplasm/revenant/attack_self(mob/user)
if(!reforming)
if(!reforming || inert)
return ..()
user.visible_message("<span class='notice'>[user] scatters [src] in all directions.</span>", \
"<span class='notice'>You scatter [src] across the area. The particles slowly fade away.</span>")
@@ -378,39 +415,58 @@
/obj/item/weapon/ectoplasm/revenant/throw_impact(atom/hit_atom)
..()
if(inert)
return
visible_message("<span class='notice'>[src] breaks into particles upon impact, which fade away to nothingness.</span>")
qdel(src)
/obj/item/weapon/ectoplasm/revenant/examine(mob/user)
..(user)
if(reforming)
user << "<span class='warning'>It is shifting and distorted. It would be wise to destroy this.</span>"
else if(!reforming)
user << "<span class='notice'>It seems inert.</span>"
if(inert)
user << "<span class='revennotice'>It seems inert.</span>"
else if(reforming)
user << "<span class='revenwarning'>It is shifting and distorted. It would be wise to destroy this.</span>"
/obj/item/weapon/ectoplasm/revenant/proc/reform()
if(!reforming || !src)
if(inert || !src)
return
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and has reformed into a new revenant.")
var/key_of_revenant
message_admins("Revenant ectoplasm was left undestroyed for 1 minute and is reforming into a new revenant.")
loc = get_turf(src) //In case it's in a backpack or someone's hand
visible_message("<span class='boldannounce'>[src] suddenly rises into the air before fading away.</span>")
var/mob/living/simple_animal/revenant/R = new(get_turf(src))
qdel(src)
var/list/candidates = get_candidates(BE_REVENANT)
if(!candidates.len)
message_admins("No candidates were found for the new revenant. Oh well!")
return 0
var/client/C = pick(candidates)
var/key_of_revenant = C.key
if(client_to_revive)
for(var/mob/M in dead_mob_list)
if(M.client == client_to_revive) //Only recreates the mob if the mob the client is in is dead
R.client = client_to_revive
key_of_revenant = client_to_revive.key
if(!key_of_revenant)
message_admins("No ckey was found for the new revenant. Oh well!")
return 0
message_admins("The new revenant's old client either could not be found or is in a new, living mob - grabbing a random candidate instead...")
var/list/candidates = get_candidates(BE_REVENANT)
if(!candidates.len)
qdel(R)
message_admins("No candidates were found for the new revenant. Oh well!")
inert = 1
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return 0
var/client/C = pick(candidates)
key_of_revenant = C.key
if(!key_of_revenant)
qdel(R)
message_admins("No ckey was found for the new revenant. Oh well!")
inert = 1
visible_message("<span class='revenwarning'>[src] settles down and seems lifeless.</span>")
return 0
var/datum/mind/player_mind = new /datum/mind(key_of_revenant)
player_mind.active = 1
player_mind.transfer_to(R)
player_mind.assigned_role = "revenant"
player_mind.special_role = "Revenant"
ticker.mode.traitors |= player_mind
message_admins("[key_of_revenant] has been made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was spawned as a revenant by reforming ectoplasm.")
message_admins("[key_of_revenant] has been [client_to_revive ? "re":""]made into a revenant by reforming ectoplasm.")
log_game("[key_of_revenant] was [client_to_revive ? "re":""]made as a revenant by reforming ectoplasm.")
visible_message("<span class='revenboldnotice'>[src] suddenly rises into the air before fading away.</span>")
qdel(src)
if(src) //Should never happen, but just in case
inert = 1
return 1
@@ -1,18 +1,4 @@
//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"
desc = "Siphons the lingering spectral essence from a human, empowering yourself."
panel = "Revenant Abilities"
charge_max = 0 //Short cooldown
clothes_req = 0
range = 1
/obj/effect/proc_holder/spell/targeted/revenant_harvest/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
for(var/mob/living/carbon/human/target in targets)
spawn(0)
user.Harvest(target)
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob for 5E.
//Transmit: the revemant's only direct way to communicate. Sends a single message silently to a single mob
/obj/effect/proc_holder/spell/targeted/revenant_transmit
name = "Transmit"
desc = "Telepathically transmits a message to the target."
@@ -21,155 +7,184 @@
clothes_req = 0
range = 7
include_user = 0
action_icon_state = "r_transmit"
action_background_icon_state = "bg_revenant"
/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
/obj/effect/proc_holder/spell/targeted/revenant_transmit/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
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
log_say("Revenant Transmit: [key_name(usr)]->[key_name(M)]: [msg]")
usr << "<span class='info'><b>You transmit to [M]: </b>[msg]</span>"
M << "<span class='deadsay'><b>A strange voice resonates in your head... </b></span><i>[msg]</I>"
for(var/mob/dead/observer/G in player_list)
G.show_message("<i>Revenant message from <b>[usr]</b> ([ghost_follow_link(usr, ghost=G)]) to <b>[M]</b> ([ghost_follow_link(M, ghost=G)]): [msg]</i>")
usr << "<span class='revennotice'><b>You transmit to [M]:</b> [msg]</span>"
M << "<span class='revennotice'><b>An alien voice resonates from all around...</b></span><i> [msg]</I>"
/obj/effect/proc_holder/spell/aoe_turf/revenant
clothes_req = 0
action_background_icon_state = "bg_revenant"
panel = "Revenant Abilities (Locked)"
name = "Report this to a coder"
var/reveal = 80 //How long it reveals the revenant in deciseconds
var/stun = 20 //How long it stuns the revenant in deciseconds
var/locked = 1 //If it's locked and needs to be unlocked before use
var/unlock_amount = 100 //How much essence it costs to unlock
var/cast_amount = 50 //How much essence it costs to use
/obj/effect/proc_holder/spell/aoe_turf/revenant/New()
..()
if(locked)
name = "[initial(name)] ([unlock_amount]E)"
else
name = "[initial(name)] ([cast_amount]E)"
/obj/effect/proc_holder/spell/aoe_turf/revenant/can_cast(mob/living/simple_animal/revenant/user = usr)
if(user.inhibited)
return 0
if(charge_counter < charge_max)
return 0
if(locked)
if(user.essence <= unlock_amount)
return 0
if(user.essence <= cast_amount)
return 0
return 1
/obj/effect/proc_holder/spell/aoe_turf/revenant/proc/attempt_cast(mob/living/simple_animal/revenant/user = usr)
if(locked)
if(!user.castcheck(-unlock_amount))
charge_counter = charge_max
return 0
name = "[initial(name)] ([cast_amount]E)"
user << "<span class='revennotice'>You have unlocked [initial(name)]!</span>"
panel = "Revenant Abilities"
locked = 0
charge_counter = charge_max
return 0
if(!user.castcheck(-cast_amount))
charge_counter = charge_max
return 0
name = "[initial(name)] ([cast_amount]E)"
user.reveal(reveal)
user.stun(stun)
user.update_action_buttons()
return 1
//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 (30E)"
/obj/effect/proc_holder/spell/aoe_turf/revenant/overload
name = "Overload Lights"
desc = "Directs a large amount of essence into nearby electrical lights, causing lights to shock those nearby."
panel = "Revenant Abilities (Locked)"
charge_max = 200
clothes_req = 0
range = 1
var/reveal = 80
var/stun = 20
var/locked = 1
range = 5
stun = 30
cast_amount = 45
var/shock_range = 2
var/shock_damage = 18
action_icon_state = "overload_lights"
/obj/effect/proc_holder/spell/aoe_turf/revenant_light/cast(list/targets, var/mob/living/simple_animal/revenant/user = usr)
if(locked)
if(!user.castcheck(-30))
charge_counter = charge_max
return
user << "<span class='info'>You have unlocked Overload Lights!</span>"
name = "Overload Lights (20E)"
panel = "Revenant Abilities"
locked = 0
range = 6
charge_counter = charge_max
return
if(!user.castcheck(-20))
charge_counter = charge_max
return
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/light/L in T.contents)
spawn(0)
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()
sleep(10)
for(var/mob/living/M in orange(4, L))
if(M == user)
/obj/effect/proc_holder/spell/aoe_turf/revenant/overload/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(attempt_cast(user))
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/light/L in T.contents)
spawn(0)
if(!L.on)
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(reveal)
user.stun(stun)
L.visible_message("<span class='warning'><b>\The [L] suddenly flares brightly and begins to spark!</span>")
var/datum/effect/effect/system/spark_spread/s = new /datum/effect/effect/system/spark_spread/
s.set_up(4, 0, L)
s.start()
new/obj/effect/overlay/temp/revenant(L.loc)
sleep(20)
if(!L.on) //wait, wait, don't shock me
return
flick("[L.base_state]2", L)
for(var/mob/living/carbon/human/M in view(shock_range, L))
if(M == user)
return
M.Beam(L,icon_state="purple_lightning",icon='icons/effects/effects.dmi',time=5)
M.electrocute_act(shock_damage, "[L.name]")
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)
//Defile: Corrupts nearby stuff, unblesses floor tiles.
/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 = 200
clothes_req = 0
range = 1
var/reveal = 100
var/stun = 20
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(-35))
charge_counter = charge_max
return
user << "<span class='info'>You have unlocked Defile!</span>"
name = "Defile (20E)"
panel = "Revenant Abilities"
locked = 0
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
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 << "<span class='warning'>You suddenly feel tired.</span>"
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)"
/obj/effect/proc_holder/spell/aoe_turf/revenant/defile
name = "Defile"
desc = "Twists and corrupts the nearby area as well as dispelling holy auras on floors."
charge_max = 150
clothes_req = 0
range = 1
var/reveal = 60
var/stun = 30
var/locked = 1
range = 3
unlock_amount = 75
cast_amount = 40
action_icon_state = "defile"
var/stamdamage= 25
var/toxdamage = 5
var/confusion = 50
/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 << "<span class='info'>You have unlocked Malfunction!</span>"
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)
/obj/effect/proc_holder/spell/aoe_turf/revenant/defile/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(attempt_cast(user))
for(var/turf/T in targets)
spawn(0)
if(T.flags & NOJAUNT)
T.flags -= NOJAUNT
new/obj/effect/overlay/temp/revenant(T)
for(var/mob/living/carbon/human/human in T.contents)
human << "<span class='warning'>You suddenly feel [pick("sick and tired", "tired and confused", "nauseated", "dizzy")].</span>"
human.adjustStaminaLoss(stamdamage)
human.adjustToxLoss(toxdamage)
human.confused += confusion
new/obj/effect/overlay/temp/revenant(human.loc)
if(!istype(T, /turf/simulated/shuttle) && !istype(T, /turf/simulated/wall/rust) && !istype(T, /turf/simulated/wall/r_wall) && istype(T, /turf/simulated/wall) && prob(15))
new/obj/effect/overlay/temp/revenant(T)
T.ChangeTurf(/turf/simulated/wall/rust)
if(!istype(T, /turf/simulated/wall/r_wall/rust) && istype(T, /turf/simulated/wall/r_wall) && prob(15))
new/obj/effect/overlay/temp/revenant(T)
T.ChangeTurf(/turf/simulated/wall/r_wall/rust)
for(var/obj/structure/window/window in T.contents)
window.hit(rand(50,90))
if(window && window.is_fulltile())
new/obj/effect/overlay/temp/revenant/cracks(window.loc)
for(var/obj/machinery/light/light in T.contents)
light.flicker(30) //spooky
//Malfunction: Makes bad stuff happen to robots and machines.
/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction
name = "Malfunction"
desc = "Corrupts and damages nearby machines and mechanical objects."
charge_max = 200
range = 4
unlock_amount = 150
action_icon_state = "malfunction"
//A note to future coders: do not replace this with an EMP because it will wreck malf AIs and gang dominators and everyone will hate you.
/obj/effect/proc_holder/spell/aoe_turf/revenant/malfunction/cast(list/targets, mob/living/simple_animal/revenant/user = usr)
if(attempt_cast(user))
for(var/turf/T in targets)
spawn(0)
for(var/obj/machinery/bot/bot in T.contents)
if(!bot.emagged)
new/obj/effect/overlay/temp/revenant(bot.loc)
bot.locked = 0
bot.open = 1
bot.Emag(null)
for(var/mob/living/carbon/human/human in T.contents)
human << "<span class='warning'>You feel [pick("your sense of direction flicker out", "a stabbing pain in your head", "your mind fill with static")].</span>"
new/obj/effect/overlay/temp/revenant(human.loc)
human.emp_act(1)
for(var/obj/thing in T.contents)
if(istype(thing, /obj/machinery/power/apc) || istype(thing, /obj/machinery/power/smes) || istype(thing, /obj/machinery/bot)) //Doesn't work on dominators, SMES and APCs, to prevent kekkery
continue
if(prob(20))
if(prob(50))
new/obj/effect/overlay/temp/revenant(thing.loc)
thing.emag_act(null)
else
if(!istype(thing, /obj/machinery/clonepod)) //I hate everything but mostly the fact there's no better way to do this without just not affecting it at all
thing.emp_act(1)
for(var/mob/living/silicon/robot/S in T.contents) //Only works on cyborgs, not AI
playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1)
new/obj/effect/overlay/temp/revenant(S.loc)
S.spark_system.start()
S.emp_act(1)