From 78bea7312e0046381d18f4005c8f165abba151a4 Mon Sep 17 00:00:00 2001 From: Leon Friedrich <60421075+ElectroJr@users.noreply.github.com> Date: Thu, 24 Nov 2022 15:38:09 +1300 Subject: [PATCH] Fix grid chunk double subscription (#3526) --- Robust.Client/Console/Commands/Debug.cs | 2 +- .../EntitySystems/MapLoaderSystem.cs | 2 +- Robust.Shared/GameObjects/IComponent.cs | 2 +- .../Map/Components/MapGridComponent.cs | 17 ++++++++++------- Robust.Shared/Map/MapChunk.cs | 4 ++++ Robust.Shared/Map/MapManager.Queries.cs | 2 +- 6 files changed, 18 insertions(+), 11 deletions(-) diff --git a/Robust.Client/Console/Commands/Debug.cs b/Robust.Client/Console/Commands/Debug.cs index 2e8c0d665..8cb84f618 100644 --- a/Robust.Client/Console/Commands/Debug.cs +++ b/Robust.Client/Console/Commands/Debug.cs @@ -625,7 +625,7 @@ namespace Robust.Client.Console.Commands } var chunkIndex = grid.LocalToChunkIndices(grid.MapToGrid(mousePos)); - var chunk = grid.GetChunk(chunkIndex); + var chunk = grid.GetOrAddChunk(chunkIndex); shell.WriteLine($"worldBounds: {grid.CalcWorldAABB(chunk)} localBounds: {chunk.CachedBounds}"); } diff --git a/Robust.Server/GameObjects/EntitySystems/MapLoaderSystem.cs b/Robust.Server/GameObjects/EntitySystems/MapLoaderSystem.cs index 54d370371..4116ef99b 100644 --- a/Robust.Server/GameObjects/EntitySystems/MapLoaderSystem.cs +++ b/Robust.Server/GameObjects/EntitySystems/MapLoaderSystem.cs @@ -622,7 +622,7 @@ public sealed class MapLoaderSystem : EntitySystem foreach (var chunkNode in yamlGridChunks.Cast()) { var (chunkOffsetX, chunkOffsetY) = _serManager.Read(chunkNode["ind"]); - var chunk = grid.GetChunk(chunkOffsetX, chunkOffsetY); + var chunk = grid.GetOrAddChunk(chunkOffsetX, chunkOffsetY); _serManager.Read(chunkNode, _context, value: chunk); } } diff --git a/Robust.Shared/GameObjects/IComponent.cs b/Robust.Shared/GameObjects/IComponent.cs index bc510cbea..4d9c5bc0d 100644 --- a/Robust.Shared/GameObjects/IComponent.cs +++ b/Robust.Shared/GameObjects/IComponent.cs @@ -40,7 +40,7 @@ namespace Robust.Shared.GameObjects EntityUid Owner { get; } /// - /// Component has been properly initialized. + /// Component has been (or is currently being) initialized. /// bool Initialized { get; } diff --git a/Robust.Shared/Map/Components/MapGridComponent.cs b/Robust.Shared/Map/Components/MapGridComponent.cs index e0a5f7669..fbf6d0795 100644 --- a/Robust.Shared/Map/Components/MapGridComponent.cs +++ b/Robust.Shared/Map/Components/MapGridComponent.cs @@ -93,7 +93,7 @@ namespace Robust.Shared.Map.Components if (chunkData.IsDeleted()) continue; - var chunk = gridComp.GetChunk(chunkData.Index); + var chunk = gridComp.GetOrAddChunk(chunkData.Index); chunk.SuppressCollisionRegeneration = true; DebugTools.Assert(chunkData.TileData.Length == gridComp.ChunkSize * gridComp.ChunkSize); @@ -123,7 +123,7 @@ namespace Robust.Shared.Map.Components continue; } - var chunk = gridComp.GetChunk(chunkData.Index); + var chunk = gridComp.GetOrAddChunk(chunkData.Index); chunk.SuppressCollisionRegeneration = false; gridComp.RegenerateCollision(chunk); } @@ -428,9 +428,9 @@ namespace Robust.Shared.Map.Components public int ChunkCount => Chunks.Count; /// - internal MapChunk GetChunk(int xIndex, int yIndex) + internal MapChunk GetOrAddChunk(int xIndex, int yIndex) { - return GetChunk(new Vector2i(xIndex, yIndex)); + return GetOrAddChunk(new Vector2i(xIndex, yIndex)); } internal bool TryGetChunk(Vector2i chunkIndices, [NotNullWhen(true)] out MapChunk? chunk) @@ -439,14 +439,17 @@ namespace Robust.Shared.Map.Components } /// - internal MapChunk GetChunk(Vector2i chunkIndices) + internal MapChunk GetOrAddChunk(Vector2i chunkIndices) { if (Chunks.TryGetValue(chunkIndices, out var output)) return output; var newChunk = new MapChunk(chunkIndices.X, chunkIndices.Y, ChunkSize); newChunk.LastTileModifiedTick = _mapManager.GameTiming.CurTick; - newChunk.TileModified += OnTileModified; + + if (Initialized) + newChunk.TileModified += OnTileModified; + return Chunks[chunkIndices] = newChunk; } @@ -644,7 +647,7 @@ namespace Robust.Shared.Map.Components private (MapChunk, Vector2i) ChunkAndOffsetForTile(Vector2i pos) { var gridChunkIndices = GridTileToChunkIndices(pos); - var chunk = GetChunk(gridChunkIndices); + var chunk = GetOrAddChunk(gridChunkIndices); var chunkTile = chunk.GridTileToChunkTile(pos); return (chunk, chunkTile); } diff --git a/Robust.Shared/Map/MapChunk.cs b/Robust.Shared/Map/MapChunk.cs index 3ff823147..3eb21e6c5 100644 --- a/Robust.Shared/Map/MapChunk.cs +++ b/Robust.Shared/Map/MapChunk.cs @@ -155,6 +155,10 @@ namespace Robust.Shared.Map _tiles[xIndex, yIndex] = tile; var tileIndices = new Vector2i(xIndex, yIndex); + + // God I hate C# events sometimes. + DebugTools.Assert(TileModified == null || TileModified.GetInvocationList().Length <= 1); + TileModified?.Invoke(this, tileIndices, tile, oldTile, shapeChanged); } diff --git a/Robust.Shared/Map/MapManager.Queries.cs b/Robust.Shared/Map/MapManager.Queries.cs index 39ed9e58b..f7f723271 100644 --- a/Robust.Shared/Map/MapManager.Queries.cs +++ b/Robust.Shared/Map/MapManager.Queries.cs @@ -185,7 +185,7 @@ internal partial class MapManager if (!iGrid.HasChunk(chunkIndices)) return true; - var chunk = iGrid.GetChunk(chunkIndices); + var chunk = iGrid.GetOrAddChunk(chunkIndices); Vector2i indices = chunk.GridTileToChunkTile(tile); var chunkTile = chunk.GetTile((ushort)indices.X, (ushort)indices.Y);