Refactored ProductionQueue to support different production styles.
This commit is contained in:
@@ -120,7 +120,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
|
|
||||||
bool TickQueue(ProductionQueue queue)
|
bool TickQueue(ProductionQueue queue)
|
||||||
{
|
{
|
||||||
var currentBuilding = queue.CurrentItem();
|
var currentBuilding = queue.AllQueued().FirstOrDefault();
|
||||||
|
|
||||||
// Waiting to build something
|
// Waiting to build something
|
||||||
if (currentBuilding == null && failCount < ai.Info.MaximumFailedPlacementAttempts)
|
if (currentBuilding == null && failCount < ai.Info.MaximumFailedPlacementAttempts)
|
||||||
|
|||||||
@@ -947,7 +947,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
void BuildUnit(string category, bool buildRandom)
|
void BuildUnit(string category, bool buildRandom)
|
||||||
{
|
{
|
||||||
// Pick a free queue
|
// Pick a free queue
|
||||||
var queue = FindQueues(category).FirstOrDefault(q => q.CurrentItem() == null);
|
var queue = FindQueues(category).FirstOrDefault(q => !q.AllQueued().Any());
|
||||||
if (queue == null)
|
if (queue == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -973,7 +973,7 @@ namespace OpenRA.Mods.Common.AI
|
|||||||
|
|
||||||
void BuildUnit(string category, string name)
|
void BuildUnit(string category, string name)
|
||||||
{
|
{
|
||||||
var queue = FindQueues(category).FirstOrDefault(q => q.CurrentItem() == null);
|
var queue = FindQueues(category).FirstOrDefault(q => !q.AllQueued().Any());
|
||||||
if (queue == null)
|
if (queue == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|||||||
@@ -149,7 +149,7 @@ namespace OpenRA.Mods.Common.Orders
|
|||||||
|
|
||||||
public void Tick(World world)
|
public void Tick(World world)
|
||||||
{
|
{
|
||||||
if (queue.CurrentItem() == null || queue.CurrentItem().Item != actorInfo.Name)
|
if (queue.AllQueued().All(i => !i.Done || i.Item != actorInfo.Name))
|
||||||
world.CancelInputMode();
|
world.CancelInputMode();
|
||||||
|
|
||||||
if (preview == null)
|
if (preview == null)
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
var queue = queues.Where(q => actorTypes.All(t => GetBuildableInfo(t).Queue.Contains(q.Info.Type)))
|
var queue = queues.Where(q => actorTypes.All(t => GetBuildableInfo(t).Queue.Contains(q.Info.Type)))
|
||||||
.FirstOrDefault(q => q.CurrentItem() == null);
|
.FirstOrDefault(q => !q.AllQueued().Any());
|
||||||
|
|
||||||
if (queue == null)
|
if (queue == null)
|
||||||
return false;
|
return false;
|
||||||
@@ -163,7 +163,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
return queues.Where(q => GetBuildableInfo(actorType).Queue.Contains(q.Info.Type))
|
return queues.Where(q => GetBuildableInfo(actorType).Queue.Contains(q.Info.Type))
|
||||||
.Any(q => q.CurrentItem() != null);
|
.Any(q => q.AllQueued().Any());
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildableInfo GetBuildableInfo(string actorType)
|
BuildableInfo GetBuildableInfo(string actorType)
|
||||||
@@ -225,7 +225,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
if (queueTypes.Any(t => !queues.ContainsKey(t) || productionHandlers.ContainsKey(t)))
|
if (queueTypes.Any(t => !queues.ContainsKey(t) || productionHandlers.ContainsKey(t)))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (queueTypes.Any(t => queues[t].CurrentItem() != null))
|
if (queueTypes.Any(t => queues[t].AllQueued().Any()))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (actionFunc != null)
|
if (actionFunc != null)
|
||||||
@@ -270,7 +270,7 @@ namespace OpenRA.Mods.Common.Scripting
|
|||||||
if (!queues.ContainsKey(queue))
|
if (!queues.ContainsKey(queue))
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
return productionHandlers.ContainsKey(queue) || queues[queue].CurrentItem() != null;
|
return productionHandlers.ContainsKey(queue) || queues[queue].AllQueued().Any();
|
||||||
}
|
}
|
||||||
|
|
||||||
BuildableInfo GetBuildableInfo(string actorType)
|
BuildableInfo GetBuildableInfo(string actorType)
|
||||||
|
|||||||
@@ -126,7 +126,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
if (p.Trait.Produce(p.Actor, unit, type, inits))
|
if (p.Trait.Produce(p.Actor, unit, type, inits))
|
||||||
{
|
{
|
||||||
FinishProduction();
|
EndProduction(Queue.FirstOrDefault(i => i.Done && i.Item == unit.Name));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -70,11 +70,17 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
var actorInfo = self.World.Map.Rules.Actors[order.TargetString];
|
var actorInfo = self.World.Map.Rules.Actors[order.TargetString];
|
||||||
var queue = targetActor.TraitsImplementing<ProductionQueue>()
|
var queue = targetActor.TraitsImplementing<ProductionQueue>()
|
||||||
.FirstOrDefault(q => q.CanBuild(actorInfo) && q.CurrentItem() != null && q.CurrentItem().Item == order.TargetString && q.CurrentItem().RemainingTime == 0);
|
.FirstOrDefault(q => q.CanBuild(actorInfo) && q.AllQueued().Any(i => i.Done && i.Item == order.TargetString));
|
||||||
|
|
||||||
if (queue == null)
|
if (queue == null)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
// Find the ProductionItem associated with the building that we are trying to place
|
||||||
|
var item = queue.AllQueued().FirstOrDefault(i => i.Done && i.Item == order.TargetString);
|
||||||
|
|
||||||
|
if (item == null)
|
||||||
|
return;
|
||||||
|
|
||||||
var producer = queue.MostLikelyProducer();
|
var producer = queue.MostLikelyProducer();
|
||||||
var faction = producer.Trait != null ? producer.Trait.Faction : self.Owner.Faction.InternalName;
|
var faction = producer.Trait != null ? producer.Trait.Faction : self.Owner.Faction.InternalName;
|
||||||
var buildingInfo = actorInfo.TraitInfo<BuildingInfo>();
|
var buildingInfo = actorInfo.TraitInfo<BuildingInfo>();
|
||||||
@@ -173,7 +179,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
foreach (var nbp in producer.Actor.TraitsImplementing<INotifyBuildingPlaced>())
|
foreach (var nbp in producer.Actor.TraitsImplementing<INotifyBuildingPlaced>())
|
||||||
nbp.BuildingPlaced(producer.Actor);
|
nbp.BuildingPlaced(producer.Actor);
|
||||||
|
|
||||||
queue.FinishProduction();
|
queue.EndProduction(item);
|
||||||
|
|
||||||
if (buildingInfo.RequiresBaseProvider)
|
if (buildingInfo.RequiresBaseProvider)
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -97,26 +97,20 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
readonly Actor self;
|
readonly Actor self;
|
||||||
|
|
||||||
// A list of things we could possibly build
|
// A list of things we could possibly build
|
||||||
readonly Dictionary<ActorInfo, ProductionState> producible = new Dictionary<ActorInfo, ProductionState>();
|
protected readonly Dictionary<ActorInfo, ProductionState> Producible = new Dictionary<ActorInfo, ProductionState>();
|
||||||
readonly List<ProductionItem> queue = new List<ProductionItem>();
|
protected readonly List<ProductionItem> Queue = new List<ProductionItem>();
|
||||||
readonly IEnumerable<ActorInfo> allProducibles;
|
readonly IEnumerable<ActorInfo> allProducibles;
|
||||||
readonly IEnumerable<ActorInfo> buildableProducibles;
|
readonly IEnumerable<ActorInfo> buildableProducibles;
|
||||||
|
|
||||||
Production[] productionTraits;
|
protected Production[] productionTraits;
|
||||||
|
|
||||||
// Will change if the owner changes
|
// Will change if the owner changes
|
||||||
PowerManager playerPower;
|
PowerManager playerPower;
|
||||||
PlayerResources playerResources;
|
protected PlayerResources playerResources;
|
||||||
protected DeveloperMode developerMode;
|
protected DeveloperMode developerMode;
|
||||||
|
|
||||||
public Actor Actor { get { return self; } }
|
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 bool Enabled { get; protected set; }
|
[Sync] public bool Enabled { get; protected set; }
|
||||||
|
|
||||||
public string Faction { get; private set; }
|
public string Faction { get; private set; }
|
||||||
@@ -134,8 +128,8 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
Enabled = IsValidFaction;
|
Enabled = IsValidFaction;
|
||||||
|
|
||||||
CacheProducibles(playerActor);
|
CacheProducibles(playerActor);
|
||||||
allProducibles = producible.Where(a => a.Value.Buildable || a.Value.Visible).Select(a => a.Key);
|
allProducibles = Producible.Where(a => a.Value.Buildable || a.Value.Visible).Select(a => a.Key);
|
||||||
buildableProducibles = producible.Where(a => a.Value.Buildable).Select(a => a.Key);
|
buildableProducibles = Producible.Where(a => a.Value.Buildable).Select(a => a.Key);
|
||||||
}
|
}
|
||||||
|
|
||||||
void INotifyCreated.Created(Actor self)
|
void INotifyCreated.Created(Actor self)
|
||||||
@@ -150,12 +144,10 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
protected void ClearQueue()
|
protected void ClearQueue()
|
||||||
{
|
{
|
||||||
if (queue.Count == 0)
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Refund the current item
|
// Refund the current item
|
||||||
playerResources.GiveCash(queue[0].TotalCost - queue[0].RemainingCost);
|
foreach (var item in Queue)
|
||||||
queue.Clear();
|
playerResources.GiveCash(item.TotalCost - item.RemainingCost);
|
||||||
|
Queue.Clear();
|
||||||
}
|
}
|
||||||
|
|
||||||
void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
|
void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
|
||||||
@@ -188,7 +180,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
void CacheProducibles(Actor playerActor)
|
void CacheProducibles(Actor playerActor)
|
||||||
{
|
{
|
||||||
producible.Clear();
|
Producible.Clear();
|
||||||
if (!Enabled)
|
if (!Enabled)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -198,7 +190,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
{
|
{
|
||||||
var bi = a.TraitInfo<BuildableInfo>();
|
var bi = a.TraitInfo<BuildableInfo>();
|
||||||
|
|
||||||
producible.Add(a, new ProductionState());
|
Producible.Add(a, new ProductionState());
|
||||||
ttc.Add(a.Name, bi.Prerequisites, bi.BuildLimit, this);
|
ttc.Add(a.Name, bi.Prerequisites, bi.BuildLimit, this);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -214,38 +206,38 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
public void PrerequisitesAvailable(string key)
|
public void PrerequisitesAvailable(string key)
|
||||||
{
|
{
|
||||||
producible[self.World.Map.Rules.Actors[key]].Buildable = true;
|
Producible[self.World.Map.Rules.Actors[key]].Buildable = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PrerequisitesUnavailable(string key)
|
public void PrerequisitesUnavailable(string key)
|
||||||
{
|
{
|
||||||
producible[self.World.Map.Rules.Actors[key]].Buildable = false;
|
Producible[self.World.Map.Rules.Actors[key]].Buildable = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PrerequisitesItemHidden(string key)
|
public void PrerequisitesItemHidden(string key)
|
||||||
{
|
{
|
||||||
producible[self.World.Map.Rules.Actors[key]].Visible = false;
|
Producible[self.World.Map.Rules.Actors[key]].Visible = false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void PrerequisitesItemVisible(string key)
|
public void PrerequisitesItemVisible(string key)
|
||||||
{
|
{
|
||||||
producible[self.World.Map.Rules.Actors[key]].Visible = true;
|
Producible[self.World.Map.Rules.Actors[key]].Visible = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
public ProductionItem CurrentItem()
|
public virtual bool IsProducing(ProductionItem item)
|
||||||
{
|
{
|
||||||
return queue.ElementAtOrDefault(0);
|
return Queue.Count > 0 && Queue[0] == item;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IEnumerable<ProductionItem> AllQueued()
|
public virtual IEnumerable<ProductionItem> AllQueued()
|
||||||
{
|
{
|
||||||
return queue;
|
return Queue;
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IEnumerable<ActorInfo> AllItems()
|
public virtual IEnumerable<ActorInfo> AllItems()
|
||||||
{
|
{
|
||||||
if (developerMode.AllTech)
|
if (developerMode.AllTech)
|
||||||
return producible.Keys;
|
return Producible.Keys;
|
||||||
|
|
||||||
return allProducibles;
|
return allProducibles;
|
||||||
}
|
}
|
||||||
@@ -255,7 +247,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (!Enabled)
|
if (!Enabled)
|
||||||
return Enumerable.Empty<ActorInfo>();
|
return Enumerable.Empty<ActorInfo>();
|
||||||
if (developerMode.AllTech)
|
if (developerMode.AllTech)
|
||||||
return producible.Keys;
|
return Producible.Keys;
|
||||||
|
|
||||||
return buildableProducibles;
|
return buildableProducibles;
|
||||||
}
|
}
|
||||||
@@ -263,7 +255,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
public bool CanBuild(ActorInfo actor)
|
public bool CanBuild(ActorInfo actor)
|
||||||
{
|
{
|
||||||
ProductionState ps;
|
ProductionState ps;
|
||||||
if (!producible.TryGetValue(actor, out ps))
|
if (!Producible.TryGetValue(actor, out ps))
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
return ps.Buildable || developerMode.AllTech;
|
return ps.Buildable || developerMode.AllTech;
|
||||||
@@ -289,21 +281,32 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
ClearQueue();
|
ClearQueue();
|
||||||
|
|
||||||
Enabled = IsValidFaction && anyEnabledProduction;
|
Enabled = IsValidFaction && anyEnabledProduction;
|
||||||
|
|
||||||
TickInner(self, !anyUnpausedProduction);
|
TickInner(self, !anyUnpausedProduction);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual void TickInner(Actor self, bool allProductionPaused)
|
protected virtual void TickInner(Actor self, bool allProductionPaused)
|
||||||
{
|
{
|
||||||
while (queue.Count > 0 && BuildableItems().All(b => b.Name != queue[0].Item))
|
CancelUnbuildableItems();
|
||||||
{
|
|
||||||
// Refund what's been paid so far
|
|
||||||
playerResources.GiveCash(queue[0].TotalCost - queue[0].RemainingCost);
|
|
||||||
FinishProduction();
|
|
||||||
}
|
|
||||||
|
|
||||||
if (queue.Count > 0 && !allProductionPaused)
|
if (Queue.Count > 0 && !allProductionPaused)
|
||||||
queue[0].Tick(playerResources);
|
Queue[0].Tick(playerResources);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected void CancelUnbuildableItems()
|
||||||
|
{
|
||||||
|
var buildableNames = BuildableItems().Select(b => b.Name).ToList();
|
||||||
|
|
||||||
|
// EndProduction removes the item from the queue, so we enumerate
|
||||||
|
// by index in reverse to avoid issues with index reassignment
|
||||||
|
for (var i = Queue.Count - 1; i >= 0; i--)
|
||||||
|
{
|
||||||
|
if (buildableNames.Contains(Queue[i].Item))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
// Refund what's been paid so far
|
||||||
|
playerResources.GiveCash(Queue[i].TotalCost - Queue[i].RemainingCost);
|
||||||
|
EndProduction(Queue[i]);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool CanQueue(ActorInfo actor, out string notificationAudio)
|
public bool CanQueue(ActorInfo actor, out string notificationAudio)
|
||||||
@@ -316,13 +319,13 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
if (!developerMode.AllTech)
|
if (!developerMode.AllTech)
|
||||||
{
|
{
|
||||||
if (Info.QueueLimit > 0 && queue.Count >= Info.QueueLimit)
|
if (Info.QueueLimit > 0 && Queue.Count >= Info.QueueLimit)
|
||||||
{
|
{
|
||||||
notificationAudio = Info.LimitedAudio;
|
notificationAudio = Info.LimitedAudio;
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
var queueCount = queue.Count(i => i.Item == actor.Name);
|
var queueCount = Queue.Count(i => i.Item == actor.Name);
|
||||||
if (Info.ItemLimit > 0 && queueCount >= Info.ItemLimit)
|
if (Info.ItemLimit > 0 && queueCount >= Info.ItemLimit)
|
||||||
{
|
{
|
||||||
notificationAudio = Info.LimitedAudio;
|
notificationAudio = Info.LimitedAudio;
|
||||||
@@ -367,14 +370,14 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
if (!developerMode.AllTech)
|
if (!developerMode.AllTech)
|
||||||
{
|
{
|
||||||
if (Info.QueueLimit > 0)
|
if (Info.QueueLimit > 0)
|
||||||
fromLimit = Info.QueueLimit - queue.Count;
|
fromLimit = Info.QueueLimit - Queue.Count;
|
||||||
|
|
||||||
if (Info.ItemLimit > 0)
|
if (Info.ItemLimit > 0)
|
||||||
fromLimit = Math.Min(fromLimit, Info.ItemLimit - queue.Count(i => i.Item == order.TargetString));
|
fromLimit = Math.Min(fromLimit, Info.ItemLimit - Queue.Count(i => i.Item == order.TargetString));
|
||||||
|
|
||||||
if (bi.BuildLimit > 0)
|
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.ActorsHavingTrait<Buildable>().Count(a => a.Info.Name == order.TargetString && a.Owner == self.Owner);
|
var owned = self.Owner.World.ActorsHavingTrait<Buildable>().Count(a => a.Info.Name == order.TargetString && a.Owner == self.Owner);
|
||||||
fromLimit = Math.Min(fromLimit, bi.BuildLimit - (inQueue + owned));
|
fromLimit = Math.Min(fromLimit, bi.BuildLimit - (inQueue + owned));
|
||||||
}
|
}
|
||||||
@@ -408,8 +411,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
case "PauseProduction":
|
case "PauseProduction":
|
||||||
if (queue.Count > 0 && queue[0].Item == order.TargetString)
|
PauseProduction(order.TargetString, order.ExtraData != 0);
|
||||||
queue[0].Pause(order.ExtraData != 0);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
case "CancelProduction":
|
case "CancelProduction":
|
||||||
@@ -434,6 +436,13 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
return time;
|
return time;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected void PauseProduction(string itemName, bool paused)
|
||||||
|
{
|
||||||
|
var item = Queue.FirstOrDefault(a => a.Item == itemName);
|
||||||
|
if (item != null)
|
||||||
|
item.Pause(paused);
|
||||||
|
}
|
||||||
|
|
||||||
protected void CancelProduction(string itemName, uint numberToCancel)
|
protected void CancelProduction(string itemName, uint numberToCancel)
|
||||||
{
|
{
|
||||||
for (var i = 0; i < numberToCancel; i++)
|
for (var i = 0; i < numberToCancel; i++)
|
||||||
@@ -443,33 +452,32 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
bool CancelProductionInner(string itemName)
|
bool CancelProductionInner(string itemName)
|
||||||
{
|
{
|
||||||
var lastIndex = queue.FindLastIndex(a => a.Item == itemName);
|
var item = Queue.LastOrDefault(a => a.Item == itemName);
|
||||||
|
|
||||||
if (lastIndex > 0)
|
if (item != null)
|
||||||
queue.RemoveAt(lastIndex);
|
|
||||||
else if (lastIndex == 0)
|
|
||||||
{
|
{
|
||||||
var item = queue[0];
|
|
||||||
|
|
||||||
// Refund what has been paid
|
// Refund what has been paid
|
||||||
playerResources.GiveCash(item.TotalCost - item.RemainingCost);
|
playerResources.GiveCash(item.TotalCost - item.RemainingCost);
|
||||||
FinishProduction();
|
EndProduction(item);
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
else
|
|
||||||
return false;
|
|
||||||
|
|
||||||
return true;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
public void FinishProduction()
|
public void EndProduction(ProductionItem item)
|
||||||
{
|
{
|
||||||
if (queue.Count != 0)
|
Queue.Remove(item);
|
||||||
queue.RemoveAt(0);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void BeginProduction(ProductionItem item)
|
protected void BeginProduction(ProductionItem item)
|
||||||
{
|
{
|
||||||
queue.Add(item);
|
Queue.Add(item);
|
||||||
|
}
|
||||||
|
|
||||||
|
public virtual int RemainingTimeActual(ProductionItem item)
|
||||||
|
{
|
||||||
|
return item.RemainingTimeActual;
|
||||||
}
|
}
|
||||||
|
|
||||||
// Returns the actor/trait that is most likely (but not necessarily guaranteed) to produce something in this queue
|
// Returns the actor/trait that is most likely (but not necessarily guaranteed) to produce something in this queue
|
||||||
@@ -504,7 +512,7 @@ namespace OpenRA.Mods.Common.Traits
|
|||||||
|
|
||||||
if (!mostLikelyProducerTrait.IsTraitPaused && mostLikelyProducerTrait.Produce(self, unit, type, inits))
|
if (!mostLikelyProducerTrait.IsTraitPaused && mostLikelyProducerTrait.Produce(self, unit, type, inits))
|
||||||
{
|
{
|
||||||
FinishProduction();
|
EndProduction(Queue.FirstOrDefault(i => i.Done && i.Item == unit.Name));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -67,7 +67,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
|||||||
|
|
||||||
void ITick.Tick(Actor self)
|
void ITick.Tick(Actor self)
|
||||||
{
|
{
|
||||||
var current = queue.CurrentItem();
|
var current = queue.AllQueued().Where(i => i.Started).OrderBy(i => i.RemainingTime).FirstOrDefault();
|
||||||
value = current != null ? 1 - (float)current.RemainingCost / current.TotalCost : 0;
|
value = current != null ? 1 - (float)current.RemainingCost / current.TotalCost : 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
@@ -49,7 +49,7 @@ namespace OpenRA.Mods.Common.Traits.Render
|
|||||||
|
|
||||||
bool IsProducing
|
bool IsProducing
|
||||||
{
|
{
|
||||||
get { return queues != null && queues.Any(q => q.Enabled && q.CurrentItem() != null && !q.CurrentPaused); }
|
get { return queues != null && queues.Any(q => q.Enabled && q.AllQueued().Any(i => !i.Paused && i.Started)); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public WithProductionOverlay(Actor self, WithProductionOverlayInfo info)
|
public WithProductionOverlay(Actor self, WithProductionOverlayInfo info)
|
||||||
|
|||||||
@@ -52,7 +52,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
|
|||||||
var chromeName = button.ProductionGroup.ToLowerInvariant();
|
var chromeName = button.ProductionGroup.ToLowerInvariant();
|
||||||
var icon = button.Get<ImageWidget>("ICON");
|
var icon = button.Get<ImageWidget>("ICON");
|
||||||
icon.GetImageName = () => button.IsDisabled() ? chromeName + "-disabled" :
|
icon.GetImageName = () => button.IsDisabled() ? chromeName + "-disabled" :
|
||||||
queues.Any(q => q.CurrentDone) ? chromeName + "-alert" : chromeName;
|
queues.Any(q => q.AllQueued().Any(i => i.Done)) ? chromeName + "-alert" : chromeName;
|
||||||
}
|
}
|
||||||
|
|
||||||
[ObjectCreator.UseCtor]
|
[ObjectCreator.UseCtor]
|
||||||
|
|||||||
@@ -114,7 +114,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
if (!clocks.ContainsKey(queue.Trait))
|
if (!clocks.ContainsKey(queue.Trait))
|
||||||
clocks.Add(queue.Trait, new Animation(world, ClockAnimation));
|
clocks.Add(queue.Trait, new Animation(world, ClockAnimation));
|
||||||
|
|
||||||
var current = queue.Trait.CurrentItem();
|
var current = queue.Trait.AllQueued().FirstOrDefault();
|
||||||
if (current == null || queue.i >= icons.Length)
|
if (current == null || queue.i >= icons.Length)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
@@ -162,7 +162,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
if (item.Done)
|
if (item.Done)
|
||||||
return "READY";
|
return "READY";
|
||||||
|
|
||||||
return WidgetUtils.FormatTime(item.RemainingTimeActual, timestep);
|
return WidgetUtils.FormatTime(item.Queue.RemainingTimeActual(item), timestep);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Widget Clone()
|
public override Widget Clone()
|
||||||
|
|||||||
@@ -334,7 +334,9 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
bool HandleEvent(ProductionIcon icon, MouseButton btn, Modifiers modifiers)
|
bool HandleEvent(ProductionIcon icon, MouseButton btn, Modifiers modifiers)
|
||||||
{
|
{
|
||||||
var startCount = modifiers.HasModifier(Modifiers.Shift) ? 5 : 1;
|
var startCount = modifiers.HasModifier(Modifiers.Shift) ? 5 : 1;
|
||||||
var cancelCount = modifiers.HasModifier(Modifiers.Ctrl) ? CurrentQueue.QueueLength : startCount;
|
|
||||||
|
// PERF: avoid an unnecessary enumeration by casting back to its known type
|
||||||
|
var cancelCount = modifiers.HasModifier(Modifiers.Ctrl) ? ((List<ProductionItem>)CurrentQueue.AllQueued()).Count : startCount;
|
||||||
var item = icon.Queued.FirstOrDefault();
|
var item = icon.Queued.FirstOrDefault();
|
||||||
var handled = btn == MouseButton.Left ? HandleLeftClick(item, icon, startCount)
|
var handled = btn == MouseButton.Left ? HandleLeftClick(item, icon, startCount)
|
||||||
: btn == MouseButton.Right ? HandleRightClick(item, icon, cancelCount)
|
: btn == MouseButton.Right ? HandleRightClick(item, icon, cancelCount)
|
||||||
@@ -465,7 +467,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
if (total > 0)
|
if (total > 0)
|
||||||
{
|
{
|
||||||
var first = icon.Queued[0];
|
var first = icon.Queued[0];
|
||||||
var waiting = first != CurrentQueue.CurrentItem() && !first.Done;
|
var waiting = !CurrentQueue.IsProducing(first) && !first.Done;
|
||||||
if (first.Done)
|
if (first.Done)
|
||||||
{
|
{
|
||||||
if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber * worldRenderer.World.Timestep / 360 % 2 == 0)
|
if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber * worldRenderer.World.Timestep / 360 % 2 == 0)
|
||||||
@@ -478,7 +480,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
icon.Pos + holdOffset,
|
icon.Pos + holdOffset,
|
||||||
Color.White, Color.Black, 1);
|
Color.White, Color.Black, 1);
|
||||||
else if (!waiting && DrawTime)
|
else if (!waiting && DrawTime)
|
||||||
overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(first.RemainingTimeActual, World.Timestep),
|
overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(first.Queue.RemainingTimeActual(first), World.Timestep),
|
||||||
icon.Pos + timeOffset,
|
icon.Pos + timeOffset,
|
||||||
Color.White, Color.Black, 1);
|
Color.White, Color.Black, 1);
|
||||||
|
|
||||||
|
|||||||
@@ -30,7 +30,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
public List<ProductionTab> Tabs = new List<ProductionTab>();
|
public List<ProductionTab> Tabs = new List<ProductionTab>();
|
||||||
public string Group;
|
public string Group;
|
||||||
public int NextQueueName = 1;
|
public int NextQueueName = 1;
|
||||||
public bool Alert { get { return Tabs.Any(t => t.Queue.CurrentDone); } }
|
public bool Alert { get { return Tabs.Any(t => t.Queue.AllQueued().Any(i => i.Done)); } }
|
||||||
|
|
||||||
public void Update(IEnumerable<ProductionQueue> allQueues)
|
public void Update(IEnumerable<ProductionQueue> allQueues)
|
||||||
{
|
{
|
||||||
@@ -111,7 +111,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
|
|
||||||
// Prioritize alerted queues
|
// Prioritize alerted queues
|
||||||
var queues = Groups[queueGroup].Tabs.Select(t => t.Queue)
|
var queues = Groups[queueGroup].Tabs.Select(t => t.Queue)
|
||||||
.OrderByDescending(q => q.CurrentDone ? 1 : 0)
|
.OrderByDescending(q => q.AllQueued().Any(i => i.Done) ? 1 : 0)
|
||||||
.ToList();
|
.ToList();
|
||||||
|
|
||||||
if (reverse) queues.Reverse();
|
if (reverse) queues.Reverse();
|
||||||
@@ -195,7 +195,7 @@ namespace OpenRA.Mods.Common.Widgets
|
|||||||
|
|
||||||
var textSize = font.Measure(tab.Name);
|
var textSize = font.Measure(tab.Name);
|
||||||
var position = new int2(rect.X + (rect.Width - textSize.X) / 2, rect.Y + (rect.Height - textSize.Y) / 2);
|
var position = new int2(rect.X + (rect.Width - textSize.X) / 2, rect.Y + (rect.Height - textSize.Y) / 2);
|
||||||
font.DrawTextWithContrast(tab.Name, position, tab.Queue.CurrentDone ? Color.Gold : Color.White, Color.Black, 1);
|
font.DrawTextWithContrast(tab.Name, position, tab.Queue.AllQueued().Any(i => i.Done) ? Color.Gold : Color.White, Color.Black, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
Game.Renderer.DisableScissor();
|
Game.Renderer.DisableScissor();
|
||||||
|
|||||||
Reference in New Issue
Block a user