1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-18 21:02:56 +08:00

New miss penalty formula, using relevant difficult notes in each skill (targets diffspikes)

This commit is contained in:
apollo-dw 2021-12-26 23:51:49 +00:00
parent 60e2a8ed4b
commit 5640918c8c
4 changed files with 26 additions and 12 deletions

View File

@ -24,6 +24,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty
[JsonProperty("slider_factor")]
public double SliderFactor { get; set; }
[JsonProperty("aim_difficult_strain_count")]
public int AimDifficultStrainCount { get; set; }
[JsonProperty("speed_difficult_strain_count")]
public int SpeedDifficultStrainCount { get; set; }
[JsonProperty("approach_rate")]
public double ApproachRate { get; set; }

View File

@ -40,6 +40,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
int aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).RelevantDifficultStrains();
int speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).RelevantDifficultStrains();
// Total number of strains in a map can vary by clockrate, and this needs to be corrected for.
aimDifficultyStrainCount = (int)(aimDifficultyStrainCount * clockRate);
speedDifficultyStrainCount = (int)(aimDifficultyStrainCount * clockRate);
if (mods.Any(h => h is OsuModRelax))
speedRating = 0.0;
@ -78,6 +85,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
SpeedStrain = speedRating,
FlashlightRating = flashlightRating,
SliderFactor = sliderFactor,
AimDifficultStrainCount = aimDifficultyStrainCount,
SpeedDifficultStrainCount = speedDifficultyStrainCount,
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
OverallDifficulty = (80 - hitWindowGreat) / 6,
DrainRate = drainRate,

View File

@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
aimValue *= lengthBonus;
if (effectiveMissCount > 0)
aimValue *= calculateMissPenalty(effectiveMissCount);
aimValue *= calculateMissPenalty(effectiveMissCount, Attributes.AimDifficultStrainCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
speedValue *= lengthBonus;
if (effectiveMissCount > 0)
speedValue *= calculateMissPenalty(effectiveMissCount);
speedValue *= calculateMissPenalty(effectiveMissCount, Attributes.SpeedDifficultStrainCount);
double approachRateFactor = 0.0;
if (Attributes.ApproachRate > 10.33)
@ -267,17 +267,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
return Math.Max(countMiss, (int)Math.Floor(comboBasedMissCount));
}
private double calculateMissPenalty(double missCount)
private double calculateMissPenalty(double missCount, double strainCount)
{
double leniency = 4.3;
if (missCount > totalHits - leniency)
return 0;
double missApprox = SpecialFunctions.ErfInv((totalHits - leniency - missCount) / totalHits);
double fcApprox = SpecialFunctions.ErfInv((totalHits - leniency) / totalHits);
return Math.Pow(missApprox / fcApprox, 3.5);
return 0.95 / ((missCount / (3 * Math.Sqrt(strainCount))) + 1);
}
private int totalHits => countGreat + countOk + countMeh + countMiss;

View File

@ -57,5 +57,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
return difficulty * DifficultyMultiplier;
}
public int RelevantDifficultStrains()
{
List<double> strains = GetCurrentStrainPeaks().OrderByDescending(d => d).ToList();
return strains.Count(s => s > strains[0] * 0.66);
}
}
}