diff --git a/code/__defines/subsystem-defines.dm b/code/__defines/subsystem-defines.dm index f0a1a635966..d7b72ed06ac 100644 --- a/code/__defines/subsystem-defines.dm +++ b/code/__defines/subsystem-defines.dm @@ -86,3 +86,7 @@ // Connection prefixes for player-editable fields #define WP_ELECTRONICS "elec_" + + +// -- SSicon_cache -- +#define LIGHT_FIXTURE_CACHE(icon,state,color) SSicon_cache.light_fixture_cache["[icon]_[state]_[color]"] || (SSicon_cache.light_fixture_cache["[icon]_[state]_[color]"] = SSicon_cache.generate_color_variant(icon,state,color)) diff --git a/code/_helpers/icons.dm b/code/_helpers/icons.dm index c609555fd69..7d45d399186 100644 --- a/code/_helpers/icons.dm +++ b/code/_helpers/icons.dm @@ -553,6 +553,11 @@ proc/BlendHSV(hsv1, hsv2, amount) amount<0 or amount>1 are allowed */ proc/BlendRGB(rgb1, rgb2, amount) + var/cachekey = "[rgb1]_[rgb2]_[amount]" + . = SSicon_cache.rgb_blend_cache[cachekey] + if (.) + return + var/list/RGB1 = ReadRGB(rgb1) var/list/RGB2 = ReadRGB(rgb2) @@ -566,7 +571,8 @@ proc/BlendRGB(rgb1, rgb2, amount) var/b = round(RGB1[3] + (RGB2[3] - RGB1[3]) * amount, 1) var/alpha = usealpha ? round(RGB1[4] + (RGB2[4] - RGB1[4]) * amount, 1) : null - return isnull(alpha) ? rgb(r, g, b) : rgb(r, g, b, alpha) + . = isnull(alpha) ? rgb(r, g, b) : rgb(r, g, b, alpha) + SSicon_cache.rgb_blend_cache[cachekey] = . proc/BlendRGBasHSV(rgb1, rgb2, amount) return HSVtoRGB(RGBtoHSV(rgb1), RGBtoHSV(rgb2), amount) diff --git a/code/controllers/subsystems/icon_cache.dm b/code/controllers/subsystems/icon_cache.dm index 5aec7e9665a..00041ce6d15 100644 --- a/code/controllers/subsystems/icon_cache.dm +++ b/code/controllers/subsystems/icon_cache.dm @@ -63,6 +63,10 @@ var/list/ao_cache = list() + var/list/light_fixture_cache = list() + + var/list/rgb_blend_cache = list() // not an icon per-se, but this proc could be expensive so we might as well cache it. + /datum/controller/subsystem/icon_cache/New() NEW_SS_GLOBAL(SSicon_cache) @@ -85,3 +89,8 @@ uniform_states = list() for (var/i in icon_states('icons/mob/uniform.dmi')) uniform_states[i] = TRUE + +/datum/controller/subsystem/icon_cache/proc/generate_color_variant(icon/icon, icon_state, color) + var/image/I = new(icon, icon_state) + I.color = color + return I diff --git a/code/modules/power/lighting.dm b/code/modules/power/lighting.dm index d3731ad909c..4a084677bef 100644 --- a/code/modules/power/lighting.dm +++ b/code/modules/power/lighting.dm @@ -218,30 +218,21 @@ icon_state = "[base_state]_empty" switch(status) // set icon_states if(LIGHT_OK) - var/image/I = image(icon, "[base_state][on]") - I.color = brightness_color - add_overlay(I) + var/target_color = brightness_color if (supports_nightmode && nightmode && on) - color = "#d2d2d2" - else - color = null + target_color = BlendRGB("#d2d2d2", target_color, 0.25) + + add_overlay(LIGHT_FIXTURE_CACHE(icon, "[base_state][on]", target_color)) if(LIGHT_EMPTY) on = 0 if(LIGHT_BURNED) - var/image/I = image(icon, "[base_state]_burned") - I.color = brightness_color - add_overlay(I) + add_overlay(LIGHT_FIXTURE_CACHE(icon, "[base_state]_burned", brightness_color)) on = 0 if(LIGHT_BROKEN) - var/image/I = image(icon, "[base_state]_broken") - I.color = brightness_color - add_overlay(I) + add_overlay(LIGHT_FIXTURE_CACHE(icon, "[base_state]_broken", brightness_color)) on = 0 - if (!on) - color = null - // update the icon_state and luminosity of the light depending on its state /obj/machinery/light/proc/update(var/trigger = 1) update_icon()