diff --git a/code/_helpers/global_lists.dm b/code/_helpers/global_lists.dm
index f455f505b4..1a1eced63a 100644
--- a/code/_helpers/global_lists.dm
+++ b/code/_helpers/global_lists.dm
@@ -51,45 +51,7 @@ var/global/list/facial_hair_styles_male_list = list()
var/global/list/facial_hair_styles_female_list = list()
var/global/list/skin_styles_female_list = list() //unused
//Underwear
-var/global/list/underwear_top_t = list(
- "Bra, Red" = "t1", "Bra, White" = "t2", "Bra, Yellow" = "t3", "Bra, Blue" = "t4", "Bra, Black" = "t5", "Lacy Bra" = "t6", "Sports Bra, Black" = "t7", "Sports Bra, White" = "t8",
- "Sports Bra Alt, Black" = "t9", "Sporta Bra Alt, White" = "t10", "Bra, Baby-Blue" = "t11", "Bra, Green" = "t12", "Bra, Pink" = "t13", "Bra, Violet" = "t14",
- "Lacy Bra Alt" = "t15", "Lacy Bra Alt, Violet" = "t16", "Halterneck Bra, Black" = "t17", "Halterneck Bra, Blue" = "t18", "Halterneck Bra, Green" = "t19", "Halterneck Bra, Purple" = "t20",
- "Halterneck Bra, Red" = "t21", "Halterneck Bra, Teal" = "t22", "Halterneck Bra, Violet" = "t23", "Halterneck Bra, White" = "t24", "None")
-var/global/list/underwear_bottom_t = list(
- "Briefs, White" = "b1", "Briefs, Grey" = "b2", "Briefs, Green" = "b3", "Briefs, Blue" = "b4", "Briefs, Black" = "b5", "Boxers, Loveheart" = "b7", "Boxers, Black" = "b8",
- "Boxers, Grey" = "b9", "Boxers, Green & Blue Striped" = "b10", "Panties, Red" = "b11", "Panties, White" = "b12", "Panties, Yellow" = "b13", "Panties, Blue" = "b14",
- "Panties, Light-Black" = "b15", "Thong" = "b16", "Panties, Black" = "b17", "Panties Alt, White" = "b18", "Compression Shorts, Black" = "b19", "Compression Shorts, White" = "b20",
- "Compression Shorts, Baby-Blue" = "b21", "Panties, Green" = "b22", "Compression Shorts, Pink" = "b23", "Thong, Violet" = "b24", "Thong Alt" = "b25", "Thong Alt, Violet" = "b26",
- "Alt Thong, Black" = "b27", "Alt Thong, Blue" = "b28", "Alt Thong, Green" = "b29", "Alt Thong, Purple" = "b30", "Alt Thong, Red" = "b31", "Alt Thong, Teal" = "b32",
- "Alt Thong, Violet" = "b33", "Alt Thong, White" = "b34", "None")
- //undershirt
-var/global/list/undershirt_t = list(
- "White tank top" = "u1", "Black tank top" = "u2", "Black shirt" = "u3",
- "White shirt" = "u4", "White shirt 2" = "shirt_white_s", "White tank top 2" = "tank_white_s",
- "Black shirt 2" = "shirt_black_s", "Grey shirt" = "shirt_grey_s", "Heart shirt" = "lover_s",
- "I love NT shirt" = "ilovent_s", "White shortsleeve shirt" = "whiteshortsleeve_s", "Purple shortsleeve shirt" = "purpleshortsleeve_s",
- "Blue shortsleeve shirt" = "blueshortsleeve_s", "Green shortsleeve shirt" = "greenshortsleeve_s", "Black shortsleeve shirt" = "blackshortsleeve_s",
- "Blue shirt" = "blueshirt_s", "Red shirt" = "redshirt_s", "Yellow shirt" = "yellowshirt_s", "Green shirt" = "greenshirt_s",
- "Blue polo shirt" = "bluepolo_s", "Red polo shirt" = "redpolo_s", "White polo shirt" = "whitepolo_s",
- "Grey-yellow polo shirt" = "grayyellowpolo_s", "Fire tank top" = "tank_fire_s", "NT shirt" = "shirt_nano_s",
- "Blue shirt 2" = "shirt_blue_s", "Red shirt 2" = "shirt_red_s", "Red tank top" = "tank_red_s", "Green shirt 2" = "shirt_green_s",
- "Tiedye shirt" = "shirt_tiedye_s", "Green sport shirt" = "greenshirtsport_s", "Red sport shirt" = "redshirtsport_s",
- "Blue striped shirt" = "shirt_stripes_s", "Blue sport shirt" = "blueshirtsport_s", "None")
- //Socks
-var/global/list/socks_t = list(
- "White normal" = "white_norm", "White short" = "white_short", "White knee" = "white_knee",
- "White thigh" = "white_thigh", "Black normal" = "black_norm", "Black short" = "black_short",
- "Black knee" = "black_knee", "Black thigh" = "black_thigh", "Thin knee" = "thin_knee",
- "Thin thigh" = "thin_thigh", "Pantyhose" = "pantyhose", "Striped thigh" = "striped_thigh",
- "Striped knee" = "striped_knee", "Rainbow knee" = "rainbow_knee", "Rainbow thigh" = "rainbow_thigh",
- "Fishnets" = "fishnet", "Thin white thigh" = "thinwhite_thigh", "Thin white knee" = "thinwhite_knee",
- "Green striped thigh" = "gstriped_thigh", "Green striped knee" = "gstriped_knee",
- "Purple striped thigh" = "pstriped_thigh", "Purple striped knee" = "pstriped_knee",
- "Blue striped thigh" = "bstriped_thigh", "Blue striped knee" = "bstriped_knee",
- "Yellow striped thigh" = "ystriped_thigh", "Yellow striped knee" = "ystriped_knee",
- "Red striped thigh" = "rstriped_thigh", "Red striped knee" = "rstriped_knee",
- "Orange striped thigh" = "ostriped_thigh", "Orange striped knee" = "ostriped_knee", "None")
+var/datum/category_collection/underwear/global_underwear = new()
//Backpacks
var/global/list/backbaglist = list("Nothing", "Backpack", "Satchel", "Satchel Alt")
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index c631a3435d..3f872f53e6 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -388,10 +388,7 @@
f_style = "Shaved"
if(dna.species == "Human") //no more xenos losing ears/tentacles
h_style = pick("Bedhead", "Bedhead 2", "Bedhead 3")
- undershirt = null
- underwear_top = null
- underwear_bottom = null
- socks = null
+ all_underwear.Cut()
regenerate_icons()
/obj/screen/ling
diff --git a/code/datums/category.dm b/code/datums/category.dm
index 01cbc21386..3bc9640b79 100644
--- a/code/datums/category.dm
+++ b/code/datums/category.dm
@@ -2,17 +2,20 @@
* Category Collection *
**********************/
/datum/category_collection
- var/category_group_type // The type of categories to initialize
- var/list/datum/category_group/categories // The list of initialized categories
+ var/category_group_type // Type of categories to initialize
+ var/list/datum/category_group/categories // List of initialized categories
+ var/list/datum/category_group/categories_by_name // Associative list of initialized categories, keyed by name
/datum/category_collection/New()
..()
categories = new()
+ categories_by_name = new()
for(var/category_type in typesof(category_group_type))
var/datum/category_group/category = category_type
if(initial(category.name))
category = new category(src)
categories += category
+ categories_by_name[category.name] = category
categories = dd_sortedObjectList(categories)
/datum/category_collection/Destroy()
@@ -26,20 +29,23 @@
******************/
/datum/category_group
var/name = ""
- var/category_item_type // The type of items to initialize
- var/list/datum/category_item/items // The list of initialized items
- var/datum/category_collection/collection // The collection this group belongs to
+ var/category_item_type // Type of items to initialize
+ var/list/datum/category_item/items // List of initialized items
+ var/list/datum/category_item/items_by_name // Associative list of initialized items, by name
+ var/datum/category_collection/collection // The collection this group belongs to
/datum/category_group/New(var/datum/category_collection/cc)
..()
collection = cc
items = new()
+ items_by_name = new()
for(var/item_type in typesof(category_item_type))
var/datum/category_item/item = item_type
if(initial(item.name))
item = new item(src)
items += item
+ items_by_name[item.name] = item
// For whatever reason dd_insertObjectList(items, item) doesn't insert in the correct order
// If you change this, confirm that character setup doesn't become completely unordered.
diff --git a/code/datums/underwear/bottom.dm b/code/datums/underwear/bottom.dm
new file mode 100644
index 0000000000..04e2c42622
--- /dev/null
+++ b/code/datums/underwear/bottom.dm
@@ -0,0 +1,145 @@
+/datum/category_item/underwear/bottom/none
+ name = "None"
+ always_last = TRUE
+
+/datum/category_item/underwear/bottom/briefs_white
+ name = "Briefs, white"
+ icon_state = "b1"
+
+/datum/category_item/underwear/bottom/briefs_white/is_default(var/gender)
+ return gender != FEMALE
+
+/datum/category_item/underwear/bottom/briefs_grey
+ name = "Briefs, grey"
+ icon_state = "b2"
+
+/datum/category_item/underwear/bottom/briefs_green
+ name = "Briefs, green"
+ icon_state = "b3"
+
+/datum/category_item/underwear/bottom/briefs_blue
+ name = "Briefs, blue"
+ icon_state = "b4"
+
+/datum/category_item/underwear/bottom/briefs_black
+ name = "Briefs, black"
+ icon_state = "b5"
+
+/datum/category_item/underwear/bottom/panties_noback
+ name = "Panties, noback"
+ icon_state = "b6"
+
+/datum/category_item/underwear/bottom/boxers_loveheart
+ name = "Boxers, Loveheart"
+ icon_state = "b7"
+
+/datum/category_item/underwear/bottom/boxers_black
+ name = "Boxers, black"
+ icon_state = "b8"
+
+/datum/category_item/underwear/bottom/boxers_grey
+ name = "Boxers, grey"
+ icon_state = "b9"
+
+/datum/category_item/underwear/bottom/boxers_green_and_blue
+ name = "Boxers, green & blue striped"
+ icon_state = "b10"
+
+/datum/category_item/underwear/bottom/panties_red
+ name = "Panties, red"
+ icon_state = "b11"
+
+/datum/category_item/underwear/bottom/panties_white
+ name = "Panties, white"
+ icon_state = "b12"
+
+/datum/category_item/underwear/bottom/panties_white/is_default(var/gender)
+ return gender == FEMALE
+
+/datum/category_item/underwear/bottom/panties_yellow
+ name = "Panties, yellow"
+ icon_state = "b13"
+
+/datum/category_item/underwear/bottom/panties_blue
+ name = "Panties, blue"
+ icon_state = "b14"
+
+/datum/category_item/underwear/bottom/panties_light_black
+ name = "Panties, light-black"
+ icon_state = "b15"
+
+/datum/category_item/underwear/bottom/thong
+ name = "Thong"
+ icon_state = "b16"
+
+/datum/category_item/underwear/bottom/panties_black
+ name = "Panties, black"
+ icon_state = "b17"
+
+/datum/category_item/underwear/bottom/panties_white_alt
+ name = "Bra, white alt"
+ icon_state = "b18"
+
+/datum/category_item/underwear/bottom/compression_shorts_black
+ name = "Compression shorts, black"
+ icon_state = "b19"
+
+/datum/category_item/underwear/bottom/compression_shorts_white
+ name = "Compression shorts, white"
+ icon_state = "b20"
+
+/datum/category_item/underwear/bottom/compression_shorts_baby_blue
+ name = "Compression shorts, baby-blue"
+ icon_state = "b21"
+
+/datum/category_item/underwear/bottom/panties_green
+ name = "Panties, green"
+ icon_state = "b22"
+
+/datum/category_item/underwear/bottom/compression_shorts_pink
+ name = "Compression shorts, pink"
+ icon_state = "b23"
+
+/datum/category_item/underwear/bottom/thong_violet
+ name = "Thong, violet"
+ icon_state = "b24"
+
+/datum/category_item/underwear/bottom/thong_alt
+ name = "Thong, alt"
+ icon_state = "b25"
+
+/datum/category_item/underwear/bottom/thong_violet_alt
+ name = "Thong, violet alt"
+ icon_state = "b26"
+
+/datum/category_item/underwear/bottom/alt_thong_black
+ name = "Alt. thong, black"
+ icon_state = "b27"
+
+/datum/category_item/underwear/bottom/alt_thong_blue
+ name = "Alt. thong, blue"
+ icon_state = "b28"
+
+/datum/category_item/underwear/bottom/alt_thong_green
+ name = "Alt. thong, green"
+ icon_state = "b29"
+
+/datum/category_item/underwear/bottom/alt_thong_purple
+ name = "Alt. thong, purple"
+ icon_state = "b30"
+
+/datum/category_item/underwear/bottom/alt_thong_red
+ name = "Alt. thong, red"
+ icon_state = "b31"
+
+/datum/category_item/underwear/bottom/alt_thong_teal
+ name = "Alt. thong, teal"
+ icon_state = "b32"
+
+/datum/category_item/underwear/bottom/alt_thong_violet
+ name = "Alt. thong, violet"
+ icon_state = "b33"
+
+/datum/category_item/underwear/bottom/alt_thong_white
+ name = "Alt. thong, white"
+ icon_state = "b34"
\ No newline at end of file
diff --git a/code/datums/underwear/socks.dm b/code/datums/underwear/socks.dm
new file mode 100644
index 0000000000..ab33162e04
--- /dev/null
+++ b/code/datums/underwear/socks.dm
@@ -0,0 +1,75 @@
+/datum/category_item/underwear/socks/none
+ always_last = TRUE
+ name = "None"
+
+/datum/category_item/underwear/socks/white_normal
+ name = "Normal, white"
+ icon_state = "white_norm"
+
+/datum/category_item/underwear/socks/white_short
+ name = "Short, white"
+ icon_state = "white_short"
+
+/datum/category_item/underwear/socks/white_knee
+ name = "Knee, white"
+ icon_state = "white_knee"
+
+/datum/category_item/underwear/socks/white_thigh
+ name = "Thigh, white"
+ icon_state = "white_thigh"
+
+/datum/category_item/underwear/socks/black_normal
+ name = "Normal, black"
+ icon_state = "black_norm"
+
+/datum/category_item/underwear/socks/black_short
+ name = "Short, black"
+ icon_state = "black_short"
+
+/datum/category_item/underwear/socks/black_knee
+ name = "Knee, black"
+ icon_state = "black_knee"
+
+/datum/category_item/underwear/socks/black_thigh
+ name = "Thigh, black"
+ icon_state = "black_thigh"
+
+/datum/category_item/underwear/socks/thin_knee
+ name = "Knee, thin"
+ icon_state = "thin_knee"
+
+/datum/category_item/underwear/socks/thin_thigh
+ name = "Thigh, thin"
+ icon_state = "thin_thigh"
+
+/datum/category_item/underwear/socks/pantyhose
+ name = "Pantyhose"
+ icon_state = "pantyhose"
+
+/datum/category_item/underwear/socks/striped_thigh
+ name = "Thigh, striped"
+ icon_state = "striped_thigh"
+
+/datum/category_item/underwear/socks/striped_knee
+ name = "Knee, striped"
+ icon_state = "striped_knee"
+
+/datum/category_item/underwear/socks/rainbow_thigh
+ name = "Thigh, rainbow"
+ icon_state = "rainbow_thigh"
+
+/datum/category_item/underwear/socks/rainbow_knee
+ name = "Knee, rainbow"
+ icon_state = "rainbow_knee"
+
+/datum/category_item/underwear/socks/fishnet
+ name = "Fishnet"
+ icon_state = "fishnet"
+
+/datum/category_item/underwear/socks/thinwhite_thigh
+ name = "Thigh, thin white"
+ icon_state = "thinwhite_thigh"
+
+/datum/category_item/underwear/socks/thinwhite_knee
+ name = "Knee, thin white"
+ icon_state = "thinwhite_knee"
\ No newline at end of file
diff --git a/code/datums/underwear/top.dm b/code/datums/underwear/top.dm
new file mode 100644
index 0000000000..4e23a70295
--- /dev/null
+++ b/code/datums/underwear/top.dm
@@ -0,0 +1,106 @@
+/datum/category_item/underwear/top/none
+ name = "None"
+ always_last = TRUE
+
+/datum/category_item/underwear/top/none/is_default(var/gender)
+ return gender != FEMALE
+
+/datum/category_item/underwear/top/bra_red
+ name = "Bra, red"
+ icon_state = "t1"
+
+/datum/category_item/underwear/top/bra_white
+ is_default = TRUE
+ name = "Bra, white"
+ icon_state = "t2"
+
+/datum/category_item/underwear/top/bra_white/is_default(var/gender)
+ return gender == FEMALE
+
+/datum/category_item/underwear/top/bra_yellow
+ name = "Bra, yellow"
+ icon_state = "t3"
+
+/datum/category_item/underwear/top/bra_blue
+ name = "Bra, blue"
+ icon_state = "t4"
+
+/datum/category_item/underwear/top/bra_black
+ name = "Bra, black"
+ icon_state = "t5"
+
+/datum/category_item/underwear/top/lacy_bra
+ name = "Lacy bra"
+ icon_state = "t6"
+
+/datum/category_item/underwear/top/sports_bra_black
+ name = "Sports bra, black"
+ icon_state = "t7"
+
+/datum/category_item/underwear/top/sports_bra_white
+ name = "Sports bra, white"
+ icon_state = "t8"
+
+/datum/category_item/underwear/top/sports_bra_black_alt
+ name = "Sports bra, black alt"
+ icon_state = "t9"
+
+/datum/category_item/underwear/top/sports_bra_white_alt
+ name = "Sports bra, white alt"
+ icon_state = "t10"
+
+/datum/category_item/underwear/top/bra_baby_blue
+ name = "Bra, baby blue"
+ icon_state = "t11"
+
+/datum/category_item/underwear/top/bra_green
+ name = "Bra, green"
+ icon_state = "t12"
+
+/datum/category_item/underwear/top/bra_pink
+ name = "Bra, pink"
+ icon_state = "t13"
+
+/datum/category_item/underwear/top/bra_violet
+ name = "Bra, violet"
+ icon_state = "t14"
+
+/datum/category_item/underwear/top/lacy_bra_alt
+ name = "Lacy bra, alt"
+ icon_state = "t15"
+
+/datum/category_item/underwear/top/bra_lacy_violet
+ name = "Lacy bra, violet"
+ icon_state = "t16"
+
+/datum/category_item/underwear/top/halterneck_bra_black
+ name = "Halterneck bra, black"
+ icon_state = "t17"
+
+/datum/category_item/underwear/top/halterneck_bra_blue
+ name = "Halterneck bra, blue"
+ icon_state = "t18"
+
+/datum/category_item/underwear/top/halterneck_bra_green
+ name = "Halterneck bra, green"
+ icon_state = "t19"
+
+/datum/category_item/underwear/top/halterneck_bra_purple
+ name = "Halterneck bra, purple"
+ icon_state = "t20"
+
+/datum/category_item/underwear/top/halterneck_bra_red
+ name = "Halterneck bra, red"
+ icon_state = "t21"
+
+/datum/category_item/underwear/top/halterneck_bra_teal
+ name = "Halterneck bra, teal"
+ icon_state = "t22"
+
+/datum/category_item/underwear/top/halterneck_bra_violet
+ name = "Halterneck bra, violet"
+ icon_state = "t23"
+
+/datum/category_item/underwear/top/halterneck_bra_white
+ name = "Halterneck bra, white"
+ icon_state = "t24"
\ No newline at end of file
diff --git a/code/datums/underwear/undershirts.dm b/code/datums/underwear/undershirts.dm
new file mode 100644
index 0000000000..f1149dabb7
--- /dev/null
+++ b/code/datums/underwear/undershirts.dm
@@ -0,0 +1,140 @@
+/datum/category_item/underwear/undershirt/none
+ is_default = TRUE
+ name = "None"
+ always_last = TRUE
+
+/datum/category_item/underwear/undershirt/tank_top_white
+ name = "Tank top, white"
+ icon_state = "u1"
+
+/datum/category_item/underwear/undershirt/tank_top_white_alt
+ name = "Tank top, white alt"
+ icon_state = "tank_white_s"
+
+/datum/category_item/underwear/undershirt/tank_top_black
+ name = "Tank top, black"
+ icon_state = "u2"
+
+/datum/category_item/underwear/undershirt/tank_top_red
+ name = "Tank top, red"
+ icon_state = "tank_red_s"
+
+/datum/category_item/underwear/undershirt/tank_top_fire
+ name = "Tank top, fire"
+ icon_state = "tank_fire_s"
+
+/datum/category_item/underwear/undershirt/shirt_black
+ name = "Shirt, black"
+ icon_state = "u3"
+
+/datum/category_item/underwear/undershirt/shirt_black_alt
+ name = "Shirt, black alt"
+ icon_state = "shirt_black_s"
+
+/datum/category_item/underwear/undershirt/shirt_white
+ name = "Shirt, white"
+ icon_state = "u4"
+
+/datum/category_item/underwear/undershirt/shirt_white_alt
+ name = "Shirt, white alt"
+ icon_state = "shirt_white_s"
+
+/datum/category_item/underwear/undershirt/shirt_grey
+ name = "Shirt, grey"
+ icon_state = "shirt_grey_s"
+
+/datum/category_item/underwear/undershirt/shirt_blue
+ name = "Shirt, blue"
+ icon_state = "blueshirt_s"
+
+/datum/category_item/underwear/undershirt/shirt_blue_alt
+ name = "Shirt, blue alt"
+ icon_state = "shirt_blue_s"
+
+/datum/category_item/underwear/undershirt/shirt_red
+ name = "Shirt, red"
+ icon_state = "redshirt_s"
+
+/datum/category_item/underwear/undershirt/shirt_red_alt
+ name = "Shirt, red alt"
+ icon_state = "shirt_red_s"
+
+/datum/category_item/underwear/undershirt/shirt_yellow
+ name = "Shirt, yellow"
+ icon_state = "yellowshirt_s"
+
+/datum/category_item/underwear/undershirt/shirt_green
+ name = "Shirt, green"
+ icon_state = "greenshirt_s"
+
+/datum/category_item/underwear/undershirt/shirt_green_alt
+ name = "Shirt, green alt"
+ icon_state = "shirt_green_s"
+
+/datum/category_item/underwear/undershirt/shirt_heart
+ name = "Shirt, heart"
+ icon_state = "lover_s"
+
+/datum/category_item/underwear/undershirt/shirt_nt
+ name = "Shirt, NT"
+ icon_state = "shirt_nano_s"
+
+/datum/category_item/underwear/undershirt/shirt_love_nt
+ name = "Shirt, I<3NT"
+ icon_state = "lover_s"
+
+/datum/category_item/underwear/undershirt/shortsleeve_shirt_white
+ name = "Shortsleeve shirt, white"
+ icon_state = "whiteshortsleeve_s"
+
+/datum/category_item/underwear/undershirt/shortsleeve_shirt_purple
+ name = "Shortsleeve shirt, purple"
+ icon_state = "purpleshortsleeve_s"
+
+/datum/category_item/underwear/undershirt/shortsleeve_shirt_blue
+ name = "Shortsleeve shirt, blue"
+ icon_state = "blueshortsleeve_s"
+
+/datum/category_item/underwear/undershirt/shortsleeve_shirt_green
+ name = "Shortsleeve shirt, green"
+ icon_state = "greenshortsleeve_s"
+
+/datum/category_item/underwear/undershirt/shortsleeve_shirt_black
+ name = "Shortsleeve shirt, black"
+ icon_state = "blackshortsleeve_s"
+
+/datum/category_item/underwear/undershirt/polo_shirt_blue
+ name = "Polo shirt, blue"
+ icon_state = "bluepolo_s"
+
+/datum/category_item/underwear/undershirt/polo_shirt_red
+ name = "Polo shirt, red"
+ icon_state = "redpolo_s"
+
+/datum/category_item/underwear/undershirt/polo_shirt_white
+ name = "Polo shirt, white"
+ icon_state = "whitepolo_s"
+
+/datum/category_item/underwear/undershirt/polo_shirt_grey_yellow
+ name = "Polo shirt, grey and yellow"
+ icon_state = "grayyellowpolo_s"
+
+/datum/category_item/underwear/undershirt/sport_shirt_green
+ name = "Sport shirt, green"
+ icon_state = "greenshirtsport_s"
+
+/datum/category_item/underwear/undershirt/sport_shirt_red
+ name = "Sport shirt, red"
+ icon_state = "redshirtsport_s"
+
+/datum/category_item/underwear/undershirt/sport_shirt_blue
+ name = "Sport shirt, blue"
+ icon_state = "blueshirtsport_s"
+
+/datum/category_item/underwear/undershirt/shirt_tiedye
+ name = "Shirt, tiedye"
+ icon_state = "shirt_tiedye_s"
+
+/datum/category_item/underwear/undershirt/shirt_blue_striped
+ name = "Shirt, blue stripes"
+ icon_state = "shirt_stripes_s"
\ No newline at end of file
diff --git a/code/datums/underwear/underwear.dm b/code/datums/underwear/underwear.dm
new file mode 100644
index 0000000000..8b73dbddbb
--- /dev/null
+++ b/code/datums/underwear/underwear.dm
@@ -0,0 +1,56 @@
+/****************************
+* Category Collection Setup *
+****************************/
+/datum/category_collection/underwear
+ category_group_type = /datum/category_group/underwear
+
+/*************
+* Categories *
+*************/
+/datum/category_group/underwear
+ var/sort_order // Lower sort order is applied as icons first
+
+datum/category_group/underwear/dd_SortValue()
+ return sort_order
+
+/datum/category_group/underwear/top
+ name = "Underwear, top"
+ sort_order = 1
+ category_item_type = /datum/category_item/underwear/top
+
+/datum/category_group/underwear/bottom
+ name = "Underwear, bottom"
+ sort_order = 2
+ category_item_type = /datum/category_item/underwear/bottom
+
+/datum/category_group/underwear/socks
+ name = "Socks"
+ sort_order = 3
+ category_item_type = /datum/category_item/underwear/socks
+
+/datum/category_group/underwear/undershirt
+ name = "Undershirt"
+ sort_order = 4 // Undershirts currently have the highest sort order because they may cover both underwear and socks.
+ category_item_type = /datum/category_item/underwear/undershirt
+
+/*******************
+* Category entries *
+*******************/
+/datum/category_item/underwear
+ var/always_last = FALSE // Should this entry be sorte last?
+ var/is_default = FALSE // Should this entry be considered the default for its type?
+ var/icon = 'icons/mob/human.dmi' // Which icon to get the underwear from
+ var/icon_state // And the particular item state
+
+/datum/category_item/underwear/dd_SortValue()
+ if(always_last)
+ return "~"+name
+ return name
+
+/datum/category_item/underwear/proc/is_default(var/gender)
+ return is_default
+
+/datum/category_item/underwear/proc/apply_to_icon(var/icon/I)
+ if(!icon_state)
+ return
+ I.Blend(new /icon('icons/mob/human.dmi', icon_state), ICON_OVERLAY)
\ No newline at end of file
diff --git a/code/game/gamemodes/cult/runes.dm b/code/game/gamemodes/cult/runes.dm
index 37445326ca..3cb41cc872 100644
--- a/code/game/gamemodes/cult/runes.dm
+++ b/code/game/gamemodes/cult/runes.dm
@@ -470,8 +470,7 @@ var/list/sacrificed = list()
D.r_eyes = 200
D.g_eyes = 200
D.update_eyes()
- D.underwear_top = 0
- D.underwear_bottom = 0
+ D.all_underwear.Cut()
D.key = ghost.key
cult.add_antagonist(D.mind)
diff --git a/code/game/objects/structures/under_wardrobe.dm b/code/game/objects/structures/under_wardrobe.dm
index a02c67c968..2ded3ef17e 100644
--- a/code/game/objects/structures/under_wardrobe.dm
+++ b/code/game/objects/structures/under_wardrobe.dm
@@ -5,39 +5,51 @@
icon_state = "cabinet_closed"
density = 1
-/obj/structure/undies_wardrobe/attack_hand(mob/user as mob)
- src.add_fingerprint(user)
- var/mob/living/carbon/human/H = user
- if(!ishuman(user) || (H.species && !(H.species.appearance_flags & HAS_UNDERWEAR)))
+/obj/structure/undies_wardrobe/attack_hand(var/mob/user)
+ if(!human_who_can_use_underwear(user))
user << "Sadly there's nothing in here for you to wear."
- return 0
+ return
+ interact(user)
- var/utype = alert("Which section do you want to pick from?",,"Underwear", "Undershirts", "Socks",)
- var/list/selection
- switch(utype)
- if("Underwear")
- utype = alert("Which section do you want to pick from?",, "Top", "Bottom",)
- switch(utype)
- if("Top")
- selection = underwear_top_t
- if("Bottom")
- selection = underwear_bottom_t
- if("Undershirts")
- selection = undershirt_t
- if("Socks")
- selection = socks_t
- var/pick = input("Select the style") as null|anything in selection
- if(pick)
- if(get_dist(src,user) > 1)
+/obj/structure/undies_wardrobe/interact(var/mob/living/carbon/human/H)
+ var/dat = list()
+ dat += "Underwear:
"
+ for(var/datum/category_group/underwear/UWC in global_underwear.categories)
+ var/datum/category_item/underwear/UWI = H.all_underwear[UWC.name]
+ var/item_name = UWI ? UWI.name : "None"
+ dat += "[UWC.name]: [item_name] (Remove)
"
+
+ dat = jointext(dat)
+ H << browse(dat, "window=wardrobe;size=400x200")
+
+/obj/structure/undies_wardrobe/proc/human_who_can_use_underwear(var/mob/living/carbon/human/H)
+ if(!istype(H) || !H.species || !(H.species.appearance_flags & HAS_UNDERWEAR))
+ return FALSE
+ return TRUE
+
+/obj/structure/undies_wardrobe/CanUseTopic(var/user)
+ if(!human_who_can_use_underwear(user))
+ return STATUS_CLOSE
+
+ return ..()
+
+/obj/structure/undies_wardrobe/Topic(href, href_list, state)
+ if(..())
+ return TRUE
+
+ var/mob/living/carbon/human/H = usr
+ if(href_list["remove_underwear"])
+ if(href_list["remove_underwear"] in H.all_underwear)
+ H.all_underwear -= href_list["remove_underwear"]
+ . = TRUE
+ else if(href_list["change_underwear"])
+ var/datum/category_group/underwear/UWC = global_underwear.categories_by_name[href_list["change_underwear"]]
+ if(!UWC)
return
- if(utype == "Undershirts")
- H.undershirt = selection[pick]
- else if(utype == "Socks")
- H.socks = selection[pick]
- else if(utype == "Top")
- H.underwear_top = selection[pick]
- else
- H.underwear_bottom = selection[pick]
+ var/datum/category_item/underwear/selected_underwear = input(H, "Choose underwear:", "Choose underwear", H.all_underwear[UWC.name]) as null|anything in UWC.items
+ if(selected_underwear && CanUseTopic(H, default_state))
+ H.all_underwear[UWC.name] = selected_underwear
+ . = TRUE
+ if(.)
H.update_body(1)
-
- return 1
\ No newline at end of file
+ interact(H)
\ No newline at end of file
diff --git a/code/modules/client/preference_setup/general/04_equipment.dm b/code/modules/client/preference_setup/general/04_equipment.dm
index 68e5eb9d31..b7758a6fa9 100644
--- a/code/modules/client/preference_setup/general/04_equipment.dm
+++ b/code/modules/client/preference_setup/general/04_equipment.dm
@@ -1,82 +1,57 @@
+/datum/preferences
+ var/list/all_underwear
+
/datum/category_item/player_setup_item/general/equipment
name = "Clothing"
sort_order = 4
/datum/category_item/player_setup_item/general/equipment/load_character(var/savefile/S)
- S["underwear_top"] >> pref.underwear_top
- S["underwear_bottom"] >> pref.underwear_bottom
- S["undershirt"] >> pref.undershirt
- S["socks"] >> pref.socks
+ S["all_underwear"] >> pref.all_underwear
S["backbag"] >> pref.backbag
S["pdachoice"] >> pref.pdachoice
/datum/category_item/player_setup_item/general/equipment/save_character(var/savefile/S)
- S["underwear_top"] << pref.underwear_top
- S["underwear_bottom"] << pref.underwear_bottom
- S["undershirt"] << pref.undershirt
- S["socks"] << pref.socks
+ S["all_underwear"] << pref.all_underwear
S["backbag"] << pref.backbag
S["pdachoice"] << pref.pdachoice
/datum/category_item/player_setup_item/general/equipment/sanitize_character()
+ if(!islist(pref.gear)) pref.gear = list()
+
+ if(!istype(pref.all_underwear))
+ pref.all_underwear = list()
+
+ for(var/datum/category_group/underwear/WRC in global_underwear.categories)
+ for(var/datum/category_item/underwear/WRI in WRC.items)
+ if(WRI.is_default(pref.identifying_gender ? pref.identifying_gender : MALE))
+ pref.all_underwear[WRC.name] = WRI.name
+ break
+
+ for(var/underwear_category in pref.all_underwear)
+ var/datum/category_group/underwear/UWC = global_underwear.categories_by_name[underwear_category]
+ if(!UWC)
+ pref.all_underwear -= UWC
+ else
+ var/datum/category_item/underwear/UWI = UWC.items_by_name[pref.all_underwear[underwear_category]]
+ if(!UWI)
+ pref.all_underwear -= UWC
+
pref.backbag = sanitize_integer(pref.backbag, 1, backbaglist.len, initial(pref.backbag))
pref.pdachoice = sanitize_integer(pref.pdachoice, 1, pdachoicelist.len, initial(pref.pdachoice))
- if(!islist(pref.gear)) pref.gear = list()
-
- var/undies_top = get_undies_top()
- var/undies_bottom = get_undies_bottom()
- if(!get_key_by_value(undies_top, pref.underwear_top))
- pref.underwear_top = undies_top[1]
- if(!get_key_by_value(undies_bottom, pref.underwear_bottom))
- pref.underwear_bottom = undies_bottom[1]
- if(!get_key_by_value(undershirt_t, pref.undershirt))
- pref.undershirt = undershirt_t[1]
- if(!get_key_by_value(socks_t, pref.socks))
- pref.socks = socks_t[1]
-
/datum/category_item/player_setup_item/general/equipment/content()
+ . = list()
. += "Equipment:
"
- . += "Underwear Top: [get_key_by_value(get_undies_top(),pref.underwear_top)]
"
- . += "Underwear Bottom: [get_key_by_value(get_undies_bottom(),pref.underwear_bottom)]
"
- . += "Undershirt: [get_key_by_value(undershirt_t,pref.undershirt)]
"
- . += "Socks: [get_key_by_value(socks_t,pref.socks)]
"
+ for(var/datum/category_group/underwear/UWC in global_underwear.categories)
+ var/item_name = pref.all_underwear[UWC.name] ? pref.all_underwear[UWC.name] : "None"
+ . += "[UWC.name]: [item_name]
"
. += "Backpack Type: [backbaglist[pref.backbag]]
"
. += "PDA Type: [pdachoicelist[pref.pdachoice]]
"
-/datum/category_item/player_setup_item/general/equipment/proc/get_undies_top()
- return underwear_top_t
-/datum/category_item/player_setup_item/general/equipment/proc/get_undies_bottom()
- return underwear_bottom_t
+ return jointext(.)
/datum/category_item/player_setup_item/general/equipment/OnTopic(var/href,var/list/href_list, var/mob/user)
- if(href_list["change_underwear_top"])
- var/underwear_top_options = get_undies_top()
- var/new_underwear_top = input(user, "Choose your character's top underwear:", "Character Preference", get_key_by_value(get_undies_top(),pref.underwear_top)) as null|anything in underwear_top_options
- if(!isnull(new_underwear_top) && CanUseTopic(user))
- pref.underwear_top = underwear_top_options[new_underwear_top]
- return TOPIC_REFRESH_UPDATE_PREVIEW
-
- else if(href_list["change_underwear_bottom"])
- var/underwear_bottom_options = get_undies_bottom()
- var/new_underwear_bottom = input(user, "Choose your character's bottom underwear:", "Character Preference", get_key_by_value(get_undies_bottom(),pref.underwear_bottom)) as null|anything in underwear_bottom_options
- if(!isnull(new_underwear_bottom) && CanUseTopic(user))
- pref.underwear_bottom = underwear_bottom_options[new_underwear_bottom]
- return TOPIC_REFRESH_UPDATE_PREVIEW
-
- else if(href_list["change_undershirt"])
- var/new_undershirt = input(user, "Choose your character's undershirt:", "Character Preference", get_key_by_value(undershirt_t,pref.undershirt)) as null|anything in undershirt_t
- if(!isnull(new_undershirt) && CanUseTopic(user))
- pref.undershirt = undershirt_t[new_undershirt]
- return TOPIC_REFRESH_UPDATE_PREVIEW
-
- else if(href_list["change_socks"])
- var/new_socks = input(user, "Choose your character's socks:", "Character Preference", get_key_by_value(socks_t,pref.socks)) as null|anything in socks_t
- if(!isnull(new_socks) && CanUseTopic(user))
- pref.socks = socks_t[new_socks]
- return TOPIC_REFRESH_UPDATE_PREVIEW
-
- else if(href_list["change_backpack"])
+ if(href_list["change_backpack"])
var/new_backbag = input(user, "Choose your character's style of bag:", "Character Preference", backbaglist[pref.backbag]) as null|anything in backbaglist
if(!isnull(new_backbag) && CanUseTopic(user))
pref.backbag = backbaglist.Find(new_backbag)
@@ -87,4 +62,14 @@
if(!isnull(new_pdachoice) && CanUseTopic(user))
pref.pdachoice = pdachoicelist.Find(new_pdachoice)
return TOPIC_REFRESH
- return ..()
+
+ else if(href_list["change_underwear"])
+ var/datum/category_group/underwear/UWC = global_underwear.categories_by_name[href_list["change_underwear"]]
+ if(!UWC)
+ return
+ var/datum/category_item/underwear/selected_underwear = input(user, "Choose underwear:", "Character Preference", pref.all_underwear[UWC.name]) as null|anything in UWC.items
+ if(selected_underwear && CanUseTopic(user))
+ pref.all_underwear[UWC.name] = selected_underwear.name
+ return TOPIC_REFRESH_UPDATE_PREVIEW
+
+ return ..()
\ No newline at end of file
diff --git a/code/modules/client/preference_setup/loadout/loadout.dm b/code/modules/client/preference_setup/loadout/loadout.dm
index cb0b31ba28..dd494b03bc 100644
--- a/code/modules/client/preference_setup/loadout/loadout.dm
+++ b/code/modules/client/preference_setup/loadout/loadout.dm
@@ -63,6 +63,8 @@ var/list/gear_datums = list()
return valid_gear_choices
/datum/category_item/player_setup_item/loadout/sanitize_character()
+ if(!islist(pref.gear))
+ pref.gear = list()
for(var/gear_name in pref.gear)
if(!(gear_name in gear_datums))
diff --git a/code/modules/client/preferences.dm b/code/modules/client/preferences.dm
index f133466a19..d72cb29a08 100644
--- a/code/modules/client/preferences.dm
+++ b/code/modules/client/preferences.dm
@@ -28,10 +28,6 @@ datum/preferences
var/age = 30 //age of character
var/spawnpoint = "Arrivals Shuttle" //where this character will spawn (0-2).
var/b_type = "A+" //blood type (not-chooseable)
- var/underwear_top
- var/underwear_bottom
- var/undershirt //undershirt type
- var/socks //socks type
var/backbag = 2 //backpack type
var/pdachoice = 1 //PDA type
var/h_style = "Bald" //Hair type
@@ -347,10 +343,11 @@ datum/preferences
else if(status == "mechanical")
I.robotize()
- character.underwear_bottom = underwear_bottom
- character.underwear_top = underwear_top
- character.undershirt = undershirt
- character.socks = socks
+ character.all_underwear.Cut()
+ for(var/underwear_category_name in all_underwear)
+ var/underwear_item_name = all_underwear[underwear_category_name]
+ var/datum/category_group/underwear/underwear_category = global_underwear.categories_by_name[underwear_category_name]
+ character.all_underwear[underwear_category_name] = underwear_category.items_by_name[underwear_item_name]
if(backbag > 4 || backbag < 1)
backbag = 1 //Same as above
diff --git a/code/modules/mob/living/carbon/human/human_defines.dm b/code/modules/mob/living/carbon/human/human_defines.dm
index 5a9d384602..cec1328f73 100644
--- a/code/modules/mob/living/carbon/human/human_defines.dm
+++ b/code/modules/mob/living/carbon/human/human_defines.dm
@@ -33,10 +33,7 @@
var/b_type = "A+" //Player's bloodtype
var/synthetic //If they are a synthetic (aka synthetic torso)
- var/underwear_top = 1 //Which underwear the player wants
- var/underwear_bottom = 1
- var/undershirt = 0 //Which undershirt the player wants.
- var/socks = 0 //Which socks the player wants.
+ var/list/all_underwear = list()
var/backbag = 2 //Which backpack type the player has chosen. Nothing, Satchel or Backpack.
var/pdachoice = 1 //Which PDA type the player has chosen. Default, Slim, or Old.
diff --git a/code/modules/mob/living/carbon/human/update_icons.dm b/code/modules/mob/living/carbon/human/update_icons.dm
index 64a50e2696..5f28fbf0e8 100644
--- a/code/modules/mob/living/carbon/human/update_icons.dm
+++ b/code/modules/mob/living/carbon/human/update_icons.dm
@@ -319,16 +319,10 @@ var/global/list/damage_icon_parts = list()
stand_icon.Blend(base_icon,ICON_OVERLAY)
//Underwear
- if(underwear_top && species.appearance_flags & HAS_UNDERWEAR)
- stand_icon.Blend(new /icon('icons/mob/human.dmi', underwear_top), ICON_OVERLAY)
- if(underwear_bottom && species.appearance_flags & HAS_UNDERWEAR)
- stand_icon.Blend(new /icon('icons/mob/human.dmi', underwear_bottom), ICON_OVERLAY)
-
- if(undershirt && species.appearance_flags & HAS_UNDERWEAR)
- stand_icon.Blend(new /icon('icons/mob/human.dmi', undershirt), ICON_OVERLAY)
-
- if(socks && species.appearance_flags & HAS_UNDERWEAR)
- stand_icon.Blend(new /icon('icons/mob/human.dmi', socks), ICON_OVERLAY)
+ if(species.appearance_flags & HAS_UNDERWEAR)
+ for(var/category in all_underwear)
+ var/datum/category_item/underwear/UW = all_underwear[category]
+ UW.apply_to_icon(stand_icon)
if(update_icons)
update_icons()
diff --git a/code/modules/mob/new_player/preferences_setup.dm b/code/modules/mob/new_player/preferences_setup.dm
index 9167c284a3..527ad8b70b 100644
--- a/code/modules/mob/new_player/preferences_setup.dm
+++ b/code/modules/mob/new_player/preferences_setup.dm
@@ -15,11 +15,6 @@
b_skin = rand (0,255)
if(current_species.appearance_flags & HAS_EYE_COLOR)
randomize_eyes_color()
- if(current_species.appearance_flags & HAS_UNDERWEAR)
- underwear_top = underwear_top_t[pick(underwear_top_t)]
- underwear_bottom = underwear_bottom_t[pick(underwear_bottom_t)]
- undershirt = undershirt_t[pick(undershirt_t)]
- socks = socks_t[pick(socks_t)]
if(current_species.appearance_flags & HAS_HAIR_COLOR)
randomize_hair_color("hair")
randomize_hair_color("facial")
@@ -27,6 +22,11 @@
r_skin = rand (0,255)
g_skin = rand (0,255)
b_skin = rand (0,255)
+ if(current_species.appearance_flags & HAS_UNDERWEAR)
+ all_underwear.Cut()
+ for(var/datum/category_group/underwear/WRC in global_underwear.categories)
+ var/datum/category_item/underwear/WRI = pick(WRC.items)
+ all_underwear[WRC.name] = WRI.name
backbag = rand(1,4)
diff --git a/polaris.dme b/polaris.dme
index c09bd6af43..60a5004565 100644
--- a/polaris.dme
+++ b/polaris.dme
@@ -186,6 +186,11 @@
#include "code\datums\repositories\cameras.dm"
#include "code\datums\repositories\crew.dm"
#include "code\datums\repositories\repository.dm"
+#include "code\datums\underwear\bottom.dm"
+#include "code\datums\underwear\socks.dm"
+#include "code\datums\underwear\top.dm"
+#include "code\datums\underwear\undershirts.dm"
+#include "code\datums\underwear\underwear.dm"
#include "code\datums\uplink\ammunition.dm"
#include "code\datums\uplink\announcements.dm"
#include "code\datums\uplink\armor.dm"