diff --git a/code/__DEFINES/hud.dm b/code/__DEFINES/hud.dm index 0126fde5384..d2c854462a8 100644 --- a/code/__DEFINES/hud.dm +++ b/code/__DEFINES/hud.dm @@ -24,4 +24,5 @@ #define ANTAG_HUD_OPS 7 #define ANTAG_HUD_GANG_A 8 #define ANTAG_HUD_GANG_B 9 -#define ANTAG_HUD_WIZ 10 \ No newline at end of file +#define ANTAG_HUD_WIZ 10 +#define ANTAG_HUD_SHADOW 11 diff --git a/code/datums/hud.dm b/code/datums/hud.dm index f3315d1cfd6..e1fa433e26f 100644 --- a/code/datums/hud.dm +++ b/code/datums/hud.dm @@ -12,6 +12,7 @@ var/datum/atom_hud/huds = list( \ ANTAG_HUD_GANG_A = new/datum/atom_hud/antag(), \ ANTAG_HUD_GANG_B = new/datum/atom_hud/antag(), \ ANTAG_HUD_WIZ = new/datum/atom_hud/antag(), \ + ANTAG_HUD_SHADOW = new/datum/atom_hud/antag(), \ ) /datum/atom_hud diff --git a/code/datums/mind.dm b/code/datums/mind.dm index e178c01e30a..e2ff2b5bfc7 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -1058,6 +1058,7 @@ else if(href_list["shadowling"]) switch(href_list["shadowling"]) if("clear") + ticker.mode.update_shadow_icons_removed(src) src.spell_list = null if(src in ticker.mode.shadows) ticker.mode.shadows -= src @@ -1083,9 +1084,8 @@ 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 - src.spell_list += new /obj/effect/proc_holder/spell/targeted/enthrall - current.verbs += /mob/living/carbon/human/proc/shadowling_hatch + ticker.mode.finalize_shadowling(src) + ticker.mode.update_shadow_icons_added(src) if("thrall") if(!ishuman(current)) usr << "This only works on humans!" @@ -1097,7 +1097,6 @@ 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 diff --git a/code/game/gamemodes/shadowling/shadowling.dm b/code/game/gamemodes/shadowling/shadowling.dm index c14ad379d68..372ee45ff10 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -1,3 +1,7 @@ +#define LIGHT_DAM_THRESHOLD 4 +#define LIGHT_HEAL_THRESHOLD 2 +#define LIGHT_DAMAGE_TAKEN 10 + /* SHADOWLING: A gamemode based on previously-run events @@ -72,7 +76,7 @@ Made by Xhuis /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." + 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) @@ -114,6 +118,7 @@ Made by Xhuis /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 << "Any other shadowlings are you allies. You must assist them as they shall assist you." shadow.current << "If you are new to shadowling, or want to read about abilities, check the wiki page at https://tgstation13.org/wiki/Shadowling
" @@ -131,17 +136,25 @@ Made by Xhuis 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) + spawn(0) + shadow_mind.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_hivemind + update_shadow_icons_added(shadow_mind) + 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)) + update_shadow_icons_added(new_thrall_mind) thralls += new_thrall_mind new_thrall_mind.current.attack_log += "\[[time_stamp()]\] Became a thrall" + new_thrall_mind.memory += "The Shadowlings' Objectives: 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." + new_thrall_mind.current << "The objectives of your shadowlings:: 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." + new_thrall_mind.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_hivemind return 1 @@ -175,11 +188,11 @@ Made by Xhuis /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!" + 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!" + 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!" + world << "The crew has escaped the station before the shadowlings could ascend!" ..() return 1 @@ -187,15 +200,14 @@ Made by Xhuis /datum/game_mode/proc/auto_declare_completion_shadowling() var/text = "" if(shadows.len) - text += "
The shadowlings were:" + text += "
The shadowlings were:" for(var/datum/mind/shadow in shadows) text += printplayer(shadow) + text += "
" if(thralls.len) - text += "
The thralls were:" + 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 @@ -224,12 +236,24 @@ Made by Xhuis 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) + if(light_amount > LIGHT_DAM_THRESHOLD) //Not complete blackness - they can live in very small light levels plus starlight + H.take_overall_damage(0, LIGHT_DAMAGE_TAKEN) 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) + else if (light_amount < LIGHT_HEAL_THRESHOLD) + H.heal_overall_damage(5,5) + H.adjustToxLoss(-5) + H.adjustBrainLoss(-25) //gibbering shadowlings are hilarious but also bad to have + H.adjustCloneLoss(-1) H.SetWeakened(0) H.SetStunned(0) + +/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) //This should never actually occur, but it's here anyway. + 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) diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index baf3d70c4b2..844f52bbe5b 100644 --- a/code/game/gamemodes/shadowling/shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/shadowling_abilities.dm @@ -21,7 +21,7 @@ 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..." + target << "Your gaze is forcibly drawn into [usr]'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) @@ -53,9 +53,26 @@ 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)) + for(var/obj/item/device/pda/P in T.contents) P.fon = 0 - P.SetLuminosity(0) //failsafe + P.SetLuminosity(0) + for(var/obj/effect/glowshroom/G in orange(2, usr)) //Very small radius + G.visible_message("\The [G] withers away!") + qdel(G) + for(var/mob/living/carbon/human/H in T.contents) + for(var/obj/item/device/flashlight/F in H) + 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/item/device/pda/P in H) + P.fon = 0 + P.SetLuminosity(0) //failsafe + if(H != usr) + H << "You feel a chill and are plunged into darkness." + H.luminosity = 0 //This is required with the object-based lighting @@ -164,11 +181,23 @@ 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) + sleep(20) + if(isloyal(target)) + usr << "They are enslaved by Nanotrasen. You begin to shut down the nanobot implant - this will take some time." + usr.visible_message("[usr] halts for a moment, then begins passing its hand over [target]'s body.") + target << "You feel your loyalties begin to weaken!" + sleep(150) //15 seconds - not spawn() so the enthralling takes longer + usr << "The nanobots composing the loyalty implant have been rendered inert. Now to continue." + usr.visible_message("[usr] halts thier hand and resumes staring into [target]'s face.") + for(var/obj/item/weapon/implant/loyalty/L in target) + if(L && L.implanted) + qdel(L) + target << "Your unwavering loyalty to Nanotrasen falters, dims, dies." 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 + if(!do_mob(usr, target, 100)) //around 30 seconds total for enthralling, 45 for someone with a loyalty implant 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 @@ -183,8 +212,6 @@ target.adjustOxyLoss(-200) //In case the shadowling was choking them out ticker.mode.add_thrall(target.mind) target.mind.special_role = "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 @@ -208,6 +235,30 @@ +/obj/effect/proc_holder/spell/targeted/shadowling_regenarmor + name = "Regenerate Chitin" + desc = "Re-forms protective chitin that may be lost during cloning or similar processes." + panel = "Shadowling Abilities" + charge_max = 600 + clothes_req = 0 + range = -1 + include_user = 1 + +/obj/effect/proc_holder/spell/targeted/shadowling_regenarmor/cast(list/targets) + for(var/mob/living/user in targets) + user.visible_message("[user]'s skin suddenly bubbles and begins to shift around their body!", \ + "You regenerate your protective armor and cleanse your form of defects.") + user.equip_to_slot_or_del(new /obj/item/clothing/under/shadowling(usr), slot_w_uniform) + user.equip_to_slot_or_del(new /obj/item/clothing/shoes/shadowling(usr), slot_shoes) + user.equip_to_slot_or_del(new /obj/item/clothing/suit/space/shadowling(usr), slot_wear_suit) + user.equip_to_slot_or_del(new /obj/item/clothing/head/shadowling(usr), slot_head) + user.equip_to_slot_or_del(new /obj/item/clothing/gloves/shadowling(usr), slot_gloves) + user.equip_to_slot_or_del(new /obj/item/clothing/mask/gas/shadowling(usr), slot_wear_mask) + user.equip_to_slot_or_del(new /obj/item/clothing/glasses/night/shadowling(usr), slot_glasses) + hardset_dna(user, null, null, null, null, /datum/species/shadow/ling) //can't be a shadowling without being a shadowling + + + /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." @@ -254,7 +305,7 @@ 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) + if(thralls >= 9 && !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." @@ -351,7 +402,6 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob) if(iscarbon(target)) var/mob/living/carbon/M = target M << "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)) @@ -364,7 +414,7 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob) sp.start() S.Weaken(6) for(var/obj/structure/window/W in T.contents) - W.hit(rand(25,50)) + W.hit(rand(50,100)) @@ -448,7 +498,7 @@ datum/reagent/shadowling_blindness_smoke/on_mob_life(var/mob/living/M as mob) charge_counter = charge_max return - for(var/mob/boom in targets) + for(var/mob/living/carbon/human/boom in targets) if(is_shadow_or_thrall(boom)) usr << "Making an ally explode seems unwise." charge_counter = charge_max diff --git a/code/game/gamemodes/shadowling/shadowling_items.dm b/code/game/gamemodes/shadowling/shadowling_items.dm index 683d0a4bb81..01e0f5ae928 100644 --- a/code/game/gamemodes/shadowling/shadowling_items.dm +++ b/code/game/gamemodes/shadowling/shadowling_items.dm @@ -46,7 +46,7 @@ /obj/item/clothing/gloves/shadowling name = "chitin hands" - desc = "An electricity-resistant yet thin covering of the hands." + desc = "An electricity-resistant covering of the hands." icon_state = "golem" item_state = null origin_tech = null @@ -75,10 +75,11 @@ vision_flags = SEE_MOBS darkness_view = 3 invis_view = 2 - flash_protect = 2 + flash_protect = -1 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." diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 472bee1cd61..b1ff12edd22 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -85,6 +85,7 @@ 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 + usr.mind.spell_list += new /obj/effect/proc_holder/spell/targeted/shadowling_regenarmor @@ -158,4 +159,5 @@ sleep(50) if(!ticker.mode.shadowling_ascended) SSshuttle.emergency.request(null, 0.3) + ticker.mode.shadowling_ascended = 1 qdel(usr) diff --git a/code/game/objects/items/weapons/implants/implant.dm b/code/game/objects/items/weapons/implants/implant.dm index a8b7ae88590..c644c33ab0d 100644 --- a/code/game/objects/items/weapons/implants/implant.dm +++ b/code/game/objects/items/weapons/implants/implant.dm @@ -173,7 +173,7 @@ /obj/item/weapon/implant/loyalty/implanted(mob/target) ..() - if((target.mind in ticker.mode.head_revolutionaries) || (target.mind in ticker.mode.A_bosses) || (target.mind in ticker.mode.B_bosses)) + if((target.mind in ticker.mode.head_revolutionaries) || (target.mind in ticker.mode.A_bosses) || (target.mind in ticker.mode.B_bosses) || is_shadow_or_thrall(target)) target.visible_message("[target] seems to resist the implant!", "You feel the corporate tendrils of Nanotrasen try to invade your mind!") return 0 if((target.mind in ticker.mode.revolutionaries) || (target.mind in ticker.mode.A_gangsters) || (target.mind in ticker.mode.B_gangsters)) diff --git a/code/modules/reagents/Chemistry-Goon-Medicine.dm b/code/modules/reagents/Chemistry-Goon-Medicine.dm index 864b48fd34a..2659fed7197 100644 --- a/code/modules/reagents/Chemistry-Goon-Medicine.dm +++ b/code/modules/reagents/Chemistry-Goon-Medicine.dm @@ -684,7 +684,8 @@ proc/chemical_mob_spawn(var/datum/reagents/holder, var/amount_to_spawn, var/reac /mob/living/simple_animal/hostile/carp/holocarp, /mob/living/simple_animal/hostile/mining_drone, /mob/living/simple_animal/hostile/poison, - /mob/living/simple_animal/hostile/blob + /mob/living/simple_animal/hostile/blob, + /mob/living/simple_animal/ascendant_shadowling )//exclusion list for things you don't want the reaction to create. var/list/critters = typesof(/mob/living/simple_animal/hostile) - blocked // list of possible hostile mobs var/atom/A = holder.my_atom diff --git a/html/changelogs/Xhuis-ShadowlingUpdateI.yml b/html/changelogs/Xhuis-ShadowlingUpdateI.yml new file mode 100644 index 00000000000..a22e7a4e426 --- /dev/null +++ b/html/changelogs/Xhuis-ShadowlingUpdateI.yml @@ -0,0 +1,6 @@ +author: AnturK + +delete-after: True + +changes: + - rscadd: "Many changes have been made to shadowling. The full change list can be found at https://github.com/tgstation/-tg-station/pull/8927" \ No newline at end of file diff --git a/icons/mob/hud.dmi b/icons/mob/hud.dmi index a9746f5b5c3..84ed7d9fc07 100644 Binary files a/icons/mob/hud.dmi and b/icons/mob/hud.dmi differ diff --git a/interface/stylesheet.dm b/interface/stylesheet.dm index ff36313485c..411af48189e 100644 --- a/interface/stylesheet.dm +++ b/interface/stylesheet.dm @@ -77,6 +77,10 @@ h1.alert, h2.alert {color: #000000;} .sans {font-family: "Comic Sans MS", cursive, sans-serif;} .robot {font-family: "Courier New", cursive, sans-serif;} +.big {font-size: 3;} +.greentext {color: #00FF00; font-size: 3;} +.redtext {color: #FF0000; font-size: 3;} + BIG IMG.icon {width: 32px; height: 32px;} "}