moved directions to a shared place; fixed pathfinder to use the appropriate movement type

This commit is contained in:
Chris Forbes
2009-10-26 10:45:29 +13:00
parent e61ef4a93f
commit 482273f604
4 changed files with 47 additions and 28 deletions

View File

@@ -5,6 +5,7 @@ using System.Text;
using OpenRa.Game.GameRules;
using IjwFramework.Types;
using IjwFramework.Collections;
using OpenRa.Game.Graphics;
namespace OpenRa.Game
{
@@ -66,7 +67,7 @@ namespace OpenRa.Game
if (c.distance + 1 > maxDistance) continue;
foreach (var d in PathFinder.directions)
foreach (var d in Util.directions)
{
var e = c.location + d;
if (e.X < min.X || e.Y < min.Y || e.X > max.X || e.Y > max.Y)

View File

@@ -42,6 +42,18 @@ namespace OpenRa.Game.Graphics
return result;
}
public static readonly int2[] directions =
new int2[] {
new int2( -1, -1 ),
new int2( -1, 0 ),
new int2( -1, 1 ),
new int2( 0, -1 ),
new int2( 0, 1 ),
new int2( 1, -1 ),
new int2( 1, 0 ),
new int2( 1, 1 ),
};
static float[] channelSelect = { 0.75f, 0.25f, -0.25f, -0.75f };
public static void FastCreateQuad(Vertex[] vertices, ushort[] indices, float2 o, Sprite r, int palette, int nv, int ni)

View File

@@ -2,27 +2,35 @@ using System;
using System.Collections.Generic;
using IjwFramework.Collections;
using OpenRa.FileFormats;
using OpenRa.Game.Graphics;
namespace OpenRa.Game
{
class PathFinder
{
double[ , ] passableCost = new double[ 128, 128 ];
double[][,] passableCost = new double[4][,];
Map map;
public PathFinder(Map map, TileSet tileSet)
{
this.map = map;
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++)
passableCost[(int)umt] = new double[128, 128];
for( int x = 0 ; x < 128 ; x++ )
for( int y = 0 ; y < 128 ; y++ )
passableCost[ x, y ] = ( map.IsInMap( x, y ) )
? TerrainCosts.Cost( UnitMovementType.Wheel, tileSet.GetWalkability( map.MapTiles[ x, y ] ) )
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++ )
passableCost[(int)umt][ x, y ] = ( map.IsInMap( x, y ) )
? TerrainCosts.Cost( umt, tileSet.GetWalkability( map.MapTiles[ x, y ] ) )
: double.PositiveInfinity;
}
public List<int2> FindUnitPath( int2 unitLocation, Func<int2,double> estimator )
public List<int2> FindUnitPath(int2 src, int2 dest, UnitMovementType umt)
{
return FindUnitPath(src, DefaultEstimator(dest), umt);
}
List<int2> FindUnitPath( int2 unitLocation, Func<int2,double> estimator, UnitMovementType umt )
{
var startLocation = unitLocation + map.Offset;
@@ -32,10 +40,10 @@ namespace OpenRa.Game
for( int y = 0 ; y < 128 ; y++ )
cellInfo[ x, y ] = new CellInfo( double.PositiveInfinity, new int2( x, y ), false );
return FindUnitPath( new[] {startLocation}, estimator, map.Offset, cellInfo );
return FindUnitPath( new[] {startLocation}, estimator, umt, map.Offset, cellInfo );
}
List<int2> FindUnitPath(IEnumerable<int2> startLocations, Func<int2, double> estimator, int2 offset, CellInfo[,] cellInfo)
List<int2> FindUnitPath(IEnumerable<int2> startLocations, Func<int2, double> estimator, UnitMovementType umt, int2 offset, CellInfo[,] cellInfo)
{
var queue = new PriorityQueue<PathDistance>();
@@ -54,20 +62,20 @@ namespace OpenRa.Game
if( estimator( here - offset ) == 0.0 )
return MakePath( cellInfo, here, offset );
foreach( int2 d in directions )
foreach( int2 d in Util.directions )
{
int2 newHere = here + d;
if( cellInfo[ newHere.X, newHere.Y ].Seen )
continue;
if( passableCost[ newHere.X, newHere.Y ] == double.PositiveInfinity )
if( passableCost[(int)umt][ newHere.X, newHere.Y ] == double.PositiveInfinity )
continue;
if (Game.BuildingInfluence.GetBuildingAt(newHere - offset) != null)
continue;
if (Game.UnitInfluence.GetUnitAt(newHere - offset) != null)
continue;
double cellCost = ( ( d.X * d.Y != 0 ) ? 1.414213563 : 1.0 ) * passableCost[ newHere.X, newHere.Y ];
double cellCost = ( ( d.X * d.Y != 0 ) ? 1.414213563 : 1.0 ) * passableCost[(int)umt][ newHere.X, newHere.Y ];
double newCost = cellInfo[ here.X, here.Y ].MinCost + cellCost;
if( newCost >= cellInfo[ newHere.X, newHere.Y ].MinCost )
@@ -98,19 +106,7 @@ namespace OpenRa.Game
return ret;
}
public static readonly int2[] directions =
new int2[] {
new int2( -1, -1 ),
new int2( -1, 0 ),
new int2( -1, 1 ),
new int2( 0, -1 ),
new int2( 0, 1 ),
new int2( 1, -1 ),
new int2( 1, 0 ),
new int2( 1, 1 ),
};
public static Func<int2, double> DefaultEstimator(int2 destination)
static Func<int2, double> DefaultEstimator(int2 destination)
{
return here =>
{

View File

@@ -68,6 +68,15 @@ namespace OpenRa.Game.Traits
return new[] { fromCell, toCell };
}
public UnitMovementType GetMovementType()
{
/* todo: boats, planes */
var vi = self.unitInfo as UnitInfo.VehicleInfo;
if (vi == null) return UnitMovementType.Foot;
return vi.Tracked ? UnitMovementType.Track : UnitMovementType.Wheel;
}
public interface CurrentAction
{
CurrentAction NextAction { get; set; }
@@ -138,7 +147,7 @@ namespace OpenRa.Game.Traits
}
if( path == null )
path = Game.pathFinder.FindUnitPath( self.Location, PathFinder.DefaultEstimator( destination ) );
path = Game.pathFinder.FindUnitPath( self.Location, destination, mobile.GetMovementType() );
if( path.Count == 0 )
{
destination = mobile.toCell;
@@ -189,7 +198,7 @@ namespace OpenRa.Game.Traits
void CalculateMoveFraction()
{
var d = to - from;
moveFractionTotal = (int)Math.Sqrt( d.X * d.X + d.Y * d.Y ) * (25 / 6);
moveFractionTotal = (int)d.Length * (25 / 6);
}
static float2 CenterOfCell( int2 loc )
@@ -216,7 +225,8 @@ namespace OpenRa.Game.Traits
mobile.fromCell = mobile.toCell;
mobile.toCell = nextCell;
fromFacing = mobile.facing;
toFacing = Util.GetNearestFacing( fromFacing, Util.GetFacing( mobile.toCell-mobile.fromCell, fromFacing ) );
toFacing = Util.GetNearestFacing( fromFacing,
Util.GetFacing( mobile.toCell-mobile.fromCell, fromFacing ) );
OnComplete = OnCompleteFirstHalf;
return;
}