]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Spreaders travels across connected grids and SpreaderIgnore tag (#15419)
authormetalgearsloth <31366439+metalgearsloth@users.noreply.github.com>
Mon, 24 Apr 2023 20:04:49 +0000 (06:04 +1000)
committerGitHub <noreply@github.com>
Mon, 24 Apr 2023 20:04:49 +0000 (16:04 -0400)
Content.Server/Fluids/EntitySystems/PuddleSystem.cs
Content.Server/Fluids/EntitySystems/SmokeSystem.cs
Content.Server/Spreader/KudzuSystem.cs
Content.Server/Spreader/SpreadNeighborsEvent.cs
Content.Server/Spreader/SpreaderSystem.cs
Resources/Prototypes/Entities/Structures/Doors/Airlocks/shuttle.yml
Resources/Prototypes/Entities/Structures/Piping/Atmospherics/special.yml
Resources/Prototypes/tags.yml

index c444afa83464e48bd5041f2bc946316801d6fb84..902f2188e296140633d0681fae3d837b596c6c23 100644 (file)
@@ -86,14 +86,6 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
             return;
         }
 
-        var xform = Transform(uid);
-
-        if (!TryComp<MapGridComponent>(xform.GridUid, out var grid))
-        {
-            RemCompDeferred<EdgeSpreaderComponent>(uid);
-            return;
-        }
-
         var puddleQuery = GetEntityQuery<PuddleComponent>();
 
         // For overflows, we never go to a fully evaporative tile just to avoid continuously having to mop it.
@@ -152,10 +144,10 @@ public sealed partial class PuddleSystem : SharedPuddleSystem
             spillCount = Math.Min(args.NeighborFreeTiles.Count, spillCount);
             var spillAmount = overflow.Volume / spillCount;
 
