Atmos Delta-Pressure Window Shattering (#39238)

This PR adds delta-pressure damage. In short, airtight structures can now take damage proportional to the difference in pressures between the sides of the structure.
This commit is contained in:
ArtisticRoomba
2025-09-03 16:58:48 -07:00
committed by GitHub
parent f63eb2e97a
commit 20f2cb920b
22 changed files with 1685 additions and 1 deletions

View File

@@ -467,6 +467,66 @@ namespace Content.Server.Atmos.EntitySystems
return true;
}
/// <summary>
/// Processes all entities with a <see cref="DeltaPressureComponent"/>, doing damage to them
/// depending on certain pressure differential conditions.
/// </summary>
/// <returns>True if we've finished processing all entities that required processing this run,
/// otherwise, false.</returns>
private bool ProcessDeltaPressure(Entity<GridAtmosphereComponent, GasTileOverlayComponent, MapGridComponent, TransformComponent> ent)
{
var atmosphere = ent.Comp1;
var count = atmosphere.DeltaPressureEntities.Count;
if (!atmosphere.ProcessingPaused)
{
atmosphere.DeltaPressureCursor = 0;
atmosphere.DeltaPressureDamageResults.Clear();
}
var remaining = count - atmosphere.DeltaPressureCursor;
var batchSize = Math.Max(50, DeltaPressureParallelProcessPerIteration);
var toProcess = Math.Min(batchSize, remaining);
var timeCheck1 = 0;
while (atmosphere.DeltaPressureCursor < count)
{
var job = new DeltaPressureParallelJob(this,
atmosphere,
atmosphere.DeltaPressureCursor,
DeltaPressureParallelBatchSize);
_parallel.ProcessNow(job, toProcess);
atmosphere.DeltaPressureCursor += toProcess;
if (timeCheck1++ < LagCheckIterations)
continue;
timeCheck1 = 0;
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
return false;
}
var timeCheck2 = 0;
while (atmosphere.DeltaPressureDamageResults.TryDequeue(out var result))
{
PerformDamage(result.Ent,
result.Pressure,
result.DeltaPressure);
if (timeCheck2++ < LagCheckIterations)
continue;
timeCheck2 = 0;
// Process the rest next time.
if (_simulationStopwatch.Elapsed.TotalMilliseconds >= AtmosMaxProcessTime)
{
return false;
}
}
return true;
}
private bool ProcessPipeNets(GridAtmosphereComponent atmosphere)
{
if (!atmosphere.ProcessingPaused)
@@ -510,6 +570,8 @@ namespace Content.Server.Atmos.EntitySystems
num--;
if (!ExcitedGroups)
num--;
if (!DeltaPressureDamage)
num--;
if (!Superconduction)
num--;
return num * AtmosTime;
@@ -653,6 +715,18 @@ namespace Content.Server.Atmos.EntitySystems
return;
}
atmosphere.ProcessingPaused = false;
atmosphere.State = DeltaPressureDamage
? AtmosphereProcessingState.DeltaPressure
: AtmosphereProcessingState.Hotspots;
continue;
case AtmosphereProcessingState.DeltaPressure:
if (!ProcessDeltaPressure(ent))
{
atmosphere.ProcessingPaused = true;
return;
}
atmosphere.ProcessingPaused = false;
atmosphere.State = AtmosphereProcessingState.Hotspots;
continue;
@@ -721,6 +795,7 @@ namespace Content.Server.Atmos.EntitySystems
ActiveTiles,
ExcitedGroups,
HighPressureDelta,
DeltaPressure,
Hotspots,
Superconductivity,
PipeNet,