Makes Eyepatches Flippable (#26277)
This commit is contained in:
@@ -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);
|
||||
|
||||
48
Content.Client/Clothing/FlippableClothingVisualizerSystem.cs
Normal file
48
Content.Client/Clothing/FlippableClothingVisualizerSystem.cs
Normal 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;
|
||||
}
|
||||
}
|
||||
}
|
||||
16
Content.Client/Clothing/FlippableClothingVisualsComponent.cs
Normal file
16
Content.Client/Clothing/FlippableClothingVisualsComponent.cs
Normal 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";
|
||||
}
|
||||
@@ -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)
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
|
||||
|
||||
@@ -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)
|
||||
|
||||
@@ -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);
|
||||
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user