make the pathfinder use integers

This commit is contained in:
Bob
2010-09-22 07:40:21 +12:00
parent ac8d408ba7
commit 2f6315b816
6 changed files with 42 additions and 49 deletions

View File

@@ -207,11 +207,11 @@ namespace OpenRA
public struct CellInfo public struct CellInfo
{ {
public float MinCost; public int MinCost;
public int2 Path; public int2 Path;
public bool Seen; public bool Seen;
public CellInfo( float minCost, int2 path, bool seen ) public CellInfo( int minCost, int2 path, bool seen )
{ {
MinCost = minCost; MinCost = minCost;
Path = path; Path = path;
@@ -221,10 +221,10 @@ namespace OpenRA
public struct PathDistance : IComparable<PathDistance> public struct PathDistance : IComparable<PathDistance>
{ {
public float EstTotal; public int EstTotal;
public int2 Location; public int2 Location;
public PathDistance(float estTotal, int2 location) public PathDistance(int estTotal, int2 location)
{ {
EstTotal = estTotal; EstTotal = estTotal;
Location = location; Location = location;

View File

@@ -20,7 +20,7 @@ namespace OpenRA
World world; World world;
public CellInfo[ , ] cellInfo; public CellInfo[ , ] cellInfo;
public PriorityQueue<PathDistance> queue; public PriorityQueue<PathDistance> queue;
public Func<int2, float> heuristic; public Func<int2, int> heuristic;
Func<int2, bool> customBlock; Func<int2, bool> customBlock;
public bool checkForBlocked; public bool checkForBlocked;
public Actor ignoreBuilding; public Actor ignoreBuilding;
@@ -58,7 +58,7 @@ namespace OpenRA
return this; return this;
} }
public PathSearch WithHeuristic(Func<int2, float> h) public PathSearch WithHeuristic(Func<int2, int> h)
{ {
heuristic = h; heuristic = h;
return this; return this;
@@ -66,7 +66,7 @@ namespace OpenRA
public PathSearch WithoutLaneBias() public PathSearch WithoutLaneBias()
{ {
LaneBias = 0f; LaneBias = 0;
return this; return this;
} }
@@ -76,7 +76,7 @@ namespace OpenRA
return this; return this;
} }
float LaneBias = .5f; int LaneBias = 1;
public int2 Expand( World world ) public int2 Expand( World world )
{ {
@@ -91,7 +91,7 @@ namespace OpenRA
var thisCost = Mobile.MovementCostForCell(mobileInfo, world, p.Location); var thisCost = Mobile.MovementCostForCell(mobileInfo, world, p.Location);
if (thisCost == float.PositiveInfinity) if (thisCost == int.MaxValue)
return p.Location; return p.Location;
foreach( int2 d in directions ) foreach( int2 d in directions )
@@ -102,9 +102,9 @@ namespace OpenRA
if( cellInfo[ newHere.X, newHere.Y ].Seen ) if( cellInfo[ newHere.X, newHere.Y ].Seen )
continue; continue;
var costHere = (float)Mobile.MovementCostForCell(mobileInfo, world, newHere); var costHere = Mobile.MovementCostForCell(mobileInfo, world, newHere);
if (costHere == float.PositiveInfinity) if (costHere == int.MaxValue)
continue; continue;
if (!Mobile.CanEnterCell(mobileInfo, world, uim, bim, newHere, ignoreBuilding, checkForBlocked)) if (!Mobile.CanEnterCell(mobileInfo, world, uim, bim, newHere, ignoreBuilding, checkForBlocked))
@@ -114,10 +114,11 @@ namespace OpenRA
continue; continue;
var est = heuristic( newHere ); var est = heuristic( newHere );
if( est == float.PositiveInfinity ) if( est == int.MaxValue )
continue; continue;
float cellCost = (float)(((d.X * d.Y != 0) ? 1.414213563f : 1.0f) * costHere); int cellCost = costHere;
if( d.X * d.Y != 0 ) cellCost = ( cellCost * 34 ) / 24;
// directional bonuses for smoother flow! // directional bonuses for smoother flow!
var ux = (newHere.X + (inReverse ? 1 : 0) & 1); var ux = (newHere.X + (inReverse ? 1 : 0) & 1);
@@ -128,7 +129,7 @@ namespace OpenRA
if (uy == 0 && d.X < 0) cellCost += LaneBias; if (uy == 0 && d.X < 0) cellCost += LaneBias;
else if (uy == 1 && d.X > 0) cellCost += LaneBias; else if (uy == 1 && d.X > 0) cellCost += LaneBias;
float newCost = (float)(cellInfo[ p.Location.X, p.Location.Y ].MinCost + cellCost); int newCost = cellInfo[ p.Location.X, p.Location.Y ].MinCost + cellCost;
if( newCost >= cellInfo[ newHere.X, newHere.Y ].MinCost ) if( newCost >= cellInfo[ newHere.X, newHere.Y ].MinCost )
continue; continue;
@@ -199,18 +200,18 @@ namespace OpenRA
var cellInfo = new CellInfo[ world.Map.MapSize.X, world.Map.MapSize.Y ]; var cellInfo = new CellInfo[ world.Map.MapSize.X, world.Map.MapSize.Y ];
for( int x = 0 ; x < world.Map.MapSize.X ; x++ ) for( int x = 0 ; x < world.Map.MapSize.X ; x++ )
for( int y = 0 ; y < world.Map.MapSize.Y ; y++ ) for( int y = 0 ; y < world.Map.MapSize.Y ; y++ )
cellInfo[ x, y ] = new CellInfo( float.PositiveInfinity, new int2( x, y ), false ); cellInfo[ x, y ] = new CellInfo( int.MaxValue, new int2( x, y ), false );
return cellInfo; return cellInfo;
} }
public static Func<int2, float> DefaultEstimator( int2 destination ) public static Func<int2, int> DefaultEstimator( int2 destination )
{ {
return here => return here =>
{ {
int2 d = ( here - destination ).Abs(); int2 d = ( here - destination ).Abs();
int diag = Math.Min( d.X, d.Y ); int diag = Math.Min( d.X, d.Y );
int straight = Math.Abs( d.X - d.Y ); int straight = Math.Abs( d.X - d.Y );
return 1.5f * diag + straight; return (3400 * diag / 24) + (100 * straight);
}; };
} }
} }

View File

@@ -39,7 +39,7 @@ namespace OpenRA.Traits
foreach (var t in y.NodesDict["TerrainSpeeds"].Nodes) foreach (var t in y.NodesDict["TerrainSpeeds"].Nodes)
{ {
var speed = (float)FieldLoader.GetValue("speed", typeof(float),t.Value.Value); var speed = (float)FieldLoader.GetValue("speed", typeof(float),t.Value.Value);
var cost = t.Value.NodesDict.ContainsKey("PathingCost") ? (float)FieldLoader.GetValue("cost", typeof(float), t.Value.NodesDict["PathingCost"].Value) : 1f/speed; var cost = t.Value.NodesDict.ContainsKey("PathingCost") ? (int)FieldLoader.GetValue("cost", typeof(int), t.Value.NodesDict["PathingCost"].Value) : (int)(10000/speed);
ret.Add(t.Key, new TerrainInfo{Speed = speed, Cost = cost}); ret.Add(t.Key, new TerrainInfo{Speed = speed, Cost = cost});
} }
@@ -48,7 +48,7 @@ namespace OpenRA.Traits
public class TerrainInfo public class TerrainInfo
{ {
public float Cost = float.PositiveInfinity; public int Cost = int.MaxValue;
public float Speed = 0; public float Speed = 0;
} }
} }
@@ -250,7 +250,7 @@ namespace OpenRA.Traits
public static bool CanEnterCell( MobileInfo mobileInfo, World world, UnitInfluence uim, BuildingInfluence bim, int2 cell, Actor ignoreActor, bool checkTransientActors ) public static bool CanEnterCell( MobileInfo mobileInfo, World world, UnitInfluence uim, BuildingInfluence bim, int2 cell, Actor ignoreActor, bool checkTransientActors )
{ {
if (MovementCostForCell(mobileInfo, world, cell) == float.PositiveInfinity) if (MovementCostForCell(mobileInfo, world, cell) == int.MaxValue)
return false; return false;
// Check for buildings // Check for buildings
@@ -295,19 +295,14 @@ namespace OpenRA.Traits
} }
} }
public float MovementCostForCell( Actor self, int2 cell ) public static int MovementCostForCell(MobileInfo info, World world, int2 cell)
{
return MovementCostForCell( Info, self.World, cell );
}
public static float MovementCostForCell(MobileInfo info, World world, int2 cell)
{ {
if (!world.Map.IsInMap(cell.X,cell.Y)) if (!world.Map.IsInMap(cell.X,cell.Y))
return float.PositiveInfinity; return int.MaxValue;
var type = world.GetTerrainType(cell); var type = world.GetTerrainType(cell);
if (!info.TerrainSpeeds.ContainsKey(type)) if (!info.TerrainSpeeds.ContainsKey(type))
return float.PositiveInfinity; return int.MaxValue;
return info.TerrainSpeeds[type].Cost; return info.TerrainSpeeds[type].Cost;
} }
@@ -323,7 +318,7 @@ namespace OpenRA.Traits
.TraitsImplementing<ISpeedModifier>() .TraitsImplementing<ISpeedModifier>()
.Select(t => t.GetSpeedModifier()) .Select(t => t.GetSpeedModifier())
.Product(); .Product();
return Info.Speed * Info.TerrainSpeeds[type].Speed * modifier; return Info.Speed * Info.TerrainSpeeds[type].Speed * modifier / 100f;
} }
public IEnumerable<float2> GetCurrentPath(Actor self) public IEnumerable<float2> GetCurrentPath(Actor self)

