diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapOffsetControl.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapOffsetControl.cs index 0f47c3cd27..aa99b22701 100644 --- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapOffsetControl.cs +++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapOffsetControl.cs @@ -27,18 +27,7 @@ namespace osu.Game.Tests.Visual.Gameplay [SetUpSteps] public void SetUpSteps() { - AddStep("Create control", () => - { - Child = new PlayerSettingsGroup("Some settings") - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Children = new Drawable[] - { - offsetControl = new BeatmapOffsetControl() - } - }; - }); + recreateControl(); } [Test] @@ -123,13 +112,14 @@ namespace osu.Game.Tests.Visual.Gameplay [Test] public void TestCalibrationFromZero() { + ScoreInfo referenceScore = null!; const double average_error = -4.5; AddAssert("Offset is neutral", () => offsetControl.Current.Value == 0); AddAssert("No calibration button", () => !offsetControl.ChildrenOfType().Any()); AddStep("Set reference score", () => { - offsetControl.ReferenceScore.Value = new ScoreInfo + offsetControl.ReferenceScore.Value = referenceScore = new ScoreInfo { HitEvents = TestSceneHitEventTimingDistributionGraph.CreateDistributedHitEvents(average_error), BeatmapInfo = Beatmap.Value.BeatmapInfo, @@ -143,6 +133,10 @@ namespace osu.Game.Tests.Visual.Gameplay AddUntilStep("Button is disabled", () => !offsetControl.ChildrenOfType().Single().Enabled.Value); AddStep("Remove reference score", () => offsetControl.ReferenceScore.Value = null); AddAssert("No calibration button", () => !offsetControl.ChildrenOfType().Any()); + + recreateControl(); + AddStep("Set same reference score", () => offsetControl.ReferenceScore.Value = referenceScore); + AddAssert("No calibration button", () => !offsetControl.ChildrenOfType().Any()); } /// @@ -251,5 +245,21 @@ namespace osu.Game.Tests.Visual.Gameplay AddStep("Remove reference score", () => offsetControl.ReferenceScore.Value = null); AddAssert("No calibration button", () => !offsetControl.ChildrenOfType().Any()); } + + private void recreateControl() + { + AddStep("Create control", () => + { + Child = new PlayerSettingsGroup("Some settings") + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Children = new Drawable[] + { + offsetControl = new BeatmapOffsetControl() + } + }; + }); + } } } diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 5646649d33..58e780cf16 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -355,18 +355,18 @@ namespace osu.Game.Tests.Visual.Navigation } [Test] - public void TestLastScoreNullAfterExitingPlayer() + public void TestLastScoreNotNullAfterExitingPlayer() { - AddUntilStep("wait for last play null", getLastPlay, () => Is.Null); + AddUntilStep("last play null", getLastPlay, () => Is.Null); var getOriginalPlayer = playToCompletion(); AddStep("attempt to retry", () => getOriginalPlayer().ChildrenOfType().First().Action()); - AddUntilStep("wait for last play matches player", getLastPlay, () => Is.EqualTo(getOriginalPlayer().Score.ScoreInfo)); + AddUntilStep("last play matches player", getLastPlay, () => Is.EqualTo(getOriginalPlayer().Score.ScoreInfo)); AddUntilStep("wait for player", () => Game.ScreenStack.CurrentScreen != getOriginalPlayer() && Game.ScreenStack.CurrentScreen is Player); AddStep("exit player", () => (Game.ScreenStack.CurrentScreen as Player)?.Exit()); - AddUntilStep("wait for last play null", getLastPlay, () => Is.Null); + AddUntilStep("last play not null", getLastPlay, () => Is.Not.Null); ScoreInfo getLastPlay() => Game.Dependencies.Get().Get(Static.LastLocalUserScore); } diff --git a/osu.Game/Configuration/SessionStatics.cs b/osu.Game/Configuration/SessionStatics.cs index 18631f5d00..c55a597c32 100644 --- a/osu.Game/Configuration/SessionStatics.cs +++ b/osu.Game/Configuration/SessionStatics.cs @@ -10,7 +10,6 @@ using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Mods; using osu.Game.Scoring; -using osu.Game.Screens.Play; namespace osu.Game.Configuration { @@ -30,6 +29,7 @@ namespace osu.Game.Configuration SetDefault(Static.SeasonalBackgrounds, null); SetDefault(Static.TouchInputActive, RuntimeInfo.IsMobile); SetDefault(Static.LastLocalUserScore, null); + SetDefault(Static.LastAppliedOffsetScore, null); } /// @@ -78,11 +78,15 @@ namespace osu.Game.Configuration TouchInputActive, /// - /// Contains the local user's last score (can be completed or aborted) after exiting . - /// Will be cleared to null when leaving . + /// Stores the local user's last score (can be completed or aborted). /// LastLocalUserScore, + /// + /// Stores the local user's last score which was used to apply an offset. + /// + LastAppliedOffsetScore, + /// /// Whether the intro animation for the daily challenge screen has been played once. /// This is reset when a new challenge is up. diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 837974a8f2..06086c1004 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -29,7 +29,6 @@ using osu.Game.Overlays; using osu.Game.Overlays.Notifications; using osu.Game.Overlays.Volume; using osu.Game.Performance; -using osu.Game.Scoring; using osu.Game.Screens.Menu; using osu.Game.Screens.Play.PlayerSettings; using osu.Game.Skinning; @@ -80,8 +79,6 @@ namespace osu.Game.Screens.Play private FillFlowContainer disclaimers = null!; private OsuScrollContainer settingsScroll = null!; - private Bindable lastScore = null!; - private Bindable showStoryboards = null!; private bool backgroundBrightnessReduction; @@ -183,8 +180,6 @@ namespace osu.Game.Screens.Play { muteWarningShownOnce = sessionStatics.GetBindable(Static.MutedAudioNotificationShownOnce); batteryWarningShownOnce = sessionStatics.GetBindable(Static.LowBatteryNotificationShownOnce); - lastScore = sessionStatics.GetBindable(Static.LastLocalUserScore); - showStoryboards = config.GetBindable(OsuSetting.ShowStoryboard); const float padding = 25; @@ -354,8 +349,6 @@ namespace osu.Game.Screens.Play highPerformanceSession?.Dispose(); highPerformanceSession = null; - lastScore.Value = null; - return base.OnExiting(e); } diff --git a/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs b/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs index 74b887481f..f93fa1b3c5 100644 --- a/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs +++ b/osu.Game/Screens/Play/PlayerSettings/BeatmapOffsetControl.cs @@ -15,6 +15,7 @@ using osu.Framework.Input.Events; using osu.Framework.Localisation; using osu.Framework.Utils; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Database; using osu.Game.Graphics; using osu.Game.Graphics.Containers; @@ -36,6 +37,8 @@ namespace osu.Game.Screens.Play.PlayerSettings { public Bindable ReferenceScore { get; } = new Bindable(); + private Bindable lastAppliedScore { get; } = new Bindable(); + public BindableDouble Current { get; } = new BindableDouble { MinValue = -50, @@ -100,6 +103,12 @@ namespace osu.Game.Screens.Play.PlayerSettings }; } + [BackgroundDependencyLoader] + private void load(SessionStatics statics) + { + statics.BindWith(Static.LastAppliedOffsetScore, lastAppliedScore); + } + protected override void LoadComplete() { base.LoadComplete(); @@ -176,6 +185,9 @@ namespace osu.Game.Screens.Play.PlayerSettings if (score.NewValue == null) return; + if (score.NewValue.Equals(lastAppliedScore.Value)) + return; + if (!score.NewValue.BeatmapInfo.AsNonNull().Equals(beatmap.Value.BeatmapInfo)) return; @@ -230,7 +242,11 @@ namespace osu.Game.Screens.Play.PlayerSettings useAverageButton = new SettingsButton { Text = BeatmapOffsetControlStrings.CalibrateUsingLastPlay, - Action = () => Current.Value = lastPlayBeatmapOffset - lastPlayAverage, + Action = () => + { + Current.Value = lastPlayBeatmapOffset - lastPlayAverage; + lastAppliedScore.Value = ReferenceScore.Value; + }, Enabled = { Value = !Precision.AlmostEquals(lastPlayAverage, 0, Current.Precision / 2) } }, globalOffsetText = new LinkFlowContainer