mirror of
https://github.com/ppy/osu.git
synced 2026-06-05 17:54:14 +08:00
Buff precision difficulty rating in osu! (#28877)
* Buff precision difficulty rating in osu! * Fix position repetition calculation * Fix aim evaluator crashing, move small circle bonus calculation, adjust the curve slightly * Refactor * Fix code quality * Semicolon * Apply small circle bonus to speed too * Fix formatting --------- Co-authored-by: James Wilson <tsunyoku@gmail.com>
This commit is contained in:
@@ -34,6 +34,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
|
||||
var osuCurrObj = (OsuDifficultyHitObject)current;
|
||||
var osuLastObj = (OsuDifficultyHitObject)current.Previous(0);
|
||||
var osuLastLastObj = (OsuDifficultyHitObject)current.Previous(1);
|
||||
var osuLast2Obj = (OsuDifficultyHitObject)current.Previous(2);
|
||||
|
||||
const int radius = OsuDifficultyHitObject.NORMALISED_RADIUS;
|
||||
const int diameter = OsuDifficultyHitObject.NORMALISED_DIAMETER;
|
||||
@@ -103,6 +104,21 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
|
||||
* DifficultyCalculationUtils.Smootherstep(osuLastObj.LazyJumpDistance, radius, diameter)
|
||||
* Math.Pow(DifficultyCalculationUtils.ReverseLerp(osuLastObj.LazyJumpDistance, diameter * 3, diameter), 1.8)
|
||||
* DifficultyCalculationUtils.Smootherstep(lastAngle, double.DegreesToRadians(110), double.DegreesToRadians(60));
|
||||
|
||||
if (osuLast2Obj != null)
|
||||
{
|
||||
// If objects just go back and forth through a middle point - don't give as much wide bonus
|
||||
// Use Previous(2) and Previous(0) because angles calculation is done prevprev-prev-curr, so any object's angle's center point is always the previous object
|
||||
var lastBaseObject = (OsuHitObject)osuLastObj.BaseObject;
|
||||
var last2BaseObject = (OsuHitObject)osuLast2Obj.BaseObject;
|
||||
|
||||
float distance = (last2BaseObject.StackedPosition - lastBaseObject.StackedPosition).Length;
|
||||
|
||||
if (distance < 1)
|
||||
{
|
||||
wideAngleBonus *= 1 - 0.35 * (1 - distance);
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -139,6 +155,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
|
||||
if (withSliderTravelDistance)
|
||||
aimStrain += sliderBonus * slider_multiplier;
|
||||
|
||||
// Apply high circle size bonus
|
||||
aimStrain *= osuCurrObj.SmallCircleBonus;
|
||||
|
||||
return aimStrain;
|
||||
}
|
||||
|
||||
|
||||
@@ -60,6 +60,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
|
||||
// Max distance bonus is 1 * `distance_multiplier` at single_spacing_threshold
|
||||
double distanceBonus = Math.Pow(distance / single_spacing_threshold, 3.95) * distance_multiplier;
|
||||
|
||||
// Apply reduced small circle bonus because flow aim difficulty on small circles doesn't scale as hard as jumps
|
||||
distanceBonus *= Math.Sqrt(osuCurrObj.SmallCircleBonus);
|
||||
|
||||
if (mods.OfType<OsuModAutopilot>().Any())
|
||||
distanceBonus = 0;
|
||||
|
||||
|
||||
@@ -105,6 +105,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
||||
/// </summary>
|
||||
public double HitWindowGreat { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Selective bonus for maps with higher circle size.
|
||||
/// </summary>
|
||||
public double SmallCircleBonus { get; private set; }
|
||||
|
||||
private readonly OsuDifficultyHitObject? lastLastDifficultyObject;
|
||||
private readonly OsuDifficultyHitObject? lastDifficultyObject;
|
||||
|
||||
@@ -117,6 +122,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
||||
// Capped to 25ms to prevent difficulty calculation breaking from simultaneous objects.
|
||||
StrainTime = Math.Max(DeltaTime, MIN_DELTA_TIME);
|
||||
|
||||
SmallCircleBonus = Math.Max(1.0, 1.0 + (30 - BaseObject.Radius) / 40);
|
||||
|
||||
if (BaseObject is Slider sliderObject)
|
||||
{
|
||||
HitWindowGreat = 2 * sliderObject.HeadCircle.HitWindows.WindowFor(HitResult.Great) / clockRate;
|
||||
@@ -193,12 +200,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
||||
// We will scale distances by this factor, so we can assume a uniform CircleSize among beatmaps.
|
||||
float scalingFactor = NORMALISED_RADIUS / (float)BaseObject.Radius;
|
||||
|
||||
if (BaseObject.Radius < 30)
|
||||
{
|
||||
float smallCircleBonus = Math.Min(30 - (float)BaseObject.Radius, 5) / 50;
|
||||
scalingFactor *= 1 + smallCircleBonus;
|
||||
}
|
||||
|
||||
Vector2 lastCursorPosition = lastDifficultyObject != null ? getEndCursorPosition(lastDifficultyObject) : LastObject.StackedPosition;
|
||||
|
||||
LazyJumpDistance = (BaseObject.StackedPosition * scalingFactor - lastCursorPosition * scalingFactor).Length;
|
||||
|
||||
Reference in New Issue
Block a user