diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 4f36ddbb1e..2e1524ebac 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -64,6 +64,8 @@ #define STATUS_EFFECT_KINDLE /datum/status_effect/kindle //A knockdown reduced by 1 second for every 3 points of damage the target takes. +#define STATUS_EFFECT_ICHORIAL_STAIN /datum/status_effect/ichorial_stain //Prevents a servant from being revived by vitality matrices for one minute. + ///////////// // NEUTRAL // ///////////// diff --git a/code/datums/status_effects/debuffs.dm b/code/datums/status_effects/debuffs.dm index cc64cc2eb8..22868f855f 100644 --- a/code/datums/status_effects/debuffs.dm +++ b/code/datums/status_effects/debuffs.dm @@ -479,3 +479,27 @@ desc = "Blinding light dances in your vision, stunning and silencing you. Any damage taken will shorten the light's effects!" icon_state = "kindle" alerttooltipstyle = "clockcult" + + +//Ichorial Stain: Applied to servants revived by a vitality matrix. Prevents them from being revived by one again until the effect fades. +/datum/status_effect/ichorial_stain + id = "ichorial_stain" + status_type = STATUS_EFFECT_UNIQUE + duration = 600 + examine_text = "SUBJECTPRONOUN is drenched in thick, blue ichor!" + alert_type = /obj/screen/alert/status_effect/ichorial_stain + +/datum/status_effect/ichorial_stain/on_apply() + owner.visible_message("[owner] gets back up, [owner.p_their()] body dripping blue ichor!", \ + "Thick blue ichor covers your body; you can't be revived like this again until it dries!") + return TRUE + +/datum/status_effect/ichorial_stain/on_remove() + owner.visible_message("The blue ichor on [owner]'s body dries out!", \ + "The ichor on your body is dry - you can now be revived by vitality matrices again!") + +/obj/screen/alert/status_effect/ichorial_stain + name = "Ichorial Stain" + desc = "Your body is covered in blue ichor! You can't be revived by vitality matrices." + icon_state = "ichorial_stain" + alerttooltipstyle = "clockcult" diff --git a/code/datums/status_effects/status_effect.dm b/code/datums/status_effects/status_effect.dm index 19bd880a77..e24359d18c 100644 --- a/code/datums/status_effects/status_effect.dm +++ b/code/datums/status_effects/status_effect.dm @@ -9,6 +9,7 @@ var/mob/living/owner //The mob affected by the status effect. var/status_type = STATUS_EFFECT_UNIQUE //How many of the effect can be on one mob, and what happens when you try to add another var/on_remove_on_mob_delete = FALSE //if we call on_remove() when the mob is deleted + var/examine_text //If defined, this text will appear when the mob is examined - to use he, she etc. use "SUBJECTPRONOUN" and replace it in the examines themselves var/alert_type = /obj/screen/alert/status_effect //the alert thrown by the status effect, contains name and description var/obj/screen/alert/status_effect/linked_alert = null //the alert itself, if it exists diff --git a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm index 29655a0ac9..3237cf5d35 100644 --- a/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm +++ b/code/game/gamemodes/clock_cult/clock_effects/clock_sigils.dm @@ -278,7 +278,7 @@ animate(src, alpha = 255, time = 10, flags = ANIMATION_END_NOW) //we may have a previous animation going. finish it first, then do this one without delay. sleep(10) //as long as they're still on the sigil and are either not a servant or they're a servant AND it has remaining vitality - while(L && (!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && (GLOB.ratvar_awakens || GLOB.clockwork_vitality))) && get_turf(L) == get_turf(src)) + while(L && (!is_servant_of_ratvar(L) || (is_servant_of_ratvar(L) && (GLOB.ratvar_awakens || GLOB.clockwork_vitality))) && get_turf(L) == get_turf(src) && !L.buckled) sigil_active = TRUE if(animation_number >= 4) new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src)) @@ -313,21 +313,28 @@ revival_cost = 0 var/mob/dead/observer/ghost = L.get_ghost(TRUE) if(GLOB.clockwork_vitality >= revival_cost && (ghost || (L.mind && L.mind.active))) - if(ghost) - ghost.reenter_corpse() - L.revive(1, 1) - var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src)) - animate(V, alpha = 0, transform = matrix()*2, time = 8) - playsound(L, 'sound/magic/staff_healing.ogg', 50, 1) - L.visible_message("[L] suddenly gets back up, [L.p_their()] body dripping blue ichor!", "\"[text2ratvar("You will be okay, child.")]\"") - GLOB.clockwork_vitality -= revival_cost + if(L.has_status_effect(STATUS_EFFECT_ICHORIAL_STAIN)) + visible_message("[src] strains, but nothing happens...") + if(L.pulledby) + to_chat(L.pulledby, "[L] was already revived recently by a vitality matrix! Wait a bit longer!") + break + else + if(ghost) + ghost.reenter_corpse() + L.revive(1, 1) + var/obj/effect/temp_visual/ratvar/sigil/vitality/V = new /obj/effect/temp_visual/ratvar/sigil/vitality(get_turf(src)) + animate(V, alpha = 0, transform = matrix()*2, time = 8) + playsound(L, 'sound/magic/staff_healing.ogg', 50, 1) + to_chat(L, "\"[text2ratvar("You will be okay, child.")]\"") + L.apply_status_effect(STATUS_EFFECT_ICHORIAL_STAIN) + GLOB.clockwork_vitality -= revival_cost break if(!L.client || L.client.is_afk()) set waitfor = FALSE var/list/mob/dead/observer/candidates = pollCandidatesForMob("Do you want to play as a [L.name], an inactive clock cultist?", "[name]", null, "Clock Cultist", 50, L) var/mob/dead/observer/theghost = null if(candidates.len) - to_chat(L, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form!") + to_chat(L, "Your physical form has been taken over by another soul due to your inactivity! Ahelp if you wish to regain your form!") message_admins("[key_name_admin(theghost)] has taken control of ([key_name_admin(L)]) to replace an inactive clock cultist.") L.ghostize(0) L.key = theghost.key diff --git a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm index 09cfeb99d3..c4774fe0ad 100644 --- a/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm +++ b/code/game/gamemodes/clock_cult/clock_scriptures/scripture_scripts.dm @@ -70,6 +70,12 @@ quickbind = TRUE quickbind_desc = "Creates a Vitality Matrix, which drains non-Servants on it to heal Servants that cross it." +/datum/clockwork_scripture/create_object/vitality_matrix/check_special_requirements() + if(locate(object_path) in range(1, invoker)) + to_chat(invoker, "Vitality matrices placed next to each other could interfere and cause a feedback loop! Move away from the other ones!") + return FALSE + return ..() + //Judicial Visor: Creates a judicial visor, which can smite an area. /datum/clockwork_scripture/create_object/judicial_visor diff --git a/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm index f6a7b8e347..fffabe8f5c 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/trap_triggers/pressure_sensor.dm @@ -3,7 +3,7 @@ name = "pressure sensor" desc = "A thin plate of brass, barely visible but clearly distinct." clockwork_desc = "A trigger that will activate when a non-servant runs across it." - max_integrity = 25 + max_integrity = 5 icon_state = "pressure_sensor" alpha = 80 layer = LOW_ITEM_LAYER diff --git a/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm b/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm index d79ca88ecb..c91cf594e8 100644 --- a/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm +++ b/code/game/gamemodes/clock_cult/clock_structures/traps/brass_skewer.dm @@ -21,9 +21,10 @@ STOP_PROCESSING(SSfastprocess, src) if(buckled_mobs && buckled_mobs.len) var/mob/living/L = buckled_mobs[1] - L.Knockdown(100) - L.visible_message("[L] is maimed as the skewer shatters while still in their body!") - L.adjustBruteLoss(15) + if(iscarbon(L)) + L.Knockdown(100) + L.visible_message("[L] is maimed as the skewer shatters while still in their body!") + L.adjustBruteLoss(15) unbuckle_mob(L) return ..() @@ -48,14 +49,22 @@ /obj/structure/destructible/clockwork/trap/brass_skewer/activate() if(density) return - var/mob/living/carbon/squirrel = locate() in get_turf(src) + var/mob/living/squirrel = locate() in get_turf(src) if(squirrel) - squirrel.visible_message("A massive brass spike erupts from the ground, impaling [squirrel]!", \ - "A massive brass spike rams through your chest, hoisting you into the air!") - squirrel.emote("scream") - playsound(squirrel, 'sound/effects/splat.ogg', 50, TRUE) - playsound(squirrel, 'sound/misc/desceration-03.ogg', 50, TRUE) - squirrel.apply_damage(20, BRUTE, "chest") + if(iscyborg(squirrel)) + if(!squirrel.stat) + squirrel.visible_message("A massive brass spike erupts from the ground, rending [squirrel]'s chassis but shattering into pieces!", \ + "A massive brass spike rips through your chassis and bursts into shrapnel in your casing!") + squirrel.adjustBruteLoss(50) + squirrel.Stun(20) + addtimer(CALLBACK(src, .proc/take_damage, max_integrity), 1) + else + squirrel.visible_message("A massive brass spike erupts from the ground, impaling [squirrel]!", \ + "A massive brass spike rams through your chest, hoisting you into the air!") + squirrel.emote("scream") + playsound(squirrel, 'sound/effects/splat.ogg', 50, TRUE) + playsound(squirrel, 'sound/misc/desceration-03.ogg', 50, TRUE) + squirrel.apply_damage(20, BRUTE, "chest") mouse_opacity = MOUSE_OPACITY_OPAQUE //So players can interact with the tile it's on to pull them off buckle_mob(squirrel, TRUE) else diff --git a/code/modules/mob/living/carbon/human/examine.dm b/code/modules/mob/living/carbon/human/examine.dm index bc4fd83334..9999d8c330 100644 --- a/code/modules/mob/living/carbon/human/examine.dm +++ b/code/modules/mob/living/carbon/human/examine.dm @@ -121,6 +121,9 @@ if(wear_id) msg += "[t_He] [t_is] wearing [icon2html(wear_id, user)] \a [wear_id].\n" + //Status effects + msg += status_effect_examines() + //Jitters switch(jitteriness) if(300 to INFINITY) @@ -354,3 +357,16 @@ msg += "*---------*" to_chat(user, msg) + +/mob/living/proc/status_effect_examines(pronoun_replacement) //You can include this in any mob's examine() to show the examine texts of status effects! + var/list/dat = list() + if(!pronoun_replacement) + pronoun_replacement = p_they(TRUE) + for(var/V in status_effects) + var/datum/status_effect/E = V + if(E.examine_text) + var/new_text = replacetext(E.examine_text, "SUBJECTPRONOUN", pronoun_replacement) + new_text = replacetext(new_text, "[pronoun_replacement] is", "[pronoun_replacement] [p_are()]") //To make sure something become "They are" or "She is", not "They are" and "She are" + dat += "[new_text]\n" //dat.Join("\n") doesn't work here, for some reason + if(dat.len) + return dat.Join() diff --git a/code/modules/mob/living/silicon/robot/examine.dm b/code/modules/mob/living/silicon/robot/examine.dm index 788a8f4255..3f5b12ae20 100644 --- a/code/modules/mob/living/silicon/robot/examine.dm +++ b/code/modules/mob/living/silicon/robot/examine.dm @@ -6,6 +6,7 @@ var/obj/act_module = get_active_held_item() if(act_module) msg += "It is holding [icon2html(act_module, user)] \a [act_module].\n" + msg += status_effect_examines() msg += "" if (src.getBruteLoss()) if (src.getBruteLoss() < maxHealth*0.5) diff --git a/icons/mob/screen_alert.dmi b/icons/mob/screen_alert.dmi index ef680c266a..e6d40977a7 100644 Binary files a/icons/mob/screen_alert.dmi and b/icons/mob/screen_alert.dmi differ