mirror of
https://github.com/ppy/osu
synced 2025-02-25 23:21:26 +00:00
Merge pull request #17991 from frenzibyte/invoke-all-fail-conditions
Fix `HealthProcessor` fail conditions not handling multiple invocations
This commit is contained in:
commit
26f34e8fb9
@ -9,6 +9,10 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
{
|
||||
public class OsuModSuddenDeath : ModSuddenDeath
|
||||
{
|
||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(OsuModAutopilot)).ToArray();
|
||||
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[]
|
||||
{
|
||||
typeof(OsuModAutopilot),
|
||||
typeof(OsuModTarget),
|
||||
}).ToArray();
|
||||
}
|
||||
}
|
||||
|
@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
||||
public override string Description => @"Practice keeping up with the beat of the song.";
|
||||
public override double ScoreMultiplier => 1;
|
||||
|
||||
public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles) };
|
||||
public override Type[] IncompatibleMods => new[] { typeof(IRequiresApproachCircles), typeof(OsuModSuddenDeath) };
|
||||
|
||||
[SettingSource("Seed", "Use a custom seed instead of a random one", SettingControlType = typeof(SettingsNumberBox))]
|
||||
public Bindable<int?> Seed { get; } = new Bindable<int?>
|
||||
|
@ -160,6 +160,40 @@ namespace osu.Game.Tests.Gameplay
|
||||
assertHealthNotEqualTo(1);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestFailConditions()
|
||||
{
|
||||
var beatmap = createBeatmap(0, 1000);
|
||||
createProcessor(beatmap);
|
||||
|
||||
AddStep("setup fail conditions", () => processor.FailConditions += ((_, result) => result.Type == HitResult.Miss));
|
||||
|
||||
AddStep("apply perfect hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = HitResult.Perfect }));
|
||||
AddAssert("not failed", () => !processor.HasFailed);
|
||||
AddStep("apply miss hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = HitResult.Miss }));
|
||||
AddAssert("failed", () => processor.HasFailed);
|
||||
}
|
||||
|
||||
[TestCase(HitResult.Miss)]
|
||||
[TestCase(HitResult.Meh)]
|
||||
public void TestMultipleFailConditions(HitResult resultApplied)
|
||||
{
|
||||
var beatmap = createBeatmap(0, 1000);
|
||||
createProcessor(beatmap);
|
||||
|
||||
AddStep("setup multiple fail conditions", () =>
|
||||
{
|
||||
processor.FailConditions += ((_, result) => result.Type == HitResult.Miss);
|
||||
processor.FailConditions += ((_, result) => result.Type == HitResult.Meh);
|
||||
});
|
||||
|
||||
AddStep("apply perfect hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = HitResult.Perfect }));
|
||||
AddAssert("not failed", () => !processor.HasFailed);
|
||||
|
||||
AddStep($"apply {resultApplied.ToString().ToLower()} hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = resultApplied }));
|
||||
AddAssert("failed", () => processor.HasFailed);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBonusObjectsExcludedFromDrain()
|
||||
{
|
||||
|
@ -43,11 +43,11 @@ namespace osu.Game.Rulesets.Scoring
|
||||
|
||||
Health.Value += GetHealthIncreaseFor(result);
|
||||
|
||||
if (!DefaultFailCondition && FailConditions?.Invoke(this, result) != true)
|
||||
return;
|
||||
|
||||
if (Failed?.Invoke() != false)
|
||||
HasFailed = true;
|
||||
if (meetsAnyFailCondition(result))
|
||||
{
|
||||
if (Failed?.Invoke() != false)
|
||||
HasFailed = true;
|
||||
}
|
||||
}
|
||||
|
||||
protected override void RevertResultInternal(JudgementResult result)
|
||||
@ -69,6 +69,28 @@ namespace osu.Game.Rulesets.Scoring
|
||||
/// </summary>
|
||||
protected virtual bool DefaultFailCondition => 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.
|
||||
/// </summary>
|
||||
/// <param name="result">The judgement result.</param>
|
||||
private bool meetsAnyFailCondition(JudgementResult result)
|
||||
{
|
||||
if (DefaultFailCondition)
|
||||
return true;
|
||||
|
||||
if (FailConditions != null)
|
||||
{
|
||||
foreach (var condition in FailConditions.GetInvocationList())
|
||||
{
|
||||
bool conditionResult = (bool)condition.Method.Invoke(condition.Target, new object[] { this, result });
|
||||
if (conditionResult)
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
protected override void Reset(bool storeResults)
|
||||
{
|
||||
base.Reset(storeResults);
|
||||
|
Loading…
Reference in New Issue
Block a user