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");
|
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>
|
/// <summary>
|
||||||
/// Asserts that an entity with a DeltaPressureComponent with autoJoinProcessingList
|
/// Asserts that an entity with a DeltaPressureComponent with autoJoinProcessingList
|
||||||
/// set to true is automatically added to the DeltaPressure processing list
|
/// 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))]
|
[Access(typeof(DeltaPressureSystem), typeof(AtmosphereSystem))]
|
||||||
public bool IsTakingDamage;
|
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>
|
/// <summary>
|
||||||
/// The grid this entity is currently joined to for processing.
|
/// The grid this entity is currently joined to for processing.
|
||||||
/// Required for proper deletion, as we cannot reference the grid
|
/// Required for proper deletion, as we cannot reference the grid
|
||||||
/// for removal while the entity is being deleted.
|
/// for removal while the entity is being deleted.
|
||||||
/// </summary>
|
/// </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]
|
[DataField]
|
||||||
public EntityUid? GridUid;
|
public EntityUid? GridUid;
|
||||||
|
|
||||||
|
|||||||
@@ -355,10 +355,6 @@ public partial class AtmosphereSystem
|
|||||||
grid.Comp.DeltaPressureEntityLookup[ent.Owner] = grid.Comp.DeltaPressureEntities.Count;
|
grid.Comp.DeltaPressureEntityLookup[ent.Owner] = grid.Comp.DeltaPressureEntities.Count;
|
||||||
grid.Comp.DeltaPressureEntities.Add(ent);
|
grid.Comp.DeltaPressureEntities.Add(ent);
|
||||||
|
|
||||||
ent.Comp.CurrentPosition = _map.CoordinatesToTile(grid,
|
|
||||||
Comp<MapGridComponent>(grid),
|
|
||||||
xform.Coordinates);
|
|
||||||
|
|
||||||
ent.Comp.GridUid = grid.Owner;
|
ent.Comp.GridUid = grid.Owner;
|
||||||
ent.Comp.InProcessingList = true;
|
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.
|
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];
|
var tiles = new TileAtmosphere?[Atmospherics.Directions];
|
||||||
for (var i = 0; i < Atmospherics.Directions; i++)
|
for (var i = 0; i < Atmospherics.Directions; i++)
|
||||||
{
|
{
|
||||||
var direction = (AtmosDirection)(1 << i);
|
var direction = (AtmosDirection)(1 << i);
|
||||||
var offset = ent.Comp.CurrentPosition.Offset(direction);
|
var offset = currentPos.Offset(direction);
|
||||||
tiles[i] = gridAtmosComp.Tiles.GetValueOrDefault(offset);
|
tiles[i] = gridAtmosComp.Tiles.GetValueOrDefault(offset);
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -51,6 +53,21 @@ public sealed partial class AtmosphereSystem
|
|||||||
|
|
||||||
GetBulkTileAtmospherePressures(tiles, pressures);
|
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> opposingGroupA = stackalloc float[DeltaPressurePairCount];
|
||||||
Span<float> opposingGroupB = stackalloc float[DeltaPressurePairCount];
|
Span<float> opposingGroupB = stackalloc float[DeltaPressurePairCount];
|
||||||
Span<float> opposingGroupMax = stackalloc float[DeltaPressurePairCount];
|
Span<float> opposingGroupMax = stackalloc float[DeltaPressurePairCount];
|
||||||
|
|||||||
@@ -17,7 +17,6 @@ namespace Content.Server.Atmos.EntitySystems;
|
|||||||
public sealed class DeltaPressureSystem : EntitySystem
|
public sealed class DeltaPressureSystem : EntitySystem
|
||||||
{
|
{
|
||||||
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
[Dependency] private readonly AtmosphereSystem _atmosphereSystem = default!;
|
||||||
[Dependency] private readonly SharedMapSystem _map = default!;
|
|
||||||
|
|
||||||
public override void Initialize()
|
public override void Initialize()
|
||||||
{
|
{
|
||||||
@@ -26,29 +25,17 @@ public sealed class DeltaPressureSystem : EntitySystem
|
|||||||
SubscribeLocalEvent<DeltaPressureComponent, ComponentInit>(OnComponentInit);
|
SubscribeLocalEvent<DeltaPressureComponent, ComponentInit>(OnComponentInit);
|
||||||
SubscribeLocalEvent<DeltaPressureComponent, ComponentShutdown>(OnComponentShutdown);
|
SubscribeLocalEvent<DeltaPressureComponent, ComponentShutdown>(OnComponentShutdown);
|
||||||
SubscribeLocalEvent<DeltaPressureComponent, ExaminedEvent>(OnExamined);
|
SubscribeLocalEvent<DeltaPressureComponent, ExaminedEvent>(OnExamined);
|
||||||
SubscribeLocalEvent<DeltaPressureComponent, MoveEvent>(OnMoveEvent);
|
|
||||||
|
|
||||||
SubscribeLocalEvent<DeltaPressureComponent, GridUidChangedEvent>(OnGridChanged);
|
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)
|
private void OnComponentInit(Entity<DeltaPressureComponent> ent, ref ComponentInit args)
|
||||||
{
|
{
|
||||||
var xform = Transform(ent);
|
var xform = Transform(ent);
|
||||||
if (xform.GridUid == null)
|
if (xform.GridUid == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
EnsureComp<AirtightComponent>(ent);
|
||||||
_atmosphereSystem.TryAddDeltaPressureEntity(xform.GridUid.Value, ent);
|
_atmosphereSystem.TryAddDeltaPressureEntity(xform.GridUid.Value, ent);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user