diff --git a/OpenRA.Game/Network/OrderManager.cs b/OpenRA.Game/Network/OrderManager.cs index 33d9a8c808..640926c3b8 100644 --- a/OpenRA.Game/Network/OrderManager.cs +++ b/OpenRA.Game/Network/OrderManager.cs @@ -57,7 +57,9 @@ namespace OpenRA.Network bool generateSyncReport = false; int sentOrdersFrame = 0; float tickScale = 1f; - bool outOfSync = false; + + /// Should only be set in + public bool IsOutOfSync { get; private set; } = false; public struct ClientOrder { @@ -72,12 +74,12 @@ namespace OpenRA.Network void OutOfSync(int frame) { - if (outOfSync) + if (IsOutOfSync) return; syncReport.DumpSyncReport(frame); World.OutOfSync(); - outOfSync = true; + IsOutOfSync = true; TextNotificationsManager.AddSystemLine($"Out of sync in frame {frame}.\nCompare syncreport.log with other players."); } diff --git a/OpenRA.Game/World.cs b/OpenRA.Game/World.cs index f76b8f4ce6..49c8f4808b 100644 --- a/OpenRA.Game/World.cs +++ b/OpenRA.Game/World.cs @@ -618,6 +618,9 @@ namespace OpenRA public void OutOfSync() { EndGame(); + + // In the event the replay goes out of sync, it becomes no longer usable. For polish we permanently pause the world. + ReplayTimestep = 0; } } diff --git a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ReplayControlBarLogic.cs b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ReplayControlBarLogic.cs index c88ea0c674..9aba4f6d56 100644 --- a/OpenRA.Mods.Common/Widgets/Logic/Ingame/ReplayControlBarLogic.cs +++ b/OpenRA.Mods.Common/Widgets/Logic/Ingame/ReplayControlBarLogic.cs @@ -45,18 +45,21 @@ namespace OpenRA.Mods.Common.Widgets.Logic var speed = PlaybackSpeed.Regular; var originalTimestep = world.Timestep; + // In the event the replay goes out of sync, it becomes no longer usable. For polish we permanently pause the world. + Func isWidgetDisabled = () => orderManager.IsOutOfSync || orderManager.NetFrameNumber >= replayNetTicks; + var pauseButton = widget.Get("BUTTON_PAUSE"); - pauseButton.IsVisible = () => world.ReplayTimestep != 0 && orderManager.NetFrameNumber < replayNetTicks; + pauseButton.IsVisible = () => world.ReplayTimestep != 0 && !isWidgetDisabled(); pauseButton.OnClick = () => world.ReplayTimestep = 0; var playButton = widget.Get("BUTTON_PLAY"); - playButton.IsVisible = () => world.ReplayTimestep == 0 || orderManager.NetFrameNumber >= replayNetTicks; + playButton.IsVisible = () => world.ReplayTimestep == 0 || isWidgetDisabled(); playButton.OnClick = () => world.ReplayTimestep = (int)Math.Ceiling(originalTimestep * multipliers[speed]); - playButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks; + playButton.IsDisabled = isWidgetDisabled; var slowButton = widget.Get("BUTTON_SLOW"); slowButton.IsHighlighted = () => speed == PlaybackSpeed.Slow; - slowButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks; + slowButton.IsDisabled = isWidgetDisabled; slowButton.OnClick = () => { speed = PlaybackSpeed.Slow; @@ -66,7 +69,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var normalSpeedButton = widget.Get("BUTTON_REGULAR"); normalSpeedButton.IsHighlighted = () => speed == PlaybackSpeed.Regular; - normalSpeedButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks; + normalSpeedButton.IsDisabled = isWidgetDisabled; normalSpeedButton.OnClick = () => { speed = PlaybackSpeed.Regular; @@ -76,7 +79,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var fastButton = widget.Get("BUTTON_FAST"); fastButton.IsHighlighted = () => speed == PlaybackSpeed.Fast; - fastButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks; + fastButton.IsDisabled = isWidgetDisabled; fastButton.OnClick = () => { speed = PlaybackSpeed.Fast; @@ -86,7 +89,7 @@ namespace OpenRA.Mods.Common.Widgets.Logic var maximumButton = widget.Get("BUTTON_MAXIMUM"); maximumButton.IsHighlighted = () => speed == PlaybackSpeed.Maximum; - maximumButton.IsDisabled = () => orderManager.NetFrameNumber >= replayNetTicks; + maximumButton.IsDisabled = isWidgetDisabled; maximumButton.OnClick = () => { speed = PlaybackSpeed.Maximum;