Fix missing tiny droplet not triggering fail with perfect on

Stable does this:

    46cd3a10af/osu!/GameplayElements/HitObjectManagerFruits.cs#L98-L102

I'd rather not say what I think about it doing that, since it's likely
to be unpublishable, but to approximate that, just make it so that
only the "default fail condition" is beholden to the weird ebbs
and flows of what the ruleset wants. This appears to fix the problem
case and I'm hoping it doesn't break something else but I'm like 50/50
on it happening anyway at this point. Just gotta add tests add nauseam.
This commit is contained in:
Bartłomiej Dach 2024-02-14 14:21:48 +01:00
parent f53bce8ff7
commit 2c0a5b7ef5
No known key found for this signature in database
4 changed files with 16 additions and 17 deletions

View File

@ -22,7 +22,7 @@ public CatchHealthProcessor(double drainStartTime)
protected override IEnumerable<HitObject> EnumerateNestedHitObjects(HitObject hitObject) => Enumerable.Empty<HitObject>();
protected override bool CanFailOn(JudgementResult result)
protected override bool CheckDefaultFailCondition(JudgementResult result)
{
// matches stable.
// see: https://github.com/peppy/osu-stable-reference/blob/46cd3a10af7cc6cc96f4eba92ef1812dc8c3a27e/osu!/GameModes/Play/Rulesets/Ruleset.cs#L967
@ -32,7 +32,7 @@ protected override bool CanFailOn(JudgementResult result)
if (result.Type == HitResult.SmallTickMiss)
return false;
return base.CanFailOn(result);
return base.CheckDefaultFailCondition(result);
}
protected override double GetHealthIncreaseFor(HitObject hitObject, HitResult result)

View File

@ -1,6 +1,8 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Judgements;
namespace osu.Game.Rulesets.Scoring
{
/// <summary>
@ -9,7 +11,7 @@ namespace osu.Game.Rulesets.Scoring
/// </summary>
public partial class AccumulatingHealthProcessor : HealthProcessor
{
protected override bool DefaultFailCondition => JudgedHits == MaxHits && Health.Value < requiredHealth;
protected override bool CheckDefaultFailCondition(JudgementResult _) => JudgedHits == MaxHits && Health.Value < requiredHealth;
private readonly double requiredHealth;

View File

@ -142,9 +142,12 @@ protected override void ApplyResultInternal(JudgementResult result)
}
}
protected override bool CanFailOn(JudgementResult result)
protected override bool CheckDefaultFailCondition(JudgementResult result)
{
return !result.Judgement.MaxResult.IsBonus() && result.Type != HitResult.IgnoreHit;
if (result.Judgement.MaxResult.IsBonus() || result.Type == HitResult.IgnoreHit)
return false;
return base.CheckDefaultFailCondition(result);
}
protected override void Reset(bool storeResults)

View File

@ -17,7 +17,7 @@ public abstract partial class HealthProcessor : JudgementProcessor
public event Func<bool>? Failed;
/// <summary>
/// Additional conditions on top of <see cref="DefaultFailCondition"/> that cause a failing state.
/// Additional conditions on top of <see cref="CheckDefaultFailCondition"/> that cause a failing state.
/// </summary>
public event Func<HealthProcessor, JudgementResult, bool>? FailConditions;
@ -50,7 +50,7 @@ protected override void ApplyResultInternal(JudgementResult result)
Health.Value += GetHealthIncreaseFor(result);
if (CanFailOn(result) && meetsAnyFailCondition(result))
if (meetsAnyFailCondition(result))
TriggerFailure();
}
@ -69,16 +69,10 @@ protected override void RevertResultInternal(JudgementResult result)
protected virtual double GetHealthIncreaseFor(JudgementResult result) => result.HealthIncrease;
/// <summary>
/// Whether a failure can occur on a given <paramref name="result"/>.
/// If the return value of this method is <see langword="false"/>, neither <see cref="DefaultFailCondition"/> nor <see cref="FailConditions"/> will be checked
/// after this <paramref name="result"/>.
/// Checks whether the default conditions for failing are met.
/// </summary>
protected virtual bool CanFailOn(JudgementResult result) => true;
/// <summary>
/// The default conditions for failing.
/// </summary>
protected virtual bool DefaultFailCondition => Precision.AlmostBigger(Health.MinValue, Health.Value);
/// <returns><see langword="true"/> if failure should be invoked.</returns>
protected virtual bool CheckDefaultFailCondition(JudgementResult result) => Precision.AlmostBigger(Health.MinValue, Health.Value);
/// <summary>
/// Whether the current state of <see cref="HealthProcessor"/> or the provided <paramref name="result"/> meets any fail condition.
@ -86,7 +80,7 @@ protected override void RevertResultInternal(JudgementResult result)
/// <param name="result">The judgement result.</param>
private bool meetsAnyFailCondition(JudgementResult result)
{
if (DefaultFailCondition)
if (CheckDefaultFailCondition(result))
return true;
if (FailConditions != null)