diff --git a/Content.Server/Atmos/Components/GridAtmosphereComponent.cs b/Content.Server/Atmos/Components/GridAtmosphereComponent.cs index 76840c37c2..ad548f1b9d 100644 --- a/Content.Server/Atmos/Components/GridAtmosphereComponent.cs +++ b/Content.Server/Atmos/Components/GridAtmosphereComponent.cs @@ -24,9 +24,6 @@ namespace Content.Server.Atmos.Components public virtual bool Simulated => true; - [ViewVariables] - public bool RevalidatePaused { get; set; } = false; - [ViewVariables] public bool ProcessingPaused { get; set; } = false; diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Grid.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Grid.cs index fa31bd8fc8..24cef3fa78 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Grid.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Grid.cs @@ -217,113 +217,6 @@ namespace Content.Server.Atmos.EntitySystems #endregion - #region Grid Revalidate - - /// - /// Revalidates all invalid coordinates in a grid atmosphere. - /// - /// The grid in question. - /// The grid atmosphere in question. - /// Whether the process succeeded or got paused due to time constrains. - private bool GridRevalidate(IMapGrid mapGrid, GridAtmosphereComponent gridAtmosphere) - { - var volume = GetVolumeForTiles(mapGrid, 1); - - if (!gridAtmosphere.RevalidatePaused) - gridAtmosphere.CurrentRunInvalidatedCoordinates = new Queue(gridAtmosphere.InvalidatedCoords); - - gridAtmosphere.InvalidatedCoords.Clear(); - - var number = 0; - while (gridAtmosphere.CurrentRunInvalidatedCoordinates.TryDequeue(out var indices)) - { - var tile = GetTileAtmosphere(gridAtmosphere, indices); - - if (tile == null) - { - tile = new TileAtmosphere(mapGrid.Index, indices, new GasMixture(volume){Temperature = Atmospherics.T20C}); - gridAtmosphere.Tiles[indices] = tile; - } - - var isAirBlocked = IsTileAirBlocked(mapGrid, indices); - - tile.BlockedAirflow = GetBlockedDirections(mapGrid, indices); - UpdateAdjacent(mapGrid, gridAtmosphere, tile); - - if (IsTileSpace(mapGrid, indices) && !isAirBlocked) - { - tile.Air = new GasMixture(volume); - tile.Air.MarkImmutable(); - gridAtmosphere.Tiles[indices] = tile; - - } else if (isAirBlocked) - { - var nullAir = false; - - foreach (var airtight in GetObstructingComponents(mapGrid, indices)) - { - if (!airtight.NoAirWhenFullyAirBlocked) - continue; - - nullAir = true; - break; - } - - if (nullAir) - { - tile.Air = null; - tile.Hotspot = new Hotspot(); - } - } - else - { - if (tile.Air == null && NeedsVacuumFixing(mapGrid, indices)) - { - FixVacuum(gridAtmosphere, tile.GridIndices); - } - - // Tile used to be space, but isn't anymore. - if (tile.Air?.Immutable ?? false) - { - tile.Air = null; - } - - tile.Air ??= new GasMixture(volume){Temperature = Atmospherics.T20C}; - } - - // By removing the active tile, we effectively remove its excited group, if any. - RemoveActiveTile(gridAtmosphere, tile); - - // Then we activate the tile again. - AddActiveTile(gridAtmosphere, tile); - - // TODO ATMOS: Query all the contents of this tile (like walls) and calculate the correct thermal conductivity - tile.ThermalConductivity = tile.Tile?.Tile.GetContentTileDefinition().ThermalConductivity ?? 0.5f; - InvalidateVisuals(mapGrid.Index, indices); - - for (var i = 0; i < Atmospherics.Directions; i++) - { - var direction = (AtmosDirection) (1 << i); - var otherIndices = indices.Offset(direction); - var otherTile = GetTileAtmosphere(gridAtmosphere, otherIndices); - if (otherTile != null) - AddActiveTile(gridAtmosphere, otherTile); - } - - if (number++ < InvalidCoordinatesLagCheckIterations) continue; - number = 0; - // Process the rest next time. - if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime) - { - return false; - } - } - - return true; - } - - #endregion - #region Grid Repopulate /// diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs index 9de6cbcc9a..86d981b33b 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.Processing.cs @@ -4,8 +4,10 @@ using Content.Server.Atmos.Components; using Content.Server.Atmos.Piping.Components; using Content.Server.NodeContainer.NodeGroups; using Content.Shared.Atmos; +using Content.Shared.Maps; using Robust.Shared.GameObjects; using Robust.Shared.IoC; +using Robust.Shared.Maths; using Robust.Shared.Timing; namespace Content.Server.Atmos.EntitySystems @@ -32,6 +34,112 @@ namespace Content.Server.Atmos.EntitySystems private readonly List _currentRunAtmosphere = new(); + /// + /// Revalidates all invalid coordinates in a grid atmosphere. + /// + /// The grid atmosphere in question. + /// Whether the process succeeded or got paused due to time constrains. + private bool ProcessRevalidate(GridAtmosphereComponent atmosphere) + { + if (!atmosphere.ProcessingPaused) + { + atmosphere.CurrentRunInvalidatedCoordinates = new Queue(atmosphere.InvalidatedCoords); + atmosphere.InvalidatedCoords.Clear(); + } + + if (!TryGetMapGrid(atmosphere, out var mapGrid)) + return true; + + var volume = GetVolumeForTiles(mapGrid, 1); + + var number = 0; + while (atmosphere.CurrentRunInvalidatedCoordinates.TryDequeue(out var indices)) + { + var tile = GetTileAtmosphere(atmosphere, indices); + + if (tile == null) + { + tile = new TileAtmosphere(mapGrid.Index, indices, new GasMixture(volume){Temperature = Atmospherics.T20C}); + atmosphere.Tiles[indices] = tile; + } + + var isAirBlocked = IsTileAirBlocked(mapGrid, indices); + + tile.BlockedAirflow = GetBlockedDirections(mapGrid, indices); + UpdateAdjacent(mapGrid, atmosphere, tile); + + if (IsTileSpace(mapGrid, indices) && !isAirBlocked) + { + tile.Air = new GasMixture(volume); + tile.Air.MarkImmutable(); + atmosphere.Tiles[indices] = tile; + + } else if (isAirBlocked) + { + var nullAir = false; + + foreach (var airtight in GetObstructingComponents(mapGrid, indices)) + { + if (!airtight.NoAirWhenFullyAirBlocked) + continue; + + nullAir = true; + break; + } + + if (nullAir) + { + tile.Air = null; + tile.Hotspot = new Hotspot(); + } + } + else + { + if (tile.Air == null && NeedsVacuumFixing(mapGrid, indices)) + { + FixVacuum(atmosphere, tile.GridIndices); + } + + // Tile used to be space, but isn't anymore. + if (tile.Air?.Immutable ?? false) + { + tile.Air = null; + } + + tile.Air ??= new GasMixture(volume){Temperature = Atmospherics.T20C}; + } + + // By removing the active tile, we effectively remove its excited group, if any. + RemoveActiveTile(atmosphere, tile); + + // Then we activate the tile again. + AddActiveTile(atmosphere, tile); + + // TODO ATMOS: Query all the contents of this tile (like walls) and calculate the correct thermal conductivity + tile.ThermalConductivity = tile.Tile?.Tile.GetContentTileDefinition().ThermalConductivity ?? 0.5f; + InvalidateVisuals(mapGrid.Index, indices); + + for (var i = 0; i < Atmospherics.Directions; i++) + { + var direction = (AtmosDirection) (1 << i); + var otherIndices = indices.Offset(direction); + var otherTile = GetTileAtmosphere(atmosphere, otherIndices); + if (otherTile != null) + AddActiveTile(atmosphere, otherTile); + } + + if (number++ < InvalidCoordinatesLagCheckIterations) continue; + number = 0; + // Process the rest next time. + if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime) + { + return false; + } + } + + return true; + } + private bool ProcessTileEqualize(GridAtmosphereComponent atmosphere) { if(!atmosphere.ProcessingPaused) @@ -246,15 +354,6 @@ namespace Content.Server.Atmos.EntitySystems atmosphere.Timer += frameTime; - if ((atmosphere.InvalidatedCoords.Count != 0 || atmosphere.RevalidatePaused) && TryGetMapGrid(atmosphere, out var mapGrid)) - if (!GridRevalidate(mapGrid, atmosphere)) - { - atmosphere.RevalidatePaused = true; - return; - } - - atmosphere.RevalidatePaused = false; - if (atmosphere.Timer < AtmosTime) continue; @@ -263,6 +362,21 @@ namespace Content.Server.Atmos.EntitySystems switch (atmosphere.State) { + case AtmosphereProcessingState.Revalidate: + if (!ProcessRevalidate(atmosphere)) + { + atmosphere.ProcessingPaused = true; + return; + } + + atmosphere.ProcessingPaused = false; + // Next state depends on whether monstermos equalization is enabled or not. + // Note: We do this here instead of on the tile equalization step to prevent ending it early. + // Therefore, a change to this CVar might only be applied after that step is over. + atmosphere.State = MonstermosEqualization + ? AtmosphereProcessingState.TileEqualize + : AtmosphereProcessingState.ActiveTiles; + continue; case AtmosphereProcessingState.TileEqualize: if (!ProcessTileEqualize(atmosphere)) { @@ -347,12 +461,7 @@ namespace Content.Server.Atmos.EntitySystems } atmosphere.ProcessingPaused = false; - // Next state depends on whether monstermos equalization is enabled or not. - // Note: We do this here instead of on the tile equalization step to prevent ending it early. - // Therefore, a change to this CVar might only be applied after that step is over. - atmosphere.State = MonstermosEqualization - ? AtmosphereProcessingState.TileEqualize - : AtmosphereProcessingState.ActiveTiles; + atmosphere.State = AtmosphereProcessingState.Revalidate; // We reached the end of this atmosphere's update tick. Break out of the switch. break; @@ -369,6 +478,7 @@ namespace Content.Server.Atmos.EntitySystems public enum AtmosphereProcessingState : byte { + Revalidate, TileEqualize, ActiveTiles, ExcitedGroups,