1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-31 14:25:10 +08:00

Fix osu!catch "buzz slider" SR abuse (#31126)

* Implement fix for catch buzz sliders SR abuse

* Run formatting

---------

Co-authored-by: StanR <hi@stanr.info>
This commit is contained in:
Bastien D. 2025-01-18 20:26:23 +01:00 committed by GitHub
parent 8354cd5f93
commit 67723b3e52
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194

View File

@ -26,7 +26,9 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
private float? lastPlayerPosition; private float? lastPlayerPosition;
private float lastDistanceMoved; private float lastDistanceMoved;
private float lastExactDistanceMoved;
private double lastStrainTime; private double lastStrainTime;
private bool isBuzzSliderTriggered;
/// <summary> /// <summary>
/// The speed multiplier applied to the player's catcher. /// The speed multiplier applied to the player's catcher.
@ -59,6 +61,9 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
float distanceMoved = playerPosition - lastPlayerPosition.Value; float distanceMoved = playerPosition - lastPlayerPosition.Value;
// For the exact position we consider that the catcher is in the correct position for both objects
float exactDistanceMoved = catchCurrent.NormalizedPosition - lastPlayerPosition.Value;
double weightedStrainTime = catchCurrent.StrainTime + 13 + (3 / catcherSpeedMultiplier); double weightedStrainTime = catchCurrent.StrainTime + 13 + (3 / catcherSpeedMultiplier);
double distanceAddition = (Math.Pow(Math.Abs(distanceMoved), 1.3) / 510); double distanceAddition = (Math.Pow(Math.Abs(distanceMoved), 1.3) / 510);
@ -92,12 +97,30 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
playerPosition = catchCurrent.NormalizedPosition; playerPosition = catchCurrent.NormalizedPosition;
} }
distanceAddition *= 1.0 + edgeDashBonus * ((20 - catchCurrent.LastObject.DistanceToHyperDash) / 20) * Math.Pow((Math.Min(catchCurrent.StrainTime * catcherSpeedMultiplier, 265) / 265), 1.5); // Edge Dashes are easier at lower ms values distanceAddition *= 1.0 + edgeDashBonus * ((20 - catchCurrent.LastObject.DistanceToHyperDash) / 20)
* Math.Pow((Math.Min(catchCurrent.StrainTime * catcherSpeedMultiplier, 265) / 265), 1.5); // Edge Dashes are easier at lower ms values
}
// There is an edge case where horizontal back and forth sliders create "buzz" patterns which are repeated "movements" with a distance lower than
// the platter's width but high enough to be considered a movement due to the absolute_player_positioning_error and normalized_hitobject_radius offsets
// We are detecting this exact scenario. The first back and forth is counted but all subsequent ones are nullified.
// To achieve that, we need to store the exact distances (distance ignoring absolute_player_positioning_error and normalized_hitobject_radius)
if (Math.Abs(exactDistanceMoved) <= HalfCatcherWidth * 2 && exactDistanceMoved == -lastExactDistanceMoved && catchCurrent.StrainTime == lastStrainTime)
{
if (isBuzzSliderTriggered)
distanceAddition = 0;
else
isBuzzSliderTriggered = true;
}
else
{
isBuzzSliderTriggered = false;
} }
lastPlayerPosition = playerPosition; lastPlayerPosition = playerPosition;
lastDistanceMoved = distanceMoved; lastDistanceMoved = distanceMoved;
lastStrainTime = catchCurrent.StrainTime; lastStrainTime = catchCurrent.StrainTime;
lastExactDistanceMoved = exactDistanceMoved;
return distanceAddition / weightedStrainTime; return distanceAddition / weightedStrainTime;
} }