Fix tile equalization terrible mistake
This commit is contained in:
@@ -401,171 +401,171 @@ namespace Content.Server.Atmos
|
|||||||
takerTiles[takerTilesLength++] = tile;
|
takerTiles[takerTilesLength++] = tile;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
|
||||||
// This is the part that can become O(n^2).
|
// This is the part that can become O(n^2).
|
||||||
if (giverTilesLength < takerTilesLength)
|
if (giverTilesLength < takerTilesLength)
|
||||||
|
{
|
||||||
|
// as an optimization, we choose one of two methods based on which list is smaller. We really want to avoid O(n^2) if we can.
|
||||||
|
var queue = ArrayPool<TileAtmosphere>.Shared.Rent(tileCount);
|
||||||
|
for (var j = 0; j < giverTilesLength; j++)
|
||||||
{
|
{
|
||||||
// as an optimization, we choose one of two methods based on which list is smaller. We really want to avoid O(n^2) if we can.
|
var giver = giverTiles[j];
|
||||||
var queue = ArrayPool<TileAtmosphere>.Shared.Rent(tileCount);
|
giver._tileAtmosInfo.CurrentTransferDirection = AtmosDirection.Invalid;
|
||||||
for (var j = 0; j < giverTilesLength; j++)
|
giver._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||||
|
var queueCycleSlow = ++_gridAtmosphereComponent.EqualizationQueueCycleControl;
|
||||||
|
var queueLength = 0;
|
||||||
|
queue[queueLength++] = giver;
|
||||||
|
giver._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow;
|
||||||
|
for (var i = 0; i < queueLength; i++)
|
||||||
{
|
{
|
||||||
var giver = giverTiles[j];
|
if (giver._tileAtmosInfo.MoleDelta <= 0)
|
||||||
giver._tileAtmosInfo.CurrentTransferDirection = AtmosDirection.Invalid;
|
break; // We're done here now. Let's not do more work than needed.
|
||||||
giver._tileAtmosInfo.CurrentTransferAmount = 0;
|
|
||||||
var queueCycleSlow = ++_gridAtmosphereComponent.EqualizationQueueCycleControl;
|
var tile = queue[i];
|
||||||
var queueLength = 0;
|
for (var k = 0; k < Atmospherics.Directions; k++)
|
||||||
queue[queueLength++] = giver;
|
|
||||||
giver._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow;
|
|
||||||
for (var i = 0; i < queueLength; i++)
|
|
||||||
{
|
{
|
||||||
if (giver._tileAtmosInfo.MoleDelta <= 0)
|
var direction = (AtmosDirection) (1 << k);
|
||||||
break; // We're done here now. Let's not do more work than needed.
|
if (!tile._adjacentBits.IsFlagSet(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;
|
||||||
|
|
||||||
var tile = queue[i];
|
queue[queueLength++] = tile2;
|
||||||
for (var k = 0; k < Atmospherics.Directions; k++)
|
tile2._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow;
|
||||||
|
tile2._tileAtmosInfo.CurrentTransferDirection = direction.GetOpposite();
|
||||||
|
tile2._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||||
|
if (tile2._tileAtmosInfo.MoleDelta < 0)
|
||||||
{
|
{
|
||||||
var direction = (AtmosDirection) (1 << k);
|
// This tile needs gas. Let's give it to 'em.
|
||||||
if (!tile._adjacentBits.IsFlagSet(direction)) continue;
|
if (-tile2._tileAtmosInfo.MoleDelta > giver._tileAtmosInfo.MoleDelta)
|
||||||
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;
|
|
||||||
|
|
||||||
queue[queueLength++] = tile2;
|
|
||||||
tile2._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow;
|
|
||||||
tile2._tileAtmosInfo.CurrentTransferDirection = direction.GetOpposite();
|
|
||||||
tile2._tileAtmosInfo.CurrentTransferAmount = 0;
|
|
||||||
if (tile2._tileAtmosInfo.MoleDelta < 0)
|
|
||||||
{
|
{
|
||||||
// This tile needs gas. Let's give it to 'em.
|
// We don't have enough gas!
|
||||||
if (-tile2._tileAtmosInfo.MoleDelta > giver._tileAtmosInfo.MoleDelta)
|
tile2._tileAtmosInfo.CurrentTransferAmount -= giver._tileAtmosInfo.MoleDelta;
|
||||||
{
|
tile2._tileAtmosInfo.MoleDelta += giver._tileAtmosInfo.MoleDelta;
|
||||||
// We don't have enough gas!
|
giver._tileAtmosInfo.MoleDelta = 0;
|
||||||
tile2._tileAtmosInfo.CurrentTransferAmount -= giver._tileAtmosInfo.MoleDelta;
|
}
|
||||||
tile2._tileAtmosInfo.MoleDelta += giver._tileAtmosInfo.MoleDelta;
|
else
|
||||||
giver._tileAtmosInfo.MoleDelta = 0;
|
{
|
||||||
}
|
// We have enough gas.
|
||||||
else
|
tile2._tileAtmosInfo.CurrentTransferAmount += tile2._tileAtmosInfo.MoleDelta;
|
||||||
{
|
giver._tileAtmosInfo.MoleDelta += tile2._tileAtmosInfo.MoleDelta;
|
||||||
// We have enough gas.
|
tile2._tileAtmosInfo.MoleDelta = 0;
|
||||||
tile2._tileAtmosInfo.CurrentTransferAmount += tile2._tileAtmosInfo.MoleDelta;
|
|
||||||
giver._tileAtmosInfo.MoleDelta += tile2._tileAtmosInfo.MoleDelta;
|
|
||||||
tile2._tileAtmosInfo.MoleDelta = 0;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Putting this loop here helps make it O(n^2) over O(n^3)
|
|
||||||
for (var i = queueLength - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
var tile = queue[i];
|
|
||||||
if (tile._tileAtmosInfo.CurrentTransferAmount != 0 && tile._tileAtmosInfo.CurrentTransferDirection != AtmosDirection.Invalid)
|
|
||||||
{
|
|
||||||
tile.AdjustEqMovement(tile._tileAtmosInfo.CurrentTransferDirection, tile._tileAtmosInfo.CurrentTransferAmount);
|
|
||||||
tile._adjacentTiles[tile._tileAtmosInfo.CurrentTransferDirection.ToIndex()]
|
|
||||||
._tileAtmosInfo.CurrentTransferAmount += tile._tileAtmosInfo.CurrentTransferAmount;
|
|
||||||
tile._tileAtmosInfo.CurrentTransferAmount = 0;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayPool<TileAtmosphere>.Shared.Return(queue);
|
// Putting this loop here helps make it O(n^2) over O(n^3)
|
||||||
}
|
for (var i = queueLength - 1; i >= 0; i--)
|
||||||
else
|
|
||||||
{
|
|
||||||
var queue = ArrayPool<TileAtmosphere>.Shared.Rent(tileCount);
|
|
||||||
for (var j = 0; j < takerTilesLength; j++)
|
|
||||||
{
|
{
|
||||||
var taker = takerTiles[j];
|
var tile = queue[i];
|
||||||
taker._tileAtmosInfo.CurrentTransferDirection = AtmosDirection.Invalid;
|
if (tile._tileAtmosInfo.CurrentTransferAmount != 0 && tile._tileAtmosInfo.CurrentTransferDirection != AtmosDirection.Invalid)
|
||||||
taker._tileAtmosInfo.CurrentTransferAmount = 0;
|
|
||||||
var queueCycleSlow = ++_gridAtmosphereComponent.EqualizationQueueCycleControl;
|
|
||||||
var queueLength = 0;
|
|
||||||
queue[queueLength++] = taker;
|
|
||||||
taker._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow;
|
|
||||||
for (var i = 0; i < queueLength; i++)
|
|
||||||
{
|
{
|
||||||
if (taker._tileAtmosInfo.MoleDelta >= 0)
|
|
||||||
break; // We're done here now. Let's not do more work than needed.
|
|
||||||
|
|
||||||
var tile = queue[i];
|
|
||||||
for (var k = 0; k < Atmospherics.Directions; k++)
|
|
||||||
{
|
|
||||||
var direction = (AtmosDirection) (1 << k);
|
|
||||||
if (!tile._adjacentBits.IsFlagSet(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;
|
|
||||||
if (tile2._tileAtmosInfo.LastSlowQueueCycle == queueCycleSlow) continue;
|
|
||||||
queue[queueLength++] = tile2;
|
|
||||||
tile2._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow;
|
|
||||||
tile2._tileAtmosInfo.CurrentTransferDirection = direction.GetOpposite();
|
|
||||||
tile2._tileAtmosInfo.CurrentTransferAmount = 0;
|
|
||||||
|
|
||||||
if (tile2._tileAtmosInfo.MoleDelta > 0)
|
|
||||||
{
|
|
||||||
// This tile has gas we can suck, so let's
|
|
||||||
if (tile2._tileAtmosInfo.MoleDelta > -taker._tileAtmosInfo.MoleDelta)
|
|
||||||
{
|
|
||||||
// They have enough gas
|
|
||||||
tile2._tileAtmosInfo.CurrentTransferAmount -= taker._tileAtmosInfo.MoleDelta;
|
|
||||||
tile2._tileAtmosInfo.MoleDelta += taker._tileAtmosInfo.MoleDelta;
|
|
||||||
taker._tileAtmosInfo.MoleDelta = 0;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// They don't have enough gas!
|
|
||||||
tile2._tileAtmosInfo.CurrentTransferAmount += tile2._tileAtmosInfo.MoleDelta;
|
|
||||||
taker._tileAtmosInfo.MoleDelta += tile2._tileAtmosInfo.MoleDelta;
|
|
||||||
tile2._tileAtmosInfo.MoleDelta = 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
for (var i = queueLength - 1; i >= 0; i--)
|
|
||||||
{
|
|
||||||
var tile = queue[i];
|
|
||||||
if (tile._tileAtmosInfo.CurrentTransferAmount == 0 || tile._tileAtmosInfo.CurrentTransferDirection == AtmosDirection.Invalid)
|
|
||||||
continue;
|
|
||||||
|
|
||||||
tile.AdjustEqMovement(tile._tileAtmosInfo.CurrentTransferDirection, tile._tileAtmosInfo.CurrentTransferAmount);
|
tile.AdjustEqMovement(tile._tileAtmosInfo.CurrentTransferDirection, tile._tileAtmosInfo.CurrentTransferAmount);
|
||||||
|
|
||||||
tile._adjacentTiles[tile._tileAtmosInfo.CurrentTransferDirection.ToIndex()]
|
tile._adjacentTiles[tile._tileAtmosInfo.CurrentTransferDirection.ToIndex()]
|
||||||
._tileAtmosInfo.CurrentTransferAmount += tile._tileAtmosInfo.CurrentTransferAmount;
|
._tileAtmosInfo.CurrentTransferAmount += tile._tileAtmosInfo.CurrentTransferAmount;
|
||||||
tile._tileAtmosInfo.CurrentTransferAmount = 0;
|
tile._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayPool<TileAtmosphere>.Shared.Return(queue);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
for (var i = 0; i < tileCount; i++)
|
ArrayPool<TileAtmosphere>.Shared.Return(queue);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var queue = ArrayPool<TileAtmosphere>.Shared.Rent(tileCount);
|
||||||
|
for (var j = 0; j < takerTilesLength; j++)
|
||||||
{
|
{
|
||||||
var tile = tiles[i];
|
var taker = takerTiles[j];
|
||||||
tile.FinalizeEq();
|
taker._tileAtmosInfo.CurrentTransferDirection = AtmosDirection.Invalid;
|
||||||
}
|
taker._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||||
|
var queueCycleSlow = ++_gridAtmosphereComponent.EqualizationQueueCycleControl;
|
||||||
for (var i = 0; i < tileCount; i++)
|
var queueLength = 0;
|
||||||
{
|
queue[queueLength++] = taker;
|
||||||
var tile = tiles[i];
|
taker._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow;
|
||||||
for (var j = 0; j < Atmospherics.Directions; j++)
|
for (var i = 0; i < queueLength; i++)
|
||||||
{
|
{
|
||||||
var direction = (AtmosDirection) (1 << j);
|
if (taker._tileAtmosInfo.MoleDelta >= 0)
|
||||||
if (!tile._adjacentBits.IsFlagSet(direction)) continue;
|
break; // We're done here now. Let's not do more work than needed.
|
||||||
var tile2 = tile._adjacentTiles[j];
|
|
||||||
if (tile2?.Air?.Compare(Air) == GasMixture.GasCompareResult.NoExchange) continue;
|
var tile = queue[i];
|
||||||
_gridAtmosphereComponent.AddActiveTile(tile2);
|
for (var k = 0; k < Atmospherics.Directions; k++)
|
||||||
break;
|
{
|
||||||
|
var direction = (AtmosDirection) (1 << k);
|
||||||
|
if (!tile._adjacentBits.IsFlagSet(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;
|
||||||
|
if (tile2._tileAtmosInfo.LastSlowQueueCycle == queueCycleSlow) continue;
|
||||||
|
queue[queueLength++] = tile2;
|
||||||
|
tile2._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow;
|
||||||
|
tile2._tileAtmosInfo.CurrentTransferDirection = direction.GetOpposite();
|
||||||
|
tile2._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||||
|
|
||||||
|
if (tile2._tileAtmosInfo.MoleDelta > 0)
|
||||||
|
{
|
||||||
|
// This tile has gas we can suck, so let's
|
||||||
|
if (tile2._tileAtmosInfo.MoleDelta > -taker._tileAtmosInfo.MoleDelta)
|
||||||
|
{
|
||||||
|
// They have enough gas
|
||||||
|
tile2._tileAtmosInfo.CurrentTransferAmount -= taker._tileAtmosInfo.MoleDelta;
|
||||||
|
tile2._tileAtmosInfo.MoleDelta += taker._tileAtmosInfo.MoleDelta;
|
||||||
|
taker._tileAtmosInfo.MoleDelta = 0;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
// They don't have enough gas!
|
||||||
|
tile2._tileAtmosInfo.CurrentTransferAmount += tile2._tileAtmosInfo.MoleDelta;
|
||||||
|
taker._tileAtmosInfo.MoleDelta += tile2._tileAtmosInfo.MoleDelta;
|
||||||
|
tile2._tileAtmosInfo.MoleDelta = 0;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = queueLength - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
var tile = queue[i];
|
||||||
|
if (tile._tileAtmosInfo.CurrentTransferAmount == 0 || tile._tileAtmosInfo.CurrentTransferDirection == AtmosDirection.Invalid)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tile.AdjustEqMovement(tile._tileAtmosInfo.CurrentTransferDirection, tile._tileAtmosInfo.CurrentTransferAmount);
|
||||||
|
|
||||||
|
tile._adjacentTiles[tile._tileAtmosInfo.CurrentTransferDirection.ToIndex()]
|
||||||
|
._tileAtmosInfo.CurrentTransferAmount += tile._tileAtmosInfo.CurrentTransferAmount;
|
||||||
|
tile._tileAtmosInfo.CurrentTransferAmount = 0;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ArrayPool<TileAtmosphere>.Shared.Return(tiles);
|
ArrayPool<TileAtmosphere>.Shared.Return(queue);
|
||||||
ArrayPool<TileAtmosphere>.Shared.Return(giverTiles);
|
|
||||||
ArrayPool<TileAtmosphere>.Shared.Return(takerTiles);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tileCount; i++)
|
||||||
|
{
|
||||||
|
var tile = tiles[i];
|
||||||
|
tile.FinalizeEq();
|
||||||
|
}
|
||||||
|
|
||||||
|
for (var i = 0; i < tileCount; i++)
|
||||||
|
{
|
||||||
|
var tile = tiles[i];
|
||||||
|
for (var j = 0; j < Atmospherics.Directions; j++)
|
||||||
|
{
|
||||||
|
var direction = (AtmosDirection) (1 << j);
|
||||||
|
if (!tile._adjacentBits.IsFlagSet(direction)) continue;
|
||||||
|
var tile2 = tile._adjacentTiles[j];
|
||||||
|
if (tile2?.Air?.Compare(Air) == GasMixture.GasCompareResult.NoExchange) continue;
|
||||||
|
_gridAtmosphereComponent.AddActiveTile(tile2);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
ArrayPool<TileAtmosphere>.Shared.Return(tiles);
|
||||||
|
ArrayPool<TileAtmosphere>.Shared.Return(giverTiles);
|
||||||
|
ArrayPool<TileAtmosphere>.Shared.Return(takerTiles);
|
||||||
}
|
}
|
||||||
|
|
||||||
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
[MethodImpl(MethodImplOptions.AggressiveInlining)]
|
||||||
|
|||||||
Reference in New Issue
Block a user