1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 22:07:25 +08:00

reverted overwritten file

This commit is contained in:
Xexxar 2021-10-21 18:37:06 +00:00
parent d6aa2fe6e4
commit 2f8972b529

View File

@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
private int countMeh; private int countMeh;
private int countMiss; private int countMiss;
private int effectiveMissCount;
public OsuPerformanceCalculator(Ruleset ruleset, DifficultyAttributes attributes, ScoreInfo score) public OsuPerformanceCalculator(Ruleset ruleset, DifficultyAttributes attributes, ScoreInfo score)
: base(ruleset, attributes, score) : base(ruleset, attributes, score)
{ {
@ -39,16 +41,23 @@ namespace osu.Game.Rulesets.Osu.Difficulty
countOk = Score.Statistics.GetValueOrDefault(HitResult.Ok); countOk = Score.Statistics.GetValueOrDefault(HitResult.Ok);
countMeh = Score.Statistics.GetValueOrDefault(HitResult.Meh); countMeh = Score.Statistics.GetValueOrDefault(HitResult.Meh);
countMiss = Score.Statistics.GetValueOrDefault(HitResult.Miss); countMiss = Score.Statistics.GetValueOrDefault(HitResult.Miss);
effectiveMissCount = calculateEffectiveMissCount();
// Custom multipliers for NoFail and SpunOut.
double multiplier = 1.12; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things. double multiplier = 1.12; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things.
// Custom multipliers for NoFail and SpunOut.
if (mods.Any(m => m is OsuModNoFail)) if (mods.Any(m => m is OsuModNoFail))
multiplier *= Math.Max(0.90, 1.0 - 0.02 * countMiss); multiplier *= Math.Max(0.90, 1.0 - 0.02 * effectiveMissCount);
if (mods.Any(m => m is OsuModSpunOut)) if (mods.Any(m => m is OsuModSpunOut))
multiplier *= 1.0 - Math.Pow((double)Attributes.SpinnerCount / totalHits, 0.85); multiplier *= 1.0 - Math.Pow((double)Attributes.SpinnerCount / totalHits, 0.85);
if (mods.Any(h => h is OsuModRelax))
{
effectiveMissCount += countOk + countMeh;
multiplier *= 0.6;
}
double aimValue = computeAimValue(); double aimValue = computeAimValue();
double speedValue = computeSpeedValue(); double speedValue = computeSpeedValue();
double accuracyValue = computeAccuracyValue(); double accuracyValue = computeAccuracyValue();
@ -91,8 +100,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
aimValue *= lengthBonus; aimValue *= lengthBonus;
// Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses. // Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (countMiss > 0) if (effectiveMissCount > 0)
aimValue *= 0.97 * Math.Pow(1 - Math.Pow((double)countMiss / totalHits, 0.775), countMiss); aimValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), effectiveMissCount);
// Combo scaling. // Combo scaling.
if (Attributes.MaxCombo > 0) if (Attributes.MaxCombo > 0)
@ -108,9 +117,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double approachRateBonus = 1.0 + (0.03 + 0.37 * approachRateTotalHitsFactor) * approachRateFactor; double approachRateBonus = 1.0 + (0.03 + 0.37 * approachRateTotalHitsFactor) * approachRateFactor;
// We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR. if (mods.Any(m => m is OsuModBlinds))
if (mods.Any(h => h is OsuModHidden)) aimValue *= 1.3 + (totalHits * (0.0016 / (1 + 2 * effectiveMissCount)) * Math.Pow(accuracy, 16)) * (1 - 0.003 * Attributes.DrainRate * Attributes.DrainRate);
else if (mods.Any(h => h is OsuModHidden))
{
// We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR.
aimValue *= 1.0 + 0.04 * (12.0 - Attributes.ApproachRate); aimValue *= 1.0 + 0.04 * (12.0 - Attributes.ApproachRate);
}
aimValue *= approachRateBonus; aimValue *= approachRateBonus;
@ -132,8 +145,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
speedValue *= lengthBonus; speedValue *= lengthBonus;
// Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses. // Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (countMiss > 0) if (effectiveMissCount > 0)
speedValue *= 0.97 * Math.Pow(1 - Math.Pow((double)countMiss / totalHits, 0.775), Math.Pow(countMiss, .875)); speedValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), Math.Pow(effectiveMissCount, .875));
// Combo scaling. // Combo scaling.
if (Attributes.MaxCombo > 0) if (Attributes.MaxCombo > 0)
@ -147,11 +160,20 @@ namespace osu.Game.Rulesets.Osu.Difficulty
speedValue *= 1.0 + (0.03 + 0.37 * approachRateTotalHitsFactor) * approachRateFactor; speedValue *= 1.0 + (0.03 + 0.37 * approachRateTotalHitsFactor) * approachRateFactor;
if (mods.Any(m => m is OsuModHidden)) if (mods.Any(m => m is OsuModBlinds))
{
// Increasing the speed value by object count for Blinds isn't ideal, so the minimum buff is given.
speedValue *= 1.12;
}
else if (mods.Any(m => m is OsuModHidden))
{
// We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR.
speedValue *= 1.0 + 0.04 * (12.0 - Attributes.ApproachRate); speedValue *= 1.0 + 0.04 * (12.0 - Attributes.ApproachRate);
}
// Scale the speed value with accuracy and OD. // Scale the speed value with accuracy and OD.
speedValue *= (0.95 + Math.Pow(Attributes.OverallDifficulty, 2) / 750) * Math.Pow(accuracy, (14.5 - Math.Max(Attributes.OverallDifficulty, 8)) / 2); speedValue *= (0.95 + Math.Pow(Attributes.OverallDifficulty, 2) / 750) * Math.Pow(accuracy, (14.5 - Math.Max(Attributes.OverallDifficulty, 8)) / 2);
// Scale the speed value with # of 50s to punish doubletapping. // Scale the speed value with # of 50s to punish doubletapping.
speedValue *= Math.Pow(0.98, countMeh < totalHits / 500.0 ? 0 : countMeh - totalHits / 500.0); speedValue *= Math.Pow(0.98, countMeh < totalHits / 500.0 ? 0 : countMeh - totalHits / 500.0);
@ -160,6 +182,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
private double computeAccuracyValue() private double computeAccuracyValue()
{ {
if (mods.Any(h => h is OsuModRelax))
return 0.0;
// This percentage only considers HitCircles of any value - in this part of the calculation we focus on hitting the timing hit window. // This percentage only considers HitCircles of any value - in this part of the calculation we focus on hitting the timing hit window.
double betterAccuracyPercentage; double betterAccuracyPercentage;
int amountHitObjectsWithAccuracy = Attributes.HitCircleCount; int amountHitObjectsWithAccuracy = Attributes.HitCircleCount;
@ -180,8 +205,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty
// Bonus for many hitcircles - it's harder to keep good accuracy up for longer. // Bonus for many hitcircles - it's harder to keep good accuracy up for longer.
accuracyValue *= Math.Min(1.15, Math.Pow(amountHitObjectsWithAccuracy / 1000.0, 0.3)); accuracyValue *= Math.Min(1.15, Math.Pow(amountHitObjectsWithAccuracy / 1000.0, 0.3));
if (mods.Any(m => m is OsuModHidden)) // Increasing the accuracy value by object count for Blinds isn't ideal, so the minimum buff is given.
if (mods.Any(m => m is OsuModBlinds))
accuracyValue *= 1.14;
else if (mods.Any(m => m is OsuModHidden))
accuracyValue *= 1.08; accuracyValue *= 1.08;
if (mods.Any(m => m is OsuModFlashlight)) if (mods.Any(m => m is OsuModFlashlight))
accuracyValue *= 1.02; accuracyValue *= 1.02;
@ -205,8 +234,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
flashlightValue *= 1.3; flashlightValue *= 1.3;
// Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses. // Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (countMiss > 0) if (effectiveMissCount > 0)
flashlightValue *= 0.97 * Math.Pow(1 - Math.Pow((double)countMiss / totalHits, 0.775), Math.Pow(countMiss, .875)); flashlightValue *= 0.97 * Math.Pow(1 - Math.Pow((double)effectiveMissCount / totalHits, 0.775), Math.Pow(effectiveMissCount, .875));
// Combo scaling. // Combo scaling.
if (Attributes.MaxCombo > 0) if (Attributes.MaxCombo > 0)
@ -224,6 +253,24 @@ namespace osu.Game.Rulesets.Osu.Difficulty
return flashlightValue; return flashlightValue;
} }
private int calculateEffectiveMissCount()
{
// guess the number of misses + slider breaks from combo
double comboBasedMissCount = 0.0;
if (Attributes.SliderCount > 0)
{
double fullComboThreshold = Attributes.MaxCombo - 0.1 * Attributes.SliderCount;
if (scoreMaxCombo < fullComboThreshold)
comboBasedMissCount = fullComboThreshold / Math.Max(1.0, scoreMaxCombo);
}
// we're clamping misscount because since its derived from combo it can be higher than total hits and that breaks some calculations
comboBasedMissCount = Math.Min(comboBasedMissCount, totalHits);
return Math.Max(countMiss, (int)Math.Floor(comboBasedMissCount));
}
private int totalHits => countGreat + countOk + countMeh + countMiss; private int totalHits => countGreat + countOk + countMeh + countMiss;
private int totalSuccessfulHits => countGreat + countOk + countMeh; private int totalSuccessfulHits => countGreat + countOk + countMeh;
} }