From f6e265bccb2df35d62d12caa5b09b7a102694ac8 Mon Sep 17 00:00:00 2001 From: PJB3005 Date: Sun, 24 Sep 2017 21:09:26 +0200 Subject: [PATCH] Inventories WiP --- Content.Server/Content.Server.csproj | 6 + .../Components/Items/HandsComponent.cs | 11 ++ .../Components/Items/InventoryComponent.cs | 105 ++++++++++++++++++ .../Components/Items/ItemComponent.cs | 35 ++++++ .../Components/Items/IHandsComponent.cs | 50 +++++++++ .../Components/Items/IInventoryComponent.cs | 84 ++++++++++++++ .../Components/Items/IItemComponent.cs | 22 ++++ 7 files changed, 313 insertions(+) create mode 100644 Content.Server/GameObjects/Components/Items/HandsComponent.cs create mode 100644 Content.Server/GameObjects/Components/Items/InventoryComponent.cs create mode 100644 Content.Server/GameObjects/Components/Items/ItemComponent.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Items/IInventoryComponent.cs create mode 100644 Content.Server/Interfaces/GameObjects/Components/Items/IItemComponent.cs diff --git a/Content.Server/Content.Server.csproj b/Content.Server/Content.Server.csproj index 07b85bcc33..d2cdb12b80 100644 --- a/Content.Server/Content.Server.csproj +++ b/Content.Server/Content.Server.csproj @@ -56,6 +56,12 @@ + + + + + + diff --git a/Content.Server/GameObjects/Components/Items/HandsComponent.cs b/Content.Server/GameObjects/Components/Items/HandsComponent.cs new file mode 100644 index 0000000000..0dc7a00e86 --- /dev/null +++ b/Content.Server/GameObjects/Components/Items/HandsComponent.cs @@ -0,0 +1,11 @@ +using SS14.Shared.GameObjects; +using SS14.Shared.Interfaces.GameObjects; +using System.Collections.Generic; + +namespace Content.Server.Interfaces.GameObjects +{ + public class HandsComponent : Component, IHandsComponent + { + public override string Name => "Hands"; + } +} diff --git a/Content.Server/GameObjects/Components/Items/InventoryComponent.cs b/Content.Server/GameObjects/Components/Items/InventoryComponent.cs new file mode 100644 index 0000000000..2374532b95 --- /dev/null +++ b/Content.Server/GameObjects/Components/Items/InventoryComponent.cs @@ -0,0 +1,105 @@ +using Content.Server.Interfaces.GameObjects; +using SS14.Server.GameObjects; +using SS14.Server.Interfaces.GameObjects; +using SS14.Shared.GameObjects; +using SS14.Shared.Interfaces.GameObjects; +using System; +using System.Collections.Generic; + +namespace Content.Server.Interfaces.GameObjects +{ + public class InventoryComponent : Component, IInventoryComponent + { + public override string Name => "Inventory"; + + private Dictionary slots = new Dictionary(); + private TransformComponent transform; + // TODO: Make this container unique per-slot. + private IContainer container; + + public override void Initialize() + { + transform = Owner.GetComponent(); + base.Initialize(); + } + + public override void OnRemove() + { + transform = null; + base.OnRemove(); + } + + public IItemComponent Get(string slot) + { + return _GetSlot(slot).Item; + } + + public IInventorySlot GetSlot(string slot) + { + return slots[slot]; + } + + // Private version that returns our concrete implementation. + private InventorySlot _GetSlot(string slot) + { + return slots[slot]; + } + + public bool PutInSlot(string slot, IItemComponent item) + { + var inventorySlot = _GetSlot(slot); + if (inventorySlot.Item != null) + { + return false; + } + + inventorySlot.Item = item; + item.EquippedToSlot(inventorySlot); + return true; + } + + public bool DropSlot(string slot) + { + var inventorySlot = _GetSlot(slot); + var item = inventorySlot.Item; + if (item == null || !container.Remove(item.Owner)) + { + return false; + } + + item.RemovedFromSlot(); + inventorySlot.Item = null; + + // TODO: The item should be dropped to the container our owner is in, if any. + var itemTransform = item.Owner.GetComponent(); + itemTransform.LocalPosition = transform.LocalPosition; + return true; + } + + public void AddSlot(string slot) + { + if (slots.ContainsKey(slot)) + { + + } + } + + public void RemoveSlot(string slot) + { + throw new NotImplementedException(); + } + + private class InventorySlot : IInventorySlot + { + public IItemComponent Item { get; set; } + public string Name { get; } + public IInventoryComponent Owner { get; } + + public InventorySlot(string name, IInventoryComponent owner) + { + Name = name; + Owner = owner; + } + } + } +} diff --git a/Content.Server/GameObjects/Components/Items/ItemComponent.cs b/Content.Server/GameObjects/Components/Items/ItemComponent.cs new file mode 100644 index 0000000000..0571ab8492 --- /dev/null +++ b/Content.Server/GameObjects/Components/Items/ItemComponent.cs @@ -0,0 +1,35 @@ +using Content.Server.Interfaces.GameObjects; +using SS14.Shared.GameObjects; +using SS14.Shared.Interfaces.GameObjects; +using System; + +namespace Content.Server.Interfaces.GameObjects +{ + public class ItemComponent : Component, IItemComponent + { + public override string Name => "Item"; + + /// + public IInventorySlot ContainingSlot { get; private set; } + + public void RemovedFromSlot() + { + if (ContainingSlot == null) + { + throw new InvalidOperationException("Item is not in a slot."); + } + + ContainingSlot = null; + } + + public void EquippedToSlot(IInventorySlot slot) + { + if (ContainingSlot != null) + { + throw new InvalidOperationException("Item is already in a slot."); + } + + ContainingSlot = slot; + } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs b/Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs new file mode 100644 index 0000000000..881f30328b --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Items/IHandsComponent.cs @@ -0,0 +1,50 @@ +using SS14.Shared.Interfaces.GameObjects; +using System.Collections.Generic; + +namespace Content.Server.Interfaces.GameObjects +{ + public interface IHandsComponent : IComponent + { + /// + /// The hand index of the currently active hand. + /// + string ActiveIndex { get; } + + /// + /// Enumerates over every held item. + /// + IEnumerable GetAllHands(); + + /// + /// Gets the item held by a hand. + /// + /// The index of the hand to get. + /// The item in the held, null if no item is held + IItemComponent GetHand(string index); + + /// + /// Puts an item into any empty hand, preferring the active hand. + /// + /// The item to put in a hand. + /// True if the item was inserted, false otherwise. + bool PutInHand(IItemComponent item); + + /// + /// Puts an item into a specific hand. + /// + /// The item to put in the hand. + /// The index of the hand to put the item into. + /// + /// If true and the provided hand is full, the method will fall back to + /// + /// True if the item was inserted into a hand, false otherwise. + bool PutInHand(IItemComponent item, string index, bool fallback=true); + + /// + /// Drops an item on the ground, removing it from the hand. + /// + /// The hand to drop from. + /// True if an item was successfully dropped, false otherwise. + bool Drop(string index); + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Items/IInventoryComponent.cs b/Content.Server/Interfaces/GameObjects/Components/Items/IInventoryComponent.cs new file mode 100644 index 0000000000..4f3247ecdf --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Items/IInventoryComponent.cs @@ -0,0 +1,84 @@ +using SS14.Server.Interfaces.GameObjects; +using SS14.Shared.Interfaces.GameObjects; +using System; + +namespace Content.Server.Interfaces.GameObjects +{ + public interface IInventoryComponent : IComponent + { + /// + /// Gets the item in the specified slot. + /// + /// The slot to get the item for. + /// Null if the slot is empty, otherwise the item. + IItemComponent Get(string slot); + + /// + /// Gets the slot with specified name. + /// This gets the slot, NOT the item contained therein. + /// + /// The name of the slot to get. + IInventorySlot GetSlot(string slot); + + /// + /// Puts an item in a slot. + /// + /// + /// This will fail if there is already an item in the specified slot. + /// + /// The slot to put the item in. + /// The item to insert into the slot. + /// True if the item was successfully inserted, false otherwise. + bool PutInSlot(string slot, IItemComponent item); + + /// + /// Drops the item in a slot. + /// + /// The slot to drop the item from. + /// True if an item was dropped, false otherwise. + bool DropSlot(string slot); + + /// + /// Adds a new slot to this inventory component. + /// + /// The name of the slot to add. + /// + /// Thrown if the slot with specified name already exists. + /// + void AddSlot(string slot); + + /// + /// Removes a slot from this inventory component. + /// + /// + /// If the slot contains an item, the item is dropped. + /// + /// The name of the slot to remove. + void RemoveSlot(string slot); + + /// + /// + /// + /// + /// + bool HasSlot(string slot); + } + + public interface IInventorySlot + { + /// + /// The name of the slot. + /// + string Name { get; } + + /// + /// The item contained in the slot, can be null. + /// + IItemComponent Item { get; } + + /// + /// The component owning us. + /// + IInventoryComponent Owner { get; } + } +} diff --git a/Content.Server/Interfaces/GameObjects/Components/Items/IItemComponent.cs b/Content.Server/Interfaces/GameObjects/Components/Items/IItemComponent.cs new file mode 100644 index 0000000000..cd54ef375c --- /dev/null +++ b/Content.Server/Interfaces/GameObjects/Components/Items/IItemComponent.cs @@ -0,0 +1,22 @@ +using SS14.Shared.Interfaces.GameObjects; + +namespace Content.Server.Interfaces.GameObjects +{ + public interface IItemComponent : IComponent + { + /// + /// The inventory slot this item is stored in, if any. + /// + IInventorySlot ContainingSlot { get; } + + /// + /// Called when the item is removed from its inventory slot. + /// + void RemovedFromSlot(); + + /// + /// Called when the item is inserted into a new inventory slot. + /// + void EquippedToSlot(IInventorySlot slot); + } +}