From 6905394e8a39bcd3dbcc2c769d7c8c345e594737 Mon Sep 17 00:00:00 2001 From: zumorica Date: Tue, 3 Mar 2020 18:04:16 +0100 Subject: [PATCH 01/14] Add placeholder ghost UI, ghost component --- Content.Client/Observer/GhostComponent.cs | 53 +++++++++++++++++++ Content.Client/UserInterface/GhostGui.cs | 18 +++++++ .../Observer/SharedGhostComponent.cs | 9 ++++ .../Prototypes/Entities/mobs/observer.yml | 1 + 4 files changed, 81 insertions(+) create mode 100644 Content.Client/Observer/GhostComponent.cs create mode 100644 Content.Client/UserInterface/GhostGui.cs create mode 100644 Content.Shared/Observer/SharedGhostComponent.cs diff --git a/Content.Client/Observer/GhostComponent.cs b/Content.Client/Observer/GhostComponent.cs new file mode 100644 index 0000000000..31f45d84b8 --- /dev/null +++ b/Content.Client/Observer/GhostComponent.cs @@ -0,0 +1,53 @@ +using Content.Client.UserInterface; +using Content.Shared.Observer; +using Robust.Client.GameObjects; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.Interfaces.Network; +using Robust.Shared.IoC; + +namespace Content.Client.Observer +{ + [RegisterComponent] + public class GhostComponent : SharedGhostComponent + { + private GhostGui _gui; + +#pragma warning disable 649 + [Dependency] private readonly IGameHud _gameHud; +#pragma warning restore 649 + + public override void OnRemove() + { + base.OnRemove(); + + _gui?.Dispose(); + } + + public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, + IComponent component = null) + { + base.HandleMessage(message, netChannel, component); + + switch (message) + { + case PlayerAttachedMsg _: + if (_gui == null) + { + _gui = new GhostGui(); + } + else + { + _gui.Parent?.RemoveChild(_gui); + } + + _gameHud.HandsContainer.AddChild(_gui); + break; + + case PlayerDetachedMsg _: + _gui.Parent?.RemoveChild(_gui); + break; + } + } + } +} diff --git a/Content.Client/UserInterface/GhostGui.cs b/Content.Client/UserInterface/GhostGui.cs new file mode 100644 index 0000000000..63f7a870ba --- /dev/null +++ b/Content.Client/UserInterface/GhostGui.cs @@ -0,0 +1,18 @@ +using Robust.Client.UserInterface; +using Robust.Client.UserInterface.Controls; +using Robust.Shared.IoC; + +namespace Content.Client.UserInterface +{ + public class GhostGui : Control + { + public GhostGui() + { + IoCManager.InjectDependencies(this); + + MouseFilter = MouseFilterMode.Ignore; + + AddChild(new Label(){Text = "YES THIS IS GHOST WHOOOOOO"}); + } + } +} diff --git a/Content.Shared/Observer/SharedGhostComponent.cs b/Content.Shared/Observer/SharedGhostComponent.cs new file mode 100644 index 0000000000..dca348b285 --- /dev/null +++ b/Content.Shared/Observer/SharedGhostComponent.cs @@ -0,0 +1,9 @@ +using Robust.Shared.GameObjects; + +namespace Content.Shared.Observer +{ + public class SharedGhostComponent : Component + { + public override string Name => "Ghost"; + } +} diff --git a/Resources/Prototypes/Entities/mobs/observer.yml b/Resources/Prototypes/Entities/mobs/observer.yml index c99257b300..8fc3adb84f 100644 --- a/Resources/Prototypes/Entities/mobs/observer.yml +++ b/Resources/Prototypes/Entities/mobs/observer.yml @@ -15,3 +15,4 @@ - type: Examiner DoRangeCheck: false - type: IgnorePause + - type: Ghost From 055f09d5015602781b60e57bcd70221bef79050b Mon Sep 17 00:00:00 2001 From: zumorica Date: Tue, 3 Mar 2020 19:10:07 +0100 Subject: [PATCH 02/14] Button to return to body --- Content.Client/Observer/GhostComponent.cs | 25 ++++++++- Content.Client/UserInterface/GhostGui.cs | 12 +++- Content.Server/Observer/GhostComponent.cs | 56 +++++++++++++++++++ Content.Shared/GameObjects/ContentNetIDs.cs | 1 + .../Observer/SharedGhostComponent.cs | 23 ++++++++ 5 files changed, 114 insertions(+), 3 deletions(-) create mode 100644 Content.Server/Observer/GhostComponent.cs diff --git a/Content.Client/Observer/GhostComponent.cs b/Content.Client/Observer/GhostComponent.cs index 31f45d84b8..f1b05fcc29 100644 --- a/Content.Client/Observer/GhostComponent.cs +++ b/Content.Client/Observer/GhostComponent.cs @@ -5,6 +5,8 @@ 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 { @@ -12,6 +14,14 @@ namespace Content.Client.Observer public class GhostComponent : SharedGhostComponent { private GhostGui _gui; + private bool _canReturnToBody = true; + + [ViewVariables(VVAccess.ReadOnly)] + public override bool CanReturnToBody + { + get => _canReturnToBody; + set {} + } #pragma warning disable 649 [Dependency] private readonly IGameHud _gameHud; @@ -34,7 +44,7 @@ namespace Content.Client.Observer case PlayerAttachedMsg _: if (_gui == null) { - _gui = new GhostGui(); + _gui = new GhostGui(this); } else { @@ -49,5 +59,18 @@ namespace Content.Client.Observer break; } } + + public void SendReturnToBodyMessage() => SendNetworkMessage(new ReturnToBodyComponentMessage()); + + public override void HandleComponentState(ComponentState curState, ComponentState nextState) + { + base.HandleComponentState(curState, nextState); + + if (!(curState is GhostComponentState state)) return; + + _canReturnToBody = state.CanReturnToBody; + if (_gui == null) return; + _gui.ReturnToBody.Disabled = !_canReturnToBody; + } } } diff --git a/Content.Client/UserInterface/GhostGui.cs b/Content.Client/UserInterface/GhostGui.cs index 63f7a870ba..2a73c6f0fd 100644 --- a/Content.Client/UserInterface/GhostGui.cs +++ b/Content.Client/UserInterface/GhostGui.cs @@ -1,3 +1,4 @@ +using Content.Client.Observer; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; using Robust.Shared.IoC; @@ -6,13 +7,20 @@ namespace Content.Client.UserInterface { public class GhostGui : Control { - public GhostGui() + public Button ReturnToBody = new Button(){Text = "Return to body"}; + private GhostComponent _owner; + + public GhostGui(GhostComponent owner) { IoCManager.InjectDependencies(this); + _owner = owner; + MouseFilter = MouseFilterMode.Ignore; - AddChild(new Label(){Text = "YES THIS IS GHOST WHOOOOOO"}); + ReturnToBody.OnPressed += (args) => { owner.SendReturnToBodyMessage(); }; + + AddChild(ReturnToBody); } } } diff --git a/Content.Server/Observer/GhostComponent.cs b/Content.Server/Observer/GhostComponent.cs new file mode 100644 index 0000000000..d3ea271c52 --- /dev/null +++ b/Content.Server/Observer/GhostComponent.cs @@ -0,0 +1,56 @@ +using System.Threading; +using Content.Server.Players; +using Content.Shared.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 +{ + [RegisterComponent] + public class GhostComponent : SharedGhostComponent + { + private bool _canReturnToBody = true; + + [ViewVariables(VVAccess.ReadWrite)] + public override bool CanReturnToBody + { + get => _canReturnToBody; + set + { + _canReturnToBody = value; + Dirty(); + } + } + + public override ComponentState GetComponentState() => new GhostComponentState(CanReturnToBody); + + public override void HandleMessage(ComponentMessage message, INetChannel netChannel = null, + IComponent component = null) + { + base.HandleMessage(message, netChannel, component); + + switch (message) + { + case ReturnToBodyComponentMessage reenter: + if (!Owner.TryGetComponent(out IActorComponent actor) || !CanReturnToBody) break; + if (netChannel == null || netChannel == actor.playerSession.ConnectedClient) + { + actor.playerSession.ContentData().Mind.UnVisit(); + } + break; + case PlayerDetachedMsg _: + Timer.Spawn(100, Owner.Delete); + break; + default: + break; + } + } + } +} diff --git a/Content.Shared/GameObjects/ContentNetIDs.cs b/Content.Shared/GameObjects/ContentNetIDs.cs index eeecefda41..ef69972f4d 100644 --- a/Content.Shared/GameObjects/ContentNetIDs.cs +++ b/Content.Shared/GameObjects/ContentNetIDs.cs @@ -41,5 +41,6 @@ public const uint HANDHELD_LIGHT = 1036; public const uint PAPER = 1037; public const uint REAGENT_INJECTOR = 1038; + public const uint GHOST = 1039; } } diff --git a/Content.Shared/Observer/SharedGhostComponent.cs b/Content.Shared/Observer/SharedGhostComponent.cs index dca348b285..b768b1e7a5 100644 --- a/Content.Shared/Observer/SharedGhostComponent.cs +++ b/Content.Shared/Observer/SharedGhostComponent.cs @@ -1,9 +1,32 @@ +using System; +using Content.Shared.GameObjects; using Robust.Shared.GameObjects; +using Robust.Shared.Serialization; namespace Content.Shared.Observer { public class SharedGhostComponent : Component { public override string Name => "Ghost"; + public override uint? NetID => ContentNetIDs.GHOST; + + public virtual bool CanReturnToBody { get; set; } = true; + } + + [Serializable, NetSerializable] + public class GhostComponentState : ComponentState + { + public bool CanReturnToBody { get; } + + public GhostComponentState(bool canReturnToBody) : base(ContentNetIDs.GHOST) + { + CanReturnToBody = canReturnToBody; + } + } + + [Serializable, NetSerializable] + public class ReturnToBodyComponentMessage : ComponentMessage + { + public ReturnToBodyComponentMessage() => Directed = true; } } From 7f19381bec2225d3ee0a89147bdf904da9e59dcf Mon Sep 17 00:00:00 2001 From: zumorica Date: Tue, 3 Mar 2020 20:37:26 +0100 Subject: [PATCH 03/14] Ghost command, some other stuff --- Content.Client/Observer/GhostComponent.cs | 3 +- Content.Client/UserInterface/GhostGui.cs | 8 +++ Content.IntegrationTests/DummyGameTicker.cs | 5 ++ .../Components/Damage/DamageableComponent.cs | 8 ++- .../Components/Markers/SpawnPointComponent.cs | 1 + Content.Server/GameTicking/GameTicker.cs | 25 +++++-- .../Interfaces/GameTicking/IGameTicker.cs | 5 ++ Content.Server/Observer/Ghost.cs | 67 +++++++++++++++++++ Resources/Groups/groups.yml | 4 ++ 9 files changed, 119 insertions(+), 7 deletions(-) create mode 100644 Content.Server/Observer/Ghost.cs diff --git a/Content.Client/Observer/GhostComponent.cs b/Content.Client/Observer/GhostComponent.cs index f1b05fcc29..a35059dd48 100644 --- a/Content.Client/Observer/GhostComponent.cs +++ b/Content.Client/Observer/GhostComponent.cs @@ -69,8 +69,7 @@ namespace Content.Client.Observer if (!(curState is GhostComponentState state)) return; _canReturnToBody = state.CanReturnToBody; - if (_gui == null) return; - _gui.ReturnToBody.Disabled = !_canReturnToBody; + _gui?.Update(); } } } diff --git a/Content.Client/UserInterface/GhostGui.cs b/Content.Client/UserInterface/GhostGui.cs index 2a73c6f0fd..13d41aea69 100644 --- a/Content.Client/UserInterface/GhostGui.cs +++ b/Content.Client/UserInterface/GhostGui.cs @@ -1,3 +1,4 @@ +using System.Data; using Content.Client.Observer; using Robust.Client.UserInterface; using Robust.Client.UserInterface.Controls; @@ -21,6 +22,13 @@ namespace Content.Client.UserInterface ReturnToBody.OnPressed += (args) => { owner.SendReturnToBodyMessage(); }; AddChild(ReturnToBody); + + Update(); + } + + public void Update() + { + ReturnToBody.Disabled = !_owner.CanReturnToBody; } } } diff --git a/Content.IntegrationTests/DummyGameTicker.cs b/Content.IntegrationTests/DummyGameTicker.cs index 5732e413ea..33bc84ac24 100644 --- a/Content.IntegrationTests/DummyGameTicker.cs +++ b/Content.IntegrationTests/DummyGameTicker.cs @@ -4,6 +4,7 @@ using Content.Server.GameTicking; using Content.Server.Interfaces.GameTicking; using Content.Shared; using Robust.Server.Interfaces.Player; +using Robust.Shared.Map; using Robust.Shared.Timing; namespace Content.IntegrationTests @@ -54,6 +55,10 @@ namespace Content.IntegrationTests { } + public GridCoordinates GetLateJoinSpawnPoint() => GridCoordinates.InvalidGrid; + public GridCoordinates GetJobSpawnPoint(string jobId) => GridCoordinates.InvalidGrid; + public GridCoordinates GetObserverSpawnPoint() => GridCoordinates.InvalidGrid; + public T AddGameRule() where T : GameRule, new() { return new T(); diff --git a/Content.Server/GameObjects/Components/Damage/DamageableComponent.cs b/Content.Server/GameObjects/Components/Damage/DamageableComponent.cs index 76d34a39af..d341520159 100644 --- a/Content.Server/GameObjects/Components/Damage/DamageableComponent.cs +++ b/Content.Server/GameObjects/Components/Damage/DamageableComponent.cs @@ -75,7 +75,13 @@ namespace Content.Server.GameObjects { if (damageType == DamageType.Total) { - throw new ArgumentException("Cannot take damage for DamageType.Total"); + foreach (DamageType e in Enum.GetValues(typeof(DamageType))) + { + if (e == damageType) continue; + TakeDamage(e, amount, source, sourceMob); + } + + return; } InitializeDamageType(damageType); diff --git a/Content.Server/GameObjects/Components/Markers/SpawnPointComponent.cs b/Content.Server/GameObjects/Components/Markers/SpawnPointComponent.cs index e502a08f1a..77b01c34a1 100644 --- a/Content.Server/GameObjects/Components/Markers/SpawnPointComponent.cs +++ b/Content.Server/GameObjects/Components/Markers/SpawnPointComponent.cs @@ -38,5 +38,6 @@ namespace Content.Server.GameObjects.Components.Markers Unset = 0, LateJoin, Job, + Observer, } } diff --git a/Content.Server/GameTicking/GameTicker.cs b/Content.Server/GameTicking/GameTicker.cs index e8c654b2c3..5f6542172c 100644 --- a/Content.Server/GameTicking/GameTicker.cs +++ b/Content.Server/GameTicking/GameTicker.cs @@ -273,7 +273,7 @@ namespace Content.Server.GameTicking private IEntity _spawnPlayerMob(Job job, bool lateJoin = true) { - GridCoordinates coordinates = lateJoin ? _getLateJoinSpawnPoint() : _getJobSpawnPoint(job.Prototype.ID); + GridCoordinates coordinates = lateJoin ? GetLateJoinSpawnPoint() : GetJobSpawnPoint(job.Prototype.ID); var entity = _entityManager.SpawnEntity(PlayerPrototypeName, coordinates); if (entity.TryGetComponent(out InventoryComponent inventory)) { @@ -299,11 +299,11 @@ namespace Content.Server.GameTicking private IEntity _spawnObserverMob() { - GridCoordinates coordinates = _getLateJoinSpawnPoint(); + var coordinates = GetObserverSpawnPoint(); return _entityManager.SpawnEntity(ObserverPrototypeName, coordinates); } - private GridCoordinates _getLateJoinSpawnPoint() + public GridCoordinates GetLateJoinSpawnPoint() { var location = _spawnPoint; @@ -319,7 +319,7 @@ namespace Content.Server.GameTicking return location; } - private GridCoordinates _getJobSpawnPoint(string jobId) + public GridCoordinates GetJobSpawnPoint(string jobId) { var location = _spawnPoint; @@ -336,6 +336,23 @@ namespace Content.Server.GameTicking return location; } + public GridCoordinates GetObserverSpawnPoint() + { + var location = _spawnPoint; + + var possiblePoints = new List(); + foreach (var entity in _entityManager.GetEntities(new TypeEntityQuery(typeof(SpawnPointComponent)))) + { + var point = entity.GetComponent(); + if (point.SpawnType == SpawnPointType.Observer) + possiblePoints.Add(entity.Transform.GridPosition); + } + + if (possiblePoints.Count != 0) location = _robustRandom.Pick(possiblePoints); + + return location; + } + /// /// Cleanup that has to run to clear up anything from the previous round. /// Stuff like wiping the previous map clean. diff --git a/Content.Server/Interfaces/GameTicking/IGameTicker.cs b/Content.Server/Interfaces/GameTicking/IGameTicker.cs index e3754e1a7d..67bf2857d2 100644 --- a/Content.Server/Interfaces/GameTicking/IGameTicker.cs +++ b/Content.Server/Interfaces/GameTicking/IGameTicker.cs @@ -2,6 +2,7 @@ using System; using System.Collections.Generic; using Content.Server.GameTicking; using Robust.Server.Interfaces.Player; +using Robust.Shared.Map; using Robust.Shared.Timing; namespace Content.Server.Interfaces.GameTicking @@ -27,6 +28,10 @@ namespace Content.Server.Interfaces.GameTicking void MakeJoinGame(IPlayerSession player); void ToggleReady(IPlayerSession player, bool ready); + GridCoordinates GetLateJoinSpawnPoint(); + GridCoordinates GetJobSpawnPoint(string jobId); + GridCoordinates GetObserverSpawnPoint(); + // GameRule system. T AddGameRule() where T : GameRule, new(); void RemoveGameRule(GameRule rule); diff --git a/Content.Server/Observer/Ghost.cs b/Content.Server/Observer/Ghost.cs new file mode 100644 index 0000000000..3ee16adf73 --- /dev/null +++ b/Content.Server/Observer/Ghost.cs @@ -0,0 +1,67 @@ +using Content.Server.GameObjects; +using Content.Server.Interfaces.GameTicking; +using Content.Server.Players; +using Content.Shared.GameObjects; +using Robust.Server.Interfaces.Console; +using Robust.Server.Interfaces.Player; +using Robust.Shared.Interfaces.GameObjects; +using Robust.Shared.IoC; +using Robust.Shared.Map; + +namespace Content.Server.Observer +{ + public class Ghost : IClientCommand + { + public string Command => "ghost"; + public string Description => "Give up on life and become a ghost."; + public string Help => "ghost"; + + public void Execute(IConsoleShell shell, IPlayerSession player, string[] args) + { + if (player == null) + { + shell.SendText((IPlayerSession) null, "Nah"); + return; + } + + var mind = player.ContentData().Mind; + GridCoordinates position; + var canReturn = player.AttachedEntity != null; + + if (mind.VisitingEntity != null) + { + mind.UnVisit(); + } + + position = player.AttachedEntity?.Transform.GridPosition ?? IoCManager.Resolve().GetObserverSpawnPoint(); + + if (canReturn && player.AttachedEntity.TryGetComponent(out SpeciesComponent species)) + { + switch (species.CurrentDamageState) + { + case DeadState _: + canReturn = true; + break; + case CriticalState _: + canReturn = true; + if (!player.AttachedEntity.TryGetComponent(out DamageableComponent damageable)) break; + damageable.TakeDamage(DamageType.Total, 100); // TODO: Use airloss/oxyloss instead + break; + default: + canReturn = false; + break; + } + } + + var entityManager = IoCManager.Resolve(); + var ghost = entityManager.SpawnEntity("MobObserver", position); + var ghostComponent = ghost.GetComponent(); + ghostComponent.CanReturnToBody = canReturn; + + if(canReturn) + mind.Visit(ghost); + else + mind.TransferTo(ghost); + } + } +} diff --git a/Resources/Groups/groups.yml b/Resources/Groups/groups.yml index d1fe708455..50b84be17f 100644 --- a/Resources/Groups/groups.yml +++ b/Resources/Groups/groups.yml @@ -11,6 +11,7 @@ - ooc - observe - toggleready + - ghost - Index: 50 Name: Moderator @@ -26,6 +27,7 @@ - showtime - observe - toggleready + - ghost - kick - listplayers - loc @@ -44,6 +46,7 @@ - aghost - observe - toggleready + - ghost - spawn - delete - tp @@ -84,6 +87,7 @@ - aghost - observe - toggleready + - ghost - spawn - delete - tp From 16353a89e6b2541ad67d5a1eb9487021a4832d1a Mon Sep 17 00:00:00 2001 From: zumorica Date: Mon, 30 Mar 2020 01:15:03 +0200 Subject: [PATCH 04/14] Default interface implementation for IActionBlocker (defaults to true) --- .../EntitySystems/ActionBlockerSystem.cs | 18 +++++++++--------- 1 file changed, 9 insertions(+), 9 deletions(-) diff --git a/Content.Server/GameObjects/EntitySystems/ActionBlockerSystem.cs b/Content.Server/GameObjects/EntitySystems/ActionBlockerSystem.cs index ce3205bb01..36de02bb79 100644 --- a/Content.Server/GameObjects/EntitySystems/ActionBlockerSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/ActionBlockerSystem.cs @@ -5,23 +5,23 @@ namespace Content.Server.GameObjects.EntitySystems { public interface IActionBlocker { - bool CanMove(); + bool CanMove() => true; - bool CanInteract(); + bool CanInteract() => true; - bool CanUse(); + bool CanUse() => true; - bool CanThrow(); + bool CanThrow() => true; - bool CanSpeak(); + bool CanSpeak() => true; - bool CanDrop(); + bool CanDrop() => true; - bool CanPickup(); + bool CanPickup() => true; - bool CanEmote(); + bool CanEmote() => true; - bool CanAttack(); + bool CanAttack() => true; } public class ActionBlockerSystem : EntitySystem From aba3b0217e3143369dc94c7918c701f2f941d87e Mon Sep 17 00:00:00 2001 From: zumorica Date: Mon, 30 Mar 2020 01:15:23 +0200 Subject: [PATCH 05/14] Moving when dead ghosts you --- Content.Server/GameObjects/EntitySystems/MoverSystem.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Content.Server/GameObjects/EntitySystems/MoverSystem.cs b/Content.Server/GameObjects/EntitySystems/MoverSystem.cs index 5860ac4e35..4b2038d855 100644 --- a/Content.Server/GameObjects/EntitySystems/MoverSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/MoverSystem.cs @@ -3,12 +3,14 @@ using Content.Server.GameObjects.Components.Mobs; using Content.Server.GameObjects.Components.Movement; using Content.Server.GameObjects.Components.Sound; using Content.Server.Interfaces.GameObjects.Components.Movement; +using Content.Server.Observer; using Content.Shared.Audio; using Content.Shared.GameObjects.Components.Inventory; using Content.Shared.Maps; using JetBrains.Annotations; using Robust.Server.GameObjects; using Robust.Server.GameObjects.EntitySystems; +using Robust.Server.Interfaces.GameObjects; using Robust.Server.Interfaces.Player; using Robust.Server.Interfaces.Timing; using Robust.Shared.Configuration; @@ -25,6 +27,7 @@ using Robust.Shared.IoC; using Robust.Shared.Log; using Robust.Shared.Map; using Robust.Shared.Maths; +using Robust.Shared.Network; using Robust.Shared.Players; using Robust.Shared.Prototypes; using Robust.Shared.Random; @@ -138,6 +141,7 @@ namespace Content.Server.GameObjects.EntitySystems { if (physics.LinearVelocity != Vector2.Zero) physics.LinearVelocity = Vector2.Zero; + } else { @@ -185,6 +189,11 @@ namespace Content.Server.GameObjects.EntitySystems if (!TryGetAttachedComponent(session as IPlayerSession, out IMoverComponent moverComp)) return; + var owner = (session as IPlayerSession)?.AttachedEntity; + + if (owner != null && owner.TryGetComponent(out SpeciesComponent species) && species.CurrentDamageState is DeadState) + new Ghost().Execute(null, (IPlayerSession)session, null); + moverComp.SetVelocityDirection(dir, state); } From a07c407f2ecbb195e11948099e7938a15d58b7e2 Mon Sep 17 00:00:00 2001 From: zumorica Date: Mon, 30 Mar 2020 01:15:43 +0200 Subject: [PATCH 06/14] Deadchat --- Content.Server/Chat/ChatCommands.cs | 6 +++++- Content.Server/Chat/ChatManager.cs | 12 ++++++++++++ Content.Server/Interfaces/Chat/IChatManager.cs | 1 + Content.Shared/Chat/ChatChannel.cs | 9 +++++++-- 4 files changed, 25 insertions(+), 3 deletions(-) diff --git a/Content.Server/Chat/ChatCommands.cs b/Content.Server/Chat/ChatCommands.cs index 04fdaeef94..4a88fab4b9 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.Observer; using Robust.Server.Interfaces.Console; using Robust.Server.Interfaces.Player; using Robust.Shared.Enums; @@ -24,7 +25,10 @@ namespace Content.Server.Chat var message = string.Join(" ", args); - chat.EntitySay(player.AttachedEntity, message); + if (player.AttachedEntity.HasComponent()) + chat.SendDeadChat(player, message); + else + chat.EntitySay(player.AttachedEntity, message); } } diff --git a/Content.Server/Chat/ChatManager.cs b/Content.Server/Chat/ChatManager.cs index 218fc31dcd..14ae50d395 100644 --- a/Content.Server/Chat/ChatManager.cs +++ b/Content.Server/Chat/ChatManager.cs @@ -2,6 +2,7 @@ using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces; using Content.Server.Interfaces.Chat; +using Content.Server.Observer; using Content.Shared.Chat; using Robust.Server.Interfaces.Player; using Robust.Shared.Interfaces.GameObjects; @@ -93,6 +94,17 @@ namespace Content.Server.Chat _mommiLink.SendOOCMessage(player.SessionId.ToString(), message); } + public void SendDeadChat(IPlayerSession player, string message) + { + var clients = _playerManager.GetPlayersBy(x => x.AttachedEntity != null && x.AttachedEntity.HasComponent()).Select(p => p.ConnectedClient);; + + var msg = _netManager.CreateNetMessage(); + msg.Channel = ChatChannel.Dead; + msg.Message = message; + msg.MessageWrap = $"DEAD: {player.AttachedEntity.Name}: {{0}}"; + _netManager.ServerSendToMany(msg, clients.ToList()); + } + public void SendHookOOC(string sender, string message) { var msg = _netManager.CreateNetMessage(); diff --git a/Content.Server/Interfaces/Chat/IChatManager.cs b/Content.Server/Interfaces/Chat/IChatManager.cs index 7cfe1b4f44..26af31827a 100644 --- a/Content.Server/Interfaces/Chat/IChatManager.cs +++ b/Content.Server/Interfaces/Chat/IChatManager.cs @@ -18,6 +18,7 @@ namespace Content.Server.Interfaces.Chat void EntityMe(IEntity source, string action); void SendOOC(IPlayerSession player, string message); + void SendDeadChat(IPlayerSession player, string message); void SendHookOOC(string sender, string message); } diff --git a/Content.Shared/Chat/ChatChannel.cs b/Content.Shared/Chat/ChatChannel.cs index 0aac182734..4c9da79f0b 100644 --- a/Content.Shared/Chat/ChatChannel.cs +++ b/Content.Shared/Chat/ChatChannel.cs @@ -6,7 +6,7 @@ namespace Content.Shared.Chat /// Represents chat channels that the player can filter chat tabs by. /// [Flags] - public enum ChatChannel : byte + public enum ChatChannel : short { None = 0, @@ -46,9 +46,14 @@ namespace Content.Shared.Chat /// Emotes = 64, + /// + /// Deadchat + /// + Dead = 128, + /// /// Unspecified. /// - Unspecified = 128, + Unspecified = 256, } } From 24c5909c43a5b011385fb7b432f5329871dc6806 Mon Sep 17 00:00:00 2001 From: zumorica Date: Mon, 30 Mar 2020 01:16:44 +0200 Subject: [PATCH 07/14] Ghosts retain their prior name, before defaulting to username. --- Content.Server/Observer/Ghost.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/Content.Server/Observer/Ghost.cs b/Content.Server/Observer/Ghost.cs index 3ee16adf73..66410bff7f 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.EntitySystems; using Content.Server.Interfaces.GameTicking; using Content.Server.Players; using Content.Shared.GameObjects; @@ -25,15 +26,18 @@ namespace Content.Server.Observer } var mind = player.ContentData().Mind; - GridCoordinates position; var canReturn = player.AttachedEntity != null; + var name = player.AttachedEntity?.Name ?? player.Name; + + if (player.AttachedEntity != null && player.AttachedEntity.HasComponent()) + return; if (mind.VisitingEntity != null) { mind.UnVisit(); } - position = player.AttachedEntity?.Transform.GridPosition ?? IoCManager.Resolve().GetObserverSpawnPoint(); + var position = player.AttachedEntity?.Transform.GridPosition ?? IoCManager.Resolve().GetObserverSpawnPoint(); if (canReturn && player.AttachedEntity.TryGetComponent(out SpeciesComponent species)) { @@ -55,6 +59,7 @@ namespace Content.Server.Observer var entityManager = IoCManager.Resolve(); var ghost = entityManager.SpawnEntity("MobObserver", position); + ghost.Name = name; var ghostComponent = ghost.GetComponent(); ghostComponent.CanReturnToBody = canReturn; From d28af07fce7764bce34d0946fbad9fbf2ff6e899 Mon Sep 17 00:00:00 2001 From: zumorica Date: Mon, 30 Mar 2020 01:18:28 +0200 Subject: [PATCH 08/14] Ghost component implements IActionBlocker --- Content.Server/Observer/GhostComponent.cs | 12 +++++++++++- 1 file changed, 11 insertions(+), 1 deletion(-) diff --git a/Content.Server/Observer/GhostComponent.cs b/Content.Server/Observer/GhostComponent.cs index d3ea271c52..029e7814ed 100644 --- a/Content.Server/Observer/GhostComponent.cs +++ b/Content.Server/Observer/GhostComponent.cs @@ -1,4 +1,5 @@ using System.Threading; +using Content.Server.GameObjects.EntitySystems; using Content.Server.Players; using Content.Shared.Observer; using Robust.Server.GameObjects; @@ -14,7 +15,7 @@ using Timer = Robust.Shared.Timers.Timer; namespace Content.Server.Observer { [RegisterComponent] - public class GhostComponent : SharedGhostComponent + public class GhostComponent : SharedGhostComponent, IActionBlocker { private bool _canReturnToBody = true; @@ -52,5 +53,14 @@ namespace Content.Server.Observer break; } } + + + public bool CanInteract() => false; + public bool CanUse() => false; + public bool CanThrow() => false; + public bool CanDrop() => false; + public bool CanPickup() => false; + public bool CanEmote() => false; + public bool CanAttack() => false; } } From a0d114c67235344a3782b6d9561e88f4f04a9115 Mon Sep 17 00:00:00 2001 From: zumorica Date: Sun, 5 Apr 2020 02:29:04 +0200 Subject: [PATCH 09/14] Ghost sprites and a bunch of fixes --- .../Components}/Observer/GhostComponent.cs | 37 +++++++++++++++++-- Content.Client/UserInterface/GhostGui.cs | 2 +- Content.Server/Administration/AGhost.cs | 11 ++++-- Content.Server/Chat/ChatCommands.cs | 3 +- Content.Server/Chat/ChatManager.cs | 1 + .../Components}/Observer/GhostComponent.cs | 10 ++--- Content.Server/Observer/Ghost.cs | 2 + .../Observer/SharedGhostComponent.cs | 3 +- .../Prototypes/Entities/mobs/observer.yml | 4 ++ 9 files changed, 57 insertions(+), 16 deletions(-) rename Content.Client/{ => GameObjects/Components}/Observer/GhostComponent.cs (62%) rename Content.Server/{ => GameObjects/Components}/Observer/GhostComponent.cs (90%) rename Content.Shared/{ => GameObjects/Components}/Observer/SharedGhostComponent.cs (92%) 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 From 612790840c27307c262117ebbb8c854f7ec24fcc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Aguilera=20Puerto?= <6766154+Zumorica@users.noreply.github.com> Date: Thu, 9 Apr 2020 02:59:20 +0200 Subject: [PATCH 10/14] Update Content.Client/GameObjects/Components/Observer/GhostComponent.cs Co-Authored-By: Pieter-Jan Briers --- .../GameObjects/Components/Observer/GhostComponent.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/Content.Client/GameObjects/Components/Observer/GhostComponent.cs b/Content.Client/GameObjects/Components/Observer/GhostComponent.cs index c71310845a..244dd7a5d6 100644 --- a/Content.Client/GameObjects/Components/Observer/GhostComponent.cs +++ b/Content.Client/GameObjects/Components/Observer/GhostComponent.cs @@ -69,7 +69,7 @@ namespace Content.Client.GameObjects.Components.Observer } else { - _gui.Parent?.RemoveChild(_gui); + _gui.Orphan(); } _gameHud.HandsContainer.AddChild(_gui); From c0bdfdf123294970f02b3e38746cca51fa10a2d0 Mon Sep 17 00:00:00 2001 From: zumorica Date: Thu, 9 Apr 2020 03:01:56 +0200 Subject: [PATCH 11/14] Remove CanReturnToBody property from SharedGhostComponent --- .../GameObjects/Components/Observer/GhostComponent.cs | 9 ++------- .../GameObjects/Components/Observer/GhostComponent.cs | 2 +- .../Components/Observer/SharedGhostComponent.cs | 2 -- 3 files changed, 3 insertions(+), 10 deletions(-) diff --git a/Content.Client/GameObjects/Components/Observer/GhostComponent.cs b/Content.Client/GameObjects/Components/Observer/GhostComponent.cs index 244dd7a5d6..67b81a6345 100644 --- a/Content.Client/GameObjects/Components/Observer/GhostComponent.cs +++ b/Content.Client/GameObjects/Components/Observer/GhostComponent.cs @@ -14,14 +14,9 @@ namespace Content.Client.GameObjects.Components.Observer public class GhostComponent : SharedGhostComponent { private GhostGui _gui; - private bool _canReturnToBody = true; [ViewVariables(VVAccess.ReadOnly)] - public override bool CanReturnToBody - { - get => _canReturnToBody; - set {} - } + public bool CanReturnToBody { get; private set; } = true; #pragma warning disable 649 [Dependency] private readonly IGameHud _gameHud; @@ -92,7 +87,7 @@ namespace Content.Client.GameObjects.Components.Observer if (!(curState is GhostComponentState state)) return; - _canReturnToBody = state.CanReturnToBody; + CanReturnToBody = state.CanReturnToBody; if (Owner == _playerManager.LocalPlayer.ControlledEntity) { diff --git a/Content.Server/GameObjects/Components/Observer/GhostComponent.cs b/Content.Server/GameObjects/Components/Observer/GhostComponent.cs index 11eb1d40db..4853900fed 100644 --- a/Content.Server/GameObjects/Components/Observer/GhostComponent.cs +++ b/Content.Server/GameObjects/Components/Observer/GhostComponent.cs @@ -18,7 +18,7 @@ namespace Content.Server.GameObjects.Components.Observer private bool _canReturnToBody = true; [ViewVariables(VVAccess.ReadWrite)] - public override bool CanReturnToBody + public bool CanReturnToBody { get => _canReturnToBody; set diff --git a/Content.Shared/GameObjects/Components/Observer/SharedGhostComponent.cs b/Content.Shared/GameObjects/Components/Observer/SharedGhostComponent.cs index f7a302bcba..b838c3b63e 100644 --- a/Content.Shared/GameObjects/Components/Observer/SharedGhostComponent.cs +++ b/Content.Shared/GameObjects/Components/Observer/SharedGhostComponent.cs @@ -8,8 +8,6 @@ namespace Content.Shared.GameObjects.Components.Observer { public override string Name => "Ghost"; public override uint? NetID => ContentNetIDs.GHOST; - - public virtual bool CanReturnToBody { get; set; } = true; } [Serializable, NetSerializable] From 50273679885d36b577c82272d245e8193413ce46 Mon Sep 17 00:00:00 2001 From: zumorica Date: Thu, 9 Apr 2020 03:08:06 +0200 Subject: [PATCH 12/14] Add localization to deadchat --- Content.Server/Chat/ChatManager.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/Content.Server/Chat/ChatManager.cs b/Content.Server/Chat/ChatManager.cs index ebd06862ee..12d8f27efa 100644 --- a/Content.Server/Chat/ChatManager.cs +++ b/Content.Server/Chat/ChatManager.cs @@ -9,6 +9,7 @@ using Robust.Server.Interfaces.Player; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; +using Robust.Shared.Localization; namespace Content.Server.Chat { @@ -22,6 +23,7 @@ namespace Content.Server.Chat #pragma warning disable 649 [Dependency] private readonly IServerNetManager _netManager; [Dependency] private readonly IPlayerManager _playerManager; + [Dependency] private readonly ILocalizationManager _localizationManager; [Dependency] private readonly IMoMMILink _mommiLink; #pragma warning restore 649 @@ -102,7 +104,7 @@ namespace Content.Server.Chat var msg = _netManager.CreateNetMessage(); msg.Channel = ChatChannel.Dead; msg.Message = message; - msg.MessageWrap = $"DEAD: {player.AttachedEntity.Name}: {{0}}"; + msg.MessageWrap = $"{_localizationManager.GetString("DEAD")}: {player.AttachedEntity.Name}: {{0}}"; _netManager.ServerSendToMany(msg, clients.ToList()); } From 3ba2e5de807252713d28a01faf9114d71eb36363 Mon Sep 17 00:00:00 2001 From: zumorica Date: Thu, 9 Apr 2020 03:31:40 +0200 Subject: [PATCH 13/14] Speech bubbles! --- Content.Client/Chat/ChatManager.cs | 2 +- Content.Server/Chat/ChatManager.cs | 3 +++ Content.Shared/Chat/MsgChatMessage.cs | 4 +++- 3 files changed, 7 insertions(+), 2 deletions(-) diff --git a/Content.Client/Chat/ChatManager.cs b/Content.Client/Chat/ChatManager.cs index a2a3e04ae7..dd8f437142 100644 --- a/Content.Client/Chat/ChatManager.cs +++ b/Content.Client/Chat/ChatManager.cs @@ -288,7 +288,7 @@ namespace Content.Client.Chat WriteChatMessage(storedMessage); // Local messages that have an entity attached get a speech bubble. - if (msg.Channel == ChatChannel.Local && msg.SenderEntity != default) + if ((msg.Channel == ChatChannel.Local || msg.Channel == ChatChannel.Dead) && msg.SenderEntity != default) { AddSpeechBubble(msg); } diff --git a/Content.Server/Chat/ChatManager.cs b/Content.Server/Chat/ChatManager.cs index 12d8f27efa..f4f3df49e0 100644 --- a/Content.Server/Chat/ChatManager.cs +++ b/Content.Server/Chat/ChatManager.cs @@ -4,12 +4,14 @@ using Content.Server.GameObjects.EntitySystems; using Content.Server.Interfaces; using Content.Server.Interfaces.Chat; using Content.Server.Observer; +using Content.Server.Players; using Content.Shared.Chat; using Robust.Server.Interfaces.Player; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Interfaces.Network; using Robust.Shared.IoC; using Robust.Shared.Localization; +using Robust.Shared.Log; namespace Content.Server.Chat { @@ -105,6 +107,7 @@ namespace Content.Server.Chat msg.Channel = ChatChannel.Dead; msg.Message = message; msg.MessageWrap = $"{_localizationManager.GetString("DEAD")}: {player.AttachedEntity.Name}: {{0}}"; + msg.SenderEntity = player.AttachedEntityUid.GetValueOrDefault(); _netManager.ServerSendToMany(msg, clients.ToList()); } diff --git a/Content.Shared/Chat/MsgChatMessage.cs b/Content.Shared/Chat/MsgChatMessage.cs index de2a5f980c..10e73d881e 100644 --- a/Content.Shared/Chat/MsgChatMessage.cs +++ b/Content.Shared/Chat/MsgChatMessage.cs @@ -35,7 +35,7 @@ namespace Content.Shared.Chat /// /// The sending entity. - /// Only applies to and . + /// Only applies to , and . /// public EntityUid SenderEntity { get; set; } @@ -48,6 +48,7 @@ namespace Content.Shared.Chat switch (Channel) { case ChatChannel.Local: + case ChatChannel.Dead: case ChatChannel.Emotes: SenderEntity = buffer.ReadEntityUid(); break; @@ -63,6 +64,7 @@ namespace Content.Shared.Chat switch (Channel) { case ChatChannel.Local: + case ChatChannel.Dead: case ChatChannel.Emotes: buffer.Write(SenderEntity); break; From a6e6edab0ef2aa882d9c6725de3849969c3f7f00 Mon Sep 17 00:00:00 2001 From: Pieter-Jan Briers Date: Thu, 9 Apr 2020 16:57:10 +0200 Subject: [PATCH 14/14] Update submodule --- RobustToolbox | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/RobustToolbox b/RobustToolbox index ec52102d02..1cdb279319 160000 --- a/RobustToolbox +++ b/RobustToolbox @@ -1 +1 @@ -Subproject commit ec52102d0279281a00cc1c6811330a13ddaf975b +Subproject commit 1cdb279319bdb16efdc9671d0d4e0e5947b0493f