diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
index 17ab4884c0..7073279bc8 100644
--- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
+++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj
@@ -410,6 +410,7 @@
+
diff --git a/OpenRA.Mods.RA/SupportPowers/SupportPower.cs b/OpenRA.Mods.RA/SupportPowers/SupportPower.cs
index 8ae0f094b2..e7fecd849e 100755
--- a/OpenRA.Mods.RA/SupportPowers/SupportPower.cs
+++ b/OpenRA.Mods.RA/SupportPowers/SupportPower.cs
@@ -28,6 +28,8 @@ namespace OpenRA.Mods.RA
public readonly string SelectTargetSound = null;
public readonly string LaunchSound = null;
+ public readonly bool DisplayTimer = false;
+
public readonly string OrderName;
public abstract object Create(ActorInitializer init);
diff --git a/OpenRA.Mods.RA/Widgets/SupportPowerTimerWidget.cs b/OpenRA.Mods.RA/Widgets/SupportPowerTimerWidget.cs
new file mode 100644
index 0000000000..f8465d6529
--- /dev/null
+++ b/OpenRA.Mods.RA/Widgets/SupportPowerTimerWidget.cs
@@ -0,0 +1,65 @@
+#region Copyright & License Information
+/*
+ * Copyright 2007-2013 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. For more information,
+ * see COPYING.
+ */
+#endregion
+
+using System.Collections.Generic;
+using System.Drawing;
+using System.Linq;
+using OpenRA.FileFormats;
+using OpenRA.Traits;
+using OpenRA.Widgets;
+
+namespace OpenRA.Mods.RA.Widgets
+{
+ public class SupportPowerTimerWidget : Widget
+ {
+ public readonly string Font = "Bold";
+ public readonly string Format = "{0}: {1}";
+ public readonly TimerOrder Order = TimerOrder.Descending;
+
+ readonly IEnumerable powers;
+ Pair[] texts;
+
+ [ObjectCreator.UseCtor]
+ public SupportPowerTimerWidget(World world)
+ {
+ powers = world.ActorsWithTrait()
+ .Where(p => !p.Actor.IsDead() && !p.Actor.Owner.NonCombatant)
+ .SelectMany(s => s.Trait.Powers.Values)
+ .Where(p => p.Instances.Any() && p.Info.DisplayTimer && !p.Disabled);
+ }
+
+ public override void Tick()
+ {
+ texts = powers.Select(p =>
+ {
+ var time = WidgetUtils.FormatTime(p.RemainingTime, false);
+ var text = Format.F(p.Info.Description, time);
+ var color = !p.Ready || Game.LocalTick % 50 < 25 ? p.Instances[0].self.Owner.Color.RGB : Color.White;
+ return Pair.New(text, color);
+ }).ToArray();
+ }
+
+ public override void Draw()
+ {
+ if (!IsVisible() || texts == null)
+ return;
+
+ var y = 0;
+ foreach (var t in texts)
+ {
+ var font = Game.Renderer.Fonts[Font];
+ font.DrawTextWithContrast(t.First, new float2(Bounds.Location) + new float2(0, y), t.Second, Color.Black, 1);
+ y += (font.Measure(t.First).Y + 5) * (int)Order;
+ }
+ }
+
+ public enum TimerOrder { Ascending = -1, Descending = 1 }
+ }
+}
diff --git a/mods/ra/chrome/ingame.yaml b/mods/ra/chrome/ingame.yaml
index 761cc1b247..52a556b481 100644
--- a/mods/ra/chrome/ingame.yaml
+++ b/mods/ra/chrome/ingame.yaml
@@ -52,6 +52,10 @@ Container@INGAME_ROOT:
Width:170
Height:40
TooltipContainer@TOOLTIP_CONTAINER:
+ SupportPowerTimer@SUPPORT_POWER_TIMER:
+ X:15
+ Y:WINDOW_BOTTOM-30
+ Order:Ascending
Container@PLAYER_WIDGETS:
Children:
diff --git a/mods/ra/rules/structures.yaml b/mods/ra/rules/structures.yaml
index 8b8eba74fe..8dd771b30a 100644
--- a/mods/ra/rules/structures.yaml
+++ b/mods/ra/rules/structures.yaml
@@ -35,6 +35,7 @@ MSLO:
LaunchSound: alaunch1.aud
MissileWeapon: atomic
SpawnOffset: 0,427,0
+ DisplayTimer: True
CanPowerDown:
RequiresPower:
SupportPowerChargeBar:
@@ -849,9 +850,10 @@ ATEK:
OneShot: yes
ChargeTime: 480
Description: GPS Satellite
- LongDesc: Reveals the entire map
+ LongDesc: Reveals the entire map.
RevealDelay: 15
LaunchSound: satlnch1.aud
+ DisplayTimer: True
SupportPowerChargeBar:
WEAP: