Allow ProductionQueue to filter by race.

This commit is contained in:
Paul Chote
2014-06-21 19:33:39 +12:00
parent d9e0559c7a
commit ca082e3cec
8 changed files with 39 additions and 15 deletions

View File

@@ -41,10 +41,10 @@ namespace OpenRA.Mods.Cnc.Widgets
// Find an actor with a queue // Find an actor with a queue
var producer = world.Selection.Actors.FirstOrDefault(a => a.IsInWorld var producer = world.Selection.Actors.FirstOrDefault(a => a.IsInWorld
&& a.World.LocalPlayer == a.Owner && a.World.LocalPlayer == a.Owner
&& a.HasTrait<ProductionQueue>()); && a.TraitsImplementing<ProductionQueue>().Any(q => q.Enabled));
if (producer != null) if (producer != null)
tabsWidget.Value.CurrentQueue = producer.TraitsImplementing<ProductionQueue>().First(); tabsWidget.Value.CurrentQueue = producer.TraitsImplementing<ProductionQueue>().First(q => q.Enabled);
} }
} }
} }

View File

@@ -196,7 +196,7 @@ namespace OpenRA.Mods.Cnc.Widgets
if (a.HasTrait<ProductionQueue>()) if (a.HasTrait<ProductionQueue>())
{ {
var allQueues = a.World.ActorsWithTrait<ProductionQueue>() var allQueues = a.World.ActorsWithTrait<ProductionQueue>()
.Where(p => p.Actor.Owner == p.Actor.World.LocalPlayer && p.Actor.IsInWorld) .Where(p => p.Actor.Owner == p.Actor.World.LocalPlayer && p.Actor.IsInWorld && p.Trait.Enabled)
.Select(p => p.Trait).ToArray(); .Select(p => p.Trait).ToArray();
foreach (var g in Groups.Values) foreach (var g in Groups.Values)

View File

@@ -68,12 +68,12 @@ namespace OpenRA.Mods.RA.Render
var production = self.TraitOrDefault<Production>(); var production = self.TraitOrDefault<Production>();
var perBuildingQueues = self.TraitsImplementing<ProductionQueue>(); var perBuildingQueues = self.TraitsImplementing<ProductionQueue>();
queue = perBuildingQueues.FirstOrDefault(q => production.Info.Produces.Contains(q.Info.Type)); queue = perBuildingQueues.FirstOrDefault(q => q.Enabled && production.Info.Produces.Contains(q.Info.Type));
if (queue == null) if (queue == null)
{ {
var perPlayerQueues = self.Owner.PlayerActor.TraitsImplementing<ProductionQueue>(); var perPlayerQueues = self.Owner.PlayerActor.TraitsImplementing<ProductionQueue>();
queue = perPlayerQueues.FirstOrDefault(q => production.Info.Produces.Contains(q.Info.Type)); queue = perPlayerQueues.FirstOrDefault(q => q.Enabled && production.Info.Produces.Contains(q.Info.Type));
} }
if (queue == null) if (queue == null)

View File

@@ -809,7 +809,7 @@ namespace OpenRA.Mods.RA.AI
internal IEnumerable<ProductionQueue> FindQueues(string category) internal IEnumerable<ProductionQueue> FindQueues(string category)
{ {
return world.ActorsWithTrait<ProductionQueue>() return world.ActorsWithTrait<ProductionQueue>()
.Where(a => a.Actor.Owner == p && a.Trait.Info.Type == category) .Where(a => a.Actor.Owner == p && a.Trait.Info.Type == category && a.Trait.Enabled)
.Select(a => a.Trait); .Select(a => a.Trait);
} }

View File

@@ -30,6 +30,12 @@ namespace OpenRA.Mods.RA
[Desc("Filter buildable items based on their Owner.")] [Desc("Filter buildable items based on their Owner.")]
public readonly bool RequireOwner = true; public readonly bool RequireOwner = true;
[Desc("Only enable this queue for certain factions")]
public readonly string[] Race = { };
[Desc("Should the prerequisite remain enabled if the owner changes?")]
public readonly bool Sticky = true;
[Desc("This value is used to translate the unit cost into build time.")] [Desc("This value is used to translate the unit cost into build time.")]
public readonly float BuildSpeed = 0.4f; public readonly float BuildSpeed = 0.4f;
@@ -64,11 +70,11 @@ namespace OpenRA.Mods.RA
{ {
public readonly ProductionQueueInfo Info; public readonly ProductionQueueInfo Info;
readonly Actor self; readonly Actor self;
readonly string race;
// Can change if the actor is captured // Will change if the owner changes
PowerManager playerPower; PowerManager playerPower;
PlayerResources playerResources; PlayerResources playerResources;
string race;
// A list of things we could possibly build // A list of things we could possibly build
Dictionary<ActorInfo, ProductionState> produceable; Dictionary<ActorInfo, ProductionState> produceable;
@@ -83,6 +89,7 @@ namespace OpenRA.Mods.RA
[Sync] public int CurrentSlowdown { get { return QueueLength == 0 ? 0 : queue[0].Slowdown; } } [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 CurrentPaused { get { return QueueLength != 0 && queue[0].Paused; } }
[Sync] public bool CurrentDone { get { return QueueLength != 0 && queue[0].Done; } } [Sync] public bool CurrentDone { get { return QueueLength != 0 && queue[0].Done; } }
[Sync] public bool Enabled { get; private set; }
public ProductionQueue(ActorInitializer init, Actor playerActor, ProductionQueueInfo info) public ProductionQueue(ActorInitializer init, Actor playerActor, ProductionQueueInfo info)
{ {
@@ -91,7 +98,9 @@ namespace OpenRA.Mods.RA
playerResources = playerActor.Trait<PlayerResources>(); playerResources = playerActor.Trait<PlayerResources>();
playerPower = playerActor.Trait<PowerManager>(); playerPower = playerActor.Trait<PowerManager>();
race = self.Owner.Country.Race; race = init.Contains<RaceInit>() ? init.Get<RaceInit, string>() : self.Owner.Country.Race;
Enabled = !info.Race.Any() || info.Race.Contains(race);
CacheProduceables(playerActor); CacheProduceables(playerActor);
} }
@@ -111,6 +120,12 @@ namespace OpenRA.Mods.RA
playerResources = newOwner.PlayerActor.Trait<PlayerResources>(); playerResources = newOwner.PlayerActor.Trait<PlayerResources>();
ClearQueue(); ClearQueue();
if (!Info.Sticky)
{
race = self.Owner.Country.Race;
Enabled = !Info.Race.Any() || Info.Race.Contains(race);
}
// Regenerate the produceables and tech tree state // Regenerate the produceables and tech tree state
oldOwner.PlayerActor.Trait<TechTree>().Remove(this); oldOwner.PlayerActor.Trait<TechTree>().Remove(this);
CacheProduceables(newOwner.PlayerActor); CacheProduceables(newOwner.PlayerActor);
@@ -125,6 +140,9 @@ namespace OpenRA.Mods.RA
void CacheProduceables(Actor playerActor) void CacheProduceables(Actor playerActor)
{ {
produceable = new Dictionary<ActorInfo, ProductionState>(); produceable = new Dictionary<ActorInfo, ProductionState>();
if (!Enabled)
return;
var ttc = playerActor.Trait<TechTree>(); var ttc = playerActor.Trait<TechTree>();
foreach (var a in AllBuildables(Info.Type)) foreach (var a in AllBuildables(Info.Type))
@@ -216,6 +234,9 @@ namespace OpenRA.Mods.RA
public void ResolveOrder(Actor self, Order order) public void ResolveOrder(Actor self, Order order)
{ {
if (!Enabled)
return;
switch (order.OrderString) switch (order.OrderString)
{ {
case "StartProduction": case "StartProduction":

View File

@@ -44,6 +44,7 @@ namespace OpenRA.Mods.RA
var type = info.ProductionType ?? self.Trait<Production>().Info.Produces.First(); var type = info.ProductionType ?? self.Trait<Production>().Info.Produces.First();
// Per-actor queue // Per-actor queue
// Note: this includes disabled queues, as each bar must bind to exactly one queue.
queue = self.TraitsImplementing<ProductionQueue>() queue = self.TraitsImplementing<ProductionQueue>()
.FirstOrDefault(q => type == null || type == q.Info.Type); .FirstOrDefault(q => type == null || type == q.Info.Type);

View File

@@ -414,7 +414,8 @@ namespace OpenRA.Mods.RA.Scripting
if (bi == null) if (bi == null)
return; return;
var queue = factory.TraitOrDefault<ProductionQueue>(); var queue = factory.TraitsImplementing<ProductionQueue>()
.FirstOrDefault(q => q.Enabled);
if (queue != null) if (queue != null)
queue.ResolveOrder(factory, Order.StartProduction(factory, unit, (int)amount)); queue.ResolveOrder(factory, Order.StartProduction(factory, unit, (int)amount));
@@ -434,7 +435,8 @@ namespace OpenRA.Mods.RA.Scripting
[LuaGlobal] [LuaGlobal]
public bool PerFactoryQueueIsBusy(Actor factory) public bool PerFactoryQueueIsBusy(Actor factory)
{ {
var queue = factory.TraitOrDefault<ProductionQueue>(); var queue = factory.TraitsImplementing<ProductionQueue>()
.FirstOrDefault(q => q.Enabled);
if (queue == null) if (queue == null)
return true; return true;

View File

@@ -36,12 +36,12 @@ namespace OpenRA.Mods.RA
return; return;
// Queue-per-structure // Queue-per-structure
var perqueue = world.Selection.Actors.FirstOrDefault( var perqueue = world.Selection.Actors.FirstOrDefault(a => a.IsInWorld && a.World.LocalPlayer == a.Owner
a => a.IsInWorld && a.World.LocalPlayer == a.Owner && a.HasTrait<ProductionQueue>()); && a.TraitsImplementing<ProductionQueue>().Any(q => q.Enabled));
if (perqueue != null) if (perqueue != null)
{ {
palette.SetCurrentTab(perqueue.TraitsImplementing<ProductionQueue>().First()); palette.SetCurrentTab(perqueue.TraitsImplementing<ProductionQueue>().First(q => q.Enabled));
return; return;
} }
@@ -55,7 +55,7 @@ namespace OpenRA.Mods.RA
return; return;
palette.SetCurrentTab(world.LocalPlayer.PlayerActor.TraitsImplementing<ProductionQueue>() palette.SetCurrentTab(world.LocalPlayer.PlayerActor.TraitsImplementing<ProductionQueue>()
.FirstOrDefault(t => types.Contains(t.Info.Type))); .FirstOrDefault(q => q.Enabled && types.Contains(q.Info.Type)));
} }
} }
} }