diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index 84e0d15172..a28cbd1768 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -1,4 +1,11 @@
-
+ /* CAUTION! CAUTION! CAUTION! CAUTION! CAUTION! *\
+ | THIS FILE CONTAINS A SHITTON OF |
+ | CHANGES SPECIFIC TO CITADEL. IF |
+ | YOU'RE FIXING A MERGE CONFLICT |
+ | HERE, PLEASE ASK FOR REVIEW FROM |
+ | ANOTHER MAINTAINER TO ENSURE YOU |
+ | DON'T INTRODUCE REGRESSIONS. |
+ \* */
GLOBAL_LIST_EMPTY(preferences_datums)
@@ -220,6 +227,7 @@ GLOBAL_LIST_EMPTY(preferences_datums)
dat += "Character Settings"
dat += "Character Appearance"
+ dat += "Loadout"
dat += "Game Preferences"
if(!path)
@@ -536,6 +544,49 @@ GLOBAL_LIST_EMPTY(preferences_datums)
*/
dat += ""
+ if(3)
+ if(!gear_tab)
+ gear_tab = GLOB.loadout_items[1]
+ . += "
"
+ . += "| [gear_points] loadout points remaining. \[Clear Loadout\] |
"
+ . += "| You can only choose one item per category, unless it's an item that spawns in your backpack or hands. |
"
+ . += "| "
+ var/firstcat = TRUE
+ for(var/i in GLOB.loadout_items)
+ if(firstcat)
+ firstcat = FALSE
+ else
+ . += " |"
+ if(i == gear_tab)
+ . += " [i] "
+ else
+ . += " [i] "
+ . += " |
"
+ . += "
|
"
+ . += "| [gear_tab] |
"
+ . += "
|
"
+ . += "| Name | "
+ . += "Cost | "
+ . += "Restrictions | "
+ . += "Description |
"
+ for(var/j in GLOB.loadout_items[gear_tab])
+ var/datum/gear/gear = GLOB.loadout_items[gear_tab][j]
+ var/class_link = ""
+ if(gear.type in chosen_gear)
+ class_link = "class='linkOn' href='?_src_=prefs;preference=gear;toggle_gear_path=[j];toggle_gear=0'"
+ else if(gear_points <= 0)
+ class_link = "class='linkOff'"
+ else
+ class_link = "href='?_src_=prefs;preference=gear;toggle_gear_path=[j];toggle_gear=1'"
+ . += "| [j] | "
+ . += "[gear.cost] | "
+ if(islist(gear.restricted_roles))
+ if(gear.restricted_roles.len)
+ . += ""
+ . += gear.restricted_roles.Join(";")
+ . += ""
+ . += " | [gear.description] |
"
+ . += "
"
dat += "
"
if(!IsGuestKey(user.key))
@@ -1618,6 +1669,31 @@ GLOBAL_LIST_EMPTY(preferences_datums)
if (href_list["tab"])
current_tab = text2num(href_list["tab"])
+ if(href_list["preference"] == "gear")
+ if(href_list["clear_loadout"])
+ LAZYCLEARLIST(chosen_gear)
+ gear_points = initial(gear_points)
+ save_preferences()
+ if(href_list["select_category"])
+ for(var/i in GLOB.loadout_items)
+ if(i == href_list["select_category"])
+ gear_tab = i
+ if(href_list["toggle_gear_path"])
+ var/datum/gear/G = GLOB.loadout_items[gear_tab][href_list["toggle_gear_path"]]
+ if(!G)
+ return
+ var/toggle = text2num(href_list["toggle_gear"])
+ if(!toggle && (G.type in chosen_gear))//toggling off and the item effectively is in chosen gear)
+ LAZYREMOVE(chosen_gear, G.type)
+ gear_points += initial(G.cost)
+ else if(toggle && (!(is_type_in_ref_list(G, chosen_gear))))
+ if(!is_loadout_slot_available(G.category))
+ to_chat(user, "You cannot take this loadout, as you've already chosen too many of the same category!")
+ return
+ if(gear_points >= initial(G.cost))
+ LAZYADD(chosen_gear, G.type)
+ gear_points -= initial(G.cost)
+
ShowChoices(user)
return 1
diff --git a/modular_citadel/code/modules/client/loadout/glasses.dm b/modular_citadel/code/modules/client/loadout/glasses.dm
new file mode 100644
index 0000000000..68ba745311
--- /dev/null
+++ b/modular_citadel/code/modules/client/loadout/glasses.dm
@@ -0,0 +1,39 @@
+/datum/gear/cold
+ name = "Cold goggles"
+ category = slot_glasses
+ path = /obj/item/clothing/glasses/cold
+
+/datum/gear/eyepatch
+ name = "Eyepatch"
+ category = slot_glasses
+ path = /obj/item/clothing/glasses/eyepatch
+
+/datum/gear/heat
+ name = "Heat goggles"
+ category = slot_glasses
+ path = /obj/item/clothing/glasses/heat
+
+/datum/gear/hipster
+ name = "Hipster glasses"
+ category = slot_glasses
+ path = /obj/item/clothing/glasses/regular/hipster
+
+/datum/gear/jamjar
+ name = "Jamjar glasses"
+ category = slot_glasses
+ path = /obj/item/clothing/glasses/regular/jamjar
+
+/datum/gear/monocle
+ name = "Monocle"
+ category = slot_glasses
+ path = /obj/item/clothing/glasses/monocle
+
+/datum/gear/orange
+ name = "Orange glasses"
+ category = slot_glasses
+ path = /obj/item/clothing/glasses/orange
+
+/datum/gear/prescription
+ name = "Prescription glasses"
+ category = slot_glasses
+ path = /obj/item/clothing/glasses/regular
diff --git a/modular_citadel/code/modules/client/loadout/hands.dm b/modular_citadel/code/modules/client/loadout/hands.dm
new file mode 100644
index 0000000000..2e8d157e5f
--- /dev/null
+++ b/modular_citadel/code/modules/client/loadout/hands.dm
@@ -0,0 +1,54 @@
+/datum/gear/cane
+ name = "Cane"
+ category = slot_hands
+ path = /obj/item/cane
+
+/datum/gear/cigarettes
+ name = "Cigarette pack"
+ category = slot_hands
+ path = /obj/item/storage/fancy/cigarettes
+
+/datum/gear/dice
+ name = "Dice bag"
+ category = slot_hands
+ path = /obj/item/storage/pill_bottle/dice
+
+/datum/gear/flyswatter
+ name = "Flyswatter"
+ category = slot_hands
+ path = /obj/item/melee/flyswatter
+
+/datum/gear/eightball
+ name = "Magic eightball"
+ category = slot_hands
+ path = /obj/item/toy/eightball
+
+/datum/gear/matches
+ name = "Matchbox"
+ category = slot_hands
+ path = /obj/item/storage/box/matches
+
+/datum/gear/cards
+ name = "Playing cards"
+ category = slot_hands
+ path = /obj/item/toy/cards/deck
+
+/datum/gear/skub
+ name = "Skub"
+ category = slot_hands
+ path = /obj/item/skub
+
+/datum/gear/slapper
+ name = "Slapper"
+ category = slot_hands
+ path = /obj/item/slapper
+
+/datum/gear/carpplushie
+ name = "Space carp plushie"
+ category = slot_hands
+ path = /obj/item/toy/plush/carpplushie
+
+/datum/gear/wallet
+ name = "Wallet"
+ category = slot_hands
+ path = /obj/item/storage/wallet
diff --git a/modular_citadel/code/modules/client/loadout/head.dm b/modular_citadel/code/modules/client/loadout/head.dm
new file mode 100644
index 0000000000..66701903d5
--- /dev/null
+++ b/modular_citadel/code/modules/client/loadout/head.dm
@@ -0,0 +1,39 @@
+/datum/gear/baseball
+ name = "Ballcap"
+ category = slot_head
+ path = /obj/item/clothing/head/soft/mime
+
+/datum/gear/beanie
+ name = "Beanie"
+ category = slot_head
+ path = /obj/item/clothing/head/beanie
+
+/datum/gear/beret
+ name = "Black beret"
+ category = slot_head
+ path = /obj/item/clothing/head/beret/black
+
+/datum/gear/flatcap
+ name = "Flat cap"
+ category = slot_head
+ path = /obj/item/clothing/head/flatcap
+
+/datum/gear/pirate
+ name = "Pirate hat"
+ category = slot_head
+ path = /obj/item/clothing/head/pirate
+
+/datum/gear/rice_hat
+ name = "Rice hat"
+ category = slot_head
+ path = /obj/item/clothing/head/rice_hat
+
+/datum/gear/ushanka
+ name = "Ushanka"
+ category = slot_head
+ path = /obj/item/clothing/head/ushanka
+
+/datum/gear/slime
+ name = "Slime hat"
+ category = slot_head
+ path = /obj/item/clothing/head/collectable/slime
diff --git a/modular_citadel/code/modules/client/loadout/loadout.dm b/modular_citadel/code/modules/client/loadout/loadout.dm
new file mode 100644
index 0000000000..17d04138cc
--- /dev/null
+++ b/modular_citadel/code/modules/client/loadout/loadout.dm
@@ -0,0 +1,30 @@
+// Loadout system. All items are children of /datum/gear. To make a new item, you usually just define a new item like /datum/gear/example
+// then set required vars like name(string), category(slot define, take them from code/__DEFINES/inventory.dm (the lowertext ones) (be sure that there is an entry in
+// slot_to_string(slot) proc in hippiestation/code/_HELPERS/mobs.dm to show the category name in preferences menu) and path (the actual item path).
+// description defaults to the path initial desc, cost defaults to 1 point but if you think your item requires more points, the framework allows that
+// and lastly, restricted_roles list allows you to let someone spawn with certain items only if the job they spawned with is on the list.
+
+GLOBAL_LIST_EMPTY(loadout_items)
+
+/proc/initialize_global_loadout_items()
+ LAZYINITLIST(GLOB.loadout_items)
+ for(var/item in subtypesof(/datum/gear))
+ var/datum/gear/I = new item
+ if(!GLOB.loadout_items[slot_to_string(I.category)])
+ LAZYINITLIST(GLOB.loadout_items[slot_to_string(I.category)])
+ LAZYSET(GLOB.loadout_items[slot_to_string(I.category)], I.name, I)
+
+
+/datum/gear
+ var/name
+ var/category
+ var/description
+ var/path //item-to-spawn path
+ var/cost = 1 //normally, each loadout costs a single point.
+ var/list/restricted_roles
+
+/datum/gear/New()
+ ..()
+ if(!description && path)
+ var/obj/O = path
+ description = initial(O.desc)
diff --git a/modular_citadel/code/modules/client/loadout/mask.dm b/modular_citadel/code/modules/client/loadout/mask.dm
new file mode 100644
index 0000000000..8b13789179
--- /dev/null
+++ b/modular_citadel/code/modules/client/loadout/mask.dm
@@ -0,0 +1 @@
+
diff --git a/modular_citadel/code/modules/client/loadout/neck.dm b/modular_citadel/code/modules/client/loadout/neck.dm
new file mode 100644
index 0000000000..b82e1215a8
--- /dev/null
+++ b/modular_citadel/code/modules/client/loadout/neck.dm
@@ -0,0 +1,85 @@
+/datum/gear/bluetie
+ name = "Blue tie"
+ category = slot_neck
+ path = /obj/item/clothing/neck/tie/blue
+
+/datum/gear/redtie
+ name = "Red tie"
+ category = slot_neck
+ path = /obj/item/clothing/neck/tie/red
+
+/datum/gear/blacktie
+ name = "Black tie"
+ category = slot_neck
+ path = /obj/item/clothing/neck/tie/black
+
+/datum/gear/stethoscope
+ name = "Stethoscope"
+ category = slot_neck
+ path = /obj/item/clothing/neck/stethoscope
+ restricted_roles = list("Medical Doctor", "Chief Medical Officer")
+
+/datum/gear/scarf
+ name = "White scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/scarf
+
+/datum/gear/blackscarf
+ name = "Black scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/scarf/black
+
+/datum/gear/redscarf
+ name = "Red scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/scarf/red
+
+/datum/gear/greenscarf
+ name = "Green scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/scarf/green
+
+/datum/gear/darkbluescarf
+ name = "Dark blue scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/scarf/darkblue
+
+/datum/gear/purplescarf
+ name = "Purple scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/scarf/purple
+
+/datum/gear/yellowscarf
+ name = "Yellow scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/scarf/yellow
+
+/datum/gear/orangescarf
+ name = "Orange scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/scarf/orange
+
+/datum/gear/cyanscarf
+ name = "Cyan scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/scarf/cyan
+
+/datum/gear/stripedredscarf
+ name = "Striped red scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/stripedredscarf
+
+/datum/gear/stripedbluescarf
+ name = "Striped blue scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/stripedbluescarf
+
+/datum/gear/stripedgreenscarf
+ name = "Striped green scarf"
+ category = slot_neck
+ path = /obj/item/clothing/neck/stripedgreenscarf
+
+/datum/gear/headphones
+ name = "Headphones"
+ category = slot_neck
+ path = /obj/item/clothing/ears/headphones
diff --git a/modular_citadel/code/modules/client/loadout/shoes.dm b/modular_citadel/code/modules/client/loadout/shoes.dm
new file mode 100644
index 0000000000..c66cd6c1dd
--- /dev/null
+++ b/modular_citadel/code/modules/client/loadout/shoes.dm
@@ -0,0 +1,4 @@
+/datum/gear/laceup
+ name = "Laceup shoes"
+ category = slot_shoes
+ path = /obj/item/clothing/shoes/laceup
diff --git a/modular_citadel/code/modules/client/preferences.dm b/modular_citadel/code/modules/client/preferences.dm
new file mode 100644
index 0000000000..695d306b34
--- /dev/null
+++ b/modular_citadel/code/modules/client/preferences.dm
@@ -0,0 +1,91 @@
+#define DEFAULT_SLOT_AMT 1
+#define HANDS_SLOT_AMT 2
+#define BACKPACK_SLOT_AMT 3
+
+/datum/preferences
+ var/gear_points = 5
+ var/list/gear_categories
+ var/list/chosen_gear
+ var/gear_tab
+
+/datum/preferences/New(client/C)
+ ..()
+ LAZYINITLIST(chosen_gear)
+
+
+
+/datum/preferences/proc/hippie_dat_replace(current_tab)
+ //This proc is for menus other than game pref and char pref
+ . = ""
+
+ . += "Character Settings "
+ . += "Game Preferences"
+ . += "Loadout"
+
+ if(!path)
+ . += "Please create an account to save your preferences
"
+
+ . += ""
+
+ . += "
"
+ if(current_tab == 2)
+ if(!gear_tab)
+ gear_tab = GLOB.loadout_items[1]
+ . += ""
+ . += "| [gear_points] loadout points remaining. \[Clear Loadout\] |
"
+ . += "| You can only choose one item per category, unless it's an item that spawns in your backpack or hands. |
"
+ . += "| "
+ var/firstcat = TRUE
+ for(var/i in GLOB.loadout_items)
+ if(firstcat)
+ firstcat = FALSE
+ else
+ . += " |"
+ if(i == gear_tab)
+ . += " [i] "
+ else
+ . += " [i] "
+ . += " |
"
+ . += "
|
"
+ . += "| [gear_tab] |
"
+ . += "
|
"
+ . += "| Name | "
+ . += "Cost | "
+ . += "Restrictions | "
+ . += "Description |
"
+ for(var/j in GLOB.loadout_items[gear_tab])
+ var/datum/gear/gear = GLOB.loadout_items[gear_tab][j]
+ var/class_link = ""
+ if(gear.type in chosen_gear)
+ class_link = "class='linkOn' href='?_src_=prefs;preference=gear;toggle_gear_path=[j];toggle_gear=0'"
+ else if(gear_points <= 0)
+ class_link = "class='linkOff'"
+ else
+ class_link = "href='?_src_=prefs;preference=gear;toggle_gear_path=[j];toggle_gear=1'"
+ . += "| [j] | "
+ . += "[gear.cost] | "
+ if(islist(gear.restricted_roles))
+ if(gear.restricted_roles.len)
+ . += ""
+ . += gear.restricted_roles.Join(";")
+ . += ""
+ . += " | [gear.description] |
"
+ . += "
"
+
+/datum/preferences/proc/is_loadout_slot_available(slot)
+ var/list/L
+ LAZYINITLIST(L)
+ for(var/i in chosen_gear)
+ var/datum/gear/G = i
+ var/occupied_slots = L[slot_to_string(initial(G.category))] ? L[slot_to_string(initial(G.category))] + 1 : 1
+ LAZYSET(L, slot_to_string(initial(G.category)), occupied_slots)
+ switch(slot)
+ if(slot_in_backpack)
+ if(L[slot_to_string(slot_in_backpack)] < BACKPACK_SLOT_AMT)
+ return TRUE
+ if(slot_hands)
+ if(L[slot_to_string(slot_hands)] < HANDS_SLOT_AMT)
+ return TRUE
+ else
+ if(L[slot_to_string(slot)] < DEFAULT_SLOT_AMT)
+ return TRUE
diff --git a/modular_citadel/code/modules/client/preferences_savefile.dm b/modular_citadel/code/modules/client/preferences_savefile.dm
new file mode 100644
index 0000000000..700353f3e8
--- /dev/null
+++ b/modular_citadel/code/modules/client/preferences_savefile.dm
@@ -0,0 +1,21 @@
+/datum/preferences/proc/hippie_character_pref_load(savefile/S)
+ //gear loadout
+ var/text_to_load
+ S["loadout"] >> text_to_load
+ var/list/saved_loadout_paths = splittext(text_to_load, "|")
+ LAZYCLEARLIST(chosen_gear)
+ gear_points = initial(gear_points)
+ for(var/i in saved_loadout_paths)
+ var/datum/gear/path = text2path(i)
+ if(path)
+ LAZYADD(chosen_gear, path)
+ gear_points -= initial(path.cost)
+
+/datum/preferences/proc/hippie_character_pref_save(savefile/S)
+ //gear loadout
+ if(islist(chosen_gear))
+ if(chosen_gear.len)
+ var/text_to_save = chosen_gear.Join("|")
+ S["loadout"] << text_to_save
+ else
+ S["loadout"] << "" //empty string to reset the value