#nullable enable using System; using System.Collections.Generic; using System.Linq; using System.Numerics; using Content.Shared.GameObjects.EntitySystems; using Content.Shared.GameObjects.EntitySystems.ActionBlocker; using Content.Shared.Interfaces.GameObjects.Components; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Map; using Robust.Shared.Serialization; namespace Content.Shared.GameObjects.Components.Storage { public abstract class SharedStorageComponent : Component, IDraggable { public override string Name => "Storage"; public override uint? NetID => ContentNetIDs.INVENTORY; public abstract IReadOnlyList? StoredEntities { get; } /// /// Removes from the storage container and updates the stored value /// /// The entity to remove /// True if no longer in storage, false otherwise public abstract bool Remove(IEntity entity); bool IDraggable.CanDrop(CanDropEventArgs args) { return args.Target.TryGetComponent(out SharedPlaceableSurfaceComponent? placeable) && placeable.IsPlaceable; } bool IDraggable.Drop(DragDropEventArgs eventArgs) { if (!ActionBlockerSystem.CanInteract(eventArgs.User)) { return false; } var storedEntities = StoredEntities?.ToArray(); if (storedEntities == null) { return false; } // empty everything out foreach (var storedEntity in storedEntities) { if (Remove(storedEntity)) { storedEntity.Transform.WorldPosition = eventArgs.DropLocation.Position; } } return true; } } [Serializable, NetSerializable] public class StorageComponentState : ComponentState { public readonly EntityUid[] StoredEntities; public StorageComponentState(EntityUid[] storedEntities) : base(ContentNetIDs.INVENTORY) { StoredEntities = storedEntities; } } /// /// Updates the client component about what entities this storage is holding /// [Serializable, NetSerializable] public class StorageHeldItemsMessage : ComponentMessage { public readonly int StorageSizeMax; public readonly int StorageSizeUsed; public readonly EntityUid[] StoredEntities; public StorageHeldItemsMessage(EntityUid[] storedEntities, int storageUsed, int storageMaxSize) { Directed = true; StorageSizeMax = storageMaxSize; StorageSizeUsed = storageUsed; StoredEntities = storedEntities; } } /// /// Component message for adding an entity to the storage entity. /// [Serializable, NetSerializable] public class InsertEntityMessage : ComponentMessage { public InsertEntityMessage() { Directed = true; } } /// /// Component message for displaying an animation of entities flying into a storage entity /// [Serializable, NetSerializable] public class AnimateInsertingEntitiesMessage : ComponentMessage { public readonly List StoredEntities; public readonly List EntityPositions; public AnimateInsertingEntitiesMessage(List storedEntities, List entityPositions) { Directed = true; StoredEntities = storedEntities; EntityPositions = entityPositions; } } /// /// Component message for removing a contained entity from the storage entity /// [Serializable, NetSerializable] public class RemoveEntityMessage : ComponentMessage { public EntityUid EntityUid; public RemoveEntityMessage(EntityUid entityuid) { Directed = true; EntityUid = entityuid; } } /// /// Component message for opening the storage UI /// [Serializable, NetSerializable] public class OpenStorageUIMessage : ComponentMessage { public OpenStorageUIMessage() { Directed = true; } } /// /// Component message for closing the storage UI. /// E.g when the player moves too far away from the container. /// [Serializable, NetSerializable] public class CloseStorageUIMessage : ComponentMessage { public CloseStorageUIMessage() { Directed = true; } } [NetSerializable] [Serializable] public enum StorageVisuals { Open, CanWeld, Welded, CanLock, Locked } }