Skip to content
6 changes: 5 additions & 1 deletion code/__DEFINES/inventory.dm
Original file line number Diff line number Diff line change
Expand Up @@ -64,7 +64,11 @@
#define ITEM_SLOT_LEGCUFFED (1<<18)

/// Total amount of slots
#define SLOTS_AMT 19 // Keep this up to date!
// META EDIT - CHANGE - START - UNDERWEAR_ITEMS
// Bumped from 19 to 23 for the new ITEM_SLOT_UNDERWEAR/BRA/UNDERSHIRT/SOCKS bits, defined in
// code/__DEFINES/~~zzmeta_defines/underwear.dm (needed early by this file's own consumers).
#define SLOTS_AMT 23 // Keep this up to date!
// META EDIT - CHANGE - END - UNDERWEAR_ITEMS

///Inventory slots that can be blacklisted by a species from being equipped into
DEFINE_BITFIELD(no_equip_flags, list(
Expand Down
6 changes: 5 additions & 1 deletion code/__DEFINES/mobs.dm
Original file line number Diff line number Diff line change
Expand Up @@ -908,7 +908,11 @@ GLOBAL_LIST_INIT(human_heights_to_offsets, list(
/// Total number of standing overlays.
/// KEEP THIS UP-TO-DATE OR SHIT WILL BREAK.
/// (You ONLY need to update this if you add a standing overlay, adding an integer.)
#define TOTAL_LAYERS 29
// META EDIT - CHANGE - START - UNDERWEAR_ITEMS
// Bumped from 29 to 33 to make room for the four new underwear-category overlays_standing
// slots added in modular_zzmeta/code/modules/mob/living/carbon/human/human_underwear_icons.dm.
#define TOTAL_LAYERS 33
// META EDIT - CHANGE - END - UNDERWEAR_ITEMS

#define UPPER_BODY "upper body"
#define LOWER_BODY "lower body"
Expand Down
2 changes: 0 additions & 2 deletions code/__DEFINES/~~bubber_defines/signals.dm
Original file line number Diff line number Diff line change
Expand Up @@ -26,8 +26,6 @@
#define COMSIG_VENTCRAWL_PRE_CANCEL "ventcrawling_pre_cancel"
/// From /mob/proc/equip_to_slot_if_possible()
#define COMSIG_MOB_POST_EQUIP "mob_post_equip"
/// From /mob/living/carbon/human/verb/toggle_undies()
#define COMSIG_HUMAN_TOGGLE_UNDERWEAR "human_toggle_undies"
/// From /obj/item/restraints/handcuffs/proc/apply_cuffs()
#define COMSIG_MOB_HANDCUFFED "mob_handcuffed"
/// From /datum/bodypart_overlay/simple/emote/Destroy() - Calls when an emote that applies a temporary visual effect expires
Expand Down
12 changes: 12 additions & 0 deletions code/__DEFINES/~~zzmeta_defines/underwear.dm
Original file line number Diff line number Diff line change
@@ -0,0 +1,12 @@
// Underwear/bra/undershirt/socks item slots. Needed early by core code/modules/mob/living/carbon/human/inventory.dm
// and code/datums/outfit.dm, so these can't live in a normally-late-compiling modular_zzmeta file.
#define ITEM_SLOT_UNDERWEAR (1<<19)
#define ITEM_SLOT_BRA (1<<20)
#define ITEM_SLOT_UNDERSHIRT (1<<21)
#define ITEM_SLOT_SOCKS (1<<22)

// Strip menu keys for the same four slots. Needed early by core code/modules/mob/living/carbon/human/human_stripping.dm.
#define STRIPPABLE_ITEM_UNDERWEAR "underwear"
#define STRIPPABLE_ITEM_BRA "bra"
#define STRIPPABLE_ITEM_UNDERSHIRT "undershirt"
#define STRIPPABLE_ITEM_SOCKS "socks"
5 changes: 1 addition & 4 deletions code/__HELPERS/dynamic_human_icon_gen.dm
Original file line number Diff line number Diff line change
Expand Up @@ -14,10 +14,7 @@ GLOBAL_LIST_EMPTY(dynamic_human_appearances)
var/mob/living/carbon/human/dummy/consistent/dummy = new()
dummy.set_species(species_path)
dummy.stat = DEAD //this is to avoid side effects of mob spawners
dummy.underwear = "Nude"
dummy.undershirt = "Nude"
dummy.socks = "Nude"
dummy.bra = "Nude" // SKYRAT EDIT ADDITION - Underwear and bra split
// META EDIT - REMOVAL - UNDERWEAR_ITEMS: a freshly created dummy has no underwear items equipped, no reset needed
dummy.set_combat_mode(combat_mode)
if(outfit_path)
var/datum/outfit/outfit = new outfit_path()
Expand Down
5 changes: 4 additions & 1 deletion code/datums/elements/strippable.dm
Original file line number Diff line number Diff line change
Expand Up @@ -388,7 +388,10 @@

LAZYINITLIST(result)

result["icon"] = icon2base64(icon(item.icon, item.icon_state, frame = 1))
// META EDIT - CHANGE - START - UNDERWEAR_ITEMS
// dir = SOUTH added: without it, items whose ground icon has dirs > 1 render all directions at once.
result["icon"] = icon2base64(icon(item.icon, item.icon_state, dir = SOUTH, frame = 1))
// META EDIT - CHANGE - END - UNDERWEAR_ITEMS
result["name"] = item.name
result["alternate"] = item_data.get_alternate_actions(owner, user, item)
list_clear_nulls(result["alternate"])
Expand Down
5 changes: 1 addition & 4 deletions code/datums/martial/plasma_fist.dm
Original file line number Diff line number Diff line change
Expand Up @@ -109,10 +109,7 @@
human_attacker.set_species(/datum/species/plasmaman)
human_attacker.add_traits(list(TRAIT_FORCED_STANDING, TRAIT_BOMBIMMUNE), type)
human_attacker.unequip_everything()
human_attacker.underwear = "Nude"
human_attacker.undershirt = "Nude"
human_attacker.socks = "Nude"
human_attacker.bra = "Nude" // SKYRAT EDIT ADDITION - Underwear and bra split
human_attacker.remove_all_underwear_items() // META EDIT - CHANGE - UNDERWEAR_ITEMS
human_attacker.update_body()

var/turf/boomspot = get_turf(user)
Expand Down
21 changes: 12 additions & 9 deletions code/datums/outfit.dm
Original file line number Diff line number Diff line change
Expand Up @@ -124,10 +124,12 @@
///Should we preload some of this job's items?
var/preload = FALSE

/// Any undershirt. While on humans it is a string, here we use paths to stay consistent with the rest of the equips.
var/datum/sprite_accessory/clothing/undershirt = null
var/datum/sprite_accessory/clothing/underwear = null
var/datum/sprite_accessory/clothing/socks = null
// META EDIT - CHANGE - START - UNDERWEAR_ITEMS
// Was typed as /datum/sprite_accessory/clothing/* (cosmetic-only). These are now real items.
var/obj/item/clothing/underwear/undershirt/undershirt = null
var/obj/item/clothing/underwear/underwear/underwear = null
var/obj/item/clothing/underwear/socks/socks = null
// META EDIT - CHANGE - END - UNDERWEAR_ITEMS

/**
* Called at the start of the equip proc
Expand Down Expand Up @@ -218,19 +220,20 @@
if(suit_store)
EQUIP_OUTFIT_ITEM(suit_store, ITEM_SLOT_SUITSTORE)

// META EDIT - CHANGE - START - UNDERWEAR_ITEMS
if(undershirt)
user.undershirt = initial(undershirt.name)
EQUIP_OUTFIT_ITEM(undershirt, ITEM_SLOT_UNDERSHIRT)

if(underwear)
user.underwear = initial(underwear.name)
EQUIP_OUTFIT_ITEM(underwear, ITEM_SLOT_UNDERWEAR)

if(socks)
user.socks = initial(socks.name)

EQUIP_OUTFIT_ITEM(socks, ITEM_SLOT_SOCKS)
// META EDIT - CHANGE - END - UNDERWEAR_ITEMS

// SKYRAT EDIT ADDITION START - Underwear and bra split
if(bra)
user.bra = initial(bra.name)
EQUIP_OUTFIT_ITEM(bra, ITEM_SLOT_BRA) // META EDIT - CHANGE - UNDERWEAR_ITEMS
// SKYRAT EDIT END

if(accessory)
Expand Down
86 changes: 53 additions & 33 deletions code/game/objects/structures/dresser.dm
Original file line number Diff line number Diff line change
@@ -1,6 +1,6 @@
//THIS FILE HAS BEEN EDITED BY SKYRAT EDIT

/obj/structure/dresser//SKYRAT EDIT - ICON OVERRIDDEN BY AESTHETICS - SEE MODULE
// META EDIT - CHANGE - START - UNDERWEAR_ITEMS
// Real storage now (composition via create_storage(), not /obj/structure/closet since this type's placed on many maps and can't be reparented), stocked with one of each real underwear item.
/obj/structure/dresser
name = "dresser"
desc = "A nicely-crafted wooden dresser. It's filled with lots of undies."
icon = 'icons/obj/fluff/general.dmi'
Expand All @@ -10,10 +10,22 @@
anchored = TRUE
custom_materials = list(/datum/material/wood = SHEET_MATERIAL_AMOUNT * 10)

/obj/structure/dresser/attackby(obj/item/I, mob/user, list/modifiers, list/attack_modifiers)
if(I.tool_behaviour == TOOL_WRENCH)
/obj/structure/dresser/Initialize(mapload)
. = ..()
create_storage(max_slots = 28)
if(mapload)
PopulateContents()

/obj/structure/dresser/proc/PopulateContents()
new /obj/item/clothing/underwear/underwear/male_briefs(src)
new /obj/item/clothing/underwear/bra/bra(src)
new /obj/item/clothing/underwear/undershirt/shirt_white(src)
new /obj/item/clothing/underwear/socks/socks_norm(src)

/obj/structure/dresser/attackby(obj/item/attacking_item, mob/user, list/modifiers, list/attack_modifiers)
if(attacking_item.tool_behaviour == TOOL_WRENCH)
to_chat(user, span_notice("You begin to [anchored ? "unwrench" : "wrench"] [src]."))
if(I.use_tool(src, user, 20, volume=50))
if(attacking_item.use_tool(src, user, 20, volume = 50))
to_chat(user, span_notice("You successfully [anchored ? "unwrench" : "wrench"] [src]."))
set_anchored(!anchored)
else
Expand All @@ -22,11 +34,12 @@
/obj/structure/dresser/atom_deconstruct(disassembled = TRUE)
new /obj/item/stack/sheet/mineral/wood(drop_location(), 10)

// META EDIT - ADDITION - UNDERWEAR_ITEMS: restores the old quick-pick menu as a convenience; runs only when create_storage()'s own attack_hand handler (storage.dm) declines. Spawns+equips real items instead of setting string vars.
/obj/structure/dresser/attack_hand(mob/user, list/modifiers)
. = ..()
if(.)
return
if(!Adjacent(user))//no tele-grooming
if(!Adjacent(user))
return
if(!ishuman(user))
return
Expand All @@ -35,50 +48,57 @@
to_chat(dressing_human, span_warning("You are not capable of wearing underwear."))
return

var/choice = tgui_input_list(user, "Underwear, Bra, Undershirt, or Socks?", "Changing", list("Underwear", "Underwear Color", "Bra", "Bra Color", "Undershirt", "Undershirt Color", "Socks", "Socks Color")) //SKYRAT EDIT ADDITION - Colorable Undershirt/Socks/Bra
var/choice = tgui_input_list(user, "Underwear, Bra, Undershirt, or Socks?", "Changing", list("Underwear", "Underwear Color", "Bra", "Bra Color", "Undershirt", "Undershirt Color", "Socks", "Socks Color"))
if(isnull(choice))
return

if(!Adjacent(user))
return

switch(choice)
if("Underwear")
var/new_undies = tgui_input_list(user, "Select your underwear", "Changing", SSaccessories.underwear_list)
var/new_undies = tgui_input_list(user, "Select your underwear", "Changing", get_underwear_items_by_name())
if(new_undies)
dressing_human.underwear = new_undies
dressing_human.set_underwear(new_undies)
if("Underwear Color")
var/new_underwear_color = tgui_color_picker(dressing_human, "Choose your underwear color", "Underwear Color", dressing_human.underwear_color)
if(new_underwear_color)
dressing_human.underwear_color = sanitize_hexcolor(new_underwear_color)
if(dressing_human.w_underwear && !dressing_human.w_underwear.use_static)
dressing_human.w_underwear.color = dressing_human.underwear_color
dressing_human.w_underwear.refresh_worn_appearance()
if("Bra")
var/new_bra = tgui_input_list(user, "Select your bra", "Changing", get_bra_items_by_name())
if(new_bra)
dressing_human.set_bra(new_bra)
if("Bra Color")
var/new_bra_color = tgui_color_picker(dressing_human, "Choose your bra color", "Bra Color", dressing_human.bra_color)
if(new_bra_color)
dressing_human.bra_color = sanitize_hexcolor(new_bra_color)
if(dressing_human.w_bra && !dressing_human.w_bra.use_static)
dressing_human.w_bra.color = dressing_human.bra_color
dressing_human.w_bra.refresh_worn_appearance()
if("Undershirt")
var/new_undershirt = tgui_input_list(user, "Select your undershirt", "Changing", SSaccessories.undershirt_list)
var/new_undershirt = tgui_input_list(user, "Select your undershirt", "Changing", get_undershirt_items_by_name())
if(new_undershirt)
dressing_human.undershirt = new_undershirt
if("Socks")
var/new_socks = tgui_input_list(user, "Select your socks", "Changing", SSaccessories.socks_list)
if(new_socks)
dressing_human.socks = new_socks
//SKYRAT EDIT ADDITION BEGIN - Colorable Undershirt/Socks/Bras
dressing_human.set_undershirt(new_undershirt)
if("Undershirt Color")
var/new_undershirt_color = tgui_color_picker(dressing_human, "Choose your undershirt color", "Undershirt Color", dressing_human.undershirt_color) // BUBBERSTATION EDIT: TGUI COLOR PICKER
var/new_undershirt_color = tgui_color_picker(dressing_human, "Choose your undershirt color", "Undershirt Color", dressing_human.undershirt_color)
if(new_undershirt_color)
dressing_human.undershirt_color = sanitize_hexcolor(new_undershirt_color)
if(dressing_human.w_undershirt && !dressing_human.w_undershirt.use_static)
dressing_human.w_undershirt.color = dressing_human.undershirt_color
dressing_human.w_undershirt.refresh_worn_appearance()
if("Socks")
var/new_socks = tgui_input_list(user, "Select your socks", "Changing", get_socks_items_by_name())
if(new_socks)
dressing_human.set_socks(new_socks)
if("Socks Color")
var/new_socks_color = tgui_color_picker(dressing_human, "Choose your socks color", "Socks Color", dressing_human.socks_color) // BUBBERSTATION EDIT: TGUI COLOR PICKER
var/new_socks_color = tgui_color_picker(dressing_human, "Choose your socks color", "Socks Color", dressing_human.socks_color)
if(new_socks_color)
dressing_human.socks_color = sanitize_hexcolor(new_socks_color)

if("Bra")
var/new_bra = tgui_input_list(user, "Select your Bra", "Changing", SSaccessories.bra_list)
if(new_bra)
dressing_human.bra = new_bra

if("Bra Color")
var/new_bra_color = tgui_color_picker(dressing_human, "Choose your Bra color", "Bra Color", dressing_human.bra_color) // BUBBERSTATION EDIT: TGUI COLOR PICKER
if(new_bra_color)
dressing_human.bra_color = sanitize_hexcolor(new_bra_color)

//SKYRAT EDIT ADDITION END - Colorable Undershirt/Socks/Bras
if(dressing_human.w_socks && !dressing_human.w_socks.use_static)
dressing_human.w_socks.color = dressing_human.socks_color
dressing_human.w_socks.refresh_worn_appearance()

add_fingerprint(dressing_human)
dressing_human.update_body()
// META EDIT - CHANGE - END - UNDERWEAR_ITEMS
28 changes: 16 additions & 12 deletions code/modules/antagonists/changeling/changeling.dm
Original file line number Diff line number Diff line change
Expand Up @@ -570,12 +570,14 @@
LAZYADD(new_profile.quirks, new target_quirk.type)

// Clothes, of course
new_profile.underwear = target.underwear
// META EDIT - CHANGE - START - UNDERWEAR_ITEMS
new_profile.underwear = target.w_underwear?.name || "Nude"
new_profile.underwear_color = target.underwear_color
new_profile.undershirt = target.undershirt
new_profile.socks = target.socks
new_profile.undershirt = target.w_undershirt?.name || "Nude"
new_profile.socks = target.w_socks?.name || "Nude"
// META EDIT - CHANGE - END - UNDERWEAR_ITEMS
// SKYRAT EDIT ADDITION START
new_profile.bra = target.bra
new_profile.bra = target.w_bra?.name || "Nude" // META EDIT - CHANGE - UNDERWEAR_ITEMS
new_profile.undershirt_color = target.undershirt_color
new_profile.socks_color = target.socks_color
new_profile.bra_color = target.bra_color
Expand Down Expand Up @@ -818,19 +820,21 @@

var/datum/dna/chosen_dna = chosen_profile.dna
user.real_name = chosen_profile.name
user.underwear = chosen_profile.underwear
// META EDIT - CHANGE - START - UNDERWEAR_ITEMS
// Colors first, so set_X() below picks up the restored color rather than user's old one.
user.underwear_color = chosen_profile.underwear_color
user.undershirt = chosen_profile.undershirt
user.socks = chosen_profile.socks
user.undershirt_color = chosen_profile.undershirt_color
user.socks_color = chosen_profile.socks_color
user.bra_color = chosen_profile.bra_color
user.set_underwear(chosen_profile.underwear)
user.set_undershirt(chosen_profile.undershirt)
user.set_socks(chosen_profile.socks)
user.set_bra(chosen_profile.bra)
// META EDIT - CHANGE - END - UNDERWEAR_ITEMS
user.age = chosen_profile.age
user.physique = chosen_profile.physique
user.mind?.set_level(/datum/skill/athletics, chosen_profile.athletics_level, silent = TRUE)
// SKYRAT EDIT ADDITION START
user.bra = chosen_profile.bra

user.undershirt_color = chosen_profile.undershirt_color
user.socks_color = chosen_profile.socks_color
user.bra_color = chosen_profile.bra_color
user.blooper = chosen_profile.blooper
user.blooper_speed = chosen_profile.blooper_speed
user.blooper_pitch = chosen_profile.blooper_pitch
Expand Down
7 changes: 4 additions & 3 deletions code/modules/antagonists/voidwalker/voidwalker_traumas.dm
Original file line number Diff line number Diff line change
Expand Up @@ -55,9 +55,10 @@
//your underwear is belong to us
if(ishuman(owner))
var/mob/living/carbon/human/human = owner //CARBON WILL NEVER BE REAL!!!!!
human.underwear = "Nude"
human.undershirt = "Nude"
human.socks = "Nude"
// META EDIT - CHANGE - UNDERWEAR_ITEMS
human.set_underwear("Nude")
human.set_undershirt("Nude")
human.set_socks("Nude")

owner.update_body()

Expand Down
6 changes: 6 additions & 0 deletions code/modules/asset_cache/assets/inventory.dm
Original file line number Diff line number Diff line change
Expand Up @@ -17,4 +17,10 @@
"inventory-back.png" = 'icons/ui/inventory/back.png',
"inventory-pocket.png" = 'icons/ui/inventory/pocket.png',
"inventory-collar.png" = 'icons/ui/inventory/collar.png',
// META EDIT - ADDITION - START - UNDERWEAR_ITEMS
"inventory-underwear.png" = 'modular_zzmeta/icons/ui/inventory/underwear.png',
"inventory-bra.png" = 'modular_zzmeta/icons/ui/inventory/bra.png',
"inventory-undershirt.png" = 'modular_zzmeta/icons/ui/inventory/undershirt.png',
"inventory-socks.png" = 'modular_zzmeta/icons/ui/inventory/socks.png',
// META EDIT - ADDITION - END - UNDERWEAR_ITEMS
)
12 changes: 9 additions & 3 deletions code/modules/client/preferences/clothing.dm
Original file line number Diff line number Diff line change
Expand Up @@ -139,8 +139,10 @@

return generate_underwear_icon(SSaccessories.socks_list[value], lower_half)

// META EDIT - CHANGE - START - UNDERWEAR_ITEMS
/datum/preference/choiced/socks/apply_to_human(mob/living/carbon/human/target, value)
target.socks = value
target.set_socks(value)
// META EDIT - CHANGE - END - UNDERWEAR_ITEMS

/// Undershirt preference
/datum/preference/choiced/undershirt
Expand Down Expand Up @@ -190,8 +192,10 @@
icon_with_undershirt.scale(32, 32)
return icon_with_undershirt

// META EDIT - CHANGE - START - UNDERWEAR_ITEMS
/datum/preference/choiced/undershirt/apply_to_human(mob/living/carbon/human/target, value)
target.undershirt = value
target.set_undershirt(value)
// META EDIT - CHANGE - END - UNDERWEAR_ITEMS

/// Underwear preference
/datum/preference/choiced/underwear
Expand Down Expand Up @@ -219,8 +223,10 @@

return generate_underwear_icon(SSaccessories.underwear_list[value], lower_half, COLOR_ALMOST_BLACK, icon_offset = 5) // SKYRAT EDIT CHANGE : ICON_OFFSET // SKYRAT EDIT CHANGE - ORIGINAL: return generate_underwear_icon(SSaccessories.underwear_list[value], lower_half, COLOR_ALMOST_BLACK)

// META EDIT - CHANGE - START - UNDERWEAR_ITEMS
/datum/preference/choiced/underwear/apply_to_human(mob/living/carbon/human/target, value)
target.underwear = value
target.set_underwear(value)
// META EDIT - CHANGE - END - UNDERWEAR_ITEMS

/datum/preference/choiced/underwear/is_accessible(datum/preferences/preferences)
if (!..(preferences))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -96,8 +96,8 @@
var/mob/living/carbon/human/newwalker = new /mob/living/carbon/human(get_step(loc, pick(GLOB.alldirs)))
newwalker.set_species(/datum/species/lizard/ashwalker)
newwalker.real_name = oldmob.real_name
newwalker.undershirt = "Nude"
newwalker.underwear = "Nude"
newwalker.set_undershirt("Nude") // META EDIT - CHANGE - UNDERWEAR_ITEMS
newwalker.set_underwear("Nude") // META EDIT - CHANGE - UNDERWEAR_ITEMS
newwalker.update_body()
newwalker.remove_language(/datum/language/common)
oldmob.mind.transfer_to(newwalker)
Expand Down
8 changes: 8 additions & 0 deletions code/modules/mob/dead/observer/observer.dm
Original file line number Diff line number Diff line change
Expand Up @@ -975,6 +975,14 @@ This is the proc mobs get to turn into a ghost. Forked from ghostize due to comp
if(isobserver(target) && check_rights(R_SPAWN))
var/mob/dead/observer/target_ghost = target

// META EDIT - CHANGE - UNDERWEAR_ITEMS
// change_mob_type() already calls client.prefs.safe_transfer_prefs_to() internally (see
// change_mob_type_unchecked() in code/modules/mob/mob_transformation_simple.dm), which
// applies every character preference including underwear/bra/undershirt/socks, using the
// client reference from BEFORE it gets reassigned to the new mob. No extra code needed
// here; an earlier attempt to add a fallback outfit after this call actively broke this,
// since by then target_ghost.client had already moved to the new mob (read as null, so
// it always fell through to the hardcoded fallback and overwrote the real preference).
target_ghost.change_mob_type(/mob/living/carbon/human , null, null, TRUE) //always delmob, ghosts shouldn't be left lingering

/mob/dead/observer/examine(mob/user)
Expand Down
Loading
Loading