Rewrite production tabs (again): Avoid doing a pile of work every tick; support multiple queue types grouped under one category; Tab numbering is sticky.
This commit is contained in:
@@ -22,6 +22,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
|||||||
MenuType menu = MenuType.None;
|
MenuType menu = MenuType.None;
|
||||||
|
|
||||||
Widget ingameRoot;
|
Widget ingameRoot;
|
||||||
|
World world;
|
||||||
|
|
||||||
void AddChatLine(Color c, string from, string text)
|
void AddChatLine(Color c, string from, string text)
|
||||||
{
|
{
|
||||||
@@ -32,6 +33,13 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
|||||||
{
|
{
|
||||||
Game.AddChatLine -= AddChatLine;
|
Game.AddChatLine -= AddChatLine;
|
||||||
Game.BeforeGameStart -= UnregisterEvents;
|
Game.BeforeGameStart -= UnregisterEvents;
|
||||||
|
|
||||||
|
if (world.LocalPlayer != null)
|
||||||
|
{
|
||||||
|
var queueTabs = ingameRoot.GetWidget<ProductionTabsWidget>("PRODUCTION_TABS");
|
||||||
|
world.ActorAdded += queueTabs.ActorChanged;
|
||||||
|
world.ActorRemoved += queueTabs.ActorChanged;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
ProductionQueue QueueForType(World world, string type)
|
ProductionQueue QueueForType(World world, string type)
|
||||||
@@ -45,6 +53,7 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
|||||||
public CncIngameChromeLogic([ObjectCreator.Param] Widget widget,
|
public CncIngameChromeLogic([ObjectCreator.Param] Widget widget,
|
||||||
[ObjectCreator.Param] World world )
|
[ObjectCreator.Param] World world )
|
||||||
{
|
{
|
||||||
|
this.world = world;
|
||||||
world.WorldActor.Trait<CncMenuPaletteEffect>()
|
world.WorldActor.Trait<CncMenuPaletteEffect>()
|
||||||
.Fade(CncMenuPaletteEffect.EffectType.None);
|
.Fade(CncMenuPaletteEffect.EffectType.None);
|
||||||
|
|
||||||
@@ -65,33 +74,31 @@ namespace OpenRA.Mods.Cnc.Widgets.Logic
|
|||||||
|
|
||||||
var buildPalette = playerWidgets.GetWidget<ProductionPaletteWidget>("PRODUCTION_PALETTE");
|
var buildPalette = playerWidgets.GetWidget<ProductionPaletteWidget>("PRODUCTION_PALETTE");
|
||||||
var queueTabs = playerWidgets.GetWidget<ProductionTabsWidget>("PRODUCTION_TABS");
|
var queueTabs = playerWidgets.GetWidget<ProductionTabsWidget>("PRODUCTION_TABS");
|
||||||
|
|
||||||
|
world.ActorAdded += queueTabs.ActorChanged;
|
||||||
|
world.ActorRemoved += queueTabs.ActorChanged;
|
||||||
|
|
||||||
var queueTypes = sidebarRoot.GetWidget("PRODUCTION_TYPES");
|
var queueTypes = sidebarRoot.GetWidget("PRODUCTION_TYPES");
|
||||||
|
|
||||||
var buildingTab = queueTypes.GetWidget<ButtonWidget>("BUILDING");
|
var buildingTab = queueTypes.GetWidget<ButtonWidget>("BUILDING");
|
||||||
buildingTab.OnClick = () => queueTabs.QueueType = "Building";
|
buildingTab.OnClick = () => queueTabs.QueueType = "Building";
|
||||||
buildingTab.IsDisabled = () => !queueTabs.QueueCounts.ContainsKey("Building")
|
buildingTab.IsDisabled = () => queueTabs.Groups["Building"].Tabs.Count == 0;
|
||||||
|| queueTabs.QueueCounts["Building"] == 0;
|
|
||||||
|
|
||||||
var defenseTab = queueTypes.GetWidget<ButtonWidget>("DEFENSE");
|
var defenseTab = queueTypes.GetWidget<ButtonWidget>("DEFENSE");
|
||||||
defenseTab.OnClick = () => queueTabs.QueueType = "Defense";
|
defenseTab.OnClick = () => queueTabs.QueueType = "Defense";
|
||||||
defenseTab.IsDisabled = () => !queueTabs.QueueCounts.ContainsKey("Defense")
|
defenseTab.IsDisabled = () => queueTabs.Groups["Defense"].Tabs.Count == 0;
|
||||||
|| queueTabs.QueueCounts["Defense"] == 0;
|
|
||||||
|
|
||||||
var infantryTab = queueTypes.GetWidget<ButtonWidget>("INFANTRY");
|
var infantryTab = queueTypes.GetWidget<ButtonWidget>("INFANTRY");
|
||||||
infantryTab.OnClick = () => queueTabs.QueueType = "Infantry";
|
infantryTab.OnClick = () => queueTabs.QueueType = "Infantry";
|
||||||
infantryTab.IsDisabled = () => !queueTabs.QueueCounts.ContainsKey("Infantry")
|
infantryTab.IsDisabled = () => queueTabs.Groups["Infantry"].Tabs.Count == 0;
|
||||||
|| queueTabs.QueueCounts["Infantry"] == 0;
|
|
||||||
|
|
||||||
var vehicleTab = queueTypes.GetWidget<ButtonWidget>("VEHICLE");
|
var vehicleTab = queueTypes.GetWidget<ButtonWidget>("VEHICLE");
|
||||||
vehicleTab.OnClick = () => queueTabs.QueueType = "Vehicle";
|
vehicleTab.OnClick = () => queueTabs.QueueType = "Vehicle";
|
||||||
vehicleTab.IsDisabled = () => !queueTabs.QueueCounts.ContainsKey("Vehicle")
|
vehicleTab.IsDisabled = () => queueTabs.Groups["Vehicle"].Tabs.Count == 0;
|
||||||
|| queueTabs.QueueCounts["Vehicle"] == 0;
|
|
||||||
|
|
||||||
var aircraftTab = queueTypes.GetWidget<ButtonWidget>("AIRCRAFT");
|
var aircraftTab = queueTypes.GetWidget<ButtonWidget>("AIRCRAFT");
|
||||||
aircraftTab.OnClick = () => queueTabs.QueueType = "Aircraft";
|
aircraftTab.OnClick = () => queueTabs.QueueType = "Aircraft";
|
||||||
aircraftTab.IsDisabled = () => !queueTabs.QueueCounts.ContainsKey("Aircraft")
|
aircraftTab.IsDisabled = () => queueTabs.Groups["Aircraft"].Tabs.Count == 0;
|
||||||
|| queueTabs.QueueCounts["Aircraft"] == 0;
|
|
||||||
|
|
||||||
}
|
}
|
||||||
ingameRoot.GetWidget<ButtonWidget>("OPTIONS_BUTTON").OnClick = () =>
|
ingameRoot.GetWidget<ButtonWidget>("OPTIONS_BUTTON").OnClick = () =>
|
||||||
{
|
{
|
||||||
|
|||||||
@@ -19,6 +19,44 @@ using System;
|
|||||||
|
|
||||||
namespace OpenRA.Mods.Cnc.Widgets
|
namespace OpenRA.Mods.Cnc.Widgets
|
||||||
{
|
{
|
||||||
|
public class ProductionTab
|
||||||
|
{
|
||||||
|
public string Name;
|
||||||
|
public ProductionQueue Queue;
|
||||||
|
}
|
||||||
|
|
||||||
|
public class ProductionTabGroup
|
||||||
|
{
|
||||||
|
public List<ProductionTab> Tabs = new List<ProductionTab>();
|
||||||
|
public string Group;
|
||||||
|
public int CumulativeCount;
|
||||||
|
|
||||||
|
public void Update(IEnumerable<ProductionQueue> allQueues)
|
||||||
|
{
|
||||||
|
var queues = allQueues.Where(q => q.Info.Group == Group).ToList();
|
||||||
|
List<ProductionTab> tabs = new List<ProductionTab>();
|
||||||
|
|
||||||
|
// Remove stale queues
|
||||||
|
foreach (var t in Tabs)
|
||||||
|
{
|
||||||
|
if (!queues.Contains(t.Queue))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
tabs.Add(t);
|
||||||
|
queues.Remove(t.Queue);
|
||||||
|
}
|
||||||
|
|
||||||
|
// Add new queues
|
||||||
|
foreach (var queue in queues)
|
||||||
|
tabs.Add(new ProductionTab()
|
||||||
|
{
|
||||||
|
Name = (++CumulativeCount).ToString(),
|
||||||
|
Queue = queue
|
||||||
|
});
|
||||||
|
Tabs = tabs;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
class ProductionTabsWidget : Widget
|
class ProductionTabsWidget : Widget
|
||||||
{
|
{
|
||||||
string queueType;
|
string queueType;
|
||||||
@@ -32,9 +70,8 @@ namespace OpenRA.Mods.Cnc.Widgets
|
|||||||
{
|
{
|
||||||
queueType = value;
|
queueType = value;
|
||||||
ListOffset = 0;
|
ListOffset = 0;
|
||||||
ResetButtons();
|
|
||||||
Widget.RootWidget.GetWidget<ProductionPaletteWidget>(PaletteWidget)
|
Widget.RootWidget.GetWidget<ProductionPaletteWidget>(PaletteWidget)
|
||||||
.CurrentQueue = tabs.Keys.FirstOrDefault();
|
.CurrentQueue = Groups[queueType].Tabs[0].Queue;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -42,10 +79,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
|||||||
public float ScrollVelocity = 4f;
|
public float ScrollVelocity = 4f;
|
||||||
public int TabWidth = 30;
|
public int TabWidth = 30;
|
||||||
public int ArrowWidth = 20;
|
public int ArrowWidth = 20;
|
||||||
|
public Dictionary<string, ProductionTabGroup> Groups;
|
||||||
public ProductionQueue[] AllQueues;
|
|
||||||
public Dictionary<string, int> QueueCounts = new Dictionary<string, int>();
|
|
||||||
Dictionary<ProductionQueue, Rectangle> tabs = new Dictionary<ProductionQueue, Rectangle>();
|
|
||||||
|
|
||||||
int ContentWidth = 0;
|
int ContentWidth = 0;
|
||||||
float ListOffset = 0;
|
float ListOffset = 0;
|
||||||
@@ -53,19 +87,19 @@ namespace OpenRA.Mods.Cnc.Widgets
|
|||||||
bool rightPressed = false;
|
bool rightPressed = false;
|
||||||
Rectangle leftButtonRect;
|
Rectangle leftButtonRect;
|
||||||
Rectangle rightButtonRect;
|
Rectangle rightButtonRect;
|
||||||
|
|
||||||
readonly World world;
|
readonly World world;
|
||||||
|
|
||||||
[ObjectCreator.UseCtor]
|
[ObjectCreator.UseCtor]
|
||||||
public ProductionTabsWidget( [ObjectCreator.Param] World world )
|
public ProductionTabsWidget( [ObjectCreator.Param] World world )
|
||||||
{
|
{
|
||||||
this.world = world;
|
this.world = world;
|
||||||
|
Groups = Rules.Info.Values.SelectMany(a => a.Traits.WithInterface<ProductionQueueInfo>())
|
||||||
|
.Select(q => q.Group).Distinct().ToDictionary(g => g, g => new ProductionTabGroup() { Group = g });
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void DrawInner()
|
public override void DrawInner()
|
||||||
{
|
{
|
||||||
var rb = RenderBounds;
|
var rb = RenderBounds;
|
||||||
|
|
||||||
leftButtonRect = new Rectangle(rb.X, rb.Y, ArrowWidth, rb.Height);
|
leftButtonRect = new Rectangle(rb.X, rb.Y, ArrowWidth, rb.Height);
|
||||||
rightButtonRect = new Rectangle(rb.Right - ArrowWidth, rb.Y, ArrowWidth, rb.Height);
|
rightButtonRect = new Rectangle(rb.Right - ArrowWidth, rb.Y, ArrowWidth, rb.Height);
|
||||||
|
|
||||||
@@ -83,21 +117,24 @@ namespace OpenRA.Mods.Cnc.Widgets
|
|||||||
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", rightPressed || rightDisabled ? "down_pressed" : "down_arrow"),
|
WidgetUtils.DrawRGBA(ChromeProvider.GetImage("scrollbar", rightPressed || rightDisabled ? "down_pressed" : "down_arrow"),
|
||||||
new float2(rightButtonRect.Left + 2, rightButtonRect.Top + 2));
|
new float2(rightButtonRect.Left + 2, rightButtonRect.Top + 2));
|
||||||
|
|
||||||
|
if (QueueType == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
// Draw tab buttons
|
||||||
Game.Renderer.EnableScissor(leftButtonRect.Right, rb.Y + 1, rightButtonRect.Left - leftButtonRect.Right - 1, rb.Height);
|
Game.Renderer.EnableScissor(leftButtonRect.Right, rb.Y + 1, rightButtonRect.Left - leftButtonRect.Right - 1, rb.Height);
|
||||||
|
|
||||||
var palette = Widget.RootWidget.GetWidget<ProductionPaletteWidget>(PaletteWidget);
|
var palette = Widget.RootWidget.GetWidget<ProductionPaletteWidget>(PaletteWidget);
|
||||||
// TODO: Draw children buttons
|
var origin = new int2(leftButtonRect.Right - 1 + (int)ListOffset, leftButtonRect.Y);
|
||||||
var i = 1;
|
SpriteFont font = Game.Renderer.Fonts["TinyBold"];
|
||||||
foreach (var tab in tabs)
|
ContentWidth = 0;
|
||||||
|
foreach (var tab in Groups[QueueType].Tabs)
|
||||||
{
|
{
|
||||||
ButtonWidget.DrawBackground("button", tab.Value, false, tab.Key == palette.CurrentQueue, tab.Value.Contains(Viewport.LastMousePos));
|
var rect = new Rectangle(origin.X + ContentWidth, origin.Y, TabWidth, rb.Height);
|
||||||
|
ButtonWidget.DrawBackground("button", rect, false, tab.Queue == palette.CurrentQueue, rect.Contains(Viewport.LastMousePos));
|
||||||
|
ContentWidth += TabWidth - 1;
|
||||||
|
|
||||||
SpriteFont font = Game.Renderer.Fonts["TinyBold"];
|
int2 textSize = font.Measure(tab.Name);
|
||||||
var text = i.ToString();
|
int2 position = new int2(rect.X + (rect.Width - textSize.X)/2, rect.Y + (rect.Height - textSize.Y)/2);
|
||||||
int2 textSize = font.Measure(text);
|
font.DrawTextWithContrast(tab.Name, position, Color.White, Color.Black, 1);
|
||||||
int2 position = new int2(tab.Value.X + (tab.Value.Width - textSize.X)/2, tab.Value.Y + (tab.Value.Height - textSize.Y)/2);
|
|
||||||
font.DrawTextWithContrast(text, position, Color.White, Color.Black, 1);
|
|
||||||
i++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
Game.Renderer.DisableScissor();
|
Game.Renderer.DisableScissor();
|
||||||
@@ -109,18 +146,16 @@ namespace OpenRA.Mods.Cnc.Widgets
|
|||||||
ListOffset = Math.Min(0,Math.Max(Bounds.Width - rightButtonRect.Width - leftButtonRect.Width - ContentWidth, ListOffset));
|
ListOffset = Math.Min(0,Math.Max(Bounds.Width - rightButtonRect.Width - leftButtonRect.Width - ContentWidth, ListOffset));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ResetButtons()
|
// Is added to world.ActorAdded by the SidebarLogic handler
|
||||||
|
public void ActorChanged(Actor a)
|
||||||
{
|
{
|
||||||
tabs.Clear();
|
if (a.HasTrait<ProductionQueue>())
|
||||||
ContentWidth = 0;
|
|
||||||
var rb = RenderBounds;
|
|
||||||
var origin = new int2(leftButtonRect.Right - 1 + (int)ListOffset, leftButtonRect.Y);
|
|
||||||
|
|
||||||
foreach (var queue in AllQueues.Where(q => q.Info.Type == QueueType))
|
|
||||||
{
|
{
|
||||||
var rect = new Rectangle(origin.X + ContentWidth, origin.Y, TabWidth, rb.Height);
|
var allQueues = world.ActorsWithTrait<ProductionQueue>()
|
||||||
tabs.Add(queue, rect);
|
.Where(p => p.Actor.Owner == world.LocalPlayer && p.Actor.IsInWorld)
|
||||||
ContentWidth += TabWidth - 1;
|
.Select(p => p.Trait).ToArray();
|
||||||
|
foreach (var g in Groups.Values)
|
||||||
|
g.Update(allQueues);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -128,15 +163,6 @@ namespace OpenRA.Mods.Cnc.Widgets
|
|||||||
{
|
{
|
||||||
if (leftPressed) Scroll(1);
|
if (leftPressed) Scroll(1);
|
||||||
if (rightPressed) Scroll(-1);
|
if (rightPressed) Scroll(-1);
|
||||||
|
|
||||||
AllQueues = world.ActorsWithTrait<ProductionQueue>()
|
|
||||||
.Where(p => p.Actor.Owner == world.LocalPlayer)
|
|
||||||
.Select(p => p.Trait).ToArray();
|
|
||||||
|
|
||||||
QueueCounts = AllQueues.Select(q => q.Info.Type).Distinct()
|
|
||||||
.ToDictionary(t => t, t => AllQueues.Count(q => q.Info.Type == t));
|
|
||||||
|
|
||||||
ResetButtons();
|
|
||||||
base.Tick();
|
base.Tick();
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -145,7 +171,7 @@ namespace OpenRA.Mods.Cnc.Widgets
|
|||||||
leftPressed = rightPressed = false;
|
leftPressed = rightPressed = false;
|
||||||
return base.LoseFocus(mi);
|
return base.LoseFocus(mi);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool HandleMouseInput(MouseInput mi)
|
public override bool HandleMouseInput(MouseInput mi)
|
||||||
{
|
{
|
||||||
if (mi.Button == MouseButton.WheelDown)
|
if (mi.Button == MouseButton.WheelDown)
|
||||||
@@ -175,16 +201,16 @@ namespace OpenRA.Mods.Cnc.Widgets
|
|||||||
leftPressed = leftButtonRect.Contains(mi.Location.X, mi.Location.Y);
|
leftPressed = leftButtonRect.Contains(mi.Location.X, mi.Location.Y);
|
||||||
rightPressed = rightButtonRect.Contains(mi.Location.X, mi.Location.Y);
|
rightPressed = rightButtonRect.Contains(mi.Location.X, mi.Location.Y);
|
||||||
|
|
||||||
var queue = tabs.Where(a => a.Value.Contains(mi.Location))
|
// Check production tabs
|
||||||
.Select(a => a.Key).FirstOrDefault();
|
var offsetloc = mi.Location - new int2(leftButtonRect.Right - 1 + (int)ListOffset, leftButtonRect.Y);
|
||||||
|
if (offsetloc.X > 0 && offsetloc.X <= ContentWidth)
|
||||||
if (queue != null)
|
|
||||||
{
|
{
|
||||||
var palette = Widget.RootWidget.GetWidget<ProductionPaletteWidget>(PaletteWidget);
|
var palette = Widget.RootWidget.GetWidget<ProductionPaletteWidget>(PaletteWidget);
|
||||||
palette.CurrentQueue = queue;
|
palette.CurrentQueue = Groups[QueueType].Tabs[offsetloc.X/(TabWidth - 1)].Queue;
|
||||||
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
return (leftPressed || rightPressed || queue != null);
|
return (leftPressed || rightPressed);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -19,6 +19,8 @@ namespace OpenRA.Mods.RA
|
|||||||
public class ProductionQueueInfo : ITraitInfo
|
public class ProductionQueueInfo : ITraitInfo
|
||||||
{
|
{
|
||||||
public readonly string Type = null;
|
public readonly string Type = null;
|
||||||
|
public readonly string Group = null;
|
||||||
|
|
||||||
public float BuildSpeed = 0.4f;
|
public float BuildSpeed = 0.4f;
|
||||||
public readonly int LowPowerSlowdown = 3;
|
public readonly int LowPowerSlowdown = 3;
|
||||||
|
|
||||||
|
|||||||
@@ -25,6 +25,7 @@ FACT:
|
|||||||
Facing: 108
|
Facing: 108
|
||||||
ProductionQueue@Building:
|
ProductionQueue@Building:
|
||||||
Type: Building
|
Type: Building
|
||||||
|
Group: Building
|
||||||
BuildSpeed: .4
|
BuildSpeed: .4
|
||||||
LowPowerSlowdown: 3
|
LowPowerSlowdown: 3
|
||||||
QueuedAudio: bldging1.aud
|
QueuedAudio: bldging1.aud
|
||||||
@@ -33,6 +34,7 @@ FACT:
|
|||||||
CancelledAudio: cancel1.aud
|
CancelledAudio: cancel1.aud
|
||||||
ProductionQueue@Defense:
|
ProductionQueue@Defense:
|
||||||
Type: Defense
|
Type: Defense
|
||||||
|
Group: Defense
|
||||||
BuildSpeed: .4
|
BuildSpeed: .4
|
||||||
LowPowerSlowdown: 3
|
LowPowerSlowdown: 3
|
||||||
QueuedAudio: bldging1.aud
|
QueuedAudio: bldging1.aud
|
||||||
@@ -165,6 +167,7 @@ PYLE:
|
|||||||
Produces: Infantry
|
Produces: Infantry
|
||||||
ProductionQueue:
|
ProductionQueue:
|
||||||
Type: Infantry
|
Type: Infantry
|
||||||
|
Group: Infantry
|
||||||
BuildSpeed: .4
|
BuildSpeed: .4
|
||||||
LowPowerSlowdown: 3
|
LowPowerSlowdown: 3
|
||||||
QueuedAudio: bldging1.aud
|
QueuedAudio: bldging1.aud
|
||||||
@@ -204,6 +207,7 @@ HAND:
|
|||||||
Produces: Infantry
|
Produces: Infantry
|
||||||
ProductionQueue:
|
ProductionQueue:
|
||||||
Type: Infantry
|
Type: Infantry
|
||||||
|
Group: Infantry
|
||||||
BuildSpeed: .4
|
BuildSpeed: .4
|
||||||
LowPowerSlowdown: 3
|
LowPowerSlowdown: 3
|
||||||
QueuedAudio: bldging1.aud
|
QueuedAudio: bldging1.aud
|
||||||
@@ -245,6 +249,7 @@ AFLD:
|
|||||||
Produces: Vehicle
|
Produces: Vehicle
|
||||||
ProductionQueue:
|
ProductionQueue:
|
||||||
Type: Vehicle
|
Type: Vehicle
|
||||||
|
Group: Vehicle
|
||||||
BuildSpeed: .4
|
BuildSpeed: .4
|
||||||
LowPowerSlowdown: 3
|
LowPowerSlowdown: 3
|
||||||
QueuedAudio: bldging1.aud
|
QueuedAudio: bldging1.aud
|
||||||
@@ -287,6 +292,7 @@ WEAP:
|
|||||||
Produces: Vehicle
|
Produces: Vehicle
|
||||||
ProductionQueue:
|
ProductionQueue:
|
||||||
Type: Vehicle
|
Type: Vehicle
|
||||||
|
Group: Vehicle
|
||||||
BuildSpeed: .4
|
BuildSpeed: .4
|
||||||
LowPowerSlowdown: 3
|
LowPowerSlowdown: 3
|
||||||
QueuedAudio: bldging1.aud
|
QueuedAudio: bldging1.aud
|
||||||
@@ -413,6 +419,7 @@ HPAD:
|
|||||||
RallyPoint:
|
RallyPoint:
|
||||||
ProductionQueue:
|
ProductionQueue:
|
||||||
Type: Plane
|
Type: Plane
|
||||||
|
Group: Aircraft
|
||||||
BuildSpeed: .4
|
BuildSpeed: .4
|
||||||
LowPowerSlowdown: 3
|
LowPowerSlowdown: 3
|
||||||
QueuedAudio: bldging1.aud
|
QueuedAudio: bldging1.aud
|
||||||
|
|||||||
@@ -53,6 +53,7 @@ BIO:
|
|||||||
Produces: Biolab
|
Produces: Biolab
|
||||||
ProductionQueue:
|
ProductionQueue:
|
||||||
Type: Biolab
|
Type: Biolab
|
||||||
|
Group: Infantry
|
||||||
BuildSpeed: .4
|
BuildSpeed: .4
|
||||||
LowPowerSlowdown: 3
|
LowPowerSlowdown: 3
|
||||||
QueuedAudio: bldging1.aud
|
QueuedAudio: bldging1.aud
|
||||||
|
|||||||
Reference in New Issue
Block a user