1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-28 04:03:06 +08:00

Merge pull request #13365 from bdach/catch-colour-error-meter

Fix colour hit error meter not working with empty hit windows
This commit is contained in:
Dan Balasescu 2021-06-07 21:13:30 +09:00 committed by GitHub
commit 6ebac0b462
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
5 changed files with 41 additions and 47 deletions

View File

@ -1,22 +0,0 @@
// 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.Scoring;
namespace osu.Game.Rulesets.Catch.Scoring
{
public class CatchHitWindows : HitWindows
{
public override bool IsHitResultAllowed(HitResult result)
{
switch (result)
{
case HitResult.Great:
case HitResult.Miss:
return true;
}
return false;
}
}
}

View File

@ -4,14 +4,15 @@
using System; using System;
using System.Collections.Generic; using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis; using System.Diagnostics.CodeAnalysis;
using System.Linq;
using NUnit.Framework; using NUnit.Framework;
using osu.Framework.Allocation; using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Containers;
using osu.Framework.Testing;
using osu.Framework.Threading; using osu.Framework.Threading;
using osu.Framework.Utils; using osu.Framework.Utils;
using osu.Game.Graphics.Sprites; using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Catch.Scoring;
using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Scoring; using osu.Game.Rulesets.Mania.Scoring;
using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Mods;
@ -29,15 +30,22 @@ namespace osu.Game.Tests.Visual.Gameplay
{ {
public class TestSceneHitErrorMeter : OsuTestScene public class TestSceneHitErrorMeter : OsuTestScene
{ {
[Cached] [Cached(typeof(ScoreProcessor))]
private ScoreProcessor scoreProcessor = new ScoreProcessor(); private TestScoreProcessor scoreProcessor = new TestScoreProcessor();
[Cached(typeof(DrawableRuleset))] [Cached(typeof(DrawableRuleset))]
private TestDrawableRuleset drawableRuleset = new TestDrawableRuleset(); private TestDrawableRuleset drawableRuleset = new TestDrawableRuleset();
public TestSceneHitErrorMeter() [SetUpSteps]
public void SetUp()
{ {
recreateDisplay(new OsuHitWindows(), 5); AddStep("reset score processor", () => scoreProcessor.Reset());
}
[Test]
public void TestBasic()
{
AddStep("create display", () => recreateDisplay(new OsuHitWindows(), 5));
AddRepeatStep("New random judgement", () => newJudgement(), 40); AddRepeatStep("New random judgement", () => newJudgement(), 40);
@ -45,12 +53,11 @@ namespace osu.Game.Tests.Visual.Gameplay
AddRepeatStep("New max positive", () => newJudgement(drawableRuleset.HitWindows.WindowFor(HitResult.Meh)), 20); AddRepeatStep("New max positive", () => newJudgement(drawableRuleset.HitWindows.WindowFor(HitResult.Meh)), 20);
AddStep("New fixed judgement (50ms)", () => newJudgement(50)); AddStep("New fixed judgement (50ms)", () => newJudgement(50));
ScheduledDelegate del = null;
AddStep("Judgement barrage", () => AddStep("Judgement barrage", () =>
{ {
int runCount = 0; int runCount = 0;
ScheduledDelegate del = null;
del = Scheduler.AddDelayed(() => del = Scheduler.AddDelayed(() =>
{ {
newJudgement(runCount++ / 10f); newJudgement(runCount++ / 10f);
@ -60,6 +67,7 @@ namespace osu.Game.Tests.Visual.Gameplay
del?.Cancel(); del?.Cancel();
}, 10, true); }, 10, true);
}); });
AddUntilStep("wait for barrage", () => del.Cancelled);
} }
[Test] [Test]
@ -84,10 +92,21 @@ namespace osu.Game.Tests.Visual.Gameplay
} }
[Test] [Test]
public void TestCatch() public void TestEmpty()
{ {
AddStep("OD 1", () => recreateDisplay(new CatchHitWindows(), 1)); AddStep("empty windows", () => recreateDisplay(HitWindows.Empty, 5));
AddStep("OD 10", () => recreateDisplay(new CatchHitWindows(), 10));
AddStep("hit", () => newJudgement());
AddAssert("no bars added", () => !this.ChildrenOfType<BarHitErrorMeter.JudgementLine>().Any());
AddAssert("circle added", () =>
this.ChildrenOfType<ColourHitErrorMeter>().All(
meter => meter.ChildrenOfType<ColourHitErrorMeter.HitErrorCircle>().Count() == 1));
AddStep("miss", () => newJudgement(50, HitResult.Miss));
AddAssert("no bars added", () => !this.ChildrenOfType<BarHitErrorMeter.JudgementLine>().Any());
AddAssert("circle added", () =>
this.ChildrenOfType<ColourHitErrorMeter>().All(
meter => meter.ChildrenOfType<ColourHitErrorMeter.HitErrorCircle>().Count() == 2));
} }
private void recreateDisplay(HitWindows hitWindows, float overallDifficulty) private void recreateDisplay(HitWindows hitWindows, float overallDifficulty)
@ -154,12 +173,12 @@ namespace osu.Game.Tests.Visual.Gameplay
}); });
} }
private void newJudgement(double offset = 0) private void newJudgement(double offset = 0, HitResult result = HitResult.Perfect)
{ {
scoreProcessor.ApplyResult(new JudgementResult(new HitCircle { HitWindows = drawableRuleset.HitWindows }, new Judgement()) scoreProcessor.ApplyResult(new JudgementResult(new HitCircle { HitWindows = drawableRuleset.HitWindows }, new Judgement())
{ {
TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset, TimeOffset = offset == 0 ? RNG.Next(-150, 150) : offset,
Type = HitResult.Perfect, Type = result,
}); });
} }
@ -199,5 +218,10 @@ namespace osu.Game.Tests.Visual.Gameplay
public override void CancelResume() => throw new NotImplementedException(); public override void CancelResume() => throw new NotImplementedException();
} }
private class TestScoreProcessor : ScoreProcessor
{
public void Reset() => base.Reset(false);
}
} }
} }

