|
|
|
@@ -1,4 +1,16 @@
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/glare
|
|
|
|
|
#define EMPOWERED_THRALL_LIMIT 5
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/proc/shadowling_check(var/mob/living/carbon/human/H)
|
|
|
|
|
if(!H || !istype(H)) return
|
|
|
|
|
if(H.get_species() == "Shadowling" && is_shadow(H)) return 1
|
|
|
|
|
if(H.get_species() == "Lesser Shadowling" && is_thrall(H)) return 1
|
|
|
|
|
if(!is_shadow_or_thrall(usr)) usr << "<span class='warning'>You can't wrap your head around how to do this.</span>"
|
|
|
|
|
else if(is_thrall(usr)) usr << "<span class='warning'>You aren't powerful enough to do this.</span>"
|
|
|
|
|
else if(is_shadow(usr)) usr << "<span class='warning'>Your telepathic ability is suppressed. Hatch or use Rapid Re-Hatch first.</span>"
|
|
|
|
|
return 0
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/glare //Stuns and mutes a human target for 10 seconds
|
|
|
|
|
name = "Glare"
|
|
|
|
|
desc = "Stuns and mutes a target for a decent duration."
|
|
|
|
|
panel = "Shadowling Abilities"
|
|
|
|
@@ -9,16 +21,20 @@
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/glare/cast(list/targets)
|
|
|
|
|
for(var/mob/living/carbon/human/target in targets)
|
|
|
|
|
if(!ishuman(target))
|
|
|
|
|
usr << "<span class='warning'>You may only glare at humans!</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
if(!shadowling_check(usr))
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
if(target.stat)
|
|
|
|
|
usr << "<span class='warning'>[target] must be conscious!</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
if(is_shadow_or_thrall(target))
|
|
|
|
|
usr << "<span class='danger'>You don't see why you would want to paralyze an ally.</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
var/mob/living/carbon/human/M = target
|
|
|
|
|
usr.visible_message("<span class='warning'><b>[usr]'s eyes flash a blinding red!</b></span>")
|
|
|
|
|
target.visible_message("<span class='danger'>[target] freezes in place, their eyes glazing over...</span>")
|
|
|
|
@@ -29,6 +45,7 @@
|
|
|
|
|
target.Stun(10)
|
|
|
|
|
M.silent += 10
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/lesser_glare
|
|
|
|
|
name = "Lesser Glare"
|
|
|
|
|
desc = "Stuns and mutes a target for a short duration."
|
|
|
|
@@ -40,13 +57,15 @@
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/lesser_glare/cast(list/targets)
|
|
|
|
|
for(var/mob/living/carbon/human/target in targets)
|
|
|
|
|
if(!ishuman(target) || !target)
|
|
|
|
|
usr << "<span class='warning'>You nay only glare at humans!</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
if(target.stat)
|
|
|
|
|
usr << "<span class='warning'>[target] must be conscious!</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
if(is_shadow_or_thrall(target))
|
|
|
|
|
usr << "<span class='danger'>You don't see why you would want to paralyze an ally.</span>"
|
|
|
|
|
usr << "<span class='warning'>You cannot glare at allies!</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
var/mob/living/carbon/human/M = target
|
|
|
|
@@ -56,14 +75,15 @@
|
|
|
|
|
target << "<span class='userdanger'>Your gaze is forcibly drawn into [usr]'s eyes, and you are mesmerized by the heavenly lights...</span>"
|
|
|
|
|
else
|
|
|
|
|
target << "<span class='userdanger'>Red lights suddenly dance in your vision, and you are mesmerized by their heavenly beauty...</span>"
|
|
|
|
|
target.Stun(3) //Roughly 30% as long as the normal one
|
|
|
|
|
M.silent += 3
|
|
|
|
|
target.Stun(5) //Roughly 50% as long as the normal one
|
|
|
|
|
M.silent += 5
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/aoe_turf/veil
|
|
|
|
|
name = "Veil"
|
|
|
|
|
desc = "Extinguishes most nearby light sources."
|
|
|
|
|
panel = "Shadowling Abilities"
|
|
|
|
|
charge_max = 250 //Short cooldown because people can just turn the lights back on
|
|
|
|
|
charge_max = 150 //Short cooldown because people can just turn the lights back on
|
|
|
|
|
clothes_req = 0
|
|
|
|
|
range = 5
|
|
|
|
|
var/blacklisted_lights = list(/obj/item/device/flashlight/flare, /obj/item/device/flashlight/slime)
|
|
|
|
@@ -143,13 +163,16 @@
|
|
|
|
|
name = "Shadow Walk"
|
|
|
|
|
desc = "Phases you into the space between worlds for a short time, allowing movement through walls and invisbility."
|
|
|
|
|
panel = "Shadowling Abilities"
|
|
|
|
|
charge_max = 600
|
|
|
|
|
charge_max = 300 //Used to be twice this, buffed
|
|
|
|
|
clothes_req = 0
|
|
|
|
|
range = -1
|
|
|
|
|
include_user = 1
|
|
|
|
|
action_icon_state = "shadow_walk"
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/shadow_walk/cast(list/targets)
|
|
|
|
|
if(!shadowling_check(usr))
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
for(var/mob/living/user in targets)
|
|
|
|
|
playsound(user.loc, 'sound/effects/bamf.ogg', 50, 1)
|
|
|
|
|
user.visible_message("<span class='warning'>[user] vanishes in a puff of black mist!</span>", "<span class='shadowling'>You enter the space between worlds as a passageway.</span>")
|
|
|
|
@@ -157,12 +180,19 @@
|
|
|
|
|
user.SetWeakened(0)
|
|
|
|
|
user.incorporeal_move = 1
|
|
|
|
|
user.alpha = 0
|
|
|
|
|
user.ExtinguishMob()
|
|
|
|
|
var/turf/T = get_turf(user)
|
|
|
|
|
user.forceMove(T) //to properly move the mob out of a potential container
|
|
|
|
|
if(user.buckled)
|
|
|
|
|
user.buckled.unbuckle_mob()
|
|
|
|
|
if(user.pulledby)
|
|
|
|
|
user.pulledby.stop_pulling()
|
|
|
|
|
user.stop_pulling()
|
|
|
|
|
sleep(40) //4 seconds
|
|
|
|
|
user.visible_message("<span class='warning'>[user] suddenly manifests!</span>", "<span class='shadowling'>The pressure becomes too much and you vacate the interdimensional darkness.</span>")
|
|
|
|
|
user.incorporeal_move = 0
|
|
|
|
|
user.alpha = 255
|
|
|
|
|
user.forceMove(user.loc)
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk
|
|
|
|
|
name = "Guise"
|
|
|
|
@@ -176,15 +206,8 @@
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk/cast(list/targets)
|
|
|
|
|
for(var/mob/living/user in targets)
|
|
|
|
|
var/lumcount = 0
|
|
|
|
|
var/turf/T = get_turf(user)
|
|
|
|
|
lumcount = T.get_lumcount()*10
|
|
|
|
|
if(lumcount > 5)
|
|
|
|
|
user << "<span class='warning'>It's too bright to do that!</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
user.visible_message("<span class='warning'>[user] suddenly fades away!</span>", "<span class='shadowling'>You veil yourself in darkness, making you harder to see.</span>")
|
|
|
|
|
user.alpha = 20
|
|
|
|
|
user.alpha = 10
|
|
|
|
|
sleep(40)
|
|
|
|
|
user.visible_message("<span class='warning'>[user] appears from nowhere!</span>", "<span class='shadowling'>Your shadowy guise slips away.</span>")
|
|
|
|
|
user.alpha = initial(user.alpha)
|
|
|
|
@@ -198,7 +221,8 @@
|
|
|
|
|
range = -1
|
|
|
|
|
include_user = 1
|
|
|
|
|
clothes_req = 0
|
|
|
|
|
var/datum/vision_override/vision_path = /datum/vision_override/nightvision/thermals
|
|
|
|
|
var/datum/vision_override/vision_path = /datum/vision_override/nightvision
|
|
|
|
|
action_icon_state = "darksight"
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/shadow_vision/cast(list/targets)
|
|
|
|
|
for(var/mob/living/user in targets)
|
|
|
|
@@ -216,18 +240,20 @@
|
|
|
|
|
desc = "Thrall Darksight"
|
|
|
|
|
desc = "Gives you night vision."
|
|
|
|
|
panel = "Thrall Abilities"
|
|
|
|
|
vision_path = /datum/vision_override/nightvision
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/aoe_turf/flashfreeze
|
|
|
|
|
name = "Icy Veins"
|
|
|
|
|
desc = "Instantly freezes the blood of nearby people, stunning them and causing burn damage."
|
|
|
|
|
panel = "Shadowling Abilities"
|
|
|
|
|
range = 5
|
|
|
|
|
charge_max = 1200
|
|
|
|
|
charge_max = 250
|
|
|
|
|
clothes_req = 0
|
|
|
|
|
action_icon_state = "icy_veins"
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/aoe_turf/flashfreeze/cast(list/targets)
|
|
|
|
|
if(!shadowling_check(usr))
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
usr << "<span class='shadowling'>You freeze the nearby air.</span>"
|
|
|
|
|
playsound(usr.loc, 'sound/effects/ghost2.ogg', 50, 1)
|
|
|
|
|
|
|
|
|
@@ -239,17 +265,16 @@
|
|
|
|
|
else
|
|
|
|
|
M << "<span class='danger'>You feel a blast of paralyzingly cold air wrap around you and flow past, but you are unaffected!</span>"
|
|
|
|
|
continue
|
|
|
|
|
M << "<span class='userdanger'>You are hit by a blast of paralyzingly cold air and feel goosebumps break out across your body!</span>"
|
|
|
|
|
M << "<span class='userdanger'>A wave of shockingly cold air engulfs you!</span>"
|
|
|
|
|
M.Stun(2)
|
|
|
|
|
M.apply_damage(10, BURN)
|
|
|
|
|
if(M.bodytemperature)
|
|
|
|
|
M.bodytemperature -= 200 //Extreme amount of initial cold
|
|
|
|
|
if(M.reagents)
|
|
|
|
|
M.reagents.add_reagent("frostoil", 15) //Half of a cryosting
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
//Enthrall is the single most important spell
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/enthrall
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/enthrall //Turns a target into the shadowling's slave. This overrides all previous loyalties
|
|
|
|
|
name = "Enthrall"
|
|
|
|
|
desc = "Allows you to enslave a conscious, non-braindead, non-catatonic human to your will. This takes some time to cast."
|
|
|
|
|
panel = "Shadowling Abilities"
|
|
|
|
@@ -262,10 +287,12 @@
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/enthrall/cast(list/targets)
|
|
|
|
|
var/mob/living/carbon/human/user = usr
|
|
|
|
|
listclearnulls(ticker.mode.shadowling_thralls)
|
|
|
|
|
if(ticker.mode.shadowling_thralls.len >= 5 && (!istype(user.species, /datum/species/shadow/ling)))
|
|
|
|
|
user << "<span class='warning'>With your telepathic abilities suppressed, your human form will not allow you to enthrall any others. Hatch first.</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
if(!(user.mind in ticker.mode.shadows))
|
|
|
|
|
return
|
|
|
|
|
if(user.get_species() != "Shadowling")
|
|
|
|
|
if(ticker.mode.shadowling_thralls.len >= 5)
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
for(var/mob/living/carbon/human/target in targets)
|
|
|
|
|
if(!in_range(usr, target))
|
|
|
|
|
usr << "<span class='warning'>You need to be closer to enthrall [target].</span>"
|
|
|
|
@@ -291,6 +318,8 @@
|
|
|
|
|
usr << "<span class='warning'>You are already enthralling!</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
if(!target.client)
|
|
|
|
|
usr << "<span class='warning'>[target]'s mind is vacant of activity.</span>"
|
|
|
|
|
enthralling = 1
|
|
|
|
|
usr << "<span class='danger'>This target is valid. You begin the enthralling.</span>"
|
|
|
|
|
target << "<span class='userdanger'>[usr] stares at you. You feel your head begin to pulse.</span>"
|
|
|
|
@@ -298,32 +327,32 @@
|
|
|
|
|
for(var/progress = 0, progress <= 3, progress++)
|
|
|
|
|
switch(progress)
|
|
|
|
|
if(1)
|
|
|
|
|
usr << "<span class='notice'>You begin allocating energy for the enthralling.</span>"
|
|
|
|
|
usr.visible_message("<span class='warning'>[usr]'s eyes begin to throb a piercing red.</span>")
|
|
|
|
|
usr << "<span class='notice'>You place your hands to [target]'s head...</span>"
|
|
|
|
|
usr.visible_message("<span class='warning'>[usr] places their hands onto the sides of [target]'s head!</span>")
|
|
|
|
|
if(2)
|
|
|
|
|
usr << "<span class='notice'>You begin the enthralling of [target].</span>"
|
|
|
|
|
usr.visible_message("<span class='danger'>[usr] leans over [target], their eyes glowing a deep crimson, and stares into their face.</span>")
|
|
|
|
|
target << "<span class='danger'>Your gaze is forcibly drawn into a blinding red light. You fall to the floor as conscious thought is wiped away.</span>"
|
|
|
|
|
usr << "<span class='notice'>You begin preparing [target]'s mind as a blank slate...</span>"
|
|
|
|
|
usr.visible_message("<span class='warning'>[usr]'s palms flare a bright red against [target]'s temples!</span>")
|
|
|
|
|
target << "<span class='danger'>A terrible red light floods your mind. You collapse as conscious thought is wiped away.</span>"
|
|
|
|
|
target.Weaken(12)
|
|
|
|
|
sleep(20)
|
|
|
|
|
if(isloyal(target))
|
|
|
|
|
usr << "<span class='notice'>They are enslaved by Nanotrasen. You begin to shut down the nanobot implant - this will take some time.</span>"
|
|
|
|
|
usr.visible_message("<span class='boldannounce'>[usr] halts for a moment, then begins passing its hand over [target]'s body.</span>")
|
|
|
|
|
usr.visible_message("<span class='warning'>[usr] pauses, then dips their head in concentration!</span>")
|
|
|
|
|
target << "<span class='boldannounce'>You feel your loyalties begin to weaken!</span>"
|
|
|
|
|
sleep(150) //15 seconds - not spawn() so the enthralling takes longer
|
|
|
|
|
sleep(100) //10 seconds - not spawn() so the enthralling takes longer
|
|
|
|
|
usr << "<span class='notice'>The nanobots composing the loyalty implant have been rendered inert. Now to continue.</span>"
|
|
|
|
|
usr.visible_message("<span class='danger'>[usr] halts thier hand and resumes staring into [target]'s face.</span>")
|
|
|
|
|
usr.visible_message("<span class='warning'>[usr] relaxes again.</span>")
|
|
|
|
|
for(var/obj/item/weapon/implant/loyalty/L in target)
|
|
|
|
|
if(L && L.implanted)
|
|
|
|
|
qdel(L)
|
|
|
|
|
target << "<span class='boldannounce'>Your unwavering loyalty to Nanotrasen falters, dims, dies.</span>"
|
|
|
|
|
target << "<span class='boldannounce'>Your unwavering loyalty to Nanotrasen unexpectedly falters, dims, dies.</span>"
|
|
|
|
|
if(3)
|
|
|
|
|
usr << "<span class='notice'>You begin rearranging [target]'s memories.</span>"
|
|
|
|
|
usr.visible_message("<span class='danger'>[usr]'s eyes flare brightly.</span>")
|
|
|
|
|
target << "<span class='boldannounce'>Your head cries out. The veil of reality begins to crumple and something evil bleeds through.</span>" //Ow the edge
|
|
|
|
|
if(!do_mob(usr, target, 100)) //around 30 seconds total for enthralling, 45 for someone with a loyalty implant
|
|
|
|
|
usr << "<span class='danger'>The enthralling has been interrupted - your target's mind returns to its previous state.</span>"
|
|
|
|
|
target << "<span class='userdanger'>A spike of pain drives into your head, wiping your memory. You aren't sure what's happened, but you feel a faint sense of revulsion.</span>"
|
|
|
|
|
usr << "<span class='notice'>You begin planting the tumor that will control the new thrall...</span>"
|
|
|
|
|
usr.visible_message("<span class='warning'>A strange energy passes from [usr]'s hands into [target]'s head!</span>")
|
|
|
|
|
target << "<span class='boldannounce'>You feel your memories twisting, morphing. A sense of horror dominates your mind.</span>"
|
|
|
|
|
if(!do_mob(usr, target, 70)) //around 21 seconds total for enthralling, 31 for someone with a loyalty implant
|
|
|
|
|
usr << "<span class='warning'>The enthralling has been interrupted - your target's mind returns to its previous state.</span>"
|
|
|
|
|
target << "<span class='userdanger'>You wrest yourself away from [usr]'s hands and compose yourself</span>"
|
|
|
|
|
enthralling = 0
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
@@ -335,7 +364,38 @@
|
|
|
|
|
ticker.mode.add_thrall(target.mind)
|
|
|
|
|
target.mind.special_role = "shadowling thrall"
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/collective_mind
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/shadowling_regenarmor //Resets a shadowling's species to normal, removes genetic defects, and re-equips their armor
|
|
|
|
|
name = "Rapid Re-Hatch"
|
|
|
|
|
desc = "Re-forms protective chitin that may be lost during cloning or similar processes."
|
|
|
|
|
panel = "Shadowling Abilities"
|
|
|
|
|
charge_max = 600
|
|
|
|
|
range = -1
|
|
|
|
|
include_user = 1
|
|
|
|
|
clothes_req = 0
|
|
|
|
|
action_icon_state = "regen_armor"
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/shadowling_regenarmor/cast(list/targets)
|
|
|
|
|
if(!is_shadow(usr))
|
|
|
|
|
usr << "<span class='warning'>You must be a shadowling to do this!</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
for(var/mob/living/user in targets)
|
|
|
|
|
if(!istype(user) || !ishuman(user))
|
|
|
|
|
return
|
|
|
|
|
var/mob/living/carbon/human/H = user
|
|
|
|
|
H.visible_message("<span class='warning'>[H]'s skin suddenly bubbles and shifts around their body!</span>", \
|
|
|
|
|
"<span class='shadowling'>You regenerate your protective armor and cleanse your form of defects.</span>")
|
|
|
|
|
H.adjustCloneLoss(user.getCloneLoss())
|
|
|
|
|
H.equip_to_slot_or_del(new /obj/item/clothing/under/shadowling(H), slot_w_uniform)
|
|
|
|
|
H.equip_to_slot_or_del(new /obj/item/clothing/shoes/shadowling(H), slot_shoes)
|
|
|
|
|
H.equip_to_slot_or_del(new /obj/item/clothing/suit/space/shadowling(H), slot_wear_suit)
|
|
|
|
|
H.equip_to_slot_or_del(new /obj/item/clothing/head/shadowling(H), slot_head)
|
|
|
|
|
H.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(H), slot_gloves)
|
|
|
|
|
H.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(H), slot_wear_mask)
|
|
|
|
|
H.equip_to_slot_or_del(new /obj/item/clothing/glasses/shadowling(H), slot_glasses)
|
|
|
|
|
H.set_species("Shadowling")
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/collective_mind //Lets a shadowling bring together their thralls' strength, granting new abilities and a headcount
|
|
|
|
|
name = "Collective Hivemind"
|
|
|
|
|
desc = "Gathers the power of all of your thralls and compares it to what is needed for ascendance. Also gains you new abilities."
|
|
|
|
|
panel = "Shadowling Abilities"
|
|
|
|
@@ -350,6 +410,9 @@
|
|
|
|
|
action_icon_state = "collective_mind"
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/collective_mind/cast(list/targets)
|
|
|
|
|
if(!shadowling_check(usr))
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
for(var/mob/living/user in targets)
|
|
|
|
|
var/thralls = 0
|
|
|
|
|
var/victory_threshold = 15
|
|
|
|
@@ -366,22 +429,22 @@
|
|
|
|
|
user << "<span class='warning'>Your concentration has been broken. The mental hooks you have sent out now retract into your mind.</span>"
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
if(thralls >= 3 && !blind_smoke_acquired)
|
|
|
|
|
if(thralls >= 3 && !screech_acquired)
|
|
|
|
|
screech_acquired = 1
|
|
|
|
|
user << "<span class='shadowling'><i>The power of your thralls has granted you the <b>Sonic Screech</b> ability. This ability will shatter nearby windows and deafen enemies, plus stunning silicon lifeforms.</span>"
|
|
|
|
|
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/unearthly_screech)
|
|
|
|
|
|
|
|
|
|
if(thralls >= 5 && !blind_smoke_acquired)
|
|
|
|
|
blind_smoke_acquired = 1
|
|
|
|
|
user << "<span class='shadowling'><i>The power of your thralls has granted you the <b>Blinding Smoke</b> ability. It will create a choking cloud that will blind any non-thralls who enter. \
|
|
|
|
|
</i></span>"
|
|
|
|
|
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/blindness_smoke)
|
|
|
|
|
|
|
|
|
|
if(thralls >= 5 && !drainLifeAcquired)
|
|
|
|
|
if(thralls >= 7 && !drainLifeAcquired)
|
|
|
|
|
drainLifeAcquired = 1
|
|
|
|
|
user << "<span class='shadowling'><i>The power of your thralls has granted you the <b>Drain Life</b> ability. You can now drain the health of nearby humans to heal yourself.</i></span>"
|
|
|
|
|
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/drainLife)
|
|
|
|
|
|
|
|
|
|
if(thralls >= 7 && !screech_acquired)
|
|
|
|
|
screech_acquired = 1
|
|
|
|
|
user << "<span class='shadowling'><i>The power of your thralls has granted you the <b>Sonic Screech</b> ability. This ability will shatter nearby windows and deafen enemies, plus stunning silicon lifeforms.</span>"
|
|
|
|
|
user.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/unearthly_screech)
|
|
|
|
|
|
|
|
|
|
if(thralls >= 9 && !reviveThrallAcquired)
|
|
|
|
|
reviveThrallAcquired = 1
|
|
|
|
|
user << "<span class='shadowling'><i>The power of your thralls has granted you the <b>Black Recuperation</b> ability. This will, after a short time, bring a dead thrall completely back to life \
|
|
|
|
@@ -420,6 +483,9 @@
|
|
|
|
|
action_icon_state = "black_smoke"
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/blindness_smoke/cast(list/targets) //Extremely hacky
|
|
|
|
|
if(!shadowling_check(usr))
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
for(var/mob/living/user in targets)
|
|
|
|
|
user.visible_message("<span class='warning'>[user] suddenly bends over and coughs out a cloud of black smoke, which begins to spread rapidly!</span>")
|
|
|
|
|
user << "<span class='deadsay'>You regurgitate a vast cloud of blinding smoke.</span>"
|
|
|
|
@@ -471,6 +537,9 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob)
|
|
|
|
|
action_icon_state = "screech"
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/aoe_turf/unearthly_screech/cast(list/targets)
|
|
|
|
|
if(!shadowling_check(usr))
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
usr.audible_message("<span class='warning'><b>[usr] lets out a horrible scream!</b></span>")
|
|
|
|
|
playsound(usr.loc, 'sound/effects/screech.ogg', 100, 1)
|
|
|
|
|
|
|
|
|
@@ -484,7 +553,6 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob)
|
|
|
|
|
if(iscarbon(target))
|
|
|
|
|
var/mob/living/carbon/M = target
|
|
|
|
|
M << "<span class='danger'><b>A spike of pain drives into your head and scrambles your thoughts!</b></span>"
|
|
|
|
|
M.Weaken(2)
|
|
|
|
|
M.confused += 10
|
|
|
|
|
M.ear_damage += 3
|
|
|
|
|
else if(issilicon(target))
|
|
|
|
@@ -497,7 +565,7 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob)
|
|
|
|
|
sp.start()
|
|
|
|
|
S.Weaken(6)
|
|
|
|
|
for(var/obj/structure/window/W in T.contents)
|
|
|
|
|
W.hit(rand(80,100))
|
|
|
|
|
W.hit(rand(80, 100))
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
@@ -513,6 +581,9 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob)
|
|
|
|
|
action_icon_state = "drain_life"
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/aoe_turf/drainLife/cast(list/targets, var/mob/living/carbon/human/U = usr)
|
|
|
|
|
if(!shadowling_check(usr))
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
targetsDrained = 0
|
|
|
|
|
nearbyTargets = list()
|
|
|
|
|
for(var/turf/T in targets)
|
|
|
|
@@ -541,46 +612,143 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob)
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/reviveThrall
|
|
|
|
|
name = "Black Recuperation"
|
|
|
|
|
desc = "Brings a dead thrall back to life."
|
|
|
|
|
desc = "Revives or empowers a thrall."
|
|
|
|
|
panel = "Shadowling Abilities"
|
|
|
|
|
range = 1
|
|
|
|
|
charge_max = 3000
|
|
|
|
|
charge_max = 600
|
|
|
|
|
clothes_req = 0
|
|
|
|
|
include_user = 0
|
|
|
|
|
var/list/thralls_in_world = list()
|
|
|
|
|
action_icon_state = "revive_thrall"
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/reviveThrall/cast(list/targets)
|
|
|
|
|
if(!shadowling_check(usr))
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
for(var/mob/living/carbon/human/thrallToRevive in targets)
|
|
|
|
|
if(!is_thrall(thrallToRevive))
|
|
|
|
|
usr << "<span class='warning'>[thrallToRevive] is not a thrall.</span>"
|
|
|
|
|
var/choice = alert(usr,"Empower a living thrall or revive a dead one?",,"Empower","Revive","Cancel")
|
|
|
|
|
switch(choice)
|
|
|
|
|
if("Empower")
|
|
|
|
|
if(!is_thrall(thrallToRevive))
|
|
|
|
|
usr << "<span class='warning'>[thrallToRevive] is not a thrall.</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
if(thrallToRevive.stat != CONSCIOUS)
|
|
|
|
|
usr << "<span class='warning'>[thrallToRevive] must be conscious to become empowered.</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
var/empowered_thralls = 0
|
|
|
|
|
for(var/datum/mind/M in ticker.mode.shadowling_thralls)
|
|
|
|
|
if(!ishuman(M.current))
|
|
|
|
|
return
|
|
|
|
|
var/mob/living/carbon/human/H = M.current
|
|
|
|
|
if(H.get_species() == "Lesser Shadowling")
|
|
|
|
|
empowered_thralls++
|
|
|
|
|
if(empowered_thralls >= EMPOWERED_THRALL_LIMIT)
|
|
|
|
|
usr << "<span class='warning'>You cannot spare this much energy. There are too many empowered thralls.</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
usr.visible_message("<span class='danger'>[usr] places their hands over [thrallToRevive]'s face, red light shining from beneath.</span>", \
|
|
|
|
|
"<span class='shadowling'>You place your hands on [thrallToRevive]'s face and begin gathering energy...</span>")
|
|
|
|
|
thrallToRevive << "<span class='userdanger'>[usr] places their hands over your face. You feel energy gathering. Stand still...</span>"
|
|
|
|
|
if(!do_mob(usr, thrallToRevive, 80))
|
|
|
|
|
usr << "<span class='warning'>Your concentration snaps. The flow of energy ebbs.</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
usr << "<span class='shadowling'><b><i>You release a massive surge of power into [thrallToRevive]!</b></i></span>"
|
|
|
|
|
usr.visible_message("<span class='boldannounce'><i>Red lightning surges into [thrallToRevive]'s face!</i></span>")
|
|
|
|
|
playsound(thrallToRevive, 'sound/weapons/Egloves.ogg', 50, 1)
|
|
|
|
|
playsound(thrallToRevive, 'sound/machines/defib_zap.ogg', 50, 1)
|
|
|
|
|
usr.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1)
|
|
|
|
|
thrallToRevive.Weaken(5)
|
|
|
|
|
thrallToRevive.visible_message("<span class='warning'><b>[thrallToRevive] collapses, their skin and face distorting!</span>", \
|
|
|
|
|
"<span class='userdanger'><i>AAAAAAAAAAAAAAAAAAAGH-</i></span>")
|
|
|
|
|
sleep(20)
|
|
|
|
|
thrallToRevive.visible_message("<span class='warning'>[thrallToRevive] slowly rises, no longer recognizable as human.</span>", \
|
|
|
|
|
"<span class='shadowling'><b>You feel new power flow into you. You have been gifted by your masters. You now closely resemble them. You are empowered in \
|
|
|
|
|
darkness but wither slowly in light. In addition, Lesser Glare and Guise have been upgraded into their true forms.</b></span>")
|
|
|
|
|
thrallToRevive.set_species("Lesser Shadowling")
|
|
|
|
|
thrallToRevive.mind.remove_spell(/obj/effect/proc_holder/spell/targeted/lesser_glare)
|
|
|
|
|
thrallToRevive.mind.remove_spell(/obj/effect/proc_holder/spell/targeted/lesser_shadow_walk)
|
|
|
|
|
thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare)
|
|
|
|
|
thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadow_walk)
|
|
|
|
|
if("Revive")
|
|
|
|
|
if(!is_thrall(thrallToRevive))
|
|
|
|
|
usr << "<span class='warning'>[thrallToRevive] is not a thrall.</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
if(thrallToRevive.stat != DEAD)
|
|
|
|
|
usr << "<span class='warning'>[thrallToRevive] is not dead.</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
usr.visible_message("<span class='danger'>[usr] kneels over [thrallToRevive], placing their hands on \his chest.</span>", \
|
|
|
|
|
"<span class='shadowling'>You crouch over the body of your thrall and begin gathering energy...</span>")
|
|
|
|
|
thrallToRevive.notify_ghost_cloning("Your masters are resuscitating you! Re-enter your corpse if you wish to be brought to life.", source = thrallToRevive)
|
|
|
|
|
if(!do_mob(usr, thrallToRevive, 30))
|
|
|
|
|
usr << "<span class='warning'>Your concentration snaps. The flow of energy ebbs.</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
usr << "<span class='shadowling'><b><i>You release a massive surge of power into [thrallToRevive]!</b></i></span>"
|
|
|
|
|
usr.visible_message("<span class='boldannounce'><i>Red lightning surges from [usr]'s hands into [thrallToRevive]'s chest!</i></span>")
|
|
|
|
|
playsound(thrallToRevive, 'sound/weapons/Egloves.ogg', 50, 1)
|
|
|
|
|
playsound(thrallToRevive, 'sound/machines/defib_zap.ogg', 50, 1)
|
|
|
|
|
usr.Beam(thrallToRevive,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1)
|
|
|
|
|
sleep(10)
|
|
|
|
|
if(thrallToRevive.revive(full_heal = 1))
|
|
|
|
|
thrallToRevive.visible_message("<span class='boldannounce'>[thrallToRevive] heaves in breath, dim red light shining in their eyes.</span>", \
|
|
|
|
|
"<span class='shadowling'><b><i>You have returned. One of your masters has brought you from the darkness beyond.</b></i></span>")
|
|
|
|
|
thrallToRevive.Weaken(4)
|
|
|
|
|
thrallToRevive.emote("gasp")
|
|
|
|
|
playsound(thrallToRevive, "bodyfall", 50, 1)
|
|
|
|
|
else
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle
|
|
|
|
|
name = "Destroy Engines"
|
|
|
|
|
desc = "Extends the time of the emergency shuttle's arrival by fifteen minutes. This can only be used once."
|
|
|
|
|
panel = "Shadowling Abilities"
|
|
|
|
|
range = 1
|
|
|
|
|
clothes_req = 0
|
|
|
|
|
charge_max = 600
|
|
|
|
|
action_icon_state = "extend_shuttle"
|
|
|
|
|
|
|
|
|
|
/obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle/cast(list/targets)
|
|
|
|
|
if(!shadowling_check(usr))
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
for(var/mob/living/carbon/human/target in targets)
|
|
|
|
|
if(target.stat)
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
if(thrallToRevive.stat != DEAD)
|
|
|
|
|
usr << "<span class='warning'>[thrallToRevive] is not dead.</span>"
|
|
|
|
|
if(!is_thrall(target))
|
|
|
|
|
usr << "<span class='warning'>[target] must be a thrall.</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
usr.visible_message("<span class='danger'>[usr] kneels over [thrallToRevive], placing their hands on \his chest.</span>", \
|
|
|
|
|
"<span class='shadowling'>You crouch over the body of your thrall and begin gathering energy...</span>")
|
|
|
|
|
var/mob/dead/observer/ghost = thrallToRevive.get_ghost()
|
|
|
|
|
if(ghost)
|
|
|
|
|
ghost << "<span class='ghostalert'>Your masters are resuscitating you! Return to your corpse if you wish to be brought to life.</span> (Verbs -> Ghost -> Re-enter corpse)"
|
|
|
|
|
ghost << 'sound/effects/genetics.ogg'
|
|
|
|
|
if(!do_mob(usr, thrallToRevive, 30))
|
|
|
|
|
usr << "<span class='warning'>Your concentration snaps. The flow of energy ebbs.</span>"
|
|
|
|
|
charge_counter= charge_max
|
|
|
|
|
if(shuttle_master.emergency.mode != SHUTTLE_CALL)
|
|
|
|
|
usr << "<span class='warning'>The shuttle must be inbound only to the station.</span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
usr << "<span class='shadowling'><b><i>You release a massive surge of power into [thrallToRevive]!</b></i></span>"
|
|
|
|
|
usr.visible_message("<span class='boldannounce'><i>Red lightning surges from [usr]'s hands into [thrallToRevive]'s chest!</i></span>")
|
|
|
|
|
playsound(thrallToRevive, 'sound/weapons/Egloves.ogg', 50, 1)
|
|
|
|
|
playsound(thrallToRevive, 'sound/machines/defib_zap.ogg', 50, 1)
|
|
|
|
|
sleep(10)
|
|
|
|
|
thrallToRevive.revive()
|
|
|
|
|
thrallToRevive.visible_message("<span class='boldannounce'>[thrallToRevive] draws in a huge breath, blinding violet light shining from their eyes.</span>", \
|
|
|
|
|
"<span class='shadowling'><b><i>You have returned. One of your masters has brought you from the darkness beyond.</b></i></span>")
|
|
|
|
|
thrallToRevive.Weaken(4)
|
|
|
|
|
thrallToRevive.emote("gasp")
|
|
|
|
|
playsound(thrallToRevive, "bodyfall", 50, 1)
|
|
|
|
|
var/mob/living/carbon/human/M = target
|
|
|
|
|
usr.visible_message("<span class='warning'>[usr]'s eyes flash a bright red!</span>", \
|
|
|
|
|
"<span class='notice'>You begin to draw [M]'s life force.</span>")
|
|
|
|
|
M.visible_message("<span class='warning'>[M]'s face falls slack, their jaw slightly distending.</span>", \
|
|
|
|
|
"<span class='boldannounce'>You are suddenly transported... far, far away...</span>")
|
|
|
|
|
if(!do_after(usr, 50, target = M))
|
|
|
|
|
M << "<span class='warning'>You are snapped back to reality, your haze dissipating!</span>"
|
|
|
|
|
usr << "<span class='warning'>You have been interrupted. The draw has failed.</span>"
|
|
|
|
|
return
|
|
|
|
|
usr << "<span class='notice'>You project [M]'s life force toward the approaching shuttle, extending its arrival duration!</span>"
|
|
|
|
|
M.visible_message("<span class='warning'>[M]'s eyes suddenly flare red. They proceed to collapse on the floor, not breathing.</span>", \
|
|
|
|
|
"<span class='warning'><b>...speeding by... ...pretty blue glow... ...touch it... ...no glow now... ...no light... ...nothing at all...</span>")
|
|
|
|
|
M.death()
|
|
|
|
|
if(shuttle_master.emergency.mode == SHUTTLE_CALL)
|
|
|
|
|
var/more_minutes = 9000
|
|
|
|
|
var/timer = shuttle_master.emergency.timeLeft()
|
|
|
|
|
timer += more_minutes
|
|
|
|
|
command_announcement.Announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 15 minutes..", "System Failure", 'sound/misc/notice1.ogg')
|
|
|
|
|
shuttle_master.emergency.setTimer(timer)
|
|
|
|
|
usr.mind.spell_list.Remove(src) //Can only be used once!
|
|
|
|
|
qdel(src)
|
|
|
|
|
|
|
|
|
|
// ASCENDANT ABILITIES BEYOND THIS POINT //
|
|
|
|
|
|
|
|
|
@@ -600,15 +768,17 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob)
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
|
|
|
|
|
playsound(usr.loc, 'sound/magic/Staff_Chaos.ogg', 100, 1)
|
|
|
|
|
for(var/mob/living/boom in targets)
|
|
|
|
|
if(is_shadow_or_thrall(boom))
|
|
|
|
|
if(is_shadow(boom)) //Used to not work on thralls. Now it does so you can PUNISH THEM LIKE THE WRATHFUL GOD YOU ARE.
|
|
|
|
|
usr << "<span class='warning'>Making an ally explode seems unwise.<span>"
|
|
|
|
|
charge_counter = charge_max
|
|
|
|
|
return
|
|
|
|
|
usr.visible_message("<span class='danger'>[usr]'s markings flare as they gesture at [boom]!</span>", \
|
|
|
|
|
"<span class='shadowling'>You direct a lance of telekinetic energy at [boom].</span>")
|
|
|
|
|
playsound(usr, 'sound/effects/supermatter.ogg', 100, 1)
|
|
|
|
|
sleep(4)
|
|
|
|
|
if(iscarbon(boom))
|
|
|
|
|
playsound(boom, 'sound/magic/Disintegrate.ogg', 100, 1)
|
|
|
|
|
boom.visible_message("<span class='userdanger'>[boom] explodes!</span>")
|
|
|
|
|
boom.gib()
|
|
|
|
|
|
|
|
|
@@ -701,7 +871,7 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob)
|
|
|
|
|
|
|
|
|
|
usr.visible_message("<span class='warning'><b>A massive ball of lightning appears in [usr]'s hands and flares out!</b></span>", \
|
|
|
|
|
"<span class='shadowling'>You conjure a ball of lightning and release it.</span>")
|
|
|
|
|
|
|
|
|
|
playsound(usr.loc, 'sound/magic/lightningbolt.ogg', 100, 1)
|
|
|
|
|
for(var/turf/T in targets)
|
|
|
|
|
for(var/mob/living/carbon/human/target in T.contents)
|
|
|
|
|
if(is_shadow_or_thrall(target))
|
|
|
|
|