Files
FalloutFalcon 8042c69b4f Gives missing icon unit tests a shared parent (#95122)
## About The Pull Request
Gives the 3 main missing icon tests a shared parent for behavior. Made
the list of icon states not static because of this but that shouldn't
really matter.
Additional icon locations is made a list for evil down streams that are
grandchildren of TG rather then just children, or repos with multiple
spots for icons, `modular_downstream/master_files/icons` and
`modular_downstream/modules` can both have icons in alot of them

Was considering also making them filter out abstract_types but maybe
should be a diff pr.
## Why It's Good For The Game
All 3 present unit tests copy paste ALOT of their behavior, but very low
hanging fruit is the compiling of folders, which while claiming have
modularity support its a bit silly to require 3 separate additions just
to make sure all tests are properly working.
## Changelog
N/A

---------

Co-authored-by: Jordan Dominion <dominion@tgstation13.org>
2026-02-11 18:50:14 -05:00

90 lines
4.4 KiB
Plaintext

/// Makes sure suit slot items aren't using CS:S fallbacks.
/datum/unit_test/missing_icons/worn_icons
default_location = "icons/mob/clothing/"
/datum/unit_test/missing_icons/worn_icons/Run()
compile_icon_state_locations()
var/list/already_warned_icons = list()
for(var/obj/item/item_path as anything in (subtypesof(/obj/item) - typesof(/obj/item/mod)))
var/cached_slot_flags = initial(item_path.slot_flags)
if(!cached_slot_flags || (cached_slot_flags & ITEM_SLOT_LPOCKET) || (cached_slot_flags & ITEM_SLOT_RPOCKET) || initial(item_path.item_flags) & ABSTRACT)
continue
if(initial(item_path.greyscale_colors) && initial(item_path.greyscale_config_worn)) //GAGS has its own unit test.
continue
var/worn_icon = initial(item_path.worn_icon) //override icon file. where our sprite is contained if set. (ie modularity stuff)
var/worn_icon_state = initial(item_path.worn_icon_state) //overrides icon_state.
var/icon_state = worn_icon_state || initial(item_path.icon_state) //icon_state. what sprite name we are looking for.
if(isnull(icon_state))
continue //no sprite for the item.
if(icon_state in already_warned_icons)
continue
var/match_message
if(icon_state in possible_icon_states)
for(var/file_place in possible_icon_states[icon_state])
match_message += (match_message ? " & '[file_place]'" : " - Matching sprite found in: '[file_place]'")
if(worn_icon) //easiest to check since we override everything. this automatically includes downstream support.
if(isnull(worn_icon_state)) // no worn sprite for this item.
continue
if(!(icon_state in icon_states(worn_icon, 1)))
TEST_FAIL("[item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in worn_icon override file, '[worn_icon]'[match_message]")
continue
var/icon_file //checks against all the default icon locations if one isn't defined.
if(cached_slot_flags & ITEM_SLOT_BACK)
icon_file = 'icons/mob/clothing/back.dmi'
if(!(icon_state in icon_states(icon_file, 1)))
already_warned_icons += icon_state
TEST_FAIL("[item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]")
if(cached_slot_flags & ITEM_SLOT_ID)
icon_file = 'icons/mob/clothing/id.dmi'
if(!(icon_state in icon_states(icon_file, 1)))
already_warned_icons += icon_state
TEST_FAIL("[item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]")
if(cached_slot_flags & ITEM_SLOT_GLOVES)
icon_file = 'icons/mob/clothing/hands.dmi'
if(!(icon_state in icon_states(icon_file, 1)))
already_warned_icons += icon_state
TEST_FAIL("[item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]")
if(cached_slot_flags & ITEM_SLOT_EYES)
icon_file = 'icons/mob/clothing/eyes.dmi'
if(!(icon_state in icon_states(icon_file, 1)))
already_warned_icons += icon_state
TEST_FAIL("[item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]")
if(cached_slot_flags & ITEM_SLOT_EARS)
icon_file = 'icons/mob/clothing/ears.dmi'
if(!(icon_state in icon_states(icon_file, 1)))
already_warned_icons += icon_state
TEST_FAIL("[item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]")
if(cached_slot_flags & ITEM_SLOT_NECK)
icon_file = 'icons/mob/clothing/neck.dmi'
if(!(icon_state in icon_states(icon_file, 1)))
already_warned_icons += icon_state
TEST_FAIL("[item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]")
if(cached_slot_flags & ITEM_SLOT_MASK)
icon_file = 'icons/mob/clothing/mask.dmi'
if(!(icon_state in icon_states(icon_file, 1)))
already_warned_icons += icon_state
TEST_FAIL("[item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]")
if(cached_slot_flags & ITEM_SLOT_BELT)
icon_file = 'icons/mob/clothing/belt.dmi'
if(!(icon_state in icon_states(icon_file, 1)))
already_warned_icons += icon_state
TEST_FAIL("[item_path] using invalid [worn_icon_state ? "worn_icon_state" : "icon_state"], \"[icon_state]\" in '[icon_file]'[match_message]")