]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Modernize `GhostComponent` & Ghost API (#36858)
authorTayrtahn <tayrtahn@gmail.com>
Wed, 23 Apr 2025 18:28:10 +0000 (14:28 -0400)
committerGitHub <noreply@github.com>
Wed, 23 Apr 2025 18:28:10 +0000 (20:28 +0200)
* Move CanReturnToBody to system

* Move CanGhostInteract to system

* Cleanup redundant datafields and viewvariables

* Document datafields

* Document component

* Add SetTimeOfDeath Entity<T> overload, obsolete old version

* Document public methods

* Cleanup obsoleted method calls

Content.Server/Administration/Commands/AGhostCommand.cs
Content.Server/Ghost/GhostSystem.cs
Content.Server/Mind/MindSystem.cs
Content.Shared/Ghost/GhostComponent.cs
Content.Shared/Ghost/SharedGhostSystem.cs

index 09c8d0eb5086b7f5b52070664873bc51d66866e0..1e3c00dffef0c9975651a3192fb40301111aa8df 100644 (file)
@@ -117,6 +117,6 @@ public sealed class AGhostCommand : LocalizedCommands
         }
 
         var comp = _entities.GetComponent<GhostComponent>(ghost);
-        ghostSystem.SetCanReturnToBody(comp, canReturn);
+        ghostSystem.SetCanReturnToBody((ghost, comp), canReturn);
     }
 }
index 0cccab64b69fa24603ce6ac87ce105a060dd1f6a..8596927b28a89165300651c491559ee8c8c4aeed 100644 (file)
@@ -489,10 +489,10 @@ namespace Content.Server.Ghost
 
             if (mind.Comp.TimeOfDeath.HasValue)
             {
-                SetTimeOfDeath(ghost, mind.Comp.TimeOfDeath!.Value, ghostComponent);
+                SetTimeOfDeath((ghost, ghostComponent), mind.Comp.TimeOfDeath!.Value);
             }
 
-            SetCanReturnToBody(ghostComponent, canReturn);
+            SetCanReturnToBody((ghost, ghostComponent), canReturn);
 
             if (canReturn)
                 _minds.Visit(mind.Owner, ghost, mind.Comp);
index 5601f19e5888493c9aead4edba4f28ecba535632..71d38c688be3702ae7a2137982f5f43776e5bff3 100644 (file)
@@ -62,7 +62,7 @@ public sealed class MindSystem : SharedMindSystem
         {
             TransferTo(mindId, visiting, mind: mind);
             if (TryComp(visiting, out GhostComponent? ghostComp))
-                _ghosts.SetCanReturnToBody(ghostComp, false);
+                _ghosts.SetCanReturnToBody((visiting, ghostComp), false);
             return;
         }
 
@@ -214,7 +214,7 @@ public sealed class MindSystem : SharedMindSystem
             entity = Spawn(GameTicker.ObserverPrototypeName, position);
             component = EnsureComp<MindContainerComponent>(entity.Value);
             var ghostComponent = Comp<GhostComponent>(entity.Value);
-            _ghosts.SetCanReturnToBody(ghostComponent, false);
+            _ghosts.SetCanReturnToBody((entity.Value, ghostComponent), false);
         }
 
         var oldEntity = mind.OwnedEntity;
index 6fbb59a711ce15a358e2110274638d335127bd90..84416f8abc53b636ae498ea13dc063b3b03a4fb2 100644 (file)
@@ -4,6 +4,10 @@ using Robust.Shared.Prototypes;
 
 namespace Content.Shared.Ghost;
 
+/// <summary>
+/// Represents an observer ghost.
+/// Handles limiting interactions, using ghost abilities, ghost visibility, and ghost warping.
+/// </summary>
 [RegisterComponent, NetworkedComponent, Access(typeof(SharedGhostSystem))]
 [AutoGenerateComponentState(true), AutoGenerateComponentPause]
 public sealed partial class GhostComponent : Component
@@ -41,46 +45,47 @@ public sealed partial class GhostComponent : Component
 
     // End actions
 
-    [ViewVariables(VVAccess.ReadWrite), DataField, AutoPausedField]
+    /// <summary>
+    /// Time at which the player died and created this ghost.
+    /// Used to determine votekick eligibility.
+    /// </summary>
+    /// <remarks>
+    /// May not reflect actual time of death if this entity has been paused,
+    /// but will give an accurate length of time <i>since</i> death.
+    /// </remarks>
+    [DataField, AutoPausedField]
     public TimeSpan TimeOfDeath = TimeSpan.Zero;
 
-    [DataField("booRadius"), ViewVariables(VVAccess.ReadWrite)]
+    /// <summary>
+    /// Range of the Boo action.
+    /// </summary>
+    [DataField]
     public float BooRadius = 3;
 
-    [DataField("booMaxTargets"), ViewVariables(VVAccess.ReadWrite)]
+    /// <summary>
+    /// Maximum number of entities that can affected by the Boo action.
+    /// </summary>
+    [DataField]
     public int BooMaxTargets = 3;
 
