Fixes explosive depressurization and improves high pressure movements (#1683)
This commit is contained in:
committed by
GitHub
parent
33baa73f06
commit
a7fc2bccbd
@@ -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();
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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()
|
||||
|
||||
Reference in New Issue
Block a user