From 229910f33dd8d3d1af89aaaeaf39a2c14bb945dc Mon Sep 17 00:00:00 2001 From: MrMelbert <51863163+MrMelbert@users.noreply.github.com> Date: Fri, 17 Oct 2025 09:32:14 -0500 Subject: [PATCH] Adds job palette system to loadout / Adds jobs colored overalls to loadout (#93312) ## About The Pull Request ### Adds job palette system to loadout Loadout items now have a system for coloring the equipped item based on job palettes. Job palettes are generically defined but can be overriden on a per-job, per-department basis for subtypes. ### Adds overalls to the Loadout These use the job palette system. image Some notes: - Assistant always picks black. Initially I was going to go full grey, but black fits grey and colored jumpsuits. - Clown is a bit of a sin, but it's kind of unavoidable. - Jobs with suit storage items will attempt to relocate them - Either to the backpack, belt slot, or one of the two hands. If all of these fail it'll just delete the suit storage item. - Before anyone says "The botanist color doesn't fit!!", that's LITERALLY the color we already give them in their vendor ## Why It's Good For The Game The job palette system lets us add more variety to loadouts, opening up player customization without harming the indetifiability of jobs at a glance. In this case, overalls are a retro sci-fi stable (see: Paranoia ttrpg) but we couldn't hand them out willy-nilly as they were fully recolorable - A scientist could have bright red overalls, looking more like a security officer. But the palette system gives the scientist a dark purple set of overalls, which makse them very obviously scientist. Colors are subject to change. ## Changelog :cl: Melbert add: Adds job-colored overalls to the loadout /:cl: --- code/__DEFINES/preferences.dm | 31 +++- code/datums/outfit.dm | 12 +- code/modules/jobs/job_types/lawyer.dm | 1 - .../modules/loadout/categories/accessories.dm | 18 +-- code/modules/loadout/categories/pocket.dm | 48 ++---- code/modules/loadout/categories/shoes.dm | 2 +- code/modules/loadout/categories/suits.dm | 42 +++++ code/modules/loadout/loadout_helpers.dm | 4 +- code/modules/loadout/loadout_items.dm | 146 ++++++++++++------ code/modules/mob/living/carbon/human/dummy.dm | 1 + tgstation.dme | 1 + 11 files changed, 200 insertions(+), 106 deletions(-) create mode 100644 code/modules/loadout/categories/suits.dm diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm index 31465051e15..42e4d3869d2 100644 --- a/code/__DEFINES/preferences.dm +++ b/code/__DEFINES/preferences.dm @@ -156,8 +156,17 @@ #define SPRITE_ACCESSORY_NONE "None" // Loadout -/// Used to make something not recolorable even if it's capable -#define DONT_GREYSCALE -1 +/// When equipped, applies a job specific palette to the item. Only applicable to GAGS items. +#define LOADOUT_FLAG_JOB_GREYSCALING (1<<0) +/// Prevents GAGS items from being player customizable. +#define LOADOUT_FLAG_BLOCK_GREYSCALING (1<<1) +/// Allows the item to be greyscaled by the player, if it's a GAGS item. Automatically set if the item is innately recolorable. +#define LOADOUT_FLAG_GREYSCALING_ALLOWED (1<<2) +/// Allows the item to be renamed by the player. +#define LOADOUT_FLAG_ALLOW_NAMING (1<<3) +/// Allows the item to be reskinned by the player. Only applicable to items with unique_reskin defined. +#define LOADOUT_FLAG_ALLOW_RESKIN (1<<4) + // Loadout item info keys // Changing these will break existing loadouts /// Tracks GAGS color information @@ -173,3 +182,21 @@ #define UPPER_LIP "Upper" #define MIDDLE_LIP "Middle" #define LOWER_LIP "Lower" + +// Job greyscale colors for loadout items +#define COLOR_JOB_ASSISTANT /obj/item/clothing/under/color/grey::greyscale_colors +#define COLOR_JOB_BOTANIST "#33cc33" +#define COLOR_JOB_CARGO_GENERIC "#824b32" +#define COLOR_JOB_CE "#d0d0d0" +#define COLOR_JOB_CHEF "#d0d0d0" +#define COLOR_JOB_CHEMIST "#ff6600" +#define COLOR_JOB_CLOWN "#ffbeff" +#define COLOR_JOB_CMO "#009999" +#define COLOR_JOB_DEFAULT "#303030" +#define COLOR_JOB_ENGI_GENERIC "#ff6600" +#define COLOR_JOB_JANITOR /obj/item/clothing/gloves/color/purple::greyscale_colors +#define COLOR_JOB_LAWYER "#003399" +#define COLOR_JOB_SCI_GENERIC "#800080" +#define COLOR_JOB_SEC_GENERIC "#A53228" +#define COLOR_JOB_MED_GENERIC "#5B97BC" +#define COLOR_JOB_COMMAND_GENERIC "#3C5A96" diff --git a/code/datums/outfit.dm b/code/datums/outfit.dm index 1badba3f160..007f7a26daa 100644 --- a/code/datums/outfit.dm +++ b/code/datums/outfit.dm @@ -24,20 +24,20 @@ var/id_trim = null /// Type path of item to go in uniform slot - var/uniform = null + var/obj/item/uniform = null /// Type path of item to go in suit slot - var/suit = null + var/obj/item/suit = null /** * Type path of item to go in suit storage slot * * (make sure it's valid for that suit) */ - var/suit_store = null + var/obj/item/suit_store = null /// Type path of item to go in back slot - var/back = null + var/obj/item/back = null /** * list of items that should go in the backpack of the user @@ -47,7 +47,7 @@ var/list/backpack_contents = null /// Type path of item to go in belt slot - var/belt = null + var/obj/item/belt = null /** * list of items that should go in the belt of the user @@ -505,7 +505,7 @@ for(var/item in beltpack) var/itype = text2path(item) if(itype) - belt_contents[itype] = belt[item] + belt_contents[itype] = beltpack[item] box = text2path(outfit_data["box"]) var/list/impl = outfit_data["implants"] implants = list() diff --git a/code/modules/jobs/job_types/lawyer.dm b/code/modules/jobs/job_types/lawyer.dm index c1cdafab00b..449d004e76b 100644 --- a/code/modules/jobs/job_types/lawyer.dm +++ b/code/modules/jobs/job_types/lawyer.dm @@ -29,7 +29,6 @@ job_tone = "objection" - /datum/outfit/job/lawyer name = "Lawyer" jobtype = /datum/job/lawyer diff --git a/code/modules/loadout/categories/accessories.dm b/code/modules/loadout/categories/accessories.dm index 3ffb02f686d..2c90385b113 100644 --- a/code/modules/loadout/categories/accessories.dm +++ b/code/modules/loadout/categories/accessories.dm @@ -55,17 +55,13 @@ LAZYADD(outfit.backpack_contents, outfit.accessory) outfit.accessory = item_path -/datum/loadout_item/accessory/on_equip_item( - obj/item/clothing/accessory/equipped_item, - datum/preferences/preference_source, - list/preference_list, - mob/living/carbon/human/equipper, - visuals_only = FALSE, -) +/datum/loadout_item/accessory/on_equip_item(obj/item/equipped_item, list/item_details, mob/living/carbon/human/equipper, datum/outfit/job/outfit, visuals_only = FALSE) . = ..() - if(istype(equipped_item)) - equipped_item.above_suit = !!preference_list[item_path]?[INFO_LAYER] - . |= (ITEM_SLOT_OCLOTHING|ITEM_SLOT_ICLOTHING) + if(isnull(equipped_item)) + return . + var/obj/item/clothing/accessory/accessory_item = equipped_item + accessory_item.above_suit = !!item_details[INFO_LAYER] + return . | ITEM_SLOT_OCLOTHING | ITEM_SLOT_ICLOTHING /datum/loadout_item/accessory/maid_apron name = "Maid Apron" @@ -86,4 +82,4 @@ /datum/loadout_item/accessory/pride name = "Pride Pin" item_path = /obj/item/clothing/accessory/pride - can_be_reskinned = TRUE + loadout_flags = LOADOUT_FLAG_ALLOW_RESKIN diff --git a/code/modules/loadout/categories/pocket.dm b/code/modules/loadout/categories/pocket.dm index 58e9bb459b9..21fc4d32416 100644 --- a/code/modules/loadout/categories/pocket.dm +++ b/code/modules/loadout/categories/pocket.dm @@ -30,13 +30,7 @@ /datum/loadout_item/pocket_items abstract_type = /datum/loadout_item/pocket_items -/datum/loadout_item/pocket_items/on_equip_item( - obj/item/equipped_item, - datum/preferences/preference_source, - list/preference_list, - mob/living/carbon/human/equipper, - visuals_only = FALSE, -) +/datum/loadout_item/pocket_items/on_equip_item(obj/item/equipped_item, list/item_details, mob/living/carbon/human/equipper, datum/outfit/job/outfit, visuals_only = FALSE) // Backpack items aren't created if it's a visual equipping, so don't do any on equip stuff. It doesn't exist. if(visuals_only) return NONE @@ -47,7 +41,7 @@ /datum/loadout_item/pocket_items/plush group = "Plushies" abstract_type = /datum/loadout_item/pocket_items/plush - can_be_named = TRUE + loadout_flags = LOADOUT_FLAG_ALLOW_NAMING /datum/loadout_item/pocket_items/plush/bee name = "Plush (Bee)" @@ -63,7 +57,7 @@ /datum/loadout_item/pocket_items/plush/lizard_random name = "Plush (Lizard, Random)" - can_be_greyscale = DONT_GREYSCALE + loadout_flags = parent_type::loadout_flags | LOADOUT_FLAG_BLOCK_GREYSCALING ui_icon = 'icons/obj/fluff/previews.dmi' ui_icon_state = "plushie_lizard_random" item_path = /obj/item/toy/plush/lizard_plushie @@ -180,19 +174,15 @@ . = ..() .[FA_ICON_PALETTE] = "Recolorable" -/datum/loadout_item/pocket_items/lipstick/on_equip_item( - obj/item/lipstick/equipped_item, - datum/preferences/preference_source, - list/preference_list, - mob/living/carbon/human/equipper, - visuals_only, -) +/datum/loadout_item/pocket_items/lipstick/on_equip_item(obj/item/equipped_item, list/item_details, mob/living/carbon/human/equipper, datum/outfit/job/outfit, visuals_only = FALSE) . = ..() - var/picked_style = style_to_style(preference_list[item_path]?[INFO_LAYER]) - var/picked_color = preference_list[item_path]?[INFO_GREYSCALE] || /obj/item/lipstick::lipstick_color - if(istype(equipped_item)) // can be null for visuals_only - equipped_item.style = picked_style - equipped_item.lipstick_color = picked_color + if(isnull(equipped_item)) + return + var/picked_style = style_to_style(item_details[INFO_LAYER]) + var/picked_color = item_details[INFO_GREYSCALE] || /obj/item/lipstick::lipstick_color + var/obj/item/lipstick/lipstick_item = equipped_item + lipstick_item.style = picked_style + lipstick_item.lipstick_color = picked_color equipper.update_lips(picked_style, picked_color) /// Converts style (readable) to style (internal) @@ -289,13 +279,7 @@ /datum/loadout_item/pocket_items/wallet/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE) return -/datum/loadout_item/pocket_items/wallet/on_equip_item( - obj/item/equipped_item, - datum/preferences/preference_source, - list/preference_list, - mob/living/carbon/human/equipper, - visuals_only = FALSE, -) +/datum/loadout_item/pocket_items/wallet/on_equip_item(obj/item/equipped_item, list/item_details, mob/living/carbon/human/equipper, datum/outfit/job/outfit, visuals_only = FALSE) // Do this at the very end of the setup process so we can insert quirk items and such if(!visuals_only && !isdummy(equipper)) RegisterSignal(equipper, COMSIG_HUMAN_CHARACTER_SETUP_FINISHED, PROC_REF(apply_after_setup), override = TRUE) @@ -334,13 +318,7 @@ /datum/loadout_item/pocket_items/borg_me_dogtag item_path = /obj/item/clothing/accessory/dogtag/borg_ready -/datum/loadout_item/pocket_items/borg_me_dogtag/on_equip_item( - obj/item/equipped_item, - datum/preferences/preference_source, - list/preference_list, - mob/living/carbon/human/equipper, - visuals_only = FALSE, -) +/datum/loadout_item/pocket_items/borg_me_dogtag/on_equip_item(obj/item/equipped_item, list/item_details, mob/living/carbon/human/equipper, datum/outfit/job/outfit, visuals_only) // We're hooking this datum to add an extra bit of flavor to the dogtag - a pregenerated medical record if(!visuals_only && !isdummy(equipper)) RegisterSignal(equipper, COMSIG_HUMAN_CHARACTER_SETUP_FINISHED, PROC_REF(apply_after_setup), override = TRUE) diff --git a/code/modules/loadout/categories/shoes.dm b/code/modules/loadout/categories/shoes.dm index 22ef52d62be..0ba99288351 100644 --- a/code/modules/loadout/categories/shoes.dm +++ b/code/modules/loadout/categories/shoes.dm @@ -12,7 +12,7 @@ outfit.shoes = item_path /datum/loadout_item/shoes/sneakers - name = "Sneakers (Colourable)" + name = "Sneakers" item_path = /obj/item/clothing/shoes/sneakers /datum/loadout_item/shoes/sandals_laced diff --git a/code/modules/loadout/categories/suits.dm b/code/modules/loadout/categories/suits.dm new file mode 100644 index 00000000000..0637671de37 --- /dev/null +++ b/code/modules/loadout/categories/suits.dm @@ -0,0 +1,42 @@ +/datum/loadout_category/suits + category_name = "Suits" + category_ui_icon = FA_ICON_USER_SECRET + type_to_generate = /datum/loadout_item/suit + tab_order = /datum/loadout_category/head::tab_order + 3 + +/datum/loadout_item/suit + abstract_type = /datum/loadout_item/suit + +/datum/loadout_item/suit/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE) + if(outfit.suit) + LAZYADD(outfit.backpack_contents, outfit.suit) + if(outfit.suit_store) + if(outfit.suit_store::w_class <= WEIGHT_CLASS_NORMAL) + LAZYADD(outfit.backpack_contents, outfit.suit_store) + else if((!outfit.belt || (outfit.belt::w_class <= WEIGHT_CLASS_NORMAL)) && (outfit.suit_store::slot_flags & ITEM_SLOT_BELT)) + if(outfit.belt) + LAZYADD(outfit.backpack_contents, outfit.belt) + outfit.belt = outfit.suit_store + else if(!outfit.r_hand) + outfit.r_hand = outfit.suit_store + else if(!outfit.l_hand) + outfit.l_hand = outfit.suit_store + // no else condition - if every check failed, we just nuke whatever was there + // which is fine, suitstore generally contains replaceable items like pens, tanks, or weapons + outfit.suit_store = null + + outfit.suit = item_path + +/datum/loadout_item/suit/overall + name = "Overall" + item_path = /obj/item/clothing/suit/apron/overalls + loadout_flags = LOADOUT_FLAG_JOB_GREYSCALING + job_greyscale_palettes = list( + /datum/job/assistant = COLOR_JOB_DEFAULT, + /datum/job/botanist = /obj/item/clothing/suit/apron/overalls::greyscale_colors, + /datum/job/captain = COLOR_JOB_COMMAND_GENERIC, + /datum/job/head_of_personnel = COLOR_JOB_COMMAND_GENERIC, + /datum/job/head_of_security = COLOR_JOB_DEFAULT, + /datum/job/paramedic = "#28324b", + /datum/job/prisoner = "#ff8b00", + ) diff --git a/code/modules/loadout/loadout_helpers.dm b/code/modules/loadout/loadout_helpers.dm index f3fbda697df..4de6f1631b8 100644 --- a/code/modules/loadout/loadout_helpers.dm +++ b/code/modules/loadout/loadout_helpers.dm @@ -41,9 +41,9 @@ for(var/datum/loadout_item/item as anything in loadout_datums) update |= item.on_equip_item( equipped_item = locate(item.item_path) in new_contents, - preference_source = preference_source, - preference_list = preference_list, + item_details = preference_list?[item.item_path] || list(), equipper = src, + outfit = equipped_outfit, visuals_only = visuals_only, ) if(update) diff --git a/code/modules/loadout/loadout_items.dm b/code/modules/loadout/loadout_items.dm index 2400798bbeb..78561a9401c 100644 --- a/code/modules/loadout/loadout_items.dm +++ b/code/modules/loadout/loadout_items.dm @@ -40,17 +40,8 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) /// Title of a group that this item will be bundled under /// Defaults to parent category's title if unset var/group = null - /// Whether this item has greyscale support. - /// Only works if the item is compatible with the GAGS system of coloring. - /// Set automatically to TRUE for all items that have the flag [IS_PLAYER_COLORABLE_1]. - /// If you really want it to not be colorable set this to [DONT_GREYSCALE] - var/can_be_greyscale = FALSE - /// Whether this item can be renamed. - /// I recommend you apply this sparingly becuase it certainly can go wrong (or get reset / overridden easily) - var/can_be_named = FALSE - /// Whether this item can be reskinned. - /// Only works if the item has a "unique reskin" list set. - var/can_be_reskinned = FALSE + /// Loadout flags, see LOADOUT_FLAG_* defines + var/loadout_flags = NONE /// The actual item path of the loadout item. var/obj/item/item_path /// Icon file (DMI) for the UI to use for preview icons. @@ -61,14 +52,27 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) var/ui_icon_state /// Reskin options of this item if it can be reskinned. VAR_FINAL/list/cached_reskin_options + /// A list of greyscale colors that are used for items that have greyscale support, but don't allow full customization. + /// This is an assoc list of /datum/job_department -> colors, or /datum/job -> colors, allowing for preset colors based on player chosen job. + /// Jobs are prioritized over departments. + /// Note: You don't need to set a color for every job or department! + var/list/job_greyscale_palettes /datum/loadout_item/New(category) src.category = category - if(can_be_greyscale == DONT_GREYSCALE) - can_be_greyscale = FALSE - else if((item_path::flags_1 & IS_PLAYER_COLORABLE_1) && item_path::greyscale_config && item_path::greyscale_colors) - can_be_greyscale = TRUE + if(!(loadout_flags & LOADOUT_FLAG_BLOCK_GREYSCALING) && is_greyscale_item()) + loadout_flags |= LOADOUT_FLAG_GREYSCALING_ALLOWED + + if(loadout_flags & LOADOUT_FLAG_JOB_GREYSCALING) + var/default_colors = SSgreyscale.ParseColorString(item_path::greyscale_colors) + var/list/final_palette = LAZYLISTDUPLICATE(job_greyscale_palettes) + switch(length(default_colors)) + if(1) + LAZYOR(final_palette, default_one_color_job_palette()) + if(2 to INFINITY) + stack_trace("[length(default_colors)] color job palettes are not implemented yet, please do so.") + job_greyscale_palettes = final_palette if(isnull(name)) name = item_path::name @@ -77,23 +81,31 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) ui_icon = item_path::icon_preview || item_path::icon ui_icon_state = item_path::icon_state_preview || item_path::icon_state - if(can_be_reskinned) + if(loadout_flags & LOADOUT_FLAG_ALLOW_RESKIN) var/obj/item/dummy_item = new item_path() if(!length(dummy_item.unique_reskin)) - can_be_reskinned = FALSE - stack_trace("Loadout item [item_path] has can_be_reskinned set to TRUE but has no unique reskins.") + loadout_flags &= ~LOADOUT_FLAG_ALLOW_RESKIN + stack_trace("Loadout item [item_path] has LOADOUT_FLAG_ALLOW_RESKIN but has no unique reskins.") else cached_reskin_options = dummy_item.unique_reskin.Copy() qdel(dummy_item) /datum/loadout_item/Destroy(force, ...) - if(force) + if(!force) stack_trace("QDEL called on loadout item [type]. This shouldn't ever happen. (Use FORCE if necessary.)") return QDEL_HINT_LETMELIVE GLOB.all_loadout_datums -= item_path return ..() +/// Checks if the item is capable of being recolored / is a GAGS item. +/datum/loadout_item/proc/is_greyscale_item() + if(!(item_path::flags_1 & IS_PLAYER_COLORABLE_1)) + return FALSE + if(!item_path::greyscale_config || !item_path::greyscale_colors) + return FALSE + return TRUE + /** * Takes in an action from a loadout manager and applies it * @@ -106,15 +118,16 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) switch(action) if("select_color") - if(can_be_greyscale) + if((loadout_flags & LOADOUT_FLAG_GREYSCALING_ALLOWED) && !(loadout_flags & LOADOUT_FLAG_JOB_GREYSCALING)) return set_item_color(manager, user) if("set_name") - if(can_be_named) + if(loadout_flags & LOADOUT_FLAG_ALLOW_NAMING) return set_name(manager, user) if("set_skin") - return set_skin(manager, user, params) + if(loadout_flags & LOADOUT_FLAG_ALLOW_RESKIN) + return set_skin(manager, user, params) return TRUE @@ -192,9 +205,6 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) /// Used for reskinning an item to an alt skin. /datum/loadout_item/proc/set_skin(datum/preference_middleware/loadout/manager, mob/user, params) - if(!can_be_reskinned) - return FALSE - var/reskin_to = params["skin"] if(!cached_reskin_options[reskin_to]) return FALSE @@ -207,6 +217,26 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) manager.preferences.update_preference(GLOB.preference_entries[/datum/preference/loadout], loadout) return TRUE // always update UI +/// When passed an outfit, attempts to select a job-appropriate color from job_greyscale_palettes +/datum/loadout_item/proc/get_job_color(datum/outfit/base_outfit) + if(!istype(base_outfit, /datum/outfit/job)) + return job_greyscale_palettes[/datum/job] // default color + + var/datum/outfit/job/job_outfit = base_outfit + var/jobtype = job_outfit.jobtype + if(job_greyscale_palettes[jobtype]) + return job_greyscale_palettes[jobtype] + + var/datum/job/job = SSjob.get_job_type(jobtype) + if(job.department_for_prefs && job_greyscale_palettes[job.department_for_prefs]) + return job_greyscale_palettes[job.department_for_prefs] + + for(var/job_dept in job.departments_list) + if(job_greyscale_palettes[job_dept]) + return job_greyscale_palettes[job_dept] + + return job_greyscale_palettes[/datum/job] // default color + /** * Place our [item_path] into the passed [outfit]. * @@ -228,37 +258,32 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) * * Arguments: * * preference_source - the datum/preferences our loadout item originated from - cannot be null + * * item_details - the details of the item in the loadout preferences, such as greyscale, name, reskin, etc * * equipper - the mob we're equipping this item onto + * * outfit - the rest of the outfit being equipped, may be null * * visuals_only - whether or not this is only concerned with visual things (not backpack, not renaming, etc) - * * preference_list - what the raw loadout list looks like in the preferences * * Return a bitflag of slot flags to update */ -/datum/loadout_item/proc/on_equip_item( - obj/item/equipped_item, - datum/preferences/preference_source, - list/preference_list, - mob/living/carbon/human/equipper, - visuals_only = FALSE, -) +/datum/loadout_item/proc/on_equip_item(obj/item/equipped_item, list/item_details, mob/living/carbon/human/equipper, datum/outfit/outfit, visuals_only = FALSE) if(isnull(equipped_item)) return NONE if(!visuals_only) ADD_TRAIT(equipped_item, TRAIT_ITEM_OBJECTIVE_BLOCKED, "Loadout") - var/list/item_details = preference_list[item_path] var/update_flag = NONE - if(can_be_greyscale && item_details?[INFO_GREYSCALE]) - equipped_item.set_greyscale(item_details[INFO_GREYSCALE]) + if((loadout_flags & LOADOUT_FLAG_GREYSCALING_ALLOWED) && ((loadout_flags & LOADOUT_FLAG_JOB_GREYSCALING) || item_details?[INFO_GREYSCALE])) + var/item_color = (loadout_flags & LOADOUT_FLAG_JOB_GREYSCALING) ? get_job_color(outfit) : item_details?[INFO_GREYSCALE] + equipped_item.set_greyscale(item_color) update_flag |= equipped_item.slot_flags - if(can_be_named && item_details?[INFO_NAMED] && !visuals_only) + if((loadout_flags & LOADOUT_FLAG_ALLOW_NAMING) && item_details?[INFO_NAMED] && !visuals_only) equipped_item.name = trim(item_details[INFO_NAMED], PREVENT_CHARACTER_TRIM_LOSS(MAX_NAME_LEN)) ADD_TRAIT(equipped_item, TRAIT_WAS_RENAMED, "Loadout") - if(can_be_reskinned && item_details?[INFO_RESKIN]) + if((loadout_flags & LOADOUT_FLAG_ALLOW_RESKIN) && item_details?[INFO_RESKIN]) var/skin_chosen = item_details[INFO_RESKIN] if(skin_chosen in equipped_item.unique_reskin) equipped_item.current_skin = skin_chosen @@ -272,11 +297,6 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) else update_flag |= equipped_item.slot_flags - else - // Not valid, update the preference - item_details -= INFO_RESKIN - preference_source.write_preference(GLOB.preference_entries[/datum/preference/loadout], preference_list) - return update_flag /** @@ -313,10 +333,10 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) // Mothblocks is hellbent on recolorable and reskinnable being only tooltips for items for visual clarity, so ask her before changing these var/list/displayed_text = list() - if(can_be_greyscale) + if((loadout_flags & LOADOUT_FLAG_GREYSCALING_ALLOWED) && !(loadout_flags & LOADOUT_FLAG_JOB_GREYSCALING)) displayed_text[FA_ICON_PALETTE] = "Recolorable" - if(can_be_reskinned) + if(loadout_flags & LOADOUT_FLAG_ALLOW_RESKIN) displayed_text[FA_ICON_SWATCHBOOK] = "Reskinnable" return displayed_text @@ -339,7 +359,7 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) var/list/button_list = list() - if(can_be_greyscale) + if((loadout_flags & LOADOUT_FLAG_GREYSCALING_ALLOWED) && !(loadout_flags & LOADOUT_FLAG_JOB_GREYSCALING)) UNTYPED_LIST_ADD(button_list, list( "label" = "Recolor", "act_key" = "select_color", @@ -347,7 +367,7 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) "active_key" = INFO_GREYSCALE, )) - if(can_be_named) + if(loadout_flags & LOADOUT_FLAG_ALLOW_NAMING) UNTYPED_LIST_ADD(button_list, list( "label" = "Rename", "act_key" = "set_name", @@ -361,7 +381,7 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) * Returns a list of options this item can be reskinned into. */ /datum/loadout_item/proc/get_reskin_options() as /list - if(!can_be_reskinned) + if(!(loadout_flags & LOADOUT_FLAG_ALLOW_RESKIN)) return null var/list/reskins = list() @@ -374,3 +394,33 @@ GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories()) )) return reskins + +/// Default job gags colors for one color gags items +/datum/loadout_item/proc/default_one_color_job_palette() + return list( + /datum/job/assistant = COLOR_JOB_ASSISTANT, + /datum/job/bitrunner = COLOR_JOB_DEFAULT, + /datum/job/botanist = COLOR_JOB_BOTANIST, + /datum/job/chemist = COLOR_JOB_CHEMIST, + /datum/job/chief_engineer = COLOR_JOB_CE, + /datum/job/chief_medical_officer = COLOR_JOB_CMO, + /datum/job/clown = COLOR_JOB_CLOWN, + /datum/job/cook = COLOR_JOB_CHEF, + /datum/job/coroner = COLOR_JOB_DEFAULT, + /datum/job/curator = COLOR_DRIED_TAN, + /datum/job/detective = COLOR_DRIED_TAN, + /datum/job/geneticist = COLOR_BLUE_GRAY, + /datum/job/janitor = COLOR_JOB_JANITOR, + /datum/job/lawyer = COLOR_JOB_LAWYER, + /datum/job/prisoner = COLOR_PRISONER_ORANGE, + /datum/job/psychologist = COLOR_DRIED_TAN, + /datum/job/roboticist = COLOR_JOB_DEFAULT, + /datum/job/shaft_miner = COLOR_DARK_BROWN, + /datum/job_department/command = COLOR_JOB_COMMAND_GENERIC, + /datum/job_department/engineering = COLOR_JOB_ENGI_GENERIC, + /datum/job_department/medical = COLOR_JOB_MED_GENERIC, + /datum/job_department/security = COLOR_JOB_SEC_GENERIC, + /datum/job_department/science = COLOR_JOB_SCI_GENERIC, + /datum/job_department/cargo = COLOR_JOB_CARGO_GENERIC, + /datum/job = COLOR_JOB_DEFAULT, // default for any job not listed above + ) diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm index 81fb9f8c6b8..ae6d8fad2c3 100644 --- a/code/modules/mob/living/carbon/human/dummy.dm +++ b/code/modules/mob/living/carbon/human/dummy.dm @@ -82,6 +82,7 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy) /mob/living/carbon/human/dummy/proc/wipe_state() delete_equipment() + update_lips(null, null, null, update = FALSE) cut_overlays(TRUE) /mob/living/carbon/human/dummy/setup_human_dna() diff --git a/tgstation.dme b/tgstation.dme index aaedbfc3150..ba97677cab1 100644 --- a/tgstation.dme +++ b/tgstation.dme @@ -4739,6 +4739,7 @@ #include "code\modules\loadout\categories\neck.dm" #include "code\modules\loadout\categories\pocket.dm" #include "code\modules\loadout\categories\shoes.dm" +#include "code\modules\loadout\categories\suits.dm" #include "code\modules\logging\log_category.dm" #include "code\modules\logging\log_entry.dm" #include "code\modules\logging\log_holder.dm"