diff --git a/Content.Client/Content.Client.csproj b/Content.Client/Content.Client.csproj index 9027e22d6f..3db55c508d 100644 --- a/Content.Client/Content.Client.csproj +++ b/Content.Client/Content.Client.csproj @@ -69,6 +69,7 @@ + diff --git a/Content.Client/EntryPoint.cs b/Content.Client/EntryPoint.cs index 4a9ecf740c..c15a0700ee 100644 --- a/Content.Client/EntryPoint.cs +++ b/Content.Client/EntryPoint.cs @@ -13,7 +13,6 @@ namespace Content.Client { var factory = IoCManager.Resolve(); - factory.RegisterIgnore("Inventory"); factory.RegisterIgnore("Item"); factory.RegisterIgnore("Interactable"); factory.RegisterIgnore("Damageable"); @@ -38,12 +37,14 @@ namespace Content.Client factory.RegisterIgnore("MeleeWeapon"); factory.RegisterIgnore("Storeable"); + factory.RegisterIgnore("Clothing"); factory.Register(); factory.RegisterReference(); factory.Register(); factory.Register(); + factory.Register(); } } } diff --git a/Content.Client/GameObjects/Components/Inventory/ClientInventoryComponent.cs b/Content.Client/GameObjects/Components/Inventory/ClientInventoryComponent.cs new file mode 100644 index 0000000000..1ff7a11e75 --- /dev/null +++ b/Content.Client/GameObjects/Components/Inventory/ClientInventoryComponent.cs @@ -0,0 +1,231 @@ +using Content.Shared.GameObjects; +using SS14.Client.GameObjects; +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.GameObjects.Serialization; +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.Utility; +using System; +using System.Collections.Generic; +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 + public event EventHandler OnCharacterMenuKey; + + public override void ExposeData(EntitySerializer serializer) + { + base.ExposeData(serializer); + + Window = new InventoryWindow(this); + serializer.DataField(ref TemplateName, "Template", "HumanInventory"); + Window.CreateInventory(TemplateName); + } + + public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null) + { + 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; + } + } + + /// + /// Register a hotkey to open the character menu with + /// + public override void Initialize() + { + base.Initialize(); + OnCharacterMenuKey += OpenMenu; + IoCManager.Resolve().SubscribeEvent(OnCharacterMenuKey, this); + } + + /// + /// Hotkey opens the character menu window + /// + /// + /// + private void OpenMenu(object sender, BoundKeyChangedMessage message) + { + if(message.Function == BoundKeyFunctions.OpenCharacterMenu && message.State == BoundKeyState.Down) + { + Window.AddToScreen(); + Window.Open(); + } + } + + public void SendUnequipMessage(Slots slot) + { + var unequipmessage = new ClientInventoryMessage(slot, ClientInventoryUpdate.Unequip); + SendNetworkMessage(unequipmessage); + } + + public void SendEquipMessage(Slots slot) + { + var equipmessage = new ClientInventoryMessage(slot, ClientInventoryUpdate.Equip); + SendNetworkMessage(equipmessage); + } + + /// + /// Temporary window to hold the basis for inventory hud + /// + private class InventoryWindow : SS14Window + { + private int elements_x; + + private GridContainer GridContainer; + private List IndexedSlots; + private Dictionary InventorySlots = new Dictionary(); //ordered dictionary? + private ClientInventoryComponent InventoryComponent; + + protected override ResourcePath ScenePath => new ResourcePath("/Scenes/Inventory/HumanInventory.tscn"); + + public InventoryWindow(ClientInventoryComponent inventory) + { + InventoryComponent = inventory; + + HideOnClose = true; + } + + /// + /// Creates a grid container filled with slot buttons loaded from an inventory template + /// + /// + public void CreateInventory(string TemplateName) + { + 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"); + GridContainer.Columns = elements_x; + IndexedSlots = new List(inventory.SlotMasks); + + foreach(Slots slot in IndexedSlots) + { + InventoryButton newbutton = new InventoryButton(slot); + + if (slot == Slots.NONE) + { + //TODO: Re-enable when godot grid container maintains grid with invisible elements + //newbutton.Visible = false; + } + else + { + //Store slot button and give it the default onpress behavior for empty elements + newbutton.GetChild