diff --git a/code/__DEFINES/preferences.dm b/code/__DEFINES/preferences.dm
index 42672bed044..6fc12601d7f 100644
--- a/code/__DEFINES/preferences.dm
+++ b/code/__DEFINES/preferences.dm
@@ -143,3 +143,17 @@
/// The key used for sprite accessories that should never actually be applied to the player.
#define SPRITE_ACCESSORY_NONE "None"
+
+// Loadout
+/// Used to make something not recolorable even if it's capable
+#define DONT_GREYSCALE -1
+// Loadout item info keys
+// Changing these will break existing loadouts
+/// Tracks GAGS color information
+#define INFO_GREYSCALE "greyscale"
+/// Used to set custom names
+#define INFO_NAMED "name"
+/// Used for specific alt-reskins, like the pride pin
+#define INFO_RESKIN "reskin"
+/// Handles which layer the item will be on, for accessories
+#define INFO_LAYER "layer"
diff --git a/code/__DEFINES/traits/declarations.dm b/code/__DEFINES/traits/declarations.dm
index 62556c7c9f9..4dda0ba34f9 100644
--- a/code/__DEFINES/traits/declarations.dm
+++ b/code/__DEFINES/traits/declarations.dm
@@ -1153,4 +1153,17 @@ Remember to update _globalvars/traits.dm if you're adding/removing/renaming trai
/// Does this item bypass ranged armor checks?
#define TRAIT_BYPASS_RANGED_ARMOR "bypass_ranged_armor"
+/// Traits given by settler, each with their own specific effects for cases where someone would have that trait, but not the other settler effects
+
+#define TRAIT_EXPERT_FISHER "expert_fisher" // fishing is easier
+#define TRAIT_ROUGHRIDER "roughrider" // you can improve speed on mounted animals with a good mood
+#define TRAIT_STUBBY_BODY "stubby_body" // you have a stubby body that lessens your agility
+#define TRAIT_BEAST_EMPATHY "beast_empathy" // you're good with animals, such as with taming them
+#define TRAIT_STURDY_FRAME "sturdy_frame" // you suffer much lesser effects from equipment that slows you down
+
+/// This item cannot be selected for or used by a theft objective (Spies, Traitors, etc.)
+#define TRAIT_ITEM_OBJECTIVE_BLOCKED "item_objective_blocked"
+/// This trait lets you attach limbs to any player without surgery.
+#define TRAIT_EASY_ATTACH "easy_attach"
+
// END TRAIT DEFINES
diff --git a/code/__DEFINES/~skyrat_defines/loadout.dm b/code/__DEFINES/~skyrat_defines/loadout.dm
new file mode 100644
index 00000000000..9ef84f7911a
--- /dev/null
+++ b/code/__DEFINES/~skyrat_defines/loadout.dm
@@ -0,0 +1,9 @@
+/// Defines for extra info blurbs, for loadout items.
+#define TOOLTIP_NO_ARMOR "ARMORLESS"
+#define TOOLTIP_NO_DAMAGE "CEREMONIAL"
+#define TOOLTIP_RANDOM_COLOR "RANDOM COLOR"
+#define TOOLTIP_GREYSCALE "GREYSCALED"
+
+#define LOADOUT_OVERRIDE_JOB "Delete job items"
+#define LOADOUT_OVERRIDE_BACKPACK "Move job to backpack"
+#define LOADOUT_OVERRIDE_CASE "Place all in case"
diff --git a/code/__DEFINES/~skyrat_defines/loadouts.dm b/code/__DEFINES/~skyrat_defines/loadouts.dm
deleted file mode 100644
index 5bb359f8f77..00000000000
--- a/code/__DEFINES/~skyrat_defines/loadouts.dm
+++ /dev/null
@@ -1,33 +0,0 @@
-/// Defines for what loadout slot a corresponding item belongs to.
-#define LOADOUT_ITEM_BELT "belt"
-#define LOADOUT_ITEM_EARS "ears"
-#define LOADOUT_ITEM_GLASSES "glasses"
-#define LOADOUT_ITEM_GLOVES "gloves"
-#define LOADOUT_ITEM_HEAD "head"
-#define LOADOUT_ITEM_MASK "mask"
-#define LOADOUT_ITEM_NECK "neck"
-#define LOADOUT_ITEM_SHOES "shoes"
-#define LOADOUT_ITEM_SUIT "suit"
-#define LOADOUT_ITEM_UNIFORM "under"
-#define LOADOUT_ITEM_ACCESSORY "accessory"
-#define LOADOUT_ITEM_INHAND "inhand_items"
-#define LOADOUT_ITEM_MISC "pocket_items"
-#define LOADOUT_ITEM_TOYS "toys"
-
-#define INFO_GREYSCALE "greyscale"
-#define INFO_NAMED "name"
-#define INFO_DESCRIBED "description"
-
-/// Max amonut of misc / backpack items that are allowed.
-#define MAX_ALLOWED_MISC_ITEMS 3
-
-/// Defines for extra info blurbs, for loadout items.
-#define TOOLTIP_NO_ARMOR "ARMORLESS - This item has no armor and is entirely cosmetic."
-#define TOOLTIP_NO_DAMAGE "CEREMONIAL - This item has very low force and is cosmetic."
-#define TOOLTIP_RANDOM_COLOR "RANDOM COLOR -This item has a random color and will change every round."
-#define TOOLTIP_GREYSCALE "GREYSCALED - This item can be customized via the greyscale modification UI."
-#define TOOLTIP_RENAMABLE "RENAMABLE - This item can be given a custom name."
-
-#define LOADOUT_OVERRIDE_JOB "Delete job items"
-#define LOADOUT_OVERRIDE_BACKPACK "Move job to backpack"
-#define LOADOUT_OVERRIDE_CASE "Place all in case"
diff --git a/code/_globalvars/traits/_traits.dm b/code/_globalvars/traits/_traits.dm
index 81c39986526..6f4bbf8aa8b 100644
--- a/code/_globalvars/traits/_traits.dm
+++ b/code/_globalvars/traits/_traits.dm
@@ -526,6 +526,7 @@ GLOBAL_LIST_INIT(traits_by_type, list(
"TRAIT_HAUNTED" = TRAIT_HAUNTED,
"TRAIT_HONKSPAMMING" = TRAIT_HONKSPAMMING,
"TRAIT_INNATELY_FANTASTICAL_ITEM" = TRAIT_INNATELY_FANTASTICAL_ITEM,
+ "TRAIT_ITEM_OBJECTIVE_BLOCKED" = TRAIT_ITEM_OBJECTIVE_BLOCKED,
"TRAIT_NEEDS_TWO_HANDS" = TRAIT_NEEDS_TWO_HANDS,
"TRAIT_NO_BARCODES" = TRAIT_NO_BARCODES,
"TRAIT_NO_STORAGE_INSERT" = TRAIT_NO_STORAGE_INSERT,
diff --git a/code/controllers/subsystem/job.dm b/code/controllers/subsystem/job.dm
index 8f50cc02b12..c0cd22f5293 100644
--- a/code/controllers/subsystem/job.dm
+++ b/code/controllers/subsystem/job.dm
@@ -568,7 +568,7 @@ SUBSYSTEM_DEF(job)
SEND_SIGNAL(equipping, COMSIG_JOB_RECEIVED, job)
equipping.mind?.set_assigned_role_with_greeting(job, player_client, alt_title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: equipping.mind?.set_assigned_role_with_greeting(job, player_client)
- equipping.on_job_equipping(job, player_client?.prefs, player_client) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: equipping.on_job_equipping(job)
+ equipping.on_job_equipping(job, player_client) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: equipping.on_job_equipping(job)
job.announce_job(equipping, alt_title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES - ORIGINAL: job.announce_job(equipping)
if(player_client?.holder)
diff --git a/code/controllers/subsystem/processing/quirks.dm b/code/controllers/subsystem/processing/quirks.dm
index 3813a3592c1..9b258a82b4f 100644
--- a/code/controllers/subsystem/processing/quirks.dm
+++ b/code/controllers/subsystem/processing/quirks.dm
@@ -10,7 +10,7 @@ GLOBAL_LIST_INIT_TYPED(quirk_blacklist, /list/datum/quirk, list(
list(/datum/quirk/no_taste, /datum/quirk/vegetarian, /datum/quirk/deviant_tastes, /datum/quirk/gamer),
list(/datum/quirk/pineapple_liker, /datum/quirk/pineapple_hater, /datum/quirk/gamer),
list(/datum/quirk/alcohol_tolerance, /datum/quirk/light_drinker),
- list(/datum/quirk/item_quirk/clown_enjoyer, /datum/quirk/item_quirk/mime_fan, /datum/quirk/item_quirk/pride_pin),
+ list(/datum/quirk/item_quirk/clown_enjoyer, /datum/quirk/item_quirk/mime_fan),
list(/datum/quirk/bad_touch, /datum/quirk/friendly),
list(/datum/quirk/extrovert, /datum/quirk/introvert),
list(/datum/quirk/prosthetic_limb, /datum/quirk/quadruple_amputee, /datum/quirk/transhumanist, /datum/quirk/body_purist),
diff --git a/code/controllers/subsystem/ticker.dm b/code/controllers/subsystem/ticker.dm
index 2e2fd930ba1..2885a087df8 100644
--- a/code/controllers/subsystem/ticker.dm
+++ b/code/controllers/subsystem/ticker.dm
@@ -457,13 +457,6 @@ SUBSYSTEM_DEF(ticker)
new_player_mob.client.prefs.hardcore_random_setup(new_player_living)
SSquirks.AssignQuirks(new_player_living, new_player_mob.client)
- //SKYRAT EDIT ADDITION
- if(ishuman(new_player_living))
- for(var/datum/loadout_item/item as anything in loadout_list_to_datums(new_player_mob.client?.prefs?.loadout_list))
- if (item.restricted_roles && length(item.restricted_roles) && !(player_assigned_role.title in item.restricted_roles))
- continue
- item.post_equip_item(new_player_mob.client?.prefs, new_player_living)
- //SKYRAT EDIT END
CHECK_TICK
if(captainless)
diff --git a/code/datums/quirks/neutral_quirks/pride_pin.dm b/code/datums/quirks/neutral_quirks/pride_pin.dm
deleted file mode 100644
index 488c0a2bccb..00000000000
--- a/code/datums/quirks/neutral_quirks/pride_pin.dm
+++ /dev/null
@@ -1,19 +0,0 @@
-/datum/quirk/item_quirk/pride_pin
- name = "Pride Pin"
- desc = "Show off your pride with this changing pride pin!"
- icon = FA_ICON_RAINBOW
- value = 0
- gain_text = span_notice("You feel fruity.")
- lose_text = span_danger("You feel only slightly less fruity than before.")
- medical_record_text = "Patient appears to be fruity."
-
-/datum/quirk/item_quirk/pride_pin/add_unique(client/client_source)
- var/obj/item/clothing/accessory/pride/pin = new(get_turf(quirk_holder))
-
- var/pride_choice = client_source?.prefs?.read_preference(/datum/preference/choiced/pride_pin) || assoc_to_keys(GLOB.pride_pin_reskins)[1]
- var/pride_reskin = GLOB.pride_pin_reskins[pride_choice]
-
- pin.current_skin = pride_choice
- pin.icon_state = pride_reskin
-
- give_item_to_holder(pin, list(LOCATION_BACKPACK = ITEM_SLOT_BACKPACK, LOCATION_HANDS = ITEM_SLOT_HANDS))
diff --git a/code/game/gamemodes/objective.dm b/code/game/gamemodes/objective.dm
index a67e48f041c..21b2da3b9c7 100644
--- a/code/game/gamemodes/objective.dm
+++ b/code/game/gamemodes/objective.dm
@@ -7,7 +7,7 @@ GLOBAL_LIST_EMPTY(objectives) //SKYRAT EDIT ADDITION
var/name = "generic objective" //Name for admin prompts
var/explanation_text = "Nothing" //What that person is supposed to do.
///if this objective doesn't print failure or success in the roundend report
- var/no_failure = FALSE
+ var/no_failure = FALSE
///name used in printing this objective (Objective #1)
var/objective_name = "Objective"
var/team_explanation_text //For when there are multiple owners.
@@ -699,6 +699,9 @@ GLOBAL_LIST_EMPTY(possible_items)
var/list/all_items = M.current.get_all_contents() //this should get things in cheesewheels, books, etc.
for(var/obj/I in all_items) //Check for items
+ if(HAS_TRAIT(I, TRAIT_ITEM_OBJECTIVE_BLOCKED))
+ continue
+
if(istype(I, steal_target))
if(!targetinfo) //If there's no targetinfo, then that means it was a custom objective. At this point, we know you have the item, so return 1.
return TRUE
diff --git a/code/game/gamemodes/objective_items.dm b/code/game/gamemodes/objective_items.dm
index 3dddc560e6a..2e82e549cd5 100644
--- a/code/game/gamemodes/objective_items.dm
+++ b/code/game/gamemodes/objective_items.dm
@@ -5,7 +5,7 @@
//Contains the target item datums for Steal objectives.
/datum/objective_item
/// How the item is described in the objective
- var/name = "A silly bike horn! Honk!"
+ var/name = "a silly bike horn! Honk!"
/// Typepath of item
var/targetitem = /obj/item/bikehorn
/// Valid containers that the target item can be in.
@@ -570,7 +570,7 @@
// A number of special early-game steal objectives intended to be used with the steal-and-destroy objective.
// They're basically items of utility or emotional value that may be found on many players or lying around the station.
/datum/objective_item/steal/traitor/insuls
- name = "insulated gloves"
+ name = "some insulated gloves"
targetitem = /obj/item/clothing/gloves/color/yellow
excludefromjob = list(JOB_CARGO_TECHNICIAN, JOB_QUARTERMASTER, JOB_ATMOSPHERIC_TECHNICIAN, JOB_STATION_ENGINEER, JOB_CHIEF_ENGINEER)
item_owner = list(JOB_STATION_ENGINEER, JOB_CHIEF_ENGINEER)
@@ -582,7 +582,7 @@
return add_item_to_steal(src, /obj/item/clothing/gloves/color/yellow)
/datum/objective_item/steal/traitor/moth_plush
- name = "cute moth plush toy"
+ name = "a cute moth plush toy"
targetitem = /obj/item/toy/plush/moth
excludefromjob = list(JOB_PSYCHOLOGIST, JOB_PARAMEDIC, JOB_CHEMIST, JOB_MEDICAL_DOCTOR, JOB_CHIEF_MEDICAL_OFFICER, JOB_CORONER)
exists_on_map = TRUE
@@ -593,7 +593,7 @@
return add_item_to_steal(src, /obj/item/toy/plush/moth)
/datum/objective_item/steal/traitor/lizard_plush
- name = "cute lizard plush toy"
+ name = "a cute lizard plush toy"
targetitem = /obj/item/toy/plush/lizard_plushie
exists_on_map = TRUE
difficulty = 1
@@ -637,7 +637,7 @@
return add_item_to_steal(src, /obj/item/book/manual/wiki/security_space_law)
/datum/objective_item/steal/traitor/rpd
- name = "rapid pipe dispenser"
+ name = "a rapid pipe dispenser"
targetitem = /obj/item/pipe_dispenser
excludefromjob = list(
JOB_ATMOSPHERIC_TECHNICIAN,
@@ -683,7 +683,7 @@
objective_type = OBJECTIVE_ITEM_TYPE_SPY
/datum/objective_item/steal/spy/lamarr
- name = "The Research Director's pet headcrab"
+ name = "the Research Director's pet headcrab"
targetitem = /obj/item/clothing/mask/facehugger/lamarr
excludefromjob = list(JOB_RESEARCH_DIRECTOR)
exists_on_map = TRUE
@@ -813,7 +813,7 @@
return add_item_to_steal(src, /obj/item/stamp/head)
/datum/objective_item/steal/spy/sunglasses
- name = "sunglasses"
+ name = "some sunglasses"
targetitem = /obj/item/clothing/glasses/sunglasses
excludefromjob = list(
JOB_CAPTAIN,
@@ -832,7 +832,7 @@
You can also obtain a pair from dissassembling hudglasses."
/datum/objective_item/steal/spy/ce_modsuit
- name = "the cheif engineer's advanced MOD control unit"
+ name = "the chief engineer's advanced MOD control unit"
targetitem = /obj/item/mod/control/pre_equipped/advanced
excludefromjob = list(JOB_CHIEF_ENGINEER)
exists_on_map = TRUE
diff --git a/code/game/objects/items/plushes.dm b/code/game/objects/items/plushes.dm
index 3d3c975102f..c56e1eb7cdc 100644
--- a/code/game/objects/items/plushes.dm
+++ b/code/game/objects/items/plushes.dm
@@ -532,6 +532,11 @@
desc = "An adorable stuffed toy that resembles a green lizardperson. This one fills you with nostalgia and soul."
greyscale_colors = "#66ff33#000000"
+/obj/item/toy/plush/lizard_plushie/greyscale
+ desc = "An adorable stuffed toy that resembles a lizardperson. This one has been custom made."
+ greyscale_colors = "#d3d3d3#000000"
+ flags_1 = IS_PLAYER_COLORABLE_1
+
/obj/item/toy/plush/lizard_plushie/space
name = "space lizard plushie"
desc = "An adorable stuffed toy that resembles a very determined spacefaring lizardperson. To infinity and beyond, little guy."
diff --git a/code/modules/admin/verbs/mapping.dm b/code/modules/admin/verbs/mapping.dm
index 69dd533e097..809413e2796 100644
--- a/code/modules/admin/verbs/mapping.dm
+++ b/code/modules/admin/verbs/mapping.dm
@@ -210,10 +210,11 @@ ADMIN_VERB(create_mapping_job_icons, R_DEBUG, "Generate job landmarks icons", "G
for(var/obj/item/I in D)
qdel(I)
randomize_human(D)
- // SKYRAT EDIT CHANGE START - ORIGINAL: D.dress_up_as_job(JB, TRUE)
- if(JB.outfit)
- D.equipOutfit(JB.outfit, TRUE)
- // SKYRAT EDIT CHANGE END
+ D.dress_up_as_job(
+ equipping = JB,
+ visual_only = TRUE,
+ consistent = TRUE,
+ )
var/icon/I = icon(getFlatIcon(D), frame = 1)
job_key_to_icon[JB.title] = I // SKYRAT EDIT CHANGE - ORIGINAL: final.Insert(I, JB.title)
qdel(D)
diff --git a/code/modules/antagonists/spy/spy_bounty.dm b/code/modules/antagonists/spy/spy_bounty.dm
index 0a9422e07b8..28984ce2272 100644
--- a/code/modules/antagonists/spy/spy_bounty.dm
+++ b/code/modules/antagonists/spy/spy_bounty.dm
@@ -219,6 +219,8 @@
continue
if(!is_station_level(thing_turf.z) && !is_mining_level(thing_turf.z))
continue
+ if(HAS_TRAIT(existing_thing, TRAIT_ITEM_OBJECTIVE_BLOCKED))
+ continue
all_valid_existing_things += existing_thing
if(!length(all_valid_existing_things))
@@ -253,16 +255,14 @@
return FALSE
desired_item = pick(valid_possible_items)
- // We need to do some snowflake for items that do exist vs generic items
- var/list/obj/item/existing_items = GLOB.steal_item_handler.objectives_by_path[desired_item.targetitem]
- var/obj/item/the_item = length(existing_items) ? pick(existing_items) : desired_item.targetitem
- var/the_item_name = istype(the_item) ? the_item.name : initial(the_item.name)
- name = "[the_item_name] [difficulty == SPY_DIFFICULTY_HARD ? "Grand ":""]Theft"
- help = "Steal any [the_item_name][desired_item.steal_hint ? ": [desired_item.steal_hint]" : "."]"
+ name = "[desired_item.name] [difficulty == SPY_DIFFICULTY_HARD ? "Grand ":""]Theft"
+ help = "Steal [desired_item.name][desired_item.steal_hint ? ": [desired_item.steal_hint]" : "."]"
return TRUE
/datum/spy_bounty/objective_item/is_stealable(atom/movable/stealing)
- return istype(stealing, desired_item.targetitem) && desired_item.check_special_completion(stealing)
+ return istype(stealing, desired_item.targetitem) \
+ && !HAS_TRAIT(stealing, TRAIT_ITEM_OBJECTIVE_BLOCKED) \
+ && desired_item.check_special_completion(stealing)
/datum/spy_bounty/objective_item/random_easy
difficulty = SPY_DIFFICULTY_EASY
diff --git a/code/modules/antagonists/traitor/objectives/steal.dm b/code/modules/antagonists/traitor/objectives/steal.dm
index b8e62beefea..fdcd693fed8 100644
--- a/code/modules/antagonists/traitor/objectives/steal.dm
+++ b/code/modules/antagonists/traitor/objectives/steal.dm
@@ -29,6 +29,8 @@ GLOBAL_DATUM_INIT(steal_item_handler, /datum/objective_item_handler, new())
/datum/objective_item_handler/proc/new_item_created(datum/source, obj/item/item)
SIGNAL_HANDLER
+ if(HAS_TRAIT(item, TRAIT_ITEM_OBJECTIVE_BLOCKED))
+ return
if(!generated_items)
item.add_stealing_item_objective()
return
@@ -224,6 +226,8 @@ GLOBAL_DATUM_INIT(steal_item_handler, /datum/objective_item_handler, new())
/datum/traitor_objective/steal_item/proc/handle_special_case(obj/item/source, obj/item/target)
SIGNAL_HANDLER
+ if(HAS_TRAIT(target, TRAIT_ITEM_OBJECTIVE_BLOCKED))
+ return COMPONENT_FORCE_FAIL_PLACEMENT
if(istype(target, target_item.targetitem))
if(!target_item.check_special_completion(target))
return COMPONENT_FORCE_FAIL_PLACEMENT
diff --git a/code/modules/client/client_procs.dm b/code/modules/client/client_procs.dm
index 0942520e73c..7b8f81eb3c6 100644
--- a/code/modules/client/client_procs.dm
+++ b/code/modules/client/client_procs.dm
@@ -610,7 +610,6 @@ GLOBAL_LIST_INIT(blacklisted_builds, list(
QDEL_NULL(view_size)
QDEL_NULL(void)
QDEL_NULL(tooltips)
- QDEL_NULL(open_loadout_ui) //SKYRAT EDIT ADDITION
QDEL_NULL(loot_panel)
QDEL_NULL(parallax_rock)
QDEL_LIST(parallax_layers_cached)
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index a242e27d21c..c38797e8116 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -263,7 +263,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character_preview_view.dir = turn(character_preview_view.dir, -90)
*/ // ORIGINAL END - SKYRAT EDIT START:
var/backwards = params["backwards"]
- character_preview_view.dir = turn(character_preview_view.dir, backwards ? 90 : -90)
+ character_preview_view.setDir(turn(character_preview_view.dir, backwards ? 90 : -90))
// SKYRAT EDIT END
return TRUE
@@ -325,16 +325,6 @@ GLOBAL_LIST_EMPTY(preferences_datums)
character_preview_view.update_body()
return TRUE
- if ("open_loadout")
- var/datum/loadout_manager/open_loadout_ui = parent.open_loadout_ui?.resolve()
- if(open_loadout_ui)
- open_loadout_ui.ui_interact(usr)
- else
- parent.open_loadout_ui = null
- var/datum/loadout_manager/tgui = new(usr)
- tgui.ui_interact(usr)
- return TRUE
-
if ("open_food")
GLOB.food_prefs_menu.ui_interact(usr)
return TRUE
@@ -454,6 +444,8 @@ GLOBAL_LIST_EMPTY(preferences_datums)
var/mob/living/carbon/human/dummy/body
/// The preferences this refers to
var/datum/preferences/preferences
+ /// Whether we show current job clothes or nude/loadout only
+ var/show_job_clothes = TRUE
/atom/movable/screen/map_view/char_preview/Initialize(mapload, datum/preferences/preferences)
. = ..()
@@ -471,16 +463,14 @@ GLOBAL_LIST_EMPTY(preferences_datums)
create_body()
else
body.wipe_state()
- appearance = preferences.render_new_preview_appearance(body)
+
+ appearance = preferences.render_new_preview_appearance(body, show_job_clothes)
/atom/movable/screen/map_view/char_preview/proc/create_body()
QDEL_NULL(body)
body = new
- // Without this, it doesn't show up in the menu
- body.appearance_flags |= KEEP_TOGETHER // SKYRAT EDIT - Fix pixel scaling - ORIGINAL: body.appearance_flags &= ~KEEP_TOGETHER
-
/datum/preferences/proc/create_character_profiles()
var/list/profiles = list()
diff --git a/code/modules/client/preferences/_preference.dm b/code/modules/client/preferences/_preference.dm
index 1f71601ebf0..401b4a20bea 100644
--- a/code/modules/client/preferences/_preference.dm
+++ b/code/modules/client/preferences/_preference.dm
@@ -18,11 +18,16 @@
/// support the "use gender" option.
#define PREFERENCE_PRIORITY_BODY_TYPE 5
+/// Equpping items based on preferences.
+/// Should happen after species and body type to make sure it looks right.
+/// Mostly redundant, but a safety net for saving/loading.
+#define PREFERENCE_PRIORITY_LOADOUT 6
+
/// The priority at which names are decided, needed for proper randomization.
-#define PREFERENCE_PRIORITY_NAMES 6
+#define PREFERENCE_PRIORITY_NAMES 7
/// Preferences that aren't names, but change the name changes set by PREFERENCE_PRIORITY_NAMES.
-#define PREFERENCE_PRIORITY_NAME_MODIFICATIONS 7
+#define PREFERENCE_PRIORITY_NAME_MODIFICATIONS 8
/// The maximum preference priority, keep this updated, but don't use it for `priority`.
#define MAX_PREFERENCE_PRIORITY PREFERENCE_PRIORITY_NAME_MODIFICATIONS
diff --git a/code/modules/client/preferences/migrations/quirk_loadout_migration.dm b/code/modules/client/preferences/migrations/quirk_loadout_migration.dm
new file mode 100644
index 00000000000..52fcd993c57
--- /dev/null
+++ b/code/modules/client/preferences/migrations/quirk_loadout_migration.dm
@@ -0,0 +1,27 @@
+/**
+ * Move quirk items into loadout items
+ *
+ * If this is accompanied with removal of a quirk,
+ * you don't need to worry about handling that here -
+ * quirk sanitization happens AFTER migration
+ */
+/datum/preferences/proc/migrate_quirk_to_loadout(quirk_to_migrate, new_typepath, list/data_to_migrate)
+ ASSERT(istext(quirk_to_migrate) && ispath(new_typepath, /obj/item))
+ if(quirk_to_migrate in all_quirks)
+ add_loadout_item(new_typepath, data_to_migrate)
+
+/// Helper for slotting in a new loadout item
+/datum/preferences/proc/add_loadout_item(typepath, list/data = list())
+ PRIVATE_PROC(TRUE)
+
+ var/list/loadout_list = read_preference(/datum/preference/loadout) || list()
+ loadout_list[typepath] = data
+ write_preference(GLOB.preference_entries[/datum/preference/loadout], loadout_list)
+
+/// Helper for removing a loadout item
+/datum/preferences/proc/remove_loadout_item(typepath)
+ PRIVATE_PROC(TRUE)
+
+ var/list/loadout_list = read_preference(/datum/preference/loadout)
+ if(loadout_list?.Remove(typepath))
+ write_preference(GLOB.preference_entries[/datum/preference/loadout], loadout_list)
diff --git a/code/modules/client/preferences/pride_pin.dm b/code/modules/client/preferences/pride_pin.dm
deleted file mode 100644
index 326dad69979..00000000000
--- a/code/modules/client/preferences/pride_pin.dm
+++ /dev/null
@@ -1,16 +0,0 @@
-/datum/preference/choiced/pride_pin
- category = PREFERENCE_CATEGORY_SECONDARY_FEATURES
- savefile_key = "pride_pin"
- savefile_identifier = PREFERENCE_CHARACTER
-
-/datum/preference/choiced/pride_pin/init_possible_values()
- return assoc_to_keys(GLOB.pride_pin_reskins)
-
-/datum/preference/choiced/pride_pin/is_accessible(datum/preferences/preferences)
- if (!..(preferences))
- return FALSE
-
- return "Pride Pin" in preferences.all_quirks
-
-/datum/preference/choiced/pride_pin/apply_to_human(mob/living/carbon/human/target, value)
- return
diff --git a/code/modules/client/preferences_savefile.dm b/code/modules/client/preferences_savefile.dm
index e9eb42c3551..698f420a9ef 100644
--- a/code/modules/client/preferences_savefile.dm
+++ b/code/modules/client/preferences_savefile.dm
@@ -5,7 +5,7 @@
// You do not need to raise this if you are adding new values that have sane defaults.
// Only raise this value when changing the meaning/format/name/layout of an existing value
// where you would want the updater procs below to run
-#define SAVEFILE_VERSION_MAX 44
+#define SAVEFILE_VERSION_MAX 45
/*
SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Carn
@@ -105,6 +105,13 @@ SAVEFILE UPDATING/VERSIONING - 'Simplified', or rather, more coder-friendly ~Car
if (current_version < 43)
migrate_legacy_sound_toggles(savefile)
+ if (current_version < 45)
+ migrate_quirk_to_loadout(
+ quirk_to_migrate = "Pride Pin",
+ new_typepath = /obj/item/clothing/accessory/pride,
+ data_to_migrate = list(INFO_RESKIN = save_data?["pride_pin"]),
+ )
+
/// checks through keybindings for outdated unbound keys and updates them
/datum/preferences/proc/check_keybindings()
if(!parent)
diff --git a/code/modules/clothing/head/hat.dm b/code/modules/clothing/head/hat.dm
index eeb7f1653f3..15929ac5f06 100644
--- a/code/modules/clothing/head/hat.dm
+++ b/code/modules/clothing/head/hat.dm
@@ -84,6 +84,8 @@
name = "flat cap"
desc = "A working man's cap."
icon_state = "beret_flat"
+ icon_preview = 'icons/obj/clothing/head/beret.dmi'
+ icon_state_preview = "beret_flat"
greyscale_config = /datum/greyscale_config/beret
greyscale_config_worn = /datum/greyscale_config/beret/worn
greyscale_colors = "#8F7654"
diff --git a/code/modules/clothing/head/jobs.dm b/code/modules/clothing/head/jobs.dm
index 97d31e1d4e6..53f08faaa12 100644
--- a/code/modules/clothing/head/jobs.dm
+++ b/code/modules/clothing/head/jobs.dm
@@ -310,7 +310,7 @@
else
balloon_alert(wearer, "can't put in hands!")
break
-
+
return .
/obj/item/clothing/head/fedora/inspector_hat/attackby(obj/item/item, mob/user, params)
@@ -385,6 +385,8 @@
name = "beret"
desc = "A beret, a mime's favorite headwear."
icon_state = "beret"
+ icon_preview = 'icons/obj/clothing/head/beret.dmi'
+ icon_state_preview = "beret"
dog_fashion = /datum/dog_fashion/head/beret
greyscale_config = /datum/greyscale_config/beret
greyscale_config_worn = /datum/greyscale_config/beret/worn
diff --git a/code/modules/clothing/neck/_neck.dm b/code/modules/clothing/neck/_neck.dm
index d89b2169d28..3ea26de01c5 100644
--- a/code/modules/clothing/neck/_neck.dm
+++ b/code/modules/clothing/neck/_neck.dm
@@ -398,6 +398,8 @@
/obj/item/clothing/neck/large_scarf
name = "large scarf"
icon_state = "large_scarf"
+ icon_preview = 'icons/obj/fluff/previews.dmi'
+ icon_state_preview = "scarf_large"
w_class = WEIGHT_CLASS_TINY
custom_price = PAYCHECK_CREW
greyscale_colors = "#C6C6C6#EEEEEE"
diff --git a/code/modules/clothing/under/accessories/badges.dm b/code/modules/clothing/under/accessories/badges.dm
index 5b2bda98416..0ea3922893a 100644
--- a/code/modules/clothing/under/accessories/badges.dm
+++ b/code/modules/clothing/under/accessories/badges.dm
@@ -175,28 +175,23 @@
name = "Pre-Approved Cyborg Candidate dogtag"
display = "This employee has been screened for negative mental traits to an acceptable level of accuracy, and is approved for the NT Cyborg program as an alternative to medical resuscitation."
-/* MODULAR SKYRAT - OVERRIDDEN IN (\modular_skyrat\modules\customization\modules\clothing\under\accessories.dm)
-/// Reskins for the pride pin accessory, mapped by display name to icon state
-GLOBAL_LIST_INIT(pride_pin_reskins, list(
- "Rainbow Pride" = "pride",
- "Bisexual Pride" = "pride_bi",
- "Pansexual Pride" = "pride_pan",
- "Asexual Pride" = "pride_ace",
- "Non-binary Pride" = "pride_enby",
- "Transgender Pride" = "pride_trans",
- "Intersex Pride" = "pride_intersex",
- "Lesbian Pride" = "pride_lesbian",
-))
-*/
-
/obj/item/clothing/accessory/pride
name = "pride pin"
desc = "A Nanotrasen Diversity & Inclusion Center-sponsored holographic pin to show off your pride, reminding the crew of their unwavering commitment to equity, diversity, and inclusion!"
icon_state = "pride"
obj_flags = UNIQUE_RENAME | INFINITE_RESKIN
+ unique_reskin = list(
+ "Rainbow Pride" = "pride",
+ "Bisexual Pride" = "pride_bi",
+ "Pansexual Pride" = "pride_pan",
+ "Asexual Pride" = "pride_ace",
+ "Non-binary Pride" = "pride_enby",
+ "Transgender Pride" = "pride_trans",
+ "Intersex Pride" = "pride_intersex",
+ "Lesbian Pride" = "pride_lesbian",
+ )
/obj/item/clothing/accessory/pride/setup_reskinning()
- unique_reskin = GLOB.pride_pin_reskins
if(!check_setup_reskinning())
return
diff --git a/code/modules/jobs/job_types/_job.dm b/code/modules/jobs/job_types/_job.dm
index 40ea10b9002..0b8c28d370f 100644
--- a/code/modules/jobs/job_types/_job.dm
+++ b/code/modules/jobs/job_types/_job.dm
@@ -182,7 +182,7 @@
spawned_human.mind.adjust_experience(i, roundstart_experience[i], TRUE)
/// Return the outfit to use
-/datum/job/proc/get_outfit()
+/datum/job/proc/get_outfit(consistent)
return outfit
/// Announce that this job as joined the round to all crew members.
@@ -197,12 +197,12 @@
return TRUE
-/mob/living/proc/on_job_equipping(datum/job/equipping)
+/mob/living/proc/on_job_equipping(datum/job/equipping, client/player_client)
return
#define VERY_LATE_ARRIVAL_TOAST_PROB 20
-/mob/living/carbon/human/on_job_equipping(datum/job/equipping, datum/preferences/used_pref, client/player_client) //SKYRAT EDIT CHANGE - ORIGINAL: /mob/living/carbon/human/on_job_equipping(datum/job/equipping)
+/mob/living/carbon/human/on_job_equipping(datum/job/equipping, client/player_client)
if(equipping.paycheck_department)
var/datum/bank_account/bank_account = new(real_name, equipping, dna.species.payday_modifier)
bank_account.payday(STARTING_PAYCHECKS, TRUE)
@@ -210,7 +210,12 @@
bank_account.replaceable = FALSE
add_mob_memory(/datum/memory/key/account, remembered_id = account_id)
- dress_up_as_job(equipping, FALSE, used_pref) //SKYRAT EDIT CHANGE - ORIGINAL: dress_up_as_job(equipping)
+ dress_up_as_job(
+ equipping = equipping,
+ visual_only = FALSE,
+ player_client = player_client,
+ consistent = FALSE,
+ )
if(EMERGENCY_PAST_POINT_OF_NO_RETURN && prob(VERY_LATE_ARRIVAL_TOAST_PROB))
//equipping.equip_to_slot_or_del(new /obj/item/food/griddle_toast(equipping), ITEM_SLOT_MASK) // SKYRAT EDIT REMOVAL - See below
@@ -223,12 +228,12 @@
#undef VERY_LATE_ARRIVAL_TOAST_PROB
-/mob/living/proc/dress_up_as_job(datum/job/equipping, visual_only = FALSE)
+/mob/living/proc/dress_up_as_job(datum/job/equipping, visual_only = FALSE, client/player_client, consistent = FALSE)
return
-/mob/living/carbon/human/dress_up_as_job(datum/job/equipping, visual_only = FALSE, datum/preferences/used_pref) //SKYRAT EDIT CHANGE
+/mob/living/carbon/human/dress_up_as_job(datum/job/equipping, visual_only = FALSE, client/player_client, consistent = FALSE)
dna.species.pre_equip_species_outfit(equipping, src, visual_only)
- equip_outfit_and_loadout(equipping.get_outfit(), used_pref, visual_only, equipping) //SKYRAT EDIT CHANGE
+ equip_outfit_and_loadout(equipping.get_outfit(consistent), player_client?.prefs, visual_only, equipping) // SKYRAT EDIT CHANGE - Add equipping param
// Original: /datum/job/proc/announce_head(mob/living/carbon/human/H, channels) //tells the given channel that the given mob is the new department head. See communications.dm for valid channels.
/datum/job/proc/announce_head(mob/living/carbon/human/H, channels, job_title) // SKYRAT EDIT CHANGE - ALTERNATIVE_JOB_TITLES
diff --git a/code/modules/jobs/job_types/assistant/assistant.dm b/code/modules/jobs/job_types/assistant/assistant.dm
index 45c439c1957..4e25f6a35b4 100644
--- a/code/modules/jobs/job_types/assistant/assistant.dm
+++ b/code/modules/jobs/job_types/assistant/assistant.dm
@@ -37,7 +37,9 @@ Assistant
rpg_title = "Lout"
config_tag = "ASSISTANT"
-/datum/job/assistant/get_outfit()
+/datum/job/assistant/get_outfit(consistent)
+ if(consistent)
+ return /datum/outfit/job/assistant/consistent
if(!HAS_TRAIT(SSstation, STATION_TRAIT_ASSISTANT_GIMMICKS))
return ..()
diff --git a/code/modules/loadout/categories/accessories.dm b/code/modules/loadout/categories/accessories.dm
new file mode 100644
index 00000000000..4a180bc3745
--- /dev/null
+++ b/code/modules/loadout/categories/accessories.dm
@@ -0,0 +1,94 @@
+/// Accessory Items (Moves overrided items to backpack)
+/datum/loadout_category/accessories
+ category_name = "Accessory"
+ category_ui_icon = FA_ICON_VEST
+ type_to_generate = /datum/loadout_item/accessory
+ tab_order = /datum/loadout_category/head::tab_order + 3
+
+/datum/loadout_item/accessory
+ abstract_type = /datum/loadout_item/accessory
+ /// Can we adjust this accessory to be above or below suits?
+ VAR_FINAL/can_be_layer_adjusted = FALSE
+
+/datum/loadout_item/accessory/New()
+ . = ..()
+ if(ispath(item_path, /obj/item/clothing/accessory))
+ can_be_layer_adjusted = TRUE
+
+/datum/loadout_item/accessory/get_ui_buttons()
+ if(!can_be_layer_adjusted)
+ return ..()
+
+ var/list/buttons = ..()
+
+ UNTYPED_LIST_ADD(buttons, list(
+ "label" = "Layer",
+ "act_key" = "set_layer",
+ "active_key" = INFO_LAYER,
+ "active_text" = "Above Suit",
+ "inactive_text" = "Below Suit",
+ ))
+
+ return buttons
+
+/datum/loadout_item/accessory/handle_loadout_action(datum/preference_middleware/loadout/manager, mob/user, action, params)
+ if(action == "set_layer")
+ return set_accessory_layer(manager, user)
+
+ return ..()
+
+/datum/loadout_item/accessory/proc/set_accessory_layer(datum/preference_middleware/loadout/manager, mob/user)
+ if(!can_be_layer_adjusted)
+ return FALSE
+
+ var/list/loadout = manager.preferences.read_preference(/datum/preference/loadout)
+ if(!loadout?[item_path])
+ return FALSE
+
+ if(isnull(loadout[item_path][INFO_LAYER]))
+ loadout[item_path][INFO_LAYER] = FALSE
+
+ loadout[item_path][INFO_LAYER] = !loadout[item_path][INFO_LAYER]
+ manager.preferences.update_preference(GLOB.preference_entries[/datum/preference/loadout], loadout)
+ return TRUE // Update UI
+
+/datum/loadout_item/accessory/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, loadout_placement_preference) // SKYRAT EDIT CHANGE - Added loadout_placement_preference
+ // SKYRAT EDIT CHANGE
+ if(loadout_placement_preference != LOADOUT_OVERRIDE_JOB && outfit.accessory)
+ LAZYADD(outfit.backpack_contents, outfit.accessory)
+ // SKYRAT EDIT END
+ 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,
+)
+ . = ..()
+ if(istype(equipped_item))
+ equipped_item.above_suit = !!preference_list[item_path]?[INFO_LAYER]
+ . |= (ITEM_SLOT_OCLOTHING|ITEM_SLOT_ICLOTHING)
+
+/datum/loadout_item/accessory/maid_apron
+ name = "Maid Apron"
+ item_path = /obj/item/clothing/accessory/maidapron
+
+/datum/loadout_item/accessory/waistcoat
+ name = "Waistcoat"
+ item_path = /obj/item/clothing/accessory/waistcoat
+
+/datum/loadout_item/accessory/pocket_protector
+ name = "Pocket Protector"
+ item_path = /obj/item/clothing/accessory/pocketprotector
+
+/datum/loadout_item/accessory/full_pocket_protector
+ name = "Pocket Protector (Filled)"
+ item_path = /obj/item/clothing/accessory/pocketprotector/full
+ additional_displayed_text = list("Contains pens")
+
+/datum/loadout_item/accessory/pride
+ name = "Pride Pin"
+ item_path = /obj/item/clothing/accessory/pride
+ can_be_reskinned = TRUE
diff --git a/code/modules/loadout/categories/glasses.dm b/code/modules/loadout/categories/glasses.dm
new file mode 100644
index 00000000000..75c16e74d45
--- /dev/null
+++ b/code/modules/loadout/categories/glasses.dm
@@ -0,0 +1,57 @@
+/// Glasses Slot Items (Moves overrided items to backpack)
+/datum/loadout_category/glasses
+ category_name = "Glasses"
+ category_ui_icon = FA_ICON_GLASSES
+ type_to_generate = /datum/loadout_item/glasses
+ tab_order = /datum/loadout_category/head::tab_order + 1
+
+/datum/loadout_item/glasses
+ abstract_type = /datum/loadout_item/glasses
+
+/datum/loadout_item/glasses/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, loadout_placement_preference) // SKYRAT EDIT CHANGE - Added loadout_placement
+ // SKYRAT EDIT CHANGE
+ if(loadout_placement_preference != LOADOUT_OVERRIDE_JOB && outfit.glasses)
+ LAZYADD(outfit.backpack_contents, outfit.glasses)
+ // SKYRAT EDIT END
+ outfit.glasses = item_path
+
+/datum/loadout_item/glasses/prescription_glasses
+ name = "Glasses"
+ item_path = /obj/item/clothing/glasses/regular
+ additional_displayed_text = list("Prescription")
+
+/datum/loadout_item/glasses/prescription_glasses/circle_glasses
+ name = "Circle Glasses"
+ item_path = /obj/item/clothing/glasses/regular/circle
+
+/datum/loadout_item/glasses/prescription_glasses/hipster_glasses
+ name = "Hipster Glasses"
+ item_path = /obj/item/clothing/glasses/regular/hipster
+
+/datum/loadout_item/glasses/prescription_glasses/jamjar_glasses
+ name = "Jamjar Glasses"
+ item_path = /obj/item/clothing/glasses/regular/jamjar
+
+/datum/loadout_item/glasses/black_blindfold
+ name = "Black Blindfold"
+ item_path = /obj/item/clothing/glasses/blindfold
+
+/datum/loadout_item/glasses/cold_glasses
+ name = "Cold Glasses"
+ item_path = /obj/item/clothing/glasses/cold
+
+/datum/loadout_item/glasses/heat_glasses
+ name = "Heat Glasses"
+ item_path = /obj/item/clothing/glasses/heat
+
+/datum/loadout_item/glasses/orange_glasses
+ name = "Orange Glasses"
+ item_path = /obj/item/clothing/glasses/orange
+
+/datum/loadout_item/glasses/red_glasses
+ name = "Red Glasses"
+ item_path = /obj/item/clothing/glasses/red
+
+/datum/loadout_item/glasses/eyepatch
+ name = "Eyepatch"
+ item_path = /obj/item/clothing/glasses/eyepatch
diff --git a/code/modules/loadout/categories/heads.dm b/code/modules/loadout/categories/heads.dm
new file mode 100644
index 00000000000..5d491cc63c5
--- /dev/null
+++ b/code/modules/loadout/categories/heads.dm
@@ -0,0 +1,142 @@
+/// Head Slot Items (Deletes overrided items)
+/datum/loadout_category/head
+ category_name = "Head"
+ category_ui_icon = FA_ICON_HAT_COWBOY
+ type_to_generate = /datum/loadout_item/head
+ tab_order = 1
+
+/datum/loadout_item/head
+ abstract_type = /datum/loadout_item/head
+
+/datum/loadout_item/head/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, loadout_placement_preference) // SKYRAT EDIT CHANGE - Added loadout_placement_preference
+ if(equipper.dna?.species?.outfit_important_for_life)
+ if(!visuals_only)
+ to_chat(equipper, "Your loadout helmet was not equipped directly due to your species outfit.")
+ LAZYADD(outfit.backpack_contents, item_path)
+ else
+ // SKYRAT EDIT ADDITION
+ if(loadout_placement_preference != LOADOUT_OVERRIDE_JOB && outfit.head)
+ LAZYADD(outfit.backpack_contents, outfit.head)
+ // SKYRAT EDIT END
+ outfit.head = item_path
+
+/datum/loadout_item/head/beanie
+ name = "Beanie (Colorable)"
+ item_path = /obj/item/clothing/head/beanie
+
+/datum/loadout_item/head/fancy_cap
+ name = "Fancy Hat (Colorable)"
+ item_path = /obj/item/clothing/head/costume/fancy
+
+/datum/loadout_item/head/red_beret
+ name = "Red Beret (Colorable)"
+ item_path = /obj/item/clothing/head/beret
+
+/datum/loadout_item/head/black_cap
+ name = "Cap (Black)"
+ item_path = /obj/item/clothing/head/soft/black
+
+/datum/loadout_item/head/blue_cap
+ name = "Cap (Blue)"
+ item_path = /obj/item/clothing/head/soft/blue
+
+/datum/loadout_item/head/delinquent_cap
+ name = "Cap (Delinquent)"
+ item_path = /obj/item/clothing/head/costume/delinquent
+
+/datum/loadout_item/head/green_cap
+ name = "Cap (Green)"
+ item_path = /obj/item/clothing/head/soft/green
+
+/datum/loadout_item/head/grey_cap
+ name = "Cap (Grey)"
+ item_path = /obj/item/clothing/head/soft/grey
+
+/datum/loadout_item/head/orange_cap
+ name = "Cap (Orange)"
+ item_path = /obj/item/clothing/head/soft/orange
+
+/datum/loadout_item/head/purple_cap
+ name = "Cap (Purple)"
+ item_path = /obj/item/clothing/head/soft/purple
+
+/datum/loadout_item/head/rainbow_cap
+ name = "Cap (Rainbow)"
+ item_path = /obj/item/clothing/head/soft/rainbow
+
+/datum/loadout_item/head/red_cap
+ name = "Cap (Red)"
+ item_path = /obj/item/clothing/head/soft/red
+
+/datum/loadout_item/head/white_cap
+ name = "Cap (White)"
+ item_path = /obj/item/clothing/head/soft
+
+/datum/loadout_item/head/yellow_cap
+ name = "Cap (Yellow)"
+ item_path = /obj/item/clothing/head/soft/yellow
+
+/datum/loadout_item/head/flatcap
+ name = "Cap (Flat)"
+ item_path = /obj/item/clothing/head/flatcap
+
+/datum/loadout_item/head/beige_fedora
+ name = "Fedora (Beige)"
+ item_path = /obj/item/clothing/head/fedora/beige
+
+/datum/loadout_item/head/black_fedora
+ name = "Fedora (Black)"
+ item_path = /obj/item/clothing/head/fedora
+
+/datum/loadout_item/head/white_fedora
+ name = "Fedora (White)"
+ item_path = /obj/item/clothing/head/fedora/white
+
+/datum/loadout_item/head/mail_cap
+ name = "Cap (Mail)"
+ item_path = /obj/item/clothing/head/costume/mailman
+
+/datum/loadout_item/head/kitty_ears
+ name = "Kitty Ears"
+ item_path = /obj/item/clothing/head/costume/kitty
+
+/datum/loadout_item/head/rabbit_ears
+ name = "Rabbit Ears"
+ item_path = /obj/item/clothing/head/costume/rabbitears
+
+/datum/loadout_item/head/bandana
+ name = "Bandana Thin"
+ item_path = /obj/item/clothing/head/costume/tmc
+
+/datum/loadout_item/head/rastafarian
+ name = "Cap (Rastafarian)"
+ item_path = /obj/item/clothing/head/rasta
+
+/datum/loadout_item/head/top_hat
+ name = "Top Hat"
+ item_path = /obj/item/clothing/head/hats/tophat
+
+/datum/loadout_item/head/bowler_hat
+ name = "Bowler Hat"
+ item_path = /obj/item/clothing/head/hats/bowler
+
+/datum/loadout_item/head/bear_pelt
+ name = "Bear Pelt"
+ item_path = /obj/item/clothing/head/costume/bearpelt
+
+/datum/loadout_item/head/ushanka
+ name ="Ushanka"
+ item_path = /obj/item/clothing/head/costume/ushanka
+
+/datum/loadout_item/head/plague_doctor
+ name = "Cap (Plague Doctor)"
+ item_path = /obj/item/clothing/head/bio_hood/plague
+
+/datum/loadout_item/head/rose
+ name = "Rose"
+ item_path = /obj/item/food/grown/rose
+
+/datum/loadout_item/head/wig
+ name = "Wig"
+ item_path = /obj/item/clothing/head/wig/natural
+ additional_displayed_text = list("Hair Color")
diff --git a/code/modules/loadout/categories/inhands.dm b/code/modules/loadout/categories/inhands.dm
new file mode 100644
index 00000000000..8ddc15676ab
--- /dev/null
+++ b/code/modules/loadout/categories/inhands.dm
@@ -0,0 +1,33 @@
+/// Inhand items (Moves overrided items to backpack)
+/datum/loadout_category/inhands
+ category_name = "Inhand"
+ category_ui_icon = FA_ICON_BRIEFCASE
+ type_to_generate = /datum/loadout_item/inhand
+ tab_order = /datum/loadout_category/head::tab_order + 4
+
+/datum/loadout_item/inhand
+ abstract_type = /datum/loadout_item/inhand
+
+/datum/loadout_item/inhand/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE)
+ if(outfit.l_hand && !outfit.r_hand)
+ outfit.r_hand = item_path
+ else
+ if(outfit.l_hand)
+ LAZYADD(outfit.backpack_contents, outfit.l_hand)
+ outfit.l_hand = item_path
+
+/datum/loadout_item/inhand/cane
+ name = "Cane"
+ item_path = /obj/item/cane
+
+/datum/loadout_item/inhand/cane_white
+ name = "White Cane"
+ item_path = /obj/item/cane/white
+
+/datum/loadout_item/inhand/briefcase
+ name = "Briefcase (Leather)"
+ item_path = /obj/item/storage/briefcase
+
+/datum/loadout_item/inhand/briefcase_secure
+ name = "Briefcase (Secure)"
+ item_path = /obj/item/storage/briefcase/secure
diff --git a/code/modules/loadout/categories/neck.dm b/code/modules/loadout/categories/neck.dm
new file mode 100644
index 00000000000..04a42a19da1
--- /dev/null
+++ b/code/modules/loadout/categories/neck.dm
@@ -0,0 +1,40 @@
+/// Neck Slot Items (Deletes overrided items)
+/datum/loadout_category/neck
+ category_name = "Neck"
+ category_ui_icon = FA_ICON_USER_TIE
+ type_to_generate = /datum/loadout_item/neck
+ tab_order = /datum/loadout_category/head::tab_order + 2
+
+/datum/loadout_item/neck
+ abstract_type = /datum/loadout_item/neck
+
+/datum/loadout_item/neck/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, loadout_placement_preference)
+ // SKYRAT EDIT CHANGE
+ if(loadout_placement_preference != LOADOUT_OVERRIDE_JOB && outfit.neck)
+ LAZYADD(outfit.backpack_contents, outfit.neck)
+ outfit.neck = item_path
+ // SKYRAT EDIT END
+
+/datum/loadout_item/neck/scarf_greyscale
+ name = "Scarf (Colorable)"
+ item_path = /obj/item/clothing/neck/scarf
+
+/datum/loadout_item/neck/greyscale_large
+ name = "Scarf (Large, Colorable)"
+ item_path = /obj/item/clothing/neck/large_scarf
+
+/datum/loadout_item/neck/greyscale_larger
+ name = "Scarf (Larger, Colorable)"
+ item_path = /obj/item/clothing/neck/infinity_scarf
+
+/datum/loadout_item/neck/necktie
+ name = "Necktie (Colorable)"
+ item_path = /obj/item/clothing/neck/tie
+
+/datum/loadout_item/neck/necktie_disco
+ name = "Necktie (Ugly)"
+ item_path = /obj/item/clothing/neck/tie/horrible
+
+/datum/loadout_item/neck/necktie_loose
+ name = "Necktie (Loose)"
+ item_path = /obj/item/clothing/neck/tie/detective
diff --git a/code/modules/loadout/categories/pocket.dm b/code/modules/loadout/categories/pocket.dm
new file mode 100644
index 00000000000..8206192bb81
--- /dev/null
+++ b/code/modules/loadout/categories/pocket.dm
@@ -0,0 +1,204 @@
+/// Pocket items (Moved to backpack)
+/datum/loadout_category/pocket
+ category_name = "Other"
+ category_ui_icon = FA_ICON_QUESTION
+ type_to_generate = /datum/loadout_item/pocket_items
+ tab_order = /datum/loadout_category/head::tab_order + 5
+ /// How many pocket items are allowed
+ VAR_PRIVATE/max_allowed = 2
+
+/datum/loadout_category/pocket/New()
+ . = ..()
+ category_info = "([max_allowed] allowed)"
+
+/datum/loadout_category/pocket/handle_duplicate_entires(
+ datum/preference_middleware/loadout/manager,
+ datum/loadout_item/conflicting_item,
+ datum/loadout_item/added_item,
+ list/datum/loadout_item/all_loadout_items,
+)
+ var/list/datum/loadout_item/pocket_items/other_pocket_items = list()
+ for(var/datum/loadout_item/pocket_items/other_pocket_item in all_loadout_items)
+ other_pocket_items += other_pocket_item
+
+ if(length(other_pocket_items) >= max_allowed)
+ // We only need to deselect something if we're above the limit
+ // (And if we are we prioritize the first item found, FIFO)
+ manager.deselect_item(other_pocket_items[1])
+ return TRUE
+
+/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,
+)
+ // 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
+
+ return ..()
+
+/datum/loadout_item/pocket_items/lipstick_black
+ name = "Lipstick (Black)"
+ item_path = /obj/item/lipstick/black
+ additional_displayed_text = list("Black")
+
+/datum/loadout_item/pocket_items/lipstick_blue
+ name = "Lipstick (Blue)"
+ item_path = /obj/item/lipstick/blue
+ additional_displayed_text = list("Blue")
+
+
+/datum/loadout_item/pocket_items/lipstick_green
+ name = "Lipstick (Green)"
+ item_path = /obj/item/lipstick/green
+ additional_displayed_text = list("Green")
+
+
+/datum/loadout_item/pocket_items/lipstick_jade
+ name = "Lipstick (Jade)"
+ item_path = /obj/item/lipstick/jade
+ additional_displayed_text = list("Jade")
+
+/datum/loadout_item/pocket_items/lipstick_purple
+ name = "Lipstick (Purple)"
+ item_path = /obj/item/lipstick/purple
+ additional_displayed_text = list("Purple")
+
+/datum/loadout_item/pocket_items/lipstick_red
+ name = "Lipstick (Red)"
+ item_path = /obj/item/lipstick
+ additional_displayed_text = list("Red")
+
+/datum/loadout_item/pocket_items/lipstick_white
+ name = "Lipstick (White)"
+ item_path = /obj/item/lipstick/white
+ additional_displayed_text = list("White")
+/* SKYRAT EDIT REMOVAL
+/datum/loadout_item/pocket_items/plush
+ abstract_type = /datum/loadout_item/pocket_items/plush
+ can_be_named = TRUE
+
+/datum/loadout_item/pocket_items/plush/bee
+ name = "Plush (Bee)"
+ item_path = /obj/item/toy/plush/beeplushie
+
+/datum/loadout_item/pocket_items/plush/carp
+ name = "Plush (Carp)"
+ item_path = /obj/item/toy/plush/carpplushie
+
+/datum/loadout_item/pocket_items/plush/lizard_greyscale
+ name = "Plush (Lizard, Colorable)"
+ item_path = /obj/item/toy/plush/lizard_plushie/greyscale
+
+/datum/loadout_item/pocket_items/plush/lizard_random
+ name = "Plush (Lizard, Random)"
+ can_be_greyscale = DONT_GREYSCALE
+ item_path = /obj/item/toy/plush/lizard_plushie
+ additional_displayed_text = list("Random color")
+
+/datum/loadout_item/pocket_items/plush/moth
+ name = "Plush (Moth)"
+ item_path = /obj/item/toy/plush/moth
+
+/datum/loadout_item/pocket_items/plush/narsie
+ name = "Plush (Nar'sie)"
+ item_path = /obj/item/toy/plush/narplush
+
+/datum/loadout_item/pocket_items/plush/nukie
+ name = "Plush (Nukie)"
+ item_path = /obj/item/toy/plush/nukeplushie
+
+/datum/loadout_item/pocket_items/plush/peacekeeper
+ name = "Plush (Peacekeeper)"
+ item_path = /obj/item/toy/plush/pkplush
+
+/datum/loadout_item/pocket_items/plush/plasmaman
+ name = "Plush (Plasmaman)"
+ item_path = /obj/item/toy/plush/plasmamanplushie
+
+/datum/loadout_item/pocket_items/plush/ratvar
+ name = "Plush (Ratvar)"
+ item_path = /obj/item/toy/plush/ratplush
+
+/datum/loadout_item/pocket_items/plush/rouny
+ name = "Plush (Rouny)"
+ item_path = /obj/item/toy/plush/rouny
+
+/datum/loadout_item/pocket_items/plush/snake
+ name = "Plush (Snake)"
+ item_path = /obj/item/toy/plush/snakeplushie
+
+/datum/loadout_item/pocket_items/card_binder
+ name = "Card Binder"
+ item_path = /obj/item/storage/card_binder
+
+/datum/loadout_item/pocket_items/card_deck
+ name = "Playing Card Deck"
+ item_path = /obj/item/toy/cards/deck
+
+/datum/loadout_item/pocket_items/kotahi_deck
+ name = "Kotahi Deck"
+ item_path = /obj/item/toy/cards/deck/kotahi
+
+/datum/loadout_item/pocket_items/wizoff_deck
+ name = "Wizoff Deck"
+ item_path = /obj/item/toy/cards/deck/wizoff
+
+/datum/loadout_item/pocket_items/dice_bag
+ name = "Dice Bag"
+ item_path = /obj/item/storage/dice
+
+/datum/loadout_item/pocket_items/d1
+ name = "D1"
+ item_path = /obj/item/dice/d1
+
+/datum/loadout_item/pocket_items/d2
+ name = "D2"
+ item_path = /obj/item/dice/d2
+
+/datum/loadout_item/pocket_items/d4
+ name = "D4"
+ item_path = /obj/item/dice/d4
+
+/datum/loadout_item/pocket_items/d6
+ name = "D6"
+ item_path = /obj/item/dice/d6
+
+/datum/loadout_item/pocket_items/d6_ebony
+ name = "D6 (Ebony)"
+ item_path = /obj/item/dice/d6/ebony
+
+/datum/loadout_item/pocket_items/d6_space
+ name = "D6 (Space)"
+ item_path = /obj/item/dice/d6/space
+
+/datum/loadout_item/pocket_items/d8
+ name = "D8"
+ item_path = /obj/item/dice/d8
+
+/datum/loadout_item/pocket_items/d10
+ name = "D10"
+ item_path = /obj/item/dice/d10
+
+/datum/loadout_item/pocket_items/d12
+ name = "D12"
+ item_path = /obj/item/dice/d12
+
+/datum/loadout_item/pocket_items/d20
+ name = "D20"
+ item_path = /obj/item/dice/d20
+
+/datum/loadout_item/pocket_items/d100
+ name = "D100"
+ item_path = /obj/item/dice/d100
+
+/datum/loadout_item/pocket_items/d00
+ name = "D00"
+ item_path = /obj/item/dice/d00
+*/
diff --git a/code/modules/loadout/loadout_categories.dm b/code/modules/loadout/loadout_categories.dm
new file mode 100644
index 00000000000..ae9aca7e914
--- /dev/null
+++ b/code/modules/loadout/loadout_categories.dm
@@ -0,0 +1,86 @@
+/**
+ * # Loadout categories
+ *
+ * Loadout categories are singletons used to group loadout items together in the loadout screen.
+ */
+/datum/loadout_category
+ /// The name of the category, shown in the tabs
+ var/category_name
+ /// FontAwesome icon for the category
+ var/category_ui_icon
+ /// String to display on the top-right of a category tab
+ var/category_info
+ /// Order which they appear in the tabs, ties go alphabetically
+ var/tab_order = -1
+ /// What type of loadout items should be generated for this category?
+ var/type_to_generate
+ /// List of all loadout items in this category
+ VAR_FINAL/list/datum/loadout_item/associated_items
+
+/datum/loadout_category/New()
+ . = ..()
+ associated_items = get_items()
+ for(var/datum/loadout_item/item as anything in associated_items)
+ if(GLOB.all_loadout_datums[item.item_path])
+ stack_trace("Loadout datum collision - [item.item_path] is shared between multiple loadout datums.")
+ GLOB.all_loadout_datums[item.item_path] = item
+
+/datum/loadout_category/Destroy(force, ...)
+ if(!force)
+ stack_trace("QDEL called on loadout category [type]. This shouldn't ever happen. (Use FORCE if necessary.)")
+ return QDEL_HINT_LETMELIVE
+
+ associated_items.Cut()
+ return ..()
+
+/// Return a list of all /datum/loadout_items in this category.
+/datum/loadout_category/proc/get_items() as /list
+ var/list/all_items = list()
+ for(var/datum/loadout_item/found_type as anything in typesof(type_to_generate))
+ if(found_type == initial(found_type.abstract_type))
+ continue
+
+ if(!initial(found_type.item_path)) // SKYRAT EDIT ADDITION
+ continue
+
+ if(!ispath(initial(found_type.item_path), /obj/item))
+ stack_trace("Loadout get_items(): Attempted to instantiate a loadout item ([found_type]) with an invalid or null typepath! (got path: [initial(found_type.item_path)])")
+ continue
+
+ var/datum/loadout_item/spawned_type = new found_type(src)
+ all_items += spawned_type
+
+ return all_items
+
+/// Returns a list of all /datum/loadout_items in this category, formatted for UI use. Only ran once.
+/datum/loadout_category/proc/items_to_ui_data(client/user) as /list // SKYRAT EDIT CHANGE - Added user poaram
+ if(!length(associated_items))
+ return list()
+
+ var/list/formatted_list = list()
+
+ for(var/datum/loadout_item/item as anything in associated_items)
+ // SKYRAT EDIT ADDITION
+ if(item.ckeywhitelist && !(user?.ckey in item.ckeywhitelist))
+ continue
+ // SKYRAT EDIT END
+ var/list/item_data = item.to_ui_data()
+ UNTYPED_LIST_ADD(formatted_list, item_data)
+
+ sortTim(formatted_list, /proc/cmp_assoc_list_name) // Alphabetizing
+ return formatted_list
+
+/**
+ * Handles what happens when two items of this category are selected at once
+ *
+ * Return TRUE if it's okay to continue with adding the incoming item,
+ * or return FALSE to stop the new item from being added
+ */
+/datum/loadout_category/proc/handle_duplicate_entires(
+ datum/preference_middleware/loadout/manager,
+ datum/loadout_item/conflicting_item,
+ datum/loadout_item/added_item,
+ list/datum/loadout_item/all_loadout_items,
+)
+ manager.deselect_item(conflicting_item)
+ return TRUE
diff --git a/code/modules/loadout/loadout_helpers.dm b/code/modules/loadout/loadout_helpers.dm
new file mode 100644
index 00000000000..c2f83fb3ca7
--- /dev/null
+++ b/code/modules/loadout/loadout_helpers.dm
@@ -0,0 +1,142 @@
+/**
+ * Equips this mob with a given outfit and loadout items as per the passed preferences.
+ *
+ * Loadout items override the pre-existing item in the corresponding slot of the job outfit.
+ * Some job items are preserved after being overridden - belt items, ear items, and glasses.
+ * The rest of the slots, the items are overridden completely and deleted.
+ *
+ * Species with special outfits are snowflaked to have loadout items placed in their bags instead of overriding the outfit.
+ *
+ * * outfit - the job outfit we're equipping
+ * * preference_source - the preferences to draw loadout items from.
+ * * visuals_only - whether we call special equipped procs, or if we just look like we equipped it
+ */
+/mob/living/carbon/human/proc/equip_outfit_and_loadout(
+ datum/outfit/outfit = /datum/outfit,
+ datum/preferences/preference_source,
+ visuals_only = FALSE,
+ datum/job/equipping,
+) // SKYRAT EDIT CHANGE - Added equipping param
+ if(isnull(preference_source))
+ return equipOutfit(outfit, visuals_only)
+
+ var/datum/outfit/equipped_outfit
+ if(ispath(outfit, /datum/outfit))
+ equipped_outfit = new outfit()
+ else if(istype(outfit, /datum/outfit))
+ equipped_outfit = outfit
+ else
+ CRASH("Invalid outfit passed to equip_outfit_and_loadout ([outfit])")
+
+ var/list/preference_list = preference_source.read_preference(/datum/preference/loadout)
+ var/list/loadout_datums = loadout_list_to_datums(preference_list)
+ var/obj/item/storage/briefcase/empty/travel_suitcase // SKYRAT EDIT ADDITIONi
+ var/loadout_placement_preference = preference_source.read_preference(/datum/preference/choiced/loadout_override_preference)
+ // Slap our things into the outfit given
+ for(var/datum/loadout_item/item as anything in loadout_datums)
+ // SKYRAT EDIT ADDITION
+ if(item.restricted_roles && equipping && !(equipping.title in item.restricted_roles))
+ if(preference_source.parent)
+ to_chat(preference_source.parent, span_warning("You were unable to get a loadout item([initial(item.item_path.name)]) due to job restrictions!"))
+ continue
+
+ if(item.blacklisted_roles && equipping && (equipping.title in item.blacklisted_roles))
+ if(preference_source.parent)
+ to_chat(preference_source.parent, span_warning("You were unable to get a loadout item([initial(item.item_path.name)]) due to job blacklists!"))
+ continue
+
+ if(item.restricted_species && !(dna.species.id in item.restricted_species))
+ if(preference_source.parent)
+ to_chat(preference_source.parent, span_warning("You were unable to get a loadout item ([initial(item.item_path.name)]) due to species restrictions!"))
+ continue
+
+ if(item.ckeywhitelist && !(preference_source?.parent?.ckey in item.ckeywhitelist)) // Sanity checking
+ if(preference_source.parent)
+ to_chat(preference_source.parent, span_warning("You were unable to get a loadout item ([initial(item.item_path.name)]) due to CKEY restrictions!"))
+ continue
+
+ if(loadout_placement_preference == LOADOUT_OVERRIDE_CASE)
+ if(!travel_suitcase)
+ travel_suitcase = new(loc)
+ new item.item_path(travel_suitcase)
+ else // SKYRAT EDIT END
+ item.insert_path_into_outfit(equipped_outfit, src, visuals_only, loadout_placement_preference)
+ // Equip the outfit loadout items included
+ if(!equipped_outfit.equip(src, visuals_only))
+ return FALSE
+
+ // SKYRAT EDIT ADDITION
+ if(travel_suitcase)
+ put_in_hands(travel_suitcase)
+ // SKYRAT EDIT END
+
+ // Handle any snowflake on_equips.
+ var/list/new_contents = get_all_gear()
+ var/update = NONE
+ for(var/datum/loadout_item/item as anything in loadout_datums)
+ var/obj/item/equipped = locate(item.item_path) in new_contents
+ if(isnull(equipped))
+ continue
+ update |= item.on_equip_item(
+ equipped_item = equipped,
+ preference_source = preference_source,
+ preference_list = preference_list,
+ equipper = src,
+ visuals_only = visuals_only,
+ )
+
+ if(update)
+ update_clothing(update)
+
+ return TRUE
+
+/**
+ * Takes a list of paths (such as a loadout list)
+ * and returns a list of their singleton loadout item datums
+ *
+ * loadout_list - the list being checked
+ *
+ * Returns a list of singleton datums
+ */
+/proc/loadout_list_to_datums(list/loadout_list) as /list
+ var/list/datums = list()
+
+ if(!length(GLOB.all_loadout_datums))
+ CRASH("No loadout datums in the global loadout list!")
+
+ for(var/path in loadout_list)
+ var/actual_datum = GLOB.all_loadout_datums[path]
+ if(!istype(actual_datum, /datum/loadout_item))
+ stack_trace("Could not find ([path]) loadout item in the global list of loadout datums!")
+ continue
+
+ datums += actual_datum
+
+ return datums
+
+// SKYRAT EDIT ADDITION
+/*
+ * Removes all invalid paths from loadout lists.
+ *
+ * passed_list - the loadout list we're sanitizing.
+ *
+ * returns a list
+ */
+/proc/sanitize_loadout_list(list/passed_list)
+ RETURN_TYPE(/list)
+
+ var/list/list_to_clean = LAZYLISTDUPLICATE(passed_list)
+ for(var/path in list_to_clean)
+ if(!ispath(path))
+ stack_trace("invalid path found in loadout list! (Path: [path])")
+ LAZYREMOVE(list_to_clean, path)
+
+ else if(!(path in GLOB.all_loadout_datums))
+ stack_trace("invalid loadout slot found in loadout list! Path: [path]")
+ LAZYREMOVE(list_to_clean, path)
+
+ return list_to_clean
+
+/obj/item/storage/briefcase/empty/PopulateContents()
+ return
+// SKYRAT EDIT END
diff --git a/code/modules/loadout/loadout_items.dm b/code/modules/loadout/loadout_items.dm
new file mode 100644
index 00000000000..e02d15e7a44
--- /dev/null
+++ b/code/modules/loadout/loadout_items.dm
@@ -0,0 +1,406 @@
+/// Global list of ALL loadout datums instantiated.
+/// Loadout datums are created by loadout categories.
+GLOBAL_LIST_EMPTY(all_loadout_datums)
+
+/// Global list of all loadout categories
+/// Doesn't really NEED to be a global but we need to init this early for preferences,
+/// as the categories instantiate all the loadout datums
+GLOBAL_LIST_INIT(all_loadout_categories, init_loadout_categories())
+
+/// Inits the global list of loadout category singletons
+/// Also inits loadout item singletons
+/proc/init_loadout_categories()
+ var/list/loadout_categories = list()
+ for(var/category_type in subtypesof(/datum/loadout_category))
+ loadout_categories += new category_type()
+
+ sortTim(loadout_categories, /proc/cmp_loadout_categories)
+ return loadout_categories
+
+/proc/cmp_loadout_categories(datum/loadout_category/A, datum/loadout_category/B)
+ var/a_order = A::tab_order
+ var/b_order = B::tab_order
+ if(a_order == b_order)
+ return cmp_text_asc(A::category_name, B::category_name)
+ return cmp_numeric_asc(a_order, b_order)
+
+/**
+ * # Loadout item datum
+ *
+ * Singleton that holds all the information about each loadout items, and how to equip them.
+ */
+/datum/loadout_item
+ /// The category of the loadout item. Set automatically in New
+ VAR_FINAL/datum/loadout_category/category
+ /// Displayed name of the loadout item.
+ /// Defaults to the item's name if unset.
+ var/name
+ /// 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
+ /// The abstract parent of this loadout item, to determine which items to not instantiate
+ var/abstract_type = /datum/loadout_item
+ /// The actual item path of the loadout item.
+ var/obj/item/item_path
+ /// Lazylist of additional "information" text to display about this item.
+ var/list/additional_displayed_text
+ /// Icon file (DMI) for the UI to use for preview icons.
+ /// Set automatically if null
+ var/ui_icon
+ /// Icon state for the UI to use for preview icons.
+ /// Set automatically if null
+ var/ui_icon_state
+ /// Reskin options of this item if it can be reskinned.
+ VAR_FINAL/list/cached_reskin_options
+
+ //SKYRAT EDIT ADDITION
+ /// If set, it's a list containing ckeys which only can get the item
+ var/list/ckeywhitelist
+ /// If set, is a list of job names of which can get the loadout item
+ var/list/restricted_roles
+ /// If set, is a list of job names of which can't get the loadout item
+ var/list/blacklisted_roles
+ /// If set, is a list of species which can get the loadout item
+ var/list/restricted_species
+ /// Whether the item is restricted to supporters
+ var/donator_only
+ /// Whether the item requires a specific season in order to be available
+ var/required_season = null
+ /// If the item won't appear when the ERP config is disabled
+ var/erp_item = FALSE
+
+
+/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)
+ can_be_greyscale = TRUE
+
+ if(isnull(name))
+ name = item_path::name
+
+ if(isnull(ui_icon) && isnull(ui_icon_state))
+ 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)
+ 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.")
+ else
+ cached_reskin_options = dummy_item.unique_reskin.Copy()
+ qdel(dummy_item)
+
+ // SKYRAT EDIT ADDITION
+ // Let's sanitize in case somebody inserted the player's byond name instead of ckey in canonical form
+ if(ckeywhitelist)
+ for (var/i = 1, i <= length(ckeywhitelist), i++)
+ ckeywhitelist[i] = ckey(ckeywhitelist[i])
+ // SKYRAT EDIT END
+
+/datum/loadout_item/Destroy(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 ..()
+
+/**
+ * Takes in an action from a loadout manager and applies it
+ *
+ * Useful for subtypes of loadout items with unique actions
+ *
+ * Return TRUE to force an update to the UI / character preview
+ */
+/datum/loadout_item/proc/handle_loadout_action(datum/preference_middleware/loadout/manager, mob/user, action, params)
+ SHOULD_CALL_PARENT(TRUE)
+
+ switch(action)
+ if("select_color")
+ if(can_be_greyscale)
+ return set_item_color(manager, user)
+
+ if("set_name")
+ if(can_be_named)
+ return set_name(manager, user)
+
+ if("set_skin")
+ return set_skin(manager, user, params)
+
+ return TRUE
+
+/// Opens up the GAGS editing menu.
+/datum/loadout_item/proc/set_item_color(datum/preference_middleware/loadout/manager, mob/user)
+ if(manager.menu)
+ return FALSE
+
+ var/list/loadout = manager.preferences.read_preference(/datum/preference/loadout)
+ var/list/allowed_configs = list()
+ if(initial(item_path.greyscale_config))
+ allowed_configs += "[initial(item_path.greyscale_config)]"
+ if(initial(item_path.greyscale_config_worn))
+ allowed_configs += "[initial(item_path.greyscale_config_worn)]"
+ if(initial(item_path.greyscale_config_inhand_left))
+ allowed_configs += "[initial(item_path.greyscale_config_inhand_left)]"
+ if(initial(item_path.greyscale_config_inhand_right))
+ allowed_configs += "[initial(item_path.greyscale_config_inhand_right)]"
+
+ var/datum/greyscale_modify_menu/menu = new(
+ manager,
+ user,
+ allowed_configs,
+ CALLBACK(src, PROC_REF(set_slot_greyscale), manager),
+ starting_icon_state = initial(item_path.icon_state),
+ starting_config = initial(item_path.greyscale_config),
+ starting_colors = loadout?[item_path]?[INFO_GREYSCALE] || initial(item_path.greyscale_colors),
+ )
+
+ manager.register_greyscale_menu(menu)
+ menu.ui_interact(user)
+ return TRUE
+
+/// Callback for GAGS menu to set this item's color.
+/datum/loadout_item/proc/set_slot_greyscale(datum/preference_middleware/loadout/manager, datum/greyscale_modify_menu/open_menu)
+ if(!istype(open_menu))
+ CRASH("set_slot_greyscale called without a greyscale menu!")
+
+ var/list/loadout = manager.preferences.read_preference(/datum/preference/loadout)
+ if(!loadout?[item_path])
+ return FALSE
+
+ var/list/colors = open_menu.split_colors
+ if(!colors)
+ return FALSE
+
+ loadout[item_path][INFO_GREYSCALE] = colors.Join("")
+ manager.preferences.update_preference(GLOB.preference_entries[/datum/preference/loadout], loadout)
+ return TRUE // update UI
+
+/// Sets the name of the item.
+/datum/loadout_item/proc/set_name(datum/preference_middleware/loadout/manager, mob/user)
+ var/list/loadout = manager.preferences.read_preference(/datum/preference/loadout)
+ var/input_name = tgui_input_text(
+ user = user,
+ message = "What name do you want to give the [name]? Leave blank to clear.",
+ title = "[name] name",
+ default = loadout?[item_path]?[INFO_NAMED], // plop in existing name (if any)
+ max_length = MAX_NAME_LEN,
+ )
+ if(QDELETED(src) || QDELETED(user) || QDELETED(manager) || QDELETED(manager.preferences))
+ return FALSE
+
+ loadout = manager.preferences.read_preference(/datum/preference/loadout) // Make sure no shenanigans happened
+ if(!loadout?[item_path])
+ return FALSE
+
+ if(input_name)
+ loadout[item_path][INFO_NAMED] = input_name
+ else if(input_name == "")
+ loadout[item_path] -= INFO_NAMED
+
+ manager.preferences.update_preference(GLOB.preference_entries[/datum/preference/loadout], loadout)
+ return FALSE // no update needed
+
+/// 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
+
+ var/list/loadout = manager.preferences.read_preference(/datum/preference/loadout)
+ if(!loadout?[item_path])
+ return FALSE
+
+ loadout[item_path][INFO_RESKIN] = reskin_to
+ manager.preferences.update_preference(GLOB.preference_entries[/datum/preference/loadout], loadout)
+ return TRUE // always update UI
+
+/**
+ * Place our [item_path] into the passed [outfit].
+ *
+ * By default, just adds the item into the outfit's backpack contents, if non-visual.
+ *
+ * Arguments:
+ * * outfit - The outfit we're equipping our items into.
+ * * equipper - If we're equipping out outfit onto a mob at the time, this is the mob it is equipped on. Can be null.
+ * * visual - If TRUE, then our outfit is only for visual use (for example, a preview).
+ */
+/datum/loadout_item/proc/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, loadout_placement_preference) // SKYRAT EDIT CHANGE - Added loadout_placement_preference
+ if(!visuals_only)
+ LAZYADD(outfit.backpack_contents, item_path)
+
+/**
+ * Called When the item is equipped on [equipper].
+ *
+ * At this point the item is in the mob's contents
+ *
+ * Arguments:
+ * * preference_source - the datum/preferences our loadout item originated from - cannot be null
+ * * equipper - the mob we're equipping this item onto - cannot 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,
+)
+ ASSERT(!isnull(equipped_item))
+
+ 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])
+ update_flag |= equipped_item.slot_flags
+
+ if(can_be_named && 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])
+ var/skin_chosen = item_details[INFO_RESKIN]
+ if(skin_chosen in equipped_item.unique_reskin)
+ equipped_item.current_skin = skin_chosen
+ equipped_item.icon_state = equipped_item.unique_reskin[skin_chosen]
+ if(istype(equipped_item, /obj/item/clothing/accessory))
+ // Snowflake handing for accessories, because we need to update the thing it's attached to instead
+ if(isclothing(equipped_item.loc))
+ var/obj/item/clothing/under/attached_to = equipped_item.loc
+ attached_to.update_accessory_overlay()
+ update_flag |= (ITEM_SLOT_OCLOTHING|ITEM_SLOT_ICLOTHING)
+ 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
+
+/**
+ * Returns a formatted list of data for this loadout item.
+ */
+/datum/loadout_item/proc/to_ui_data() as /list
+ SHOULD_CALL_PARENT(TRUE)
+
+ var/list/formatted_item = list()
+ formatted_item["name"] = name
+ formatted_item["path"] = item_path
+ formatted_item["information"] = get_item_information()
+ formatted_item["buttons"] = get_ui_buttons()
+ formatted_item["reskins"] = get_reskin_options()
+ formatted_item["icon"] = ui_icon
+ formatted_item["icon_state"] = ui_icon_state
+ return formatted_item
+
+/**
+ * Returns a list of information to display about this item in the loadout UI.
+ *
+ * These should be short strings, sub 14 characters generally.
+ */
+/datum/loadout_item/proc/get_item_information() as /list
+ SHOULD_CALL_PARENT(TRUE)
+
+ var/list/displayed_text = list()
+
+ displayed_text += (additional_displayed_text || list())
+
+ if(can_be_greyscale)
+ displayed_text += "Recolorable"
+
+ if(can_be_named)
+ displayed_text += "Renamable"
+
+ if(can_be_reskinned)
+ displayed_text += "Reskinnable"
+
+ // SKYRAT EDIT ADDITION
+ if(donator_only)
+ displayed_text += "Donator only"
+
+ if(restricted_roles || blacklisted_roles)
+ displayed_text += "Role restricted"
+
+ if(restricted_species)
+ displayed_text += "Species restricted"
+ // SKYRAT EDIT ADDITION
+ return displayed_text
+
+/**
+ * Returns a list of buttons that are shown in the loadout UI for customizing this item.
+ *
+ * Buttons contain
+ * - 'L'abel: The text displayed beside the button
+ * - act_key: The key that is sent to the loadout manager when the button is clicked,
+ * for use in handle_loadout_action
+ * - button_icon: The FontAwesome icon to display on the button
+ * - active_key: In the loadout UI, this key is checked in the user's loadout list for this item
+ * to determine if the button is 'active' (green) or not (blue).
+ * - active_text: Optional, if provided, the button appears to be a checkbox and this text is shown when 'active'
+ * - inactive_text: Optional, if provided, the button appears to be a checkbox and this text is shown when not 'active'
+ */
+/datum/loadout_item/proc/get_ui_buttons() as /list
+ SHOULD_CALL_PARENT(TRUE)
+
+ var/list/button_list = list()
+
+ if(can_be_greyscale)
+ UNTYPED_LIST_ADD(button_list, list(
+ "label" = "Recolor",
+ "act_key" = "select_color",
+ "button_icon" = FA_ICON_PALETTE,
+ "active_key" = INFO_GREYSCALE,
+ ))
+
+ if(can_be_named)
+ UNTYPED_LIST_ADD(button_list, list(
+ "label" = "Rename",
+ "act_key" = "set_name",
+ "button_icon" = FA_ICON_PEN,
+ "active_key" = INFO_NAMED,
+ ))
+
+ return button_list
+
+/**
+ * Returns a list of options this item can be reskinned into.
+ */
+/datum/loadout_item/proc/get_reskin_options() as /list
+ if(!can_be_reskinned)
+ return null
+
+ var/list/reskins = list()
+
+ for(var/skin in cached_reskin_options)
+ UNTYPED_LIST_ADD(reskins, list(
+ "name" = skin,
+ "tooltip" = skin,
+ "skin_icon_state" = cached_reskin_options[skin],
+ ))
+
+ return reskins
+
diff --git a/code/modules/loadout/loadout_menu.dm b/code/modules/loadout/loadout_menu.dm
new file mode 100644
index 00000000000..f01d4215c69
--- /dev/null
+++ b/code/modules/loadout/loadout_menu.dm
@@ -0,0 +1,129 @@
+/datum/preference_middleware/loadout
+ action_delegations = list(
+ "clear_all_items" = PROC_REF(action_clear_all),
+ "pass_to_loadout_item" = PROC_REF(action_pass_to_loadout_item),
+ "rotate_dummy" = PROC_REF(action_rotate_model_dir),
+ "select_item" = PROC_REF(action_select_item),
+ "toggle_job_clothes" = PROC_REF(action_toggle_job_outfit),
+ "close_greyscale_menu" = PROC_REF(force_close_greyscale_menu),
+ )
+ /// Our currently open greyscaling menu.
+ VAR_FINAL/datum/greyscale_modify_menu/menu
+
+/datum/preference_middleware/loadout/Destroy(force, ...)
+ QDEL_NULL(menu)
+ return ..()
+
+/datum/preference_middleware/loadout/on_new_character(mob/user)
+ preferences.character_preview_view?.update_body()
+
+/datum/preference_middleware/loadout/proc/action_select_item(list/params, mob/user)
+ PRIVATE_PROC(TRUE)
+ var/path_to_use = text2path(params["path"])
+ var/datum/loadout_item/interacted_item = GLOB.all_loadout_datums[path_to_use]
+ if(!istype(interacted_item))
+ stack_trace("Failed to locate desired loadout item (path: [params["path"]]) in the global list of loadout datums!")
+ return TRUE // update
+
+ if(params["deselect"])
+ deselect_item(interacted_item)
+ else
+ select_item(interacted_item)
+ return TRUE
+
+/datum/preference_middleware/loadout/proc/action_clear_all(list/params, mob/user)
+ PRIVATE_PROC(TRUE)
+ preferences.update_preference(GLOB.preference_entries[/datum/preference/loadout], null)
+ return TRUE
+
+/datum/preference_middleware/loadout/proc/action_toggle_job_outfit(list/params, mob/user)
+ PRIVATE_PROC(TRUE)
+ preferences.character_preview_view.show_job_clothes = !preferences.character_preview_view.show_job_clothes
+ preferences.character_preview_view.update_body()
+ return TRUE
+
+/datum/preference_middleware/loadout/proc/action_rotate_model_dir(list/params, mob/user)
+ PRIVATE_PROC(TRUE)
+ switch(params["dir"])
+ if("left")
+ preferences.character_preview_view.setDir(turn(preferences.character_preview_view.dir, -90))
+ if("right")
+ preferences.character_preview_view.setDir(turn(preferences.character_preview_view.dir, 90))
+
+/datum/preference_middleware/loadout/proc/action_pass_to_loadout_item(list/params, mob/user)
+ PRIVATE_PROC(TRUE)
+ var/path_to_use = text2path(params["path"])
+ var/datum/loadout_item/interacted_item = GLOB.all_loadout_datums[path_to_use]
+ if(!istype(interacted_item)) // no you cannot href exploit to spawn with a pulse rifle
+ stack_trace("Failed to locate desired loadout item (path: [params["path"]]) in the global list of loadout datums!")
+ return TRUE // update
+
+ if(interacted_item.handle_loadout_action(src, user, params["subaction"], params))
+ preferences.character_preview_view.update_body()
+ return TRUE
+
+ return FALSE
+
+/// Select [path] item to [category_slot] slot.
+/datum/preference_middleware/loadout/proc/select_item(datum/loadout_item/selected_item)
+ var/list/loadout = preferences.read_preference(/datum/preference/loadout)
+ var/list/datum/loadout_item/loadout_datums = loadout_list_to_datums(loadout)
+ for(var/datum/loadout_item/item as anything in loadout_datums)
+ if(item.category != selected_item.category)
+ continue
+ if(!item.category.handle_duplicate_entires(src, item, selected_item, loadout_datums))
+ return
+ // SKYRAT EDIT ADDITION
+ if(item.ckeywhitelist && !(preferences?.parent?.ckey in item.ckeywhitelist))
+ to_chat(preferences.parent, span_warning("You cannot select this item!"))
+ return
+
+ if(item.donator_only && !GLOB.donator_list[preferences?.parent?.ckey])
+ to_chat(preferences.parent, span_warning("That item is for donators only."))
+ return
+ // SKYRAT EDIT END
+
+ LAZYSET(loadout, selected_item.item_path, list())
+ preferences.update_preference(GLOB.preference_entries[/datum/preference/loadout], loadout)
+
+/// Deselect [deselected_item].
+/datum/preference_middleware/loadout/proc/deselect_item(datum/loadout_item/deselected_item)
+ var/list/loadout = preferences.read_preference(/datum/preference/loadout)
+ LAZYREMOVE(loadout, deselected_item.item_path)
+ preferences.update_preference(GLOB.preference_entries[/datum/preference/loadout], loadout)
+
+/datum/preference_middleware/loadout/proc/register_greyscale_menu(datum/greyscale_modify_menu/open_menu)
+ src.menu = open_menu
+ RegisterSignal(menu, COMSIG_QDELETING, PROC_REF(cleanup_greyscale_menu))
+
+/datum/preference_middleware/loadout/proc/cleanup_greyscale_menu()
+ SIGNAL_HANDLER
+ menu = null
+
+/datum/preference_middleware/loadout/proc/force_close_greyscale_menu()
+ menu?.ui_close()
+
+/datum/preference_middleware/loadout/get_ui_data(mob/user)
+ var/list/data = list()
+ data["job_clothes"] = preferences.character_preview_view.show_job_clothes
+ return data
+
+/datum/preference_middleware/loadout/get_ui_static_data(mob/user)
+ var/list/data = list()
+ data["loadout_preview_view"] = preferences.character_preview_view.assigned_map
+ return data
+
+/datum/preference_middleware/loadout/get_constant_data()
+ var/list/data = list()
+ var/list/loadout_tabs = list()
+ for(var/datum/loadout_category/category as anything in GLOB.all_loadout_categories)
+ var/list/cat_data = list(
+ "name" = category.category_name,
+ "category_icon" = category.category_ui_icon,
+ "category_info" = category.category_info,
+ "contents" = category.items_to_ui_data(preferences?.parent),
+ ) // SKYRAT EDIT CHANGE - items_to_ui_data(preferences?.parent)
+ UNTYPED_LIST_ADD(loadout_tabs, cat_data)
+
+ data["loadout_tabs"] = loadout_tabs
+ return data
diff --git a/code/modules/loadout/loadout_preference.dm b/code/modules/loadout/loadout_preference.dm
new file mode 100644
index 00000000000..739226f5da7
--- /dev/null
+++ b/code/modules/loadout/loadout_preference.dm
@@ -0,0 +1,68 @@
+/datum/preference/loadout
+ savefile_key = "loadout_list"
+ savefile_identifier = PREFERENCE_CHARACTER
+ priority = PREFERENCE_PRIORITY_LOADOUT
+ can_randomize = FALSE
+ // Loadout preference is an assoc list [item_path] = [loadout item information list]
+ //
+ // it may look something like
+ // - list(/obj/item/glasses = list())
+ // or
+ // - list(/obj/item/plush/lizard = list("name" = "Tests-The-Loadout", "color" = "#FF0000"))
+
+// Loadouts are applied with job equip code.
+/datum/preference/loadout/apply_to_human(mob/living/carbon/human/target, value)
+ return
+
+// Sanitize on load to ensure no invalid paths from older saves get in
+/datum/preference/loadout/deserialize(input, datum/preferences/preferences)
+ return sanitize_loadout_list(input, preferences.parent?.mob, preferences.parent) // SKYRAT EDIT CHANGE parent
+
+// Default value is null - the loadout list is a lazylist
+/datum/preference/loadout/create_default_value(datum/preferences/preferences)
+ return null
+
+/datum/preference/loadout/is_valid(value)
+ return isnull(value) || islist(value)
+
+/**
+ * Removes all invalid paths from loadout lists.
+ * This is a general sanitization for preference loading.
+ *
+ * Returns a list, or null if empty
+ */
+/datum/preference/loadout/proc/sanitize_loadout_list(list/passed_list, mob/optional_loadout_owner, client/owner_client) as /list // SKYRAT EDIT CHANGE - client/owner_client
+ var/list/sanitized_list
+ for(var/path in passed_list)
+ // Loading from json has each path in the list as a string that we need to convert back to typepath
+ var/obj/item/real_path = istext(path) ? text2path(path) : path
+ if(!ispath(real_path, /obj/item))
+ if(optional_loadout_owner)
+ to_chat(optional_loadout_owner, span_boldnotice("The following invalid item path was found \
+ in your character loadout: [real_path || "null"]. \
+ It has been removed, renamed, or is otherwise missing - \
+ You may want to check your loadout settings."))
+ continue
+
+ else if(!istype(GLOB.all_loadout_datums[real_path], /datum/loadout_item))
+ if(optional_loadout_owner)
+ to_chat(optional_loadout_owner, span_boldnotice("The following invalid loadout item was found \
+ in your character loadout: [real_path || "null"]. \
+ It has been removed, renamed, or is otherwise missing - \
+ You may want to check your loadout settings."))
+ continue
+
+ // SKYRAT EDIT ADDITION
+ else if(owner_client)
+ var/datum/loadout_item/loadout_item = GLOB.all_loadout_datums[real_path]
+ if(loadout_item?.ckeywhitelist && !(owner_client?.ckey in loadout_item.ckeywhitelist))
+ continue
+ if(loadout_item?.donator_only && !GLOB.donator_list[owner_client?.ckey])
+ continue
+ // SKYRAT EDIT END
+
+ // Set into sanitize list using converted path key
+ var/list/data = passed_list[path]
+ LAZYSET(sanitized_list, real_path, LAZYLISTDUPLICATE(data))
+
+ return sanitized_list
diff --git a/code/modules/mob/dead/new_player/new_player.dm b/code/modules/mob/dead/new_player/new_player.dm
index 71c8a57e7a5..955b16a772a 100644
--- a/code/modules/mob/dead/new_player/new_player.dm
+++ b/code/modules/mob/dead/new_player/new_player.dm
@@ -287,14 +287,6 @@
humanc.put_in_hands(new /obj/item/crowbar/large/emergency(get_turf(humanc))) //if hands full then just drops on the floor
log_manifest(character.mind.key, character.mind, character, latejoin = TRUE)
- // SKYRAT EDIT ADDITION START
- if(humanc)
- for(var/datum/loadout_item/item as anything in loadout_list_to_datums(humanc?.client?.prefs?.loadout_list))
- if (item.restricted_roles && length(item.restricted_roles) && !(job.title in item.restricted_roles))
- continue
- item.post_equip_item(humanc.client?.prefs, humanc)
- // SKYRAT EDIT END
-
/mob/dead/new_player/proc/AddEmploymentContract(mob/living/carbon/human/employee)
//TODO: figure out a way to exclude wizards/nukeops/demons from this.
for(var/C in GLOB.employmentCabinets)
diff --git a/code/modules/mob/dead/new_player/preferences_setup.dm b/code/modules/mob/dead/new_player/preferences_setup.dm
index e15218a9fef..cd5111c235c 100644
--- a/code/modules/mob/dead/new_player/preferences_setup.dm
+++ b/code/modules/mob/dead/new_player/preferences_setup.dm
@@ -108,9 +108,13 @@
// Set up the dummy for its photoshoot
apply_prefs_to(mannequin, TRUE)
- if(preview_job)
- mannequin.job = preview_job.title
- mannequin.dress_up_as_job(preview_job, TRUE)
+ mannequin.job = preview_job.title
+ mannequin.dress_up_as_job(
+ equipping = show_job_clothes ? preview_job : no_job,
+ visual_only = TRUE,
+ player_client = parent,
+ consistent = TRUE,
+ )
// Apply visual quirks
// Yes we do it every time because it needs to be done after job gear
diff --git a/code/modules/mob/living/carbon/human/human_update_icons.dm b/code/modules/mob/living/carbon/human/human_update_icons.dm
index 522fa663601..cdb685e6e56 100644
--- a/code/modules/mob/living/carbon/human/human_update_icons.dm
+++ b/code/modules/mob/living/carbon/human/human_update_icons.dm
@@ -118,13 +118,13 @@ There are several things that need to be remembered:
var/mutant_styles = NONE // SKYRAT EDIT ADDITON - mutant styles to pass down to build_worn_icon.
//BEGIN SPECIES HANDLING
if((bodyshape & BODYSHAPE_MONKEY) && (uniform.supports_variations_flags & CLOTHING_MONKEY_VARIATION))
- icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_UNIFORM, w_uniform, src) // SKYRAT EDIT CHANGE - ORIGINAL: icon_file = MONKEY_UNIFORM_FILE
+ icon_file = dna.species.generate_custom_worn_icon(OFFSET_UNIFORM, w_uniform, src) // SKYRAT EDIT CHANGE - ORIGINAL: icon_file = MONKEY_UNIFORM_FILE
else if((bodyshape & BODYSHAPE_DIGITIGRADE) && (uniform.supports_variations_flags & CLOTHING_DIGITIGRADE_VARIATION))
icon_file = uniform.worn_icon_digi || DIGITIGRADE_UNIFORM_FILE // SKYRAT EDIT CHANGE - ORIGINAL: icon_file = DIGITIGRADE_UNIFORM_FILE
digi = TRUE // SKYRAT EDIT ADDITION - Digi female gender shaping
// SKYRAT EDIT ADDITION - birbs
else if(bodyshape & BODYSHAPE_CUSTOM)
- icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_UNIFORM, w_uniform, src) // Might have to refactor how this works eventually, maybe.
+ icon_file = dna.species.generate_custom_worn_icon(OFFSET_UNIFORM, w_uniform, src) // Might have to refactor how this works eventually, maybe.
// SKYRAT EDIT END
//Female sprites have lower priority than digitigrade sprites
if(!dna.species.no_gender_shaping && dna.species.sexes && (bodyshape & BODYSHAPE_HUMANOID) && physique == FEMALE && !(female_sprite_flags & NO_FEMALE_UNIFORM)) // SKYRAT EDIT CHANGE - ORIGINAL: else if(dna.species.sexes && (bodyshape & BODYSHAPE_HUMANOID) && physique == FEMALE && !(uniform.female_sprite_flags & NO_FEMALE_UNIFORM)) //Agggggggghhhhh
@@ -231,7 +231,7 @@ There are several things that need to be remembered:
// SKYRAT EDIT ADDITION
var/mutant_override = FALSE
if(bodyshape & BODYSHAPE_CUSTOM)
- var/species_icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_GLOVES, gloves, src)
+ var/species_icon_file = dna.species.generate_custom_worn_icon(OFFSET_GLOVES, gloves, src)
if(species_icon_file)
icon_file = species_icon_file
mutant_override = TRUE
@@ -277,7 +277,7 @@ There are several things that need to be remembered:
// SKYRAT EDIT ADDITION
var/mutant_override = FALSE
if(bodyshape & BODYSHAPE_CUSTOM)
- var/species_icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_GLASSES, glasses, src)
+ var/species_icon_file = dna.species.generate_custom_worn_icon(OFFSET_GLASSES, glasses, src)
if(species_icon_file)
icon_file = species_icon_file
mutant_override = TRUE
@@ -319,7 +319,7 @@ There are several things that need to be remembered:
// SKYRAT EDIT ADDITION
var/mutant_override = FALSE
if(bodyshape & BODYSHAPE_CUSTOM)
- var/species_icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_EARS, ears, src)
+ var/species_icon_file = dna.species.generate_custom_worn_icon(OFFSET_EARS, ears, src)
if(species_icon_file)
icon_file = species_icon_file
mutant_override = TRUE
@@ -356,7 +356,7 @@ There are several things that need to be remembered:
// SKYRAT EDIT ADDITION
var/mutant_override = FALSE
if(bodyshape & BODYSHAPE_CUSTOM)
- var/species_icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_NECK, wear_neck, src)
+ var/species_icon_file = dna.species.generate_custom_worn_icon(OFFSET_NECK, wear_neck, src)
if(species_icon_file)
icon_file = species_icon_file
mutant_override = TRUE
@@ -410,7 +410,7 @@ There are several things that need to be remembered:
icon_file = worn_item.worn_icon_digi || DIGITIGRADE_SHOES_FILE // SKYRAT EDIT CHANGE
mutant_override = TRUE // SKYRAT EDIT ADDITION
if(!mutant_override && bodyshape & BODYSHAPE_CUSTOM)
- var/species_icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_SHOES, shoes, src)
+ var/species_icon_file = dna.species.generate_custom_worn_icon(OFFSET_SHOES, shoes, src)
if(species_icon_file)
icon_file = species_icon_file
mutant_override = TRUE
@@ -484,7 +484,7 @@ There are several things that need to be remembered:
// SKYRAT EDIT ADDITION - This needs to be refactored.
var/mutant_override = FALSE
if(bodyshape & BODYSHAPE_CUSTOM)
- var/species_icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_HEAD, head, src)
+ var/species_icon_file = dna.species.generate_custom_worn_icon(OFFSET_HEAD, head, src)
if(species_icon_file)
icon_file = species_icon_file
mutant_override = TRUE
@@ -528,7 +528,7 @@ There are several things that need to be remembered:
// SKYRAT EDIT ADDITION
var/mutant_override = FALSE
if(bodyshape & BODYSHAPE_CUSTOM)
- var/species_icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_BELT, belt, src)
+ var/species_icon_file = dna.species.generate_custom_worn_icon(OFFSET_BELT, belt, src)
if(species_icon_file)
icon_file = species_icon_file
mutant_override = TRUE
@@ -572,7 +572,7 @@ There are several things that need to be remembered:
mutant_override = TRUE
if(!mutant_override && bodyshape & BODYSHAPE_CUSTOM)
- var/species_icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_SUIT, wear_suit, src)
+ var/species_icon_file = dna.species.generate_custom_worn_icon(OFFSET_SUIT, wear_suit, src)
if(species_icon_file)
icon_file = species_icon_file
mutant_override = TRUE
@@ -644,7 +644,7 @@ There are several things that need to be remembered:
// SKYRAT EDIT ADDITION
var/mutant_override = FALSE
if(bodyshape & BODYSHAPE_CUSTOM)
- var/species_icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_MASK, wear_mask, src)
+ var/species_icon_file = dna.species.generate_custom_worn_icon(OFFSET_FACEMASK, wear_mask, src)
if(species_icon_file)
icon_file = species_icon_file
mutant_override = TRUE
@@ -686,7 +686,7 @@ There are several things that need to be remembered:
// SKYRAT EDIT ADDITION
var/mutant_override = FALSE
if(bodyshape & BODYSHAPE_CUSTOM)
- var/species_icon_file = dna.species.generate_custom_worn_icon(LOADOUT_ITEM_MISC, back, src)
+ var/species_icon_file = dna.species.generate_custom_worn_icon(OFFSET_HELD, back, src)
if(species_icon_file)
icon_file = species_icon_file
mutant_override = TRUE
diff --git a/code/modules/unit_tests/_unit_tests.dm b/code/modules/unit_tests/_unit_tests.dm
index bd46aeea334..121c259b10f 100644
--- a/code/modules/unit_tests/_unit_tests.dm
+++ b/code/modules/unit_tests/_unit_tests.dm
@@ -286,7 +286,6 @@
#include "worn_icons.dm"
// SKYRAT EDIT START
#include "~skyrat\automapper.dm"
-#include "~skyrat\loadout_dupes.dm"
#include "~skyrat\opposing_force.dm"
// SKYRAT EDIT END
// END_INCLUDE
diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_driftingcontractor.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_driftingcontractor.png
deleted file mode 100644
index d75bf8fffec..00000000000
Binary files a/code/modules/unit_tests/screenshots/screenshot_antag_icons_driftingcontractor.png and /dev/null differ
diff --git a/code/modules/unit_tests/screenshots/screenshot_antag_icons_sentientdisease.png b/code/modules/unit_tests/screenshots/screenshot_antag_icons_sentientdisease.png
deleted file mode 100644
index e7e1cbd661f..00000000000
Binary files a/code/modules/unit_tests/screenshots/screenshot_antag_icons_sentientdisease.png and /dev/null differ
diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_holodeck.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_holodeck.png
deleted file mode 100644
index 28f6b0b1dcc..00000000000
Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_monkey_holodeck.png and /dev/null differ
diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_teshari.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_teshari.png
index aec29b7c0c8..2bf863348c0 100644
Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_teshari.png and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_teshari.png differ
diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vox.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vox.png
index e61083c8943..dbee83aaba7 100644
Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vox.png and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vox.png differ
diff --git a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vox_primalis.png b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vox_primalis.png
index cfbd40f8db7..73dff7a6448 100644
Binary files a/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vox_primalis.png and b/code/modules/unit_tests/screenshots/screenshot_humanoids__datum_species_vox_primalis.png differ
diff --git a/code/modules/unit_tests/~skyrat/loadout_dupes.dm b/code/modules/unit_tests/~skyrat/loadout_dupes.dm
deleted file mode 100644
index 23bfe368905..00000000000
--- a/code/modules/unit_tests/~skyrat/loadout_dupes.dm
+++ /dev/null
@@ -1,14 +0,0 @@
-///Checks that loadout items' item_paths are unique to the category of loadout item it belongs to
-/datum/unit_test/loadout_dupes
-
-/datum/unit_test/loadout_dupes/Run()
- var/list/item_paths = list()
- for(var/datum/loadout_item/item as anything in subtypesof(/datum/loadout_item))
- var/loadout_item_category = initial(item.category)
- var/item_path = initial(item.item_path)
- if(item_paths[item_path] == loadout_item_category)
- TEST_FAIL("Duplicate loadout item! [item_path] is already being used by [item].")
- if(isnull(item_path)) // can be null, for subcategories of loadout items
- continue
-
- item_paths[item_path] = loadout_item_category
diff --git a/icons/obj/fluff/previews.dmi b/icons/obj/fluff/previews.dmi
index c62b055f71e..8a69c136318 100644
Binary files a/icons/obj/fluff/previews.dmi and b/icons/obj/fluff/previews.dmi differ
diff --git a/modular_skyrat/master_files/code/modules/client/preferences.dm b/modular_skyrat/master_files/code/modules/client/preferences.dm
index da1f0e282de..90a1ce9c83a 100644
--- a/modular_skyrat/master_files/code/modules/client/preferences.dm
+++ b/modular_skyrat/master_files/code/modules/client/preferences.dm
@@ -1,8 +1,6 @@
#define MAX_MUTANT_ROWS 4
/datum/preferences
- /// Loadout prefs. Assoc list of [typepaths] to [associated list of item info].
- var/list/loadout_list
/// Associative list, keyed by language typepath, pointing to LANGUAGE_UNDERSTOOD, or LANGUAGE_SPOKEN, for whether we understand or speak the language
var/list/languages = list()
/// List of chosen augmentations. It's an associative list with key name of the slot, pointing to a typepath of an augment define
diff --git a/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm b/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm
index d2cb359c89f..567f825c25c 100644
--- a/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm
+++ b/modular_skyrat/master_files/code/modules/client/preferences_savefile.dm
@@ -66,16 +66,6 @@
background_info = sanitize_text(background_info)
exploitable_info = sanitize_text(exploitable_info)
- var/list/save_loadout = SANITIZE_LIST(save_data["loadout_list"])
- for(var/loadout in save_loadout)
- var/entry = save_loadout[loadout]
- save_loadout -= loadout
-
- if(istext(loadout))
- loadout = _text2path(loadout)
- save_loadout[loadout] = entry
- loadout_list = sanitize_loadout_list(save_loadout)
-
var/list/save_languages = SANITIZE_LIST(save_data["languages"])
for(var/language in save_languages)
var/value = save_languages[language]
@@ -267,7 +257,6 @@
/// Saves the modular customizations of a character on the savefile
/datum/preferences/proc/save_character_skyrat(list/save_data)
- save_data["loadout_list"] = loadout_list
save_data["augments"] = augments
save_data["augment_limb_styles"] = augment_limb_styles
save_data["features"] = features
diff --git a/modular_skyrat/master_files/code/modules/loadout/categories/accessories.dm b/modular_skyrat/master_files/code/modules/loadout/categories/accessories.dm
new file mode 100644
index 00000000000..beec66ae715
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/accessories.dm
@@ -0,0 +1,56 @@
+/*
+* ARMBANDS
+*/
+
+/datum/loadout_item/accessory/armband_medblue
+ name = "Blue-White Armband"
+ item_path = /obj/item/clothing/accessory/armband/medblue/nonsec
+
+/datum/loadout_item/accessory/armband_med
+ name = "White Armband"
+ item_path = /obj/item/clothing/accessory/armband/med/nonsec
+
+/datum/loadout_item/accessory/armband_cargo
+ name = "Brown Armband"
+ item_path = /obj/item/clothing/accessory/armband/cargo/nonsec
+
+/datum/loadout_item/accessory/armband_engineering
+ name = "Orange Armband"
+ item_path = /obj/item/clothing/accessory/armband/engine/nonsec
+
+/datum/loadout_item/accessory/armband_security_nonsec
+ name = "Blue Armband"
+ item_path = /obj/item/clothing/accessory/armband/deputy/lopland/nonsec
+
+/datum/loadout_item/accessory/armband_security
+ name = "Security Armband"
+ item_path = /obj/item/clothing/accessory/armband/deputy/lopland
+ restricted_roles = list(JOB_HEAD_OF_SECURITY, JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_DETECTIVE, JOB_CORRECTIONS_OFFICER)
+
+/datum/loadout_item/accessory/armband_security_deputy
+ name = "Security Deputy Armband"
+ item_path = /obj/item/clothing/accessory/armband/deputy
+ restricted_roles = list(JOB_HEAD_OF_SECURITY, JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_DETECTIVE, JOB_CORRECTIONS_OFFICER)
+
+/datum/loadout_item/accessory/armband_science
+ name = "Purple Armband"
+ item_path = /obj/item/clothing/accessory/armband/science/nonsec
+
+/*
+* ARMOURLESS
+*/
+
+/datum/loadout_item/accessory/bone_charm
+ name = "Heirloom Bone Talisman"
+ item_path = /obj/item/clothing/accessory/talisman/armourless
+ additional_displayed_text = list(TOOLTIP_NO_ARMOR)
+
+/datum/loadout_item/accessory/bone_codpiece
+ name = "Heirloom Skull Codpiece"
+ item_path = /obj/item/clothing/accessory/skullcodpiece/armourless
+ additional_displayed_text = list(TOOLTIP_NO_ARMOR)
+
+/datum/loadout_item/accessory/sinew_kilt
+ name = "Heirloom Sinew Skirt"
+ item_path = /obj/item/clothing/accessory/skilt/armourless
+ additional_displayed_text = list(TOOLTIP_NO_ARMOR)
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_belts.dm b/modular_skyrat/master_files/code/modules/loadout/categories/belts.dm
similarity index 67%
rename from modular_skyrat/modules/loadouts/loadout_items/loadout_datum_belts.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/belts.dm
index eaca1035a27..f482fcab184 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_belts.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/belts.dm
@@ -1,24 +1,16 @@
-/*
-* LOADOUT ITEM DATUMS FOR THE BELT SLOT
-*/
-
-/// Belt Slot Items (Moves overrided items to backpack)
-GLOBAL_LIST_INIT(loadout_belts, generate_loadout_items(/datum/loadout_item/belts))
+/datum/loadout_category/belts
+ category_name = "Belts"
+ category_ui_icon = FA_ICON_USER_TIE
+ type_to_generate = /datum/loadout_item/belts
+ tab_order = /datum/loadout_category/head::tab_order + 6
/datum/loadout_item/belts
- category = LOADOUT_ITEM_BELT
+ abstract_type = /datum/loadout_item/belts
-/datum/loadout_item/belts/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE) // don't bother storing in backpack, can't fit
- if(initial(outfit_important_for_life.belt))
- return TRUE
-
-/datum/loadout_item/belts/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only)
- if(outfit.belt)
- LAZYADD(outfit.backpack_contents, outfit.belt)
- outfit.belt = item_path
- else
- outfit.belt = item_path
+/datum/loadout_item/belts/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only, loadout_placement_preference)
+ if(loadout_placement_preference != LOADOUT_OVERRIDE_JOB && outfit.belt)
+ LAZYADD(outfit.backpack_contents, outfit.belt)
+ outfit.belt = item_path
/datum/loadout_item/belts/fanny_pack_black
name = "Black Fannypack"
diff --git a/modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm b/modular_skyrat/master_files/code/modules/loadout/categories/donator_personal.dm
similarity index 100%
rename from modular_skyrat/modules/loadouts/loadout_items/donator/personal/donator_personal.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/donator_personal.dm
diff --git a/modular_skyrat/master_files/code/modules/loadout/categories/ears.dm b/modular_skyrat/master_files/code/modules/loadout/categories/ears.dm
new file mode 100644
index 00000000000..b2d7118ad20
--- /dev/null
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/ears.dm
@@ -0,0 +1,21 @@
+/datum/loadout_category/ears
+ category_name = "Ears"
+ category_ui_icon = FA_ICON_EAR_LISTEN
+ type_to_generate = /datum/loadout_item/ears
+ tab_order = /datum/loadout_category/head::tab_order + 7
+
+/datum/loadout_item/ears
+ abstract_type = /datum/loadout_item/ears
+
+/datum/loadout_item/ears/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only, loadout_placement_preference)
+ if(loadout_placement_preference != LOADOUT_OVERRIDE_JOB && outfit.ears)
+ LAZYADD(outfit.backpack_contents, outfit.ears)
+ outfit.ears = item_path
+
+/datum/loadout_item/ears/headphones
+ name = "Headphones"
+ item_path = /obj/item/instrument/piano_synth/headphones
+
+/datum/loadout_item/ears/earmuffs
+ name = "Earmuffs"
+ item_path = /obj/item/clothing/ears/earmuffs
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_glasses.dm b/modular_skyrat/master_files/code/modules/loadout/categories/glasses.dm
similarity index 86%
rename from modular_skyrat/modules/loadouts/loadout_items/loadout_datum_glasses.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/glasses.dm
index 0a1d94de1b5..0c104a252cb 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_glasses.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/glasses.dm
@@ -1,47 +1,11 @@
/*
-* LOADOUT ITEM DATUMS FOR THE EYE SLOT
-*/
-
-/// Glasses Slot Items (Moves overrided items to backpack)
-GLOBAL_LIST_INIT(loadout_glasses, generate_loadout_items(/datum/loadout_item/glasses))
-
-/datum/loadout_item/glasses
- category = LOADOUT_ITEM_GLASSES
-
-/datum/loadout_item/glasses/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE)
- if(initial(outfit_important_for_life.glasses))
- .. ()
- return TRUE
-
-/datum/loadout_item/glasses/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only)
- if(outfit.glasses)
- LAZYADD(outfit.backpack_contents, outfit.glasses)
- outfit.glasses = item_path
- else
- outfit.glasses = item_path
-
-/datum/loadout_item/glasses/post_equip_item(datum/preferences/preference_source, mob/living/carbon/human/equipper)
- var/obj/item/clothing/glasses/equipped_glasses = locate(item_path) in equipper.get_equipped_items()
- if (!equipped_glasses)
- return
- if(equipped_glasses.glass_colour_type)
- equipper.update_glasses_color(equipped_glasses, TRUE)
- if(equipped_glasses.tint)
- equipper.update_tint()
- if(equipped_glasses.vision_flags \
- || equipped_glasses.invis_override \
- || equipped_glasses.invis_view \
- || !isnull(equipped_glasses.color_cutoffs))
- equipper.update_sight()
-/*
* PRESCRIPTION GLASSES
*/
/datum/loadout_item/glasses/prescription_glasses
name = "Glasses"
item_path = /obj/item/clothing/glasses/regular
- additional_tooltip_contents = list("PRESCRIPTION - This item functions with the 'nearsighted' quirk.")
+ additional_displayed_text = list("PRESCRIPTION")
/datum/loadout_item/glasses/prescription_glasses/circle_glasses
name = "Circle Glasses"
@@ -111,9 +75,6 @@ GLOBAL_LIST_INIT(loadout_glasses, generate_loadout_items(/datum/loadout_item/gla
name = "Medical Eyepatch"
item_path = /obj/item/clothing/glasses/eyepatch/medical
-/datum/loadout_item/glasses/blindfold
- name = "Blindfold"
- item_path = /obj/item/clothing/glasses/blindfold
/datum/loadout_item/glasses/fakeblindfold
name = "Fake Blindfold"
@@ -289,9 +250,7 @@ GLOBAL_LIST_INIT(loadout_glasses, generate_loadout_items(/datum/loadout_item/gla
* DONATOR
*/
-/datum/loadout_item/glasses/donator
- donator_only = TRUE
-
-/datum/loadout_item/glasses/donator/fake_sunglasses
+/datum/loadout_item/glasses/fake_sunglasses
name = "Fake Sunglasses"
item_path = /obj/item/clothing/glasses/fake_sunglasses
+ donator_only = TRUE
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_gloves.dm b/modular_skyrat/master_files/code/modules/loadout/categories/gloves.dm
similarity index 75%
rename from modular_skyrat/modules/loadouts/loadout_items/loadout_datum_gloves.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/gloves.dm
index 3d78c20d1aa..190c7a1db44 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_gloves.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/gloves.dm
@@ -1,24 +1,20 @@
-/*
-* LOADOUT ITEM DATUMS FOR THE HAND SLOT
-*/
-
-/// Glove Slot Items (Deletes overrided items)
-GLOBAL_LIST_INIT(loadout_gloves, generate_loadout_items(/datum/loadout_item/gloves))
+/datum/loadout_category/gloves
+ category_name = "Gloves"
+ category_ui_icon = FA_ICON_HAND
+ type_to_generate = /datum/loadout_item/gloves
+ tab_order = /datum/loadout_category/head::tab_order + 8
/datum/loadout_item/gloves
- category = LOADOUT_ITEM_GLOVES
+ abstract_type = /datum/loadout_item/gloves
-/datum/loadout_item/gloves/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE)
- if(initial(outfit_important_for_life.gloves))
- .. ()
- return TRUE
-
-/datum/loadout_item/gloves/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only)
- if(outfit.gloves)
- LAZYADD(outfit.backpack_contents, outfit.gloves)
- outfit.gloves = item_path
+/datum/loadout_item/gloves/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only, loadout_placement_preference)
+ if(equipper.dna?.species?.outfit_important_for_life)
+ if(!visuals_only)
+ to_chat(equipper, "Your loadout gloves were not equipped directly due to your species outfit.")
+ LAZYADD(outfit.backpack_contents, item_path)
else
+ if(loadout_placement_preference != LOADOUT_OVERRIDE_JOB && outfit.gloves)
+ LAZYADD(outfit.backpack_contents, outfit.gloves)
outfit.gloves = item_path
/datum/loadout_item/gloves/fingerless
@@ -64,7 +60,7 @@ GLOBAL_LIST_INIT(loadout_gloves, generate_loadout_items(/datum/loadout_item/glov
/datum/loadout_item/gloves/yellow
name = "Yellow Gloves"
item_path = /obj/item/clothing/gloves/color/ffyellow
- additional_tooltip_contents = list("NON-INSULATING - This item is purely cosmetic and provide no shock insulation.")
+ additional_displayed_text = list("NON-INSULATING - This item is purely cosmetic and provide no shock insulation.")
/datum/loadout_item/gloves/white
name = "White Gloves"
@@ -114,9 +110,7 @@ GLOBAL_LIST_INIT(loadout_gloves, generate_loadout_items(/datum/loadout_item/glov
* DONATOR
*/
-/datum/loadout_item/gloves/donator
- donator_only = TRUE
-
-/datum/loadout_item/gloves/donator/military
+/datum/loadout_item/gloves/military
name = "Military Gloves"
item_path = /obj/item/clothing/gloves/military
+ donator_only = TRUE
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_heads.dm b/modular_skyrat/master_files/code/modules/loadout/categories/heads.dm
similarity index 87%
rename from modular_skyrat/modules/loadouts/loadout_items/loadout_datum_heads.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/heads.dm
index f9bdd75292a..0180fff6ddc 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_heads.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/heads.dm
@@ -1,54 +1,7 @@
-/*
-* LOADOUT ITEM DATUMS FOR THE HEAD SLOT
-*/
-
-/// Head Slot Items (Moves overrided items to backpack)
-GLOBAL_LIST_INIT(loadout_helmets, generate_loadout_items(/datum/loadout_item/head))
-
-/datum/loadout_item/head
- category = LOADOUT_ITEM_HEAD
-
-/datum/loadout_item/head/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE)
- if(initial(outfit_important_for_life.head))
- .. ()
- return TRUE
-
-/datum/loadout_item/head/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only)
- if(outfit.head)
- LAZYADD(outfit.backpack_contents, outfit.head)
- outfit.head = item_path
- else
- outfit.head = item_path
-
/*
* BEANIES
*/
-/datum/loadout_item/head/white_beanie
- name = "Recolorable Beanie"
- item_path = /obj/item/clothing/head/beanie
-
-/datum/loadout_item/head/black_beanie
- name = "Black Beanie"
- item_path = /obj/item/clothing/head/beanie/black
-
-/datum/loadout_item/head/red_beanie
- name = "Red Beanie"
- item_path = /obj/item/clothing/head/beanie/red
-
-/datum/loadout_item/head/dark_blue_beanie
- name = "Dark Blue Beanie"
- item_path = /obj/item/clothing/head/beanie/darkblue
-
-/datum/loadout_item/head/yellow_beanie
- name = "Yellow Beanie"
- item_path = /obj/item/clothing/head/beanie/yellow
-
-/datum/loadout_item/head/orange_beanie
- name = "Orange Beanie"
- item_path = /obj/item/clothing/head/beanie/orange
-
/datum/loadout_item/head/rastafarian
name = "Rastafarian Cap"
item_path = /obj/item/clothing/head/rasta
@@ -61,11 +14,7 @@ GLOBAL_LIST_INIT(loadout_helmets, generate_loadout_items(/datum/loadout_item/hea
* BERETS
*/
-/datum/loadout_item/head/greyscale_beret
- name = "Greyscale Beret"
- item_path = /obj/item/clothing/head/beret
-
-/datum/loadout_item/head/greyscale_beret/badge
+/datum/loadout_item/head/beret_with_badge
name = "Greyscale Beret with Badge"
item_path = /obj/item/clothing/head/beret/badge
@@ -385,12 +334,12 @@ GLOBAL_LIST_INIT(loadout_helmets, generate_loadout_items(/datum/loadout_item/hea
/datum/loadout_item/head/maidhead
name = "Simple Maid Headband"
item_path = /obj/item/clothing/head/costume/skyrat/maid
- additional_tooltip_contents = list("Small headband that only fits on top the head.")
+ additional_displayed_text = list("Small headband that only fits on top the head.")
/datum/loadout_item/head/maidhead2
name = "Frilly Maid Headband"
item_path = /obj/item/clothing/head/costume/maidheadband
- additional_tooltip_contents = list("Larger headband from the maid rework. Fits around head and ears.")
+ additional_displayed_text = list("Larger headband from the maid rework. Fits around head and ears.")
/datum/loadout_item/head/wig
name = "Wig"
@@ -645,57 +594,60 @@ GLOBAL_LIST_INIT(loadout_helmets, generate_loadout_items(/datum/loadout_item/hea
name = "Deckers Hat"
item_path = /obj/item/clothing/head/costume/deckers
-/datum/loadout_item/head/saints
- name = "Fancy Hat"
- item_path = /obj/item/clothing/head/costume/fancy
-
/*
* DONATOR
*/
-/datum/loadout_item/head/donator
- donator_only = TRUE
/*
* FLOWERS
*/
-/datum/loadout_item/head/donator/poppy
+/datum/loadout_item/head/poppy
name = "Poppy Flower"
item_path = /obj/item/food/grown/poppy
+ donator_only = TRUE
-/datum/loadout_item/head/donator/lily
+/datum/loadout_item/head/lily
name = "Lily Flower"
item_path = /obj/item/food/grown/poppy/lily
+ donator_only = TRUE
-/datum/loadout_item/head/donator/geranium
+/datum/loadout_item/head/geranium
name = "Geranium Flower"
item_path = /obj/item/food/grown/poppy/geranium
+ donator_only = TRUE
-/datum/loadout_item/head/donator/fraxinella
+/datum/loadout_item/head/fraxinella
name = "Fraxinella Flower"
item_path = /obj/item/food/grown/poppy/geranium/fraxinella
+ donator_only = TRUE
-/datum/loadout_item/head/donator/harebell
+/datum/loadout_item/head/harebell
name = "Harebell Flower"
item_path = /obj/item/food/grown/harebell
+ donator_only = TRUE
-/datum/loadout_item/head/donator/rose
+/datum/loadout_item/head/rose
name = "Rose Flower"
item_path = /obj/item/food/grown/rose
+ donator_only = TRUE
-/datum/loadout_item/head/donator/carbon_rose
+/datum/loadout_item/head/carbon_rose
name = "Carbon Rose Flower"
item_path = /obj/item/grown/carbon_rose
+ donator_only = TRUE
-/datum/loadout_item/head/donator/sunflower
+/datum/loadout_item/head/sunflower
name = "Sunflower"
item_path = /obj/item/food/grown/sunflower
+ donator_only = TRUE
-/datum/loadout_item/head/donator/rainbow_bunch
+/datum/loadout_item/head/rainbow_bunch
name = "Rainbow Bunch"
item_path = /obj/item/food/grown/rainbow_flower
- additional_tooltip_contents = list(TOOLTIP_RANDOM_COLOR)
+ additional_displayed_text = list(TOOLTIP_RANDOM_COLOR)
+ donator_only = TRUE
// Legacy unpaintable cowboy hat because it fits a character better
/datum/loadout_item/head/cowboyhat_legacy
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_inhands.dm b/modular_skyrat/master_files/code/modules/loadout/categories/inhands.dm
similarity index 63%
rename from modular_skyrat/modules/loadouts/loadout_items/loadout_datum_inhands.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/inhands.dm
index 7d3cb8ff756..c0150492708 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_inhands.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/inhands.dm
@@ -1,27 +1,3 @@
-/*
-* LOADOUT ITEM DATUMS FOR BOTH HAND SLOTS
-*/
-
-/// Inhand items (Moves overrided items to backpack)
-GLOBAL_LIST_INIT(loadout_inhand_items, generate_loadout_items(/datum/loadout_item/inhand))
-
-/datum/loadout_item/inhand
- category = LOADOUT_ITEM_INHAND
-
-/datum/loadout_item/inhand/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE)
- // if no hands are available then put in backpack
- if(initial(outfit_important_for_life.r_hand) && initial(outfit_important_for_life.l_hand))
- if(!visuals_only)
- LAZYADD(outfit.backpack_contents, item_path)
- return TRUE
-
-/datum/loadout_item/inhand/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(outfit.l_hand && !outfit.r_hand)
- outfit.r_hand = item_path
- else
- if(outfit.l_hand)
- LAZYADD(outfit.backpack_contents, outfit.l_hand)
- outfit.l_hand = item_path
/datum/loadout_item/inhand/cane
name = "Cane"
@@ -31,10 +7,6 @@ GLOBAL_LIST_INIT(loadout_inhand_items, generate_loadout_items(/datum/loadout_ite
name = "Crutch"
item_path = /obj/item/cane/crutch
-/datum/loadout_item/inhand/cane/white
- name = "White Cane"
- item_path = /obj/item/cane/white
-
/datum/loadout_item/inhand/briefcase
name = "Briefcase"
item_path = /obj/item/storage/briefcase
@@ -72,10 +44,6 @@ GLOBAL_LIST_INIT(loadout_inhand_items, generate_loadout_items(/datum/loadout_ite
name = "Rose Bouquet"
item_path = /obj/item/bouquet/rose
-/datum/loadout_item/inhand/smokingpipe
- name = "Smoking Pipe"
- item_path = /obj/item/clothing/mask/cigarette/pipe
-
/datum/loadout_item/inhand/flag_nt
name = "Folded Nanotrasen Flag"
item_path = /obj/item/sign/flag/nanotrasen
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_masks.dm b/modular_skyrat/master_files/code/modules/loadout/categories/mask.dm
similarity index 84%
rename from modular_skyrat/modules/loadouts/loadout_items/loadout_datum_masks.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/mask.dm
index 160ff263b0b..b7de4ae7edd 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_masks.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/mask.dm
@@ -1,25 +1,16 @@
-/*
-* LOADOUT ITEM DATUMS FOR THE MASK SLOT
-*/
-
-/// Mask Slot Items (Deletes overrided items)
-GLOBAL_LIST_INIT(loadout_masks, generate_loadout_items(/datum/loadout_item/mask))
+/datum/loadout_category/mask
+ category_name = "Masks"
+ category_ui_icon = FA_ICON_MASK
+ type_to_generate = /datum/loadout_item/mask
+ tab_order = /datum/loadout_category/head::tab_order + 12
/datum/loadout_item/mask
- category = LOADOUT_ITEM_MASK
+ abstract_type = /datum/loadout_item/mask
-/datum/loadout_item/mask/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE)
- if(initial(outfit_important_for_life.mask))
- ..()
- return TRUE
-
-/datum/loadout_item/mask/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only)
- if(outfit.mask)
- LAZYADD(outfit.backpack_contents, outfit.mask)
- outfit.mask = item_path
- else
- outfit.mask = item_path
+/datum/loadout_item/mask/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only, loadout_placement_preference)
+ if(loadout_placement_preference != LOADOUT_OVERRIDE_JOB && outfit.mask)
+ LAZYADD(outfit.backpack_contents, outfit.mask)
+ outfit.mask = item_path
/*
* BANDANAS
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_neck.dm b/modular_skyrat/master_files/code/modules/loadout/categories/neck.dm
similarity index 86%
rename from modular_skyrat/modules/loadouts/loadout_items/loadout_datum_neck.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/neck.dm
index 5b8e042926e..f783703dc53 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_neck.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/neck.dm
@@ -1,25 +1,3 @@
-/*
-* LOADOUT ITEM DATUMS FOR THE NECK SLOT
-*/
-
-/// Neck Slot Items (Deletes overrided items)
-GLOBAL_LIST_INIT(loadout_necks, generate_loadout_items(/datum/loadout_item/neck))
-
-/datum/loadout_item/neck
- category = LOADOUT_ITEM_NECK
-
-/datum/loadout_item/neck/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE)
- if(initial(outfit_important_for_life.neck))
- .. ()
- return TRUE
-
-/datum/loadout_item/neck/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(override_items == LOADOUT_OVERRIDE_BACKPACK)
- if(outfit.neck)
- LAZYADD(outfit.backpack_contents, outfit.neck && !visuals_only)
- outfit.neck = item_path
- else
- outfit.neck = item_path
/*
@@ -66,9 +44,6 @@ GLOBAL_LIST_INIT(loadout_necks, generate_loadout_items(/datum/loadout_item/neck)
name = "Yellow Scarf"
item_path = /obj/item/clothing/neck/scarf/yellow
-/datum/loadout_item/neck/scarf_white
- name = "White Scarf"
- item_path = /obj/item/clothing/neck/scarf
/datum/loadout_item/neck/scarf_red_striped
name = "Striped Red Scarf"
@@ -86,10 +61,6 @@ GLOBAL_LIST_INIT(loadout_necks, generate_loadout_items(/datum/loadout_item/neck)
name = "Zebra Scarf"
item_path = /obj/item/clothing/neck/scarf/zebra
-/datum/loadout_item/neck/scarf_infinity
- name = "Infinity Scarf"
- item_path = /obj/item/clothing/neck/infinity_scarf
-
/*
* NECKTIES
*/
@@ -287,10 +258,6 @@ BUBBER EDIT END */
name = "Maid Neck Cover"
item_path = /obj/item/clothing/neck/maid
-/datum/loadout_item/neck/link_scryer
- name = "MODlink Scryer"
- item_path = /obj/item/clothing/neck/link_scryer/loaded
-
/datum/loadout_item/neck/holobadge
name = "Holobadge"
item_path = /obj/item/clothing/accessory/badge/holo
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_pocket.dm b/modular_skyrat/master_files/code/modules/loadout/categories/pocket.dm
similarity index 99%
rename from modular_skyrat/modules/loadouts/loadout_items/loadout_datum_pocket.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/pocket.dm
index b84a5ace076..67087ff72cc 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_pocket.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/pocket.dm
@@ -354,4 +354,4 @@ GLOBAL_LIST_INIT(loadout_pocket_items, generate_loadout_items(/datum/loadout_ite
/datum/loadout_item/pocket_items/donator/vape
name = "E-Cigarette"
- item_path = /obj/item/clothing/mask/vape
\ No newline at end of file
+ item_path = /obj/item/clothing/mask/vape
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_shoes.dm b/modular_skyrat/master_files/code/modules/loadout/categories/shoes.dm
similarity index 89%
rename from modular_skyrat/modules/loadouts/loadout_items/loadout_datum_shoes.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/shoes.dm
index 71d665a904e..2dc0c1ff29d 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_shoes.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/shoes.dm
@@ -1,25 +1,16 @@
-/*
-* LOADOUT ITEM DATUMS FOR THE SHOE SLOT
-*/
-
-/// Shoe Slot Items (Deletes overrided items)
-GLOBAL_LIST_INIT(loadout_shoes, generate_loadout_items(/datum/loadout_item/shoes))
+/datum/loadout_category/shoes
+ category_name = "Shoes"
+ category_ui_icon = FA_ICON_SHOE_PRINTS
+ type_to_generate = /datum/loadout_item/shoes
+ tab_order = /datum/loadout_category/head::tab_order + 11
/datum/loadout_item/shoes
- category = LOADOUT_ITEM_SHOES
+ abstract_type = /datum/loadout_item/shoes
-/datum/loadout_item/shoes/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE)
- if(initial(outfit_important_for_life.shoes))
- .. ()
- return TRUE
-
-/datum/loadout_item/shoes/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only)
- if(outfit.shoes)
- LAZYADD(outfit.backpack_contents, outfit.shoes)
- outfit.shoes = item_path
- else
- outfit.shoes = item_path
+/datum/loadout_item/shoes/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only, loadout_placement_preference)
+ if(loadout_placement_preference != LOADOUT_OVERRIDE_JOB && outfit.shoes)
+ LAZYADD(outfit.backpack_contents, outfit.shoes)
+ outfit.shoes = item_path
/*
* JACKBOOTS
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_suit.dm b/modular_skyrat/master_files/code/modules/loadout/categories/suit.dm
similarity index 96%
rename from modular_skyrat/modules/loadouts/loadout_items/loadout_datum_suit.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/suit.dm
index 11ba23c667b..bda99eccec6 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_suit.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/suit.dm
@@ -1,24 +1,16 @@
-/*
-* LOADOUT ITEM DATUMS FOR THE (EXO/OUTER)SUIT SLOT
-*/
-
-/// Exosuit / Outersuit Slot Items (Moves items to backpack)
-GLOBAL_LIST_INIT(loadout_exosuits, generate_loadout_items(/datum/loadout_item/suit))
+/datum/loadout_category/suit
+ category_name = "Suits"
+ category_ui_icon = FA_ICON_TOILET
+ type_to_generate = /datum/loadout_item/suit
+ tab_order = /datum/loadout_category/head::tab_order + 10
/datum/loadout_item/suit
- category = LOADOUT_ITEM_SUIT
+ abstract_type = /datum/loadout_item/suit
-/datum/loadout_item/suit/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE) // don't bother storing in backpack, can't fit
- if(initial(outfit_important_for_life.suit))
- return TRUE
-
-/datum/loadout_item/suit/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only)
- if(outfit.suit)
- LAZYADD(outfit.backpack_contents, outfit.suit)
- outfit.suit = item_path
- else
- outfit.suit = item_path
+/datum/loadout_item/suit/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only, loadout_placement_preference)
+ if(loadout_placement_preference != LOADOUT_OVERRIDE_JOB && outfit.suit)
+ LAZYADD(outfit.backpack_contents, outfit.suit)
+ outfit.suit = item_path
/*
* WINTER COATS
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_toys.dm b/modular_skyrat/master_files/code/modules/loadout/categories/toys.dm
similarity index 96%
rename from modular_skyrat/modules/loadouts/loadout_items/loadout_datum_toys.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/toys.dm
index cfb0cc14e3a..e6315cda2dc 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_toys.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/toys.dm
@@ -1,14 +1,11 @@
-GLOBAL_LIST_INIT(loadout_toys, generate_loadout_items(/datum/loadout_item/toys))
+/datum/loadout_category/toys
+ category_name = "Toys"
+ category_ui_icon = FA_ICON_GOLF_BALL
+ type_to_generate = /datum/loadout_item/toys
+ tab_order = /datum/loadout_category/head::tab_order + 13
/datum/loadout_item/toys
- category = LOADOUT_ITEM_TOYS
-
-/*
-* PLUSHIES
-*/
-
-/datum/loadout_item/toys/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE) // these go in the backpack
- return FALSE
+ abstract_type = /datum/loadout_item/toys
/datum/loadout_item/toys/bee
name = "Bee Plushie"
diff --git a/modular_skyrat/modules/loadouts/loadout_items/under/loadout_datum_under.dm b/modular_skyrat/master_files/code/modules/loadout/categories/uniform.dm
similarity index 64%
rename from modular_skyrat/modules/loadouts/loadout_items/under/loadout_datum_under.dm
rename to modular_skyrat/master_files/code/modules/loadout/categories/uniform.dm
index 9269b02860a..fe44fdcc656 100644
--- a/modular_skyrat/modules/loadouts/loadout_items/under/loadout_datum_under.dm
+++ b/modular_skyrat/master_files/code/modules/loadout/categories/uniform.dm
@@ -1,244 +1,233 @@
+/datum/loadout_category/uniform
+ category_name = "Uniform"
+ category_ui_icon = FA_ICON_SHIRT
+ type_to_generate = /datum/loadout_item/uniform
+ tab_order = /datum/loadout_category/head::tab_order + 9
-// --- Loadout item datums for under suits ---
+/datum/loadout_item/uniform
+ abstract_type = /datum/loadout_item/uniform
-/// Underslot - Jumpsuit Items (Deletes overrided items)
-GLOBAL_LIST_INIT(loadout_jumpsuits, generate_loadout_items(/datum/loadout_item/under/jumpsuit))
-
-/// Underslot - Formal Suit Items (Deletes overrided items)
-GLOBAL_LIST_INIT(loadout_undersuits, generate_loadout_items(/datum/loadout_item/under/formal))
-
-/// Underslot - Misc. Under Items (Deletes overrided items)
-GLOBAL_LIST_INIT(loadout_miscunders, generate_loadout_items(/datum/loadout_item/under/miscellaneous))
-
-/datum/loadout_item/under
- category = LOADOUT_ITEM_UNIFORM
-
-/datum/loadout_item/under/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE)
- if(initial(outfit_important_for_life.uniform))
- .. ()
- return TRUE
-
-/datum/loadout_item/under/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only)
- if(outfit.uniform)
+/datum/loadout_item/uniform/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only, loadout_placement_preference)
+ if(equipper.dna?.species?.outfit_important_for_life)
+ if(!visuals_only)
+ to_chat(equipper, "Your loadout uniform was not equipped directly due to your species outfit.")
+ LAZYADD(outfit.backpack_contents, item_path)
+ else
+ if(loadout_placement_preference != LOADOUT_OVERRIDE_JOB && outfit.uniform)
LAZYADD(outfit.backpack_contents, outfit.uniform)
outfit.uniform = item_path
- else
- outfit.uniform = item_path
- outfit.modified_outfit_slots |= ITEM_SLOT_ICLOTHING
+
/*
* JUMPSUITS
*/
-/datum/loadout_item/under/jumpsuit
-
-/datum/loadout_item/under/jumpsuit/greyscale
+/datum/loadout_item/uniform/jumpsuit/greyscale
name = "Greyscale Jumpsuit"
item_path = /obj/item/clothing/under/color
-/datum/loadout_item/under/jumpsuit/greyscale_skirt
+/datum/loadout_item/uniform/jumpsuit/greyscale_skirt
name = "Greyscale Jumpskirt"
item_path = /obj/item/clothing/under/color/jumpskirt
-/datum/loadout_item/under/jumpsuit/random
+/datum/loadout_item/uniform/jumpsuit/random
name = "Random Jumpsuit"
item_path = /obj/item/clothing/under/color/random
- additional_tooltip_contents = list(TOOLTIP_RANDOM_COLOR)
+ additional_displayed_text = list(TOOLTIP_RANDOM_COLOR)
-/datum/loadout_item/under/jumpsuit/random_skirt
+/datum/loadout_item/uniform/jumpsuit/random_skirt
name = "Random Jumpskirt"
item_path = /obj/item/clothing/under/color/jumpskirt/random
- additional_tooltip_contents = list(TOOLTIP_RANDOM_COLOR)
+ additional_displayed_text = list(TOOLTIP_RANDOM_COLOR)
-/datum/loadout_item/under/jumpsuit/rainbow
+/datum/loadout_item/uniform/jumpsuit/rainbow
name = "Rainbow Jumpsuit"
item_path = /obj/item/clothing/under/color/rainbow
-/datum/loadout_item/under/jumpsuit/rainbow_skirt
+/datum/loadout_item/uniform/jumpsuit/rainbow_skirt
name = "Rainbow Jumpskirt"
item_path = /obj/item/clothing/under/color/jumpskirt/rainbow
-/datum/loadout_item/under/jumpsuit/akula_wetsuit
+/datum/loadout_item/uniform/jumpsuit/akula_wetsuit
name = "Shoredress Wetsuit"
item_path = /obj/item/clothing/under/akula_wetsuit
-/datum/loadout_item/under/jumpsuit/impcap
+/datum/loadout_item/uniform/jumpsuit/impcap
name = "Captain's Naval Jumpsuit"
item_path = /obj/item/clothing/under/rank/captain/skyrat/imperial
restricted_roles = list(JOB_CAPTAIN, JOB_NT_REP)
-/datum/loadout_item/under/jumpsuit/imphop
+/datum/loadout_item/uniform/jumpsuit/imphop
name = "Head of Personnel's Naval Jumpsuit"
item_path = /obj/item/clothing/under/rank/civilian/head_of_personnel/skyrat/imperial
restricted_roles = list(JOB_HEAD_OF_PERSONNEL, JOB_NT_REP)
-/datum/loadout_item/under/jumpsuit/imphos
+/datum/loadout_item/uniform/jumpsuit/imphos
name = "Head of Security's Naval Uniform"
item_path = /obj/item/clothing/under/rank/security/head_of_security/skyrat/imperial
restricted_roles = list(JOB_HEAD_OF_SECURITY)
-/datum/loadout_item/under/jumpsuit/impcmo
+/datum/loadout_item/uniform/jumpsuit/impcmo
name = "Chief Medical Officer's Naval Uniform"
item_path = /obj/item/clothing/under/rank/medical/chief_medical_officer/skyrat/imperial
restricted_roles = list(JOB_CHIEF_MEDICAL_OFFICER)
-/datum/loadout_item/under/jumpsuit/impce
+/datum/loadout_item/uniform/jumpsuit/impce
name = "Chief Engineer's Naval Uniform"
item_path = /obj/item/clothing/under/rank/engineering/chief_engineer/skyrat/imperial
restricted_roles = list(JOB_CHIEF_ENGINEER)
-/datum/loadout_item/under/jumpsuit/imprd
+/datum/loadout_item/uniform/jumpsuit/imprd
name = "Research Director's Naval Uniform"
item_path = /obj/item/clothing/under/rank/rnd/research_director/skyrat/imperial
restricted_roles = list(JOB_RESEARCH_DIRECTOR)
-/datum/loadout_item/under/jumpsuit/impcommand
+/datum/loadout_item/uniform/jumpsuit/impcommand
name = "Light Grey Officer's Naval Jumpsuit"
item_path = /obj/item/clothing/under/rank/captain/skyrat/imperial/generic
-/datum/loadout_item/under/jumpsuit/impcom
+/datum/loadout_item/uniform/jumpsuit/impcom
name = "Grey Officer's Naval Jumpsuit"
item_path = /obj/item/clothing/under/rank/captain/skyrat/imperial/generic/grey
-/datum/loadout_item/under/jumpsuit/impred
+/datum/loadout_item/uniform/jumpsuit/impred
name = "Red Officer's Naval Jumpsuit"
item_path = /obj/item/clothing/under/rank/captain/skyrat/imperial/generic/red
-/datum/loadout_item/under/jumpsuit/impcomtrous
+/datum/loadout_item/uniform/jumpsuit/impcomtrous
name = "Grey Officer's Naval Jumpsuit (Trousers)"
item_path = /obj/item/clothing/under/rank/captain/skyrat/imperial/generic/pants
-/datum/loadout_item/under/jumpsuit/security_skirt
+/datum/loadout_item/uniform/jumpsuit/security_skirt
name = "Security Battledress"
item_path = /obj/item/clothing/under/rank/security/peacekeeper/skirt
restricted_roles = list(JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_HEAD_OF_SECURITY)
-/datum/loadout_item/under/jumpsuit/security_trousers
+/datum/loadout_item/uniform/jumpsuit/security_trousers
name = "Security Trousers"
item_path = /obj/item/clothing/under/rank/security/peacekeeper/trousers
restricted_roles = list(JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_HEAD_OF_SECURITY, JOB_SECURITY_MEDIC)
-/datum/loadout_item/under/jumpsuit/security_shorts
+/datum/loadout_item/uniform/jumpsuit/security_shorts
name = "Security Shorts"
item_path = /obj/item/clothing/under/rank/security/peacekeeper/trousers/shorts
restricted_roles = list(JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_HEAD_OF_SECURITY)
-/datum/loadout_item/under/jumpsuit/security_jumpskirt
+/datum/loadout_item/uniform/jumpsuit/security_jumpskirt
name = "Security Jumpskirt"
item_path = /obj/item/clothing/under/rank/security/officer/skirt
restricted_roles = list(JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_HEAD_OF_SECURITY)
-/datum/loadout_item/under/jumpsuit/security_shortskirt
+/datum/loadout_item/uniform/jumpsuit/security_shortskirt
name = "Security Shortskirt"
item_path = /obj/item/clothing/under/rank/security/peacekeeper/shortskirt
restricted_roles = list(JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_HEAD_OF_SECURITY)
-/datum/loadout_item/under/jumpsuit/security_miniskirt
+/datum/loadout_item/uniform/jumpsuit/security_miniskirt
name = "Security Miniskirt"
item_path = /obj/item/clothing/under/rank/security/peacekeeper/miniskirt
restricted_roles = list(JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_HEAD_OF_SECURITY)
-/datum/loadout_item/under/jumpsuit/security_jumpsuit
+/datum/loadout_item/uniform/jumpsuit/security_jumpsuit
name = "Security Jumpsuit"
item_path = /obj/item/clothing/under/rank/security/peacekeeper/jumpsuit
restricted_roles = list(JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_HEAD_OF_SECURITY)
-/datum/loadout_item/under/jumpsuit/security_peacekeeper
+/datum/loadout_item/uniform/jumpsuit/security_peacekeeper
name = "Security Peacekeeper Uniform"
item_path = /obj/item/clothing/under/rank/security/peacekeeper
restricted_roles = list(JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_HEAD_OF_SECURITY, JOB_SECURITY_MEDIC)
-/datum/loadout_item/under/jumpsuit/imperial_police_uniform
+/datum/loadout_item/uniform/jumpsuit/imperial_police_uniform
name = "Imperial Police Uniform"
item_path = /obj/item/clothing/under/colonial/nri_police
restricted_roles = list(JOB_SECURITY_OFFICER, JOB_DETECTIVE)
-/datum/loadout_item/under/jumpsuit/disco
+/datum/loadout_item/uniform/jumpsuit/disco
name = "Superstar Cop Uniform"
item_path = /obj/item/clothing/under/rank/security/detective/disco
-/datum/loadout_item/under/jumpsuit/kim
+/datum/loadout_item/uniform/jumpsuit/kim
name = "Aerostatic Suit"
item_path = /obj/item/clothing/under/rank/security/detective/kim
-/datum/loadout_item/under/jumpsuit/paramed_light
+/datum/loadout_item/uniform/jumpsuit/paramed_light
name = "Light Paramedic Uniform"
item_path = /obj/item/clothing/under/rank/medical/paramedic/skyrat/light
-/datum/loadout_item/under/jumpsuit/paramed_light_skirt
+/datum/loadout_item/uniform/jumpsuit/paramed_light_skirt
name = "Light Paramedic Skirt"
item_path = /obj/item/clothing/under/rank/medical/paramedic/skyrat/light/skirt
-/datum/loadout_item/under/jumpsuit/chemist_formal
+/datum/loadout_item/uniform/jumpsuit/chemist_formal
name = "Chemist's Formal Jumpsuit"
item_path = /obj/item/clothing/under/rank/medical/chemist/skyrat/formal
-/datum/loadout_item/under/jumpsuit/chemist_formal_skirt
+/datum/loadout_item/uniform/jumpsuit/chemist_formal_skirt
name = "Chemist's Formal Jumpskirt"
item_path = /obj/item/clothing/under/rank/medical/chemist/skyrat/formal/skirt
-/datum/loadout_item/under/jumpsuit/viro_jumpsuit
+/datum/loadout_item/uniform/jumpsuit/viro_jumpsuit
name = "Virologist's Jumpsuit"
item_path = /obj/item/clothing/under/rank/medical/virologist
-/datum/loadout_item/under/jumpsuit/hlscientist
+/datum/loadout_item/uniform/jumpsuit/hlscientist
name = "Ridiculous Scientist Outfit"
item_path = /obj/item/clothing/under/rank/rnd/scientist/skyrat/hlscience
-/datum/loadout_item/under/jumpsuit/rd_jumpsuit
+/datum/loadout_item/uniform/jumpsuit/rd_jumpsuit
name = "Research Director's Jumpsuit"
item_path = /obj/item/clothing/under/rank/rnd/research_director/skyrat/jumpsuit
restricted_roles = list(JOB_RESEARCH_DIRECTOR)
-/datum/loadout_item/under/jumpsuit/rd_jumpskirt
+/datum/loadout_item/uniform/jumpsuit/rd_jumpskirt
name = "Research Director's Jumpskirt"
item_path = /obj/item/clothing/under/rank/rnd/research_director/skyrat/jumpsuit/skirt
restricted_roles = list(JOB_RESEARCH_DIRECTOR)
-/datum/loadout_item/under/jumpsuit/cargo
+/datum/loadout_item/uniform/jumpsuit/cargo
name = "Cargo Technician's Jumpsuit"
item_path = /obj/item/clothing/under/rank/cargo/tech
-/datum/loadout_item/under/jumpsuit/cargo/skirt
+/datum/loadout_item/uniform/jumpsuit/cargo/skirt
name = "Cargo Technician's Skirt"
item_path = /obj/item/clothing/under/rank/cargo/tech/skirt
-/datum/loadout_item/under/jumpsuit/cargo/skirt/alt
+/datum/loadout_item/uniform/jumpsuit/cargo/skirt/alt
name = "Cargo Technician's Shortskirt"
item_path = /obj/item/clothing/under/rank/cargo/tech/skirt/alt
-/datum/loadout_item/under/jumpsuit/cargo/qm
+/datum/loadout_item/uniform/jumpsuit/cargo/qm
name = "Quartermaster's Uniform"
item_path = /obj/item/clothing/under/rank/cargo/qm
restricted_roles = list(JOB_QUARTERMASTER)
-/datum/loadout_item/under/jumpsuit/utility
+/datum/loadout_item/uniform/jumpsuit/utility
name = "Utility Uniform"
item_path = /obj/item/clothing/under/misc/skyrat/utility
-/datum/loadout_item/under/jumpsuit/utility_eng
+/datum/loadout_item/uniform/jumpsuit/utility_eng
name = "Engineering Utility Uniform"
item_path = /obj/item/clothing/under/rank/engineering/engineer/skyrat/utility
-/datum/loadout_item/under/jumpsuit/utility_med
+/datum/loadout_item/uniform/jumpsuit/utility_med
name = "Medical Utility Uniform"
item_path = /obj/item/clothing/under/rank/medical/doctor/skyrat/utility
-/datum/loadout_item/under/jumpsuit/utility_sci
+/datum/loadout_item/uniform/jumpsuit/utility_sci
name = "Science Utility Uniform"
item_path = /obj/item/clothing/under/rank/rnd/scientist/skyrat/utility
-/datum/loadout_item/under/jumpsuit/utility_cargo
+/datum/loadout_item/uniform/jumpsuit/utility_cargo
name = "Supply Utility Uniform"
item_path = /obj/item/clothing/under/rank/cargo/tech/skyrat/utility
-/datum/loadout_item/under/jumpsuit/utility_sec
+/datum/loadout_item/uniform/jumpsuit/utility_sec
name = "Security Utility Uniform"
item_path = /obj/item/clothing/under/rank/security/skyrat/utility
restricted_roles = list(JOB_SECURITY_OFFICER, JOB_DETECTIVE, JOB_WARDEN, JOB_BLUESHIELD, JOB_HEAD_OF_SECURITY, JOB_CORRECTIONS_OFFICER)
-/datum/loadout_item/under/jumpsuit/utility_com
+/datum/loadout_item/uniform/jumpsuit/utility_com
name = "Command Utility Uniform"
item_path = /obj/item/clothing/under/rank/captain/skyrat/utility
restricted_roles = list(JOB_CAPTAIN, JOB_HEAD_OF_PERSONNEL, JOB_BLUESHIELD, JOB_HEAD_OF_SECURITY, JOB_RESEARCH_DIRECTOR, JOB_QUARTERMASTER, JOB_CHIEF_MEDICAL_OFFICER, JOB_CHIEF_ENGINEER)
@@ -247,422 +236,422 @@ GLOBAL_LIST_INIT(loadout_miscunders, generate_loadout_items(/datum/loadout_item/
* MISC UNDERSUITS
*/
-/datum/loadout_item/under/miscellaneous
+/datum/loadout_item/uniform/miscellaneous
-/datum/loadout_item/under/miscellaneous/christmas
+/datum/loadout_item/uniform/miscellaneous/christmas
name = "Christmas Suit"
item_path = /obj/item/clothing/under/costume/skyrat/christmas
-/datum/loadout_item/under/miscellaneous/christmas/green
+/datum/loadout_item/uniform/miscellaneous/christmas/green
name = "Green Christmas Suit"
item_path = /obj/item/clothing/under/costume/skyrat/christmas/green
-/datum/loadout_item/under/miscellaneous/christmas/female
+/datum/loadout_item/uniform/miscellaneous/christmas/female
name = "Revealing Christmas Suit"
item_path = /obj/item/clothing/under/costume/skyrat/christmas/croptop
-/datum/loadout_item/under/miscellaneous/christmas/female/green
+/datum/loadout_item/uniform/miscellaneous/christmas/female/green
name = "Revealing Green Christmas Suit"
item_path = /obj/item/clothing/under/costume/skyrat/christmas/croptop/green
-/datum/loadout_item/under/miscellaneous/buttondown
+/datum/loadout_item/uniform/miscellaneous/buttondown
name = "Recolorable Buttondown Shirt with Slacks"
item_path = /obj/item/clothing/under/costume/buttondown/slacks
-/datum/loadout_item/under/miscellaneous/buttondown_shorts
+/datum/loadout_item/uniform/miscellaneous/buttondown_shorts
name = "Recolorable Buttondown Shirt with Shorts"
item_path = /obj/item/clothing/under/costume/buttondown/shorts
-/datum/loadout_item/under/miscellaneous/buttondown_skirt
+/datum/loadout_item/uniform/miscellaneous/buttondown_skirt
name = "Recolorable Buttondown Shirt with Skirt"
item_path = /obj/item/clothing/under/costume/buttondown/skirt
-/datum/loadout_item/under/miscellaneous/vicvest
+/datum/loadout_item/uniform/miscellaneous/vicvest
name = "Recolorable Buttondown Shirt with Double-Breasted Vest"
item_path = /obj/item/clothing/under/pants/skyrat/vicvest
-/datum/loadout_item/under/miscellaneous/slacks
+/datum/loadout_item/uniform/miscellaneous/slacks
name = "Recolorable Slacks"
item_path = /obj/item/clothing/under/pants/slacks
-/datum/loadout_item/under/miscellaneous/jeans
+/datum/loadout_item/uniform/miscellaneous/jeans
name = "Recolorable Jeans"
item_path = /obj/item/clothing/under/pants/jeans
-/datum/loadout_item/under/miscellaneous/jeansripped
+/datum/loadout_item/uniform/miscellaneous/jeansripped
name = "Recolorable Ripped Jeans"
item_path = /obj/item/clothing/under/pants/skyrat/jeans_ripped
-/datum/loadout_item/under/miscellaneous/yoga
+/datum/loadout_item/uniform/miscellaneous/yoga
name = "Recolorable Yoga Pants"
item_path = /obj/item/clothing/under/pants/skyrat/yoga
-/datum/loadout_item/under/miscellaneous/track
+/datum/loadout_item/uniform/miscellaneous/track
name = "Track Pants"
item_path = /obj/item/clothing/under/pants/track
-/datum/loadout_item/under/miscellaneous/camo
+/datum/loadout_item/uniform/miscellaneous/camo
name = "Camo Pants"
item_path = /obj/item/clothing/under/pants/camo
-/datum/loadout_item/under/miscellaneous/jeanshorts //This doesnt look like a word. Short. Jean-Short. Eugh.
+/datum/loadout_item/uniform/miscellaneous/jeanshorts //This doesnt look like a word. Short. Jean-Short. Eugh.
name = "Recolorable Jean Shorts"
item_path = /obj/item/clothing/under/shorts/jeanshorts
-/datum/loadout_item/under/miscellaneous/pants_blackshorts
+/datum/loadout_item/uniform/miscellaneous/pants_blackshorts
name = "Recolorable Ripped Jean Shorts"
item_path = /obj/item/clothing/under/shorts/skyrat/shorts_ripped
-/datum/loadout_item/under/miscellaneous/shortershorts
+/datum/loadout_item/uniform/miscellaneous/shortershorts
name = "Recolorable Shorter Shorts"
item_path = /obj/item/clothing/under/shorts/skyrat/shortershorts
-/datum/loadout_item/under/miscellaneous/shorts
+/datum/loadout_item/uniform/miscellaneous/shorts
name = "Recolorable Shorts"
item_path = /obj/item/clothing/under/shorts
-/datum/loadout_item/under/miscellaneous/red_short
+/datum/loadout_item/uniform/miscellaneous/red_short
name = "Red Shorts"
item_path = /obj/item/clothing/under/shorts/red
-/datum/loadout_item/under/miscellaneous/green_short
+/datum/loadout_item/uniform/miscellaneous/green_short
name = "Green Shorts"
item_path = /obj/item/clothing/under/shorts/green
-/datum/loadout_item/under/miscellaneous/blue_short
+/datum/loadout_item/uniform/miscellaneous/blue_short
name = "Blue Shorts"
item_path = /obj/item/clothing/under/shorts/blue
-/datum/loadout_item/under/miscellaneous/black_short
+/datum/loadout_item/uniform/miscellaneous/black_short
name = "Black Shorts"
item_path = /obj/item/clothing/under/shorts/black
-/datum/loadout_item/under/miscellaneous/grey_short
+/datum/loadout_item/uniform/miscellaneous/grey_short
name = "Grey Shorts"
item_path = /obj/item/clothing/under/shorts/grey
-/datum/loadout_item/under/miscellaneous/purple_short
+/datum/loadout_item/uniform/miscellaneous/purple_short
name = "Purple Shorts"
item_path = /obj/item/clothing/under/shorts/purple
-/datum/loadout_item/under/miscellaneous/recolorable_kilt
+/datum/loadout_item/uniform/miscellaneous/recolorable_kilt
name = "Recolorable Kilt"
item_path = /obj/item/clothing/under/pants/skyrat/kilt
//TODO: split loadout's miscellaneous to have "Pants/Shorts" and "Dresses/Skirts" as options too. Misc is stupid.
-/datum/loadout_item/under/miscellaneous/dress_striped
+/datum/loadout_item/uniform/miscellaneous/dress_striped
name = "Striped Dress"
item_path = /obj/item/clothing/under/dress/striped
-/datum/loadout_item/under/miscellaneous/skirt_black
+/datum/loadout_item/uniform/miscellaneous/skirt_black
name = "Black Skirt"
item_path = /obj/item/clothing/under/dress/skirt
-/datum/loadout_item/under/miscellaneous/skirt_plaid
+/datum/loadout_item/uniform/miscellaneous/skirt_plaid
name = "Recolorable Plaid Skirt"
item_path = /obj/item/clothing/under/dress/skirt/plaid
-/datum/loadout_item/under/miscellaneous/skirt_turtleneck
+/datum/loadout_item/uniform/miscellaneous/skirt_turtleneck
name = "Recolorable Turtleneck Skirt"
item_path = /obj/item/clothing/under/dress/skirt/turtleskirt
-/datum/loadout_item/under/miscellaneous/skirt_cableknit
+/datum/loadout_item/uniform/miscellaneous/skirt_cableknit
name = "Recolorable Cableknit Skirt"
item_path = /obj/item/clothing/under/dress/skirt/skyrat/turtleskirt_knit
-/datum/loadout_item/under/miscellaneous/dress_tango
+/datum/loadout_item/uniform/miscellaneous/dress_tango
name = "Recolorable Tango Dress"
item_path = /obj/item/clothing/under/dress/tango
-/datum/loadout_item/under/miscellaneous/dress_sun
+/datum/loadout_item/uniform/miscellaneous/dress_sun
name = "Recolorable Sundress"
item_path = /obj/item/clothing/under/dress/sundress
-/datum/loadout_item/under/miscellaneous/straplessdress
+/datum/loadout_item/uniform/miscellaneous/straplessdress
name = "Recolorable Strapless Dress"
item_path = /obj/item/clothing/under/dress/skyrat/strapless
-/datum/loadout_item/under/miscellaneous/pentagramdress
+/datum/loadout_item/uniform/miscellaneous/pentagramdress
name = "Recolorable Pentagram Strapped Dress"
item_path = /obj/item/clothing/under/dress/skyrat/pentagram
-/datum/loadout_item/under/miscellaneous/jacarta_dress
+/datum/loadout_item/uniform/miscellaneous/jacarta_dress
name = "Jacarta Dress"
item_path = /obj/item/clothing/under/dress/skyrat/jute
-/datum/loadout_item/under/miscellaneous/striped_skirt
+/datum/loadout_item/uniform/miscellaneous/striped_skirt
name = "Red Striped Skirt"
item_path = /obj/item/clothing/under/dress/skirt/skyrat/striped_skirt
-/datum/loadout_item/under/miscellaneous/red_skirt
+/datum/loadout_item/uniform/miscellaneous/red_skirt
name = "Red Skirt"
item_path = /obj/item/clothing/under/dress/skirt/skyrat/red_skirt
-/datum/loadout_item/under/miscellaneous/black_skirt
+/datum/loadout_item/uniform/miscellaneous/black_skirt
name = "Black Skirt (Skyrat)"
item_path = /obj/item/clothing/under/dress/skirt/skyrat/black_skirt
-/datum/loadout_item/under/miscellaneous/swept_skirt
+/datum/loadout_item/uniform/miscellaneous/swept_skirt
name = "Swept Skirt"
item_path = /obj/item/clothing/under/dress/skirt/skyrat/swept
-/datum/loadout_item/under/miscellaneous/lone_skirt
+/datum/loadout_item/uniform/miscellaneous/lone_skirt
name = "Recolorable Skirt"
item_path = /obj/item/clothing/under/dress/skirt/skyrat/lone_skirt
-/datum/loadout_item/under/miscellaneous/medium_skirt
+/datum/loadout_item/uniform/miscellaneous/medium_skirt
name = "Medium Colourable Skirt"
item_path = /obj/item/clothing/under/dress/skirt/skyrat/medium
-/datum/loadout_item/under/miscellaneous/long_skirt
+/datum/loadout_item/uniform/miscellaneous/long_skirt
name = "Long Colourable Skirt"
item_path = /obj/item/clothing/under/dress/skirt/skyrat/long
-/datum/loadout_item/under/miscellaneous/denim_skirt
+/datum/loadout_item/uniform/miscellaneous/denim_skirt
name = "Jean Skirt"
item_path = /obj/item/clothing/under/dress/skirt/skyrat/jean
-/datum/loadout_item/under/miscellaneous/littleblack
+/datum/loadout_item/uniform/miscellaneous/littleblack
name = "Short Black Dress"
item_path = /obj/item/clothing/under/dress/skyrat/short_dress
-/datum/loadout_item/under/miscellaneous/pinktutu
+/datum/loadout_item/uniform/miscellaneous/pinktutu
name = "Pink Tutu"
item_path = /obj/item/clothing/under/dress/skyrat/pinktutu
-/datum/loadout_item/under/miscellaneous/flowerdress
+/datum/loadout_item/uniform/miscellaneous/flowerdress
name = "Flower Dress"
item_path = /obj/item/clothing/under/dress/skyrat/flower
-/datum/loadout_item/under/miscellaneous/kilt
+/datum/loadout_item/uniform/miscellaneous/kilt
name = "Kilt"
item_path = /obj/item/clothing/under/costume/kilt
-/datum/loadout_item/under/miscellaneous/treasure_hunter
+/datum/loadout_item/uniform/miscellaneous/treasure_hunter
name = "Treasure Hunter"
item_path = /obj/item/clothing/under/rank/civilian/curator/treasure_hunter
-/datum/loadout_item/under/miscellaneous/jester
+/datum/loadout_item/uniform/miscellaneous/jester
name = "Jester Suit"
item_path = /obj/item/clothing/under/rank/civilian/clown/jester
-/datum/loadout_item/under/miscellaneous/jesteralt
+/datum/loadout_item/uniform/miscellaneous/jesteralt
name = "Jeset Suit (Alt)"
item_path = /obj/item/clothing/under/rank/civilian/clown/jesteralt
-/datum/loadout_item/under/miscellaneous/overalls
+/datum/loadout_item/uniform/miscellaneous/overalls
name = "Overalls"
item_path = /obj/item/clothing/under/misc/overalls
-/datum/loadout_item/under/miscellaneous/pj_blue
+/datum/loadout_item/uniform/miscellaneous/pj_blue
name = "Mailman Jumpsuit"
item_path = /obj/item/clothing/under/misc/mailman
-/datum/loadout_item/under/miscellaneous/vice_officer
+/datum/loadout_item/uniform/miscellaneous/vice_officer
name = "Vice Officer Jumpsuit"
item_path = /obj/item/clothing/under/misc/vice_officer
-/datum/loadout_item/under/miscellaneous/soviet
+/datum/loadout_item/uniform/miscellaneous/soviet
name = "Soviet Uniform"
item_path = /obj/item/clothing/under/costume/soviet
-/datum/loadout_item/under/miscellaneous/redcoat
+/datum/loadout_item/uniform/miscellaneous/redcoat
name = "Redcoat"
item_path = /obj/item/clothing/under/costume/redcoat
-/datum/loadout_item/under/miscellaneous/pj_red
+/datum/loadout_item/uniform/miscellaneous/pj_red
name = "Red PJs"
item_path = /obj/item/clothing/under/misc/pj/red
-/datum/loadout_item/under/miscellaneous/pj_blue
+/datum/loadout_item/uniform/miscellaneous/pj_blue
name = "Blue PJs"
item_path = /obj/item/clothing/under/misc/pj/blue
-/datum/loadout_item/under/miscellaneous/tactical_hawaiian_orange
+/datum/loadout_item/uniform/miscellaneous/tactical_hawaiian_orange
name = "Tactical Hawaiian Outfit - Orange"
item_path = /obj/item/clothing/under/tachawaiian
-/datum/loadout_item/under/miscellaneous/tactical_hawaiian_blue
+/datum/loadout_item/uniform/miscellaneous/tactical_hawaiian_blue
name = "Tactical Hawaiian Outfit - Blue"
item_path = /obj/item/clothing/under/tachawaiian/blue
-/datum/loadout_item/under/miscellaneous/tactical_hawaiian_purple
+/datum/loadout_item/uniform/miscellaneous/tactical_hawaiian_purple
name = "Tactical Hawaiian Outfit - Purple"
item_path = /obj/item/clothing/under/tachawaiian/purple
-/datum/loadout_item/under/miscellaneous/tactical_hawaiian_green
+/datum/loadout_item/uniform/miscellaneous/tactical_hawaiian_green
name = "Tactical Hawaiian Outfit - Green"
item_path = /obj/item/clothing/under/tachawaiian/green
-/datum/loadout_item/under/miscellaneous/maidcostume
+/datum/loadout_item/uniform/miscellaneous/maidcostume
name = "Maid Costume"
item_path = /obj/item/clothing/under/costume/maid
-/datum/loadout_item/under/miscellaneous/maid_costume
+/datum/loadout_item/uniform/miscellaneous/maid_costume
name = "Colourable Maid Uniform"
item_path = /obj/item/clothing/under/maid_costume
-/datum/loadout_item/under/miscellaneous/yukata
+/datum/loadout_item/uniform/miscellaneous/yukata
name = "Recolorable Yukata"
item_path = /obj/item/clothing/under/costume/skyrat/yukata
-/datum/loadout_item/under/miscellaneous/qipao_black
+/datum/loadout_item/uniform/miscellaneous/qipao_black
name = "Recolorable Qipao"
item_path = /obj/item/clothing/under/costume/skyrat/qipao
-/datum/loadout_item/under/miscellaneous/cheongsam
+/datum/loadout_item/uniform/miscellaneous/cheongsam
name = "Recolorable Cheongsam"
item_path = /obj/item/clothing/under/costume/skyrat/cheongsam
-/datum/loadout_item/under/miscellaneous/kimono
+/datum/loadout_item/uniform/miscellaneous/kimono
name = "Fancy Kimono"
item_path = /obj/item/clothing/under/costume/skyrat/kimono
-/datum/loadout_item/under/miscellaneous/chaps
+/datum/loadout_item/uniform/miscellaneous/chaps
name = "Black Chaps"
item_path = /obj/item/clothing/under/pants/skyrat/chaps
-/datum/loadout_item/under/miscellaneous/tracky
+/datum/loadout_item/uniform/miscellaneous/tracky
name = "Blue Tracksuit"
item_path = /obj/item/clothing/under/misc/bluetracksuit
-/datum/loadout_item/under/miscellaneous/cybersleek
+/datum/loadout_item/uniform/miscellaneous/cybersleek
name = "Sleek Modern Coat"
item_path = /obj/item/clothing/under/costume/cybersleek
-/datum/loadout_item/under/miscellaneous/cybersleek_long
+/datum/loadout_item/uniform/miscellaneous/cybersleek_long
name = "Long Modern Coat"
item_path = /obj/item/clothing/under/costume/cybersleek/long
-/datum/loadout_item/under/miscellaneous/dutch
+/datum/loadout_item/uniform/miscellaneous/dutch
name = "Dutch Suit"
item_path = /obj/item/clothing/under/costume/dutch
-/datum/loadout_item/under/miscellaneous/cavalry
+/datum/loadout_item/uniform/miscellaneous/cavalry
name = "Cavalry Uniform"
item_path = /obj/item/clothing/under/costume/skyrat/cavalry
-/datum/loadout_item/under/miscellaneous/tacticool_turtleneck
+/datum/loadout_item/uniform/miscellaneous/tacticool_turtleneck
name = "Tacticool Turtleneck"
item_path = /obj/item/clothing/under/syndicate/tacticool //This has been rebalanced in modular_skyrat\master_files\code\modules\clothing\under\syndicate.dm
-/datum/loadout_item/under/miscellaneous/tactical_skirt
+/datum/loadout_item/uniform/miscellaneous/tactical_skirt
name = "Tacticool Skirtleneck"
item_path = /obj/item/clothing/under/syndicate/tacticool/skirt //This has been rebalanced in modular_skyrat\master_files\code\modules\clothing\under\syndicate.dm
-/datum/loadout_item/under/miscellaneous/tactical_pants
+/datum/loadout_item/uniform/miscellaneous/tactical_pants
name = "Tactical Pants"
item_path = /obj/item/clothing/under/pants/tactical
-/datum/loadout_item/under/miscellaneous/blastwave_uniform
+/datum/loadout_item/uniform/miscellaneous/blastwave_uniform
name = "Blastwave Uniform"
item_path = /obj/item/clothing/under/blastwave
//HALLOWEEN
-/datum/loadout_item/under/miscellaneous/pj_blood
+/datum/loadout_item/uniform/miscellaneous/pj_blood
name = "Blood-red Pajamas"
item_path = /obj/item/clothing/under/syndicate/bloodred/sleepytime/sensors
-/datum/loadout_item/under/miscellaneous/gladiator
+/datum/loadout_item/uniform/miscellaneous/gladiator
name = "Gladiator Uniform"
item_path = /obj/item/clothing/under/costume/gladiator
-/datum/loadout_item/under/miscellaneous/griffon
+/datum/loadout_item/uniform/miscellaneous/griffon
name = "Griffon Uniform"
item_path = /obj/item/clothing/under/costume/griffin
-/datum/loadout_item/under/miscellaneous/owl
+/datum/loadout_item/uniform/miscellaneous/owl
name = "Owl Uniform"
item_path = /obj/item/clothing/under/costume/owl
-/datum/loadout_item/under/miscellaneous/villain
+/datum/loadout_item/uniform/miscellaneous/villain
name = "Villain Suit"
item_path = /obj/item/clothing/under/costume/villain
-/datum/loadout_item/under/miscellaneous/sweater
+/datum/loadout_item/uniform/miscellaneous/sweater
name = "Cableknit Sweater" //Different than the Suit item ("Sweater")!!
item_path = /obj/item/clothing/under/sweater
-/datum/loadout_item/under/miscellaneous/keyhole
+/datum/loadout_item/uniform/miscellaneous/keyhole
name = "Keyhole Sweater"
item_path = /obj/item/clothing/under/sweater/keyhole
-/datum/loadout_item/under/miscellaneous/blacknwhite
+/datum/loadout_item/uniform/miscellaneous/blacknwhite
name = "Classic Prisoner Jumpsuit"
item_path = /obj/item/clothing/under/rank/prisoner/classic
-/datum/loadout_item/under/miscellaneous/redscrubs
+/datum/loadout_item/uniform/miscellaneous/redscrubs
name = "Red Scrubs"
item_path = /obj/item/clothing/under/rank/medical/scrubs/skyrat/red
-/datum/loadout_item/under/miscellaneous/bluescrubs
+/datum/loadout_item/uniform/miscellaneous/bluescrubs
name = "Blue Scrubs"
item_path = /obj/item/clothing/under/rank/medical/scrubs/blue
-/datum/loadout_item/under/miscellaneous/greenscrubs
+/datum/loadout_item/uniform/miscellaneous/greenscrubs
name = "Green Scrubs"
item_path = /obj/item/clothing/under/rank/medical/scrubs/green
-/datum/loadout_item/under/miscellaneous/purplescrubs
+/datum/loadout_item/uniform/miscellaneous/purplescrubs
name = "Purple Scrubs"
item_path = /obj/item/clothing/under/rank/medical/scrubs/purple
-/datum/loadout_item/under/miscellaneous/whitescrubs
+/datum/loadout_item/uniform/miscellaneous/whitescrubs
name = "White Scrubs"
item_path = /obj/item/clothing/under/rank/medical/scrubs/skyrat/white
-/datum/loadout_item/under/miscellaneous/gear_harness
+/datum/loadout_item/uniform/miscellaneous/gear_harness
name = "Gear Harness"
item_path = /obj/item/clothing/under/misc/skyrat/gear_harness
-/datum/loadout_item/under/miscellaneous/taccas
+/datum/loadout_item/uniform/miscellaneous/taccas
name = "Tacticasual Uniform"
item_path = /obj/item/clothing/under/misc/skyrat/taccas
-/datum/loadout_item/under/miscellaneous/cargo_casual
+/datum/loadout_item/uniform/miscellaneous/cargo_casual
name = "Cargo Tech Casualwear"
item_path = /obj/item/clothing/under/rank/cargo/tech/skyrat/casualman
-/datum/loadout_item/under/miscellaneous/cargo_shorts
+/datum/loadout_item/uniform/miscellaneous/cargo_shorts
name = "Cargo Tech Shorts"
item_path = /obj/item/clothing/under/rank/cargo/tech/alt
-/datum/loadout_item/under/miscellaneous/cargo_black
+/datum/loadout_item/uniform/miscellaneous/cargo_black
name = "Black Cargo Uniform"
item_path = /obj/item/clothing/under/rank/cargo/tech/skyrat/evil
-/datum/loadout_item/under/miscellaneous/cargo_turtle
+/datum/loadout_item/uniform/miscellaneous/cargo_turtle
name = "Cargo Turtleneck"
item_path = /obj/item/clothing/under/rank/cargo/tech/skyrat/turtleneck
-/datum/loadout_item/under/miscellaneous/cargo_skirtle
+/datum/loadout_item/uniform/miscellaneous/cargo_skirtle
name = "Cargo Skirtleneck"
item_path = /obj/item/clothing/under/rank/cargo/tech/skyrat/turtleneck/skirt
-/datum/loadout_item/under/miscellaneous/qm_skirtle
+/datum/loadout_item/uniform/miscellaneous/qm_skirtle
name = "Quartermaster's Skirtleneck"
item_path = /obj/item/clothing/under/rank/cargo/qm/skyrat/turtleneck/skirt
restricted_roles = list(JOB_QUARTERMASTER)
-/datum/loadout_item/under/miscellaneous/qm_gorka
+/datum/loadout_item/uniform/miscellaneous/qm_gorka
name = "Quartermaster's Gorka Uniform"
item_path = /obj/item/clothing/under/rank/cargo/qm/skyrat/gorka
restricted_roles = list(JOB_QUARTERMASTER)
-/datum/loadout_item/under/miscellaneous/eve
+/datum/loadout_item/uniform/miscellaneous/eve
name = "Collection of Leaves"
item_path = /obj/item/clothing/under/misc/skyrat/gear_harness/eve
-/datum/loadout_item/under/miscellaneous/adam
+/datum/loadout_item/uniform/miscellaneous/adam
name = "Leaf"
item_path = /obj/item/clothing/under/misc/skyrat/gear_harness/adam
-/datum/loadout_item/under/miscellaneous/ethereal_tunic
+/datum/loadout_item/uniform/miscellaneous/ethereal_tunic
name = "Ethereal Tunic"
item_path = /obj/item/clothing/under/ethereal_tunic
-/datum/loadout_item/under/miscellaneous/mech_suit
+/datum/loadout_item/uniform/miscellaneous/mech_suit
name = "Mech Suit"
item_path = /obj/item/clothing/under/costume/mech_suit
@@ -670,290 +659,303 @@ GLOBAL_LIST_INIT(loadout_miscunders, generate_loadout_items(/datum/loadout_item/
* FORMAL UNDERSUITS
*/
-/datum/loadout_item/under/formal
+/datum/loadout_item/uniform/formal
-/datum/loadout_item/under/formal/amish_suit
+/datum/loadout_item/uniform/formal/amish_suit
name = "White Buttondown Shirt with Black Slacks"
item_path = /obj/item/clothing/under/costume/buttondown/slacks/service
-/datum/loadout_item/under/formal/formaldressred
+/datum/loadout_item/uniform/formal/formaldressred
name = "Formal Red Dress"
item_path = /obj/item/clothing/under/dress/skyrat/redformal
-/datum/loadout_item/under/formal/countessdress
+/datum/loadout_item/uniform/formal/countessdress
name = "Countess Dress"
item_path = /obj/item/clothing/under/dress/skyrat/countess
-/datum/loadout_item/under/formal/assistant
+/datum/loadout_item/uniform/formal/assistant
name = "Assistant Formal"
item_path = /obj/item/clothing/under/misc/assistantformal
-/datum/loadout_item/under/formal/beige_suit
+/datum/loadout_item/uniform/formal/beige_suit
name = "Beige Suit"
item_path = /obj/item/clothing/under/suit/beige
-/datum/loadout_item/under/formal/black_suit
+/datum/loadout_item/uniform/formal/black_suit
name = "Black Suit"
item_path = /obj/item/clothing/under/suit/black
-/datum/loadout_item/under/formal/black_suitskirt
+/datum/loadout_item/uniform/formal/black_suitskirt
name = "Black Suitskirt"
item_path = /obj/item/clothing/under/suit/black/skirt
-/datum/loadout_item/under/formal/black_lawyer_suit
+/datum/loadout_item/uniform/formal/black_lawyer_suit
name = "Black Lawyer Suit"
item_path = /obj/item/clothing/under/rank/civilian/lawyer/black
-/datum/loadout_item/under/formal/black_lawyer_skirt
+/datum/loadout_item/uniform/formal/black_lawyer_skirt
name = "Black Lawyer Suitskirt"
item_path = /obj/item/clothing/under/rank/civilian/lawyer/black/skirt
-/datum/loadout_item/under/formal/blue_suit
+/datum/loadout_item/uniform/formal/blue_suit
name = "Blue Buttondown Suit"
item_path = /obj/item/clothing/under/rank/civilian/lawyer/bluesuit
-/datum/loadout_item/under/formal/blue_suitskirt
+/datum/loadout_item/uniform/formal/blue_suitskirt
name = "Blue Buttondown Suitskirt"
item_path = /obj/item/clothing/under/rank/civilian/lawyer/bluesuit/skirt
-/datum/loadout_item/under/formal/blue_lawyer_suit
+/datum/loadout_item/uniform/formal/blue_lawyer_suit
name = "Blue Lawyer Suit"
item_path = /obj/item/clothing/under/rank/civilian/lawyer/blue
-/datum/loadout_item/under/formal/blue_lawyer_skirt
+/datum/loadout_item/uniform/formal/blue_lawyer_skirt
name = "Blue Lawyer Suitskirt"
item_path = /obj/item/clothing/under/rank/civilian/lawyer/blue/skirt
-/datum/loadout_item/under/formal/burgundy_suit
+/datum/loadout_item/uniform/formal/burgundy_suit
name = "Burgundy Suit"
item_path = /obj/item/clothing/under/suit/burgundy
-/datum/loadout_item/under/formal/charcoal_suit
+/datum/loadout_item/uniform/formal/charcoal_suit
name = "Charcoal Suit"
item_path = /obj/item/clothing/under/suit/charcoal
-/datum/loadout_item/under/formal/checkered_suit
+/datum/loadout_item/uniform/formal/checkered_suit
name = "Checkered Suit"
item_path = /obj/item/clothing/under/suit/checkered
-/datum/loadout_item/under/formal/executive_suit
+/datum/loadout_item/uniform/formal/executive_suit
name = "Executive Suit"
item_path = /obj/item/clothing/under/suit/black_really
-/datum/loadout_item/under/formal/executive_skirt
+/datum/loadout_item/uniform/formal/executive_skirt
name = "Executive Suitskirt"
item_path = /obj/item/clothing/under/suit/black_really/skirt
-/datum/loadout_item/under/formal/executive_suit_alt
+/datum/loadout_item/uniform/formal/executive_suit_alt
name = "Wide-collared Executive Suit"
item_path = /obj/item/clothing/under/suit/skyrat/black_really_collared
-/datum/loadout_item/under/formal/executive_skirt_alt
+/datum/loadout_item/uniform/formal/executive_skirt_alt
name = "Wide-collared Executive Suitskirt"
item_path = /obj/item/clothing/under/suit/skyrat/black_really_collared/skirt
-/datum/loadout_item/under/formal/navy_suit
+/datum/loadout_item/uniform/formal/navy_suit
name = "Navy Suit"
item_path = /obj/item/clothing/under/suit/navy
-/datum/loadout_item/under/formal/maid_uniform
+/datum/loadout_item/uniform/formal/maid_uniform
name = "Maid Uniform"
item_path = /obj/item/clothing/under/rank/civilian/janitor/maid
-/datum/loadout_item/under/formal/purple_suit
+/datum/loadout_item/uniform/formal/purple_suit
name = "Purple Suit"
item_path = /obj/item/clothing/under/rank/civilian/lawyer/purpsuit
-/datum/loadout_item/under/formal/purple_suitskirt
+/datum/loadout_item/uniform/formal/purple_suitskirt
name = "Purple Suitskirt"
item_path = /obj/item/clothing/under/rank/civilian/lawyer/purpsuit/skirt
-/datum/loadout_item/under/formal/red_suit
+/datum/loadout_item/uniform/formal/red_suit
name = "Red Suit"
item_path = /obj/item/clothing/under/suit/red
-/datum/loadout_item/under/formal/helltaker
+/datum/loadout_item/uniform/formal/helltaker
name = "Red Shirt with White Trousers"
item_path = /obj/item/clothing/under/suit/skyrat/helltaker
-/datum/loadout_item/under/formal/helltaker/skirt
+/datum/loadout_item/uniform/formal/helltaker/skirt
name = "Red Shirt with White Skirt"
item_path = /obj/item/clothing/under/suit/skyrat/helltaker/skirt
-/datum/loadout_item/under/formal/red_lawyer_skirt
+/datum/loadout_item/uniform/formal/red_lawyer_skirt
name = "Red Lawyer Suit"
item_path = /obj/item/clothing/under/rank/civilian/lawyer/red
-/datum/loadout_item/under/formal/red_lawyer_skirt
+/datum/loadout_item/uniform/formal/red_lawyer_skirt
name = "Red Lawyer Suitskirt"
item_path = /obj/item/clothing/under/rank/civilian/lawyer/red/skirt
-/datum/loadout_item/under/formal/red_gown
+/datum/loadout_item/uniform/formal/red_gown
name = "Red Evening Gown"
item_path = /obj/item/clothing/under/dress/eveninggown
-/datum/loadout_item/under/formal/sailor
+/datum/loadout_item/uniform/formal/sailor
name = "Sailor Suit"
item_path = /obj/item/clothing/under/costume/sailor
-/datum/loadout_item/under/formal/sailor_skirt
+/datum/loadout_item/uniform/formal/sailor_skirt
name = "Sailor Dress"
item_path = /obj/item/clothing/under/dress/sailor
-/datum/loadout_item/under/formal/sensible_suit
+/datum/loadout_item/uniform/formal/sensible_suit
name = "Sensible Suit"
item_path = /obj/item/clothing/under/rank/civilian/curator
-/datum/loadout_item/under/formal/sensible_skirt
+/datum/loadout_item/uniform/formal/sensible_skirt
name = "Sensible Suitskirt"
item_path = /obj/item/clothing/under/rank/civilian/curator/skirt
-/datum/loadout_item/under/formal/tuxedo
+/datum/loadout_item/uniform/formal/tuxedo
name = "Tuxedo Suit"
item_path = /obj/item/clothing/under/suit/tuxedo
-/datum/loadout_item/under/formal/waiter
+/datum/loadout_item/uniform/formal/waiter
name = "Waiter's Suit"
item_path = /obj/item/clothing/under/suit/waiter
-/datum/loadout_item/under/formal/white_suit
+/datum/loadout_item/uniform/formal/white_suit
name = "White Suit"
item_path = /obj/item/clothing/under/suit/white
-/datum/loadout_item/under/formal/fancy_suit
+/datum/loadout_item/uniform/formal/fancy_suit
name = "Fancy Suit"
item_path = /obj/item/clothing/under/suit/fancy
-/datum/loadout_item/under/formal/recolorable_suit
+/datum/loadout_item/uniform/formal/recolorable_suit
name = "Recolorable Formal Suit"
item_path = /obj/item/clothing/under/suit/skyrat/recolorable
-/datum/loadout_item/under/formal/recolorable_suitskirt
+/datum/loadout_item/uniform/formal/recolorable_suitskirt
name = "Recolorable Formal Suitskirt"
item_path = /obj/item/clothing/under/suit/skyrat/recolorable/skirt
-/datum/loadout_item/under/formal/trek_command
+/datum/loadout_item/uniform/formal/trek_command
name = "Trekkie Command Uniform"
item_path = /obj/item/clothing/under/trek/command
-/datum/loadout_item/under/formal/trek_engsec
+/datum/loadout_item/uniform/formal/trek_engsec
name = "Trekkie Engsec Uniform"
item_path = /obj/item/clothing/under/trek/engsec
-/datum/loadout_item/under/formal/trek_medsci
+/datum/loadout_item/uniform/formal/trek_medsci
name = "Trekkie Medsci Uniform"
item_path = /obj/item/clothing/under/trek/medsci
-/datum/loadout_item/under/formal/trek_next_command
+/datum/loadout_item/uniform/formal/trek_next_command
name = "Trekkie TNG Command Uniform"
item_path = /obj/item/clothing/under/trek/command/next
-/datum/loadout_item/under/formal/trek_next_engsec
+/datum/loadout_item/uniform/formal/trek_next_engsec
name = "Trekkie TNG Engsec Uniform"
item_path = /obj/item/clothing/under/trek/engsec/next
-/datum/loadout_item/under/formal/trek_next_medsci
+/datum/loadout_item/uniform/formal/trek_next_medsci
name = "Trekkie TNG Medsci Uniform"
item_path = /obj/item/clothing/under/trek/medsci/next
-/datum/loadout_item/under/formal/trek_ent_command
+/datum/loadout_item/uniform/formal/trek_ent_command
name = "Trekkie ENT Command Uniform"
item_path = /obj/item/clothing/under/trek/command/ent
-/datum/loadout_item/under/formal/trek_ent_engsec
+/datum/loadout_item/uniform/formal/trek_ent_engsec
name = "Trekkie ENT Engsec Uniform"
item_path = /obj/item/clothing/under/trek/engsec/ent
-/datum/loadout_item/under/formal/trek_ent_medsci
+/datum/loadout_item/uniform/formal/trek_ent_medsci
name = "Trekkie ENT Medsci Uniform"
item_path = /obj/item/clothing/under/trek/medsci/ent
-/datum/loadout_item/under/formal/the_q
+/datum/loadout_item/uniform/formal/the_q
name = "French Marshall's Uniform"
item_path = /obj/item/clothing/under/trek/q
//FAMILIES GEAR
-/datum/loadout_item/under/formal/osi
+/datum/loadout_item/uniform/formal/osi
name = "OSI Uniform"
item_path = /obj/item/clothing/under/costume/osi
-/datum/loadout_item/under/formal/tmc
+/datum/loadout_item/uniform/formal/tmc
name = "TMC Uniform"
item_path = /obj/item/clothing/under/costume/tmc
-/datum/loadout_item/under/formal/inferno
+/datum/loadout_item/uniform/formal/inferno
name = "Inferno Suit"
item_path = /obj/item/clothing/under/suit/skyrat/inferno
-/datum/loadout_item/under/formal/inferno_skirt
+/datum/loadout_item/uniform/formal/inferno_skirt
name = "Inferno Skirt"
item_path = /obj/item/clothing/under/suit/skyrat/inferno/skirt
-/datum/loadout_item/under/formal/designer_inferno
+/datum/loadout_item/uniform/formal/designer_inferno
name = "Designer Inferno Suit"
item_path = /obj/item/clothing/under/suit/skyrat/inferno/beeze
-/datum/loadout_item/under/formal/pencil
+/datum/loadout_item/uniform/formal/pencil
name = "Black Pencilskirt"
item_path = /obj/item/clothing/under/suit/skyrat/pencil
-/datum/loadout_item/under/formal/pencil/black_really
+/datum/loadout_item/uniform/formal/pencil/black_really
name = "Executive Pencilskirt"
item_path = /obj/item/clothing/under/suit/skyrat/pencil/black_really
-/datum/loadout_item/under/formal/pencil/charcoal
+/datum/loadout_item/uniform/formal/pencil/charcoal
name = "Charcoal Pencilskirt"
item_path = /obj/item/clothing/under/suit/skyrat/pencil/charcoal
-/datum/loadout_item/under/formal/pencil/navy
+/datum/loadout_item/uniform/formal/pencil/navy
name = "Navy Pencilskirt"
item_path = /obj/item/clothing/under/suit/skyrat/pencil/navy
-/datum/loadout_item/under/formal/pencil/burgandy
+/datum/loadout_item/uniform/formal/pencil/burgandy
name = "Burgandy Pencilskirt"
item_path = /obj/item/clothing/under/suit/skyrat/pencil/burgandy
-/datum/loadout_item/under/formal/pencil/checkered
+/datum/loadout_item/uniform/formal/pencil/checkered
name = "Checkered Pencilskirt"
item_path = /obj/item/clothing/under/suit/skyrat/pencil/checkered
-/datum/loadout_item/under/formal/pencil/tan
+/datum/loadout_item/uniform/formal/pencil/tan
name = "Tan Pencilskirt"
item_path = /obj/item/clothing/under/suit/skyrat/pencil/tan
-/datum/loadout_item/under/formal/pencil/green
+/datum/loadout_item/uniform/formal/pencil/green
name = "Green Pencilskirt"
item_path = /obj/item/clothing/under/suit/skyrat/pencil/green
-/datum/loadout_item/under/formal/azulea_oldblood
+/datum/loadout_item/uniform/formal/azulea_oldblood
name = " Oldblood's Royal regalia"
item_path = /obj/item/clothing/under/rank/azulean/old_blood
restricted_roles = list(JOB_CAPTAIN, JOB_NT_REP)
restricted_species = list(SPECIES_AKULA)
-/datum/loadout_item/under/formal/azulea_oldblood/skirt
+/datum/loadout_item/uniform/formal/azulea_oldblood/skirt
name = " Oldblood's Royal regalia (Skirt)"
item_path = /obj/item/clothing/under/rank/azulean/old_blood/skirt
restricted_roles = list(JOB_CAPTAIN, JOB_NT_REP)
restricted_species = list(SPECIES_AKULA)
-/datum/loadout_item/under/formal/azulea_upstart
+/datum/loadout_item/uniform/formal/azulea_upstart
name = "Upstart's Noble Getup"
item_path = /obj/item/clothing/under/rank/azulean/upstart
restricted_roles = list(JOB_CAPTAIN, JOB_NT_REP)
restricted_species = list(SPECIES_AKULA)
-/datum/loadout_item/under/formal/azulea_upstart/skirt
+/datum/loadout_item/uniform/formal/azulea_upstart/skirt
name = "Upstart's Noble Getup (Skirt)"
item_path = /obj/item/clothing/under/rank/azulean/upstart/skirt
restricted_roles = list(JOB_CAPTAIN, JOB_NT_REP)
restricted_species = list(SPECIES_AKULA)
-/// DONATOR
-/datum/loadout_item/under/donator
- donator_only = TRUE
-
-/datum/loadout_item/under/donator/captain_black
+// DONATOR ONLY
+/datum/loadout_item/uniform/captain_black
name = "Captains Black Uniform"
item_path = /obj/item/clothing/under/rank/captain/skyrat/black
restricted_roles = list(JOB_CAPTAIN)
+ donator_only = TRUE
+
+/datum/loadout_item/under/jumpsuit/donator
+ donator_only = TRUE
+
+/datum/loadout_item/under/jumpsuit/donator/enclavesergeant
+ name = "Enclave - Sergeant"
+ item_path = /obj/item/clothing/under/syndicate/skyrat/enclave
+
+/datum/loadout_item/under/jumpsuit/donator/enclaveofficer
+ name = "Enclave - Officer"
+ item_path = /obj/item/clothing/under/syndicate/skyrat/enclave/officer
+
+/datum/loadout_item/under/jumpsuit/donator/blondie
+ name = "Blonde Cowboy Uniform"
+ item_path = /obj/item/clothing/under/rank/security/detective/cowboy/armorless
diff --git a/modular_skyrat/modules/better_vox/code/vox_species.dm b/modular_skyrat/modules/better_vox/code/vox_species.dm
index 04f8e0f65c8..76a7e13643e 100644
--- a/modular_skyrat/modules/better_vox/code/vox_species.dm
+++ b/modular_skyrat/modules/better_vox/code/vox_species.dm
@@ -36,16 +36,16 @@
BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant/vox_primalis,
)
custom_worn_icons = list(
- LOADOUT_ITEM_HEAD = VOX_PRIMALIS_HEAD_ICON,
- LOADOUT_ITEM_MASK = VOX_PRIMALIS_MASK_ICON,
+ OFFSET_HEAD = VOX_PRIMALIS_HEAD_ICON,
+ OFFSET_MASK = VOX_PRIMALIS_MASK_ICON,
LOADOUT_ITEM_SUIT = VOX_PRIMALIS_SUIT_ICON,
LOADOUT_ITEM_UNIFORM = VOX_PRIMALIS_UNIFORM_ICON,
LOADOUT_ITEM_GLOVES = VOX_PRIMALIS_GLOVES_ICON,
- LOADOUT_ITEM_SHOES = VOX_PRIMALIS_FEET_ICON,
+ OFFSET_SHOES = VOX_PRIMALIS_FEET_ICON,
LOADOUT_ITEM_GLASSES = VOX_PRIMALIS_EYES_ICON,
- LOADOUT_ITEM_BELT = VOX_PRIMALIS_BELT_ICON,
+ OFFSET_BELT = VOX_PRIMALIS_BELT_ICON,
LOADOUT_ITEM_MISC = VOX_PRIMALIS_BACK_ICON,
- LOADOUT_ITEM_EARS = VOX_PRIMALIS_EARS_ICON,
+ OFFSET_EARS = VOX_PRIMALIS_EARS_ICON,
)
/datum/species/vox_primalis/get_default_mutant_bodyparts()
diff --git a/modular_skyrat/modules/customization/__HELPERS/global_lists.dm b/modular_skyrat/modules/customization/__HELPERS/global_lists.dm
index 564ca6941c3..70f6d6a1bad 100644
--- a/modular_skyrat/modules/customization/__HELPERS/global_lists.dm
+++ b/modular_skyrat/modules/customization/__HELPERS/global_lists.dm
@@ -109,37 +109,6 @@
// Chemical reactions aren't handled here because they're loaded in the reagents SS
// See Initialize() on SSReagents
- // Loadouts
- for(var/loadout_path in GLOB.all_loadout_datums)
- var/datum/loadout_item/loadout_datum = GLOB.all_loadout_datums[loadout_path]
- if(!loadout_datum.erp_item)
- continue
- GLOB.all_loadout_datums -= loadout_path
- // Ensure this FULLY works later
-
- var/list/loadout_lists = list(
- GLOB.loadout_belts,
- GLOB.loadout_ears,
- GLOB.loadout_glasses,
- GLOB.loadout_gloves,
- GLOB.loadout_helmets,
- GLOB.loadout_masks,
- GLOB.loadout_necks,
- GLOB.loadout_shoes,
- GLOB.loadout_exosuits,
- GLOB.loadout_jumpsuits,
- GLOB.loadout_undersuits,
- GLOB.loadout_miscunders,
- GLOB.loadout_accessory,
- GLOB.loadout_inhand_items,
- GLOB.loadout_toys,
- GLOB.loadout_pocket_items,
- )
- for(var/loadout_list in loadout_lists)
- for(var/datum/loadout_item/loadout_typepath in loadout_list)
- if(!initial(loadout_typepath.erp_item))
- continue
- loadout_list -= loadout_typepath
// Underwear
for(var/sprite_name in SSaccessories.underwear_list)
diff --git a/modular_skyrat/modules/customization/modules/clothing/under/accessories.dm b/modular_skyrat/modules/customization/modules/clothing/under/accessories.dm
index c6e25fb1e24..79382f4b01a 100644
--- a/modular_skyrat/modules/customization/modules/clothing/under/accessories.dm
+++ b/modular_skyrat/modules/customization/modules/clothing/under/accessories.dm
@@ -160,22 +160,3 @@
new /obj/item/clothing/accessory/badge/holo/cord(src)
return
-// Pride Pin Over-ride
-/obj/item/clothing/accessory/pride
- icon = 'modular_skyrat/master_files/icons/obj/clothing/accessories.dmi'
- worn_icon = 'modular_skyrat/master_files/icons/mob/clothing/accessories.dmi'
-
-GLOBAL_LIST_INIT(pride_pin_reskins, list(
- "Rainbow Pride" = "pride",
- "Bisexual Pride" = "pride_bi",
- "Pansexual Pride" = "pride_pan",
- "Asexual Pride" = "pride_ace",
- "Non-binary Pride" = "pride_enby",
- "Transgender Pride" = "pride_trans",
- "Intersex Pride" = "pride_intersex",
- "Lesbian Pride" = "pride_lesbian",
- "Man-Loving-Man / Gay Pride" = "pride_mlm",
- "Genderfluid Pride" = "pride_genderfluid",
- "Genderqueer Pride" = "pride_genderqueer",
- "Aromantic Pride" = "pride_aromantic",
-))
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/custom_bodytype.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/custom_bodytype.dm
index d5b07bc60ed..d82eefa85d8 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/custom_bodytype.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/custom_bodytype.dm
@@ -1,7 +1,7 @@
/**
* Modularly returns one of worn_icon_vox, worn_icon_teshari, etc.
* Arguments:
- * * item_slot: The slot we're updating. One of LOADOUT_ITEM_HEAD, etc.
+ * * item_slot: The slot we're updating. One of OFFSET_HEAD, etc.
* * item is the item we're checking.
*/
/datum/species/proc/get_custom_worn_icon(item_slot, obj/item/item)
@@ -10,7 +10,7 @@
/**
* Modularly set one of worn_icon_vox, worn_icon_teshari, etc.
* Arguments:
- * * item_slot: The slot we're updating. One of LOADOUT_ITEM_HEAD, etc.
+ * * item_slot: The slot we're updating. One of OFFSET_HEAD, etc.
* * item is the item we're updating.
* * icon is the icon we're setting to the var.
*/
@@ -21,7 +21,7 @@
* Modularly get the species' fallback greyscale config.
* Only used if you use generate_custom_worn_icon_fallback()
* Arguments:
- * * item_slot: The slot we're updating. One of LOADOUT_ITEM_HEAD, etc.
+ * * item_slot: The slot we're updating. One of OFFSET_HEAD, etc.
* * item: The item being rendered.
*/
/datum/species/proc/get_custom_worn_config_fallback(item_slot, obj/item/item)
@@ -55,7 +55,7 @@
* Allow for custom clothing icon generation. Only called if the species is BODYSHAPE_CUSTOM
* If null is returned, use default human icon.
* Arguments:
- * * item_slot: The slot we're updating. One of LOADOUT_ITEM_HEAD, etc.
+ * * item_slot: The slot we're updating. One of OFFSET_HEAD, etc.
* * item: The item being rendered.
* * human_owner: The human wearing the item.
*/
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm
index ea6ac0ac479..2937cfccdc8 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/species/vox.dm
@@ -33,16 +33,16 @@
BODY_ZONE_R_LEG = /obj/item/bodypart/leg/right/mutant/vox,
)
custom_worn_icons = list(
- LOADOUT_ITEM_HEAD = VOX_HEAD_ICON,
- LOADOUT_ITEM_MASK = VOX_MASK_ICON,
+ OFFSET_HEAD = VOX_HEAD_ICON,
+ OFFSET_MASK = VOX_MASK_ICON,
LOADOUT_ITEM_SUIT = VOX_SUIT_ICON,
LOADOUT_ITEM_UNIFORM = VOX_UNIFORM_ICON,
LOADOUT_ITEM_HANDS = VOX_HANDS_ICON,
- LOADOUT_ITEM_SHOES = VOX_FEET_ICON,
+ OFFSET_SHOES = VOX_FEET_ICON,
LOADOUT_ITEM_GLASSES = VOX_EYES_ICON,
- LOADOUT_ITEM_BELT = VOX_BELT_ICON,
+ OFFSET_BELT = VOX_BELT_ICON,
LOADOUT_ITEM_MISC = VOX_BACK_ICON,
- LOADOUT_ITEM_EARS = VOX_EARS_ICON
+ OFFSET_EARS = VOX_EARS_ICON
)
meat = /obj/item/food/meat/slab/chicken/human //item file in teshari module
@@ -79,7 +79,7 @@
/datum/species/vox/get_custom_worn_icon(item_slot, obj/item/item)
// snowflakey but vox legs weird.
- if(item_slot == LOADOUT_ITEM_SHOES)
+ if(item_slot == OFFSET_SHOES)
var/obj/item/bodypart/leg = bodypart_overrides[BODY_ZONE_L_LEG] || bodypart_overrides[BODY_ZONE_R_LEG]
if(initial(leg?.limb_id) != "digitigrade")
// normal legs, use normal human shoes
diff --git a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/worn_overlays.dm b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/worn_overlays.dm
index a35a261439a..a5802e962cf 100644
--- a/modular_skyrat/modules/customization/modules/mob/living/carbon/human/worn_overlays.dm
+++ b/modular_skyrat/modules/customization/modules/mob/living/carbon/human/worn_overlays.dm
@@ -7,9 +7,9 @@
var/mob/living/carbon/human/human_wearer = loc
- // Handle custom_worn_icons[LOADOUT_ITEM_ACCESSORY]
- if(LOADOUT_ITEM_ACCESSORY in human_wearer.dna.species.custom_worn_icons)
- var/icon/custom_accessory_icon = human_wearer.dna.species.custom_worn_icons[LOADOUT_ITEM_ACCESSORY]
+ // Handle custom_worn_icons[OFFSET_ACCESSORY]
+ if(OFFSET_ACCESSORY in human_wearer.dna.species.custom_worn_icons)
+ var/icon/custom_accessory_icon = human_wearer.dna.species.custom_worn_icons[OFFSET_ACCESSORY]
var/list/custom_accessory_states = icon_states(custom_accessory_icon)
if(accessory_overlay.icon_state in custom_accessory_states)
diff --git a/modular_skyrat/modules/events/code/event_spawner.dm b/modular_skyrat/modules/events/code/event_spawner.dm
index bc375763455..16d9f209baf 100644
--- a/modular_skyrat/modules/events/code/event_spawner.dm
+++ b/modular_skyrat/modules/events/code/event_spawner.dm
@@ -126,10 +126,6 @@
else
equipped.forceMove(get_turf(H))
- if(gets_loadout)
- for(var/datum/loadout_item/item as anything in loadout_list_to_datums(H?.client?.prefs?.loadout_list))
- item.post_equip_item(H.client?.prefs, H)
-
//Override access of the ID card here
var/obj/item/card/id/ID
if(length(access_override))
diff --git a/modular_skyrat/modules/loadouts/loadout_items/_loadout_datum.dm b/modular_skyrat/modules/loadouts/loadout_items/_loadout_datum.dm
deleted file mode 100644
index 5a4d3bc6a54..00000000000
--- a/modular_skyrat/modules/loadouts/loadout_items/_loadout_datum.dm
+++ /dev/null
@@ -1,135 +0,0 @@
-// -- The loadout item datum and related procs. --
-
-/// Global list of ALL loadout datums instantiated.
-GLOBAL_LIST_EMPTY(all_loadout_datums)
-
-/*
- * Generate a list of singleton loadout_item datums from all subtypes of [type_to_generate]
- *
- * returns a list of singleton datums.
- */
-/proc/generate_loadout_items(type_to_generate)
- RETURN_TYPE(/list)
-
- . = list()
- if(!ispath(type_to_generate))
- CRASH("generate_loadout_items(): called with an invalid or null path as an argument!")
-
- for(var/datum/loadout_item/found_type as anything in subtypesof(type_to_generate))
- /// Any item without a name is "abstract"
- if(isnull(initial(found_type.name)))
- continue
-
- if(!ispath(initial(found_type.item_path)))
- stack_trace("generate_loadout_items(): Attempted to instantiate a loadout item ([initial(found_type.name)]) with an invalid or null typepath! (got path: [initial(found_type.item_path)])")
- continue
-
- var/datum/loadout_item/spawned_type = new found_type()
- // Let's sanitize in case somebody inserted the player's byond name instead of ckey in canonical form
- if(spawned_type.ckeywhitelist)
- for (var/i = 1, i <= length(spawned_type.ckeywhitelist), i++)
- spawned_type.ckeywhitelist[i] = ckey(spawned_type.ckeywhitelist[i])
- GLOB.all_loadout_datums[spawned_type.item_path] = spawned_type
- . |= spawned_type
-
-/// Loadout item datum.
-/// Holds all the information about each loadout items.
-/// A list of singleton loadout items are generated on initialize.
-/datum/loadout_item
- /// Displayed name of the loadout item.
- var/name
- /// Whether this item can be renamed and described.
- var/can_be_named = TRUE
- /// The category of the loadout item.
- var/category
- /// The actual item path of the loadout item.
- var/atom/item_path
- /// List of additional text for the tooltip displayed on this item.
- var/list/additional_tooltip_contents
- /// If set, it's a list containing ckeys which only can get the item
- var/list/ckeywhitelist
- /// If set, is a list of job names of which can get the loadout item
- var/list/restricted_roles
- /// If set, is a list of job names of which can't get the loadout item
- var/list/blacklisted_roles
- /// If set, is a list of species which can get the loadout item
- var/list/restricted_species
- /// Whether the item is restricted to supporters
- var/donator_only
- /// Whether the item requires a specific season in order to be available
- var/required_season = null
- /// If the item won't appear when the ERP config is disabled
- var/erp_item = FALSE
-
-/*
- * Place our [var/item_path] into [outfit].
- *
- * By default, just adds the item into the outfit's backpack contents, if non-visual.
- *
- * equipper - If we're equipping our outfit onto a mob at the time, this is the mob it is equipped on. Can be null.
- * outfit - The outfit we're equipping our items into.
- * visual - If TRUE, then our outfit is only for visual use (for example, a preview).
- */
-/datum/loadout_item/proc/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(!visuals_only)
- LAZYADD(outfit.backpack_contents, item_path)
-
-/*
- * To be called before insert_path_into_outfit()
- *
- * Checks if an important_for_life item exists and puts the loadout item into the backpack if they would take up the same slot as it.
- *
- * equipper - If we're equipping our outfit onto a mob at the time, this is the mob it is equipped on. Can be null.
- * outfit - The outfit we're equipping our items into.
- * outfit_important_for_life - The outfit whose slots we want to make sure we don't equip an item into.
- * visual - If TRUE, then our outfit is only for visual use (for example, a preview).
- *
- * Returns TRUE if there is an important_for_life item in the slot that the loadout item would normally occupy, FALSE otherwise
- */
-/datum/loadout_item/proc/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE)
- if(!visuals_only)
- LAZYADD(outfit.backpack_contents, item_path)
-
-/*
- * Called When the item is equipped on [equipper].
- */
-/datum/loadout_item/proc/on_equip_item(datum/preferences/preference_source, mob/living/carbon/human/equipper, visuals_only = FALSE)
- if(!preference_source)
- return
-
- var/list/our_loadout = preference_source.loadout_list
- var/atom/loadout_atom = item_path
- var/can_be_greyscale = !!(initial(loadout_atom.greyscale_config) && initial(loadout_atom.greyscale_colors) && (initial(loadout_atom.flags_1) & IS_PLAYER_COLORABLE_1))
- if(can_be_greyscale && (INFO_GREYSCALE in our_loadout[item_path]))
- if(ispath(item_path, /obj/item/clothing))
- // When an outfit is equipped in preview, get_equipped_items() does not work, so we have to use get_all_contents()
- var/obj/item/clothing/equipped_item = locate(item_path) in (visuals_only ? equipper.get_all_contents() : equipper.get_all_gear()) // needs held items for briefcasers
- if(equipped_item)
- equipped_item.set_greyscale(our_loadout[item_path][INFO_GREYSCALE])
- else
- stack_trace("[type] on_equip_item(): Could not locate clothing item (path: [item_path]) in [equipper]'s [visuals_only ? "visible":"all"] contents to set greyscaling!")
-
- else if(!visuals_only)
- var/obj/item/other_item = locate(item_path) in equipper.get_all_gear()
- if(other_item)
- other_item.set_greyscale(our_loadout[item_path][INFO_GREYSCALE])
- else
- stack_trace("[type] on_equip_item(): Could not locate backpack item (path: [item_path]) in [equipper]'s contents to set greyscaling!")
-
- if(can_be_named && !visuals_only)
- var/obj/item/equipped_item = locate(item_path) in equipper.get_all_gear()
- if(equipped_item)
- if(INFO_NAMED in our_loadout[item_path])
- equipped_item.name = our_loadout[item_path][INFO_NAMED]
- equipped_item.on_loadout_custom_named()
- if(INFO_DESCRIBED in our_loadout[item_path])
- equipped_item.desc = our_loadout[item_path][INFO_DESCRIBED]
- equipped_item.on_loadout_custom_described()
- else
- stack_trace("[type] on_equip_item(): Could not locate item (path: [item_path]) in [equipper]'s contents to set name/desc!")
-
-/*
- * Called after the item is equipped on [equipper], at the end of character setup.
- */
-/datum/loadout_item/proc/post_equip_item(datum/preferences/preference_source, mob/living/carbon/human/equipper)
- return FALSE
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_accessory.dm b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_accessory.dm
deleted file mode 100644
index addd37faf58..00000000000
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_accessory.dm
+++ /dev/null
@@ -1,104 +0,0 @@
-/*
-* LOADOUT ITEM DATUMS FOR THE ACCESSORY SLOT
-*/
-
-/// Accessory Items (Moves overrided items to backpack)
-GLOBAL_LIST_INIT(loadout_accessory, generate_loadout_items(/datum/loadout_item/accessory))
-
-/datum/loadout_item/accessory
- category = LOADOUT_ITEM_ACCESSORY
-
-/datum/loadout_item/accessory/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, visuals_only = FALSE)
- if(initial(outfit_important_for_life.accessory))
- .. ()
- return TRUE
-
-/datum/loadout_item/accessory/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only)
- if(outfit.accessory)
- LAZYADD(outfit.backpack_contents, outfit.accessory)
- outfit.accessory = item_path
- else
- outfit.accessory = item_path
-
-/datum/loadout_item/accessory/maid_apron
- name = "Maid Apron"
- item_path = /obj/item/clothing/accessory/maidapron
-
-/datum/loadout_item/accessory/waistcoat
- name = "Waistcoat"
- item_path = /obj/item/clothing/accessory/waistcoat
-
-/datum/loadout_item/accessory/pocket_protector
- name = "Pocket Protector (Empty)"
- item_path = /obj/item/clothing/accessory/pocketprotector
-
-/datum/loadout_item/accessory/full_pocket_protector
- name = "Pocket Protector (Filled)"
- item_path = /obj/item/clothing/accessory/pocketprotector/full
- additional_tooltip_contents = list("CONTAINS PENS - This item contains multiple pens on spawn.")
-
-/datum/loadout_item/accessory/ribbon
- name = "Ribbon"
- item_path = /obj/item/clothing/accessory/medal/ribbon
-
-/datum/loadout_item/accessory/pride
- name = "Pride Pin"
- item_path = /obj/item/clothing/accessory/pride
-
-/*
-* ARMBANDS
-*/
-
-/datum/loadout_item/accessory/armband_medblue
- name = "Blue-White Armband"
- item_path = /obj/item/clothing/accessory/armband/medblue/nonsec
-
-/datum/loadout_item/accessory/armband_med
- name = "White Armband"
- item_path = /obj/item/clothing/accessory/armband/med/nonsec
-
-/datum/loadout_item/accessory/armband_cargo
- name = "Brown Armband"
- item_path = /obj/item/clothing/accessory/armband/cargo/nonsec
-
-/datum/loadout_item/accessory/armband_engineering
- name = "Orange Armband"
- item_path = /obj/item/clothing/accessory/armband/engine/nonsec
-
-/datum/loadout_item/accessory/armband_security_nonsec
- name = "Blue Armband"
- item_path = /obj/item/clothing/accessory/armband/deputy/lopland/nonsec
-
-/datum/loadout_item/accessory/armband_security
- name = "Security Armband"
- item_path = /obj/item/clothing/accessory/armband/deputy/lopland
- restricted_roles = list(JOB_HEAD_OF_SECURITY, JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_DETECTIVE, JOB_CORRECTIONS_OFFICER)
-
-/datum/loadout_item/accessory/armband_security_deputy
- name = "Security Deputy Armband"
- item_path = /obj/item/clothing/accessory/armband/deputy
- restricted_roles = list(JOB_HEAD_OF_SECURITY, JOB_SECURITY_OFFICER, JOB_WARDEN, JOB_DETECTIVE, JOB_CORRECTIONS_OFFICER)
-
-/datum/loadout_item/accessory/armband_science
- name = "Purple Armband"
- item_path = /obj/item/clothing/accessory/armband/science/nonsec
-
-/*
-* ARMOURLESS
-*/
-
-/datum/loadout_item/accessory/bone_charm
- name = "Heirloom Bone Talisman"
- item_path = /obj/item/clothing/accessory/talisman/armourless
- additional_tooltip_contents = list(TOOLTIP_NO_ARMOR)
-
-/datum/loadout_item/accessory/bone_codpiece
- name = "Heirloom Skull Codpiece"
- item_path = /obj/item/clothing/accessory/skullcodpiece/armourless
- additional_tooltip_contents = list(TOOLTIP_NO_ARMOR)
-
-/datum/loadout_item/accessory/sinew_kilt
- name = "Heirloom Sinew Skirt"
- item_path = /obj/item/clothing/accessory/skilt/armourless
- additional_tooltip_contents = list(TOOLTIP_NO_ARMOR)
diff --git a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_ears.dm b/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_ears.dm
deleted file mode 100644
index 81c1b149480..00000000000
--- a/modular_skyrat/modules/loadouts/loadout_items/loadout_datum_ears.dm
+++ /dev/null
@@ -1,30 +0,0 @@
-/*
-* LOADOUT ITEM DATUMS FOR THE EAR SLOT
-*/
-
-/// Ear Slot Items (Moves overrided items to backpack)
-GLOBAL_LIST_INIT(loadout_ears, generate_loadout_items(/datum/loadout_item/ears))
-
-/datum/loadout_item/ears
- category = LOADOUT_ITEM_EARS
-
-/datum/loadout_item/ears/pre_equip_item(datum/outfit/outfit, datum/outfit/outfit_important_for_life, mob/living/carbon/human/equipper, visuals_only = FALSE)
- if(initial(outfit_important_for_life.ears))
- .. ()
- return TRUE
-
-/datum/loadout_item/ears/insert_path_into_outfit(datum/outfit/outfit, mob/living/carbon/human/equipper, visuals_only = FALSE, override_items = LOADOUT_OVERRIDE_BACKPACK)
- if(override_items == LOADOUT_OVERRIDE_BACKPACK && !visuals_only)
- if(outfit.ears)
- LAZYADD(outfit.backpack_contents, outfit.ears)
- outfit.ears = item_path
- else
- outfit.ears = item_path
-
-/datum/loadout_item/ears/headphones
- name = "Headphones"
- item_path = /obj/item/instrument/piano_synth/headphones
-
-/datum/loadout_item/ears/earmuffs
- name = "Earmuffs"
- item_path = /obj/item/clothing/ears/earmuffs
diff --git a/modular_skyrat/modules/loadouts/loadout_items/under/donator.dm b/modular_skyrat/modules/loadouts/loadout_items/under/donator.dm
deleted file mode 100644
index da5fb6bbd22..00000000000
--- a/modular_skyrat/modules/loadouts/loadout_items/under/donator.dm
+++ /dev/null
@@ -1,14 +0,0 @@
-/datum/loadout_item/under/jumpsuit/donator
- donator_only = TRUE
-
-/datum/loadout_item/under/jumpsuit/donator/enclavesergeant
- name = "Enclave - Sergeant"
- item_path = /obj/item/clothing/under/syndicate/skyrat/enclave
-
-/datum/loadout_item/under/jumpsuit/donator/enclaveofficer
- name = "Enclave - Officer"
- item_path = /obj/item/clothing/under/syndicate/skyrat/enclave/officer
-
-/datum/loadout_item/under/jumpsuit/donator/blondie
- name = "Blonde Cowboy Uniform"
- item_path = /obj/item/clothing/under/rank/security/detective/cowboy/armorless
diff --git a/modular_skyrat/modules/loadouts/loadout_ui/loadout_manager.dm b/modular_skyrat/modules/loadouts/loadout_ui/loadout_manager.dm
deleted file mode 100644
index 3d5c144a69a..00000000000
--- a/modular_skyrat/modules/loadouts/loadout_ui/loadout_manager.dm
+++ /dev/null
@@ -1,342 +0,0 @@
-/// -- The loadout manager and UI --
-/// Tracking when a client has an open loadout manager, to prevent funky stuff.
-/client
- /// A weakref to loadout_manager datum.
- var/datum/weakref/open_loadout_ui
-
-/// Datum holder for the loadout manager UI.
-/datum/loadout_manager
- /// The client of the person using the UI
- var/client/owner
- /// The current selected loadout list.
- var/list/loadout_on_open
- /// Our currently open greyscaling menu.
- var/datum/greyscale_modify_menu/menu
-
-/datum/loadout_manager/Destroy(force, ...)
- if(menu)
- SStgui.close_uis(menu)
- menu = null
- owner?.open_loadout_ui = null
- owner = null
- QDEL_NULL(menu)
- return ..()
-
-/datum/loadout_manager/New(user)
- owner = CLIENT_FROM_VAR(user)
- loadout_on_open = LAZYLISTDUPLICATE(owner.prefs.loadout_list)
- owner.open_loadout_ui = WEAKREF(src)
-
-/datum/loadout_manager/ui_close(mob/user)
- owner?.prefs.save_character()
- if(menu)
- SStgui.close_uis(menu)
- menu = null
- owner?.open_loadout_ui = null
- qdel(src)
-
-/datum/loadout_manager/ui_state(mob/user)
- return GLOB.always_state
-
-/datum/loadout_manager/ui_interact(mob/user, datum/tgui/ui)
-
- ui = SStgui.try_update_ui(user, src, ui)
- if(!ui)
- ui = new(user, src, "LoadoutManager")
- ui.set_autoupdate(FALSE)
- ui.open()
-
-/datum/loadout_manager/ui_act(action, list/params, datum/tgui/ui, datum/ui_state/state)
- . = ..()
- if(.)
- return
-
- var/datum/loadout_item/interacted_item
- if(params["path"])
- interacted_item = GLOB.all_loadout_datums[text2path(params["path"])]
- if(!interacted_item)
- stack_trace("Failed to locate desired loadout item (path: [params["path"]]) in the global list of loadout datums!")
- return
-
- switch(action)
- // Closes the UI, reverting our loadout to before edits if params["revert"] is set
- if("close_ui")
- if(params["revert"])
- owner.prefs.loadout_list = loadout_on_open
- SStgui.close_uis(src)
- return
-
- if("select_item")
- //Here we will perform basic checks to ensure there are no exploits happening
- if(interacted_item.donator_only && !GLOB.donator_list[owner.ckey] && !is_admin(owner))
- message_admins("LOADOUT SYSTEM: Possible exploit detected, non-donator [owner.ckey] tried loading [interacted_item.item_path], but this is donator only.")
- return
-
- if(interacted_item.ckeywhitelist && !(owner.ckey in interacted_item.ckeywhitelist))
- message_admins("LOADOUT SYSTEM: Possible exploit detected, non-donator [owner.ckey] tried loading [interacted_item.item_path], but this is ckey locked.")
- return
- if(params["deselect"])
- deselect_item(interacted_item)
- owner?.prefs?.character_preview_view.update_body()
- else
- select_item(interacted_item)
- owner?.prefs?.character_preview_view.update_body()
-
- if("select_color")
- select_item_color(interacted_item)
-
- if("set_name")
- set_item_name(interacted_item)
-
- if("display_restrictions")
- display_job_restrictions(interacted_item)
- display_job_blacklists(interacted_item)
- display_species_restrictions(interacted_item)
-
- // Clears the loadout list entirely.
- if("clear_all_items")
- LAZYNULL(owner.prefs.loadout_list)
- owner?.prefs?.character_preview_view.update_body()
-
- if("donator_explain")
- if(GLOB.donator_list[owner.ckey])
- to_chat(owner, examine_block("Thank you for donating, this item is for you <3!"))
- else
- to_chat(owner, examine_block(span_boldnotice("This item is restricted to donators only, for more information, please check the discord(#server-info) for more information!")))
-
- if("ckey_explain")
- to_chat(owner, examine_block(span_green("This item is restricted to your ckey only. Thank you!")))
-
- return TRUE
-
-/// Select [path] item to [category_slot] slot.
-/datum/loadout_manager/proc/select_item(datum/loadout_item/selected_item)
- var/num_misc_items = 0
- var/datum/loadout_item/first_misc_found
- for(var/datum/loadout_item/item as anything in loadout_list_to_datums(owner.prefs.loadout_list))
- if(item.category == selected_item.category)
- if((item.category == LOADOUT_ITEM_MISC || item.category == LOADOUT_ITEM_TOYS) && ++num_misc_items < MAX_ALLOWED_MISC_ITEMS)
- if(!first_misc_found)
- first_misc_found = item
- continue
-
- deselect_item(first_misc_found || item)
- continue
-
- LAZYSET(owner.prefs.loadout_list, selected_item.item_path, list())
-
-/// Deselect [deselected_item].
-/datum/loadout_manager/proc/deselect_item(datum/loadout_item/deselected_item)
- LAZYREMOVE(owner.prefs.loadout_list, deselected_item.item_path)
-
-/// Select [path] item to [category_slot] slot, and open up the greyscale UI to customize [path] in [category] slot.
-/datum/loadout_manager/proc/select_item_color(datum/loadout_item/item)
- if(menu)
- to_chat(owner, span_warning("You already have a greyscaling window open!"))
- return
-
- var/obj/item/colored_item = item.item_path
-
- var/list/allowed_configs = list()
- if(initial(colored_item.greyscale_config))
- allowed_configs += "[initial(colored_item.greyscale_config)]"
- if(initial(colored_item.greyscale_config_worn))
- allowed_configs += "[initial(colored_item.greyscale_config_worn)]"
- if(initial(colored_item.greyscale_config_inhand_left))
- allowed_configs += "[initial(colored_item.greyscale_config_inhand_left)]"
- if(initial(colored_item.greyscale_config_inhand_right))
- allowed_configs += "[initial(colored_item.greyscale_config_inhand_right)]"
-
- var/slot_starting_colors = initial(colored_item.greyscale_colors)
- if((colored_item in owner.prefs.loadout_list) && (INFO_GREYSCALE in owner.prefs.loadout_list[colored_item]))
- slot_starting_colors = owner.prefs.loadout_list[colored_item][INFO_GREYSCALE]
-
- menu = new(
- src,
- usr,
- allowed_configs,
- CALLBACK(src, PROC_REF(set_slot_greyscale), colored_item),
- starting_icon_state = initial(colored_item.icon_state),
- starting_config = initial(colored_item.greyscale_config),
- starting_colors = slot_starting_colors,
- unlocked = TRUE,
- )
- RegisterSignal(menu, COMSIG_PREQDELETED, TYPE_PROC_REF(/datum/loadout_manager, cleanup_greyscale_menu))
- menu.ui_interact(usr)
-
-/// A proc to make sure our menu gets null'd properly when it's deleted.
-/// If we delete the greyscale menu from the greyscale datum, we don't null it correctly here, it harddels.
-/datum/loadout_manager/proc/cleanup_greyscale_menu(datum/source)
- SIGNAL_HANDLER
-
- menu = null
-
-/// Sets [category_slot]'s greyscale colors to the colors in the currently opened [open_menu].
-/datum/loadout_manager/proc/set_slot_greyscale(path, datum/greyscale_modify_menu/open_menu)
- if(!open_menu)
- CRASH("set_slot_greyscale called without a greyscale menu!")
-
- if(isnull(owner))
- CRASH("set_slot_greyscale called without an owner!")
-
- if(!(path in owner.prefs.loadout_list))
- to_chat(owner, span_warning("Select the item before attempting to apply greyscale to it!"))
- return
-
- var/list/colors = open_menu.split_colors
- if(colors)
- owner.prefs.loadout_list[path][INFO_GREYSCALE] = colors.Join("")
- owner.prefs?.character_preview_view.update_body()
-
-/// Set [item]'s name to input provided.
-/datum/loadout_manager/proc/set_item_name(datum/loadout_item/item)
- var/current_name = ""
- var/current_desc = ""
-
- if(!(item.item_path in owner.prefs.loadout_list))
- to_chat(owner, span_warning("Select the item before attempting to name it!"))
- return
-
- if(INFO_NAMED in owner.prefs.loadout_list[item.item_path])
- current_name = owner.prefs.loadout_list[item.item_path][INFO_NAMED]
- if(INFO_DESCRIBED in owner.prefs.loadout_list[item.item_path])
- current_desc = owner.prefs.loadout_list[item.item_path][INFO_DESCRIBED]
-
- var/input_name = tgui_input_text(owner, "What name do you want to give [item.name]? Leave blank to clear.", "[item.name] name", current_name, MAX_NAME_LEN)
- var/input_desc = tgui_input_text(owner, "What description do you want to give [item.name]? 256 character max, leave blank to clear.", "[item.name] description", current_desc, 256, multiline = TRUE)
- if(QDELETED(src) || QDELETED(owner) || QDELETED(owner.prefs))
- return
-
- if(input_name)
- owner.prefs.loadout_list[item.item_path][INFO_NAMED] = input_name
- else
- if(INFO_NAMED in owner.prefs.loadout_list[item.item_path])
- owner.prefs.loadout_list[item.item_path] -= INFO_NAMED
- if(input_desc)
- owner.prefs.loadout_list[item.item_path][INFO_DESCRIBED] = input_desc
- else
- if(INFO_DESCRIBED in owner.prefs.loadout_list[item.item_path])
- owner.prefs.loadout_list[item.item_path] -= INFO_DESCRIBED
-
-/// If only certain jobs are allowed to equip this loadout item, display which
-/datum/loadout_manager/proc/display_job_restrictions(datum/loadout_item/item)
- if(!length(item.restricted_roles))
- return
- var/composed_message = span_boldnotice("The [initial(item.item_path.name)] is whitelisted to the following roles:
")
- for(var/job_type in item.restricted_roles)
- composed_message += span_green("[job_type]
")
-
- to_chat(owner, examine_block(composed_message))
-
-/// If certain jobs aren't allowed to equip this loadout item, display which
-/datum/loadout_manager/proc/display_job_blacklists(datum/loadout_item/item)
- if(!length(item.blacklisted_roles))
- return
- var/composed_message = span_boldnotice("The [initial(item.item_path.name)] is blacklisted from the following roles:
")
- for(var/job_type in item.blacklisted_roles)
- composed_message += span_red("[job_type]
")
-
- to_chat(owner, examine_block(composed_message))
-
-/// If only a certain species is allowed to equip this loadout item, display which
-/datum/loadout_manager/proc/display_species_restrictions(datum/loadout_item/item)
- if(!length(item.restricted_species))
- return
- var/composed_message = span_boldnotice("\The [initial(item.item_path.name)] is restricted to the following species:
")
- for(var/species_type in item.restricted_species)
- composed_message += span_grey("[species_type]
")
-
- to_chat(owner, examine_block(composed_message))
-
-/datum/loadout_manager/ui_data(mob/user)
- var/list/data = list()
-
- var/list/all_selected_paths = list()
- for(var/path in owner?.prefs?.loadout_list)
- all_selected_paths += path
- data["selected_loadout"] = all_selected_paths
- data["user_is_donator"] = !!(GLOB.donator_list[owner.ckey] || is_admin(owner))
-
- return data
-
-/datum/loadout_manager/ui_static_data()
- var/list/data = list()
-
- // [name] is the name of the tab that contains all the corresponding contents.
- // [title] is the name at the top of the list of corresponding contents.
- // [contents] is a formatted list of all the possible items for that slot.
- // - [contents.path] is the path the singleton datum holds
- // - [contents.name] is the name of the singleton datum
- // - [contents.is_renamable], whether the item can be renamed in the UI
- // - [contents.is_greyscale], whether the item can be greyscaled in the UI
- // - [contents.tooltip_text], any additional tooltip text that hovers over the item's select button
-
- var/list/loadout_tabs = list()
- loadout_tabs += list(list("name" = "Belt", "title" = "Belt Slot Items", "contents" = list_to_data(GLOB.loadout_belts)))
- loadout_tabs += list(list("name" = "Ears", "title" = "Ear Slot Items", "contents" = list_to_data(GLOB.loadout_ears)))
- loadout_tabs += list(list("name" = "Glasses", "title" = "Glasses Slot Items", "contents" = list_to_data(GLOB.loadout_glasses)))
- loadout_tabs += list(list("name" = "Gloves", "title" = "Glove Slot Items", "contents" = list_to_data(GLOB.loadout_gloves)))
- loadout_tabs += list(list("name" = "Head", "title" = "Head Slot Items", "contents" = list_to_data(GLOB.loadout_helmets)))
- loadout_tabs += list(list("name" = "Mask", "title" = "Mask Slot Items", "contents" = list_to_data(GLOB.loadout_masks)))
- loadout_tabs += list(list("name" = "Neck", "title" = "Neck Slot Items", "contents" = list_to_data(GLOB.loadout_necks)))
- loadout_tabs += list(list("name" = "Shoes", "title" = "Shoe Slot Items", "contents" = list_to_data(GLOB.loadout_shoes)))
- loadout_tabs += list(list("name" = "Suit", "title" = "Suit Slot Items", "contents" = list_to_data(GLOB.loadout_exosuits)))
- loadout_tabs += list(list("name" = "Jumpsuit", "title" = "Uniform Slot Items", "contents" = list_to_data(GLOB.loadout_jumpsuits)))
- loadout_tabs += list(list("name" = "Formal", "title" = "Uniform Slot Items (cont)", "contents" = list_to_data(GLOB.loadout_undersuits)))
- loadout_tabs += list(list("name" = "Misc. Under", "title" = "Uniform Slot Items (cont)", "contents" = list_to_data(GLOB.loadout_miscunders)))
- loadout_tabs += list(list("name" = "Accessory", "title" = "Uniform Accessory Slot Items", "contents" = list_to_data(GLOB.loadout_accessory)))
- loadout_tabs += list(list("name" = "Inhand", "title" = "In-hand Items", "contents" = list_to_data(GLOB.loadout_inhand_items)))
- loadout_tabs += list(list("name" = "Toys", "title" = "Toys! ([MAX_ALLOWED_MISC_ITEMS] max)", "contents" = list_to_data(GLOB.loadout_toys)))
- loadout_tabs += list(list("name" = "Other", "title" = "Backpack Items ([MAX_ALLOWED_MISC_ITEMS] max)", "contents" = list_to_data(GLOB.loadout_pocket_items)))
-
- data["loadout_tabs"] = loadout_tabs
-
- return data
-
-/*
- * Takes an assoc list of [typepath]s to [singleton datum]
- * And formats it into an object for TGUI.
- *
- * - list[name] is the name of the datum.
- * - list[path] is the typepath of the item.
- */
-/datum/loadout_manager/proc/list_to_data(list_of_datums)
- if(!LAZYLEN(list_of_datums))
- return
-
- var/list/formatted_list = new(length(list_of_datums))
-
- var/array_index = 1
- for(var/datum/loadout_item/item as anything in list_of_datums)
- if(!isnull(item.ckeywhitelist)) //These checks are also performed in the backend.
- if(!(owner.ckey in item.ckeywhitelist))
- formatted_list.len--
- continue
- if(item.donator_only) //These checks are also performed in the backend.
- if(!GLOB.donator_list[owner.ckey] && !is_admin(owner))
- formatted_list.len--
- continue
- if(item.required_season && !check_holidays(item.required_season))
- formatted_list.len--
- continue
-
- var/atom/loadout_atom = item.item_path
-
- var/list/formatted_item = list()
- formatted_item["name"] = item.name
- formatted_item["path"] = item.item_path
- formatted_item["is_greyscale"] = !!(initial(loadout_atom.greyscale_config) && initial(loadout_atom.greyscale_colors) && (initial(loadout_atom.flags_1) & IS_PLAYER_COLORABLE_1))
- formatted_item["is_renameable"] = item.can_be_named
- formatted_item["is_job_restricted"] = !isnull(item.restricted_roles)
- formatted_item["is_job_blacklisted"] = !isnull(item.blacklisted_roles)
- formatted_item["is_species_restricted"] = !isnull(item.restricted_species)
- formatted_item["is_donator_only"] = !isnull(item.donator_only)
- formatted_item["is_ckey_whitelisted"] = !isnull(item.ckeywhitelist)
- if(LAZYLEN(item.additional_tooltip_contents))
- formatted_item["tooltip_text"] = item.additional_tooltip_contents.Join("\n")
-
- formatted_list[array_index++] = formatted_item
-
- return formatted_list
-
-
diff --git a/modular_skyrat/modules/loadouts/loadout_ui/loadout_outfit_helpers.dm b/modular_skyrat/modules/loadouts/loadout_ui/loadout_outfit_helpers.dm
deleted file mode 100644
index 2469deb875e..00000000000
--- a/modular_skyrat/modules/loadouts/loadout_ui/loadout_outfit_helpers.dm
+++ /dev/null
@@ -1,168 +0,0 @@
-/// -- Outfit and mob helpers to equip our loadout items. --
-
-/// An empty outfit we fill in with our loadout items to dress our dummy.
-/datum/outfit/player_loadout
- name = "Player Loadout"
-
-/datum/outfit/player_loadout/equip(mob/living/carbon/human/user, visualsOnly)
- . = ..()
- user.equip_outfit_and_loadout(new /datum/outfit(), user.client.prefs)
-
-/*
- * Actually equip our mob with our job outfit and our loadout items.
- * Loadout items override the pre-existing item in the corresponding slot of the job outfit.
- * Some job items are preserved after being overridden - belt items, ear items, and glasses.
- * The rest of the slots, the items are overridden completely and deleted.
- *
- * Plasmamen are snowflaked to not have any envirosuit pieces removed just in case.
- * Their loadout items for those slots will be added to their backpack on spawn.
- *
- * outfit - the job outfit we're equipping
- * visuals_only - whether we call special equipped procs, or if we just look like we equipped it
- * preference_source - the preferences of the thing we're equipping
- */
-/mob/living/carbon/human/proc/equip_outfit_and_loadout(datum/outfit/outfit, datum/preferences/preference_source, visuals_only = FALSE, datum/job/equipping_job)
- if (!preference_source)
- equipOutfit(outfit, visuals_only) // no prefs for loadout items, but we should still equip the outfit.
- return FALSE
-
- var/datum/outfit/equipped_outfit
-
- if(ispath(outfit))
- equipped_outfit = new outfit()
- else if(istype(outfit))
- equipped_outfit = outfit
- else
- CRASH("Outfit passed to equip_outfit_and_loadout was neither a path nor an instantiated type!")
-
- var/override_preference = preference_source.read_preference(/datum/preference/choiced/loadout_override_preference)
-
- var/list/loadout_datums = loadout_list_to_datums(preference_source?.loadout_list)
-
- if(override_preference == LOADOUT_OVERRIDE_CASE && !visuals_only)
- var/obj/item/storage/briefcase/empty/briefcase = new(loc)
-
- for(var/datum/loadout_item/item as anything in loadout_datums)
- if(item.restricted_roles && equipping_job && !(equipping_job.title in item.restricted_roles))
- if(client)
- to_chat(src, span_warning("You were unable to get a loadout item([initial(item.item_path.name)]) due to job restrictions!"))
- continue
-
- if(item.blacklisted_roles && equipping_job && (equipping_job.title in item.blacklisted_roles))
- if(client)
- to_chat(src, span_warning("You were unable to get a loadout item([initial(item.item_path.name)]) due to job blacklists!"))
- continue
-
- if(item.restricted_species && !(dna.species.id in item.restricted_species))
- if(client)
- to_chat(src, span_warning("You were unable to get a loadout item ([initial(item.item_path.name)]) due to species restrictions!"))
- continue
-
- new item.item_path(briefcase)
-
- briefcase.name = "[preference_source.read_preference(/datum/preference/name/real_name)]'s travel suitcase"
- equipOutfit(equipped_outfit, visuals_only)
- put_in_hands(briefcase)
- else
- for(var/datum/loadout_item/item as anything in loadout_datums)
- if(item.restricted_roles && equipping_job && !(equipping_job.title in item.restricted_roles))
- if(client)
- to_chat(src, span_warning("You were unable to get a loadout item([initial(item.item_path.name)]) due to job restrictions!"))
- continue
-
- if(item.blacklisted_roles && equipping_job && (equipping_job.title in item.blacklisted_roles))
- if(client)
- to_chat(src, span_warning("You were unable to get a loadout item([initial(item.item_path.name)]) due to job blacklists!"))
- continue
-
- if(item.restricted_species && !(dna.species.id in item.restricted_species))
- if(client)
- to_chat(src, span_warning("You were unable to get a loadout item ([initial(item.item_path.name)]) due to species restrictions!"))
- continue
-
- // Make sure the item is not overriding an important for life outfit item
- var/datum/outfit/outfit_important_for_life = dna.species.outfit_important_for_life
- if(!outfit_important_for_life || !item.pre_equip_item(equipped_outfit, outfit_important_for_life, src, visuals_only))
- item.insert_path_into_outfit(equipped_outfit, src, visuals_only, override_preference)
-
-
- equipOutfit(equipped_outfit, visuals_only)
-
- for(var/datum/loadout_item/item as anything in loadout_datums)
- if(item.restricted_roles && equipping_job && !(equipping_job.title in item.restricted_roles))
- continue
- item.on_equip_item(preference_source, src, visuals_only)
-
- regenerate_icons()
- return TRUE
-
-/*
- * Takes a list of paths (such as a loadout list)
- * and returns a list of their singleton loadout item datums
- *
- * loadout_list - the list being checked
- *
- * returns a list of singleton datums
- */
-/proc/loadout_list_to_datums(list/loadout_list)
- RETURN_TYPE(/list)
-
- . = list()
-
- if(!GLOB.all_loadout_datums.len)
- CRASH("No loadout datums in the global loadout list!")
-
- for(var/path in loadout_list)
- if(!GLOB.all_loadout_datums[path])
- stack_trace("Could not find ([path]) loadout item in the global list of loadout datums!")
- continue
-
- . |= GLOB.all_loadout_datums[path]
-
-
-/*
- * Removes all invalid paths from loadout lists.
- *
- * passed_list - the loadout list we're sanitizing.
- *
- * returns a list
- */
-/proc/update_loadout_list(list/passed_list)
- RETURN_TYPE(/list)
-
- var/list/list_to_update = LAZYLISTDUPLICATE(passed_list)
- for(var/thing in list_to_update) //thing, 'cause it could be a lot of things
- if(ispath(thing))
- break
- var/our_path = text2path(list_to_update[thing])
-
- LAZYREMOVE(list_to_update, thing)
- if(ispath(our_path))
- LAZYSET(list_to_update, our_path, list())
-
- return list_to_update
-
-/*
- * Removes all invalid paths from loadout lists.
- *
- * passed_list - the loadout list we're sanitizing.
- *
- * returns a list
- */
-/proc/sanitize_loadout_list(list/passed_list)
- RETURN_TYPE(/list)
-
- var/list/list_to_clean = LAZYLISTDUPLICATE(passed_list)
- for(var/path in list_to_clean)
- if(!ispath(path))
- stack_trace("invalid path found in loadout list! (Path: [path])")
- LAZYREMOVE(list_to_clean, path)
-
- else if(!(path in GLOB.all_loadout_datums))
- stack_trace("invalid loadout slot found in loadout list! Path: [path]")
- LAZYREMOVE(list_to_clean, path)
-
- return list_to_clean
-
-/obj/item/storage/briefcase/empty/PopulateContents()
- return
diff --git a/modular_skyrat/modules/loadouts/readme.md b/modular_skyrat/modules/loadouts/readme.md
deleted file mode 100644
index f3ce555ea8f..00000000000
--- a/modular_skyrat/modules/loadouts/readme.md
+++ /dev/null
@@ -1,12 +0,0 @@
-## Title: MrMelbert's loadout system!
-
-MODULE ID: LOADOUT
-
-### Description:
-
-A loadout system that uses TGUI to equip players post roundstart.
-
-
-### Credits:
-MrMelbert - https://github.com/Jolly-66/JollyStationCode/pull/78 (original code)
-Gandalf2k15 - Porting
diff --git a/modular_skyrat/modules/teshari/code/_teshari.dm b/modular_skyrat/modules/teshari/code/_teshari.dm
index 6fd29811055..39dd33443bf 100644
--- a/modular_skyrat/modules/teshari/code/_teshari.dm
+++ b/modular_skyrat/modules/teshari/code/_teshari.dm
@@ -20,18 +20,18 @@
payday_modifier = 1.0
mutanttongue = /obj/item/organ/internal/tongue/teshari
custom_worn_icons = list(
- LOADOUT_ITEM_HEAD = TESHARI_HEAD_ICON,
- LOADOUT_ITEM_MASK = TESHARI_MASK_ICON,
- LOADOUT_ITEM_NECK = TESHARI_NECK_ICON,
+ OFFSET_HEAD = TESHARI_HEAD_ICON,
+ OFFSET_MASK = TESHARI_MASK_ICON,
+ OFFSET_NECK = TESHARI_NECK_ICON,
LOADOUT_ITEM_SUIT = TESHARI_SUIT_ICON,
LOADOUT_ITEM_UNIFORM = TESHARI_UNIFORM_ICON,
LOADOUT_ITEM_HANDS = TESHARI_HANDS_ICON,
- LOADOUT_ITEM_SHOES = TESHARI_FEET_ICON,
+ OFFSET_SHOES = TESHARI_FEET_ICON,
LOADOUT_ITEM_GLASSES = TESHARI_EYES_ICON,
- LOADOUT_ITEM_BELT = TESHARI_BELT_ICON,
+ OFFSET_BELT = TESHARI_BELT_ICON,
LOADOUT_ITEM_MISC = TESHARI_BACK_ICON,
- LOADOUT_ITEM_ACCESSORY = TESHARI_ACCESSORIES_ICON,
- LOADOUT_ITEM_EARS = TESHARI_EARS_ICON
+ OFFSET_ACCESSORY = TESHARI_ACCESSORIES_ICON,
+ OFFSET_EARS = TESHARI_EARS_ICON
)
coldmod = TESHARI_COLDMOD
heatmod = TESHARI_HEATMOD
diff --git a/modular_skyrat/modules/teshari/code/teshari_bodytype.dm b/modular_skyrat/modules/teshari/code/teshari_bodytype.dm
index 2cd6d1b918d..57a83a48e3e 100644
--- a/modular_skyrat/modules/teshari/code/teshari_bodytype.dm
+++ b/modular_skyrat/modules/teshari/code/teshari_bodytype.dm
@@ -29,12 +29,12 @@
return
// If there isn't even a fallback, use snouted sprites for masks and helmets, but offsetted
- if((item_slot == LOADOUT_ITEM_MASK || item_slot == LOADOUT_ITEM_HEAD) && (item.supports_variations_flags & CLOTHING_SNOUTED_VARIATION))
+ if((item_slot == OFFSET_FACEMASK || item_slot == OFFSET_HEAD) && (item.supports_variations_flags & CLOTHING_SNOUTED_VARIATION))
var/obj/item/bodypart/head/my_head = human_owner.get_bodypart(BODY_ZONE_HEAD)
var/datum/worn_feature_offset/selected_offset
var/human_icon
var/human_icon_state = item.worn_icon_state || item.icon_state
- if(item_slot == LOADOUT_ITEM_HEAD)
+ if(item_slot == OFFSET_HEAD)
human_icon = item.worn_icon_muzzled || SNOUTED_HEAD_FILE
selected_offset = my_head?.worn_head_offset
diff --git a/tgstation.dme b/tgstation.dme
index fbf9f7d6d54..29723ab8fa4 100644
--- a/tgstation.dme
+++ b/tgstation.dme
@@ -438,7 +438,7 @@
#include "code\__DEFINES\~skyrat_defines\lewd_defines.dm"
#include "code\__DEFINES\~skyrat_defines\liquids.dm"
#include "code\__DEFINES\~skyrat_defines\living.dm"
-#include "code\__DEFINES\~skyrat_defines\loadouts.dm"
+#include "code\__DEFINES\~skyrat_defines\loadout.dm"
#include "code\__DEFINES\~skyrat_defines\logging.dm"
#include "code\__DEFINES\~skyrat_defines\manufacturer_strings.dm"
#include "code\__DEFINES\~skyrat_defines\mapping.dm"
@@ -1843,7 +1843,6 @@
#include "code\datums\quirks\neutral_quirks\photographer.dm"
#include "code\datums\quirks\neutral_quirks\pineapple_hater.dm"
#include "code\datums\quirks\neutral_quirks\pineapple_liker.dm"
-#include "code\datums\quirks\neutral_quirks\pride_pin.dm"
#include "code\datums\quirks\neutral_quirks\shifty_eyes.dm"
#include "code\datums\quirks\neutral_quirks\snob.dm"
#include "code\datums\quirks\neutral_quirks\transhumanist.dm"
@@ -3814,7 +3813,6 @@
#include "code\modules\client\preferences\pixel_size.dm"
#include "code\modules\client\preferences\playtime_reward_cloak.dm"
#include "code\modules\client\preferences\preferred_map.dm"
-#include "code\modules\client\preferences\pride_pin.dm"
#include "code\modules\client\preferences\prisoner_crime.dm"
#include "code\modules\client\preferences\prosthetic_limb.dm"
#include "code\modules\client\preferences\prosthetic_organ.dm"
@@ -3850,6 +3848,7 @@
#include "code\modules\client\preferences\migrations\body_type_migration.dm"
#include "code\modules\client\preferences\migrations\convert_to_json_savefile.dm"
#include "code\modules\client\preferences\migrations\legacy_sound_toggles_migration.dm"
+#include "code\modules\client\preferences\migrations\quirk_loadout_migration.dm"
#include "code\modules\client\preferences\migrations\tgui_prefs_migration.dm"
#include "code\modules\client\preferences\migrations\tts_blip_migration.dm"
#include "code\modules\client\preferences\species_features\basic.dm"
@@ -4524,6 +4523,17 @@
#include "code\modules\lighting\lighting_source.dm"
#include "code\modules\lighting\lighting_turf.dm"
#include "code\modules\lighting\static_lighting_area.dm"
+#include "code\modules\loadout\loadout_categories.dm"
+#include "code\modules\loadout\loadout_helpers.dm"
+#include "code\modules\loadout\loadout_items.dm"
+#include "code\modules\loadout\loadout_menu.dm"
+#include "code\modules\loadout\loadout_preference.dm"
+#include "code\modules\loadout\categories\accessories.dm"
+#include "code\modules\loadout\categories\glasses.dm"
+#include "code\modules\loadout\categories\heads.dm"
+#include "code\modules\loadout\categories\inhands.dm"
+#include "code\modules\loadout\categories\neck.dm"
+#include "code\modules\loadout\categories\pocket.dm"
#include "code\modules\logging\log_category.dm"
#include "code\modules\logging\log_entry.dm"
#include "code\modules\logging\log_holder.dm"
@@ -6630,6 +6640,21 @@
#include "modular_skyrat\master_files\code\modules\jobs\job_types\warden.dm"
#include "modular_skyrat\master_files\code\modules\language\_language.dm"
#include "modular_skyrat\master_files\code\modules\language\language_holder.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\accessories.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\belts.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\donator_personal.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\ears.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\glasses.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\gloves.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\heads.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\inhands.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\mask.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\neck.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\pocket.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\shoes.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\suit.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\toys.dm"
+#include "modular_skyrat\master_files\code\modules\loadout\categories\uniform.dm"
#include "modular_skyrat\master_files\code\modules\logging\categories\log_category_debug.dm"
#include "modular_skyrat\master_files\code\modules\logging\categories\log_category_game.dm"
#include "modular_skyrat\master_files\code\modules\logging\categories\log_category_uplink.dm"
@@ -7621,25 +7646,6 @@
#include "modular_skyrat\modules\liquids\code\reagents\reagent_containers.dm"
#include "modular_skyrat\modules\liquids\code\reagents\chemistry\holder.dm"
#include "modular_skyrat\modules\liquids\code\reagents\chemistry\reagents.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\_loadout_datum.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_accessory.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_belts.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_ears.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_glasses.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_gloves.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_heads.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_inhands.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_masks.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_neck.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_pocket.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_shoes.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_suit.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\loadout_datum_toys.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\donator\personal\donator_personal.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\under\donator.dm"
-#include "modular_skyrat\modules\loadouts\loadout_items\under\loadout_datum_under.dm"
-#include "modular_skyrat\modules\loadouts\loadout_ui\loadout_manager.dm"
-#include "modular_skyrat\modules\loadouts\loadout_ui\loadout_outfit_helpers.dm"
#include "modular_skyrat\modules\lorecaster\code\archive_viewer.dm"
#include "modular_skyrat\modules\lorecaster\code\config.dm"
#include "modular_skyrat\modules\lorecaster\code\story_manager.dm"
diff --git a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx
index a366ee881fd..05ce025e4d3 100644
--- a/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx
+++ b/tgui/packages/tgui/interfaces/PreferencesMenu/CharacterPreferenceWindow.tsx
@@ -11,6 +11,7 @@ import { JobsPage } from './JobsPage';
import { LanguagesPage } from './LanguagesMenu';
import { LimbsPage } from './LimbsPage';
// SKYRAT EDIT END
+import { LoadoutPage } from './loadout/index';
import { MainPage } from './MainPage';
import { PageButton } from './PageButton';
import { QuirksPage } from './QuirksPage';
@@ -26,6 +27,7 @@ enum Page {
// SKYRAT EDIT END
Species,
Quirks,
+ Loadout,
}
const CharacterProfiles = (props: {
@@ -95,6 +97,11 @@ export const CharacterPreferenceWindow = (props) => {
case Page.Quirks:
pageContents = ;
break;
+
+ case Page.Loadout:
+ pageContents = ;
+ break;
+
default:
exhaustiveCheck(currentPage);
}
@@ -136,6 +143,16 @@ export const CharacterPreferenceWindow = (props) => {
+
+
+ Loadout
+
+
+
void;
handleOpenSpecies: () => void;
- handleLoadout: () => void; // SKYRAT EDIT ADDITION
handleFood: () => void; // SKYRAT EDIT ADDITION
gender: Gender;
setGender: (gender: Gender) => void;
@@ -82,17 +81,6 @@ const CharacterControls = (props: {
)}
{/* SKYRAT EDIT ADDITION START */}
- {props.handleLoadout && (
-
-
-
- )}