Makes Eyepatches Flippable (#26277)

This commit is contained in:
Cojoke
2024-06-16 22:21:29 -05:00
committed by GitHub
parent f7aca6b15f
commit 390f8d19d1
10 changed files with 175 additions and 56 deletions

View File

@@ -1,5 +1,6 @@
using System.Diagnostics.CodeAnalysis;
using System.Linq;
using System.Numerics;
using Content.Client.Inventory;
using Content.Shared.Clothing;
using Content.Shared.Clothing.Components;
@@ -113,6 +114,7 @@ public sealed class ClientClothingSystem : ClothingSystem
i++;
}
item.MappedLayer = key;
args.Layers.Add((key, layer));
}
}
@@ -153,13 +155,9 @@ public sealed class ClientClothingSystem : ClothingSystem
// species specific
if (speciesId != null && rsi.TryGetState($"{state}-{speciesId}", out _))
{
state = $"{state}-{speciesId}";
}
else if (!rsi.TryGetState(state, out _))
{
return false;
}
var layer = new PrototypeLayerData();
layer.RsiPath = rsi.Path.ToString();
@@ -287,6 +285,8 @@ public sealed class ClientClothingSystem : ClothingSystem
if (layerData.Color != null)
sprite.LayerSetColor(key, layerData.Color.Value);
if (layerData.Scale != null)
sprite.LayerSetScale(key, layerData.Scale.Value);
}
else
index = sprite.LayerMapReserveBlank(key);

View File

@@ -0,0 +1,48 @@
using Content.Shared.Clothing;
using Content.Shared.Clothing.Components;
using Content.Shared.Clothing.EntitySystems;
using Content.Shared.Foldable;
using Content.Shared.Item;
using Robust.Client.GameObjects;
namespace Content.Client.Clothing;
public sealed class FlippableClothingVisualizerSystem : VisualizerSystem<FlippableClothingVisualsComponent>
{
[Dependency] private readonly SharedItemSystem _itemSys = default!;
public override void Initialize()
{
base.Initialize();
SubscribeLocalEvent<FlippableClothingVisualsComponent, GetEquipmentVisualsEvent>(OnGetVisuals, after: [typeof(ClothingSystem)]);
SubscribeLocalEvent<FlippableClothingVisualsComponent, FoldedEvent>(OnFolded);
}
private void OnFolded(Entity<FlippableClothingVisualsComponent> ent, ref FoldedEvent args)
{
_itemSys.VisualsChanged(ent);
}
private void OnGetVisuals(Entity<FlippableClothingVisualsComponent> ent, ref GetEquipmentVisualsEvent args)
{
if (!TryComp(ent, out SpriteComponent? sprite) ||
!TryComp(ent, out ClothingComponent? clothing))
return;
if (clothing.MappedLayer == null ||
!AppearanceSystem.TryGetData<bool>(ent, FoldableSystem.FoldedVisuals.State, out var folding) ||
!sprite.LayerMapTryGet(folding ? ent.Comp.FoldingLayer : ent.Comp.UnfoldingLayer, out var idx))
return;
// add each layer to the visuals
var spriteLayer = sprite[idx];
foreach (var layer in args.Layers)
{
if (layer.Item1 != clothing.MappedLayer)
continue;
layer.Item2.Scale = spriteLayer.Scale;
}
}
}

View File

@@ -0,0 +1,16 @@
namespace Content.Client.Clothing;
/// <summary>
/// Communicates folded layers data (currently only Scale to handle flipping)
/// to the wearer clothing sprite layer
/// </summary>
[RegisterComponent]
[Access(typeof(FlippableClothingVisualizerSystem))]
public sealed partial class FlippableClothingVisualsComponent : Component
{
[DataField]
public string FoldingLayer = "foldedLayer";
[DataField]
public string UnfoldingLayer = "unfoldedLayer";
}

View File

