Skip to content

Fixes for mania simulate command #252

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 7 commits into
base: master
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from 3 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
25 changes: 22 additions & 3 deletions PerformanceCalculator/Simulate/ManiaSimulateCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -36,12 +36,14 @@

public override Ruleset Ruleset => new ManiaRuleset();

protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap, Mod[] mods) => generateHitResults(beatmap, Accuracy / 100, Misses, Mehs, oks, Goods, greats);
protected override Dictionary<HitResult, int> GenerateHitResults(IBeatmap beatmap, Mod[] mods) => generateHitResults(beatmap, mods, Accuracy / 100, Misses, Mehs, oks, Goods, greats);

private static Dictionary<HitResult, int> generateHitResults(IBeatmap beatmap, double accuracy, int countMiss, int? countMeh, int? countOk, int? countGood, int? countGreat)
private static Dictionary<HitResult, int> generateHitResults(IBeatmap beatmap, Mod[] mods, double accuracy, int countMiss, int? countMeh, int? countOk, int? countGood, int? countGreat)
{
// One judgement per normal note. Two judgements per hold note (head + tail).
int totalHits = beatmap.HitObjects.Count + beatmap.HitObjects.Count(ho => ho is HoldNote);
int totalHits = beatmap.HitObjects.Count;
if (!mods.Any(m => m.Acronym == "CL"))

Check notice on line 45 in PerformanceCalculator/Simulate/ManiaSimulateCommand.cs

View workflow job for this annotation

GitHub Actions / Code Quality

Simplify LINQ expression (use 'All') in PerformanceCalculator\Simulate\ManiaSimulateCommand.cs on line 45
totalHits += beatmap.HitObjects.Count(ho => ho is HoldNote);

if (countMeh != null || countOk != null || countGood != null || countGreat != null)
{
Expand Down Expand Up @@ -96,5 +98,22 @@
{ HitResult.Miss, countMiss }
};
}

protected override double GetAccuracy(IBeatmap beatmap, Dictionary<HitResult, int> statistics)
{
int countPerfect = statistics[HitResult.Perfect];
int countGreat = statistics[HitResult.Great];
int countGood = statistics[HitResult.Good];
int countOk = statistics[HitResult.Ok];
int countMeh = statistics[HitResult.Meh];
int countMiss = statistics[HitResult.Miss];

int perfectWeight = Mods != null && Mods.Any(m => m == "CL") ? 300 : 305;

double total = perfectWeight * countPerfect + 300 * countGreat + 200 * countGood + 100 * countOk + 50 * countMeh;
double max = perfectWeight * (countPerfect + countGreat + countGood + countOk + countMeh + countMiss);

return total / max;
}
}
}
25 changes: 15 additions & 10 deletions PerformanceCalculatorGUI/RulesetHelper.cs
Original file line number Diff line number Diff line change
Expand Up @@ -10,6 +10,7 @@
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Mania;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Objects;
Expand Down Expand Up @@ -61,14 +62,14 @@
return (int)Math.Round(1000000 * scoreMultiplier);
}

public static Dictionary<HitResult, int> GenerateHitResultsForRuleset(RulesetInfo ruleset, double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood, int? countLargeTickMisses, int? countSliderTailMisses)
public static Dictionary<HitResult, int> GenerateHitResultsForRuleset(RulesetInfo ruleset, double accuracy, IBeatmap beatmap, Mod[] mods, int countMiss, int? countMeh, int? countGood, int? countLargeTickMisses, int? countSliderTailMisses)
{
return ruleset.OnlineID switch
{
0 => generateOsuHitResults(accuracy, beatmap, countMiss, countMeh, countGood, countLargeTickMisses, countSliderTailMisses),
1 => generateTaikoHitResults(accuracy, beatmap, countMiss, countGood),
2 => generateCatchHitResults(accuracy, beatmap, countMiss, countMeh, countGood),
3 => generateManiaHitResults(accuracy, beatmap, countMiss),
3 => generateManiaHitResults(accuracy, beatmap, mods, countMiss),
_ => throw new ArgumentException("Invalid ruleset ID provided.")
};
}
Expand Down Expand Up @@ -225,9 +226,11 @@
};
}