View File

@ -214,7 +214,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
protected override void OnNewJudgement(JudgementResult judgement) protected override void OnNewJudgement(JudgementResult judgement)
{ {
if (!judgement.IsHit) if (!judgement.IsHit || judgement.HitObject.HitWindows?.WindowFor(HitResult.Miss) == 0)
return; return;
if (judgementsContainer.Count > max_concurrent_judgements) if (judgementsContainer.Count > max_concurrent_judgements)
@ -244,7 +244,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
private float getRelativeJudgementPosition(double value) => Math.Clamp((float)((value / maxHitWindow) + 1) / 2, 0, 1); private float getRelativeJudgementPosition(double value) => Math.Clamp((float)((value / maxHitWindow) + 1) / 2, 0, 1);
private class JudgementLine : CompositeDrawable internal class JudgementLine : CompositeDrawable
{ {
private const int judgement_fade_duration = 5000; private const int judgement_fade_duration = 5000;

View File

@ -53,7 +53,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
} }
} }
private class HitErrorCircle : Container internal class HitErrorCircle : Container
{ {
public bool IsRemoved { get; private set; } public bool IsRemoved { get; private set; }

View File

@ -32,15 +32,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
{ {
base.LoadComplete(); base.LoadComplete();
processor.NewJudgement += onNewJudgement; processor.NewJudgement += OnNewJudgement;
}
private void onNewJudgement(JudgementResult result)
{
if (result.HitObject.HitWindows?.WindowFor(HitResult.Miss) == 0)
return;
OnNewJudgement(result);
} }
protected abstract void OnNewJudgement(JudgementResult judgement); protected abstract void OnNewJudgement(JudgementResult judgement);
@ -74,7 +66,7 @@ namespace osu.Game.Screens.Play.HUD.HitErrorMeters
base.Dispose(isDisposing); base.Dispose(isDisposing);
if (processor != null) if (processor != null)
processor.NewJudgement -= onNewJudgement; processor.NewJudgement -= OnNewJudgement;
} }
} }
} }