Repath around blocking units or structures.

This commit is contained in:
Bob
2009-10-28 17:59:09 +13:00
parent 58f9347cb7
commit 222b72a679
4 changed files with 245 additions and 181 deletions

View File

@@ -49,9 +49,9 @@ namespace OpenRa.Game.Traits
public Order Order(Actor self, int2 xy, bool lmb, Actor underCursor)
{
if( lmb ) return null;
if( underCursor != null )
if( lmb ) return null;
if( underCursor != null )
return null;
if (xy != toCell)
@@ -121,31 +121,32 @@ namespace OpenRa.Game.Traits
public CurrentActivity NextActivity { get; set; }
int2? destination;
public List<int2> path;
public List<int2> path;
Func<Actor, Mobile, List<int2>> getPath;
MovePart move;
public MoveTo( int2 destination )
{
this.getPath = (self, mobile) => Game.pathFinder.FindUnitPath(
self.Location, destination,
{
this.getPath = (self, mobile) => Game.PathFinder.FindUnitPath(
self.Location, destination,
mobile.GetMovementType());
this.destination = destination;
}
public MoveTo(Actor target, int range)
{
this.getPath = (self, mobile) => Game.pathFinder.FindUnitPathToRange(
self.Location, target.Location,
mobile.GetMovementType(), range);
this.destination = null;
}
public MoveTo(Actor target, int range)
{
this.getPath = (self, mobile) => Game.PathFinder.FindUnitPathToRange(
self.Location, target.Location,
mobile.GetMovementType(), range);
this.destination = null;
}
static bool CanEnterCell(int2 c, Actor self)
{
var u = Game.UnitInfluence.GetUnitAt(c);
return u == null || u == self;
var u = Game.UnitInfluence.GetUnitAt(c);
var b = Game.BuildingInfluence.GetBuildingAt(c);
return (u == null || u == self) && b == null;
}
public void Tick( Actor self, Mobile mobile )
@@ -154,46 +155,67 @@ namespace OpenRa.Game.Traits
{
move.TickMove( self, mobile, this );
return;
}
}
if( destination == self.Location )
{
mobile.currentActivity = NextActivity;
return;
}
}
if (path == null) path = getPath(self, mobile).TakeWhile(a => a != self.Location).ToList();
if (path.Count == 0)
{
destination = mobile.toCell;
return;
}
destination = path[0];
if (path == null) path = getPath(self, mobile).TakeWhile(a => a != self.Location).ToList();
if (path.Count == 0)
var nextCell = PopPath( self, mobile );
if( nextCell == null )
return;
int2 dir = nextCell.Value - mobile.fromCell;
var firstFacing = Util.GetFacing( dir, mobile.facing );
if( firstFacing != mobile.facing )
{
destination = mobile.toCell;
return;
mobile.currentActivity = new Turn( firstFacing ) { NextActivity = this };
path.Add( nextCell.Value );
}
else
destination = path[0];
var nextCell = path[ path.Count - 1 ];
int2 dir = nextCell - mobile.fromCell;
var firstFacing = Util.GetFacing( dir, mobile.facing );
if( firstFacing != mobile.facing )
mobile.currentActivity = new Turn( firstFacing ) { NextActivity = this };
else
{
if (!CanEnterCell(nextCell, self)) return; /* todo: repath, sometimes */
mobile.toCell = nextCell;
path.RemoveAt( path.Count - 1 );
move = new MoveFirstHalf(
CenterOfCell( mobile.fromCell ),
BetweenCells( mobile.fromCell, mobile.toCell ),
mobile.facing,
mobile.facing,
0 );
Game.UnitInfluence.Update(mobile);
{
mobile.toCell = nextCell.Value;
move = new MoveFirstHalf(
CenterOfCell( mobile.fromCell ),
BetweenCells( mobile.fromCell, mobile.toCell ),
mobile.facing,
mobile.facing,
0 );
Game.UnitInfluence.Update( mobile );
}
mobile.currentActivity.Tick( self, mobile );
}
int2? PopPath( Actor self, Mobile mobile )
{
if( path.Count == 0 ) return null;
var nextCell = path[ path.Count - 1 ];
if( !CanEnterCell( nextCell, self ) )
{
Game.UnitInfluence.Remove( mobile );
path = Game.PathFinder.FindPathToPath( self.Location, path, mobile.GetMovementType() )
.TakeWhile( a => a != self.Location )
.ToList();
Game.UnitInfluence.Add( mobile );
if( path.Count == 0 )
return null;
nextCell = path[ path.Count - 1 ];
}
path.RemoveAt( path.Count - 1 );
return nextCell;
}
static float2 CenterOfCell( int2 loc )
@@ -260,28 +282,25 @@ namespace OpenRa.Game.Traits
}
protected override MovePart OnComplete( Actor self, Mobile mobile, MoveTo parent )
{
if( parent.path.Count > 0 )
{
var nextCell = parent.path[ parent.path.Count - 1 ];
if( ( nextCell - mobile.toCell ) != ( mobile.toCell - mobile.fromCell ) )
{
if( CanEnterCell( nextCell, self ) )
{
parent.path.RemoveAt( parent.path.Count - 1 );
var ret = new MoveFirstHalf(
BetweenCells( mobile.fromCell, mobile.toCell ),
BetweenCells( mobile.toCell, nextCell ),
mobile.facing,
Util.GetNearestFacing( mobile.facing, Util.GetFacing( nextCell - mobile.toCell, mobile.facing ) ),
moveFraction - moveFractionTotal );
mobile.fromCell = mobile.toCell;
mobile.toCell = nextCell;
Game.UnitInfluence.Update( mobile );
return ret;
}
}
{
var nextCell = parent.PopPath( self, mobile );
if( nextCell != null )
{
if( ( nextCell - mobile.toCell ) != ( mobile.toCell - mobile.fromCell ) )
{
var ret = new MoveFirstHalf(
BetweenCells( mobile.fromCell, mobile.toCell ),
BetweenCells( mobile.toCell, nextCell.Value ),
mobile.facing,
Util.GetNearestFacing( mobile.facing, Util.GetFacing( nextCell.Value - mobile.toCell, mobile.facing ) ),
moveFraction - moveFractionTotal );
mobile.fromCell = mobile.toCell;
mobile.toCell = nextCell.Value;
Game.UnitInfluence.Update( mobile );
return ret;
}
else
parent.path.Add( nextCell.Value );
}
var ret2 = new MoveSecondHalf(
BetweenCells( mobile.fromCell, mobile.toCell ),
@@ -314,13 +333,13 @@ namespace OpenRa.Game.Traits
path.Clear();
NextActivity = null;
}
}
public IEnumerable<int2> GetCurrentPath()
{
var move = currentActivity as MoveTo;
if (move == null || move.path == null) return new int2[] { };
return Enumerable.Reverse(move.path);
}
}
public IEnumerable<int2> GetCurrentPath()
{
var move = currentActivity as MoveTo;
if (move == null || move.path == null) return new int2[] { };
return Enumerable.Reverse(move.path);
}
}
}