From 7e557152fb430219ab484107d592311e983094f9 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 22 Dec 2023 12:40:24 +0100 Subject: [PATCH] Fix relax mod not considering full follow area radius when automatically holding sliders Closes https://github.com/ppy/osu/issues/25947. Regressed in https://github.com/ppy/osu/pull/25776 with the changes to `DrawableSliderBall`. I would have liked to include tests, but relax mod is a bit untestable, because it disengages completely in the presence of a replay: https://github.com/ppy/osu/blob/7e09164d7084265536570ac7036d7244934b651c/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs#L49-L58 Additionally, `RulesetInputManager` disengages completely from parent inputs when there is a replay active: https://github.com/ppy/osu/blob/7e09164d7084265536570ac7036d7244934b651c/osu.Game/Rulesets/UI/RulesetInputManager.cs#L116 which means there is really no easy way to control positional input while still having relax logic work. So I'm hoping the fix could be considered obvious enough to not require test coverage. --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 2 +- .../Objects/Drawables/SliderInputManager.cs | 8 ++++---- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index aaa7c70a8d..40fadfb77e 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Mods if (!slider.HeadCircle.IsHit) handleHitCircle(slider.HeadCircle); - requiresHold |= slider.Ball.IsHovered || h.IsHovered; + requiresHold |= slider.SliderInputManager.IsMouseInFollowArea(true); break; case DrawableSpinner spinner: diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs index 8aa982783e..95896c7c91 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs @@ -65,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void Update() { base.Update(); - updateTracking(isMouseInFollowArea(Tracking)); + updateTracking(IsMouseInFollowArea(Tracking)); } public void PostProcessHeadJudgement(DrawableSliderHead head) @@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables if (!head.Judged || !head.Result.IsHit) return; - if (!isMouseInFollowArea(true)) + if (!IsMouseInFollowArea(true)) return; Debug.Assert(screenSpaceMousePosition != null); @@ -129,7 +129,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables // If all ticks were hit so far, enable tracking the full extent. // If any ticks were missed, assume tracking would've broken at some point, and should only activate if the cursor is within the slider ball. // For the second case, this may be the last chance we have to enable tracking before other objects get judged, otherwise the same would normally happen via Update(). - updateTracking(allTicksInRange || isMouseInFollowArea(false)); + updateTracking(allTicksInRange || IsMouseInFollowArea(false)); } public void TryJudgeNestedObject(DrawableOsuHitObject nestedObject, double timeOffset) @@ -174,7 +174,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables /// Whether the mouse is currently in the follow area. /// /// Whether to test against the maximum area of the follow circle. - private bool isMouseInFollowArea(bool expanded) + public bool IsMouseInFollowArea(bool expanded) { if (screenSpaceMousePosition is not Vector2 pos) return false;