diff --git a/OpenRa.Game/Chat.cs b/OpenRa.Game/Chat.cs index f92fbad601..ecad834da9 100644 --- a/OpenRa.Game/Chat.cs +++ b/OpenRa.Game/Chat.cs @@ -53,6 +53,7 @@ namespace OpenRa.Game public void AddLine(Color c, string from, string text) { + Log.Write( "Chat: {0}: {1}", from, text ); recentLines.Add(Tuple.New(c, from, text)); Sound.Play("rabeep1.aud"); while (recentLines.Count > logLength) recentLines.RemoveAt(0); diff --git a/OpenRa.Game/Chrome.cs b/OpenRa.Game/Chrome.cs index 7b0533a384..9dec3ea165 100644 --- a/OpenRa.Game/Chrome.cs +++ b/OpenRa.Game/Chrome.cs @@ -108,6 +108,8 @@ namespace OpenRa.Game if (currentTab == null || !Rules.TechTree.BuildableItems(Game.LocalPlayer, currentTab).Any()) ChooseAvailableTab(); + var queue = Game.LocalPlayer.PlayerActor.traits.Get(); + foreach (var q in tabSprites) { var groupName = q.Key; @@ -117,7 +119,7 @@ namespace OpenRa.Game continue; } - var producing = Game.LocalPlayer.Producing(groupName); + var producing = queue.Producing(groupName); var index = q.Key == currentTab ? 2 : (producing != null && producing.Done) ? 1 : 0; chromeRenderer.DrawSprite(q.Value[index], new float2(x, y), 0); @@ -134,7 +136,8 @@ namespace OpenRa.Game void CheckDeadTab( string groupName ) { - var item = Game.LocalPlayer.Producing(groupName); + var queue = Game.LocalPlayer.PlayerActor.traits.Get(); + var item = queue.Producing( groupName ); if (item != null) Game.controller.AddOrder(Order.CancelProduction(Game.LocalPlayer, item.Item)); } @@ -186,7 +189,8 @@ namespace OpenRa.Game { return () => { - var producing = Game.LocalPlayer.Producing(group); + var queue = Game.LocalPlayer.PlayerActor.traits.Get(); + var producing = queue.Producing( group ); if (producing == null) return 0; return (producing.TotalTime - producing.RemainingTime) * NumClockFrames / producing.TotalTime; }; @@ -195,7 +199,7 @@ namespace OpenRa.Game void DrawBuildPalette(string queueName) { if (queueName == null) return; - var buildItem = Game.LocalPlayer.Producing(queueName); + var x = 0; var y = 0; @@ -205,7 +209,8 @@ namespace OpenRa.Game .Where(a => Rules.UnitInfo[a].TechLevel != -1) .OrderBy(a => Rules.UnitInfo[a].TechLevel); - var currentItem = Game.LocalPlayer.Producing(queueName); + var queue = Game.LocalPlayer.PlayerActor.traits.Get(); + var currentItem = queue.Producing( queueName ); var overlayBits = new List>(); @@ -272,7 +277,8 @@ namespace OpenRa.Game { var player = Game.LocalPlayer; var group = Rules.UnitCategory[item]; - var producing = player.Producing(group); + var queue = player.PlayerActor.traits.Get(); + var producing = queue.Producing( group ); Sound.Play("ramenu1.aud"); diff --git a/OpenRa.Game/Game.cs b/OpenRa.Game/Game.cs index 36d842604c..5aeb0b6dcf 100644 --- a/OpenRa.Game/Game.cs +++ b/OpenRa.Game/Game.cs @@ -278,24 +278,5 @@ namespace OpenRa.Game return Game.PathFinder.FindPath(search).Count != 0; } - - public static void BuildUnit(Player player, string name) - { - var newUnitType = Rules.UnitInfo[ name ]; - var producerTypes = Rules.TechTree.UnitBuiltAt( newUnitType ); - // TODO: choose producer based on "primary building" - var producer = world.Actors - .Where( x => producerTypes.Contains( x.Info ) && x.Owner == player ) - .FirstOrDefault(); - - if (producer == null) - { - player.CancelProduction(Rules.UnitCategory[name]); - return; - } - - if( producer.traits.WithInterface().Any( p => p.Produce( producer, newUnitType ) ) ) - player.FinishProduction(Rules.UnitCategory[name]); - } } } diff --git a/OpenRa.Game/PlaceBuilding.cs b/OpenRa.Game/PlaceBuilding.cs index c16311b066..467804a118 100644 --- a/OpenRa.Game/PlaceBuilding.cs +++ b/OpenRa.Game/PlaceBuilding.cs @@ -34,7 +34,7 @@ namespace OpenRa.Game public void Tick() { - var producing = Owner.Producing( Rules.UnitCategory[ Building.Name ] ); + var producing = Owner.PlayerActor.traits.Get().Producing( Rules.UnitCategory[ Building.Name ] ); if( producing == null || producing.Item != Building.Name || producing.RemainingTime != 0 ) Game.world.AddFrameEndTask( _ => { Game.controller.orderGenerator = null; } ); } diff --git a/OpenRa.Game/Player.cs b/OpenRa.Game/Player.cs index f3c1bab792..8d3a560cff 100644 --- a/OpenRa.Game/Player.cs +++ b/OpenRa.Game/Player.cs @@ -35,9 +35,6 @@ namespace OpenRa.Game this.Ore = 0; this.DisplayCash = 0; this.powerProvided = this.powerDrained = 0; - - foreach( var cat in Rules.Categories.Keys ) - ProductionInit( cat ); } void UpdatePower() @@ -127,10 +124,6 @@ namespace OpenRa.Game { UpdatePower(); - foreach( var p in production ) - if( p.Value != null ) - p.Value.Tick( this ); - if (this == Game.LocalPlayer) { var totalMoney = Cash + Ore; @@ -149,37 +142,5 @@ namespace OpenRa.Game } } } - - // Key: Production category. Categories are: Building, Infantry, Vehicle, Ship, Plane (and one per super, if they're done in here) - readonly Dictionary production = new Dictionary(); - - public void ProductionInit( string category ) - { - production.Add( category, null ); - } - - public ProductionItem Producing( string category ) - { - return production[ category ]; - } - - public void CancelProduction( string category ) - { - var item = production[ category ]; - if( item == null ) return; - GiveCash( item.TotalCost - item.RemainingCost ); // refund what's been paid so far. - FinishProduction( category ); - } - - public void FinishProduction( string category ) - { - production[ category ] = null; - } - - public void BeginProduction( string group, ProductionItem item ) - { - if( production[ group ] != null ) return; - production[ group ] = item; - } } } diff --git a/OpenRa.Game/Traits/ProductionQueue.cs b/OpenRa.Game/Traits/ProductionQueue.cs index f7a6354238..18e35d35f0 100755 --- a/OpenRa.Game/Traits/ProductionQueue.cs +++ b/OpenRa.Game/Traits/ProductionQueue.cs @@ -5,11 +5,22 @@ using System.Text; namespace OpenRa.Game.Traits { - class ProductionQueue : IOrder + class ProductionQueue : IOrder, ITick { + Actor self; + public ProductionQueue( Actor self ) { + this.self = self; + foreach( var cat in Rules.Categories.Keys ) + ProductionInit( cat ); + } + public void Tick( Actor self ) + { + foreach( var p in production ) + if( p.Value != null ) + p.Value.Tick( self.Owner ); } public Order IssueOrder( Actor self, int2 xy, bool lmb, Actor underCursor ) @@ -38,7 +49,7 @@ namespace OpenRa.Game.Traits bool hasPlayedSound = false; - order.Player.BeginProduction( group, + BeginProduction( group, new ProductionItem( order.TargetString, (int)time, ui.Cost, () => Game.world.AddFrameEndTask( _ => @@ -50,25 +61,77 @@ namespace OpenRa.Game.Traits hasPlayedSound = true; } if( !isBuilding ) - Game.BuildUnit( order.Player, order.TargetString ); + BuildUnit( order.TargetString ); } ) ) ); break; } case "PauseProduction": { - var producing = order.Player.Producing( Rules.UnitCategory[ order.TargetString ] ); + var producing = Producing( Rules.UnitCategory[ order.TargetString ] ); if( producing != null && producing.Item == order.TargetString ) producing.Paused = ( order.TargetLocation.X != 0 ); break; } case "CancelProduction": { - var producing = order.Player.Producing( Rules.UnitCategory[ order.TargetString ] ); + var producing = Producing( Rules.UnitCategory[ order.TargetString ] ); if( producing != null && producing.Item == order.TargetString ) - order.Player.CancelProduction( Rules.UnitCategory[ order.TargetString ] ); + CancelProduction( Rules.UnitCategory[ order.TargetString ] ); break; } } } + + // Key: Production category. Categories are: Building, Infantry, Vehicle, Ship, Plane (and one per super, if they're done in here) + readonly Dictionary production = new Dictionary(); + + void ProductionInit( string category ) + { + production.Add( category, null ); + } + + public ProductionItem Producing( string category ) + { + return production[ category ]; + } + + public void CancelProduction( string category ) + { + var item = production[ category ]; + if( item == null ) return; + self.Owner.GiveCash( item.TotalCost - item.RemainingCost ); // refund what's been paid so far. + FinishProduction( category ); + } + + public void FinishProduction( string category ) + { + production[ category ] = null; + } + + public void BeginProduction( string group, ProductionItem item ) + { + if( production[ group ] != null ) return; + production[ group ] = item; + } + + public void BuildUnit( string name ) + { + var newUnitType = Rules.UnitInfo[ name ]; + var producerTypes = Rules.TechTree.UnitBuiltAt( newUnitType ); + + // TODO: choose producer based on "primary building" + var producer = Game.world.Actors + .Where( x => producerTypes.Contains( x.Info ) && x.Owner == self.Owner ) + .FirstOrDefault(); + + if( producer == null ) + { + CancelProduction( Rules.UnitCategory[ name ] ); + return; + } + + if( producer.traits.WithInterface().Any( p => p.Produce( producer, newUnitType ) ) ) + FinishProduction( Rules.UnitCategory[ name ] ); + } } } diff --git a/OpenRa.Game/UnitOrders.cs b/OpenRa.Game/UnitOrders.cs index fd6c86b4a6..25bcea9cd4 100755 --- a/OpenRa.Game/UnitOrders.cs +++ b/OpenRa.Game/UnitOrders.cs @@ -36,8 +36,9 @@ namespace OpenRa.Game { Game.world.AddFrameEndTask( _ => { + var queue = order.Player.PlayerActor.traits.Get(); var building = (BuildingInfo)Rules.UnitInfo[ order.TargetString ]; - var producing = order.Player.Producing(Rules.UnitCategory[order.TargetString]); + var producing = queue.Producing(Rules.UnitCategory[order.TargetString]); if( producing == null || producing.Item != order.TargetString || producing.RemainingTime != 0 ) return; @@ -50,7 +51,7 @@ namespace OpenRa.Game Sound.Play("build5.aud"); } - order.Player.FinishProduction(Rules.UnitCategory[building.Name]); + queue.FinishProduction(Rules.UnitCategory[building.Name]); } ); break; }