using System; using System.Diagnostics.CodeAnalysis; using JetBrains.Annotations; using Robust.Shared.GameObjects; using Robust.Shared.IoC; using Robust.Shared.Map; using Robust.Shared.Utility; namespace Robust.Shared.Containers { /// /// Helper functions for the container system. /// [PublicAPI] public static class ContainerHelpers { /// /// Am I inside a container? Only checks the direct parent. To see if the entity, or any parent entity, is /// inside a container, use /// /// Entity that might be inside a container. /// If the entity is inside of a container. [Obsolete("Use ContainerSystem.IsEntityInContainer() instead")] public static bool IsInContainer(this EntityUid entity, IEntityManager? entMan = null) { IoCManager.Resolve(ref entMan); return (entMan.GetComponent(entity).Flags & MetaDataFlags.InContainer) == MetaDataFlags.InContainer; } /// /// Tries to find the container manager that this entity is inside (if any). /// /// Entity that might be inside a container. /// The container manager that this entity is inside of. /// If a container manager was found. public static bool TryGetContainerMan(this EntityUid entity, [NotNullWhen(true)] out ContainerManagerComponent? manager, IEntityManager? entMan = null) { IoCManager.Resolve(ref entMan); DebugTools.Assert(entMan.EntityExists(entity)); var parent = entMan.GetComponent(entity).ParentUid; if (parent.IsValid() && TryGetManagerComp(parent, out manager, entMan) && manager.ContainsEntity(entity)) return true; manager = default; return false; } /// /// Tries to find the container that this entity is inside (if any). /// /// Entity that might be inside a container. /// The container that this entity is inside of. /// If a container was found. [Obsolete("Use ContainerSystem.TryGetContainingContainer() instead")] public static bool TryGetContainer(this EntityUid entity, [NotNullWhen(true)] out BaseContainer? container, IEntityManager? entMan = null) { IoCManager.Resolve(ref entMan); DebugTools.Assert(entMan.EntityExists(entity)); if (TryGetContainerMan(entity, out var manager, entMan)) return manager.TryGetContainer(entity, out container); container = default; return false; } /// /// Attempts to remove an entity from its container, if any. /// /// /// Entity that might be inside a container. /// Whether to forcibly remove the entity from the container. /// Whether the entity was actually inside a container or not. /// If the entity could be removed. Also returns false if it wasn't inside a container. [Obsolete("Use SharedContainerSystem.TryRemoveFromContainer() instead")] public static bool TryRemoveFromContainer(this EntityUid entity, bool force, out bool wasInContainer, IEntityManager? entMan = null) { return IoCManager.Resolve().GetEntitySystem() .TryRemoveFromContainer(entity, force, out wasInContainer); } /// /// Attempts to remove an entity from its container, if any. /// /// /// Entity that might be inside a container. /// Whether to forcibly remove the entity from the container. /// If the entity could be removed. Also returns false if it wasn't inside a container. [Obsolete("Use SharedContainerSystem.TryRemoveFromContainer() instead")] public static bool TryRemoveFromContainer(this EntityUid entity, bool force = false, IEntityManager? entMan = null) { return IoCManager.Resolve().GetEntitySystem() .TryRemoveFromContainer(entity, force); } /// /// Attempts to remove all entities in a container. /// /// [Obsolete("Use SharedContainerSystem.EmptyContainer() instead")] public static void EmptyContainer(this BaseContainer container, bool force = false, EntityCoordinates? moveTo = null, bool attachToGridOrMap = false, IEntityManager? entMan = null) { IoCManager.Resolve().GetEntitySystem() .EmptyContainer(container, force, moveTo, attachToGridOrMap); } /// /// Attempts to remove and delete all entities in a container. /// /// [Obsolete("Use SharedContainerSystem.CleanContainer() instead")] public static void CleanContainer(this BaseContainer container, IEntityManager? entMan = null) { IoCManager.Resolve().GetEntitySystem() .CleanContainer(container); } /// /// /// [Obsolete("Use SharedContainerSystem.AttachParentToContainerOrGrid() instead")] public static void AttachParentToContainerOrGrid(this TransformComponent transform, IEntityManager? entMan = null) { IoCManager.Resolve().GetEntitySystem() .AttachParentToContainerOrGrid(transform); } /// /// /// [Obsolete("Use SharedContainerSystem.TryGetManagerComp() instead")] private static bool TryGetManagerComp(this EntityUid entity, [NotNullWhen(true)] out ContainerManagerComponent? manager, IEntityManager? entMan = null) { IoCManager.Resolve(ref entMan); return entMan.System() .TryGetManagerComp(entity, out manager); } /// /// Shortcut method to make creation of containers easier. /// Creates a new container on the entity and gives it back to you. /// /// The entity to create the container for. /// /// The new container. /// Thrown if there already is a container with the specified ID. /// [Obsolete("Use ContainerSystem.MakeContainer() instead")] public static T CreateContainer(this EntityUid entity, string containerId, IEntityManager? entMan = null) where T : BaseContainer { IoCManager.Resolve(ref entMan); var containermanager = entMan.EnsureComponent(entity); return containermanager.MakeContainer(containerId); } [Obsolete("Use ContainerSystem.EnsureContainer() instead")] public static T EnsureContainer(this EntityUid entity, string containerId, IEntityManager? entMan = null) where T : BaseContainer { IoCManager.Resolve(ref entMan); return EnsureContainer(entity, containerId, out _, entMan); } [Obsolete("Use ContainerSystem.EnsureContainer() instead")] public static T EnsureContainer(this EntityUid entity, string containerId, out bool alreadyExisted, IEntityManager? entMan = null) where T : BaseContainer { IoCManager.Resolve(ref entMan); var containerManager = entMan.EnsureComponent(entity); if (!containerManager.TryGetContainer(containerId, out var existing)) { alreadyExisted = false; return containerManager.MakeContainer(containerId); } if (!(existing is T container)) { throw new InvalidOperationException( $"The container exists but is of a different type: {existing.GetType()}"); } alreadyExisted = true; return container; } } }