using System; using System.Collections.Generic; using System.Linq; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Utility; using Robust.Shared.ViewVariables; namespace Robust.Shared.Containers { /// /// Base container class that all container inherit from. /// [ImplicitDataDefinitionForInheritors] public abstract partial class BaseContainer { // Will be null until after the component has been initialized. protected SharedContainerSystem? System; [Access(typeof(SharedContainerSystem), typeof(ContainerManagerComponent))] internal void Init(SharedContainerSystem system, string id, Entity owner) { DebugTools.Assert(ID == null || ID == id); ID = id; Owner = owner; Manager = owner; System = system; } /// /// Readonly collection of all the entities contained within this specific container /// public abstract IReadOnlyList ContainedEntities { get; } // VV convenience field [ViewVariables] private IReadOnlyList NetContainedEntities => ContainedEntities .Select(o => IoCManager.Resolve().GetNetEntity(o)).ToList(); /// /// Number of contained entities. /// public abstract int Count { get; } [ViewVariables, NonSerialized] public List ExpectedEntities = new(); /// /// The ID of this container. /// [ViewVariables, NonSerialized, Access(typeof(SharedContainerSystem), typeof(ContainerManagerComponent))] public string ID = default!; [NonSerialized] protected internal ContainerManagerComponent Manager = default!; /// /// Prevents light from escaping the container, from ex. a flashlight. /// [ViewVariables(VVAccess.ReadWrite)] [DataField("occludes")] public bool OccludesLight { get; set; } = true; /// /// The entity that owns this container. /// [ViewVariables] public EntityUid Owner { get; internal set; } /// /// Should the contents of this container be shown? False for closed containers like lockers, true for /// things like glass display cases. /// [ViewVariables(VVAccess.ReadWrite)] [DataField("showEnts")] public bool ShowContents { get; set; } /// /// Checks if the entity is contained in this container. /// This is not recursive, so containers of children are not checked. /// /// The entity to check. /// True if the entity is immediately contained in this container, false otherwise. public abstract bool Contains(EntityUid contained); /// /// Whether the given entity can be inserted into this container. /// /// Whether to assume that the container is currently empty. protected internal virtual bool CanInsert(EntityUid toInsert, bool assumeEmpty, IEntityManager entMan) => true; /// /// Implement to store the reference in whatever form you want /// /// /// [Access(typeof(SharedContainerSystem))] protected internal abstract void InternalInsert(EntityUid toInsert, IEntityManager entMan); /// /// Implement to remove the reference you used to store the entity /// /// /// [Access(typeof(SharedContainerSystem))] protected internal abstract void InternalRemove(EntityUid toRemove, IEntityManager entMan); /// /// Implement to clear the container and mark it as deleted. /// /// /// /// [Access(typeof(SharedContainerSystem))] protected internal abstract void InternalShutdown(IEntityManager entMan, SharedContainerSystem system, bool isClient); } }