From 0d3498e8d9d98e614329dc4c1dde02779b776c83 Mon Sep 17 00:00:00 2001 From: Moony Date: Mon, 7 Mar 2022 06:09:54 -0600 Subject: [PATCH] Makes grids that pass a certain size airtight. (#6934) Co-authored-by: metalgearsloth --- .../EntitySystems/AutomaticAtmosSystem.cs | 52 +++++++++++++++++++ .../Shuttles/EntitySystems/ShuttleSystem.cs | 2 +- 2 files changed, 53 insertions(+), 1 deletion(-) create mode 100644 Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs diff --git a/Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs b/Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs new file mode 100644 index 0000000000..b8836da618 --- /dev/null +++ b/Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs @@ -0,0 +1,52 @@ +using Content.Server.Atmos.Components; +using Content.Server.Shuttles.EntitySystems; +using Content.Shared.Maps; +using Robust.Shared.Map; + +namespace Content.Server.Atmos.EntitySystems; + +/// +/// Handles automatically adding a grid atmosphere to grids that become large enough, allowing players to build shuttles +/// with a sealed atmosphere from scratch. +/// +public sealed class AutomaticAtmosSystem : EntitySystem +{ + [Dependency] private readonly IMapManager _mapManager = default!; + [Dependency] private readonly ITileDefinitionManager _tileDefinitionManager = default!; + + public override void Initialize() + { + base.Initialize(); + _mapManager.TileChanged += MapManagerOnTileChanged; + } + + public override void Shutdown() + { + base.Shutdown(); + _mapManager.TileChanged -= MapManagerOnTileChanged; + } + + private void MapManagerOnTileChanged(object? sender, TileChangedEventArgs e) + { + // Only if a atmos-holding tile has been added or removed. + // Also, these calls are surprisingly slow. + // TODO: Make tiledefmanager cache the IsSpace property, and turn this lookup-through-two-interfaces into + // TODO: a simple array lookup, as tile IDs are likely contiguous, and there's at most 2^16 possibilities anyway. + if (!((e.OldTile.IsSpace(_tileDefinitionManager) && !e.NewTile.IsSpace(_tileDefinitionManager)) || + (!e.OldTile.IsSpace(_tileDefinitionManager) && e.NewTile.IsSpace(_tileDefinitionManager)))) + return; + + var uid = _mapManager.GetGridEuid(e.NewTile.GridIndex); + if (!TryComp(uid, out var physics)) + return; + + // We can't actually count how many tiles there are efficiently, so instead estimate with the mass. + if (physics.Mass / ShuttleSystem.TileMassMultiplier >= 7.0f && !HasComp(uid)) + { + AddComp(uid); + Logger.InfoS("atmos", $"Giving grid {uid} GridAtmosphereComponent."); + } + // It's not super important to remove it should the grid become too small again. + // If explosions ever gain the ability to outright shatter grids, do rethink this. + } +} diff --git a/Content.Server/Shuttles/EntitySystems/ShuttleSystem.cs b/Content.Server/Shuttles/EntitySystems/ShuttleSystem.cs index 005dc4c4ca..ca16f8a1ba 100644 --- a/Content.Server/Shuttles/EntitySystems/ShuttleSystem.cs +++ b/Content.Server/Shuttles/EntitySystems/ShuttleSystem.cs @@ -12,7 +12,7 @@ namespace Content.Server.Shuttles.EntitySystems [UsedImplicitly] internal sealed class ShuttleSystem : EntitySystem { - private const float TileMassMultiplier = 4f; + public const float TileMassMultiplier = 4f; public float ShuttleMaxLinearSpeed;