From 40d1196aea1871751f6094d8878a4457045854ad Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 4 Sep 2023 11:15:35 +0200 Subject: [PATCH] Add test cases covering overlapping slider input expectations --- .../TestSceneLegacyHitPolicy.cs | 54 +++++++++++++++++++ .../TestSceneStartTimeOrderedHitPolicy.cs | 52 ++++++++++++++++++ 2 files changed, 106 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyHitPolicy.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyHitPolicy.cs index 2cfbe6611f..c9aa44eb5a 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyHitPolicy.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyHitPolicy.cs @@ -505,6 +505,54 @@ namespace osu.Game.Rulesets.Osu.Tests addClickActionAssert(0, ClickAction.Shake); } + [Test] + public void TestInputDoesNotFallThroughOverlappingSliders() + { + const double time_first_slider = 1000; + const double time_second_slider = 1250; + Vector2 positionFirstSlider = new Vector2(100, 50); + Vector2 positionSecondSlider = new Vector2(100, 80); + var midpoint = (positionFirstSlider + positionSecondSlider) / 2; + + var hitObjects = new List + { + new Slider + { + StartTime = time_first_slider, + Position = positionFirstSlider, + Path = new SliderPath(PathType.Linear, new[] + { + Vector2.Zero, + new Vector2(25, 0), + }) + }, + new Slider + { + StartTime = time_second_slider, + Position = positionSecondSlider, + Path = new SliderPath(PathType.Linear, new[] + { + Vector2.Zero, + new Vector2(25, 0), + }) + } + }; + + performTest(hitObjects, new List + { + new OsuReplayFrame { Time = time_first_slider, Position = midpoint, Actions = { OsuAction.RightButton } }, + new OsuReplayFrame { Time = time_first_slider + 25, Position = midpoint, Actions = { OsuAction.LeftButton } }, + new OsuReplayFrame { Time = time_first_slider + 50, Position = midpoint }, + }); + + addJudgementAssert(hitObjects[0], HitResult.Ok); + addJudgementOffsetAssert("first slider head", () => ((Slider)hitObjects[0]).HeadCircle, 0); + addJudgementAssert(hitObjects[1], HitResult.Miss); + // the slider head of the first slider prevents the second slider's head from being hit, so the judgement offset should be very late. + addJudgementOffsetAssert("second slider head", () => ((Slider)hitObjects[1]).HeadCircle, referenceHitWindows.WindowFor(HitResult.Meh)); + addClickActionAssert(0, ClickAction.Hit); + } + private void addJudgementAssert(OsuHitObject hitObject, HitResult result) { AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judgement is {result}", @@ -523,6 +571,12 @@ namespace osu.Game.Rulesets.Osu.Tests () => judgementResults.Single(r => r.HitObject == hitObject).TimeOffset, () => Is.EqualTo(offset).Within(50)); } + private void addJudgementOffsetAssert(string name, Func hitObject, double offset) + { + AddAssert($"{name} @ judged at {offset}", + () => judgementResults.Single(r => r.HitObject == hitObject()).TimeOffset, () => Is.EqualTo(offset).Within(50)); + } + private void addClickActionAssert(int inputIndex, ClickAction action) => AddAssert($"input #{inputIndex} resulted in {action}", () => testPolicy.ClickActions[inputIndex], () => Is.EqualTo(action)); diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs index f4257a9ee7..909eb821cf 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestSceneStartTimeOrderedHitPolicy.cs @@ -336,6 +336,52 @@ namespace osu.Game.Rulesets.Osu.Tests addJudgementAssert(hitObjects[1], HitResult.IgnoreHit); } + [Test] + public void TestInputFallsThroughJudgedSliders() + { + const double time_first_slider = 1000; + const double time_second_slider = 1250; + Vector2 positionFirstSlider = new Vector2(100, 50); + Vector2 positionSecondSlider = new Vector2(100, 80); + var midpoint = (positionFirstSlider + positionSecondSlider) / 2; + + var hitObjects = new List + { + new TestSlider + { + StartTime = time_first_slider, + Position = positionFirstSlider, + Path = new SliderPath(PathType.Linear, new[] + { + Vector2.Zero, + new Vector2(25, 0), + }) + }, + new TestSlider + { + StartTime = time_second_slider, + Position = positionSecondSlider, + Path = new SliderPath(PathType.Linear, new[] + { + Vector2.Zero, + new Vector2(25, 0), + }) + } + }; + + performTest(hitObjects, new List + { + new OsuReplayFrame { Time = time_first_slider, Position = midpoint, Actions = { OsuAction.RightButton } }, + new OsuReplayFrame { Time = time_first_slider + 25, Position = midpoint, Actions = { OsuAction.LeftButton } }, + new OsuReplayFrame { Time = time_first_slider + 50, Position = midpoint }, + }); + + addJudgementAssert("first slider head", () => ((Slider)hitObjects[0]).HeadCircle, HitResult.Great); + addJudgementOffsetAssert("first slider head", () => ((Slider)hitObjects[0]).HeadCircle, 0); + addJudgementAssert("second slider head", () => ((Slider)hitObjects[1]).HeadCircle, HitResult.Great); + addJudgementOffsetAssert("second slider head", () => ((Slider)hitObjects[1]).HeadCircle, -200); + } + private void addJudgementAssert(OsuHitObject hitObject, HitResult result) { AddAssert($"({hitObject.GetType().ReadableName()} @ {hitObject.StartTime}) judgement is {result}", @@ -354,6 +400,12 @@ namespace osu.Game.Rulesets.Osu.Tests () => Precision.AlmostEquals(judgementResults.Single(r => r.HitObject == hitObject).TimeOffset, offset, 100)); } + private void addJudgementOffsetAssert(string name, Func hitObject, double offset) + { + AddAssert($"{name} @ judged at {offset}", + () => judgementResults.Single(r => r.HitObject == hitObject()).TimeOffset, () => Is.EqualTo(offset).Within(50)); + } + private ScoreAccessibleReplayPlayer currentPlayer; private List judgementResults;