Removes shadowling (#18951)

This commit is contained in:
Xhuis
2016-06-27 20:53:35 -04:00
committed by KorPhaeron
parent 7e6b9b908a
commit 8a852f196b
25 changed files with 5 additions and 1826 deletions

View File

@@ -19,7 +19,6 @@
#define ROLE_NINJA "space ninja"
#define ROLE_MONKEY "monkey"
#define ROLE_GANG "gangster"
#define ROLE_SHADOWLING "shadowling"
#define ROLE_ABDUCTOR "abductor"
#define ROLE_HOG_GOD "hand of god: god"
#define ROLE_HOG_CULTIST "hand of god: cultist"
@@ -43,7 +42,6 @@ var/global/list/special_roles = list(
ROLE_NINJA,
ROLE_MONKEY = /datum/game_mode/monkey,
ROLE_GANG = /datum/game_mode/gang,
ROLE_SHADOWLING = /datum/game_mode/shadowling,
ROLE_ABDUCTOR = /datum/game_mode/abduction,
ROLE_HOG_GOD = /datum/game_mode/hand_of_god,
ROLE_HOG_CULTIST = /datum/game_mode/hand_of_god,

View File

@@ -469,25 +469,6 @@
sections["traitor"] = text
/** SHADOWLING **/
text = "shadowling"
if(ticker.mode.config_tag == "shadowling")
text = uppertext(text)
text = "<i><b>[text]</b></i>: "
if(src in ticker.mode.shadows)
text += "<b>SHADOWLING</b>|thrall|<a href='?src=\ref[src];shadowling=clear'>human</a>"
else if(src in ticker.mode.thralls)
text += "shadowling|<b>THRALL</b>|<a href='?src=\ref[src];shadowling=clear'>human</a>"
else
text += "<a href='?src=\ref[src];shadowling=shadowling'>shadowling</a>|<a href='?src=\ref[src];shadowling=thrall'>thrall</a>|<b>HUMAN</b>"
if(current && current.client && (ROLE_SHADOWLING in current.client.prefs.be_special))
text += "|Enabled in Prefs"
else
text += "|Disabled in Prefs"
sections["shadowling"] = text
/** Abductors **/
text = "Abductor"
@@ -1188,43 +1169,6 @@
ticker.mode.forge_traitor_objectives(src)
usr << "<span class='notice'>The objectives for traitor [key] have been generated. You can edit them and anounce manually.</span>"
else if(href_list["shadowling"])
switch(href_list["shadowling"])
if("clear")
ticker.mode.update_shadow_icons_removed(src)
if(src in ticker.mode.shadows)
ticker.mode.shadows -= src
special_role = null
current << "<span class='userdanger'>Your powers have been quenched! You are no longer a shadowling!</span>"
RemoveSpell(/obj/effect/proc_holder/spell/self/shadowling_hatch)
RemoveSpell(/obj/effect/proc_holder/spell/self/shadowling_ascend)
RemoveSpell(/obj/effect/proc_holder/spell/targeted/enthrall)
RemoveSpell(/obj/effect/proc_holder/spell/self/shadowling_hivemind)
message_admins("[key_name_admin(usr)] has de-shadowling'ed [current].")
log_admin("[key_name(usr)] has de-shadowling'ed [current].")
else if(src in ticker.mode.thralls)
ticker.mode.remove_thrall(src,0)
message_admins("[key_name_admin(usr)] has de-thrall'ed [current].")
log_admin("[key_name(usr)] has de-thrall'ed [current].")
if("shadowling")
if(!ishuman(current))
usr << "<span class='warning'>This only works on humans!</span>"
return
ticker.mode.shadows += src
special_role = "shadowling"
current << "<span class='shadowling'><b>Something stirs deep in your mind. A red light floods your vision, and slowly you remember. Though your human disguise has served you well, the \
time is nigh to cast it off and enter your true form. You have disguised yourself amongst the humans, but you are not one of them. You are a shadowling, and you are to ascend at all costs.\
</b></span>"
ticker.mode.finalize_shadowling(src)
ticker.mode.update_shadow_icons_added(src)
if("thrall")
if(!ishuman(current))
usr << "<span class='warning'>This only works on humans!</span>"
return
ticker.mode.add_thrall(src)
message_admins("[key_name_admin(usr)] has thrall'ed [current].")
log_admin("[key_name(usr)] has thrall'ed [current].")
else if(href_list["devil"])
switch(href_list["devil"])
if("clear")

View File

@@ -85,10 +85,6 @@
src.text = ""
src.build_changeling(correct_person)
return src.text
if("shadowling")
src.text = ""
src.build_shadowling(correct_person)
return src.text
else
return null
@@ -283,9 +279,3 @@
src.text += "These lifeforms are associated with the <B><U>[orgname1] [orgname2]</U></B> and may be attempting to acquire sensitive materials on their behalf. "
src.text += "Please take care not to alarm the crew, as <B><U>[cname]</U></B> may take advantage of a panic situation. Remember, they can be anybody, suspect everybody!"
src.text += "<BR><HR>"
/datum/intercept_text/proc/build_shadowling(datum/mind/correct_person)
src.text += "<br><br>Sightings of strange alien creatures have been observed in your area. These aliens supposedly possess the ability to enslave unwitting personnel and leech from their power. \
Be wary of dark areas and ensure all lights are kept well-maintained. Closely monitor all crew for suspicious behavior and perform dethralling surgery if they have obvious tells. Investigate all \
reports of odd or suspicious sightings in maintenance."
src.text += "<br><br>"

View File

@@ -1,51 +0,0 @@
/mob/living/simple_animal/ascendant_shadowling
name = "ascendant shadowling"
desc = "HOLY SHIT RUN THE FUCK AWAY"
icon = 'icons/mob/mob.dmi'
icon_state = "shadowling_ascended"
icon_living = "shadowling_ascended"
verb_say = "telepathically thunders"
verb_ask = "telepathically thunders"
verb_exclaim = "telepathically thunders"
verb_yell = "telepathically thunders"
force_threshold = INFINITY //Can't die by normal means
health = 100000
maxHealth = 100000
speed = 0
see_in_dark = 8
see_invisible = SEE_INVISIBLE_MINIMUM
hud_possible = list(ANTAG_HUD)
response_help = "pokes"
response_disarm = "flails at"
response_harm = "flails at"
harm_intent_damage = 0
melee_damage_lower = 60 //Was 35, buffed
melee_damage_upper = 60
attacktext = "rends"
attack_sound = 'sound/weapons/slash.ogg'
minbodytemp = 0
maxbodytemp = INFINITY
environment_smash = 3
faction = list("faithless")
/mob/living/simple_animal/ascendant_shadowling/med_hud_set_health()
return //we're invincible!
/mob/living/simple_animal/ascendant_shadowling/med_hud_set_status()
return //we're invincible!
/mob/living/simple_animal/ascendant_shadowling/Process_Spacemove(movement_dir = 0)
return 1 //copypasta from carp code
/mob/living/simple_animal/ascendant_shadowling/get_spans()
return ..() | list(SPAN_REALLYBIG, SPAN_YELL) //MAKES THEM SHOUT WHEN THEY TALK
/mob/living/simple_animal/ascendant_shadowling/ex_act(severity)
return 0 //You think an ascendant can be hurt by bombs? HA
/mob/living/simple_animal/ascendant_shadowling/singularity_act()
return 0 //Well hi, fellow god! How are you today?

View File

@@ -1,315 +0,0 @@
#define LIGHT_DAM_THRESHOLD 4
#define LIGHT_HEAL_THRESHOLD 2
#define LIGHT_DAMAGE_TAKEN 7
/*
SHADOWLING: A gamemode based on previously-run events
Aliens called shadowlings are on the station.
These shadowlings can 'enthrall' crew members and enslave them.
They also burn in the light but heal rapidly whilst in the dark.
The game will end under two conditions:
1. The shadowlings die
2. The emergency shuttle docks at CentCom
Shadowling strengths:
- The dark
- Hard vacuum (They are not affected by it, but are affected by starlight!)
- Their thralls who are not harmed by the light
- Stealth
Shadowling weaknesses:
- The light
- Fire
- Enemy numbers
- Burn-based weapons and items (flashbangs, lasers, etc.)
Shadowlings start off disguised as normal crew members, and they only have two abilities: Hatch and Enthrall.
They can still enthrall and perhaps complete their objectives in this form.
Hatch will, after a short time, cast off the human disguise and assume the shadowling's true identity.
They will then assume the normal shadowling form and gain their abilities.
The shadowling will seem OP, and that's because it kinda is. Being restricted to the dark while being alone most of the time is extremely difficult and as such the shadowling needs powerful abilities.
Made by Xhuis
*/
/*
GAMEMODE
*/
/datum/game_mode
var/list/datum/mind/shadows = list()
var/list/datum/mind/thralls = list()
var/list/shadow_objectives = list()
var/required_thralls = 15 //How many thralls are needed (hardcoded for now)
var/shadowling_ascended = 0 //If at least one shadowling has ascended
var/shadowling_dead = 0 //is shadowling kill
var/objective_explanation
/proc/is_thrall(var/mob/living/M)
return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.thralls)
/proc/is_shadow_or_thrall(var/mob/living/M)
return istype(M) && M.mind && ticker && ticker.mode && ((M.mind in ticker.mode.thralls) || (M.mind in ticker.mode.shadows))
/proc/is_shadow(var/mob/living/M)
return istype(M) && M.mind && ticker && ticker.mode && (M.mind in ticker.mode.shadows)
/datum/game_mode/shadowling
name = "shadowling"
config_tag = "shadowling"
antag_flag = ROLE_SHADOWLING
required_players = 30
required_enemies = 2
recommended_enemies = 2
restricted_jobs = list("AI", "Cyborg")
protected_jobs = list("Security Officer", "Warden", "Detective", "Head of Security", "Captain")
/datum/game_mode/shadowling/announce()
world << "<b>The current game mode is - Shadowling!</b>"
world << "<b>There are alien <span class='shadowling'>shadowlings</span> on the station. Crew: Kill the shadowlings before they can enthrall the crew. Shadowlings: Enthrall the crew while remaining in hiding.</b>"
/datum/game_mode/shadowling/pre_setup()
if(config.protect_roles_from_antagonist)
restricted_jobs += protected_jobs
if(config.protect_assistant_from_antagonist)
restricted_jobs += "Assistant"
var/shadowlings = max(3, round(num_players()/14))
while(shadowlings)
var/datum/mind/shadow = pick(antag_candidates)
shadows += shadow
antag_candidates -= shadow
modePlayer += shadow
shadow.special_role = "Shadowling"
shadow.restricted_roles = restricted_jobs
shadowlings--
return 1
/datum/game_mode/shadowling/post_setup()
for(var/datum/mind/shadow in shadows)
log_game("[shadow.key] (ckey) has been selected as a Shadowling.")
sleep(10)
shadow.current << "<br>"
shadow.current << "<span class='shadowling'><b><font size=3>You are a shadowling!</font></b></span>"
greet_shadow(shadow)
finalize_shadowling(shadow)
process_shadow_objectives(shadow)
//give_shadowling_abilities(shadow)
..()
return
/datum/game_mode/proc/greet_shadow(datum/mind/shadow)
shadow.current << "<b>Currently, you are disguised as an employee aboard [station_name()]].</b>"
shadow.current << "<b>In your limited state, you have three abilities: Enthrall, Hatch, and Hivemind Commune.</b>"
shadow.current << "<b>Any other shadowlings are your allies. You must assist them as they shall assist you.</b>"
shadow.current << "<b>If you are new to shadowling, or want to read about abilities, check the wiki page at https://tgstation13.org/wiki/Shadowling</b><br>"
/datum/game_mode/proc/process_shadow_objectives(datum/mind/shadow_mind)
var/objective = "enthrall" //may be devour later, but for now it seems murderbone-y
if(objective == "enthrall")
objective_explanation = "Ascend to your true form by use of the Ascendance ability. This may only be used with [required_thralls] collective thralls, while hatched, and is unlocked with the Collective Mind ability."
shadow_objectives += "enthrall"
shadow_mind.memory += "<b>Objective #1</b>: [objective_explanation]"
shadow_mind.current << "<b>Objective #1</b>: [objective_explanation]<br>"
/datum/game_mode/proc/finalize_shadowling(datum/mind/shadow_mind)
var/mob/living/carbon/human/S = shadow_mind.current
shadow_mind.AddSpell(new /obj/effect/proc_holder/spell/self/shadowling_hatch(null))
shadow_mind.AddSpell(new /obj/effect/proc_holder/spell/self/shadowling_hivemind(null))
spawn(0)
update_shadow_icons_added(shadow_mind)
if(shadow_mind.assigned_role == "Clown")
S << "<span class='notice'>Your alien nature has allowed you to overcome your clownishness.</span>"
S.dna.remove_mutation(CLOWNMUT)
/datum/game_mode/proc/add_thrall(datum/mind/new_thrall_mind)
if(!istype(new_thrall_mind))
return 0
if(!(new_thrall_mind in thralls))
update_shadow_icons_added(new_thrall_mind)
thralls += new_thrall_mind
new_thrall_mind.special_role = "thrall"
new_thrall_mind.current.attack_log += "\[[time_stamp()]\] <span class='danger'>Became a thrall</span>"
new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/self/lesser_shadowling_hivemind(null))
new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/lesser_glare(null))
new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/self/lesser_shadow_walk(null))
new_thrall_mind.AddSpell(new /obj/effect/proc_holder/spell/self/thrall_vision(null))
new_thrall_mind.current << "<span class='shadowling'><b>You see the truth. Reality has been torn away and you realize what a fool you've been.</b></span>"
new_thrall_mind.current << "<span class='shadowling'><b>The shadowlings are your masters.</b> Serve them above all else and ensure they complete their goals.</span>"
new_thrall_mind.current << "<span class='shadowling'>You may not harm other thralls or the shadowlings. However, you do not need to obey other thralls.</span>"
new_thrall_mind.current << "<span class='shadowling'>Your body has been irreversibly altered. The attentive can see this - you may conceal it by wearing a mask.</span>"
new_thrall_mind.current << "<span class='shadowling'>Though not nearly as powerful as your masters, you possess some weak powers. These can be found in the Thrall Abilities tab.</span>"
new_thrall_mind.current << "<span class='shadowling'>You may communicate with your allies by using the Lesser Commune ability.</span>"
if(jobban_isbanned(new_thrall_mind.current, ROLE_SHADOWLING))
replace_jobbaned_player(new_thrall_mind.current, ROLE_SHADOWLING, ROLE_SHADOWLING)
return 1
/datum/game_mode/proc/remove_thrall(datum/mind/thrall_mind, var/kill = 0)
if(!istype(thrall_mind) || !(thrall_mind in thralls) || !isliving(thrall_mind.current)) return 0 //If there is no mind, the mind isn't a thrall, or the mind's mob isn't alive, return
update_shadow_icons_removed(thrall_mind)
thralls.Remove(thrall_mind)
thrall_mind.current.attack_log += "\[[time_stamp()]\] <span class='danger'>Dethralled</span>"
thrall_mind.special_role = null
for(var/obj/effect/proc_holder/spell/S in thrall_mind.spell_list)
thrall_mind.RemoveSpell(S)
if(kill && ishuman(thrall_mind.current)) //If dethrallization surgery fails, kill the mob as well as dethralling them
var/mob/living/carbon/human/H = thrall_mind.current
H.visible_message("<span class='warning'>[H] jerks violently and falls still.</span>", \
"<span class='userdanger'>A piercing white light floods your mind, banishing your memories as a thrall and--</span>")
H.death()
return 1
var/mob/living/M = thrall_mind.current
if(issilicon(M))
M.audible_message("<span class='notice'>[M] lets out a short blip.</span>", \
"<span class='userdanger'>You have been turned into a robot! You are no longer a thrall! Though you try, you cannot remember anything about your servitude...</span>")
else
M.visible_message("<span class='big'>[M] looks like their mind is their own again!</span>", \
"<span class='userdanger'>A piercing white light floods your eyes. Your mind is your own again! Though you try, you cannot remember anything about the shadowlings or your time \
under their command...</span>")
return 1
/datum/game_mode/proc/remove_shadowling(datum/mind/ling_mind)
if(!istype(ling_mind) || !(ling_mind in shadows)) return 0
update_shadow_icons_removed(ling_mind)
shadows.Remove(ling_mind)
ling_mind.current.attack_log += "\[[time_stamp()]\] <span class='danger'>Deshadowlinged</span>"
ling_mind.special_role = null
for(var/obj/effect/proc_holder/spell/S in ling_mind.spell_list)
ling_mind.RemoveSpell(S)
var/mob/living/M = ling_mind.current
if(issilicon(M))
M.audible_message("<span class='notice'>[M] lets out a short blip.</span>", \
"<span class='userdanger'>You have been turned into a robot! You are no longer a shadowling! Though you try, you cannot remember anything about your time as one...</span>")
else
M.visible_message("<span class='big'>[M] screams and contorts!</span>", \
"<span class='userdanger'>THE LIGHT-- YOUR MIND-- <i>BURNS--</i></span>")
spawn(30)
if(!M || qdeleted(M))
return
M.visible_message("<span class='warning'>[M] suddenly bloats and explodes!</span>", \
"<span class='warning'><b>AAAAAAAAA<font size=3>AAAAAAAAAAAAA</font><font size=4>AAAAAAAAAAAA----</font></span>")
playsound(M, 'sound/magic/Disintegrate.ogg', 100, 1)
M.gib()
/datum/game_mode/shadowling/proc/check_shadow_victory()
var/success = 0 //Did they win?
if(shadow_objectives.Find("enthrall"))
success = shadowling_ascended
return success
/datum/game_mode/shadowling/declare_completion()
if(check_shadow_victory() && EMERGENCY_ESCAPED_OR_ENDGAMED) //Doesn't end instantly - this is hacky and I don't know of a better way ~X
world << "<span class='greentext'>The shadowlings have ascended and taken over the station!</span>"
else if(shadowling_dead && !check_shadow_victory()) //If the shadowlings have ascended, they can not lose the round
world << "<span class='redtext'>The shadowlings have been killed by the crew!</span>"
else if(!check_shadow_victory() && EMERGENCY_ESCAPED_OR_ENDGAMED)
world << "<span class='redtext'>The crew escaped the station before the shadowlings could ascend!</span>"
else
world << "<span class='redtext'>The shadowlings have failed!</span>"
..()
return 1
/datum/game_mode/proc/auto_declare_completion_shadowling()
var/text = ""
if(shadows.len)
text += "<br><span class='big'><b>The shadowlings were:</b></span>"
for(var/datum/mind/shadow in shadows)
text += printplayer(shadow)
text += "<br>"
if(thralls.len)
text += "<br><span class='big'><b>The thralls were:</b></span>"
for(var/datum/mind/thrall in thralls)
text += printplayer(thrall)
text += "<br>"
world << text
/*
MISCELLANEOUS
*/
/datum/species/shadow/ling
//Normal shadowpeople but with enhanced effects
name = "Shadowling"
id = "shadowling"
say_mod = "chitters"
specflags = list(NOBREATH,NOBLOOD,RADIMMUNE,NOGUNS,NODISMEMBER) //Can't use guns due to muzzle flash
burnmod = 1.5 //1.5x burn damage, 2x is excessive
heatmod = 1.5
/datum/species/shadow/ling/spec_life(mob/living/carbon/human/H)
if(!H.weakeyes) H.weakeyes = 1 //Makes them more vulnerable to flashes and flashbangs
var/light_amount = 0
H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry
if(isturf(H.loc))
var/turf/T = H.loc
light_amount = T.get_lumcount()
if(light_amount > LIGHT_DAM_THRESHOLD && !H.incorporeal_move) //Can survive in very small light levels. Also doesn't take damage while incorporeal, for shadow walk purposes
H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN)
if(H.stat != DEAD)
H << "<span class='userdanger'>The light burns you!</span>" //Message spam to say "GET THE FUCK OUT"
H << 'sound/weapons/sear.ogg'
else if (light_amount < LIGHT_HEAL_THRESHOLD)
H.heal_overall_damage(5,5)
H.adjustToxLoss(-5)
H.adjustBrainLoss(-25) //Shad O. Ling gibbers, "CAN U BE MY THRALL?!!"
H.adjustCloneLoss(-1)
H.SetWeakened(0)
H.SetStunned(0)
/datum/species/shadow/ling/lesser //Empowered thralls. Obvious, but powerful
name = "Lesser Shadowling"
id = "l_shadowling"
say_mod = "chitters"
specflags = list(NOBREATH,NOBLOOD,RADIMMUNE)
burnmod = 1.1
heatmod = 1.1
/datum/species/shadow/ling/lesser/spec_life(mob/living/carbon/human/H)
if(!H.weakeyes) H.weakeyes = 1
var/light_amount = 0
H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry
if(isturf(H.loc))
var/turf/T = H.loc
light_amount = T.get_lumcount()
if(light_amount > LIGHT_DAM_THRESHOLD && !H.incorporeal_move)
H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN/2)
else if (light_amount < LIGHT_HEAL_THRESHOLD)
H.heal_overall_damage(2,2)
H.adjustToxLoss(-5)
H.adjustBrainLoss(-25)
H.adjustCloneLoss(-1)
/datum/game_mode/proc/update_shadow_icons_added(datum/mind/shadow_mind)
var/datum/atom_hud/antag/shadow_hud = huds[ANTAG_HUD_SHADOW]
shadow_hud.join_hud(shadow_mind.current)
set_antag_hud(shadow_mind.current, ((shadow_mind in shadows) ? "shadowling" : "thrall"))
/datum/game_mode/proc/update_shadow_icons_removed(datum/mind/shadow_mind)
var/datum/atom_hud/antag/shadow_hud = huds[ANTAG_HUD_SHADOW]
shadow_hud.leave_hud(shadow_mind.current)
set_antag_hud(shadow_mind.current, null)

