diff --git a/Content.Server/Atmos/HighPressureMovementController.cs b/Content.Server/Atmos/HighPressureMovementController.cs index 60086206b9..2e27f513ad 100644 --- a/Content.Server/Atmos/HighPressureMovementController.cs +++ b/Content.Server/Atmos/HighPressureMovementController.cs @@ -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(); } } diff --git a/Content.Server/Atmos/TileAtmosphere.cs b/Content.Server/Atmos/TileAtmosphere.cs index b01bba9baa..8e634a1c7d 100644 --- a/Content.Server/Atmos/TileAtmosphere.cs +++ b/Content.Server/Atmos/TileAtmosphere.cs @@ -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(); 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(); 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 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()