diff --git a/code/__DEFINES/prefs.dm b/code/__DEFINES/prefs.dm
index 4d058b8ac1e..6725d511af1 100644
--- a/code/__DEFINES/prefs.dm
+++ b/code/__DEFINES/prefs.dm
@@ -1,6 +1,22 @@
-#define EQUIP_PREVIEW_LOADOUT 1
-#define EQUIP_PREVIEW_JOB 2
-#define EQUIP_PREVIEW_ALL (EQUIP_PREVIEW_LOADOUT|EQUIP_PREVIEW_JOB)
+// Character Preview Bitflags
+
+/// Will show loadout items
+#define EQUIP_PREVIEW_LOADOUT BITFLAG(0)
+
+/// Will show job items, specific item bitflags will determine if those ones are shown or not
+#define EQUIP_PREVIEW_JOB BITFLAG(1)
+
+/// Will show job hat if true, will hide if this is false or EQUIP_PREVIEW_JOB is false
+#define EQUIP_PREVIEW_JOB_HAT BITFLAG(2)
+
+/// Will show job uniform if true, will hide if this is false or EQUIP_PREVIEW_JOB is false
+#define EQUIP_PREVIEW_JOB_UNIFORM BITFLAG(3)
+
+/// Will show job suit if true, will hide if this is false or EQUIP_PREVIEW_JOB is false
+#define EQUIP_PREVIEW_JOB_SUIT BITFLAG(4)
+
+/// The default EQUIP_PREVIEW bitflag, with this, all character creation items are shown
+#define EQUIP_PREVIEW_ALL (EQUIP_PREVIEW_LOADOUT|EQUIP_PREVIEW_JOB|EQUIP_PREVIEW_JOB_HAT|EQUIP_PREVIEW_JOB_UNIFORM|EQUIP_PREVIEW_JOB_SUIT)
/// External organ. Is a prosthesis with a robo-limb manufacturer.
#define ORGAN_PREF_CYBORG "cyborg"
diff --git a/code/__HELPERS/lists.dm b/code/__HELPERS/lists.dm
index 3ec1cf83641..767f0d5189e 100644
--- a/code/__HELPERS/lists.dm
+++ b/code/__HELPERS/lists.dm
@@ -295,6 +295,22 @@
return L[i+1]
return L[1]
+/// Returns the value after the current value in a key-value pair associated list. If this is the last element, or the element isn't present in the list, it'll return the first value in the list
+/proc/next_in_assoc_list(element, list/our_list)
+ // this is the index we'll use to get the key at the end of the function, which is used to get the value
+ var/index = 1
+
+ // loop through to the list to find where exactly our value element is in the list
+ for(var/i in 1 to length(our_list))
+ if(our_list[our_list[i]] == element)
+ // we've found our value, now we need to check if it's at the end of the list
+ // if not, we can select our index + 1
+ // First element in the list if we're at the end of it, next one otherwise
+ index = ((i == length(our_list)) ? 1 : i + 1)
+ break
+
+ return our_list[our_list[index]]
+
/*
* Sorting
*/
diff --git a/code/game/jobs/job/job.dm b/code/game/jobs/job/job.dm
index 529557a77e8..752b8bed198 100644
--- a/code/game/jobs/job/job.dm
+++ b/code/game/jobs/job/job.dm
@@ -111,7 +111,7 @@
to_chat(H, SPAN_BOLD(SPAN_NOTICE("Your account number is: [account.account_number], your account pin is: [account.remote_access_pin]")))
// overrideable separately so AIs/borgs can have cardborg hats without unneccessary new()/del()
-/datum/job/proc/equip_preview(mob/living/carbon/human/H, var/alt_title, var/faction_override)
+/datum/job/proc/equip_preview(mob/living/carbon/human/H, datum/preferences/prefs, var/alt_title, var/faction_override)
if(faction_override)
var/faction = SSjobs.name_factions[faction_override]
if(faction)
@@ -123,9 +123,33 @@
O.pre_equip(H, TRUE)
O.equip(H, TRUE)
return
+
+ var/pre_hat_ref = H.head ? REF(H.head) : null
+ var/pre_uniform_ref = H.w_uniform ? REF(H.w_uniform) : null
+ var/pre_suit_ref = H.wear_suit ? REF(H.wear_suit) : null
+
pre_equip(H, TRUE)
. = equip(H, TRUE, FALSE, alt_title=alt_title)
+ // slightly hacky, but effectively what we're doing here is checking whether we want this preview mob to actually have the uniform we're putting onto it
+ // if not, we drop it from the inventory into nullspace, and then deleting it
+ // i don't THINK this'll make performance that much worse, considering how much we already do to equip the mob in the first place
+ // the reasoning for the ref checks is that we don't want to delete loadout uniforms, just the job ones, so we need to confirm the before and after
+
+ var/equip_preview_mob = prefs.equip_preview_mob
+
+ if(!(equip_preview_mob & EQUIP_PREVIEW_JOB_HAT) && H.head && REF(H.head) != pre_hat_ref)
+ H.drop_from_inventory(H.head)
+ qdel(H.head)
+
+ if(!(equip_preview_mob & EQUIP_PREVIEW_JOB_UNIFORM) && H.w_uniform && REF(H.w_uniform) != pre_uniform_ref)
+ H.drop_from_inventory(H.w_uniform)
+ qdel(H.w_uniform)
+
+ if(!(equip_preview_mob & EQUIP_PREVIEW_JOB_UNIFORM) && H.wear_suit && REF(H.wear_suit) != pre_suit_ref)
+ H.drop_from_inventory(H.wear_suit)
+ qdel(H.wear_suit)
+
/datum/job/proc/get_access(selected_title)
SHOULD_NOT_SLEEP(TRUE)
diff --git a/code/modules/client/preference_setup/general/03_body.dm b/code/modules/client/preference_setup/general/03_body.dm
index 31a7e5d562c..13a358d4a41 100644
--- a/code/modules/client/preference_setup/general/03_body.dm
+++ b/code/modules/client/preference_setup/general/03_body.dm
@@ -214,8 +214,8 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
if (!pref.disabilities || !islist(pref.disabilities))
pref.disabilities = list()
- if(!pref.bgstate || !(pref.bgstate in pref.bgstate_options))
- pref.bgstate = "000000"
+ if(!pref.bgstate || !(pref.bgstate in list_values(pref.bgstate_options)))
+ pref.bgstate = "plain_black"
/datum/category_item/player_setup_item/general/body/content(var/mob/user)
var/list/out = list()
@@ -283,10 +283,14 @@ var/global/list/valid_bloodtypes = list("A+", "A-", "B+", "B-", "AB+", "AB-", "O
out += "
"
out += "