1
0
mirror of https://github.com/ppy/osu.git synced 2026-06-05 19:36:03 +08:00

Fix crashes when attempting to adjust length of slider whose maximum path length is less than the current beat snap

Closes https://github.com/ppy/osu/issues/32289.

There are two possible choices here: either pulling the lower bound of
the clamp down to `HitObject.Path.CalculatedDistance`, or pulling the
higher bound up to `minDistance`, if it happens to be larger than the
path's calculated distance.

Both options are a bit weird; pulling down can result in unsnapped
sliders when attempting to drag a slider's end when on a lower beat
divisor than was used to place the slider, and pulling up can result in
weird sliders wherein they get extended beyond their path's definition
with a weird linear section at the end without an anchor that is tangent
to the slider shape's end. I decided the first one was less weird, but
I'm open to discuss further.
This commit is contained in:
Bartłomiej Dach
2025-05-14 13:33:13 +02:00
Unverified
parent 93fda73062
commit 9b2f25cb93
@@ -275,6 +275,13 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
else
{
double minDistance = distanceSnapProvider?.GetBeatSnapDistance() * oldVelocityMultiplier ?? 1;
// do not allow the slider to extend beyond the path's calculated distance.
// this can happen in two specific circumstances:
// - floating point issues (`minDistance` is just ever so slightly larger than the calculated distance)
// - the slider was placed with a higher beat snap active than the current one,
// therefore snapping it to the current beat snap distance would mean extrapolating it beyond its actual shape as defined by its control points
minDistance = Math.Min(minDistance, HitObject.Path.CalculatedDistance);
// Add a small amount to the proposed distance to make it easier to snap to the full length of the slider.
proposedDistance = distanceSnapProvider?.FindSnappedDistance((float)proposedDistance + 1, HitObject.StartTime, HitObject) ?? proposedDistance;
proposedDistance = Math.Clamp(proposedDistance, minDistance, HitObject.Path.CalculatedDistance);