#nullable enable using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Content.Server.GameObjects.Components.Items.Storage; using Content.Shared.GameObjects.Components.Items; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.GameObjects.EntitySystems.ActionBlocker; using Robust.Server.GameObjects.Components.Container; using Robust.Server.GameObjects.EntitySystemMessages; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Map; namespace Content.Server.Interfaces.GameObjects.Components.Items { public interface IHandsComponent : ISharedHandsComponent { /// /// Invoked when the hand contents changes or when a hand is added/removed. /// event Action? OnItemChanged; /// /// The hands in this component. /// IEnumerable Hands { get; } /// /// The hand name of the currently active hand. /// string? ActiveHand { get; set; } /// /// Enumerates over every held item. /// IEnumerable GetAllHeldItems(); /// /// Gets the item held by a hand. /// /// The name of the hand to get. /// The item in the held, null if no item is held ItemComponent? GetItem(string handName); /// /// Attempts to get an item in a hand. /// /// The name of the hand to get. /// The item in the held, null if no item is held /// Whether it was holding an item bool TryGetItem(string handName, [NotNullWhen(true)] out ItemComponent? item); /// /// Gets item held by the current active hand /// ItemComponent? GetActiveHand { get; } /// /// Puts an item into any empty hand, preferring the active hand. /// /// The item to put in a hand. /// Whether to perform an ActionBlocker check to the entity. /// True if the item was inserted, false otherwise. bool PutInHand(ItemComponent item, bool mobCheck = true); /// /// Puts an item into a specific hand. /// /// The item to put in the hand. /// The name of the hand to put the item into. /// /// If true and the provided hand is full, the method will fall back to /// Whether to perform an ActionBlocker check to the entity. /// /// True if the item was inserted into a hand, false otherwise. bool PutInHand(ItemComponent item, string index, bool fallback=true, bool mobCheck = true); /// /// Checks to see if an item can be put in any hand. /// /// The item to check for. /// Whether to perform an ActionBlocker check to the entity. /// True if the item can be inserted, false otherwise. bool CanPutInHand(ItemComponent item, bool mobCheck = true); /// /// Checks to see if an item can be put in the specified hand. /// /// The item to check for. /// The name for the hand to check for. /// Whether to perform an ActionBlocker check to the entity. /// True if the item can be inserted, false otherwise. bool CanPutInHand(ItemComponent item, string index, bool mobCheck = true); /// /// Finds the hand slot holding the specified entity, if any. /// /// The entity to look for in our hands. /// /// The name of the hand slot if the entity is indeed held, /// otherwise. /// /// /// true if the entity is held, false otherwise /// bool TryHand(IEntity entity, [NotNullWhen(true)] out string? handName); /// /// Drops the item contained in the slot to the same position as our entity. /// /// The slot of which to drop to drop the item. /// Whether to check the for the mob or not. /// Whether to perform Dropped interactions. /// True on success, false if something blocked the drop. bool Drop(string slot, bool mobChecks = true, bool doDropInteraction = true); /// /// Drops an item held by one of our hand slots to the same position as our owning entity. /// /// The item to drop. /// Whether to check the for the mob or not. /// Whether to perform Dropped interactions. /// True on success, false if something blocked the drop. /// /// Thrown if is null. /// /// /// Thrown if is not actually held in any hand. /// bool Drop(IEntity entity, bool mobChecks = true, bool doDropInteraction = true); /// /// Drops the item in a slot. /// /// The slot to drop the item from. /// /// Whether to check the for the mob or not. /// Whether to perform Dropped interactions. /// True if an item was dropped, false otherwise. bool Drop(string slot, EntityCoordinates coords, bool doMobChecks = true, bool doDropInteraction = true); /// /// Drop the specified entity in our hands to a certain position. /// /// /// There are no checks whether or not the user is within interaction range of the drop location /// or whether the drop location is occupied. /// /// The entity to drop, must be held in one of the hands. /// The coordinates to drop the entity at. /// Whether to check the for the mob or not. /// Whether to perform Dropped interactions. /// /// True if the drop succeeded, /// false if it failed (due to failing to eject from our hand slot, etc...) /// /// /// Thrown if is null. /// /// /// Thrown if is not actually held in any hand. /// bool Drop(IEntity entity, EntityCoordinates coords, bool doMobChecks = true, bool doDropInteraction = true); /// /// Drop the item contained in a slot into another container. /// /// The slot of which to drop the entity. /// The container to drop into. /// Whether to check the for the mob or not. /// Whether to perform Dropped interactions. /// True on success, false if something was blocked (insertion or removal). /// /// Thrown if dry-run checks reported OK to remove and insert, /// but practical remove or insert returned false anyways. /// This is an edge-case that is currently unhandled. /// bool Drop(string slot, BaseContainer targetContainer, bool doMobChecks = true, bool doDropInteraction = true); /// /// Drops an item in one of the hands into a container. /// /// The item to drop. /// The container to drop into. /// Whether to check the for the mob or not. /// Whether to perform Dropped interactions. /// True on success, false if something was blocked (insertion or removal). /// /// Thrown if dry-run checks reported OK to remove and insert, /// but practical remove or insert returned false anyways. /// This is an edge-case that is currently unhandled. /// /// /// Thrown if is null. /// /// /// Thrown if is not actually held in any hand. /// bool Drop(IEntity entity, BaseContainer targetContainer, bool doMobChecks = true, bool doDropInteraction = true); /// /// Checks whether the item in the specified hand can be dropped. /// /// The hand to check for. /// Whether to perform an ActionBlocker check to the entity. /// /// True if the item can be dropped, false if the hand is empty or the item in the hand cannot be dropped. /// bool CanDrop(string name, bool mobCheck = true); /// /// Adds a new hand to this hands component. /// /// The name of the hand to add. /// /// Thrown if a hand with specified name already exists. /// void AddHand(string name); /// /// Removes a hand from this hands component. /// /// /// If the hand contains an item, the item is dropped. /// /// The name of the hand to remove. void RemoveHand(string name); /// /// Checks whether a hand with the specified name exists. /// /// The hand name to check. /// True if the hand exists, false otherwise. bool HasHand(string name); void HandleSlotModifiedMaybe(ContainerModifiedMessage message); } }