diff --git a/OpenRa.Game/Actor.cs b/OpenRa.Game/Actor.cs index 24774dc06a..c5386e77fe 100755 --- a/OpenRa.Game/Actor.cs +++ b/OpenRa.Game/Actor.cs @@ -14,14 +14,16 @@ namespace OpenRa.Game class Actor { public readonly TypeDictionary traits = new TypeDictionary(); - public readonly UnitInfo unitInfo; - + public readonly UnitInfo unitInfo; + + public readonly uint ActorID; public int2 Location; public Player Owner; public int Health; public Actor( string name, int2 location, Player owner ) - { + { + ActorID = Game.world.NextAID(); unitInfo = Rules.UnitInfo[ name ]; Location = location; CenterLocation = new float2( 12, 12 ) + Game.CellSize * (float2)Location; diff --git a/OpenRa.Game/Controller.cs b/OpenRa.Game/Controller.cs index 78519e5fc0..db8d074d3e 100644 --- a/OpenRa.Game/Controller.cs +++ b/OpenRa.Game/Controller.cs @@ -11,20 +11,30 @@ namespace OpenRa.Game { class Controller { - public IOrderGenerator orderGenerator; - + public IOrderGenerator orderGenerator; + + List recentOrders = new List(); + void ApplyOrders(float2 xy, bool left) { - var doVoice = null as Actor; - if (orderGenerator != null) - foreach( var order in orderGenerator.Order( xy.ToInt2(), left ) ) - { - UnitOrders.ProcessOrder( order ); - if( order.Subject != null && order.Player == Game.LocalPlayer ) - doVoice = order.Subject; + var doVoice = null as Actor; + if( orderGenerator != null ) + foreach( var order in orderGenerator.Order( xy.ToInt2(), left ) ) + { + recentOrders.Add( order ); + //UnitOrders.ProcessOrder( order ); + if( order.Subject != null && order.Player == Game.LocalPlayer ) + doVoice = order.Subject; } if( doVoice != null ) Game.PlaySound( Game.SovietVoices.First.GetNext() + GetVoiceSuffix( doVoice ), false ); + } + + public List GetRecentOrders() + { + var ret = recentOrders; + recentOrders = new List(); + return ret; } static string GetVoiceSuffix( Actor unit ) diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index ff6d9244fb..048b99f8b9 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -25,7 +25,9 @@ namespace OpenRa.Game public static PathFinder PathFinder; public static Network network; public static WorldRenderer worldRenderer; - public static Controller controller; + public static Controller controller; + + public static OrderManager orderManager; static int localPlayerIndex; @@ -73,7 +75,9 @@ namespace OpenRa.Game worldRenderer = new WorldRenderer(renderer); soundEngine = new ISoundEngine(); - sounds = new Cache(LoadSound); + sounds = new Cache(LoadSound); + + orderManager = new OrderManager( new OrderSource[] { new LocalOrderSource() }, "replay.rep" ); PlaySound("intro.aud", false); } @@ -128,7 +132,9 @@ namespace OpenRa.Game world.Update(); UnitInfluence.Tick(); - viewport.DrawRegions(); + viewport.DrawRegions(); + + orderManager.Tick(); } public static bool IsCellBuildable(int2 a, UnitMovementType umt) diff --git a/OpenRa.Game/OpenRa.Game.csproj b/OpenRa.Game/OpenRa.Game.csproj index c82c6b29b7..d06c1f319c 100644 --- a/OpenRa.Game/OpenRa.Game.csproj +++ b/OpenRa.Game/OpenRa.Game.csproj @@ -1,197 +1,198 @@ - - - Debug - AnyCPU - 9.0.30729 - 2.0 - {0DFB103F-2962-400F-8C6D-E2C28CCBA633} - WinExe - Properties - OpenRa.Game - OpenRa.Game - - - 2.0 - - - publish\ - true - Disk - false - Foreground - 7 - Days - false - false - true - 0 - 1.0.0.%2a - false - false - true - v3.5 - - - true - bin\x86\Debug\ - DEBUG;TRACE - true - full - x86 - false - prompt - - - bin\x86\Release\ - TRACE - true - true - pdbonly - x86 - false - prompt - - - - False - ..\Ijw.DirectX\Release\Ijw.DirectX.dll - - - False - ..\Ijw.DirectX\Ijw.Framework\IjwFramework\bin\Debug\IjwFramework.dll - - - False - ..\thirdparty\irrKlang.NET2.0.dll - - - - 3.5 - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - Form - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - - {2F9E7A23-56C0-4286-9C8E-1060A9B2F073} - OpenRa.DataStructures - - - {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA} - OpenRa.FileFormats - - - - - False - .NET Framework 2.0 %28x86%29 - true - - - False - .NET Framework 3.0 %28x86%29 - false - - - False - .NET Framework 3.5 - false - - - - - - - + + + Debug + AnyCPU + 9.0.30729 + 2.0 + {0DFB103F-2962-400F-8C6D-E2C28CCBA633} + WinExe + Properties + OpenRa.Game + OpenRa.Game + + + 2.0 + + + publish\ + true + Disk + false + Foreground + 7 + Days + false + false + true + 0 + 1.0.0.%2a + false + false + true + v3.5 + + + true + bin\x86\Debug\ + DEBUG;TRACE + true + full + x86 + false + prompt + + + bin\x86\Release\ + TRACE + true + true + pdbonly + x86 + false + prompt + + + + False + ..\Ijw.DirectX\Release\Ijw.DirectX.dll + + + False + ..\Ijw.DirectX\Ijw.Framework\IjwFramework\bin\Debug\IjwFramework.dll + + + False + ..\thirdparty\irrKlang.NET2.0.dll + + + + 3.5 + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + Form + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + {2F9E7A23-56C0-4286-9C8E-1060A9B2F073} + OpenRa.DataStructures + + + {BDAEAB25-991E-46A7-AF1E-4F0E03358DAA} + OpenRa.FileFormats + + + + + False + .NET Framework 2.0 %28x86%29 + true + + + False + .NET Framework 3.0 %28x86%29 + false + + + False + .NET Framework 3.5 + false + + + + + + + + --> \ No newline at end of file diff --git a/OpenRa.Game/Order.cs b/OpenRa.Game/Order.cs index a3a4686899..88dab7be82 100644 --- a/OpenRa.Game/Order.cs +++ b/OpenRa.Game/Order.cs @@ -2,7 +2,8 @@ using System; using System.Collections.Generic; using System.Text; using System.Linq; -using OpenRa.Game.Traits; +using OpenRa.Game.Traits; +using System.IO; namespace OpenRa.Game { @@ -23,10 +24,67 @@ namespace OpenRa.Game this.TargetActor = targetActor; this.TargetLocation = targetLocation; this.TargetString = targetString; - } - - // TODO: serialize / deserialize - + } + + public byte[] Serialize() + { + switch( OrderString ) + { + // Format: + // u32 : player, with msb set. (if msb is clear, not an order) + // u8 : orderID. + // 0xFF: Full serialized order. + // varies: rest of order. + default: + // TODO: specific serializers for specific orders. + { + var ret = new MemoryStream(); + var w = new BinaryWriter(ret); + w.Write( (uint)Player.Palette | 0x80000000u ); + w.Write( (byte)0xFF ); // + w.Write( OrderString ); + w.Write( Subject == null ? 0xFFFFFFFF : Subject.ActorID ); + w.Write( TargetActor == null ? 0xFFFFFFFF : TargetActor.ActorID ); + w.Write( TargetLocation.X ); + w.Write( TargetLocation.Y ); + w.Write( TargetString != null ); + if( TargetString != null ) + w.Write( TargetString ); + return ret.ToArray(); + } + } + } + + public static Order Deserialize( BinaryReader r, uint first ) + { + if( ( first >> 31 ) == 0 ) return null; + + var player = Game.players.Where( x => x.Value.Palette == (first & 0x7FFFFFFF) ).First().Value; + switch( r.ReadByte() ) + { + case 0xFF: + { + var order = r.ReadString(); + var subject = ActorFromUInt( r.ReadUInt32() ); + var targetActor = ActorFromUInt( r.ReadUInt32() ); + var targetLocation = new int2( r.ReadInt32(), 0 ); + targetLocation.Y = r.ReadInt32(); + var targetString = null as string; + if( r.ReadBoolean() ) + targetString = r.ReadString(); + return new Order( player, order, subject, targetActor, targetLocation, targetString ); + } + default: + throw new NotImplementedException(); + } + } + + static Actor ActorFromUInt( uint aID ) + { + if( aID == 0xFFFFFFFF ) return null; + return Game.world.Actors.Where( x => x.ActorID == aID ).First(); + } + public static Order Attack( Actor subject, Actor target ) { return new Order( subject.Owner, "Attack", subject, target, int2.Zero, null ); @@ -45,6 +103,6 @@ namespace OpenRa.Game public static Order PlaceBuilding( Player subject, int2 target, string buildingName ) { return new Order( subject, "PlaceBuilding", null, null, target, buildingName ); - } + } } } diff --git a/OpenRa.Game/World.cs b/OpenRa.Game/World.cs index 59daaf976d..7f6384a90a 100644 --- a/OpenRa.Game/World.cs +++ b/OpenRa.Game/World.cs @@ -13,15 +13,15 @@ namespace OpenRa.Game int lastTime = Environment.TickCount; const int timestep = 40; - public void Add(Actor a) { actors.Add(a); ActorAdded(a); } + public void Add(Actor a) { actors.Add(a); ActorAdded(a); } public void Remove(Actor a) { actors.Remove(a); ActorRemoved(a); } - public void Add(IEffect b) { effects.Add(b); } + public void Add(IEffect b) { effects.Add(b); } public void Remove(IEffect b) { effects.Remove(b); } public void AddFrameEndTask( Action a ) { frameEndActions.Add( a ); } - public event Action ActorAdded = _ => { }; + public event Action ActorAdded = _ => { }; public event Action ActorRemoved = a => { a.Health = 0; }; /* make sure everyone sees it as dead */ public void ResetTimer() @@ -32,16 +32,16 @@ namespace OpenRa.Game public void Update() { int t = Environment.TickCount; - int dt = t - lastTime; - if (dt >= timestep) - { - lastTime += timestep; - - foreach (var a in actors) a.Tick(); - foreach (var e in effects) e.Tick(); - - Renderer.waterFrame += 0.00125f * timestep; - Game.viewport.Tick(); + int dt = t - lastTime; + if (dt >= timestep) + { + lastTime += timestep; + + foreach (var a in actors) a.Tick(); + foreach (var e in effects) e.Tick(); + + Renderer.waterFrame += 0.00125f * timestep; + Game.viewport.Tick(); } foreach (Action a in frameEndActions) a(this); @@ -49,6 +49,12 @@ namespace OpenRa.Game } public IEnumerable Actors { get { return actors; } } - public IEnumerable Effects { get { return effects; } } + public IEnumerable Effects { get { return effects; } } + + uint nextAID = 0; + internal uint NextAID() + { + return nextAID++; + } } }