From 333a20d29eea2784d0c7c35066535f3382a0be3f Mon Sep 17 00:00:00 2001 From: bob Date: Mon, 16 Jul 2007 03:45:05 +0000 Subject: [PATCH] git-svn-id: svn://svn.ijw.co.nz/svn/OpenRa@1285 993157c7-ee19-0410-b2c4-bb4e9862e678 --- OpenRa.Game/Actor.cs | 2 +- OpenRa.Game/ISelectable.cs | 2 +- OpenRa.Game/MainWindow.cs | 8 +- OpenRa.Game/Mcv.cs | 143 ++++++++++++++++++++++++--------- OpenRa.Game/MoveOrder.cs | 33 +++++--- OpenRa.Game/OpenRa.Game.csproj | 1 + OpenRa.Game/Refinery.cs | 2 +- OpenRa.Game/Tree.cs | 2 +- OpenRa.Game/World.cs | 10 ++- OpenRa.Game/int2.cs | 51 ++++++++++++ 10 files changed, 196 insertions(+), 58 deletions(-) create mode 100644 OpenRa.Game/int2.cs diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index 95aa0736a3..2be06e73a3 100644 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -13,6 +13,6 @@ namespace OpenRa.Game public float2 renderLocation; public int palette; public abstract Sprite[] CurrentImages { get; } - public abstract void Tick( double t ); + public abstract void Tick( World world, double t ); } } diff --git a/OpenRa.Game/ISelectable.cs b/OpenRa.Game/ISelectable.cs index eb0926fcd5..75b73e36f2 100644 --- a/OpenRa.Game/ISelectable.cs +++ b/OpenRa.Game/ISelectable.cs @@ -7,6 +7,6 @@ namespace OpenRa.Game interface ISelectable { //Sprite CurrentCursor( int x, int y ); - MoveOrder Order( int x, int y ); + IOrder Order( int2 xy ); } } diff --git a/OpenRa.Game/MainWindow.cs b/OpenRa.Game/MainWindow.cs index 1bd6bc1a06..ad926cf8e1 100644 --- a/OpenRa.Game/MainWindow.cs +++ b/OpenRa.Game/MainWindow.cs @@ -60,9 +60,9 @@ namespace OpenRa.Game foreach (TreeReference treeReference in map.Trees) world.Add(new Tree(treeReference, treeCache, map)); - world.Add(new Mcv(24 * new float2(5, 5), 3)); - world.Add(new Mcv(24 * new float2(7, 5), 2)); - Mcv mcv = new Mcv( 24 * new float2( 9, 5 ), 1 ); + 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 ); @@ -91,7 +91,7 @@ namespace OpenRa.Game { int x = (int)( ( e.X + viewport.Location.X ) / 24 ); int y = (int)( ( e.Y + viewport.Location.Y ) / 24 ); - myUnit.Order( x, y ).Apply(); + myUnit.Order( new int2( x, y ) ).Apply(); } } diff --git a/OpenRa.Game/Mcv.cs b/OpenRa.Game/Mcv.cs index b20891b64f..f4c96ed0ae 100644 --- a/OpenRa.Game/Mcv.cs +++ b/OpenRa.Game/Mcv.cs @@ -10,14 +10,19 @@ namespace OpenRa.Game class Mcv : Actor, ISelectable { static Range? mcvRange = null; - MoveOrder currentOrder = null; int facing = 0; - float2 location; + int2 fromCell, toCell; + int moveFraction, moveFractionTotal; - public Mcv( float2 location, int palette ) + delegate void TickFunc( World world, double t ); + TickFunc currentOrder = null; + TickFunc nextOrder = null; + + public Mcv( int2 cell, int palette ) { - this.location = location; - this.renderLocation = this.location - new float2( 12, 12 ); // HACK: display the mcv centered in it's cell + fromCell = toCell = cell; + float2 location = ( cell * 24 ).ToFloat2(); + this.renderLocation = location - new float2( 12, 12 ); // HACK: display the mcv centered in it's cell this.palette = palette; if (mcvRange == null) @@ -65,48 +70,106 @@ namespace OpenRa.Game } } - public void Accept(MoveOrder o) + const int Speed = 6; + + public override void Tick( World world, double t ) { - currentOrder = o; - } - - const float Speed = 48.0f; - - public override void Tick( double t ) - { - if( currentOrder == null ) - return; - - if( float2.WithinEpsilon( location, currentOrder.Destination, 1.0f ) ) + if( currentOrder == null && nextOrder != null ) { - currentOrder = null; - return; + currentOrder = nextOrder; + nextOrder = null; } - Range r = new Range( - new float2( -Speed * (float)t, -Speed * (float)t ), - new float2( Speed * (float)t, Speed * (float)t ) ); - - float2 d = ( currentOrder.Destination - location ).Constrain( r ); - - int desiredFacing = GetFacing( d ); - int df = (desiredFacing - facing + 32) % 32; - if( df == 0 ) - location += d; - else if( df > 16 ) - facing = ( facing + 31 ) % 32; - else - facing = ( facing + 1 ) % 32; - - renderLocation = location - new float2( 12, 12 ); // HACK: center mcv in it's cell - - renderLocation.X = (float)Math.Round( renderLocation.X ); - renderLocation.Y = (float)Math.Round( renderLocation.Y ); + if( currentOrder != null ) + currentOrder( world, t ); } - public MoveOrder Order( int x, int y ) + public void AcceptMoveOrder( int2 destination ) { - return new MoveOrder( this, x, y ); + 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 ) + { + int df = ( desiredFacing - facing + 32 ) % 32; + if( df > 16 ) + facing = ( facing + 31 ) % 32; + else + facing = ( facing + 1 ) % 32; + } + else + { + moveFraction += speed; + if( moveFraction >= moveFractionTotal ) + { + moveFraction = 0; + moveFractionTotal = 0; + fromCell = toCell; + + if( toCell == destination ) + { + currentOrder = null; + } + else + { + int2 dir = destination - fromCell; + toCell = fromCell + new int2( Math.Sign( dir.X ), Math.Sign( dir.Y ) ); + moveFractionTotal = ( dir.X != 0 && dir.Y != 0 ) ? 250 : 200; + } + } + } + + float2 location; + if( moveFraction > 0 ) + { + float frac = (float)moveFraction / moveFractionTotal; + location = 24 * ( ( 1 - frac ) * fromCell.ToFloat2() + frac * toCell.ToFloat2() ); + } + else + location = 24 * fromCell.ToFloat2(); + + renderLocation = location - new float2( 12, 12 ); // HACK: center mcv in it's cell + + renderLocation.X = (float)Math.Round( renderLocation.X ); + renderLocation.Y = (float)Math.Round( renderLocation.Y ); + }; + } + + public void AcceptDeployOrder() + { + nextOrder = delegate( World world, double t ) + { + int desiredFacing = 12; + if( facing != desiredFacing ) + { + int df = ( desiredFacing - facing + 32 ) % 32; + if( df > 16 ) + facing = ( facing + 31 ) % 32; + else + facing = ( facing + 1 ) % 32; + } + else + { + world.AddFrameEndTask( delegate + { + world.Add( new Refinery( ( fromCell * 24 - new int2( 24, 24 ) ).ToFloat2(), palette ) ); + } ); + currentOrder = null; + } + }; + } + + public IOrder Order( int2 xy ) + { + if( ( fromCell == toCell || moveFraction == 0 ) && fromCell == xy ) + return new DeployMcvOrder( this ); + else + return new MoveOrder( this, xy ); } } } diff --git a/OpenRa.Game/MoveOrder.cs b/OpenRa.Game/MoveOrder.cs index 432880dd4c..09ea4dfad3 100644 --- a/OpenRa.Game/MoveOrder.cs +++ b/OpenRa.Game/MoveOrder.cs @@ -4,17 +4,17 @@ using System.Text; namespace OpenRa.Game { - class MoveOrder + interface IOrder + { + void Apply(); + } + + class MoveOrder : IOrder { public readonly Mcv Unit; - public readonly float2 Destination; + public readonly int2 Destination; - public MoveOrder( Mcv unit, int x, int y ) - : this( unit, new float2( x * 24, y * 24 ) ) - { - } - - public MoveOrder(Mcv unit, float2 destination) + public MoveOrder(Mcv unit, int2 destination) { this.Unit = unit; this.Destination = destination; @@ -22,7 +22,22 @@ namespace OpenRa.Game public void Apply() { - Unit.Accept( this ); + Unit.AcceptMoveOrder( Destination ); + } + } + + class DeployMcvOrder : IOrder + { + public Mcv Unit; + + public DeployMcvOrder( Mcv unit ) + { + this.Unit = unit; + } + + public void Apply() + { + Unit.AcceptDeployOrder(); } } } diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index 6afaf20740..5f1204f2ef 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -43,6 +43,7 @@ + diff --git a/OpenRa.Game/Refinery.cs b/OpenRa.Game/Refinery.cs index 9fab4f597d..52845edaee 100644 --- a/OpenRa.Game/Refinery.cs +++ b/OpenRa.Game/Refinery.cs @@ -30,6 +30,6 @@ namespace OpenRa.Game } } - public override void Tick(double t) { } + public override void Tick( World world, double t ) { } } } diff --git a/OpenRa.Game/Tree.cs b/OpenRa.Game/Tree.cs index 003e69eb91..ba134b8ccd 100644 --- a/OpenRa.Game/Tree.cs +++ b/OpenRa.Game/Tree.cs @@ -20,6 +20,6 @@ namespace OpenRa.Game get { return currentImages; } } - public override void Tick(double t){} + public override void Tick( World world, double t ) { } } } diff --git a/OpenRa.Game/World.cs b/OpenRa.Game/World.cs index 9f8d9b7a53..47f026465f 100644 --- a/OpenRa.Game/World.cs +++ b/OpenRa.Game/World.cs @@ -11,6 +11,7 @@ namespace OpenRa.Game class World { List actors = new List(); + List> frameEndActions = new List>(); SpriteRenderer spriteRenderer; Renderer renderer; Viewport viewport; @@ -24,6 +25,7 @@ namespace OpenRa.Game } public void Add(Actor a) { actors.Add(a); } + public void AddFrameEndTask( Action a ) { frameEndActions.Add( a ); } double lastTime = Environment.TickCount / 1000.0; @@ -37,7 +39,7 @@ namespace OpenRa.Game foreach (Actor a in actors) { - a.Tick( dt ); + a.Tick( this, dt ); Sprite[] images = a.CurrentImages; @@ -51,6 +53,12 @@ namespace OpenRa.Game spriteRenderer.DrawSprite(image, a.renderLocation, a.palette); } + foreach( Action a in frameEndActions ) + { + a( this ); + } + frameEndActions.Clear(); + spriteRenderer.Flush(); } } diff --git a/OpenRa.Game/int2.cs b/OpenRa.Game/int2.cs new file mode 100644 index 0000000000..7363a1adf0 --- /dev/null +++ b/OpenRa.Game/int2.cs @@ -0,0 +1,51 @@ +using System; +using System.Collections.Generic; +using System.Text; +using System.Drawing; + +namespace OpenRa.Game +{ + struct int2 + { + public int X; + public int Y; + + public int2( int x, int y ) { this.X = x; this.Y = y; } + public int2( Point p ) { X = p.X; Y = p.Y; } + public int2( Size p ) { X = p.Width; Y = p.Height; } + + public static int2 operator +( int2 a, int2 b ) + { + return new int2( a.X + b.X, a.Y + b.Y ); + } + + public static int2 operator -( int2 a, int2 b ) + { + return new int2( a.X - b.X, a.Y - b.Y ); + } + + public static int2 operator *( int a, int2 b ) + { + return new int2( a * b.X, a * b.Y ); + } + public static int2 operator *( int2 b, int a ) + { + return new int2( a * b.X, a * b.Y ); + } + + public float2 ToFloat2() + { + return new float2( X, Y ); + } + + public static bool operator ==( int2 me, int2 other ) + { + return ( me.X == other.X && me.Y == other.Y ); + } + + public static bool operator !=( int2 me, int2 other ) + { + return !( me == other ); + } +} +}