From 51c0d67fc87885b264e9ab36467c7a852785ab2c Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 27 Dec 2024 09:25:39 +0100 Subject: [PATCH 1/3] Add failing test case --- .../Mods/TestSceneOsuModStrictTracking.cs | 34 +++++++++++++++++++ 1 file changed, 34 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModStrictTracking.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModStrictTracking.cs index 66a60e354273..39d5f6696897 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModStrictTracking.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModStrictTracking.cs @@ -49,5 +49,39 @@ public void TestSliderInput() => CreateModTest(new ModTestData }, PassCondition = () => Player.ScoreProcessor.Combo.Value == 2 }); + + [Test] + public void TestReleaseOverSliderBeforeHeadHit() => CreateModTest(new ModTestData + { + Mod = new OsuModStrictTracking(), + Autoplay = false, + CreateBeatmap = () => new Beatmap + { + HitObjects = new List + { + new Slider + { + StartTime = 1000, + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(0, 100)) + } + } + } + } + }, + ReplayFrames = new List + { + new OsuReplayFrame(501, new Vector2(200, 0), OsuAction.LeftButton), + new OsuReplayFrame(1000, new Vector2()), + new OsuReplayFrame(1020, new Vector2(), OsuAction.LeftButton), + new OsuReplayFrame(1750, new Vector2(0, 100), OsuAction.LeftButton), + new OsuReplayFrame(1751, new Vector2(0, 100)), + }, + PassCondition = () => Player.ScoreProcessor.Combo.Value == 2 + }); } } From 04046566295f3c1d8acd2afc06d3882f85725bc3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 27 Dec 2024 09:29:00 +0100 Subject: [PATCH 2/3] Do not force miss slider with strict tracking active if tracking is lost before head was hit Closes https://github.com/ppy/osu/issues/29371. https://github.com/ppy/osu/pull/26053 is a related fix that should probably have included this change but did not go far enough. --- osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs index 7d2fd628f6fd..bf55f3c4c8e0 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModStrictTracking.cs @@ -36,7 +36,7 @@ public void ApplyToDrawableHitObject(DrawableHitObject drawable) { if (e.NewValue || slider.Judged) return; - if (slider.Time.Current < slider.HitObject.StartTime) + if (slider.Time.Current < slider.HitObject.StartTime || !slider.HeadCircle.Judged) return; var tail = slider.NestedHitObjects.OfType().First(); From 033fe3fad541113c47060b1c83949dc398893252 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 27 Dec 2024 09:41:52 +0100 Subject: [PATCH 3/3] Add some extra negative test cases --- .../Mods/TestSceneOsuModStrictTracking.cs | 129 ++++++++++++++++++ 1 file changed, 129 insertions(+) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModStrictTracking.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModStrictTracking.cs index 39d5f6696897..bcc52892da0d 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModStrictTracking.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModStrictTracking.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; using NUnit.Framework; using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; @@ -9,6 +10,7 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Replays; +using osu.Game.Rulesets.Scoring; using osuTK; namespace osu.Game.Rulesets.Osu.Tests.Mods @@ -83,5 +85,132 @@ public void TestReleaseOverSliderBeforeHeadHit() => CreateModTest(new ModTestDat }, PassCondition = () => Player.ScoreProcessor.Combo.Value == 2 }); + + [Test] + public void TestDoNothing() => CreateModTest(new ModTestData + { + Mod = new OsuModStrictTracking(), + Autoplay = false, + CreateBeatmap = () => new Beatmap + { + HitObjects = new List + { + new Slider + { + StartTime = 1000, + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(0, 100)) + } + } + } + } + }, + ReplayFrames = new List + { + new OsuReplayFrame(0, new Vector2()), + }, + PassCondition = () => Player.ScoreProcessor.JudgedHits == 3 && Player.ScoreProcessor.Statistics.All(s => s.Key.IsMiss()) + }); + + [Test] + public void TestMissHeadButTrackRestOfSlider() => CreateModTest(new ModTestData + { + Mod = new OsuModStrictTracking(), + Autoplay = false, + CreateBeatmap = () => new Beatmap + { + HitObjects = new List + { + new Slider + { + StartTime = 1000, + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(0, 100)) + } + } + } + } + }, + ReplayFrames = new List + { + new OsuReplayFrame(0, new Vector2()), + new OsuReplayFrame(1375, new Vector2(0, 50), OsuAction.LeftButton), + new OsuReplayFrame(1751, new Vector2(0, 100)), + }, + PassCondition = () => Player.ScoreProcessor.JudgedHits == 3 && Player.ScoreProcessor.Statistics[HitResult.Miss] == 1 && Player.ScoreProcessor.Statistics[HitResult.Great] == 1 + }); + + [Test] + public void TestMissHeadThenDropTracking() => CreateModTest(new ModTestData + { + Mod = new OsuModStrictTracking(), + Autoplay = false, + CreateBeatmap = () => new Beatmap + { + HitObjects = new List + { + new Slider + { + StartTime = 1000, + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(0, 100)) + } + } + } + } + }, + ReplayFrames = new List + { + new OsuReplayFrame(0, new Vector2()), + new OsuReplayFrame(1375, new Vector2(0, 50), OsuAction.LeftButton), + new OsuReplayFrame(1475, new Vector2(), OsuAction.LeftButton), + }, + PassCondition = () => Player.ScoreProcessor.JudgedHits == 3 && Player.ScoreProcessor.Statistics.All(s => s.Key.IsMiss()) + }); + + [Test] + public void TestLosingTrackingMissesTail() => CreateModTest(new ModTestData + { + Mod = new OsuModStrictTracking(), + Autoplay = false, + CreateBeatmap = () => new Beatmap + { + HitObjects = new List + { + new Slider + { + StartTime = 1000, + Path = new SliderPath + { + ControlPoints = + { + new PathControlPoint(), + new PathControlPoint(new Vector2(0, 100)) + } + } + } + } + }, + ReplayFrames = new List + { + new OsuReplayFrame(0, new Vector2(), OsuAction.LeftButton), + new OsuReplayFrame(500, new Vector2(200, 0), OsuAction.LeftButton), + new OsuReplayFrame(501, new Vector2(200, 0)), + new OsuReplayFrame(1000, new Vector2(), OsuAction.LeftButton), + }, + PassCondition = () => Player.ScoreProcessor.Statistics.GetValueOrDefault(HitResult.Miss) == 1 + }); } }