Skip to content
Closed
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
12 changes: 2 additions & 10 deletions osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -88,10 +88,6 @@ private double computeAimValue(ScoreInfo score, OsuDifficultyAttributes attribut
{
double aimValue = Math.Pow(5.0 * Math.Max(1.0, attributes.AimDifficulty / 0.0675) - 4.0, 3.0) / 100000.0;

double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
aimValue *= lengthBonus;

// Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (effectiveMissCount > 0)
aimValue *= 0.97 * Math.Pow(1 - Math.Pow(effectiveMissCount / totalHits, 0.775), effectiveMissCount);
Expand All @@ -107,7 +103,7 @@ private double computeAimValue(ScoreInfo score, OsuDifficultyAttributes attribut
if (score.Mods.Any(h => h is OsuModRelax))
approachRateFactor = 0.0;

aimValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR.
aimValue *= 1.0 + approachRateFactor;

if (score.Mods.Any(m => m is OsuModBlinds))
aimValue *= 1.3 + (totalHits * (0.0016 / (1 + 2 * effectiveMissCount)) * Math.Pow(accuracy, 16)) * (1 - 0.003 * attributes.DrainRate * attributes.DrainRate);
Expand Down Expand Up @@ -141,10 +137,6 @@ private double computeSpeedValue(ScoreInfo score, OsuDifficultyAttributes attrib

double speedValue = Math.Pow(5.0 * Math.Max(1.0, attributes.SpeedDifficulty / 0.0675) - 4.0, 3.0) / 100000.0;

double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
speedValue *= lengthBonus;

// Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (effectiveMissCount > 0)
speedValue *= 0.97 * Math.Pow(1 - Math.Pow(effectiveMissCount / totalHits, 0.775), Math.Pow(effectiveMissCount, .875));
Expand All @@ -155,7 +147,7 @@ private double computeSpeedValue(ScoreInfo score, OsuDifficultyAttributes attrib
if (attributes.ApproachRate > 10.33)
approachRateFactor = 0.3 * (attributes.ApproachRate - 10.33);

speedValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR.
speedValue *= 1.0 + approachRateFactor;

if (score.Mods.Any(m => m is OsuModBlinds))
{
Expand Down
13 changes: 11 additions & 2 deletions osu.Game.Rulesets.Osu/Difficulty/Skills/OsuStrainSkill.cs
Original file line number Diff line number Diff line change
Expand Up @@ -34,6 +34,9 @@ public abstract class OsuStrainSkill : StrainSkill
/// </summary>
protected virtual double DifficultyMultiplier => DEFAULT_DIFFICULTY_MULTIPLIER;

private const double a = 10.0;
private const double b = 1.3675;

protected OsuStrainSkill(Mod[] mods)
: base(mods)
{
Expand All @@ -42,7 +45,6 @@ protected OsuStrainSkill(Mod[] mods)
public override double DifficultyValue()
{
double difficulty = 0;
double weight = 1;

// Sections with 0 strain are excluded to avoid worst-case time complexity of the following sort (e.g. /b/2351871).
// These sections will not contribute to the difficulty.
Expand All @@ -57,12 +59,19 @@ public override double DifficultyValue()
strains[i] *= Interpolation.Lerp(ReducedStrainBaseline, 1.0, scale);
}

int index = 0;

// Difficulty is the weighted sum of the highest strains from every section.
// We're sorting from highest to lowest strain.
foreach (double strain in strains.OrderByDescending(d => d))
{
// Below uses harmonic sum scaling which makes the resulting summation logarithmic rather than geometric.
// Good for properly weighting difficulty across full map instead of using object count for LengthBonus.
// a and b are arbitrary constants that worked well.
double weight = b * ((1 + (a / (1 + index))) / (index + 1 + (a / (1 + index))));

difficulty += strain * weight;
weight *= DecayWeight;
index += 1;
}

return difficulty * DifficultyMultiplier;
Expand Down