From 5b7b94a5c139f09c35abc016af26aad6747ecec9 Mon Sep 17 00:00:00 2001 From: kyunkyunkyun <120701975+kyunkyunkyun@users.noreply.github.com> Date: Wed, 5 Nov 2025 21:44:08 +0500 Subject: [PATCH] MODSuit clothing icon files can be overridden by its skin (#29598) * support downstream's modsuits * why would i do that * fix runtime * use existing helper * fix that one existing helper that is unused cos it's broken * update --- code/__DEFINES/mod.dm | 10 ++++++- code/__HELPERS/lists.dm | 2 +- code/modules/mod/mod_control.dm | 46 ++++++++++++++++++++++++++------- 3 files changed, 46 insertions(+), 12 deletions(-) diff --git a/code/__DEFINES/mod.dm b/code/__DEFINES/mod.dm index f1be922e66f..7249f37bffb 100644 --- a/code/__DEFINES/mod.dm +++ b/code/__DEFINES/mod.dm @@ -40,6 +40,14 @@ // Flags for skin modifiers #define MAKE_SPACEPROOF (1<<0) -//Defines used to override MOD clothing's icon and worn icon files in the skin. +// Defines used to override MOD clothing's icon, worn icon and sprite sheets files in the skin. #define MOD_ICON_OVERRIDE "mod_icon_override" +#define MOD_WORN_ICON_OVERRIDE "mod_worn_icon_override" + +#define MOD_SPRITE_SHEETS_OVERRIDE "mod_sprite_sheets_override" + +#define HELMET_SPRITE_SHEETS "helmet_sprite_sheets" +#define CHESTPLATE_SPRITE_SHEETS "chestplate_sprite_sheets" +#define GAUNTLETS_SPRITE_SHEETS "gauntlets_sprite_sheets" +#define BOOTS_SPRITE_SHEETS "boots_sprite_sheets" diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm index c689ff745e4..b1349b63199 100644 --- a/code/__HELPERS/lists.dm +++ b/code/__HELPERS/lists.dm @@ -777,7 +777,7 @@ ///Removes the value V from the item K, if the item K is empty will remove it from the list, if the list is empty will set the list to null #define LAZYREMOVEASSOC(L, K, V) if(L) { if(L[K]) { L[K] -= V; if(!length(L[K])) L -= K; } if(!length(L)) L = null; } ///Accesses an associative list, returns null if nothing is found -#define LAZYACCESSASSOC(L, I, K) L ? L[I] ? L[I][K] ? L[I][K] : null : null : null +#define LAZYACCESSASSOC(L, I, K) (L?[I]?[K]) ///Qdel every item in the list before setting the list to null #define QDEL_LAZYLIST(L) for(var/I in L) qdel(I); L = null; ///If the lazy list is currently initialized find item I in list L diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm index bfded3cc1d2..6b4a6ed00d8 100644 --- a/code/modules/mod/mod_control.dm +++ b/code/modules/mod/mod_control.dm @@ -1,3 +1,7 @@ +#define PART_FLAGS "part_flags" +#define SPRITE_SHEETS_OVERRIDE "sprite_sheets_override" +#define SPRITE_SHEETS_DEFAULT "sprite_sheets_default" + /// MODsuits, trade-off between armor and utility /obj/item/mod name = "Base MOD" @@ -92,6 +96,8 @@ var/datum/mod_link/mod_link /// The starting MODlink frequency, by default NT to make it easier for everyone to use. var/starting_frequency = MODLINK_FREQ_NANOTRASEN + /// Used when we set up new skins for a modsuit + var/list/part_data = list() /obj/item/mod/control/serialize() var/list/data = ..() @@ -128,13 +134,33 @@ new_core?.install(src) helmet = new /obj/item/clothing/head/mod(src) mod_parts += helmet + part_data[helmet] = list( + PART_FLAGS = HELMET_FLAGS, + SPRITE_SHEETS_OVERRIDE = HELMET_SPRITE_SHEETS, + SPRITE_SHEETS_DEFAULT = /obj/item/clothing/head/mod::sprite_sheets, + ) chestplate = new /obj/item/clothing/suit/mod(src) chestplate.allowed += theme.allowed_suit_storage mod_parts += chestplate + part_data[chestplate] = list( + PART_FLAGS = CHESTPLATE_FLAGS, + SPRITE_SHEETS_OVERRIDE = CHESTPLATE_SPRITE_SHEETS, + SPRITE_SHEETS_DEFAULT = /obj/item/clothing/suit/mod::sprite_sheets, + ) gauntlets = new /obj/item/clothing/gloves/mod(src) mod_parts += gauntlets + part_data[gauntlets] = list( + PART_FLAGS = GAUNTLETS_FLAGS, + SPRITE_SHEETS_OVERRIDE = GAUNTLETS_SPRITE_SHEETS, + SPRITE_SHEETS_DEFAULT = /obj/item/clothing/gloves/mod::sprite_sheets, + ) boots = new /obj/item/clothing/shoes/mod(src) mod_parts += boots + part_data[boots] = list( + PART_FLAGS = BOOTS_FLAGS, + SPRITE_SHEETS_OVERRIDE = BOOTS_SPRITE_SHEETS, + SPRITE_SHEETS_DEFAULT = /obj/item/clothing/shoes/mod::sprite_sheets, + ) var/list/all_parts = mod_parts + src for(var/obj/item/part as anything in all_parts) part.name = "[theme.name] [part.name]" @@ -191,6 +217,7 @@ QDEL_NULL(core) QDEL_NULL(mod_link) QDEL_NULL(wires) + part_data = null wearer = null selected_module = null bag = null @@ -754,18 +781,13 @@ var/list/used_skin = theme.skins[new_skin] var/list/skin_updating = mod_parts + src for(var/obj/item/part as anything in skin_updating) - part.icon = used_skin[MOD_ICON_OVERRIDE] || 'icons/obj/clothing/modsuit/mod_clothing.dmi' + part.icon = used_skin[MOD_ICON_OVERRIDE] || initial(part.icon) + part.worn_icon = used_skin[MOD_WORN_ICON_OVERRIDE] || initial(part.worn_icon) part.icon_state = "[skin]-[part.base_icon_state]" for(var/obj/item/clothing/part as anything in mod_parts) - var/used_category - if(part == helmet) - used_category = HELMET_FLAGS - if(part == chestplate) - used_category = CHESTPLATE_FLAGS - if(part == gauntlets) - used_category = GAUNTLETS_FLAGS - if(part == boots) - used_category = BOOTS_FLAGS + part.sprite_sheets = LAZYACCESSASSOC(used_skin, MOD_SPRITE_SHEETS_OVERRIDE, LAZYACCESSASSOC(part_data, part, SPRITE_SHEETS_OVERRIDE)) \ + || LAZYACCESSASSOC(part_data, part, SPRITE_SHEETS_DEFAULT) + var/used_category = LAZYACCESSASSOC(part_data, part, PART_FLAGS) var/list/category = used_skin[used_category] part.flags = category[UNSEALED_CLOTHING] || NONE part.visor_flags = category[SEALED_CLOTHING] || NONE @@ -858,3 +880,7 @@ if(bag) for(var/obj/object in bag) object.hear_message(user, msg) + +#undef PART_FLAGS +#undef SPRITE_SHEETS_OVERRIDE +#undef SPRITE_SHEETS_DEFAULT