Using Locomotor instead of Info for pathfinding

This commit is contained in:
teinarss
2019-07-07 19:44:39 +02:00
committed by reaperrr
parent c00b13a18e
commit 2ddf9fa826
9 changed files with 41 additions and 29 deletions

View File

@@ -181,7 +181,7 @@ namespace OpenRA.Mods.Common.Activities
// Find any harvestable resources: // Find any harvestable resources:
List<CPos> path; List<CPos> path;
using (var search = PathSearch.Search(self.World, locomotorInfo, self, true, loc => using (var search = PathSearch.Search(self.World, mobile.Locomotor, self, true, loc =>
domainIndex.IsPassable(self.Location, loc, locomotorInfo) && harv.CanHarvestCell(self, loc) && claimLayer.CanClaimCell(self, loc)) domainIndex.IsPassable(self.Location, loc, locomotorInfo) && harv.CanHarvestCell(self, loc) && claimLayer.CanClaimCell(self, loc))
.WithCustomCost(loc => .WithCustomCost(loc =>
{ {

View File

@@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Activities
{ {
List<CPos> path; List<CPos> path;
using (var search = using (var search =
PathSearch.FromPoint(self.World, mobile.Info.LocomotorInfo, self, mobile.ToCell, destination, false) PathSearch.FromPoint(self.World, mobile.Locomotor, self, mobile.ToCell, destination, false)
.WithoutLaneBias()) .WithoutLaneBias())
path = self.World.WorldActor.Trait<IPathFinder>().FindPath(search); path = self.World.WorldActor.Trait<IPathFinder>().FindPath(search);
return path; return path;

View File

@@ -137,8 +137,8 @@ namespace OpenRA.Mods.Common.Activities
if (!searchCells.Any()) if (!searchCells.Any())
return NoPath; return NoPath;
using (var fromSrc = PathSearch.FromPoints(self.World, Mobile.Info.LocomotorInfo, self, searchCells, loc, true)) using (var fromSrc = PathSearch.FromPoints(self.World, Mobile.Locomotor, self, searchCells, loc, true))
using (var fromDest = PathSearch.FromPoint(self.World, Mobile.Info.LocomotorInfo, self, loc, lastVisibleTargetLocation, true).Reverse()) using (var fromDest = PathSearch.FromPoint(self.World, Mobile.Locomotor, self, loc, lastVisibleTargetLocation, true).Reverse())
return pathFinder.FindBidiPath(fromSrc, fromDest); return pathFinder.FindBidiPath(fromSrc, fromDest);
} }

View File

@@ -83,7 +83,7 @@ namespace OpenRA.Mods.Common.Pathfinder
public Actor IgnoreActor { get; set; } public Actor IgnoreActor { get; set; }
readonly CellConditions checkConditions; readonly CellConditions checkConditions;
readonly LocomotorInfo locomotorInfo; readonly Locomotor locomotor;
readonly LocomotorInfo.WorldMovementInfo worldMovementInfo; readonly LocomotorInfo.WorldMovementInfo worldMovementInfo;
readonly CellInfoLayerPool.PooledCellInfoLayer pooledLayer; readonly CellInfoLayerPool.PooledCellInfoLayer pooledLayer;
readonly bool checkTerrainHeight; readonly bool checkTerrainHeight;
@@ -92,11 +92,12 @@ namespace OpenRA.Mods.Common.Pathfinder
readonly Dictionary<byte, Pair<ICustomMovementLayer, CellLayer<CellInfo>>> customLayerInfo = readonly Dictionary<byte, Pair<ICustomMovementLayer, CellLayer<CellInfo>>> customLayerInfo =
new Dictionary<byte, Pair<ICustomMovementLayer, CellLayer<CellInfo>>>(); new Dictionary<byte, Pair<ICustomMovementLayer, CellLayer<CellInfo>>>();
public PathGraph(CellInfoLayerPool layerPool, LocomotorInfo li, Actor actor, World world, bool checkForBlocked) public PathGraph(CellInfoLayerPool layerPool, Locomotor locomotor, Actor actor, World world, bool checkForBlocked)
{ {
pooledLayer = layerPool.Get(); pooledLayer = layerPool.Get();
groundInfo = pooledLayer.GetLayer(); groundInfo = pooledLayer.GetLayer();
locomotorInfo = li; var locomotorInfo = locomotor.Info;
this.locomotor = locomotor;
var layers = world.GetCustomMovementLayers().Values var layers = world.GetCustomMovementLayers().Values
.Where(cml => cml.EnabledForActor(actor.Info, locomotorInfo)); .Where(cml => cml.EnabledForActor(actor.Info, locomotorInfo));
@@ -153,7 +154,7 @@ namespace OpenRA.Mods.Common.Pathfinder
foreach (var cli in customLayerInfo.Values) foreach (var cli in customLayerInfo.Values)
{ {
var layerPosition = new CPos(position.X, position.Y, cli.First.Index); var layerPosition = new CPos(position.X, position.Y, cli.First.Index);
var entryCost = cli.First.EntryMovementCost(Actor.Info, locomotorInfo, layerPosition); var entryCost = cli.First.EntryMovementCost(Actor.Info, locomotor.Info, layerPosition);
if (entryCost != Constants.InvalidNode) if (entryCost != Constants.InvalidNode)
validNeighbors.Add(new GraphConnection(layerPosition, entryCost)); validNeighbors.Add(new GraphConnection(layerPosition, entryCost));
} }
@@ -161,7 +162,7 @@ namespace OpenRA.Mods.Common.Pathfinder
else else
{ {
var layerPosition = new CPos(position.X, position.Y, 0); var layerPosition = new CPos(position.X, position.Y, 0);
var exitCost = customLayerInfo[position.Layer].First.ExitMovementCost(Actor.Info, locomotorInfo, layerPosition); var exitCost = customLayerInfo[position.Layer].First.ExitMovementCost(Actor.Info, locomotor.Info, layerPosition);
if (exitCost != Constants.InvalidNode) if (exitCost != Constants.InvalidNode)
validNeighbors.Add(new GraphConnection(layerPosition, exitCost)); validNeighbors.Add(new GraphConnection(layerPosition, exitCost));
} }

View File

@@ -45,18 +45,18 @@ namespace OpenRA.Mods.Common.Pathfinder
considered = new LinkedList<Pair<CPos, int>>(); considered = new LinkedList<Pair<CPos, int>>();
} }
public static IPathSearch Search(World world, LocomotorInfo li, Actor self, bool checkForBlocked, Func<CPos, bool> goalCondition) public static IPathSearch Search(World world, Locomotor locomotor, Actor self, bool checkForBlocked, Func<CPos, bool> goalCondition)
{ {
var graph = new PathGraph(LayerPoolForWorld(world), li, self, world, checkForBlocked); var graph = new PathGraph(LayerPoolForWorld(world), locomotor, self, world, checkForBlocked);
var search = new PathSearch(graph); var search = new PathSearch(graph);
search.isGoal = goalCondition; search.isGoal = goalCondition;
search.heuristic = loc => 0; search.heuristic = loc => 0;
return search; return search;
} }
public static IPathSearch FromPoint(World world, LocomotorInfo li, Actor self, CPos from, CPos target, bool checkForBlocked) public static IPathSearch FromPoint(World world, Locomotor locomotor, Actor self, CPos @from, CPos target, bool checkForBlocked)
{ {
var graph = new PathGraph(LayerPoolForWorld(world), li, self, world, checkForBlocked); var graph = new PathGraph(LayerPoolForWorld(world), locomotor, self, world, checkForBlocked);
var search = new PathSearch(graph) var search = new PathSearch(graph)
{ {
heuristic = DefaultEstimator(target) heuristic = DefaultEstimator(target)
@@ -74,9 +74,9 @@ namespace OpenRA.Mods.Common.Pathfinder
return search; return search;
} }
public static IPathSearch FromPoints(World world, LocomotorInfo li, Actor self, IEnumerable<CPos> froms, CPos target, bool checkForBlocked) public static IPathSearch FromPoints(World world, Locomotor locomotor, Actor self, IEnumerable<CPos> froms, CPos target, bool checkForBlocked)
{ {
var graph = new PathGraph(LayerPoolForWorld(world), li, self, world, checkForBlocked); var graph = new PathGraph(LayerPoolForWorld(world), locomotor, self, world, checkForBlocked);
var search = new PathSearch(graph) var search = new PathSearch(graph)
{ {
heuristic = DefaultEstimator(target) heuristic = DefaultEstimator(target)

View File

@@ -44,14 +44,15 @@ namespace OpenRA.Mods.Common.Traits
public readonly Actor Actor; public readonly Actor Actor;
public readonly Harvester Harvester; public readonly Harvester Harvester;
public readonly Parachutable Parachutable; public readonly Parachutable Parachutable;
public readonly LocomotorInfo LocomotorInfo; public readonly Locomotor Locomotor;
public HarvesterTraitWrapper(Actor actor) public HarvesterTraitWrapper(Actor actor)
{ {
Actor = actor; Actor = actor;
Harvester = actor.Trait<Harvester>(); Harvester = actor.Trait<Harvester>();
Parachutable = actor.TraitOrDefault<Parachutable>(); Parachutable = actor.TraitOrDefault<Parachutable>();
LocomotorInfo = actor.Info.TraitInfo<MobileInfo>().LocomotorInfo; var mobile = actor.Trait<Mobile>();
Locomotor = mobile.Locomotor;
} }
} }
@@ -141,12 +142,12 @@ namespace OpenRA.Mods.Common.Traits
Target FindNextResource(Actor actor, HarvesterTraitWrapper harv) Target FindNextResource(Actor actor, HarvesterTraitWrapper harv)
{ {
Func<CPos, bool> isValidResource = cell => Func<CPos, bool> isValidResource = cell =>
domainIndex.IsPassable(actor.Location, cell, harv.LocomotorInfo) && domainIndex.IsPassable(actor.Location, cell, harv.Locomotor.Info) &&
harv.Harvester.CanHarvestCell(actor, cell) && harv.Harvester.CanHarvestCell(actor, cell) &&
claimLayer.CanClaimCell(actor, cell); claimLayer.CanClaimCell(actor, cell);
var path = pathfinder.FindPath( var path = pathfinder.FindPath(
PathSearch.Search(world, harv.LocomotorInfo, actor, true, isValidResource) PathSearch.Search(world, harv.Locomotor, actor, true, isValidResource)
.WithCustomCost(loc => world.FindActorsInCircle(world.Map.CenterOfCell(loc), Info.HarvesterEnemyAvoidanceRadius) .WithCustomCost(loc => world.FindActorsInCircle(world.Map.CenterOfCell(loc), Info.HarvesterEnemyAvoidanceRadius)
.Where(u => !u.IsDead && actor.Owner.Stances[u.Owner] == Stance.Enemy) .Where(u => !u.IsDead && actor.Owner.Stances[u.Owner] == Stance.Enemy)
.Sum(u => Math.Max(WDist.Zero.Length, Info.HarvesterEnemyAvoidanceRadius.Length - (world.Map.CenterOfCell(loc) - u.CenterPosition).Length))) .Sum(u => Math.Max(WDist.Zero.Length, Info.HarvesterEnemyAvoidanceRadius.Length - (world.Map.CenterOfCell(loc) - u.CenterPosition).Length)))

View File

@@ -201,8 +201,8 @@ namespace OpenRA.Mods.Common.Traits
// Start a search from each refinery's delivery location: // Start a search from each refinery's delivery location:
List<CPos> path; List<CPos> path;
var li = self.Info.TraitInfo<MobileInfo>().LocomotorInfo;
using (var search = PathSearch.FromPoints(self.World, li, self, refs.Values.Select(r => r.Location), self.Location, false) using (var search = PathSearch.FromPoints(self.World, mobile.Locomotor, self, refs.Values.Select(r => r.Location), self.Location, false)
.WithCustomCost(loc => .WithCustomCost(loc =>
{ {
if (!refs.ContainsKey(loc)) if (!refs.ContainsKey(loc))

View File

@@ -185,6 +185,8 @@ namespace OpenRA.Mods.Common.Traits
[Sync] [Sync]
public int PathHash; // written by Move.EvalPath, to temporarily debug this crap. public int PathHash; // written by Move.EvalPath, to temporarily debug this crap.
public Locomotor Locomotor { get; private set; }
#region IOccupySpace #region IOccupySpace
[Sync] [Sync]
@@ -235,6 +237,8 @@ namespace OpenRA.Mods.Common.Traits
notifyMoving = self.TraitsImplementing<INotifyMoving>().ToArray(); notifyMoving = self.TraitsImplementing<INotifyMoving>().ToArray();
notifyFinishedMoving = self.TraitsImplementing<INotifyFinishedMoving>().ToArray(); notifyFinishedMoving = self.TraitsImplementing<INotifyFinishedMoving>().ToArray();
moveWrappers = self.TraitsImplementing<IWrapMove>().ToArray(); moveWrappers = self.TraitsImplementing<IWrapMove>().ToArray();
Locomotor = self.World.WorldActor.TraitsImplementing<Locomotor>()
.Single(l => l.Info.Name == Info.Locomotor);
base.Created(self); base.Created(self);
} }
@@ -704,7 +708,7 @@ namespace OpenRA.Mods.Common.Traits
var pathFinder = self.World.WorldActor.Trait<IPathFinder>(); var pathFinder = self.World.WorldActor.Trait<IPathFinder>();
List<CPos> path; List<CPos> path;
using (var search = PathSearch.Search(self.World, Info.LocomotorInfo, self, true, using (var search = PathSearch.Search(self.World, Locomotor, self, true,
loc => loc.Layer == 0 && CanEnterCell(loc)) loc => loc.Layer == 0 && CanEnterCell(loc))
.FromPoint(self.Location)) .FromPoint(self.Location))
path = pathFinder.FindPath(search); path = pathFinder.FindPath(search);

View File

@@ -64,7 +64,9 @@ namespace OpenRA.Mods.Common.Traits
public List<CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor) public List<CPos> FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor)
{ {
var li = self.Info.TraitInfo<MobileInfo>().LocomotorInfo; var mobile = self.Trait<Mobile>();
var locomotor = mobile.Locomotor;
if (!cached) if (!cached)
{ {
domainIndex = world.WorldActor.TraitOrDefault<DomainIndex>(); domainIndex = world.WorldActor.TraitOrDefault<DomainIndex>();
@@ -72,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits
} }
// If a water-land transition is required, bail early // If a water-land transition is required, bail early
if (domainIndex != null && !domainIndex.IsPassable(source, target, li)) if (domainIndex != null && !domainIndex.IsPassable(source, target, locomotor.Info))
return EmptyPath; return EmptyPath;
var distance = source - target; var distance = source - target;
@@ -80,8 +82,9 @@ namespace OpenRA.Mods.Common.Traits
return new List<CPos> { target }; return new List<CPos> { target };
List<CPos> pb; List<CPos> pb;
using (var fromSrc = PathSearch.FromPoint(world, li, self, target, source, true).WithIgnoredActor(ignoreActor))
using (var fromDest = PathSearch.FromPoint(world, li, self, source, target, true).WithIgnoredActor(ignoreActor).Reverse()) using (var fromSrc = PathSearch.FromPoint(world, locomotor, self, target, source, true).WithIgnoredActor(ignoreActor))
using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, target, true).WithIgnoredActor(ignoreActor).Reverse())
pb = FindBidiPath(fromSrc, fromDest); pb = FindBidiPath(fromSrc, fromDest);
return pb; return pb;
@@ -95,7 +98,8 @@ namespace OpenRA.Mods.Common.Traits
cached = true; cached = true;
} }
var mi = self.Info.TraitInfo<MobileInfo>(); var mobile = self.Trait<Mobile>();
var mi = mobile.Info;
var li = mi.LocomotorInfo; var li = mi.LocomotorInfo;
var targetCell = world.Map.CellContaining(target); var targetCell = world.Map.CellContaining(target);
@@ -117,8 +121,10 @@ namespace OpenRA.Mods.Common.Traits
return EmptyPath; return EmptyPath;
} }
using (var fromSrc = PathSearch.FromPoints(world, li, self, tilesInRange, source, true)) var locomotor = mobile.Locomotor;
using (var fromDest = PathSearch.FromPoint(world, li, self, source, targetCell, true).Reverse())
using (var fromSrc = PathSearch.FromPoints(world, locomotor, self, tilesInRange, source, true))
using (var fromDest = PathSearch.FromPoint(world, locomotor, self, source, targetCell, true).Reverse())
return FindBidiPath(fromSrc, fromDest); return FindBidiPath(fromSrc, fromDest);
} }