Show effect of beatmap attributes on gameplay metrics in taiko

This commit is contained in:
Bartłomiej Dach
2025-07-31 14:37:20 +02:00
parent 655733c06d
commit 1f28add95a
2 changed files with 36 additions and 5 deletions

View File

@@ -146,7 +146,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
case IHasDuration endTimeData:
{
double hitMultiplier = IBeatmapDifficultyInfo.DifficultyRange(beatmap.Difficulty.OverallDifficulty, 3, 5, 7.5) * swell_hit_multiplier;
double hitMultiplier = RequiredSwellHitsPerSecond(beatmap.Difficulty.OverallDifficulty);
yield return new Swell
{
@@ -172,6 +172,9 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
}
}
public static double RequiredSwellHitsPerSecond(double overallDifficulty)
=> IBeatmapDifficultyInfo.DifficultyRange(overallDifficulty, 3, 5, 7.5) * swell_hit_multiplier;
private bool shouldConvertSliderToHits(HitObject obj, IBeatmap beatmap, IHasPath pathData, out int taikoDuration, out double tickSpacing)
{
// DO NOT CHANGE OR REFACTOR ANYTHING IN HERE WITHOUT TESTING AGAINST _ALL_ BEATMAPS.

View File

@@ -287,11 +287,39 @@ namespace osu.Game.Rulesets.Taiko
public override IEnumerable<RulesetBeatmapAttribute> GetBeatmapAttributesForDisplay(IBeatmapInfo beatmapInfo, IReadOnlyCollection<Mod> mods)
{
var originalDifficulty = beatmapInfo.Difficulty;
var adjustedDifficulty = GetAdjustedDisplayDifficulty(beatmapInfo, mods);
// `modAdjustedDifficulty` contains only the direct effect of mods.
// `effectiveDifficulty` contains the "perceived" effect of rate-adjusting mods on OD and AR.
// we make a distinction here, because some of the calculations below will require very careful maneuvering between the two for correct results.
var modAdjustedDifficulty = base.GetAdjustedDisplayDifficulty(beatmapInfo, mods);
var effectiveDifficulty = GetAdjustedDisplayDifficulty(beatmapInfo, mods);
var colours = new OsuColour();
yield return new RulesetBeatmapAttribute(SongSelectStrings.Accuracy, @"OD", originalDifficulty.OverallDifficulty, adjustedDifficulty.OverallDifficulty, 10);
yield return new RulesetBeatmapAttribute(SongSelectStrings.HPDrain, @"HP", originalDifficulty.DrainRate, adjustedDifficulty.DrainRate, 10);
yield return new RulesetBeatmapAttribute(SongSelectStrings.ScrollSpeed, @"SS", 1f, (float)(adjustedDifficulty.SliderMultiplier / originalDifficulty.SliderMultiplier), 4);
// when displaying hit window ranges with rate-changing mods active, we will want to adjust for rate ourselves, as `effectiveDifficulty` may not be accurate
// because `TaikoHitWindows` applies a floor-and-round operation that will result in inaccurate results.
var hitWindows = new TaikoHitWindows();
hitWindows.SetDifficulty(modAdjustedDifficulty.OverallDifficulty);
double rate = ModUtils.CalculateRateWithMods(mods);
yield return new RulesetBeatmapAttribute(SongSelectStrings.Accuracy, @"OD", originalDifficulty.OverallDifficulty, effectiveDifficulty.OverallDifficulty, 10)
{
Description = "Affects timing requirements for hits and mash rate requirements for swells.",
AdditionalMetrics =
[
new RulesetBeatmapAttribute.AdditionalMetric("GREAT hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Great) / rate:N1}ms"), colours.ForHitResult(HitResult.Great)),
new RulesetBeatmapAttribute.AdditionalMetric("OK hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Ok) / rate:N1}ms"), colours.ForHitResult(HitResult.Ok)),
new RulesetBeatmapAttribute.AdditionalMetric("MISS hit window", LocalisableString.Interpolate($@"±{hitWindows.WindowFor(HitResult.Miss) / rate:N1}ms"), colours.ForHitResult(HitResult.Miss)),
new RulesetBeatmapAttribute.AdditionalMetric("Hits per second required to clear swells", LocalisableString.Interpolate($@"{TaikoBeatmapConverter.RequiredSwellHitsPerSecond(modAdjustedDifficulty.OverallDifficulty):N1}")),
]
};
yield return new RulesetBeatmapAttribute(SongSelectStrings.HPDrain, @"HP", originalDifficulty.DrainRate, effectiveDifficulty.DrainRate, 10)
{
Description = "Affects the harshness of health drain and the health penalties for missing."
};
yield return new RulesetBeatmapAttribute(SongSelectStrings.ScrollSpeed, @"SS", 1f, (float)(effectiveDifficulty.SliderMultiplier / originalDifficulty.SliderMultiplier), 4)
{
Description = "Multiplier applied to the baseline scroll speed of the playfield when no mods are active."
};
}
}
}