Moved Activity and friends into separate files.
This commit is contained in:
@@ -299,7 +299,7 @@ namespace OpenRa.Game
|
|||||||
unit = new Actor(name, (1 / 24f * producer.CenterLocation).ToInt2(), player);
|
unit = new Actor(name, (1 / 24f * producer.CenterLocation).ToInt2(), player);
|
||||||
var mobile = unit.traits.Get<Mobile>();
|
var mobile = unit.traits.Get<Mobile>();
|
||||||
mobile.facing = 128;
|
mobile.facing = 128;
|
||||||
mobile.QueueActivity(new Mobile.MoveTo(unit.Location + new int2(0, 3)));
|
mobile.QueueActivity(new Traits.Activities.Move(unit.Location + new int2(0, 3)));
|
||||||
}
|
}
|
||||||
|
|
||||||
world.Add( unit );
|
world.Add( unit );
|
||||||
|
|||||||
@@ -77,6 +77,7 @@
|
|||||||
<Compile Include="GameRules\TechTree.cs" />
|
<Compile Include="GameRules\TechTree.cs" />
|
||||||
<Compile Include="OrderManager.cs" />
|
<Compile Include="OrderManager.cs" />
|
||||||
<Compile Include="Traits\AcceptsOre.cs" />
|
<Compile Include="Traits\AcceptsOre.cs" />
|
||||||
|
<Compile Include="Traits\Activities\Activity.cs" />
|
||||||
<Compile Include="Traits\Activities\DeployMcv.cs" />
|
<Compile Include="Traits\Activities\DeployMcv.cs" />
|
||||||
<Compile Include="Actor.cs" />
|
<Compile Include="Actor.cs" />
|
||||||
<Compile Include="Bullet.cs" />
|
<Compile Include="Bullet.cs" />
|
||||||
@@ -128,6 +129,8 @@
|
|||||||
<Compile Include="TerrainCosts.cs" />
|
<Compile Include="TerrainCosts.cs" />
|
||||||
<Compile Include="Graphics\TerrainRenderer.cs" />
|
<Compile Include="Graphics\TerrainRenderer.cs" />
|
||||||
<Compile Include="Graphics\TreeCache.cs" />
|
<Compile Include="Graphics\TreeCache.cs" />
|
||||||
|
<Compile Include="Traits\Activities\Move.cs" />
|
||||||
|
<Compile Include="Traits\Activities\Turn.cs" />
|
||||||
<Compile Include="Traits\AttackTurreted.cs" />
|
<Compile Include="Traits\AttackTurreted.cs" />
|
||||||
<Compile Include="Traits\Building.cs" />
|
<Compile Include="Traits\Building.cs" />
|
||||||
<Compile Include="Traits\Harvester.cs" />
|
<Compile Include="Traits\Harvester.cs" />
|
||||||
|
|||||||
@@ -197,11 +197,6 @@ namespace OpenRa.Game
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
static bool IsAutoCompleting(string group)
|
|
||||||
{
|
|
||||||
return group != "Building";
|
|
||||||
}
|
|
||||||
|
|
||||||
SidebarItem mouseOverItem;
|
SidebarItem mouseOverItem;
|
||||||
|
|
||||||
void MouseHandler(MouseInput mi)
|
void MouseHandler(MouseInput mi)
|
||||||
|
|||||||
14
OpenRa.Game/Traits/Activities/Activity.cs
Executable file
14
OpenRa.Game/Traits/Activities/Activity.cs
Executable file
@@ -0,0 +1,14 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenRa.Game.Traits.Activities
|
||||||
|
{
|
||||||
|
interface Activity
|
||||||
|
{
|
||||||
|
Activity NextActivity { get; set; }
|
||||||
|
void Tick( Actor self, Mobile mobile );
|
||||||
|
void Cancel( Actor self, Mobile mobile );
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -5,9 +5,9 @@ using System.Text;
|
|||||||
|
|
||||||
namespace OpenRa.Game.Traits.Activities
|
namespace OpenRa.Game.Traits.Activities
|
||||||
{
|
{
|
||||||
class DeployMcv : Mobile.CurrentActivity
|
class DeployMcv : Activity
|
||||||
{
|
{
|
||||||
public Mobile.CurrentActivity NextActivity { get; set; }
|
public Activity NextActivity { get; set; }
|
||||||
|
|
||||||
public void Tick( Actor self, Mobile mobile )
|
public void Tick( Actor self, Mobile mobile )
|
||||||
{
|
{
|
||||||
|
|||||||
245
OpenRa.Game/Traits/Activities/Move.cs
Executable file
245
OpenRa.Game/Traits/Activities/Move.cs
Executable file
@@ -0,0 +1,245 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using OpenRa.Game.GameRules;
|
||||||
|
|
||||||
|
namespace OpenRa.Game.Traits.Activities
|
||||||
|
{
|
||||||
|
class Move : Activity
|
||||||
|
{
|
||||||
|
public Activity NextActivity { get; set; }
|
||||||
|
|
||||||
|
int2? destination;
|
||||||
|
public List<int2> path;
|
||||||
|
Func<Actor, Mobile, List<int2>> getPath;
|
||||||
|
|
||||||
|
MovePart move;
|
||||||
|
|
||||||
|
public Move( int2 destination )
|
||||||
|
{
|
||||||
|
this.getPath = ( self, mobile ) => Game.PathFinder.FindUnitPath(
|
||||||
|
self.Location, destination,
|
||||||
|
mobile.GetMovementType() );
|
||||||
|
this.destination = destination;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Move( 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 );
|
||||||
|
var b = Game.BuildingInfluence.GetBuildingAt( c );
|
||||||
|
return ( u == null || u == self ) && b == null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Tick( Actor self, Mobile mobile )
|
||||||
|
{
|
||||||
|
if( move != null )
|
||||||
|
{
|
||||||
|
move.TickMove( self, mobile, this );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if( destination == self.Location )
|
||||||
|
{
|
||||||
|
mobile.InternalSetActivity( 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 ];
|
||||||
|
|
||||||
|
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 )
|
||||||
|
{
|
||||||
|
var t = new Turn( firstFacing ) { NextActivity = this };
|
||||||
|
mobile.InternalSetActivity( t );
|
||||||
|
path.Add( nextCell.Value );
|
||||||
|
|
||||||
|
t.Tick( self, mobile );
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
mobile.toCell = nextCell.Value;
|
||||||
|
move = new MoveFirstHalf(
|
||||||
|
CenterOfCell( mobile.fromCell ),
|
||||||
|
BetweenCells( mobile.fromCell, mobile.toCell ),
|
||||||
|
mobile.facing,
|
||||||
|
mobile.facing,
|
||||||
|
0 );
|
||||||
|
|
||||||
|
Game.UnitInfluence.Update( mobile );
|
||||||
|
|
||||||
|
move.TickMove( self, mobile, this );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int2? PopPath( Actor self, Mobile mobile )
|
||||||
|
{
|
||||||
|
if( path.Count == 0 ) return null;
|
||||||
|
var nextCell = path[ path.Count - 1 ];
|
||||||
|
if( !CanEnterCell( nextCell, self ) )
|
||||||
|
{
|
||||||
|
if( ( mobile.toCell - destination.Value ).LengthSquared <= 8 )
|
||||||
|
{
|
||||||
|
path.Clear();
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
Game.UnitInfluence.Remove( mobile );
|
||||||
|
var newPath = Game.PathFinder.FindPathToPath( self.Location, path, mobile.GetMovementType() )
|
||||||
|
.TakeWhile( a => a != self.Location )
|
||||||
|
.ToList();
|
||||||
|
Game.UnitInfluence.Add( mobile );
|
||||||
|
if( newPath.Count == 0 )
|
||||||
|
return null;
|
||||||
|
|
||||||
|
while( path[ path.Count - 1 ] != newPath[ 0 ] )
|
||||||
|
path.RemoveAt( path.Count - 1 );
|
||||||
|
for( int i = 1 ; i < newPath.Count ; i++ )
|
||||||
|
path.Add( newPath[ i ] );
|
||||||
|
|
||||||
|
if( path.Count == 0 )
|
||||||
|
return null;
|
||||||
|
nextCell = path[ path.Count - 1 ];
|
||||||
|
}
|
||||||
|
path.RemoveAt( path.Count - 1 );
|
||||||
|
return nextCell;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float2 CenterOfCell( int2 loc )
|
||||||
|
{
|
||||||
|
return new float2( 12, 12 ) + Game.CellSize * (float2)loc;
|
||||||
|
}
|
||||||
|
|
||||||
|
static float2 BetweenCells( int2 from, int2 to )
|
||||||
|
{
|
||||||
|
return 0.5f * ( CenterOfCell( from ) + CenterOfCell( to ) );
|
||||||
|
}
|
||||||
|
|
||||||
|
abstract class MovePart
|
||||||
|
{
|
||||||
|
public readonly float2 from, to;
|
||||||
|
public readonly int fromFacing, toFacing;
|
||||||
|
public int moveFraction;
|
||||||
|
public readonly int moveFractionTotal;
|
||||||
|
|
||||||
|
public MovePart( float2 from, float2 to, int fromFacing, int toFacing, int startingFraction )
|
||||||
|
{
|
||||||
|
this.from = from;
|
||||||
|
this.to = to;
|
||||||
|
this.fromFacing = fromFacing;
|
||||||
|
this.toFacing = toFacing;
|
||||||
|
this.moveFraction = startingFraction;
|
||||||
|
this.moveFractionTotal = (int)( to - from ).Length * ( 25 / 6 );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void TickMove( Actor self, Mobile mobile, Move parent )
|
||||||
|
{
|
||||||
|
var oldFraction = moveFraction;
|
||||||
|
var oldTotal = moveFractionTotal;
|
||||||
|
|
||||||
|
moveFraction += ( self.unitInfo as UnitInfo.MobileInfo ).Speed;
|
||||||
|
UpdateCenterLocation( self, mobile );
|
||||||
|
if( moveFraction >= moveFractionTotal )
|
||||||
|
{
|
||||||
|
parent.move = OnComplete( self, mobile, parent );
|
||||||
|
if( parent.move == null )
|
||||||
|
UpdateCenterLocation( self, mobile );
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void UpdateCenterLocation( Actor self, Mobile mobile )
|
||||||
|
{
|
||||||
|
var frac = (float)moveFraction / moveFractionTotal;
|
||||||
|
|
||||||
|
self.CenterLocation = float2.Lerp( from, to, frac );
|
||||||
|
if( moveFraction >= moveFractionTotal )
|
||||||
|
mobile.facing = toFacing & 0xFF;
|
||||||
|
else
|
||||||
|
mobile.facing = ( fromFacing + ( toFacing - fromFacing ) * moveFraction / moveFractionTotal ) & 0xFF;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected abstract MovePart OnComplete( Actor self, Mobile mobile, Move parent );
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveFirstHalf : MovePart
|
||||||
|
{
|
||||||
|
public MoveFirstHalf( float2 from, float2 to, int fromFacing, int toFacing, int startingFraction )
|
||||||
|
: base( from, to, fromFacing, toFacing, startingFraction )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override MovePart OnComplete( Actor self, Mobile mobile, Move parent )
|
||||||
|
{
|
||||||
|
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 ),
|
||||||
|
CenterOfCell( mobile.toCell ),
|
||||||
|
mobile.facing,
|
||||||
|
mobile.facing,
|
||||||
|
moveFraction - moveFractionTotal );
|
||||||
|
mobile.fromCell = mobile.toCell;
|
||||||
|
Game.UnitInfluence.Update( mobile );
|
||||||
|
return ret2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class MoveSecondHalf : MovePart
|
||||||
|
{
|
||||||
|
public MoveSecondHalf( float2 from, float2 to, int fromFacing, int toFacing, int startingFraction )
|
||||||
|
: base( from, to, fromFacing, toFacing, startingFraction )
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override MovePart OnComplete( Actor self, Mobile mobile, Move parent )
|
||||||
|
{
|
||||||
|
self.CenterLocation = CenterOfCell( mobile.toCell );
|
||||||
|
mobile.fromCell = mobile.toCell;
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Cancel( Actor self, Mobile mobile )
|
||||||
|
{
|
||||||
|
path = new List<int2>();
|
||||||
|
NextActivity = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
37
OpenRa.Game/Traits/Activities/Turn.cs
Executable file
37
OpenRa.Game/Traits/Activities/Turn.cs
Executable file
@@ -0,0 +1,37 @@
|
|||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using System.Text;
|
||||||
|
|
||||||
|
namespace OpenRa.Game.Traits.Activities
|
||||||
|
{
|
||||||
|
class Turn : Activity
|
||||||
|
{
|
||||||
|
public Activity NextActivity { get; set; }
|
||||||
|
|
||||||
|
public int desiredFacing;
|
||||||
|
|
||||||
|
public Turn( int desiredFacing )
|
||||||
|
{
|
||||||
|
this.desiredFacing = desiredFacing;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Tick( Actor self, Mobile mobile )
|
||||||
|
{
|
||||||
|
if( desiredFacing == mobile.facing )
|
||||||
|
{
|
||||||
|
mobile.InternalSetActivity( NextActivity );
|
||||||
|
if( NextActivity != null )
|
||||||
|
NextActivity.Tick( self, mobile );
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
Util.TickFacing( ref mobile.facing, desiredFacing, self.unitInfo.ROT );
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Cancel( Actor self, Mobile mobile )
|
||||||
|
{
|
||||||
|
desiredFacing = mobile.facing;
|
||||||
|
NextActivity = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -4,6 +4,7 @@ using System.Linq;
|
|||||||
using System.Text;
|
using System.Text;
|
||||||
using OpenRa.Game.GameRules;
|
using OpenRa.Game.GameRules;
|
||||||
using OpenRa.Game.Graphics;
|
using OpenRa.Game.Graphics;
|
||||||
|
using OpenRa.Game.Traits.Activities;
|
||||||
|
|
||||||
namespace OpenRa.Game.Traits
|
namespace OpenRa.Game.Traits
|
||||||
{
|
{
|
||||||
@@ -16,7 +17,7 @@ namespace OpenRa.Game.Traits
|
|||||||
public int facing;
|
public int facing;
|
||||||
|
|
||||||
public int Voice = Game.CosmeticRandom.Next(2);
|
public int Voice = Game.CosmeticRandom.Next(2);
|
||||||
CurrentActivity currentActivity;
|
Activity currentActivity;
|
||||||
|
|
||||||
public Mobile(Actor self)
|
public Mobile(Actor self)
|
||||||
{
|
{
|
||||||
@@ -25,7 +26,7 @@ namespace OpenRa.Game.Traits
|
|||||||
Game.UnitInfluence.Update( this );
|
Game.UnitInfluence.Update( this );
|
||||||
}
|
}
|
||||||
|
|
||||||
public void QueueActivity( CurrentActivity nextActivity )
|
public void QueueActivity( Activity nextActivity )
|
||||||
{
|
{
|
||||||
if( currentActivity == null )
|
if( currentActivity == null )
|
||||||
{
|
{
|
||||||
@@ -40,6 +41,11 @@ namespace OpenRa.Game.Traits
|
|||||||
act.NextActivity = nextActivity;
|
act.NextActivity = nextActivity;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public void InternalSetActivity( Activity activity )
|
||||||
|
{
|
||||||
|
currentActivity = activity;
|
||||||
|
}
|
||||||
|
|
||||||
public void Tick(Actor self)
|
public void Tick(Actor self)
|
||||||
{
|
{
|
||||||
if( currentActivity != null )
|
if( currentActivity != null )
|
||||||
@@ -80,280 +86,9 @@ namespace OpenRa.Game.Traits
|
|||||||
return vi.Tracked ? UnitMovementType.Track : UnitMovementType.Wheel;
|
return vi.Tracked ? UnitMovementType.Track : UnitMovementType.Wheel;
|
||||||
}
|
}
|
||||||
|
|
||||||
public interface CurrentActivity
|
|
||||||
{
|
|
||||||
CurrentActivity NextActivity { get; set; }
|
|
||||||
void Tick( Actor self, Mobile mobile );
|
|
||||||
void Cancel( Actor self, Mobile mobile );
|
|
||||||
}
|
|
||||||
|
|
||||||
public class Turn : CurrentActivity
|
|
||||||
{
|
|
||||||
public CurrentActivity NextActivity { get; set; }
|
|
||||||
|
|
||||||
public int desiredFacing;
|
|
||||||
|
|
||||||
public Turn( int desiredFacing )
|
|
||||||
{
|
|
||||||
this.desiredFacing = desiredFacing;
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Tick( Actor self, Mobile mobile )
|
|
||||||
{
|
|
||||||
if( desiredFacing == mobile.facing )
|
|
||||||
{
|
|
||||||
mobile.currentActivity = NextActivity;
|
|
||||||
if( NextActivity != null )
|
|
||||||
NextActivity.Tick( self, mobile );
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
Util.TickFacing( ref mobile.facing, desiredFacing, self.unitInfo.ROT );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Cancel( Actor self, Mobile mobile )
|
|
||||||
{
|
|
||||||
desiredFacing = mobile.facing;
|
|
||||||
NextActivity = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public class MoveTo : CurrentActivity
|
|
||||||
{
|
|
||||||
public CurrentActivity NextActivity { get; set; }
|
|
||||||
|
|
||||||
int2? destination;
|
|
||||||
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,
|
|
||||||
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;
|
|
||||||
}
|
|
||||||
|
|
||||||
static bool CanEnterCell(int2 c, Actor 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 )
|
|
||||||
{
|
|
||||||
if( move != null )
|
|
||||||
{
|
|
||||||
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];
|
|
||||||
|
|
||||||
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 )
|
|
||||||
{
|
|
||||||
mobile.currentActivity = new Turn( firstFacing ) { NextActivity = this };
|
|
||||||
path.Add( nextCell.Value );
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
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 ) )
|
|
||||||
{
|
|
||||||
if( ( mobile.toCell - destination.Value ).LengthSquared <= 8 )
|
|
||||||
{
|
|
||||||
path.Clear();
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
|
|
||||||
Game.UnitInfluence.Remove( mobile );
|
|
||||||
var newPath = Game.PathFinder.FindPathToPath( self.Location, path, mobile.GetMovementType() )
|
|
||||||
.TakeWhile( a => a != self.Location )
|
|
||||||
.ToList();
|
|
||||||
Game.UnitInfluence.Add( mobile );
|
|
||||||
if( newPath.Count == 0 )
|
|
||||||
return null;
|
|
||||||
|
|
||||||
while( path[ path.Count - 1 ] != newPath[ 0 ] )
|
|
||||||
path.RemoveAt( path.Count - 1 );
|
|
||||||
for( int i = 1 ; i < newPath.Count ; i++ )
|
|
||||||
path.Add( newPath[ i ] );
|
|
||||||
|
|
||||||
if( path.Count == 0 )
|
|
||||||
return null;
|
|
||||||
nextCell = path[ path.Count - 1 ];
|
|
||||||
}
|
|
||||||
path.RemoveAt( path.Count - 1 );
|
|
||||||
return nextCell;
|
|
||||||
}
|
|
||||||
|
|
||||||
static float2 CenterOfCell( int2 loc )
|
|
||||||
{
|
|
||||||
return new float2( 12, 12 ) + Game.CellSize * (float2)loc;
|
|
||||||
}
|
|
||||||
|
|
||||||
static float2 BetweenCells( int2 from, int2 to )
|
|
||||||
{
|
|
||||||
return 0.5f * ( CenterOfCell( from ) + CenterOfCell( to ) );
|
|
||||||
}
|
|
||||||
|
|
||||||
abstract class MovePart
|
|
||||||
{
|
|
||||||
public readonly float2 from, to;
|
|
||||||
public readonly int fromFacing, toFacing;
|
|
||||||
public int moveFraction;
|
|
||||||
public readonly int moveFractionTotal;
|
|
||||||
|
|
||||||
public MovePart( float2 from, float2 to, int fromFacing, int toFacing, int startingFraction )
|
|
||||||
{
|
|
||||||
this.from = from;
|
|
||||||
this.to = to;
|
|
||||||
this.fromFacing = fromFacing;
|
|
||||||
this.toFacing = toFacing;
|
|
||||||
this.moveFraction = startingFraction;
|
|
||||||
this.moveFractionTotal = (int)( to - from ).Length * ( 25 / 6 );
|
|
||||||
}
|
|
||||||
|
|
||||||
public void TickMove( Actor self, Mobile mobile, MoveTo parent )
|
|
||||||
{
|
|
||||||
var oldFraction = moveFraction;
|
|
||||||
var oldTotal = moveFractionTotal;
|
|
||||||
|
|
||||||
moveFraction += ( self.unitInfo as UnitInfo.MobileInfo ).Speed;
|
|
||||||
UpdateCenterLocation( self, mobile );
|
|
||||||
if( moveFraction >= moveFractionTotal )
|
|
||||||
{
|
|
||||||
parent.move = OnComplete( self, mobile, parent );
|
|
||||||
if( parent.move == null )
|
|
||||||
UpdateCenterLocation( self, mobile );
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
void UpdateCenterLocation( Actor self, Mobile mobile )
|
|
||||||
{
|
|
||||||
var frac = (float)moveFraction / moveFractionTotal;
|
|
||||||
|
|
||||||
self.CenterLocation = float2.Lerp( from, to, frac );
|
|
||||||
if( moveFraction >= moveFractionTotal )
|
|
||||||
mobile.facing = toFacing & 0xFF;
|
|
||||||
else
|
|
||||||
mobile.facing = ( fromFacing + ( toFacing - fromFacing ) * moveFraction / moveFractionTotal ) & 0xFF;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected abstract MovePart OnComplete( Actor self, Mobile mobile, MoveTo parent );
|
|
||||||
}
|
|
||||||
|
|
||||||
class MoveFirstHalf : MovePart
|
|
||||||
{
|
|
||||||
public MoveFirstHalf( float2 from, float2 to, int fromFacing, int toFacing, int startingFraction )
|
|
||||||
: base( from, to, fromFacing, toFacing, startingFraction )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override MovePart OnComplete( Actor self, Mobile mobile, MoveTo parent )
|
|
||||||
{
|
|
||||||
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 ),
|
|
||||||
CenterOfCell( mobile.toCell ),
|
|
||||||
mobile.facing,
|
|
||||||
mobile.facing,
|
|
||||||
moveFraction - moveFractionTotal );
|
|
||||||
mobile.fromCell = mobile.toCell;
|
|
||||||
Game.UnitInfluence.Update( mobile );
|
|
||||||
return ret2;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
class MoveSecondHalf : MovePart
|
|
||||||
{
|
|
||||||
public MoveSecondHalf( float2 from, float2 to, int fromFacing, int toFacing, int startingFraction )
|
|
||||||
: base( from, to, fromFacing, toFacing, startingFraction )
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override MovePart OnComplete( Actor self, Mobile mobile, MoveTo parent )
|
|
||||||
{
|
|
||||||
self.CenterLocation = CenterOfCell( mobile.toCell );
|
|
||||||
mobile.fromCell = mobile.toCell;
|
|
||||||
return null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public void Cancel( Actor self, Mobile mobile )
|
|
||||||
{
|
|
||||||
path = new List<int2>();
|
|
||||||
NextActivity = null;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<int2> GetCurrentPath()
|
public IEnumerable<int2> GetCurrentPath()
|
||||||
{
|
{
|
||||||
var move = currentActivity as MoveTo;
|
var move = currentActivity as Traits.Activities.Move;
|
||||||
if (move == null || move.path == null) return new int2[] { };
|
if (move == null || move.path == null) return new int2[] { };
|
||||||
return Enumerable.Reverse(move.path);
|
return Enumerable.Reverse(move.path);
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -1,9 +1,8 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Text;
|
|
||||||
using OpenRa.Game.Traits;
|
|
||||||
using OpenRa.Game.GameRules;
|
using OpenRa.Game.GameRules;
|
||||||
|
using OpenRa.Game.Traits;
|
||||||
|
|
||||||
namespace OpenRa.Game
|
namespace OpenRa.Game
|
||||||
{
|
{
|
||||||
@@ -17,7 +16,7 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
var mobile = order.Subject.traits.Get<Mobile>();
|
var mobile = order.Subject.traits.Get<Mobile>();
|
||||||
mobile.Cancel( order.Subject );
|
mobile.Cancel( order.Subject );
|
||||||
mobile.QueueActivity( new Mobile.MoveTo( order.TargetLocation ) );
|
mobile.QueueActivity( new Traits.Activities.Move( order.TargetLocation ) );
|
||||||
|
|
||||||
var attackBase = order.Subject.traits.WithInterface<AttackBase>().FirstOrDefault();
|
var attackBase = order.Subject.traits.WithInterface<AttackBase>().FirstOrDefault();
|
||||||
if( attackBase != null )
|
if( attackBase != null )
|
||||||
@@ -37,7 +36,7 @@ namespace OpenRa.Game
|
|||||||
var range = Rules.WeaponInfo[ weapon ].Range;
|
var range = Rules.WeaponInfo[ weapon ].Range;
|
||||||
|
|
||||||
mobile.QueueActivity(
|
mobile.QueueActivity(
|
||||||
new Mobile.MoveTo( order.TargetActor,
|
new Traits.Activities.Move( order.TargetActor,
|
||||||
Math.Max( 0, (int)range - RangeTolerance ) ) );
|
Math.Max( 0, (int)range - RangeTolerance ) ) );
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -50,7 +49,7 @@ namespace OpenRa.Game
|
|||||||
break; /* throw the order on the floor */
|
break; /* throw the order on the floor */
|
||||||
|
|
||||||
var mobile = order.Subject.traits.Get<Mobile>();
|
var mobile = order.Subject.traits.Get<Mobile>();
|
||||||
mobile.QueueActivity( new Mobile.Turn( 96 ) );
|
mobile.QueueActivity( new Traits.Activities.Turn( 96 ) );
|
||||||
mobile.QueueActivity( new Traits.Activities.DeployMcv() );
|
mobile.QueueActivity( new Traits.Activities.DeployMcv() );
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@@ -58,8 +57,8 @@ namespace OpenRa.Game
|
|||||||
{
|
{
|
||||||
var mobile = order.Subject.traits.Get<Mobile>();
|
var mobile = order.Subject.traits.Get<Mobile>();
|
||||||
mobile.Cancel(order.Subject);
|
mobile.Cancel(order.Subject);
|
||||||
mobile.QueueActivity(new Mobile.MoveTo(order.TargetActor.Location + new int2(1, 2)));
|
mobile.QueueActivity( new Traits.Activities.Move( order.TargetActor.Location + new int2( 1, 2 ) ) );
|
||||||
mobile.QueueActivity(new Mobile.Turn(64));
|
mobile.QueueActivity( new Traits.Activities.Turn( 64 ) );
|
||||||
|
|
||||||
/* todo: actual deliver activity! [animation + add cash] */
|
/* todo: actual deliver activity! [animation + add cash] */
|
||||||
break;
|
break;
|
||||||
|
|||||||
Reference in New Issue
Block a user