From a7d6f717c460c3c0783cc210ae645cea9007c444 Mon Sep 17 00:00:00 2001 From: Paul Chote Date: Wed, 12 Mar 2014 12:23:24 +1300 Subject: [PATCH] Overhaul ingame timer displays. Fixes #3062. --- OpenRA.Game/Game.cs | 4 +- OpenRA.Game/OpenRA.Game.csproj | 1 - OpenRA.Game/Widgets/TimerWidget.cs | 36 --------------- OpenRA.Game/World.cs | 4 ++ OpenRA.Mods.RA/OpenRA.Mods.RA.csproj | 2 + .../Widgets/Logic/GameTimerLogic.cs | 46 +++++++++++++++++++ mods/cnc/chrome/ingame.yaml | 24 ++++++++-- mods/d2k/chrome/ingame.yaml | 24 ++++++++-- mods/ra/chrome/ingame.yaml | 24 ++++++++-- 9 files changed, 112 insertions(+), 53 deletions(-) delete mode 100644 OpenRA.Game/Widgets/TimerWidget.cs create mode 100644 OpenRA.Mods.RA/Widgets/Logic/GameTimerLogic.cs diff --git a/OpenRA.Game/Game.cs b/OpenRA.Game/Game.cs index be44b976a0..f0b61be1e6 100644 --- a/OpenRA.Game/Game.cs +++ b/OpenRA.Game/Game.cs @@ -73,7 +73,8 @@ namespace OpenRA public static int RenderFrame = 0; public static int NetFrameNumber { get { return orderManager.NetFrameNumber; } } public static int LocalTick { get { return orderManager.LocalFrameNumber; } } - public const int NetTickScale = 3; // 120ms net tick for 40ms local tick + public const int NetTickScale = 3; // 120ms net tick for 40ms local tick + public const int Timestep = 40; public static event Action ConnectionStateChanged = _ => { }; static ConnectionState lastConnectionState = ConnectionState.PreConnecting; @@ -224,6 +225,7 @@ namespace OpenRA var map = modData.PrepareMap(mapUID); orderManager.world = new World(modData.Manifest, map, orderManager, isShellmap); + orderManager.world.Timestep = Timestep; worldRenderer = new WorldRenderer(orderManager.world); orderManager.world.LoadComplete(worldRenderer); diff --git a/OpenRA.Game/OpenRA.Game.csproj b/OpenRA.Game/OpenRA.Game.csproj index fc228d25dd..b0970f43d1 100644 --- a/OpenRA.Game/OpenRA.Game.csproj +++ b/OpenRA.Game/OpenRA.Game.csproj @@ -200,7 +200,6 @@ - diff --git a/OpenRA.Game/Widgets/TimerWidget.cs b/OpenRA.Game/Widgets/TimerWidget.cs deleted file mode 100644 index 9a63adf860..0000000000 --- a/OpenRA.Game/Widgets/TimerWidget.cs +++ /dev/null @@ -1,36 +0,0 @@ -#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; -using System.Drawing; -using OpenRA.FileFormats; -using OpenRA.Graphics; - -namespace OpenRA.Widgets -{ - public class TimerWidget : LabelWidget - { - public override void Draw() - { - var font = Game.Renderer.Fonts[Font]; - var rb = RenderBounds; - var color = GetColor(); - var contrast = GetContrastColor(); - - var s = WidgetUtils.FormatTime(Game.LocalTick) + (Game.orderManager.world.Paused?" (paused)":""); - var pos = new float2(rb.Left - font.Measure(s).X / 2, rb.Top); - if (Contrast) - font.DrawTextWithContrast(s, pos, color, contrast, 1); - else - font.DrawText(s, pos, color); - } - } -} - diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index 462fe8e82d..2c4e170570 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -31,6 +31,7 @@ namespace OpenRA Queue> frameEndActions = new Queue>(); public int FrameNumber { get { return orderManager.LocalFrameNumber; } } + public int Timestep; internal readonly OrderManager orderManager; public Session LobbyInfo { get { return orderManager.LobbyInfo; } } @@ -190,6 +191,7 @@ namespace OpenRA public bool PredictedPaused { get; internal set; } public bool PauseStateLocked { get; set; } public bool IsShellmap = false; + public int WorldTick { get; private set; } public void SetPauseState(bool paused) { @@ -209,6 +211,8 @@ namespace OpenRA { if (!Paused && (!IsShellmap || Game.Settings.Game.ShowShellmap)) { + WorldTick++; + using (new PerfSample("tick_idle")) foreach (var ni in ActorsWithTrait()) if (ni.Actor.IsIdle) diff --git a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj index 0d30d9f469..4e19ed923b 100644 --- a/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj +++ b/OpenRA.Mods.RA/OpenRA.Mods.RA.csproj @@ -479,6 +479,8 @@ + + diff --git a/OpenRA.Mods.RA/Widgets/Logic/GameTimerLogic.cs b/OpenRA.Mods.RA/Widgets/Logic/GameTimerLogic.cs new file mode 100644 index 0000000000..a2e6a87b1f --- /dev/null +++ b/OpenRA.Mods.RA/Widgets/Logic/GameTimerLogic.cs @@ -0,0 +1,46 @@ +#region Copyright & License Information +/* + * Copyright 2007-2014 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; +using OpenRA.Network; +using OpenRA.Widgets; + +namespace OpenRA.Mods.RA.Widgets.Logic +{ + public class GameTimerLogic + { + [ObjectCreator.UseCtor] + public GameTimerLogic(Widget widget, OrderManager orderManager, World world) + { + var timer = widget.GetOrNull("GAME_TIMER"); + if (timer != null) + timer.GetText = () => WidgetUtils.FormatTime(world.WorldTick); + + var status = widget.GetOrNull("GAME_TIMER_STATUS"); + if (status != null) + { + // Blink the status line + status.IsVisible = () => (world.Paused || world.Timestep != Game.Timestep) + && orderManager.LocalFrameNumber / 25 % 2 == 0; + + status.GetText = () => + { + if (world.Paused || world.Timestep == 0) + return "Paused"; + + if (world.Timestep == 1) + return "Max Speed"; + + return "{0:F1}x Speed".F(Game.Timestep * 1f / world.Timestep); + }; + } + } + } +} diff --git a/mods/cnc/chrome/ingame.yaml b/mods/cnc/chrome/ingame.yaml index 3e6182850b..719d7e8a8f 100644 --- a/mods/cnc/chrome/ingame.yaml +++ b/mods/cnc/chrome/ingame.yaml @@ -3,11 +3,25 @@ Container@INGAME_ROOT: Children: LogicTicker@DISCONNECT_WATCHER: Logic:DisconnectWatcherLogic - Timer@GAME_TIMER: - X: WINDOW_RIGHT/2 - Y: 0 - Font: Title - Contrast: true + Container@GAME_TIMER_BLOCK: + Logic:GameTimerLogic + X:WINDOW_RIGHT/2 - WIDTH + Width:100 + Height:55 + Children: + Label@GAME_TIMER: + Width:PARENT_RIGHT + Height:30 + Align:Center + Font:Title + Contrast:true + Label@GAME_TIMER_STATUS: + Y:35 + Width:PARENT_RIGHT + Height:15 + Align:Center + Font:Bold + Contrast:true StrategicProgress@STRATEGIC_PROGRESS: X: WINDOW_RIGHT/2 Y: 40 diff --git a/mods/d2k/chrome/ingame.yaml b/mods/d2k/chrome/ingame.yaml index 177cce6a79..191fa3280c 100644 --- a/mods/d2k/chrome/ingame.yaml +++ b/mods/d2k/chrome/ingame.yaml @@ -19,11 +19,25 @@ Container@INGAME_ROOT: Y:0 Width:WINDOW_RIGHT Height:WINDOW_BOTTOM - Timer@GAME_TIMER: - X: WINDOW_RIGHT/2 - Y: 0 - Font: Title - Contrast: true + Container@GAME_TIMER_BLOCK: + Logic:GameTimerLogic + X:WINDOW_RIGHT/2 - WIDTH + Width:100 + Height:55 + Children: + Label@GAME_TIMER: + Width:PARENT_RIGHT + Height:30 + Align:Center + Font:Title + Contrast:true + Label@GAME_TIMER_STATUS: + Y:32 + Width:PARENT_RIGHT + Height:15 + Align:Center + Font:Bold + Contrast:true StrategicProgress@STRATEGIC_PROGRESS: X: WINDOW_RIGHT/2 Y: 40 diff --git a/mods/ra/chrome/ingame.yaml b/mods/ra/chrome/ingame.yaml index 2700640889..c16e160d3e 100644 --- a/mods/ra/chrome/ingame.yaml +++ b/mods/ra/chrome/ingame.yaml @@ -19,11 +19,25 @@ Container@INGAME_ROOT: Y:0 Width:WINDOW_RIGHT Height:WINDOW_BOTTOM - Timer@GAME_TIMER: - X: WINDOW_RIGHT/2 - Y: 0-10 - Font: Title - Contrast: true + Container@GAME_TIMER_BLOCK: + Logic:GameTimerLogic + X:WINDOW_RIGHT/2 - WIDTH + Width:100 + Height:55 + Children: + Label@GAME_TIMER: + Width:PARENT_RIGHT + Height:15 + Align:Center + Font:Title + Contrast:true + Label@GAME_TIMER_STATUS: + Y:35 + Width:PARENT_RIGHT + Height:15 + Align:Center + Font:Bold + Contrast:true StrategicProgress@STRATEGIC_PROGRESS: X: WINDOW_RIGHT/2 Y: 40