From c9338f72126114446dfbff206b458b92a324fbe3 Mon Sep 17 00:00:00 2001 From: Xhuis Date: Wed, 8 Apr 2015 22:04:50 -0400 Subject: [PATCH 1/2] Shadowling: RELEASE EDITION --- code/__DEFINES/preferences.dm | 1 + code/datums/mind.dm | 62 ++ code/game/gamemodes/shadowling/shadowling.dm | 239 +++++++ .../shadowling/shadowling_abilities.dm | 615 ++++++++++++++++++ .../gamemodes/shadowling/shadowling_items.dm | 102 +++ .../special_shadowling_abilities.dm | 161 +++++ code/game/objects/effects/aliens.dm | 5 + code/modules/admin/player_panel.dm | 18 + code/modules/client/preferences.dm | 3 +- .../simple_animal/ascendant_shadowling.dm | 33 + config/game_options.txt | 1 + html/changelogs/Xhuis-Shadowling.yml | 7 + icons/mob/human.dmi | Bin 65666 -> 67119 bytes icons/mob/mob.dmi | Bin 193105 -> 195473 bytes interface/stylesheet.dm | 1 + tgstation.dme | 5 + 16 files changed, 1252 insertions(+), 1 deletion(-) create mode 100644 code/game/gamemodes/shadowling/shadowling.dm create mode 100644 code/game/gamemodes/shadowling/shadowling_abilities.dm create mode 100644 code/game/gamemodes/shadowling/shadowling_items.dm create mode 100644 code/game/gamemodes/shadowling/special_shadowling_abilities.dm create mode 100644 code/modules/mob/living/simple_animal/ascendant_shadowling.dm create mode 100644 html/changelogs/Xhuis-Shadowling.yml diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index bdfc636ee20..8f17fbaed20 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -40,3 +40,4 @@ #define BE_NINJA 1024 #define BE_MONKEY 2048 #define BE_GANG 4096 +#define BE_SHADOWLING 8192 diff --git a/code/datums/mind.dm b/code/datums/mind.dm index dbdcb3afadb..8d40b54fbe5 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -448,6 +448,25 @@ sections["traitor"] = text + /** SHADOWLING **/ + text = "shadowling" + if(ticker.mode.config_tag == "shadowling") + text = uppertext(text) + text = "[text]: " + if(src in ticker.mode.shadows) + text += "SHADOWLING|thrall|human" + else if(src in ticker.mode.thralls) + text += "shadowling|THRALL|human" + else + text += "shadowling|thrall|HUMAN" + + if(current && current.client && current.client.prefs.be_special & BE_SHADOWLING) + text += "|Enabled in Prefs" + else + text += "|Disabled in Prefs" + + sections["shadowling"] = text + /** MONKEY ***/ if (istype(current, /mob/living/carbon)) text = "monkey" @@ -1035,6 +1054,49 @@ ticker.mode.forge_traitor_objectives(src) usr << "The objectives for traitor [key] have been generated. You can edit them and anounce manually." + else if(href_list["shadowling"]) + switch(href_list["shadowling"]) + if("clear") + src.spell_list = null + if(src in ticker.mode.shadows) + ticker.mode.shadows -= src + special_role = null + current << "Your powers have been quenched! You are no longer a shadowling!" + src.spell_list = null + message_admins("[key_name_admin(usr)] has de-shadowling'ed [current].") + log_admin("[key_name(usr)] has de-shadowling'ed [current].") + current.verbs -= /mob/living/carbon/human/proc/shadowling_hatch + current.verbs -= /mob/living/carbon/human/proc/shadowling_ascendance + else if(src in ticker.mode.thralls) + ticker.mode.thralls -= src + special_role = null + current << "You have been brainwashed! You are no longer a thrall!" + 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 << "This only works on humans!" + return + ticker.mode.shadows += src + special_role = "shadowling" + current << "You notice a brightening around you. No, it isn't that. The shadows grow, darken, swirl. The darkness has a new welcome for you, and you realize with a \ + start that you can't be human. No, you are a shadowling, a harbringer of the shadows! Your alien abilities have been unlocked from within, and you may both commune with your allies and use \ + a chrysalis to reveal your true form. You are to ascend at all costs." + src.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_hivemind + current.verbs += /mob/living/carbon/human/proc/shadowling_hatch + if("thrall") + if(!ishuman(current)) + usr << "This only works on humans!" + return + ticker.mode.add_thrall(src) + special_role = "thrall" + current << "All at once it becomes clear to you. Where others see darkness, you see an ally. You realize that the shadows are not dead and dark as one would think, but \ + living, and breathing, and eating. Their children, the Shadowlings, are to be obeyed and protected at all costs." + current << "You may use the Hivemind Commune ability to communicate with your fellow enlightened ones." + message_admins("[key_name_admin(usr)] has thrall'ed [current].") + log_admin("[key_name(usr)] has thrall'ed [current].") + src.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_hivemind + else if (href_list["monkey"]) var/mob/living/L = current if (L.notransform) diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm new file mode 100644 index 00000000000..2cd6e7d9ef6 --- /dev/null +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -0,0 +1,239 @@ +/* + +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) + - Their thralls who are not harmed by the light + - Stealth + +Shadowling weaknesses: + - The light + - Fire + - Enemy numbers + - Lasers (Lasers are concentrated light and do more damage) + - Flashbangs (High stun and high burn damage; if the light stuns humans, you bet your ass it'll hurt the shadowling very much!) + +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 + + +/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 = BE_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 << "The current game mode is - Shadowling!" + world << "There are alien shadowlings on the station. Crew: Kill the shadowlings before they can eat or enthrall the crew. Shadowlings: Enthrall the crew while remaining in hiding." + +/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" + + for(var/datum/mind/player in antag_candidates) + for(var/job in restricted_jobs) + if(player.assigned_role == job) + antag_candidates -= player + + var/shadowlings = 2 //How many shadowlings there are; hardcoded to 2 + + while(shadowlings) + var/datum/mind/shadow = pick(antag_candidates) + shadows += shadow + antag_candidates -= shadow + modePlayer += shadow + shadow.special_role = "Shadowling" + 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 << "
" + shadow.current << "You are a shadowling!" + greet_shadow(shadow) + finalize_shadowling(shadow) + process_shadow_objectives(shadow) + //give_shadowling_abilities(shadow) + ..() + return + +/datum/game_mode/proc/greet_shadow(var/datum/mind/shadow) + shadow.current << "Currently, you are disguised as an employee aboard [world.name]." + shadow.current << "In your limited state, you have three abilities: Enthrall, Hatch, and Hivemind Commune." + shadow.current << "If you are new to shadowling, or want to read about abilities, check the wiki page at https://tgstation13.org/wiki/Shadowling
" + + +/datum/game_mode/proc/process_shadow_objectives(var/datum/mind/shadow_mind) + var/objective = "enthrall" //may be devour later, but for now it seems murderbone-y + + if(objective == "enthrall") + var/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 += "Objective #1: [objective_explanation]" + shadow_mind.current << "Objective #1: [objective_explanation]
" + + +/datum/game_mode/proc/finalize_shadowling(var/datum/mind/shadow_mind) + var/mob/living/carbon/human/S = shadow_mind.current + shadow_mind.current.verbs += /mob/living/carbon/human/proc/shadowling_hatch + shadow_mind.spell_list += new /obj/effect/proc_holder/spell/targeted/enthrall + shadow_mind.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_hivemind + if(shadow_mind.assigned_role == "Clown") + S << "Your alien nature has allowed you to overcome your clownishness." + 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)) + thralls += new_thrall_mind + new_thrall_mind.current.attack_log += "\[[time_stamp()]\] Became a thrall" + return 1 + + + +/* + GAME FINISH CHECKS +*/ + + +/datum/game_mode/shadowling/check_finished() + var/shadows_alive = 0 //and then shadowling was kill + for(var/datum/mind/shadow in shadows) //but what if shadowling was not kill? + if(!istype(shadow.current,/mob/living/carbon/human) && !istype(shadow.current,/mob/living/simple_animal/ascendant_shadowling)) + continue + if(shadow.current.stat == DEAD) + continue + shadows_alive++ + if(shadows_alive) + return ..() + else + shadowling_dead = 1 //but shadowling was kill :( + return 1 + + +/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() && SSshuttle.emergency.mode >= SHUTTLE_ESCAPE) //Doesn't end instantly - this is hacky and I don't know of a better way ~X + world << "The shadowlings have ascended and taken over the station!" + else if(shadowling_dead && !check_shadow_victory()) //If the shadowlings have ascended, they can not lose the round + world << "The shadowlings have been killed by the crew!" + else if(!check_shadow_victory() && SSshuttle.emergency.mode >= SHUTTLE_ESCAPE) + world << "The crew has escaped the station before the shadowlings could ascend!" + ..() + return 1 + + +/datum/game_mode/proc/auto_declare_completion_shadowling() + var/text = "" + if(shadows.len) + text += "
The shadowlings were:" + for(var/datum/mind/shadow in shadows) + text += printplayer(shadow) + if(thralls.len) + text += "
The thralls were:" + for(var/datum/mind/thrall in thralls) + text += printplayer(thrall) + else + world << "Round-end code broke! Please report this and its circumstances on GitHub at https://github.com/tgstation/-tg-station/issues" + text += "
" + 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) //Can't use guns due to muzzle flash + burnmod = 2 //2x burn damage lel + heatmod = 2 + +/datum/species/shadow/ling/spec_life(mob/living/carbon/human/H) + //H.shadowling_status = 1 //If they are affected more strongly by flashes and stuff + var/light_amount = 0 + H.nutrition = NUTRITION_LEVEL_WELL_FED //i aint never get hongry + if(isturf(H.loc)) //Copypasta + var/turf/T = H.loc + var/area/A = T.loc + if(A) + if(A.lighting_use_dynamic) light_amount = T.lighting_lumcount + else light_amount = 10 + if(light_amount > 2) //Rapid death while in the light, countered by... + H.take_overall_damage(0,6) + H << "The light burns you!" + H << 'sound/weapons/sear.ogg' + else if (light_amount < 2) //...extreme benefits while in the dark + H.heal_overall_damage(5,3) + H.adjustToxLoss(-3) + H.SetWeakened(0) + H.SetStunned(0) + +/datum/species/human/thrall + name = "Human?" //Can discern from a health analyzer; one of the few ways of finding thralls. Fluff-wise, it's close enough to human to give it that assumption, but altered in some ways + id = "thrall" diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm new file mode 100644 index 00000000000..79028097a94 --- /dev/null +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -0,0 +1,615 @@ +/obj/effect/proc_holder/spell/targeted/glare + name = "Glare" + desc = "Stuns and mutes a target for a decent duration." + panel = "Shadowling Abilities" + charge_max = 300 + clothes_req = 0 + +/obj/effect/proc_holder/spell/targeted/glare/cast(list/targets) + for(var/mob/living/carbon/human/target in targets) + if(!ishuman(target)) + charge_counter = charge_max + return + if(target.stat) + charge_counter = charge_max + return + if(is_shadow_or_thrall(target)) + usr << "You don't see why you would want to paralyze an ally." + charge_counter = charge_max + return + + usr.visible_message("[usr]'s eyes flash a blinding red!") + target.visible_message("[target] freezes in place, their eyes glazing over...") + if(in_range(target, usr)) + target << "Your gaze is forcibly drawn into [src]'s eyes, and you are mesmerized by the heavenly lights..." + else //Only alludes to the shadowling if the target is close by + target << "Red lights suddenly dance in your vision, and you are mesmerized by the heavenly lights..." + target.Stun(10) + if(target.reagents) + target.reagents.add_reagent("mutetoxin", 4) //This is really bad but it's the only way it works. + + + +/obj/effect/proc_holder/spell/aoe_turf/veil + name = "Veil" + desc = "Extinguishes all electronic lights in a decent radius." + panel = "Shadowling Abilities" + charge_max = 250 //Short cooldown because people can just turn the lights back on + clothes_req = 0 + range = 5 + +/obj/effect/proc_holder/spell/aoe_turf/veil/cast(list/targets) + usr << "You silently disable all nearby lights." + var/list/blacklisted_lights = list(/obj/item/device/flashlight/flare, /obj/item/device/flashlight/slime) + for(var/turf/T in targets) + for(var/obj/item/device/flashlight/F in T.contents) + if(is_type_in_list(F, blacklisted_lights)) + F.visible_message("[F] goes slightly dim for a moment.") + return + F.on = 0 + F.visible_message("[F] gutters and falls dark.") + F.update_brightness() + for(var/obj/machinery/light/L in T.contents) + L.on = 0 + L.visible_message("[L] flickers and falls dark.") + L.update(0) + for(var/obj/item/device/pda/P in orange(5, usr)) + P.fon = 0 + P.SetLuminosity(0) //failsafe + + + +/obj/effect/proc_holder/spell/targeted/shadow_walk + 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 + clothes_req = 0 + range = -1 + include_user = 1 + +/obj/effect/proc_holder/spell/targeted/shadow_walk/cast(list/targets) + for(var/mob/living/user in targets) + playsound(user.loc, 'sound/effects/bamf.ogg', 50, 1) + user.visible_message("[user] vanishes into thin air!", "You enter the space between worlds as a passageway.") + user.SetStunned(0) + user.SetWeakened(0) + user.incorporeal_move = 1 + user.alpha = 0 + if(user.buckled) + user.buckled.unbuckle_mob() + sleep(40) //4 seconds + user.visible_message("[user] appears out of nowhere!", "The pressure becomes too much and you vacate the interdimensional darkness.") + user.incorporeal_move = 0 + user.alpha = 255 + + + +/obj/effect/proc_holder/spell/aoe_turf/flashfreeze + name = "Flash Freeze" + desc = "Instantly freezes the blood of nearby people, stunning them and causing burn damage." + panel = "Shadowling Abilities" + range = 5 + charge_max = 1200 + clothes_req = 0 + +/obj/effect/proc_holder/spell/aoe_turf/flashfreeze/cast(list/targets) + usr << "You freeze the nearby air." + playsound(usr.loc, 'sound/effects/ghost2.ogg', 50, 1) + + for(var/turf/T in targets) + for(var/mob/living/carbon/human/target in T.contents) + if(is_shadow_or_thrall(target)) + if(target == usr) //No message for the user, of course + continue + else + target << "You feel a blast of paralyzingly cold air wrap around you and flow past, but you are unaffected!" + continue + target << "You are hit by a blast of paralyzingly cold air and feel goosebumps break out across your body!" + target.Stun(2) + if(target.bodytemperature) + target.bodytemperature -= 200 //Extreme amount of initial cold + if(target.reagents) + target.reagents.add_reagent("frostoil", 15) //Half of a cryosting + + + +//Enthrall is the single most important spell +/obj/effect/proc_holder/spell/targeted/enthrall + 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 = 450 + clothes_req = 0 + range = 1 //Adjacent to user + var/enthralling = 0 + +/obj/effect/proc_holder/spell/targeted/enthrall/cast(list/targets) + for(var/mob/living/carbon/human/target in targets) + if(!in_range(usr, target)) + usr << "You need to be closer to enthrall [target]." + charge_counter = charge_max + return + if(!target.ckey) + usr << "The target has no mind." + charge_counter = charge_max + return + if(target.stat) + usr << "The target must be conscious." + charge_counter = charge_max + return + if(is_shadow_or_thrall(target)) + usr << "You can not enthrall allies." + charge_counter = charge_max + return + if(!ishuman(target)) + usr << "You can only enthrall humans." + charge_counter = charge_max + return + if(enthralling) + usr << "You are already enthralling!" + charge_counter = charge_max + return + enthralling = 1 + usr << "This target is valid. You begin the enthralling." + target << "[usr] focuses in concentration. Your head begins to ache." + + for(var/progress = 0, progress <= 3, progress++) + switch(progress) + if(1) + usr << "You begin allocating energy for the enthralling." + usr.visible_message("[usr]'s eyes begin to throb a piercing red.") + if(2) + usr << "You begin the enthralling of [target]." + usr.visible_message("[usr] leans over [target], their eyes glowing a deep crimson, and stares into their face.") + target << "Your gaze is forcibly drawn into a blinding red light. You fall to the floor as conscious thought is wiped away." + target.Weaken(12) + if(3) + usr << "You begin rearranging [target]'s memories." + usr.visible_message("[usr]'s eyes flare brightly, and a horrible grin begins to spread across [target]'s face...") + target << "Your head cries out. The veil of reality begins to crumple and something evil bleeds through." //Ow the edge + if(!do_mob(usr, target, 100)) //around 30 seconds total for enthralling + usr << "The enthralling has been interrupted - your target's mind returns to its previous state." + target << "Your thoughts become coherent once more. Already you can barely remember what's happened to you." + enthralling = 0 + return + + enthralling = 0 + usr << "You have enthralled [target]!" + target << "You see the Truth. Reality has been torn away and you realize what a fool you've been." + target << "The shadowlings are your masters. Serve them above all else and ensure they complete their goals." + target << "You may not harm other thralls or the shadowlings. However, you do not need to obey other thralls." + target << "You can communicate with the other enlightened ones by using the Hivemind Commune ability." + target.adjustOxyLoss(-200) //In case the shadowling was choking them out + ticker.mode.add_thrall(target.mind) + target.mind.special_role = "Thrall" + hardset_dna(target, null, null, null, null, /datum/species/human/thrall) + var/datum/mind/thrall_mind = target.mind + thrall_mind.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_hivemind //Lets thralls hive-chat + + + +/obj/effect/proc_holder/spell/targeted/shadowling_hivemind + name = "Hivemind Commune" + desc = "Allows you to silently communicate with all other shadowlings and thralls." + panel = "Shadowling Abilities" + charge_max = 25 + clothes_req = 0 + range = -1 + include_user = 1 + +/obj/effect/proc_holder/spell/targeted/shadowling_hivemind/cast(list/targets) + for(var/mob/living/user in targets) + var/text = stripped_input(user, "What do you want to say to fellow thralls and shadowlings?.", "Hive Chat", "") + if(!text) + return + for(var/mob/M in mob_list) + if(is_shadow_or_thrall(M) || (M in dead_mob_list)) + M << "\[Hive Chat\] [usr.real_name]: [text]" + + + +/obj/effect/proc_holder/spell/targeted/collective_mind + 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 + clothes_req = 0 + range = -1 + include_user = 1 + var/blind_smoke_acquired + var/screech_acquired + var/drain_thrall_acquired + var/thrall_swap_acquired + +/obj/effect/proc_holder/spell/targeted/collective_mind/cast(list/targets) + for(var/mob/living/user in targets) + var/thralls = 0 + var/victory_threshold = 15 + var/mob/M + + user << "You focus your telepathic energies abound, harnessing and drawing together the strength of your thralls." + + for(M in living_mob_list) + if(is_thrall(M)) + thralls++ + M << "You feel hooks sink into your mind and pull." + + if(!do_after(user, 30)) + user << "Your concentration has been broken. The mental hooks you have sent out now retract into your mind." + return + + if(thralls >= 3 && !blind_smoke_acquired) + blind_smoke_acquired = 1 + user << "The power of your thralls has granted you the Blinding Smoke ability. It will create a choking cloud that will blind any non-thralls who enter. \ + " + user.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/blindness_smoke + + if(thralls >= 5 && !drain_thrall_acquired) + drain_thrall_acquired = 1 + user << "The power of your thralls has granted you the Drain Thrall ability. You can now drain nearby thralls to heal yourself." + user.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/drain_thralls + + if(thralls >= 7 && !screech_acquired) + screech_acquired = 1 + user << "The power of your thralls has granted you the Sonic Screech ability. This ability will shatter nearby windows and deafen enemies." + user.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/unearthly_screech + + if(thralls >= 10 && !thrall_swap_acquired) + thrall_swap_acquired = 1 + user << "The power of your thralls has granted you the Spatial Relocation ability. This will, allow you to instantly swap places with one of your thralls in \ + addition to shattering nearby lights." + user.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/spatial_relocation + + if(thralls < victory_threshold) + user << "You do not have the power to ascend. You require [victory_threshold] thralls, but only [thralls] living thralls are present." + + else if(thralls >= victory_threshold) + usr << "You are now powerful enough to ascend. Use the Ascendance ability when you are ready. This will kill all of your thralls." + usr << "You may find Ascendance in the Shadowling Evolution tab." + for(M in living_mob_list) + if(is_shadow(M)) + M.mind.spell_list -= /obj/effect/proc_holder/spell/targeted/collective_mind + M.mind.current.verbs -= /mob/living/carbon/human/proc/shadowling_hatch //In case a shadowling hasn't hatched + M.mind.current.verbs += /mob/living/carbon/human/proc/shadowling_ascendance + if(M == usr) + return + M << "[user.real_name] has coalesced the strength of the thralls. You can draw upon it at any time to ascend." //Tells all the other shadowlings + + + +/obj/effect/proc_holder/spell/targeted/blindness_smoke + name = "Blindness Smoke" + desc = "Spews a cloud of smoke which will blind enemies." + panel = "Shadowling Abilities" + charge_max = 600 + clothes_req = 0 + range = -1 + include_user = 1 + +/obj/effect/proc_holder/spell/targeted/blindness_smoke/cast(list/targets) //Extremely hacky + for(var/mob/living/user in targets) + user.visible_message("[user] suddenly bends over and coughs out a cloud of black smoke, which begins to spread rapidly!") + user << "You regurgitate a vast cloud of blinding smoke." + playsound(user, 'sound/effects/bamf.ogg', 50, 1) + var/obj/item/weapon/reagent_containers/glass/beaker/large/B = new /obj/item/weapon/reagent_containers/glass/beaker/large(user.loc) + B.reagents.clear_reagents() //Just in case! + B.icon_state = null //Invisible + B.reagents.add_reagent("blindness_smoke", 10) + var/datum/effect/effect/system/chem_smoke_spread/S = new /datum/effect/effect/system/chem_smoke_spread + S.attach(B) + if(S) + S.set_up(B.reagents, 10, 0, B.loc) + S.start() + sleep(10) + S.start() + qdel(B) + +datum/reagent/shadowling_blindness_smoke //Blinds non-shadowlings, heals shadowlings/thralls + name = "!(%@ ERROR )!@$" + 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(var/mob/living/M as mob) + if(!M) M = holder.my_atom + if(!is_shadow_or_thrall(M)) + M << "You breathe in the black smoke, and your eyes burn horribly!" + M.eye_blind = 5 + if(prob(25)) + M.visible_message("[M] screams and claws at their eyes!") + M.Stun(2) + else + M << "You breathe in the black smoke, and you feel revitalized!" + M.heal_organ_damage(2,2) + M.adjustOxyLoss(-2) + M.adjustToxLoss(-2) + ..() + return + + + +/obj/effect/proc_holder/spell/aoe_turf/unearthly_screech + name = "Sonic Screech" + desc = "Deafens, stuns, and confuses nearby people. Also shatters windows." + panel = "Shadowling Abilities" + range = 7 + charge_max = 300 + clothes_req = 0 + +/obj/effect/proc_holder/spell/aoe_turf/unearthly_screech/cast(list/targets) + usr.audible_message("[usr] lets out a horrible scream!") + playsound(usr.loc, 'sound/effects/screech.ogg', 100, 1) + + for(var/turf/T in targets) + for(var/mob/target in T.contents) + if(is_shadow_or_thrall(target)) + if(target == usr) //No message for the user, of course + continue + else + continue + if(iscarbon(target)) + var/mob/living/carbon/M = target + M << "A spike of pain drives into your head and scrambles your thoughts!" + M.Weaken(2) + M.confused += 10 + M.setEarDamage(M.ear_damage + 3) + else if(issilicon(target)) + var/mob/living/silicon/S = target + S << "ERROR $!(@ ERROR )#^! SENSOR INTERFERENCE DETECTED" + S << 'sound/misc/interference.ogg' + playsound(S, 'sound/machines/warning-buzzer.ogg', 50, 1) + var/datum/effect/effect/system/spark_spread/sp = new /datum/effect/effect/system/spark_spread + sp.set_up(5, 1, S) + sp.start() + S.Weaken(6) + for(var/obj/structure/window/W in T.contents) + W.hit(rand(25,50)) + + + +/obj/effect/proc_holder/spell/aoe_turf/drain_thralls + name = "Drain Thralls" + desc = "Damages nearby thralls, draining their life and healing yourself." + panel = "Shadowling Abilities" + range = 3 + charge_max = 100 + clothes_req = 0 + var/thralls_drained = 0 + var/list/nearby_thralls = list() + +/obj/effect/proc_holder/spell/aoe_turf/drain_thralls/cast(list/targets) + thralls_drained = 0 + nearby_thralls = list() + for(var/turf/T in targets) + for(var/mob/living/carbon/M in T.contents) + if(is_thrall(M)) + thralls_drained++ + nearby_thralls.Add(M) + M << "You feel a curious draining sensation and a wave of exhaustion washes over you." + for(var/mob/living/carbon/M in nearby_thralls) + nearby_thralls.Remove(M) //To prevent someone dying like a zillion times + M.take_organ_damage(25/thralls_drained,25/thralls_drained) //For every nearby thrall, the damage to each is reduced - 1 thrall = 50 for him, 2 thralls = 25 for each, etc. + usr << "You draw the life from [M] to heal your wounds." + if(thralls_drained) + var/mob/living/carbon/U = usr + U.heal_organ_damage(25, 25) + else + charge_counter = charge_max + usr << "There were no nearby thralls for you to drain." + + + +/obj/effect/proc_holder/spell/targeted/spatial_relocation + name = "Spatial Relocation" + desc = "Swaps places with a thrall and breaks nearby lights." + panel = "Shadowling Abilities" + range = -1 + charge_max = 3000 + clothes_req = 0 + include_user = 1 + var/list/thralls_in_world = list() + +/obj/effect/proc_holder/spell/targeted/spatial_relocation/cast(list/targets, distanceoverride) + for(var/mob/living/carbon/human/M in world) + if(is_thrall(M)) + thralls_in_world += M + if(!thralls_in_world) + charge_counter = charge_max + return + var/mob/living/carbon/thrall_to_swap = input("Who do you wish to swap places with?", "Available Thralls") as null|anything in (thralls_in_world) + var/turf/shadowturf = get_turf(usr) + var/turf/thrallturf = get_turf(thrall_to_swap) + thrall_to_swap.visible_message("[thrall_to_swap] suddenly vanishes in a puff of black smoke!") + thrall_to_swap << "You feel a brief sense of nausea before finding yourself in an entirely new place!" + usr.visible_message("[usr] suddenly goes transparent and vanishes!") + usr << "You experience vertigo as you swap your location with [thrall_to_swap]'s." + thrall_to_swap.loc = shadowturf + usr.loc = thrallturf + thrall_to_swap.Weaken(4) + usr.Weaken(4) + usr.regenerate_icons() + thrall_to_swap.regenerate_icons() + +// ASCENDANT ABILITIES BEYOND THIS POINT // + +/obj/effect/proc_holder/spell/targeted/annihilate + name = "Annihilate" + desc = "Gibs a human after a short time." + panel = "Ascendant" + range = 7 + charge_max = 300 + clothes_req = 0 + +/obj/effect/proc_holder/spell/targeted/annihilate/cast(list/targets) + var/mob/living/simple_animal/ascendant_shadowling/SHA = usr + if(SHA.phasing) + usr << "You are not in the same plane of existence. Unphase first." + charge_counter = charge_max + return + + for(var/mob/boom in targets) + if(is_shadow_or_thrall(boom)) + usr << "Making an ally explode seems unwise." + charge_counter = charge_max + return + usr.visible_message("[usr]'s eyes flare as they gesture at [boom]!", \ + "You direct a lance of telekinetic energy at [boom].") + boom << "You feel an immense pressure building all across your body!" + boom.Stun(10) + boom.audible_message("[boom] screams!") + sleep(20) + playsound(boom, 'sound/effects/splat.ogg', 100, 1) + boom.visible_message("[boom] explodes!") + boom.gib() + + + +/obj/effect/proc_holder/spell/targeted/hypnosis + name = "Hypnosis" + desc = "Instantly enthralls a human." + panel = "Ascendant" + range = 7 + charge_max = 450 + clothes_req = 0 + +/obj/effect/proc_holder/spell/targeted/hypnosis/cast(list/targets) + var/mob/living/simple_animal/ascendant_shadowling/SHA = usr + if(SHA.phasing) + charge_counter = charge_max + usr << "You are not in the same plane of existence. Unphase first." + return + + for(var/mob/living/carbon/human/target in targets) + if(is_shadow_or_thrall(target)) + usr << "You cannot enthrall an ally." + charge_counter = charge_max + return + if(!target.ckey) + usr << "The target has no mind." + charge_counter = charge_max + return + if(target.stat) + usr << "The target must be conscious." + charge_counter = charge_max + return + if(!ishuman(target)) + usr << "You can only enthrall humans." + charge_counter = charge_max + return + + usr << "You instantly rearrange [target]'s memories, hyptonitizing them into a thrall." + target << "An agonizing spike of pain drives into your mind, and--" + target << "And you see the Truth. Reality has been torn away and you realize what a fool you've been." + target << "The shadowlings are your masters. Serve them above all else and ensure they complete their goals." + target << "You may not harm other thralls or the shadowlings. However, you do not need to obey other thralls." + target << "You can communicate with the other enlightened ones by using the Hivemind Commune ability." + ticker.mode.add_thrall(target.mind) + target.mind.special_role = "Thrall" + hardset_dna(target, null, null, null, null, /datum/species/human/thrall) + var/datum/mind/thrall_mind = target.mind + thrall_mind.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_hivemind + + + +/obj/effect/proc_holder/spell/targeted/shadowling_phase_shift + name = "Phase Shift" + desc = "Phases you into the space between worlds at will, allowing you to move through walls and become invisible." + panel = "Ascendant" + range = -1 + include_user = 1 + charge_max = 15 + clothes_req = 0 + +/obj/effect/proc_holder/spell/targeted/shadowling_phase_shift/cast(list/targets) + var/mob/living/simple_animal/ascendant_shadowling/SHA = usr + for(SHA in targets) + SHA.phasing = !SHA.phasing + if(SHA.phasing) + SHA.visible_message("[SHA] suddenly vanishes!", \ + "You begin phasing through planes of existence. Use the ability again to return.") + SHA.incorporeal_move = 1 + SHA.alpha = 0 + else + SHA.visible_message("[SHA] suddenly appears from nowhere!", \ + "You return from the space between worlds.") + SHA.incorporeal_move = 0 + SHA.alpha = 255 + + + +/obj/effect/proc_holder/spell/aoe_turf/glacial_blast + name = "Glacial Blast" + desc = "Extremely empowered version of Flash Freeze." + panel = "Ascendant" + range = 5 + charge_max = 600 + clothes_req = 0 + +/obj/effect/proc_holder/spell/aoe_turf/glacial_blast/cast(list/targets) + var/mob/living/simple_animal/ascendant_shadowling/SHA = usr + if(SHA.phasing) + usr << "You are not in the same plane of existence. Unphase first." + return + + usr << "You freeze the nearby air." + playsound(usr.loc, 'sound/effects/ghost2.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)) + if(target == usr) //No message for the user, of course + continue + else + target << "You feel a blast of paralyzingly cold air wrap around you and flow past, but you are unaffected!" + continue + target << "You are hit by a blast of cold unlike anything you have ever felt. Your limbs instantly lock in place and you feel ice burns across your body!" + target.Weaken(15) + if(target.bodytemperature) + target.bodytemperature -= INFINITY //:^) + target.take_organ_damage(0,80) + + + +/obj/effect/proc_holder/spell/targeted/vortex + name = "Vortex" + desc = "Tears open a hole in reality. Anyone, INCLUDING YOU, walking through it will be trapped there for eternity." + panel = "Ascendant" + range = -1 + include_user = 1 + charge_max = 1200 + clothes_req = 0 + +/obj/effect/proc_holder/spell/targeted/vortex/cast(list/targets) + var/mob/living/simple_animal/ascendant_shadowling/SHA = usr + if(SHA.phasing) + usr << "You are not in the same plane of existence. Unphase first." + return + + for(SHA in targets) + SHA.visible_message("[SHA] raises their arms upward as the markings on their body flare a blinding red!", \ + "You tear open a rift to the black space between worlds. It would be wise to avoid it.") + + new /obj/structure/shadow_vortex(SHA.loc) + + + +/obj/effect/proc_holder/spell/targeted/shadowling_hivemind_ascendant + name = "Ascendant Commune" + desc = "Allows you to silently communicate with all other shadowlings and thralls." + panel = "Ascendant" + charge_max = 20 + clothes_req = 0 + range = -1 + include_user = 1 + +/obj/effect/proc_holder/spell/targeted/shadowling_hivemind_ascendant/cast(list/targets) + for(var/mob/living/user in targets) + var/text = stripped_input(user, "What do you want to say to fellow thralls and shadowlings?.", "Hive Chat", "") + if(!text) + return + text = "[text]" + for(var/mob/M in mob_list) + if(is_shadow_or_thrall(M) || (M in dead_mob_list)) + M << "\[Hive Chat\] [usr.real_name] (ASCENDANT): [text]" //Bigger text for ascendants. diff --git a/code/game/gamemodes/shadowling/shadowling_items.dm b/code/game/gamemodes/shadowling/shadowling_items.dm new file mode 100644 index 00000000000..683d0a4bb81 --- /dev/null +++ b/code/game/gamemodes/shadowling/shadowling_items.dm @@ -0,0 +1,102 @@ +/obj/item/clothing/under/shadowling + name = "blackened flesh" + desc = "Black, chitonous skin." + item_state = "golem" + origin_tech = null + icon_state = "golem" + flags = ABSTRACT | NODROP + has_sensor = 0 + unacidable = 1 + + +/obj/item/clothing/suit/space/shadowling + name = "chitin shell" + desc = "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 = "golem" + item_state = "golem" + 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 + flags = ABSTRACT | NODROP | THICKMATERIAL + 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 + + +/obj/item/clothing/shoes/shadowling + name = "chitin feet" + desc = "Charred-looking feet. They have minature hooks that latch onto flooring." + icon_state = "golem" + 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 = "golem" + item_state = "golem" + origin_tech = null + siemens_coefficient = 0 + unacidable = 1 + flags = ABSTRACT | NODROP + + +/obj/item/clothing/gloves/shadowling + name = "chitin hands" + desc = "An electricity-resistant yet thin covering of the hands." + icon_state = "golem" + 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 = "golem" + item_state = null + origin_tech = null + unacidable = 1 + flags = ABSTRACT | NODROP + + +/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 = null + icon_state = null + item_state = null + origin_tech = null + vision_flags = SEE_MOBS + darkness_view = 3 + invis_view = 2 + flash_protect = 2 + unacidable = 1 + flags = ABSTRACT | NODROP + +/obj/structure/shadow_vortex + name = "vortex" + desc = "A swirling hole in the fabric of reality. Eye-watering chimes sound from its depths." + density = 0 + anchored = 1 + icon = 'icons/effects/genetics.dmi' + icon_state = "shadow_portal" + +/obj/structure/shadow_vortex/New() + src.audible_message("\The [src] lets out a dismaying screech as dimensional barriers are torn apart!") + playsound(loc, 'sound/effects/supermatter.ogg', 100, 1) + sleep(100) + qdel(src) + +/obj/structure/shadow_vortex/Crossed(var/td) + ..() + if(ismob(td)) + td << "You enter the rift. Sickening chimes begin to jangle in your ears. \ + All around you is endless blackness. After you see something moving, you realize it isn't entirely lifeless." //A bit of spooking before they die + playsound(loc, 'sound/effects/EMPulse.ogg', 25, 1) + qdel(td) diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm new file mode 100644 index 00000000000..472bee1cd61 --- /dev/null +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -0,0 +1,161 @@ +//In here: Hatch and Ascendance + +/mob/living/carbon/human/proc/shadowling_hatch() + set category = "Shadowling Evolution" + set name = "Hatch" + + if(usr.stat) + return + usr.verbs -= /mob/living/carbon/human/proc/shadowling_hatch + switch(alert("Are you sure you want to hatch? You cannot undo this!",,"Yes","No")) + if("No") + usr << "You decide against hatching for now." + usr.verbs += /mob/living/carbon/human/proc/shadowling_hatch + return + if("Yes") + usr.notransform = 1 + usr.visible_message("[usr]'s things suddenly slip off. They hunch over and vomit up a copious amount of purple goo which begins to shape around them!", \ + "You remove any equipment which would hinder your hatching and begin regurgitating the resin which will protect you.") + + for(var/obj/item/I in usr) //drops all items + usr.unEquip(I) + + sleep(50) + var/turf/simulated/floor/F + var/turf/shadowturf = get_turf(usr) + for(F in orange(1, usr)) + 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 with the chrysalis + + usr.visible_message("A chrysalis forms around [usr], sealing them inside.", \ + "You create your chrysalis and begin to contort within.") + + sleep(100) + usr.visible_message("The skin on [usr]'s back begins to split apart. Black spines slowly emerge from the divide.", \ + "Spines pierce your back. Your claws break apart your fingers. You feel excruciating pain as your true form begins its exit.") + + sleep(90) + usr.visible_message("[usr], now no longer recognizable as human, begins clawing at the resin walls around them.", \ + "Your false skin slips away. You begin tearing at the fragile membrane protecting you.") + + sleep(80) + playsound(usr.loc, 'sound/weapons/slash.ogg', 25, 1) + usr << "You rip and slice." + sleep(10) + playsound(usr.loc, 'sound/weapons/slashmiss.ogg', 25, 1) + usr << "The chrysalis falls like water before you." + sleep(10) + playsound(usr.loc, 'sound/weapons/slice.ogg', 25, 1) + usr << "You are free!" + + sleep(10) + playsound(usr.loc, 'sound/effects/ghost.ogg', 100, 1) + usr.real_name = "Shadowling ([rand(1,1000)])" + usr.name = usr.real_name + usr.notransform = 0 + usr << "YOU LIVE!!!" + + for(var/obj/structure/alien/resin/wall/shadowling/W in orange(usr, 1)) + playsound(W, 'sound/effects/splat.ogg', 50, 1) + qdel(W) + for(var/obj/structure/alien/weeds/node/N in shadowturf) + qdel(N) + usr.visible_message("The chrysalis explodes in a shower of purple flesh and fluid!") + var/mob/living/carbon/human/M = usr + M.underwear = "Nude" + M.undershirt = "Nude" + M.socks = "Nude" + M.faction |= "faithless" + + usr.equip_to_slot_or_del(new /obj/item/clothing/under/shadowling(usr), slot_w_uniform) + usr.equip_to_slot_or_del(new /obj/item/clothing/shoes/shadowling(usr), slot_shoes) + usr.equip_to_slot_or_del(new /obj/item/clothing/suit/space/shadowling(usr), slot_wear_suit) + usr.equip_to_slot_or_del(new /obj/item/clothing/head/shadowling(usr), slot_head) + usr.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(usr), slot_gloves) + usr.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(usr), slot_wear_mask) + usr.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/shadowling(usr), slot_glasses) + hardset_dna(usr, null, null, null, null, /datum/species/shadow/ling) //can't be a shadowling without being a shadowling + + sleep(10) + usr << "Your powers are awoken. You may now live to your fullest extent. Remember your goal. Cooperate with your thralls and allies." + usr.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/glare + usr.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/veil + usr.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/shadow_walk + usr.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/flashfreeze + usr.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/collective_mind + + + +/mob/living/carbon/human/proc/shadowling_ascendance() + set category = "Shadowling Evolution" + set name = "Ascendance" + + if(usr.stat) + return + usr.verbs -= /mob/living/carbon/human/proc/shadowling_ascendance + switch(alert("It is time to ascend. Are you completely sure about this? You cannot undo this!",,"Yes","No")) + if("No") + usr << "You decide against ascending for now." + usr.verbs += /mob/living/carbon/human/proc/shadowling_ascendance + return + if("Yes") + usr.notransform = 1 + usr.visible_message("[usr] rapidly bends and contorts, their eyes flaring a deep crimson!", \ + "You begin unlocking the genetic vault within you and prepare yourself for the power to come.") + + sleep(30) + usr.visible_message("[usr] suddenly shoots up a few inches in the air and begins hovering there, still twisting.", \ + "You hover into the air to make room for your new form.") + + sleep(60) + usr.visible_message("[usr]'s skin begins to pulse red in sync with their eyes. Their form slowly expands outward.", \ + "You feel yourself beginning to mutate.") + + sleep(20) + if(!ticker.mode.shadowling_ascended) + usr << "It isn't enough. Time to draw upon your thralls." + else + usr << "After some telepathic searching, you find the reservoir of life energy from the thralls and tap into it." + + sleep(50) + for(var/mob/M in mob_list) + if(is_thrall(M) && !ticker.mode.shadowling_ascended) + M.visible_message("[M] trembles minutely as their form turns to ash, black smoke pouring from their disintegrating face.", \ + "It's time! Your masters are ascending! Your last thoughts are happy as your body is drained of life.") + + ticker.mode.thralls -= M.mind //To prevent message spam + M.death(0) + M.dust() + + usr << "Drawing upon your thralls, you find the strength needed to finish and rend apart the final barriers to godhood." + + sleep(40) + for(var/mob/living/M in orange(7, src)) + M.Weaken(10) + M << "An immense pressure slams you onto the ground!" + usr << "YOU LIVE!!!" + world << "

