From 3208404f14a7526887199af041912da5929c9543 Mon Sep 17 00:00:00 2001 From: oranges Date: Sun, 31 Dec 2017 11:58:41 +1300 Subject: [PATCH 1/2] Merge pull request #33580 from Xhuis/defenses_balancing Some modest clockcult balancing - vitality matrices, brass skewers, pressure sensors --- code/__DEFINES/status_effects.dm | 2 ++ code/datums/status_effects/debuffs.dm | 24 +++++++++++++++ code/datums/status_effects/status_effect.dm | 1 + .../clock_cult/clock_effects/clock_sigils.dm | 27 ++++++++++------ .../clock_scriptures/scripture_scripts.dm | 6 ++++ .../trap_triggers/pressure_sensor.dm | 2 +- .../clock_structures/traps/brass_skewer.dm | 29 ++++++++++++------ .../mob/living/carbon/human/examine.dm | 16 ++++++++++ .../mob/living/silicon/robot/examine.dm | 1 + icons/mob/screen_alert.dmi | Bin 75852 -> 77077 bytes 10 files changed, 87 insertions(+), 21 deletions(-) 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 ef680c266a9ce8e5ae33d7eccc7e83e972c3d7ce..e6d40977a7accd2dbc7ed07ab77a71fe991ef0e6 100644 GIT binary patch delta 5764 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