diff --git a/OpenRa.Game/Graphics/WorldRenderer.cs b/OpenRa.Game/Graphics/WorldRenderer.cs index 157b9ee2ab..1060f5467a 100644 --- a/OpenRa.Game/Graphics/WorldRenderer.cs +++ b/OpenRa.Game/Graphics/WorldRenderer.cs @@ -242,6 +242,9 @@ namespace OpenRa.Game.Graphics { foreach (var tag in tags.GetTags()) { + if (tag == TagType.None) + continue; + var tagImages = new Animation("pips"); tagImages.PlayRepeating(tagStrings[(int)tag]); spriteRenderer.DrawSprite(tagImages.Image, tagxyBase + tagxyOffset, PaletteType.Chrome); diff --git a/OpenRa.Game/Traits/Production.cs b/OpenRa.Game/Traits/Production.cs index c4d1413f39..e24eec3a68 100755 --- a/OpenRa.Game/Traits/Production.cs +++ b/OpenRa.Game/Traits/Production.cs @@ -4,8 +4,11 @@ using System.Collections.Generic; namespace OpenRa.Game.Traits { - class Production : IProducer, ITags + class Production : IOrder, IProducer, ITags { + bool isPrimary = false; + public bool IsPrimary { get { return isPrimary; } } + public Production( Actor self ) { } public virtual int2? CreationLocation( Actor self, UnitInfo producee ) @@ -50,7 +53,45 @@ namespace OpenRa.Game.Traits public IEnumerable GetTags() { - yield return (true) ? TagType.Primary : TagType.None; + yield return (isPrimary) ? TagType.Primary : TagType.None; + } + + public Order IssueOrder(Actor self, int2 xy, MouseInput mi, Actor underCursor) + { + if (mi.Button == MouseButton.Right && underCursor == self) + return new Order("Deploy", self, null, int2.Zero, null); + return null; + } + + public void ResolveOrder(Actor self, Order order) + { + if (order.OrderString == "Deploy") + { + SetPrimaryProducer(self, !isPrimary); + } + } + + public void SetPrimaryProducer(Actor self, bool state) + { + if (state == false) + { + isPrimary = false; + return; + } + + // Cancel existing primaries + foreach (var p in (self.Info as BuildingInfo).Produces) + { + foreach (var b in Game.world.Actors.Where(x => x.traits.Contains() + && x.Owner == self.Owner + && x.traits.Get().IsPrimary == true + && (x.Info as BuildingInfo).Produces.Contains(p))) + { + b.traits.Get().SetPrimaryProducer(b, false); + } + } + isPrimary = true; + Sound.Play("pribldg1.aud"); } } } diff --git a/OpenRa.Game/Traits/ProductionQueue.cs b/OpenRa.Game/Traits/ProductionQueue.cs index 869277d5c8..0e58800572 100755 --- a/OpenRa.Game/Traits/ProductionQueue.cs +++ b/OpenRa.Game/Traits/ProductionQueue.cs @@ -128,12 +128,36 @@ namespace OpenRa.Game.Traits { 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(); - + Actor producer = null; + + // Prioritise primary structure in build order + var primaryProducers = Game.world.Actors + .Where(x => x.traits.Contains() + && producerTypes.Contains(x.Info) + && x.Owner == self.Owner + && x.traits.Get().IsPrimary == true); + + foreach (var p in primaryProducers) + { + // Ignore buildings that are disabled + if (p.traits.Contains() && p.traits.Get().InsuffientPower()) + continue; + producer = p; + break; + } + + // TODO: Be smart about disabled buildings. Units in progress should be paused(?) + // Ignore this for now + + // Pick the first available producer + if (producer == null) + { + producer = Game.world.Actors + .Where( x => producerTypes.Contains( x.Info ) && x.Owner == self.Owner ) + .FirstOrDefault(); + } + + // Something went wrong somewhere... if( producer == null ) { CancelProduction( Rules.UnitCategory[ name ] ); diff --git a/OpenRa.Game/Traits/TraitsInterfaces.cs b/OpenRa.Game/Traits/TraitsInterfaces.cs index da3e3bb431..5ee0a485ef 100644 --- a/OpenRa.Game/Traits/TraitsInterfaces.cs +++ b/OpenRa.Game/Traits/TraitsInterfaces.cs @@ -22,7 +22,11 @@ namespace OpenRa.Game.Traits Order IssueOrder( Actor self, int2 xy, MouseInput mi, Actor underCursor ); void ResolveOrder( Actor self, Order order ); } - interface IProducer { bool Produce( Actor self, UnitInfo producee ); } + interface IProducer + { + bool Produce( Actor self, UnitInfo producee ); + void SetPrimaryProducer(Actor self, bool isPrimary); + } interface IOccupySpace { IEnumerable OccupiedCells(); } interface INotifyAttack { void Attacking(Actor self); } interface IRenderModifier { IEnumerable ModifyRender(Actor self, IEnumerable r); }