using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using Content.Server.Items; using Content.Shared.ActionBlocker; using Content.Shared.Hands.Components; using Content.Shared.Item; using Robust.Shared.Containers; using Robust.Shared.GameObjects; using Robust.Shared.Map; namespace Content.Server.Hands.Components { 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 HandNames { 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(SharedItemComponent item, 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); /// /// 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.True on success, false if something blocked the drop. bool Drop(string slot, bool mobChecks = true, bool intentional = 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. /// 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 intentional = true); /// /// Drops the item in a slot. /// /// The slot to drop the item from. /// /// Whether to check the for the mob or not. /// True if an item was dropped, false otherwise. bool TryDropHand(string slot, EntityCoordinates coords, bool doMobChecks = true, bool intentional = 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. /// /// 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 TryDropEntity(IEntity entity, EntityCoordinates coords, bool doMobChecks = true, bool intentional = 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. /// 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 TryPutHandIntoContainer(string slot, BaseContainer targetContainer, bool doMobChecks = 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. /// 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); /// /// 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, HandLocation handLocation); /// /// 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); } }