Merge pull request #6986 from chrisforbes/minimal-neighbors
Prune neighbor sets based on direction we arrived at a cell
This commit is contained in:
@@ -52,13 +52,8 @@ namespace OpenRA.Mods.RA.Activities
|
||||
var searchRadiusSquared = searchRadius * searchRadius;
|
||||
|
||||
// Find harvestable resources nearby:
|
||||
// Avoid enemy territory:
|
||||
// TODO: calculate weapons ranges of units and factor those in instead of hard-coding 8.
|
||||
var path = self.World.WorldActor.Trait<PathFinder>().FindPath(
|
||||
PathSearch.Search(self.World, mobileInfo, self, true)
|
||||
.WithCustomCost(loc => self.World.FindActorsInCircle(self.World.Map.CenterOfCell(loc), WRange.FromCells(8))
|
||||
.Where(u => !u.Destroyed && self.Owner.Stances[u.Owner] == Stance.Enemy)
|
||||
.Sum(u => Math.Max(0, 64 - (loc - u.Location).LengthSquared)))
|
||||
.WithHeuristic(loc =>
|
||||
{
|
||||
// Avoid this cell:
|
||||
|
||||
@@ -33,7 +33,6 @@ namespace OpenRA.Mods.RA.Move
|
||||
MobileInfo mobileInfo;
|
||||
Func<CPos, int> customCost;
|
||||
Func<CPos, bool> customBlock;
|
||||
Pair<CVec, int>[] nextDirections;
|
||||
int laneBias = 1;
|
||||
|
||||
public PathSearch(World world, MobileInfo mobileInfo, Actor self)
|
||||
@@ -46,7 +45,6 @@ namespace OpenRA.Mods.RA.Move
|
||||
Queue = new PriorityQueue<PathDistance>();
|
||||
Considered = new HashSet<CPos>();
|
||||
MaxCost = 0;
|
||||
nextDirections = CVec.directions.Select(d => new Pair<CVec, int>(d, 0)).ToArray();
|
||||
}
|
||||
|
||||
public static PathSearch Search(World world, MobileInfo mi, Actor self, bool checkForBlocked)
|
||||
@@ -140,6 +138,32 @@ namespace OpenRA.Mods.RA.Move
|
||||
return this;
|
||||
}
|
||||
|
||||
// Sets of neighbors for each incoming direction. These exclude the neighbors which are guaranteed
|
||||
// to be reached more cheaply by a path through our parent cell which does not include the current cell.
|
||||
// For horizontal/vertical directions, the set is the three cells 'ahead'. For diagonal directions, the set
|
||||
// is the three cells ahead, plus the two cells to the side, which we cannot exclude without knowing if
|
||||
// the cell directly between them and our parent is passable.
|
||||
static CVec[][] DirectedNeighbors = {
|
||||
new CVec[] { new CVec(-1, -1), new CVec(0, -1), new CVec(1, -1), new CVec(-1, 0), new CVec(-1, 1) },
|
||||
new CVec[] { new CVec(-1, -1), new CVec(0, -1), new CVec(1, -1) },
|
||||
new CVec[] { new CVec(-1, -1), new CVec(0, -1), new CVec(1, -1), new CVec(1, 0), new CVec(1, 1) },
|
||||
new CVec[] { new CVec(-1, -1), new CVec(-1, 0), new CVec(-1, 1) },
|
||||
CVec.directions,
|
||||
new CVec[] { new CVec(1, -1), new CVec(1, 0), new CVec(1, 1) },
|
||||
new CVec[] { new CVec(-1, -1), new CVec(-1, 0), new CVec(-1, 1), new CVec(0, 1), new CVec(1, 1) },
|
||||
new CVec[] { new CVec(-1, 1), new CVec(0, 1), new CVec(1, 1) },
|
||||
new CVec[] { new CVec(1, -1), new CVec(1, 0), new CVec(-1, 1), new CVec(0, 1), new CVec(1, 1) },
|
||||
};
|
||||
|
||||
static CVec[] GetNeighbors(CPos p, CPos prev)
|
||||
{
|
||||
var dx = p.X - prev.X;
|
||||
var dy = p.Y - prev.Y;
|
||||
var index = dy * 3 + dx + 4;
|
||||
|
||||
return DirectedNeighbors[index];
|
||||
}
|
||||
|
||||
public CPos Expand(World world)
|
||||
{
|
||||
var p = Queue.Pop();
|
||||
@@ -167,13 +191,14 @@ namespace OpenRA.Mods.RA.Move
|
||||
return p.Location;
|
||||
}
|
||||
|
||||
// This current cell is ok; check all immediate directions:
|
||||
// This current cell is ok; check useful immediate directions:
|
||||
Considered.Add(p.Location);
|
||||
|
||||
for (var i = 0; i < nextDirections.Length; ++i)
|
||||
var directions = GetNeighbors(p.Location, pCell.Path);
|
||||
|
||||
for (var i = 0; i < directions.Length; ++i)
|
||||
{
|
||||
var d = nextDirections[i].First;
|
||||
nextDirections[i].Second = int.MaxValue;
|
||||
var d = directions[i];
|
||||
|
||||
var newHere = p.Location + d;
|
||||
|
||||
@@ -239,7 +264,6 @@ namespace OpenRA.Mods.RA.Move
|
||||
hereCell.MinCost = newCost;
|
||||
CellInfo[newHere] = hereCell;
|
||||
|
||||
nextDirections[i].Second = newCost + est;
|
||||
Queue.Add(new PathDistance(newCost + est, newHere));
|
||||
|
||||
if (newCost > MaxCost)
|
||||
@@ -248,8 +272,6 @@ namespace OpenRA.Mods.RA.Move
|
||||
Considered.Add(newHere);
|
||||
}
|
||||
|
||||
// Sort to prefer the cheaper direction:
|
||||
// Array.Sort(nextDirections, (a, b) => a.Second.CompareTo(b.Second));
|
||||
return p.Location;
|
||||
}
|
||||
|
||||
|
||||
Reference in New Issue
Block a user