From 135a09182b9dce16ac3c77b918cd62331bb77ed7 Mon Sep 17 00:00:00 2001
From: MrMelbert <51863163+MrMelbert@users.noreply.github.com>
Date: Sun, 7 Sep 2025 02:24:34 -0500
Subject: [PATCH] Refactors obscured (#92779)
## About The Pull Request
Fixes #85028
Obscured flags and covered flags are tracked on carbons, updated as
items are equipped and unequipped. It's that shrimple.
Closes #92760
Just removes the species exception checks for not making sense
Also refactors handcuffs / legcuffs removal. In all of these situations
they were hardcoded when they could easily just use an inventory proc to
work.
## Why It's Good For The Game
Stops a million excessive calls to `check_obscured_slots`
Makes obscured behavior more consistent
Makes obscured behavior easier to use
Cleans up human rendering (There was some cursed stuff before with
render item -> updated obscured -> update body -> cause side effects)
## Changelog
:cl: Melbert
del: Golems which somehow manage to grow wings and somehow manage to
equip something that covers their jumpsuit can no longer fly.
(Seriously, this will not affect anyone)
refactor: Refactored clothing obscurity entirely. Items should be a
loooot more consistent and what covers what, and should update a lot
snappier. As always, report any oddities, like mysteriously disappearing
articles of clothing, hair, or species parts
refactored: Refactored handcuffs and legcuffs a bit, report any odd
situations with cuffs like getting stuck restrained
/:cl:
---
code/__DEFINES/inventory.dm | 2 +-
code/__HELPERS/pronouns.dm | 4 +-
code/_globalvars/bitfields.dm | 47 ++++---
code/_onclick/hud/fullscreen.dm | 2 -
code/_onclick/hud/human.dm | 4 +-
code/datums/components/bloodysoles.dm | 2 +-
code/datums/components/cuff_n_stun.dm | 1 -
.../components/toggle_attached_clothing.dm | 1 -
code/datums/elements/strippable.dm | 4 +-
code/datums/mutations/hulk.dm | 2 +-
code/datums/status_effects/debuffs/drunk.dm | 4 +-
code/datums/wounds/scars/_scars.dm | 2 +-
code/game/objects/items.dm | 5 +-
.../abductor/equipment/gear/abductor_items.dm | 1 -
code/modules/antagonists/cult/blood_magic.dm | 1 -
.../sacrifice_knowledge.dm | 8 +-
.../clothing/chameleon/_chameleon_action.dm | 1 +
code/modules/clothing/clothing.dm | 4 +-
code/modules/clothing/head/animalears.dm | 2 +-
code/modules/clothing/masks/animal_masks.dm | 1 +
code/modules/clothing/shoes/_shoes.dm | 2 +-
code/modules/fishing/fish/types/rift.dm | 7 +-
code/modules/forensics/forensics_helpers.dm | 2 +-
code/modules/mob/inventory.dm | 23 ++--
.../mob/living/basic/drone/visuals_icons.dm | 4 +-
code/modules/mob/living/carbon/carbon.dm | 47 +------
.../mob/living/carbon/carbon_defines.dm | 5 +
.../mob/living/carbon/carbon_update_icons.dm | 34 ++---
code/modules/mob/living/carbon/examine.dm | 40 +++---
code/modules/mob/living/carbon/human/dummy.dm | 7 +-
code/modules/mob/living/carbon/human/human.dm | 6 +-
.../mob/living/carbon/human/human_defense.dm | 17 ++-
.../mob/living/carbon/human/human_helpers.dm | 4 +-
.../living/carbon/human/human_update_icons.dm | 90 ++++---------
.../mob/living/carbon/human/init_signals.dm | 18 +--
.../mob/living/carbon/human/inventory.dm | 20 +--
.../carbon/human/species_types/mushpeople.dm | 7 +-
code/modules/mob/living/carbon/inventory.dm | 126 +++++++++---------
code/modules/mob/living/emote.dm | 2 +-
code/modules/mob/living/living.dm | 5 -
.../mob/living/simple_animal/bot/secbot.dm | 1 -
code/modules/mob/mob.dm | 16 ++-
code/modules/mob/mob_update_icons.dm | 56 +++-----
code/modules/mod/mod_activation.dm | 2 +-
code/modules/mod/mod_control.dm | 1 +
code/modules/mod/mod_theme.dm | 1 +
code/modules/photography/camera/camera.dm | 5 +-
.../surgery/bodyparts/dismemberment.dm | 14 +-
.../surgery/bodyparts/head_hair_and_lips.dm | 11 +-
.../species_parts/lizard_bodyparts.dm | 2 +-
.../surgery/organs/external/_visual_organs.dm | 35 +----
.../modules/surgery/organs/external/spines.dm | 7 +-
code/modules/surgery/organs/external/tails.dm | 14 +-
.../organs/external/wings/functional_wings.dm | 4 +-
.../organs/external/wings/moth_wings.dm | 13 +-
.../surgery/organs/external/wings/wings.dm | 13 +-
.../surgery/organs/internal/ears/_ears.dm | 7 +-
.../surgery/organs/internal/eyes/_eyes.dm | 3 +-
.../screenshots/screenshot_digi_leg_test.png | Bin 1758 -> 1759 bytes
code/modules/unit_tests/strippable.dm | 1 -
.../mecha/equipment/weapons/weapons.dm | 1 -
61 files changed, 279 insertions(+), 492 deletions(-)
diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm
index 621954eee09..9a369301967 100644
--- a/code/__DEFINES/inventory.dm
+++ b/code/__DEFINES/inventory.dm
@@ -86,7 +86,7 @@ DEFINE_BITFIELD(no_equip_flags, list(
ITEM_SLOT_MASK | ITEM_SLOT_HEAD | ITEM_SLOT_FEET | ITEM_SLOT_ID | ITEM_SLOT_BELT | ITEM_SLOT_BACK | ITEM_SLOT_NECK )
//Bit flags for the flags_inv variable, which determine when a piece of clothing hides another. IE a helmet hiding glasses.
-//Make sure to update check_obscured_slots() if you add more.
+//Make sure to update obscured_slots if you add more.
#define HIDEGLOVES (1<<0)
#define HIDESUITSTORAGE (1<<1)
#define HIDEJUMPSUIT (1<<2) //these first four are only used in exterior suits
diff --git a/code/__HELPERS/pronouns.dm b/code/__HELPERS/pronouns.dm
index 7aaca3e7556..cc907f1bc49 100644
--- a/code/__HELPERS/pronouns.dm
+++ b/code/__HELPERS/pronouns.dm
@@ -413,8 +413,8 @@
/mob/living/carbon/human/get_visible_gender()
if(HAS_TRAIT(src, TRAIT_UNKNOWN))
return PLURAL
- var/face_hidden = (wear_mask?.flags_inv & HIDEFACE) || (head?.flags_inv & HIDEFACE)
- if(face_hidden && (check_obscured_slots() & ITEM_SLOT_ICLOTHING))
+ // If both face and uniform are hidden, can't assess gender
+ if(obscured_slots & (HIDEFACE|HIDEJUMPSUIT) == (HIDEFACE|HIDEJUMPSUIT))
return PLURAL
return gender
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 2d8d098b09b..f8f1b2cc917 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -206,24 +206,35 @@ DEFINE_BITFIELD(item_flags, list(
"NO_BLOOD_ON_ITEM" = NO_BLOOD_ON_ITEM,
))
-DEFINE_BITFIELD(flags_inv, list(
- "HIDEEARS" = HIDEEARS,
- "HIDEEYES" = HIDEEYES,
- "HIDEFACE" = HIDEFACE,
- "HIDEFACIALHAIR" = HIDEFACIALHAIR,
- "HIDEGLOVES" = HIDEGLOVES,
- "HIDEHAIR" = HIDEHAIR,
- "HIDEHEADGEAR" = HIDEHEADGEAR,
- "HIDEJUMPSUIT" = HIDEJUMPSUIT,
- "HIDEMASK" = HIDEMASK,
- "HIDEBELT" = HIDEBELT,
- "HIDENECK" = HIDENECK,
- "HIDESHOES" = HIDESHOES,
- "HIDESNOUT" = HIDESNOUT,
- "HIDESUITSTORAGE" = HIDESUITSTORAGE,
- "HIDEMUTWINGS" = HIDEMUTWINGS,
- "HIDEANTENNAE" = HIDEANTENNAE,
-))
+#define HIDEFLAGS_BITFIELD list( \
+ "HIDEEARS" = HIDEEARS, \
+ "HIDEEYES" = HIDEEYES, \
+ "HIDEFACE" = HIDEFACE, \
+ "HIDEFACIALHAIR" = HIDEFACIALHAIR, \
+ "HIDEGLOVES" = HIDEGLOVES, \
+ "HIDEHAIR" = HIDEHAIR, \
+ "HIDEHEADGEAR" = HIDEHEADGEAR, \
+ "HIDEJUMPSUIT" = HIDEJUMPSUIT, \
+ "HIDEMASK" = HIDEMASK, \
+ "HIDEBELT" = HIDEBELT, \
+ "HIDENECK" = HIDENECK, \
+ "HIDESHOES" = HIDESHOES, \
+ "HIDESNOUT" = HIDESNOUT, \
+ "HIDESUITSTORAGE" = HIDESUITSTORAGE, \
+ "HIDEMUTWINGS" = HIDEMUTWINGS, \
+ "HIDEANTENNAE" = HIDEANTENNAE, \
+)
+
+/// Item obscured flags
+DEFINE_BITFIELD(flags_inv, HIDEFLAGS_BITFIELD)
+/// Item coverage flags
+DEFINE_BITFIELD(transparent_protection, HIDEFLAGS_BITFIELD)
+/// Mob obscured flags
+DEFINE_BITFIELD(obscured_slots, HIDEFLAGS_BITFIELD)
+/// Mob covered flags
+DEFINE_BITFIELD(covered_slots, HIDEFLAGS_BITFIELD)
+
+#undef HIDEFLAGS_BITFIELD
DEFINE_BITFIELD(strict_coverage_zones, list(
"HAIR_APPENDAGE_FRONT" = HAIR_APPENDAGE_FRONT,
diff --git a/code/_onclick/hud/fullscreen.dm b/code/_onclick/hud/fullscreen.dm
index c3ce31d9d3d..e26eb16f6cc 100644
--- a/code/_onclick/hud/fullscreen.dm
+++ b/code/_onclick/hud/fullscreen.dm
@@ -72,8 +72,6 @@
if(screen.needs_offsetting)
screen.plane = GET_NEW_PLANE(initial(screen.plane), offset)
-INITIALIZE_IMMEDIATE(/atom/movable/screen/fullscreen)
-
/atom/movable/screen/fullscreen
icon = 'icons/hud/screen_full.dmi'
icon_state = "default"
diff --git a/code/_onclick/hud/human.dm b/code/_onclick/hud/human.dm
index fda5012a4c7..3ccab614996 100644
--- a/code/_onclick/hud/human.dm
+++ b/code/_onclick/hud/human.dm
@@ -301,7 +301,7 @@
var/mob/living/carbon/human/human_mob = mymob
if(istype(human_mob))
blocked_slots |= human_mob.dna?.species?.no_equip_flags
- if(isnull(human_mob.w_uniform) && !HAS_TRAIT(human_mob, TRAIT_NO_JUMPSUIT))
+ if((isnull(human_mob.w_uniform) || !(human_mob.w_uniform.item_flags & IN_INVENTORY)) && !HAS_TRAIT(human_mob, TRAIT_NO_JUMPSUIT))
var/obj/item/bodypart/chest = human_mob.get_bodypart(BODY_ZONE_CHEST)
if(isnull(chest) || IS_ORGANIC_LIMB(chest))
blocked_slots |= ITEM_SLOT_ID|ITEM_SLOT_BELT
@@ -311,7 +311,7 @@
var/obj/item/bodypart/right_leg = human_mob.get_bodypart(BODY_ZONE_R_LEG)
if(isnull(right_leg) || IS_ORGANIC_LIMB(right_leg))
blocked_slots |= ITEM_SLOT_RPOCKET
- if(isnull(human_mob.wear_suit))
+ if(isnull(human_mob.wear_suit) || !(human_mob.wear_suit.item_flags & IN_INVENTORY))
blocked_slots |= ITEM_SLOT_SUITSTORE
if(human_mob.num_hands <= 0)
blocked_slots |= ITEM_SLOT_GLOVES
diff --git a/code/datums/components/bloodysoles.dm b/code/datums/components/bloodysoles.dm
index 0f4b5d8321e..4dc7a7feeb6 100644
--- a/code/datums/components/bloodysoles.dm
+++ b/code/datums/components/bloodysoles.dm
@@ -43,7 +43,7 @@
* Returns true if the parent item is obscured by something else that the wielder is wearing
*/
/datum/component/bloodysoles/proc/is_obscured()
- return (wielder.check_covered_slots() & equipped_slot) || is_under_feet_covered()
+ return (hidden_slots_to_inventory_slots(wielder.covered_slots) & equipped_slot) || is_under_feet_covered()
/**
* Returns true if the parent item is worn in the ITEM_SLOT_ICLOTHING slot and the
diff --git a/code/datums/components/cuff_n_stun.dm b/code/datums/components/cuff_n_stun.dm
index fda9618e93c..6f9355cb6f1 100644
--- a/code/datums/components/cuff_n_stun.dm
+++ b/code/datums/components/cuff_n_stun.dm
@@ -82,7 +82,6 @@
if(!do_after(parent, handcuff_timer, human_target))
return
human_target.set_handcuffed(new handcuff_type(human_target))
- human_target.update_handcuffed()
post_arrest_callback?.Invoke(human_target)
/datum/component/stun_n_cuff/proc/stun_target(mob/living/carbon/human_target)
diff --git a/code/datums/components/toggle_attached_clothing.dm b/code/datums/components/toggle_attached_clothing.dm
index 87af014396e..a251fd0e38a 100644
--- a/code/datums/components/toggle_attached_clothing.dm
+++ b/code/datums/components/toggle_attached_clothing.dm
@@ -140,7 +140,6 @@
parent_gear.icon_state = "[initial(parent_gear.post_init_icon_state) || initial(parent_gear.icon_state)][parent_icon_state_suffix]"
parent_gear.worn_icon_state = parent_gear.icon_state
parent_gear.update_slot_icon()
- wearer.update_obscured_slots(deployable.flags_inv)
wearer.update_mob_action_buttons()
/// Undeploy gear if it moves slots somehow
diff --git a/code/datums/elements/strippable.dm b/code/datums/elements/strippable.dm
index 70b7e2968ab..b041aa47c3d 100644
--- a/code/datums/elements/strippable.dm
+++ b/code/datums/elements/strippable.dm
@@ -262,10 +262,10 @@
return STRIPPABLE_OBSCURING_NONE
var/mob/living/carbon/carbon_source = source
- if (carbon_source.check_obscured_slots() & item_slot)
+ if (hidden_slots_to_inventory_slots(carbon_source.obscured_slots) & item_slot)
return STRIPPABLE_OBSCURING_COMPLETELY
- if (carbon_source.check_covered_slots() & item_slot)
+ if (hidden_slots_to_inventory_slots(carbon_source.covered_slots) & item_slot)
return STRIPPABLE_OBSCURING_INACCESSIBLE
return STRIPPABLE_OBSCURING_NONE
diff --git a/code/datums/mutations/hulk.dm b/code/datums/mutations/hulk.dm
index 91f57f46fa8..6f9225cfdd1 100644
--- a/code/datums/mutations/hulk.dm
+++ b/code/datums/mutations/hulk.dm
@@ -123,7 +123,7 @@
if(ishuman(possible_throwable))
var/mob/living/carbon/human/human_throwable = possible_throwable
- if(human_throwable.wear_suit && (human_throwable.wear_suit.flags_inv & HIDEJUMPSUIT))
+ if(human_throwable.obscured_slots & HIDEJUMPSUIT)
to_chat(user, span_warning("You can't reach [human_throwable]'s tail through [human_throwable.p_their()] [human_throwable.wear_suit.name]!"))
return
diff --git a/code/datums/status_effects/debuffs/drunk.dm b/code/datums/status_effects/debuffs/drunk.dm
index fc5c74f46d5..8202f526f26 100644
--- a/code/datums/status_effects/debuffs/drunk.dm
+++ b/code/datums/status_effects/debuffs/drunk.dm
@@ -33,9 +33,7 @@
// Having your face covered conceals your drunkness
if(iscarbon(owner))
var/mob/living/carbon/carbon_owner = owner
- if(carbon_owner.wear_mask?.flags_inv & HIDEFACE)
- return null
- if(carbon_owner.head?.flags_inv & HIDEFACE)
+ if(carbon_owner.obscured_slots & HIDEFACE)
return null
// .01s are used in case the drunk value ends up to be a small decimal.
diff --git a/code/datums/wounds/scars/_scars.dm b/code/datums/wounds/scars/_scars.dm
index 2fdd92b82d0..d5125521787 100644
--- a/code/datums/wounds/scars/_scars.dm
+++ b/code/datums/wounds/scars/_scars.dm
@@ -178,7 +178,7 @@
var/mob/living/carbon/human/human_victim = victim
if(istype(limb, /obj/item/bodypart/head))
- if((human_victim.wear_mask && (human_victim.wear_mask.flags_inv & HIDEFACE)) || (human_victim.head && (human_victim.head.flags_inv & HIDEFACE)))
+ if(human_victim.obscured_slots & HIDEFACE)
return FALSE
else if(limb.scars_covered_by_clothes)
var/num_covers = LAZYLEN(human_victim.get_clothing_on_part(limb))
diff --git a/code/game/objects/items.dm b/code/game/objects/items.dm
index cd3f17e1622..cfc296cf327 100644
--- a/code/game/objects/items.dm
+++ b/code/game/objects/items.dm
@@ -755,7 +755,6 @@
SEND_SIGNAL(src, COMSIG_ITEM_DROPPED, user)
if(!silent)
play_drop_sound(DROP_SOUND_VOLUME)
- user?.update_equipment(src)
/// called just as an item is picked up (loc is not yet changed)
/obj/item/proc/pickup(mob/user)
@@ -792,7 +791,7 @@
* polling ghosts while it's just being equipped as a visual preview for a dummy.
*/
/obj/item/proc/visual_equipped(mob/user, slot, initial = FALSE)
- return
+ return TRUE
/**
* Called by on_equipped. Don't call this directly, we want the ITEM_POST_EQUIPPED signal to be sent after everything else.
@@ -818,8 +817,6 @@
item_flags |= IN_INVENTORY
RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_NO_WORN_ICON), SIGNAL_REMOVETRAIT(TRAIT_NO_WORN_ICON)), PROC_REF(update_slot_icon), override = TRUE)
- user.update_equipment(src)
-
if(!initial && (slot_flags & slot) && (play_equip_sound()))
return
diff --git a/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm b/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm
index 90d2d5a9053..b056ecbef30 100644
--- a/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm
+++ b/code/modules/antagonists/abductor/equipment/gear/abductor_items.dm
@@ -445,7 +445,6 @@ Return to step 11 of normal process."}
if(do_after(user, time_to_cuff, carbon_victim) && carbon_victim.canBeHandcuffed())
if(!carbon_victim.handcuffed)
carbon_victim.set_handcuffed(new /obj/item/restraints/handcuffs/energy/used(carbon_victim))
- carbon_victim.update_handcuffed()
to_chat(user, span_notice("You restrain [carbon_victim]."))
log_combat(user, carbon_victim, "handcuffed")
else
diff --git a/code/modules/antagonists/cult/blood_magic.dm b/code/modules/antagonists/cult/blood_magic.dm
index db66083062a..1bafdb7a3ef 100644
--- a/code/modules/antagonists/cult/blood_magic.dm
+++ b/code/modules/antagonists/cult/blood_magic.dm
@@ -573,7 +573,6 @@
if(do_after(user, 3 SECONDS, C))
if(!C.handcuffed)
C.set_handcuffed(new /obj/item/restraints/handcuffs/energy/cult/used(C))
- C.update_handcuffed()
C.adjust_silence(10 SECONDS)
to_chat(user, span_notice("You shackle [C]."))
log_combat(user, C, "shackled")
diff --git a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm
index 9e9cc36c948..210baad0dda 100644
--- a/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm
+++ b/code/modules/antagonists/heretic/knowledge/sacrifice_knowledge/sacrifice_knowledge.dm
@@ -334,13 +334,7 @@
sac_target.visible_message(span_danger("[sac_target] begins to shudder violenty as dark tendrils begin to drag them into thin air!"))
sac_target.set_handcuffed(new /obj/item/restraints/handcuffs/energy/cult(sac_target))
- sac_target.update_handcuffed()
-
- if(sac_target.legcuffed)
- sac_target.legcuffed.forceMove(sac_target.drop_location())
- sac_target.legcuffed.dropped(sac_target)
- sac_target.legcuffed = null
- sac_target.update_worn_legcuffs()
+ sac_target.dropItemToGround(sac_target.legcuffed, TRUE)
sac_target.adjustOrganLoss(ORGAN_SLOT_BRAIN, 85, 150)
sac_target.do_jitter_animation()
diff --git a/code/modules/clothing/chameleon/_chameleon_action.dm b/code/modules/clothing/chameleon/_chameleon_action.dm
index d0fdf826991..4befe80fbe8 100644
--- a/code/modules/clothing/chameleon/_chameleon_action.dm
+++ b/code/modules/clothing/chameleon/_chameleon_action.dm
@@ -120,6 +120,7 @@
if(ismob(chameleon_item.loc))
var/mob/wearer = chameleon_item.loc
wearer.update_clothing(chameleon_item.slot_flags | ITEM_SLOT_HANDS)
+ wearer.refresh_obscured()
/datum/action/item_action/chameleon/change/proc/update_item(obj/item/picked_item)
PROTECTED_PROC(TRUE) // Call update_look, not this!
diff --git a/code/modules/clothing/clothing.dm b/code/modules/clothing/clothing.dm
index 53bbcbe6377..f388cea8805 100644
--- a/code/modules/clothing/clothing.dm
+++ b/code/modules/clothing/clothing.dm
@@ -563,12 +563,12 @@ BLIND // can't see anything
if(user.is_holding(src))
user.update_held_items()
return TRUE
- if(up)
- user.update_obscured_slots(visor_flags_inv)
user.update_clothing(slot_flags)
if(!iscarbon(user))
return TRUE
var/mob/living/carbon/carbon_user = user
+ if(up)
+ carbon_user.refresh_obscured()
if(visor_vars_to_toggle & VISOR_TINT)
carbon_user.update_tint()
if((visor_flags & (MASKINTERNALS|HEADINTERNALS)) && carbon_user.invalid_internals())
diff --git a/code/modules/clothing/head/animalears.dm b/code/modules/clothing/head/animalears.dm
index 77ed57a9083..bcb5ffb63ed 100644
--- a/code/modules/clothing/head/animalears.dm
+++ b/code/modules/clothing/head/animalears.dm
@@ -10,7 +10,7 @@
if(ishuman(user) && (slot & ITEM_SLOT_HEAD))
update_icon(ALL, user)
user.update_worn_head() //Color might have been changed by update_appearance.
- ..()
+ return ..()
/obj/item/clothing/head/costume/kitty/update_icon(updates=ALL, mob/living/carbon/human/user)
. = ..()
diff --git a/code/modules/clothing/masks/animal_masks.dm b/code/modules/clothing/masks/animal_masks.dm
index fd900810e67..d3482a2c39e 100644
--- a/code/modules/clothing/masks/animal_masks.dm
+++ b/code/modules/clothing/masks/animal_masks.dm
@@ -91,6 +91,7 @@ GLOBAL_LIST_INIT(cursed_animal_masks, list(
RegisterSignal(M, COMSIG_MOB_SAY, PROC_REF(handle_speech))
to_chat(M, span_userdanger("[src] was cursed!"))
M.update_worn_mask()
+ M.refresh_obscured()
/obj/item/clothing/mask/animal/proc/clear_curse()
REMOVE_TRAIT(src, TRAIT_NODROP, CURSED_MASK_TRAIT)
diff --git a/code/modules/clothing/shoes/_shoes.dm b/code/modules/clothing/shoes/_shoes.dm
index 1d57e38ac39..5463ac03d1c 100644
--- a/code/modules/clothing/shoes/_shoes.dm
+++ b/code/modules/clothing/shoes/_shoes.dm
@@ -77,7 +77,7 @@
. += "The [fastening_type] are all knotted together."
/obj/item/clothing/shoes/visual_equipped(mob/user, slot)
- ..()
+ . = ..()
if(offset && (slot_flags & slot))
user.pixel_z += offset
worn_y_dimension -= (offset * 2)
diff --git a/code/modules/fishing/fish/types/rift.dm b/code/modules/fishing/fish/types/rift.dm
index eb72c82ac44..ba6a0142ed4 100644
--- a/code/modules/fishing/fish/types/rift.dm
+++ b/code/modules/fishing/fish/types/rift.dm
@@ -722,12 +722,7 @@
icon_state = "babbearfish"
/datum/bodypart_overlay/simple/babbearfish/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if((human.head?.flags_inv & HIDEEARS) || (human.wear_mask?.flags_inv & HIDEEARS))
- return FALSE
- return TRUE
+ return !(bodypart_owner.owner?.obscured_slots & HIDEEARS)
/obj/item/organ/ears/babbelfish/Initialize(mapload)
. = ..()
diff --git a/code/modules/forensics/forensics_helpers.dm b/code/modules/forensics/forensics_helpers.dm
index 46c0bfa3a9d..5b32ee43418 100644
--- a/code/modules/forensics/forensics_helpers.dm
+++ b/code/modules/forensics/forensics_helpers.dm
@@ -200,7 +200,7 @@
var/dirty_hands = !!(target_flags & (ITEM_SLOT_GLOVES|ITEM_SLOT_HANDS))
var/dirty_feet = !!(target_flags & ITEM_SLOT_FEET)
- var/slots_to_bloody = target_flags & ~check_covered_slots()
+ var/slots_to_bloody = target_flags & ~hidden_slots_to_inventory_slots(covered_slots)
var/list/all_worn = get_equipped_items()
for(var/obj/item/thing as anything in all_worn)
if(thing.slot_flags & slots_to_bloody)
diff --git a/code/modules/mob/inventory.dm b/code/modules/mob/inventory.dm
index 324282c0af0..d1a0e084f3a 100644
--- a/code/modules/mob/inventory.dm
+++ b/code/modules/mob/inventory.dm
@@ -295,10 +295,7 @@
location = turf
break
- I.forceMove(location)
- I.layer = initial(I.layer)
- SET_PLANE_EXPLICIT(I, initial(I.plane), location)
- I.dropped(src)
+ transferItemToLoc(I, location, force = TRUE, silent = TRUE, animated = !ignore_animation)
return FALSE
/// Returns true if a mob is holding something
@@ -424,13 +421,10 @@
if(!item_dropping)
return FALSE
- if(client)
- client.screen -= item_dropping
+ client?.screen -= item_dropping
- if(observers?.len)
- for(var/mob/dead/observe as anything in observers)
- if(observe.client)
- observe.client.screen -= item_dropping
+ for(var/mob/dead/observe as anything in observers)
+ observe.client?.screen -= item_dropping
item_dropping.layer = initial(item_dropping.layer)
SET_PLANE_EXPLICIT(item_dropping, initial(item_dropping.plane), newloc)
@@ -441,7 +435,7 @@
else
item_dropping.forceMove(newloc)
- item_dropping.dropped(src, silent)
+ has_unequipped(item_dropping, silent)
SEND_SIGNAL(item_dropping, COMSIG_ITEM_POST_UNEQUIP, force, newloc, no_move, invdrop, silent)
SEND_SIGNAL(src, COMSIG_MOB_UNEQUIPPED_ITEM, item_dropping, force, newloc, no_move, invdrop, silent)
return TRUE
@@ -520,8 +514,15 @@
/// This proc is called after an item has been successfully handled and equipped to a slot.
/mob/proc/has_equipped(obj/item/item, slot, initial = FALSE)
+ SHOULD_CALL_PARENT(TRUE)
return item.on_equipped(src, slot, initial)
+/// This proc is called after an item has been removed from a mob but before it has been officially deslotted.
+/mob/proc/has_unequipped(obj/item/item, silent = FALSE)
+ SHOULD_CALL_PARENT(TRUE)
+ item.dropped(src, silent)
+ return TRUE
+
/**
* Equip an item to the slot or delete
*
diff --git a/code/modules/mob/living/basic/drone/visuals_icons.dm b/code/modules/mob/living/basic/drone/visuals_icons.dm
index fb89e82c8a1..59952d8d249 100644
--- a/code/modules/mob/living/basic/drone/visuals_icons.dm
+++ b/code/modules/mob/living/basic/drone/visuals_icons.dm
@@ -27,7 +27,7 @@
client.screen += internal_storage
-/mob/living/basic/drone/update_worn_head(update_obscured = TRUE)
+/mob/living/basic/drone/update_worn_head()
remove_overlay(DRONE_HEAD_LAYER)
if(head)
@@ -44,7 +44,7 @@
apply_overlay(DRONE_HEAD_LAYER)
-/mob/living/basic/drone/update_worn_mask(update_obscured = TRUE)
+/mob/living/basic/drone/update_worn_mask()
update_worn_head()
/mob/living/basic/drone/regenerate_icons()
diff --git a/code/modules/mob/living/carbon/carbon.dm b/code/modules/mob/living/carbon/carbon.dm
index 6a16b8ea879..004dbedb06a 100644
--- a/code/modules/mob/living/carbon/carbon.dm
+++ b/code/modules/mob/living/carbon/carbon.dm
@@ -220,32 +220,10 @@
/mob/living/carbon/proc/uncuff()
if (handcuffed)
- var/obj/item/W = handcuffed
- set_handcuffed(null)
- if (buckled?.buckle_requires_restraints)
- buckled.unbuckle_mob(src)
- update_handcuffed()
- if (client)
- client.screen -= W
- if (W)
- W.forceMove(drop_location())
- W.dropped(src)
- if (W)
- W.layer = initial(W.layer)
- SET_PLANE_EXPLICIT(W, initial(W.plane), src)
+ dropItemToGround(handcuffed, TRUE)
changeNext_move(0)
if (legcuffed)
- var/obj/item/W = legcuffed
- legcuffed = null
- update_worn_legcuffs()
- if (client)
- client.screen -= W
- if (W)
- W.forceMove(drop_location())
- W.dropped(src)
- if (W)
- W.layer = initial(W.layer)
- SET_PLANE_EXPLICIT(W, initial(W.plane), src)
+ dropItemToGround(legcuffed, TRUE)
changeNext_move(0)
/mob/living/carbon/proc/clear_cuffs(obj/item/I, cuff_break)
@@ -263,18 +241,10 @@
else
if(I == handcuffed)
- handcuffed.forceMove(drop_location())
- set_handcuffed(null)
- I.dropped(src)
- if(buckled?.buckle_requires_restraints)
- buckled.unbuckle_mob(src)
- update_handcuffed()
+ dropItemToGround(I, TRUE)
return TRUE
if(I == legcuffed)
- legcuffed.forceMove(drop_location())
- legcuffed = null
- I.dropped(src)
- update_worn_legcuffs()
+ dropItemToGround(I, TRUE)
return TRUE
/mob/living/carbon/proc/accident(obj/item/I)
@@ -836,8 +806,6 @@
if(heal_flags & HEAL_RESTRAINTS)
QDEL_NULL(handcuffed)
QDEL_NULL(legcuffed)
- set_handcuffed(null)
- update_handcuffed()
return ..()
@@ -1128,7 +1096,7 @@
. |= held_thing.wash(clean_types)
// Check and wash stuff that isn't covered
- var/covered = check_covered_slots()
+ var/covered = hidden_slots_to_inventory_slots(covered_slots)
for(var/obj/item/worn as anything in get_equipped_items())
var/slot = get_slot_by_item(worn)
// Don't wash glasses if something other than them is covering our eyes
@@ -1185,9 +1153,6 @@
scaries.fake = TRUE
QDEL_NULL(phantom_wound)
-/mob/living/carbon/is_face_visible()
- return !(wear_mask?.flags_inv & HIDEFACE) && !(head?.flags_inv & HIDEFACE)
-
/// Returns whether or not the carbon should be able to be shocked
/mob/living/carbon/proc/should_electrocute(power_source)
if (ismecha(loc))
@@ -1231,7 +1196,7 @@
REMOVE_TRAIT(src, TRAIT_RESTRAINED, HANDCUFFED_TRAIT)
else if(handcuffed)
ADD_TRAIT(src, TRAIT_RESTRAINED, HANDCUFFED_TRAIT)
-
+ update_handcuffed()
/mob/living/carbon/on_lying_down(new_lying_angle)
. = ..()
diff --git a/code/modules/mob/living/carbon/carbon_defines.dm b/code/modules/mob/living/carbon/carbon_defines.dm
index 1efea4923e5..d137f110f3a 100644
--- a/code/modules/mob/living/carbon/carbon_defines.dm
+++ b/code/modules/mob/living/carbon/carbon_defines.dm
@@ -125,3 +125,8 @@
var/bodyshape = BODYSHAPE_HUMANOID
COOLDOWN_DECLARE(bleeding_message_cd)
+
+ /// Obscured hide flags (hideflags that can't be seen AND can't be interacted with)
+ var/obscured_slots = NONE
+ /// Covered hide flags (hideflags that can be seen, BUT can't be interacted with)
+ var/covered_slots = NONE
diff --git a/code/modules/mob/living/carbon/carbon_update_icons.dm b/code/modules/mob/living/carbon/carbon_update_icons.dm
index a7b22ed39b5..78f5d38205b 100644
--- a/code/modules/mob/living/carbon/carbon_update_icons.dm
+++ b/code/modules/mob/living/carbon/carbon_update_icons.dm
@@ -1,7 +1,3 @@
-/mob/living/carbon/update_obscured_slots(obscured_flags)
- ..()
- update_body()
-
/// Updates features and clothing attached to a specific limb with limb-specific offsets
/mob/living/carbon/proc/update_features(feature_key)
switch(feature_key)
@@ -338,7 +334,7 @@
overlays_standing[WOUND_LAYER] = wound_overlay
apply_overlay(WOUND_LAYER)
-/mob/living/carbon/update_worn_mask(update_obscured = TRUE)
+/mob/living/carbon/update_worn_mask()
remove_overlay(FACEMASK_LAYER)
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
@@ -349,15 +345,13 @@
inv.update_appearance()
if(wear_mask)
- if(update_obscured)
- update_obscured_slots(wear_mask.flags_inv)
- if(!(check_obscured_slots() & ITEM_SLOT_MASK))
+ if(!(obscured_slots & HIDEMASK))
overlays_standing[FACEMASK_LAYER] = wear_mask.build_worn_icon(default_layer = FACEMASK_LAYER, default_icon_file = 'icons/mob/clothing/mask.dmi')
update_hud_wear_mask(wear_mask)
apply_overlay(FACEMASK_LAYER)
-/mob/living/carbon/update_worn_neck(update_obscured = TRUE)
+/mob/living/carbon/update_worn_neck()
remove_overlay(NECK_LAYER)
if(client && hud_used?.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1])
@@ -365,15 +359,13 @@
inv.update_appearance()
if(wear_neck)
- if(update_obscured)
- update_obscured_slots(wear_neck.flags_inv)
- if(!(check_obscured_slots() & ITEM_SLOT_NECK))
+ if(!(obscured_slots & HIDENECK))
overlays_standing[NECK_LAYER] = wear_neck.build_worn_icon(default_layer = NECK_LAYER, default_icon_file = 'icons/mob/clothing/neck.dmi')
update_hud_neck(wear_neck)
apply_overlay(NECK_LAYER)
-/mob/living/carbon/update_worn_back(update_obscured = TRUE)
+/mob/living/carbon/update_worn_back()
remove_overlay(BACK_LAYER)
if(client && hud_used?.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1])
@@ -381,24 +373,20 @@
inv.update_appearance()
if(back)
- if(update_obscured)
- update_obscured_slots(back.flags_inv)
overlays_standing[BACK_LAYER] = back.build_worn_icon(default_layer = BACK_LAYER, default_icon_file = 'icons/mob/clothing/back.dmi')
update_hud_back(back)
apply_overlay(BACK_LAYER)
-/mob/living/carbon/update_worn_legcuffs(update_obscured = TRUE)
+/mob/living/carbon/update_worn_legcuffs()
remove_overlay(LEGCUFF_LAYER)
clear_alert("legcuffed")
if(legcuffed)
- if(update_obscured)
- update_obscured_slots(legcuffed.flags_inv)
overlays_standing[LEGCUFF_LAYER] = mutable_appearance('icons/mob/simple/mob.dmi', "legcuff1", -LEGCUFF_LAYER)
apply_overlay(LEGCUFF_LAYER)
throw_alert("legcuffed", /atom/movable/screen/alert/restrained/legcuffed, new_master = src.legcuffed)
-/mob/living/carbon/update_worn_head(update_obscured = TRUE)
+/mob/living/carbon/update_worn_head()
remove_overlay(HEAD_LAYER)
if(!get_bodypart(BODY_ZONE_HEAD)) //Decapitated
@@ -409,20 +397,16 @@
inv.update_appearance()
if(head)
- if(update_obscured)
- update_obscured_slots(head.flags_inv)
- if(!(check_obscured_slots() & ITEM_SLOT_HEAD))
+ if(!(obscured_slots & HIDEHEADGEAR))
overlays_standing[HEAD_LAYER] = head.build_worn_icon(default_layer = HEAD_LAYER, default_icon_file = 'icons/mob/clothing/head/default.dmi')
update_hud_head(head)
apply_overlay(HEAD_LAYER)
-/mob/living/carbon/update_worn_handcuffs(update_obscured = TRUE)
+/mob/living/carbon/update_worn_handcuffs()
remove_overlay(HANDCUFF_LAYER)
if(handcuffed)
- if(update_obscured)
- update_obscured_slots(handcuffed.flags_inv)
var/mutable_appearance/handcuff_overlay = mutable_appearance('icons/mob/simple/mob.dmi', "handcuff1", -HANDCUFF_LAYER)
if(handcuffed.blocks_emissive != EMISSIVE_BLOCK_NONE)
handcuff_overlay.overlays += emissive_blocker(handcuff_overlay.icon, handcuff_overlay.icon_state, src, alpha = handcuff_overlay.alpha)
diff --git a/code/modules/mob/living/carbon/examine.dm b/code/modules/mob/living/carbon/examine.dm
index 8e1c9d91fbf..a562204f65e 100644
--- a/code/modules/mob/living/carbon/examine.dm
+++ b/code/modules/mob/living/carbon/examine.dm
@@ -365,14 +365,13 @@
/// Coolects examine information about the mob's clothing and equipment
/mob/living/carbon/proc/get_clothing_examine_info(mob/living/user)
. = list()
- var/obscured = check_obscured_slots()
var/t_He = p_They()
var/t_His = p_Their()
var/t_his = p_their()
var/t_has = p_have()
var/t_is = p_are()
//head
- if(head && !(obscured & ITEM_SLOT_HEAD) && !HAS_TRAIT(head, TRAIT_EXAMINE_SKIP))
+ if(head && !(obscured_slots & HIDEHEADGEAR) && !HAS_TRAIT(head, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_is] wearing [head.examine_title(user)] on [t_his] head."
//back
if(back && !HAS_TRAIT(back, TRAIT_EXAMINE_SKIP))
@@ -388,7 +387,7 @@
var/obj/item/corresponding_item = get_item_for_held_index(part.held_index) || part
. += "[t_He] [t_has] a [corresponding_item.examine_title(user)] in place of [t_his] [initial(part.plaintext_zone)]."
//gloves
- if(gloves && !(obscured & ITEM_SLOT_GLOVES) && !HAS_TRAIT(gloves, TRAIT_EXAMINE_SKIP))
+ if(gloves && !(obscured_slots & HIDEGLOVES) && !HAS_TRAIT(gloves, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_has] [gloves.examine_title(user)] on [t_his] hands."
else if(GET_ATOM_BLOOD_DECAL_LENGTH(src) && num_hands)
var/list/blood_stains = GET_ATOM_BLOOD_DECALS(src)
@@ -402,15 +401,15 @@
var/cables_or_cuffs = istype(handcuffed, /obj/item/restraints/handcuffs/cable) ? "restrained with cable" : "handcuffed"
. += span_warning("[t_He] [t_is] [icon2html(handcuffed, user)] [cables_or_cuffs]!")
//shoes
- if(shoes && !(obscured & ITEM_SLOT_FEET) && !HAS_TRAIT(shoes, TRAIT_EXAMINE_SKIP))
+ if(shoes && !(obscured_slots & HIDESHOES) && !HAS_TRAIT(shoes, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_is] wearing [shoes.examine_title(user)] on [t_his] feet."
//mask
- if(wear_mask && !(obscured & ITEM_SLOT_MASK) && !HAS_TRAIT(wear_mask, TRAIT_EXAMINE_SKIP))
+ if(wear_mask && !(obscured_slots & HIDEMASK) && !HAS_TRAIT(wear_mask, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_has] [wear_mask.examine_title(user)] on [t_his] face."
- if(wear_neck && !(obscured & ITEM_SLOT_NECK) && !HAS_TRAIT(wear_neck, TRAIT_EXAMINE_SKIP))
+ if(wear_neck && !(obscured_slots & HIDENECK) && !HAS_TRAIT(wear_neck, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_is] wearing [wear_neck.examine_title(user)] around [t_his] neck."
//eyes
- if(!(obscured & ITEM_SLOT_EYES) )
+ if(!(obscured_slots & HIDEEYES))
if(glasses && !HAS_TRAIT(glasses, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_has] [glasses.examine_title(user)] covering [t_his] eyes."
else if(HAS_TRAIT(src, TRAIT_UNNATURAL_RED_GLOWY_EYES))
@@ -418,13 +417,12 @@
else if(HAS_TRAIT(src, TRAIT_BLOODSHOT_EYES))
. += span_warning("[t_His] eyes are bloodshot!")
//ears
- if(ears && !(obscured & ITEM_SLOT_EARS) && !HAS_TRAIT(ears, TRAIT_EXAMINE_SKIP))
+ if(ears && !(obscured_slots & HIDEEARS) && !HAS_TRAIT(ears, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_has] [ears.examine_title(user)] on [t_his] ears."
// Yes there's a lot of copypasta here, we can improve this later when carbons are less dumb in general
/mob/living/carbon/human/get_clothing_examine_info(mob/living/user)
. = list()
- var/obscured = check_obscured_slots()
var/t_He = p_They()
var/t_His = p_Their()
var/t_his = p_their()
@@ -432,7 +430,7 @@
var/t_is = p_are()
//uniform
- if(w_uniform && !(obscured & ITEM_SLOT_ICLOTHING) && !HAS_TRAIT(w_uniform, TRAIT_EXAMINE_SKIP))
+ if(w_uniform && !(obscured_slots & HIDEJUMPSUIT) && !HAS_TRAIT(w_uniform, TRAIT_EXAMINE_SKIP))
//accessory
var/accessory_message = ""
if(istype(w_uniform, /obj/item/clothing/under))
@@ -443,16 +441,16 @@
. += "[t_He] [t_is] wearing [w_uniform.examine_title(user)][accessory_message]."
//head
- if(head && !(obscured & ITEM_SLOT_HEAD) && !HAS_TRAIT(head, TRAIT_EXAMINE_SKIP))
+ if(head && !(obscured_slots & HIDEHEADGEAR) && !HAS_TRAIT(head, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_is] wearing [head.examine_title(user)] on [t_his] head."
//mask
- if(wear_mask && !(obscured & ITEM_SLOT_MASK) && !HAS_TRAIT(wear_mask, TRAIT_EXAMINE_SKIP))
+ if(wear_mask && !(obscured_slots & HIDEMASK) && !HAS_TRAIT(wear_mask, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_has] [wear_mask.examine_title(user)] on [t_his] face."
//neck
- if(wear_neck && !(obscured & ITEM_SLOT_NECK) && !HAS_TRAIT(wear_neck, TRAIT_EXAMINE_SKIP))
+ if(wear_neck && !(obscured_slots & HIDENECK) && !HAS_TRAIT(wear_neck, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_is] wearing [wear_neck.examine_title(user)] around [t_his] neck."
//eyes
- if(!(obscured & ITEM_SLOT_EYES) )
+ if(!(obscured_slots & HIDEEYES))
if(glasses && !HAS_TRAIT(glasses, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_has] [glasses.examine_title(user)] covering [t_his] eyes."
else if(HAS_TRAIT(src, TRAIT_UNNATURAL_RED_GLOWY_EYES))
@@ -460,13 +458,13 @@
else if(HAS_TRAIT(src, TRAIT_BLOODSHOT_EYES))
. += span_warning("[t_His] eyes are bloodshot!")
//ears
- if(ears && !(obscured & ITEM_SLOT_EARS) && !HAS_TRAIT(ears, TRAIT_EXAMINE_SKIP))
+ if(ears && !(obscured_slots & HIDEEARS) && !HAS_TRAIT(ears, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_has] [ears.examine_title(user)] on [t_his] ears."
//suit/armor
if(wear_suit && !HAS_TRAIT(wear_suit, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_is] wearing [wear_suit.examine_title(user)]."
//suit/armor storage
- if(s_store && !(obscured & ITEM_SLOT_SUITSTORE) && !HAS_TRAIT(s_store, TRAIT_EXAMINE_SKIP))
+ if(s_store && !(obscured_slots & HIDESUITSTORAGE) && !HAS_TRAIT(s_store, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_is] carrying [s_store.examine_title(user)] on [t_his] [wear_suit.name]."
//back
if(back && !HAS_TRAIT(back, TRAIT_EXAMINE_SKIP))
@@ -491,7 +489,7 @@
var/obj/item/corresponding_item = get_item_for_held_index(part.held_index) || part
. += "[t_He] [t_has] [corresponding_item.examine_title(user)] in place of [t_his] [initial(part.plaintext_zone)]."
//gloves
- if(gloves && !(obscured & ITEM_SLOT_GLOVES) && !HAS_TRAIT(gloves, TRAIT_EXAMINE_SKIP))
+ if(gloves && !(obscured_slots & HIDEGLOVES) && !HAS_TRAIT(gloves, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_has] [gloves.examine_title(user)] on [t_his] hands."
else if(GET_ATOM_BLOOD_DECAL_LENGTH(src) || blood_in_hands)
if(num_hands)
@@ -501,10 +499,10 @@
var/cables_or_cuffs = istype(handcuffed, /obj/item/restraints/handcuffs/cable) ? "restrained with cable" : "handcuffed"
. += span_warning("[t_He] [t_is] [icon2html(handcuffed, user)] [cables_or_cuffs]!")
//belt
- if(belt && !(obscured & ITEM_SLOT_BELT) && !HAS_TRAIT(belt, TRAIT_EXAMINE_SKIP))
+ if(belt && !(obscured_slots & HIDEBELT) && !HAS_TRAIT(belt, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_has] [belt.examine_title(user)] about [t_his] waist."
//shoes
- if(shoes && !(obscured & ITEM_SLOT_FEET) && !HAS_TRAIT(shoes, TRAIT_EXAMINE_SKIP))
+ if(shoes && !(obscured_slots & HIDESHOES) && !HAS_TRAIT(shoes, TRAIT_EXAMINE_SKIP))
. += "[t_He] [t_is] wearing [shoes.examine_title(user)] on [t_his] feet."
/// Collects info displayed about any HUDs the user has when examining src
@@ -584,7 +582,7 @@
/mob/living/carbon/human/examine_more(mob/user)
. = ..()
- if(istype(w_uniform, /obj/item/clothing/under) && !(check_obscured_slots() & ITEM_SLOT_ICLOTHING) && !HAS_TRAIT(w_uniform, TRAIT_EXAMINE_SKIP))
+ if(istype(w_uniform, /obj/item/clothing/under) && !(obscured_slots & HIDEJUMPSUIT) && !HAS_TRAIT(w_uniform, TRAIT_EXAMINE_SKIP))
var/obj/item/clothing/under/undershirt = w_uniform
if(undershirt.has_sensor == BROKEN_SENSORS)
. += list(span_notice("\The [undershirt]'s medical sensors are sparking."))
@@ -622,7 +620,7 @@
/// Reports how old the mob appears to be
/mob/living/carbon/human/proc/get_age_text()
- if((wear_mask?.flags_inv & HIDEFACE) || (head?.flags_inv & HIDEFACE))
+ if(obscured_slots & HIDEFACE)
return
var/age_text
diff --git a/code/modules/mob/living/carbon/human/dummy.dm b/code/modules/mob/living/carbon/human/dummy.dm
index 7ef6b08251c..d5b60051347 100644
--- a/code/modules/mob/living/carbon/human/dummy.dm
+++ b/code/modules/mob/living/carbon/human/dummy.dm
@@ -72,8 +72,13 @@ INITIALIZE_IMMEDIATE(/mob/living/carbon/human/dummy)
qdel(delete)
/mob/living/carbon/human/dummy/has_equipped(obj/item/item, slot, initial = FALSE)
+ SHOULD_CALL_PARENT(FALSE) // assuming direct control
item.item_flags |= IN_INVENTORY
- return item.visual_equipped(src, slot, initial)
+ if(!item.visual_equipped(src, slot, initial))
+ return FALSE
+
+ add_item_coverage(item)
+ return TRUE
/mob/living/carbon/human/dummy/proc/wipe_state()
delete_equipment()
diff --git a/code/modules/mob/living/carbon/human/human.dm b/code/modules/mob/living/carbon/human/human.dm
index d2c86f4da5f..9792d645ebb 100644
--- a/code/modules/mob/living/carbon/human/human.dm
+++ b/code/modules/mob/living/carbon/human/human.dm
@@ -588,7 +588,7 @@
* Returns false if we couldn't wash our hands due to them being obscured, otherwise true
*/
/mob/living/carbon/human/proc/wash_hands(clean_types)
- if(check_covered_slots() & ITEM_SLOT_GLOVES)
+ if(covered_slots & HIDEGLOVES)
return FALSE
if(gloves)
@@ -611,7 +611,7 @@
if(glasses && !is_eyes_covered(ITEM_SLOT_MASK|ITEM_SLOT_HEAD) && glasses.wash(clean_types))
. = TRUE
- if(wear_mask && !(check_covered_slots() & ITEM_SLOT_MASK) && wear_mask.wash(clean_types))
+ if(wear_mask && !(covered_slots & HIDEMASK) && wear_mask.wash(clean_types))
. = TRUE
/**
@@ -623,7 +623,7 @@
. |= COMPONENT_CLEANED
// Wash hands if exposed
- if(!gloves && (clean_types & CLEAN_TYPE_BLOOD) && blood_in_hands > 0 && !(check_covered_slots() & ITEM_SLOT_GLOVES))
+ if(!gloves && (clean_types & CLEAN_TYPE_BLOOD) && blood_in_hands > 0 && !(covered_slots & HIDEGLOVES))
blood_in_hands = 0
update_worn_gloves()
. |= COMPONENT_CLEANED
diff --git a/code/modules/mob/living/carbon/human/human_defense.dm b/code/modules/mob/living/carbon/human/human_defense.dm
index 4e9e37010ee..a3034d11719 100644
--- a/code/modules/mob/living/carbon/human/human_defense.dm
+++ b/code/modules/mob/living/carbon/human/human_defense.dm
@@ -393,7 +393,7 @@
if (!(flags & SHOCK_NO_HUMAN_ANIM))
electrocution_animation(4 SECONDS)
-/mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit) //todo: update this to utilize check_obscured_slots() //and make sure it's check_obscured_slots(TRUE) to stop aciding through visors etc
+/mob/living/carbon/human/acid_act(acidpwr, acid_volume, bodyzone_hit) //todo: update this to utilize obscured_slots //and make sure it's check_obscured_slots(TRUE) to stop aciding through visors etc
var/list/damaged = list()
var/list/inventory_items_to_kill = list()
var/acidity = acidpwr * min(acid_volume*0.005, 0.1)
@@ -673,29 +673,28 @@
/mob/living/carbon/human/proc/burn_clothing(seconds_per_tick, stacks)
var/list/burning_items = list()
- var/covered = check_covered_slots()
//HEAD//
- if(glasses && !(covered & ITEM_SLOT_EYES))
+ if(glasses && !(covered_slots & HIDEEYES))
burning_items += glasses
- if(wear_mask && !(covered & ITEM_SLOT_MASK))
+ if(wear_mask && !(covered_slots & HIDEMASK))
burning_items += wear_mask
- if(wear_neck && !(covered & ITEM_SLOT_NECK))
+ if(wear_neck && !(covered_slots & HIDENECK))
burning_items += wear_neck
- if(ears && !(covered & ITEM_SLOT_EARS))
+ if(ears && !(covered_slots & HIDEEARS))
burning_items += ears
if(head)
burning_items += head
//CHEST//
- if(w_uniform && !(covered & ITEM_SLOT_ICLOTHING))
+ if(w_uniform && !(covered_slots & HIDEJUMPSUIT))
burning_items += w_uniform
if(wear_suit)
burning_items += wear_suit
//ARMS & HANDS//
var/obj/item/clothing/arm_clothes = null
- if(gloves && !(covered & ITEM_SLOT_GLOVES))
+ if(gloves && !(covered_slots & HIDEGLOVES))
arm_clothes = gloves
else if(wear_suit && ((wear_suit.body_parts_covered & HANDS) || (wear_suit.body_parts_covered & ARMS)))
arm_clothes = wear_suit
@@ -706,7 +705,7 @@
//LEGS & FEET//
var/obj/item/clothing/leg_clothes = null
- if(shoes && !(covered & ITEM_SLOT_FEET))
+ if(shoes && !(covered_slots & HIDESHOES))
leg_clothes = shoes
else if(wear_suit && ((wear_suit.body_parts_covered & FEET) || (wear_suit.body_parts_covered & LEGS)))
leg_clothes = wear_suit
diff --git a/code/modules/mob/living/carbon/human/human_helpers.dm b/code/modules/mob/living/carbon/human/human_helpers.dm
index 5c4140223be..5a84b21169a 100644
--- a/code/modules/mob/living/carbon/human/human_helpers.dm
+++ b/code/modules/mob/living/carbon/human/human_helpers.dm
@@ -80,9 +80,7 @@
/mob/living/carbon/human/get_face_name(if_no_face = "Unknown")
if(HAS_TRAIT(src, TRAIT_UNKNOWN))
return if_no_face //We're Unknown, no face information for you
- for(var/obj/item/worn_item in get_equipped_items())
- if(!(worn_item.flags_inv & HIDEFACE))
- continue
+ if(obscured_slots & HIDEFACE)
return if_no_face
var/obj/item/bodypart/head = get_bodypart(BODY_ZONE_HEAD)
if(isnull(head) || (HAS_TRAIT(src, TRAIT_DISFIGURED)) || (head.brutestate + head.burnstate) > 2 || !real_name || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN)) //disfigured. use id-name if possible
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 8c91fee3dc5..044315bd2b8 100644
--- a/code/modules/mob/living/carbon/human/human_update_icons.dm
+++ b/code/modules/mob/living/carbon/human/human_update_icons.dm
@@ -70,14 +70,10 @@ There are several things that need to be remembered:
//damage overlays
update_damage_overlays()
-/mob/living/carbon/human/update_obscured_slots(obscured_flags)
- ..()
- sec_hud_set_security_status()
-
/* --------------------------------------- */
//vvvvvv UPDATE_INV PROCS vvvvvv
-/mob/living/carbon/human/update_worn_undersuit(update_obscured = TRUE)
+/mob/living/carbon/human/update_worn_undersuit()
remove_overlay(UNIFORM_LAYER)
if(client && hud_used)
@@ -88,10 +84,7 @@ There are several things that need to be remembered:
var/obj/item/clothing/under/uniform = w_uniform
update_hud_uniform(uniform)
- if(update_obscured)
- update_obscured_slots(uniform.flags_inv)
-
- if(HAS_TRAIT(uniform, TRAIT_NO_WORN_ICON) || (check_obscured_slots() & ITEM_SLOT_ICLOTHING))
+ if(HAS_TRAIT(uniform, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEJUMPSUIT))
return
var/target_overlay = uniform.icon_state
@@ -136,7 +129,7 @@ There are several things that need to be remembered:
apply_overlay(UNIFORM_LAYER)
check_body_shape(BODYSHAPE_DIGITIGRADE, ITEM_SLOT_ICLOTHING)
-/mob/living/carbon/human/update_worn_id(update_obscured = TRUE)
+/mob/living/carbon/human/update_worn_id()
remove_overlay(ID_LAYER)
if(client && hud_used)
@@ -149,9 +142,6 @@ There are several things that need to be remembered:
var/obj/item/worn_item = wear_id
update_hud_id(worn_item)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON))
return
@@ -169,7 +159,7 @@ There are several things that need to be remembered:
apply_overlay(ID_LAYER)
-/mob/living/carbon/human/update_worn_gloves(update_obscured = TRUE)
+/mob/living/carbon/human/update_worn_gloves()
remove_overlay(GLOVES_LAYER)
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_GLOVES) + 1])
@@ -198,10 +188,7 @@ There are several things that need to be remembered:
var/obj/item/worn_item = gloves
update_hud_gloves(worn_item)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
- if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots() & ITEM_SLOT_GLOVES))
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEGLOVES))
return
var/icon_file = 'icons/mob/clothing/hands.dmi'
@@ -233,7 +220,7 @@ There are several things that need to be remembered:
overlays_standing[GLOVES_LAYER] = gloves_overlay
apply_overlay(GLOVES_LAYER)
-/mob/living/carbon/human/update_worn_glasses(update_obscured = TRUE)
+/mob/living/carbon/human/update_worn_glasses()
remove_overlay(GLASSES_LAYER)
var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD)
@@ -248,10 +235,7 @@ There are several things that need to be remembered:
var/obj/item/worn_item = glasses
update_hud_glasses(worn_item)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
- if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots() & ITEM_SLOT_EYES))
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEEYES))
return
var/icon_file = 'icons/mob/clothing/eyes.dmi'
@@ -261,7 +245,8 @@ There are several things that need to be remembered:
overlays_standing[GLASSES_LAYER] = glasses_overlay
apply_overlay(GLASSES_LAYER)
-/mob/living/carbon/human/update_worn_ears(update_obscured = TRUE)
+
+/mob/living/carbon/human/update_worn_ears()
remove_overlay(EARS_LAYER)
var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD)
@@ -276,10 +261,7 @@ There are several things that need to be remembered:
var/obj/item/worn_item = ears
update_hud_ears(worn_item)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
- if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots() & ITEM_SLOT_EARS))
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEEARS))
return
var/icon_file = 'icons/mob/clothing/ears.dmi'
@@ -289,7 +271,7 @@ There are several things that need to be remembered:
overlays_standing[EARS_LAYER] = ears_overlay
apply_overlay(EARS_LAYER)
-/mob/living/carbon/human/update_worn_neck(update_obscured = TRUE)
+/mob/living/carbon/human/update_worn_neck()
remove_overlay(NECK_LAYER)
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_NECK) + 1])
@@ -300,10 +282,7 @@ There are several things that need to be remembered:
var/obj/item/worn_item = wear_neck
update_hud_neck(wear_neck)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
- if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots() & ITEM_SLOT_NECK))
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDENECK))
return
var/icon_file = 'icons/mob/clothing/neck.dmi'
@@ -315,7 +294,7 @@ There are several things that need to be remembered:
apply_overlay(NECK_LAYER)
-/mob/living/carbon/human/update_worn_shoes(update_obscured = TRUE)
+/mob/living/carbon/human/update_worn_shoes()
remove_overlay(SHOES_LAYER)
if(num_legs < 2)
@@ -329,10 +308,7 @@ There are several things that need to be remembered:
var/obj/item/worn_item = shoes
update_hud_shoes(worn_item)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
- if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots() & ITEM_SLOT_FEET))
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDESHOES))
return
var/icon_file = DEFAULT_SHOES_FILE
@@ -356,7 +332,7 @@ There are several things that need to be remembered:
apply_overlay(SHOES_LAYER)
check_body_shape(BODYSHAPE_DIGITIGRADE, ITEM_SLOT_FEET)
-/mob/living/carbon/human/update_suit_storage(update_obscured = TRUE)
+/mob/living/carbon/human/update_suit_storage()
remove_overlay(SUIT_STORE_LAYER)
if(client && hud_used)
@@ -367,10 +343,7 @@ There are several things that need to be remembered:
var/obj/item/worn_item = s_store
update_hud_s_store(worn_item)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
- if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots() & ITEM_SLOT_SUITSTORE))
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDESUITSTORAGE))
return
var/mutable_appearance/s_store_overlay = worn_item.build_worn_icon(default_layer = SUIT_STORE_LAYER, default_icon_file = 'icons/mob/clothing/belt_mirror.dmi')
@@ -379,7 +352,7 @@ There are several things that need to be remembered:
overlays_standing[SUIT_STORE_LAYER] = s_store_overlay
apply_overlay(SUIT_STORE_LAYER)
-/mob/living/carbon/human/update_worn_head(update_obscured = TRUE)
+/mob/living/carbon/human/update_worn_head()
remove_overlay(HEAD_LAYER)
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1])
var/atom/movable/screen/inventory/inv = hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_HEAD) + 1]
@@ -389,10 +362,7 @@ There are several things that need to be remembered:
var/obj/item/worn_item = head
update_hud_head(worn_item)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
- if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots() & ITEM_SLOT_HEAD))
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEHEADGEAR))
return
var/icon_file = 'icons/mob/clothing/head/default.dmi'
@@ -405,7 +375,7 @@ There are several things that need to be remembered:
apply_overlay(HEAD_LAYER)
check_body_shape(BODYSHAPE_SNOUTED, ITEM_SLOT_HEAD)
-/mob/living/carbon/human/update_worn_belt(update_obscured = TRUE)
+/mob/living/carbon/human/update_worn_belt()
remove_overlay(BELT_LAYER)
if(client && hud_used)
@@ -416,10 +386,7 @@ There are several things that need to be remembered:
var/obj/item/worn_item = belt
update_hud_belt(worn_item)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
- if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots() & ITEM_SLOT_BELT))
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEBELT))
return
var/icon_file = 'icons/mob/clothing/belt.dmi'
@@ -431,7 +398,7 @@ There are several things that need to be remembered:
apply_overlay(BELT_LAYER)
-/mob/living/carbon/human/update_worn_oversuit(update_obscured = TRUE)
+/mob/living/carbon/human/update_worn_oversuit()
remove_overlay(SUIT_LAYER)
if(client && hud_used)
@@ -442,9 +409,6 @@ There are several things that need to be remembered:
var/obj/item/worn_item = wear_suit
update_hud_wear_suit(worn_item)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON))
return
@@ -479,7 +443,7 @@ There are several things that need to be remembered:
client.screen += r_store
update_observer_view(r_store)
-/mob/living/carbon/human/update_worn_mask(update_obscured = TRUE)
+/mob/living/carbon/human/update_worn_mask()
remove_overlay(FACEMASK_LAYER)
var/obj/item/bodypart/head/my_head = get_bodypart(BODY_ZONE_HEAD)
@@ -494,10 +458,7 @@ There are several things that need to be remembered:
var/obj/item/worn_item = wear_mask
update_hud_wear_mask(worn_item)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
- if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (check_obscured_slots() & ITEM_SLOT_MASK))
+ if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON) || (obscured_slots & HIDEMASK))
return
var/icon_file = 'icons/mob/clothing/mask.dmi'
@@ -509,7 +470,7 @@ There are several things that need to be remembered:
apply_overlay(FACEMASK_LAYER)
check_body_shape(BODYSHAPE_SNOUTED, ITEM_SLOT_MASK)
-/mob/living/carbon/human/update_worn_back(update_obscured = TRUE)
+/mob/living/carbon/human/update_worn_back()
remove_overlay(BACK_LAYER)
if(client && hud_used && hud_used.inv_slots[TOBITSHIFT(ITEM_SLOT_BACK) + 1])
@@ -521,9 +482,6 @@ There are several things that need to be remembered:
var/mutable_appearance/back_overlay
update_hud_back(worn_item)
- if(update_obscured)
- update_obscured_slots(worn_item.flags_inv)
-
if(HAS_TRAIT(worn_item, TRAIT_NO_WORN_ICON))
return
diff --git a/code/modules/mob/living/carbon/human/init_signals.dm b/code/modules/mob/living/carbon/human/init_signals.dm
index 4bea0e925ea..06016b7a07c 100644
--- a/code/modules/mob/living/carbon/human/init_signals.dm
+++ b/code/modules/mob/living/carbon/human/init_signals.dm
@@ -13,15 +13,9 @@
RegisterSignal(src, COMSIG_COMPONENT_CLEAN_FACE_ACT, PROC_REF(clean_face))
- // List of signals which force a visible name update
- // TRAIT_UNKNOWN is excluded as it calls update_ID_card which also calls update_visible_name
- var/static/list/name_update_signals = list(
- SIGNAL_ADDTRAIT(TRAIT_INVISIBLE_MAN),
- SIGNAL_REMOVETRAIT(TRAIT_INVISIBLE_MAN),
- SIGNAL_ADDTRAIT(TRAIT_DISFIGURED),
- SIGNAL_REMOVETRAIT(TRAIT_DISFIGURED),
- )
- RegisterSignals(src, name_update_signals, PROC_REF(update_visible_name))
+ RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_HUSK), SIGNAL_REMOVETRAIT(TRAIT_HUSK)), PROC_REF(refresh_obscured))
+ RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_INVISIBLE_MAN), SIGNAL_REMOVETRAIT(TRAIT_INVISIBLE_MAN)), PROC_REF(invisible_man_toggle))
+ RegisterSignals(src, list(SIGNAL_ADDTRAIT(TRAIT_DISFIGURED), SIGNAL_REMOVETRAIT(TRAIT_DISFIGURED)), PROC_REF(update_visible_name))
/// Gaining or losing [TRAIT_DWARF] updates our height and grants passtable
/mob/living/carbon/human/proc/on_dwarf_trait(datum/source)
@@ -91,3 +85,9 @@
vision_distance = COMBAT_MESSAGE_RANGE,
)
playsound(src, SFX_RUSTLE, 50, TRUE, -5, frequency = 0.8)
+
+/// When [TRAIT_INVISIBLE_MAN] is added or removed we need to update a few things
+/mob/living/carbon/human/proc/invisible_man_toggle(datum/source)
+ SIGNAL_HANDLER
+ refresh_obscured()
+ update_visible_name()
diff --git a/code/modules/mob/living/carbon/human/inventory.dm b/code/modules/mob/living/carbon/human/inventory.dm
index 0805e2a1169..a2dfad08eee 100644
--- a/code/modules/mob/living/carbon/human/inventory.dm
+++ b/code/modules/mob/living/carbon/human/inventory.dm
@@ -215,7 +215,6 @@
. = ..() //See mob.dm for an explanation on this and some rage about people copypasting instead of calling ..() like they should.
if(!. || !item_dropping)
return
- var/not_handled = FALSE //if we actually unequipped an item, this is because we dont want to run this proc twice, once for carbons and once for humans
if(item_dropping == wear_suit)
if(s_store && invdrop)
dropItemToGround(s_store, TRUE) //It makes no sense for your suit storage to stay on you if you drop your suit.
@@ -280,15 +279,12 @@
s_store = null
if(!QDELETED(src))
update_suit_storage()
- else
- not_handled = TRUE
- if(not_handled)
- return
-
- update_equipment_speed_mods()
- update_obscured_slots(item_dropping.flags_inv)
- hud_used?.update_locked_slots()
+/mob/living/carbon/human/item_coverage_changed(added_slots, removed_slots)
+ . = ..()
+ if((added_slots|removed_slots) & HIDEFACE)
+ sec_hud_set_security_status()
+ update_visible_name()
/mob/living/carbon/human/toggle_internals(obj/item/tank, is_external = FALSE)
// Just close the tank if it's the one the mob already has open.
@@ -420,9 +416,3 @@
new_bodypart.try_attach_limb(src, TRUE)
hand_bodyparts[i] = new_bodypart
..() //Don't redraw hands until we have organs for them
-
-/mob/living/carbon/human/update_equipment(obj/item/source)
- . = ..()
- // If the item we equipped/unequipped hides our face, we (potentially) need to update our name
- if (source.flags_inv & HIDEFACE)
- update_visible_name()
diff --git a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
index e03cef43cf3..9d0797e0b04 100644
--- a/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
+++ b/code/modules/mob/living/carbon/human/species_types/mushpeople.dm
@@ -78,12 +78,7 @@
return SSaccessories.caps_list
/datum/bodypart_overlay/mutant/mushroom_cap/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if((human.head?.flags_inv & HIDEHAIR) || (human.wear_mask?.flags_inv & HIDEHAIR))
- return FALSE
- return TRUE
+ return !(bodypart_owner.owner?.obscured_slots & HIDEHAIR)
/datum/bodypart_overlay/mutant/mushroom_cap/override_color(obj/item/bodypart/bodypart_owner)
//The mushroom cap is red by default (can still be dyed)
diff --git a/code/modules/mob/living/carbon/inventory.dm b/code/modules/mob/living/carbon/inventory.dm
index a2f4b623826..f4cf1757d9a 100644
--- a/code/modules/mob/living/carbon/inventory.dm
+++ b/code/modules/mob/living/carbon/inventory.dm
@@ -1,21 +1,3 @@
-/// Returns a list of slots that are *visibly* covered by clothing and thus cannot be seen by others
-/mob/living/carbon/proc/check_obscured_slots()
- var/hidden_slots = NONE
-
- for(var/obj/item/equipped_item in get_equipped_items())
- hidden_slots |= equipped_item.flags_inv
-
- return hidden_slots_to_inventory_slots(hidden_slots)
-
-/// Returns a list of slots that are protected by other clothing, but could possibly be seen by others, via transparent visors and similar stuff
-/mob/living/carbon/proc/check_covered_slots()
- var/hidden_slots = NONE
-
- for(var/obj/item/equipped_item in get_equipped_items())
- hidden_slots |= equipped_item.flags_inv | equipped_item.transparent_protection
-
- return hidden_slots_to_inventory_slots(hidden_slots)
-
/// Convers HIDEX to ITEM_SLOT_X, should be phased out in favor of using latter everywhere later
/proc/hidden_slots_to_inventory_slots(hidden_slots)
var/obscured = NONE
@@ -81,34 +63,13 @@
/// Returns items which are currently visible on the mob
/mob/living/carbon/proc/get_visible_items()
- var/static/list/visible_slots = list(
- ITEM_SLOT_OCLOTHING,
- ITEM_SLOT_ICLOTHING,
- ITEM_SLOT_GLOVES,
- ITEM_SLOT_EYES,
- ITEM_SLOT_EARS,
- ITEM_SLOT_MASK,
- ITEM_SLOT_HEAD,
- ITEM_SLOT_FEET,
- ITEM_SLOT_ID,
- ITEM_SLOT_BELT,
- ITEM_SLOT_BACK,
- ITEM_SLOT_NECK,
- ITEM_SLOT_HANDS,
- ITEM_SLOT_SUITSTORE,
- ITEM_SLOT_HANDCUFFED,
- ITEM_SLOT_LEGCUFFED,
- )
- var/list/obscured = check_obscured_slots()
var/list/visible_items = list()
- for (var/slot in visible_slots)
- if (obscured & slot)
- continue
- var/obj/item/equipped = get_item_by_slot(slot)
- if (equipped)
- visible_items += equipped
+ var/obscured_item_slots = hidden_slots_to_inventory_slots(obscured_slots)
for (var/obj/item/held in held_items)
visible_items += held
+ for(var/obj/item/thing in get_equipped_items())
+ if(!(get_slot_by_item(thing) & obscured_item_slots))
+ visible_items += thing
return visible_items
/mob/living/carbon/proc/equip_in_one_of_slots(obj/item/equipping, list/slots, qdel_on_fail = TRUE, indirect_action = FALSE)
@@ -154,13 +115,10 @@
equipping.pulledby.stop_pulling()
equipping.screen_loc = null
- if(client)
- client.screen -= equipping
+ client?.screen -= equipping
- if(observers?.len)
- for(var/mob/dead/observe as anything in observers)
- if(observe.client)
- observe.client.screen -= equipping
+ for(var/mob/dead/observe as anything in observers)
+ observe.client?.screen -= equipping
equipping.forceMove(src)
SET_PLANE_EXPLICIT(equipping, ABOVE_HUD_PLANE, src)
@@ -190,7 +148,6 @@
update_worn_neck(equipping)
if(ITEM_SLOT_HANDCUFFED)
set_handcuffed(equipping)
- update_handcuffed()
if(ITEM_SLOT_LEGCUFFED)
legcuffed = equipping
update_worn_legcuffs()
@@ -208,19 +165,32 @@
return not_handled
-/mob/living/carbon/has_equipped(obj/item/item, slot, initial)
- . = ..()
- hud_used?.update_locked_slots()
-
/mob/living/carbon/get_equipped_speed_mod_items()
return ..() + get_equipped_items()
+/mob/living/carbon/has_equipped(obj/item/item, slot, initial = FALSE)
+ . = ..()
+ if(!.)
+ return
+
+ update_equipment_speed_mods()
+ hud_used?.update_locked_slots()
+ add_item_coverage(item)
+
+/mob/living/carbon/has_unequipped(obj/item/item)
+ . = ..() // NB: ATP the item is still in the slot, but no longer has the IN_INVENTORY flag (so is not returned by get_equipped_items)
+ if(!.)
+ return
+
+ update_equipment_speed_mods()
+ hud_used?.update_locked_slots()
+ remove_item_coverage(item)
+
/mob/living/carbon/doUnEquip(obj/item/item_dropping, force, newloc, no_move, invdrop = TRUE, silent = FALSE)
. = ..() //Sets the default return value to what the parent returns.
if(!. || !item_dropping) //We don't want to set anything to null if the parent returned 0.
return
- var/not_handled = FALSE //if we actually unequipped an item, this is because we dont want to run this proc twice, once for carbons and once for humans
if(item_dropping == head)
head = null
if(!QDELETED(src))
@@ -241,14 +211,10 @@
set_handcuffed(null)
if(buckled?.buckle_requires_restraints)
buckled.unbuckle_mob(src)
- if(!QDELETED(src))
- update_handcuffed()
else if(item_dropping == legcuffed)
legcuffed = null
if(!QDELETED(src))
update_worn_legcuffs()
- else
- not_handled = TRUE
// Not an else-if because we're probably equipped in another slot
if(item_dropping == internal && (QDELETED(src) || QDELETED(item_dropping) || item_dropping.loc != src))
@@ -256,12 +222,44 @@
if(!QDELETED(src))
update_mob_action_buttons(UPDATE_BUTTON_STATUS)
- if(not_handled)
- return
+/// Adds the passed item's coverage to the mob's coverage related flags
+/mob/living/carbon/proc/add_item_coverage(obj/item/item)
+ var/pre_coverage = obscured_slots
+ obscured_slots |= item.flags_inv
+ covered_slots |= item.flags_inv | item.transparent_protection
+ if(pre_coverage != obscured_slots)
+ item_coverage_changed(obscured_slots & ~pre_coverage, pre_coverage & ~obscured_slots)
- update_equipment_speed_mods()
- update_obscured_slots(item_dropping.flags_inv)
- hud_used?.update_locked_slots()
+/// Removes the passed item's coverage from the mob's coverage related flags
+/mob/living/carbon/proc/remove_item_coverage(obj/item/item)
+ refresh_obscured() // No way to remove a single item's coverage without recalculating everything
+
+/mob/living/carbon/refresh_obscured()
+ var/pre_coverage = obscured_slots
+
+ obscured_slots = NONE
+ covered_slots = NONE
+ for(var/obj/item/other_equipped_item as anything in get_equipped_items())
+ obscured_slots |= other_equipped_item.flags_inv
+ covered_slots |= other_equipped_item.flags_inv | other_equipped_item.transparent_protection
+
+ if(HAS_TRAIT(src, TRAIT_HUSK) || HAS_TRAIT(src, TRAIT_INVISIBLE_MAN))
+ obscured_slots |= HIDEHAIR|HIDEFACIALHAIR
+
+ if(pre_coverage != obscured_slots)
+ item_coverage_changed(obscured_slots & ~pre_coverage, pre_coverage & ~obscured_slots)
+
+/**
+ * Called when a mob's obscured slots change
+ *
+ * Args
+ * * added_slots - slots that were added to obscured_slots
+ * * removed_slots - slots that were removed from obscured_slots
+ */
+/mob/living/carbon/proc/item_coverage_changed(added_slots, removed_slots)
+ update_clothing(hidden_slots_to_inventory_slots(added_slots|removed_slots))
+ if((added_slots|removed_slots) & (HIDEJUMPSUIT|HIDEEARS|HIDEEYES|HIDEHAIR|HIDEFACIALHAIR|HIDESNOUT|HIDEMUTWINGS|HIDEANTENNAE))
+ update_body()
/// Returns the helmet if an air tank compatible helmet is equipped.
/mob/living/carbon/proc/can_breathe_helmet()
diff --git a/code/modules/mob/living/emote.dm b/code/modules/mob/living/emote.dm
index 98077996f0a..2c007f75ae5 100644
--- a/code/modules/mob/living/emote.dm
+++ b/code/modules/mob/living/emote.dm
@@ -630,7 +630,7 @@
TIMER_COOLDOWN_START(user, COOLDOWN_YAWN_PROPAGATION, cooldown * 3)
var/mob/living/carbon/carbon_user = user
- if(istype(carbon_user) && ((carbon_user.wear_mask?.flags_inv & HIDEFACE) || carbon_user.head?.flags_inv & HIDEFACE))
+ if(carbon_user.obscured_slots & HIDEFACE)
return // if your face is obscured, skip propagation
var/propagation_distance = user.client ? 5 : 2 // mindless mobs are less able to spread yawns
diff --git a/code/modules/mob/living/living.dm b/code/modules/mob/living/living.dm
index f0d3e1f249e..d8352bacb74 100644
--- a/code/modules/mob/living/living.dm
+++ b/code/modules/mob/living/living.dm
@@ -2478,11 +2478,6 @@ GLOBAL_LIST_EMPTY(fire_appearances)
if(GRAB_KILL)
add_movespeed_modifier(/datum/movespeed_modifier/grab_slowdown/kill)
-
-/// Only defined for carbons who can wear masks and helmets, we just assume other mobs have visible faces
-/mob/living/proc/is_face_visible()
- return TRUE
-
/// Sprite to show for photocopying mob butts
/mob/living/proc/get_butt_sprite()
return null
diff --git a/code/modules/mob/living/simple_animal/bot/secbot.dm b/code/modules/mob/living/simple_animal/bot/secbot.dm
index d2fb1785b86..d902fdf1eff 100644
--- a/code/modules/mob/living/simple_animal/bot/secbot.dm
+++ b/code/modules/mob/living/simple_animal/bot/secbot.dm
@@ -349,7 +349,6 @@
return FALSE
if(!current_target.handcuffed)
current_target.set_handcuffed(new cuff_type(current_target))
- current_target.update_handcuffed()
playsound(src, SFX_LAW, 50, FALSE)
back_to_idle()
diff --git a/code/modules/mob/mob.dm b/code/modules/mob/mob.dm
index a047f0dc1ed..4f5432ee1f0 100644
--- a/code/modules/mob/mob.dm
+++ b/code/modules/mob/mob.dm
@@ -675,18 +675,25 @@
return
// check to see if their face is blocked or, if not, a signal blocks it
- if(examined_mob.is_face_visible() && SEND_SIGNAL(src, COMSIG_MOB_EYECONTACT, examined_mob, TRUE) != COMSIG_BLOCK_EYECONTACT)
+ if(examined_mob.can_eye_contact() && SEND_SIGNAL(src, COMSIG_MOB_EYECONTACT, examined_mob, TRUE) != COMSIG_BLOCK_EYECONTACT)
var/obj/item/clothing/eye_cover = examined_mob.is_eyes_covered()
if (!eye_cover || (!eye_cover.tint && !eye_cover.flash_protect))
var/msg = span_smallnotice("You make eye contact with [examined_mob].")
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(to_chat), src, msg), 0.3 SECONDS) // so the examine signal has time to fire and this will print after
- if(!imagined_eye_contact && is_face_visible() && !examined_mob.is_blind() && SEND_SIGNAL(examined_mob, COMSIG_MOB_EYECONTACT, src, FALSE) != COMSIG_BLOCK_EYECONTACT)
+ if(!imagined_eye_contact && can_eye_contact() && !examined_mob.is_blind() && SEND_SIGNAL(examined_mob, COMSIG_MOB_EYECONTACT, src, FALSE) != COMSIG_BLOCK_EYECONTACT)
var/obj/item/clothing/eye_cover = is_eyes_covered()
if (!eye_cover || (!eye_cover.tint && !eye_cover.flash_protect))
var/msg = span_smallnotice("[src] makes eye contact with you.")
addtimer(CALLBACK(GLOBAL_PROC, GLOBAL_PROC_REF(to_chat), examined_mob, msg), 0.3 SECONDS)
+/// Checks if we can make eye contact or someone can make eye contact with us
+/mob/living/proc/can_eye_contact()
+ return TRUE
+
+/mob/living/carbon/can_eye_contact()
+ return !(obscured_slots & HIDEFACE)
+
/**
* Called by using Activate Held Object with an empty hand/limb
*
@@ -1502,11 +1509,6 @@
else
living_flags |= QUEUE_NUTRITION_UPDATE
-/// Update mob stats based on equipment we are wearing when an item is equipped/dropped, to be overriden by children
-/// source - Item that caused the update by being equipped/dropped
-/mob/proc/update_equipment(obj/item/source)
- update_equipment_speed_mods()
-
/// Apply a proper movespeed modifier based on items we have equipped
/mob/proc/update_equipment_speed_mods()
var/speedies = 0
diff --git a/code/modules/mob/mob_update_icons.dm b/code/modules/mob/mob_update_icons.dm
index b14da72e830..210c041408c 100644
--- a/code/modules/mob/mob_update_icons.dm
+++ b/code/modules/mob/mob_update_icons.dm
@@ -42,42 +42,24 @@
if(slot_flags & ITEM_SLOT_HANDS)
update_held_items()
-///Updates item slots obscured by this item (or using an override of flags to check)
-/mob/proc/update_obscured_slots(obscured_flags)
- if(obscured_flags & HIDEGLOVES)
- update_worn_gloves(update_obscured = FALSE)
- if(obscured_flags & HIDESUITSTORAGE)
- update_suit_storage(update_obscured = FALSE)
- if(obscured_flags & HIDEJUMPSUIT)
- update_worn_undersuit(update_obscured = FALSE)
- if(obscured_flags & HIDESHOES)
- update_worn_shoes(update_obscured = FALSE)
- if(obscured_flags & HIDEMASK)
- update_worn_mask(update_obscured = FALSE)
- if(obscured_flags & HIDEBELT)
- update_worn_belt(update_obscured = FALSE)
- if(obscured_flags & HIDEEARS)
- update_worn_ears(update_obscured = FALSE)
- if(obscured_flags & HIDEEYES)
- update_worn_glasses(update_obscured = FALSE)
- if(obscured_flags & HIDENECK)
- update_worn_neck(update_obscured = FALSE)
- if(obscured_flags & HIDEHEADGEAR)
- update_worn_head(update_obscured = FALSE)
+/// Recalculates the mob's obscured and covered slots based on currently equipped items
+/mob/proc/refresh_obscured()
+ SIGNAL_HANDLER
+ return
/mob/proc/update_icons()
return
///Updates the handcuff overlay & HUD element.
-/mob/proc/update_worn_handcuffs(update_obscured = FALSE)
+/mob/proc/update_worn_handcuffs()
return
///Updates the legcuff overlay & HUD element.
-/mob/proc/update_worn_legcuffs(update_obscured = FALSE)
+/mob/proc/update_worn_legcuffs()
return
///Updates the back overlay & HUD element.
-/mob/proc/update_worn_back(update_obscured = FALSE)
+/mob/proc/update_worn_back()
return
///Updates the held items overlay(s) & HUD element.
@@ -86,27 +68,27 @@
SEND_SIGNAL(src, COMSIG_MOB_UPDATE_HELD_ITEMS)
///Updates the mask overlay & HUD element.
-/mob/proc/update_worn_mask(update_obscured = FALSE)
+/mob/proc/update_worn_mask()
return
///Updates the neck overlay & HUD element.
-/mob/proc/update_worn_neck(update_obscured = FALSE)
+/mob/proc/update_worn_neck()
return
///Updates the oversuit overlay & HUD element.
-/mob/proc/update_worn_oversuit(update_obscured = FALSE)
+/mob/proc/update_worn_oversuit()
return
///Updates the undersuit/uniform overlay & HUD element.
-/mob/proc/update_worn_undersuit(update_obscured = FALSE)
+/mob/proc/update_worn_undersuit()
return
///Updates the belt overlay & HUD element.
-/mob/proc/update_worn_belt(update_obscured = FALSE)
+/mob/proc/update_worn_belt()
return
///Updates the on-head overlay & HUD element.
-/mob/proc/update_worn_head(update_obscured = FALSE)
+/mob/proc/update_worn_head()
return
///Updates every part of a carbon's body. Including parts, mutant parts, lips, underwear, and socks.
@@ -117,23 +99,23 @@
return
///Updates the glasses overlay & HUD element.
-/mob/proc/update_worn_glasses(update_obscured = FALSE)
+/mob/proc/update_worn_glasses()
return
///Updates the id overlay & HUD element.
-/mob/proc/update_worn_id(update_obscured = FALSE)
+/mob/proc/update_worn_id()
return
///Updates the shoes overlay & HUD element.
-/mob/proc/update_worn_shoes(update_obscured = FALSE)
+/mob/proc/update_worn_shoes()
return
///Updates the glasses overlay & HUD element.
-/mob/proc/update_worn_gloves(update_obscured = FALSE)
+/mob/proc/update_worn_gloves()
return
///Updates the suit storage overlay & HUD element.
-/mob/proc/update_suit_storage(update_obscured = FALSE)
+/mob/proc/update_suit_storage()
return
///Updates the pocket overlay & HUD element.
@@ -141,5 +123,5 @@
return
///Updates the headset overlay & HUD element.
-/mob/proc/update_worn_ears(update_obscured = FALSE)
+/mob/proc/update_worn_ears()
return
diff --git a/code/modules/mod/mod_activation.dm b/code/modules/mod/mod_activation.dm
index 76fa31d5eac..d2baba9c8d2 100644
--- a/code/modules/mod/mod_activation.dm
+++ b/code/modules/mod/mod_activation.dm
@@ -271,7 +271,7 @@
part.alternate_worn_layer = part_datum.unsealed_layer
update_speed()
wearer.update_clothing(part.slot_flags | slot_flags)
- wearer.update_obscured_slots(part.visor_flags_inv)
+ wearer.refresh_obscured()
if((part.clothing_flags & (MASKINTERNALS|HEADINTERNALS)) && wearer.invalid_internals())
wearer.cutoff_internals()
SEND_SIGNAL(src, COMSIG_MOD_PART_SEALED, part_datum)
diff --git a/code/modules/mod/mod_control.dm b/code/modules/mod/mod_control.dm
index d6974643acf..883eee631d0 100644
--- a/code/modules/mod/mod_control.dm
+++ b/code/modules/mod/mod_control.dm
@@ -191,6 +191,7 @@
set_wearer(user)
else if(wearer)
unset_wearer()
+ return ..()
/obj/item/mod/control/dropped(mob/user)
. = ..()
diff --git a/code/modules/mod/mod_theme.dm b/code/modules/mod/mod_theme.dm
index 2a1c677b641..db4b0f61c25 100644
--- a/code/modules/mod/mod_theme.dm
+++ b/code/modules/mod/mod_theme.dm
@@ -167,6 +167,7 @@
part.worn_icon = used_skin[MOD_WORN_ICON_OVERRIDE] || 'icons/mob/clothing/modsuit/mod_clothing.dmi'
part.icon_state = "[skin]-[part.base_icon_state][mod.get_part_datum(part).sealed ? "-sealed" : ""]"
mod.wearer?.update_clothing(part.slot_flags)
+ mod.wearer?.refresh_obscured()
/datum/armor/mod_theme
melee = 10
diff --git a/code/modules/photography/camera/camera.dm b/code/modules/photography/camera/camera.dm
index c55c038de29..9ef40666fc3 100644
--- a/code/modules/photography/camera/camera.dm
+++ b/code/modules/photography/camera/camera.dm
@@ -315,8 +315,9 @@
qdel(clone_area)
get_icon.Blend("#000", ICON_UNDERLAY)
for(var/mob/living/carbon/human/person in mobs)
- if(person.is_face_visible())
- names += "[person.name]"
+ if(person.obscured_slots & HIDEFACE)
+ continue
+ names += "[person.name]"
var/datum/picture/picture = new("picture", desc.Join("
"), mobs_spotted, dead_spotted, names, get_icon, null, psize_x, psize_y, blueprints, can_see_ghosts = see_ghosts)
after_picture(user, picture)
diff --git a/code/modules/surgery/bodyparts/dismemberment.dm b/code/modules/surgery/bodyparts/dismemberment.dm
index 0e25e1b981f..fb979ab054d 100644
--- a/code/modules/surgery/bodyparts/dismemberment.dm
+++ b/code/modules/surgery/bodyparts/dismemberment.dm
@@ -206,10 +206,9 @@
arm_owner.dropItemToGround(arm_owner.get_item_for_held_index(held_index), 1)
. = ..()
if(arm_owner.handcuffed)
- arm_owner.handcuffed.forceMove(drop_location())
- arm_owner.handcuffed.dropped(arm_owner)
+ var/obj/item/lost_cuffs = arm_owner.handcuffed
arm_owner.set_handcuffed(null)
- arm_owner.update_handcuffed()
+ arm_owner.dropItemToGround(lost_cuffs, force = TRUE)
if(arm_owner.hud_used)
var/atom/movable/screen/inventory/hand/associated_hand = arm_owner.hud_used.hand_slots["[held_index]"]
associated_hand?.update_appearance()
@@ -222,13 +221,8 @@
. = ..()
if(special || !leg_owner)
return
- if(leg_owner.legcuffed)
- leg_owner.legcuffed.forceMove(drop_location())
- leg_owner.legcuffed.dropped(leg_owner)
- leg_owner.legcuffed = null
- leg_owner.update_worn_legcuffs()
- if(leg_owner.shoes)
- leg_owner.dropItemToGround(leg_owner.shoes, force = TRUE)
+ leg_owner.dropItemToGround(leg_owner.legcuffed, force = TRUE)
+ leg_owner.dropItemToGround(leg_owner.shoes, force = TRUE)
/obj/item/bodypart/head/drop_limb(special, dismembered, move_to_floor = TRUE)
if(!special)
diff --git a/code/modules/surgery/bodyparts/head_hair_and_lips.dm b/code/modules/surgery/bodyparts/head_hair_and_lips.dm
index 6cc44094d21..1d3ed4dfe5e 100644
--- a/code/modules/surgery/bodyparts/head_hair_and_lips.dm
+++ b/code/modules/surgery/bodyparts/head_hair_and_lips.dm
@@ -11,17 +11,10 @@
LAZYNULL(hair_masks)
if(human_head_owner)
for(var/obj/item/worn_item in human_head_owner.get_equipped_items())
- if(worn_item.flags_inv & HIDEHAIR)
- hair_hidden = TRUE
- if(worn_item.flags_inv & HIDEFACIALHAIR)
- facial_hair_hidden = TRUE
if(worn_item.hair_mask)
LAZYSET(hair_masks, worn_item.hair_mask, TRUE)
-
- //invisibility and husk stuff
- if(HAS_TRAIT(human_head_owner, TRAIT_INVISIBLE_MAN) || HAS_TRAIT(human_head_owner, TRAIT_HUSK))
- hair_hidden = TRUE
- facial_hair_hidden = TRUE
+ hair_hidden = !!(human_head_owner.obscured_slots & HIDEHAIR)
+ facial_hair_hidden = !!(human_head_owner.obscured_slots & HIDEFACIALHAIR)
if(is_husked)
hair_hidden = TRUE
facial_hair_hidden = TRUE
diff --git a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm
index b431000b9e2..d8d1ed59774 100644
--- a/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm
+++ b/code/modules/surgery/bodyparts/species_parts/lizard_bodyparts.dm
@@ -64,7 +64,7 @@
var/uniform_compatible = isnull(worn_uniform) \
|| (worn_uniform.supports_variations_flags & DIGITIGRADE_VARIATIONS) \
|| !(worn_uniform.body_parts_covered & LEGS) \
- || (worn_suit?.flags_inv & HIDEJUMPSUIT) // If suit hides our jumpsuit, it doesn't matter if it squishes
+ || (obscured_slots & HIDEJUMPSUIT) // If suit hides our jumpsuit, it doesn't matter if it squishes
var/suit_compatible = isnull(worn_suit) \
|| (worn_suit.supports_variations_flags & DIGITIGRADE_VARIATIONS) \
diff --git a/code/modules/surgery/organs/external/_visual_organs.dm b/code/modules/surgery/organs/external/_visual_organs.dm
index b4924471195..2978ffa0dcf 100644
--- a/code/modules/surgery/organs/external/_visual_organs.dm
+++ b/code/modules/surgery/organs/external/_visual_organs.dm
@@ -123,12 +123,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
dyable = TRUE
/datum/bodypart_overlay/mutant/horns/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if((human.head?.flags_inv & HIDEHAIR) || (human.wear_mask?.flags_inv & HIDEHAIR))
- return FALSE
- return TRUE
+ return !(bodypart_owner.owner?.obscured_slots & HIDEHAIR)
/datum/bodypart_overlay/mutant/horns/get_global_feature_list()
return SSaccessories.horns_list
@@ -155,12 +150,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
feature_key = FEATURE_FRILLS
/datum/bodypart_overlay/mutant/frills/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if(!(human.head?.flags_inv & HIDEEARS))
- return TRUE
- return FALSE
+ return !(bodypart_owner.owner?.obscured_slots & HIDEEARS)
/datum/bodypart_overlay/mutant/frills/get_global_feature_list()
return SSaccessories.frills_list
@@ -189,12 +179,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
feature_key = FEATURE_SNOUT
/datum/bodypart_overlay/mutant/snout/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if((human.head?.flags_inv & HIDESNOUT) || (human.wear_mask?.flags_inv & HIDESNOUT))
- return FALSE
- return TRUE
+ return !(bodypart_owner.owner?.obscured_slots & HIDESNOUT)
/datum/bodypart_overlay/mutant/snout/get_global_feature_list()
return SSaccessories.snouts_list
@@ -282,12 +267,7 @@ Unlike normal organs, we're actually inside a persons limbs at all times
return burnt ? burn_datum.icon_state : sprite_datum.icon_state
/datum/bodypart_overlay/mutant/antennae/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if(!(human.head?.flags_inv & HIDEANTENNAE))
- return TRUE
- return FALSE
+ return !(bodypart_owner.owner?.obscured_slots & HIDEANTENNAE)
///The leafy hair of a podperson
/obj/item/organ/pod_hair
@@ -333,9 +313,4 @@ Unlike normal organs, we're actually inside a persons limbs at all times
overlay.color = null
/datum/bodypart_overlay/mutant/pod_hair/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if((human.head?.flags_inv & HIDEHAIR) || (human.wear_mask?.flags_inv & HIDEHAIR))
- return FALSE
- return TRUE
+ return !(bodypart_owner.owner?.obscured_slots & HIDEHAIR)
diff --git a/code/modules/surgery/organs/external/spines.dm b/code/modules/surgery/organs/external/spines.dm
index 0cb680c112e..4fc3c862b05 100644
--- a/code/modules/surgery/organs/external/spines.dm
+++ b/code/modules/surgery/organs/external/spines.dm
@@ -38,12 +38,7 @@
return SSaccessories.spines_list
/datum/bodypart_overlay/mutant/spines/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if(human.wear_suit?.flags_inv & HIDEJUMPSUIT)
- return FALSE
- return TRUE
+ return !(bodypart_owner.owner?.obscured_slots & HIDEJUMPSUIT)
/datum/bodypart_overlay/mutant/spines/set_dye_color(new_color, obj/item/organ/tail/organ)
var/obj/item/organ/tail/tail = organ?.owner.get_organ_slot(ORGAN_SLOT_EXTERNAL_TAIL)
diff --git a/code/modules/surgery/organs/external/tails.dm b/code/modules/surgery/organs/external/tails.dm
index 48eeffece85..a554e759713 100644
--- a/code/modules/surgery/organs/external/tails.dm
+++ b/code/modules/surgery/organs/external/tails.dm
@@ -148,12 +148,7 @@
return "[wagging ? "wagging_" : ""][sprite_datum.icon_state]" //add the wagging tag if we be wagging
/datum/bodypart_overlay/mutant/tail/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if(human.wear_suit?.flags_inv & HIDEJUMPSUIT)
- return FALSE
- return TRUE
+ return !(bodypart_owner.owner?.obscured_slots & HIDEJUMPSUIT)
/obj/item/organ/tail/cat
name = "tail"
@@ -283,12 +278,7 @@
return (!isnull(tail_spine_key) ? "[tail_spine_key]_" : "") + (wagging ? "wagging_" : "") + sprite_datum.icon_state // Select the wagging state if appropriate
/datum/bodypart_overlay/mutant/tail_spines/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if(human.wear_suit?.flags_inv & HIDEJUMPSUIT)
- return FALSE
- return TRUE
+ return !(bodypart_owner.owner?.obscured_slots & HIDEJUMPSUIT)
/datum/bodypart_overlay/mutant/tail_spines/set_dye_color(new_color, obj/item/organ/organ)
dye_color = new_color //no update_body_parts() call, tail/set_dye_color will do it.
diff --git a/code/modules/surgery/organs/external/wings/functional_wings.dm b/code/modules/surgery/organs/external/wings/functional_wings.dm
index 86bad3a1b57..ee6f45de75e 100644
--- a/code/modules/surgery/organs/external/wings/functional_wings.dm
+++ b/code/modules/surgery/organs/external/wings/functional_wings.dm
@@ -82,8 +82,8 @@
if(human.stat || human.body_position == LYING_DOWN || isnull(human.client))
return FALSE
//Jumpsuits have tail holes, so it makes sense they have wing holes too
- if(!cant_hide && human.wear_suit && ((human.wear_suit.flags_inv & HIDEJUMPSUIT) && (!human.wear_suit.species_exception || !is_type_in_list(src, human.wear_suit.species_exception))))
- to_chat(human, span_warning("Your suit blocks your wings from extending!"))
+ if(!cant_hide && (human.obscured_slots & HIDEJUMPSUIT))
+ to_chat(human, span_warning("Your clothing blocks your wings from extending!"))
return FALSE
var/turf/location = get_turf(human)
if(!location)
diff --git a/code/modules/surgery/organs/external/wings/moth_wings.dm b/code/modules/surgery/organs/external/wings/moth_wings.dm
index ff282b30666..e71251e8ebf 100644
--- a/code/modules/surgery/organs/external/wings/moth_wings.dm
+++ b/code/modules/surgery/organs/external/wings/moth_wings.dm
@@ -54,11 +54,7 @@
return FALSE
if(owner.has_gravity())
return FALSE
- if(ishuman(owner))
- var/mob/living/carbon/human/human_owner = owner
- if(human_owner.wear_suit?.flags_inv & HIDEMUTWINGS)
- return FALSE //Can't fly with hidden wings
- if(burnt)
+ if((owner.obscured_slots & HIDEMUTWINGS) || burnt)
return FALSE
var/datum/gas_mixture/current = owner.loc.return_air()
if(current && (current.return_pressure() >= ONE_ATMOSPHERE*0.85))
@@ -117,12 +113,7 @@
return SSaccessories.moth_wings_list
/datum/bodypart_overlay/mutant/wings/moth/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if(human.wear_suit?.flags_inv & HIDEMUTWINGS)
- return FALSE
- return TRUE
+ return !(bodypart_owner.owner?.obscured_slots & HIDEMUTWINGS)
/datum/bodypart_overlay/mutant/wings/moth/get_base_icon_state()
return burnt ? burn_datum.icon_state : sprite_datum.icon_state
diff --git a/code/modules/surgery/organs/external/wings/wings.dm b/code/modules/surgery/organs/external/wings/wings.dm
index ac990ba1032..a801f9720da 100644
--- a/code/modules/surgery/organs/external/wings/wings.dm
+++ b/code/modules/surgery/organs/external/wings/wings.dm
@@ -25,15 +25,4 @@
feature_key = FEATURE_WINGS
/datum/bodypart_overlay/mutant/wings/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if(!human.wear_suit)
- return TRUE
- if(!(human.wear_suit.flags_inv & HIDEJUMPSUIT))
- return TRUE
- if(human.wear_suit.species_exception && is_type_in_list(src, human.wear_suit.species_exception))
- return TRUE
- return FALSE
-
-
+ return !(bodypart_owner.owner?.obscured_slots & HIDEJUMPSUIT)
diff --git a/code/modules/surgery/organs/internal/ears/_ears.dm b/code/modules/surgery/organs/internal/ears/_ears.dm
index 66991b6d236..0c86cac08d5 100644
--- a/code/modules/surgery/organs/internal/ears/_ears.dm
+++ b/code/modules/surgery/organs/internal/ears/_ears.dm
@@ -178,12 +178,7 @@
return SSaccessories.ears_list
/datum/bodypart_overlay/mutant/cat_ears/can_draw_on_bodypart(obj/item/bodypart/bodypart_owner)
- var/mob/living/carbon/human/human = bodypart_owner.owner
- if(!istype(human))
- return TRUE
- if((human.head?.flags_inv & HIDEHAIR) || (human.wear_mask?.flags_inv & HIDEHAIR))
- return FALSE
- return TRUE
+ return !(bodypart_owner.owner?.obscured_slots & HIDEHAIR)
/datum/bodypart_overlay/mutant/cat_ears/get_image(image_layer, obj/item/bodypart/limb)
var/mutable_appearance/base_ears = ..()
diff --git a/code/modules/surgery/organs/internal/eyes/_eyes.dm b/code/modules/surgery/organs/internal/eyes/_eyes.dm
index 98d32916c58..97d5943f855 100644
--- a/code/modules/surgery/organs/internal/eyes/_eyes.dm
+++ b/code/modules/surgery/organs/internal/eyes/_eyes.dm
@@ -267,8 +267,7 @@
var/mutable_appearance/eye_right = mutable_appearance('icons/mob/human/human_face.dmi', "[eye_icon_state]_r", -EYES_LAYER, parent)
var/list/overlays = list(eye_left, eye_right)
- var/obscured = parent.check_obscured_slots()
- if(overlay_ignore_lighting && !(obscured & ITEM_SLOT_EYES))
+ if(overlay_ignore_lighting && !(parent.obscured_slots & HIDEEYES))
overlays += emissive_appearance(eye_left.icon, eye_left.icon_state, parent, -EYES_LAYER, alpha = eye_left.alpha)
overlays += emissive_appearance(eye_right.icon, eye_right.icon_state, parent, -EYES_LAYER, alpha = eye_right.alpha)
diff --git a/code/modules/unit_tests/screenshots/screenshot_digi_leg_test.png b/code/modules/unit_tests/screenshots/screenshot_digi_leg_test.png
index 3907b46b8709b4db3a6a2aeaa4b68a3dba36c500..8fb16d008feb0fb38330be17cc50c85b0a17758d 100644
GIT binary patch
delta 1380
zcmV-q1)KWb4c`rrP7#li%*@OHWB^uLW3#ifb9R4`Uor`EBP1y;Ei)7ok(yZv9VDfx
zwuF@AZ;||r0Ya0B0XTn`_pXryT;65ur)til?epWDvm-|c;T-AR=f|0pu6rbU5U5O`zX_X5xN$6jE-hv8UFbW`JSXv{BZnU08sdIJMxCIX-GQ*U6HPQr0i
z6GY>1GBpu6w7lpVp=D+oq`>#aL=sc-vFEo5l$udur4$j(lrrR}yd%AkX^=EiJAXW&
zpC8ak4B|FJ6wQBTgPDrLNKrqFqBa3%#6WXE`5A8$c)=jJBhY&-f-o5*Dk6eN(OzgE
za2Z`F`V2VjwFu%MX7>d3x2G*h<}8_oNs@%Kgw2!0K)~q)^fDbeyiK6-_>Lep;Pd$~
ziNbI?orYnQ4CnJUfuMUxvrJvlo&$}?f#=1Z7sLj9O3QzfMrWd$uDy)7zS+uph@`&Z
z?%z%Hzh1q5^UJTly?Oo0fS)Rr%;$4jrL;|yI^8Frr;yNdEcGl4!y}3F)bqSFuD1r9
zMm^az)}Df96r^xmN0=@%-BKEUP2l^f5obx%G-LLfK>v6>(`EvF5yxq)FK2TCrD%Sm
z&~TOQ2xxzWa=ljV1SwBD2!@JAhqhJ%?$%EW>kxS<;WS2;AyU(tU}__v)k*2;421ca
zq30lWX^t7qvL(NsY<3;ES`fx9siN*}|M(4X1w-#nfcFKg)XDsk!gOyPAM{BfdO8
zUl76K{CsK4e@Xx-v5y@_qpHJ$sR@jxUc_*~)kV2fQBuea~LztINyF
zRc?Pi1^j-1^!*82=PUZGjrk9GKfwBbO>1h4|sl+?cpf?LH`r}dnv>pe?C28o#%hq1D@ymIEsJJ|HXE@*>JwuZl4~o&Y1p%
zevN1A7LMZCPX8C%V*9cDNZZx{dJ;W54&xjBUu=r&Puow|)VBy|fy8zk#y9%ED67xc
z<@M)ke+-+8iP>=&-{}9UD9SI}FJ)0wMglty;~V{7{Z&=l&9`R(>kC#{y_b|{Pu0R_|CpB
z^v(~&AFTgxm&@DR3wCj@{D=Pj0P-Jt`vb^-V9($W!1n`C
z|3~^C`VXM~kMuwCA5i@t>3`%up!$D5(*MYRfc1Z*|B?TI>i-1LQxz`akjykpBSd
z|HwZ;{sXN4BmV&T53v4^`~&1afcii550L-BI_v+?KS2J2Zr1uget$sz!+j`zQ~e*l
mKOq0%p1@rHNBST64}Sxj)#@nQ&g2yU0000)aF@5SY6aJzPPFDz5NL_So#9#Kp8FyVyH%WhVV!}`Q;dOC!
zv4QNQC(eW;Ip@+57JT4&gnQn=h7W6eXv2kcM%0BPN17Q1#
zen2-dh}#TNG@E}7W-1CJMfEI-+60^t1C0U2XS_||1%u#@K%cb;!eo%BhzKG@XQ6?>
zWwcQA9dJ5p5yU~v?g{E|PfL=_SuzWgBnf8;n(&O|j;dm3^5u$6TeN&Udx
zf12ojy?XuTmtTK-^ZJzmKUFH3&*wBt>6j>Wx=%oFA)&`u>QNSkR}$x`=Xq&d9}PJ5
zda^65Jp@fJNa47SFfB7(QtEz9;QOf&XGzo)WAvIp|9CypW&*v4<22UG*&IMA8s8{1
ztg;;e%}{@?=c=6`OO|Ce
zsQ3P$j=#EG*%M@dggq9{_#NUgoRI%ga@6
zz6F20KS28agst-xeb&bKhwKlq{$JA=SmGbh9_xS4%k#Vw?{1IvzaLxyyrVtR|NZf9
z{ofad`u`d5PW|5(hx)%S4)uRu{IUKoO0EBkr#P+P>>khPTk&JQeWU-2O>zBc`{|nM76DC=*p9>Yjs7pn>hpDZ
z{khuj!)7rtI}Y17`oAiQ^2_#1SrnC#z>dTAjsCCxs;cc~TTyK$u;QrwPXAXoo05O#
z+D$9IejIe*p#3BL|MjM-s++H^_$;PE2O|#JAEf^m3k~T*>w@m~2kQUjw{OeEclLdu
zPkx~N!TSGpxxBr-U>CRgkB-e*pOp>>2z4xIX~-
zf29AR{{Zs;NdF`M0p{K>h>F|0DkZ`42Gv
zkNgAVKfwGy@(+;z0Q3LIKS2Hi$p1tC0QnEBGyf0$1LQyGV$J{K{R8qJ?&Bw$^8axE
lfc%Gh0(1T!>3`%u{0)xB>U4TAMYR9`002ovPDHLkV1oL?-V6W$
diff --git a/code/modules/unit_tests/strippable.dm b/code/modules/unit_tests/strippable.dm
index 47a76a1ca75..36083804b15 100644
--- a/code/modules/unit_tests/strippable.dm
+++ b/code/modules/unit_tests/strippable.dm
@@ -25,7 +25,6 @@
var/handcuffs = allocate(/obj/item/restraints/handcuffs, user)
user.forceMove(target.loc)
user.set_handcuffed(handcuffs)
- user.update_handcuffed()
TEST_ASSERT_EQUAL(strip_menu.ui_status(user, ui_state), UI_UPDATE, "Being within range but cuffed was not update-only.")
user.set_handcuffed(null)
qdel(handcuffs)
diff --git a/code/modules/vehicles/mecha/equipment/weapons/weapons.dm b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm
index c3545fc0edf..d4dbc1257f6 100644
--- a/code/modules/vehicles/mecha/equipment/weapons/weapons.dm
+++ b/code/modules/vehicles/mecha/equipment/weapons/weapons.dm
@@ -668,7 +668,6 @@
if(autocuff && iscarbon(target))
var/mob/living/carbon/carbontarget = target
carbontarget.set_handcuffed(new cuff_type(carbontarget))
- carbontarget.update_handcuffed()
return
if(istype(target, /obj/machinery/door))