Update UI timers for variable game speed.

This commit is contained in:
Paul Chote
2015-09-03 22:23:37 +01:00
parent 301b698c81
commit 1109ec53d1
12 changed files with 47 additions and 37 deletions

View File

@@ -158,14 +158,14 @@ namespace OpenRA.Widgets
DrawRGBA(cornerBottomRight, new float2(bounds.Right - cornerBottomRight.Size.X, bounds.Bottom - cornerBottomRight.Size.Y));
}
public static string FormatTime(int ticks)
public static string FormatTime(int ticks, int timestep)
{
return FormatTime(ticks, true);
return FormatTime(ticks, true, timestep);
}
public static string FormatTime(int ticks, bool leadingMinuteZero)
public static string FormatTime(int ticks, bool leadingMinuteZero, int timestep)
{
var seconds = (int)Math.Ceiling(ticks / 25f);
var seconds = (int)Math.Ceiling(ticks * timestep / 1000f);
return FormatTimeSeconds(seconds, leadingMinuteZero);
}

View File

@@ -19,7 +19,12 @@ namespace OpenRA.Mods.Common.Scripting
[ScriptGlobal("Utils")]
public class UtilsGlobal : ScriptGlobal
{
public UtilsGlobal(ScriptContext context) : base(context) { }
readonly World world;
public UtilsGlobal(ScriptContext context)
: base(context)
{
world = context.World;
}
[Desc("Calls a function on every element in a collection.")]
public void Do(LuaValue[] collection, LuaFunction func)
@@ -101,7 +106,7 @@ namespace OpenRA.Mods.Common.Scripting
[Desc("Returns the ticks formatted to HH:MM:SS.")]
public string FormatTime(int ticks, bool leadingMinuteZero = true)
{
return WidgetUtils.FormatTime(ticks, leadingMinuteZero);
return WidgetUtils.FormatTime(ticks, leadingMinuteZero, world.Timestep);
}
}
}

View File

@@ -44,7 +44,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (status == null && shouldShowStatus())
return statusText();
return WidgetUtils.FormatTime(world.WorldTick);
return WidgetUtils.FormatTime(world.WorldTick, world.Timestep);
};
}

View File

@@ -20,7 +20,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public class ProductionTooltipLogic
{
[ObjectCreator.UseCtor]
public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, ProductionPaletteWidget palette)
public ProductionTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, ProductionPaletteWidget palette, World world)
{
var mapRules = palette.World.Map.Rules;
var pm = palette.World.LocalPlayer.PlayerActor.Trait<PowerManager>();
@@ -83,7 +83,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var lowpower = pm.PowerState != PowerState.Normal;
var time = palette.CurrentQueue == null ? 0 : palette.CurrentQueue.GetBuildTime(actor.Name)
* (lowpower ? palette.CurrentQueue.Info.LowPowerSlowdown : 1);
var timeString = WidgetUtils.FormatTime(time);
var timeString = WidgetUtils.FormatTime(time, world.Timestep);
timeLabel.GetText = () => timeString;
timeLabel.GetColor = () => lowpower ? Color.Red : Color.White;

View File

@@ -8,6 +8,7 @@
*/
#endregion
using System;
using System.Collections.Generic;
using OpenRA.Network;
using OpenRA.Widgets;
@@ -18,12 +19,12 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
enum PlaybackSpeed { Regular, Slow, Fast, Maximum }
readonly Dictionary<PlaybackSpeed, int> timesteps = new Dictionary<PlaybackSpeed, int>()
readonly Dictionary<PlaybackSpeed, float> multipliers = new Dictionary<PlaybackSpeed, float>()
{
{ PlaybackSpeed.Regular, Game.Timestep },
{ PlaybackSpeed.Slow, Game.Timestep * 2 },
{ PlaybackSpeed.Fast, Game.Timestep / 2 },
{ PlaybackSpeed.Maximum, 1 },
{ PlaybackSpeed.Regular, 1 },
{ PlaybackSpeed.Slow, 2 },
{ PlaybackSpeed.Fast, 0.5f },
{ PlaybackSpeed.Maximum, 0.001f },
};
[ObjectCreator.UseCtor]
@@ -41,6 +42,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
container.Visible = true;
var speed = PlaybackSpeed.Regular;
var originalTimestep = world.Timestep;
var pauseButton = widget.Get<ButtonWidget>("BUTTON_PAUSE");
pauseButton.IsVisible = () => world.Timestep != 0 && orderManager.NetFrameNumber < replayNetTicks;
@@ -48,7 +50,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
var playButton = widget.Get<ButtonWidget>("BUTTON_PLAY");
playButton.IsVisible = () => world.Timestep == 0 || orderManager.NetFrameNumber >= replayNetTicks;
playButton.OnClick = () => world.Timestep = timesteps[speed];
playButton.OnClick = () => world.Timestep = (int)Math.Ceiling(originalTimestep * multipliers[speed]);
playButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks;
var slowButton = widget.Get<ButtonWidget>("BUTTON_SLOW");
@@ -58,7 +60,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
speed = PlaybackSpeed.Slow;
if (world.Timestep != 0)
world.Timestep = timesteps[speed];
world.Timestep = (int)Math.Ceiling(originalTimestep * multipliers[speed]);
};
var normalSpeedButton = widget.Get<ButtonWidget>("BUTTON_REGULAR");
@@ -68,7 +70,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
speed = PlaybackSpeed.Regular;
if (world.Timestep != 0)
world.Timestep = timesteps[speed];
world.Timestep = (int)Math.Ceiling(originalTimestep * multipliers[speed]);
};
var fastButton = widget.Get<ButtonWidget>("BUTTON_FAST");
@@ -78,7 +80,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
speed = PlaybackSpeed.Fast;
if (world.Timestep != 0)
world.Timestep = timesteps[speed];
world.Timestep = (int)Math.Ceiling(originalTimestep * multipliers[speed]);
};
var maximumButton = widget.Get<ButtonWidget>("BUTTON_MAXIMUM");
@@ -88,7 +90,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
{
speed = PlaybackSpeed.Maximum;
if (world.Timestep != 0)
world.Timestep = timesteps[speed];
world.Timestep = (int)Math.Ceiling(originalTimestep * multipliers[speed]);
};
}
}

