Begin cleaning up terraintypes/movetypes
This commit is contained in:
@@ -31,21 +31,11 @@ namespace OpenRA
|
|||||||
public class PathFinder
|
public class PathFinder
|
||||||
{
|
{
|
||||||
readonly World world;
|
readonly World world;
|
||||||
float[][,] passableCost = new float[5][,];
|
|
||||||
|
|
||||||
public PathFinder( World world )
|
public PathFinder( World world )
|
||||||
{
|
{
|
||||||
this.world = world;
|
this.world = world;
|
||||||
var map = world.Map;
|
var map = world.Map;
|
||||||
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Fly; umt++)
|
|
||||||
passableCost[(int)umt] = new float[map.MapSize.X, map.MapSize.Y];
|
|
||||||
for( int x = 0 ; x < map.MapSize.X ; x++ )
|
|
||||||
for( int y = 0 ; y < map.MapSize.Y ; y++ )
|
|
||||||
for (var umt = UnitMovementType.Foot; umt <= UnitMovementType.Fly; umt++ )
|
|
||||||
passableCost[(int)umt][ x, y ] = (umt == UnitMovementType.Fly) ? 1f : ( world.Map.IsInMap( x, y ) )
|
|
||||||
? (float)Rules.TerrainTypes[world.TileSet.GetTerrainType(world.Map.MapTiles[x, y])]
|
|
||||||
.GetCost(umt)
|
|
||||||
: float.PositiveInfinity;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
class CachedPath
|
class CachedPath
|
||||||
@@ -117,7 +107,7 @@ namespace OpenRA
|
|||||||
{
|
{
|
||||||
while (!search.queue.Empty)
|
while (!search.queue.Empty)
|
||||||
{
|
{
|
||||||
var p = search.Expand( world, passableCost );
|
var p = search.Expand( world );
|
||||||
PerfHistory.Increment("nodes_expanded", .01);
|
PerfHistory.Increment("nodes_expanded", .01);
|
||||||
|
|
||||||
if (search.heuristic(p) == 0)
|
if (search.heuristic(p) == 0)
|
||||||
@@ -154,13 +144,13 @@ namespace OpenRA
|
|||||||
while (!fromSrc.queue.Empty && !fromDest.queue.Empty)
|
while (!fromSrc.queue.Empty && !fromDest.queue.Empty)
|
||||||
{
|
{
|
||||||
/* make some progress on the first search */
|
/* make some progress on the first search */
|
||||||
var p = fromSrc.Expand( world, passableCost );
|
var p = fromSrc.Expand( world );
|
||||||
|
|
||||||
if (fromDest.cellInfo[p.X, p.Y].Seen && fromDest.cellInfo[p.X, p.Y].MinCost < float.PositiveInfinity)
|
if (fromDest.cellInfo[p.X, p.Y].Seen && fromDest.cellInfo[p.X, p.Y].MinCost < float.PositiveInfinity)
|
||||||
return MakeBidiPath(fromSrc, fromDest, p);
|
return MakeBidiPath(fromSrc, fromDest, p);
|
||||||
|
|
||||||
/* make some progress on the second search */
|
/* make some progress on the second search */
|
||||||
var q = fromDest.Expand( world, passableCost );
|
var q = fromDest.Expand( world );
|
||||||
|
|
||||||
if (fromSrc.cellInfo[q.X, q.Y].Seen && fromSrc.cellInfo[q.X, q.Y].MinCost < float.PositiveInfinity)
|
if (fromSrc.cellInfo[q.X, q.Y].Seen && fromSrc.cellInfo[q.X, q.Y].MinCost < float.PositiveInfinity)
|
||||||
return MakeBidiPath(fromSrc, fromDest, q);
|
return MakeBidiPath(fromSrc, fromDest, q);
|
||||||
|
|||||||
@@ -39,15 +39,12 @@ namespace OpenRA
|
|||||||
Actor self;
|
Actor self;
|
||||||
public bool inReverse;
|
public bool inReverse;
|
||||||
|
|
||||||
BuildingInfluence buildingInfluence;
|
|
||||||
|
|
||||||
public PathSearch(Actor self)
|
public PathSearch(Actor self)
|
||||||
{
|
{
|
||||||
this.self = self;
|
this.self = self;
|
||||||
world = self.World;
|
world = self.World;
|
||||||
cellInfo = InitCellInfo();
|
cellInfo = InitCellInfo();
|
||||||
queue = new PriorityQueue<PathDistance>();
|
queue = new PriorityQueue<PathDistance>();
|
||||||
buildingInfluence = world.WorldActor.traits.Get<BuildingInfluence>();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public PathSearch InReverse()
|
public PathSearch InReverse()
|
||||||
@@ -82,16 +79,16 @@ namespace OpenRA
|
|||||||
|
|
||||||
const float LaneBias = .5f;
|
const float LaneBias = .5f;
|
||||||
|
|
||||||
public int2 Expand( World world, float[][ , ] passableCost )
|
public int2 Expand( World world )
|
||||||
{
|
{
|
||||||
var umt = self.traits.Get<Mobile>().GetMovementType();
|
var umt = self.traits.Get<Mobile>().GetMovementType();
|
||||||
|
|
||||||
var p = queue.Pop();
|
var p = queue.Pop();
|
||||||
cellInfo[ p.Location.X, p.Location.Y ].Seen = true;
|
cellInfo[ p.Location.X, p.Location.Y ].Seen = true;
|
||||||
|
|
||||||
var thisCost = passableCost[(int)umt][p.Location.X, p.Location.Y]*
|
var mobile = self.traits.Get<Mobile>();
|
||||||
world.WorldActor.traits.WithInterface<ICustomTerrain>().Aggregate(1f, (a, x) => a * x.GetCost(p.Location,self));
|
var thisCost = mobile.MovementCostForCell(self, p.Location);
|
||||||
|
|
||||||
if (thisCost == float.PositiveInfinity)
|
if (thisCost == float.PositiveInfinity)
|
||||||
return p.Location;
|
return p.Location;
|
||||||
|
|
||||||
@@ -103,14 +100,11 @@ namespace OpenRA
|
|||||||
if( cellInfo[ newHere.X, newHere.Y ].Seen )
|
if( cellInfo[ newHere.X, newHere.Y ].Seen )
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var costHere = passableCost[(int)umt][newHere.X, newHere.Y]*
|
var costHere = mobile.MovementCostForCell(self, newHere);
|
||||||
world.WorldActor.traits.WithInterface<ICustomTerrain>()
|
|
||||||
.Aggregate(1f, (a, x) => a * x.GetCost(newHere,self));
|
|
||||||
|
|
||||||
if (costHere == float.PositiveInfinity)
|
if (costHere == float.PositiveInfinity)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
var mobile = self.traits.Get<Mobile>();
|
|
||||||
if (checkForBlocked && !mobile.CanEnterCell(newHere, ignoreBuilding, checkForBlocked))
|
if (checkForBlocked && !mobile.CanEnterCell(newHere, ignoreBuilding, checkForBlocked))
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
|
|||||||
@@ -124,15 +124,15 @@ namespace OpenRA.Traits
|
|||||||
return CanEnterCell(p, null, true);
|
return CanEnterCell(p, null, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual bool CanEnterCell(int2 p, Actor ignoreActor, bool checkTransientActors)
|
public virtual bool CanEnterCell(int2 cell, Actor ignoreActor, bool checkTransientActors)
|
||||||
{
|
{
|
||||||
if (!self.World.WorldActor.traits.Get<BuildingInfluence>().CanMoveHere(p, ignoreActor))
|
if (!self.World.WorldActor.traits.Get<BuildingInfluence>().CanMoveHere(cell, ignoreActor))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (checkTransientActors)
|
if (checkTransientActors)
|
||||||
{
|
{
|
||||||
var canShare = self.traits.Contains<SharesCell>();
|
var canShare = self.traits.Contains<SharesCell>();
|
||||||
var actors = self.World.WorldActor.traits.Get<UnitInfluence>().GetUnitsAt(p).Where(a => a != self && a != ignoreActor);
|
var actors = self.World.WorldActor.traits.Get<UnitInfluence>().GetUnitsAt(cell).Where(a => a != self && a != ignoreActor);
|
||||||
var nonshareable = actors.Where(a => !(canShare && a.traits.Contains<SharesCell>()));
|
var nonshareable = actors.Where(a => !(canShare && a.traits.Contains<SharesCell>()));
|
||||||
var shareable = actors.Where(a => canShare && a.traits.Contains<SharesCell>());
|
var shareable = actors.Where(a => canShare && a.traits.Contains<SharesCell>());
|
||||||
|
|
||||||
@@ -146,9 +146,20 @@ namespace OpenRA.Traits
|
|||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
return self.World.Map.IsInMap(p.X, p.Y) &&
|
return MovementCostForCell(self, cell) < float.PositiveInfinity;
|
||||||
Rules.TerrainTypes[self.World.TileSet.GetTerrainType(self.World.Map.MapTiles[p.X, p.Y])]
|
}
|
||||||
.GetCost(GetMovementType()) < float.PositiveInfinity;
|
|
||||||
|
public float MovementCostForCell(Actor self, int2 cell)
|
||||||
|
{
|
||||||
|
if (!self.World.Map.IsInMap(cell.X,cell.Y))
|
||||||
|
return float.PositiveInfinity;
|
||||||
|
|
||||||
|
var type = self.World.TileSet.GetTerrainType(self.World.Map.MapTiles[cell.X, cell.Y]);
|
||||||
|
var umt = self.Info.Traits.Get<MobileInfo>().MovementType;
|
||||||
|
|
||||||
|
// Todo: Cache cost for each terraintype
|
||||||
|
return (float)Rules.TerrainTypes[type].GetCost(umt)*
|
||||||
|
self.World.WorldActor.traits.WithInterface<ICustomTerrain>().Aggregate(1f, (a, x) => a * x.GetCost(cell,self));
|
||||||
}
|
}
|
||||||
|
|
||||||
public IEnumerable<float2> GetCurrentPath(Actor self)
|
public IEnumerable<float2> GetCurrentPath(Actor self)
|
||||||
|
|||||||
@@ -109,6 +109,7 @@ namespace OpenRA.Traits
|
|||||||
{
|
{
|
||||||
UnitMovementType GetMovementType();
|
UnitMovementType GetMovementType();
|
||||||
bool CanEnterCell(int2 location);
|
bool CanEnterCell(int2 location);
|
||||||
|
float MovementCostForCell(Actor self, int2 cell);
|
||||||
IEnumerable<float2> GetCurrentPath(Actor self);
|
IEnumerable<float2> GetCurrentPath(Actor self);
|
||||||
void SetPosition(Actor self, int2 cell);
|
void SetPosition(Actor self, int2 cell);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -61,6 +61,14 @@ namespace OpenRA.Traits
|
|||||||
|
|
||||||
return self.World.WorldActor.traits.Get<AircraftInfluence>().GetUnitsAt(p).Count() == 0;
|
return self.World.WorldActor.traits.Get<AircraftInfluence>().GetUnitsAt(p).Count() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public float MovementCostForCell(Actor self, int2 cell)
|
||||||
|
{
|
||||||
|
if (!self.World.Map.IsInMap(cell.X,cell.Y))
|
||||||
|
return float.PositiveInfinity;
|
||||||
|
|
||||||
|
return self.World.WorldActor.traits.WithInterface<ICustomTerrain>().Aggregate(1f, (a, x) => a * x.GetCost(cell,self));
|
||||||
|
}
|
||||||
|
|
||||||
public override IEnumerable<int2> OccupiedCells()
|
public override IEnumerable<int2> OccupiedCells()
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -72,7 +72,9 @@ namespace OpenRA.Mods.RA
|
|||||||
|
|
||||||
public UnitMovementType GetMovementType() { return UnitMovementType.Fly; }
|
public UnitMovementType GetMovementType() { return UnitMovementType.Fly; }
|
||||||
public bool CanEnterCell(int2 location) { return true; }
|
public bool CanEnterCell(int2 location) { return true; }
|
||||||
|
|
||||||
|
public float MovementCostForCell(Actor self, int2 cell) { return 1f; }
|
||||||
|
|
||||||
int2[] noCells = new int2[] { };
|
int2[] noCells = new int2[] { };
|
||||||
public IEnumerable<int2> OccupiedCells() { return noCells; }
|
public IEnumerable<int2> OccupiedCells() { return noCells; }
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user