]> git.smokeofanarchy.ru Git - space-station-14.git/commitdiff
Allow protected grids to be repaired (#36989)
authorNemanja <98561806+EmoGarbage404@users.noreply.github.com>
Sat, 17 May 2025 01:54:27 +0000 (21:54 -0400)
committerGitHub <noreply@github.com>
Sat, 17 May 2025 01:54:27 +0000 (11:54 +1000)
* Allow protected grids to be repaired

* Probably implement it

---------

Co-authored-by: metalgearsloth <comedian_vs_clown@hotmail.com>
Content.Shared/RCD/Systems/RCDSystem.cs
Content.Shared/Tiles/FloorTileAttemptEvent.cs
Content.Shared/Tiles/FloorTileSystem.cs
Content.Shared/Tiles/ProtectedGridComponent.cs
Content.Shared/Tiles/ProtectedGridSystem.cs [new file with mode: 0644]

index 2025f2f3cca25eb0c629f1b9520d937d0f1a4e85..238daf6bf76c0d97345eb5cafa252643eeef06ed 100644 (file)
@@ -395,7 +395,7 @@ public sealed class RCDSystem : EntitySystem
         if (prototype.Mode == RcdMode.ConstructTile)
         {
             // Check rule: Tile placement is valid
-            if (!_floors.CanPlaceTile(gridUid, mapGrid, out var reason))
+            if (!_floors.CanPlaceTile(gridUid, mapGrid, tile.GridIndices, out var reason))
             {
                 if (popMsgs)
                     _popup.PopupClient(reason, uid, user);
index 7d4480f182b34928f14d4c3727bfa09797921bf9..4a7dfc3d40bf19f98e99ff3c9f8bdf8219d74a49 100644 (file)
@@ -4,4 +4,4 @@ namespace Content.Shared.Tiles;
 /// Raised directed on a grid when attempting a floor tile placement.
 /// </summary>
 [ByRefEvent]
-public record struct FloorTileAttemptEvent(bool Cancelled);
+public record struct FloorTileAttemptEvent(Vector2i GridIndices, bool Cancelled = false);
index 9b78904859ad78e0c942fd5d96c7e28541a44050..d798fa2473d867c146ada6245097f4a3c12e0abc 100644 (file)
@@ -126,14 +126,14 @@ public sealed class FloorTileSystem : EntitySystem
             if (mapGrid != null)
             {
                 var gridUid = location.EntityId;
+                var tile = _map.GetTileRef(gridUid, mapGrid, location);
 
-                if (!CanPlaceTile(gridUid, mapGrid, out var reason))
+                if (!CanPlaceTile(gridUid, mapGrid, tile.GridIndices, out var reason))
                 {
                     _popup.PopupClient(reason, args.User, args.User);
                     return;
                 }
 
-                var tile = _map.GetTileRef(gridUid, mapGrid, location);
                 var baseTurf = (ContentTileDefinition) _tileDefinitionManager[tile.Tile.TypeId];
 
                 if (HasBaseTurf(currentTileDefinition, baseTurf.ID))
@@ -182,12 +182,12 @@ public sealed class FloorTileSystem : EntitySystem
         _audio.PlayPredicted(placeSound, location, user);
     }
 
-    public bool CanPlaceTile(EntityUid gridUid, MapGridComponent component, [NotNullWhen(false)] out string? reason)
+    public bool CanPlaceTile(EntityUid gridUid, MapGridComponent component, Vector2i gridIndices, [NotNullWhen(false)] out string? reason)
     {
-        var ev = new FloorTileAttemptEvent();
+        var ev = new FloorTileAttemptEvent(gridIndices);
         RaiseLocalEvent(gridUid, ref ev);
 
-        if (HasComp<ProtectedGridComponent>(gridUid) || ev.Cancelled)
+        if (ev.Cancelled)
         {
             reason = Loc.GetString("invalid-floor-placement");
             return false;
index cf71edbe2bff6bdef204dca05abb086839f85a27..6b8e8df4ca45a644e33fa2fbd39914d5a57f9d73 100644 (file)
@@ -5,8 +5,13 @@ namespace Content.Shared.Tiles;
 /// <summary>
 /// Prevents floor tile updates when attached to a grid.
 /// </summary>
-[RegisterComponent, NetworkedComponent]
+[RegisterComponent, NetworkedComponent, AutoGenerateComponentState]
+[Access(typeof(ProtectedGridSystem))]
 public sealed partial class ProtectedGridComponent : Component
 {
-
+    /// <summary>
+    /// A bitmask of all the initial tiles on this grid.
+    /// </summary>
+    [DataField, AutoNetworkedField]
+    public Dictionary<Vector2i, ulong> BaseIndices = new();
 }
diff --git a/Content.Shared/Tiles/ProtectedGridSystem.cs b/Content.Shared/Tiles/ProtectedGridSystem.cs
new file mode 100644 (file)
index 0000000..0d6f5b7
--- /dev/null
@@ -0,0 +1,70 @@
+using System.Linq;
+using Robust.Shared.Map.Components;
+using Robust.Shared.Map.Enumerators;
+
+namespace Content.Shared.Tiles;
+
+public sealed class ProtectedGridSystem : EntitySystem
+{
+    [Dependency] private readonly SharedMapSystem _map = default!;
+
+    /// <inheritdoc/>
+    public override void Initialize()
+    {
+        SubscribeLocalEvent<ProtectedGridComponent, MapInitEvent>(OnMapInit);
+        SubscribeLocalEvent<ProtectedGridComponent, FloorTileAttemptEvent>(OnFloorTileAttempt);
+    }
+
+    private void OnMapInit(Entity<ProtectedGridComponent> ent, ref MapInitEvent args)
+    {
+        if (!TryComp<MapGridComponent>(ent, out var grid))
+            return;
+
+        // Engine default is currently 16x size chunks which means we can't just easily have 64bit flags.
+        var chunkEnumerator = new ChunkIndicesEnumerator(grid.LocalAABB, 8);
+
+        while (chunkEnumerator.MoveNext(out var chunk))
+        {
+            ulong flag = 0;
+
+            for (var x = 0; x < 8; x++)
+            {
+                for (var y = 0; y < 8; y++)
+                {
+                    var index = new Vector2i(x + chunk.Value.X * 8, y + chunk.Value.Y * 8);
+                    var tile = _map.GetTileRef(ent.Owner, grid, index);
+
+                    if (tile.Tile.IsEmpty)
+                        continue;
+
+                    var data = SharedMapSystem.ToBitmask(new Vector2i(x, y));
+
+                    flag |= data;
+                }
+            }
+
+            if (flag == 0)
+                continue;
+
+            ent.Comp.BaseIndices[chunk.Value] = flag;
+        }
+
+        Dirty(ent);
+    }
+
+    private void OnFloorTileAttempt(Entity<ProtectedGridComponent> ent, ref FloorTileAttemptEvent args)
+    {
+        var chunkOrigin = SharedMapSystem.GetChunkIndices(args.GridIndices, 8);
+
+        if (!ent.Comp.BaseIndices.TryGetValue(chunkOrigin, out var data))
+        {
+            args.Cancelled = true;
+            return;
+        }
+
+        if (SharedMapSystem.FromBitmask(args.GridIndices, data))
+        {
+            args.Cancelled = true;
+        }
+    }
+}