1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-22 00:30:45 +08:00

Fix low distance snap/flow relation (#37306)

Currently all low spaced (<radius) aim is evaluated as low difficulty
snap. After we separated snap, flow and agility we don't actually need
snap aim to be reduced for low distance - this is something that flow
aim should cover instead as low spacing is guaranteed to be either
flowed or not aimed at all. By extension this fixes the need for the
flow velocity bonus to be extremely high as it no longer clashes with
snap when the changes happen between low and high spacing.
This commit is contained in:
StanR
2026-04-15 22:39:08 +03:00
committed by GitHub
Unverified
parent b20b3670af
commit a057138eaf
3 changed files with 9 additions and 11 deletions
@@ -3,7 +3,6 @@
using System;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Utils;
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
using osu.Game.Rulesets.Osu.Objects;
@@ -11,7 +10,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators.Aim
{
public static class AgilityEvaluator
{
private const double distance_cap = OsuDifficultyHitObject.NORMALISED_DIAMETER * 1.25; // 1.25 circles distance between centers
private const double distance_cap = OsuDifficultyHitObject.NORMALISED_DIAMETER * 1.2; // 1.25 circles distance between centers
/// <summary>
/// Evaluates the difficulty of fast aiming
@@ -35,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators.Aim
strain *= highBpmBonus(osuCurrObj.AdjustedDeltaTime);
return strain * DifficultyCalculationUtils.Smootherstep(distance, 0, OsuDifficultyHitObject.NORMALISED_RADIUS);
return strain;
}
private static double highBpmBonus(double ms) => 1 / (1 - Math.Pow(0.2, ms / 1000));
@@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators.Aim
{
public static class FlowAimEvaluator
{
private const double velocity_change_multiplier = 2.0;
private const double velocity_change_multiplier = 0.52;
/// <summary>
/// Evaluates difficulty of "flow aim" - aiming pattern where player doesn't stop their cursor on every object and instead "flows" through them.
@@ -108,7 +108,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators.Aim
}
// Final velocity is being raised to a power because flow difficulty scales harder with both high distance and time, and we want to account for that
return Math.Pow(flowDifficulty, 1.45);
flowDifficulty = Math.Pow(flowDifficulty, 1.45);
// Reduce difficulty for low spacing since spacing below radius is always to be flowed
return flowDifficulty * DifficultyCalculationUtils.Smootherstep(currDistance, 0, OsuDifficultyHitObject.NORMALISED_RADIUS);
}
private static double calculateOverlapFactor(OsuDifficultyHitObject first, OsuDifficultyHitObject second)
@@ -152,16 +152,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators.Aim
// Apply high circle size bonus
aimStrain *= osuCurrObj.SmallCircleBonus;
aimStrain *= highBpmBonus(osuCurrObj.AdjustedDeltaTime, osuCurrObj.LazyJumpDistance);
aimStrain *= highBpmBonus(osuCurrObj.AdjustedDeltaTime);
return aimStrain;
}
// We decrease strain for distances <radius to fix cases where doubles with no aim requirement
// have their strain buffed incredibly high due to the delta time.
// These objects do not require any movement, so it does not make sense to award them.
private static double highBpmBonus(double ms, double distance) => 1 / (1 - Math.Pow(0.03, Math.Pow(ms / 1000, 0.65)))
* DifficultyCalculationUtils.Smootherstep(distance, 0, OsuDifficultyHitObject.NORMALISED_RADIUS);
private static double highBpmBonus(double ms) => 1 / (1 - Math.Pow(0.03, Math.Pow(ms / 1000, 0.65)));
private static double vectorAngleRepetition(OsuDifficultyHitObject current, OsuDifficultyHitObject previous)
{