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:
@@ -123,7 +123,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
|||||||
{
|
{
|
||||||
ClearCache(region);
|
ClearCache(region);
|
||||||
}
|
}
|
||||||
|
|
||||||
_queuedCacheDeletions.Clear();
|
_queuedCacheDeletions.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -228,7 +228,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
|||||||
public HashSet<PathfindingRegion> GetReachableRegions(ReachableArgs reachableArgs, PathfindingRegion region)
|
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 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>();
|
return new HashSet<PathfindingRegion>();
|
||||||
}
|
}
|
||||||
@@ -357,7 +357,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
|||||||
|
|
||||||
foreach (var neighbor in region.Neighbors)
|
foreach (var neighbor in region.Neighbors)
|
||||||
{
|
{
|
||||||
if (closedSet.Contains(neighbor) || neighbor.Deleted)
|
if (closedSet.Contains(neighbor))
|
||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
@@ -504,7 +504,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
|||||||
{
|
{
|
||||||
bottomRegion.Add(node);
|
bottomRegion.Add(node);
|
||||||
existingRegions.Add(node, bottomRegion);
|
existingRegions.Add(node, bottomRegion);
|
||||||
MergeInto(leftRegion, bottomRegion);
|
MergeInto(leftRegion, bottomRegion, existingRegions);
|
||||||
|
|
||||||
// Cleanup leftRegion
|
// Cleanup leftRegion
|
||||||
// MergeInto will remove it from the overall region chunk cache while we need to remove it from
|
// 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);
|
_regions[parentChunk.GridId][parentChunk].Add(newRegion);
|
||||||
existingRegions.Add(node, newRegion);
|
existingRegions.Add(node, newRegion);
|
||||||
UpdateRegionEdge(newRegion, node);
|
UpdateRegionEdge(newRegion, node);
|
||||||
|
|
||||||
return newRegion;
|
return newRegion;
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -550,7 +549,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="source"></param>
|
/// <param name="source"></param>
|
||||||
/// <param name="target"></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(source);
|
||||||
DebugTools.AssertNotNull(target);
|
DebugTools.AssertNotNull(target);
|
||||||
@@ -560,6 +559,14 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
|||||||
target.Add(node);
|
target.Add(node);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (existingRegions != null)
|
||||||
|
{
|
||||||
|
foreach (var node in source.Nodes)
|
||||||
|
{
|
||||||
|
existingRegions[node] = target;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
source.Shutdown();
|
source.Shutdown();
|
||||||
// This doesn't check the cachedaccessible to see if it's reachable but maybe it should?
|
// 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
|
// 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>
|
/// <param name="region"></param>
|
||||||
private void ClearCache(PathfindingRegion region)
|
private void ClearCache(PathfindingRegion region)
|
||||||
{
|
{
|
||||||
|
DebugTools.Assert(region.Deleted);
|
||||||
|
|
||||||
// Need to forcibly clear cache for ourself and anything that includes us
|
// Need to forcibly clear cache for ourself and anything that includes us
|
||||||
foreach (var (_, cachedRegions) in _cachedAccessible)
|
foreach (var (_, cachedRegions) in _cachedAccessible)
|
||||||
{
|
{
|
||||||
@@ -604,6 +613,14 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
|||||||
cachedRegions.Remove(otherRegion);
|
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>
|
/// <summary>
|
||||||
@@ -647,14 +664,19 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
|||||||
{
|
{
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
chunkRegions.Add(region);
|
chunkRegions.Add(region);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
foreach (var region in chunkRegions)
|
||||||
|
{
|
||||||
|
DebugTools.Assert(!region.Deleted);
|
||||||
|
}
|
||||||
|
|
||||||
|
DebugTools.Assert(chunkRegions.Count < Math.Pow(PathfindingChunk.ChunkSize, 2));
|
||||||
SendRegionsDebugMessage(chunk.GridId);
|
SendRegionsDebugMessage(chunk.GridId);
|
||||||
#endif
|
#endif
|
||||||
DebugTools.Assert(chunkRegions.Count(region => region.Deleted) == 0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if DEBUG
|
#if DEBUG
|
||||||
|
|||||||
@@ -34,7 +34,7 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
|||||||
|
|
||||||
public bool IsDoor { get; }
|
public bool IsDoor { get; }
|
||||||
public HashSet<PathfindingNode> Nodes => _nodes;
|
public HashSet<PathfindingNode> Nodes => _nodes;
|
||||||
private HashSet<PathfindingNode> _nodes;
|
private readonly HashSet<PathfindingNode> _nodes;
|
||||||
|
|
||||||
public bool Deleted { get; private set; }
|
public bool Deleted { get; private set; }
|
||||||
|
|
||||||
@@ -55,6 +55,9 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
|||||||
var neighbor = neighbors[i];
|
var neighbor = neighbors[i];
|
||||||
neighbor.Neighbors.Remove(this);
|
neighbor.Neighbors.Remove(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_nodes.Clear();
|
||||||
|
Neighbors.Clear();
|
||||||
|
|
||||||
Deleted = true;
|
Deleted = true;
|
||||||
}
|
}
|
||||||
@@ -127,7 +130,10 @@ namespace Content.Server.GameObjects.EntitySystems.AI.Pathfinding.Accessible
|
|||||||
{
|
{
|
||||||
if (other == null) return false;
|
if (other == null) return false;
|
||||||
if (ReferenceEquals(this, other)) return true;
|
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()
|
public override int GetHashCode()
|
||||||
|
|||||||
Reference in New Issue
Block a user