mirror of
https://github.com/ppy/osu.git
synced 2025-01-31 15:52:55 +08:00
Improve convert considerations in osu!taiko (#31546)
* return a higher finger count * implement isConvert * diffcalc cleanup * harshen monostaminafactor accuracy curve * readd comment * adjusts tests
This commit is contained in:
parent
e320f17faf
commit
e04727afb1
@ -14,13 +14,13 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
||||
{
|
||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko";
|
||||
|
||||
[TestCase(3.3167800835687551d, 200, "diffcalc-test")]
|
||||
[TestCase(3.3167800835687551d, 200, "diffcalc-test-strong")]
|
||||
[TestCase(3.3056113401782845d, 200, "diffcalc-test")]
|
||||
[TestCase(3.3056113401782845d, 200, "diffcalc-test-strong")]
|
||||
public void Test(double expectedStarRating, int expectedMaxCombo, string name)
|
||||
=> base.Test(expectedStarRating, expectedMaxCombo, name);
|
||||
|
||||
[TestCase(4.4631326105105122d, 200, "diffcalc-test")]
|
||||
[TestCase(4.4631326105105122d, 200, "diffcalc-test-strong")]
|
||||
[TestCase(4.4473902679506896d, 200, "diffcalc-test")]
|
||||
[TestCase(4.4473902679506896d, 200, "diffcalc-test-strong")]
|
||||
public void TestClockRateAdjusted(double expectedStarRating, int expectedMaxCombo, string name)
|
||||
=> Test(expectedStarRating, expectedMaxCombo, name, new TaikoModDoubleTime());
|
||||
|
||||
|
@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
|
||||
return 2;
|
||||
}
|
||||
|
||||
return 4;
|
||||
return 8;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -20,6 +20,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
|
||||
private double strainDecayBase => 0.4;
|
||||
|
||||
private readonly bool singleColourStamina;
|
||||
private readonly bool isConvert;
|
||||
|
||||
private double currentStrain;
|
||||
|
||||
@ -28,10 +29,12 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
|
||||
/// </summary>
|
||||
/// <param name="mods">Mods for use in skill calculations.</param>
|
||||
/// <param name="singleColourStamina">Reads when Stamina is from a single coloured pattern.</param>
|
||||
public Stamina(Mod[] mods, bool singleColourStamina)
|
||||
/// <param name="isConvert">Determines if the currently evaluated beatmap is converted.</param>
|
||||
public Stamina(Mod[] mods, bool singleColourStamina, bool isConvert)
|
||||
: base(mods)
|
||||
{
|
||||
this.singleColourStamina = singleColourStamina;
|
||||
this.isConvert = isConvert;
|
||||
}
|
||||
|
||||
private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);
|
||||
@ -45,7 +48,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
|
||||
var currentObject = current as TaikoDifficultyHitObject;
|
||||
int index = currentObject?.Colour.MonoStreak?.HitObjects.IndexOf(currentObject) ?? 0;
|
||||
|
||||
double monolengthBonus = 1 + Math.Min(Math.Max((index - 5) / 50.0, 0), 0.30);
|
||||
double monolengthBonus = isConvert ? 1 : 1 + Math.Min(Math.Max((index - 5) / 50.0, 0), 0.30);
|
||||
|
||||
if (singleColourStamina)
|
||||
return DifficultyCalculationUtils.Logistic(-(index - 10) / 2.0, currentStrain);
|
||||
|
@ -32,6 +32,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
private double strainLengthBonus;
|
||||
private double patternMultiplier;
|
||||
|
||||
private bool isConvert;
|
||||
|
||||
public override int Version => 20241007;
|
||||
|
||||
public TaikoDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
|
||||
@ -44,13 +46,15 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
HitWindows hitWindows = new HitWindows();
|
||||
hitWindows.SetDifficulty(beatmap.Difficulty.OverallDifficulty);
|
||||
|
||||
isConvert = beatmap.BeatmapInfo.Ruleset.OnlineID == 0;
|
||||
|
||||
return new Skill[]
|
||||
{
|
||||
new Rhythm(mods, hitWindows.WindowFor(HitResult.Great) / clockRate),
|
||||
new Reading(mods),
|
||||
new Colour(mods),
|
||||
new Stamina(mods, false),
|
||||
new Stamina(mods, true)
|
||||
new Stamina(mods, false, isConvert),
|
||||
new Stamina(mods, true, isConvert)
|
||||
};
|
||||
}
|
||||
|
||||
@ -130,19 +134,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
+ Math.Min(Math.Max((staminaDifficultStrains - 1350) / 5000, 0), 0.15)
|
||||
+ Math.Min(Math.Max((staminaRating - 7.0) / 1.0, 0), 0.05);
|
||||
|
||||
double combinedRating = combinedDifficultyValue(rhythm, reading, colour, stamina, isRelax);
|
||||
double combinedRating = combinedDifficultyValue(rhythm, reading, colour, stamina, isRelax, isConvert);
|
||||
double starRating = rescale(combinedRating * 1.4);
|
||||
|
||||
// Converts are penalised outside the scope of difficulty calculation, as our assumptions surrounding standard play-styles becomes out-of-scope.
|
||||
if (beatmap.BeatmapInfo.Ruleset.OnlineID == 0)
|
||||
{
|
||||
starRating *= 0.7;
|
||||
|
||||
// For maps with relax, multiple inputs are more likely to be abused.
|
||||
if (isRelax)
|
||||
starRating *= 0.60;
|
||||
}
|
||||
|
||||
HitWindows hitWindows = new TaikoHitWindows();
|
||||
hitWindows.SetDifficulty(beatmap.Difficulty.OverallDifficulty);
|
||||
|
||||
@ -173,7 +167,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
/// For each section, the peak strains of all separate skills are combined into a single peak strain for the section.
|
||||
/// The resulting partial rating of the beatmap is a weighted sum of the combined peaks (higher peaks are weighted more).
|
||||
/// </remarks>
|
||||
private double combinedDifficultyValue(Rhythm rhythm, Reading reading, Colour colour, Stamina stamina, bool isRelax)
|
||||
private double combinedDifficultyValue(Rhythm rhythm, Reading reading, Colour colour, Stamina stamina, bool isRelax, bool isConvert)
|
||||
{
|
||||
List<double> peaks = new List<double>();
|
||||
|
||||
@ -186,14 +180,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
{
|
||||
double rhythmPeak = rhythmPeaks[i] * rhythm_skill_multiplier * patternMultiplier;
|
||||
double readingPeak = readingPeaks[i] * reading_skill_multiplier;
|
||||
double colourPeak = colourPeaks[i] * colour_skill_multiplier;
|
||||
double colourPeak = isRelax ? 0 : colourPeaks[i] * colour_skill_multiplier; // There is no colour difficulty in relax.
|
||||
double staminaPeak = staminaPeaks[i] * stamina_skill_multiplier * strainLengthBonus;
|
||||
|
||||
if (isRelax)
|
||||
{
|
||||
colourPeak = 0; // There is no colour difficulty in relax.
|
||||
staminaPeak /= 1.5; // Stamina difficulty is decreased with an increased available finger count.
|
||||
}
|
||||
staminaPeak /= isConvert || isRelax ? 1.5 : 1.0; // Available finger count is increased by 150%, thus we adjust accordingly.
|
||||
|
||||
double peak = DifficultyCalculationUtils.Norm(2, DifficultyCalculationUtils.Norm(1.5, colourPeak, staminaPeak), rhythmPeak, readingPeak);
|
||||
|
||||
|
@ -97,7 +97,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||
|
||||
// Scale accuracy more harshly on nearly-completely mono (single coloured) speed maps.
|
||||
double accScalingExponent = 2 + attributes.MonoStaminaFactor;
|
||||
double accScalingShift = 500 - 100 * attributes.MonoStaminaFactor;
|
||||
double accScalingShift = 500 - 100 * (attributes.MonoStaminaFactor * 3);
|
||||
|
||||
return difficultyValue * Math.Pow(DifficultyCalculationUtils.Erf(accScalingShift / (Math.Sqrt(2) * estimatedUnstableRate.Value)), accScalingExponent);
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user