From 4dc1c4c3d671d95be68c203a7f76766dcabacd14 Mon Sep 17 00:00:00 2001 From: Tayrtahn Date: Thu, 15 May 2025 06:26:47 -0400 Subject: [PATCH] Content changes for SetTiles change (#37229) * Content changes for SetTiles change * Retest with new engine changes * Derp * Update for new engine PR changes --- .../Atmos/EntitySystems/AtmosphereSystem.cs | 5 +- .../EntitySystems/AutomaticAtmosSystem.cs | 47 +++++----- Content.Server/Decals/DecalSystem.cs | 51 ++++++----- .../EntitySystems/ExplosionSystem.GridMap.cs | 91 ++++++++++--------- .../NPC/Pathfinding/PathfindingSystem.Grid.cs | 9 +- Content.Server/Pinpointer/NavMapSystem.cs | 41 +++++---- .../Shuttles/Systems/ThrusterSystem.cs | 52 ++++++----- Content.Server/Tiles/RequiresTileSystem.cs | 19 ++-- .../SubFloor/SharedSubFloorHideSystem.cs | 13 ++- 9 files changed, 177 insertions(+), 151 deletions(-) diff --git a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs index 0f5bc1af04..e9383f3a23 100644 --- a/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs +++ b/Content.Server/Atmos/EntitySystems/AtmosphereSystem.cs @@ -81,7 +81,10 @@ public sealed partial class AtmosphereSystem : SharedAtmosphereSystem private void OnTileChanged(ref TileChangedEvent ev) { - InvalidateTile(ev.NewTile.GridUid, ev.NewTile.GridIndices); + foreach (var change in ev.Changes) + { + InvalidateTile(ev.Entity.Owner, change.GridIndices); + } } private void OnPrototypesReloaded(PrototypesReloadedEventArgs ev) diff --git a/Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs b/Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs index 70e3eef3c4..76775638ee 100644 --- a/Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs +++ b/Content.Server/Atmos/EntitySystems/AutomaticAtmosSystem.cs @@ -23,29 +23,32 @@ public sealed class AutomaticAtmosSystem : EntitySystem private void OnTileChanged(ref TileChangedEvent ev) { - // Only if a atmos-holding tile has been added or removed. - // Also, these calls are surprisingly slow. - // TODO: Make tiledefmanager cache the IsSpace property, and turn this lookup-through-two-interfaces into - // TODO: a simple array lookup, as tile IDs are likely contiguous, and there's at most 2^16 possibilities anyway. - - var oldSpace = ev.OldTile.IsSpace(_tileDefinitionManager); - var newSpace = ev.NewTile.IsSpace(_tileDefinitionManager); - - if (!(oldSpace && !newSpace || - !oldSpace && newSpace) || - _atmosphereSystem.HasAtmosphere(ev.Entity)) - return; - - if (!TryComp(ev.Entity, out var physics)) - return; - - // We can't actually count how many tiles there are efficiently, so instead estimate with the mass. - if (physics.Mass / ShuttleSystem.TileMassMultiplier >= 7.0f) + foreach (var change in ev.Changes) { - AddComp(ev.Entity); - Log.Info($"Giving grid {ev.Entity} GridAtmosphereComponent."); + // Only if a atmos-holding tile has been added or removed. + // Also, these calls are surprisingly slow. + // TODO: Make tiledefmanager cache the IsSpace property, and turn this lookup-through-two-interfaces into + // TODO: a simple array lookup, as tile IDs are likely contiguous, and there's at most 2^16 possibilities anyway. + + var oldSpace = change.OldTile.IsSpace(_tileDefinitionManager); + var newSpace = change.NewTile.IsSpace(_tileDefinitionManager); + + if (!(oldSpace && !newSpace || + !oldSpace && newSpace) || + _atmosphereSystem.HasAtmosphere(ev.Entity)) + continue; + + if (!TryComp(ev.Entity, out var physics)) + return; + + // We can't actually count how many tiles there are efficiently, so instead estimate with the mass. + if (physics.Mass / ShuttleSystem.TileMassMultiplier >= 7.0f) + { + AddComp(ev.Entity); + Log.Info($"Giving grid {ev.Entity} GridAtmosphereComponent."); + } + // It's not super important to remove it should the grid become too small again. + // If explosions ever gain the ability to outright shatter grids, do rethink this. } - // It's not super important to remove it should the grid become too small again. - // If explosions ever gain the ability to outright shatter grids, do rethink this. } } diff --git a/Content.Server/Decals/DecalSystem.cs b/Content.Server/Decals/DecalSystem.cs index 2e1ed2c68d..2af95c7c23 100644 --- a/Content.Server/Decals/DecalSystem.cs +++ b/Content.Server/Decals/DecalSystem.cs @@ -160,38 +160,41 @@ namespace Content.Server.Decals private void OnTileChanged(ref TileChangedEvent args) { - if (!args.NewTile.IsSpace(_tileDefMan)) - return; + foreach (var change in args.Changes) + { + if (!change.NewTile.IsSpace(_tileDefMan)) + return; - if (!TryComp(args.Entity, out DecalGridComponent? grid)) - return; + if (!TryComp(args.Entity, out DecalGridComponent? grid)) + return; - var indices = GetChunkIndices(args.NewTile.GridIndices); - var toDelete = new HashSet(); - if (!grid.ChunkCollection.ChunkCollection.TryGetValue(indices, out var chunk)) - return; + var indices = GetChunkIndices(change.GridIndices); + var toDelete = new HashSet(); + if (!grid.ChunkCollection.ChunkCollection.TryGetValue(indices, out var chunk)) + return; - foreach (var (uid, decal) in chunk.Decals) - { - if (new Vector2((int) Math.Floor(decal.Coordinates.X), (int) Math.Floor(decal.Coordinates.Y)) == - args.NewTile.GridIndices) + foreach (var (uid, decal) in chunk.Decals) { - toDelete.Add(uid); + if (new Vector2((int)Math.Floor(decal.Coordinates.X), (int)Math.Floor(decal.Coordinates.Y)) == + change.GridIndices) + { + toDelete.Add(uid); + } } - } - if (toDelete.Count == 0) - return; + if (toDelete.Count == 0) + return; - foreach (var decalId in toDelete) - { - grid.DecalIndex.Remove(decalId); - chunk.Decals.Remove(decalId); - } + foreach (var decalId in toDelete) + { + grid.DecalIndex.Remove(decalId); + chunk.Decals.Remove(decalId); + } - DirtyChunk(args.Entity, indices, chunk); - if (chunk.Decals.Count == 0) - grid.ChunkCollection.ChunkCollection.Remove(indices); + DirtyChunk(args.Entity, indices, chunk); + if (chunk.Decals.Count == 0) + grid.ChunkCollection.ChunkCollection.Remove(indices); + } } private void OnPlayerStatusChanged(object? sender, SessionStatusEventArgs e) diff --git a/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs b/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs index 3b63750ff6..77def3abba 100644 --- a/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs +++ b/Content.Server/Explosion/EntitySystems/ExplosionSystem.GridMap.cs @@ -233,65 +233,66 @@ public sealed partial class ExplosionSystem /// private void OnTileChanged(ref TileChangedEvent ev) { - // only need to update the grid-edge map if a tile was added or removed from the grid. - if (!ev.NewTile.Tile.IsEmpty && !ev.OldTile.IsEmpty) - return; - - if (!TryComp(ev.Entity, out MapGridComponent? grid)) - return; - - var tileRef = ev.NewTile; - - if (!_gridEdges.TryGetValue(tileRef.GridUid, out var edges)) + foreach (var change in ev.Changes) { - edges = new(); - _gridEdges[tileRef.GridUid] = edges; - } + // only need to update the grid-edge map if a tile was added or removed from the grid. + if (!change.NewTile.IsEmpty && !change.OldTile.IsEmpty) + return; - if (tileRef.Tile.IsEmpty) - { - // if the tile is empty, it cannot itself be an edge tile. - edges.Remove(tileRef.GridIndices); + if (!TryComp(ev.Entity, out MapGridComponent? grid)) + return; - // add any valid neighbours to the list of edge-tiles - for (var i = 0; i < NeighbourVectors.Length; i++) + if (!_gridEdges.TryGetValue(ev.Entity, out var edges)) + { + edges = new(); + _gridEdges[ev.Entity] = edges; + } + + if (change.NewTile.IsEmpty) { - var neighbourIndex = tileRef.GridIndices + NeighbourVectors[i]; + // if the tile is empty, it cannot itself be an edge tile. + edges.Remove(change.GridIndices); - if (_mapSystem.TryGetTileRef(ev.Entity, grid, neighbourIndex, out var neighbourTile) && !neighbourTile.Tile.IsEmpty) + // add any valid neighbours to the list of edge-tiles + for (var i = 0; i < NeighbourVectors.Length; i++) { - var oppositeDirection = (NeighborFlag) (1 << ((i + 4) % 8)); - edges[neighbourIndex] = edges.GetValueOrDefault(neighbourIndex) | oppositeDirection; - } - } + var neighbourIndex = change.GridIndices + NeighbourVectors[i]; - return; - } + if (_mapSystem.TryGetTileRef(ev.Entity, grid, neighbourIndex, out var neighbourTile) && !neighbourTile.Tile.IsEmpty) + { + var oppositeDirection = (NeighborFlag)(1 << ((i + 4) % 8)); + edges[neighbourIndex] = edges.GetValueOrDefault(neighbourIndex) | oppositeDirection; + } + } - // the tile is not empty space, but was previously. So update directly adjacent neighbours, which may no longer - // be edge tiles. - for (var i = 0; i < NeighbourVectors.Length; i++) - { - var neighbourIndex = tileRef.GridIndices + NeighbourVectors[i]; + return; + } - if (edges.TryGetValue(neighbourIndex, out var neighborSpaceDir)) + // the tile is not empty space, but was previously. So update directly adjacent neighbours, which may no longer + // be edge tiles. + for (var i = 0; i < NeighbourVectors.Length; i++) { - var oppositeDirection = (NeighborFlag) (1 << ((i + 4) % 8)); - neighborSpaceDir &= ~oppositeDirection; - if (neighborSpaceDir == NeighborFlag.Invalid) + var neighbourIndex = change.GridIndices + NeighbourVectors[i]; + + if (edges.TryGetValue(neighbourIndex, out var neighborSpaceDir)) { - // no longer an edge tile - edges.Remove(neighbourIndex); - continue; - } + var oppositeDirection = (NeighborFlag)(1 << ((i + 4) % 8)); + neighborSpaceDir &= ~oppositeDirection; + if (neighborSpaceDir == NeighborFlag.Invalid) + { + // no longer an edge tile + edges.Remove(neighbourIndex); + continue; + } - edges[neighbourIndex] = neighborSpaceDir; + edges[neighbourIndex] = neighborSpaceDir; + } } - } - // finally check if the new tile is itself an edge tile - if (IsEdge(grid, tileRef.GridIndices, out var spaceDir)) - edges.Add(tileRef.GridIndices, spaceDir); + // finally check if the new tile is itself an edge tile + if (IsEdge(grid, change.GridIndices, out var spaceDir)) + edges.Add(change.GridIndices, spaceDir); + } } /// diff --git a/Content.Server/NPC/Pathfinding/PathfindingSystem.Grid.cs b/Content.Server/NPC/Pathfinding/PathfindingSystem.Grid.cs index 7105bda0a2..3def3feedc 100644 --- a/Content.Server/NPC/Pathfinding/PathfindingSystem.Grid.cs +++ b/Content.Server/NPC/Pathfinding/PathfindingSystem.Grid.cs @@ -50,10 +50,13 @@ public sealed partial class PathfindingSystem private void OnTileChange(ref TileChangedEvent ev) { - if (ev.OldTile.IsEmpty == ev.NewTile.Tile.IsEmpty) - return; + foreach (var change in ev.Changes) + { + if (change.OldTile.IsEmpty == change.NewTile.IsEmpty) + return; - DirtyChunk(ev.Entity, Comp(ev.Entity).GridTileToLocal(ev.NewTile.GridIndices)); + DirtyChunk(ev.Entity, _maps.GridTileToLocal(ev.Entity, ev.Entity.Comp, change.GridIndices)); + } } diff --git a/Content.Server/Pinpointer/NavMapSystem.cs b/Content.Server/Pinpointer/NavMapSystem.cs index 5ffbbe53ab..ffa048acd6 100644 --- a/Content.Server/Pinpointer/NavMapSystem.cs +++ b/Content.Server/Pinpointer/NavMapSystem.cs @@ -101,30 +101,33 @@ public sealed partial class NavMapSystem : SharedNavMapSystem private void OnTileChanged(ref TileChangedEvent ev) { - if (!ev.EmptyChanged || !_navQuery.TryComp(ev.NewTile.GridUid, out var navMap)) - return; + foreach (var change in ev.Changes) + { + if (!change.EmptyChanged || !_navQuery.TryComp(ev.Entity, out var navMap)) + return; - var tile = ev.NewTile.GridIndices; - var chunkOrigin = SharedMapSystem.GetChunkIndices(tile, ChunkSize); + var tile = change.GridIndices; + var chunkOrigin = SharedMapSystem.GetChunkIndices(tile, ChunkSize); - var chunk = EnsureChunk(navMap, chunkOrigin); + var chunk = EnsureChunk(navMap, chunkOrigin); - // This could be easily replaced in the future to accommodate diagonal tiles - var relative = SharedMapSystem.GetChunkRelative(tile, ChunkSize); - ref var tileData = ref chunk.TileData[GetTileIndex(relative)]; + // This could be easily replaced in the future to accommodate diagonal tiles + var relative = SharedMapSystem.GetChunkRelative(tile, ChunkSize); + ref var tileData = ref chunk.TileData[GetTileIndex(relative)]; - if (ev.NewTile.IsSpace(_tileDefManager)) - { - tileData = 0; - if (PruneEmpty((ev.NewTile.GridUid, navMap), chunk)) - return; - } - else - { - tileData = FloorMask; - } + if (change.NewTile.IsSpace(_tileDefManager)) + { + tileData = 0; + if (PruneEmpty((ev.Entity, navMap), chunk)) + return; + } + else + { + tileData = FloorMask; + } - DirtyChunk((ev.NewTile.GridUid, navMap), chunk); + DirtyChunk((ev.Entity, navMap), chunk); + } } private void DirtyChunk(Entity entity, NavMapChunk chunk) diff --git a/Content.Server/Shuttles/Systems/ThrusterSystem.cs b/Content.Server/Shuttles/Systems/ThrusterSystem.cs index 74008a6af7..294200af9a 100644 --- a/Content.Server/Shuttles/Systems/ThrusterSystem.cs +++ b/Content.Server/Shuttles/Systems/ThrusterSystem.cs @@ -94,41 +94,45 @@ public sealed class ThrusterSystem : EntitySystem private void OnShuttleTileChange(EntityUid uid, ShuttleComponent component, ref TileChangedEvent args) { - // If the old tile was space but the new one isn't then disable all adjacent thrusters - if (args.NewTile.IsSpace(_tileDefManager) || !args.OldTile.IsSpace(_tileDefManager)) - return; - - var tilePos = args.NewTile.GridIndices; - var grid = Comp(uid); - var xformQuery = GetEntityQuery(); - var thrusterQuery = GetEntityQuery(); - - for (var x = -1; x <= 1; x++) + foreach (var change in args.Changes) { - for (var y = -1; y <= 1; y++) - { - if (x != 0 && y != 0) - continue; + // If the old tile was space but the new one isn't then disable all adjacent thrusters + if (change.NewTile.IsSpace(_tileDefManager) || !change.OldTile.IsSpace(_tileDefManager)) + return; - var checkPos = tilePos + new Vector2i(x, y); - var enumerator = _mapSystem.GetAnchoredEntitiesEnumerator(uid, grid, checkPos); + var tilePos = change.GridIndices; + var grid = Comp(uid); + var xformQuery = GetEntityQuery(); + var thrusterQuery = GetEntityQuery(); - while (enumerator.MoveNext(out var ent)) + for (var x = -1; x <= 1; x++) + { + for (var y = -1; y <= 1; y++) { - if (!thrusterQuery.TryGetComponent(ent.Value, out var thruster) || !thruster.RequireSpace) + if (x != 0 && y != 0) continue; - // Work out if the thruster is facing this direction - var xform = xformQuery.GetComponent(ent.Value); - var direction = xform.LocalRotation.ToWorldVec(); + var checkPos = tilePos + new Vector2i(x, y); + var enumerator = _mapSystem.GetAnchoredEntitiesEnumerator(uid, grid, checkPos); - if (new Vector2i((int)direction.X, (int)direction.Y) != new Vector2i(x, y)) - continue; + while (enumerator.MoveNext(out var ent)) + { + if (!thrusterQuery.TryGetComponent(ent.Value, out var thruster) || !thruster.RequireSpace) + continue; - DisableThruster(ent.Value, thruster, xform.GridUid); + // Work out if the thruster is facing this direction + var xform = xformQuery.GetComponent(ent.Value); + var direction = xform.LocalRotation.ToWorldVec(); + + if (new Vector2i((int)direction.X, (int)direction.Y) != new Vector2i(x, y)) + continue; + + DisableThruster(ent.Value, thruster, xform.GridUid); + } } } } + } private void OnActivateThruster(EntityUid uid, ThrusterComponent component, ActivateInWorldEvent args) diff --git a/Content.Server/Tiles/RequiresTileSystem.cs b/Content.Server/Tiles/RequiresTileSystem.cs index 571065c828..aae07fa660 100644 --- a/Content.Server/Tiles/RequiresTileSystem.cs +++ b/Content.Server/Tiles/RequiresTileSystem.cs @@ -26,16 +26,19 @@ public sealed class RequiresTileSystem : EntitySystem if (!TryComp(ev.Entity, out var grid)) return; - var anchored = _maps.GetAnchoredEntitiesEnumerator(ev.Entity, grid, ev.NewTile.GridIndices); - if (anchored.Equals(AnchoredEntitiesEnumerator.Empty)) - return; - - while (anchored.MoveNext(out var ent)) + foreach (var change in ev.Changes) { - if (!_tilesQuery.HasComponent(ent.Value)) - continue; + var anchored = _maps.GetAnchoredEntitiesEnumerator(ev.Entity, grid, change.GridIndices); + if (anchored.Equals(AnchoredEntitiesEnumerator.Empty)) + return; + + while (anchored.MoveNext(out var ent)) + { + if (!_tilesQuery.HasComponent(ent.Value)) + continue; - QueueDel(ent.Value); + QueueDel(ent.Value); + } } } } diff --git a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs index 9a7ce0d1df..65d5e0adb2 100644 --- a/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs +++ b/Content.Shared/SubFloor/SharedSubFloorHideSystem.cs @@ -122,13 +122,16 @@ namespace Content.Shared.SubFloor private void OnTileChanged(ref TileChangedEvent args) { - if (args.OldTile.IsEmpty) - return; // Nothing is anchored here anyways. + foreach (var change in args.Changes) + { + if (change.OldTile.IsEmpty) + return; // Nothing is anchored here anyways. - if (args.NewTile.Tile.IsEmpty) - return; // Anything that was here will be unanchored anyways. + if (change.NewTile.IsEmpty) + return; // Anything that was here will be unanchored anyways. - UpdateTile(args.NewTile.GridUid, args.Entity.Comp, args.NewTile.GridIndices); + UpdateTile(args.Entity, args.Entity.Comp, change.GridIndices); + } } /// -- 2.51.2