diff --git a/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs index 5de24f8886..392f9b0b18 100644 --- a/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs +++ b/OpenRA.Mods.RA/Widgets/Logic/ObserverStatsLogic.cs @@ -36,10 +36,7 @@ namespace OpenRA.Mods.RA.Widgets.Logic var players = world.Players.Where(p => !p.NonCombatant); widget.Height = (200 + (Math.Min(8, players.Count()) * 25)).ToString(); - var args = new WidgetArgs(); - widget.Initialize(args); - widget.Get("BACKGROUND").Initialize(args); - widget.Get("PLAYERS").Initialize(args); + Initialize(widget, widget.Get("BACKGROUND"), widget.Get("PLAYERS")); var teams = players.GroupBy(p => (world.LobbyInfo.ClientWithIndex(p.ClientIndex) ?? new Session.Client()).Team).OrderBy(g => g.Key); foreach (var t in teams) @@ -97,6 +94,15 @@ namespace OpenRA.Mods.RA.Widgets.Logic } } + static void Initialize(params Widget[] widgets) + { + var args = new WidgetArgs(); + foreach (var widget in widgets) + { + widget.Initialize(args); + } + } + static Color GetPowerColor(PowerState state) { if (state == PowerState.Critical) return Color.Red; diff --git a/OpenRA.Mods.RA/Widgets/ObserverBuildIconsWidget.cs b/OpenRA.Mods.RA/Widgets/ObserverBuildIconsWidget.cs index 1dceac570e..d66fa78714 100644 --- a/OpenRA.Mods.RA/Widgets/ObserverBuildIconsWidget.cs +++ b/OpenRA.Mods.RA/Widgets/ObserverBuildIconsWidget.cs @@ -23,6 +23,7 @@ namespace OpenRA.Mods.RA.Widgets Dictionary iconSprites; World world; WorldRenderer worldRenderer; + Dictionary clocks; [ObjectCreator.UseCtor] public ObserverBuildIconsWidget(World world, WorldRenderer worldRenderer) @@ -34,6 +35,7 @@ namespace OpenRA.Mods.RA.Widgets u => Game.modData.SpriteLoader.LoadAllSprites(u.Traits.Get().Icon ?? (u.Name + "icon"))[0]); this.world = world; this.worldRenderer = worldRenderer; + clocks = new Dictionary(); } protected ObserverBuildIconsWidget(ObserverBuildIconsWidget other) @@ -43,6 +45,7 @@ namespace OpenRA.Mods.RA.Widgets iconSprites = other.iconSprites; world = other.world; worldRenderer = other.worldRenderer; + clocks = other.clocks; } public override void Draw() @@ -56,19 +59,46 @@ namespace OpenRA.Mods.RA.Widgets .Where(a => a.Actor.Owner == player) .Select((a, i) => new { a.Trait, i }); foreach (var queue in queues) + { + if (!clocks.ContainsKey(queue.Trait)) + { + clocks.Add(queue.Trait, new Animation("clock")); + } + } + foreach (var queue in queues) { var item = queue.Trait.CurrentItem(); if (item == null) { - return; + continue; } var sprite = iconSprites[item.Item]; var size = sprite.size / new float2(2, 2); var location = new float2(RenderBounds.Location) + new float2(queue.i * (int)size.Length, 0); WidgetUtils.DrawSHP(sprite, location, worldRenderer, size); + + var clock = clocks[queue.Trait]; + clock.PlayFetchIndex("idle", + () => (item.TotalTime - item.RemainingTime) + * (clock.CurrentSequence.Length - 1) / item.TotalTime); + clock.Tick(); + WidgetUtils.DrawSHP(clock.Image, location, worldRenderer, size); + + var tiny = Game.Renderer.Fonts["Tiny"]; + var text = GetOverlayForItem(item); + tiny.DrawTextWithContrast(text, + location + new float2(16, 16) - new float2(tiny.Measure(text).X / 2, 0), + Color.White, Color.Black, 1); } } + static string GetOverlayForItem(ProductionItem item) + { + if (item.Paused) return "ON HOLD"; + if (item.Done) return "READY"; + return WidgetUtils.FormatTime(item.RemainingTimeActual); + } + public override Widget Clone() { return new ObserverBuildIconsWidget(this); diff --git a/mods/ra/chrome/ingame.yaml b/mods/ra/chrome/ingame.yaml index c5d706e4ed..7f18d17eaf 100644 --- a/mods/ra/chrome/ingame.yaml +++ b/mods/ra/chrome/ingame.yaml @@ -490,10 +490,10 @@ Container@OBSERVER_ROOT: Height:25 Children: Image@FACTION_FLAG: - X:15 + X:20 Y:5 - Width:40 - Height:PARENT_BOTTOM + Width:35 + Height:PARENT_BOTTOM-5 ImageName:random ImageCollection:flags Label@PLAYER: