From 419ce0126ac12ebd8342bca6ee1a87a7deed9c96 Mon Sep 17 00:00:00 2001 From: silicons <2003111+silicons@users.noreply.github.com> Date: Sun, 21 May 2023 14:12:23 -0700 Subject: [PATCH] reworks staggering effects (#5504) Co-authored-by: silicons --- citadel.dme | 2 +- code/__DEFINES/traits/sources.dm | 12 +++++++ code/datums/status_effects/basic/staggered.dm | 18 ---------- code/datums/status_effects/grouped.dm | 18 +++++++--- .../status_effects/grouped/staggered.dm | 22 ++++++++++++ code/game/objects/items/devices/flash.dm | 6 +++- code/modules/mob/living/carbon/human/human.dm | 9 ++--- code/modules/mob/status_procs.dm | 34 ++++++++++++++----- 8 files changed, 83 insertions(+), 38 deletions(-) delete mode 100644 code/datums/status_effects/basic/staggered.dm create mode 100644 code/datums/status_effects/grouped/staggered.dm diff --git a/citadel.dme b/citadel.dme index 36b9235d7ab..5a2de597d7c 100644 --- a/citadel.dme +++ b/citadel.dme @@ -788,8 +788,8 @@ #include "code\datums\status_effects\status_effect.dm" #include "code\datums\status_effects\basic\crusher_track.dm" #include "code\datums\status_effects\basic\incapacitation.dm" -#include "code\datums\status_effects\basic\staggered.dm" #include "code\datums\status_effects\grouped\crusher_mark.dm" +#include "code\datums\status_effects\grouped\staggered.dm" #include "code\datums\underwear\bottom.dm" #include "code\datums\underwear\socks.dm" #include "code\datums\underwear\top.dm" diff --git a/code/__DEFINES/traits/sources.dm b/code/__DEFINES/traits/sources.dm index bea0a1088cf..0ef131e9550 100644 --- a/code/__DEFINES/traits/sources.dm +++ b/code/__DEFINES/traits/sources.dm @@ -5,6 +5,18 @@ /// Trait is from ourselves (src) #define INNATE_TRAIT "innate" +//? Automata / AoE effect sources + +/// From an EMP blast +#define EMP_TRAIT "emp" +/// Secondary / tiered effects from EMP blast +#define EMP_TRAIT_N(n) "emp_[n]" + +//? Item Sources + +/// From a flashbulb +#define FLASH_TRAIT "flash" + //? Mob Sources /// From species diff --git a/code/datums/status_effects/basic/staggered.dm b/code/datums/status_effects/basic/staggered.dm deleted file mode 100644 index a82b8a7fe01..00000000000 --- a/code/datums/status_effects/basic/staggered.dm +++ /dev/null @@ -1,18 +0,0 @@ -#define MAX_STAGGER_STACKS 30 -#define STACKS_TO_SLOWDOWN(amt) (amt * (1 / 3.5)) - -/datum/status_effect/stacking/staggered - identifier = "staggered" - duration = 1 SECONDS - max_stacks = MAX_STAGGER_STACKS - - -/datum/status_effect/stacking/staggered/on_stacks(old_stacks, new_stacks, decayed) - . = ..() - if(!new_stacks) - owner.remove_movespeed_modifier(/datum/movespeed_modifier/mob_staggered) - else - owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/mob_staggered, multiplicative_slowdown = STACKS_TO_SLOWDOWN(new_stacks)) - -#undef STACKS_TO_SLOWDOWN -#undef MAX_STAGGER_STACKS diff --git a/code/datums/status_effects/grouped.dm b/code/datums/status_effects/grouped.dm index b35ec7583af..6b6ea375c5e 100644 --- a/code/datums/status_effects/grouped.dm +++ b/code/datums/status_effects/grouped.dm @@ -53,9 +53,10 @@ if((old_expires - world.time) < duration) // refresh deltimer(timers[source]) - expires[source] = world.time + duration - timers[source] = addtimer(CALLBACK(src, PROC_REF(remove_source), source, TRUE), duration, TIMER_STOPPABLE) - else if(old && (duration > 0)) + if(duration) + expires[source] = world.time + duration + timers[source] = addtimer(CALLBACK(src, PROC_REF(remove_source), source, TRUE), duration, TIMER_STOPPABLE) + else if(!old && (duration > 0)) // didn't exist, set expires[source] = world.time + duration timers[source] = addtimer(CALLBACK(src, PROC_REF(remove_source), source, TRUE), duration, TIMER_STOPPABLE) @@ -64,7 +65,12 @@ /datum/status_effect/grouped/proc/set_source(source, value, duration = src.duration) // source can technically be any non-number value, but to enforce code durability // we don't want any del'able reference types. - ASSERT(istext(source) && !isnull(value)) + ASSERT(istext(source)) + if(isnull(value)) + // autodetect if we're just setting duration + value = sources[source] + if(isnull(value)) + return FALSE // just a duration set and it ain't there var/old = sources[source] sources[source] = value var/old_expires = expires[source] @@ -75,7 +81,9 @@ if(duration > 0) expires[source] = world.time + duration timers[source] = addtimer(CALLBACK(src, PROC_REF(remove_source), source, TRUE), duration, TIMER_STOPPABLE) - on_change(source, old, value) + if(old != value) + on_change(source, old, value) + return TRUE /** * called on a change of source or value. diff --git a/code/datums/status_effects/grouped/staggered.dm b/code/datums/status_effects/grouped/staggered.dm new file mode 100644 index 00000000000..88e17df556e --- /dev/null +++ b/code/datums/status_effects/grouped/staggered.dm @@ -0,0 +1,22 @@ +/datum/status_effect/grouped/staggered + identifier = "staggered" + duration = 1 SECONDS + var/applied_highest = 0 + +/datum/status_effect/grouped/staggered/on_change(source, old_value, new_value) + . = ..() + var/highest = 0 + for(var/a_source in sources) + highest = max(highest, sources[a_source]) + if(!highest) + owner.remove_movespeed_modifier(/datum/movespeed_modifier/mob_staggered) + applied_highest = 0 + return + if(applied_highest == highest) + return + applied_highest = highest + owner.add_or_update_variable_movespeed_modifier(/datum/movespeed_modifier/mob_staggered, multiplicative_slowdown = highest) + +/datum/status_effect/grouped/staggered/on_remove() + . = ..() + owner.remove_movespeed_modifier(/datum/movespeed_modifier/mob_staggered) diff --git a/code/game/objects/items/devices/flash.dm b/code/game/objects/items/devices/flash.dm index b248dd8a7cb..9ece7196e69 100644 --- a/code/game/objects/items/devices/flash.dm +++ b/code/game/objects/items/devices/flash.dm @@ -33,6 +33,10 @@ var/cell_type = /obj/item/cell/device + //? damage + var/stagger_strength = 1.5 + var/stagger_duration = 3 SECONDS + /obj/item/flash/Initialize(mapload) . = ..() power_supply = new cell_type(src) @@ -193,7 +197,7 @@ if(flash_strength > 0) H.Confuse(flash_strength + 5) - H.afflict_stagger(5) + H.afflict_stagger(FLASH_TRAIT, stagger_strength, stagger_duration) H.Blind(flash_strength) H.eye_blurry = max(H.eye_blurry, flash_strength + 5) H.flash_eyes() diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm index 1e11f3f3920..350830df935 100644 --- a/code/modules/mob/living/carbon/human/human.dm +++ b/code/modules/mob/living/carbon/human/human.dm @@ -1268,16 +1268,17 @@ if(isSynthetic()) switch(severity) if(1) - afflict_stagger(20, 30) + afflict_stagger(EMP_TRAIT_N(1), 2, 10) + afflict_stagger(EMP_TRAIT_N(2), 5, 2) Confuse(10) if(2) - afflict_stagger(10, 15) + afflict_stagger(EMP_TRAIT_N(1), 2, 10) Confuse(7) if(3) - afflict_stagger(5, 10) + afflict_stagger(EMP_TRAIT_N(1), 1, 5) Confuse(5) if(4) - afflict_stagger(2) + afflict_stagger(EMP_TRAIT_N(1), 0.5, 3) Confuse(2) flash_eyes() to_chat(src, "*BZZZT*") diff --git a/code/modules/mob/status_procs.dm b/code/modules/mob/status_procs.dm index ea2cac2513b..c5381e7c507 100644 --- a/code/modules/mob/status_procs.dm +++ b/code/modules/mob/status_procs.dm @@ -141,18 +141,34 @@ afflict_root(amount) return TRUE -/mob/proc/afflict_stagger(stacks, maximum) - apply_stacking_effect(/datum/status_effect/stacking/staggered, stacks, maximum) +/** + * apply a staggering effect + * + * @params + * * source - source enum + * * strength - how strong of a slowdown. the maximum of all stagger effects is taken + * * duration - how long to stagger for + */ +/mob/proc/afflict_stagger(source, strength, duration) + apply_grouped_effect(/datum/status_effect/grouped/staggered, source, strength, duration) -/mob/proc/cure_stagger(stacks) - remove_stacking_effect(/datum/status_effect/stacking/staggered, stacks) +/** + * removes a staggering effect source + * + * @params + * * source - source enum + * * duration - the duration to remove. if null (default), removes all. + */ +/mob/proc/cure_stagger(source, duration) + if(!isnull(duration)) + var/datum/status_effect/grouped/effect = is_staggered() + effect.set_source(source, duration = duration) + return + remove_grouped_effect(/datum/status_effect/grouped/staggered, source) /mob/proc/is_staggered() - RETURN_TYPE(/datum/status_effect/stacking/staggered) - return has_status_effect(/datum/status_effect/stacking/staggered) - -/mob/proc/stacks_staggered() - return is_staggered()?.stacks + RETURN_TYPE(/datum/status_effect/grouped/staggered) + return has_status_effect(/datum/status_effect/grouped/staggered) /mob/proc/is_unconscious() RETURN_TYPE(/datum/status_effect)