Skip to content

Commit

Permalink
Use betterAccuracyPercentage Everywhere
Browse files Browse the repository at this point in the history
Someone brought this up during discussion, and from what I can tell, there's no real reason why this wasn't done either.

All this does is use the number of circles instead of the number of objects for accuracy calculations, since circles are the only objects that check for accuracy.

Could also be merged with ppy#27063 to use circles + sliders when sliders check for accuracy (aka when classic mod is disabled). Currently the code for that is included but commented out.
  • Loading branch information
Finadoggie committed Mar 22, 2024
1 parent 42aa372 commit 65e125f
Showing 1 changed file with 14 additions and 13 deletions.
27 changes: 14 additions & 13 deletions osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ public class OsuPerformanceCalculator : PerformanceCalculator
private int countMiss;

private double effectiveMissCount;
private int amountHitObjectsWithAccuracy;

public OsuPerformanceCalculator()
: base(new OsuRuleset())
Expand All @@ -39,7 +40,16 @@ protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo s
countMeh = score.Statistics.GetValueOrDefault(HitResult.Meh);
countMiss = score.Statistics.GetValueOrDefault(HitResult.Miss);
effectiveMissCount = calculateEffectiveMissCount(osuAttributes);
accuracy = calculateEffectiveAccuracy(countGreat, countOk, countMeh, countMiss, totalHits);

amountHitObjectsWithAccuracy = osuAttributes.HitCircleCount;
// Potential merge with #27063
//if (!score.Mods.Any(h => h is OsuModClassic cl && cl.NoSliderHeadAccuracy.Value))
// amountHitObjectsWithAccuracy += osuAttributes.SliderCount;

if (amountHitObjectsWithAccuracy > 0)
accuracy = calculateEffectiveAccuracy(countGreat - (totalHits - amountHitObjectsWithAccuracy), countOk, countMeh, countMiss, amountHitObjectsWithAccuracy);
else
accuracy = 0;

double multiplier = PERFORMANCE_BASE_MULTIPLIER;

Expand Down Expand Up @@ -190,22 +200,13 @@ private double computeAccuracyValue(ScoreInfo score, OsuDifficultyAttributes att
if (score.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.
double betterAccuracyPercentage;
int amountHitObjectsWithAccuracy = attributes.HitCircleCount;

if (amountHitObjectsWithAccuracy > 0)
betterAccuracyPercentage = calculateEffectiveAccuracy(countGreat - (totalHits - amountHitObjectsWithAccuracy), countOk, countMeh, countMiss, amountHitObjectsWithAccuracy);
else
betterAccuracyPercentage = 0;

// It is possible to reach a negative accuracy with this formula. Cap it at zero - zero points.
if (betterAccuracyPercentage < 0)
betterAccuracyPercentage = 0;
if (accuracy < 0)
accuracy = 0;

// Lots of arbitrary values from testing.
// Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution.
double accuracyValue = Math.Pow(1.52163, attributes.OverallDifficulty) * Math.Pow(betterAccuracyPercentage, 24) * 2.83;
double accuracyValue = Math.Pow(1.52163, attributes.OverallDifficulty) * Math.Pow(accuracy, 24) * 2.83;

// 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));
Expand Down

0 comments on commit 65e125f

Please sign in to comment.