Clothing/item ECS & cleanup (#9706)
This commit is contained in:
@@ -1,18 +1,15 @@
|
||||
using Content.Client.Items.Components;
|
||||
using Content.Shared.Item;
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Robust.Shared.GameStates;
|
||||
|
||||
namespace Content.Client.Clothing
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedItemComponent))]
|
||||
[ComponentReference(typeof(ItemComponent))]
|
||||
[NetworkedComponent()]
|
||||
public sealed class ClothingComponent : ItemComponent
|
||||
[ComponentReference(typeof(SharedClothingComponent))]
|
||||
public sealed class ClothingComponent : SharedClothingComponent
|
||||
{
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
[DataField("femaleMask")]
|
||||
public FemaleClothingMask FemaleMask { get; } = FemaleClothingMask.UniformFull;
|
||||
public FemaleClothingMask FemaleMask = FemaleClothingMask.UniformFull;
|
||||
|
||||
public string? InSlot;
|
||||
}
|
||||
|
||||
@@ -4,6 +4,7 @@ using System.Linq;
|
||||
using Content.Client.Inventory;
|
||||
using Content.Shared.CharacterAppearance;
|
||||
using Content.Shared.Clothing;
|
||||
using Content.Shared.Clothing.Components;
|
||||
using Content.Shared.Inventory;
|
||||
using Content.Shared.Inventory.Events;
|
||||
using Content.Shared.Item;
|
||||
@@ -16,7 +17,7 @@ using static Robust.Shared.GameObjects.SharedSpriteComponent;
|
||||
|
||||
namespace Content.Client.Clothing;
|
||||
|
||||
public sealed class ClothingSystem : EntitySystem
|
||||
public sealed class ClothingVisualsSystem : EntitySystem
|
||||
{
|
||||
/// <summary>
|
||||
/// This is a shitty hotfix written by me (Paul) to save me from renaming all files.
|
||||
@@ -52,13 +53,13 @@ public sealed class ClothingSystem : EntitySystem
|
||||
SubscribeLocalEvent<ClothingComponent, GotEquippedEvent>(OnGotEquipped);
|
||||
SubscribeLocalEvent<ClothingComponent, GotUnequippedEvent>(OnGotUnequipped);
|
||||
|
||||
SubscribeLocalEvent<SharedItemComponent, GetEquipmentVisualsEvent>(OnGetVisuals);
|
||||
SubscribeLocalEvent<ClothingComponent, GetEquipmentVisualsEvent>(OnGetVisuals);
|
||||
|
||||
SubscribeLocalEvent<ClientInventoryComponent, VisualsChangedEvent>(OnVisualsChanged);
|
||||
SubscribeLocalEvent<SpriteComponent, DidUnequipEvent>(OnDidUnequip);
|
||||
}
|
||||
|
||||
private void OnGetVisuals(EntityUid uid, SharedItemComponent item, GetEquipmentVisualsEvent args)
|
||||
private void OnGetVisuals(EntityUid uid, ClothingComponent item, GetEquipmentVisualsEvent args)
|
||||
{
|
||||
if (!TryComp(args.Equipee, out ClientInventoryComponent? inventory))
|
||||
return;
|
||||
@@ -99,15 +100,15 @@ public sealed class ClothingSystem : EntitySystem
|
||||
/// <remarks>
|
||||
/// Useful for lazily adding clothing sprites without modifying yaml. And for backwards compatibility.
|
||||
/// </remarks>
|
||||
private bool TryGetDefaultVisuals(EntityUid uid, SharedItemComponent item, string slot, string? speciesId,
|
||||
private bool TryGetDefaultVisuals(EntityUid uid, ClothingComponent clothing, string slot, string? speciesId,
|
||||
[NotNullWhen(true)] out List<PrototypeLayerData>? layers)
|
||||
{
|
||||
layers = null;
|
||||
|
||||
RSI? rsi = null;
|
||||
|
||||
if (item.RsiPath != null)
|
||||
rsi = _cache.GetResource<RSIResource>(TextureRoot / item.RsiPath).RSI;
|
||||
if (clothing.RsiPath != null)
|
||||
rsi = _cache.GetResource<RSIResource>(TextureRoot / clothing.RsiPath).RSI;
|
||||
else if (TryComp(uid, out SpriteComponent? sprite))
|
||||
rsi = sprite.BaseRSI;
|
||||
|
||||
@@ -117,9 +118,9 @@ public sealed class ClothingSystem : EntitySystem
|
||||
var correctedSlot = slot;
|
||||
TemporarySlotMap.TryGetValue(correctedSlot, out correctedSlot);
|
||||
|
||||
var state = (item.EquippedPrefix == null)
|
||||
var state = (clothing.EquippedPrefix == null)
|
||||
? $"equipped-{correctedSlot}"
|
||||
: $"{item.EquippedPrefix}-equipped-{correctedSlot}";
|
||||
: $"{clothing.EquippedPrefix}-equipped-{correctedSlot}";
|
||||
|
||||
// species specific
|
||||
if (speciesId != null && rsi.TryGetState($"{state}-{speciesId}", out _))
|
||||
@@ -36,7 +36,7 @@ namespace Content.Client.Inventory
|
||||
[Dependency] private readonly IPrototypeManager _prototypeManager = default!;
|
||||
[Dependency] private readonly IConfigurationManager _config = default!;
|
||||
[Dependency] private readonly IItemSlotManager _itemSlotManager = default!;
|
||||
[Dependency] private readonly ClothingSystem _clothingSystem = default!;
|
||||
[Dependency] private readonly ClothingVisualsSystem _clothingVisualsSystem = default!;
|
||||
|
||||
public const int ButtonSize = 64;
|
||||
private const int ButtonSeparation = 4;
|
||||
@@ -165,7 +165,7 @@ namespace Content.Client.Inventory
|
||||
|
||||
private void OnInit(EntityUid uid, ClientInventoryComponent component, ComponentInit args)
|
||||
{
|
||||
_clothingSystem.InitClothing(uid, component);
|
||||
_clothingVisualsSystem.InitClothing(uid, component);
|
||||
|
||||
if (!TryGetUIElements(uid, out var window, out var bottomLeft, out var bottomRight, out var topQuick,
|
||||
component))
|
||||
|
||||
@@ -1,11 +0,0 @@
|
||||
using Content.Shared.Item;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.IoC;
|
||||
|
||||
namespace Content.Client.Items.Components
|
||||
{
|
||||
[RegisterComponent]
|
||||
[ComponentReference(typeof(SharedItemComponent))]
|
||||
[Virtual]
|
||||
public class ItemComponent : SharedItemComponent { }
|
||||
}
|
||||
@@ -1,11 +1,11 @@
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using Content.Shared.Hands;
|
||||
using Content.Shared.Item;
|
||||
using Robust.Client.GameObjects;
|
||||
using Robust.Client.Graphics;
|
||||
using Robust.Client.ResourceManagement;
|
||||
using Robust.Shared.Containers;
|
||||
using System.Diagnostics.CodeAnalysis;
|
||||
using System.Linq;
|
||||
using static Robust.Shared.GameObjects.SharedSpriteComponent;
|
||||
|
||||
namespace Content.Client.Items.Systems;
|
||||
@@ -19,18 +19,16 @@ public sealed class ItemSystem : SharedItemSystem
|
||||
{
|
||||
base.Initialize();
|
||||
|
||||
SubscribeLocalEvent<SharedItemComponent, GetInhandVisualsEvent>(OnGetVisuals);
|
||||
SubscribeLocalEvent<ItemComponent, GetInhandVisualsEvent>(OnGetVisuals);
|
||||
}
|
||||
|
||||
#region InhandVisuals
|
||||
|
||||
/// <summary>
|
||||
/// When an items visual state changes, notify and entities that are holding this item that their sprite may need updating.
|
||||
/// </summary>
|
||||
public override void VisualsChanged(EntityUid uid, SharedItemComponent? item = null)
|
||||
public override void VisualsChanged(EntityUid uid)
|
||||
{
|
||||
if (!Resolve(uid, ref item, false))
|
||||
return;
|
||||
|
||||
// if the item is in a container, it might be equipped to hands or inventory slots --> update visuals.
|
||||
if (_containerSystem.TryGetContainingContainer(uid, out var container))
|
||||
RaiseLocalEvent(container.Owner, new VisualsChangedEvent(uid, container.ID), true);
|
||||
@@ -39,12 +37,12 @@ public sealed class ItemSystem : SharedItemSystem
|
||||
/// <summary>
|
||||
/// An entity holding this item is requesting visual information for in-hand sprites.
|
||||
/// </summary>
|
||||
private void OnGetVisuals(EntityUid uid, SharedItemComponent item, GetInhandVisualsEvent args)
|
||||
private void OnGetVisuals(EntityUid uid, ItemComponent item, GetInhandVisualsEvent args)
|
||||
{
|
||||
var defaultKey = $"inhand-{args.Location.ToString().ToLowerInvariant()}";
|
||||
|
||||
// try get explicit visuals
|
||||
if (item.InhandVisuals == null || !item.InhandVisuals.TryGetValue(args.Location, out var layers))
|
||||
if (!item.InhandVisuals.TryGetValue(args.Location, out var layers))
|
||||
{
|
||||
// get defaults
|
||||
if (!TryGetDefaultVisuals(uid, item, defaultKey, out layers))
|
||||
@@ -71,7 +69,7 @@ public sealed class ItemSystem : SharedItemSystem
|
||||
/// <remarks>
|
||||
/// Useful for lazily adding in-hand sprites without modifying yaml. And backwards compatibility.
|
||||
/// </remarks>
|
||||
private bool TryGetDefaultVisuals(EntityUid uid, SharedItemComponent item, string defaultKey, [NotNullWhen(true)] out List<PrototypeLayerData>? result)
|
||||
private bool TryGetDefaultVisuals(EntityUid uid, ItemComponent item, string defaultKey, [NotNullWhen(true)] out List<PrototypeLayerData>? result)
|
||||
{
|
||||
result = null;
|
||||
|
||||
@@ -85,9 +83,9 @@ public sealed class ItemSystem : SharedItemSystem
|
||||
if (rsi == null || rsi.Path == null)
|
||||
return false;
|
||||
|
||||
var state = (item.EquippedPrefix == null)
|
||||
var state = (item.HeldPrefix == null)
|
||||
? defaultKey
|
||||
: $"{item.EquippedPrefix}-{defaultKey}";
|
||||
: $"{item.HeldPrefix}-{defaultKey}";
|
||||
|
||||
if (!rsi.TryGetState(state, out var _))
|
||||
return false;
|
||||
|
||||
@@ -30,10 +30,9 @@ public sealed class HandheldLightSystem : EntitySystem
|
||||
|
||||
// really hand-held lights should be using a separate unshaded layer. (see FlashlightVisualizer)
|
||||
// this prefix stuff is largely for backwards compatibility with RSIs/yamls that have not been updated.
|
||||
if (component.AddPrefix && TryComp(uid, out SharedItemComponent? item))
|
||||
if (component.AddPrefix && TryComp(uid, out ItemComponent? item))
|
||||
{
|
||||
item.EquippedPrefix = state.Activated ? "on" : "off";
|
||||
_itemSys.VisualsChanged(uid);
|
||||
_itemSys.SetHeldPrefix(uid, state.Activated ? "on" : "off", item);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
using Content.Client.Clothing;
|
||||
using Content.Shared.Clothing.EntitySystems;
|
||||
using Content.Shared.Movement.Components;
|
||||
using Content.Shared.Movement.Systems;
|
||||
using Content.Shared.Weapons.Ranged.Systems;
|
||||
@@ -14,6 +15,7 @@ public sealed class JetpackSystem : SharedJetpackSystem
|
||||
{
|
||||
[Dependency] private readonly IGameTiming _timing = default!;
|
||||
[Dependency] private readonly IMapManager _mapManager = default!;
|
||||
[Dependency] private readonly ClothingSystem _clothing = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -35,7 +37,7 @@ public sealed class JetpackSystem : SharedJetpackSystem
|
||||
args.Sprite?.LayerSetState(0, state);
|
||||
|
||||
if (TryComp<ClothingComponent>(uid, out var clothing))
|
||||
clothing.EquippedPrefix = enabled ? "on" : null;
|
||||
_clothing.SetEquippedPrefix(uid, enabled ? "on" : null, clothing);
|
||||
}
|
||||
|
||||
public override void Update(float frameTime)
|
||||
|
||||
@@ -4,6 +4,7 @@ using Robust.Client.UserInterface.Controls;
|
||||
using Robust.Client.UserInterface.CustomControls;
|
||||
using Content.Client.Items.Components;
|
||||
using Content.Client.UserInterface.Controls;
|
||||
using Content.Shared.Item;
|
||||
using Robust.Client.UserInterface;
|
||||
using static Robust.Client.UserInterface.Controls.BoxContainer;
|
||||
using static Content.Shared.Storage.SharedStorageComponent;
|
||||
|
||||
@@ -18,7 +18,7 @@ public sealed class ToggleableLightVisualsSystem : VisualizerSystem<ToggleableLi
|
||||
{
|
||||
base.Initialize();
|
||||
SubscribeLocalEvent<ToggleableLightVisualsComponent, GetInhandVisualsEvent>(OnGetHeldVisuals, after: new[] { typeof(ItemSystem) });
|
||||
SubscribeLocalEvent<ToggleableLightVisualsComponent, GetEquipmentVisualsEvent>(OnGetEquipmentVisuals, after: new[] { typeof(ClothingSystem) });
|
||||
SubscribeLocalEvent<ToggleableLightVisualsComponent, GetEquipmentVisualsEvent>(OnGetEquipmentVisuals, after: new[] { typeof(ClothingVisualsSystem) });
|
||||
}
|
||||
|
||||
protected override void OnAppearanceChange(EntityUid uid, ToggleableLightVisualsComponent component, ref AppearanceChangeEvent args)
|
||||
|
||||
Reference in New Issue
Block a user