View File

@@ -17,7 +17,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic
public class SupportPowerTooltipLogic
{
[ObjectCreator.UseCtor]
public SupportPowerTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, SupportPowersWidget palette)
public SupportPowerTooltipLogic(Widget widget, TooltipContainerWidget tooltipContainer, SupportPowersWidget palette, World world)
{
widget.IsVisible = () => palette.TooltipIcon != null;
var nameLabel = widget.Get<LabelWidget>("NAME");
@@ -46,8 +46,9 @@ namespace OpenRA.Mods.Common.Widgets.Logic
if (sp.Info == null)
return; // no instances actually exist (race with destroy)
time = "{0} / {1}".F(WidgetUtils.FormatTime(sp.RemainingTime),
WidgetUtils.FormatTime(sp.Info.ChargeTime * 25));
var remaining = WidgetUtils.FormatTime(sp.RemainingTime, world.Timestep);
var total = WidgetUtils.FormatTime(sp.Info.ChargeTime * 25, world.Timestep);
time = "{0} / {1}".F(remaining, total);
if (sp == lastPower)
return;

View File

@@ -92,18 +92,18 @@ namespace OpenRA.Mods.Common.Widgets
WidgetUtils.DrawSHPCentered(clock.Image, location + 0.5f * iconSize, worldRenderer.Palette(bi.IconPalette), 0.5f);
var tiny = Game.Renderer.Fonts["Tiny"];
var text = GetOverlayForItem(current);
var text = GetOverlayForItem(current, world.Timestep);
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)
static string GetOverlayForItem(ProductionItem item, int timestep)
{
if (item.Paused) return "ON HOLD";
if (item.Done) return "READY";
return WidgetUtils.FormatTime(item.RemainingTimeActual);
return WidgetUtils.FormatTime(item.RemainingTimeActual, timestep);
}
public override Widget Clone()

View File

@@ -82,18 +82,18 @@ namespace OpenRA.Mods.Common.Widgets
WidgetUtils.DrawSHPCentered(clock.Image, location + 0.5f * iconSize, worldRenderer.Palette(item.Info.IconPalette), 0.5f);
var tiny = Game.Renderer.Fonts["Tiny"];
var text = GetOverlayForItem(item);
var text = GetOverlayForItem(item, world.Timestep);
tiny.DrawTextWithContrast(text,
location + new float2(16, 16) - new float2(tiny.Measure(text).X / 2, 0),
Color.White, Color.Black, 1);
}
}
static string GetOverlayForItem(SupportPowerInstance item)
static string GetOverlayForItem(SupportPowerInstance item, int timestep)
{
if (item.Disabled) return "ON HOLD";
if (item.Ready) return "READY";
return WidgetUtils.FormatTime(item.RemainingTime);
return WidgetUtils.FormatTime(item.RemainingTime, timestep);
}
public override Widget Clone()

View File

