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:
parent
60e2a8ed4b
commit
5640918c8c
@ -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; }
|
||||
|
||||
|
@ -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,
|
||||
|
@ -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;
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user