diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index e119666366..31aed69f6c 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -70,6 +70,7 @@ + diff --git a/OpenRa.Game/PathFinder.cs b/OpenRa.Game/PathFinder.cs index 654f9f8793..b79cb84139 100644 --- a/OpenRa.Game/PathFinder.cs +++ b/OpenRa.Game/PathFinder.cs @@ -11,34 +11,19 @@ namespace OpenRa.Game { public static PathFinder Instance; - bool[ , ] passable = new bool[ 128, 128 ]; + double[ , ] passableCost = new double[ 128, 128 ]; Map map; - static bool IsPassable(int terrainType) - { - switch (terrainType) - { - case 0: - case 2: - case 6: - case 8: - case 9: - return true; - default: - return false; - } - } - public PathFinder(Map map, TileSet tileSet) { this.map = map; - //todo: speed hax for roads + for( int x = 0 ; x < 128 ; x++ ) + for( int y = 0 ; y < 128 ; y++ ) - for (int x = 0; x < 128; x++) - for (int y = 0; y < 128; y++) - passable[x, y] = map.IsInMap(x, y) && - IsPassable(tileSet.GetWalkability(map.MapTiles[x, y])); + passableCost[ x, y ] = ( map.IsInMap( x, y ) ) + ? TerrainCosts.Cost( UnitMovementType.Wheel, tileSet.GetWalkability( map.MapTiles[ x, y ] ) ) + : double.PositiveInfinity; } public List FindUnitPath( World world, Unit unit, int2 destination ) @@ -83,13 +68,14 @@ namespace OpenRa.Game ++seenCount; continue; } - if( !passable[ newHere.X, newHere.Y ] ) + if( passableCost[ newHere.X, newHere.Y ] == double.PositiveInfinity ) { ++impassableCount; continue; } - double newCost = cellInfo[ here.X, here.Y ].MinCost + ( ( d.X * d.Y != 0 ) ? 1.414213563 : 1.0 ); + double cellCost = ( ( d.X * d.Y != 0 ) ? 1.414213563 : 1.0 ) * passableCost[ newHere.X, newHere.Y ]; + double newCost = cellInfo[ here.X, here.Y ].MinCost + cellCost; if( newCost >= cellInfo[ newHere.X, newHere.Y ].MinCost ) continue; diff --git a/OpenRa.Game/TerrainCosts.cs b/OpenRa.Game/TerrainCosts.cs new file mode 100644 index 0000000000..62f17c6db8 --- /dev/null +++ b/OpenRa.Game/TerrainCosts.cs @@ -0,0 +1,59 @@ +using System; +using System.Collections.Generic; +using System.Text; +using OpenRa.FileFormats; +using System.IO; + +namespace OpenRa.Game +{ + enum UnitMovementType : byte + { + Foot = 0, + Track = 1, + Wheel = 2, + Float = 3, + } + + enum TerrainMovementType : byte + { + Clear = 0, + Water = 1, + Road = 2, + Rock = 3, + //Tree = 4, + River = 5, + Rough = 6, + Wall = 7, + Beach = 8, + Ore = 9, + } + + static class TerrainCosts + { + static double[][] costs = Util.MakeArray( 4, + delegate { return Util.MakeArray( 10, + delegate { return double.PositiveInfinity; } ); } ); + + static TerrainCosts() + { + IniFile file = new IniFile( File.OpenRead( "../../../rules.ini" ) ); + + for( int i = 0 ; i < 10 ; i++ ) + { + if( i == 4 ) + continue; + IniSection section = file.GetSection( ( (TerrainMovementType)i ).ToString() ); + for( int j = 0 ; j < 4 ; j++ ) + { + string val = section.GetValue( ( (UnitMovementType)j ).ToString(), "0%" ); + costs[ j ][ i ] = 100.0 / double.Parse( val.Substring( 0, val.Length - 1 ) ); + } + } + } + + public static double Cost( UnitMovementType unitMovementType, int r ) + { + return costs[ (byte)unitMovementType ][ r ]; + } + } +}