From 4ee5cb9dcc15840af2b08908a62ae1c3859e4dd1 Mon Sep 17 00:00:00 2001 From: RikuTheKiller <88713943+RikuTheKiller@users.noreply.github.com> Date: Tue, 1 Apr 2025 20:29:57 +0300 Subject: [PATCH] Allows setting tick_interval on status effects to 0, effectively passing process() straight to tick() (#90248) ## About The Pull Request Adds STATUS_EFFECT_AUTO_TICK, a define with a value of 0 that just makes process() call tick() every time. ## Why It's Good For The Game An unambiguous way to make tick() consistent with process() is quite nice. Sometimes you just have a status effect that only needs to run every 0.2s or every 2s. (past cases downstream) Other times you have a status effect that is reliant on being in sync with process() (my case downstream that started this PR) --- code/__DEFINES/status_effects.dm | 2 ++ code/datums/status_effects/_status_effect.dm | 11 +++++++---- code/modules/unit_tests/status_effect_validity.dm | 9 +++------ 3 files changed, 12 insertions(+), 10 deletions(-) diff --git a/code/__DEFINES/status_effects.dm b/code/__DEFINES/status_effects.dm index 8ea7128f5f1..ceecdb729da 100644 --- a/code/__DEFINES/status_effects.dm +++ b/code/__DEFINES/status_effects.dm @@ -11,6 +11,8 @@ #define STATUS_EFFECT_PERMANENT -1 /// Use in status effect "tick_interval" to prevent it from calling tick() #define STATUS_EFFECT_NO_TICK -1 +/// Use in status effect "tick_interval" to guarantee that tick() gets called on every process() +#define STATUS_EFFECT_AUTO_TICK 0 /// Indicates this status effect is an abstract type, ie not instantiated /// Doesn't actually do anything in practice, primarily just a marker / used in unit tests, diff --git a/code/datums/status_effects/_status_effect.dm b/code/datums/status_effects/_status_effect.dm index bda48742997..58abf9b315c 100644 --- a/code/datums/status_effects/_status_effect.dm +++ b/code/datums/status_effects/_status_effect.dm @@ -119,13 +119,16 @@ qdel(src) return - if(tick_interval != STATUS_EFFECT_NO_TICK && tick_interval < world.time) + if(tick_interval == STATUS_EFFECT_AUTO_TICK) + tick(seconds_per_tick) + else if(tick_interval != STATUS_EFFECT_NO_TICK && tick_interval < world.time) var/tick_length = (tick_interval_upperbound && tick_interval_lowerbound) ? rand(tick_interval_lowerbound, tick_interval_upperbound) : initial(tick_interval) tick(tick_length / (1 SECONDS)) tick_interval = world.time + tick_length - if(QDELING(src)) - // tick deleted us, no need to continue - return + + if(QDELING(src)) + // tick deleted us, no need to continue + return if(duration != STATUS_EFFECT_PERMANENT) if(duration < world.time) diff --git a/code/modules/unit_tests/status_effect_validity.dm b/code/modules/unit_tests/status_effect_validity.dm index cdb6ffb6b57..44c7b391610 100644 --- a/code/modules/unit_tests/status_effect_validity.dm +++ b/code/modules/unit_tests/status_effect_validity.dm @@ -11,19 +11,16 @@ if(tick_speed == INFINITY) TEST_FAIL("Status effect [checking] has tick_interval set to INFINITY, this is not how you prevent ticks - use tick_interval = STATUS_EFFECT_NO_TICK instead.") continue - if(tick_speed == 0) - TEST_FAIL("Status effect [checking] has tick_interval set to 0, this is not how you prevent ticks - use tick_interval = STATUS_EFFECT_NO_TICK instead.") - continue switch(initial(checking.processing_speed)) if(STATUS_EFFECT_FAST_PROCESS) - if(tick_speed < SSfastprocess.wait) + if(tick_speed < SSfastprocess.wait && tick_speed != STATUS_EFFECT_AUTO_TICK) TEST_FAIL("Status effect [checking] has tick_interval set to [tick_speed], which is faster than SSfastprocess can tick ([SSfastprocess.wait]).") if(STATUS_EFFECT_NORMAL_PROCESS) - if(tick_speed < SSprocessing.wait) + if(tick_speed < SSprocessing.wait && tick_speed != STATUS_EFFECT_AUTO_TICK) TEST_FAIL("Status effect [checking] has tick_interval set to [tick_speed], which is faster than SSprocessing can tick ([SSprocessing.wait]).") if(STATUS_EFFECT_PRIORITY) var/priority_wait = world.tick_lag * SSpriority_effects.wait // SSpriority_effects has the SS_TICKER flag, so its wait is in ticks, so we have to convert it to deciseconds. - if(tick_speed < priority_wait) + if(tick_speed < priority_wait && tick_speed != STATUS_EFFECT_AUTO_TICK) TEST_FAIL("Status effect [checking] has tick_interval set to [tick_speed], which is faster than SSpriority_effects can tick ([priority_wait]).") else TEST_FAIL("Invalid processing speed for status effect [checking] : [initial(checking.processing_speed)]")