diff --git a/Content.Client/Content.Client.csproj b/Content.Client/Content.Client.csproj
index b84a414408..e53fbe21b1 100644
--- a/Content.Client/Content.Client.csproj
+++ b/Content.Client/Content.Client.csproj
@@ -68,7 +68,9 @@
+
+
@@ -121,4 +123,4 @@
-
+
\ No newline at end of file
diff --git a/Content.Client/EntryPoint.cs b/Content.Client/EntryPoint.cs
index 6e96ce1976..2a2f4ee15d 100644
--- a/Content.Client/EntryPoint.cs
+++ b/Content.Client/EntryPoint.cs
@@ -1,4 +1,5 @@
using Content.Client.GameObjects;
+using Content.Client.GameObjects.Components.Clothing;
using Content.Client.GameObjects.Components.Construction;
using Content.Client.GameObjects.Components.Power;
using Content.Client.GameObjects.Components.SmoothWalling;
@@ -24,7 +25,6 @@ namespace Content.Client
var factory = IoCManager.Resolve();
var prototypes = IoCManager.Resolve();
- factory.RegisterIgnore("Item");
factory.RegisterIgnore("Interactable");
factory.RegisterIgnore("Damageable");
factory.RegisterIgnore("Destructible");
@@ -48,7 +48,6 @@ namespace Content.Client
factory.RegisterIgnore("MeleeWeapon");
factory.RegisterIgnore("Storeable");
- factory.RegisterIgnore("Clothing");
factory.RegisterIgnore("Material");
factory.RegisterIgnore("Stack");
@@ -61,6 +60,9 @@ namespace Content.Client
factory.Register();
factory.Register();
factory.Register();
+ factory.Register();
+ factory.Register();
+ factory.RegisterReference();
factory.RegisterIgnore("Construction");
factory.RegisterIgnore("Apc");
diff --git a/Content.Client/GameObjects/Components/Clothing/ClothingComponent.cs b/Content.Client/GameObjects/Components/Clothing/ClothingComponent.cs
new file mode 100644
index 0000000000..6deb653030
--- /dev/null
+++ b/Content.Client/GameObjects/Components/Clothing/ClothingComponent.cs
@@ -0,0 +1,27 @@
+using Content.Shared.GameObjects.Components.Inventory;
+using SS14.Client.Graphics;
+
+namespace Content.Client.GameObjects.Components.Clothing
+{
+ public class ClothingComponent : ItemComponent
+ {
+ public override string Name => "Clothing";
+
+ public (RSI rsi, RSI.StateId stateId)? GetEquippedStateInfo(EquipmentSlotDefines.SlotFlags slot)
+ {
+ if (RsiPath == null)
+ {
+ return null;
+ }
+
+ var rsi = GetRSI();
+ var stateId = EquippedPrefix != null ? $"{EquippedPrefix}-equipped-{slot}" : $"equipped-{slot}";
+ if (rsi.TryGetState(stateId, out _))
+ {
+ return (rsi, stateId);
+ }
+
+ return null;
+ }
+ }
+}
diff --git a/Content.Client/GameObjects/Components/Inventory/ClientInventoryComponent.cs b/Content.Client/GameObjects/Components/Inventory/ClientInventoryComponent.cs
index 6b3b85761d..04a03b8473 100644
--- a/Content.Client/GameObjects/Components/Inventory/ClientInventoryComponent.cs
+++ b/Content.Client/GameObjects/Components/Inventory/ClientInventoryComponent.cs
@@ -6,46 +6,118 @@ using SS14.Client.Interfaces.Input;
using SS14.Client.UserInterface;
using SS14.Client.UserInterface.Controls;
using SS14.Client.UserInterface.CustomControls;
-using SS14.Shared.ContentPack;
using SS14.Shared.GameObjects;
using SS14.Shared.Input;
using SS14.Shared.Interfaces.GameObjects;
using SS14.Shared.Interfaces.Network;
using SS14.Shared.IoC;
-using SS14.Shared.Log;
-using SS14.Shared.Maths;
using SS14.Shared.Serialization;
using SS14.Shared.Utility;
using System;
using System.Collections.Generic;
+using System.Linq;
+using Content.Client.GameObjects.Components.Clothing;
+using SS14.Shared.Interfaces.Reflection;
using static Content.Shared.GameObjects.Components.Inventory.EquipmentSlotDefines;
using static Content.Shared.GameObjects.SharedInventoryComponent.ClientInventoryMessage;
-using static Content.Shared.GameObjects.SharedInventoryComponent.ServerInventoryMessage;
namespace Content.Client.GameObjects
{
public class ClientInventoryComponent : SharedInventoryComponent
{
- private InventoryWindow Window;
- private string TemplateName = "HumanInventory"; //stored for serialization purposes
+ private Dictionary _slots = new Dictionary();
+
+ private InventoryWindow _window;
+ private string _templateName = "HumanInventory"; //stored for serialization purposes
private InputCmdHandler _openMenuCmdHandler;
+ private Inventory _inventory;
+
+ private ISpriteComponent _sprite;
public override void OnRemove()
{
base.OnRemove();
- Window.Dispose();
+ _window.Dispose();
+ }
+
+ public override void OnAdd()
+ {
+ base.OnAdd();
+
+ _openMenuCmdHandler = InputCmdHandler.FromDelegate(session => { _window.AddToScreen(); _window.Open(); });
+ }
+
+ public override void Initialize()
+ {
+ base.Initialize();
+
+ var reflectionManager = IoCManager.Resolve();
+ var type = reflectionManager.LooseGetType(_templateName);
+ DebugTools.Assert(type != null);
+ _inventory = (Inventory)Activator.CreateInstance(type);
+
+ _window = new InventoryWindow(this);
+ _window.CreateInventory(_inventory);
+
+ if (Owner.TryGetComponent(out _sprite))
+ {
+ foreach (var mask in _inventory.SlotMasks.OrderBy(s => _inventory.SlotDrawingOrder(s)))
+ {
+ if (mask == Slots.NONE)
+ {
+ continue;
+ }
+ _sprite.LayerMapReserveBlank(mask);
+ }
+ }
+
+ // Component state already came in but we couldn't set anything visually because, well, we didn't initialize yet.
+ foreach (var (slot, entity) in _slots)
+ {
+ _setSlot(slot, entity);
+ }
}
public override void ExposeData(ObjectSerializer serializer)
{
base.ExposeData(serializer);
- Window = new InventoryWindow(this);
- _openMenuCmdHandler = InputCmdHandler.FromDelegate(session => { Window.AddToScreen(); Window.Open(); });
- serializer.DataField(ref TemplateName, "Template", "HumanInventory");
- Window.CreateInventory(TemplateName);
+ serializer.DataField(ref _templateName, "Template", "HumanInventory");
+ }
+
+ public override void HandleComponentState(ComponentState state)
+ {
+ base.HandleComponentState(state);
+ var cast = (InventoryComponentState) state;
+
+ var doneSlots = new HashSet();
+
+ var entityManager = IoCManager.Resolve();
+
+ foreach (var (slot, entityUid) in cast.Entities)
+ {
+ if (_slots.ContainsKey(slot))
+ {
+ _slots.Remove(slot);
+ _clearSlot(slot);
+ }
+
+ var entity = entityManager.GetEntity(entityUid);
+ _slots[slot] = entity;
+ _setSlot(slot, entity);
+ doneSlots.Add(slot);
+ }
+
+ foreach (var slot in _slots.Keys.ToList())
+ {
+ if (!doneSlots.Contains(slot))
+ {
+ _clearSlot(slot);
+ _slots.Remove(slot);
+ }
+ }
}
public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null)
@@ -53,18 +125,6 @@ namespace Content.Client.GameObjects
var inputMgr = IoCManager.Resolve();
switch (message)
{
- //Updates what we are storing in UI slots
- case ServerInventoryMessage msg:
- if (msg.Updatetype == ServerInventoryUpdate.Addition)
- {
- Window.AddToSlot(msg);
- }
- else if (msg.Updatetype == ServerInventoryUpdate.Removal)
- {
- Window.RemoveFromSlot(msg);
- }
- break;
-
case PlayerAttachedMsg _:
inputMgr.SetInputCommand(ContentKeyFunctions.OpenCharacterMenu, _openMenuCmdHandler);
break;
@@ -75,6 +135,34 @@ namespace Content.Client.GameObjects
}
}
+ private void _setSlot(Slots slot, IEntity entity)
+ {
+ if (_sprite != null && entity.TryGetComponent(out ClothingComponent clothing))
+ {
+ var flag = SlotMasks[slot];
+ var data = clothing.GetEquippedStateInfo(flag);
+ if (data == null)
+ {
+ _sprite.LayerSetVisible(slot, false);
+ }
+ else
+ {
+ var (rsi, state) = data.Value;
+ _sprite.LayerSetVisible(slot, true);
+ _sprite.LayerSetRSI(slot, rsi);
+ _sprite.LayerSetState(slot, state);
+ }
+ }
+
+ _window?.AddToSlot(slot, entity);
+ }
+
+ private void _clearSlot(Slots slot)
+ {
+ _window?.RemoveFromSlot(slot);
+ _sprite?.LayerSetVisible(slot, false);
+ }
+
public void SendUnequipMessage(Slots slot)
{
var unequipmessage = new ClientInventoryMessage(slot, ClientInventoryUpdate.Unequip);
@@ -109,14 +197,10 @@ namespace Content.Client.GameObjects
}
///
- /// Creates a grid container filled with slot buttons loaded from an inventory template
+ /// Creates a grid container filled with slot buttons loaded from an inventory template
///
- ///
- public void CreateInventory(string TemplateName)
+ public void CreateInventory(Inventory inventory)
{
- Type type = AppDomain.CurrentDomain.GetAssemblyByName("Content.Shared").GetType("Content.Shared.GameObjects." + TemplateName);
- Inventory inventory = (Inventory)Activator.CreateInstance(type);
-
elements_x = inventory.Columns;
GridContainer = (GridContainer)Contents.GetChild("PanelContainer").GetChild("CenterContainer").GetChild("GridContainer");
@@ -151,14 +235,11 @@ namespace Content.Client.GameObjects
///
/// Adds the item we have equipped to the slot texture and prepares the slot button for removal
///
- ///
- public void AddToSlot(ServerInventoryMessage message)
+ public void AddToSlot(Slots slot, IEntity entity)
{
- InventoryButton button = InventorySlots[message.Inventoryslot];
- var entity = IoCManager.Resolve().GetEntity(message.EntityUid);
+ var button = InventorySlots[slot];
- button.EntityUid = message.EntityUid;
- var container = button.GetChild("CenterContainer");
+ button.EntityUid = entity.Uid;
button.GetChild