diff --git a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/AiReachableSystem.cs b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/AiReachableSystem.cs index ded64233b8..8ad08996c8 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/AiReachableSystem.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/AiReachableSystem.cs @@ -123,7 +123,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible { ClearCache(region); } - + _queuedCacheDeletions.Clear(); } @@ -228,7 +228,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible public HashSet GetReachableRegions(ReachableArgs reachableArgs, PathfindingRegion region) { // if we're on a node that's not tracked at all atm then region will be null - if (region == null || region.Deleted) + if (region == null) { return new HashSet(); } @@ -357,7 +357,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible foreach (var neighbor in region.Neighbors) { - if (closedSet.Contains(neighbor) || neighbor.Deleted) + if (closedSet.Contains(neighbor)) { continue; } @@ -504,7 +504,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible { bottomRegion.Add(node); existingRegions.Add(node, bottomRegion); - MergeInto(leftRegion, bottomRegion); + MergeInto(leftRegion, bottomRegion, existingRegions); // Cleanup leftRegion // MergeInto will remove it from the overall region chunk cache while we need to remove it from @@ -541,7 +541,6 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible _regions[parentChunk.GridId][parentChunk].Add(newRegion); existingRegions.Add(node, newRegion); UpdateRegionEdge(newRegion, node); - return newRegion; } @@ -550,7 +549,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible /// /// /// - private void MergeInto(PathfindingRegion source, PathfindingRegion target) + private void MergeInto(PathfindingRegion source, PathfindingRegion target, Dictionary existingRegions = null) { DebugTools.AssertNotNull(source); DebugTools.AssertNotNull(target); @@ -560,6 +559,14 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible target.Add(node); } + if (existingRegions != null) + { + foreach (var node in source.Nodes) + { + existingRegions[node] = target; + } + } + source.Shutdown(); // This doesn't check the cachedaccessible to see if it's reachable but maybe it should? // Although currently merge gets spammed so maybe when some other stuff is improved @@ -578,6 +585,8 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible /// private void ClearCache(PathfindingRegion region) { + DebugTools.Assert(region.Deleted); + // Need to forcibly clear cache for ourself and anything that includes us foreach (var (_, cachedRegions) in _cachedAccessible) { @@ -604,6 +613,14 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible cachedRegions.Remove(otherRegion); } } + +#if DEBUG + if (_regions.TryGetValue(region.ParentChunk.GridId, out var chunks) && + chunks.TryGetValue(region.ParentChunk, out var regions)) + { + DebugTools.Assert(!regions.Contains(region)); + } +#endif } /// @@ -647,14 +664,19 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible { continue; } - + chunkRegions.Add(region); } } #if DEBUG + foreach (var region in chunkRegions) + { + DebugTools.Assert(!region.Deleted); + } + + DebugTools.Assert(chunkRegions.Count < Math.Pow(PathfindingChunk.ChunkSize, 2)); SendRegionsDebugMessage(chunk.GridId); #endif - DebugTools.Assert(chunkRegions.Count(region => region.Deleted) == 0); } #if DEBUG diff --git a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/PathfindingRegion.cs b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/PathfindingRegion.cs index ea4b8c2ad6..5de05ee925 100644 --- a/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/PathfindingRegion.cs +++ b/Content.Server/GameObjects/EntitySystems/AI/Pathfinding/Accessible/PathfindingRegion.cs @@ -34,7 +34,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible public bool IsDoor { get; } public HashSet Nodes => _nodes; - private HashSet _nodes; + private readonly HashSet _nodes; public bool Deleted { get; private set; } @@ -55,6 +55,9 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible var neighbor = neighbors[i]; neighbor.Neighbors.Remove(this); } + + _nodes.Clear(); + Neighbors.Clear(); Deleted = true; } @@ -127,7 +130,10 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible { if (other == null) return false; if (ReferenceEquals(this, other)) return true; - return GetHashCode() == other.GetHashCode(); + if (_nodes.Count != other.Nodes.Count) return false; + if (Deleted != other.Deleted) return false; + if (OriginNode != other.OriginNode) return false; + return true; } public override int GetHashCode()