Makes Eyepatches Flippable (#26277)
This commit is contained in:
@@ -1,5 +1,6 @@
|
|||||||
using System.Diagnostics.CodeAnalysis;
|
using System.Diagnostics.CodeAnalysis;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using System.Numerics;
|
||||||
using Content.Client.Inventory;
|
using Content.Client.Inventory;
|
||||||
using Content.Shared.Clothing;
|
using Content.Shared.Clothing;
|
||||||
using Content.Shared.Clothing.Components;
|
using Content.Shared.Clothing.Components;
|
||||||
@@ -113,6 +114,7 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||||||
i++;
|
i++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
item.MappedLayer = key;
|
||||||
args.Layers.Add((key, layer));
|
args.Layers.Add((key, layer));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -153,13 +155,9 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||||||
|
|
||||||
// species specific
|
// species specific
|
||||||
if (speciesId != null && rsi.TryGetState($"{state}-{speciesId}", out _))
|
if (speciesId != null && rsi.TryGetState($"{state}-{speciesId}", out _))
|
||||||
{
|
|
||||||
state = $"{state}-{speciesId}";
|
state = $"{state}-{speciesId}";
|
||||||
}
|
|
||||||
else if (!rsi.TryGetState(state, out _))
|
else if (!rsi.TryGetState(state, out _))
|
||||||
{
|
|
||||||
return false;
|
return false;
|
||||||
}
|
|
||||||
|
|
||||||
var layer = new PrototypeLayerData();
|
var layer = new PrototypeLayerData();
|
||||||
layer.RsiPath = rsi.Path.ToString();
|
layer.RsiPath = rsi.Path.ToString();
|
||||||
@@ -287,6 +285,8 @@ public sealed class ClientClothingSystem : ClothingSystem
|
|||||||
|
|
||||||
if (layerData.Color != null)
|
if (layerData.Color != null)
|
||||||
sprite.LayerSetColor(key, layerData.Color.Value);
|
sprite.LayerSetColor(key, layerData.Color.Value);
|
||||||
|
if (layerData.Scale != null)
|
||||||
|
sprite.LayerSetScale(key, layerData.Scale.Value);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
index = sprite.LayerMapReserveBlank(key);
|
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))
|
if (!Resolve(uid, ref clothing, false))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
if (clothing.ClothingVisuals == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var slotPair in clothing.ClothingVisuals)
|
foreach (var slotPair in clothing.ClothingVisuals)
|
||||||
{
|
{
|
||||||
foreach (var keyColorPair in component.Selected)
|
foreach (var keyColorPair in component.Selected)
|
||||||
|
|||||||
@@ -16,9 +16,14 @@ namespace Content.Shared.Clothing.Components;
|
|||||||
public sealed partial class ClothingComponent : Component
|
public sealed partial class ClothingComponent : Component
|
||||||
{
|
{
|
||||||
[DataField("clothingVisuals")]
|
[DataField("clothingVisuals")]
|
||||||
[Access(typeof(ClothingSystem), typeof(InventorySystem), Other = AccessPermissions.ReadExecute)] // TODO remove execute permissions.
|
|
||||||
public Dictionary<string, List<PrototypeLayerData>> ClothingVisuals = new();
|
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)]
|
[ViewVariables(VVAccess.ReadWrite)]
|
||||||
[DataField("quickEquip")]
|
[DataField("quickEquip")]
|
||||||
public bool QuickEquip = true;
|
public bool QuickEquip = true;
|
||||||
@@ -121,4 +126,3 @@ public sealed partial class ClothingUnequipDoAfterEvent : DoAfterEvent
|
|||||||
|
|
||||||
public override DoAfterEvent Clone() => this;
|
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)
|
public void SetLayerColor(ClothingComponent clothing, string slot, string mapKey, Color? color)
|
||||||
{
|
{
|
||||||
if (clothing.ClothingVisuals == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var layer in clothing.ClothingVisuals[slot])
|
foreach (var layer in clothing.ClothingVisuals[slot])
|
||||||
{
|
{
|
||||||
if (layer.MapKeys == null)
|
if (layer.MapKeys == null)
|
||||||
@@ -257,9 +254,6 @@ public abstract class ClothingSystem : EntitySystem
|
|||||||
}
|
}
|
||||||
public void SetLayerState(ClothingComponent clothing, string slot, string mapKey, string state)
|
public void SetLayerState(ClothingComponent clothing, string slot, string mapKey, string state)
|
||||||
{
|
{
|
||||||
if (clothing.ClothingVisuals == null)
|
|
||||||
return;
|
|
||||||
|
|
||||||
foreach (var layer in clothing.ClothingVisuals[slot])
|
foreach (var layer in clothing.ClothingVisuals[slot])
|
||||||
{
|
{
|
||||||
if (layer.MapKeys == null)
|
if (layer.MapKeys == null)
|
||||||
|
|||||||
@@ -33,32 +33,32 @@ public sealed class FoldableClothingSystem : EntitySystem
|
|||||||
|
|
||||||
private void OnFolded(Entity<FoldableClothingComponent> ent, ref FoldedEvent args)
|
private void OnFolded(Entity<FoldableClothingComponent> ent, ref FoldedEvent args)
|
||||||
{
|
{
|
||||||
if (TryComp<ClothingComponent>(ent.Owner, out var clothingComp) &&
|
if (!TryComp<ClothingComponent>(ent.Owner, out var clothingComp) ||
|
||||||
TryComp<ItemComponent>(ent.Owner, out var itemComp))
|
!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)
|
if (ent.Comp.FoldedEquippedPrefix != null)
|
||||||
_clothingSystem.SetEquippedPrefix(ent.Owner, ent.Comp.FoldedEquippedPrefix, clothingComp);
|
_clothingSystem.SetEquippedPrefix(ent.Owner, ent.Comp.FoldedEquippedPrefix, clothingComp);
|
||||||
|
|
||||||
if (ent.Comp.FoldedHeldPrefix != null)
|
if (ent.Comp.FoldedHeldPrefix != null)
|
||||||
_itemSystem.SetHeldPrefix(ent.Owner, ent.Comp.FoldedHeldPrefix, false, itemComp);
|
_itemSystem.SetHeldPrefix(ent.Owner, ent.Comp.FoldedHeldPrefix, false, itemComp);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
if (ent.Comp.UnfoldedSlots.HasValue)
|
if (ent.Comp.UnfoldedSlots.HasValue)
|
||||||
_clothingSystem.SetSlots(ent.Owner, ent.Comp.UnfoldedSlots.Value, clothingComp);
|
_clothingSystem.SetSlots(ent.Owner, ent.Comp.UnfoldedSlots.Value, clothingComp);
|
||||||
|
|
||||||
if (ent.Comp.FoldedEquippedPrefix != null)
|
if (ent.Comp.FoldedEquippedPrefix != null)
|
||||||
_clothingSystem.SetEquippedPrefix(ent.Owner, null, clothingComp);
|
_clothingSystem.SetEquippedPrefix(ent.Owner, null, clothingComp);
|
||||||
|
|
||||||
if (ent.Comp.FoldedHeldPrefix != null)
|
if (ent.Comp.FoldedHeldPrefix != null)
|
||||||
_itemSystem.SetHeldPrefix(ent.Owner, null, false, itemComp);
|
_itemSystem.SetHeldPrefix(ent.Owner, null, false, itemComp);
|
||||||
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -10,3 +10,42 @@
|
|||||||
- type: Item
|
- type: Item
|
||||||
size: Small
|
size: Small
|
||||||
storedRotation: -90
|
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
|
suffix: Syndicate
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingEyesHudMedical
|
parent: [ClothingEyesHudMedical, ClothingHeadEyeBaseFlippable]
|
||||||
id: ClothingEyesEyepatchHudMedical
|
id: ClothingEyesEyepatchHudMedical
|
||||||
name: medical hud eyepatch
|
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.
|
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
|
sprite: Clothing/Eyes/Hud/medpatch.rsi
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingEyesHudSecurity
|
parent: [ClothingEyesEyepatchHudMedical, ClothingHeadEyeBaseFlipped]
|
||||||
|
id: ClothingEyesEyepatchHudMedicalFlipped
|
||||||
|
name: medical hud eyepatch
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: [ClothingEyesHudSecurity, ClothingHeadEyeBaseFlippable]
|
||||||
id: ClothingEyesEyepatchHudSecurity
|
id: ClothingEyesEyepatchHudSecurity
|
||||||
name: security hud eyepatch
|
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.
|
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
|
sprite: Clothing/Eyes/Hud/secpatch.rsi
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingEyesHudBeer
|
parent: [ClothingEyesEyepatchHudSecurity, ClothingHeadEyeBaseFlipped]
|
||||||
|
id: ClothingEyesEyepatchHudSecurityFlipped
|
||||||
|
name: security hud eyepatch
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: [ClothingEyesHudBeer, ClothingHeadEyeBaseFlippable]
|
||||||
id: ClothingEyesEyepatchHudBeer
|
id: ClothingEyesEyepatchHudBeer
|
||||||
name: beer hud eyepatch
|
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.
|
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
|
sprite: Clothing/Eyes/Hud/beerpatch.rsi
|
||||||
|
|
||||||
- type: entity
|
- type: entity
|
||||||
parent: ClothingEyesBase
|
parent: [ClothingEyesEyepatchHudBeer, ClothingHeadEyeBaseFlipped]
|
||||||
|
id: ClothingEyesEyepatchHudBeerFlipped
|
||||||
|
name: beer hud eyepatch
|
||||||
|
|
||||||
|
- type: entity
|
||||||
|
parent: [ClothingEyesHudDiagnostic, ClothingHeadEyeBaseFlippable]
|
||||||
id: ClothingEyesEyepatchHudDiag
|
id: ClothingEyesEyepatchHudDiag
|
||||||
name: diagnostic hud eyepatch
|
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.
|
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
|
sprite: Clothing/Eyes/Hud/diagpatch.rsi
|
||||||
- type: Clothing
|
- type: Clothing
|
||||||
sprite: Clothing/Eyes/Hud/diagpatch.rsi
|
sprite: Clothing/Eyes/Hud/diagpatch.rsi
|
||||||
- type: ShowHealthBars
|
|
||||||
damageContainers:
|
- type: entity
|
||||||
- Inorganic
|
parent: [ClothingEyesEyepatchHudDiag, ClothingHeadEyeBaseFlipped]
|
||||||
- Silicon
|
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
|
- type: entity
|
||||||
parent: ClothingEyesBase
|
parent: ClothingEyesBase
|
||||||
id: ClothingEyesBlindfold
|
id: ClothingEyesBlindfold
|
||||||
@@ -26,3 +13,21 @@
|
|||||||
graph: Blindfold
|
graph: Blindfold
|
||||||
node: blindfold
|
node: blindfold
|
||||||
- type: FlashImmunity
|
- 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