From 4c45f7d938d90d41c7dd6fb6b6f23e2c51190f4b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Aug 2022 14:26:20 +0900 Subject: [PATCH 1/5] Ensure `FailAnimation` can't be `Start`ed after filters are already removed --- osu.Game/Screens/Play/FailAnimation.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index c1223d7262..312e752cc6 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -105,6 +105,7 @@ private void load(AudioManager audio, IBindable beatmap) } private bool started; + private bool filtersRemoved; /// /// Start the fail animation playing. @@ -113,6 +114,7 @@ private void load(AudioManager audio, IBindable beatmap) public void Start() { if (started) throw new InvalidOperationException("Animation cannot be started more than once."); + if (filtersRemoved) throw new InvalidOperationException("Animation cannot be started after filters have been removed."); started = true; @@ -155,6 +157,11 @@ public void Start() public void RemoveFilters(bool resetTrackFrequency = true) { + if (filtersRemoved) + return; + + filtersRemoved = true; + if (resetTrackFrequency) track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); From 8f4a953d11a4ef3ddf7eaf3d46b75a2e40f570b1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Aug 2022 14:26:42 +0900 Subject: [PATCH 2/5] Ensure fail animation sequence isn't run after the player exit sequence has started --- osu.Game/Screens/Play/Player.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 6827ff04d3..cd7bf6fe9e 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -4,6 +4,7 @@ #nullable disable using System; +using System.Diagnostics; using System.IO; using System.Linq; using System.Threading; @@ -828,9 +829,17 @@ protected override bool OnScroll(ScrollEvent e) private bool onFail() { + // Failing after the quit sequence has started may cause weird side effects with the fail animation / effects. + if (GameplayState.HasQuit) + return false; + if (!CheckModsAllowFailure()) return false; + Debug.Assert(!GameplayState.HasFailed); + Debug.Assert(!GameplayState.HasPassed); + Debug.Assert(!GameplayState.HasQuit); + GameplayState.HasFailed = true; updateGameplayState(); From ec60e164392acda3e644726e5774be04df6afd7e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Aug 2022 14:35:42 +0900 Subject: [PATCH 3/5] Apply NRT to `FailAnimation` --- osu.Game/Screens/Play/FailAnimation.cs | 24 ++++++++++-------------- 1 file changed, 10 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 312e752cc6..4d3b08cbe0 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -1,14 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -#nullable disable - using osu.Framework.Audio; using osu.Framework.Bindables; using osu.Game.Rulesets.UI; using System; using System.Collections.Generic; -using JetBrains.Annotations; using ManagedBass.Fx; using osu.Framework.Allocation; using osu.Framework.Audio.Sample; @@ -34,27 +31,27 @@ namespace osu.Game.Screens.Play /// public class FailAnimation : Container { - public Action OnComplete; + public Action? OnComplete; private readonly DrawableRuleset drawableRuleset; private readonly BindableDouble trackFreq = new BindableDouble(1); private readonly BindableDouble volumeAdjustment = new BindableDouble(0.5); - private Container filters; + private Container filters = null!; - private Box redFlashLayer; + private Box redFlashLayer = null!; - private Track track; + private Track? track; - private AudioFilter failLowPassFilter; - private AudioFilter failHighPassFilter; + private AudioFilter failLowPassFilter = null!; + private AudioFilter failHighPassFilter = null!; private const float duration = 2500; - private Sample failSample; + private Sample? failSample; [Resolved] - private OsuConfigManager config { get; set; } + private OsuConfigManager config { get; set; } = null!; protected override Container Content { get; } = new Container { @@ -66,8 +63,7 @@ public class FailAnimation : Container /// /// The player screen background, used to adjust appearance on failing. /// - [CanBeNull] - public BackgroundScreen Background { private get; set; } + public BackgroundScreen? Background { private get; set; } public FailAnimation(DrawableRuleset drawableRuleset) { @@ -127,7 +123,7 @@ public void Start() failHighPassFilter.CutoffTo(300); failLowPassFilter.CutoffTo(300, duration, Easing.OutCubic); - failSample.Play(); + failSample?.Play(); track.AddAdjustment(AdjustableProperty.Frequency, trackFreq); track.AddAdjustment(AdjustableProperty.Volume, volumeAdjustment); From ad3dd1c700e09b30a64d90e00903ae3dc24f7923 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Aug 2022 14:45:00 +0900 Subject: [PATCH 4/5] Fix a couple of oversights regarding `track` nullability --- osu.Game/Beatmaps/WorkingBeatmap.cs | 1 + osu.Game/Screens/Play/FailAnimation.cs | 14 ++++++++------ 2 files changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game/Beatmaps/WorkingBeatmap.cs b/osu.Game/Beatmaps/WorkingBeatmap.cs index 301610ee58..eb914e61d4 100644 --- a/osu.Game/Beatmaps/WorkingBeatmap.cs +++ b/osu.Game/Beatmaps/WorkingBeatmap.cs @@ -146,6 +146,7 @@ public virtual bool TryTransferTrack([NotNull] WorkingBeatmap target) /// Get the loaded audio track instance. must have first been called. /// This generally happens via MusicController when changing the global beatmap. /// + [NotNull] public Track Track { get diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 4d3b08cbe0..965d3d3454 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -41,7 +41,7 @@ public class FailAnimation : Container private Box redFlashLayer = null!; - private Track? track; + private Track track = null!; private AudioFilter failLowPassFilter = null!; private AudioFilter failHighPassFilter = null!; @@ -153,15 +153,17 @@ public void Start() public void RemoveFilters(bool resetTrackFrequency = true) { - if (filtersRemoved) - return; + if (filtersRemoved) return; filtersRemoved = true; - if (resetTrackFrequency) - track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); + if (!started) + return; - track?.RemoveAdjustment(AdjustableProperty.Volume, volumeAdjustment); + if (resetTrackFrequency) + track.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq); + + track.RemoveAdjustment(AdjustableProperty.Volume, volumeAdjustment); if (filters.Parent == null) return; From a6ed589db4fad90248c56f268c0e94a25c3edd2f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 25 Aug 2022 14:47:32 +0900 Subject: [PATCH 5/5] Remove guard against `RemoveFilters` running more than once It turns out this is required to remove some filters immediate, and some later. Weird. --- osu.Game/Screens/Play/FailAnimation.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs index 965d3d3454..7275b369c3 100644 --- a/osu.Game/Screens/Play/FailAnimation.cs +++ b/osu.Game/Screens/Play/FailAnimation.cs @@ -153,8 +153,6 @@ public void Start() public void RemoveFilters(bool resetTrackFrequency = true) { - if (filtersRemoved) return; - filtersRemoved = true; if (!started)