diff --git a/code/__HELPERS/global_lists.dm b/code/__HELPERS/global_lists.dm index 32bd4f9a823..34082be122e 100644 --- a/code/__HELPERS/global_lists.dm +++ b/code/__HELPERS/global_lists.dm @@ -62,7 +62,8 @@ var/global/list/blocked_mobs = list(/mob/living/simple_animal/hostile, /mob/living/simple_animal/hostile/carp/holocarp, /mob/living/simple_animal/hostile/mining_drone, /mob/living/simple_animal/hostile/spaceWorm, - /mob/living/simple_animal/hostile/spaceWorm/wormHead + /mob/living/simple_animal/hostile/spaceWorm/wormHead, + /mob/living/simple_animal/ascendant_shadowling ) //Preferences stuff diff --git a/code/datums/mind.dm b/code/datums/mind.dm index 07741d08633..40032ae5fef 100644 --- a/code/datums/mind.dm +++ b/code/datums/mind.dm @@ -965,6 +965,7 @@ datum/mind else if(href_list["shadowling"]) switch(href_list["shadowling"]) if("clear") + ticker.mode.update_shadow_icons_removed(src) current.spell_list = null if(src in ticker.mode.shadows) ticker.mode.shadows -= src @@ -990,9 +991,8 @@ datum/mind 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." - current.spell_list += new /obj/effect/proc_holder/spell/wizard/targeted/shadowling_hivemind - current.spell_list += new /obj/effect/proc_holder/spell/wizard/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!" @@ -1004,7 +1004,6 @@ datum/mind 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].") - current.spell_list += new /obj/effect/proc_holder/spell/wizard/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 308e893cda6..3def17f9c6e 100644 --- a/code/game/gamemodes/shadowling/shadowling.dm +++ b/code/game/gamemodes/shadowling/shadowling.dm @@ -71,7 +71,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) @@ -115,6 +115,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
" @@ -132,17 +133,25 @@ Made by Xhuis var/mob/living/carbon/human/S = shadow_mind.current shadow_mind.current.verbs += /mob/living/carbon/human/proc/shadowling_hatch S.spell_list += new /obj/effect/proc_holder/spell/wizard/targeted/enthrall - S.spell_list += new /obj/effect/proc_holder/spell/wizard/targeted/shadowling_hivemind - if(shadow_mind.assigned_role == "Clown") - S << "Your alien nature has allowed you to overcome your clownishness." - S.mutations.Remove(CLUMSY) + spawn(0) + shadow_mind.current.spell_list += new /obj/effect/proc_holder/spell/wizard/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.mutations.Remove(CLUMSY) /datum/game_mode/proc/add_thrall(datum/mind/new_thrall_mind) if (!istype(new_thrall_mind)) return 0 if(!(new_thrall_mind in shadowling_thralls)) shadowling_thralls += new_thrall_mind + update_shadow_icons_added(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.current.spell_list += new /obj/effect/proc_holder/spell/wizard/targeted/shadowling_hivemind return 1 @@ -176,11 +185,11 @@ Made by Xhuis /datum/game_mode/shadowling/declare_completion() if(check_shadow_victory() && emergency_shuttle.returned()) //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() && emergency_shuttle.returned()) - 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 @@ -188,7 +197,7 @@ 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 += "
[shadow.key] was [shadow.name] (" if(shadow.current) @@ -201,8 +210,9 @@ Made by Xhuis else text += "body destroyed" text += ")" + text += "
" if(shadowling_thralls.len) - text += "
The thralls were:" + text += "
The thralls were:" for(var/datum/mind/thrall in shadowling_thralls) text += "
[thrall.key] was [thrall.name] (" if(thrall.current) @@ -214,8 +224,6 @@ Made by Xhuis text += " as [thrall.current.real_name]" else text += "body destroyed" - else - world << "Round-end code broke! Please report this and its circumstances on GitHub at https://github.com/ParadiseSS13/Paradise/issues" text += "
" world << text @@ -233,8 +241,51 @@ Made by Xhuis deform = 'icons/mob/human_races/r_shadowling.dmi' light_effect_amp = 1 - blood_color = "#AAAAAA" - flesh_color = "#777777" + blood_color = "#555555" + flesh_color = "#222222" flags = NO_BLOOD | NO_BREATHE | NO_SCAN | NO_INTORGANS burn_mod = 2 //2x burn damage + +/datum/game_mode/proc/update_shadow_icons_added(datum/mind/shadow_mind) + spawn(0) + for(var/datum/mind/shadowling in shadows) + if(shadowling.current) + if(shadowling.current.client) + var/I = image('icons/mob/mob.dmi', loc = shadowling.current, icon_state = "shadowling") + shadowling.current.client.images += I + if(shadow_mind.current) + if(shadow_mind.current.client) + var/image/J = image('icons/mob/mob.dmi', loc = shadowling.current, icon_state = "shadowling") + shadow_mind.current.client.images += J + for(var/datum/mind/thrall in shadowling_thralls) + if(thrall.current) + if(thrall.current.client) + var/I = image('icons/mob/mob.dmi', loc = thrall.current, icon_state = "thrall") + thrall.current.client.images += I + if(shadow_mind.current) + if(shadow_mind.current.client) + var/image/J = image('icons/mob/mob.dmi', loc = thrall.current, icon_state = "thrall") + shadow_mind.current.client.images += J + +/datum/game_mode/proc/update_shadow_icons_removed(datum/mind/shadow_mind) + spawn(0) + for(var/datum/mind/shadowling in shadows) + if(shadowling.current) + if(shadowling.current.client) + for(var/image/I in shadowling.current.client.images) + if((I.icon_state == "thrall" || I.icon_state == "shadowling") && I.loc == shadow_mind.current) + del(I) + + for(var/datum/mind/thrall in thralls) + if(thrall.current) + if(thrall.current.client) + for(var/image/I in thrall.current.client.images) + if((I.icon_state == "thrall" || I.icon_state == "shadowling") && I.loc == shadow_mind.current) + del(I) + + if(shadow_mind.current) + if(shadow_mind.current.client) + for(var/image/I in shadow_mind.current.client.images) + if(I.icon_state == "thrall" || I.icon_state == "shadowling") + del(I) diff --git a/code/game/gamemodes/shadowling/shadowling_abilities.dm b/code/game/gamemodes/shadowling/shadowling_abilities.dm index 5e9d364ec60..f7bfdc5e738 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 might not be required, but it just acts as another failsafe. @@ -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" - target.spell_list += new /obj/effect/proc_holder/spell/wizard/targeted/shadowling_hivemind //Lets thralls hive-chat - /obj/effect/proc_holder/spell/wizard/targeted/shadowling_hivemind @@ -253,7 +280,7 @@ user << "The power of your thralls has granted you the Sonic Screech ability. This ability will shatter nearby windows and deafen enemies." user.spell_list += new /obj/effect/proc_holder/spell/wizard/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." @@ -363,7 +390,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)) @@ -447,7 +474,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 8b3bc073991..fcb84062c5e 100644 --- a/code/game/gamemodes/shadowling/shadowling_items.dm +++ b/code/game/gamemodes/shadowling/shadowling_items.dm @@ -4,6 +4,7 @@ item_state = "golem" origin_tech = null icon_state = "golem" + _color = "golem" flags = ABSTRACT | NODROP has_sensor = 0 unacidable = 1 @@ -46,7 +47,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 diff --git a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm index 0444d1ea422..dba7f327eb6 100644 --- a/code/game/gamemodes/shadowling/special_shadowling_abilities.dm +++ b/code/game/gamemodes/shadowling/special_shadowling_abilities.dm @@ -160,4 +160,5 @@ if(emergency_shuttle && emergency_shuttle.can_call()) emergency_shuttle.call_evac() emergency_shuttle.launch_time = 0 // Cannot recall + ticker.mode.shadowling_ascended = 1 qdel(usr) diff --git a/code/modules/mob/living/carbon/human/life.dm b/code/modules/mob/living/carbon/human/life.dm index f7087f64690..d21ab41af2c 100644 --- a/code/modules/mob/living/carbon/human/life.dm +++ b/code/modules/mob/living/carbon/human/life.dm @@ -767,7 +767,7 @@ var/global/list/brutefireloss_overlays = list("1" = image("icon" = 'icons/mob/sc else light_amount = 10 if(light_amount > species.light_dam) //if there's enough light, start dying if(species.light_effect_amp) - adjustFireLoss(10) + adjustFireLoss(5) //This gets doubled by Shadowling's innate fire weakness, so it ends up being 10. else adjustFireLoss(1) adjustBruteLoss(1) diff --git a/code/modules/mob/living/login.dm b/code/modules/mob/living/login.dm index b349e3b15f7..35d7f3293ed 100644 --- a/code/modules/mob/living/login.dm +++ b/code/modules/mob/living/login.dm @@ -27,4 +27,7 @@ if("vampire") if((ref in ticker.mode.thralls) || (mind in ticker.mode.enthralled)) ticker.mode.update_vampire_icons_added(mind) + if("shadowling") + if((src.mind in ticker.mode.shadowling_thralls) || (src.mind in ticker.mode.shadows)) + ticker.mode.update_shadow_icons_added(src.mind) return . diff --git a/code/stylesheet.dm b/code/stylesheet.dm index 88a1a397929..281b4c7abe4 100644 --- a/code/stylesheet.dm +++ b/code/stylesheet.dm @@ -92,6 +92,11 @@ h1.alert, h2.alert {color: #000000;} .say_quote {font-family: Georgia, Verdana, sans-serif;} .interface {color: #330033;} + +.big {font-size: 3;} +.greentext {color: #00FF00; font-size: 3;} +.redtext {color: #FF0000; font-size: 3;} + BIG IMG.icon {width: 32px; height: 32px;} diff --git a/icons/mob/mob.dmi b/icons/mob/mob.dmi index 2617ee6d723..2a003edd4f0 100644 Binary files a/icons/mob/mob.dmi and b/icons/mob/mob.dmi differ