moved directions to a shared place; fixed pathfinder to use the appropriate movement type
This commit is contained in:
@@ -5,6 +5,7 @@ using System.Text;
|
|||||||
using OpenRa.Game.GameRules;
|
using OpenRa.Game.GameRules;
|
||||||
using IjwFramework.Types;
|
using IjwFramework.Types;
|
||||||
using IjwFramework.Collections;
|
using IjwFramework.Collections;
|
||||||
|
using OpenRa.Game.Graphics;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
@@ -66,7 +67,7 @@ namespace OpenRa.Game
|
|||||||
|
|
||||||
if (c.distance + 1 > maxDistance) continue;
|
if (c.distance + 1 > maxDistance) continue;
|
||||||
|
|
||||||
foreach (var d in PathFinder.directions)
|
foreach (var d in Util.directions)
|
||||||
{
|
{
|
||||||
var e = c.location + d;
|
var e = c.location + d;
|
||||||
if (e.X < min.X || e.Y < min.Y || e.X > max.X || e.Y > max.Y)
|
if (e.X < min.X || e.Y < min.Y || e.X > max.X || e.Y > max.Y)
|
||||||
|
|||||||
@@ -42,6 +42,18 @@ namespace OpenRa.Game.Graphics
|
|||||||
return result;
|
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 };
|
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)
|
public static void FastCreateQuad(Vertex[] vertices, ushort[] indices, float2 o, Sprite r, int palette, int nv, int ni)
|
||||||
|
|||||||
@@ -2,27 +2,35 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using IjwFramework.Collections;
|
using IjwFramework.Collections;
|
||||||
using OpenRa.FileFormats;
|
using OpenRa.FileFormats;
|
||||||
|
using OpenRa.Game.Graphics;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
class PathFinder
|
class PathFinder
|
||||||
{
|
{
|
||||||
double[ , ] passableCost = new double[ 128, 128 ];
|
double[][,] passableCost = new double[4][,];
|
||||||
Map map;
|
Map map;
|
||||||
|
|
||||||
public PathFinder(Map map, TileSet tileSet)
|
public PathFinder(Map map, TileSet tileSet)
|
||||||
{
|
{
|
||||||
this.map = map;
|
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 x = 0 ; x < 128 ; x++ )
|
||||||
for( int y = 0 ; y < 128 ; y++ )
|
for( int y = 0 ; y < 128 ; y++ )
|
||||||
|
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Float; umt++ )
|
||||||
passableCost[ x, y ] = ( map.IsInMap( x, y ) )
|
passableCost[(int)umt][ x, y ] = ( map.IsInMap( x, y ) )
|
||||||
? TerrainCosts.Cost( UnitMovementType.Wheel, tileSet.GetWalkability( map.MapTiles[ x, y ] ) )
|
? TerrainCosts.Cost( umt, tileSet.GetWalkability( map.MapTiles[ x, y ] ) )
|
||||||
: double.PositiveInfinity;
|
: 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;
|
var startLocation = unitLocation + map.Offset;
|
||||||
|
|
||||||
@@ -32,10 +40,10 @@ namespace OpenRa.Game
|
|||||||
for( int y = 0 ; y < 128 ; y++ )
|
for( int y = 0 ; y < 128 ; y++ )
|
||||||
cellInfo[ x, y ] = new CellInfo( double.PositiveInfinity, new int2( x, y ), false );
|
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>();
|
var queue = new PriorityQueue<PathDistance>();
|
||||||
|
|
||||||
@@ -54,20 +62,20 @@ namespace OpenRa.Game
|
|||||||
if( estimator( here - offset ) == 0.0 )
|
if( estimator( here - offset ) == 0.0 )
|
||||||
return MakePath( cellInfo, here, offset );
|
return MakePath( cellInfo, here, offset );
|
||||||
|
|
||||||
foreach( int2 d in directions )
|
foreach( int2 d in Util.directions )
|
||||||
{
|
{
|
||||||
int2 newHere = here + d;
|
int2 newHere = here + d;
|
||||||
|
|
||||||
if( cellInfo[ newHere.X, newHere.Y ].Seen )
|
if( cellInfo[ newHere.X, newHere.Y ].Seen )
|
||||||
continue;
|
continue;
|
||||||
if( passableCost[ newHere.X, newHere.Y ] == double.PositiveInfinity )
|
if( passableCost[(int)umt][ newHere.X, newHere.Y ] == double.PositiveInfinity )
|
||||||
continue;
|
continue;
|
||||||
if (Game.BuildingInfluence.GetBuildingAt(newHere - offset) != null)
|
if (Game.BuildingInfluence.GetBuildingAt(newHere - offset) != null)
|
||||||
continue;
|
continue;
|
||||||
if (Game.UnitInfluence.GetUnitAt(newHere - offset) != null)
|
if (Game.UnitInfluence.GetUnitAt(newHere - offset) != null)
|
||||||
continue;
|
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;
|
double newCost = cellInfo[ here.X, here.Y ].MinCost + cellCost;
|
||||||
|
|
||||||
if( newCost >= cellInfo[ newHere.X, newHere.Y ].MinCost )
|
if( newCost >= cellInfo[ newHere.X, newHere.Y ].MinCost )
|
||||||
@@ -98,19 +106,7 @@ namespace OpenRa.Game
|
|||||||
return ret;
|
return ret;
|
||||||
}
|
}
|
||||||
|
|
||||||
public static readonly int2[] directions =
|
static Func<int2, double> DefaultEstimator(int2 destination)
|
||||||
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)
|
|
||||||
{
|
{
|
||||||
return here =>
|
return here =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -66,6 +66,15 @@ namespace OpenRa.Game.Traits
|
|||||||
public IEnumerable<int2> OccupiedCells()
|
public IEnumerable<int2> OccupiedCells()
|
||||||
{
|
{
|
||||||
return new[] { fromCell, toCell };
|
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
|
public interface CurrentAction
|
||||||
@@ -138,7 +147,7 @@ namespace OpenRa.Game.Traits
|
|||||||
}
|
}
|
||||||
|
|
||||||
if( path == null )
|
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 )
|
if( path.Count == 0 )
|
||||||
{
|
{
|
||||||
destination = mobile.toCell;
|
destination = mobile.toCell;
|
||||||
@@ -189,7 +198,7 @@ namespace OpenRa.Game.Traits
|
|||||||
void CalculateMoveFraction()
|
void CalculateMoveFraction()
|
||||||
{
|
{
|
||||||
var d = to - from;
|
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 )
|
static float2 CenterOfCell( int2 loc )
|
||||||
@@ -216,7 +225,8 @@ namespace OpenRa.Game.Traits
|
|||||||
mobile.fromCell = mobile.toCell;
|
mobile.fromCell = mobile.toCell;
|
||||||
mobile.toCell = nextCell;
|
mobile.toCell = nextCell;
|
||||||
fromFacing = mobile.facing;
|
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;
|
OnComplete = OnCompleteFirstHalf;
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user