From 7b3a0ebeb5cbbe9b7318f8cf1aeba708c70e8e08 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Sat, 21 Jun 2014 15:56:50 +1200 Subject: [PATCH] Tidy production traits. --- .../Widgets/ProductionPaletteWidget.cs | 12 +- OpenRA.Mods.RA/AI/BaseBuilder.cs | 6 +- OpenRA.Mods.RA/AI/HackyAI.cs | 4 +- .../Player/ClassicProductionQueue.cs | 32 ++- OpenRA.Mods.RA/Player/ProductionQueue.cs | 225 ++++++++++-------- .../Scripting/LuaScriptInterface.cs | 2 +- OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs | 12 +- 7 files changed, 160 insertions(+), 133 deletions(-) diff --git a/OpenRA.Mods.Cnc/Widgets/ProductionPaletteWidget.cs b/OpenRA.Mods.Cnc/Widgets/ProductionPaletteWidget.cs index 4dbb1af4aa..564d79b5a6 100644 --- a/OpenRA.Mods.Cnc/Widgets/ProductionPaletteWidget.cs +++ b/OpenRA.Mods.Cnc/Widgets/ProductionPaletteWidget.cs @@ -81,7 +81,7 @@ namespace OpenRA.Mods.Cnc.Widgets public override void Tick() { - if (CurrentQueue != null && !CurrentQueue.self.IsInWorld) + if (CurrentQueue != null && !CurrentQueue.Actor.IsInWorld) CurrentQueue = null; if (CurrentQueue != null) @@ -125,20 +125,20 @@ namespace OpenRA.Mods.Cnc.Widgets if (first != null && first.Done && actor.Traits.Contains()) { Sound.Play(TabClick); - World.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue.self, icon.Name); + World.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue.Actor, icon.Name); } else if (first != null && first.Paused) { // Resume a paused item Sound.Play(TabClick); - World.IssueOrder(Order.PauseProduction(CurrentQueue.self, icon.Name, false)); + World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, icon.Name, false)); } else if (CurrentQueue.BuildableItems().Any(a => a.Name == icon.Name)) { // Queue a new item Sound.Play(TabClick); Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.QueuedAudio, World.LocalPlayer.Country.Race); - World.IssueOrder(Order.StartProduction(CurrentQueue.self, icon.Name, + World.IssueOrder(Order.StartProduction(CurrentQueue.Actor, icon.Name, Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1)); } else @@ -155,13 +155,13 @@ namespace OpenRA.Mods.Cnc.Widgets if (first.Paused || first.Done || first.TotalCost == first.RemainingCost) { Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, World.LocalPlayer.Country.Race); - World.IssueOrder(Order.CancelProduction(CurrentQueue.self, icon.Name, + World.IssueOrder(Order.CancelProduction(CurrentQueue.Actor, icon.Name, Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1)); } else { Sound.PlayNotification(World.Map.Rules, World.LocalPlayer, "Speech", CurrentQueue.Info.OnHoldAudio, World.LocalPlayer.Country.Race); - World.IssueOrder(Order.PauseProduction(CurrentQueue.self, icon.Name, true)); + World.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, icon.Name, true)); } } else diff --git a/OpenRA.Mods.RA/AI/BaseBuilder.cs b/OpenRA.Mods.RA/AI/BaseBuilder.cs index 000baa5ff1..be060c8864 100644 --- a/OpenRA.Mods.RA/AI/BaseBuilder.cs +++ b/OpenRA.Mods.RA/AI/BaseBuilder.cs @@ -51,7 +51,7 @@ namespace OpenRA.Mods.RA.AI { HackyAI.BotDebug("AI: Starting production of {0}".F(item.Name)); state = BuildState.WaitForProduction; - ai.world.IssueOrder(Order.StartProduction(queue.self, item.Name, 1)); + ai.world.IssueOrder(Order.StartProduction(queue.Actor, item.Name, 1)); } break; @@ -60,7 +60,7 @@ namespace OpenRA.Mods.RA.AI return; if (currentBuilding.Paused) - ai.world.IssueOrder(Order.PauseProduction(queue.self, currentBuilding.Item, false)); + ai.world.IssueOrder(Order.PauseProduction(queue.Actor, currentBuilding.Item, false)); else if (currentBuilding.Done) { state = BuildState.WaitForFeedback; @@ -77,7 +77,7 @@ namespace OpenRA.Mods.RA.AI if (location == null) { HackyAI.BotDebug("AI: Nowhere to place {0}".F(currentBuilding.Item)); - ai.world.IssueOrder(Order.CancelProduction(queue.self, currentBuilding.Item, 1)); + ai.world.IssueOrder(Order.CancelProduction(queue.Actor, currentBuilding.Item, 1)); } else { diff --git a/OpenRA.Mods.RA/AI/HackyAI.cs b/OpenRA.Mods.RA/AI/HackyAI.cs index 4f643ec78f..4ec02f49df 100644 --- a/OpenRA.Mods.RA/AI/HackyAI.cs +++ b/OpenRA.Mods.RA/AI/HackyAI.cs @@ -839,7 +839,7 @@ namespace OpenRA.Mods.RA.AI ChooseUnitToBuild(queue); if (unit != null && Info.UnitsToBuild.Any(u => u.Key == unit.Name)) - world.IssueOrder(Order.StartProduction(queue.self, unit.Name, 1)); + world.IssueOrder(Order.StartProduction(queue.Actor, unit.Name, 1)); } void BuildUnit(string category, string name) @@ -849,7 +849,7 @@ namespace OpenRA.Mods.RA.AI return; if (Map.Rules.Actors[name] != null) - world.IssueOrder(Order.StartProduction(queue.self, name, 1)); + world.IssueOrder(Order.StartProduction(queue.Actor, name, 1)); } public void Damaged(Actor self, AttackInfo e) diff --git a/OpenRA.Mods.RA/Player/ClassicProductionQueue.cs b/OpenRA.Mods.RA/Player/ClassicProductionQueue.cs index 10992efe3c..f20ec6ca6c 100644 --- a/OpenRA.Mods.RA/Player/ClassicProductionQueue.cs +++ b/OpenRA.Mods.RA/Player/ClassicProductionQueue.cs @@ -23,22 +23,27 @@ namespace OpenRA.Mods.RA { [Desc("If you build more actors of the same type,", "the same queue will get its build time lowered for every actor produced there.")] public readonly bool SpeedUp = false; + [Desc("Every time another production building of the same queue is", "contructed, the build times of all actors in the queue", "decreased by a percentage of the original time.")] public readonly int[] BuildTimeSpeedReduction = { 100, 85, 75, 65, 60, 55, 50 }; - public override object Create(ActorInitializer init) { return new ClassicProductionQueue(init.self, this); } + public override object Create(ActorInitializer init) { return new ClassicProductionQueue(init, this); } } public class ClassicProductionQueue : ProductionQueue, ISync { - public new ClassicProductionQueueInfo Info; + static readonly ActorInfo[] NoItems = { }; - public ClassicProductionQueue(Actor self, ClassicProductionQueueInfo info) - : base(self, self, info) + readonly Actor self; + readonly ClassicProductionQueueInfo info; + + public ClassicProductionQueue(ActorInitializer init, ClassicProductionQueueInfo info) + : base(init, init.self, info) { - this.Info = info; + this.self = init.self; + this.info = info; } [Sync] bool isActive = false; @@ -47,23 +52,25 @@ namespace OpenRA.Mods.RA { isActive = false; foreach (var x in self.World.ActorsWithTrait()) + { if (x.Actor.Owner == self.Owner && x.Trait.Info.Produces.Contains(Info.Type)) { isActive = true; break; } + } + base.Tick(self); } - static ActorInfo[] None = { }; public override IEnumerable AllItems() { - return isActive ? base.AllItems() : None; + return isActive ? base.AllItems() : NoItems; } public override IEnumerable BuildableItems() { - return isActive ? base.BuildableItems() : None; + return isActive ? base.BuildableItems() : NoItems; } protected override bool BuildUnit(string name) @@ -89,10 +96,11 @@ namespace OpenRA.Mods.RA return true; } } + return false; } - public override int GetBuildTime(String unitString) + public override int GetBuildTime(string unitString) { var unit = self.World.Map.Rules.Actors[unitString]; if (unit == null || !unit.Traits.Contains()) @@ -103,15 +111,15 @@ namespace OpenRA.Mods.RA var time = (int)(unit.GetBuildTime() * Info.BuildSpeed); - if (Info.SpeedUp) + if (info.SpeedUp) { var queues = unit.Traits.Get().Queue; var selfsameBuildings = self.World.ActorsWithTrait() .Where(p => p.Actor.Owner == self.Owner && p.Trait.Info.Produces.Intersect(queues).Any()) .ToArray(); - var speedModifier = selfsameBuildings.Count().Clamp(1, Info.BuildTimeSpeedReduction.Length) - 1; - time = (time * Info.BuildTimeSpeedReduction[speedModifier]) / 100; + var speedModifier = selfsameBuildings.Count().Clamp(1, info.BuildTimeSpeedReduction.Length) - 1; + time = (time * info.BuildTimeSpeedReduction[speedModifier]) / 100; } return time; diff --git a/OpenRA.Mods.RA/Player/ProductionQueue.cs b/OpenRA.Mods.RA/Player/ProductionQueue.cs index 34d5e5cece..dc0130c9c6 100644 --- a/OpenRA.Mods.RA/Player/ProductionQueue.cs +++ b/OpenRA.Mods.RA/Player/ProductionQueue.cs @@ -23,6 +23,7 @@ namespace OpenRA.Mods.RA { [Desc("What kind of production will be added (e.g. Building, Infantry, Vehicle, ...)")] public readonly string Type = null; + [Desc("Group queues from separate buildings together into the same tab.")] public readonly string Group = null; @@ -30,96 +31,99 @@ namespace OpenRA.Mods.RA public readonly bool RequireOwner = true; [Desc("This value is used to translate the unit cost into build time.")] - public float BuildSpeed = 0.4f; + public readonly float BuildSpeed = 0.4f; + [Desc("The build time is multiplied with this value on low power.")] public readonly int LowPowerSlowdown = 3; [Desc("Notification played when production is complete.", "The filename of the audio is defined per faction in notifications.yaml.")] public readonly string ReadyAudio = "UnitReady"; + [Desc("Notification played when you can't train another unit", "when the build limit exceeded or the exit is jammed.", "The filename of the audio is defined per faction in notifications.yaml.")] public readonly string BlockedAudio = "NoBuild"; + [Desc("Notification played when user clicks on the build palette icon.", "The filename of the audio is defined per faction in notifications.yaml.")] public readonly string QueuedAudio = "Training"; + [Desc("Notification played when player right-clicks on the build palette icon.", "The filename of the audio is defined per faction in notifications.yaml.")] public readonly string OnHoldAudio = "OnHold"; + [Desc("Notification played when player right-clicks on a build palette icon that is already on hold.", "The filename of the audio is defined per faction in notifications.yaml.")] public readonly string CancelledAudio = "Cancelled"; - public virtual object Create(ActorInitializer init) { return new ProductionQueue(init.self, init.self.Owner.PlayerActor, this); } + public virtual object Create(ActorInitializer init) { return new ProductionQueue(init, init.self.Owner.PlayerActor, this); } } public class ProductionQueue : IResolveOrder, ITick, ITechTreeElement, INotifyCapture, INotifyKilled, INotifySold, ISync, INotifyTransform { - public readonly Actor self; - public ProductionQueueInfo Info; - PowerManager PlayerPower; + public readonly ProductionQueueInfo Info; + readonly Actor self; + readonly string race; + + // Can change if the actor is captured + PowerManager playerPower; PlayerResources playerResources; - readonly CountryInfo Race; + + // A list of things we could possibly build + Dictionary produceable; + List queue = new List(); // A list of things we are currently building - public List Queue = new List(); + public Actor Actor { get { return self; } } - [Sync] public int QueueLength { get { return Queue.Count; } } - [Sync] public int CurrentRemainingCost { get { return QueueLength == 0 ? 0 : Queue[0].RemainingCost; } } - [Sync] public int CurrentRemainingTime { get { return QueueLength == 0 ? 0 : Queue[0].RemainingTime; } } - [Sync] public int CurrentSlowdown { get { return QueueLength == 0 ? 0 : Queue[0].slowdown; } } - [Sync] public bool CurrentPaused { get { return QueueLength != 0 && Queue[0].Paused; } } - [Sync] public bool CurrentDone { get { return QueueLength != 0 && Queue[0].Done; } } + [Sync] public int QueueLength { get { return queue.Count; } } + [Sync] public int CurrentRemainingCost { get { return QueueLength == 0 ? 0 : queue[0].RemainingCost; } } + [Sync] public int CurrentRemainingTime { get { return QueueLength == 0 ? 0 : queue[0].RemainingTime; } } + [Sync] public int CurrentSlowdown { get { return QueueLength == 0 ? 0 : queue[0].Slowdown; } } + [Sync] public bool CurrentPaused { get { return QueueLength != 0 && queue[0].Paused; } } + [Sync] public bool CurrentDone { get { return QueueLength != 0 && queue[0].Done; } } - // A list of things we could possibly build, even if our race doesn't normally get it - public Dictionary Produceable; - - public ProductionQueue( Actor self, Actor playerActor, ProductionQueueInfo info ) + public ProductionQueue(ActorInitializer init, Actor playerActor, ProductionQueueInfo info) { - this.self = self; - this.Info = info; + self = init.self; + Info = info; playerResources = playerActor.Trait(); - PlayerPower = playerActor.Trait(); + playerPower = playerActor.Trait(); - Race = self.Owner.Country; - Produceable = InitTech(playerActor); + race = self.Owner.Country.Race; + CacheProduceables(playerActor); } void ClearQueue() { - if (Queue.Count == 0) + if (queue.Count == 0) return; // Refund the current item - playerResources.GiveCash(Queue[0].TotalCost - Queue[0].RemainingCost); - Queue.Clear(); + playerResources.GiveCash(queue[0].TotalCost - queue[0].RemainingCost); + queue.Clear(); } public void OnCapture(Actor self, Actor captor, Player oldOwner, Player newOwner) { - PlayerPower = newOwner.PlayerActor.Trait(); + playerPower = newOwner.PlayerActor.Trait(); playerResources = newOwner.PlayerActor.Trait(); ClearQueue(); - // Produceable contains the tech from the original owner - this is desired so we don't clear it. - Produceable = InitTech(self.Owner.PlayerActor); - - // Force a third(!) tech tree update to ensure that prerequisites are correct. - // The first two updates are triggered by adding/removing the actor when - // changing ownership, *before* the new techtree watchers have been set up. - // This is crap. + // Regenerate the produceables and tech tree state + CacheProduceables(newOwner.PlayerActor); self.Owner.PlayerActor.Trait().Update(); } public void Killed(Actor killed, AttackInfo e) { if (killed == self) ClearQueue(); } - public void Selling(Actor self) {} + public void Selling(Actor self) { } public void Sold(Actor self) { ClearQueue(); } public void OnTransform(Actor self) { ClearQueue(); } - Dictionary InitTech(Actor playerActor) + void CacheProduceables(Actor playerActor) { - var tech = new Dictionary(); + produceable = new Dictionary(); var ttc = playerActor.Trait(); foreach (var a in AllBuildables(Info.Type)) @@ -127,102 +131,101 @@ namespace OpenRA.Mods.RA var bi = a.Traits.Get(); // Can our race build this by satisfying normal prerequisites? - var buildable = !Info.RequireOwner || bi.Owner.Contains(Race.Race); + var buildable = !Info.RequireOwner || bi.Owner.Contains(race); // Checks if Prerequisites want to hide the Actor from buildQueue if they are false - tech.Add(a, new ProductionState { Visible = buildable }); + produceable.Add(a, new ProductionState { Visible = buildable }); if (buildable) ttc.Add(a.Name, bi.Prerequisites, bi.BuildLimit, this); } - - return tech; } IEnumerable AllBuildables(string category) { return self.World.Map.Rules.Actors.Values .Where(x => - x.Name[ 0 ] != '^' && + x.Name[0] != '^' && x.Traits.Contains() && x.Traits.Get().Queue.Contains(category)); } public void OverrideProduction(ActorInfo type, bool buildable) { - Produceable[type].Buildable = buildable; - Produceable[type].Sticky = true; + produceable[type].Buildable = buildable; + produceable[type].Sticky = true; } public void PrerequisitesAvailable(string key) { - var ps = Produceable[ self.World.Map.Rules.Actors[key] ]; + var ps = produceable[self.World.Map.Rules.Actors[key]]; if (!ps.Sticky) ps.Buildable = true; } public void PrerequisitesUnavailable(string key) { - var ps = Produceable[ self.World.Map.Rules.Actors[key] ]; + var ps = produceable[self.World.Map.Rules.Actors[key]]; if (!ps.Sticky) ps.Buildable = false; } public void PrerequisitesItemHidden(string key) { - Produceable[self.World.Map.Rules.Actors[key]].Visible = false; + produceable[self.World.Map.Rules.Actors[key]].Visible = false; } public void PrerequisitesItemVisible(string key) { - Produceable[self.World.Map.Rules.Actors[key]].Visible = true; + produceable[self.World.Map.Rules.Actors[key]].Visible = true; } public ProductionItem CurrentItem() { - return Queue.ElementAtOrDefault(0); + return queue.ElementAtOrDefault(0); } public IEnumerable AllQueued() { - return Queue; + return queue; } public virtual IEnumerable AllItems() { if (self.World.AllowDevCommands && self.Owner.PlayerActor.Trait().AllTech) - return Produceable.Select(a => a.Key); + return produceable.Select(a => a.Key); - return Produceable.Where(a => a.Value.Buildable || a.Value.Visible).Select(a => a.Key); + return produceable.Where(a => a.Value.Buildable || a.Value.Visible).Select(a => a.Key); } public virtual IEnumerable BuildableItems() { if (self.World.AllowDevCommands && self.Owner.PlayerActor.Trait().AllTech) - return Produceable.Select(a => a.Key); + return produceable.Select(a => a.Key); - return Produceable.Where(a => a.Value.Buildable).Select(a => a.Key); + return produceable.Where(a => a.Value.Buildable).Select(a => a.Key); } public bool CanBuild(ActorInfo actor) { - return Produceable.ContainsKey(actor) && Produceable[actor].Buildable; + return produceable.ContainsKey(actor) && produceable[actor].Buildable; } public virtual void Tick(Actor self) { - while (Queue.Count > 0 && BuildableItems().All(b => b.Name != Queue[ 0 ].Item)) + while (queue.Count > 0 && BuildableItems().All(b => b.Name != queue[0].Item)) { - playerResources.GiveCash(Queue[0].TotalCost - Queue[0].RemainingCost); // refund what's been paid so far. + playerResources.GiveCash(queue[0].TotalCost - queue[0].RemainingCost); // refund what's been paid so far. FinishProduction(); } - if (Queue.Count > 0) - Queue[ 0 ].Tick(playerResources); + + if (queue.Count > 0) + queue[0].Tick(playerResources); } public void ResolveOrder(Actor self, Order order) { - switch(order.OrderString) + switch (order.OrderString) { case "StartProduction": { @@ -241,7 +244,7 @@ namespace OpenRA.Mods.RA var fromLimit = int.MaxValue; if (bi.BuildLimit > 0) { - var inQueue = Queue.Count(pi => pi.Item == order.TargetString); + var inQueue = queue.Count(pi => pi.Item == order.TargetString); var owned = self.Owner.World.ActorsWithTrait().Count(a => a.Actor.Info.Name == order.TargetString && a.Actor.Owner == self.Owner); fromLimit = bi.BuildLimit - (inQueue + owned); @@ -250,37 +253,39 @@ namespace OpenRA.Mods.RA } var amountToBuild = Math.Min(fromLimit, order.ExtraData); - - for (var n = 0; n < amountToBuild; n++) // repeat count + for (var n = 0; n < amountToBuild; n++) { var hasPlayedSound = false; - BeginProduction(new ProductionItem(this, order.TargetString, cost, PlayerPower, - () => self.World.AddFrameEndTask(_ => + BeginProduction(new ProductionItem(this, order.TargetString, cost, playerPower, () => self.World.AddFrameEndTask(_ => + { + var isBuilding = unit.Traits.Contains(); + if (isBuilding && !hasPlayedSound) + { + hasPlayedSound = Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.ReadyAudio, self.Owner.Country.Race); + } + else if (!isBuilding) + { + if (BuildUnit(order.TargetString)) + Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.ReadyAudio, self.Owner.Country.Race); + else if (!hasPlayedSound && time > 0) { - var isBuilding = unit.Traits.Contains(); - if (isBuilding && !hasPlayedSound) - { - hasPlayedSound = Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.ReadyAudio, self.Owner.Country.Race); - } - else if (!isBuilding) - { - if (BuildUnit(order.TargetString)) - Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.ReadyAudio, self.Owner.Country.Race); - else if (!hasPlayedSound && time > 0) - { - hasPlayedSound = Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.BlockedAudio, self.Owner.Country.Race); - } - } - }))); + hasPlayedSound = Sound.PlayNotification(self.World.Map.Rules, self.Owner, "Speech", Info.BlockedAudio, self.Owner.Country.Race); + } + } + }))); } + break; } + case "PauseProduction": { - if (Queue.Count > 0 && Queue[0].Item == order.TargetString) - Queue[0].Paused = ( order.ExtraData != 0 ); + if (queue.Count > 0 && queue[0].Item == order.TargetString) + queue[0].Pause(order.ExtraData != 0); + break; } + case "CancelProduction": { CancelProduction(order.TargetString, order.ExtraData); @@ -289,10 +294,10 @@ namespace OpenRA.Mods.RA } } - virtual public int GetBuildTime(String unitString) + public virtual int GetBuildTime(string unitString) { var unit = self.World.Map.Rules.Actors[unitString]; - if (unit == null || ! unit.Traits.Contains()) + if (unit == null || !unit.Traits.Contains()) return 0; if (self.World.AllowDevCommands && self.Owner.PlayerActor.Trait().FastBuild) @@ -300,7 +305,7 @@ namespace OpenRA.Mods.RA var time = unit.GetBuildTime() * Info.BuildSpeed; - return (int) time; + return (int)time; } protected void CancelProduction(string itemName, uint numberToCancel) @@ -311,13 +316,13 @@ namespace OpenRA.Mods.RA void CancelProductionInner(string itemName) { - var lastIndex = Queue.FindLastIndex(a => a.Item == itemName); + var lastIndex = queue.FindLastIndex(a => a.Item == itemName); if (lastIndex > 0) - Queue.RemoveAt(lastIndex); + queue.RemoveAt(lastIndex); else if (lastIndex == 0) { - var item = Queue[0]; + var item = queue[0]; playerResources.GiveCash(item.TotalCost - item.RemainingCost); // refund what has been paid FinishProduction(); } @@ -325,13 +330,13 @@ namespace OpenRA.Mods.RA public void FinishProduction() { - if (Queue.Count == 0) return; - Queue.RemoveAt(0); + if (queue.Count != 0) + queue.RemoveAt(0); } protected void BeginProduction(ProductionItem item) { - Queue.Add(item); + queue.Add(item); } // Builds a unit from the actor that holds this queue (1 queue per building) @@ -351,6 +356,7 @@ namespace OpenRA.Mods.RA FinishProduction(); return true; } + return false; } } @@ -366,9 +372,10 @@ namespace OpenRA.Mods.RA { public readonly string Item; public readonly ProductionQueue Queue; - readonly PowerManager pm; - public int TotalTime; public readonly int TotalCost; + public readonly Action OnComplete; + + public int TotalTime { get; private set; } public int RemainingTime { get; private set; } public int RemainingCost { get; private set; } public int RemainingTimeActual @@ -380,9 +387,12 @@ namespace OpenRA.Mods.RA } } - public bool Paused = false, Done = false, Started = false; - public Action OnComplete; - public int slowdown = 0; + public bool Paused { get; private set; } + public bool Done { get; private set; } + public bool Started { get; private set; } + public int Slowdown { get; private set; } + + readonly PowerManager pm; public ProductionItem(ProductionQueue queue, string item, int cost, PowerManager pm, Action onComplete) { @@ -392,7 +402,6 @@ namespace OpenRA.Mods.RA OnComplete = onComplete; Queue = queue; this.pm = pm; - //Log.Write("debug", "new ProductionItem: {0} time={1} cost={2}", item, time, cost); } public void Tick(PlayerResources pr) @@ -400,33 +409,43 @@ namespace OpenRA.Mods.RA if (!Started) { var time = Queue.GetBuildTime(Item); - if (time > 0) RemainingTime = TotalTime = time; + if (time > 0) + RemainingTime = TotalTime = time; + Started = true; } if (Done) { - if (OnComplete != null) OnComplete(); + if (OnComplete != null) + OnComplete(); + return; } - if (Paused) return; + if (Paused) + return; if (pm.PowerState != PowerState.Normal) { - if (--slowdown <= 0) - slowdown = Queue.Info.LowPowerSlowdown; + if (--Slowdown <= 0) + Slowdown = Queue.Info.LowPowerSlowdown; else return; } var costThisFrame = RemainingCost / RemainingTime; - if (costThisFrame != 0 && !pr.TakeCash(costThisFrame)) return; + if (costThisFrame != 0 && !pr.TakeCash(costThisFrame)) + return; + RemainingCost -= costThisFrame; RemainingTime -= 1; - if (RemainingTime > 0) return; + if (RemainingTime > 0) + return; Done = true; } + + public void Pause(bool paused) { Paused = paused; } } } diff --git a/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs b/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs index 1432ff3adf..5a03d70456 100644 --- a/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs +++ b/OpenRA.Mods.RA/Scripting/LuaScriptInterface.cs @@ -402,7 +402,7 @@ namespace OpenRA.Mods.RA.Scripting var queue = GetSharedQueueForUnit(player, unit); if (queue != null) - queue.ResolveOrder(queue.self, Order.StartProduction(queue.self, unit, (int)amount)); + queue.ResolveOrder(queue.Actor, Order.StartProduction(queue.Actor, unit, (int)amount)); } [LuaGlobal] diff --git a/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs b/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs index 2460e9cb3a..9f649d6523 100644 --- a/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs +++ b/OpenRA.Mods.RA/Widgets/BuildPaletteWidget.cs @@ -94,7 +94,7 @@ namespace OpenRA.Mods.RA.Widgets .Where(p => p.Actor.Owner == world.LocalPlayer) .Select(p => p.Trait); - if (CurrentQueue != null && CurrentQueue.self.Destroyed) + if (CurrentQueue != null && CurrentQueue.Actor.Destroyed) CurrentQueue = null; foreach (var queue in queues) @@ -366,7 +366,7 @@ namespace OpenRA.Mods.RA.Widgets if (producing.Done) { if (unit.Traits.Contains()) - world.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue.self, item); + world.OrderGenerator = new PlaceBuildingOrderGenerator(CurrentQueue.Actor, item); else StartProduction(world, item); return; @@ -374,7 +374,7 @@ namespace OpenRA.Mods.RA.Widgets if (producing.Paused) { - world.IssueOrder(Order.PauseProduction(CurrentQueue.self, item, false)); + world.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, item, false)); return; } } @@ -403,12 +403,12 @@ namespace OpenRA.Mods.RA.Widgets Sound.PlayNotification(world.Map.Rules, world.LocalPlayer, "Speech", CurrentQueue.Info.CancelledAudio, world.LocalPlayer.Country.Race); var numberToCancel = Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1; - world.IssueOrder(Order.CancelProduction(CurrentQueue.self, item, numberToCancel)); + world.IssueOrder(Order.CancelProduction(CurrentQueue.Actor, item, numberToCancel)); } else { Sound.PlayNotification(world.Map.Rules, world.LocalPlayer, "Speech", CurrentQueue.Info.OnHoldAudio, world.LocalPlayer.Country.Race); - world.IssueOrder(Order.PauseProduction(CurrentQueue.self, item, true)); + world.IssueOrder(Order.PauseProduction(CurrentQueue.Actor, item, true)); } } } @@ -416,7 +416,7 @@ namespace OpenRA.Mods.RA.Widgets void StartProduction(World world, string item) { - world.IssueOrder(Order.StartProduction(CurrentQueue.self, item, + world.IssueOrder(Order.StartProduction(CurrentQueue.Actor, item, Game.GetModifierKeys().HasModifier(Modifiers.Shift) ? 5 : 1)); }