More gendered sprite masks (#14735)
@@ -60,26 +60,15 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||||||
private void OnAppearanceUpdate(EntityUid uid, InventoryComponent component, ref AppearanceChangeEvent args)
|
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
|
// 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.
|
// This is when sex is first loaded from the profile.
|
||||||
if (!TryComp(uid, out SpriteComponent? sprite) || !sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var layer))
|
|
||||||
|
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;
|
return;
|
||||||
|
|
||||||
if (!TryComp(uid, out HumanoidAppearanceComponent? humanoid)
|
SetGenderedMask(sprite, humanoid, clothing);
|
||||||
|| 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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void OnGetVisuals(EntityUid uid, ClothingComponent item, GetEquipmentVisualsEvent args)
|
private void OnGetVisuals(EntityUid uid, ClothingComponent item, GetEquipmentVisualsEvent args)
|
||||||
@@ -225,20 +214,12 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (slot == "jumpsuit" && sprite.LayerMapTryGet(HumanoidVisualLayers.StencilMask, out var suitLayer))
|
if (slot == "jumpsuit")
|
||||||
{
|
{
|
||||||
if (TryComp(equipee, out HumanoidAppearanceComponent? humanoid) && humanoid.Sex == Sex.Female)
|
if (!TryComp(equipee, out HumanoidAppearanceComponent? humanoid))
|
||||||
{
|
return;
|
||||||
sprite.LayerSetState(suitLayer, clothingComponent.FemaleMask switch
|
|
||||||
{
|
SetGenderedMask(sprite, humanoid, clothingComponent);
|
||||||
FemaleClothingMask.NoMask => "female_none",
|
|
||||||
FemaleClothingMask.UniformTop => "female_top",
|
|
||||||
_ => "female_full",
|
|
||||||
});
|
|
||||||
sprite.LayerSetVisible(suitLayer, true);
|
|
||||||
}
|
|
||||||
else
|
|
||||||
sprite.LayerSetVisible(suitLayer, false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (!_inventorySystem.TryGetSlot(equipee, slot, out var slotDef, inventory))
|
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);
|
RaiseLocalEvent(equipment, new EquipmentVisualsUpdatedEvent(equipee, slot, revealedLayers), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Sets a sprite's gendered mask based on gender (obviously).
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="sprite">Sprite to modify</param>
|
||||||
|
/// <param name="humanoid">Humanoid, to get gender from</param>
|
||||||
|
/// <param name="clothing">Clothing component, to get mask sprite type</param>
|
||||||
|
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);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -53,9 +53,17 @@ public sealed class ClothingComponent : Component
|
|||||||
[DataField("sprite")]
|
[DataField("sprite")]
|
||||||
public string? RsiPath;
|
public string? RsiPath;
|
||||||
|
|
||||||
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
|
[DataField("maleMask")]
|
||||||
|
public ClothingMask MaleMask = ClothingMask.UniformFull;
|
||||||
|
|
||||||
[ViewVariables(VVAccess.ReadWrite)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField("femaleMask")]
|
[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;
|
public string? InSlot;
|
||||||
}
|
}
|
||||||
@@ -71,7 +79,7 @@ public sealed class ClothingComponentState : ComponentState
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum FemaleClothingMask : byte
|
public enum ClothingMask : byte
|
||||||
{
|
{
|
||||||
NoMask = 0,
|
NoMask = 0,
|
||||||
UniformFull,
|
UniformFull,
|
||||||
|
|||||||
@@ -111,16 +111,16 @@
|
|||||||
# sprite refactor when
|
# sprite refactor when
|
||||||
state: l_leg
|
state: l_leg
|
||||||
- shader: StencilMask
|
- shader: StencilMask
|
||||||
map: [ "enum.HumanoidVisualLayers.StencilMask" ]
|
map: ["enum.HumanoidVisualLayers.StencilMask"]
|
||||||
sprite: Mobs/Customization/masking_helpers.rsi
|
sprite: Mobs/Customization/masking_helpers.rsi
|
||||||
state: female_full
|
state: unisex_full
|
||||||
visible: false
|
visible: false
|
||||||
- map: [ "jumpsuit" ]
|
- map: ["jumpsuit"]
|
||||||
- map: [ "enum.HumanoidVisualLayers.LHand" ]
|
- map: ["enum.HumanoidVisualLayers.LFoot"]
|
||||||
- map: [ "enum.HumanoidVisualLayers.RHand" ]
|
- map: ["enum.HumanoidVisualLayers.RFoot"]
|
||||||
- map: [ "enum.HumanoidVisualLayers.LFoot" ]
|
- map: ["enum.HumanoidVisualLayers.LHand"]
|
||||||
- map: [ "enum.HumanoidVisualLayers.RFoot" ]
|
- map: ["enum.HumanoidVisualLayers.RHand"]
|
||||||
- map: [ "enum.HumanoidVisualLayers.Handcuffs" ]
|
- map: ["enum.HumanoidVisualLayers.Handcuffs"]
|
||||||
color: "#ffffff"
|
color: "#ffffff"
|
||||||
sprite: Objects/Misc/handcuffs.rsi
|
sprite: Objects/Misc/handcuffs.rsi
|
||||||
state: body-overlay-2
|
state: body-overlay-2
|
||||||
@@ -334,16 +334,16 @@
|
|||||||
sprite: Mobs/Species/Human/parts.rsi
|
sprite: Mobs/Species/Human/parts.rsi
|
||||||
state: l_leg
|
state: l_leg
|
||||||
- shader: StencilMask
|
- shader: StencilMask
|
||||||
map: [ "enum.HumanoidVisualLayers.StencilMask" ]
|
map: ["enum.HumanoidVisualLayers.StencilMask"]
|
||||||
sprite: Mobs/Customization/masking_helpers.rsi
|
sprite: Mobs/Customization/masking_helpers.rsi
|
||||||
state: female_full
|
state: unisex_full
|
||||||
visible: false
|
visible: false
|
||||||
- map: [ "jumpsuit" ]
|
- map: ["jumpsuit"]
|
||||||
- map: [ "enum.HumanoidVisualLayers.LHand" ]
|
- map: ["enum.HumanoidVisualLayers.LFoot"]
|
||||||
- map: [ "enum.HumanoidVisualLayers.RHand" ]
|
- map: ["enum.HumanoidVisualLayers.RFoot"]
|
||||||
- map: [ "enum.HumanoidVisualLayers.LFoot" ]
|
- map: ["enum.HumanoidVisualLayers.LHand"]
|
||||||
- map: [ "enum.HumanoidVisualLayers.RFoot" ]
|
- map: ["enum.HumanoidVisualLayers.RHand"]
|
||||||
- map: [ "enum.HumanoidVisualLayers.Handcuffs" ]
|
- map: ["enum.HumanoidVisualLayers.Handcuffs"]
|
||||||
color: "#ffffff"
|
color: "#ffffff"
|
||||||
sprite: Objects/Misc/handcuffs.rsi
|
sprite: Objects/Misc/handcuffs.rsi
|
||||||
state: body-overlay-2
|
state: body-overlay-2
|
||||||
|
|||||||
@@ -37,7 +37,7 @@
|
|||||||
# sprite: Mobs/Species/Vox/parts.rsi
|
# sprite: Mobs/Species/Vox/parts.rsi
|
||||||
# state: l_leg
|
# state: l_leg
|
||||||
#- shader: StencilMask
|
#- shader: StencilMask
|
||||||
# map: [ "enum.HumanoidVisualLayers.StencilMask" ]
|
# map: [ "enum.HumanoidVisualLayers.FemaleStencilMask" ]
|
||||||
# sprite: Mobs/Customization/masking_helpers.rsi
|
# sprite: Mobs/Customization/masking_helpers.rsi
|
||||||
# state: female_full
|
# state: female_full
|
||||||
# visible: false
|
# visible: false
|
||||||
|
|||||||
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
@@ -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"}]}
|
{
|
||||||
|
"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
|
||||||
|
}
|
||||||
|
]
|
||||||
|
}
|
||||||
|
|||||||
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.6 KiB |
|
After Width: | Height: | Size: 1.5 KiB |
|
After Width: | Height: | Size: 1.5 KiB |