-            foreach (var tile in args.NeighborFreeTiles)
+            foreach (var neighbor in args.NeighborFreeTiles)
             {
                 var split = overflow.SplitSolution(spillAmount);
-                TrySpillAt(grid.GridTileToLocal(tile), split, out _, false);
+                TrySpillAt(neighbor.Grid.GridTileToLocal(neighbor.Tile), split, out _, false);
                 args.Updates--;
 
                 if (args.Updates <= 0)
index 2a6aa936b966130994d5b70d6bfb9ff2adf7fb77..b489cbc2a4d674a4b7dd36ee200142b30e5146d1 100644 (file)
@@ -73,7 +73,6 @@ public sealed class SmokeSystem : EntitySystem
     private void OnSmokeSpread(EntityUid uid, SmokeComponent component, ref SpreadNeighborsEvent args)
     {
         if (component.SpreadAmount == 0 ||
-            args.Grid == null ||
             !_solutionSystem.TryGetSolution(uid, SmokeComponent.SolutionName, out var solution) ||
             args.NeighborFreeTiles.Count == 0)
         {
@@ -94,9 +93,9 @@ public sealed class SmokeSystem : EntitySystem
         var smokePerSpread = component.SpreadAmount / args.NeighborFreeTiles.Count;
         component.SpreadAmount -= smokePerSpread;
 
-        foreach (var tile in args.NeighborFreeTiles)
+        foreach (var neighbor in args.NeighborFreeTiles)
         {
-            var coords = args.Grid.GridTileToLocal(tile);
+            var coords = neighbor.Grid.GridTileToLocal(neighbor.Tile);
             var ent = Spawn(prototype.ID, coords.SnapToGrid());
             var neighborSmoke = EnsureComp<SmokeComponent>(ent);
             neighborSmoke.SpreadAmount = Math.Max(0, smokePerSpread - 1);
index 49b1a84d56be31d07c50127f0c69a1e6564679de..407d99e478c2c37fc43d054b1834d46226809fcb 100644 (file)
@@ -28,7 +28,7 @@ public sealed class KudzuSystem : EntitySystem
             return;
         }
 
-        if (args.NeighborFreeTiles.Count == 0 || args.Grid == null)
+        if (args.NeighborFreeTiles.Count == 0)
         {
             RemCompDeferred<EdgeSpreaderComponent>(uid);
             return;
@@ -47,7 +47,7 @@ public sealed class KudzuSystem : EntitySystem
 
         foreach (var neighbor in args.NeighborFreeTiles)
         {
-            var neighborUid = Spawn(prototype, args.Grid.GridTileToLocal(neighbor));
+            var neighborUid = Spawn(prototype, neighbor.Grid.GridTileToLocal(neighbor.Tile));
             EnsureComp<EdgeSpreaderComponent>(neighborUid);
             args.Updates--;
 
index 723e510d601042dd1f9aa1a5970b4eb0bead1b98..0cee55b5880ac3eac9d9883ede4e61a76a07c34a 100644 (file)
@@ -10,9 +10,7 @@ namespace Content.Server.Spreader;
 [ByRefEvent]
 public record struct SpreadNeighborsEvent
 {
-    public MapGridComponent? Grid;
-    public ValueList<Vector2i> NeighborFreeTiles;
-    public ValueList<Vector2i> NeighborOccupiedTiles;
+    public ValueList<(MapGridComponent Grid, Vector2i Tile)> NeighborFreeTiles;
     public ValueList<EntityUid> Neighbors;
 
     /// <summary>
@@ -20,4 +18,4 @@ public record struct SpreadNeighborsEvent
     /// Subscribers can handle as they wish.
     /// </summary>
     public int Updates;
-}
\ No newline at end of file
+}
index a9d4d496280d9c4e49effbe8485839129f01dc06..b39f83e4a283d33258c47b62c60573156cbc01dd 100644 (file)
@@ -2,8 +2,10 @@ using Content.Server.Atmos.Components;
 using Content.Server.Atmos.EntitySystems;
 using Content.Server.NodeContainer;
 using Content.Server.NodeContainer.NodeGroups;
+using Content.Server.Shuttles.Components;
 using Content.Shared.Atmos;
 using Content.Shared.Spreader;
+using Content.Shared.Tag;
 using Robust.Shared.Collections;
 using Robust.Shared.Map;
 using Robust.Shared.Map.Components;
@@ -27,6 +29,8 @@ public sealed class SpreaderSystem : EntitySystem
 
     private readonly List<string> _spreaderGroups = new();
 
+    private const string IgnoredTag = "SpreaderIgnore";
+
     /// <inheritdoc/>
     public override void Initialize()
     {
@@ -178,15 +182,11 @@ public sealed class SpreaderSystem : EntitySystem
 
     private void Spread(EntityUid uid, SpreaderNode node, INodeGroup group, ref int updates)
     {
-        GetNeighbors(uid, node.Name, out var freeTiles, out var occupiedTiles, out var neighbors);
-
-        TryComp<MapGridComponent>(Transform(uid).GridUid, out var grid);
+        GetNeighbors(uid, node.Name, out var freeTiles, out _, out var neighbors);
 
         var ev = new SpreadNeighborsEvent()
         {
-            Grid = grid,
             NeighborFreeTiles = freeTiles,
-            NeighborOccupiedTiles = occupiedTiles,
             Neighbors = neighbors,
             Updates = updates,
         };
@@ -198,9 +198,9 @@ public sealed class SpreaderSystem : EntitySystem
     /// <summary>
     /// Gets the neighboring node data for the specified entity and the specified node group.
     /// </summary>
-    public void GetNeighbors(EntityUid uid, string groupName, out ValueList<Vector2i> freeTiles, out ValueList<Vector2i> occupiedTiles, out ValueList<EntityUid> neighbors)
+    public void GetNeighbors(EntityUid uid, string groupName, out ValueList<(MapGridComponent Grid, Vector2i Tile)> freeTiles, out ValueList<Vector2i> occupiedTiles, out ValueList<EntityUid> neighbors)
     {
-        freeTiles = new ValueList<Vector2i>();
+        freeTiles = new ValueList<(MapGridComponent Grid, Vector2i Tile)>();
         occupiedTiles = new ValueList<Vector2i>();
         neighbors = new ValueList<EntityUid>();
 
@@ -213,47 +213,82 @@ public sealed class SpreaderSystem : EntitySystem
         var tile = grid.TileIndicesFor(transform.Coordinates);
         var nodeQuery = GetEntityQuery<NodeContainerComponent>();
         var airtightQuery = GetEntityQuery<AirtightComponent>();
+        var dockQuery = GetEntityQuery<DockingComponent>();
+        var xformQuery = GetEntityQuery<TransformComponent>();
+        var tagQuery = GetEntityQuery<TagComponent>();
+        var blockedAtmosDirs = AtmosDirection.Invalid;
+
+        // Due to docking ports they may not necessarily be opposite directions.
+        var neighborTiles = new ValueList<(MapGridComponent grid, Vector2i Indices, AtmosDirection OtherDir, AtmosDirection OurDir)>();
+
+        // Check if anything on our own tile blocking that direction.
+        var ourEnts = grid.GetAnchoredEntitiesEnumerator(tile);
+
+        while (ourEnts.MoveNext(out var ent))
+        {
+            // Spread via docks in a special-case.
+            if (dockQuery.TryGetComponent(ent, out var dock) &&
+                dock.Docked &&
+                xformQuery.TryGetComponent(ent, out var xform) &&
+                xformQuery.TryGetComponent(dock.DockedWith, out var dockedXform) &&
+                TryComp<MapGridComponent>(dockedXform.GridUid, out var dockedGrid))
+            {
+                neighborTiles.Add((dockedGrid, dockedGrid.CoordinatesToTile(dockedXform.Coordinates), xform.LocalRotation.ToAtmosDirection(), dockedXform.LocalRotation.ToAtmosDirection()));
+            }
 
+            // If we're on a blocked tile work out which directions we can go.
+            if (!airtightQuery.TryGetComponent(ent, out var airtight) || !airtight.AirBlocked ||
+                tagQuery.TryGetComponent(ent, out var tags) && tags.Tags.Contains(IgnoredTag))
+            {
+                continue;
+            }
+
+            foreach (var value in new[] { AtmosDirection.North, AtmosDirection.East, AtmosDirection.South, AtmosDirection.West})
+            {
+                if ((value & airtight.AirBlockedDirection) == 0x0)
+                    continue;
+
+                blockedAtmosDirs |= value;
+                break;
+            }
+            break;
+        }
+
+        // Add the normal neighbors.
         for (var i = 0; i < 4; i++)
         {
             var direction = (Direction) (i * 2);
+            var atmosDir = direction.ToAtmosDirection();
             var neighborPos = SharedMapSystem.GetDirection(tile, direction);
+            neighborTiles.Add((grid, neighborPos, atmosDir, atmosDir.GetOpposite()));
+        }
 
-            if (!grid.TryGetTileRef(neighborPos, out var tileRef) || tileRef.Tile.IsEmpty)
+        foreach (var (neighborGrid, neighborPos, ourAtmosDir, otherAtmosDir) in neighborTiles)
+        {
+            // This tile is blocked to that direction.
+            if ((blockedAtmosDirs & ourAtmosDir) != 0x0)
+                continue;
+
+            if (!neighborGrid.TryGetTileRef(neighborPos, out var tileRef) || tileRef.Tile.IsEmpty)
                 continue;
 
             var directionEnumerator =
-                grid.GetAnchoredEntitiesEnumerator(neighborPos);
+                neighborGrid.GetAnchoredEntitiesEnumerator(neighborPos);
             var occupied = false;
 
             while (directionEnumerator.MoveNext(out var ent))
             {
-                if (airtightQuery.TryGetComponent(ent, out var airtight) && airtight.AirBlocked)
+                if (!airtightQuery.TryGetComponent(ent, out var airtight) || !airtight.AirBlocked ||
+                    tagQuery.TryGetComponent(ent, out var tags) && tags.Tags.Contains(IgnoredTag))
                 {
-                    // Check if air direction matters.
-                    var blocked = false;
-
-                    foreach (var value in new[] { AtmosDirection.North, AtmosDirection.East})
-                    {
-                        if ((value & airtight.AirBlockedDirection) == 0x0)
-                            continue;
-
-                        var airDirection = value.ToDirection();
-                        var oppositeDirection = value.ToDirection().GetOpposite();
-
-                        if (direction != airDirection && direction != oppositeDirection)
-                            continue;
-
-                        blocked = true;
-                        break;
-                    }
+                    continue;
+                }
 
-                    if (!blocked)
-                        continue;
+                if ((airtight.AirBlockedDirection & otherAtmosDir) == 0x0)
+                    continue;
 
-                    occupied = true;
-                    break;
-                }
+                occupied = true;
+                break;
             }
 
             if (occupied)
@@ -261,7 +296,7 @@ public sealed class SpreaderSystem : EntitySystem
 
             var oldCount = occupiedTiles.Count;
             directionEnumerator =
-                grid.GetAnchoredEntitiesEnumerator(neighborPos);
+                neighborGrid.GetAnchoredEntitiesEnumerator(neighborPos);
 
             while (directionEnumerator.MoveNext(out var ent))
             {
@@ -277,7 +312,7 @@ public sealed class SpreaderSystem : EntitySystem
             }
 
             if (oldCount == occupiedTiles.Count)
-                freeTiles.Add(neighborPos);
+                freeTiles.Add((neighborGrid, neighborPos));
         }
     }
 
index 117329cdd91a861b95516311144efb53fa9791ac..a06578fc4622ae7be754575658a488d595ff3a42 100644 (file)
       path: /Audio/Machines/airlock_deny.ogg
   - type: Airtight
     fixVacuum: true
-    airBlockedDirection:
-      - East
-      - West
-      - South
+    noAirWhenFullyAirBlocked: false
   - type: Tag
     tags:
       - ForceNoFixRotations
index c597788c6c3665d5804e0e679b851226e7dfeb54..ceae3eed4bada8b7c4cd007031354a1949ddf762 100644 (file)
@@ -22,3 +22,6 @@
   - type: Airtight
     noAirWhenFullyAirBlocked: false
   - type: Clickable
+  - type: Tag
+    tags:
+      - SpreaderIgnore
index ae37ea4f3f08423d74027f0c24ddd184db9fb02e..d1d13271d8d4d6f4ce772de06ed324e5428b2448 100644 (file)
 - type: Tag
   id: SpeedLoaderRifle
 
+- type: Tag
+  id: SpreaderIgnore
+
 - type: Tag
   id: StringInstrument