Merge pull request #7430 from Rydra/upstream/pf-optimized

[Discussion PR] Complete refactor of Pathfinder
This commit is contained in:
Paul Chote
2015-03-03 19:50:25 +00:00
31 changed files with 1866 additions and 615 deletions

View File

@@ -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;

View File

@@ -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))

View File

@@ -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);