mirror of
https://github.com/ppy/osu.git
synced 2025-01-31 13:33:20 +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")]
|
[JsonProperty("slider_factor")]
|
||||||
public double SliderFactor { get; set; }
|
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")]
|
[JsonProperty("approach_rate")]
|
||||||
public double ApproachRate { get; set; }
|
public double ApproachRate { get; set; }
|
||||||
|
|
||||||
|
@ -40,6 +40,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
|
|
||||||
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
|
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))
|
if (mods.Any(h => h is OsuModRelax))
|
||||||
speedRating = 0.0;
|
speedRating = 0.0;
|
||||||
|
|
||||||
@ -78,6 +85,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
SpeedStrain = speedRating,
|
SpeedStrain = speedRating,
|
||||||
FlashlightRating = flashlightRating,
|
FlashlightRating = flashlightRating,
|
||||||
SliderFactor = sliderFactor,
|
SliderFactor = sliderFactor,
|
||||||
|
AimDifficultStrainCount = aimDifficultyStrainCount,
|
||||||
|
SpeedDifficultStrainCount = speedDifficultyStrainCount,
|
||||||
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
|
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
|
||||||
OverallDifficulty = (80 - hitWindowGreat) / 6,
|
OverallDifficulty = (80 - hitWindowGreat) / 6,
|
||||||
DrainRate = drainRate,
|
DrainRate = drainRate,
|
||||||
|
@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
aimValue *= lengthBonus;
|
aimValue *= lengthBonus;
|
||||||
|
|
||||||
if (effectiveMissCount > 0)
|
if (effectiveMissCount > 0)
|
||||||
aimValue *= calculateMissPenalty(effectiveMissCount);
|
aimValue *= calculateMissPenalty(effectiveMissCount, Attributes.AimDifficultStrainCount);
|
||||||
|
|
||||||
double approachRateFactor = 0.0;
|
double approachRateFactor = 0.0;
|
||||||
if (Attributes.ApproachRate > 10.33)
|
if (Attributes.ApproachRate > 10.33)
|
||||||
@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
speedValue *= lengthBonus;
|
speedValue *= lengthBonus;
|
||||||
|
|
||||||
if (effectiveMissCount > 0)
|
if (effectiveMissCount > 0)
|
||||||
speedValue *= calculateMissPenalty(effectiveMissCount);
|
speedValue *= calculateMissPenalty(effectiveMissCount, Attributes.SpeedDifficultStrainCount);
|
||||||
|
|
||||||
double approachRateFactor = 0.0;
|
double approachRateFactor = 0.0;
|
||||||
if (Attributes.ApproachRate > 10.33)
|
if (Attributes.ApproachRate > 10.33)
|
||||||
@ -267,17 +267,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
return Math.Max(countMiss, (int)Math.Floor(comboBasedMissCount));
|
return Math.Max(countMiss, (int)Math.Floor(comboBasedMissCount));
|
||||||
}
|
}
|
||||||
|
|
||||||
private double calculateMissPenalty(double missCount)
|
private double calculateMissPenalty(double missCount, double strainCount)
|
||||||
{
|
{
|
||||||
double leniency = 4.3;
|
return 0.95 / ((missCount / (3 * Math.Sqrt(strainCount))) + 1);
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private int totalHits => countGreat + countOk + countMeh + countMiss;
|
private int totalHits => countGreat + countOk + countMeh + countMiss;
|
||||||
|
@ -57,5 +57,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
|||||||
|
|
||||||
return difficulty * DifficultyMultiplier;
|
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