From 43428545b271a18b7a16de8cc961901d8a212591 Mon Sep 17 00:00:00 2001 From: Ghom <42542238+Ghommie@users.noreply.github.com> Date: Sat, 12 Aug 2023 15:31:48 +0200 Subject: [PATCH] Adds a unit test for client colours. (#77484) ## About The Pull Request I'm adding a unit test for the sanity of client colours, ancient datums which I had refactored a long time ago. This also affects the `color_to_full_rgba_matrix()` proc, which I had also worked on. ## Why It's Good For The Game Ever since that aforementioned years old refactor, there have always been a few issues with client colours. The most annoying one being the monochromacy client color lingering even after the blindness status effect is ok. It's unlikely this will fix that. However, this should clear a few other runtimes with the feature. ## Changelog N/A. --- code/__HELPERS/matrices.dm | 25 ++++++++++++++----- code/modules/client/client_colour.dm | 14 +++++------ .../surgery/organs/internal/heart/_heart.dm | 2 +- code/modules/unit_tests/_unit_tests.dm | 1 + code/modules/unit_tests/client_colours.dm | 9 +++++++ 5 files changed, 37 insertions(+), 14 deletions(-) create mode 100644 code/modules/unit_tests/client_colours.dm diff --git a/code/__HELPERS/matrices.dm b/code/__HELPERS/matrices.dm index a79e0866211..075a5e5ae0e 100644 --- a/code/__HELPERS/matrices.dm +++ b/code/__HELPERS/matrices.dm @@ -185,15 +185,24 @@ round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), ro output[offset+x] = round(A[offset+1]*B[x] + A[offset+2]*B[x+4] + A[offset+3]*B[x+8] + A[offset+4]*B[x+12]+(y == 5?B[x+16]:0), 0.001) return output -///Converts RGB shorthands into RGBA matrices complete of constants rows (ergo a 20 keys list in byond). -/proc/color_to_full_rgba_matrix(color) +/** + * Converts RGB shorthands into RGBA matrices complete of constants rows (ergo a 20 keys list in byond). + * if return_identity_on_fail is true, stack_trace is called instead of CRASH, and an identity is returned. + */ +/proc/color_to_full_rgba_matrix(color, return_identity_on_fail = TRUE) + if(!color) + return color_matrix_identity() if(istext(color)) var/list/L = ReadRGB(color) if(!L) - CRASH("Invalid/unsupported color format argument in color_to_full_rgba_matrix()") + var/message = "Invalid/unsupported color ([color]) argument in color_to_full_rgba_matrix()" + if(return_identity_on_fail) + stack_trace(message) + return color_matrix_identity() + CRASH(message) return list(L[1]/255,0,0,0, 0,L[2]/255,0,0, 0,0,L[3]/255,0, 0,0,0,L.len>3?L[4]/255:1, 0,0,0,0) - else if(!islist(color)) //invalid format - return color_matrix_identity() + if(!islist(color)) //invalid format + CRASH("Invalid/unsupported color ([color]) argument in color_to_full_rgba_matrix()") var/list/L = color switch(L.len) if(3 to 5) // row-by-row hexadecimals @@ -219,7 +228,11 @@ round(cos_inv_third+sqrt3_sin, 0.001), round(cos_inv_third-sqrt3_sin, 0.001), ro for(var/b in 1 to 20-L.len) . += 0 else - CRASH("Invalid/unsupported color format argument in color_to_full_rgba_matrix()") + var/message = "Invalid/unsupported color (list of length [L.len]) argument in color_to_full_rgba_matrix()" + if(return_identity_on_fail) + stack_trace(message) + return color_matrix_identity() + CRASH(message) #undef LUMA_R #undef LUMA_G diff --git a/code/modules/client/client_colour.dm b/code/modules/client/client_colour.dm index d45bb8db4fc..88573c78e23 100644 --- a/code/modules/client/client_colour.dm +++ b/code/modules/client/client_colour.dm @@ -16,8 +16,8 @@ * Define subtypes of this datum */ /datum/client_colour - ///Any client.color-valid value - var/colour = "" + ///The color we want to give to the client. This has to be either a hexadecimal color or a color matrix. + var/colour ///The mob that owns this client_colour. var/mob/owner /** @@ -32,8 +32,8 @@ ///Same as above, but on removal. var/fade_out = 0 -/datum/client_colour/New(mob/_owner) - owner = _owner +/datum/client_colour/New(mob/owner) + src.owner = owner /datum/client_colour/Destroy() if(!QDELETED(owner)) @@ -150,7 +150,6 @@ /datum/client_colour/glass_colour priority = PRIORITY_LOW - colour = "red" /datum/client_colour/glass_colour/green colour = "#aaffaa" @@ -212,9 +211,10 @@ colour = list(0,0,0,0,0,0,0,0,0,1,0,0) //pure red. fade_out = 10 -/datum/client_colour/bloodlust/New(mob/_owner) +/datum/client_colour/bloodlust/New(mob/owner) ..() - addtimer(CALLBACK(src, PROC_REF(update_colour), list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0), 10, SINE_EASING|EASE_OUT), 1) + if(owner) + addtimer(CALLBACK(src, PROC_REF(update_colour), list(1,0,0,0.8,0.2,0, 0.8,0,0.2,0.1,0,0), 10, SINE_EASING|EASE_OUT), 1) /datum/client_colour/rave priority = PRIORITY_LOW diff --git a/code/modules/surgery/organs/internal/heart/_heart.dm b/code/modules/surgery/organs/internal/heart/_heart.dm index 78c95dadd25..ce4b948c653 100644 --- a/code/modules/surgery/organs/internal/heart/_heart.dm +++ b/code/modules/surgery/organs/internal/heart/_heart.dm @@ -194,7 +194,7 @@ /datum/client_colour/cursed_heart_blood priority = 100 //it's an indicator you're dying, so it's very high priority - colour = "red" + colour = "#FF0000" /obj/item/organ/internal/heart/cybernetic name = "basic cybernetic heart" diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm index 8e99e4bdc97..9cc43e4ce22 100644 --- a/code/modules/unit_tests/_unit_tests.dm +++ b/code/modules/unit_tests/_unit_tests.dm @@ -110,6 +110,7 @@ #include "chain_pull_through_space.dm" #include "chat_filter.dm" #include "circuit_component_category.dm" +#include "client_colours.dm" #include "closets.dm" #include "clothing_under_armor_subtype_check.dm" #include "combat.dm" diff --git a/code/modules/unit_tests/client_colours.dm b/code/modules/unit_tests/client_colours.dm new file mode 100644 index 00000000000..55b6e0b24ad --- /dev/null +++ b/code/modules/unit_tests/client_colours.dm @@ -0,0 +1,9 @@ +///Checks that client colours have valid colour variables values at least when inited. +/datum/unit_test/client_colours + +/datum/unit_test/client_colours/Run() + for(var/datum/client_colour/colour as anything in subtypesof(/datum/client_colour)) + // colours can be color matrices (lists), which initial() cannot read. + colour = new colour + if(!color_to_full_rgba_matrix(colour.colour, FALSE)) + TEST_FAIL("[colour.type] has an invalid default colour value: [colour.colour]")