AI reachable improvements (#1595)

Deleted regions in some instances were being retained indefinitely.

Co-authored-by: Metal Gear Sloth <metalgearsloth@gmail.com>
This commit is contained in:
metalgearsloth
2020-08-06 00:19:00 +10:00
committed by GitHub
parent c5d3bff266
commit 140f8f7647
2 changed files with 38 additions and 10 deletions

View File

@@ -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<PathfindingRegion> 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<PathfindingRegion>();
}
@@ -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
/// </summary>
/// <param name="source"></param>
/// <param name="target"></param>
private void MergeInto(PathfindingRegion source, PathfindingRegion target)
private void MergeInto(PathfindingRegion source, PathfindingRegion target, Dictionary<PathfindingNode, PathfindingRegion> 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
/// <param name="region"></param>
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
}
/// <summary>
@@ -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

View File

@@ -34,7 +34,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
public bool IsDoor { get; }
public HashSet<PathfindingNode> Nodes => _nodes;
private HashSet<PathfindingNode> _nodes;
private readonly HashSet<PathfindingNode> _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()