diff --git a/Content.Server/Atmos/TileAtmosphere.cs b/Content.Server/Atmos/TileAtmosphere.cs index 69cba419e3..eaebbd2f7e 100644 --- a/Content.Server/Atmos/TileAtmosphere.cs +++ b/Content.Server/Atmos/TileAtmosphere.cs @@ -197,7 +197,7 @@ namespace Content.Server.Atmos foreach (var entity in _gridTileLookupSystem.GetEntitiesIntersecting(GridIndex, GridIndices)) { if (!entity.TryGetComponent(out IPhysicsComponent physics) - || !entity.TryGetComponent(out MovedByPressureComponent pressure) + || !entity.IsMovedByPressure(out var pressure) || entity.IsInContainer()) continue; diff --git a/Content.Server/GameObjects/Components/Atmos/MovedByPressureComponent.cs b/Content.Server/GameObjects/Components/Atmos/MovedByPressureComponent.cs index 851f281a58..8e840ce03e 100644 --- a/Content.Server/GameObjects/Components/Atmos/MovedByPressureComponent.cs +++ b/Content.Server/GameObjects/Components/Atmos/MovedByPressureComponent.cs @@ -1,4 +1,7 @@ -using Robust.Shared.GameObjects; +#nullable enable +using System.Diagnostics.CodeAnalysis; +using Robust.Shared.GameObjects; +using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.Serialization; using Robust.Shared.ViewVariables; @@ -9,6 +12,8 @@ namespace Content.Server.GameObjects.Components.Atmos { public override string Name => "MovedByPressure"; + [ViewVariables(VVAccess.ReadWrite)] + public bool Enabled { get; set; } = true; [ViewVariables(VVAccess.ReadWrite)] public float PressureResistance { get; set; } = 1f; [ViewVariables(VVAccess.ReadWrite)] @@ -19,8 +24,23 @@ namespace Content.Server.GameObjects.Components.Atmos public override void ExposeData(ObjectSerializer serializer) { base.ExposeData(serializer); + serializer.DataField(this, x => x.Enabled, "enabled", true); serializer.DataField(this, x => PressureResistance, "pressureResistance", 1f); serializer.DataField(this, x => MoveResist, "moveResist", 100f); } } + + public static class MovedByPressureExtensions + { + public static bool IsMovedByPressure(this IEntity entity) + { + return entity.IsMovedByPressure(out _); + } + + public static bool IsMovedByPressure(this IEntity entity, [NotNullWhen(true)] out MovedByPressureComponent? moved) + { + return entity.TryGetComponent(out moved) && + moved.Enabled; + } + } } diff --git a/Content.Server/GameObjects/Components/Damage/DamageCommands.cs b/Content.Server/GameObjects/Components/Damage/DamageCommands.cs index e90fc5d294..820c858db5 100644 --- a/Content.Server/GameObjects/Components/Damage/DamageCommands.cs +++ b/Content.Server/GameObjects/Components/Damage/DamageCommands.cs @@ -2,12 +2,13 @@ using System; using System.Diagnostics.CodeAnalysis; using Content.Server.Administration; -using Content.Server.GameObjects.Components.Atmos; +using Content.Server.GameObjects.EntitySystems; using Content.Shared.Administration; using Content.Shared.GameObjects.Components.Damage; using Robust.Server.Interfaces.Console; using Robust.Server.Interfaces.Player; using Robust.Shared.GameObjects; +using Robust.Shared.GameObjects.Systems; using Robust.Shared.Interfaces.GameObjects; using Robust.Shared.IoC; @@ -204,17 +205,12 @@ namespace Content.Server.GameObjects.Components.Damage return; } - if (entity.HasComponent()) - { - entity.RemoveComponent(); - } + var godmodeSystem = EntitySystem.Get(); + var enabled = godmodeSystem.ToggleGodmode(entity); - if (entity.TryGetComponent(out IDamageableComponent? damageable)) - { - damageable.AddFlag(DamageFlag.Invulnerable); - } - - shell.SendText(player, $"Enabled godmode for entity {entity.Name}"); + shell.SendText(player, enabled + ? $"Enabled godmode for entity {entity.Name} with id {entity.Uid}" + : $"Disabled godmode for entity {entity.Name} with id {entity.Uid}"); } } } diff --git a/Content.Server/GameObjects/EntitySystems/GodmodeSystem.cs b/Content.Server/GameObjects/EntitySystems/GodmodeSystem.cs new file mode 100644 index 0000000000..b2495f7627 --- /dev/null +++ b/Content.Server/GameObjects/EntitySystems/GodmodeSystem.cs @@ -0,0 +1,100 @@ +#nullable enable +using System.Collections.Generic; +using Content.Server.GameObjects.Components.Atmos; +using Content.Shared.GameObjects.Components.Damage; +using Content.Shared.GameTicking; +using JetBrains.Annotations; +using Robust.Shared.GameObjects.Systems; +using Robust.Shared.Interfaces.GameObjects; + +namespace Content.Server.GameObjects.EntitySystems +{ + [UsedImplicitly] + public class GodmodeSystem : EntitySystem, IResettingEntitySystem + { + private readonly Dictionary _entities = new Dictionary(); + + public void Reset() + { + _entities.Clear(); + } + + public bool EnableGodmode(IEntity entity) + { + if (_entities.ContainsKey(entity)) + { + return false; + } + + _entities[entity] = new OldEntityInformation(entity); + + if (entity.TryGetComponent(out MovedByPressureComponent? moved)) + { + moved.Enabled = false; + } + + if (entity.TryGetComponent(out IDamageableComponent? damageable)) + { + damageable.AddFlag(DamageFlag.Invulnerable); + } + + return true; + } + + public bool HasGodmode(IEntity entity) + { + return _entities.ContainsKey(entity); + } + + public bool DisableGodmode(IEntity entity) + { + if (!_entities.Remove(entity, out var old)) + { + return false; + } + + if (entity.TryGetComponent(out MovedByPressureComponent? moved)) + { + moved.Enabled = old.MovedByPressure; + } + + if (entity.TryGetComponent(out IDamageableComponent? damageable)) + { + damageable.RemoveFlag(DamageFlag.Invulnerable); + } + + return true; + } + + /// + /// Toggles godmode for a given entity. + /// + /// The entity to toggle godmode for. + /// true if enabled, false if disabled. + public bool ToggleGodmode(IEntity entity) + { + if (HasGodmode(entity)) + { + DisableGodmode(entity); + return false; + } + else + { + EnableGodmode(entity); + return true; + } + } + + public class OldEntityInformation + { + public OldEntityInformation(IEntity entity) + { + Entity = entity; + MovedByPressure = entity.IsMovedByPressure(); + } + + public IEntity Entity { get; } + public bool MovedByPressure { get; } + } + } +}