Overhaul ProductionBar:

- Is now a conditional trait
- Now respects multiple Production trait instances
- ProductionType is now required
This commit is contained in:
abcdefg30
2018-10-28 18:39:45 +00:00
committed by abcdefg30
parent 7f255a17da
commit 5e5183549c
10 changed files with 110 additions and 21 deletions

View File

@@ -595,6 +595,7 @@
<Compile Include="UpdateRules\Rules\20180923\RemovedNotifyBuildComplete.cs" /> <Compile Include="UpdateRules\Rules\20180923\RemovedNotifyBuildComplete.cs" />
<Compile Include="UpdateRules\Rules\20180923\ChangeTakeOffSoundAndLandingSound.cs" /> <Compile Include="UpdateRules\Rules\20180923\ChangeTakeOffSoundAndLandingSound.cs" />
<Compile Include="UpdateRules\Rules\20180923\AddCarryableHarvester.cs" /> <Compile Include="UpdateRules\Rules\20180923\AddCarryableHarvester.cs" />
<Compile Include="UpdateRules\Rules\20180923\RequireProductionType.cs" />
<Compile Include="UtilityCommands\CheckYaml.cs" /> <Compile Include="UtilityCommands\CheckYaml.cs" />
<Compile Include="UtilityCommands\ConvertPngToShpCommand.cs" /> <Compile Include="UtilityCommands\ConvertPngToShpCommand.cs" />
<Compile Include="UtilityCommands\ConvertSpriteToPngCommand.cs" /> <Compile Include="UtilityCommands\ConvertSpriteToPngCommand.cs" />

View File

@@ -17,73 +17,72 @@ using OpenRA.Traits;
namespace OpenRA.Mods.Common.Traits.Render namespace OpenRA.Mods.Common.Traits.Render
{ {
[Desc("Visualizes the remaining build time of actor produced here.")] [Desc("Visualizes the remaining build time of actor produced here.")]
class ProductionBarInfo : ITraitInfo, Requires<ProductionInfo> class ProductionBarInfo : ConditionalTraitInfo, Requires<ProductionInfo>
{ {
[FieldLoader.Require]
[Desc("Production queue type, for actors with multiple queues.")] [Desc("Production queue type, for actors with multiple queues.")]
public readonly string ProductionType = null; public readonly string ProductionType = null;
public readonly Color Color = Color.SkyBlue; public readonly Color Color = Color.SkyBlue;
public object Create(ActorInitializer init) { return new ProductionBar(init.Self, this); } public override object Create(ActorInitializer init) { return new ProductionBar(init.Self, this); }
} }
class ProductionBar : ISelectionBar, ITick, INotifyCreated, INotifyOwnerChanged class ProductionBar : ConditionalTrait<ProductionBarInfo>, ISelectionBar, ITick, INotifyOwnerChanged
{ {
readonly ProductionBarInfo info;
readonly Actor self; readonly Actor self;
ProductionQueue queue; ProductionQueue queue;
float value; float value;
public ProductionBar(Actor self, ProductionBarInfo info) public ProductionBar(Actor self, ProductionBarInfo info)
: base(info)
{ {
this.self = self; this.self = self;
this.info = info; }
protected override void Created(Actor self)
{
base.Created(self);
FindQueue();
} }
void FindQueue() void FindQueue()
{ {
var type = info.ProductionType ?? self.Info.TraitInfo<ProductionInfo>().Produces.First();
// Per-actor queue // Per-actor queue
// Note: this includes disabled queues, as each bar must bind to exactly one 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 => Info.ProductionType == q.Info.Type);
if (queue == null) if (queue == null)
{ {
// No queues available - check for classic production queues // No queues available - check for classic production queues
queue = self.Owner.PlayerActor.TraitsImplementing<ProductionQueue>() queue = self.Owner.PlayerActor.TraitsImplementing<ProductionQueue>()
.FirstOrDefault(q => type == null || type == q.Info.Type); .FirstOrDefault(q => Info.ProductionType == q.Info.Type);
} }
if (queue == null)
throw new InvalidOperationException("No queues available for production type '{0}'".F(type));
}
void INotifyCreated.Created(Actor self)
{
FindQueue();
} }
void ITick.Tick(Actor self) void ITick.Tick(Actor self)
{ {
if (IsTraitDisabled)
return;
var current = queue.AllQueued().Where(i => i.Started).OrderBy(i => i.RemainingTime).FirstOrDefault(); 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;
} }
float ISelectionBar.GetValue() float ISelectionBar.GetValue()
{ {
// only people we like should see our production status. // Only people we like should see our production status.
if (!self.Owner.IsAlliedWith(self.World.RenderPlayer)) if (IsTraitDisabled || !self.Owner.IsAlliedWith(self.World.RenderPlayer))
return 0; return 0;
return value; return value;
} }
Color ISelectionBar.GetColor() { return info.Color; } Color ISelectionBar.GetColor() { return Info.Color; }
bool ISelectionBar.DisplayWhenEmpty { get { return false; } } bool ISelectionBar.DisplayWhenEmpty { get { return false; } }
public void OnOwnerChanged(Actor self, Player oldOwner, Player newOwner) void INotifyOwnerChanged.OnOwnerChanged(Actor self, Player oldOwner, Player newOwner)
{ {
FindQueue(); FindQueue();
} }

View File

@@ -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.Collections.Generic;
using System.Linq;
namespace OpenRA.Mods.Common.UpdateRules.Rules
{
public class RequireProductionType : UpdateRule
{
public override string Name { get { return "Require 'ProductionType' on 'ProductionBar'"; } }
public override string Description
{
get
{
return "The 'ProductionBar' trait now requires the 'ProductionType' to be set.\n" +
"The value will be automatically set to the first value in 'Produces' of the first 'Production' trait.";
}
}
readonly string[] productionTraits = { "Production", "ProductionAirdrop", "ProductionParadrop", "ProductionFromMapEdge" };
public override IEnumerable<string> UpdateActorNode(ModData modData, MiniYamlNode actorNode)
{
foreach (var pb in actorNode.ChildrenMatching("ProductionBar"))
{
var type = pb.LastChildMatching("ProductionType");
if (type != null)
continue;
MiniYamlNode production = null;
foreach (var trait in productionTraits)
{
if (production != null)
break;
production = actorNode.ChildrenMatching(trait).FirstOrDefault();
}
if (production == null)
continue;
var produces = production.LastChildMatching("Produces");
if (produces == null)
continue;
var toAdd = produces.NodeValue<string[]>().FirstOrDefault();
if (toAdd != null)
pb.AddNode("ProductionType", toAdd);
}
yield break;
}
}
}

View File

@@ -103,6 +103,7 @@ namespace OpenRA.Mods.Common.UpdateRules
new AddRearmable(), new AddRearmable(),
new MergeAttackPlaneAndHeli(), new MergeAttackPlaneAndHeli(),
new RemovedDemolishLocking(), new RemovedDemolishLocking(),
new RequireProductionType(),
}) })
}; };

View File

@@ -322,6 +322,7 @@ PYLE:
OnHoldAudio: OnHold OnHoldAudio: OnHold
CancelledAudio: Cancelled CancelledAudio: Cancelled
ProductionBar: ProductionBar:
ProductionType: Infantry.GDI
Power: Power:
Amount: -20 Amount: -20
ProvidesPrerequisite@buildingname: ProvidesPrerequisite@buildingname:
@@ -372,6 +373,7 @@ HAND:
OnHoldAudio: OnHold OnHoldAudio: OnHold
CancelledAudio: Cancelled CancelledAudio: Cancelled
ProductionBar: ProductionBar:
ProductionType: Infantry.Nod
Power: Power:
Amount: -20 Amount: -20
ProvidesPrerequisite@buildingname: ProvidesPrerequisite@buildingname:
@@ -431,6 +433,7 @@ AFLD:
OnHoldAudio: OnHold OnHoldAudio: OnHold
CancelledAudio: Cancelled CancelledAudio: Cancelled
ProductionBar: ProductionBar:
ProductionType: Vehicle.Nod
Power: Power:
Amount: -40 Amount: -40
ProvidesPrerequisite@buildingname: ProvidesPrerequisite@buildingname:
@@ -489,6 +492,7 @@ WEAP:
OnHoldAudio: OnHold OnHoldAudio: OnHold
CancelledAudio: Cancelled CancelledAudio: Cancelled
ProductionBar: ProductionBar:
ProductionType: Vehicle.GDI
Power: Power:
Amount: -40 Amount: -40
ProvidesPrerequisite@buildingname: ProvidesPrerequisite@buildingname:

