1
0
mirror of https://github.com/ppy/osu.git synced 2026-06-04 02:13:39 +08:00

Nerf Low AR HD bonus for slideraim (#34215)

* Refactor slider factor calculation

* Nerf low AR HD bonus for slideraim

* finish merge

* Fixes

* Fix comment

---------

Co-authored-by: James Wilson <tsunyoku@gmail.com>
This commit is contained in:
Givikap120
2025-08-09 22:40:37 +03:00
committed by GitHub
Unverified
parent fa1fea02dc
commit dce4132209
3 changed files with 13 additions and 10 deletions
@@ -98,11 +98,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double speedDifficultyValue = speed.DifficultyValue();
double mechanicalDifficultyRating = calculateMechanicalDifficultyRating(aimDifficultyValue, speedDifficultyValue);
double sliderFactor = aimDifficultyValue > 0 ? OsuRatingCalculator.CalculateDifficultyRating(aimNoSlidersDifficultyValue) / OsuRatingCalculator.CalculateDifficultyRating(aimDifficultyValue) : 1;
var osuRatingCalculator = new OsuRatingCalculator(mods, totalHits, approachRate, overallDifficulty, mechanicalDifficultyRating);
var osuRatingCalculator = new OsuRatingCalculator(mods, totalHits, approachRate, overallDifficulty, mechanicalDifficultyRating, sliderFactor);
double aimRating = osuRatingCalculator.ComputeAimRating(aimDifficultyValue);
double aimRatingNoSliders = osuRatingCalculator.ComputeAimRating(aimNoSlidersDifficultyValue);
double speedRating = osuRatingCalculator.ComputeSpeedRating(speedDifficultyValue);
double flashlightRating = 0.0;
@@ -110,8 +110,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (flashlight is not null)
flashlightRating = osuRatingCalculator.ComputeFlashlightRating(flashlight.DifficultyValue());
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
double sliderNestedScorePerObject = LegacyScoreUtils.CalculateNestedScorePerObject(beatmap, totalHits);
double legacyScoreBaseMultiplier = LegacyScoreUtils.CalculateDifficultyPeppyStars(beatmap);
@@ -209,7 +209,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
aimValue *= 1.3 + (totalHits * (0.0016 / (1 + 2 * effectiveMissCount)) * Math.Pow(accuracy, 16)) * (1 - 0.003 * attributes.DrainRate * attributes.DrainRate);
else if (score.Mods.Any(m => m is OsuModTraceable))
{
aimValue *= 1.0 + OsuRatingCalculator.CalculateVisibilityBonus(score.Mods, approachRate);
aimValue *= 1.0 + OsuRatingCalculator.CalculateVisibilityBonus(score.Mods, approachRate, attributes.SliderFactor);
}
aimValue *= accuracy;
@@ -18,14 +18,16 @@ namespace osu.Game.Rulesets.Osu.Difficulty
private readonly double approachRate;
private readonly double overallDifficulty;
private readonly double mechanicalDifficultyRating;
private readonly double sliderFactor;
public OsuRatingCalculator(Mod[] mods, int totalHits, double approachRate, double overallDifficulty, double mechanicalDifficultyRating)
public OsuRatingCalculator(Mod[] mods, int totalHits, double approachRate, double overallDifficulty, double mechanicalDifficultyRating, double sliderFactor)
{
this.mods = mods;
this.totalHits = totalHits;
this.approachRate = approachRate;
this.overallDifficulty = overallDifficulty;
this.mechanicalDifficultyRating = mechanicalDifficultyRating;
this.sliderFactor = sliderFactor;
}
public double ComputeAimRating(double aimDifficultyValue)
@@ -66,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (mods.Any(m => m is OsuModHidden))
{
double visibilityFactor = calculateAimVisibilityFactor(approachRate);
ratingMultiplier += CalculateVisibilityBonus(mods, approachRate, visibilityFactor);
ratingMultiplier += CalculateVisibilityBonus(mods, approachRate, visibilityFactor, sliderFactor);
}
// It is important to consider accuracy difficulty when scaling with accuracy.
@@ -179,7 +181,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
/// <summary>
/// Calculates a visibility bonus that is applicable to Hidden and Traceable.
/// </summary>
public static double CalculateVisibilityBonus(Mod[] mods, double approachRate, double visibilityFactor = 1)
public static double CalculateVisibilityBonus(Mod[] mods, double approachRate, double visibilityFactor = 1, double sliderFactor = 1)
{
// NOTE: TC's effect is only noticeable in performance calculations until lazer mods are accounted for server-side.
bool isAlwaysPartiallyVisible = mods.OfType<OsuModHidden>().Any(m => m.OnlyFadeApproachCircles.Value) || mods.OfType<OsuModTraceable>().Any();
@@ -189,13 +191,16 @@ namespace osu.Game.Rulesets.Osu.Difficulty
readingBonus *= visibilityFactor;
// We want to reward slideraim on low AR less
double sliderVisibilityFactor = Math.Pow(sliderFactor, 3);
// For AR up to 0 - reduce reward for very low ARs when object is visible
if (approachRate < 7)
readingBonus += (isAlwaysPartiallyVisible ? 0.03 : 0.045) * (7.0 - Math.Max(approachRate, 0));
readingBonus += (isAlwaysPartiallyVisible ? 0.03 : 0.045) * (7.0 - Math.Max(approachRate, 0)) * sliderVisibilityFactor;
// Starting from AR0 - cap values so they won't grow to infinity
if (approachRate < 0)
readingBonus += (isAlwaysPartiallyVisible ? 0.075 : 0.1) * (1 - Math.Pow(1.5, approachRate));
readingBonus += (isAlwaysPartiallyVisible ? 0.075 : 0.1) * (1 - Math.Pow(1.5, approachRate)) * sliderVisibilityFactor;
return readingBonus;
}