Repath around blocking units or structures.
This commit is contained in:
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user