mirror of
https://github.com/ppy/osu-tools.git
synced 2025-06-09 09:35:15 +09:00
Merge branch 'master' into mod-options-parameter
This commit is contained in:
commit
cca1f5e3c9
3 changed files with 59 additions and 6 deletions
|
@ -3,11 +3,13 @@
|
|||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using McMaster.Extensions.CommandLineUtils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
|
||||
namespace PerformanceCalculator.Simulate
|
||||
|
@ -31,6 +33,14 @@ namespace PerformanceCalculator.Simulate
|
|||
[Option(Template = "-C|--percent-combo <combo>", Description = "Percentage of beatmap maximum combo achieved. Alternative to combo option. Enter as decimal 0-100.")]
|
||||
public override double PercentCombo { get; } = 100;
|
||||
|
||||
[UsedImplicitly]
|
||||
[Option(Template = "-L|--large-tick-misses <misses>", Description = "Number of large tick misses. Defaults to 0.")]
|
||||
private int largeTickMisses { get; }
|
||||
|
||||
[UsedImplicitly]
|
||||
[Option(Template = "-S|--slider-tail-misses <misses>", Description = "Number of slider tail misses. Defaults to 0.")]
|
||||
private int sliderTailMisses { get; }
|
||||
|
||||
public override Ruleset Ruleset => new OsuRuleset();
|
||||
|
||||
protected override int GetMaxCombo(IBeatmap beatmap) => beatmap.GetMaxCombo();
|
||||
|
@ -116,6 +126,8 @@ namespace PerformanceCalculator.Simulate
|
|||
{ HitResult.Great, countGreat },
|
||||
{ HitResult.Ok, countGood ?? 0 },
|
||||
{ HitResult.Meh, countMeh ?? 0 },
|
||||
{ HitResult.LargeTickMiss, largeTickMisses },
|
||||
{ HitResult.SliderTailHit, beatmap.HitObjects.Count(x => x is Slider) - sliderTailMisses },
|
||||
{ HitResult.Miss, countMiss }
|
||||
};
|
||||
}
|
||||
|
|
|
@ -15,6 +15,7 @@ using osu.Game.Rulesets.Difficulty;
|
|||
using osu.Game.Rulesets.Mania;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Rulesets.Taiko;
|
||||
using osu.Game.Rulesets.Taiko.Objects;
|
||||
|
@ -103,11 +104,11 @@ namespace PerformanceCalculatorGUI
|
|||
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)
|
||||
public static Dictionary<HitResult, int> GenerateHitResultsForRuleset(RulesetInfo ruleset, double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood, int countLargeTickMisses, int countSliderTailMisses)
|
||||
{
|
||||
return ruleset.OnlineID switch
|
||||
{
|
||||
0 => generateOsuHitResults(accuracy, beatmap, countMiss, countMeh, countGood, countLargeTickMisses),
|
||||
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),
|
||||
|
@ -115,7 +116,7 @@ namespace PerformanceCalculatorGUI
|
|||
};
|
||||
}
|
||||
|
||||
private static Dictionary<HitResult, int> generateOsuHitResults(double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood, int? countLargeTickMisses)
|
||||
private static Dictionary<HitResult, int> generateOsuHitResults(double accuracy, IBeatmap beatmap, int countMiss, int? countMeh, int? countGood, int countLargeTickMisses, int countSliderTailMisses)
|
||||
{
|
||||
int countGreat;
|
||||
|
||||
|
@ -191,12 +192,15 @@ namespace PerformanceCalculatorGUI
|
|||
countGreat = (int)(totalResultCount - countGood - countMeh - countMiss);
|
||||
}
|
||||
|
||||
int sliderTailHits = beatmap.HitObjects.Count(x => x is Slider) - countSliderTailMisses;
|
||||
|
||||
return new Dictionary<HitResult, int>
|
||||
{
|
||||
{ HitResult.Great, countGreat },
|
||||
{ HitResult.Ok, countGood ?? 0 },
|
||||
{ HitResult.Meh, countMeh ?? 0 },
|
||||
{ HitResult.LargeTickMiss, countLargeTickMisses ?? 0 },
|
||||
{ HitResult.LargeTickMiss, countLargeTickMisses },
|
||||
{ HitResult.SliderTailHit, sliderTailHits },
|
||||
{ HitResult.Miss, countMiss }
|
||||
};
|
||||
}
|
||||
|
|
|
@ -28,6 +28,7 @@ using osu.Game.Rulesets;
|
|||
using osu.Game.Rulesets.Difficulty;
|
||||
using osu.Game.Rulesets.Difficulty.Skills;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Mods;
|
||||
using osu.Game.Rulesets.Scoring;
|
||||
using osu.Game.Scoring;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
|
@ -51,8 +52,10 @@ namespace PerformanceCalculatorGUI.Screens
|
|||
private LabelledTextBox beatmapIdTextBox;
|
||||
private SwitchButton beatmapImportTypeSwitch;
|
||||
|
||||
private GridContainer missesContainer;
|
||||
private LimitedLabelledNumberBox missesTextBox;
|
||||
private LimitedLabelledNumberBox largeTickMissesTextBox;
|
||||
private LimitedLabelledNumberBox sliderTailMissesTextBox;
|
||||
private LimitedLabelledNumberBox comboTextBox;
|
||||
private LimitedLabelledNumberBox scoreTextBox;
|
||||
|
||||
|
@ -263,12 +266,13 @@ namespace PerformanceCalculatorGUI.Screens
|
|||
PlaceholderText = "0",
|
||||
MinValue = 0
|
||||
},
|
||||
new GridContainer
|
||||
missesContainer = new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
ColumnDimensions = new[]
|
||||
{
|
||||
new Dimension(),
|
||||
new Dimension(),
|
||||
new Dimension()
|
||||
},
|
||||
|
@ -292,6 +296,14 @@ namespace PerformanceCalculatorGUI.Screens
|
|||
Label = "Large Tick Misses",
|
||||
PlaceholderText = "0",
|
||||
MinValue = 0
|
||||
},
|
||||
sliderTailMissesTextBox = new LimitedLabelledNumberBox
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Anchor = Anchor.TopLeft,
|
||||
Label = "Slider Tail Misses",
|
||||
PlaceholderText = "0",
|
||||
MinValue = 0
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -472,6 +484,7 @@ namespace PerformanceCalculatorGUI.Screens
|
|||
mehsTextBox.Value.BindValueChanged(_ => debouncedCalculatePerformance());
|
||||
missesTextBox.Value.BindValueChanged(_ => debouncedCalculatePerformance());
|
||||
largeTickMissesTextBox.Value.BindValueChanged(_ => debouncedCalculatePerformance());
|
||||
sliderTailMissesTextBox.Value.BindValueChanged(_ => debouncedCalculatePerformance());
|
||||
comboTextBox.Value.BindValueChanged(_ => debouncedCalculatePerformance());
|
||||
scoreTextBox.Value.BindValueChanged(_ => debouncedCalculatePerformance());
|
||||
|
||||
|
@ -511,14 +524,35 @@ namespace PerformanceCalculatorGUI.Screens
|
|||
|
||||
private void modsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
|
||||
{
|
||||
void updateMissesTextboxes()
|
||||
{
|
||||
if (ruleset.Value.ShortName == "osu")
|
||||
{
|
||||
// Large tick misses and slider tail misses are only relevant in PP if slider head accuracy exists
|
||||
if (mods.NewValue.OfType<OsuModClassic>().Any(m => m.NoSliderHeadAccuracy.Value))
|
||||
{
|
||||
missesContainer.Content = new[] { new[] { missesTextBox } };
|
||||
missesContainer.ColumnDimensions = [new Dimension()];
|
||||
}
|
||||
else
|
||||
{
|
||||
missesContainer.Content = new[] { new[] { missesTextBox, largeTickMissesTextBox, sliderTailMissesTextBox } };
|
||||
missesContainer.ColumnDimensions = [new Dimension(), new Dimension(), new Dimension()];
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
modSettingChangeTracker?.Dispose();
|
||||
|
||||
if (working is null)
|
||||
return;
|
||||
|
||||
updateMissesTextboxes();
|
||||
|
||||
modSettingChangeTracker = new ModSettingChangeTracker(mods.NewValue);
|
||||
modSettingChangeTracker.SettingChanged += m =>
|
||||
{
|
||||
updateMissesTextboxes();
|
||||
debouncedStatisticsUpdate?.Cancel();
|
||||
debouncedStatisticsUpdate = Scheduler.AddDelayed(() =>
|
||||
{
|
||||
|
@ -663,7 +697,7 @@ namespace PerformanceCalculatorGUI.Screens
|
|||
if (ruleset.Value.OnlineID != -1)
|
||||
{
|
||||
// official rulesets can generate more precise hits from accuracy
|
||||
statistics = RulesetHelper.GenerateHitResultsForRuleset(ruleset.Value, accuracyTextBox.Value.Value / 100.0, beatmap, missesTextBox.Value.Value, countMeh, countGood, largeTickMissesTextBox.Value.Value);
|
||||
statistics = RulesetHelper.GenerateHitResultsForRuleset(ruleset.Value, accuracyTextBox.Value.Value / 100.0, beatmap, missesTextBox.Value.Value, countMeh, countGood, largeTickMissesTextBox.Value.Value, sliderTailMissesTextBox.Value.Value);
|
||||
|
||||
accuracy = RulesetHelper.GetAccuracyForRuleset(ruleset.Value, statistics);
|
||||
}
|
||||
|
@ -700,6 +734,7 @@ namespace PerformanceCalculatorGUI.Screens
|
|||
comboTextBox.Hide();
|
||||
missesTextBox.Hide();
|
||||
largeTickMissesTextBox.Hide();
|
||||
sliderTailMissesTextBox.Hide();
|
||||
scoreTextBox.Hide();
|
||||
|
||||
if (ruleset.Value.ShortName == "osu" || ruleset.Value.ShortName == "taiko" || ruleset.Value.ShortName == "fruits")
|
||||
|
@ -714,6 +749,7 @@ namespace PerformanceCalculatorGUI.Screens
|
|||
if (ruleset.Value.ShortName == "osu")
|
||||
{
|
||||
largeTickMissesTextBox.Show();
|
||||
sliderTailMissesTextBox.Show();
|
||||
}
|
||||
}
|
||||
else if (ruleset.Value.ShortName == "mania")
|
||||
|
@ -736,6 +772,7 @@ namespace PerformanceCalculatorGUI.Screens
|
|||
comboTextBox.Show();
|
||||
missesTextBox.Show();
|
||||
largeTickMissesTextBox.Show();
|
||||
sliderTailMissesTextBox.Show();
|
||||
|
||||
scoreTextBox.Text = string.Empty;
|
||||
scoreTextBox.Show();
|
||||
|
|
Loading…
Add table
Add a link
Reference in a new issue