View File

@@ -1,900 +0,0 @@
#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.dna.species.id == "shadowling" && is_shadow(H)) return 1
if(H.dna.species.id == "l_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"
charge_max = 300
human_req = 1
clothes_req = 0
action_icon_state = "glare"
/obj/effect/proc_holder/spell/targeted/glare/cast(list/targets,mob/user = usr)
for(var/mob/living/target in targets)
if(!ishuman(target))
user << "<span class='warning'>You may only glare at humans!</span>"
revert_cast()
return
if(!shadowling_check(user))
revert_cast()
return
if(target.stat)
user << "<span class='warning'>[target] must be conscious!</span>"
revert_cast()
return
if(is_shadow_or_thrall(target))
user << "<span class='warning'>You cannot glare at allies!</span>"
revert_cast()
return
var/mob/living/L = user
if(L.incorporeal_move) //Other abilities can still be used, but glare needed balancing
user << "<span class='warning'>You cannot glare while shadow walking!</span>"
revert_cast()
return
var/mob/living/carbon/human/M = target
user.visible_message("<span class='warning'><b>[user]'s eyes flash a blinding red!</b></span>")
target.visible_message("<span class='danger'>[target] freezes in place, their eyes glazing over...</span>")
if(in_range(target, user))
target << "<span class='userdanger'>Your gaze is forcibly drawn into [user]'s eyes, and you are mesmerized by the heavenly lights...</span>"
else //Only alludes to the shadowling if the target is close by
target << "<span class='userdanger'>Red lights suddenly dance in your vision, and you are mesmerized by their heavenly beauty...</span>"
target.Stun(10)
M.silent += 10
/obj/effect/proc_holder/spell/aoe_turf/veil //Puts out most nearby lights except for flares and yellow slime cores
name = "Veil"
desc = "Extinguishes most nearby light sources."
panel = "Shadowling Abilities"
charge_max = 150 //Short cooldown because people can just turn the lights back on
human_req = 1
clothes_req = 0
range = 5
action_icon_state = "veil"
var/blacklisted_lights = list(/obj/item/device/flashlight/flare, /obj/item/device/flashlight/slime)
var/admin_override = 0 //Requested by Shadowlight213. Allows anyone to cast the spell, not just shadowlings.
/obj/effect/proc_holder/spell/aoe_turf/veil/proc/extinguishItem(obj/item/I) //Does not darken items held by mobs due to mobs having separate luminosity, use extinguishMob() or write your own proc.
if(istype(I, /obj/item/device/flashlight))
var/obj/item/device/flashlight/F = I
if(F.on)
if(is_type_in_list(I, blacklisted_lights))
I.visible_message("<span class='danger'>[I] dims slightly before scattering the shadows around it.</span>")
return F.brightness_on //Necessary because flashlights become 0-luminosity when held. I don't make the rules of lightcode.
F.on = 0
F.update_brightness()
else if(istype(I, /obj/item/device/pda))
var/obj/item/device/pda/P = I
P.fon = 0
I.SetLuminosity(0)
return I.luminosity
/obj/effect/proc_holder/spell/aoe_turf/veil/proc/extinguishMob(mob/living/H)
var/blacklistLuminosity = 0
for(var/obj/item/F in H)
blacklistLuminosity += extinguishItem(F)
H.SetLuminosity(blacklistLuminosity) //I hate lightcode for making me do it this way
/obj/effect/proc_holder/spell/aoe_turf/veil/cast(list/targets,mob/user = usr)
if(!shadowling_check(user) && !admin_override)
revert_cast()
return
user << "<span class='shadowling'>You silently disable all nearby lights.</span>"
for(var/turf/T in targets)
for(var/obj/item/F in T.contents)
extinguishItem(F)
for(var/obj/machinery/light/L in T.contents)
L.on = 0
L.visible_message("<span class='warning'>[L] flickers and falls dark.</span>")
L.update(0)
for(var/obj/machinery/computer/C in T.contents)
C.SetLuminosity(0)
C.visible_message("<span class='warning'>[C] grows dim, its screen barely readable.</span>")
for(var/obj/effect/glowshroom/G in orange(7, user)) //High radius because glowshroom spam wrecks shadowlings
G.visible_message("<span class='warning'>[G] withers away!</span>")
qdel(G)
for(var/mob/living/H in T.contents)
extinguishMob(H)
for(var/mob/living/silicon/robot/borgie in T.contents)
borgie.update_headlamp(1)
/obj/effect/proc_holder/spell/self/shadow_walk //Grants the shadowling invisibility and phasing for 4 seconds
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 = 300 //Used to be twice this, buffed
human_req = 1
clothes_req = 0
action_icon_state = "shadow_walk"
sound = 'sound/effects/bamf.ogg'
/obj/effect/proc_holder/spell/self/shadow_walk/cast(mob/living/carbon/human/user)
if(!shadowling_check(user))
revert_cast()
return
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 tunnel.</span>")
user.SetStunned(0)
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(user,force=1)
if(user.pulledby)
user.pulledby.stop_pulling()
user.stop_pulling()
if(user.has_buckled_mobs())
user.unbuckle_all_mobs(force=1)
sleep(40) //4 seconds
if(!qdeleted(user))
user.visible_message("<span class='warning'>[user] suddenly manifests!</span>", "<span class='shadowling'>The rift's pressure forces you back to corporeality.</span>")
user.incorporeal_move = 0
user.alpha = 255
user.forceMove(user.loc)
/obj/effect/proc_holder/spell/aoe_turf/flashfreeze //Stuns and freezes nearby people - a bit more effective than a changeling's cryosting
name = "Icy Veins"
desc = "Instantly freezes the blood of nearby people, stunning them and causing burn damage."
panel = "Shadowling Abilities"
range = 5
charge_max = 250
human_req = 1
clothes_req = 0
action_icon_state = "icy_veins"
sound = 'sound/effects/ghost2.ogg'
/obj/effect/proc_holder/spell/aoe_turf/flashfreeze/cast(list/targets,mob/user = usr)
if(!shadowling_check(user))
revert_cast()
return
user << "<span class='shadowling'>You freeze the nearby air.</span>"
for(var/turf/T in targets)
for(var/mob/living/carbon/M in T.contents)
if(is_shadow_or_thrall(M))
if(M == user) //No message for the user, of course
continue
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'>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
/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"
charge_max = 0
human_req = 1
clothes_req = 0
range = 1 //Adjacent to user
action_icon_state = "enthrall"
var/enthralling = 0
/obj/effect/proc_holder/spell/targeted/enthrall/cast(list/targets,mob/living/carbon/human/user = usr)
listclearnulls(ticker.mode.thralls)
if(!(user.mind in ticker.mode.shadows)) return
if(user.dna.species.id != "shadowling")
if(ticker.mode.thralls.len >= 5)
revert_cast()
return
for(var/mob/living/carbon/human/target in targets)
if(!in_range(user, target))
user << "<span class='warning'>You need to be closer to enthrall [target]!</span>"
revert_cast()
return
if(!target.key || !target.mind)
user << "<span class='warning'>The target has no mind!</span>"
revert_cast()
return
if(target.stat)
user << "<span class='warning'>The target must be conscious!</span>"
revert_cast()
return
if(is_shadow_or_thrall(target))
user << "<span class='warning'>You can not enthrall allies!</span>"
revert_cast()
return
if(!ishuman(target))
user << "<span class='warning'>You can only enthrall humans!</span>"
revert_cast()
return
if(enthralling)
user << "<span class='warning'>You are already enthralling!</span>"
revert_cast()
return
if(!target.client)
user << "<span class='warning'>[target]'s mind is vacant of activity.</span>"
enthralling = 1
user << "<span class='danger'>This target is valid. You begin the enthralling...</span>"
target << "<span class='userdanger'>[user] stares at you. You feel your head begin to pulse.</span>"
for(var/progress = 0, progress <= 3, progress++)
switch(progress)
if(1)
user << "<span class='notice'>You place your hands to [target]'s head...</span>"
user.visible_message("<span class='warning'>[user] places their hands onto the sides of [target]'s head!</span>")
if(2)
user << "<span class='notice'>You begin preparing [target]'s mind as a blank slate...</span>"
user.visible_message("<span class='warning'>[user]'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))
user << "<span class='notice'>They are protected by a mindshield implant. You begin to shut down the nanobot implant - this will take some time.</span>"
user.visible_message("<span class='warning'>[user] pauses, then dips their head in concentration!</span>")
target << "<span class='boldannounce'>You feel your resolve begin to fade!</span>"
sleep(100) //10 seconds - not spawn() so the enthralling takes longer
user << "<span class='notice'>The nanobots composing the mindshield implant have been rendered inert. Now to continue.</span>"
user.visible_message("<span class='warning'>[user] relaxes again.</span>")
for(var/obj/item/weapon/implant/mindshield/L in target)
if(L && L.implanted)
qdel(L)
target << "<span class='boldannounce'>You feel the protection from your mindshield implant strain and fail.</span>"
if(3)
user << "<span class='notice'>You begin planting the tumor that will control the new thrall...</span>"
user.visible_message("<span class='warning'>A strange energy passes from [user]'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(user, target, 70)) //around 21 seconds total for enthralling, 31 for someone with a mindshield implant
user << "<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 [user]'s hands and compose yourself</span>"
enthralling = 0
return
enthralling = 0
user << "<span class='shadowling'>You have enthralled <b>[target.real_name]</b>!</span>"
target.visible_message("<span class='big'>[target] looks to have experienced a revelation!</span>", \
"<span class='warning'>False faces all d<b>ark not real not real not--</b></span>")
target.setOxyLoss(0) //In case the shadowling was choking them out
target.mind.special_role = "thrall"
ticker.mode.add_thrall(target.mind)
/obj/effect/proc_holder/spell/self/shadowling_hivemind //Lets a shadowling talk to its allies
name = "Hivemind Commune"
desc = "Allows you to silently communicate with all other shadowlings and thralls."
panel = "Shadowling Abilities"
charge_max = 0
human_req = 1
clothes_req = 0
action_icon_state = "commune"
/obj/effect/proc_holder/spell/self/shadowling_hivemind/cast(mob/living/user,mob/user = usr)
if(!is_shadow(user))
user << "<span class='warning'>You must be a shadowling to do that!</span>"
return
var/text = stripped_input(user, "What do you want to say your thralls and fellow shadowlings?.", "Hive Chat", "")
if(!text)
return
var/my_message = "<span class='shadowling'><b>\[Shadowling\]</b><i> [user.real_name]</i>: [text]</span>"
for(var/mob/M in mob_list)
if(is_shadow_or_thrall(M))
M << my_message
if(isobserver(M))
var/link = FOLLOW_LINK(M, user)
M << "[link] [my_message]"
/obj/effect/proc_holder/spell/self/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
human_req = 1
clothes_req = 0
action_icon_state = "regen_armor"
/obj/effect/proc_holder/spell/self/shadowling_regenarmor/cast(mob/living/carbon/human/user)
if(!is_shadow(user))
user << "<span class='warning'>You must be a shadowling to do this!</span>"
revert_cast()
return
user.visible_message("<span class='warning'>[user]'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>")
user.adjustCloneLoss(user.getCloneLoss())
user.equip_to_slot_or_del(new /obj/item/clothing/under/shadowling(user), slot_w_uniform)
user.equip_to_slot_or_del(new /obj/item/clothing/shoes/shadowling(user), slot_shoes)
user.equip_to_slot_or_del(new /obj/item/clothing/suit/space/shadowling(user), slot_wear_suit)
user.equip_to_slot_or_del(new /obj/item/clothing/head/shadowling(user), slot_head)
user.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(user), slot_gloves)
user.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(user), slot_wear_mask)
user.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/shadowling(user), slot_glasses)
user.set_species(/datum/species/shadow/ling)
/obj/effect/proc_holder/spell/self/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"
charge_max = 300 //30 second cooldown to prevent spam
human_req = 1
clothes_req = 0
action_icon_state = "collective_mind"
var/blind_smoke_acquired
var/screech_acquired
var/drainLifeAcquired
var/reviveThrallAcquired
/obj/effect/proc_holder/spell/self/collective_mind/cast(mob/living/carbon/human/user)
if(!shadowling_check(user))
revert_cast()
return
var/thralls = 0
var/victory_threshold = 15
var/mob/M
user << "<span class='shadowling'><b>You focus your telepathic energies abound, harnessing and drawing together the strength of your thralls.</b></span>"
for(M in living_mob_list)
if(is_thrall(M))
thralls++
M << "<span class='shadowling'>You feel hooks sink into your mind and pull.</span>"
if(!do_after(user, 30, target = user))
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 && !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(null))
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/self/blindness_smoke(null))
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/drain_life(null))
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 \
with no bodily defects.</i></span>"
user.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/revive_thrall(null))
if(thralls < victory_threshold)
user << "<span class='shadowling'>You do not have the power to ascend. You require [victory_threshold] thralls, but only [thralls] living thralls are present.</span>"
else if(thralls >= victory_threshold)
user << "<span class='shadowling'><b>You are now powerful enough to ascend. Use the Ascendance ability when you are ready. <i>This will kill all of your thralls.</i></span>"
user << "<span class='shadowling'><b>You may find Ascendance in the Shadowling Evolution tab.</b></span>"
for(M in living_mob_list)
if(is_shadow(M))
var/obj/effect/proc_holder/spell/self/collective_mind/CM
if(CM in M.mind.spell_list)
M.mind.spell_list -= CM
qdel(CM)
M.mind.RemoveSpell(/obj/effect/proc_holder/spell/self/shadowling_hatch)
M.mind.AddSpell(new /obj/effect/proc_holder/spell/self/shadowling_ascend(null))
if(M == user)
M << "<span class='shadowling'><i>You project this power to the rest of the shadowlings.</i></span>"
else
M << "<span class='shadowling'><b>[user.real_name] has coalesced the strength of the thralls. You can draw upon it at any time to ascend. (Shadowling Evolution Tab)</b></span>" //Tells all the other shadowlings
/obj/effect/proc_holder/spell/self/blindness_smoke //Spawns a cloud of smoke that blinds non-thralls/shadows and grants slight healing to shadowlings and their allies
name = "Blindness Smoke"
desc = "Spews a cloud of smoke which will blind enemies."
panel = "Shadowling Abilities"
charge_max = 600
human_req = 1
clothes_req = 0
action_icon_state = "black_smoke"
sound = 'sound/effects/bamf.ogg'
/obj/effect/proc_holder/spell/self/blindness_smoke/cast(mob/living/carbon/human/user) //Extremely hacky
if(!shadowling_check(user))
revert_cast()
return
user.visible_message("<span class='warning'>[user] bends over and coughs out a cloud of black smoke!</span>")
user << "<span class='shadowling'>You regurgitate a vast cloud of blinding smoke.</span>"
var/obj/item/weapon/reagent_containers/glass/beaker/large/B = new /obj/item/weapon/reagent_containers/glass/beaker/large(user.loc) //hacky
B.reagents.clear_reagents() //Just in case!
B.invisibility = INVISIBILITY_ABSTRACT //This ought to do the trick
B.reagents.add_reagent("blindness_smoke", 10)
var/datum/effect_system/smoke_spread/chem/S = new
S.attach(B)
if(S)
S.set_up(B.reagents, 4, 0, B.loc)
S.start()
qdel(B)
/obj/effect/proc_holder/spell/aoe_turf/unearthly_screech //Damages nearby windows, confuses nearby carbons, and outright stuns silly cones
name = "Sonic Screech"
desc = "Deafens, stuns, and confuses nearby people. Also shatters windows."
panel = "Shadowling Abilities"
range = 7
charge_max = 300
human_req = 1
clothes_req = 0
action_icon_state = "screech"
sound = 'sound/effects/screech.ogg'
/obj/effect/proc_holder/spell/aoe_turf/unearthly_screech/cast(list/targets,mob/user = usr)
if(!shadowling_check(user))
revert_cast()
return
user.audible_message("<span class='warning'><b>[user] lets out a horrible scream!</b></span>")
for(var/turf/T in targets)
for(var/mob/target in T.contents)
if(is_shadow_or_thrall(target))
if(target == user) //No message for the user, of course
continue
else
continue
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.confused += 10
M.setEarDamage(M.ear_damage + 3)
else if(issilicon(target))
var/mob/living/silicon/S = target
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_system/spark_spread/sp = new /datum/effect_system/spark_spread
sp.set_up(5, 1, S)
sp.start()
S.Weaken(6)
for(var/obj/structure/window/W in T.contents)
W.take_damage(rand(80, 100))
/obj/effect/proc_holder/spell/aoe_turf/drain_life //Deals stamina and oxygen damage to nearby humans and heals the shadowling. On a short cooldown because of the small range and situational usefulness
name = "Drain Life"
desc = "Damages nearby humans, draining their life and healing your own wounds."
panel = "Shadowling Abilities"
range = 3
charge_max = 100
human_req = 1
clothes_req = 0
action_icon_state = "drain_life"
var/targetsDrained
var/list/nearbyTargets
/obj/effect/proc_holder/spell/aoe_turf/drain_life/cast(list/targets, mob/living/carbon/human/user = usr)
if(!shadowling_check(user))
revert_cast()
return
targetsDrained = 0
nearbyTargets = list()
for(var/turf/T in targets)
for(var/mob/living/carbon/M in T.contents)
if(M == user) continue
targetsDrained++
nearbyTargets.Add(M)
if(!targetsDrained)
revert_cast()
user << "<span class='warning'>There were no nearby humans for you to drain.</span>"
return
for(var/mob/living/carbon/M in nearbyTargets)
user.heal_organ_damage(10, 10)
user.adjustToxLoss(-10)
user.adjustOxyLoss(-10)
user.adjustStaminaLoss(-20)
user.AdjustWeakened(-1)
user.AdjustStunned(-1)
M.adjustOxyLoss(20)
M.adjustStaminaLoss(20)
M << "<span class='boldannounce'>You feel a wave of exhaustion and a curious draining sensation directed towards [usr]!</span>"
user << "<span class='shadowling'>You draw life from those around you to heal your wounds.</span>"
/obj/effect/proc_holder/spell/targeted/revive_thrall //Completely revives a dead thrall
name = "Black Recuperation"
desc = "Revives or empowers a thrall."
panel = "Shadowling Abilities"
range = 1
charge_max = 600
human_req = 1
clothes_req = 0
include_user = 0
action_icon_state = "revive_thrall"
/obj/effect/proc_holder/spell/targeted/revive_thrall/cast(list/targets,mob/user = usr)
if(!shadowling_check(user))
revert_cast()
return
for(var/mob/living/carbon/human/thrallToRevive in targets)
var/choice = alert(user,"Empower a living thrall or revive a dead one?",,"Empower","Revive","Cancel")
switch(choice)
if("Empower")
if(!is_thrall(thrallToRevive))
user << "<span class='warning'>[thrallToRevive] is not a thrall.</span>"
revert_cast()
return
if(thrallToRevive.stat != CONSCIOUS)
user << "<span class='warning'>[thrallToRevive] must be conscious to become empowered.</span>"
revert_cast()
return
if(thrallToRevive.dna.species.id == "l_shadowling")
user << "<span class='warning'>[thrallToRevive] is already empowered.</span>"
revert_cast()
return
var/empowered_thralls = 0
for(var/datum/mind/M in ticker.mode.thralls)
if(!ishuman(M.current))
return
var/mob/living/carbon/human/H = M.current
if(H.dna.species.id == "l_shadowling")
empowered_thralls++
if(empowered_thralls >= EMPOWERED_THRALL_LIMIT)
user << "<span class='warning'>You cannot spare this much energy. There are too many empowered thralls.</span>"
revert_cast()
return
user.visible_message("<span class='danger'>[user] 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'>[user] places their hands over your face. You feel energy gathering. Stand still...</span>"
if(!do_mob(user, thrallToRevive, 80))
user << "<span class='warning'>Your concentration snaps. The flow of energy ebbs.</span>"
revert_cast()
return
user << "<span class='shadowling'><b><i>You release a massive surge of power into [thrallToRevive]!</b></i></span>"
user.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)
user.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(/datum/species/shadow/ling/lesser)
thrallToRevive.mind.RemoveSpell(/obj/effect/proc_holder/spell/targeted/lesser_glare)
thrallToRevive.mind.RemoveSpell(/obj/effect/proc_holder/spell/self/lesser_shadow_walk)
thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare(null))
thrallToRevive.mind.AddSpell(new /obj/effect/proc_holder/spell/self/shadow_walk(null))
if("Revive")
if(!is_thrall(thrallToRevive))
user << "<span class='warning'>[thrallToRevive] is not a thrall.</span>"
revert_cast()
return
if(thrallToRevive.stat != DEAD)
user << "<span class='warning'>[thrallToRevive] is not dead.</span>"
revert_cast()
return
user.visible_message("<span class='danger'>[user] 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(user, thrallToRevive, 30))
user << "<span class='warning'>Your concentration snaps. The flow of energy ebbs.</span>"
revert_cast()
return
user << "<span class='shadowling'><b><i>You release a massive surge of power into [thrallToRevive]!</b></i></span>"
user.visible_message("<span class='boldannounce'><i>Red lightning surges from [user]'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)
user.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
revert_cast()
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
human_req = 1
clothes_req = 0
charge_max = 600
action_icon_state = "extend_shuttle"
/obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle/cast(list/targets, mob/living/carbon/human/user = usr)
if(!shadowling_check(user))
revert_cast()
return
for(var/mob/living/carbon/human/target in targets)
if(target.stat)
revert_cast()
return
if(!is_thrall(target))
user << "<span class='warning'>[target] must be a thrall.</span>"
revert_cast()
return
if(SSshuttle.emergency.mode != SHUTTLE_CALL)
user << "<span class='warning'>The shuttle must be inbound only to the station.</span>"
revert_cast()
return
var/mob/living/carbon/human/M = target
user.visible_message("<span class='warning'>[user]'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(user, 50, target = M))
M << "<span class='warning'>You are snapped back to reality, your haze dissipating!</span>"
user << "<span class='warning'>You have been interrupted. The draw has failed.</span>"
return
user << "<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(SSshuttle.emergency.mode == SHUTTLE_CALL)
var/more_minutes = 9000
var/timer = SSshuttle.emergency.timeLeft()
timer += more_minutes
priority_announce("Major system failure aboard the emergency shuttle. This will extend its arrival time by approximately 15 minutes..", "System Failure", 'sound/misc/notice1.ogg')
SSshuttle.emergency.setTimer(timer)
user.mind.spell_list.Remove(src) //Can only be used once!
qdel(src)
// THRALL ABILITIES BEYOND THIS POINT //
/obj/effect/proc_holder/spell/targeted/lesser_glare //Thrall version of Glare - same effects but for 5 seconds
name = "Lesser Glare"
desc = "Stuns and mutes a target for a short duration."
panel = "Thrall Abilities"
charge_max = 450
human_req = 1
clothes_req = 0
action_icon_state = "glare"
/obj/effect/proc_holder/spell/targeted/lesser_glare/cast(list/targets,mob/user = usr)
for(var/mob/living/target in targets)
if(!ishuman(target) || !target)
user << "<span class='warning'>You nay only glare at humans!</span>"
revert_cast()
return
if(target.stat)
user << "<span class='warning'>[target] must be conscious!</span>"
revert_cast()
return
if(is_shadow_or_thrall(target))
user << "<span class='warning'>You cannot glare at allies!</span>"
revert_cast()
return
var/mob/living/carbon/human/M = target
user.visible_message("<span class='warning'><b>[user]'s eyes flash a bright red!</b></span>")
target.visible_message("<span class='danger'>[target] freezes in place, their eyes clouding...</span>")
if(in_range(target, user))
target << "<span class='userdanger'>Your gaze is forcibly drawn into [user]'s eyes, and you are starstruck by the heavenly lights...</span>"
else //Only alludes to the shadowling if the target is close by
target << "<span class='userdanger'>Red lights suddenly dance in your vision, and you are starstruck by their heavenly beauty...</span>"
target.Stun(5) //Roughly 50% as long as the normal one
M.silent += 5
/obj/effect/proc_holder/spell/self/lesser_shadow_walk //Thrall version of Shadow Walk, only works in darkness, doesn't grant phasing, but gives near-invisibility
name = "Guise"
desc = "Wraps your form in shadows, making you harder to see."
panel = "Thrall Abilities"
charge_max = 1200
human_req = 1
clothes_req = 0
action_icon_state = "shadow_walk"
/obj/effect/proc_holder/spell/self/lesser_shadow_walk/cast(mob/living/carbon/human/user)
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 = 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)
/obj/effect/proc_holder/spell/self/thrall_vision //Toggleable night vision for thralls
name = "Darksight"
desc = "Gives you night vision."
panel = "Thrall Abilities"
charge_max = 0
human_req = 1
clothes_req = 0
action_icon_state = "darksight"
var/active = 0
/obj/effect/proc_holder/spell/self/thrall_vision/cast(mob/living/carbon/human/user)
active = !active
if(active)
user << "<span class='notice'>You shift the nerves in your eyes, allowing you to see in the dark.</span>"
user.dna.species.darksight = 8
user.dna.species.invis_sight = SEE_INVISIBLE_MINIMUM
else
user << "<span class='notice'>You return your vision to normal.</span>"
user.dna.species.darksight = 0
user.dna.species.invis_sight = initial(user.dna.species.invis_sight)
user.update_sight()
/obj/effect/proc_holder/spell/self/lesser_shadowling_hivemind //Lets a thrall talk with their allies
name = "Lesser Commune"
desc = "Allows you to silently communicate with all other shadowlings and thralls."
panel = "Thrall Abilities"
charge_max = 50
human_req = 1
clothes_req = 0
action_icon_state = "commune"
/obj/effect/proc_holder/spell/self/lesser_shadowling_hivemind/cast(mob/living/carbon/human/user)
if(!is_shadow_or_thrall(user))
user << "<span class='warning'><b>As you attempt to commune with the others, an agonizing spike of pain drives itself into your head!</b></span>"
user.apply_damage(10, BRUTE, "head")
return
var/text = stripped_input(user, "What do you want to say your masters and fellow thralls?.", "Lesser Commune", "")
if(!text)
return
text = "<span class='shadowling'><b>\[Thrall\]</b><i> [user.real_name]</i>: [text]</span>"
for(var/mob/M in mob_list)
if(is_shadow_or_thrall(M))
M << text
if(isobserver(M))
var/link = FOLLOW_LINK(M, user)
M << "[link] [text]"
log_say("[user.real_name]/[user.key] : [text]")
// ASCENDANT ABILITIES BEYOND THIS POINT //
/obj/effect/proc_holder/spell/targeted/annihilate //Gibs someone instantly.
name = "Annihilate"
desc = "Gibs someone instantly."
panel = "Ascendant"
range = 7
charge_max = 0
clothes_req = 0
action_icon_state = "annihilate"
sound = 'sound/magic/Staff_Chaos.ogg'
/obj/effect/proc_holder/spell/targeted/annihilate/cast(list/targets,mob/living/simple_animal/ascendant_shadowling/user = usr)
if(user.incorporeal_move)
user << "<span class='warning'>You are not in the same plane of existence. Unphase first.</span>"
revert_cast()
return
for(var/mob/living/boom in targets)
if(is_shadow(boom)) //Used to not work on thralls. Now it does so you can PUNISH THEM LIKE THE WRATHFUL GOD YOU ARE.
user << "<span class='warning'>Making an ally explode seems unwise.<span>"
revert_cast()
return
user.visible_message("<span class='warning'>[user]'s markings flare as they gesture at [boom]!</span>", \
"<span class='shadowling'>You direct a lance of telekinetic energy into [boom].</span>")
sleep(4)
if(iscarbon(boom))
playsound(boom, 'sound/magic/Disintegrate.ogg', 100, 1)
boom.visible_message("<span class='userdanger'>[boom] explodes!</span>")
boom.gib()
/obj/effect/proc_holder/spell/targeted/hypnosis //Enthralls someone instantly. Nonlethal alternative to Annihilate
name = "Hypnosis"
desc = "Instantly enthralls a human."
panel = "Ascendant"
range = 7
charge_max = 0
clothes_req = 0
action_icon_state = "enthrall"
/obj/effect/proc_holder/spell/targeted/hypnosis/cast(list/targets,mob/living/simple_animal/ascendant_shadowling/user = usr)
if(user.incorporeal_move)
revert_cast()
user << "<span class='warning'>You are not in the same plane of existence. Unphase first.</span>"
return
for(var/mob/living/carbon/human/target in targets)
if(is_shadow_or_thrall(target))
user << "<span class='warning'>You cannot enthrall an ally.<span>"
revert_cast()
return
if(!target.ckey || !target.mind)
user << "<span class='warning'>The target has no mind.</span>"
revert_cast()
return
if(target.stat)
user << "<span class='warning'>The target must be conscious.</span>"
revert_cast()
return
if(!ishuman(target))
user << "<span class='warning'>You can only enthrall humans.</span>"
revert_cast()
return
user << "<span class='shadowling'>You instantly rearrange <b>[target]</b>'s memories, hyptonitizing them into a thrall.</span>"
target << "<span class='userdanger'><font size=3>An agonizing spike of pain drives into your mind, and--</font></span>"
target.mind.special_role = "thrall"
ticker.mode.add_thrall(target.mind)
/obj/effect/proc_holder/spell/self/shadowling_phase_shift //Permanent version of shadow walk with no drawback. Toggleable.
name = "Phase Shift"
desc = "Phases you into the space between worlds at will, allowing you to move through walls and become invisible."
panel = "Ascendant"
charge_max = 15
clothes_req = 0
action_icon_state = "shadow_walk"
/obj/effect/proc_holder/spell/self/shadowling_phase_shift/cast(mob/living/simple_animal/ascendant_shadowling/user)
user.incorporeal_move = !user.incorporeal_move
if(user.incorporeal_move)
user.visible_message("<span class='danger'>[user] suddenly vanishes!</span>", \
"<span class='shadowling'>You begin phasing through planes of existence. Use the ability again to return.</span>")
user.density = 0
user.alpha = 0
else
user.visible_message("<span class='danger'>[user] suddenly appears from nowhere!</span>", \
"<span class='shadowling'>You return from the space between worlds.</span>")
user.density = 1
user.alpha = 255
/obj/effect/proc_holder/spell/aoe_turf/ascendant_storm //Releases bolts of lightning to everyone nearby
name = "Lightning Storm"
desc = "Shocks everyone nearby."
panel = "Ascendant"
range = 6
charge_max = 100
clothes_req = 0
action_icon_state = "lightning_storm"
sound = 'sound/magic/lightningbolt.ogg'
/obj/effect/proc_holder/spell/aoe_turf/ascendant_storm/cast(list/targets,mob/living/simple_animal/ascendant_shadowling/user = usr)
if(user.incorporeal_move)
user << "<span class='warning'>You are not in the same plane of existence. Unphase first.</span>"
revert_cast()
return
user.visible_message("<span class='warning'><b>A massive ball of lightning appears in [user]'s hands and flares out!</b></span>", \
"<span class='shadowling'>You conjure a ball of lightning and release it.</span>")
for(var/turf/T in targets)
for(var/mob/living/carbon/human/target in T.contents)
if(is_shadow_or_thrall(target))
continue
target << "<span class='userdanger'>You are struck by a bolt of lightning!</span>"
playsound(target, 'sound/magic/LightningShock.ogg', 50, 1)
target.Weaken(8)
target.take_organ_damage(0,50)
user.Beam(target,icon_state="red_lightning",icon='icons/effects/effects.dmi',time=1)
/obj/effect/proc_holder/spell/self/shadowling_hivemind_ascendant //Large, all-caps text in shadowling chat
name = "Ascendant Commune"
desc = "Allows you to LOUDLY communicate with all other shadowlings and thralls."
panel = "Ascendant"
charge_max = 0
clothes_req = 0
action_icon_state = "commune"
/obj/effect/proc_holder/spell/self/shadowling_hivemind_ascendant/cast(mob/living/carbon/human/user)
var/text = stripped_input(user, "What do you want to say to fellow thralls and shadowlings?.", "Hive Chat", "")
if(!text)
return
text = "<font size=4><span class='shadowling'><b>\[Ascendant\]<i> [user.real_name]</i>: [text]</b></span></font>"
for(var/mob/M in mob_list)
if(is_shadow_or_thrall(M))
M << text
if(isobserver(M))
var/link = FOLLOW_LINK(M, user)
M << "[link] [text]"
log_say("[user.real_name]/[user.key] : [text]")

View File

@@ -1,108 +0,0 @@
/obj/item/clothing/under/shadowling
name = "blackened flesh"
desc = "Black, chitinous skin."
item_state = null
origin_tech = null
icon_state = "shadowling"
has_sensor = 0
unacidable = 1
flags = ABSTRACT | NODROP
/obj/item/clothing/suit/space/shadowling
name = "chitin shell"
desc = "A dark, semi-transparent shell. Protects against vacuum, but not against the light of the stars." //Still takes damage from spacewalking but is immune to space itself
icon_state = "shadowling"
item_state = null
body_parts_covered = FULL_BODY //Shadowlings are immune to space
cold_protection = FULL_BODY
min_cold_protection_temperature = SPACE_SUIT_MIN_TEMP_PROTECT
flags_inv = HIDEGLOVES | HIDESHOES | HIDEJUMPSUIT
slowdown = 0
unacidable = 1
heat_protection = null //You didn't expect a light-sensitive creature to have heat resistance, did you?
max_heat_protection_temperature = null
armor = list(melee = 25, bullet = 0, laser = 0, energy = 0, bomb = 25, bio = 100, rad = 100)
flags = ABSTRACT | NODROP | THICKMATERIAL | STOPSPRESSUREDMAGE
/obj/item/clothing/shoes/shadowling
name = "chitin feet"
desc = "Charred-looking feet. They have minature hooks that latch onto flooring."
icon_state = "shadowling"
item_state = null
unacidable = 1
flags = NOSLIP | ABSTRACT | NODROP
/obj/item/clothing/mask/gas/shadowling
name = "chitin mask"
desc = "A mask-like formation with slots for facial features. A red film covers the eyes."
icon_state = "shadowling"
item_state = null
origin_tech = null
siemens_coefficient = 0
unacidable = 1
flags = ABSTRACT | NODROP
/obj/item/clothing/gloves/shadowling
name = "chitin hands"
desc = "An electricity-resistant covering of the hands."
icon_state = "shadowling"
item_state = null
origin_tech = null
siemens_coefficient = 0
unacidable = 1
flags = ABSTRACT | NODROP
/obj/item/clothing/head/shadowling
name = "chitin helm"
desc = "A helmet-like enclosure of the head."
icon_state = "shadowling"
item_state = null
cold_protection = HEAD
min_cold_protection_temperature = SPACE_HELM_MIN_TEMP_PROTECT
heat_protection = HEAD
max_heat_protection_temperature = SPACE_HELM_MAX_TEMP_PROTECT
origin_tech = null
unacidable = 1
flags = ABSTRACT | NODROP | STOPSPRESSUREDMAGE
/obj/item/clothing/glasses/night/shadowling
name = "crimson eyes"
desc = "A shadowling's eyes. Very light-sensitive and can detect body heat through walls."
icon = 'icons/obj/surgery.dmi'
icon_state = "ling_thermal"
item_state = null
origin_tech = null
vision_flags = SEE_MOBS
darkness_view = 1
invis_view = 2
flash_protect = -1
unacidable = 1
actions_types = list(/datum/action/item_action/hands_free/shift_nerves)
var/max_darkness_view = 8
var/min_darkness_view = 0
flags = ABSTRACT | NODROP
/obj/item/clothing/glasses/night/shadowling/attack_self(mob/user)
if(!ishuman(user))
return
var/mob/living/carbon/human/H = user
if(H.dna.species.id != "shadowling")
user << "<span class='warning'>You aren't sure how to do this...</span>"
return
H.dna.species.darksight = 0 //so our species' vision in the dark doesn't interfere.
var/new_dark_view
new_dark_view = (input(user, "Enter the radius of tiles to see with night vision.", "Night Vision", "[new_dark_view]") as num)
new_dark_view = Clamp(new_dark_view,min_darkness_view,max_darkness_view)
switch(new_dark_view)
if(0)
user << "<span class='notice'>Your night vision capabilities fade away for the time being.</span>"
else
user << "<span class='notice'>You shift your night vision capabilities to see [new_dark_view] tiles away.</span>"
darkness_view = new_dark_view
user.update_sight()

View File

@@ -1,180 +0,0 @@
//In here: Hatch and Ascendance
var/list/possibleShadowlingNames = list("U'ruan", "Y`shej", "Nex", "Hel-uae", "Noaey'gief", "Mii`mahza", "Amerziox", "Gyrg-mylin", "Kanet'pruunance", "Vigistaezian") //Unpronouncable 2: electric boogalo
/obj/effect/proc_holder/spell/self/shadowling_hatch
name = "Hatch"
desc = "Casts off your disguise."
panel = "Shadowling Evolution"
charge_max = 3000
human_req = 1
clothes_req = 0
action_icon_state = "hatch"
/obj/effect/proc_holder/spell/self/shadowling_hatch/cast(list/targets,mob/user = usr)
if(user.stat || !ishuman(user) || !user || !is_shadow(user || isinspace(user)))
return
var/mob/living/carbon/human/H = user
var/hatch_or_no = alert(H,"Are you sure you want to hatch? You cannot undo this!",,"Yes","No")
switch(hatch_or_no)
if("No")
H << "<span class='warning'>You decide against hatching for now."
charge_counter = charge_max
return
if("Yes")
H.stunned = INFINITY //This is bad but hulks can't be stunned with the actual procs. I'm sorry.
H.visible_message("<span class='warning'>[H]'s things suddenly slip off. They hunch over and vomit up a copious amount of purple goo which begins to shape around them!</span>", \
"<span class='shadowling'>You remove any equipment which would hinder your hatching and begin regurgitating the resin which will protect you.</span>")
var/temp_flags = H.status_flags
H.status_flags |= GODMODE //Can't die while hatching
for(var/obj/item/I in H) //drops all items
H.unEquip(I)
sleep(50)
var/turf/open/floor/F
var/turf/shadowturf = get_turf(user)
for(F in orange(1, user))
new /obj/structure/alien/resin/wall/shadowling(F)
for(var/obj/structure/alien/resin/wall/shadowling/R in shadowturf) //extremely hacky
qdel(R)
new /obj/structure/alien/weeds/node(shadowturf) //Dim lighting in the chrysalis -- removes itself afterwards
H.visible_message("<span class='warning'>A chrysalis forms around [H], sealing them inside.</span>", \
"<span class='shadowling'>You create your chrysalis and begin to contort within.</span>")
sleep(100)
H.visible_message("<span class='warning'><b>The skin on [H]'s back begins to split apart. Black spines slowly emerge from the divide.</b></span>", \
"<span class='shadowling'>Spines pierce your back. Your claws break apart your fingers. You feel excruciating pain as your true form begins its exit.</span>")
sleep(90)
H.visible_message("<span class='warning'><b>[H], skin shifting, begins tearing at the walls around them.</b></span>", \
"<span class='shadowling'>Your false skin slips away. You begin tearing at the fragile membrane protecting you.</span>")
sleep(80)
playsound(H.loc, 'sound/weapons/slash.ogg', 25, 1)
H << "<i><b>You rip and slice.</b></i>"
sleep(10)
playsound(H.loc, 'sound/weapons/slashmiss.ogg', 25, 1)
H << "<i><b>The chrysalis falls like water before you.</b></i>"
sleep(10)
playsound(H.loc, 'sound/weapons/slice.ogg', 25, 1)
H << "<i><b>You are free!</b></i>"
H.status_flags = temp_flags
sleep(10)
playsound(H.loc, 'sound/effects/ghost.ogg', 100, 1)
var/newNameId = pick(possibleShadowlingNames)
possibleShadowlingNames.Remove(newNameId)
H.real_name = newNameId
H.name = user.real_name
H.stunned = 0 //Same as above. Due to hulks.
H << "<i><b><font size=3>YOU LIVE!!!</i></b></font>"
for(var/obj/structure/alien/resin/wall/shadowling/W in orange(1, H))
playsound(W, 'sound/effects/splat.ogg', 50, 1)
qdel(W)
for(var/obj/structure/alien/weeds/node/N in shadowturf)
qdel(N)
H.visible_message("<span class='warning'>The chrysalis explodes in a shower of purple flesh and fluid!</span>")
H.underwear = "Nude"
H.undershirt = "Nude"
H.socks = "Nude"
H.faction |= "faithless"
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/night/shadowling(H), slot_glasses)
H.set_species(/datum/species/shadow/ling) //can't be a shadowling without being a shadowling
H.mind.RemoveSpell(src)
sleep(10)
H << "<span class='shadowling'><b><i>Your powers are awoken. You may now live to your fullest extent. Remember your goal. Cooperate with your thralls and allies.</b></i></span>"
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/enthrall(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/glare(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/veil(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/self/shadow_walk(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/flashfreeze(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/self/collective_mind(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/self/shadowling_regenarmor(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/shadowling_extend_shuttle(null))
/obj/effect/proc_holder/spell/self/shadowling_ascend
name = "Ascend"
desc = "Enters your true form."
panel = "Shadowling Evolution"
charge_max = 3000
clothes_req = 0
action_icon_state = "ascend"
/obj/effect/proc_holder/spell/self/shadowling_ascend/cast(list/targets,mob/user = usr)
var/mob/living/carbon/human/H = user
if(!shadowling_check(H))
return
var/hatch_or_no = alert(H,"It is time to ascend. Are you sure about this?",,"Yes","No")
switch(hatch_or_no)
if("No")
H << "<span class='warning'>You decide against ascending for now."
charge_counter = charge_max
return
if("Yes")
H.notransform = 1
H.visible_message("<span class='warning'>[H]'s things suddenly slip off. They gently rise into the air, red light glowing in their eyes.</span>", \
"<span class='shadowling'>You rise into the air and get ready for your transformation.</span>")
for(var/obj/item/I in H) //drops all items
H.unEquip(I)
sleep(50)
H.visible_message("<span class='warning'>[H]'s skin begins to crack and harden.</span>", \
"<span class='shadowling'>Your flesh begins creating a shield around yourself.</span>")
sleep(100)
H.visible_message("<span class='warning'>The small horns on [H]'s head slowly grow and elongate.</span>", \
"<span class='shadowling'>Your body continues to mutate. Your telepathic abilities grow.</span>") //y-your horns are so big, senpai...!~
sleep(90)
H.visible_message("<span class='warning'>[H]'s body begins to violently stretch and contort.</span>", \
"<span class='shadowling'>You begin to rend apart the final barriers to godhood.</span>")
sleep(40)
H << "<i><b>Yes!</b></i>"
sleep(10)
H << "<i><b><span class='big'>YES!!</span></b></i>"
sleep(10)
H << "<i><b><span class='reallybig'>YE--</span></b></i>"
sleep(1)
for(var/mob/living/M in orange(7, H))
M.Weaken(10)
M << "<span class='userdanger'>An immense pressure slams you onto the ground!</span>"
world << "<font size=5><span class='shadowling'><b>\"VYSHA NERADA YEKHEZET U'RUU!!\"</font></span>"
world << 'sound/hallucinations/veryfar_noise.ogg'
for(var/obj/machinery/power/apc/A in apcs_list)
A.overload_lighting()
var/mob/A = new /mob/living/simple_animal/ascendant_shadowling(H.loc)
for(var/obj/effect/proc_holder/spell/S in H.mind.spell_list)
if(S == src) continue
H.mind.RemoveSpell(S)
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/annihilate(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/targeted/hypnosis(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/self/shadowling_phase_shift(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/aoe_turf/ascendant_storm(null))
H.mind.AddSpell(new /obj/effect/proc_holder/spell/self/shadowling_hivemind_ascendant(null))
H.mind.transfer_to(A)
A.name = H.real_name
if(A.real_name)
A.real_name = H.real_name
H.invisibility = 60 //This is pretty bad, but is also necessary for the shuttle call to function properly
H.loc = A
sleep(50)
if(!ticker.mode.shadowling_ascended)
SSshuttle.emergency.request(null, 0.3)
ticker.mode.shadowling_ascended = 1
A.mind.RemoveSpell(src)
qdel(H)

View File

@@ -263,16 +263,6 @@
slot_flags = SLOT_BELT
attack_verb = list("whipped", "lashed")
/obj/item/weapon/nullrod/whip/afterattack(atom/movable/AM, mob/user, proximity)
if(!proximity)
return
if(istype(AM, /mob/living/carbon/human))
var/mob/living/carbon/human/H = AM
if(is_shadow(H))
var/phrase = pick("Die monster! You don't belong in this world!!!", "You steal men's souls and make them your slaves!!!", "Your words are as empty as your soul!!!", "Mankind ill needs a savior such as you!!!")
user.say("[phrase]")
H.adjustBruteLoss(8) //Bonus damage
/obj/item/weapon/nullrod/fedora
name = "atheist's fedora"
desc = "The brim of the hat is as sharp as your wit. Throwing it at someone would hurt almost as much as disproving the existence of God."

View File

@@ -19,7 +19,7 @@
/obj/item/weapon/implant/mindshield/implant(mob/target)
if(..())
if((target.mind in (ticker.mode.head_revolutionaries | ticker.mode.get_gang_bosses())) || is_shadow_or_thrall(target))
if((target.mind in (ticker.mode.head_revolutionaries | ticker.mode.get_gang_bosses())))
target.visible_message("<span class='warning'>[target] seems to resist the implant!</span>", "<span class='warning'>You feel something interfering with your mental conditioning, but you resist it!</span>")
removed(target, 1)
qdel(src)

View File

@@ -86,11 +86,6 @@
/obj/structure/alien/resin/wall/BlockSuperconductivity()
return 1
/obj/structure/alien/resin/wall/shadowling //For chrysalis
name = "chrysalis wall"
desc = "Some sort of purple substance in an egglike shape. It pulses and throbs from within and seems impenetrable."
health = INFINITY
/obj/structure/alien/resin/membrane
name = "resin membrane"
desc = "Resin just thin enough to let light pass through."

View File

@@ -552,29 +552,6 @@
dat += "<td><A href='?priv_msg=[traitor.key]'>PM</A></td></tr>"
dat += "</table>"
if(ticker.mode.shadows.len)
dat += "<br><table cellspacing=5><tr><td><B>Shadowlings</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.shadows)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
else
dat += "<tr><td><a href='?_src_=vars;Vars=\ref[N]'>[N.name]([N.key])</a><i>Shadowling body destroyed!</i></td>"
dat += "<td><A href='?priv_msg=[N.key]'>PM</A></td></tr>"
dat += "</table>"
if(ticker.mode.thralls.len)
dat += "<br><table cellspacing=5><tr><td><B>Shadowling Thralls</B></td><td></td></tr>"
for(var/datum/mind/N in ticker.mode.thralls)
var/mob/M = N.current
if(M)
dat += "<tr><td><a href='?_src_=holder;adminplayeropts=\ref[M]'>[M.real_name]</a>[M.client ? "" : " <i>(ghost)</i>"][M.stat == 2 ? " <b><font color=red>(DEAD)</font></b>" : ""]</td>"
dat += "<td><A href='?priv_msg=[M.ckey]'>PM</A></td>"
dat += "<td><A href='?_src_=holder;adminplayerobservefollow=\ref[M]'>FLW</a></td></tr>"
dat += "</table>"
if(ticker.mode.abductors.len)
dat += "<br><table cellspacing=5><tr><td><B>Abductors</B></td><td></td><td></td></tr>"
for(var/datum/mind/abductor in ticker.mode.abductors)

View File

@@ -126,13 +126,6 @@
else
message_admins("[key_name_admin(usr)] tried to start a clockwork cult. Unfortunately, there were no candidates available.")
log_admin("[key_name(usr)] failed to start a clockwork cult.")
if("16")
if(src.makeShadowling())
message_admins("[key_name(usr)] created a shadowling.")
log_admin("[key_name(usr)] created a shadowling.")
else
message_admins("[key_name_admin(usr)] tried to create a shadowling. Unfortunately, there were no candidates available.")
log_admin("[key_name(usr)] failed to create a shadowling.")
else if(href_list["forceevent"])
if(!check_rights(R_FUN))
@@ -839,12 +832,6 @@
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=servant of Ratvar;jobban4=\ref[M]'>[replacetext("Servant", " ", "&nbsp")]</a></td>"
//Shadowling
if(jobban_isbanned(M, "shadowling") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=shadowling;jobban4=\ref[M]'><font color=red>[replacetext("Shadowling", " ", "&nbsp")]</font></a></td>"
else
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=shadowling;jobban4=\ref[M]'>[replacetext("Shadowling", " ", "&nbsp")]</a></td>"
//Wizard
if(jobban_isbanned(M, "wizard") || isbanned_dept)
jobs += "<td width='20%'><a href='?src=\ref[src];jobban3=wizard;jobban4=\ref[M]'><font color=red>[replacetext("Wizard", " ", "&nbsp")]</font></a></td>"

View File

@@ -18,7 +18,6 @@
<a href='?src=\ref[src];makeAntag=15'>Make Clockwork Cult</a><br>
<a href='?src=\ref[src];makeAntag=11'>Make Blob</a><br>
<a href='?src=\ref[src];makeAntag=12'>Make Gangsters</a><br>
<a href='?src=\ref[src];makeAntag=16'>Make Shadowling</a><br>
<a href='?src=\ref[src];makeAntag=6'>Make Wizard (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=7'>Make Nuke Team (Requires Ghosts)</a><br>
<a href='?src=\ref[src];makeAntag=13'>Make Centcom Response Team (Requires Ghosts)</a><br>
@@ -550,34 +549,3 @@
/datum/admins/proc/makeAbductorTeam()
new /datum/round_event/ghost_role/abductor
return 1
//Shadowling
/datum/admins/proc/makeShadowling()
var/datum/game_mode/shadowling/temp = new
if(config.protect_roles_from_antagonist)
temp.restricted_jobs += temp.protected_jobs
if(config.protect_assistant_from_antagonist)
temp.restricted_jobs += "Assistant"
var/list/mob/living/carbon/human/candidates = list()
var/mob/living/carbon/human/H = null
for(var/mob/living/carbon/human/applicant in player_list)
if(ROLE_SHADOWLING in applicant.client.prefs.be_special)
var/turf/T = get_turf(applicant)
if(applicant.stat == CONSCIOUS && applicant.mind && !applicant.mind.special_role && T.z == ZLEVEL_STATION)
if(!jobban_isbanned(applicant, "shadowling") && !jobban_isbanned(applicant, "Syndicate"))
if(temp.age_check(applicant.client))
if(!(applicant.job in temp.restricted_jobs))
if(!(is_shadow_or_thrall(applicant)))
candidates += applicant
if(candidates.len)
H = pick(candidates)
ticker.mode.shadows += H.mind
H.mind.special_role = "shadowling"
H << "<span class='shadowling'><b><i>Something stirs in the space between worlds. A red light floods your mind, and suddenly you understand. Your human disguise has served you well, but it \
is time you cast it away. You are a shadowling, and you are to ascend at all costs.</b></i></span>"
ticker.mode.finalize_shadowling(H.mind)
message_admins("[H] has been made into a shadowling.")
candidates.Remove(H)
return 1
return 0

View File

@@ -47,10 +47,9 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
var/B_ninja = 1024
var/B_monkey = 2048
var/B_gang = 4096
var/B_shadowling = 8192
var/B_abductor = 16384
var/list/archived = list(B_traitor,B_operative,B_changeling,B_wizard,B_malf,B_rev,B_alien,B_pai,B_cultist,B_blob,B_ninja,B_monkey,B_gang,B_shadowling,B_abductor)
var/list/archived = list(B_traitor,B_operative,B_changeling,B_wizard,B_malf,B_rev,B_alien,B_pai,B_cultist,B_blob,B_ninja,B_monkey,B_gang,B_abductor)
be_special = list()
@@ -84,8 +83,6 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
be_special += ROLE_MONKEY
if(4096)
be_special += ROLE_GANG
if(8192)
be_special += ROLE_SHADOWLING
if(16384)
be_special += ROLE_ABDUCTOR

View File

@@ -298,9 +298,6 @@
if(digitalcamo)
msg += "[t_He] [t_is] moving [t_his] body in an unnatural and blatantly inhuman manner.\n"
if(!skipface && is_thrall(src) && in_range(user,src))
msg += "Their features seem unnaturally tight and drawn.\n"
if(istype(user, /mob/living/carbon/human))
var/mob/living/carbon/human/H = user
var/obj/item/organ/cyberimp/eyes/hud/CIH = H.getorgan(/obj/item/organ/cyberimp/eyes/hud)

View File

@@ -3,7 +3,5 @@
ticker.mode.remove_cultist(mind, 0, 0)
ticker.mode.remove_revolutionary(mind, 0)
ticker.mode.remove_gangster(mind, remove_bosses=1)
ticker.mode.remove_thrall(mind,0)
ticker.mode.remove_shadowling(mind)
ticker.mode.remove_hog_follower(mind,0)
..()

View File

@@ -6,6 +6,4 @@
if(mind)
ticker.mode.remove_revolutionary(mind)
ticker.mode.remove_gangster(mind,1,remove_bosses=1)
ticker.mode.remove_thrall(mind,0)
ticker.mode.remove_shadowling(mind)
ticker.mode.remove_hog_follower(mind, 0)

View File

@@ -1194,32 +1194,6 @@
id = "weakplasmavirusfood"
color = "#CEC3C6" // rgb: 206,195,198
//Reagent used for shadowling blindness smoke spell
datum/reagent/shadowling_blindness_smoke
name = "odd black liquid"
id = "blindness_smoke"
description = "<::ERROR::> CANNOT ANALYZE REAGENT <::ERROR::>"
color = "#000000" //Complete black (RGB: 0, 0, 0)
metabolization_rate = 100 //lel
/datum/reagent/shadowling_blindness_smoke/on_mob_life(mob/living/M)
if(!is_shadow_or_thrall(M))
M << "<span class='warning'><b>You breathe in the black smoke, and your eyes burn horribly!</b></span>"
M.blind_eyes(5)
if(prob(25))
M.visible_message("<b>[M]</b> claws at their eyes!")
M.Stun(3, 0)
. = 1
else
M << "<span class='notice'><b>You breathe in the black smoke, and you feel revitalized!</b></span>"
M.heal_organ_damage(2,2, 0)
M.adjustOxyLoss(-2, 0)
M.adjustToxLoss(-2, 0)
. = 1
return ..() || .
/datum/reagent/royal_bee_jelly
name = "royal bee jelly"
id = "royal_bee_jelly"

View File

@@ -64,7 +64,7 @@
playsound(get_turf(holder.my_atom), 'sound/effects/pray.ogg', 80, 0, round(created_volume/48))
strengthdiv = 8
for(var/mob/living/carbon/C in get_hearers_in_view(round(created_volume/48,1),get_turf(holder.my_atom)))
if(iscultist(C) || is_handofgod_cultist(C) || C.dna.species.id == "shadowling" || C.dna.species.id == "l_shadowling")
if(iscultist(C) || is_handofgod_cultist(C))
C << "<span class='userdanger'>The divine explosion sears you!</span>"
C.Weaken(2)
C.adjust_fire_stacks(5)

View File

@@ -515,9 +515,6 @@
else if(is_revolutionary_in_general(user))
ticker.mode.add_revolutionary(G.mind)
golem_becomes_antag = TRUE
else if(is_shadow_or_thrall(user))
ticker.mode.add_thrall(G.mind)
golem_becomes_antag = TRUE
else if(is_servant_of_ratvar(user))
add_servant_of_ratvar(G)
golem_becomes_antag = TRUE

View File

@@ -1,41 +0,0 @@
/datum/surgery/remove_thrall
name = "dethralling"
steps = list(/datum/surgery_step/incise, /datum/surgery_step/clamp_bleeders, /datum/surgery_step/retract_skin, /datum/surgery_step/saw, /datum/surgery_step/dethrall)
possible_locs = list("head")
/datum/surgery/remove_thrall/can_start(mob/user, mob/living/carbon/target)
return is_thrall(target)
/datum/surgery_step/dethrall
name = "cleanse contamination"
implements = list(/obj/item/device/assembly/flash = 100, /obj/item/device/flashlight/pen = 80, /obj/item/device/flashlight = 40)
time = 30
/datum/surgery_step/dethrall/preop(mob/user, mob/living/carbon/target, target_zone, obj/item/tool, datum/surgery/surgery)
user.visible_message("[user] reaches into [target]'s head with [tool].", "<span class='notice'>You begin aligning [tool]'s light to the tumor on [target]'s brain...</span>")
/datum/surgery_step/dethrall/success(mob/user, mob/living/carbon/target, target_zone, datum/surgery/surgery)
if(target.dna.species.id == "l_shadowling") //Empowered thralls cannot be deconverted
target << "<span class='shadowling'><b><i>NOT LIKE THIS!</i></b></span>"
user.visible_message("<span class='danger'>[target] suddenly slams upward and knocks down [user]!</span>", \
"<span class='userdanger'>[target] suddenly bolts up and slams you with tremendous force!</span>")
user.resting = 0 //Remove all stuns
user.SetSleeping(0)
user.SetStunned(0)
user.SetWeakened(0)
user.SetParalysis(0)
if(iscarbon(user))
var/mob/living/carbon/C = user
C.Weaken(6)
C.apply_damage(20, "brute", "chest")
else if(issilicon(user))
var/mob/living/silicon/S = user
S.Weaken(8)
S.apply_damage(20, "brute")
playsound(S, 'sound/effects/bang.ogg', 50, 1)
return 0
user.visible_message("[user] shines light onto the tumor in [target]'s head!", "<span class='notice'>You cleanse the contamination from [target]'s brain!</span>")
ticker.mode.remove_thrall(target.mind, 0)
target.visible_message("<span class='warning'>A strange black mass falls from [target]'s head!</span>")
new /obj/item/organ/shadowtumor(get_turf(target))
return 1

View File

@@ -433,33 +433,3 @@
if(inflamed)
S.reagents.add_reagent("????", 5)
return S
/obj/item/organ/shadowtumor
name = "black tumor"
desc = "A tiny black mass with red tendrils trailing from it. It seems to shrivel in the light."
icon_state = "blacktumor"
origin_tech = "biotech=5"
w_class = 1
zone = "head"
slot = "brain_tumor"
var/health = 3
/obj/item/organ/shadowtumor/New()
..()
START_PROCESSING(SSobj, src)
/obj/item/organ/shadowtumor/Destroy()
STOP_PROCESSING(SSobj, src)
..()
/obj/item/organ/shadowtumor/process()
if(isturf(loc))
var/turf/T = loc
var/light_count = T.get_lumcount()
if(light_count > LIGHT_DAM_THRESHOLD && health > 0) //Die in the light
health--
else if(light_count < LIGHT_HEAL_THRESHOLD && health < 3) //Heal in the dark
health++
if(health <= 0)
visible_message("<span class='warning'>[src] collapses in on itself!</span>")
qdel(src)

Binary file not shown.

Before

Width:  |  Height:  |  Size: 82 KiB

After

Width:  |  Height:  |  Size: 69 KiB

View File

@@ -384,11 +384,6 @@
#include "code\game\gamemodes\sandbox\airlock_maker.dm"
#include "code\game\gamemodes\sandbox\h_sandbox.dm"
#include "code\game\gamemodes\sandbox\sandbox.dm"
#include "code\game\gamemodes\shadowling\ascendant_shadowling.dm"
#include "code\game\gamemodes\shadowling\shadowling.dm"
#include "code\game\gamemodes\shadowling\shadowling_abilities.dm"
#include "code\game\gamemodes\shadowling\shadowling_items.dm"
#include "code\game\gamemodes\shadowling\special_shadowling_abilities.dm"
#include "code\game\gamemodes\traitor\double_agents.dm"
#include "code\game\gamemodes\traitor\traitor.dm"
#include "code\game\gamemodes\wizard\artefact.dm"
@@ -1752,7 +1747,6 @@
#include "code\modules\surgery\cavity_implant.dm"
#include "code\modules\surgery\core_removal.dm"
#include "code\modules\surgery\dental_implant.dm"
#include "code\modules\surgery\dethralling.dm"
#include "code\modules\surgery\eye_surgery.dm"
#include "code\modules\surgery\gender_reassignment.dm"
#include "code\modules\surgery\generic_steps.dm"