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);
}
}