diff --git a/Content.Server/GameObjects/Components/Observer/GhostComponent.cs b/Content.Server/GameObjects/Components/Observer/GhostComponent.cs
index c8699c7877..b68b0f3a21 100644
--- a/Content.Server/GameObjects/Components/Observer/GhostComponent.cs
+++ b/Content.Server/GameObjects/Components/Observer/GhostComponent.cs
@@ -1,4 +1,4 @@
-using System;
+using System;
using System.Collections.Generic;
using System.Linq;
using Content.Server.GameObjects.Components.Markers;
@@ -40,32 +40,40 @@ namespace Content.Server.GameObjects.Components.Observer
}
}
- public override void Initialize()
+ ///
+ protected override void Startup()
{
- base.Initialize();
+ base.Startup();
+ // Allow this entity to be seen by other ghosts.
Owner.EnsureComponent().Layer = (int) VisibilityFlags.Ghost;
+
+ // Allows this entity to see other ghosts.
+ Owner.EnsureComponent().VisibilityMask |= (uint) VisibilityFlags.Ghost;
+
_timeOfDeath = _gameTimer.RealTime;
}
- public override ComponentState GetComponentState(ICommonSession player) => new GhostComponentState(CanReturnToBody);
-
- public override void HandleMessage(ComponentMessage message, IComponent? component)
+ ///
+ protected override void Shutdown()
{
- base.HandleMessage(message, component);
-
- switch (message)
+ //Perf: If the entity is deleting itself, no reason to change these back.
+ if(Owner.LifeStage < EntityLifeStage.Terminating)
{
- case PlayerAttachedMsg msg:
- msg.NewPlayer.VisibilityMask |= (int) VisibilityFlags.Ghost;
- Dirty();
- break;
- case PlayerDetachedMsg msg:
- msg.OldPlayer.VisibilityMask &= ~(int) VisibilityFlags.Ghost;
- break;
+ // Entity can't be seen by ghosts anymore.
+ if (Owner.TryGetComponent(out var visComp))
+ visComp.Layer &= ~(int) VisibilityFlags.Ghost;
+
+ // Entity can't see ghosts anymore.
+ if (Owner.TryGetComponent(out var eyeComp))
+ eyeComp.VisibilityMask &= ~(uint) VisibilityFlags.Ghost;
}
+
+ base.Shutdown();
}
+ public override ComponentState GetComponentState(ICommonSession player) => new GhostComponentState(CanReturnToBody);
+
public override void HandleNetworkMessage(ComponentMessage message, INetChannel netChannel, ICommonSession? session = null!)
{
base.HandleNetworkMessage(message, netChannel, session);
diff --git a/Content.Server/GameObjects/EntitySystems/PointingSystem.cs b/Content.Server/GameObjects/EntitySystems/PointingSystem.cs
index 4fc87a1e26..ecf6598dda 100644
--- a/Content.Server/GameObjects/EntitySystems/PointingSystem.cs
+++ b/Content.Server/GameObjects/EntitySystems/PointingSystem.cs
@@ -131,13 +131,12 @@ namespace Content.Server.GameObjects.EntitySystems
// Get players that are in range and whose visibility layer matches the arrow's.
var viewers = _playerManager.GetPlayersBy((playerSession) =>
{
- if ((playerSession.VisibilityMask & layer) == 0)
- return false;
-
var ent = playerSession.ContentData()?.Mind?.CurrentEntity;
- return ent != null
- && ent.Transform.MapPosition.InRange(player.Transform.MapPosition, PointingRange);
+ if (ent is null || (!ent.TryGetComponent(out var eyeComp) || (eyeComp.VisibilityMask & layer) != 0))
+ return false;
+
+ return ent.Transform.MapPosition.InRange(player.Transform.MapPosition, PointingRange);
});
string selfMessage;
diff --git a/Content.Server/GameObjects/VisibilityFlags.cs b/Content.Server/GameObjects/VisibilityFlags.cs
index bcd103ddfc..5d51b1a23f 100644
--- a/Content.Server/GameObjects/VisibilityFlags.cs
+++ b/Content.Server/GameObjects/VisibilityFlags.cs
@@ -3,9 +3,10 @@ using System;
namespace Content.Server.GameObjects
{
[Flags]
- public enum VisibilityFlags
+ public enum VisibilityFlags : uint
{
- Normal = 1,
- Ghost = 2,
+ None = 0,
+ Normal = 1 << 0,
+ Ghost = 1 << 1,
}
}
diff --git a/RobustToolbox b/RobustToolbox
index 4864096b2a..37fc0d0d2a 160000
--- a/RobustToolbox
+++ b/RobustToolbox
@@ -1 +1 @@
-Subproject commit 4864096b2a2359525bc716ac3df6c7fdc4018f79
+Subproject commit 37fc0d0d2aebc394e298be51d07698100d14e61d