]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Fix Atmospherics dP not trolling partially airtight entities (#40435)
authorArtisticRoomba <145879011+ArtisticRoomba@users.noreply.github.com>
Tue, 14 Oct 2025 22:35:25 +0000 (15:35 -0700)
committerGitHub <noreply@github.com>
Tue, 14 Oct 2025 22:35:25 +0000 (22:35 +0000)
* Fix dP not trolling partially airtight entities

* Assumptions in atmospherics are the root of all evil

Content.IntegrationTests/Tests/Atmos/DeltaPressureTest.cs
Content.Server/Atmos/Components/DeltaPressureComponent.cs
Content.Server/Atmos/EntitySystems/AtmosphereSystem.API.cs
Content.Server/Atmos/EntitySystems/AtmosphereSystem.DeltaPressure.cs
Content.Server/Atmos/EntitySystems/DeltaPressureSystem.cs

index 9dda130847d5d65ce5fb0aa6866d2ba1aebd5487..839e0ea8972723771858b14d5d4f730f4cfc8df1 100644 (file)
@@ -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
index 8031cd876da45c427ea1c71b66e4848819fb3bab..0d2debe08ab6cd8fa0f743862201509ee8773e99 100644 (file)
@@ -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;
 
index 87cfce135d7a5e94db33da259c1844221646b005..29f091f34078c2c3d0a6cc313505ed1a4d42c1fb 100644 (file)
@@ -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;
 
index 9d72b195fefcb1d87051d8875467c59f88bccb97..efddcaf1a7bb8f7445f97bef7bca5c2a62e16295 100644 (file)
@@ -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];
index a6cbec0d0c834f9f7aa7641fb73c2c0caafe1a12..dd7091c270ff88f44dc9a1eb221c467db967e92d 100644 (file)
@@ -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);
     }