@@ -162,7 +162,7 @@ namespace OpenRA.Mods.Common.Widgets
{
if (TooltipContainer != null)
tooltipContainer.Value.SetTooltip(TooltipTemplate,
new WidgetArgs() { { "palette", this } });
new WidgetArgs() { { "world", World }, { "palette", this } });
}
public override void MouseExited()
@@ -353,7 +353,7 @@ namespace OpenRA.Mods.Common.Widgets
var iconOffset = 0.5f * IconSize.ToFloat2() + IconSpriteOffset;
overlayFont = Game.Renderer.Fonts["TinyBold"];
timeOffset = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;
timeOffset = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0, World.Timestep)) / 2;
queuedOffset = new float2(4, 2);
holdOffset = iconOffset - overlayFont.Measure(HoldText) / 2;
readyOffset = iconOffset - overlayFont.Measure(ReadyText) / 2;
@@ -400,7 +400,7 @@ namespace OpenRA.Mods.Common.Widgets
var waiting = first != CurrentQueue.CurrentItem() && !first.Done;
if (first.Done)
{
if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber / 9 % 2 == 0)
if (ReadyTextStyle == ReadyTextStyleOptions.Solid || orderManager.LocalFrameNumber * worldRenderer.World.Timestep / 360 % 2 == 0)
overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, Color.White, Color.Black, 1);
else if (ReadyTextStyle == ReadyTextStyleOptions.AlternatingColor)
overlayFont.DrawTextWithContrast(ReadyText, icon.Pos + readyOffset, ReadyTextAltColor, Color.Black, 1);
@@ -410,7 +410,7 @@ namespace OpenRA.Mods.Common.Widgets
icon.Pos + holdOffset,
Color.White, Color.Black, 1);
else if (!waiting)
overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(first.RemainingTimeActual),
overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(first.RemainingTimeActual, World.Timestep),
icon.Pos + timeOffset,
Color.White, Color.Black, 1);

View File

@@ -65,7 +65,7 @@ namespace OpenRA.Mods.Common.Widgets
var isVictory = pendingWinner == world.LocalPlayer || !WorldUtils.AreMutualAllies(pendingWinner, world.LocalPlayer);
var tc = "Strategic {0} in {1}".F(
isVictory ? "victory" : "defeat",
WidgetUtils.FormatTime(winnerSvc.TicksLeft));
WidgetUtils.FormatTime(winnerSvc.TicksLeft, world.Timestep));
var font = Game.Renderer.Fonts["Bold"];

View File

@@ -23,12 +23,14 @@ namespace OpenRA.Mods.Common.Widgets
public readonly string Format = "{0}: {1}";
public readonly TimerOrder Order = TimerOrder.Descending;
readonly World world;
readonly IEnumerable<SupportPowerInstance> powers;
Pair<string, Color>[] texts;
[ObjectCreator.UseCtor]
public SupportPowerTimerWidget(World world)
{
this.world = world;
powers = world.ActorsWithTrait<SupportPowerManager>()
.Where(p => !p.Actor.IsDead && !p.Actor.Owner.NonCombatant)
.SelectMany(s => s.Trait.Powers.Values)
@@ -39,7 +41,7 @@ namespace OpenRA.Mods.Common.Widgets
{
texts = powers.Select(p =>
{
var time = WidgetUtils.FormatTime(p.RemainingTime, false);
var time = WidgetUtils.FormatTime(p.RemainingTime, false, world.Timestep);
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);

View File

@@ -142,7 +142,7 @@ namespace OpenRA.Mods.Common.Widgets
holdOffset = iconOffset - overlayFont.Measure(HoldText) / 2;
readyOffset = iconOffset - overlayFont.Measure(ReadyText) / 2;
timeOffset = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0)) / 2;
timeOffset = iconOffset - overlayFont.Measure(WidgetUtils.FormatTime(0, worldRenderer.World.Timestep)) / 2;
// Icons
foreach (var p in icons.Values)
@@ -171,7 +171,7 @@ namespace OpenRA.Mods.Common.Widgets
p.Pos + holdOffset,
Color.White, Color.Black, 1);
else
overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(p.Power.RemainingTime),
overlayFont.DrawTextWithContrast(WidgetUtils.FormatTime(p.Power.RemainingTime, worldRenderer.World.Timestep),
p.Pos + timeOffset,
Color.White, Color.Black, 1);
}
@@ -189,7 +189,7 @@ namespace OpenRA.Mods.Common.Widgets
return;
tooltipContainer.Value.SetTooltip(TooltipTemplate,
new WidgetArgs() { { "palette", this } });
new WidgetArgs() { { "world", worldRenderer.World }, { "palette", this } });
}
public override void MouseExited()