using Content.Shared.Item; using Content.Shared.Storage.EntitySystems; using Content.Shared.Whitelist; using Robust.Shared.Audio; using Robust.Shared.Containers; using Robust.Shared.GameStates; using Robust.Shared.Map; using Robust.Shared.Player; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; namespace Content.Shared.Storage { /// /// Handles generic storage with window, such as backpacks. /// [RegisterComponent, NetworkedComponent] public sealed partial class StorageComponent : Component { public static string ContainerId = "storagebase"; // TODO: This fucking sucks [ViewVariables(VVAccess.ReadWrite), DataField] public bool IsUiOpen; [ViewVariables] public Container Container = default!; /// /// A dictionary storing each entity to its position within the storage grid. /// [DataField, ViewVariables(VVAccess.ReadWrite)] public Dictionary StoredItems = new(); /// /// A dictionary storing each saved item to its location in the grid. /// When trying to quick insert an item, if there is an empty location with the same name it will be placed there. /// Multiple items with the same name can be saved, they will be checked individually. /// [DataField] public Dictionary> SavedLocations = new(); /// /// A list of boxes that comprise a combined grid that determines the location that items can be stored. /// [DataField, ViewVariables(VVAccess.ReadWrite)] public List Grid = new(); /// /// The maximum size item that can be inserted into this storage, /// [DataField, ViewVariables(VVAccess.ReadWrite)] [Access(typeof(SharedStorageSystem))] public ProtoId? MaxItemSize; // TODO: Make area insert its own component. [DataField] public bool QuickInsert; // Can insert storables by clicking them with the storage entity [DataField] public bool ClickInsert = true; // Can insert stuff by clicking the storage entity with it [DataField] public bool AreaInsert; // Clicking with the storage entity causes it to insert all nearby storables after a delay [DataField] public int AreaInsertRadius = 1; /// /// Whitelist for entities that can go into the storage. /// [DataField] public EntityWhitelist? Whitelist; /// /// Blacklist for entities that can go into storage. /// [DataField] public EntityWhitelist? Blacklist; /// /// Sound played whenever an entity is inserted into storage. /// [DataField] public SoundSpecifier? StorageInsertSound = new SoundCollectionSpecifier("storageRustle"); /// /// Sound played whenever an entity is removed from storage. /// [DataField] public SoundSpecifier? StorageRemoveSound; /// /// Sound played whenever the storage window is opened. /// [DataField] public SoundSpecifier? StorageOpenSound = new SoundCollectionSpecifier("storageRustle"); /// /// Sound played whenever the storage window is closed. /// [DataField] public SoundSpecifier? StorageCloseSound; /// /// If not null, ensures that all inserted items are of the same orientation /// Horizontal - items are stored laying down /// Vertical - items are stored standing up /// [DataField, ViewVariables(VVAccess.ReadWrite)] public StorageDefaultOrientation? DefaultStorageOrientation; [Serializable, NetSerializable] public enum StorageUiKey : byte { Key, } } [Serializable, NetSerializable] public sealed class StorageInteractWithItemEvent : EntityEventArgs { public readonly NetEntity InteractedItemUid; public readonly NetEntity StorageUid; public StorageInteractWithItemEvent(NetEntity interactedItemUid, NetEntity storageUid) { InteractedItemUid = interactedItemUid; StorageUid = storageUid; } } [Serializable, NetSerializable] public sealed class StorageSetItemLocationEvent : EntityEventArgs { public readonly NetEntity ItemEnt; public readonly NetEntity StorageEnt; public readonly ItemStorageLocation Location; public StorageSetItemLocationEvent(NetEntity itemEnt, NetEntity storageEnt, ItemStorageLocation location) { ItemEnt = itemEnt; StorageEnt = storageEnt; Location = location; } } [Serializable, NetSerializable] public sealed class StorageRemoveItemEvent : EntityEventArgs { public readonly NetEntity ItemEnt; public readonly NetEntity StorageEnt; public StorageRemoveItemEvent(NetEntity itemEnt, NetEntity storageEnt) { ItemEnt = itemEnt; StorageEnt = storageEnt; } } [Serializable, NetSerializable] public sealed class StorageInsertItemIntoLocationEvent : EntityEventArgs { public readonly NetEntity ItemEnt; public readonly NetEntity StorageEnt; public readonly ItemStorageLocation Location; public StorageInsertItemIntoLocationEvent(NetEntity itemEnt, NetEntity storageEnt, ItemStorageLocation location) { ItemEnt = itemEnt; StorageEnt = storageEnt; Location = location; } } [Serializable, NetSerializable] public sealed class StorageSaveItemLocationEvent : EntityEventArgs { public readonly NetEntity Item; public readonly NetEntity Storage; public StorageSaveItemLocationEvent(NetEntity item, NetEntity storage) { Item = item; Storage = storage; } } /// /// Network event for displaying an animation of entities flying into a storage entity /// [Serializable, NetSerializable] public sealed class AnimateInsertingEntitiesEvent : EntityEventArgs { public readonly NetEntity Storage; public readonly List StoredEntities; public readonly List EntityPositions; public readonly List EntityAngles; public AnimateInsertingEntitiesEvent(NetEntity storage, List storedEntities, List entityPositions, List entityAngles) { Storage = storage; StoredEntities = storedEntities; EntityPositions = entityPositions; EntityAngles = entityAngles; } } /// /// An extra BUI message that either opens, closes, or focuses the storage window based on context. /// [Serializable, NetSerializable] public sealed class StorageModifyWindowMessage : BoundUserInterfaceMessage { } [NetSerializable] [Serializable] public enum StorageVisuals : byte { Open, HasContents, StorageUsed, Capacity } [Serializable, NetSerializable] public enum StorageDefaultOrientation : byte { Horizontal, Vertical } }