A horrible wail echoes in your mind as the world plunges into blackness.


" + world << 'sound/hallucinations/veryfar_noise.ogg' + for(var/obj/machinery/power/apc/A in world) + A.overload_lighting() + var/mob/A = new /mob/living/simple_animal/ascendant_shadowling(usr.loc) + usr.mind.spell_list = list() + usr.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/annihilate + usr.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/hypnosis + usr.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_phase_shift + usr.mind.spell_list += new /obj/effect/proc_holder/spell/aoe_turf/glacial_blast + usr.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/vortex + usr.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_hivemind_ascendant + usr.mind.transfer_to(A) + A.name = usr.real_name + if(A.real_name) + A.real_name = usr.real_name + usr.alpha = 0 //This is pretty bad, but is also necessary for the shuttle call to function properly + usr.flags |= GODMODE + usr.notransform = 1 + sleep(50) + if(!ticker.mode.shadowling_ascended) + SSshuttle.emergency.request(null, 0.3) + qdel(usr) diff --git a/code/game/objects/effects/aliens.dm b/code/game/objects/effects/aliens.dm index 1bafea2ff6d..6d62cbeebfb 100644 --- a/code/game/objects/effects/aliens.dm +++ b/code/game/objects/effects/aliens.dm @@ -56,6 +56,11 @@ /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." diff --git a/code/modules/admin/player_panel.dm b/code/modules/admin/player_panel.dm index 4b50cfa3af0..b09935e5b72 100644 --- a/code/modules/admin/player_panel.dm +++ b/code/modules/admin/player_panel.dm @@ -450,6 +450,24 @@ dat += "Traitor not found!" dat += "" + if(ticker.mode.shadows.len) + dat += "
" + for(var/datum/mind/N in ticker.mode.shadows) + var/mob/M = N.current + if(M) + dat += "" + dat += "" + dat += "
Shadowlings
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
" + + if(ticker.mode.thralls.len) + dat += "
" + for(var/datum/mind/N in ticker.mode.thralls) + var/mob/M = N.current + if(M) + dat += "" + dat += "" + dat += "
Shadowling Thralls
[M.real_name][M.client ? "" : " (logged out)"][M.stat == 2 ? " (DEAD)" : ""]PM
" + if(istype(ticker.mode, /datum/game_mode/blob)) var/datum/game_mode/blob/mode = ticker.mode dat += "
" diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm index 8c058c98459..03a2ab0c536 100644 --- a/code/modules/client/preferences.dm +++ b/code/modules/client/preferences.dm @@ -16,7 +16,8 @@ var/global/list/special_roles = list( //keep synced with the defines BE_* in set "blob" = /datum/game_mode/blob, //9 "ninja", //10 "monkey" = /datum/game_mode/monkey, //11 - "gangster" = /datum/game_mode/gang //12 + "gangster" = /datum/game_mode/gang, //12 + "shadowling" = /datum/game_mode/shadowling //13 ) diff --git a/code/modules/mob/living/simple_animal/ascendant_shadowling.dm b/code/modules/mob/living/simple_animal/ascendant_shadowling.dm new file mode 100644 index 00000000000..9445db7592c --- /dev/null +++ b/code/modules/mob/living/simple_animal/ascendant_shadowling.dm @@ -0,0 +1,33 @@ +/mob/living/simple_animal/ascendant_shadowling + name = "Ascendant Shadowling" + desc = "A large, floating eldritch horror. It has pulsing markings all about its body and large horns. It seems to be floating without any form of support." + icon = 'icons/mob/mob.dmi' + icon_state = "shadowling_ascended" + icon_living = "shadowling_ascended" + speak_emote = list("telepathically thunders", "telepathically booms") + force_threshold = INFINITY //Can't die by normal means + health = 100000 + maxHealth = 100000 + speed = 0 + var/phasing = 0 + see_in_dark = 8 + see_invisible = SEE_INVISIBLE_MINIMUM + + response_help = "stares at" + response_disarm = "flails at" + response_harm = "flails at" + + harm_intent_damage = 0 + melee_damage_lower = 35 + melee_damage_upper = 35 + attacktext = "claws at" + attack_sound = 'sound/weapons/slash.ogg' + + minbodytemp = 0 + maxbodytemp = INFINITY + environment_smash = 2 + + faction = list("faithless") + +/mob/living/simple_animal/ascendant_shadowling/Process_Spacemove(var/movement_dir = 0) + return 1 //copypasta from carp code diff --git a/config/game_options.txt b/config/game_options.txt index 683ec17b46b..3ddd7f7c990 100644 --- a/config/game_options.txt +++ b/config/game_options.txt @@ -82,6 +82,7 @@ PROBABILITY TRAITORCHAN 4 PROBABILITY DOUBLE_AGENTS 3 PROBABILITY NUCLEAR 2 PROBABILITY REVOLUTION 2 +PROBABILITY SHADOWLING 2 PROBABILITY GANG 0 PROBABILITY CULT 2 PROBABILITY CHANGELING 2 diff --git a/html/changelogs/Xhuis-Shadowling.yml b/html/changelogs/Xhuis-Shadowling.yml new file mode 100644 index 00000000000..14b5506994d --- /dev/null +++ b/html/changelogs/Xhuis-Shadowling.yml @@ -0,0 +1,7 @@ +author: Xhuis +delete-after: true + + +changes: + - rscadd: "There have been... odd sighting in Space Station 13's sector. Alien organisms have appeared on stations 57, 23, and outlying." + - rscadd: "Nanotrasen personnel have reason to believe that Space Station 13 is under attack by shadowlings. We have little intel on these creatures, but be on the lookout for odd behavior and dark areas. Use plenty of lights." diff --git a/icons/mob/human.dmi b/icons/mob/human.dmi index 39b58a18272fa8b1623894b9490e924ad786f7c6..c56f9815abd11ddf7ca5bac0410eecbce43ddf19 100644 GIT binary patch delta 22266 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 J6^1U+{{xdXX-)tD delta 20780 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 delta 3382 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 RQ#9yY+UoibD(+hc{~zS6d{zJe diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index 824d72b31a1..ff36313485c 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -63,6 +63,7 @@ h1.alert, h2.alert {color: #000000;} .unconscious {color: #0000ff; font-weight: bold;} .suicide {color: #ff5050; font-style: italic;} .green {color: #03ff39;} +.shadowling {color: #311648;} .newscaster {color: #800000;} .ghostalert {color: #5c00e6; font-style: italic; font-weight: bold;} diff --git a/tgstation.dme b/tgstation.dme index 831a5e3d646..e9411463f12 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -337,6 +337,10 @@ #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\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" @@ -1169,6 +1173,7 @@ #include "code\modules\mob\living\silicon\robot\robot_modules.dm" #include "code\modules\mob\living\silicon\robot\robot_movement.dm" #include "code\modules\mob\living\silicon\robot\say.dm" +#include "code\modules\mob\living\simple_animal\ascendant_shadowling.dm" #include "code\modules\mob\living\simple_animal\constructs.dm" #include "code\modules\mob\living\simple_animal\corpse.dm" #include "code\modules\mob\living\simple_animal\parrot.dm" From 6375286704a248f42986858439147662d5aa002d Mon Sep 17 00:00:00 2001 From: Xhuis Date: Sat, 11 Apr 2015 14:57:14 -0400 Subject: [PATCH 2/2] Fixes admin shadowlings not getting Enthrall --- code/datums/mind.dm | 1 + 1 file changed, 1 insertion(+) diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 8d40b54fbe5..b7b6317a083 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1083,6 +1083,7 @@ start that you can't be human. No, you are a shadowling, a harbringer of the shadows! Your alien abilities have been unlocked from within, and you may both commune with your allies and use \ a chrysalis to reveal your true form. You are to ascend at all costs." src.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_hivemind + src.spell_list += new /obj/effect/proc_holder/spell/targeted/enthrall current.verbs += /mob/living/carbon/human/proc/shadowling_hatch if("thrall") if(!ishuman(current))
Blob