From 7f19381bec2225d3ee0a89147bdf904da9e59dcf Mon Sep 17 00:00:00 2001 From: zumorica Date: Tue, 3 Mar 2020 20:37:26 +0100 Subject: [PATCH] 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