View File

@@ -104,6 +104,7 @@ BIO:
OnHoldAudio: OnHold OnHoldAudio: OnHold
CancelledAudio: Cancelled CancelledAudio: Cancelled
ProductionBar: ProductionBar:
ProductionType: Biolab
RallyPoint: RallyPoint:
Offset: -1,-1 Offset: -1,-1
SpawnActorOnDeath: SpawnActorOnDeath:

View File

@@ -89,6 +89,7 @@ construction_yard:
ActorTypes: light_inf, light_inf, engineer ActorTypes: light_inf, light_inf, engineer
BaseBuilding: BaseBuilding:
ProductionBar: ProductionBar:
ProductionType: Building
Power: Power:
Amount: 20 Amount: 20
RenderSprites: RenderSprites:
@@ -215,6 +216,7 @@ barracks:
ProductionQueues: Infantry ProductionQueues: Infantry
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
ProductionBar: ProductionBar:
ProductionType: Infantry
ProvidesPrerequisite@atreides: ProvidesPrerequisite@atreides:
Prerequisite: barracks.atreides Prerequisite: barracks.atreides
Factions: atreides Factions: atreides
@@ -426,6 +428,7 @@ light_factory:
ProductionQueues: Vehicle ProductionQueues: Vehicle
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
ProductionBar: ProductionBar:
ProductionType: Vehicle
ProvidesPrerequisite@atreides: ProvidesPrerequisite@atreides:
Prerequisite: light.atreides Prerequisite: light.atreides
Factions: atreides Factions: atreides
@@ -507,6 +510,7 @@ heavy_factory:
ProductionQueues: Armor ProductionQueues: Armor
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
ProductionBar: ProductionBar:
ProductionType: Armor
ProvidesPrerequisite@atreides: ProvidesPrerequisite@atreides:
Prerequisite: heavy.atreides Prerequisite: heavy.atreides
Factions: atreides Factions: atreides
@@ -669,6 +673,7 @@ starport:
RequiresCondition: !build-incomplete RequiresCondition: !build-incomplete
Palette: starportlights Palette: starportlights
ProductionBar: ProductionBar:
ProductionType: Starport
PrimaryBuilding: PrimaryBuilding:
PrimaryCondition: primary PrimaryCondition: primary
ProductionQueues: Starport ProductionQueues: Starport
@@ -933,6 +938,7 @@ high_tech_factory:
ProductionFromMapEdge: ProductionFromMapEdge:
Produces: Aircraft, Upgrade Produces: Aircraft, Upgrade
ProductionBar: ProductionBar:
ProductionType: Aircraft
PrimaryBuilding: PrimaryBuilding:
PrimaryCondition: primary PrimaryCondition: primary
ProductionQueues: Aircraft ProductionQueues: Aircraft

View File

