Makes Grid Revalidation a step in the atmos update stages.
Fixes some atmos debug assert exceptions.
This commit is contained in:
@@ -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;
|
||||
|
||||
|
||||
@@ -217,113 +217,6 @@ namespace Content.Server.Atmos.EntitySystems
|
||||
|
||||
#endregion
|
||||
|
||||
#region Grid Revalidate
|
||||
|
||||
/// <summary>
|
||||
/// Revalidates all invalid coordinates in a grid atmosphere.
|
||||
/// </summary>
|
||||
/// <param name="mapGrid">The grid in question.</param>
|
||||
/// <param name="gridAtmosphere">The grid atmosphere in question.</param>
|
||||
/// <returns>Whether the process succeeded or got paused due to time constrains.</returns>
|
||||
private bool GridRevalidate(IMapGrid mapGrid, GridAtmosphereComponent gridAtmosphere)
|
||||
{
|
||||
var volume = GetVolumeForTiles(mapGrid, 1);
|
||||
|
||||
if (!gridAtmosphere.RevalidatePaused)
|
||||
gridAtmosphere.CurrentRunInvalidatedCoordinates = new Queue<Vector2i>(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
|
||||
|
||||
/// <summary>
|
||||
|
||||
@@ -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<GridAtmosphereComponent> _currentRunAtmosphere = new();
|
||||
|
||||
/// <summary>
|
||||
/// Revalidates all invalid coordinates in a grid atmosphere.
|
||||
/// </summary>
|
||||
/// <param name="atmosphere">The grid atmosphere in question.</param>
|
||||
/// <returns>Whether the process succeeded or got paused due to time constrains.</returns>
|
||||
private bool ProcessRevalidate(GridAtmosphereComponent atmosphere)
|
||||
{
|
||||
if (!atmosphere.ProcessingPaused)
|
||||
{
|
||||
atmosphere.CurrentRunInvalidatedCoordinates = new Queue<Vector2i>(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,
|
||||
|
||||
Reference in New Issue
Block a user