@@ -43,9 +43,6 @@ public sealed class RandomSpriteSystem : SharedRandomSpriteSystem
if (!Resolve(uid, ref clothing, false))
return;
if (clothing.ClothingVisuals == null)
return;
foreach (var slotPair in clothing.ClothingVisuals)
{
foreach (var keyColorPair in component.Selected)

View File

@@ -16,9 +16,14 @@ namespace Content.Shared.Clothing.Components;
public sealed partial class ClothingComponent : Component
{
[DataField("clothingVisuals")]
[Access(typeof(ClothingSystem), typeof(InventorySystem), Other = AccessPermissions.ReadExecute)] // TODO remove execute permissions.
public Dictionary<string, List<PrototypeLayerData>> ClothingVisuals = new();
/// <summary>
/// The name of the layer in the user that this piece of clothing will map to
/// </summary>
[DataField]
public string? MappedLayer;
[ViewVariables(VVAccess.ReadWrite)]
[DataField("quickEquip")]
public bool QuickEquip = true;
@@ -121,4 +126,3 @@ public sealed partial class ClothingUnequipDoAfterEvent : DoAfterEvent
public override DoAfterEvent Clone() => this;
}

View File

@@ -241,9 +241,6 @@ public abstract class ClothingSystem : EntitySystem
public void SetLayerColor(ClothingComponent clothing, string slot, string mapKey, Color? color)
{
if (clothing.ClothingVisuals == null)
return;
foreach (var layer in clothing.ClothingVisuals[slot])
{
if (layer.MapKeys == null)
@@ -257,9 +254,6 @@ public abstract class ClothingSystem : EntitySystem
}
public void SetLayerState(ClothingComponent clothing, string slot, string mapKey, string state)
{
if (clothing.ClothingVisuals == null)
return;
foreach (var layer in clothing.ClothingVisuals[slot])
{
if (layer.MapKeys == null)

View File

@@ -33,32 +33,32 @@ public sealed class FoldableClothingSystem : EntitySystem
private void OnFolded(Entity<FoldableClothingComponent> ent, ref FoldedEvent args)
{
if (TryComp<ClothingComponent>(ent.Owner, out var clothingComp) &&
TryComp<ItemComponent>(ent.Owner, out var itemComp))
if (!TryComp<ClothingComponent>(ent.Owner, out var clothingComp) ||
!TryComp<ItemComponent>(ent.Owner, out var itemComp))
return;
if (args.IsFolded)
{
if (args.IsFolded)
{
if (ent.Comp.FoldedSlots.HasValue)
_clothingSystem.SetSlots(ent.Owner, ent.Comp.FoldedSlots.Value, clothingComp);
if (ent.Comp.FoldedSlots.HasValue)
_clothingSystem.SetSlots(ent.Owner, ent.Comp.FoldedSlots.Value, clothingComp);
if (ent.Comp.FoldedEquippedPrefix != null)
_clothingSystem.SetEquippedPrefix(ent.Owner, ent.Comp.FoldedEquippedPrefix, clothingComp);
if (ent.Comp.FoldedEquippedPrefix != null)
_clothingSystem.SetEquippedPrefix(ent.Owner, ent.Comp.FoldedEquippedPrefix, clothingComp);
if (ent.Comp.FoldedHeldPrefix != null)
_itemSystem.SetHeldPrefix(ent.Owner, ent.Comp.FoldedHeldPrefix, false, itemComp);
}
else
{
if (ent.Comp.UnfoldedSlots.HasValue)
_clothingSystem.SetSlots(ent.Owner, ent.Comp.UnfoldedSlots.Value, clothingComp);
if (ent.Comp.FoldedHeldPrefix != null)
_itemSystem.SetHeldPrefix(ent.Owner, ent.Comp.FoldedHeldPrefix, false, itemComp);
}
else
{
if (ent.Comp.UnfoldedSlots.HasValue)
_clothingSystem.SetSlots(ent.Owner, ent.Comp.UnfoldedSlots.Value, clothingComp);
if (ent.Comp.FoldedEquippedPrefix != null)
_clothingSystem.SetEquippedPrefix(ent.Owner, null, clothingComp);
if (ent.Comp.FoldedEquippedPrefix != null)
_clothingSystem.SetEquippedPrefix(ent.Owner, null, clothingComp);
if (ent.Comp.FoldedHeldPrefix != null)
_itemSystem.SetHeldPrefix(ent.Owner, null, false, itemComp);
if (ent.Comp.FoldedHeldPrefix != null)
_itemSystem.SetHeldPrefix(ent.Owner, null, false, itemComp);
}
}
}
}

View File

@@ -10,3 +10,42 @@
- type: Item
size: Small
storedRotation: -90
- type: entity
parent: [ClothingEyesBase, BaseFoldable]
id: ClothingHeadEyeBaseFlippable
abstract: true
components:
- type: Appearance
- type: FlippableClothingVisuals
- type: Foldable
canFoldInsideContainer: true
unfoldVerbText: fold-flip-verb
foldVerbText: fold-flip-verb
- type: FoldableClothing
- type: Sprite
layers:
- map: [ "unfoldedLayer" ]
state: icon
- map: ["foldedLayer"]
state: icon
visible: false
scale: -1,1
- type: entity
parent: ClothingHeadEyeBaseFlippable
id: ClothingHeadEyeBaseFlipped
suffix: flipped
abstract: true
components:
- type: Foldable
folded: true
- type: Sprite
layers:
- map: [ "unfoldedLayer" ]
state: icon
visible: false
- map: ["foldedLayer"]
state: icon
visible: true
scale: -1,1

View File

@@ -220,7 +220,7 @@
suffix: Syndicate
- type: entity
parent: ClothingEyesHudMedical
parent: [ClothingEyesHudMedical, ClothingHeadEyeBaseFlippable]
id: ClothingEyesEyepatchHudMedical
name: medical hud eyepatch
description: A heads-up display that scans the humanoids in view and provides accurate data about their health status. For true patriots.
@@ -231,7 +231,12 @@
sprite: Clothing/Eyes/Hud/medpatch.rsi
- type: entity
parent: ClothingEyesHudSecurity
parent: [ClothingEyesEyepatchHudMedical, ClothingHeadEyeBaseFlipped]
id: ClothingEyesEyepatchHudMedicalFlipped
name: medical hud eyepatch
- type: entity
parent: [ClothingEyesHudSecurity, ClothingHeadEyeBaseFlippable]
id: ClothingEyesEyepatchHudSecurity
name: security hud eyepatch
description: A heads-up display that scans the humanoids in view and provides accurate data about their ID status and security records. For true patriots.
@@ -242,7 +247,12 @@
sprite: Clothing/Eyes/Hud/secpatch.rsi
- type: entity
parent: ClothingEyesHudBeer
parent: [ClothingEyesEyepatchHudSecurity, ClothingHeadEyeBaseFlipped]
id: ClothingEyesEyepatchHudSecurityFlipped
name: security hud eyepatch
- type: entity
parent: [ClothingEyesHudBeer, ClothingHeadEyeBaseFlippable]
id: ClothingEyesEyepatchHudBeer
name: beer hud eyepatch
description: A pair of sunHud outfitted with apparatus to scan reagents, as well as providing an innate understanding of liquid viscosity while in motion. For true patriots.
@@ -253,7 +263,12 @@
sprite: Clothing/Eyes/Hud/beerpatch.rsi
- type: entity
parent: ClothingEyesBase
parent: [ClothingEyesEyepatchHudBeer, ClothingHeadEyeBaseFlipped]
id: ClothingEyesEyepatchHudBeerFlipped
name: beer hud eyepatch
- type: entity
parent: [ClothingEyesHudDiagnostic, ClothingHeadEyeBaseFlippable]
id: ClothingEyesEyepatchHudDiag
name: diagnostic hud eyepatch
description: A heads-up display capable of analyzing the integrity and status of robotics and exosuits. Made out of see-borg-ium.
@@ -262,7 +277,8 @@
sprite: Clothing/Eyes/Hud/diagpatch.rsi
- type: Clothing
sprite: Clothing/Eyes/Hud/diagpatch.rsi
- type: ShowHealthBars
damageContainers:
- Inorganic
- Silicon
- type: entity
parent: [ClothingEyesEyepatchHudDiag, ClothingHeadEyeBaseFlipped]
id: ClothingEyesEyepatchHudDiagFlipped
name: diagnostic hud eyepatch

View File

@@ -1,16 +1,3 @@
- type: entity
parent: ClothingEyesBase
id: ClothingEyesEyepatch
name: eyepatch
description: Yarr.
components:
- type: Sprite
sprite: Clothing/Eyes/Misc/eyepatch.rsi
- type: Clothing
sprite: Clothing/Eyes/Misc/eyepatch.rsi
- type: EyeProtection
protectionTime: 5
- type: entity
parent: ClothingEyesBase
id: ClothingEyesBlindfold
@@ -26,3 +13,21 @@
graph: Blindfold
node: blindfold
- type: FlashImmunity
- type: entity
parent: ClothingHeadEyeBaseFlippable
id: ClothingEyesEyepatch
name: eyepatch
description: Yarr.
components:
- type: Sprite
sprite: Clothing/Eyes/Misc/eyepatch.rsi
- type: Clothing
sprite: Clothing/Eyes/Misc/eyepatch.rsi
- type: EyeProtection
protectionTime: 5
- type: entity
parent: [ClothingEyesEyepatch, ClothingHeadEyeBaseFlipped]
id: ClothingEyesEyepatchFlipped
suffix: flipped