diff --git a/osu.Game.Rulesets.Sentakki/Mods/SentakkiModHardRock.cs b/osu.Game.Rulesets.Sentakki/Mods/SentakkiModHardRock.cs index 13d1a90f9..a8448d704 100644 --- a/osu.Game.Rulesets.Sentakki/Mods/SentakkiModHardRock.cs +++ b/osu.Game.Rulesets.Sentakki/Mods/SentakkiModHardRock.cs @@ -4,13 +4,15 @@ using osu.Game.Configuration; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Sentakki.Localisation.Mods; +using osu.Game.Rulesets.Sentakki.Objects.Drawables; using osu.Game.Rulesets.Sentakki.Scoring; namespace osu.Game.Rulesets.Sentakki.Mods { - public class SentakkiModHardRock : ModHardRock, IApplicableToHitObject + public class SentakkiModHardRock : ModHardRock, IApplicableToHitObject, IApplicableToDrawableHitObject { public override double ScoreMultiplier => 1; @@ -28,6 +30,9 @@ public override void ApplyToDifficulty(BeatmapDifficulty difficulty) [SettingSource(typeof(SentakkiModHardRockStrings), nameof(SentakkiModHardRockStrings.MinimumResult), nameof(SentakkiModHardRockStrings.MinimumResultDescription))] public Bindable MinimumValidResult { get; } = new Bindable(SentakkiHitResult.Good); + [SettingSource("Enable strict slider tracking")] + public Bindable StrictSliderTracking { get; } = new Bindable(false); + public void ApplyToHitObject(HitObject hitObject) { // Nested HitObjects should get the same treatment @@ -41,6 +46,14 @@ public void ApplyToHitObject(HitObject hitObject) shw.JudgementMode = JudgementMode.Value; } + public void ApplyToDrawableHitObject(DrawableHitObject drawable) + { + if (drawable is not DrawableSlideCheckpoint slideCheckpoint) + return; + + slideCheckpoint.StrictSliderTracking = StrictSliderTracking.Value; + } + public enum SentakkiHitResult { Good = 3, diff --git a/osu.Game.Rulesets.Sentakki/Objects/Drawables/DrawableSlideCheckpoint.cs b/osu.Game.Rulesets.Sentakki/Objects/Drawables/DrawableSlideCheckpoint.cs index 911a00a3f..526fe1a3c 100644 --- a/osu.Game.Rulesets.Sentakki/Objects/Drawables/DrawableSlideCheckpoint.cs +++ b/osu.Game.Rulesets.Sentakki/Objects/Drawables/DrawableSlideCheckpoint.cs @@ -29,7 +29,11 @@ public partial class DrawableSlideCheckpoint : DrawableSentakkiHitObject // All hits can only be done after the slide tap has been judged public bool IsHittable => ParentHitObject.IsHittable && isPreviousNodeHit(); - private bool isPreviousNodeHit() => ThisIndex < 1 || ParentHitObject.SlideCheckpoints[ThisIndex - 1].IsHit; + public bool StrictSliderTracking { get; set; } + + private int trackingLookBehindDistance => StrictSliderTracking ? 1 : 2; + + private bool isPreviousNodeHit() => ThisIndex < trackingLookBehindDistance || ParentHitObject.SlideCheckpoints[ThisIndex - trackingLookBehindDistance].IsHit; private Container nodes = null!; @@ -84,6 +88,10 @@ protected override void CheckForResult(bool userTriggered, double timeOffset) if (Judged) return; + // The previous node may not be judged due to slider hit order leniency allowing players to skip up to one node + if (ThisIndex > 0) + ParentHitObject.SlideCheckpoints[ThisIndex - 1].ApplyResult(result); + // Make sure remaining nodes are judged foreach (var node in nodes) node.ApplyResult(result);