Skip to content

Commit

Permalink
Implemented ParallelProductionQueue.
Browse files Browse the repository at this point in the history
  • Loading branch information
IceReaper committed Sep 28, 2018
1 parent 8144fca commit 1a4a11d
Show file tree
Hide file tree
Showing 15 changed files with 161 additions and 81 deletions.
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/AI/BaseBuilder.cs
Original file line number Diff line number Diff line change
Expand Up @@ -120,7 +120,7 @@ public void Tick()

bool TickQueue(ProductionQueue queue)
{
var currentBuilding = queue.CurrentItem();
var currentBuilding = queue.AllQueued().FirstOrDefault();

// Waiting to build something
if (currentBuilding == null && failCount < ai.Info.MaximumFailedPlacementAttempts)
Expand Down
4 changes: 2 additions & 2 deletions OpenRA.Mods.Common/AI/HackyAI.cs
Original file line number Diff line number Diff line change
Expand Up @@ -947,7 +947,7 @@ void ProductionUnits(Actor self)
void BuildUnit(string category, bool buildRandom)
{
// 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)
return;

Expand All @@ -973,7 +973,7 @@ void BuildUnit(string category, bool buildRandom)

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)
return;

Expand Down
1 change: 1 addition & 0 deletions OpenRA.Mods.Common/OpenRA.Mods.Common.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -410,6 +410,7 @@
<Compile Include="Traits\Player\GrantConditionOnPrerequisiteManager.cs" />
<Compile Include="Traits\Player\HarvesterAttackNotifier.cs" />
<Compile Include="Traits\Player\MissionObjectives.cs" />
<Compile Include="Traits\Player\ParallelProductionQueue.cs" />
<Compile Include="Traits\Player\PlaceBeacon.cs" />
<Compile Include="Traits\Player\PlaceBuilding.cs" />
<Compile Include="Traits\Player\PlayerExperience.cs" />
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Orders/PlaceBuildingOrderGenerator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -149,7 +149,7 @@ IEnumerable<Order> InnerOrder(World world, CPos cell, MouseInput mi)

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();

if (preview == null)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -114,7 +114,7 @@ public bool Build(string[] actorTypes, LuaFunction actionFunc = null)
return false;

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)
return false;
Expand Down Expand Up @@ -163,7 +163,7 @@ public bool IsProducing(string actorType)
return true;

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)
Expand Down Expand Up @@ -225,7 +225,7 @@ public bool Build(string[] actorTypes, LuaFunction actionFunc = null)
if (queueTypes.Any(t => !queues.ContainsKey(t) || productionHandlers.ContainsKey(t)))
return false;

if (queueTypes.Any(t => queues[t].CurrentItem() != null))
if (queueTypes.Any(t => queues[t].AllQueued().Any()))
return false;

if (actionFunc != null)
Expand Down Expand Up @@ -270,7 +270,7 @@ public bool IsProducing(string actorType)
if (!queues.ContainsKey(queue))
return true;

return productionHandlers.ContainsKey(queue) || queues[queue].CurrentItem() != null;
return productionHandlers.ContainsKey(queue) || queues[queue].AllQueued().Any();
}

BuildableInfo GetBuildableInfo(string actorType)
Expand Down
2 changes: 1 addition & 1 deletion OpenRA.Mods.Common/Traits/Player/ClassicProductionQueue.cs
Original file line number Diff line number Diff line change
Expand Up @@ -126,7 +126,7 @@ protected override bool BuildUnit(ActorInfo unit)

if (p.Trait.Produce(p.Actor, unit, type, inits))
{
FinishProduction();
EndProduction(Queue.FirstOrDefault(i => i.Done && i.Item == unit.Name));
return true;
}
}
Expand Down
63 changes: 63 additions & 0 deletions OpenRA.Mods.Common/Traits/Player/ParallelProductionQueue.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
#region Copyright & License Information
/*
* Copyright 2007-2018 The OpenRA Developers (see AUTHORS)
* This file is part of OpenRA, which is free software. It is made
* available to you under the terms of the GNU General Public License
* as published by the Free Software Foundation, either version 3 of
* the License, or (at your option) any later version. For more
* information, see COPYING.
*/
#endregion

using System.Linq;

namespace OpenRA.Mods.Common.Traits
{
public class ParallelProductionQueueInfo : ProductionQueueInfo
{
public override object Create(ActorInitializer init) { return new ParallelProductionQueue(init, init.Self.Owner.PlayerActor, this); }
}

public class ParallelProductionQueue : ProductionQueue
{
public ParallelProductionQueue(ActorInitializer init, Actor playerActor, ParallelProductionQueueInfo info)
: base(init, playerActor, info) { }

protected override void TickInner(Actor self, bool allProductionPaused)
{
CancelUnbuildableItems();

var item = Queue.FirstOrDefault(i => !i.Paused);
if (item == null)
return;

var before = item.RemainingTime;

if (!item.Paused)
item.Tick(playerResources);

if (item.RemainingTime == before)
return;

foreach (var other in Queue.FindAll(a => a.Item == item.Item))
{
Queue.Remove(other);
Queue.Add(other);
}
}

public override bool IsProducing(ProductionItem item)
{
return Queue.Contains(item);
}

public override int RemainingTimeActual(ProductionItem item)
{
var parallelBuilds = Queue.FindAll(i => !i.Paused && !i.Done)
.GroupBy(i => i.Item)
.ToList()
.Count;
return item.RemainingTimeActual * parallelBuilds;
}
}
}
10 changes: 8 additions & 2 deletions OpenRA.Mods.Common/Traits/Player/PlaceBuilding.cs
Original file line number Diff line number Diff line change
Expand Up @@ -70,11 +70,17 @@ void IResolveOrder.ResolveOrder(Actor self, Order order)
var actorInfo = self.World.Map.Rules.Actors[order.TargetString];
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)
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 faction = producer.Trait != null ? producer.Trait.Faction : self.Owner.Faction.InternalName;
var buildingInfo = actorInfo.TraitInfo<BuildingInfo>();
Expand Down Expand Up @@ -173,7 +179,7 @@ void IResolveOrder.ResolveOrder(Actor self, Order order)
foreach (var nbp in producer.Actor.TraitsImplementing<INotifyBuildingPlaced>())
nbp.BuildingPlaced(producer.Actor);
queue.FinishProduction();
queue.EndProduction(item);
if (buildingInfo.RequiresBaseProvider)
{
Expand Down
Loading

0 comments on commit 1a4a11d

Please sign in to comment.