diff --git a/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs b/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs index f88159845b..6244af156a 100644 --- a/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs +++ b/Content.Server/GameObjects/Components/GUI/InventoryComponent.cs @@ -110,7 +110,7 @@ namespace Content.Server.GameObjects return false; } - item.EquippedToSlot(); + _entitySystemManager.GetEntitySystem().EquippedInteraction(Owner, item.Owner, slot); Dirty(); return true; @@ -166,11 +166,12 @@ namespace Content.Server.GameObjects return false; } - item.RemovedFromSlot(); - // TODO: The item should be dropped to the container our owner is in, if any. var itemTransform = item.Owner.GetComponent(); itemTransform.GridPosition = Owner.GetComponent().GridPosition; + + _entitySystemManager.GetEntitySystem().UnequippedInteraction(Owner, item.Owner, slot); + Dirty(); return true; } diff --git a/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs b/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs index 745510e850..d50c346adc 100644 --- a/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs +++ b/Content.Server/GameObjects/Components/Items/Storage/ItemComponent.cs @@ -27,7 +27,7 @@ namespace Content.Server.GameObjects { [RegisterComponent] [ComponentReference(typeof(StoreableComponent))] - public class ItemComponent : StoreableComponent, IAttackHand, IExAct + public class ItemComponent : StoreableComponent, IAttackHand, IExAct, IEquipped, IUnequipped { public override string Name => "Item"; public override uint? NetID => ContentNetIDs.ITEM; @@ -69,6 +69,16 @@ namespace Content.Server.GameObjects } } + public void Equipped(EquippedEventArgs eventArgs) + { + EquippedToSlot(); + } + + public void Unequipped(UnequippedEventArgs eventArgs) + { + RemovedFromSlot(); + } + public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); diff --git a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs index e30d961669..5045d364d8 100644 --- a/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/Click/InteractionSystem.cs @@ -3,6 +3,7 @@ using System.Linq; using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Timing; using Content.Server.Interfaces.GameObjects; +using Content.Shared.GameObjects.Components.Inventory; using Content.Shared.Input; using Content.Shared.Physics; using JetBrains.Annotations; @@ -168,6 +169,46 @@ namespace Content.Server.GameObjects.EntitySystems public GridCoordinates LandingLocation { get; } } + /// + /// This interface gives components behavior when their owner is put in an inventory slot. + /// + public interface IEquipped + { + void Equipped(EquippedEventArgs eventArgs); + } + + public class EquippedEventArgs : EventArgs + { + public EquippedEventArgs(IEntity user, EquipmentSlotDefines.Slots slot) + { + User = user; + Slot = slot; + } + + public IEntity User { get; } + public EquipmentSlotDefines.Slots Slot { get; } + } + + /// + /// This interface gives components behavior when their owner is removed from an inventory slot. + /// + public interface IUnequipped + { + void Unequipped(UnequippedEventArgs eventArgs); + } + + public class UnequippedEventArgs : EventArgs + { + public UnequippedEventArgs(IEntity user, EquipmentSlotDefines.Slots slot) + { + User = user; + Slot = slot; + } + + public IEntity User { get; } + public EquipmentSlotDefines.Slots Slot { get; } + } + /// /// This interface gives components behavior when being used to "attack". /// @@ -710,6 +751,50 @@ namespace Content.Server.GameObjects.EntitySystems } } + /// + /// Calls Equipped on all components that implement the IEquipped interface + /// on an entity that has been equipped. + /// + public void EquippedInteraction(IEntity user, IEntity equipped, EquipmentSlotDefines.Slots slot) + { + var equipMsg = new EquippedMessage(user, equipped, slot); + RaiseLocalEvent(equipMsg); + if (equipMsg.Handled) + { + return; + } + + var comps = equipped.GetAllComponents().ToList(); + + // Call Thrown on all components that implement the interface + foreach (var comp in comps) + { + comp.Equipped(new EquippedEventArgs(user, slot)); + } + } + + /// + /// Calls Unequipped on all components that implement the IUnequipped interface + /// on an entity that has been equipped. + /// + public void UnequippedInteraction(IEntity user, IEntity equipped, EquipmentSlotDefines.Slots slot) + { + var unequipMsg = new UnequippedMessage(user, equipped, slot); + RaiseLocalEvent(unequipMsg); + if (unequipMsg.Handled) + { + return; + } + + var comps = equipped.GetAllComponents().ToList(); + + // Call Thrown on all components that implement the interface + foreach (var comp in comps) + { + comp.Unequipped(new UnequippedEventArgs(user, slot)); + } + } + /// /// Activates the Dropped behavior of an object /// Verifies that the user is capable of doing the drop interaction first @@ -1104,6 +1189,74 @@ namespace Content.Server.GameObjects.EntitySystems } } + /// + /// Raised when equipping the entity in an inventory slot. + /// + [PublicAPI] + public class EquippedMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that equipped the item. + /// + public IEntity User { get; } + + /// + /// Item that was equipped. + /// + public IEntity Equipped { get; } + + /// + /// Slot where the item was placed. + /// + public EquipmentSlotDefines.Slots Slot { get; } + + public EquippedMessage(IEntity user, IEntity equipped, EquipmentSlotDefines.Slots slot) + { + User = user; + Equipped = equipped; + Slot = slot; + } + } + + /// + /// Raised when removing the entity from an inventory slot. + /// + [PublicAPI] + public class UnequippedMessage : EntitySystemMessage + { + /// + /// If this message has already been "handled" by a previous system. + /// + public bool Handled { get; set; } + + /// + /// Entity that equipped the item. + /// + public IEntity User { get; } + + /// + /// Item that was equipped. + /// + public IEntity Equipped { get; } + + /// + /// Slot where the item was removed from. + /// + public EquipmentSlotDefines.Slots Slot { get; } + + public UnequippedMessage(IEntity user, IEntity equipped, EquipmentSlotDefines.Slots slot) + { + User = user; + Equipped = equipped; + Slot = slot; + } + } + /// /// Raised when an entity that was thrown lands. ///