Fix Atmospherics dP not trolling partially airtight entities (#40435)
* Fix dP not trolling partially airtight entities * Assumptions in atmospherics are the root of all evil
This commit is contained in:
@@ -93,6 +93,12 @@ public sealed class DeltaPressureTest
|
||||
|
||||
private readonly ResPath _testMap = new("Maps/Test/Atmospherics/DeltaPressure/deltapressuretest.yml");
|
||||
|
||||
// TODO ATMOS TESTS
|
||||
// - Check for directional windows (partial airtight ents) properly computing pressure differences
|
||||
// - Check for multi-tick damage (window with n damage threshold should take n ticks to destroy)
|
||||
// - Check that all maps do not explode into a million pieces on load due to dP
|
||||
// - Ensure that all tests work for a map that has an origin at a non zero coordinate
|
||||
|
||||
/// <summary>
|
||||
/// Asserts that an entity with a DeltaPressureComponent with autoJoinProcessingList
|
||||
/// set to true is automatically added to the DeltaPressure processing list
|
||||
|
||||
@@ -34,18 +34,13 @@ public sealed partial class DeltaPressureComponent : Component
|
||||
[Access(typeof(DeltaPressureSystem), typeof(AtmosphereSystem))]
|
||||
public bool IsTakingDamage;
|
||||
|
||||
/// <summary>
|
||||
/// The current cached position of this entity on the grid.
|
||||
/// Updated via MoveEvent.
|
||||
/// </summary>
|
||||
[DataField(readOnly: true)]
|
||||
public Vector2i CurrentPosition = Vector2i.Zero;
|
||||
|
||||
/// <summary>
|
||||
/// The grid this entity is currently joined to for processing.
|
||||
/// Required for proper deletion, as we cannot reference the grid
|
||||
/// for removal while the entity is being deleted.
|
||||
/// </summary>
|
||||
/// <remarks>Note that while <see cref="AirtightComponent"/> already stores the grid,
|
||||
/// we cannot trust it to be available on init or when the entity is being deleted. Tragic.</remarks>
|
||||
[DataField]
|
||||
public EntityUid? GridUid;
|
||||
|
||||
|
||||
@@ -355,10 +355,6 @@ public partial class AtmosphereSystem
|
||||
grid.Comp.DeltaPressureEntityLookup[ent.Owner] = grid.Comp.DeltaPressureEntities.Count;
|
||||
grid.Comp.DeltaPressureEntities.Add(ent);
|
||||
|
||||
ent.Comp.CurrentPosition = _map.CoordinatesToTile(grid,
|
||||
Comp<MapGridComponent>(grid),
|
||||
xform.Coordinates);
|
||||
|
||||
ent.Comp.GridUid = grid.Owner;
|
||||
ent.Comp.InProcessingList = true;
|
||||
|
||||
|
||||
@@ -39,11 +39,13 @@ public sealed partial class AtmosphereSystem
|
||||
so simple vector operations like min/max/abs can be performed on them.
|
||||
*/
|
||||
|
||||
var airtightComp = _airtightQuery.Comp(ent);
|
||||
var currentPos = airtightComp.LastPosition.Tile;
|
||||
var tiles = new TileAtmosphere?[Atmospherics.Directions];
|
||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
var direction = (AtmosDirection)(1 << i);
|
||||
var offset = ent.Comp.CurrentPosition.Offset(direction);
|
||||
var offset = currentPos.Offset(direction);
|
||||
tiles[i] = gridAtmosComp.Tiles.GetValueOrDefault(offset);
|
||||
}
|
||||
|
||||
@@ -51,6 +53,21 @@ public sealed partial class AtmosphereSystem
|
||||
|
||||
GetBulkTileAtmospherePressures(tiles, pressures);
|
||||
|
||||
// This entity could be airtight but still be able to contain air on the tile it's on (ex. directional windows).
|
||||
// As such, substitute the pressure of the pressure on top of the entity for the directions that it can accept air from.
|
||||
// (Or rather, don't do so for directions that it blocks air from.)
|
||||
if (!airtightComp.NoAirWhenFullyAirBlocked)
|
||||
{
|
||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
||||
{
|
||||
var direction = (AtmosDirection)(1 << i);
|
||||
if (!airtightComp.AirBlockedDirection.HasFlag(direction))
|
||||
{
|
||||
pressures[i] = gridAtmosComp.Tiles.GetValueOrDefault(currentPos)?.Air?.Pressure ?? 0f;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Span<float> opposingGroupA = stackalloc float[DeltaPressurePairCount];
|
||||
Span<float> opposingGroupB = stackalloc float[DeltaPressurePairCount];
|
||||
Span<float> opposingGroupMax = stackalloc float[DeltaPressurePairCount];
|
||||
|
||||
@@ -17,7 +17,6 @@ namespace Content.Server.Atmos.EntitySystems;
|
||||
public sealed class DeltaPressureSystem : EntitySystem
|
||||
{
|
||||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
||||
[Dependency] private readonly SharedMapSystem _map = default!;
|
||||
|
||||
public override void Initialize()
|
||||
{
|
||||
@@ -26,29 +25,17 @@ public sealed class DeltaPressureSystem : EntitySystem
|
||||
SubscribeLocalEvent<DeltaPressureComponent, ComponentInit>(OnComponentInit);
|
||||
SubscribeLocalEvent<DeltaPressureComponent, ComponentShutdown>(OnComponentShutdown);
|
||||
SubscribeLocalEvent<DeltaPressureComponent, ExaminedEvent>(OnExamined);
|
||||
SubscribeLocalEvent<DeltaPressureComponent, MoveEvent>(OnMoveEvent);
|
||||
|
||||
SubscribeLocalEvent<DeltaPressureComponent, GridUidChangedEvent>(OnGridChanged);
|
||||
}
|
||||
|
||||
private void OnMoveEvent(Entity<DeltaPressureComponent> ent, ref MoveEvent args)
|
||||
{
|
||||
var xform = Transform(ent);
|
||||
// May move off-grid, so, might as well protect against that.
|
||||
if (!TryComp<MapGridComponent>(xform.GridUid, out var mapGridComponent))
|
||||
{
|
||||
return;
|
||||
}
|
||||
|
||||
ent.Comp.CurrentPosition = _map.CoordinatesToTile(xform.GridUid.Value, mapGridComponent, args.NewPosition);
|
||||
}
|
||||
|
||||
private void OnComponentInit(Entity<DeltaPressureComponent> ent, ref ComponentInit args)
|
||||
{
|
||||
var xform = Transform(ent);
|
||||
if (xform.GridUid == null)
|
||||
return;
|
||||
|
||||
EnsureComp<AirtightComponent>(ent);
|
||||
_atmosphereSystem.TryAddDeltaPressureEntity(xform.GridUid.Value, ent);
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user