From 9ca858ed845f729f65d614c3fb35684fb4a50720 Mon Sep 17 00:00:00 2001 From: NovaBot <154629622+NovaBot13@users.noreply.github.com> Date: Tue, 16 Apr 2024 19:31:50 -0400 Subject: [PATCH] [MIRROR] Small optimization for Aura Healing (#2026) * Small optimization for Aura Healing (#82674) ## About The Pull Request - Makes use of the byond internal optimization for `view` to speed up aura healing a tiny bit. - In case you didn't know, byond has an optimization for `view` which speeds up iterating over objects in view if you provide it a type. This use of a ternary (likely) prevented this optimization from kicking in, and since worst-case we're doing view(7) it can add up. - Test case: 2 staff of Ascelpius users surrounded by 15 humans and 15 random objects constant being damaged. ~8 minutes of testing. - Profile: ``` /datum/component/aura_healing/proc/heal_old 0.789 6.590 6.596 0.000 4076 /datum/component/aura_healing/proc/heal_new 0.682 6.443 6.442 0.000 4081 ``` - Generalizes `SSaura_healing` to `SSaura`, makes "damage aura" component (which is totally 99% copied from "healing aura" but that's for another pr) use it as well ## Changelog :cl: Melbert refactor: Staff of Healing should perform slightly better. /:cl: * Small optimization for Aura Healing --------- Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com> --- code/controllers/subsystem/processing/aura.dm | 5 +++ .../subsystem/processing/aura_healing.dm | 5 --- code/datums/components/aura_healing.dm | 40 +++++++++++-------- code/datums/components/damage_aura.dm | 18 ++++++--- tgstation.dme | 2 +- 5 files changed, 42 insertions(+), 28 deletions(-) create mode 100644 code/controllers/subsystem/processing/aura.dm delete mode 100644 code/controllers/subsystem/processing/aura_healing.dm diff --git a/code/controllers/subsystem/processing/aura.dm b/code/controllers/subsystem/processing/aura.dm new file mode 100644 index 00000000000..12a7d511fb7 --- /dev/null +++ b/code/controllers/subsystem/processing/aura.dm @@ -0,0 +1,5 @@ +/// The subsystem used to tick auras ([/datum/component/aura_healing] and [/datum/component/damage_aura]). +PROCESSING_SUBSYSTEM_DEF(aura) + name = "Aura" + flags = SS_NO_INIT | SS_BACKGROUND | SS_KEEP_TIMING + wait = 0.3 SECONDS diff --git a/code/controllers/subsystem/processing/aura_healing.dm b/code/controllers/subsystem/processing/aura_healing.dm deleted file mode 100644 index ad3fa6f4278..00000000000 --- a/code/controllers/subsystem/processing/aura_healing.dm +++ /dev/null @@ -1,5 +0,0 @@ -/// The subsystem used to tick [/datum/component/aura_healing] instances. -PROCESSING_SUBSYSTEM_DEF(aura_healing) - name = "Aura Healing" - flags = SS_NO_INIT | SS_BACKGROUND | SS_KEEP_TIMING - wait = 0.3 SECONDS diff --git a/code/datums/components/aura_healing.dm b/code/datums/components/aura_healing.dm index 2aa33203b41..18484deb2d6 100644 --- a/code/datums/components/aura_healing.dm +++ b/code/datums/components/aura_healing.dm @@ -6,7 +6,7 @@ /// Can be applied to those only with a trait conditionally. /datum/component/aura_healing /// The range of which to heal - var/range + var/range = 5 /// Whether or not you must be a visible object of the parent var/requires_visibility = TRUE @@ -42,12 +42,13 @@ var/healing_color = COLOR_GREEN /// A list of being healed to active alerts - var/list/current_alerts = list() + var/list/mob/living/current_alerts = list() + /// Cooldown between showing the heal effect COOLDOWN_DECLARE(last_heal_effect_time) /datum/component/aura_healing/Initialize( - range, + range = 5, requires_visibility = TRUE, brute_heal = 0, burn_heal = 0, @@ -63,7 +64,7 @@ if (!isatom(parent)) return COMPONENT_INCOMPATIBLE - START_PROCESSING(SSaura_healing, src) + START_PROCESSING(SSaura, src) src.range = range src.requires_visibility = requires_visibility @@ -79,10 +80,10 @@ src.healing_color = healing_color /datum/component/aura_healing/Destroy(force) - STOP_PROCESSING(SSaura_healing, src) + STOP_PROCESSING(SSaura, src) var/alert_category = "aura_healing_[REF(src)]" - for(var/mob/living/alert_holder in current_alerts) + for(var/mob/living/alert_holder as anything in current_alerts) alert_holder.clear_alert(alert_category) current_alerts.Cut() @@ -93,20 +94,25 @@ if (should_show_effect) COOLDOWN_START(src, last_heal_effect_time, HEAL_EFFECT_COOLDOWN) - var/list/remove_alerts_from = current_alerts.Copy() - + var/list/to_heal = list() var/alert_category = "aura_healing_[REF(src)]" - for (var/mob/living/candidate in (requires_visibility ? view(range, parent) : range(range, parent))) - if (!isnull(limit_to_trait) && !HAS_TRAIT(candidate, limit_to_trait)) - continue - - remove_alerts_from -= candidate - - if (!(candidate in current_alerts)) + if(requires_visibility) + for(var/mob/living/candidate in view(range, parent)) + if (!isnull(limit_to_trait) && !HAS_TRAIT(candidate, limit_to_trait)) + continue + to_heal[candidate] = TRUE + else + for(var/mob/living/candidate in range(range, parent)) + if (!isnull(limit_to_trait) && !HAS_TRAIT(candidate, limit_to_trait)) + continue + to_heal[candidate] = TRUE + + for (var/mob/living/candidate as anything in to_heal) + if (!current_alerts[candidate]) var/atom/movable/screen/alert/aura_healing/alert = candidate.throw_alert(alert_category, /atom/movable/screen/alert/aura_healing, new_master = parent) alert.desc = "You are being healed by [parent]." - current_alerts += candidate + current_alerts[candidate] = TRUE if (should_show_effect && candidate.health < candidate.maxHealth) new /obj/effect/temp_visual/heal(get_turf(candidate), healing_color) @@ -136,7 +142,7 @@ candidate.updatehealth() - for (var/mob/remove_alert_from as anything in remove_alerts_from) + for (var/mob/living/remove_alert_from as anything in current_alerts - to_heal) remove_alert_from.clear_alert(alert_category) current_alerts -= remove_alert_from diff --git a/code/datums/components/damage_aura.dm b/code/datums/components/damage_aura.dm index b4c535cb52d..98d323aa6d5 100644 --- a/code/datums/components/damage_aura.dm +++ b/code/datums/components/damage_aura.dm @@ -4,7 +4,7 @@ /// Will deal more damage the more people are present. /datum/component/damage_aura /// The range of which to damage - var/range + var/range = 5 /// Whether or not you must be a visible object of the parent var/requires_visibility = TRUE @@ -43,7 +43,7 @@ COOLDOWN_DECLARE(last_damage_effect_time) /datum/component/damage_aura/Initialize( - range, + range = 5, requires_visibility = TRUE, brute_damage = 0, burn_damage = 0, @@ -59,7 +59,7 @@ if (!isatom(parent)) return COMPONENT_INCOMPATIBLE - START_PROCESSING(SSobj, src) + START_PROCESSING(SSaura, src) src.range = range src.requires_visibility = requires_visibility @@ -75,7 +75,7 @@ src.current_owner = WEAKREF(current_owner) /datum/component/damage_aura/Destroy(force) - STOP_PROCESSING(SSobj, src) + STOP_PROCESSING(SSaura, src) return ..() /// The requirements for the mob to be effected by the damage aura. @@ -102,7 +102,15 @@ if (should_show_effect) COOLDOWN_START(src, last_damage_effect_time, DAMAGE_EFFECT_COOLDOWN) - for (var/mob/living/candidate in (requires_visibility ? view(range, parent) : range(range, parent))) + var/list/to_damage = list() + if(requires_visibility) + for(var/mob/living/candidate in view(range, parent)) + to_damage += candidate + else + for(var/mob/living/candidate in range(range, parent)) + to_damage += candidate + + for (var/mob/living/candidate as anything in to_damage) var/mob/living/owner = current_owner?.resolve() if (owner && owner == candidate) owner_effect(owner, seconds_per_tick) diff --git a/tgstation.dme b/tgstation.dme index e707e82db75..25aaeb30c87 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -845,7 +845,7 @@ #include "code\controllers\subsystem\processing\ai_basic_avoidance.dm" #include "code\controllers\subsystem\processing\ai_behaviors.dm" #include "code\controllers\subsystem\processing\antag_hud.dm" -#include "code\controllers\subsystem\processing\aura_healing.dm" +#include "code\controllers\subsystem\processing\aura.dm" #include "code\controllers\subsystem\processing\clock_component.dm" #include "code\controllers\subsystem\processing\conveyors.dm" #include "code\controllers\subsystem\processing\digital_clock.dm"