Fixes explosive depressurization and improves high pressure movements (#1683)

This commit is contained in:
Víctor Aguilera Puerto
2020-08-15 22:43:55 +02:00
committed by GitHub
parent 33baa73f06
commit a7fc2bccbd
2 changed files with 59 additions and 54 deletions

View File

@@ -49,19 +49,23 @@ namespace Content.Server.Atmos
{
if (maxForce > ThrowForce && throwTarget != GridCoordinates.InvalidGrid)
if (maxForce > ThrowForce)
{
var moveForce = MathF.Min(maxForce * FloatMath.Clamp(moveProb, 0, 100) / 100f, 50f);
var pos = throwTarget.Position - transform.GridPosition.Position;
LinearVelocity = pos * moveForce;
}
else
{
var moveForce = MathF.Min(maxForce * FloatMath.Clamp(moveProb, 0, 100) / 100f, 25f);
LinearVelocity = direction.ToVec() * moveForce;
}
if (throwTarget != GridCoordinates.InvalidGrid)
{
var moveForce = maxForce * FloatMath.Clamp(moveProb, 0, 100) / 150f;
var pos = ((throwTarget.Position - transform.GridPosition.Position).Normalized + direction.ToVec()).Normalized;
LinearVelocity = pos * moveForce;
}
pressureComponent.LastHighPressureMovementAirCycle = cycle;
else
{
var moveForce = MathF.Min(maxForce * FloatMath.Clamp(moveProb, 0, 100) / 2500f, 20f);
LinearVelocity = direction.ToVec() * moveForce;
}
pressureComponent.LastHighPressureMovementAirCycle = cycle;
}
}
}
@@ -72,7 +76,7 @@ namespace Content.Server.Atmos
if (ControlledComponent != null && !_physicsManager.IsWeightless(ControlledComponent.Owner.Transform.GridPosition))
{
LinearVelocity *= 0.85f;
if (LinearVelocity.Length < 1f)
if (MathF.Abs(LinearVelocity.Length) < 1f)
Stop();
}
}

View File

