Allow units to give way when path is blocked by oncoming unit.
This commit is contained in:
@@ -30,37 +30,47 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
this.cacheStorage = cacheStorage;
|
||||
}
|
||||
|
||||
public List<CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor)
|
||||
public List<CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor, BlockedByActor check)
|
||||
{
|
||||
using (new PerfSample("Pathfinder"))
|
||||
{
|
||||
var key = "FindUnitPath" + self.ActorID + source.X + source.Y + target.X + target.Y;
|
||||
var cachedPath = cacheStorage.Retrieve(key);
|
||||
|
||||
if (cachedPath != null)
|
||||
return cachedPath;
|
||||
// Only cache path when transient actors are ignored, otherwise there is no guarantee that the path
|
||||
// is still valid at the next check.
|
||||
if (check == BlockedByActor.None)
|
||||
{
|
||||
var cachedPath = cacheStorage.Retrieve(key);
|
||||
if (cachedPath != null)
|
||||
return cachedPath;
|
||||
}
|
||||
|
||||
var pb = pathFinder.FindUnitPath(source, target, self, ignoreActor);
|
||||
var pb = pathFinder.FindUnitPath(source, target, self, ignoreActor, check);
|
||||
|
||||
cacheStorage.Store(key, pb);
|
||||
if (check == BlockedByActor.None)
|
||||
cacheStorage.Store(key, pb);
|
||||
|
||||
return pb;
|
||||
}
|
||||
}
|
||||
|
||||
public List<CPos> FindUnitPathToRange(CPos source, SubCell srcSub, WPos target, WDist range, Actor self)
|
||||
public List<CPos> FindUnitPathToRange(CPos source, SubCell srcSub, WPos target, WDist range, Actor self, BlockedByActor check)
|
||||
{
|
||||
using (new PerfSample("Pathfinder"))
|
||||
{
|
||||
var key = "FindUnitPathToRange" + self.ActorID + source.X + source.Y + target.X + target.Y;
|
||||
var cachedPath = cacheStorage.Retrieve(key);
|
||||
|
||||
if (cachedPath != null)
|
||||
return cachedPath;
|
||||
if (check == BlockedByActor.None)
|
||||
{
|
||||
var cachedPath = cacheStorage.Retrieve(key);
|
||||
if (cachedPath != null)
|
||||
return cachedPath;
|
||||
}
|
||||
|
||||
var pb = pathFinder.FindUnitPathToRange(source, srcSub, target, range, self);
|
||||
var pb = pathFinder.FindUnitPathToRange(source, srcSub, target, range, self, check);
|
||||
|
||||
cacheStorage.Store(key, pb);
|
||||
if (check == BlockedByActor.None)
|
||||
cacheStorage.Store(key, pb);
|
||||
|
||||
return pb;
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Pathfinder
|
||||
{
|
||||
@@ -82,7 +83,7 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
public bool InReverse { get; set; }
|
||||
public Actor IgnoreActor { get; set; }
|
||||
|
||||
readonly CellConditions checkConditions;
|
||||
readonly BlockedByActor checkConditions;
|
||||
readonly Locomotor locomotor;
|
||||
readonly LocomotorInfo.WorldMovementInfo worldMovementInfo;
|
||||
readonly CellInfoLayerPool.PooledCellInfoLayer pooledLayer;
|
||||
@@ -92,7 +93,7 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
readonly Dictionary<byte, Pair<ICustomMovementLayer, CellLayer<CellInfo>>> customLayerInfo =
|
||||
new Dictionary<byte, Pair<ICustomMovementLayer, CellLayer<CellInfo>>>();
|
||||
|
||||
public PathGraph(CellInfoLayerPool layerPool, Locomotor locomotor, Actor actor, World world, bool checkForBlocked)
|
||||
public PathGraph(CellInfoLayerPool layerPool, Locomotor locomotor, Actor actor, World world, BlockedByActor check)
|
||||
{
|
||||
pooledLayer = layerPool.Get();
|
||||
groundInfo = pooledLayer.GetLayer();
|
||||
@@ -108,7 +109,7 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
worldMovementInfo = locomotorInfo.GetWorldMovementInfo(world);
|
||||
Actor = actor;
|
||||
LaneBias = 1;
|
||||
checkConditions = checkForBlocked ? CellConditions.TransientActors : CellConditions.None;
|
||||
checkConditions = check;
|
||||
checkTerrainHeight = world.Map.Grid.MaximumTerrainHeight > 0;
|
||||
}
|
||||
|
||||
@@ -172,8 +173,7 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
|
||||
int GetCostToNode(CPos destNode, CVec direction)
|
||||
{
|
||||
var movementCost = locomotor.MovementCostToEnterCell(Actor, destNode, IgnoreActor, checkConditions);
|
||||
|
||||
var movementCost = locomotor.MovementCostToEnterCell(Actor, destNode, checkConditions, IgnoreActor);
|
||||
if (movementCost != short.MaxValue && !(CustomBlock != null && CustomBlock(destNode)))
|
||||
return CalculateCellCost(destNode, direction, movementCost);
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
|
||||
namespace OpenRA.Mods.Common.Pathfinder
|
||||
{
|
||||
@@ -45,18 +46,18 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
considered = new LinkedList<Pair<CPos, int>>();
|
||||
}
|
||||
|
||||
public static IPathSearch Search(World world, Locomotor locomotor, Actor self, bool checkForBlocked, Func<CPos, bool> goalCondition)
|
||||
public static IPathSearch Search(World world, Locomotor locomotor, Actor self, BlockedByActor check, Func<CPos, bool> goalCondition)
|
||||
{
|
||||
var graph = new PathGraph(LayerPoolForWorld(world), locomotor, self, world, checkForBlocked);
|
||||
var graph = new PathGraph(LayerPoolForWorld(world), locomotor, self, world, check);
|
||||
var search = new PathSearch(graph);
|
||||
search.isGoal = goalCondition;
|
||||
search.heuristic = loc => 0;
|
||||
return search;
|
||||
}
|
||||
|
||||
public static IPathSearch FromPoint(World world, Locomotor locomotor, Actor self, CPos @from, CPos target, bool checkForBlocked)
|
||||
public static IPathSearch FromPoint(World world, Locomotor locomotor, Actor self, CPos @from, CPos target, BlockedByActor check)
|
||||
{
|
||||
var graph = new PathGraph(LayerPoolForWorld(world), locomotor, self, world, checkForBlocked);
|
||||
var graph = new PathGraph(LayerPoolForWorld(world), locomotor, self, world, check);
|
||||
var search = new PathSearch(graph)
|
||||
{
|
||||
heuristic = DefaultEstimator(target)
|
||||
@@ -74,9 +75,9 @@ namespace OpenRA.Mods.Common.Pathfinder
|
||||
return search;
|
||||
}
|
||||
|
||||
public static IPathSearch FromPoints(World world, Locomotor locomotor, Actor self, IEnumerable<CPos> froms, CPos target, bool checkForBlocked)
|
||||
public static IPathSearch FromPoints(World world, Locomotor locomotor, Actor self, IEnumerable<CPos> froms, CPos target, BlockedByActor check)
|
||||
{
|
||||
var graph = new PathGraph(LayerPoolForWorld(world), locomotor, self, world, checkForBlocked);
|
||||
var graph = new PathGraph(LayerPoolForWorld(world), locomotor, self, world, check);
|
||||
var search = new PathSearch(graph)
|
||||
{
|
||||
heuristic = DefaultEstimator(target)
|
||||
|
||||
Reference in New Issue
Block a user