diff --git a/Content.Client/Clothing/ClientClothingSystem.cs b/Content.Client/Clothing/ClientClothingSystem.cs
index 22d639fc2f..81220e650d 100644
--- a/Content.Client/Clothing/ClientClothingSystem.cs
+++ b/Content.Client/Clothing/ClientClothingSystem.cs
@@ -60,26 +60,15 @@ public sealed class ClientClothingSystem : ClothingSystem
private void OnAppearanceUpdate(EntityUid uid, InventoryComponent component, ref AppearanceChangeEvent args)
{
// May need to update jumpsuit stencils if the sex changed. Also required to properly set the stencil on init
- // when sex is first loaded from the profile.
- if (!TryComp(uid, out SpriteComponent? sprite) || !sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var layer))
+ // This is when sex is first loaded from the profile.
+
+ if (!TryComp(uid, out SpriteComponent? sprite) ||
+ !TryComp(uid, out HumanoidAppearanceComponent? humanoid) ||
+ !_inventorySystem.TryGetSlotEntity(uid, "jumpsuit", out var suit, component) ||
+ !TryComp(suit, out ClothingComponent? clothing))
return;
- if (!TryComp(uid, out HumanoidAppearanceComponent? humanoid)
- || humanoid.Sex != Sex.Female
- || !_inventorySystem.TryGetSlotEntity(uid, "jumpsuit", out var suit, component)
- || !TryComp(suit, out ClothingComponent? clothing))
- {
- sprite.LayerSetVisible(layer, false);
- return;
- }
-
- sprite.LayerSetState(layer, clothing.FemaleMask switch
- {
- FemaleClothingMask.NoMask => "female_none",
- FemaleClothingMask.UniformTop => "female_top",
- _ => "female_full",
- });
- sprite.LayerSetVisible(layer, true);
+ SetGenderedMask(sprite, humanoid, clothing);
}
private void OnGetVisuals(EntityUid uid, ClothingComponent item, GetEquipmentVisualsEvent args)
@@ -225,20 +214,12 @@ public sealed class ClientClothingSystem : ClothingSystem
return;
}
- if (slot == "jumpsuit" && sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var suitLayer))
+ if (slot == "jumpsuit")
{
- if (TryComp(equipee, out HumanoidAppearanceComponent? humanoid) && humanoid.Sex == Sex.Female)
- {
- sprite.LayerSetState(suitLayer, clothingComponent.FemaleMask switch
- {
- FemaleClothingMask.NoMask => "female_none",
- FemaleClothingMask.UniformTop => "female_top",
- _ => "female_full",
- });
- sprite.LayerSetVisible(suitLayer, true);
- }
- else
- sprite.LayerSetVisible(suitLayer, false);
+ if (!TryComp(equipee, out HumanoidAppearanceComponent? humanoid))
+ return;
+
+ SetGenderedMask(sprite, humanoid, clothingComponent);
}
if (!_inventorySystem.TryGetSlot(equipee, slot, out var slotDef, inventory))
@@ -315,4 +296,49 @@ public sealed class ClientClothingSystem : ClothingSystem
RaiseLocalEvent(equipment, new EquipmentVisualsUpdatedEvent(equipee, slot, revealedLayers), true);
}
+
+
+ ///
+ /// Sets a sprite's gendered mask based on gender (obviously).
+ ///
+ /// Sprite to modify
+ /// Humanoid, to get gender from
+ /// Clothing component, to get mask sprite type
+ private static void SetGenderedMask(SpriteComponent sprite, HumanoidAppearanceComponent humanoid, ClothingComponent clothing)
+ {
+ if (!sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var layer))
+ return;
+
+ ClothingMask? mask = null;
+ var prefix = "";
+
+ switch (humanoid.Sex)
+ {
+ case Sex.Male:
+ mask = clothing.MaleMask;
+ prefix = "male_";
+ break;
+ case Sex.Female:
+ mask = clothing.FemaleMask;
+ prefix = "female_";
+ break;
+ case Sex.Unsexed:
+ mask = clothing.UnisexMask;
+ prefix = "unisex_";
+ break;
+ }
+
+ if (mask != null)
+ {
+ sprite.LayerSetState(layer, mask switch
+ {
+ ClothingMask.NoMask => $"{prefix}none",
+ ClothingMask.UniformTop => $"{prefix}top",
+ _ => $"{prefix}full",
+ });
+ sprite.LayerSetVisible(layer, true);
+ }
+ else
+ sprite.LayerSetVisible(layer, false);
+ }
}
diff --git a/Content.Shared/Clothing/Components/ClothingComponent.cs b/Content.Shared/Clothing/Components/ClothingComponent.cs
index 3f6925fd24..a748e2348e 100644
--- a/Content.Shared/Clothing/Components/ClothingComponent.cs
+++ b/Content.Shared/Clothing/Components/ClothingComponent.cs
@@ -53,9 +53,17 @@ public sealed class ClothingComponent : Component
[DataField("sprite")]
public string? RsiPath;
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("maleMask")]
+ public ClothingMask MaleMask = ClothingMask.UniformFull;
+
[ViewVariables(VVAccess.ReadWrite)]
[DataField("femaleMask")]
- public FemaleClothingMask FemaleMask = FemaleClothingMask.UniformFull;
+ public ClothingMask FemaleMask = ClothingMask.UniformFull;
+
+ [ViewVariables(VVAccess.ReadWrite)]
+ [DataField("unisexMask")]
+ public ClothingMask UnisexMask = ClothingMask.UniformFull;
public string? InSlot;
}
@@ -71,7 +79,7 @@ public sealed class ClothingComponentState : ComponentState
}
}
-public enum FemaleClothingMask : byte
+public enum ClothingMask : byte
{
NoMask = 0,
UniformFull,
diff --git a/Resources/Prototypes/Entities/Mobs/Species/base.yml b/Resources/Prototypes/Entities/Mobs/Species/base.yml
index 96ba3c4261..173256ec5c 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/base.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/base.yml
@@ -111,16 +111,16 @@
# sprite refactor when
state: l_leg
- shader: StencilMask
- map: [ "enum.HumanoidVisualLayers.StencilMask" ]
+ map: ["enum.HumanoidVisualLayers.StencilMask"]
sprite: Mobs/Customization/masking_helpers.rsi
- state: female_full
+ state: unisex_full
visible: false
- - map: [ "jumpsuit" ]
- - map: [ "enum.HumanoidVisualLayers.LHand" ]
- - map: [ "enum.HumanoidVisualLayers.RHand" ]
- - map: [ "enum.HumanoidVisualLayers.LFoot" ]
- - map: [ "enum.HumanoidVisualLayers.RFoot" ]
- - map: [ "enum.HumanoidVisualLayers.Handcuffs" ]
+ - map: ["jumpsuit"]
+ - map: ["enum.HumanoidVisualLayers.LFoot"]
+ - map: ["enum.HumanoidVisualLayers.RFoot"]
+ - map: ["enum.HumanoidVisualLayers.LHand"]
+ - map: ["enum.HumanoidVisualLayers.RHand"]
+ - map: ["enum.HumanoidVisualLayers.Handcuffs"]
color: "#ffffff"
sprite: Objects/Misc/handcuffs.rsi
state: body-overlay-2
@@ -334,16 +334,16 @@
sprite: Mobs/Species/Human/parts.rsi
state: l_leg
- shader: StencilMask
- map: [ "enum.HumanoidVisualLayers.StencilMask" ]
+ map: ["enum.HumanoidVisualLayers.StencilMask"]
sprite: Mobs/Customization/masking_helpers.rsi
- state: female_full
+ state: unisex_full
visible: false
- - map: [ "jumpsuit" ]
- - map: [ "enum.HumanoidVisualLayers.LHand" ]
- - map: [ "enum.HumanoidVisualLayers.RHand" ]
- - map: [ "enum.HumanoidVisualLayers.LFoot" ]
- - map: [ "enum.HumanoidVisualLayers.RFoot" ]
- - map: [ "enum.HumanoidVisualLayers.Handcuffs" ]
+ - map: ["jumpsuit"]
+ - map: ["enum.HumanoidVisualLayers.LFoot"]
+ - map: ["enum.HumanoidVisualLayers.RFoot"]
+ - map: ["enum.HumanoidVisualLayers.LHand"]
+ - map: ["enum.HumanoidVisualLayers.RHand"]
+ - map: ["enum.HumanoidVisualLayers.Handcuffs"]
color: "#ffffff"
sprite: Objects/Misc/handcuffs.rsi
state: body-overlay-2
diff --git a/Resources/Prototypes/Entities/Mobs/Species/vox.yml b/Resources/Prototypes/Entities/Mobs/Species/vox.yml
index c4f957f799..be6e170c41 100644
--- a/Resources/Prototypes/Entities/Mobs/Species/vox.yml
+++ b/Resources/Prototypes/Entities/Mobs/Species/vox.yml
@@ -37,7 +37,7 @@
# sprite: Mobs/Species/Vox/parts.rsi
# state: l_leg
#- shader: StencilMask
- # map: [ "enum.HumanoidVisualLayers.StencilMask" ]
+ # map: [ "enum.HumanoidVisualLayers.FemaleStencilMask" ]
# sprite: Mobs/Customization/masking_helpers.rsi
# state: female_full
# visible: false
diff --git a/Resources/Textures/Mobs/Customization/masking_helpers.rsi/female_none.png b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/female_none.png
new file mode 100644
index 0000000000..44e0c1358d
Binary files /dev/null and b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/female_none.png differ
diff --git a/Resources/Textures/Mobs/Customization/masking_helpers.rsi/full.png b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/full.png
new file mode 100644
index 0000000000..f78008f58a
Binary files /dev/null and b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/full.png differ
diff --git a/Resources/Textures/Mobs/Customization/masking_helpers.rsi/male_full.png b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/male_full.png
new file mode 100644
index 0000000000..f78008f58a
Binary files /dev/null and b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/male_full.png differ
diff --git a/Resources/Textures/Mobs/Customization/masking_helpers.rsi/male_none.png b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/male_none.png
new file mode 100644
index 0000000000..44e0c1358d
Binary files /dev/null and b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/male_none.png differ
diff --git a/Resources/Textures/Mobs/Customization/masking_helpers.rsi/male_top.png b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/male_top.png
new file mode 100644
index 0000000000..a96eb3c294
Binary files /dev/null and b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/male_top.png differ
diff --git a/Resources/Textures/Mobs/Customization/masking_helpers.rsi/meta.json b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/meta.json
index 35abe29aa4..090804c6e8 100644
--- a/Resources/Textures/Mobs/Customization/masking_helpers.rsi/meta.json
+++ b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/meta.json
@@ -1 +1,56 @@
-{"version":1,"size":{"x":32,"y":32},"license":"CC-BY-SA-3.0","copyright":"Discord PJB#3005","states":[{"name":"female_full","directions":4},{"name":"female_top","directions":4},{"name":"none"}]}
\ No newline at end of file
+{
+ "version": 1,
+ "size": { "x": 32, "y": 32 },
+ "license": "CC-BY-SA-3.0",
+ "copyright": "Discord PJB#3005",
+ "states": [
+ {
+ "name": "female_full",
+ "directions": 4
+ },
+ {
+ "name": "female_none",
+ "directions": 1
+ },
+ {
+ "name": "female_top",
+ "directions": 4
+ },
+ {
+ "name": "male_full",
+ "directions": 4
+ },
+ {
+ "name": "male_none",
+ "directions": 1
+ },
+ {
+ "name": "male_top",
+ "directions": 4
+ },
+ {
+ "name": "unisex_full",
+ "directions": 4
+ },
+ {
+ "name": "unisex_none",
+ "directions": 1
+ },
+ {
+ "name": "unisex_top",
+ "directions": 4
+ },
+ {
+ "name": "full",
+ "directions": 4
+ },
+ {
+ "name": "none",
+ "directions": 1
+ },
+ {
+ "name": "top",
+ "directions": 4
+ }
+ ]
+}
diff --git a/Resources/Textures/Mobs/Customization/masking_helpers.rsi/top.png b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/top.png
new file mode 100644
index 0000000000..f78008f58a
Binary files /dev/null and b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/top.png differ
diff --git a/Resources/Textures/Mobs/Customization/masking_helpers.rsi/unisex_full.png b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/unisex_full.png
new file mode 100644
index 0000000000..1b69c04a7a
Binary files /dev/null and b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/unisex_full.png differ
diff --git a/Resources/Textures/Mobs/Customization/masking_helpers.rsi/unisex_none.png b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/unisex_none.png
new file mode 100644
index 0000000000..44e0c1358d
Binary files /dev/null and b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/unisex_none.png differ
diff --git a/Resources/Textures/Mobs/Customization/masking_helpers.rsi/unisex_top.png b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/unisex_top.png
new file mode 100644
index 0000000000..44e0c1358d
Binary files /dev/null and b/Resources/Textures/Mobs/Customization/masking_helpers.rsi/unisex_top.png differ