diff --git a/Content.Client/Observer/GhostComponent.cs b/Content.Client/GameObjects/Components/Observer/GhostComponent.cs similarity index 62% rename from Content.Client/Observer/GhostComponent.cs rename to Content.Client/GameObjects/Components/Observer/GhostComponent.cs index a35059dd48..c71310845a 100644 --- a/Content.Client/Observer/GhostComponent.cs +++ b/Content.Client/GameObjects/Components/Observer/GhostComponent.cs @@ -1,14 +1,14 @@ using Content.Client.UserInterface; -using Content.Shared.Observer; +using Content.Shared.GameObjects.Components.Observer; using Robust.Client.GameObjects; +using Robust.Client.Player; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; -using Robust.Shared.Log; using Robust.Shared.ViewVariables; -namespace Content.Client.Observer +namespace Content.Client.GameObjects.Components.Observer { [RegisterComponent] public class GhostComponent : SharedGhostComponent @@ -25,6 +25,8 @@ namespace Content.Client.Observer #pragma warning disable 649 [Dependency] private readonly IGameHud _gameHud; + [Dependency] private readonly IPlayerManager _playerManager; + [Dependency] private IComponentManager _componentManager; #pragma warning restore 649 public override void OnRemove() @@ -34,6 +36,25 @@ namespace Content.Client.Observer _gui?.Dispose(); } + + private void SetGhostVisibility(bool visibility) + { + // So, for now this is a client-side hack... Please, PLEASE someone make this work server-side. + foreach (var ghost in _componentManager.GetAllComponents(typeof(GhostComponent))) + { + if (ghost.Owner.TryGetComponent(out SpriteComponent component)) + component.Visible = visibility; + } + } + + public override void Initialize() + { + base.Initialize(); + + if (Owner.TryGetComponent(out SpriteComponent component)) + component.Visible = _playerManager.LocalPlayer.ControlledEntity?.HasComponent() ?? false; + } + public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, IComponent component = null) { @@ -52,10 +73,13 @@ namespace Content.Client.Observer } _gameHud.HandsContainer.AddChild(_gui); + SetGhostVisibility(true); + break; case PlayerDetachedMsg _: _gui.Parent?.RemoveChild(_gui); + SetGhostVisibility(false); break; } } @@ -69,7 +93,12 @@ namespace Content.Client.Observer if (!(curState is GhostComponentState state)) return; _canReturnToBody = state.CanReturnToBody; - _gui?.Update(); + + if (Owner == _playerManager.LocalPlayer.ControlledEntity) + { + _gui?.Update(); + } + } } } diff --git a/Content.Client/UserInterface/GhostGui.cs b/Content.Client/UserInterface/GhostGui.cs index 13d41aea69..959b3beff6 100644 --- a/Content.Client/UserInterface/GhostGui.cs +++ b/Content.Client/UserInterface/GhostGui.cs @@ -1,5 +1,5 @@ using System.Data; -using Content.Client.Observer; +using Content.Client.GameObjects.Components.Observer; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.IoC; diff --git a/Content.Server/Administration/AGhost.cs b/Content.Server/Administration/AGhost.cs index 57d5882480..40547197e1 100644 --- a/Content.Server/Administration/AGhost.cs +++ b/Content.Server/Administration/AGhost.cs @@ -1,4 +1,5 @@ -using Content.Server.Players; +using Content.Server.GameObjects.Components.Observer; +using Content.Server.Players; using Robust.Server.Interfaces.Console; using Robust.Server.Interfaces.Player; using Robust.Shared.Interfaces.GameObjects; @@ -30,10 +31,14 @@ namespace Content.Server.Administration } else { + var canReturn = mind.CurrentEntity != null && !mind.CurrentEntity.HasComponent(); var entityManager = IoCManager.Resolve(); var ghost = entityManager.SpawnEntity("AdminObserver", player.AttachedEntity.Transform.GridPosition); - - mind.Visit(ghost); + if(canReturn) + mind.Visit(ghost); + else + mind.TransferTo(ghost); + ghost.GetComponent().CanReturnToBody = canReturn; } } } diff --git a/Content.Server/Chat/ChatCommands.cs b/Content.Server/Chat/ChatCommands.cs index 4a88fab4b9..00ca6a4124 100644 --- a/Content.Server/Chat/ChatCommands.cs +++ b/Content.Server/Chat/ChatCommands.cs @@ -1,4 +1,5 @@ -using Content.Server.Interfaces.Chat; +using Content.Server.GameObjects.Components.Observer; +using Content.Server.Interfaces.Chat; using Content.Server.Observer; using Robust.Server.Interfaces.Console; using Robust.Server.Interfaces.Player; diff --git a/Content.Server/Chat/ChatManager.cs b/Content.Server/Chat/ChatManager.cs index 14ae50d395..ebd06862ee 100644 --- a/Content.Server/Chat/ChatManager.cs +++ b/Content.Server/Chat/ChatManager.cs @@ -1,4 +1,5 @@ using System.Linq; +using Content.Server.GameObjects.Components.Observer; using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces; using Content.Server.Interfaces.Chat; diff --git a/Content.Server/Observer/GhostComponent.cs b/Content.Server/GameObjects/Components/Observer/GhostComponent.cs similarity index 90% rename from Content.Server/Observer/GhostComponent.cs rename to Content.Server/GameObjects/Components/Observer/GhostComponent.cs index 029e7814ed..11eb1d40db 100644 --- a/Content.Server/Observer/GhostComponent.cs +++ b/Content.Server/GameObjects/Components/Observer/GhostComponent.cs @@ -1,18 +1,16 @@ -using System.Threading; using Content.Server.GameObjects.EntitySystems; using Content.Server.Players; -using Content.Shared.Observer; +using Content.Shared.GameObjects.Components.Observer; using Robust.Server.GameObjects; using Robust.Server.Interfaces.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Network; -using Robust.Shared.Log; using Robust.Shared.ViewVariables; using Timer = Robust.Shared.Timers.Timer; -namespace Content.Server.Observer +namespace Content.Server.GameObjects.Components.Observer { [RegisterComponent] public class GhostComponent : SharedGhostComponent, IActionBlocker @@ -46,6 +44,9 @@ namespace Content.Server.Observer actor.playerSession.ContentData().Mind.UnVisit(); } break; + case PlayerAttachedMsg _: + Dirty(); + break; case PlayerDetachedMsg _: Timer.Spawn(100, Owner.Delete); break; @@ -54,7 +55,6 @@ namespace Content.Server.Observer } } - public bool CanInteract() => false; public bool CanUse() => false; public bool CanThrow() => false; diff --git a/Content.Server/Observer/Ghost.cs b/Content.Server/Observer/Ghost.cs index 66410bff7f..712d673c5a 100644 --- a/Content.Server/Observer/Ghost.cs +++ b/Content.Server/Observer/Ghost.cs @@ -1,4 +1,5 @@ using Content.Server.GameObjects; +using Content.Server.GameObjects.Components.Observer; using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces.GameTicking; using Content.Server.Players; @@ -7,6 +8,7 @@ using Robust.Server.Interfaces.Console; using Robust.Server.Interfaces.Player; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; +using Robust.Shared.Log; using Robust.Shared.Map; namespace Content.Server.Observer diff --git a/Content.Shared/Observer/SharedGhostComponent.cs b/Content.Shared/GameObjects/Components/Observer/SharedGhostComponent.cs similarity index 92% rename from Content.Shared/Observer/SharedGhostComponent.cs rename to Content.Shared/GameObjects/Components/Observer/SharedGhostComponent.cs index b768b1e7a5..f7a302bcba 100644 --- a/Content.Shared/Observer/SharedGhostComponent.cs +++ b/Content.Shared/GameObjects/Components/Observer/SharedGhostComponent.cs @@ -1,9 +1,8 @@ using System; -using Content.Shared.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.Serialization; -namespace Content.Shared.Observer +namespace Content.Shared.GameObjects.Components.Observer { public class SharedGhostComponent : Component { diff --git a/Resources/Prototypes/Entities/mobs/observer.yml b/Resources/Prototypes/Entities/mobs/observer.yml index 8fc3adb84f..26d817f212 100644 --- a/Resources/Prototypes/Entities/mobs/observer.yml +++ b/Resources/Prototypes/Entities/mobs/observer.yml @@ -16,3 +16,7 @@ DoRangeCheck: false - type: IgnorePause - type: Ghost + - type: Sprite + netsync: false + drawdepth: Mobs + texture: Mob/observer.png