diff --git a/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs b/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs index b37ce29ba6..4c398ad4c8 100644 --- a/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs +++ b/OpenRA.Mods.Common/Activities/FindAndDeliverResources.cs @@ -181,7 +181,7 @@ namespace OpenRA.Mods.Common.Activities // Find any harvestable resources: List 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)) .WithCustomCost(loc => { diff --git a/OpenRA.Mods.Common/Activities/Move/Move.cs b/OpenRA.Mods.Common/Activities/Move/Move.cs index cf39fc5d00..aa42431cec 100644 --- a/OpenRA.Mods.Common/Activities/Move/Move.cs +++ b/OpenRA.Mods.Common/Activities/Move/Move.cs @@ -51,7 +51,7 @@ namespace OpenRA.Mods.Common.Activities { List path; 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()) path = self.World.WorldActor.Trait().FindPath(search); return path; diff --git a/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs b/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs index c71fea425a..0dbfbaa8c0 100644 --- a/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs +++ b/OpenRA.Mods.Common/Activities/Move/MoveAdjacentTo.cs @@ -137,8 +137,8 @@ namespace OpenRA.Mods.Common.Activities if (!searchCells.Any()) return NoPath; - using (var fromSrc = PathSearch.FromPoints(self.World, Mobile.Info.LocomotorInfo, self, searchCells, loc, true)) - using (var fromDest = PathSearch.FromPoint(self.World, Mobile.Info.LocomotorInfo, self, loc, lastVisibleTargetLocation, true).Reverse()) + using (var fromSrc = PathSearch.FromPoints(self.World, Mobile.Locomotor, self, searchCells, loc, true)) + using (var fromDest = PathSearch.FromPoint(self.World, Mobile.Locomotor, self, loc, lastVisibleTargetLocation, true).Reverse()) return pathFinder.FindBidiPath(fromSrc, fromDest); } diff --git a/OpenRA.Mods.Common/Pathfinder/PathGraph.cs b/OpenRA.Mods.Common/Pathfinder/PathGraph.cs index 75820d4d5b..67fea85b87 100644 --- a/OpenRA.Mods.Common/Pathfinder/PathGraph.cs +++ b/OpenRA.Mods.Common/Pathfinder/PathGraph.cs @@ -83,7 +83,7 @@ namespace OpenRA.Mods.Common.Pathfinder public Actor IgnoreActor { get; set; } readonly CellConditions checkConditions; - readonly LocomotorInfo locomotorInfo; + readonly Locomotor locomotor; readonly LocomotorInfo.WorldMovementInfo worldMovementInfo; readonly CellInfoLayerPool.PooledCellInfoLayer pooledLayer; readonly bool checkTerrainHeight; @@ -92,11 +92,12 @@ namespace OpenRA.Mods.Common.Pathfinder readonly Dictionary>> customLayerInfo = new Dictionary>>(); - 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(); groundInfo = pooledLayer.GetLayer(); - locomotorInfo = li; + var locomotorInfo = locomotor.Info; + this.locomotor = locomotor; var layers = world.GetCustomMovementLayers().Values .Where(cml => cml.EnabledForActor(actor.Info, locomotorInfo)); @@ -153,7 +154,7 @@ namespace OpenRA.Mods.Common.Pathfinder foreach (var cli in customLayerInfo.Values) { 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) validNeighbors.Add(new GraphConnection(layerPosition, entryCost)); } @@ -161,7 +162,7 @@ namespace OpenRA.Mods.Common.Pathfinder else { 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) validNeighbors.Add(new GraphConnection(layerPosition, exitCost)); } diff --git a/OpenRA.Mods.Common/Pathfinder/PathSearch.cs b/OpenRA.Mods.Common/Pathfinder/PathSearch.cs index dfd3bb9988..3a6e55f704 100644 --- a/OpenRA.Mods.Common/Pathfinder/PathSearch.cs +++ b/OpenRA.Mods.Common/Pathfinder/PathSearch.cs @@ -45,18 +45,18 @@ namespace OpenRA.Mods.Common.Pathfinder considered = new LinkedList>(); } - public static IPathSearch Search(World world, LocomotorInfo li, Actor self, bool checkForBlocked, Func goalCondition) + public static IPathSearch Search(World world, Locomotor locomotor, Actor self, bool checkForBlocked, Func 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); search.isGoal = goalCondition; search.heuristic = loc => 0; 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) { heuristic = DefaultEstimator(target) @@ -74,9 +74,9 @@ namespace OpenRA.Mods.Common.Pathfinder return search; } - public static IPathSearch FromPoints(World world, LocomotorInfo li, Actor self, IEnumerable froms, CPos target, bool checkForBlocked) + public static IPathSearch FromPoints(World world, Locomotor locomotor, Actor self, IEnumerable 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) { heuristic = DefaultEstimator(target) diff --git a/OpenRA.Mods.Common/Traits/BotModules/HarvesterBotModule.cs b/OpenRA.Mods.Common/Traits/BotModules/HarvesterBotModule.cs index 9c419982d6..35107f9694 100644 --- a/OpenRA.Mods.Common/Traits/BotModules/HarvesterBotModule.cs +++ b/OpenRA.Mods.Common/Traits/BotModules/HarvesterBotModule.cs @@ -44,14 +44,15 @@ namespace OpenRA.Mods.Common.Traits public readonly Actor Actor; public readonly Harvester Harvester; public readonly Parachutable Parachutable; - public readonly LocomotorInfo LocomotorInfo; + public readonly Locomotor Locomotor; public HarvesterTraitWrapper(Actor actor) { Actor = actor; Harvester = actor.Trait(); Parachutable = actor.TraitOrDefault(); - LocomotorInfo = actor.Info.TraitInfo().LocomotorInfo; + var mobile = actor.Trait(); + Locomotor = mobile.Locomotor; } } @@ -141,12 +142,12 @@ namespace OpenRA.Mods.Common.Traits Target FindNextResource(Actor actor, HarvesterTraitWrapper harv) { Func isValidResource = cell => - domainIndex.IsPassable(actor.Location, cell, harv.LocomotorInfo) && + domainIndex.IsPassable(actor.Location, cell, harv.Locomotor.Info) && harv.Harvester.CanHarvestCell(actor, cell) && claimLayer.CanClaimCell(actor, cell); 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) .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))) diff --git a/OpenRA.Mods.Common/Traits/Harvester.cs b/OpenRA.Mods.Common/Traits/Harvester.cs index 66a081ca88..fe096fc470 100644 --- a/OpenRA.Mods.Common/Traits/Harvester.cs +++ b/OpenRA.Mods.Common/Traits/Harvester.cs @@ -201,8 +201,8 @@ namespace OpenRA.Mods.Common.Traits // Start a search from each refinery's delivery location: List path; - var li = self.Info.TraitInfo().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 => { if (!refs.ContainsKey(loc)) diff --git a/OpenRA.Mods.Common/Traits/Mobile.cs b/OpenRA.Mods.Common/Traits/Mobile.cs index c4958fab77..e780ff1a05 100644 --- a/OpenRA.Mods.Common/Traits/Mobile.cs +++ b/OpenRA.Mods.Common/Traits/Mobile.cs @@ -185,6 +185,8 @@ namespace OpenRA.Mods.Common.Traits [Sync] public int PathHash; // written by Move.EvalPath, to temporarily debug this crap. + public Locomotor Locomotor { get; private set; } + #region IOccupySpace [Sync] @@ -235,6 +237,8 @@ namespace OpenRA.Mods.Common.Traits notifyMoving = self.TraitsImplementing().ToArray(); notifyFinishedMoving = self.TraitsImplementing().ToArray(); moveWrappers = self.TraitsImplementing().ToArray(); + Locomotor = self.World.WorldActor.TraitsImplementing() + .Single(l => l.Info.Name == Info.Locomotor); base.Created(self); } @@ -704,7 +708,7 @@ namespace OpenRA.Mods.Common.Traits var pathFinder = self.World.WorldActor.Trait(); List 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)) .FromPoint(self.Location)) path = pathFinder.FindPath(search); diff --git a/OpenRA.Mods.Common/Traits/World/PathFinder.cs b/OpenRA.Mods.Common/Traits/World/PathFinder.cs index 67410c878e..c3be1dbb85 100644 --- a/OpenRA.Mods.Common/Traits/World/PathFinder.cs +++ b/OpenRA.Mods.Common/Traits/World/PathFinder.cs @@ -64,7 +64,9 @@ namespace OpenRA.Mods.Common.Traits public List FindUnitPath(CPos source, CPos target, Actor self, Actor ignoreActor) { - var li = self.Info.TraitInfo().LocomotorInfo; + var mobile = self.Trait(); + var locomotor = mobile.Locomotor; + if (!cached) { domainIndex = world.WorldActor.TraitOrDefault(); @@ -72,7 +74,7 @@ namespace OpenRA.Mods.Common.Traits } // 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; var distance = source - target; @@ -80,8 +82,9 @@ namespace OpenRA.Mods.Common.Traits return new List { target }; List 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); return pb; @@ -95,7 +98,8 @@ namespace OpenRA.Mods.Common.Traits cached = true; } - var mi = self.Info.TraitInfo(); + var mobile = self.Trait(); + var mi = mobile.Info; var li = mi.LocomotorInfo; var targetCell = world.Map.CellContaining(target); @@ -117,8 +121,10 @@ namespace OpenRA.Mods.Common.Traits return EmptyPath; } - using (var fromSrc = PathSearch.FromPoints(world, li, self, tilesInRange, source, true)) - using (var fromDest = PathSearch.FromPoint(world, li, self, source, targetCell, true).Reverse()) + var locomotor = mobile.Locomotor; + + 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); }