diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderLateHitJudgement.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderLateHitJudgement.cs
index 78633369c7..e1797e877e 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneSliderLateHitJudgement.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSliderLateHitJudgement.cs
@@ -341,6 +341,45 @@ public void TestHitLateWithEdgeHit()
assertSliderJudgement(HitResult.IgnoreHit);
}
+ ///
+ /// Late hit and release on each slider head of a slider stream.
+ ///
+ [Test]
+ public void TestLateHitSliderStream()
+ {
+ var beatmap = new Beatmap();
+
+ for (int i = 0; i < 20; i++)
+ {
+ beatmap.HitObjects.Add(new Slider
+ {
+ StartTime = time_slider_start + 75 * i, // 200BPM @ 1/4
+ Position = new Vector2(256 - slider_path_length / 2, 192),
+ TickDistanceMultiplier = 3,
+ Path = new SliderPath(PathType.LINEAR, new[]
+ {
+ Vector2.Zero,
+ new Vector2(20, 0),
+ }),
+ });
+ }
+
+ var replay = new List();
+
+ for (int i = 0; i < 20; i++)
+ {
+ replay.Add(new OsuReplayFrame(time_slider_start + 75 * i + 75, slider_start_position, i % 2 == 0 ? OsuAction.LeftButton : OsuAction.RightButton));
+ replay.Add(new OsuReplayFrame(time_slider_start + 75 * i + 140, slider_start_position));
+ }
+
+ performTest(replay, beatmap);
+
+ assertHeadJudgement(HitResult.Meh);
+ assertTickJudgement(0, HitResult.LargeTickMiss);
+ assertTailJudgement(HitResult.IgnoreMiss);
+ assertSliderJudgement(HitResult.IgnoreHit);
+ }
+
private void assertHeadJudgement(HitResult result)
{
AddAssert(
@@ -406,21 +445,36 @@ private void performTest(List frames, Action? adjustSliderF
adjustSliderFunc?.Invoke(slider);
+ var beatmap = new Beatmap
+ {
+ HitObjects = { slider },
+ BeatmapInfo =
+ {
+ Difficulty = new BeatmapDifficulty
+ {
+ SliderMultiplier = 4,
+ SliderTickRate = 3
+ },
+ Ruleset = new OsuRuleset().RulesetInfo,
+ }
+ };
+
+ performTest(frames, beatmap);
+ }
+
+ private void performTest(List frames, Beatmap beatmap)
+ {
+ beatmap.BeatmapInfo.Ruleset = new OsuRuleset().RulesetInfo;
+ beatmap.BeatmapInfo.StackLeniency = 0;
+ beatmap.BeatmapInfo.Difficulty = new BeatmapDifficulty
+ {
+ SliderMultiplier = 4,
+ SliderTickRate = 3,
+ };
+
AddStep("load player", () =>
{
- Beatmap.Value = CreateWorkingBeatmap(new Beatmap
- {
- HitObjects = { slider },
- BeatmapInfo =
- {
- Difficulty = new BeatmapDifficulty
- {
- SliderMultiplier = 4,
- SliderTickRate = 3
- },
- Ruleset = new OsuRuleset().RulesetInfo,
- }
- });
+ Beatmap.Value = CreateWorkingBeatmap(beatmap);
var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } });
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs
index d698ba56c4..8aa982783e 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs
@@ -162,18 +162,7 @@ public void TryJudgeNestedObject(DrawableOsuHitObject nestedObject, double timeO
}
if (!slider.HeadCircle.Judged)
- {
- if (Tracking)
- {
- // Attempt to preserve correct ordering of judgements as best we can by forcing an un-judged head to be missed when the user has clearly skipped it.
- slider.HeadCircle.MissForcefully();
- }
- else
- {
- // Don't judge this object as a miss before the head has been judged, to allow the head to be hit late.
- return;
- }
- }
+ return;
if (Tracking)
nestedObject.HitForcefully();