View File

@@ -112,7 +112,6 @@ namespace OpenRA.Traits
public interface IMove : ITeleportable public interface IMove : ITeleportable
{ {
float MovementCostForCell(Actor self, int2 cell);
float MovementSpeedForCell(Actor self, int2 cell); float MovementSpeedForCell(Actor self, int2 cell);
IEnumerable<float2> GetCurrentPath(Actor self); IEnumerable<float2> GetCurrentPath(Actor self);
int Altitude { get; set; } int Altitude { get; set; }

View File

@@ -80,8 +80,6 @@ namespace OpenRA.Mods.RA
public bool CanEnterCell(int2 location) { return true; } public bool CanEnterCell(int2 location) { return true; }
public float MovementCostForCell(Actor self, int2 cell) { return 1f; }
public float MovementSpeedForCell(Actor self, int2 cell) public float MovementSpeedForCell(Actor self, int2 cell)
{ {
var modifier = self var modifier = self

View File

@@ -3,11 +3,11 @@
Mobile: Mobile:
Crushes: atmine, crate Crushes: atmine, crate
TerrainSpeeds: TerrainSpeeds:
Clear: 60% Clear: 60
Rough: 40% Rough: 40
Road: 100% Road: 100
Ore: 90% Ore: 90
Beach: 40% Beach: 40
ROT: 5 ROT: 5
Selectable: Selectable:
Voice: VehicleVoice Voice: VehicleVoice
@@ -30,11 +30,11 @@
Mobile: Mobile:
Crushes: wall, atmine, crate Crushes: wall, atmine, crate
TerrainSpeeds: TerrainSpeeds:
Clear: 80% Clear: 80
Rough: 70% Rough: 70
Road: 100% Road: 100
Ore: 70% Ore: 70
Beach: 70% Beach: 70
ROT: 5 ROT: 5
Selectable: Selectable:
Voice: VehicleVoice Voice: VehicleVoice
@@ -62,11 +62,11 @@
Mobile: Mobile:
Crushes: apmine, crate Crushes: apmine, crate
TerrainSpeeds: TerrainSpeeds:
Clear: 90% Clear: 90
Rough: 80% Rough: 80
Road: 100% Road: 100
Ore: 100% Ore: 100
Beach: 80% Beach: 80
Selectable: Selectable:
Voice: GenericVoice Voice: GenericVoice
Targetable: Targetable:
@@ -88,7 +88,7 @@
Mobile: Mobile:
Crushes: crate Crushes: crate
TerrainSpeeds: TerrainSpeeds:
Water: 100% Water: 100
Selectable: Selectable:
Voice: ShipVoice Voice: ShipVoice
Targetable: Targetable:
@@ -208,4 +208,4 @@
Footprint: ____ ____ Footprint: ____ ____
Dimensions: 4,2 Dimensions: 4,2
Health: Health:
HP: 1000 HP: 1000