@@ -17,6 +17,7 @@ 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;
@@ -105,6 +106,7 @@ namespace Content.Server.Atmos
GridIndex = gridIndex;
GridIndices = gridIndices;
Air = mixture;
ResetTileAtmosInfo();
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
@@ -180,6 +182,8 @@ namespace Content.Server.Atmos
|| ContainerHelpers.IsInContainer(entity))
continue;
physics.WakeBody();
var pressureMovements = physics.EnsureController<HighPressureMovementController>();
if (pressure.LastHighPressureMovementAirCycle < _gridAtmosphereComponent.UpdateCounter)
{
@@ -328,7 +332,7 @@ namespace Content.Server.Atmos
var tile = tiles[i];
tile._tileAtmosInfo.FastDone = true;
if (!(tile._tileAtmosInfo.MoleDelta > 0)) continue;
Direction eligibleAdjBits = 0;
var eligibleDirections = new List<Direction>();
var amtEligibleAdj = 0;
foreach (var direction in Cardinal)
{
@@ -338,16 +342,17 @@ namespace Content.Server.Atmos
if (tile2._tileAtmosInfo.FastDone || tile2._tileAtmosInfo.LastQueueCycle != queueCycle)
continue;
eligibleAdjBits |= direction;
eligibleDirections.Add(direction);
amtEligibleAdj++;
}
if (amtEligibleAdj <= 0)
continue; // Oof we've painted ourselves into a corner. Bad luck. Next part will handle this.
var molesToMove = tile._tileAtmosInfo.MoleDelta / amtEligibleAdj;
foreach (var direction in Cardinal)
{
if ((eligibleAdjBits & direction) == 0 ||
if (eligibleDirections.Contains(direction) ||
!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue;
tile.AdjustEqMovement(direction, molesToMove);
tile._tileAtmosInfo.MoleDelta -= molesToMove;
@@ -394,13 +399,10 @@ namespace Content.Server.Atmos
foreach (var direction in Cardinal)
{
if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue;
if (giver._tileAtmosInfo.MoleDelta <= 0)
break; // We're done here now. Let's not do more work than needed.
if (tile2?._tileAtmosInfo == null || tile2._tileAtmosInfo.LastQueueCycle != queueCycle)
continue;
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();
@@ -458,7 +460,7 @@ namespace Content.Server.Atmos
var queueLength = 0;
queue[queueLength++] = taker;
taker._tileAtmosInfo.LastSlowQueueCycle = queueCycleSlow;
for (int i = 0; i < queueLength; i++)
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.
@@ -469,11 +471,8 @@ namespace Content.Server.Atmos
if (!tile._adjacentTiles.ContainsKey(direction)) continue;
var tile2 = tile._adjacentTiles[direction];
if (taker._tileAtmosInfo.MoleDelta >= 0)
break; // We're done here now. Let's not do more work than needed.
if (tile2?._tileAtmosInfo == null || tile2._tileAtmosInfo.LastQueueCycle != queueCycle)
continue;
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;
@@ -552,38 +551,34 @@ namespace Content.Server.Atmos
foreach (var direction in Cardinal)
{
var amount = _tileAtmosInfo[direction];
transferDirections[direction] = amount;
if (amount == 0) continue;
transferDirections[direction] = amount;
_tileAtmosInfo[direction] = 0;
hasTransferDirs = true;
}
if (!hasTransferDirs) return;
foreach (var direction in Cardinal)
foreach (var (direction, amount) in transferDirections)
{
var amount = transferDirections[direction];
if (!_adjacentTiles.TryGetValue(direction, out var tile) || tile.Air == null) continue;
if (amount > 0)
{
// Prevent infinite recursion.
tile._tileAtmosInfo[direction.GetOpposite()] = 0;
if (Air.TotalMoles < amount)
FinalizeEqNeighbors();
FinalizeEqNeighbors(transferDirections.Keys);
tile.Air.Merge(Air.Remove(amount));
UpdateVisuals();
tile.UpdateVisuals();
ConsiderPressureDifference(tile, amount);
ConsiderPressureDifference(direction, amount);
}
}
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void FinalizeEqNeighbors()
private void FinalizeEqNeighbors(IEnumerable<Direction> directions)
{
foreach (var direction in Cardinal)
foreach (var direction in directions)
{
var amount = _tileAtmosInfo[direction];
if(amount < 0 && _adjacentTiles.TryGetValue(direction, out var adjacent))
@@ -592,13 +587,13 @@ namespace Content.Server.Atmos
}
[MethodImpl(MethodImplOptions.AggressiveInlining)]
private void ConsiderPressureDifference(TileAtmosphere tile, float difference)
private void ConsiderPressureDifference(Direction direction, float difference)
{
_gridAtmosphereComponent.AddHighPressureDelta(this);
if (difference > PressureDifference)
{
PressureDifference = difference;
_pressureDirection = ((Vector2i) (GridIndices - tile.GridIndices)).GetCardinalDir();
_pressureDirection = difference < 0 ? direction.GetOpposite() : direction;
}
}
@@ -631,7 +626,7 @@ namespace Content.Server.Atmos
_currentCycle = fireCount;
var adjacentTileLength = 0;
foreach (var (_, enemyTile) in _adjacentTiles)
foreach (var (direction, enemyTile) in _adjacentTiles)
{
// If the tile is null or has no air, we don't do anything
if(enemyTile?.Air == null) continue;
@@ -681,11 +676,11 @@ namespace Content.Server.Atmos
// Space wind!
if (difference > 0)
{
ConsiderPressureDifference(enemyTile, difference);
ConsiderPressureDifference(direction, difference);
}
else
{
enemyTile.ConsiderPressureDifference(this, -difference);
enemyTile.ConsiderPressureDifference(direction.GetOpposite(), -difference);
}
LastShareCheck();
@@ -952,10 +947,10 @@ namespace Content.Server.Atmos
}
else
{
if (i > Atmospherics.ZumosHardTileLimit) continue;
if (i > Atmospherics.ZumosTileLimit) continue;
foreach (var direction in Cardinal)
{
if (!_adjacentTiles.TryGetValue(direction, out var tile2)) continue;
if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue;
if (tile2?.Air == null) continue;
if (tile2._tileAtmosInfo.LastQueueCycle == queueCycle) continue;
tile.ConsiderFirelocks(tile2);
@@ -985,7 +980,7 @@ namespace Content.Server.Atmos
var tile = progressionOrder[i];
foreach (var direction in Cardinal)
{
if (!_adjacentTiles.TryGetValue(direction, out var tile2)) continue;
if (!tile._adjacentTiles.TryGetValue(direction, out var tile2)) continue;
if (tile2?._tileAtmosInfo.LastQueueCycle != queueCycle) continue;
if (tile2._tileAtmosInfo.LastSlowQueueCycle == queueCycleSlow) continue;
if(tile2.Air.Immutable) continue;
@@ -998,14 +993,12 @@ namespace Content.Server.Atmos
}
}
for (int i = 0; i < progressionCount; i++)
for (var i = progressionCount - 1; i >= 0; i--)
{
var tile = progressionOrder[i];
if (tile._tileAtmosInfo.CurrentTransferDirection == Direction.Invalid) continue;
var hpdLength = _gridAtmosphereComponent.HighPressureDeltaCount;
var inHdp = _gridAtmosphereComponent.HasHighPressureDelta(tile);
if(!inHdp)
_gridAtmosphereComponent.AddHighPressureDelta(tile);
_gridAtmosphereComponent.AddHighPressureDelta(tile);
_gridAtmosphereComponent.AddActiveTile(tile);
if (!tile._adjacentTiles.TryGetValue(tile._tileAtmosInfo.CurrentTransferDirection, out var tile2) || tile2.Air == null) continue;
var sum = tile2.Air.TotalMoles;
totalGasesRemoved += sum;
@@ -1013,11 +1006,13 @@ namespace Content.Server.Atmos
tile2._tileAtmosInfo.CurrentTransferAmount += tile._tileAtmosInfo.CurrentTransferAmount;
tile.PressureDifference = tile._tileAtmosInfo.CurrentTransferAmount;
tile._pressureDirection = tile._tileAtmosInfo.CurrentTransferDirection;
if (tile2._tileAtmosInfo.CurrentTransferDirection == Direction.Invalid)
{
tile2.PressureDifference = tile2._tileAtmosInfo.CurrentTransferAmount;
tile2._pressureDirection = tile._tileAtmosInfo.CurrentTransferDirection;
}
tile.Air.Clear();
tile.UpdateVisuals();
tile.HandleDecompressionFloorRip(sum);
@@ -1026,7 +1021,8 @@ namespace Content.Server.Atmos
private void HandleDecompressionFloorRip(float sum)
{
if (sum > 20 && _robustRandom.Prob(FloatMath.Clamp(sum / 100, 0.005f, 0.5f)))
var chance = FloatMath.Clamp(sum / 500, 0.005f, 0.5f);
if (sum > 20 && _robustRandom.Prob(chance))
_gridAtmosphereComponent.PryTile(GridIndices);
}
@@ -1067,14 +1063,19 @@ namespace Content.Server.Atmos
{
foreach (var direction in Cardinal)
{
if(!_gridAtmosphereComponent.IsAirBlocked(GridIndices.Offset(direction)))
_adjacentTiles[direction] = _gridAtmosphereComponent.GetTile(GridIndices.Offset(direction));
if (!_gridAtmosphereComponent.IsAirBlocked(GridIndices.Offset(direction)))
{
var adjacent = _gridAtmosphereComponent.GetTile(GridIndices.Offset(direction));
_adjacentTiles[direction] = adjacent;
adjacent.UpdateAdjacent(direction.GetOpposite());
}
}
}
public void UpdateAdjacent(Direction direction)
{
_adjacentTiles[direction] = _gridAtmosphereComponent.GetTile(GridIndices.Offset(direction));
if (!_gridAtmosphereComponent.IsAirBlocked(GridIndices.Offset(direction)))
_adjacentTiles[direction] = _gridAtmosphereComponent.GetTile(GridIndices.Offset(direction));
}
private void LastShareCheck()