More gendered sprite masks (#14735)

This commit is contained in:
DEATHB4DEFEAT
2023-06-05 04:11:45 -07:00
committed by GitHub
parent 63b11670f7
commit a8337172ca
14 changed files with 140 additions and 51 deletions

View File

@@ -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);
}
/// <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);
}
}

View File

@@ -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,

View File

@@ -113,13 +113,13 @@
- shader: 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.LHand"]
- map: ["enum.HumanoidVisualLayers.RHand"]
- map: ["enum.HumanoidVisualLayers.Handcuffs"]
color: "#ffffff"
sprite: Objects/Misc/handcuffs.rsi
@@ -336,13 +336,13 @@
- shader: 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.LHand"]
- map: ["enum.HumanoidVisualLayers.RHand"]
- map: ["enum.HumanoidVisualLayers.Handcuffs"]
color: "#ffffff"
sprite: Objects/Misc/handcuffs.rsi

View File

@@ -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

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

View File

@@ -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
}
]
}

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.6 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB

Binary file not shown.

After

Width:  |  Height:  |  Size: 1.5 KiB