From 9beb7e48d452c75328c3733fb4a457d4530bee86 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Tue, 21 Jan 2020 18:11:15 +0100 Subject: [PATCH] Implement female uniform masking. --- .../Components/Clothing/ClothingComponent.cs | 23 ++++++++++++++++ .../HUD/Inventory/ClientInventoryComponent.cs | 14 ++++++++-- .../Mobs/HumanoidAppearanceComponent.cs | 2 ++ .../Appearance/HumanoidCharacterAppearance.cs | 1 + .../Entities/items/clothing/uniforms.yml | 3 ++- .../Prototypes/Entities/items/toolbox.yml | 9 ++++++- Resources/Prototypes/Entities/mobs/human.yml | 20 ++++++++++++++ Resources/Prototypes/Shaders/Stencils.yml | 25 ++++++++++++++++++ Resources/Shaders/stencilclear.swsl | 3 +++ Resources/Shaders/stencilmask.swsl | 7 +++++ .../Mob/masking_helpers.rsi/female_full.png | Bin 0 -> 134 bytes .../Mob/masking_helpers.rsi/female_none.png | Bin 0 -> 83 bytes .../Mob/masking_helpers.rsi/female_top.png | Bin 0 -> 130 bytes .../Mob/masking_helpers.rsi/meta.json | 1 + 14 files changed, 104 insertions(+), 4 deletions(-) create mode 100644 Resources/Prototypes/Shaders/Stencils.yml create mode 100644 Resources/Shaders/stencilclear.swsl create mode 100644 Resources/Shaders/stencilmask.swsl create mode 100644 Resources/Textures/Mob/masking_helpers.rsi/female_full.png create mode 100644 Resources/Textures/Mob/masking_helpers.rsi/female_none.png create mode 100644 Resources/Textures/Mob/masking_helpers.rsi/female_top.png create mode 100644 Resources/Textures/Mob/masking_helpers.rsi/meta.json diff --git a/Content.Client/GameObjects/Components/Clothing/ClothingComponent.cs b/Content.Client/GameObjects/Components/Clothing/ClothingComponent.cs index 57ffb68a17..9e9a08e32f 100644 --- a/Content.Client/GameObjects/Components/Clothing/ClothingComponent.cs +++ b/Content.Client/GameObjects/Components/Clothing/ClothingComponent.cs @@ -4,6 +4,7 @@ using Content.Shared.GameObjects.Components.Inventory; using Content.Shared.GameObjects.Components.Items; using Robust.Client.Graphics; using Robust.Shared.GameObjects; +using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; namespace Content.Client.GameObjects.Components.Clothing @@ -12,6 +13,7 @@ namespace Content.Client.GameObjects.Components.Clothing [ComponentReference(typeof(ItemComponent))] public class ClothingComponent : ItemComponent { + private FemaleClothingMask _femaleMask; public override string Name => "Clothing"; public override uint? NetID => ContentNetIDs.CLOTHING; public override Type StateType => typeof(ClothingComponentState); @@ -19,6 +21,20 @@ namespace Content.Client.GameObjects.Components.Clothing [ViewVariables(VVAccess.ReadWrite)] public string ClothingEquippedPrefix { get; set; } + [ViewVariables(VVAccess.ReadWrite)] + public FemaleClothingMask FemaleMask + { + get => _femaleMask; + set => _femaleMask = value; + } + + public override void ExposeData(ObjectSerializer serializer) + { + base.ExposeData(serializer); + + serializer.DataField(ref _femaleMask, "femaleMask", FemaleClothingMask.UniformFull); + } + public (RSI rsi, RSI.StateId stateId)? GetEquippedStateInfo(EquipmentSlotDefines.SlotFlags slot) { if (RsiPath == null) @@ -47,4 +63,11 @@ namespace Content.Client.GameObjects.Components.Clothing EquippedPrefix = clothingComponentState.EquippedPrefix; } } + + public enum FemaleClothingMask + { + NoMask = 0, + UniformFull, + UniformTop + } } diff --git a/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs b/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs index 853a048a92..d0290052eb 100644 --- a/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs +++ b/Content.Client/GameObjects/Components/HUD/Inventory/ClientInventoryComponent.cs @@ -5,6 +5,7 @@ using System.Collections.Generic; using System.Linq; using Content.Client.GameObjects.Components.Clothing; using Content.Shared.GameObjects; +using Content.Shared.Preferences.Appearance; using Robust.Client.GameObjects; using Robust.Client.Interfaces.GameObjects.Components; using Robust.Shared.GameObjects; @@ -14,8 +15,6 @@ using Robust.Shared.IoC; using Robust.Shared.ViewVariables; using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines; using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage; -using Content.Shared.GameObjects.Components.Inventory; -using System; namespace Content.Client.GameObjects { @@ -130,6 +129,17 @@ namespace Content.Client.GameObjects _sprite.LayerSetVisible(slot, true); _sprite.LayerSetRSI(slot, rsi); _sprite.LayerSetState(slot, state); + + if (slot == Slots.INNERCLOTHING) + { + _sprite.LayerSetState(HumanoidVisualLayers.StencilMask, clothing.FemaleMask switch + { + FemaleClothingMask.NoMask => "female_none", + FemaleClothingMask.UniformTop => "female_top", + _ => "female_full", + }); + } + return; } } diff --git a/Content.Client/GameObjects/Components/Mobs/HumanoidAppearanceComponent.cs b/Content.Client/GameObjects/Components/Mobs/HumanoidAppearanceComponent.cs index ef6ac85f17..44b4b7e4ce 100644 --- a/Content.Client/GameObjects/Components/Mobs/HumanoidAppearanceComponent.cs +++ b/Content.Client/GameObjects/Components/Mobs/HumanoidAppearanceComponent.cs @@ -47,6 +47,8 @@ namespace Content.Client.GameObjects.Components.Mobs sprite.LayerSetState(HumanoidVisualLayers.Chest, Sex == Sex.Male ? "human_chest_m" : "human_chest_f"); sprite.LayerSetState(HumanoidVisualLayers.Head, Sex == Sex.Male ? "human_head_m" : "human_head_f"); + sprite.LayerSetVisible(HumanoidVisualLayers.StencilMask, Sex == Sex.Female); + var hairStyle = Appearance.HairStyleName; if (string.IsNullOrWhiteSpace(hairStyle) || !HairStyles.HairStylesMap.ContainsKey(hairStyle)) hairStyle = HairStyles.DefaultHairStyle; diff --git a/Content.Shared/Preferences/Appearance/HumanoidCharacterAppearance.cs b/Content.Shared/Preferences/Appearance/HumanoidCharacterAppearance.cs index 253ca32729..265803fb5e 100644 --- a/Content.Shared/Preferences/Appearance/HumanoidCharacterAppearance.cs +++ b/Content.Shared/Preferences/Appearance/HumanoidCharacterAppearance.cs @@ -12,5 +12,6 @@ namespace Content.Shared.Preferences.Appearance LHand, RLeg, LLeg, + StencilMask } } diff --git a/Resources/Prototypes/Entities/items/clothing/uniforms.yml b/Resources/Prototypes/Entities/items/clothing/uniforms.yml index fa65553d34..747ff57d28 100644 --- a/Resources/Prototypes/Entities/items/clothing/uniforms.yml +++ b/Resources/Prototypes/Entities/items/clothing/uniforms.yml @@ -91,6 +91,7 @@ - type: Clothing sprite: Clothing/uniform_clown.rsi + femaleMask: UniformTop - type: entity parent: UniformBase @@ -141,4 +142,4 @@ state: captain - type: Clothing - sprite: Clothing/captain_uniform.rsi + sprite: Clothing/captain_uniform.rsi diff --git a/Resources/Prototypes/Entities/items/toolbox.yml b/Resources/Prototypes/Entities/items/toolbox.yml index b24918463b..b0c992b289 100644 --- a/Resources/Prototypes/Entities/items/toolbox.yml +++ b/Resources/Prototypes/Entities/items/toolbox.yml @@ -17,7 +17,14 @@ description: A bright red toolbox, stocked with emergency tools components: - type: Sprite - texture: Objects/Tools/toolbox_r.png + layers: + - shader: stencilClear + - texture: Objects/Tools/wrench.png + shader: stencilMask + + - texture: Objects/Tools/toolbox_r.png + shader: stencilDraw + - type: Icon texture: Objects/Tools/toolbox_r.png diff --git a/Resources/Prototypes/Entities/mobs/human.yml b/Resources/Prototypes/Entities/mobs/human.yml index 7e818e5534..88ad32a9c2 100644 --- a/Resources/Prototypes/Entities/mobs/human.yml +++ b/Resources/Prototypes/Entities/mobs/human.yml @@ -58,7 +58,18 @@ sprite: Mob/human.rsi state: human_l_leg + - shader: stencilClear + sprite: Mob/human.rsi + state: human_l_leg + - shader: stencilMask + map: ["enum.HumanoidVisualLayers.StencilMask"] + sprite: Mob/masking_helpers.rsi + state: female_full + visible: false + - map: ["enum.Slots.INNERCLOTHING"] + shader: stencilDraw + - map: ["enum.Slots.IDCARD"] - map: ["enum.Slots.GLOVES"] - map: ["enum.Slots.SHOES"] @@ -174,7 +185,16 @@ sprite: Mob/human.rsi state: human_l_leg + - shader: stencilClear + - shader: stencilMask + map: ["enum.HumanoidVisualLayers.StencilMask"] + sprite: Mob/masking_helpers.rsi + state: female_full + visible: false + - map: ["enum.Slots.INNERCLOTHING"] + shader: stencilDraw + - map: ["enum.Slots.IDCARD"] - map: ["enum.Slots.GLOVES"] - map: ["enum.Slots.SHOES"] diff --git a/Resources/Prototypes/Shaders/Stencils.yml b/Resources/Prototypes/Shaders/Stencils.yml new file mode 100644 index 0000000000..bf4efc200d --- /dev/null +++ b/Resources/Prototypes/Shaders/Stencils.yml @@ -0,0 +1,25 @@ +- type: shader + id: stencilClear + kind: source + path: "/Shaders/stencilclear.swsl" + stencil: + ref: 0 + op: Replace + func: Always + +- type: shader + id: stencilMask + kind: source + path: "/Shaders/stencilmask.swsl" + stencil: + ref: 1 + op: Replace + func: Always + +- type: shader + id: stencilDraw + kind: canvas + stencil: + ref: 1 + op: Keep + func: NotEqual diff --git a/Resources/Shaders/stencilclear.swsl b/Resources/Shaders/stencilclear.swsl new file mode 100644 index 0000000000..b0ec17e0f9 --- /dev/null +++ b/Resources/Shaders/stencilclear.swsl @@ -0,0 +1,3 @@ +void fragment() { + COLOR = vec4(0); +} diff --git a/Resources/Shaders/stencilmask.swsl b/Resources/Shaders/stencilmask.swsl new file mode 100644 index 0000000000..0e50894995 --- /dev/null +++ b/Resources/Shaders/stencilmask.swsl @@ -0,0 +1,7 @@ +void fragment() { + if (texture(TEXTURE, UV).a == 0) { + discard; // Discard if no alpha so that there's a hole in the stencil buffer. + } + + COLOR = vec4(0); +} diff --git a/Resources/Textures/Mob/masking_helpers.rsi/female_full.png b/Resources/Textures/Mob/masking_helpers.rsi/female_full.png new file mode 100644 index 0000000000000000000000000000000000000000..cd5127bc90d33fa35476e9aac9810b0c76acc749 GIT binary patch literal 134 zcmeAS@N?(olHy`uVBq!ia0vp^4j|0P3?wHke>@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pqvz@37@~1LIYA=F!GWRaBuh_#4GRNzM?iy+j=*_ig8~5_g&9&3%rX%& c%#Ya_Zly82-n{&4FimdKI;Vst0PTMzC;$Ke literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mob/masking_helpers.rsi/female_none.png b/Resources/Textures/Mob/masking_helpers.rsi/female_none.png new file mode 100644 index 0000000000000000000000000000000000000000..6e3cb09bcf701bc53ecc7886c19b82d386469aa6 GIT binary patch literal 83 zcmeAS@N?(olHy`uVBq!ia0vp^3LwnE1|*BCs=fdzDNh&2kcv5P4>B?Wc})uc*XMaS bfSB*u1QZw;C7n&)0XYnwu6{1-oD!M@jRu?6^qxB}__|Nk$&IsYz@#aI&L z7tG-B>_!@pqvh%17@~1LIYA=F!GWQv-9CX)kSm~x^-(1o8($M6OE7bC19NwB!XE~P Y>pcuFdpA6>0P14!boFyt=akR{0B)-!)c^nh literal 0 HcmV?d00001 diff --git a/Resources/Textures/Mob/masking_helpers.rsi/meta.json b/Resources/Textures/Mob/masking_helpers.rsi/meta.json new file mode 100644 index 0000000000..530b0c4848 --- /dev/null +++ b/Resources/Textures/Mob/masking_helpers.rsi/meta.json @@ -0,0 +1 @@ +{"version": 1, "size": {"x": 32, "y": 32}, "states": [{"name": "female_full", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}, {"name": "female_top", "directions": 4, "delays": [[1.0], [1.0], [1.0], [1.0]]}]} \ No newline at end of file