From dd419e77bece01f614beddf8197204b8eb7aeb41 Mon Sep 17 00:00:00 2001 From: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> Date: Mon, 13 Mar 2023 15:25:40 -0700 Subject: [PATCH] Converts the crackable element to mutable appearances, saves 0.15 seconds of init (#73941) ## About The Pull Request Instead of passing in an icon as a source to the alpha mask filter, we can stick a mutable appearance in our overlays list with a render target set, and use that render target to do our masking. Remember to use "*" to avoid rendering the crack twice ## Why It's Good For The Game CPU time --- code/datums/components/cracked.dm | 34 +++++++++++++++++-------------- code/datums/elements/crackable.dm | 16 +++++++-------- 2 files changed, 27 insertions(+), 23 deletions(-) diff --git a/code/datums/components/cracked.dm b/code/datums/components/cracked.dm index 901f847cd06..60264090b31 100644 --- a/code/datums/components/cracked.dm +++ b/code/datums/components/cracked.dm @@ -1,15 +1,15 @@ /// Tracks damage to add or remove crack overlays, when none are needed this components is qdeleted /datum/component/cracked dupe_mode = COMPONENT_DUPE_UNIQUE_PASSARGS - var/list/icon/crack_icons + var/list/mutable_appearance/crack_appearances var/crack_integrity var/list/applied_cracks = list() -/datum/component/cracked/Initialize(list/crack_icons, crack_integrity) +/datum/component/cracked/Initialize(list/crack_appearances, crack_integrity) . = ..() if(!isobj(parent)) return COMPONENT_INCOMPATIBLE - src.crack_icons = crack_icons + src.crack_appearances = crack_appearances src.crack_integrity = crack_integrity /datum/component/cracked/Destroy(force, silent) @@ -55,20 +55,24 @@ for(var/i in 1 to count) var/rand_x = rand(0, 20) - 10 var/rand_y = rand(0, 20) - 10 - var/icon/new_crack_icon = pick(crack_icons) - var/list/new_filter_data = alpha_mask_filter(icon=new_crack_icon, x=rand_x, y=rand_y, flags=MASK_INVERSE) - var/name - for(var/k in 1 to 100) - name = "crack[rand(0, 999)]" - if(!applied_cracks[name]) - break - if(applied_cracks[name]) - CRASH("No unique name could be found after 100 iterations.") - applied_cracks[name] = TRUE - source.add_filter(name, 1, new_filter_data) + var/mutable_appearance/new_crack_overlay = new(pick(crack_appearances)) + // Now that we have our overlay, we need to give it a unique render source so we can use a filter against it + var/static/uuid = 0 + uuid++ + // * so it doesn't render on its own + new_crack_overlay.render_target = "*cracked_overlay_[uuid]" + var/render_source = new_crack_overlay.render_target + + var/list/new_filter_data = alpha_mask_filter(render_source=render_source, x=rand_x, y=rand_y, flags=MASK_INVERSE) + applied_cracks[render_source] = new_crack_overlay + + // We need to add it as an overlay so the render target from the filter knows what to point at + source.add_overlay(new_crack_overlay) + source.add_filter(render_source, 1, new_filter_data) /datum/component/cracked/proc/RemoveCracks(obj/source, count) for(var/i in 1 to count) var/removed_filter = pick(applied_cracks) - applied_cracks -= removed_filter source.remove_filter(removed_filter) + source.cut_overlay(applied_cracks[removed_filter]) + applied_cracks -= removed_filter diff --git a/code/datums/elements/crackable.dm b/code/datums/elements/crackable.dm index d3037afdf3b..e479b1df68e 100644 --- a/code/datums/elements/crackable.dm +++ b/code/datums/elements/crackable.dm @@ -2,7 +2,7 @@ /datum/element/crackable element_flags = ELEMENT_BESPOKE argument_hash_start_idx = 2 - var/list/icon/crack_icons + var/list/mutable_appearance/crack_appearances /// The level at which the object starts showing cracks, 1 being at full health and 0.5 being at half health var/crack_integrity = 1 @@ -11,17 +11,17 @@ if(!isobj(target)) return ELEMENT_INCOMPATIBLE src.crack_integrity = crack_integrity || src.crack_integrity - if(!crack_icons) // This is the first attachment and we need to do first time setup - crack_icons = list() + if(!crack_appearances) // This is the first attachment and we need to do first time setup + crack_appearances = list() for(var/state in crack_states) - for(var/i in 1 to 36) - var/icon/new_crack_icon = icon(crack_icon, state) - new_crack_icon.Turn(i * 10) - crack_icons += new_crack_icon + for(var/i in 1 to 35) + var/mutable_appearance/crack = mutable_appearance(crack_icon, state) + crack.transform.Turn(i * 10) + crack_appearances += crack RegisterSignal(target, COMSIG_ATOM_INTEGRITY_CHANGED, PROC_REF(IntegrityChanged)) /datum/element/crackable/proc/IntegrityChanged(obj/source, old_value, new_value) SIGNAL_HANDLER if(new_value >= source.max_integrity * crack_integrity) return - source.AddComponent(/datum/component/cracked, crack_icons, crack_integrity) + source.AddComponent(/datum/component/cracked, crack_appearances, crack_integrity)