From c76d9ba74d8db23d2f740fd4763dec591e45e756 Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sat, 14 Jan 2023 21:20:58 +0100 Subject: [PATCH] [MIRROR] Fixes weather overlays stacking up [MDB IGNORE] (#18718) * Fixes weather overlays stacking up (#72587) ## About The Pull Request I was improperly having END_STAGE only block ONE overlay from being added This fixes that I've refactored this to use a proc to gen the current overlays, which is a lot cleaner ## Why It's Good For The Game This was causing overlay stacking on lavaland, which was leading to helllag on campbell Not of critical priority because it's not doubling, but it would be good to handle quickly so campbell can have fun after 10 hours. ## Changelog :cl: fix: Fixes clientside lavaland lag on long rounds /:cl: * Fixes weather overlays stacking up Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> --- code/datums/weather/weather.dm | 90 ++++++++++++++-------------------- 1 file changed, 37 insertions(+), 53 deletions(-) diff --git a/code/datums/weather/weather.dm b/code/datums/weather/weather.dm index faee8a3e5e6..b3d9e96743b 100644 --- a/code/datums/weather/weather.dm +++ b/code/datums/weather/weather.dm @@ -67,7 +67,8 @@ /// If this bit of weather should also draw an overlay that's uneffected by lighting onto the area /// Taken from weather_glow.dmi var/use_glow = TRUE - var/list/offsets_to_overlays + /// List of all overlays to apply to our turfs + var/list/overlay_cache /// The stage of the weather, from 1-4 var/stage = END_STAGE @@ -220,62 +221,45 @@ * */ /datum/weather/proc/update_areas() - var/using_icon_state = "" + var/list/new_overlay_cache = generate_overlay_cache() + for(var/area/impacted as anything in impacted_areas) + if(length(overlay_cache)) + impacted.overlays -= overlay_cache + if(length(new_overlay_cache)) + impacted.overlays += new_overlay_cache + + overlay_cache = new_overlay_cache + +/// Returns a list of visual offset -> overlays to use +/datum/weather/proc/generate_overlay_cache() + // We're ending, so no overlays at all + if(stage == END_STAGE) + return list() + + var/weather_state = "" switch(stage) if(STARTUP_STAGE) - using_icon_state = telegraph_overlay + weather_state = telegraph_overlay if(MAIN_STAGE) - using_icon_state = weather_overlay + weather_state = weather_overlay if(WIND_DOWN_STAGE) - using_icon_state = end_overlay - if(END_STAGE) - using_icon_state = "" + weather_state = end_overlay - // Note: what we do here is effectively apply two overlays to each area, for every unique multiz layer they inhabit - // One is the base, which will be masked by lighting. the other is "glowing", and provides a nice contrast - // This method of applying one overlay per z layer has some minor downsides, in that it could lead to improperly doubled effects if some have alpha - // I prefer it to creating 2 extra plane masters however, so it's a cost I'm willing to pay - // LU - var/list/new_offsets_to_overlays = list() - for(var/V in impacted_areas) - var/area/N = V + // Use all possible offsets + // Yes this is a bit annoying, but it's too slow to calculate and store these from turfs, and it shouldn't (I hope) look weird + var/list/gen_overlay_cache = list() + for(var/offset in 0 to SSmapping.max_plane_offset) + // Note: what we do here is effectively apply two overlays to each area, for every unique multiz layer they inhabit + // One is the base, which will be masked by lighting. the other is "glowing", and provides a nice contrast + // This method of applying one overlay per z layer has some minor downsides, in that it could lead to improperly doubled effects if some have alpha + // I prefer it to creating 2 extra plane masters however, so it's a cost I'm willing to pay + // LU + var/mutable_appearance/glow_overlay = mutable_appearance('icons/effects/glow_weather.dmi', weather_state, overlay_layer, null, ABOVE_LIGHTING_PLANE, 100, offset_const = offset) + glow_overlay.color = weather_color + gen_overlay_cache += glow_overlay - // List of overlays this area uses - var/list/mutable_appearance/overlays = list() - // Use all possible offsets - // Yes this is a bit annoying, but it's too slow to calculate and store these, and it shouldn't (I hope) look weird - for(var/offset in 0 to SSmapping.max_plane_offset) - var/keyd_offset = offset + 1 - if(length(new_offsets_to_overlays) < keyd_offset) - new_offsets_to_overlays.len = keyd_offset - var/list/mutable_appearance/existing_appearances = new_offsets_to_overlays[keyd_offset] - if(existing_appearances) - overlays += existing_appearances - continue - - var/list/offset_overlays = list() - var/mutable_appearance/glow_overlay = mutable_appearance('icons/effects/glow_weather.dmi', using_icon_state, overlay_layer, N, ABOVE_LIGHTING_PLANE, 100, offset_const = offset) - glow_overlay.color = weather_color - offset_overlays += glow_overlay - - if(stage != END_STAGE) - var/mutable_appearance/weather_overlay = mutable_appearance('icons/effects/weather_effects.dmi', using_icon_state, overlay_layer, plane = overlay_plane, offset_const = offset) - weather_overlay.color = weather_color - offset_overlays += weather_overlay - - new_offsets_to_overlays[keyd_offset] = offset_overlays - overlays += offset_overlays - - var/list/mutable_appearance/old_glows = list() - // Offset (ha) by 1 to match the key - for(var/offset in 1 to SSmapping.max_plane_offset + 1) - if(length(offsets_to_overlays) >= offset) - old_glows += offsets_to_overlays[offset] - - if(length(old_glows)) - N.overlays -= old_glows - if(length(overlays)) - N.overlays += overlays - - offsets_to_overlays = new_offsets_to_overlays + var/mutable_appearance/weather_overlay = mutable_appearance('icons/effects/weather_effects.dmi', weather_state, overlay_layer, plane = overlay_plane, offset_const = offset) + weather_overlay.color = weather_color + gen_overlay_cache += weather_overlay + return gen_overlay_cache