@@ -205,6 +205,7 @@ SPEN:
PlayerExperience: 15 PlayerExperience: 15
RallyPoint: RallyPoint:
ProductionBar: ProductionBar:
ProductionType: Ship
Power: Power:
Amount: -30 Amount: -30
DetectCloaked: DetectCloaked:
@@ -326,6 +327,7 @@ SYRD:
PlayerExperience: 15 PlayerExperience: 15
RallyPoint: RallyPoint:
ProductionBar: ProductionBar:
ProductionType: Ship
Power: Power:
Amount: -30 Amount: -30
DetectCloaked: DetectCloaked:
@@ -1055,6 +1057,7 @@ WEAP:
PrimaryCondition: primary PrimaryCondition: primary
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
ProductionBar: ProductionBar:
ProductionType: Vehicle
Power: Power:
Amount: -30 Amount: -30
ProvidesPrerequisite@buildingname: ProvidesPrerequisite@buildingname:
@@ -1320,6 +1323,7 @@ HPAD:
Produces: Aircraft, Helicopter Produces: Aircraft, Helicopter
Reservable: Reservable:
ProductionBar: ProductionBar:
ProductionType: Aircraft
PrimaryBuilding: PrimaryBuilding:
PrimaryCondition: primary PrimaryCondition: primary
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
@@ -1488,6 +1492,7 @@ AFLD:
ClockSequence: clock ClockSequence: clock
CircleSequence: circles CircleSequence: circles
ProductionBar: ProductionBar:
ProductionType: Aircraft
SupportPowerChargeBar: SupportPowerChargeBar:
PrimaryBuilding: PrimaryBuilding:
PrimaryCondition: primary PrimaryCondition: primary
@@ -1684,6 +1689,7 @@ BARR:
PrimaryCondition: primary PrimaryCondition: primary
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
ProductionBar: ProductionBar:
ProductionType: Infantry
ProvidesPrerequisite: ProvidesPrerequisite:
Prerequisite: barracks Prerequisite: barracks
ProvidesPrerequisite@soviet: ProvidesPrerequisite@soviet:
@@ -1766,6 +1772,7 @@ KENN:
PrimaryCondition: primary PrimaryCondition: primary
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
ProductionBar: ProductionBar:
ProductionType: Infantry
-SpawnActorsOnSell: -SpawnActorsOnSell:
Power: Power:
Amount: -10 Amount: -10
@@ -1826,6 +1833,7 @@ TENT:
PrimaryCondition: primary PrimaryCondition: primary
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
ProductionBar: ProductionBar:
ProductionType: Infantry
ProvidesPrerequisite@barracks: ProvidesPrerequisite@barracks:
Prerequisite: barracks Prerequisite: barracks
ProvidesPrerequisite@allies: ProvidesPrerequisite@allies:

View File

@@ -110,6 +110,7 @@ GAPILE:
PrimaryCondition: primary PrimaryCondition: primary
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
ProductionBar: ProductionBar:
ProductionType: Infantry
WithIdleOverlay@LIGHTS: WithIdleOverlay@LIGHTS:
RequiresCondition: !build-incomplete RequiresCondition: !build-incomplete
Sequence: idle-lights Sequence: idle-lights
@@ -174,6 +175,7 @@ GAWEAP:
PrimaryCondition: primary PrimaryCondition: primary
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
ProductionBar: ProductionBar:
ProductionType: Vehicle
WithIdleOverlay@ROOF: WithIdleOverlay@ROOF:
RequiresCondition: !build-incomplete RequiresCondition: !build-incomplete
Sequence: idle-roof Sequence: idle-roof
@@ -242,6 +244,7 @@ GAHPAD:
PlayerExperience: 15 PlayerExperience: 15
StartRepairingNotification: Repairing StartRepairingNotification: Repairing
ProductionBar: ProductionBar:
ProductionType: Air
WithIdleOverlay@PLATFORM: WithIdleOverlay@PLATFORM:
RequiresCondition: !build-incomplete RequiresCondition: !build-incomplete
Sequence: idle-platform Sequence: idle-platform

View File

@@ -119,6 +119,7 @@ NAHAND:
PrimaryCondition: primary PrimaryCondition: primary
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
ProductionBar: ProductionBar:
ProductionType: Infantry
WithIdleOverlay@LIGHTS: WithIdleOverlay@LIGHTS:
RequiresCondition: !build-incomplete RequiresCondition: !build-incomplete
Sequence: idle-lights Sequence: idle-lights
@@ -180,6 +181,7 @@ NAWEAP:
PrimaryCondition: primary PrimaryCondition: primary
SelectionNotification: PrimaryBuildingSelected SelectionNotification: PrimaryBuildingSelected
ProductionBar: ProductionBar:
ProductionType: Vehicle
WithIdleOverlay@ROOF: WithIdleOverlay@ROOF:
RequiresCondition: !build-incomplete RequiresCondition: !build-incomplete
Sequence: idle-roof Sequence: idle-roof
@@ -242,6 +244,7 @@ NAHPAD:
PlayerExperience: 15 PlayerExperience: 15
StartRepairingNotification: Repairing StartRepairingNotification: Repairing
ProductionBar: ProductionBar:
ProductionType: Air
WithIdleOverlay@PLATFORM: WithIdleOverlay@PLATFORM:
RequiresCondition: !build-incomplete RequiresCondition: !build-incomplete
Sequence: idle-platform Sequence: idle-platform