using System; using System.Collections.Generic; using System.Diagnostics.CodeAnalysis; using System.Runtime.CompilerServices; using Robust.Shared.Map; using Robust.Shared.Prototypes; using Robust.Shared.Timing; namespace Robust.Shared.GameObjects; public partial class EntitySystem { #region Entity LifeStage /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool Exists(EntityUid uid) { return EntityManager.EntityExists(uid); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool Exists([NotNullWhen(true)] EntityUid? uid) { return EntityManager.EntityExists(uid); } /// /// Retrieves whether the entity is initializing. Throws if the entity does not exist. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool Initializing(EntityUid uid, MetaDataComponent? metaData = null) { return LifeStage(uid, metaData) == EntityLifeStage.Initializing; } /// /// Retrieves whether the entity is initialized. Throws if the entity does not exist. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool Initialized(EntityUid uid, MetaDataComponent? metaData = null) { return LifeStage(uid, metaData) >= EntityLifeStage.Initialized; } /// /// Retrieves whether the entity is being terminated. Throws if the entity does not exist. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool Terminating(EntityUid uid, MetaDataComponent? metaData = null) { return LifeStage(uid, metaData) == EntityLifeStage.Terminating; } /// /// Retrieves whether the entity is deleted or is nonexistent. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool Deleted(EntityUid uid, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) return true; return metaData.EntityDeleted; } /// /// Retrieves whether the entity is deleted or is nonexistent. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool Deleted([NotNullWhen(false)] EntityUid? uid) { return !uid.HasValue || Deleted(uid.Value); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected EntityLifeStage LifeStage(EntityUid uid, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) throw CompNotFound(uid); return metaData.EntityLifeStage; } /// /// Attempts to retrieve whether the entity is initializing. /// /// Whether it could be retrieved. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryInitializing(EntityUid uid, [NotNullWhen(true)] out bool? initializing, MetaDataComponent? metaData = null) { if (!TryLifeStage(uid, out var lifeStage, metaData)) { initializing = null; return false; } initializing = lifeStage == EntityLifeStage.Initializing; return true; } /// /// Attempts to retrieve whether the entity is initialized. /// /// Whether it could be retrieved. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryInitialized(EntityUid uid, [NotNullWhen(true)] out bool? initialized, MetaDataComponent? metaData = null) { if (!TryLifeStage(uid, out var lifeStage, metaData)) { initialized = null; return false; } initialized = lifeStage >= EntityLifeStage.Initialized; return true; } /// /// Attempts to retrieve whether the entity is terminating. /// /// Whether it could be retrieved. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryTerminating(EntityUid uid, [NotNullWhen(true)] out bool? terminating, MetaDataComponent? metaData = null) { if (!TryLifeStage(uid, out var lifeStage, metaData)) { terminating = null; return false; } terminating = lifeStage == EntityLifeStage.Terminating; return true; } /// /// Attempts to retrieve the life-stage of the entity. /// /// /// Whether it could be retrieved. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryLifeStage(EntityUid uid, [NotNullWhen(true)] out EntityLifeStage? lifeStage, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData)) { lifeStage = null; return false; } lifeStage = metaData.EntityLifeStage; return true; } #endregion #region Entity Metadata /// /// Marks an entity as dirty. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void Dirty(EntityUid uid) { EntityManager.Dirty(uid); } /// /// Marks a component as dirty. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void Dirty(Component component) { EntityManager.Dirty(component); } /// /// Retrieves the name of an entity. /// /// Thrown when the entity doesn't exist. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected string Name(EntityUid uid, MetaDataComponent? metaData = null) { if(!Resolve(uid, ref metaData, false)) throw CompNotFound(uid); return metaData.EntityName; } /// /// Retrieves the description of an entity. /// /// Thrown when the entity doesn't exist. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected string Description(EntityUid uid, MetaDataComponent? metaData = null) { if(!Resolve(uid, ref metaData, false)) throw CompNotFound(uid); return metaData.EntityDescription; } /// /// Retrieves the prototype of an entity, if any. /// /// Thrown when the entity doesn't exist. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected EntityPrototype? Prototype(EntityUid uid, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) throw CompNotFound(uid); return metaData.EntityPrototype; } /// /// Retrieves the last the entity was modified at. /// /// Thrown when the entity doesn't exist. protected GameTick LastModifiedTick(EntityUid uid, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) throw CompNotFound(uid); return metaData.EntityLastModifiedTick; } /// /// Retrieves whether the entity is paused or not. /// /// Thrown when the entity doesn't exist. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool Paused(EntityUid uid, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) throw CompNotFound(uid); return metaData.EntityPaused; } /// /// Sets the paused status on an entity. /// /// Thrown when the entity doesn't exist. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void SetPaused(EntityUid uid, bool paused, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) throw CompNotFound(uid); metaData.EntityPaused = paused; } /// /// Attempts to mark an entity as dirty. /// /// Whether the operation succeeded. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryDirty(EntityUid uid) { if (!Exists(uid)) return false; Dirty(uid); return true; } /// /// Attempts to retrieve the name of an entity. /// /// Whether the name could be retrieved. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryName(EntityUid uid, [NotNullWhen(true)] out string? name, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) { name = null; return false; } name = metaData.EntityName; return true; } /// /// Attempts to retrieve the description of an entity. /// /// Whether the description could be retrieved. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryDescription(EntityUid uid, [NotNullWhen(true)] out string? description, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) { description = null; return false; } description = metaData.EntityDescription; return true; } /// /// Attempts to retrieve the prototype of an entity. /// /// Whether the prototype could be retrieved and was not null. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryPrototype(EntityUid uid, [NotNullWhen(true)] out EntityPrototype? prototype, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) { prototype = null; return false; } prototype = metaData.EntityPrototype; return prototype != null; } /// /// Attempts to retrieve the last the entity was modified at. /// /// Whether the last modified tick could be retrieved. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryLastModifiedTick(EntityUid uid, [NotNullWhen(true)] out GameTick? lastModifiedTick, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) { lastModifiedTick = null; return false; } lastModifiedTick = metaData.EntityLastModifiedTick; return true; } /// /// Attempts to retrieve the paused status on an entity. /// /// Whether the pause status could be retrieved. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryPaused(EntityUid uid, [NotNullWhen(true)] out bool? paused, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) { paused = null; return false; } paused = metaData.EntityPaused; return true; } /// /// Attempts to set the paused status on an entity. /// /// Whether the paused status could be set. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TrySetPaused(EntityUid uid, bool paused, MetaDataComponent? metaData = null) { if (!Resolve(uid, ref metaData, false)) return false; metaData.EntityPaused = paused; return true; } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected EntityStringRepresentation ToPrettyString(EntityUid uid) { return EntityManager.ToPrettyString(uid); } #endregion #region Component Get /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected T Comp(EntityUid uid) where T : class, IComponent { return EntityManager.GetComponent(uid); } /// /// Returns the component of a specific type, or null when it's missing or the entity does not exist. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected T? CompOrNull(EntityUid uid) where T : class, IComponent { return EntityManager.GetComponentOrNull(uid); } /// /// Returns the component of a specific type, or null when it's missing or the entity does not exist. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected T? CompOrNull(EntityUid? uid) where T : class, IComponent { return uid.HasValue ? EntityManager.GetComponentOrNull(uid.Value) : null; } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryComp(EntityUid uid, [NotNullWhen(true)] out T? comp) { return EntityManager.TryGetComponent(uid, out comp); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool TryComp([NotNullWhen(true)] EntityUid? uid, [NotNullWhen(true)] out T? comp) { if (!uid.HasValue) { comp = default; return false; } return EntityManager.TryGetComponent(uid.Value, out comp); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected IEnumerable AllComps(EntityUid uid) { return EntityManager.GetComponents(uid); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected IEnumerable AllComps(EntityUid uid) { return EntityManager.GetComponents(uid); } /// /// Returns the on an entity. /// /// Thrown when the entity doesn't exist. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected TransformComponent Transform(EntityUid uid) { return EntityManager.GetComponent(uid); } /// /// Returns the on an entity. /// /// Thrown when the entity doesn't exist. [MethodImpl(MethodImplOptions.AggressiveInlining)] protected MetaDataComponent MetaData(EntityUid uid) { return EntityManager.GetComponent(uid); } #endregion #region Component Has /// /// Retrieves whether the entity has the specified component or not. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool HasComp(EntityUid uid) { return EntityManager.HasComponent(uid); } /// /// Retrieves whether the entity has the specified component or not. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool HasComp(EntityUid uid, Type type) { return EntityManager.HasComponent(uid, type); } /// /// Retrieves whether the entity has the specified component or not. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool HasComp([NotNullWhen(true)] EntityUid? uid) { return EntityManager.HasComponent(uid); } /// /// Retrieves whether the entity has the specified component or not. /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool HasComp([NotNullWhen(true)] EntityUid? uid, Type type) { return EntityManager.HasComponent(uid, type); } #endregion #region Component Add /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected T AddComp(EntityUid uid) where T : Component, new() { return EntityManager.AddComponent(uid); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected T EnsureComp(EntityUid uid) where T : Component, new() { return EntityManager.EnsureComponent(uid); } #endregion #region Component Remove /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool RemComp(EntityUid uid) where T : class, IComponent { return EntityManager.RemoveComponent(uid); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected bool RemComp(EntityUid uid, Type type) { return EntityManager.RemoveComponent(uid, type); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void RemComp(EntityUid uid, Component component) { EntityManager.RemoveComponent(uid, component); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void RemComp(EntityUid uid, IComponent component) { EntityManager.RemoveComponent(uid, component); } #endregion #region Entity Delete /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void Del(EntityUid uid) { EntityManager.DeleteEntity(uid); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected void QueueDel(EntityUid uid) { EntityManager.QueueDeleteEntity(uid); } #endregion #region Entity Spawning /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected EntityUid Spawn(string? prototype, EntityCoordinates coordinates) { return EntityManager.SpawnEntity(prototype, coordinates); } /// [MethodImpl(MethodImplOptions.AggressiveInlining)] protected EntityUid Spawn(string? prototype, MapCoordinates coordinates) { return EntityManager.SpawnEntity(prototype, coordinates); } #endregion #region Utils /// /// Utility static method to create an exception to be thrown when an entity doesn't have a specific component. /// private static KeyNotFoundException CompNotFound(EntityUid uid) => new($"Entity {uid} does not have a component of type {typeof(T)}"); #endregion #region Entity Query [MethodImpl(MethodImplOptions.AggressiveInlining)] protected EntityQuery GetEntityQuery() where T : Component { return EntityManager.GetEntityQuery(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected IEnumerable EntityQuery(bool includePaused = false) where TComp1 : Component { return EntityManager.EntityQuery(includePaused); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected IEnumerable<(TComp1, TComp2)> EntityQuery(bool includePaused = false) where TComp1 : Component where TComp2 : Component { return EntityManager.EntityQuery(includePaused); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected IEnumerable<(TComp1, TComp2, TComp3)> EntityQuery(bool includePaused = false) where TComp1 : Component where TComp2 : Component where TComp3 : Component { return EntityManager.EntityQuery(includePaused); } [MethodImpl(MethodImplOptions.AggressiveInlining)] protected IEnumerable<(TComp1, TComp2, TComp3, TComp4)> EntityQuery(bool includePaused = false) where TComp1 : Component where TComp2 : Component where TComp3 : Component where TComp4 : Component { return EntityManager.EntityQuery(includePaused); } #endregion }