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