diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs index 64a43ce5f0..4a9e4df29e 100644 --- a/OpenRa.Game/MainWindow.cs +++ b/OpenRa.Game/MainWindow.cs @@ -62,8 +62,8 @@ namespace OpenRa.Game SequenceProvider.ForcePrecache(); - world.Add(new Mcv(new int2(5, 5), 3)); - world.Add(new Mcv(new int2(7, 5), 2)); + world.Add( new Mcv( new int2( 5, 5 ), 3 ) ); + world.Add( new Mcv( new int2( 7, 5 ), 2 ) ); Mcv mcv = new Mcv( new int2( 9, 5 ), 1 ); myUnit = mcv; world.Add( mcv ); diff --git a/OpenRa.Game/Mcv.cs b/OpenRa.Game/Mcv.cs index 1628c0ccbd..3bf114d0d3 100644 --- a/OpenRa.Game/Mcv.cs +++ b/OpenRa.Game/Mcv.cs @@ -7,122 +7,13 @@ using BluntDirectX.Direct3D; namespace OpenRa.Game { - delegate void TickFunc(World world, double t); - - class Mcv : Actor, ISelectable + class Mcv : Unit { - static Range mcvRange = UnitSheetBuilder.GetUnit("mcv"); + static Range mcvRange = UnitSheetBuilder.GetUnit( "mcv" ); - int facing = 0; - int2 fromCell, toCell; - int moveFraction, moveFractionTotal; - - TickFunc currentOrder, nextOrder; - - public Mcv(int2 cell, int palette) + public Mcv( int2 location, int palette ) + : base( location, palette ) { - fromCell = toCell = cell; - renderLocation = (cell * 24).ToFloat2() - new float2(12, 12); - this.palette = palette; - } - - static float2[] fvecs = Util.MakeArray(32, - delegate(int i) { return -float2.FromAngle(i / 16.0f * (float)Math.PI); }); - - int GetFacing(float2 d) - { - if (float2.WithinEpsilon(d, float2.Zero, 0.001f)) - return facing; - - int highest = -1; - float highestDot = -1.0f; - - for (int i = 0; i < fvecs.Length; i++) - { - float dot = float2.Dot(fvecs[i], d); - if (dot > highestDot) - { - highestDot = dot; - highest = i; - } - } - - return highest; - } - - public override Sprite[] CurrentImages - { - get { return new Sprite[] { UnitSheetBuilder.sprites[facing + mcvRange.Start] }; } - } - - const int Speed = 6; - - public override void Tick( World world, double t ) - { - if( currentOrder == null && nextOrder != null ) - { - currentOrder = nextOrder; - nextOrder = null; - } - - if( currentOrder != null ) - currentOrder( world, t ); - } - - public void AcceptMoveOrder( int2 destination ) - { - nextOrder = delegate( World world, double t ) - { - int speed = (int)( t * ( Speed * 100 ) ); - - if( nextOrder != null ) - destination = toCell; - - int desiredFacing = GetFacing( ( toCell - fromCell ).ToFloat2() ); - if( facing != desiredFacing ) - Turn(desiredFacing); - else - { - moveFraction += speed; - if( moveFraction >= moveFractionTotal ) - { - moveFraction = 0; - moveFractionTotal = 0; - fromCell = toCell; - - if( toCell == destination ) - currentOrder = null; - else - { - List res = PathFinder.Instance.FindUnitPath( world, this, destination ); - if( res.Count != 0 ) - { - toCell = res[ res.Count - 1 ]; - - int2 dir = toCell - fromCell; - moveFractionTotal = ( dir.X != 0 && dir.Y != 0 ) ? 250 : 200; - } - else - destination = toCell; - } - } - } - - float2 location; - if( moveFraction > 0 ) - location = 24 * float2.Lerp(fromCell.ToFloat2(), toCell.ToFloat2(), - (float)moveFraction / moveFractionTotal); - else - location = 24 * fromCell.ToFloat2(); - - renderLocation = (location - new float2( 12, 12 )).Round(); - }; - } - - void Turn(int desiredFacing) - { - int df = (desiredFacing - facing + 32) % 32; - facing = (facing + (df > 16 ? 31 : 1)) % 32; } public void AcceptDeployOrder() @@ -130,11 +21,11 @@ namespace OpenRa.Game nextOrder = delegate( World world, double t ) { int desiredFacing = 12; - if (facing != desiredFacing) - Turn(desiredFacing); + if( facing != desiredFacing ) + Turn( desiredFacing ); else { - world.AddFrameEndTask(delegate + world.AddFrameEndTask( delegate { world.Remove( this ); world.Add( new ConstructionYard( fromCell - new int2( 1, 1 ), palette ) ); @@ -145,17 +36,17 @@ namespace OpenRa.Game }; } - public IOrder Order( int2 xy ) + public override Sprite[] CurrentImages + { + get { return new Sprite[] { UnitSheetBuilder.sprites[ facing + mcvRange.Start ] }; } + } + + public override IOrder Order( int2 xy ) { if( ( fromCell == toCell || moveFraction == 0 ) && fromCell == xy ) return new DeployMcvOrder( this ); - else - return new MoveOrder( this, xy ); - } - public int2 Location - { - get { return toCell; } + return base.Order( xy ); } } } diff --git a/OpenRa.Game/MoveOrder.cs b/OpenRa.Game/MoveOrder.cs index 09ea4dfad3..70b7755896 100644 --- a/OpenRa.Game/MoveOrder.cs +++ b/OpenRa.Game/MoveOrder.cs @@ -11,10 +11,10 @@ namespace OpenRa.Game class MoveOrder : IOrder { - public readonly Mcv Unit; + public readonly Unit Unit; public readonly int2 Destination; - public MoveOrder(Mcv unit, int2 destination) + public MoveOrder(Unit unit, int2 destination) { this.Unit = unit; this.Destination = destination; @@ -28,16 +28,16 @@ namespace OpenRa.Game class DeployMcvOrder : IOrder { - public Mcv Unit; + public Mcv Mcv; - public DeployMcvOrder( Mcv unit ) + public DeployMcvOrder( Mcv mcv ) { - this.Unit = unit; + this.Mcv = mcv; } public void Apply() { - Unit.AcceptDeployOrder(); + Mcv.AcceptDeployOrder(); } } } diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 6ce0ec31a1..d134a9eb4f 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -72,6 +72,7 @@ + @@ -100,4 +101,4 @@ --> - + \ No newline at end of file diff --git a/OpenRa.Game/PathFinder.cs b/OpenRa.Game/PathFinder.cs index c64c764049..e570d9409a 100644 --- a/OpenRa.Game/PathFinder.cs +++ b/OpenRa.Game/PathFinder.cs @@ -34,7 +34,7 @@ namespace OpenRa.Game } } - public List FindUnitPath( World world, Mcv unit, int2 destination ) + public List FindUnitPath( World world, Unit unit, int2 destination ) { int2 offset = new int2( map.XOffset, map.YOffset ); diff --git a/OpenRa.Game/Unit.cs b/OpenRa.Game/Unit.cs new file mode 100644 index 0000000000..eb83b67687 --- /dev/null +++ b/OpenRa.Game/Unit.cs @@ -0,0 +1,131 @@ +using System; +using System.Collections.Generic; +using System.Text; + +namespace OpenRa.Game +{ + abstract class Unit : Actor, ISelectable + { + protected int facing = 0; + protected int2 fromCell, toCell; + protected int moveFraction, moveFractionTotal; + + protected delegate void TickFunc( World world, double t ); + protected TickFunc currentOrder = null; + protected TickFunc nextOrder = null; + + public Unit( int2 cell, int palette ) + { + fromCell = toCell = cell; + // HACK: display the mcv centered in it's cell; + renderLocation = ( cell * 24 ).ToFloat2() - new float2( 12, 12 ); + this.palette = palette; + } + + static float2[] fvecs = Util.MakeArray( 32, + delegate( int i ) { return -float2.FromAngle( i / 16.0f * (float)Math.PI ); } ); + + int GetFacing( float2 d ) + { + if( float2.WithinEpsilon( d, float2.Zero, 0.001f ) ) + return facing; + + int highest = -1; + float highestDot = -1.0f; + + for( int i = 0 ; i < fvecs.Length ; i++ ) + { + float dot = float2.Dot( fvecs[ i ], d ); + if( dot > highestDot ) + { + highestDot = dot; + highest = i; + } + } + + return highest; + } + + const int Speed = 6; + + public override void Tick( World world, double t ) + { + if( currentOrder == null && nextOrder != null ) + { + currentOrder = nextOrder; + nextOrder = null; + } + + if( currentOrder != null ) + currentOrder( world, t ); + } + + public void AcceptMoveOrder( int2 destination ) + { + nextOrder = delegate( World world, double t ) + { + int speed = (int)( t * ( Speed * 100 ) ); + + if( nextOrder != null ) + destination = toCell; + + int desiredFacing = GetFacing( ( toCell - fromCell ).ToFloat2() ); + if( facing != desiredFacing ) + Turn( desiredFacing ); + else + { + moveFraction += speed; + if( moveFraction >= moveFractionTotal ) + { + moveFraction = 0; + moveFractionTotal = 0; + fromCell = toCell; + + if( toCell == destination ) + currentOrder = null; + else + { + List res = PathFinder.Instance.FindUnitPath( world, this, destination ); + if( res.Count != 0 ) + { + toCell = res[ res.Count - 1 ]; + + int2 dir = toCell - fromCell; + moveFractionTotal = ( dir.X != 0 && dir.Y != 0 ) ? 250 : 200; + } + else + destination = toCell; + } + } + } + + float2 location; + if( moveFraction > 0 ) + location = 24 * float2.Lerp( fromCell.ToFloat2(), toCell.ToFloat2(), + (float)moveFraction / moveFractionTotal ); + else + location = 24 * fromCell.ToFloat2(); + + renderLocation = location - new float2( 12, 12 ); // HACK: center mcv in it's cell + + renderLocation = renderLocation.Round(); + }; + } + + protected void Turn( int desiredFacing ) + { + int df = ( desiredFacing - facing + 32 ) % 32; + facing = ( facing + ( df > 16 ? 31 : 1 ) ) % 32; + } + + public virtual IOrder Order( int2 xy ) + { + return new MoveOrder( this, xy ); + } + + public int2 Location + { + get { return toCell; } + } + } +}