Merge pull request #7430 from Rydra/upstream/pf-optimized
[Discussion PR] Complete refactor of Pathfinder
This commit is contained in:
@@ -12,6 +12,7 @@ using System.Collections.Generic;
|
||||
using System.Drawing;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Pathfinder;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -51,31 +52,34 @@ namespace OpenRA.Mods.Common.Activities
|
||||
var searchRadiusSquared = searchRadius * searchRadius;
|
||||
|
||||
// Find harvestable resources nearby:
|
||||
var path = self.World.WorldActor.Trait<PathFinder>().FindPath(
|
||||
var path = self.World.WorldActor.Trait<IPathFinder>().FindPath(
|
||||
PathSearch.Search(self.World, mobileInfo, self, true)
|
||||
.WithHeuristic(loc =>
|
||||
{
|
||||
// Avoid this cell:
|
||||
if (avoidCell.HasValue && loc == avoidCell.Value) return 1;
|
||||
if (avoidCell.HasValue && loc == avoidCell.Value)
|
||||
return Constants.CellCost;
|
||||
|
||||
// Don't harvest out of range:
|
||||
var distSquared = (loc - searchFromLoc).LengthSquared;
|
||||
if (distSquared > searchRadiusSquared)
|
||||
return int.MaxValue;
|
||||
return Constants.CellCost * 2;
|
||||
|
||||
// Get the resource at this location:
|
||||
var resType = resLayer.GetResource(loc);
|
||||
|
||||
if (resType == null) return 1;
|
||||
if (resType == null)
|
||||
return Constants.CellCost;
|
||||
|
||||
// Can the harvester collect this kind of resource?
|
||||
if (!harvInfo.Resources.Contains(resType.Info.Name)) return 1;
|
||||
if (!harvInfo.Resources.Contains(resType.Info.Name))
|
||||
return Constants.CellCost;
|
||||
|
||||
if (territory != null)
|
||||
{
|
||||
// Another harvester has claimed this resource:
|
||||
ResourceClaim claim;
|
||||
if (territory.IsClaimedByAnyoneElse(self, loc, out claim)) return 1;
|
||||
if (territory.IsClaimedByAnyoneElse(self, loc, out claim))
|
||||
return Constants.CellCost;
|
||||
}
|
||||
|
||||
return 0;
|
||||
|
||||
@@ -13,6 +13,7 @@ using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Pathfinder;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Primitives;
|
||||
using OpenRA.Traits;
|
||||
@@ -45,7 +46,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
moveDisablers = self.TraitsImplementing<IDisableMove>();
|
||||
|
||||
getPath = () =>
|
||||
self.World.WorldActor.Trait<PathFinder>().FindPath(
|
||||
self.World.WorldActor.Trait<IPathFinder>().FindPath(
|
||||
PathSearch.FromPoint(self.World, mobile.Info, self, mobile.ToCell, destination, false)
|
||||
.WithoutLaneBias());
|
||||
this.destination = destination;
|
||||
@@ -61,7 +62,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
mobile = self.Trait<Mobile>();
|
||||
moveDisablers = self.TraitsImplementing<IDisableMove>();
|
||||
|
||||
getPath = () => self.World.WorldActor.Trait<PathFinder>()
|
||||
getPath = () => self.World.WorldActor.Trait<IPathFinder>()
|
||||
.FindUnitPath(mobile.ToCell, destination, self);
|
||||
this.destination = destination;
|
||||
this.nearEnough = nearEnough;
|
||||
@@ -72,7 +73,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
mobile = self.Trait<Mobile>();
|
||||
moveDisablers = self.TraitsImplementing<IDisableMove>();
|
||||
|
||||
getPath = () => self.World.WorldActor.Trait<PathFinder>()
|
||||
getPath = () => self.World.WorldActor.Trait<IPathFinder>()
|
||||
.FindUnitPathToRange(mobile.FromCell, subCell, self.World.Map.CenterOfSubCell(destination, subCell), nearEnough, self);
|
||||
this.destination = destination;
|
||||
this.nearEnough = nearEnough;
|
||||
@@ -84,7 +85,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
moveDisablers = self.TraitsImplementing<IDisableMove>();
|
||||
|
||||
getPath = () =>
|
||||
self.World.WorldActor.Trait<PathFinder>().FindPath(
|
||||
self.World.WorldActor.Trait<IPathFinder>().FindPath(
|
||||
PathSearch.FromPoint(self.World, mobile.Info, self, mobile.ToCell, destination, false)
|
||||
.WithIgnoredActor(ignoredActor));
|
||||
|
||||
@@ -103,7 +104,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
if (!target.IsValidFor(self))
|
||||
return NoPath;
|
||||
|
||||
return self.World.WorldActor.Trait<PathFinder>().FindUnitPathToRange(
|
||||
return self.World.WorldActor.Trait<IPathFinder>().FindUnitPathToRange(
|
||||
mobile.ToCell, mobile.ToSubCell, target.CenterPosition, range, self);
|
||||
};
|
||||
|
||||
@@ -132,7 +133,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
return hash;
|
||||
}
|
||||
|
||||
List<CPos> EvalPath(Actor self, Mobile mobile)
|
||||
List<CPos> EvalPath()
|
||||
{
|
||||
var path = getPath().TakeWhile(a => a != mobile.ToCell).ToList();
|
||||
mobile.PathHash = HashList(path);
|
||||
@@ -155,7 +156,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
return this;
|
||||
}
|
||||
|
||||
path = EvalPath(self, mobile);
|
||||
path = EvalPath();
|
||||
SanityCheckPath(mobile);
|
||||
}
|
||||
|
||||
@@ -167,7 +168,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
|
||||
destination = path[0];
|
||||
|
||||
var nextCell = PopPath(self, mobile);
|
||||
var nextCell = PopPath(self);
|
||||
if (nextCell == null)
|
||||
return this;
|
||||
|
||||
@@ -202,7 +203,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
throw new InvalidOperationException("(Move) Sanity check failed");
|
||||
}
|
||||
|
||||
Pair<CPos, SubCell>? PopPath(Actor self, Mobile mobile)
|
||||
Pair<CPos, SubCell>? PopPath(Actor self)
|
||||
{
|
||||
if (path.Count == 0)
|
||||
return null;
|
||||
@@ -210,7 +211,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
var nextCell = path[path.Count - 1];
|
||||
|
||||
// Next cell in the move is blocked by another actor
|
||||
if (!mobile.CanEnterCell(nextCell, ignoredActor, true))
|
||||
if (!mobile.CanMoveFreelyInto(nextCell, ignoredActor, true))
|
||||
{
|
||||
// Are we close enough?
|
||||
var cellRange = nearEnough.Range / 1024;
|
||||
@@ -246,7 +247,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
|
||||
// Calculate a new path
|
||||
mobile.RemoveInfluence();
|
||||
var newPath = EvalPath(self, mobile);
|
||||
var newPath = EvalPath();
|
||||
mobile.AddInfluence();
|
||||
|
||||
if (newPath.Count != 0)
|
||||
@@ -372,7 +373,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
var fromSubcellOffset = self.World.Map.OffsetOfSubCell(mobile.FromSubCell);
|
||||
var toSubcellOffset = self.World.Map.OffsetOfSubCell(mobile.ToSubCell);
|
||||
|
||||
var nextCell = parent.PopPath(self, mobile);
|
||||
var nextCell = parent.PopPath(self);
|
||||
if (nextCell != null)
|
||||
{
|
||||
if (IsTurn(mobile, nextCell.Value.First))
|
||||
|
||||
@@ -12,6 +12,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using OpenRA.Activities;
|
||||
using OpenRA.Mods.Common.Pathfinder;
|
||||
using OpenRA.Mods.Common.Traits;
|
||||
using OpenRA.Traits;
|
||||
|
||||
@@ -22,7 +23,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
static readonly List<CPos> NoPath = new List<CPos>();
|
||||
|
||||
readonly Mobile mobile;
|
||||
readonly PathFinder pathFinder;
|
||||
readonly IPathFinder pathFinder;
|
||||
readonly DomainIndex domainIndex;
|
||||
readonly uint movementClass;
|
||||
|
||||
@@ -36,7 +37,7 @@ namespace OpenRA.Mods.Common.Activities
|
||||
Target = target;
|
||||
|
||||
mobile = self.Trait<Mobile>();
|
||||
pathFinder = self.World.WorldActor.Trait<PathFinder>();
|
||||
pathFinder = self.World.WorldActor.Trait<IPathFinder>();
|
||||
domainIndex = self.World.WorldActor.Trait<DomainIndex>();
|
||||
movementClass = (uint)mobile.Info.GetMovementClass(self.World.TileSet);
|
||||
|
||||
|
||||
Reference in New Issue
Block a user