From ff009b8c10bcddfbf4e1c208ee409bb975f4d4fd Mon Sep 17 00:00:00 2001
From: John Willard <53777086+JohnFulpWillard@users.noreply.github.com>
Date: Fri, 23 Jan 2026 18:03:27 -0500
Subject: [PATCH] Snouts push masks out a bit (#94640)
## About The Pull Request
If you have a snout (and it isn't already handled elsewhere by your
species), masks will now be pushed 1 whole pixel up and away from you
when facing left or right.
Examples (TOP IS OLD, BOTTOM IS NEW)
(did you know the welding visor has the lizard's snout sticking out the
front)?
I also tried moving it up one tile too, but it didn't look as nice. (To
be clear, these are not the ones being used, the above screenshot is)
(once again top row is old, bottom row is new)
## Why It's Good For The Game
I think this makes masks fit snouted faces a little bit better?
Currently they sorta clip into the face which is a little bad imo.
## Changelog
:cl:
add: Masks now fit snouted species a little bit better, maybe.
/:cl:
---
code/__DEFINES/inventory.dm | 8 +++-----
code/_globalvars/bitfields.dm | 1 -
.../clothing/under/jobs/civilian/clown_mime.dm | 2 +-
code/modules/clothing/under/shorts.dm | 2 +-
.../surgery/bodyparts/worn_feature_offset.dm | 16 ++++++++++++----
.../surgery/organs/external/_visual_organs.dm | 18 ++++++++++++++++++
6 files changed, 35 insertions(+), 12 deletions(-)
diff --git a/code/__DEFINES/inventory.dm b/code/__DEFINES/inventory.dm
index cba3fbbd386..0176504e811 100644
--- a/code/__DEFINES/inventory.dm
+++ b/code/__DEFINES/inventory.dm
@@ -163,14 +163,12 @@ DEFINE_BITFIELD(no_equip_flags, list(
#define DIGITIGRADE_STYLE 2
//Flags (actual flags, fucker ^) for /obj/item/var/supports_variations_flags
-/// No alternative sprites or handling based on bodytype
-#define CLOTHING_NO_VARIATION (1<<0)
/// Has a sprite for digitigrade legs specifically.
-#define CLOTHING_DIGITIGRADE_VARIATION (1<<1)
+#define CLOTHING_DIGITIGRADE_VARIATION (1<<0)
/// The sprite works fine for digitigrade legs as-is.
-#define CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON (1<<2)
+#define CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON (1<<1)
/// Auto-generates the leg portion of the sprite with GAGS
-#define CLOTHING_DIGITIGRADE_MASK (1<<3)
+#define CLOTHING_DIGITIGRADE_MASK (1<<2)
/// All variation flags which render "correctly" on a digitigrade leg setup
#define DIGITIGRADE_VARIATIONS (CLOTHING_DIGITIGRADE_VARIATION|CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON|CLOTHING_DIGITIGRADE_MASK)
diff --git a/code/_globalvars/bitfields.dm b/code/_globalvars/bitfields.dm
index 7046a2f8f4d..cc01b194bd8 100644
--- a/code/_globalvars/bitfields.dm
+++ b/code/_globalvars/bitfields.dm
@@ -533,7 +533,6 @@ DEFINE_BITFIELD(head_flags, list(
))
DEFINE_BITFIELD(supports_variations_flags, list(
- "CLOTHING_NO_VARIATION" = CLOTHING_NO_VARIATION,
"CLOTHING_DIGITIGRADE_VARIATION" = CLOTHING_DIGITIGRADE_VARIATION,
"CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON" = CLOTHING_DIGITIGRADE_VARIATION_NO_NEW_ICON,
"CLOTHING_DIGITIGRADE_MASK" = CLOTHING_DIGITIGRADE_MASK,
diff --git a/code/modules/clothing/under/jobs/civilian/clown_mime.dm b/code/modules/clothing/under/jobs/civilian/clown_mime.dm
index bb0c33e7e2f..a452c6c98e0 100644
--- a/code/modules/clothing/under/jobs/civilian/clown_mime.dm
+++ b/code/modules/clothing/under/jobs/civilian/clown_mime.dm
@@ -31,7 +31,7 @@
inhand_icon_state = "clown"
female_sprite_flags = FEMALE_UNIFORM_TOP_ONLY
can_adjust = FALSE
- supports_variations_flags = CLOTHING_NO_VARIATION
+ supports_variations_flags = NONE
/obj/item/clothing/under/rank/civilian/clown/Initialize(mapload)
. = ..()
diff --git a/code/modules/clothing/under/shorts.dm b/code/modules/clothing/under/shorts.dm
index eb06c86fbe4..7110fab35bc 100644
--- a/code/modules/clothing/under/shorts.dm
+++ b/code/modules/clothing/under/shorts.dm
@@ -10,7 +10,7 @@
gender = PLURAL
body_parts_covered = GROIN
female_sprite_flags = NO_FEMALE_UNIFORM
- supports_variations_flags = CLOTHING_NO_VARIATION
+ supports_variations_flags = NONE
can_adjust = FALSE
species_exception = list(/datum/species/golem)
flags_1 = IS_PLAYER_COLORABLE_1
diff --git a/code/modules/surgery/bodyparts/worn_feature_offset.dm b/code/modules/surgery/bodyparts/worn_feature_offset.dm
index 24f4cedbff8..3fee7097d2d 100644
--- a/code/modules/surgery/bodyparts/worn_feature_offset.dm
+++ b/code/modules/surgery/bodyparts/worn_feature_offset.dm
@@ -19,7 +19,6 @@
list/offset_y = list("south" = 0),
)
attached_part.feature_offsets[feature_key] = src
- owner = attached_part.owner
src.attached_part = attached_part
src.feature_key = feature_key
src.offset_x = offset_x
@@ -28,13 +27,20 @@
if (length(offset_x) <= 1 && length(offset_y) <= 1)
return // We don't need to do any extra signal handling
- if (!isnull(owner))
- changed_owner(owner)
+ changed_owner(owner, attached_part.owner)
RegisterSignal(attached_part, COMSIG_BODYPART_CHANGED_OWNER, PROC_REF(changed_owner))
+/datum/worn_feature_offset/Destroy(force)
+ attached_part.feature_offsets -= feature_key
+ attached_part = null
+ changed_owner(null, null)
+ return ..()
+
/// Returns the current offset which should be used for this feature
/datum/worn_feature_offset/proc/get_offset()
var/current_dir = owner ? owner.dir : SOUTH
+ if(ISDIAGONALDIR(current_dir))
+ current_dir = current_dir & (EAST|WEST)
current_dir = dir2text(current_dir)
var/x = length(offset_x) ? ((current_dir in offset_x) ? offset_x[current_dir] : offset_x["south"]) : 0
var/y = length(offset_y) ? ((current_dir in offset_y) ? offset_y[current_dir] : offset_y["south"]) : 0
@@ -49,9 +55,11 @@
/// When the owner of the bodypart changes, update our signal registrations
/datum/worn_feature_offset/proc/changed_owner(obj/item/bodypart/part, mob/living/new_owner, mob/living/old_owner)
SIGNAL_HANDLER
+ if(isnull(old_owner))
+ old_owner = owner
owner = new_owner
if (!isnull(old_owner))
- UnregisterSignal(old_owner, COMSIG_ATOM_POST_DIR_CHANGE)
+ UnregisterSignal(old_owner, list(COMSIG_ATOM_POST_DIR_CHANGE, COMSIG_QDELETING))
if (!isnull(new_owner))
RegisterSignal(new_owner, COMSIG_ATOM_POST_DIR_CHANGE, PROC_REF(on_dir_change))
RegisterSignal(new_owner, COMSIG_QDELETING, PROC_REF(on_owner_deleted))
diff --git a/code/modules/surgery/organs/external/_visual_organs.dm b/code/modules/surgery/organs/external/_visual_organs.dm
index ec576568ab2..f7ba0b1ce6b 100644
--- a/code/modules/surgery/organs/external/_visual_organs.dm
+++ b/code/modules/surgery/organs/external/_visual_organs.dm
@@ -163,6 +163,24 @@ Unlike normal organs, we're actually inside a persons limbs at all times
organ_flags = parent_type::organ_flags | ORGAN_EXTERNAL
+ /// Offset to apply to equipment worn on the mouth we give to the head.
+ var/datum/worn_feature_offset/worn_mask_offset
+
+/obj/item/organ/snout/on_bodypart_insert(obj/item/bodypart/head/limb)
+ . = ..()
+ if(isnull(limb.worn_mask_offset))
+ worn_mask_offset = limb.worn_mask_offset = new(
+ attached_part = limb,
+ feature_key = OFFSET_FACEMASK,
+ offset_x = list("east" = 1, "west" = -1),
+ )
+
+/obj/item/organ/snout/on_bodypart_remove(obj/item/bodypart/head/limb, movement_flags)
+ if(worn_mask_offset)
+ QDEL_NULL(worn_mask_offset)
+ limb.worn_mask_offset = null
+ return ..()
+
/datum/bodypart_overlay/mutant/snout
layers = EXTERNAL_ADJACENT
feature_key = FEATURE_SNOUT