private static Dictionary<HitResult, int> generateManiaHitResults(double accuracy, IBeatmap beatmap, int countMiss)
private static Dictionary<HitResult, int> generateManiaHitResults(double accuracy, IBeatmap beatmap, Mod[] mods, int countMiss)
{
int totalResultCount = beatmap.HitObjects.Count;
if (!mods.Any(m => m.Acronym == "CL"))

Check notice on line 232 in PerformanceCalculatorGUI/RulesetHelper.cs

View workflow job for this annotation

GitHub Actions / Code Quality

Simplify LINQ expression (use 'All') in PerformanceCalculatorGUI\RulesetHelper.cs on line 232
totalResultCount += beatmap.HitObjects.Count(ho => ho is HoldNote);

// Let Great=6, Good=2, Meh=1, Miss=0. The total should be this.
int targetTotal = (int)Math.Round(accuracy * totalResultCount * 6);
Expand All @@ -254,14 +257,14 @@
};
}

public static double GetAccuracyForRuleset(RulesetInfo ruleset, IBeatmap beatmap, Dictionary<HitResult, int> statistics)
public static double GetAccuracyForRuleset(RulesetInfo ruleset, IBeatmap beatmap, Dictionary<HitResult, int> statistics, Mod[] mods)
{
return ruleset.OnlineID switch
{
0 => getOsuAccuracy(beatmap, statistics),
1 => getTaikoAccuracy(statistics),
2 => getCatchAccuracy(statistics),
3 => getManiaAccuracy(statistics),
3 => getManiaAccuracy(statistics, mods),
_ => 0.0
};
}
Expand Down Expand Up @@ -314,19 +317,21 @@
return hits / total;
}

private static double getManiaAccuracy(Dictionary<HitResult, int> statistics)
private static double getManiaAccuracy(Dictionary<HitResult, int> statistics, Mod[] mods)
{
int countPerfect = statistics[HitResult.Perfect];
int countGreat = statistics[HitResult.Great];
int countGood = statistics[HitResult.Good];
int countOk = statistics[HitResult.Ok];
int countMeh = statistics[HitResult.Meh];
int countMiss = statistics[HitResult.Miss];
int total = countPerfect + countGreat + countGood + countOk + countMeh + countMiss;

return (double)
((6 * (countPerfect + countGreat)) + (4 * countGood) + (2 * countOk) + countMeh) /
(6 * total);
int perfectWeight = mods.Any(m => m.Acronym == "CL") ? 300 : 305;

double total = perfectWeight * countPerfect + 300 * countGreat + 200 * countGood + 100 * countOk + 50 * countMeh;
double max = perfectWeight * (countPerfect + countGreat + countGood + countOk + countMeh + countMiss);

return total / max;
}
}
}
6 changes: 3 additions & 3 deletions PerformanceCalculatorGUI/Screens/SimulateScreen.cs
Original file line number Diff line number Diff line change
Expand Up @@ -733,16 +733,16 @@ private void calculatePerformance()
// official rulesets can generate more precise hits from accuracy
if (appliedMods.Value.OfType<OsuModClassic>().Any(m => m.NoSliderHeadAccuracy.Value))
{
statistics = RulesetHelper.GenerateHitResultsForRuleset(ruleset.Value, accuracyTextBox.Value.Value / 100.0, beatmap, missesTextBox.Value.Value, countMeh, countGood,
statistics = RulesetHelper.GenerateHitResultsForRuleset(ruleset.Value, accuracyTextBox.Value.Value / 100.0, beatmap, appliedMods.Value.ToArray(), missesTextBox.Value.Value, countMeh, countGood,
null, null);
}
else
{
statistics = RulesetHelper.GenerateHitResultsForRuleset(ruleset.Value, accuracyTextBox.Value.Value / 100.0, beatmap, missesTextBox.Value.Value, countMeh, countGood,
statistics = RulesetHelper.GenerateHitResultsForRuleset(ruleset.Value, accuracyTextBox.Value.Value / 100.0, beatmap, appliedMods.Value.ToArray(), missesTextBox.Value.Value, countMeh, countGood,
largeTickMissesTextBox.Value.Value, sliderTailMissesTextBox.Value.Value);
}

accuracy = RulesetHelper.GetAccuracyForRuleset(ruleset.Value, beatmap, statistics);
accuracy = RulesetHelper.GetAccuracyForRuleset(ruleset.Value, beatmap, statistics, appliedMods.Value.ToArray());
}

var ppAttributes = performanceCalculator?.Calculate(new ScoreInfo(beatmap.BeatmapInfo, ruleset.Value)
Expand Down
Loading