-    // TODO: instead of this funny stuff just give it access and update in system dirtying when needed
-    [ViewVariables(VVAccess.ReadWrite)]
-    public bool CanGhostInteract
-    {
-        get => _canGhostInteract;
-        set
-        {
-            if (_canGhostInteract == value) return;
-            _canGhostInteract = value;
-            Dirty();
-        }
-    }
-
+    /// <summary>
+    /// Is this ghost allowed to interact with entities?
+    /// </summary>
+    /// <remarks>
+    /// Used to allow admins ghosts to interact with the world.
+    /// Changed by <see cref="SharedGhostSystem.SetCanGhostInteract"/>.
+    /// </remarks>
     [DataField("canInteract"), AutoNetworkedField]
-    private bool _canGhostInteract;
+    public bool CanGhostInteract;
 
     /// <summary>
-    ///     Changed by <see cref="SharedGhostSystem.SetCanReturnToBody"/>
+    /// Is this ghost player allowed to return to their original body?
     /// </summary>
-    // TODO MIRROR change this to use friend classes when thats merged
-    [ViewVariables(VVAccess.ReadWrite)]
-    public bool CanReturnToBody
-    {
-        get => _canReturnToBody;
-        set
-        {
-            if (_canReturnToBody == value) return;
-            _canReturnToBody = value;
-            Dirty();
-        }
-    }
+    /// <remarks>
+    /// Changed by <see cref="SharedGhostSystem.SetCanReturnToBody"/>.
+    /// </remarks>
+    [DataField, AutoNetworkedField]
+    public bool CanReturnToBody;
 
     /// <summary>
     /// Ghost color
@@ -88,9 +93,6 @@ public sealed partial class GhostComponent : Component
     /// <remarks>Used to allow admins to change ghost colors. Should be removed if the capability to edit existing sprite colors is ever added back.</remarks>
     [DataField, AutoNetworkedField]
     public Color Color = Color.White;
-
-    [DataField("canReturnToBody"), AutoNetworkedField]
-    private bool _canReturnToBody;
 }
 
 public sealed partial class ToggleFoVActionEvent : InstantActionEvent { }
index 6e62bee1310175a87bb49103de820f8d881b6226..7d3561a79f9971ab228e728d28530190c590804a 100644 (file)
@@ -37,25 +37,68 @@ namespace Content.Shared.Ghost
                 args.Cancel();
         }
 
-        public void SetTimeOfDeath(EntityUid uid, TimeSpan value, GhostComponent? component)
+        /// <summary>
+        /// Sets the ghost's time of death.
+        /// </summary>
+        public void SetTimeOfDeath(Entity<GhostComponent?> entity, TimeSpan value)
         {
-            if (!Resolve(uid, ref component))
+            if (!Resolve(entity, ref entity.Comp))
                 return;
 
-            component.TimeOfDeath = value;
+            if (entity.Comp.TimeOfDeath == value)
+                return;
+
+            entity.Comp.TimeOfDeath = value;
+            Dirty(entity);
         }
 
-        public void SetCanReturnToBody(EntityUid uid, bool value, GhostComponent? component = null)
+        [Obsolete("Use the Entity<GhostComponent?> overload")]
+        public void SetTimeOfDeath(EntityUid uid, TimeSpan value, GhostComponent? component)
         {
-            if (!Resolve(uid, ref component))
+            SetTimeOfDeath((uid, component), value);
+        }
+
+        /// <summary>
+        /// Sets whether or not the ghost player is allowed to return to their original body.
+        /// </summary>
+        public void SetCanReturnToBody(Entity<GhostComponent?> entity, bool value)
+        {
+            if (!Resolve(entity, ref entity.Comp))
+                return;
+
+            if (entity.Comp.CanReturnToBody == value)
                 return;
 
-            component.CanReturnToBody = value;
+            entity.Comp.CanReturnToBody = value;
+            Dirty(entity);
         }
 
+        [Obsolete("Use the Entity<GhostComponent?> overload")]
+        public void SetCanReturnToBody(EntityUid uid, bool value, GhostComponent? component = null)
+        {
+            SetCanReturnToBody((uid, component), value);
+        }
+
+        [Obsolete("Use the Entity<GhostComponent?> overload")]
         public void SetCanReturnToBody(GhostComponent component, bool value)
         {
-            component.CanReturnToBody = value;
+            SetCanReturnToBody((component.Owner, component), value);
+        }
+
+
+        /// <summary>
+        /// Sets whether the ghost is allowed to interact with other entities.
+        /// </summary>
+        public void SetCanGhostInteract(Entity<GhostComponent?> entity, bool value)
+        {
+            if (!Resolve(entity, ref entity.Comp))
+                return;
+
+            if (entity.Comp.CanGhostInteract == value)
+                return;
+
+            entity.Comp.CanGhostInteract = value;
+            Dirty(entity);
         }
     }