Merge pull request #8735 from reaperrr/safe-pf-changes

Minor pathfinder-related changes (preparation for mobile refactor)
This commit is contained in:
Oliver Brakmann
2015-07-22 14:42:52 +02:00
6 changed files with 21 additions and 19 deletions

View File

@@ -212,35 +212,36 @@ namespace OpenRA.Traits
yield return i.Actor; yield return i.Actor;
} }
public bool HasFreeSubCell(CPos a, bool checkTransient = true) public bool HasFreeSubCell(CPos cell, bool checkTransient = true)
{ {
return FreeSubCell(a, SubCell.Any, checkTransient) != SubCell.Invalid; return FreeSubCell(cell, SubCell.Any, checkTransient) != SubCell.Invalid;
} }
public SubCell FreeSubCell(CPos a, SubCell preferredSubCell = SubCell.Any, bool checkTransient = true) public SubCell FreeSubCell(CPos cell, SubCell preferredSubCell = SubCell.Any, bool checkTransient = true)
{ {
if (preferredSubCell > SubCell.Any && !AnyUnitsAt(a, preferredSubCell, checkTransient)) if (preferredSubCell > SubCell.Any && !AnyUnitsAt(cell, preferredSubCell, checkTransient))
return preferredSubCell; return preferredSubCell;
if (!AnyUnitsAt(a)) if (!AnyUnitsAt(cell))
return map.DefaultSubCell; return map.DefaultSubCell;
for (var i = (int)SubCell.First; i < map.SubCellOffsets.Length; i++) for (var i = (int)SubCell.First; i < map.SubCellOffsets.Length; i++)
if (i != (int)preferredSubCell && !AnyUnitsAt(a, (SubCell)i, checkTransient)) if (i != (int)preferredSubCell && !AnyUnitsAt(cell, (SubCell)i, checkTransient))
return (SubCell)i; return (SubCell)i;
return SubCell.Invalid; return SubCell.Invalid;
} }
public SubCell FreeSubCell(CPos a, SubCell preferredSubCell, Func<Actor, bool> checkIfBlocker) public SubCell FreeSubCell(CPos cell, SubCell preferredSubCell, Func<Actor, bool> checkIfBlocker)
{ {
if (preferredSubCell > SubCell.Any && !AnyUnitsAt(a, preferredSubCell, checkIfBlocker)) if (preferredSubCell > SubCell.Any && !AnyUnitsAt(cell, preferredSubCell, checkIfBlocker))
return preferredSubCell; return preferredSubCell;
if (!AnyUnitsAt(a)) if (!AnyUnitsAt(cell))
return map.DefaultSubCell; return map.DefaultSubCell;
for (var i = (int)SubCell.First; i < map.SubCellOffsets.Length; i++) for (var i = (int)SubCell.First; i < map.SubCellOffsets.Length; i++)
if (i != (int)preferredSubCell && !AnyUnitsAt(a, (SubCell)i, checkIfBlocker)) if (i != (int)preferredSubCell && !AnyUnitsAt(cell, (SubCell)i, checkIfBlocker))
return (SubCell)i; return (SubCell)i;
return SubCell.Invalid; return SubCell.Invalid;
} }
@@ -325,7 +326,7 @@ namespace OpenRA.Traits
} }
} }
void RemoveInfluenceInner(ref InfluenceNode influenceNode, Actor toRemove) static void RemoveInfluenceInner(ref InfluenceNode influenceNode, Actor toRemove)
{ {
if (influenceNode == null) if (influenceNode == null)
return; return;

View File

@@ -35,6 +35,9 @@ namespace OpenRA
public static bool operator ==(WPos me, WPos other) { return me.X == other.X && me.Y == other.Y && me.Z == other.Z; } public static bool operator ==(WPos me, WPos other) { return me.X == other.X && me.Y == other.Y && me.Z == other.Z; }
public static bool operator !=(WPos me, WPos other) { return !(me == other); } public static bool operator !=(WPos me, WPos other) { return !(me == other); }
/// <summary>
/// Returns the linear interpolation between points 'a' and 'b'
/// </summary>
public static WPos Lerp(WPos a, WPos b, int mul, int div) { return a + (b - a) * mul / div; } public static WPos Lerp(WPos a, WPos b, int mul, int div) { return a + (b - a) * mul / div; }
public static WPos LerpQuadratic(WPos a, WPos b, WAngle pitch, int mul, int div) public static WPos LerpQuadratic(WPos a, WPos b, WAngle pitch, int mul, int div)

View File

@@ -81,7 +81,7 @@ namespace OpenRA.Mods.Common.Pathfinder
if (string.IsNullOrEmpty(id)) if (string.IsNullOrEmpty(id))
{ {
var builder = new StringBuilder(); var builder = new StringBuilder();
builder.Append(this.Graph.Actor.ActorID); builder.Append(Graph.Actor.ActorID);
while (!startPoints.Empty) while (!startPoints.Empty)
{ {
var startpoint = startPoints.Pop(); var startpoint = startPoints.Pop();

View File

@@ -97,7 +97,7 @@ namespace OpenRA.Mods.Common.Pathfinder
{ {
defaultCellInfoLayer = defaultCellInfoLayer =
CellLayer<CellInfo>.CreateInstance( CellLayer<CellInfo>.CreateInstance(
mpos => new CellInfo(int.MaxValue, int.MaxValue, mpos.ToCPos(map as Map), CellStatus.Unvisited), mpos => new CellInfo(int.MaxValue, int.MaxValue, mpos.ToCPos(map), CellStatus.Unvisited),
new Size(map.MapSize.X, map.MapSize.Y), new Size(map.MapSize.X, map.MapSize.Y),
map.TileShape); map.TileShape);
} }

View File

@@ -73,8 +73,6 @@ namespace OpenRA.Mods.Common.Pathfinder
readonly MobileInfo mobileInfo; readonly MobileInfo mobileInfo;
CellLayer<CellInfo> cellInfo; CellLayer<CellInfo> cellInfo;
public const int InvalidNode = int.MaxValue;
public PathGraph(CellLayer<CellInfo> cellInfo, MobileInfo mobileInfo, Actor actor, World world, bool checkForBlocked) public PathGraph(CellLayer<CellInfo> cellInfo, MobileInfo mobileInfo, Actor actor, World world, bool checkForBlocked)
{ {
this.cellInfo = cellInfo; this.cellInfo = cellInfo;
@@ -127,11 +125,11 @@ namespace OpenRA.Mods.Common.Pathfinder
{ {
int movementCost; int movementCost;
if (mobileInfo.CanEnterCell( if (mobileInfo.CanEnterCell(
World as World, World,
Actor as Actor, Actor,
destNode, destNode,
out movementCost, out movementCost,
IgnoredActor as Actor, IgnoredActor,
checkConditions) && !(CustomBlock != null && CustomBlock(destNode))) checkConditions) && !(CustomBlock != null && CustomBlock(destNode)))
{ {
return CalculateCellCost(destNode, direction, movementCost); return CalculateCellCost(destNode, direction, movementCost);

View File

@@ -93,7 +93,7 @@ namespace OpenRA.Mods.Common.Traits
// This assumes that the SubCell does not change during the path traversal // This assumes that the SubCell does not change during the path traversal
var tilesInRange = world.Map.FindTilesInCircle(targetCell, range.Length / 1024 + 1) var tilesInRange = world.Map.FindTilesInCircle(targetCell, range.Length / 1024 + 1)
.Where(t => (world.Map.CenterOfCell(t) - target).LengthSquared <= range.LengthSquared .Where(t => (world.Map.CenterOfCell(t) - target).LengthSquared <= range.LengthSquared
&& mi.CanEnterCell(self.World as World, self as Actor, t)); && mi.CanEnterCell(self.World, self, t));
// See if there is any cell within range that does not involve a cross-domain request // See if there is any cell within range that does not involve a cross-domain request
// Really, we only need to check the circle perimeter, but it's not clear that would be a performance win // Really, we only need to check the circle perimeter, but it's not clear that would be a performance win