diff --git a/OpenRa.Game/Chrome.cs b/OpenRa.Game/Chrome.cs index b975d340f7..2dfb40f005 100644 --- a/OpenRa.Game/Chrome.cs +++ b/OpenRa.Game/Chrome.cs @@ -144,7 +144,7 @@ namespace OpenRa.Game continue; } - var producing = queue.Producing(groupName); + var producing = queue.CurrentItem(groupName); var index = q.Key == currentTab ? 2 : (producing != null && producing.Done) ? 1 : 0; @@ -173,10 +173,8 @@ namespace OpenRa.Game void CheckDeadTab( string groupName ) { var queue = Game.LocalPlayer.PlayerActor.traits.Get(); - var item = queue.Producing( groupName ); - if (item != null) - for( var n = 0; n <= item.Repeats; n++ ) - Game.controller.AddOrder(Order.CancelProduction(Game.LocalPlayer, item.Item)); + foreach( var item in queue.AllItems( groupName ) ) + Game.controller.AddOrder(Order.CancelProduction(Game.LocalPlayer, item.Item)); } void ChooseAvailableTab() @@ -227,7 +225,7 @@ namespace OpenRa.Game return () => { var queue = Game.LocalPlayer.PlayerActor.traits.Get(); - var producing = queue.Producing( group ); + var producing = queue.CurrentItem( group ); if (producing == null) return 0; return (producing.TotalTime - producing.RemainingTime) * NumClockFrames / producing.TotalTime; }; @@ -252,7 +250,7 @@ namespace OpenRa.Game .OrderBy(a => Rules.UnitInfo[a].TechLevel); var queue = Game.LocalPlayer.PlayerActor.traits.Get(); - var currentItem = queue.Producing( queueName ); + var currentItem = queue.CurrentItem( queueName ); var overlayBits = new List>(); @@ -273,14 +271,14 @@ namespace OpenRa.Game if (!buildableItems.Contains(item) || isBuildingSomethingElse) overlayBits.Add(Pair.New(cantBuild.Image, drawPos)); + var overlayPos = drawPos + new float2((64 - ready.Image.size.X) / 2, 2); + if (isBuildingThis) { clockAnimations[queueName].Tick(); buildPaletteRenderer.DrawSprite(clockAnimations[queueName].Image, drawPos, PaletteType.Chrome); - var overlayPos = drawPos + new float2((64 - ready.Image.size.X) / 2, 2); - if (currentItem.Done) { ready.Play("ready"); @@ -291,18 +289,19 @@ namespace OpenRa.Game ready.Play("hold"); overlayBits.Add(Pair.New(ready.Image, overlayPos)); } + } - if (currentItem.Repeats > 0) + var repeats = queue.AllItems(queueName).Count(a => a.Item == item); + if (repeats > 1 || isBuildingThis) + { + var offset = -20; + var digits = repeats.ToString(); + foreach (var d in digits) { - var offset = -20; - var digits = (currentItem.Repeats + 1).ToString(); - foreach (var d in digits) - { - ready.PlayFetchIndex("groups", () => d - '0'); - ready.Tick(); - overlayBits.Add(Pair.New(ready.Image, overlayPos + new float2(offset, 0))); - offset += 6; - } + ready.PlayFetchIndex("groups", () => d - '0'); + ready.Tick(); + overlayBits.Add(Pair.New(ready.Image, overlayPos + new float2(offset, 0))); + offset += 6; } } @@ -350,7 +349,7 @@ namespace OpenRa.Game var player = Game.LocalPlayer; var group = Rules.UnitCategory[item]; var queue = player.PlayerActor.traits.Get(); - var producing = queue.Producing( group ); + var producing = queue.CurrentItem( group ); Sound.Play("ramenu1.aud"); diff --git a/OpenRa.Game/PlaceBuilding.cs b/OpenRa.Game/PlaceBuilding.cs index b8306e26f7..3dbb3940d3 100644 --- a/OpenRa.Game/PlaceBuilding.cs +++ b/OpenRa.Game/PlaceBuilding.cs @@ -40,7 +40,7 @@ namespace OpenRa.Game public void Tick() { - var producing = Producer.traits.Get().Producing( Rules.UnitCategory[ Building.Name ] ); + var producing = Producer.traits.Get().CurrentItem( 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/ProductionItem.cs b/OpenRa.Game/ProductionItem.cs index 27449c7f9b..cc2ad552ea 100644 --- a/OpenRa.Game/ProductionItem.cs +++ b/OpenRa.Game/ProductionItem.cs @@ -11,8 +11,6 @@ namespace OpenRa.Game public int RemainingTime { get; private set; } public int RemainingCost { get; private set; } - public int Repeats; - public bool Paused = false, Done = false; public Action OnComplete; @@ -26,14 +24,6 @@ namespace OpenRa.Game OnComplete = onComplete; } - public void DoRepeat() - { - RemainingTime = TotalTime; - RemainingCost = TotalCost; - Done = false; - --Repeats; - } - public void Tick(Player player) { if (Done) diff --git a/OpenRa.Game/Traits/ProductionQueue.cs b/OpenRa.Game/Traits/ProductionQueue.cs index c3bea23640..dde97fa1a7 100755 --- a/OpenRa.Game/Traits/ProductionQueue.cs +++ b/OpenRa.Game/Traits/ProductionQueue.cs @@ -2,6 +2,7 @@ using System.Collections.Generic; using System.Linq; using System.Text; +using IjwFramework.Collections; namespace OpenRa.Game.Traits { @@ -12,15 +13,13 @@ namespace OpenRa.Game.Traits 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 ); + if( p.Value.Count > 0 ) + (p.Value)[0].Tick( self.Owner ); } public Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor ) @@ -67,14 +66,14 @@ namespace OpenRa.Game.Traits } case "PauseProduction": { - var producing = Producing( Rules.UnitCategory[ order.TargetString ] ); + var producing = CurrentItem( Rules.UnitCategory[ order.TargetString ] ); if( producing != null && producing.Item == order.TargetString ) producing.Paused = ( order.TargetLocation.X != 0 ); break; } case "CancelProduction": { - var producing = Producing( Rules.UnitCategory[ order.TargetString ] ); + var producing = CurrentItem( Rules.UnitCategory[ order.TargetString ] ); if( producing != null && producing.Item == order.TargetString ) CancelProduction( Rules.UnitCategory[ order.TargetString ] ); break; @@ -82,27 +81,33 @@ namespace OpenRa.Game.Traits } } - // 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(); + // Key: Production category. + readonly Cache> production + = new Cache>( _ => new List() ); - void ProductionInit( string category ) + public ProductionItem CurrentItem(string category) { - production.Add( category, null ); + return production[category].ElementAtOrDefault(0); } - public ProductionItem Producing( string category ) + public IEnumerable AllItems(string category) { - return production[ category ]; + return production[category]; } public void CancelProduction( string category ) { - var item = production[ category ]; - if( item == null ) return; - if (item.Repeats > 0) - --item.Repeats; + var queue = production[ category ]; + if (queue.Count == 0) return; + + var lastIndex = queue.FindLastIndex( a => a.Item == queue[0].Item ); + if (lastIndex > 0) + { + queue.RemoveAt(lastIndex); + } else { + var item = queue[0]; self.Owner.GiveCash(item.TotalCost - item.RemainingCost); // refund what's been paid so far. FinishProduction(category); } @@ -110,23 +115,14 @@ namespace OpenRa.Game.Traits public void FinishProduction( string category ) { - var item = production[category]; - if (item == null) return; - if (item.Repeats > 0) - item.DoRepeat(); - else - production[category] = null; + var queue = production[category]; + if (queue.Count == 0) return; + queue.RemoveAt(0); } public void BeginProduction( string group, ProductionItem item ) { - if (production[group] != null) - { - if (production[group].Item == item.Item) - ++production[group].Repeats; - return; - } - production[ group ] = item; + production[group].Add(item); } public void BuildUnit( string name ) diff --git a/OpenRa.Game/UnitOrders.cs b/OpenRa.Game/UnitOrders.cs index fa9b2b858f..ec670e62a9 100755 --- a/OpenRa.Game/UnitOrders.cs +++ b/OpenRa.Game/UnitOrders.cs @@ -19,7 +19,7 @@ namespace OpenRa.Game { var queue = order.Player.PlayerActor.traits.Get(); var building = (BuildingInfo)Rules.UnitInfo[ order.TargetString ]; - var producing = queue.Producing(Rules.UnitCategory[order.TargetString]); + var producing = queue.CurrentItem(Rules.UnitCategory[order.TargetString]); if( producing == null || producing.Item != order.TargetString || producing.RemainingTime != 0 ) return;