mirror of
https://github.com/ppy/osu.git
synced 2025-01-31 04:32:57 +08:00
Merge branch '!pp-dev' into remove-angle-bonus-rhythm-restriction
This commit is contained in:
commit
23d9e0e695
@ -191,7 +191,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
|
|
||||||
aimValue *= accuracy;
|
aimValue *= accuracy;
|
||||||
// It is important to consider accuracy difficulty when scaling with accuracy.
|
// It is important to consider accuracy difficulty when scaling with accuracy.
|
||||||
aimValue *= 0.98 + Math.Pow(attributes.OverallDifficulty, 2) / 2500;
|
aimValue *= 0.98 + Math.Pow(Math.Max(0, attributes.OverallDifficulty), 2) / 2500;
|
||||||
|
|
||||||
return aimValue;
|
return aimValue;
|
||||||
}
|
}
|
||||||
@ -238,7 +238,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
double relevantAccuracy = attributes.SpeedNoteCount == 0 ? 0 : (relevantCountGreat * 6.0 + relevantCountOk * 2.0 + relevantCountMeh) / (attributes.SpeedNoteCount * 6.0);
|
double relevantAccuracy = attributes.SpeedNoteCount == 0 ? 0 : (relevantCountGreat * 6.0 + relevantCountOk * 2.0 + relevantCountMeh) / (attributes.SpeedNoteCount * 6.0);
|
||||||
|
|
||||||
// Scale the speed value with accuracy and OD.
|
// Scale the speed value with accuracy and OD.
|
||||||
speedValue *= (0.95 + Math.Pow(attributes.OverallDifficulty, 2) / 750) * Math.Pow((accuracy + relevantAccuracy) / 2.0, (14.5 - attributes.OverallDifficulty) / 2);
|
speedValue *= (0.95 + Math.Pow(Math.Max(0, attributes.OverallDifficulty), 2) / 750) * Math.Pow((accuracy + relevantAccuracy) / 2.0, (14.5 - attributes.OverallDifficulty) / 2);
|
||||||
|
|
||||||
// Scale the speed value with # of 50s to punish doubletapping.
|
// Scale the speed value with # of 50s to punish doubletapping.
|
||||||
speedValue *= Math.Pow(0.99, countMeh < totalHits / 500.0 ? 0 : countMeh - totalHits / 500.0);
|
speedValue *= Math.Pow(0.99, countMeh < totalHits / 500.0 ? 0 : countMeh - totalHits / 500.0);
|
||||||
@ -305,7 +305,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
// Scale the flashlight value with accuracy _slightly_.
|
// Scale the flashlight value with accuracy _slightly_.
|
||||||
flashlightValue *= 0.5 + accuracy / 2.0;
|
flashlightValue *= 0.5 + accuracy / 2.0;
|
||||||
// It is important to also consider accuracy difficulty when doing that.
|
// It is important to also consider accuracy difficulty when doing that.
|
||||||
flashlightValue *= 0.98 + Math.Pow(attributes.OverallDifficulty, 2) / 2500;
|
flashlightValue *= 0.98 + Math.Pow(Math.Max(0, attributes.OverallDifficulty), 2) / 2500;
|
||||||
|
|
||||||
return flashlightValue;
|
return flashlightValue;
|
||||||
}
|
}
|
||||||
|
@ -14,13 +14,13 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
{
|
{
|
||||||
protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko";
|
protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko";
|
||||||
|
|
||||||
[TestCase(3.0950934814938953d, 200, "diffcalc-test")]
|
[TestCase(2.837609165845338d, 200, "diffcalc-test")]
|
||||||
[TestCase(3.0950934814938953d, 200, "diffcalc-test-strong")]
|
[TestCase(2.837609165845338d, 200, "diffcalc-test-strong")]
|
||||||
public void Test(double expectedStarRating, int expectedMaxCombo, string name)
|
public void Test(double expectedStarRating, int expectedMaxCombo, string name)
|
||||||
=> base.Test(expectedStarRating, expectedMaxCombo, name);
|
=> base.Test(expectedStarRating, expectedMaxCombo, name);
|
||||||
|
|
||||||
[TestCase(4.0839365008715403d, 200, "diffcalc-test")]
|
[TestCase(3.8005218640444949, 200, "diffcalc-test")]
|
||||||
[TestCase(4.0839365008715403d, 200, "diffcalc-test-strong")]
|
[TestCase(3.8005218640444949, 200, "diffcalc-test-strong")]
|
||||||
public void TestClockRateAdjusted(double expectedStarRating, int expectedMaxCombo, string name)
|
public void TestClockRateAdjusted(double expectedStarRating, int expectedMaxCombo, string name)
|
||||||
=> Test(expectedStarRating, expectedMaxCombo, name, new TaikoModDoubleTime());
|
=> Test(expectedStarRating, expectedMaxCombo, name, new TaikoModDoubleTime());
|
||||||
|
|
||||||
|
@ -36,18 +36,70 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
|
|||||||
return 2 * (1 - DifficultyCalculationUtils.Logistic(exponent: Math.E * repeatingHitPattern.RepetitionInterval - 2 * Math.E));
|
return 2 * (1 - DifficultyCalculationUtils.Logistic(exponent: Math.E * repeatingHitPattern.RepetitionInterval - 2 * Math.E));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Calculates a consistency penalty based on the number of consecutive consistent intervals,
|
||||||
|
/// considering the delta time between each colour sequence.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="hitObject">The current hitObject to consider.</param>
|
||||||
|
/// <param name="threshold"> The allowable margin of error for determining whether ratios are consistent.</param>
|
||||||
|
/// <param name="maxObjectsToCheck">The maximum objects to check per count of consistent ratio.</param>
|
||||||
|
private static double consistentRatioPenalty(TaikoDifficultyHitObject hitObject, double threshold = 0.01, int maxObjectsToCheck = 64)
|
||||||
|
{
|
||||||
|
int consistentRatioCount = 0;
|
||||||
|
double totalRatioCount = 0.0;
|
||||||
|
|
||||||
|
TaikoDifficultyHitObject current = hitObject;
|
||||||
|
|
||||||
|
for (int i = 0; i < maxObjectsToCheck; i++)
|
||||||
|
{
|
||||||
|
// Break if there is no valid previous object
|
||||||
|
if (current.Index <= 1)
|
||||||
|
break;
|
||||||
|
|
||||||
|
var previousHitObject = (TaikoDifficultyHitObject)current.Previous(1);
|
||||||
|
|
||||||
|
double currentRatio = current.Rhythm.Ratio;
|
||||||
|
double previousRatio = previousHitObject.Rhythm.Ratio;
|
||||||
|
|
||||||
|
// A consistent interval is defined as the percentage difference between the two rhythmic ratios with the margin of error.
|
||||||
|
if (Math.Abs(1 - currentRatio / previousRatio) <= threshold)
|
||||||
|
{
|
||||||
|
consistentRatioCount++;
|
||||||
|
totalRatioCount += currentRatio;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Move to the previous object
|
||||||
|
current = previousHitObject;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Ensure no division by zero
|
||||||
|
double ratioPenalty = 1 - totalRatioCount / (consistentRatioCount + 1) * 0.80;
|
||||||
|
|
||||||
|
return ratioPenalty;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Evaluate the difficulty of the first hitobject within a colour streak.
|
||||||
|
/// </summary>
|
||||||
public static double EvaluateDifficultyOf(DifficultyHitObject hitObject)
|
public static double EvaluateDifficultyOf(DifficultyHitObject hitObject)
|
||||||
{
|
{
|
||||||
TaikoDifficultyHitObjectColour colour = ((TaikoDifficultyHitObject)hitObject).Colour;
|
var taikoObject = (TaikoDifficultyHitObject)hitObject;
|
||||||
|
TaikoDifficultyHitObjectColour colour = taikoObject.Colour;
|
||||||
double difficulty = 0.0d;
|
double difficulty = 0.0d;
|
||||||
|
|
||||||
if (colour.MonoStreak?.FirstHitObject == hitObject) // Difficulty for MonoStreak
|
if (colour.MonoStreak?.FirstHitObject == hitObject) // Difficulty for MonoStreak
|
||||||
difficulty += EvaluateDifficultyOf(colour.MonoStreak);
|
difficulty += EvaluateDifficultyOf(colour.MonoStreak);
|
||||||
|
|
||||||
if (colour.AlternatingMonoPattern?.FirstHitObject == hitObject) // Difficulty for AlternatingMonoPattern
|
if (colour.AlternatingMonoPattern?.FirstHitObject == hitObject) // Difficulty for AlternatingMonoPattern
|
||||||
difficulty += EvaluateDifficultyOf(colour.AlternatingMonoPattern);
|
difficulty += EvaluateDifficultyOf(colour.AlternatingMonoPattern);
|
||||||
|
|
||||||
if (colour.RepeatingHitPattern?.FirstHitObject == hitObject) // Difficulty for RepeatingHitPattern
|
if (colour.RepeatingHitPattern?.FirstHitObject == hitObject) // Difficulty for RepeatingHitPattern
|
||||||
difficulty += EvaluateDifficultyOf(colour.RepeatingHitPattern);
|
difficulty += EvaluateDifficultyOf(colour.RepeatingHitPattern);
|
||||||
|
|
||||||
|
double consistencyPenalty = consistentRatioPenalty(taikoObject);
|
||||||
|
difficulty *= consistencyPenalty;
|
||||||
|
|
||||||
return difficulty;
|
return difficulty;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user