From 278e2271150df015c071bc6dba0fccda8c0d3adf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Aug 2024 23:10:26 +0900 Subject: [PATCH] Fix fail check ordering not being enforced correctly --- osu.Game/Rulesets/Scoring/HealthProcessor.cs | 15 ++++++++++++++- osu.Game/Screens/Play/Player.cs | 4 ++-- 2 files changed, 16 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/HealthProcessor.cs b/osu.Game/Rulesets/Scoring/HealthProcessor.cs index 6d8d3963e0..793256abb4 100644 --- a/osu.Game/Rulesets/Scoring/HealthProcessor.cs +++ b/osu.Game/Rulesets/Scoring/HealthProcessor.cs @@ -25,6 +25,11 @@ namespace osu.Game.Rulesets.Scoring /// public readonly Bindable> Mods = new Bindable>(Array.Empty()); + /// + /// Mods which can override fail ordered in the correct order for checks. + /// + public IApplicableFailOverride[] OrderedFailOverrideMods { get; private set; } = Array.Empty(); + /// /// The current health. /// @@ -59,6 +64,14 @@ namespace osu.Game.Rulesets.Scoring ModTriggeringFailure = triggeringMod; } + protected HealthProcessor() + { + Mods.BindValueChanged(mods => + { + OrderedFailOverrideMods = mods.NewValue.OfType().OrderByDescending(m => m.RestartOnFail).ToArray(); + }); + } + protected override void ApplyResultInternal(JudgementResult result) { result.HealthAtJudgement = Health.Value; @@ -102,7 +115,7 @@ namespace osu.Game.Rulesets.Scoring if (CheckDefaultFailCondition(result)) return true; - foreach (var condition in Mods.Value.OfType()) + foreach (var condition in OrderedFailOverrideMods) { if (condition.CheckFail(result) == FailState.Force) { diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 72e5515bc3..3aed7306e6 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -152,7 +152,7 @@ namespace osu.Game.Screens.Play /// Whether failing should be allowed. /// By default, this checks whether all selected mods allow failing. /// - protected virtual bool CheckModsAllowFailure() => HealthProcessor.Mods.Value.OfType().All(m => m.CheckFail(null) != FailState.Block); + protected virtual bool CheckModsAllowFailure() => HealthProcessor.OrderedFailOverrideMods.All(m => m.CheckFail(null) != FailState.Block); public readonly PlayerConfiguration Configuration; @@ -244,7 +244,7 @@ namespace osu.Game.Screens.Play HealthProcessor = gameplayMods.OfType().FirstOrDefault()?.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime); HealthProcessor ??= ruleset.CreateHealthProcessor(playableBeatmap.HitObjects[0].StartTime); - HealthProcessor.Mods.Value = gameplayMods.OrderByDescending(m => m is IApplicableFailOverride mod && mod.RestartOnFail).ToArray(); + HealthProcessor.Mods.Value = gameplayMods; HealthProcessor.ApplyBeatmap(playableBeatmap); dependencies.CacheAs(HealthProcessor);