Merge branch 'master' into 2020-08-19-firelocks
# Conflicts: # Content.Server/GameObjects/Components/Atmos/AirtightComponent.cs # Content.Server/GameObjects/Components/Atmos/GridAtmosphereComponent.cs # SpaceStation14.sln.DotSettings
This commit is contained in:
@@ -4,7 +4,6 @@ using System.Collections.Generic;
|
||||
using System.Runtime.CompilerServices;
|
||||
using Content.Server.Atmos.Reactions;
|
||||
using Content.Server.GameObjects.Components.Atmos;
|
||||
using Content.Server.GameObjects.EntitySystems;
|
||||
using Content.Server.GameObjects.EntitySystems.Atmos;
|
||||
using Content.Server.Interfaces;
|
||||
using Content.Shared.Atmos;
|
||||
@@ -12,13 +11,13 @@ using Content.Shared.Audio;
|
||||
using Content.Shared.Maps;
|
||||
using Robust.Server.GameObjects.EntitySystems;
|
||||
using Robust.Shared.Containers;
|
||||
using Robust.Shared.GameObjects;
|
||||
using Robust.Shared.GameObjects.Components;
|
||||
using Robust.Shared.GameObjects.Systems;
|
||||
using Robust.Shared.Interfaces.GameObjects;
|
||||
using Robust.Shared.Interfaces.Map;
|
||||
using Robust.Shared.Interfaces.Random;
|
||||
using Robust.Shared.IoC;
|
||||
using Robust.Shared.Log;
|
||||
using Robust.Shared.Map;
|
||||
using Robust.Shared.Maths;
|
||||
using Robust.Shared.Random;
|
||||
@@ -28,18 +27,15 @@ namespace Content.Server.Atmos
|
||||
{
|
||||
public class TileAtmosphere : IGasMixtureHolder
|
||||
{
|
||||
[Robust.Shared.IoC.Dependency] private IRobustRandom _robustRandom = default!;
|
||||
[Robust.Shared.IoC.Dependency] private IEntityManager _entityManager = default!;
|
||||
[Robust.Shared.IoC.Dependency] private IMapManager _mapManager = default!;
|
||||
[Robust.Shared.IoC.Dependency] private readonly IRobustRandom _robustRandom = default!;
|
||||
[Robust.Shared.IoC.Dependency] private readonly IEntityManager _entityManager = default!;
|
||||
[Robust.Shared.IoC.Dependency] private readonly IMapManager _mapManager = default!;
|
||||
|
||||
|
||||
private static readonly TileAtmosphereComparer _comparer = new TileAtmosphereComparer();
|
||||
private static readonly TileAtmosphereComparer Comparer = new TileAtmosphereComparer();
|
||||
|
||||
[ViewVariables]
|
||||
private int _archivedCycle = 0;
|
||||
|
||||
[ViewVariables]
|
||||
private int _currentCycle = 0;
|
||||
[ViewVariables] private int _archivedCycle;
|
||||
[ViewVariables] private int _currentCycle;
|
||||
|
||||
[ViewVariables]
|
||||
private static GasTileOverlaySystem _gasTileOverlaySystem;
|
||||
@@ -51,13 +47,13 @@ namespace Content.Server.Atmos
|
||||
private float _temperatureArchived = Atmospherics.T20C;
|
||||
|
||||
// I know this being static is evil, but I seriously can't come up with a better solution to sound spam.
|
||||
private static int _soundCooldown = 0;
|
||||
private static int _soundCooldown;
|
||||
|
||||
[ViewVariables]
|
||||
public TileAtmosphere PressureSpecificTarget { get; set; } = null;
|
||||
public TileAtmosphere PressureSpecificTarget { get; set; }
|
||||
|
||||
[ViewVariables]
|
||||
public float PressureDifference { get; set; } = 0;
|
||||
public float PressureDifference { get; set; }
|
||||
|
||||
[ViewVariables(VVAccess.ReadWrite)]
|
||||
public float HeatCapacity { get; set; } = 1f;
|
||||
@@ -66,13 +62,19 @@ namespace Content.Server.Atmos
|
||||
public float ThermalConductivity => Tile?.Tile.GetContentTileDefinition().ThermalConductivity ?? 0.05f;
|
||||
|
||||
[ViewVariables]
|
||||
public bool Excited { get; set; } = false;
|
||||
public bool Excited { get; set; }
|
||||
|
||||
[ViewVariables]
|
||||
private GridAtmosphereComponent _gridAtmosphereComponent;
|
||||
private readonly GridAtmosphereComponent _gridAtmosphereComponent;
|
||||
|
||||
/// <summary>
|
||||
/// Adjacent tiles in the same order as <see cref="AtmosDirection"/>. (NSEW)
|
||||
/// </summary>
|
||||
[ViewVariables]
|
||||
private readonly TileAtmosphere[] _adjacentTiles = new TileAtmosphere[Atmospherics.Directions];
|
||||
|
||||
[ViewVariables]
|
||||
private readonly Dictionary<Direction, TileAtmosphere> _adjacentTiles = new Dictionary<Direction, TileAtmosphere>();
|
||||
private AtmosDirection _adjacentBits = AtmosDirection.Invalid;
|
||||
|
||||
[ViewVariables]
|
||||
private TileAtmosInfo _tileAtmosInfo;
|
||||
@@ -80,7 +82,7 @@ namespace Content.Server.Atmos
|
||||
[ViewVariables]
|
||||
public Hotspot Hotspot;
|
||||
|
||||
private Direction _pressureDirection;
|
||||
private AtmosDirection _pressureDirection;
|
||||
|
||||
[ViewVariables]
|
||||
public GridId GridIndex { get; }
|
||||
@@ -100,14 +102,16 @@ namespace Content.Server.Atmos
|
||||
[ViewVariables]
|
||||
public bool BlocksAir => _gridAtmosphereComponent.IsAirBlocked(GridIndices);
|
||||
|
||||
public TileAtmosphere(GridAtmosphereComponent atmosphereComponent, GridId gridIndex, MapIndices gridIndices, GasMixture mixture = null)
|
||||
public TileAtmosphere(GridAtmosphereComponent atmosphereComponent, GridId gridIndex, MapIndices gridIndices, GasMixture mixture = null, bool immutable = false)
|
||||
{
|
||||
IoCManager.InjectDependencies(this);
|
||||
_gridAtmosphereComponent = atmosphereComponent;
|
||||
GridIndex = gridIndex;
|
||||
GridIndices = gridIndices;
|
||||
Air = mixture;
|
||||
ResetTileAtmosInfo();
|
||||
|
||||
if(immutable)
|
||||
Air?.MarkImmutable();
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -163,7 +167,7 @@ namespace Content.Server.Atmos
|
||||
}
|
||||
}
|
||||
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void HighPressureMovements()
|
||||
{
|
||||
// TODO ATMOS finish this
|
||||
@@ -175,7 +179,6 @@ namespace Content.Server.Atmos
|
||||
GridIndices.ToGridCoordinates(_mapManager, GridIndex), AudioHelpers.WithVariation(0.125f).WithVolume(MathHelper.Clamp(PressureDifference / 10, 10, 100)));
|
||||
}
|
||||
|
||||
|
||||
foreach (var entity in _entityManager.GetEntitiesIntersecting(_mapManager.GetGrid(GridIndex).ParentMapId, Box2.UnitCentered.Translated(GridIndices)))
|
||||
{
|
||||
if (!entity.TryGetComponent(out ICollidableComponent physics)
|
||||
@@ -195,7 +198,7 @@ namespace Content.Server.Atmos
|
||||
|
||||
if (PressureDifference > 100)
|
||||
{
|
||||
// Do space wind graphics here!
|
||||
// TODO ATMOS Do space wind graphics here!
|
||||
}
|
||||
|
||||
_soundCooldown++;
|
||||
@@ -220,20 +223,22 @@ namespace Content.Server.Atmos
|
||||
}
|
||||
}
|
||||
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void EqualizePressureInZone(int cycleNum)
|
||||
{
|
||||
if (Air == null || (_tileAtmosInfo.LastCycle >= cycleNum)) return; // Already done.
|
||||
|
||||
ResetTileAtmosInfo();
|
||||
|
||||
_tileAtmosInfo = new TileAtmosInfo();
|
||||
|
||||
var startingMoles = Air.TotalMoles;
|
||||
var runAtmos = false;
|
||||
|
||||
// We need to figure if this is necessary
|
||||
foreach (var (direction, other) in _adjacentTiles)
|
||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
var direction = (AtmosDirection) (1 << i);
|
||||
if (!_adjacentBits.HasFlag(direction)) continue;
|
||||
var other = _adjacentTiles[i];
|
||||
if (other?.Air == null) continue;
|
||||
var comparisonMoles = other.Air.TotalMoles;
|
||||
if (!(MathF.Abs(comparisonMoles - startingMoles) > Atmospherics.MinimumMolesDeltaToMove)) continue;
|
||||
@@ -265,13 +270,15 @@ namespace Content.Server.Atmos
|
||||
totalMoles += tileMoles;
|
||||
}
|
||||
|
||||
foreach (var (_, adj) in exploring._adjacentTiles)
|
||||
for (var j = 0; j < Atmospherics.Directions; j++)
|
||||
{
|
||||
var direction = (AtmosDirection) (1 << j);
|
||||
if (!exploring._adjacentBits.HasFlag(direction)) continue;
|
||||
var adj = exploring._adjacentTiles[j];
|
||||
if (adj?.Air == null) continue;
|
||||
if(adj._tileAtmosInfo.LastQueueCycle == queueCycle) continue;
|
||||
adj.ResetTileAtmosInfo();
|
||||
adj._tileAtmosInfo = new TileAtmosInfo {LastQueueCycle = queueCycle};
|
||||
|
||||
adj._tileAtmosInfo.LastQueueCycle = queueCycle;
|
||||
if(tileCount < Atmospherics.ZumosHardTileLimit)
|
||||
tiles[tileCount++] = adj;
|
||||
if (adj.Air.Immutable)
|
||||
@@ -326,47 +333,42 @@ namespace Content.Server.Atmos
|
||||
if (giverTilesLength > logN && takerTilesLength > logN)
|
||||
{
|
||||
// Even if it fails, it will speed up the next part.
|
||||
Array.Sort(tiles, 0, tileCount, _comparer);
|
||||
Array.Sort(tiles, 0, tileCount, Comparer);
|
||||
|
||||
for (var i = 0; i < tileCount; i++)
|
||||
{
|
||||
var tile = tiles[i];
|
||||
tile._tileAtmosInfo.FastDone = true;
|
||||
if (!(tile._tileAtmosInfo.MoleDelta > 0)) continue;
|
||||
var eligibleDirections = ArrayPool<Direction>.Shared.Rent(4);
|
||||
var eligibleDirections = AtmosDirection.Invalid;
|
||||
var eligibleDirectionCount = 0;
|
||||
foreach (var direction in Cardinal)
|
||||
for (var j = 0; j < Atmospherics.Directions; j++)
|
||||
{
|
||||
if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue;
|
||||
var direction = (AtmosDirection) (1 << j);
|
||||
if (!tile._adjacentBits.HasFlag(direction)) continue;
|
||||
var tile2 = tile._adjacentTiles[j];
|
||||
|
||||
// skip anything that isn't part of our current processing block.
|
||||
if (tile2._tileAtmosInfo.FastDone || tile2._tileAtmosInfo.LastQueueCycle != queueCycle)
|
||||
continue;
|
||||
|
||||
eligibleDirections[eligibleDirectionCount++] = direction;
|
||||
eligibleDirections |= direction;
|
||||
eligibleDirectionCount++;
|
||||
}
|
||||
|
||||
if (eligibleDirectionCount <= 0)
|
||||
continue; // Oof we've painted ourselves into a corner. Bad luck. Next part will handle this.
|
||||
|
||||
var molesToMove = tile._tileAtmosInfo.MoleDelta / eligibleDirectionCount;
|
||||
foreach (var direction in Cardinal)
|
||||
for (var j = 0; j < Atmospherics.Directions; j++)
|
||||
{
|
||||
var hasDirection = false;
|
||||
for (var j = 0; j < eligibleDirectionCount; j++)
|
||||
{
|
||||
if (eligibleDirections[j] != direction) continue;
|
||||
hasDirection = true;
|
||||
break;
|
||||
}
|
||||
var direction = (AtmosDirection) (1 << j);
|
||||
if (!eligibleDirections.HasFlag(direction)) continue;
|
||||
|
||||
if (hasDirection || !tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue;
|
||||
tile.AdjustEqMovement(direction, molesToMove);
|
||||
tile._tileAtmosInfo.MoleDelta -= molesToMove;
|
||||
tile2._tileAtmosInfo.MoleDelta += molesToMove;
|
||||
tile._adjacentTiles[j]._tileAtmosInfo.MoleDelta += molesToMove;
|
||||
}
|
||||
|
||||
ArrayPool<Direction>.Shared.Return(eligibleDirections);
|
||||
}
|
||||
|
||||
giverTilesLength = 0;
|
||||
@@ -393,7 +395,7 @@ namespace Content.Server.Atmos
|
||||
for (var j = 0; j < giverTilesLength; j++)
|
||||
{
|
||||
var giver = giverTiles[j];
|
||||
giver._tileAtmosInfo.CurrentTransferDirection = (Direction) (-1);
|
||||
giver._tileAtmosInfo.CurrentTransferDirection = AtmosDirection.Invalid;
|
||||
giver._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||
var queueCycleSlow = ++_gridAtmosphereComponent.EqualizationQueueCycleControl;
|
||||
var queueLength = 0;
|
||||
@@ -405,9 +407,11 @@ namespace Content.Server.Atmos
|
||||
break; // We're done here now. Let's not do more work than needed.
|
||||
|
||||
var tile = queue[i];
|
||||
foreach (var direction in Cardinal)
|
||||
for (var k = 0; k < Atmospherics.Directions; k++)
|
||||
{
|
||||
if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue;
|
||||
var direction = (AtmosDirection) (1 << k);
|
||||
if (!tile._adjacentBits.HasFlag(direction)) continue;
|
||||
var tile2 = tile._adjacentTiles[k];
|
||||
if (giver._tileAtmosInfo.MoleDelta <= 0) break; // We're done here now. Let's not do more work than needed.
|
||||
if (tile2._tileAtmosInfo.LastQueueCycle != queueCycle) continue;
|
||||
if (tile2._tileAtmosInfo.LastSlowQueueCycle == queueCycleSlow) continue;
|
||||
@@ -441,15 +445,11 @@ namespace Content.Server.Atmos
|
||||
for (var i = queueLength - 1; i >= 0; i--)
|
||||
{
|
||||
var tile = queue[i];
|
||||
if (tile._tileAtmosInfo.CurrentTransferAmount != 0 &&
|
||||
tile._tileAtmosInfo.CurrentTransferDirection != (Direction) (-1))
|
||||
if (tile._tileAtmosInfo.CurrentTransferAmount != 0 && tile._tileAtmosInfo.CurrentTransferDirection != AtmosDirection.Invalid)
|
||||
{
|
||||
tile.AdjustEqMovement(tile._tileAtmosInfo.CurrentTransferDirection,
|
||||
tile._tileAtmosInfo.CurrentTransferAmount);
|
||||
if (tile._adjacentTiles.TryGetValue(tile._tileAtmosInfo.CurrentTransferDirection,
|
||||
out var adjacent))
|
||||
adjacent._tileAtmosInfo.CurrentTransferAmount +=
|
||||
tile._tileAtmosInfo.CurrentTransferAmount;
|
||||
tile.AdjustEqMovement(tile._tileAtmosInfo.CurrentTransferDirection, tile._tileAtmosInfo.CurrentTransferAmount);
|
||||
tile._adjacentTiles[tile._tileAtmosInfo.CurrentTransferDirection.ToIndex()]
|
||||
._tileAtmosInfo.CurrentTransferAmount += tile._tileAtmosInfo.CurrentTransferAmount;
|
||||
tile._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||
}
|
||||
}
|
||||
@@ -463,7 +463,7 @@ namespace Content.Server.Atmos
|
||||
for (var j = 0; j < takerTilesLength; j++)
|
||||
{
|
||||
var taker = takerTiles[j];
|
||||
taker._tileAtmosInfo.CurrentTransferDirection = Direction.Invalid;
|
||||
taker._tileAtmosInfo.CurrentTransferDirection = AtmosDirection.Invalid;
|
||||
taker._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||
var queueCycleSlow = ++_gridAtmosphereComponent.EqualizationQueueCycleControl;
|
||||
var queueLength = 0;
|
||||
@@ -475,10 +475,11 @@ namespace Content.Server.Atmos
|
||||
break; // We're done here now. Let's not do more work than needed.
|
||||
|
||||
var tile = queue[i];
|
||||
foreach (var direction in Cardinal)
|
||||
for (var k = 0; k < Atmospherics.Directions; k++)
|
||||
{
|
||||
if (!tile._adjacentTiles.ContainsKey(direction)) continue;
|
||||
var tile2 = tile._adjacentTiles[direction];
|
||||
var direction = (AtmosDirection) (1 << k);
|
||||
if (!tile._adjacentBits.HasFlag(direction)) continue;
|
||||
var tile2 = tile._adjacentTiles[k];
|
||||
|
||||
if (taker._tileAtmosInfo.MoleDelta >= 0) break; // We're done here now. Let's not do more work than needed.
|
||||
if (tile2._tileAtmosInfo.LastQueueCycle != queueCycle) continue;
|
||||
@@ -512,16 +513,14 @@ namespace Content.Server.Atmos
|
||||
for (var i = queueLength - 1; i >= 0; i--)
|
||||
{
|
||||
var tile = queue[i];
|
||||
if (tile._tileAtmosInfo.CurrentTransferAmount == 0 || tile._tileAtmosInfo.CurrentTransferDirection == Direction.Invalid)
|
||||
if (tile._tileAtmosInfo.CurrentTransferAmount == 0 || tile._tileAtmosInfo.CurrentTransferDirection == AtmosDirection.Invalid)
|
||||
continue;
|
||||
|
||||
tile.AdjustEqMovement(tile._tileAtmosInfo.CurrentTransferDirection, tile._tileAtmosInfo.CurrentTransferAmount);
|
||||
|
||||
if (tile._adjacentTiles.TryGetValue(tile._tileAtmosInfo.CurrentTransferDirection, out var adjacent))
|
||||
{
|
||||
adjacent._tileAtmosInfo.CurrentTransferAmount += tile._tileAtmosInfo.CurrentTransferAmount;
|
||||
tile._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||
}
|
||||
tile._adjacentTiles[tile._tileAtmosInfo.CurrentTransferDirection.ToIndex()]
|
||||
._tileAtmosInfo.CurrentTransferAmount += tile._tileAtmosInfo.CurrentTransferAmount;
|
||||
tile._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||
}
|
||||
}
|
||||
|
||||
@@ -537,9 +536,11 @@ namespace Content.Server.Atmos
|
||||
for (var i = 0; i < tileCount; i++)
|
||||
{
|
||||
var tile = tiles[i];
|
||||
foreach (var direction in Cardinal)
|
||||
for (var j = 0; j < Atmospherics.Directions; j++)
|
||||
{
|
||||
if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue;
|
||||
var direction = (AtmosDirection) (1 << j);
|
||||
if (!tile._adjacentBits.HasFlag(direction)) continue;
|
||||
var tile2 = tile._adjacentTiles[j];
|
||||
if (tile2?.Air?.Compare(Air) == GasMixture.GasCompareResult.NoExchange) continue;
|
||||
_gridAtmosphereComponent.AddActiveTile(tile2);
|
||||
break;
|
||||
@@ -555,69 +556,68 @@ namespace Content.Server.Atmos
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void FinalizeEq()
|
||||
{
|
||||
var transferDirections = new Dictionary<Direction, float>();
|
||||
var transferDirections = new float[Atmospherics.Directions];
|
||||
var hasTransferDirs = false;
|
||||
foreach (var direction in Cardinal)
|
||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
var amount = _tileAtmosInfo[direction];
|
||||
var amount = _tileAtmosInfo[i];
|
||||
if (amount == 0) continue;
|
||||
transferDirections[direction] = amount;
|
||||
_tileAtmosInfo[direction] = 0;
|
||||
transferDirections[i] = amount;
|
||||
_tileAtmosInfo[i] = 0; // Set them to 0 to prevent infinite recursion.
|
||||
hasTransferDirs = true;
|
||||
}
|
||||
|
||||
if (!hasTransferDirs) return;
|
||||
|
||||
foreach (var (direction, amount) in transferDirections)
|
||||
for(var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
if (!_adjacentTiles.TryGetValue(direction, out var tile) || tile.Air == null) continue;
|
||||
var direction = (AtmosDirection) (1 << i);
|
||||
if (!_adjacentBits.HasFlag(direction)) continue;
|
||||
var amount = transferDirections[i];
|
||||
var tile = _adjacentTiles[i];
|
||||
if (tile?.Air == null) continue;
|
||||
if (amount > 0)
|
||||
{
|
||||
if (Air.TotalMoles < amount)
|
||||
FinalizeEqNeighbors(transferDirections.Keys);
|
||||
FinalizeEqNeighbors(transferDirections);
|
||||
|
||||
tile._tileAtmosInfo[direction.GetOpposite()] = 0;
|
||||
tile.Air.Merge(Air.Remove(amount));
|
||||
UpdateVisuals();
|
||||
tile.UpdateVisuals();
|
||||
ConsiderPressureDifference(direction, amount);
|
||||
ConsiderPressureDifference(tile, amount);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void FinalizeEqNeighbors(IEnumerable<Direction> directions)
|
||||
private void FinalizeEqNeighbors(in float[] transferDirs)
|
||||
{
|
||||
foreach (var direction in directions)
|
||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
var amount = _tileAtmosInfo[direction];
|
||||
if(amount < 0 && _adjacentTiles.TryGetValue(direction, out var adjacent))
|
||||
adjacent.FinalizeEq();
|
||||
var direction = (AtmosDirection) (1 << i);
|
||||
var amount = transferDirs[i];
|
||||
if(amount < 0 && _adjacentBits.HasFlag(direction))
|
||||
_adjacentTiles[i].FinalizeEq(); // A bit of recursion if needed.
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void ConsiderPressureDifference(Direction direction, float difference)
|
||||
private void ConsiderPressureDifference(TileAtmosphere other, float difference)
|
||||
{
|
||||
_gridAtmosphereComponent.AddHighPressureDelta(this);
|
||||
if (difference > PressureDifference)
|
||||
{
|
||||
PressureDifference = difference;
|
||||
_pressureDirection = difference < 0 ? direction.GetOpposite() : direction;
|
||||
_pressureDirection = ((Vector2i)(GridIndices - other.GridIndices)).GetDir().ToAtmosDirection();
|
||||
}
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void AdjustEqMovement(Direction direction, float molesToMove)
|
||||
private void AdjustEqMovement(AtmosDirection direction, float amount)
|
||||
{
|
||||
_tileAtmosInfo[direction] += molesToMove;
|
||||
if(direction != Direction.Invalid && _adjacentTiles.TryGetValue(direction, out var adj))
|
||||
adj._tileAtmosInfo[direction.GetOpposite()] -= molesToMove;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
private void ResetTileAtmosInfo()
|
||||
{
|
||||
_tileAtmosInfo = new TileAtmosInfo {CurrentTransferDirection = Direction.Invalid};
|
||||
_tileAtmosInfo[direction] += amount;
|
||||
_adjacentTiles[direction.ToIndex()]._tileAtmosInfo[direction.GetOpposite()] -= amount;
|
||||
}
|
||||
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
@@ -635,9 +635,13 @@ namespace Content.Server.Atmos
|
||||
|
||||
_currentCycle = fireCount;
|
||||
var adjacentTileLength = 0;
|
||||
foreach (var (direction, enemyTile) in _adjacentTiles)
|
||||
for(var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
// If the tile is null or has no air, we don't do anything
|
||||
var direction = (AtmosDirection) (1 << i);
|
||||
if (!_adjacentBits.HasFlag(direction)) continue;
|
||||
var enemyTile = _adjacentTiles[i];
|
||||
|
||||
// If the tile is null or has no air, we don't do anything for it.
|
||||
if(enemyTile?.Air == null) continue;
|
||||
adjacentTileLength++;
|
||||
if (fireCount <= enemyTile._currentCycle) continue;
|
||||
@@ -685,11 +689,11 @@ namespace Content.Server.Atmos
|
||||
// Space wind!
|
||||
if (difference > 0)
|
||||
{
|
||||
ConsiderPressureDifference(direction, difference);
|
||||
ConsiderPressureDifference(enemyTile, difference);
|
||||
}
|
||||
else
|
||||
{
|
||||
enemyTile.ConsiderPressureDifference(direction.GetOpposite(), -difference);
|
||||
enemyTile.ConsiderPressureDifference(this, -difference);
|
||||
}
|
||||
|
||||
LastShareCheck();
|
||||
@@ -737,7 +741,7 @@ namespace Content.Server.Atmos
|
||||
if (Air.Temperature > Atmospherics.FireMinimumTemperatureToSpread)
|
||||
{
|
||||
var radiatedTemperature = Air.Temperature * Atmospherics.FireSpreadRadiosityScale;
|
||||
foreach (var (_, tile) in _adjacentTiles)
|
||||
foreach (var tile in _adjacentTiles)
|
||||
{
|
||||
if(!tile.Hotspot.Valid)
|
||||
tile.HotspotExpose(radiatedTemperature, Atmospherics.CellVolume/4);
|
||||
@@ -771,17 +775,19 @@ namespace Content.Server.Atmos
|
||||
else
|
||||
{
|
||||
var affected = Air.RemoveRatio(Hotspot.Volume / Air.Volume);
|
||||
if (affected != null)
|
||||
{
|
||||
affected.Temperature = Hotspot.Temperature;
|
||||
affected.React(this);
|
||||
Hotspot.Temperature = affected.Temperature;
|
||||
Hotspot.Volume = affected.ReactionResults[GasReaction.Fire] * Atmospherics.FireGrowthRate;
|
||||
AssumeAir(affected);
|
||||
}
|
||||
affected.Temperature = Hotspot.Temperature;
|
||||
affected.React(this);
|
||||
Hotspot.Temperature = affected.Temperature;
|
||||
Hotspot.Volume = affected.ReactionResults[GasReaction.Fire] * Atmospherics.FireGrowthRate;
|
||||
AssumeAir(affected);
|
||||
}
|
||||
|
||||
// TODO ATMOS Let all entities in this tile know about the fire?
|
||||
var tileRef = GridIndices.GetTileRef(GridIndex);
|
||||
|
||||
if (tileRef == null) return;
|
||||
|
||||
_gridAtmosphereComponent.Owner.EntityManager.
|
||||
EventBus.QueueEvent(EventSource.Local, new FireActEvent(Hotspot.Temperature, Hotspot.Volume));
|
||||
}
|
||||
|
||||
private bool ConsiderSuperconductivity()
|
||||
@@ -806,24 +812,24 @@ namespace Content.Server.Atmos
|
||||
public void Superconduct()
|
||||
{
|
||||
var directions = ConductivityDirections();
|
||||
var adjacentTiles = _gridAtmosphereComponent.GetAdjacentTiles(GridIndices, true);
|
||||
|
||||
if (directions.Length > 0)
|
||||
for(var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
foreach (var direction in directions)
|
||||
{
|
||||
if (!adjacentTiles.TryGetValue(direction, out var adjacent)) continue;
|
||||
var direction = (AtmosDirection) (1 << i);
|
||||
if (!directions.HasFlag(direction)) continue;
|
||||
|
||||
if (adjacent.ThermalConductivity == 0f)
|
||||
continue;
|
||||
var adjacent = _adjacentTiles[direction.ToIndex()];
|
||||
|
||||
if(adjacent._archivedCycle < _gridAtmosphereComponent.UpdateCounter)
|
||||
adjacent.Archive(_gridAtmosphereComponent.UpdateCounter);
|
||||
// TODO ATMOS handle adjacent being null.
|
||||
if (adjacent == null || adjacent.ThermalConductivity == 0f)
|
||||
continue;
|
||||
|
||||
adjacent.NeighborConductWithSource(this);
|
||||
if(adjacent._archivedCycle < _gridAtmosphereComponent.UpdateCounter)
|
||||
adjacent.Archive(_gridAtmosphereComponent.UpdateCounter);
|
||||
|
||||
adjacent.ConsiderSuperconductivity();
|
||||
}
|
||||
adjacent.NeighborConductWithSource(this);
|
||||
|
||||
adjacent.ConsiderSuperconductivity();
|
||||
}
|
||||
|
||||
RadiateToSpace();
|
||||
@@ -917,20 +923,20 @@ namespace Content.Server.Atmos
|
||||
}
|
||||
}
|
||||
|
||||
public Direction[] ConductivityDirections()
|
||||
public AtmosDirection ConductivityDirections()
|
||||
{
|
||||
if(BlocksAir)
|
||||
{
|
||||
if(_archivedCycle < _gridAtmosphereComponent.UpdateCounter)
|
||||
Archive(_gridAtmosphereComponent.UpdateCounter);
|
||||
return Cardinal;
|
||||
return AtmosDirection.All;
|
||||
}
|
||||
|
||||
// TODO ATMOS check if this is correct
|
||||
return Cardinal;
|
||||
return AtmosDirection.All;
|
||||
}
|
||||
|
||||
//[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void ExplosivelyDepressurize(int cycleNum)
|
||||
{
|
||||
if (Air == null) return;
|
||||
@@ -947,14 +953,13 @@ namespace Content.Server.Atmos
|
||||
|
||||
tiles[tileCount++] = this;
|
||||
|
||||
ResetTileAtmosInfo();
|
||||
_tileAtmosInfo.LastQueueCycle = queueCycle;
|
||||
_tileAtmosInfo = new TileAtmosInfo {LastQueueCycle = queueCycle};
|
||||
|
||||
for (var i = 0; i < tileCount; i++)
|
||||
{
|
||||
var tile = tiles[i];
|
||||
tile._tileAtmosInfo.LastCycle = cycleNum;
|
||||
tile._tileAtmosInfo.CurrentTransferDirection = Direction.Invalid;
|
||||
tile._tileAtmosInfo.CurrentTransferDirection = AtmosDirection.Invalid;
|
||||
if (tile.Air.Immutable)
|
||||
{
|
||||
spaceTiles[spaceTileCount++] = tile;
|
||||
@@ -962,18 +967,19 @@ namespace Content.Server.Atmos
|
||||
}
|
||||
else
|
||||
{
|
||||
foreach (var direction in Cardinal)
|
||||
for (var j = 0; j < Atmospherics.Directions; j++)
|
||||
{
|
||||
if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue;
|
||||
var direction = (AtmosDirection) (1 << j);
|
||||
if (!tile._adjacentBits.HasFlag(direction)) continue;
|
||||
var tile2 = tile._adjacentTiles[j];
|
||||
if (tile2.Air == null) continue;
|
||||
if (tile2._tileAtmosInfo.LastQueueCycle == queueCycle) continue;
|
||||
|
||||
tile.ConsiderFirelocks(tile2);
|
||||
|
||||
// The firelocks might have closed on us.
|
||||
if (tile._adjacentTiles[direction]?.Air == null) continue;
|
||||
tile2.ResetTileAtmosInfo();
|
||||
tile2._tileAtmosInfo.LastQueueCycle = queueCycle;
|
||||
if (!tile._adjacentBits.HasFlag(direction)) continue;
|
||||
tile2._tileAtmosInfo = new TileAtmosInfo {LastQueueCycle = queueCycle};
|
||||
tiles[tileCount++] = tile2;
|
||||
}
|
||||
}
|
||||
@@ -991,18 +997,21 @@ namespace Content.Server.Atmos
|
||||
var tile = spaceTiles[i];
|
||||
progressionOrder[progressionCount++] = tile;
|
||||
tile._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow;
|
||||
tile._tileAtmosInfo.CurrentTransferDirection = Direction.Invalid;
|
||||
tile._tileAtmosInfo.CurrentTransferDirection = AtmosDirection.Invalid;
|
||||
}
|
||||
|
||||
for (var i = 0; i < progressionCount; i++)
|
||||
{
|
||||
var tile = progressionOrder[i];
|
||||
foreach (var direction in Cardinal)
|
||||
for (var j = 0; j < Atmospherics.Directions; j++)
|
||||
{
|
||||
if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue;
|
||||
var direction = (AtmosDirection) (1 << j);
|
||||
// TODO ATMOS This is a terrible hack that accounts for the mess that are space TileAtmospheres.
|
||||
if (!tile._adjacentBits.HasFlag(direction) && !tile.Air.Immutable) continue;
|
||||
var tile2 = tile._adjacentTiles[j];
|
||||
if (tile2?._tileAtmosInfo.LastQueueCycle != queueCycle) continue;
|
||||
if (tile2._tileAtmosInfo.LastSlowQueueCycle == queueCycleSlow) continue;
|
||||
if(tile2.Air.Immutable) continue;
|
||||
if(tile2.Air?.Immutable ?? false) continue;
|
||||
tile2._tileAtmosInfo.CurrentTransferDirection = direction.GetOpposite();
|
||||
tile2._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||
tile2.PressureSpecificTarget = tile.PressureSpecificTarget;
|
||||
@@ -1014,10 +1023,11 @@ namespace Content.Server.Atmos
|
||||
for (var i = progressionCount - 1; i >= 0; i--)
|
||||
{
|
||||
var tile = progressionOrder[i];
|
||||
if (tile._tileAtmosInfo.CurrentTransferDirection == Direction.Invalid) continue;
|
||||
if (tile._tileAtmosInfo.CurrentTransferDirection == AtmosDirection.Invalid) continue;
|
||||
_gridAtmosphereComponent.AddHighPressureDelta(tile);
|
||||
_gridAtmosphereComponent.AddActiveTile(tile);
|
||||
if (!tile._adjacentTiles.TryGetValue(tile._tileAtmosInfo.CurrentTransferDirection, out var tile2) || tile2.Air == null) continue;
|
||||
var tile2 = tile._adjacentTiles[tile._tileAtmosInfo.CurrentTransferDirection.ToIndex()];
|
||||
if (tile2?.Air == null) continue;
|
||||
var sum = tile2.Air.TotalMoles;
|
||||
totalGasesRemoved += sum;
|
||||
tile._tileAtmosInfo.CurrentTransferAmount += sum;
|
||||
@@ -1025,7 +1035,7 @@ namespace Content.Server.Atmos
|
||||
tile.PressureDifference = tile._tileAtmosInfo.CurrentTransferAmount;
|
||||
tile._pressureDirection = tile._tileAtmosInfo.CurrentTransferDirection;
|
||||
|
||||
if (tile2._tileAtmosInfo.CurrentTransferDirection == Direction.Invalid)
|
||||
if (tile2._tileAtmosInfo.CurrentTransferDirection == AtmosDirection.Invalid)
|
||||
{
|
||||
tile2.PressureDifference = tile2._tileAtmosInfo.CurrentTransferAmount;
|
||||
tile2._pressureDirection = tile._tileAtmosInfo.CurrentTransferDirection;
|
||||
@@ -1101,21 +1111,30 @@ namespace Content.Server.Atmos
|
||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||
public void UpdateAdjacent()
|
||||
{
|
||||
foreach (var direction in Cardinal)
|
||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
if (!_gridAtmosphereComponent.IsAirBlocked(GridIndices.Offset(direction)))
|
||||
var direction = (AtmosDirection) (1 << i);
|
||||
|
||||
var otherIndices = GridIndices.Offset(direction.ToDirection());
|
||||
|
||||
var isSpace = _gridAtmosphereComponent.IsSpace(GridIndices);
|
||||
var adjacent = _gridAtmosphereComponent.GetTile(otherIndices, !isSpace);
|
||||
_adjacentTiles[direction.ToIndex()] = adjacent;
|
||||
adjacent?.UpdateAdjacent(direction.GetOpposite());
|
||||
|
||||
if (adjacent != null && !_gridAtmosphereComponent.IsAirBlocked(adjacent.GridIndices))
|
||||
{
|
||||
var adjacent = _gridAtmosphereComponent.GetTile(GridIndices.Offset(direction));
|
||||
_adjacentTiles[direction] = adjacent;
|
||||
adjacent.UpdateAdjacent(direction.GetOpposite());
|
||||
_adjacentBits |= direction;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
public void UpdateAdjacent(Direction direction)
|
||||
public void UpdateAdjacent(AtmosDirection direction)
|
||||
{
|
||||
if (!_gridAtmosphereComponent.IsAirBlocked(GridIndices.Offset(direction)))
|
||||
_adjacentTiles[direction] = _gridAtmosphereComponent.GetTile(GridIndices.Offset(direction));
|
||||
if (!_gridAtmosphereComponent.IsAirBlocked(GridIndices.Offset(direction.ToDirection())))
|
||||
{
|
||||
_adjacentTiles[direction.ToIndex()] = _gridAtmosphereComponent.GetTile(GridIndices.Offset(direction.ToDirection()));
|
||||
}
|
||||
}
|
||||
|
||||
private void LastShareCheck()
|
||||
@@ -1130,13 +1149,7 @@ namespace Content.Server.Atmos
|
||||
}
|
||||
}
|
||||
|
||||
private static readonly Direction[] Cardinal =
|
||||
new Direction[]
|
||||
{
|
||||
Direction.North, Direction.East, Direction.South, Direction.West
|
||||
};
|
||||
|
||||
public void TemperatureExpose(GasMixture mixture, float temperature, float cellVolume)
|
||||
public void TemperatureExpose(GasMixture air, float temperature, float volume)
|
||||
{
|
||||
// TODO ATMOS do this
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user