using System; using Robust.Shared.GameStates; using Robust.Shared.IoC; using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Serialization; using Robust.Shared.Serialization.Manager.Attributes; using Robust.Shared.Timing; using Robust.Shared.ViewVariables; namespace Robust.Shared.GameObjects { /// /// Serialized state of a . /// [Serializable, NetSerializable] public sealed class MetaDataComponentState : ComponentState { /// /// The in-game name of this entity. /// public string? Name { get; } /// /// The in-game description of this entity. /// public string? Description { get; } /// /// The prototype this entity was created from, if any. /// public string? PrototypeId { get; } /// /// Constructs a new instance of . /// /// The in-game name of this entity. /// The in-game description of this entity. /// The prototype this entity was created from, if any. public MetaDataComponentState(string? name, string? description, string? prototypeId) { Name = name; Description = description; PrototypeId = prototypeId; } } /// /// Contains meta data about this entity that isn't component specific. /// [NetworkedComponent] public sealed class MetaDataComponent : Component { [DataField("name")] internal string? _entityName; [DataField("desc")] internal string? _entityDescription; internal EntityPrototype? _entityPrototype; private bool _entityPaused; // Every entity starts at tick 1, because they are conceptually created in the time between 0->1 [ViewVariables] public GameTick EntityLastModifiedTick { get; internal set; } = new(1); /// /// The in-game name of this entity. /// [ViewVariables(VVAccess.ReadWrite)] public string EntityName { get { if (_entityName == null) return _entityPrototype != null ? _entityPrototype.Name : string.Empty; return _entityName; } set { string? newValue = value; if (_entityPrototype != null && _entityPrototype.Name == newValue) newValue = null; if (_entityName == newValue) return; _entityName = newValue; Dirty(); } } /// /// The in-game description of this entity. /// [ViewVariables(VVAccess.ReadWrite)] public string EntityDescription { get { if (_entityDescription == null) return _entityPrototype != null ? _entityPrototype.Description : string.Empty; return _entityDescription; } set { string? newValue = value; if (_entityPrototype != null && _entityPrototype.Description == newValue) newValue = null; if(_entityDescription == newValue) return; _entityDescription = newValue; Dirty(); } } /// /// The prototype this entity was created from, if any. /// [ViewVariables] public EntityPrototype? EntityPrototype { get => _entityPrototype; set { _entityPrototype = value; Dirty(); } } /// /// The current lifetime stage of this entity. You can use this to check /// if the entity is initialized or being deleted. /// [ViewVariables] public EntityLifeStage EntityLifeStage { get; internal set; } [ViewVariables] public MetaDataFlags Flags { get; internal set; } /// /// The sum of our visibility layer and our parent's visibility layers. /// Server-only. /// [ViewVariables] public int VisibilityMask { get; internal set; } [ViewVariables] public bool EntityPaused { get => _entityPaused; set { if (_entityPaused == value) return; _entityPaused = value; IoCManager.Resolve().EventBus.RaiseLocalEvent(Owner, new EntityPausedEvent(Owner, value)); } } public bool EntityInitialized => EntityLifeStage >= EntityLifeStage.Initialized; public bool EntityInitializing => EntityLifeStage == EntityLifeStage.Initializing; public bool EntityDeleted => EntityLifeStage >= EntityLifeStage.Deleted; internal override void ClearTicks() { // Do not clear modified ticks. // MetaDataComponent is used in the game state system to carry initial data like prototype ID. // So it ALWAYS has to be sent. // (Creation can still be cleared though) ClearCreationTick(); } } [Flags] public enum MetaDataFlags : byte { None = 0, /// /// Whether the entity has states specific to a particular player. /// EntitySpecific = 1 << 0, /// /// Whether the entity is currently inside of a container. /// InContainer = 1 << 1, } }