From 52e98e29d7d54ae985436723b7342af320ea53ca Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?V=C3=ADctor=20Aguilera=20Puerto?= Date: Sun, 30 Aug 2020 15:00:40 +0200 Subject: [PATCH] Support for non-fulltile firelocks! --- .../Atmos/IGridAtmosphereComponent.cs | 10 +- Content.Server/Atmos/TileAtmosphere.cs | 2 +- .../Components/Atmos/AirtightComponent.cs | 47 +++++--- .../Atmos/GridAtmosphereComponent.cs | 102 +++++++++--------- Content.Shared/Atmos/AtmosDirection.cs | 8 +- 5 files changed, 95 insertions(+), 74 deletions(-) diff --git a/Content.Server/Atmos/IGridAtmosphereComponent.cs b/Content.Server/Atmos/IGridAtmosphereComponent.cs index 8060276652..20707b9b77 100644 --- a/Content.Server/Atmos/IGridAtmosphereComponent.cs +++ b/Content.Server/Atmos/IGridAtmosphereComponent.cs @@ -1,4 +1,5 @@ using System.Collections.Generic; +using Content.Server.GameObjects.Components.Atmos; using Content.Server.GameObjects.Components.Atmos.Piping; using Content.Server.GameObjects.Components.NodeContainer.NodeGroups; using Content.Shared.Atmos; @@ -48,7 +49,7 @@ namespace Content.Server.Atmos /// Revalidates indices immediately. /// /// - void Revalidate(MapIndices indices); + void UpdateAdjacentBits(MapIndices indices); /// /// Adds an active tile so it becomes processed every update until it becomes inactive. @@ -117,6 +118,7 @@ namespace Content.Server.Atmos /// Returns a tile. /// /// + /// /// TileAtmosphere GetTile(MapIndices indices, bool createSpace = true); @@ -124,17 +126,19 @@ namespace Content.Server.Atmos /// Returns a tile. /// /// + /// /// TileAtmosphere GetTile(GridCoordinates coordinates, bool createSpace = true); /// /// Returns if the tile in question is air-blocked. /// This could be due to a wall, an airlock, etc. - /// Also see AirtightComponent. + /// /// /// + /// /// - bool IsAirBlocked(MapIndices indices); + bool IsAirBlocked(MapIndices indices, AtmosDirection direction); /// /// Returns if the tile in question is space. diff --git a/Content.Server/Atmos/TileAtmosphere.cs b/Content.Server/Atmos/TileAtmosphere.cs index 8091830976..0a09904f53 100644 --- a/Content.Server/Atmos/TileAtmosphere.cs +++ b/Content.Server/Atmos/TileAtmosphere.cs @@ -1122,7 +1122,7 @@ namespace Content.Server.Atmos _adjacentTiles[direction.ToIndex()] = adjacent; adjacent?.UpdateAdjacent(direction.GetOpposite()); - if (adjacent != null && !_gridAtmosphereComponent.IsAirBlocked(adjacent.GridIndices)) + if (adjacent != null && !_gridAtmosphereComponent.IsAirBlocked(adjacent.GridIndices, direction.GetOpposite())) { _adjacentBits |= direction; } diff --git a/Content.Server/GameObjects/Components/Atmos/AirtightComponent.cs b/Content.Server/GameObjects/Components/Atmos/AirtightComponent.cs index e4085a66af..cecd58aae1 100644 --- a/Content.Server/GameObjects/Components/Atmos/AirtightComponent.cs +++ b/Content.Server/GameObjects/Components/Atmos/AirtightComponent.cs @@ -1,5 +1,6 @@ #nullable enable using Content.Server.GameObjects.EntitySystems; +using Content.Shared.Atmos; using Robust.Server.Interfaces.GameObjects; using Robust.Shared.GameObjects; using Robust.Shared.GameObjects.Components.Transform; @@ -22,6 +23,8 @@ namespace Content.Server.GameObjects.Components.Atmos public override string Name => "Airtight"; + [ViewVariables] + private int _airBlockedDirection; private bool _airBlocked = true; private bool _fixVacuum = false; @@ -33,10 +36,18 @@ namespace Content.Server.GameObjects.Components.Atmos { _airBlocked = value; - if (Owner.TryGetComponent(out SnapGridComponent? snapGrid)) - { - EntitySystem.Get().GetGridAtmosphere(Owner.Transform.GridID)?.Revalidate(snapGrid.Position); - } + UpdatePosition(); + } + } + + public AtmosDirection AirBlockedDirection + { + get => (AtmosDirection)_airBlockedDirection; + set + { + _airBlockedDirection = (int) value; + + UpdatePosition(); } } @@ -49,16 +60,16 @@ namespace Content.Server.GameObjects.Components.Atmos serializer.DataField(ref _airBlocked, "airBlocked", true); serializer.DataField(ref _fixVacuum, "fixVacuum", true); + serializer.DataField(ref _airBlockedDirection, "airBlockedDirection", (int)AtmosDirection.All, WithFormat.Flags()); } public override void Initialize() { base.Initialize(); - // Using the SnapGrid is critical for the performance of the room builder, and thus if - // it is absent the component will not be airtight. A warning is much easier to track - // down than the object magically not being airtight, so log one if the SnapGrid component - // is missing. + // Using the SnapGrid is critical for performance, and thus if it is absent the component + // will not be airtight. A warning is much easier to track down than the object magically + // not being airtight, so log one if the SnapGrid component is missing. if (!Owner.EnsureComponent(out SnapGridComponent _)) Logger.Warning($"Entity {Owner} at {Owner.Transform.MapPosition.ToString()} didn't have a {nameof(SnapGridComponent)}"); @@ -87,13 +98,10 @@ namespace Content.Server.GameObjects.Components.Atmos snapGrid.OnPositionChanged -= OnTransformMove; } - if (_fixVacuum) - { - var mapIndices = Owner.Transform.GridPosition.ToMapIndices(_mapManager); - EntitySystem.Get().GetGridAtmosphere(Owner.Transform.GridID)?.FixVacuum(mapIndices); - } + UpdatePosition(_lastPosition.Item1, _lastPosition.Item2); - UpdatePosition(); + if (_fixVacuum) + EntitySystem.Get().GetGridAtmosphere(_lastPosition.Item1)?.FixVacuum(_lastPosition.Item2); } private void OnTransformMove() @@ -109,13 +117,18 @@ namespace Content.Server.GameObjects.Components.Atmos private void UpdatePosition() { - var mapIndices = Owner.Transform.GridPosition.ToMapIndices(_mapManager); - UpdatePosition(Owner.Transform.GridID, mapIndices); + if (Owner.TryGetComponent(out SnapGridComponent? snapGrid)) + UpdatePosition(Owner.Transform.GridID, snapGrid.Position); } private void UpdatePosition(GridId gridId, MapIndices pos) { - EntitySystem.Get().GetGridAtmosphere(gridId)?.Invalidate(pos); + var gridAtmos = EntitySystem.Get().GetGridAtmosphere(gridId); + + if (gridAtmos == null) return; + + gridAtmos.UpdateAdjacentBits(pos); + gridAtmos.Invalidate(pos); } } } diff --git a/Content.Server/GameObjects/Components/Atmos/GridAtmosphereComponent.cs b/Content.Server/GameObjects/Components/Atmos/GridAtmosphereComponent.cs index a1186c9bd2..0b94087cd9 100644 --- a/Content.Server/GameObjects/Components/Atmos/GridAtmosphereComponent.cs +++ b/Content.Server/GameObjects/Components/Atmos/GridAtmosphereComponent.cs @@ -210,64 +210,64 @@ namespace Content.Server.GameObjects.Components.Atmos private void Revalidate() { + if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return; + foreach (var indices in _invalidatedCoords.ToArray()) { - Revalidate(indices); + var tile = GetTile(indices); + + if (tile == null) + { + tile = new TileAtmosphere(this, mapGrid.Grid.Index, indices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C}); + _tiles[indices] = tile; + } + + if (IsSpace(indices)) + { + tile.Air = new GasMixture(GetVolumeForCells(1)); + tile.Air.MarkImmutable(); + _tiles[indices] = tile; + + } else if (IsAirBlocked(indices)) + { + tile.Air = null; + } + else + { + var obs = GetObstructingComponent(indices); + + if (obs != null) + { + if (tile.Air == null && obs.FixVacuum) + { + FixVacuum(tile.GridIndices); + } + } + + tile.Air ??= new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C}; + } + + AddActiveTile(tile); + tile.UpdateAdjacent(); + tile.UpdateVisuals(); + + for (var i = 0; i < Atmospherics.Directions; i++) + { + var direction = (AtmosDirection) (1 << i); + var otherIndices = indices.Offset(direction.ToDirection()); + var otherTile = GetTile(otherIndices); + AddActiveTile(otherTile); + otherTile?.UpdateAdjacent(direction.GetOpposite()); + } } _invalidatedCoords.Clear(); } [MethodImpl(MethodImplOptions.AggressiveInlining)] - public void Revalidate(MapIndices indices) + public void UpdateAdjacentBits(MapIndices indices) { - if (!Owner.TryGetComponent(out IMapGridComponent? mapGrid)) return; - - var tile = GetTile(indices); - - if (tile == null) - { - tile = new TileAtmosphere(this, mapGrid.Grid.Index, indices, new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C}); - _tiles[indices] = tile; - } - - if (IsSpace(indices)) - { - tile.Air = new GasMixture(GetVolumeForCells(1)); - tile.Air.MarkImmutable(); - _tiles[indices] = tile; - - } else if (IsAirBlocked(indices)) - { - tile.Air = null; - } - else - { - var obs = GetObstructingComponent(indices); - - if (obs != null) - { - if (tile.Air == null && obs.FixVacuum) - { - FixVacuum(tile.GridIndices); - } - } - - tile.Air ??= new GasMixture(GetVolumeForCells(1)){Temperature = Atmospherics.T20C}; - } - - AddActiveTile(tile); - tile.UpdateAdjacent(); - tile.UpdateVisuals(); - - for (var i = 0; i < Atmospherics.Directions; i++) - { - var direction = (AtmosDirection) (1 << i); - var otherIndices = indices.Offset(direction.ToDirection()); - var otherTile = GetTile(otherIndices); - AddActiveTile(otherTile); - otherTile?.UpdateAdjacent(direction.GetOpposite()); - } + GetTile(indices)?.UpdateAdjacent(); } /// @@ -413,10 +413,10 @@ namespace Content.Server.GameObjects.Components.Atmos } /// - public bool IsAirBlocked(MapIndices indices) + public bool IsAirBlocked(MapIndices indices, AtmosDirection direction = AtmosDirection.All) { var ac = GetObstructingComponent(indices); - return ac != null && ac.AirBlocked; + return ac != null && ac.AirBlocked && ac.AirBlockedDirection.HasFlag(direction); } /// diff --git a/Content.Shared/Atmos/AtmosDirection.cs b/Content.Shared/Atmos/AtmosDirection.cs index 450a92e4df..2b46faad18 100644 --- a/Content.Shared/Atmos/AtmosDirection.cs +++ b/Content.Shared/Atmos/AtmosDirection.cs @@ -1,13 +1,15 @@ using System; using Robust.Shared.Maths; +using Robust.Shared.Serialization; namespace Content.Shared.Atmos { /// /// The reason we use this over is that we are going to do some heavy bitflag usage. /// - [Flags] - public enum AtmosDirection : byte + [Flags, Serializable] + [FlagsFor(typeof(AtmosDirectionFlags))] + public enum AtmosDirection { Invalid = 0, North = 1 << 0, @@ -86,4 +88,6 @@ namespace Content.Shared.Atmos return direction | other; } } + + public sealed class AtmosDirectionFlags { } }