Files
Bubberstation/code/controllers/subsystem/sprite_accessories.dm
Alexis 21b4095dfd [MDB IGNORE] [IDB IGNORE] Upstream Sync - 04/17/2026 (#5453)
Upstream 04/17/2026

fixes https://github.com/Bubberstation/Bubberstation/issues/5549

---------

Signed-off-by: dependabot[bot] <support@github.com>
Co-authored-by: tgstation-ci[bot] <179393467+tgstation-ci[bot]@users.noreply.github.com>
Co-authored-by: ArcaneMusic <41715314+ArcaneMusic@users.noreply.github.com>
Co-authored-by: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Co-authored-by: Rhials <28870487+Rhials@users.noreply.github.com>
Co-authored-by: rageguy505 <54517726+rageguy505@users.noreply.github.com>
Co-authored-by: LemonInTheDark <58055496+LemonInTheDark@users.noreply.github.com>
Co-authored-by: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Co-authored-by: Aliceee2ch <160794176+Aliceee2ch@users.noreply.github.com>
Co-authored-by: Time-Green <7501474+Time-Green@users.noreply.github.com>
Co-authored-by: Tsar-Salat <62388554+Tsar-Salat@users.noreply.github.com>
Co-authored-by: SmArtKar <44720187+SmArtKar@users.noreply.github.com>
Co-authored-by: Maxipat <108554989+Maxipat112@users.noreply.github.com>
Co-authored-by: SyncIt21 <110812394+SyncIt21@users.noreply.github.com>
Co-authored-by: deltanedas <39013340+deltanedas@users.noreply.github.com>
Co-authored-by: SimplyLogan <47579821+loganuk@users.noreply.github.com>
Co-authored-by: loganuk <fakeemail123@aol.com>
Co-authored-by: Leland Kemble <70413276+lelandkemble@users.noreply.github.com>
Co-authored-by: FalloutFalcon <86381784+FalloutFalcon@users.noreply.github.com>
Co-authored-by: Roxy <75404941+TealSeer@users.noreply.github.com>
Co-authored-by: Lucy <lucy@absolucy.moe>
Co-authored-by: siliconOpossum <138069572+siliconOpossum@users.noreply.github.com>
Co-authored-by: Isratosh <Isratosh@hotmail.com>
Co-authored-by: TheRyeGuyWhoWillNowDie <70169560+TheRyeGuyWhoWillNowDie@users.noreply.github.com>
Co-authored-by: Neocloudy <88008002+Neocloudy@users.noreply.github.com>
Co-authored-by: Alexander V. <volas@ya.ru>
Co-authored-by: ElGitificador <168473461+ElGitificador@users.noreply.github.com>
Co-authored-by: Twaticus <46540570+Twaticus@users.noreply.github.com>
Co-authored-by: dependabot[bot] <49699333+dependabot[bot]@users.noreply.github.com>
Co-authored-by: Bloop <13398309+vinylspiders@users.noreply.github.com>
Co-authored-by: Cameron Lennox <killer65311@gmail.com>
Co-authored-by: Tim <timothymtorres@gmail.com>
Co-authored-by: Iamgoofball <iamgoofball@gmail.com>
Co-authored-by: Layzu666 <121319428+Layzu666@users.noreply.github.com>
Co-authored-by: Arturlang <24881678+Arturlang@users.noreply.github.com>
Co-authored-by: _0Steven <42909981+00-Steven@users.noreply.github.com>
Co-authored-by: mrmanlikesbt <99309552+mrmanlikesbt@users.noreply.github.com>
Co-authored-by: Ben10Omintrix <138636438+Ben10Omintrix@users.noreply.github.com>
Co-authored-by: John F. Kennedy <54908920+MacaroniCritter@users.noreply.github.com>
Co-authored-by: Cursor <102828457+theselfish@users.noreply.github.com>
Co-authored-by: Josh <josh.adam.powell@gmail.com>
Co-authored-by: Josh Powell <josh.powell@softwire.com>
Co-authored-by: Yobrocharlie <Charliemiller5617@gmail.com>
Co-authored-by: Hardly3D <66234359+Hardly3D@users.noreply.github.com>
Co-authored-by: shayoki <96078776+shayoki@users.noreply.github.com>
Co-authored-by: LT3 <83487515+lessthnthree@users.noreply.github.com>
2026-05-16 00:56:00 +02:00

178 lines
8.9 KiB
Plaintext

/// The non gender specific list that we get from init_sprite_accessory_subtypes()
#define DEFAULT_SPRITE_LIST "default_sprites"
/// The male specific list that we get from init_sprite_accessory_subtypes()
#define MALE_SPRITE_LIST "male_sprites"
/// The female specific list that we get from init_sprite_accessory_subtypes()
#define FEMALE_SPRITE_LIST "female_sprites"
/// Use this to init a sprite accessory list for a feature where mobs are required to have one selected
#define INIT_ACCESSORY(sprite_accessory) init_sprite_accessory_subtypes(sprite_accessory, add_blank = FALSE)[DEFAULT_SPRITE_LIST]
/// Use this to init a sprite accessory list for a feature where mobs can opt to not have one selected
#define INIT_OPTIONAL_ACCESSORY(sprite_accessory) init_sprite_accessory_subtypes(sprite_accessory, add_blank = TRUE)[DEFAULT_SPRITE_LIST]
/// subsystem that just holds lists of sprite accessories for accession in generating said sprites.
/// A sprite accessory is something that we add to a human sprite to make them look different. This is hair, facial hair, underwear, mutant bits, etc.
SUBSYSTEM_DEF(accessories) // just 'accessories' for brevity
name = "Sprite Accessories"
ss_flags = SS_NO_FIRE | SS_NO_INIT
// HOLY SHIT COMPACT THIS INTO ASSOCIATED LISTS SO WE STOP ADDING VARIABLES
//Hairstyles
var/list/hairstyles_list //! stores /datum/sprite_accessory/hair indexed by name
var/list/hairstyles_male_list //! stores only hair names
var/list/hairstyles_female_list //! stores only hair names
var/list/facial_hairstyles_list //! stores /datum/sprite_accessory/facial_hair indexed by name
var/list/facial_hairstyles_male_list //! stores only hair names
var/list/facial_hairstyles_female_list //! stores only hair names
var/list/hair_gradients_list //! stores /datum/sprite_accessory/hair_gradient indexed by name
var/list/facial_hair_gradients_list //! stores /datum/sprite_accessory/facial_hair_gradient indexed by name
var/list/hair_masks_list //! stores /datum/hair_mask indexed by type
//Underwear
var/list/underwear_list //! stores /datum/sprite_accessory/clothing/underwear indexed by name
var/list/underwear_m //! stores only underwear name
var/list/underwear_f //! stores only underwear name
//Undershirts
var/list/undershirt_list //! stores /datum/sprite_accessory/clothing/undershirt indexed by name
var/list/undershirt_m //! stores only undershirt name
var/list/undershirt_f //! stores only undershirt name
// SKYRAT EDIT ADDITION START - Underwear/bra split
var/list/bra_list
var/list/bra_m
var/list/bra_f
// SKYRAT EDIT ADDITION END
//Socks
var/list/socks_list //! stores /datum/sprite_accessory/clothing/socks indexed by name
//All features, indexed by feature key, then name of the sprite accessory to the datum iteslf
var/list/list/feature_list
// SKYRAT EDIT ADDITION START - Customization
var/list/sprite_accessories = list()
var/list/cached_mutant_icon_files = list()
// SKYRAT EDIT ADDITION END
/datum/controller/subsystem/accessories/PreInit() // this stuff NEEDS to be set up before GLOB for preferences and stuff to work so this must go here. sorry
setup_lists()
init_hair_gradients()
init_hair_masks()
make_sprite_accessory_references() // SKYRAT EDIT ADDITION - Customization
/// Sets up all of the lists for later utilization in the round and building sprites.
/// In an ideal world we could tack everything that just needed `DEFAULT_SPRITE_LIST` into static variables on the top, but due to the initialization order
/// where this subsystem will initialize BEFORE statics, it's just not feasible since this all needs to be ready for actual subsystems to use.
/// Sorry.
/datum/controller/subsystem/accessories/proc/setup_lists()
var/hair_lists = init_sprite_accessory_subtypes(/datum/sprite_accessory/hair)
hairstyles_list = hair_lists[DEFAULT_SPRITE_LIST]
hairstyles_male_list = hair_lists[MALE_SPRITE_LIST]
hairstyles_female_list = hair_lists[FEMALE_SPRITE_LIST]
var/facial_hair_lists = init_sprite_accessory_subtypes(/datum/sprite_accessory/facial_hair)
facial_hairstyles_list = facial_hair_lists[DEFAULT_SPRITE_LIST]
facial_hairstyles_male_list = facial_hair_lists[MALE_SPRITE_LIST]
facial_hairstyles_female_list = facial_hair_lists[FEMALE_SPRITE_LIST]
var/underwear_lists = init_sprite_accessory_subtypes(/datum/sprite_accessory/clothing/underwear)
underwear_list = underwear_lists[DEFAULT_SPRITE_LIST]
underwear_m = underwear_lists[MALE_SPRITE_LIST]
underwear_f = underwear_lists[FEMALE_SPRITE_LIST]
var/undershirt_lists = init_sprite_accessory_subtypes(/datum/sprite_accessory/clothing/undershirt)
undershirt_list = undershirt_lists[DEFAULT_SPRITE_LIST]
undershirt_m = undershirt_lists[MALE_SPRITE_LIST]
undershirt_f = undershirt_lists[FEMALE_SPRITE_LIST]
socks_list = init_sprite_accessory_subtypes(/datum/sprite_accessory/clothing/socks)[DEFAULT_SPRITE_LIST]
// SKYRAT EDIT ADDITION START - Underwear/bra split
var/bra_lists = init_sprite_accessory_subtypes(/datum/sprite_accessory/clothing/bra)
bra_list = bra_lists[DEFAULT_SPRITE_LIST]
bra_m = bra_lists[MALE_SPRITE_LIST]
bra_f = bra_lists[FEMALE_SPRITE_LIST]
// SKYRAT EDIT ADDITION END
feature_list = list()
// felinids
feature_list[FEATURE_TAIL_CAT] = INIT_OPTIONAL_ACCESSORY(/datum/sprite_accessory/tails/felinid)
feature_list[FEATURE_EARS] = INIT_OPTIONAL_ACCESSORY(/datum/sprite_accessory/ears)
// lizards
feature_list[FEATURE_FRILLS] = INIT_OPTIONAL_ACCESSORY(/datum/sprite_accessory/frills)
feature_list[FEATURE_HORNS] = INIT_OPTIONAL_ACCESSORY(/datum/sprite_accessory/horns)
feature_list[FEATURE_LIZARD_MARKINGS] = INIT_OPTIONAL_ACCESSORY(/datum/sprite_accessory/lizard_markings)
feature_list[FEATURE_SNOUT] = INIT_ACCESSORY(/datum/sprite_accessory/snouts)
feature_list[FEATURE_SPINES] = INIT_OPTIONAL_ACCESSORY(/datum/sprite_accessory/spines)
feature_list[FEATURE_TAILSPINES] = INIT_OPTIONAL_ACCESSORY(/datum/sprite_accessory/tail_spines)
feature_list[FEATURE_TAIL_LIZARD] = INIT_ACCESSORY(/datum/sprite_accessory/tails/lizard)
// moths
feature_list[FEATURE_MOTH_WINGS] = INIT_ACCESSORY(/datum/sprite_accessory/moth_wings)
feature_list[FEATURE_MOTH_ANTENNAE] = INIT_ACCESSORY(/datum/sprite_accessory/moth_antennae)
feature_list[FEATURE_MOTH_MARKINGS] = INIT_OPTIONAL_ACCESSORY(/datum/sprite_accessory/moth_markings)
// generic wings
feature_list[FEATURE_WINGS] = INIT_OPTIONAL_ACCESSORY(/datum/sprite_accessory/wings)
feature_list[FEATURE_WINGS_OPEN] = INIT_OPTIONAL_ACCESSORY(/datum/sprite_accessory/wings_open)
// generic features
feature_list[FEATURE_MUSH_CAP] = INIT_ACCESSORY(/datum/sprite_accessory/caps)
feature_list[FEATURE_POD_HAIR] = INIT_ACCESSORY(/datum/sprite_accessory/pod_hair)
feature_list[FEATURE_TAIL_FISH] = INIT_ACCESSORY(/datum/sprite_accessory/tails/fish)
feature_list[FEATURE_TAIL_MONKEY] = INIT_ACCESSORY(/datum/sprite_accessory/tails/monkey)
feature_list[FEATURE_TAIL_XENO] = INIT_ACCESSORY(/datum/sprite_accessory/tails/xeno)
/// This proc just initializes all /datum/sprite_accessory/hair_gradient into an list indexed by gradient-style name
/datum/controller/subsystem/accessories/proc/init_hair_gradients()
hair_gradients_list = list()
facial_hair_gradients_list = list()
for(var/path in subtypesof(/datum/sprite_accessory/gradient))
var/datum/sprite_accessory/gradient/gradient = new path
if(gradient.gradient_category & GRADIENT_APPLIES_TO_HAIR)
hair_gradients_list[gradient.name] = gradient
if(gradient.gradient_category & GRADIENT_APPLIES_TO_FACIAL_HAIR)
facial_hair_gradients_list[gradient.name] = gradient
/datum/controller/subsystem/accessories/proc/init_hair_masks()
hair_masks_list = list()
for(var/path in subtypesof(/datum/hair_mask))
var/datum/hair_mask/mask = new path
hair_masks_list[path] = mask
/// This reads the applicable sprite accessory datum's subtypes and adds it to the subsystem's list of sprite accessories.
/// The boolean `add_blank` argument just adds a "None" option to the list of sprite accessories, like if a felinid doesn't want a tail or something, typically good for gated-off things.
/datum/controller/subsystem/accessories/proc/init_sprite_accessory_subtypes(prototype, add_blank = FALSE)
RETURN_TYPE(/list)
var/returnable_list = list(
DEFAULT_SPRITE_LIST = list(),
MALE_SPRITE_LIST = list(),
FEMALE_SPRITE_LIST = list(),
)
for(var/path in subtypesof(prototype))
var/datum/sprite_accessory/accessory = new path
if(accessory.icon_state)
returnable_list[DEFAULT_SPRITE_LIST][accessory.name] = accessory
else
returnable_list[DEFAULT_SPRITE_LIST] += accessory.name
switch(accessory.gender)
if(MALE)
returnable_list[MALE_SPRITE_LIST] += accessory.name
if(FEMALE)
returnable_list[FEMALE_SPRITE_LIST] += accessory.name
else
returnable_list[MALE_SPRITE_LIST] += accessory.name
returnable_list[FEMALE_SPRITE_LIST] += accessory.name
if(add_blank)
returnable_list[DEFAULT_SPRITE_LIST][SPRITE_ACCESSORY_NONE] = new /datum/sprite_accessory/blank
return returnable_list
#undef INIT_ACCESSORY
#undef INIT_OPTIONAL_ACCESSORY
#undef DEFAULT_SPRITE_LIST
#undef MALE_SPRITE_LIST
#undef FEMALE_SPRITE_LIST