From 9a11e0c5d3ed42ac64b8b0257c257e757f4b073c Mon Sep 17 00:00:00 2001 From: SkyratBot <59378654+SkyratBot@users.noreply.github.com> Date: Sat, 21 Oct 2023 20:22:25 +0200 Subject: [PATCH] [MIRROR] Actually supports alpha passed into emissive stuff [MDB IGNORE] (#24481) * Actually supports alpha passed into emissive stuff (#79117) ## About The Pull Request Ok so like, the emissive procs have an alpha argument right? The thing is, the thing is it doesn't fucking do anything. Alpha is a component of the color var (at least when it's a matrix), so when we set alpha and then set color to a matrix, the alpha gets overriden. Inverse is also true. I want to support alpha args, since I like the idea of dimmable emissives. Soooooo Let's take the alpha arg, divide it by 255, and replace everything that cares about alpha (as an intensity thing) with it. This lets us do transparent emissives and transparent emissive blockers. I added some guard checks to hopefully avoid the list init most of the time (it is in theory comprable since color sets should copy but I don't trust byond to optimize for that) Also modified the macros to suppport what I'm doing nicely ## Why It's Good For The Game We should support this, and now we do * Actually supports alpha passed into emissive stuff --------- Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com> --- code/__DEFINES/lighting.dm | 8 ++++++-- code/__HELPERS/lighting.dm | 24 +++++++++++++++--------- 2 files changed, 21 insertions(+), 11 deletions(-) diff --git a/code/__DEFINES/lighting.dm b/code/__DEFINES/lighting.dm index 731f37fdf64..6c56105f0ec 100644 --- a/code/__DEFINES/lighting.dm +++ b/code/__DEFINES/lighting.dm @@ -78,14 +78,18 @@ /// Don't block any emissives. Useful for things like, pieces of paper? #define EMISSIVE_BLOCK_NONE 2 +#define _EMISSIVE_COLOR(val) list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, val,val,val,0) /// The color matrix applied to all emissive overlays. Should be solely dependent on alpha and not have RGB overlap with [EM_BLOCK_COLOR]. -#define EMISSIVE_COLOR list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 1,1,1,0) +#define EMISSIVE_COLOR _EMISSIVE_COLOR(1) /// A globaly cached version of [EMISSIVE_COLOR] for quick access. GLOBAL_LIST_INIT(emissive_color, EMISSIVE_COLOR) + +#define _EM_BLOCK_COLOR(val) list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,val, 0,0,0,0) /// The color matrix applied to all emissive blockers. Should be solely dependent on alpha and not have RGB overlap with [EMISSIVE_COLOR]. -#define EM_BLOCK_COLOR list(0,0,0,0, 0,0,0,0, 0,0,0,0, 0,0,0,1, 0,0,0,0) +#define EM_BLOCK_COLOR _EM_BLOCK_COLOR(1) /// A globaly cached version of [EM_BLOCK_COLOR] for quick access. GLOBAL_LIST_INIT(em_block_color, EM_BLOCK_COLOR) + /// A set of appearance flags applied to all emissive and emissive blocker overlays. /// KEEP_APART to prevent parent hooking, KEEP_TOGETHER for children, and we reset the color and alpha of our parent so nothing gets overriden #define EMISSIVE_APPEARANCE_FLAGS (KEEP_APART|KEEP_TOGETHER|RESET_COLOR|RESET_ALPHA) diff --git a/code/__HELPERS/lighting.dm b/code/__HELPERS/lighting.dm index ee87d7f9af3..96087ba1737 100644 --- a/code/__HELPERS/lighting.dm +++ b/code/__HELPERS/lighting.dm @@ -1,9 +1,11 @@ /// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EMISSIVE_COLOR]. /proc/emissive_appearance(icon, icon_state = "", atom/offset_spokesman, layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE, offset_const) - // Note: alpha doesn't "do" anything, since it's overriden by the color set shortly after - // Consider removing it someday? (I wonder if we made emissives blend right we could make alpha actually matter. dreams man, dreams) var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, offset_spokesman, EMISSIVE_PLANE, 255, appearance_flags | EMISSIVE_APPEARANCE_FLAGS, offset_const) - appearance.color = GLOB.emissive_color + if(alpha == 255) + appearance.color = GLOB.emissive_color + else + var/alpha_ratio = alpha/255 + appearance.color = _EMISSIVE_COLOR(alpha_ratio) //Test to make sure emissives with broken or missing icon states are created if(PERFORM_ALL_TESTS(focus_only/invalid_emissives)) @@ -15,15 +17,17 @@ // This is a semi hot proc, so we micro it. saves maybe 150ms // sorry :) /proc/fast_emissive_blocker(atom/make_blocker) - // Note: alpha doesn't "do" anything, since it's overriden by the color set shortly after - // Consider removing it someday? var/mutable_appearance/blocker = new() blocker.icon = make_blocker.icon blocker.icon_state = make_blocker.icon_state // blocker.layer = FLOAT_LAYER // Implied, FLOAT_LAYER is default for appearances blocker.appearance_flags |= make_blocker.appearance_flags | EMISSIVE_APPEARANCE_FLAGS blocker.dir = make_blocker.dir - blocker.color = GLOB.em_block_color + if(make_blocker.alpha == 255) + blocker.color = GLOB.em_block_color + else + var/alpha_ratio = make_blocker.alpha/255 + blocker.color = _EM_BLOCK_COLOR(alpha_ratio) // Note, we are ok with null turfs, that's not an error condition we'll just default to 0, the error would be // Not passing ANYTHING in, key difference @@ -32,10 +36,12 @@ /// Produces a mutable appearance glued to the [EMISSIVE_PLANE] dyed to be the [EM_BLOCK_COLOR]. /proc/emissive_blocker(icon, icon_state = "", atom/offset_spokesman, layer = FLOAT_LAYER, alpha = 255, appearance_flags = NONE, offset_const) - // Note: alpha doesn't "do" anything, since it's overriden by the color set shortly after - // Consider removing it someday? var/mutable_appearance/appearance = mutable_appearance(icon, icon_state, layer, offset_spokesman, EMISSIVE_PLANE, alpha, appearance_flags | EMISSIVE_APPEARANCE_FLAGS, offset_const) - appearance.color = GLOB.em_block_color + if(alpha == 255) + appearance.color = GLOB.em_block_color + else + var/alpha_ratio = alpha/255 + appearance.color = _EM_BLOCK_COLOR(alpha_ratio) return appearance /// Takes a non area atom and a threshold