From 420df124b5fba03eaf59196b5a2d70f2c973f4c8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 3 Jun 2021 17:27:21 +0900 Subject: [PATCH] Add framestable-bypassing seek for spectator --- .../Visual/Gameplay/TestSceneHitErrorMeter.cs | 1 + osu.Game/Rulesets/UI/DrawableRuleset.cs | 4 ++- osu.Game/Screens/Play/Player.cs | 18 ++++++++++++ osu.Game/Screens/Play/SpectatorPlayer.cs | 28 ++++++++++--------- 4 files changed, 37 insertions(+), 14 deletions(-) diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs index 2c5443fe08..ab13095af4 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneHitErrorMeter.cs @@ -177,6 +177,7 @@ namespace osu.Game.Tests.Visual.Gameplay public override Container Overlays { get; } public override Container FrameStableComponents { get; } public override IFrameStableClock FrameStableClock { get; } + internal override bool FrameStablePlayback { get; set; } public override IReadOnlyList Mods { get; } public override double GameplayStartTime { get; } diff --git a/osu.Game/Rulesets/UI/DrawableRuleset.cs b/osu.Game/Rulesets/UI/DrawableRuleset.cs index a2dade2627..0cd5804fd0 100644 --- a/osu.Game/Rulesets/UI/DrawableRuleset.cs +++ b/osu.Game/Rulesets/UI/DrawableRuleset.cs @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.UI /// /// Whether to enable frame-stable playback. /// - internal bool FrameStablePlayback + internal override bool FrameStablePlayback { get => frameStablePlayback; set @@ -432,6 +432,8 @@ namespace osu.Game.Rulesets.UI /// public abstract IFrameStableClock FrameStableClock { get; } + internal abstract bool FrameStablePlayback { get; set; } + /// /// The mods which are to be applied. /// diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 2258d509b7..f8f9103c89 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -576,6 +576,24 @@ namespace osu.Game.Screens.Play /// The destination time to seek to. public void Seek(double time) => GameplayClockContainer.Seek(time); + /// + /// Seeks to a specific time in gameplay, bypassing frame stability. + /// + /// + /// Intermediate hitobject judgements may not be applied or reverted correctly during this seek. + /// + /// The destination time to seek to. + public void NonFrameStableSeek(double time) + { + bool wasFrameStable = DrawableRuleset.FrameStablePlayback; + DrawableRuleset.FrameStablePlayback = false; + + Seek(time); + + // Delay resetting frame-stable playback for one frame to give the FrameStabilityContainer a chance to seek. + ScheduleAfterChildren(() => DrawableRuleset.FrameStablePlayback = wasFrameStable); + } + /// /// Restart gameplay via a parent . /// This can be called from a child screen in order to trigger the restart process. diff --git a/osu.Game/Screens/Play/SpectatorPlayer.cs b/osu.Game/Screens/Play/SpectatorPlayer.cs index c5e26bdef6..605702c8e2 100644 --- a/osu.Game/Screens/Play/SpectatorPlayer.cs +++ b/osu.Game/Screens/Play/SpectatorPlayer.cs @@ -1,11 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Screens; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Online.Spectator; @@ -50,6 +48,7 @@ namespace osu.Game.Screens.Play base.LoadComplete(); spectatorClient.OnNewFrames += userSentFrames; + seekToGameplay(); } private void userSentFrames(int userId, FrameDataBundle bundle) @@ -73,6 +72,20 @@ namespace osu.Game.Screens.Play score.Replay.Frames.Add(convertedFrame); } + + seekToGameplay(); + } + + private bool seekedToGameplay; + + private void seekToGameplay() + { + if (seekedToGameplay || score.Replay.Frames.Count == 0) + return; + + NonFrameStableSeek(score.Replay.Frames[0].Time); + + seekedToGameplay = true; } protected override ResultsScreen CreateResults(ScoreInfo score) @@ -85,17 +98,6 @@ namespace osu.Game.Screens.Play DrawableRuleset?.SetReplayScore(score); } - protected override GameplayClockContainer CreateGameplayClockContainer(WorkingBeatmap beatmap, double gameplayStart) - { - // if we already have frames, start gameplay at the point in time they exist, should they be too far into the beatmap. - double? firstFrameTime = score.Replay.Frames.FirstOrDefault()?.Time; - - if (firstFrameTime == null || firstFrameTime <= gameplayStart + 5000) - return base.CreateGameplayClockContainer(beatmap, gameplayStart); - - return new MasterGameplayClockContainer(beatmap, firstFrameTime.Value, true); - } - public override bool OnExiting(IScreen next) { spectatorClient.OnUserBeganPlaying -= userBeganPlaying;