1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-05 02:53:21 +08:00
This commit is contained in:
KermitNuggies 2024-12-03 16:58:59 +09:00 committed by GitHub
commit 86ab77385d
No known key found for this signature in database
GPG Key ID: B5690EEEBB952194
4 changed files with 49 additions and 14 deletions

View File

@ -52,6 +52,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty
[JsonProperty("speed_difficult_strain_count")]
public double SpeedDifficultStrainCount { get; set; }
// DEV ATTRIBUTE - DO NOT STORE
[JsonProperty("aim_relevant_object_count")]
public double AimRelevantObjectCount { get; set; }
// DEV ATTRIBUTE - DO NOTE STORE
[JsonProperty("speed_relevant_object_count")]
public double SpeedRelevantObjectCount { get; set; }
/// <summary>
/// The perceived approach rate inclusive of rate-adjusting mods (DT/HT/etc).
/// </summary>

View File

@ -46,24 +46,41 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (mods.Any(h => h is OsuModFlashlight))
flashlightRating = Math.Sqrt(skills[3].DifficultyValue()) * difficulty_multiplier;
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
double aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountTopWeightedStrains();
double speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountTopWeightedStrains();
if (mods.Any(m => m is OsuModTouchDevice))
{
aimRating = Math.Pow(aimRating, 0.8);
aimRatingNoSliders = Math.Pow(aimRatingNoSliders, 0.8);
flashlightRating = Math.Pow(flashlightRating, 0.8);
}
if (mods.Any(h => h is OsuModRelax))
{
aimRating *= 0.9;
aimRatingNoSliders *= 0.9;
speedRating = 0.0;
flashlightRating *= 0.7;
}
double aimRelevantObjectCount = ((OsuStrainSkill)skills[0]).CountRelevantObjects();
double aimNoSlidersRelevantObjectCount = ((OsuStrainSkill)skills[1]).CountRelevantObjects();
double speedRelevantObjectCount = ((OsuStrainSkill)skills[2]).CountRelevantObjects();
double aimLengthBonus = (aimRelevantObjectCount < 25 ? 0.8 + aimRelevantObjectCount / 150.0 : 0.9 + Math.Min(1.5, aimRelevantObjectCount / 375.0) +
(aimRelevantObjectCount > 562.5 ? Math.Log10(aimRelevantObjectCount / 562.5) : 0));
aimRating *= Math.Cbrt(aimLengthBonus);
double aimNoSlidersLengthBonus = (aimNoSlidersRelevantObjectCount < 25 ? 0.8 + aimNoSlidersRelevantObjectCount / 150.0 : 0.9 + aimNoSlidersRelevantObjectCount / 375.0);
aimRatingNoSliders *= Math.Cbrt(aimNoSlidersLengthBonus);
double speedLengthBonus = 0.9 + 0.5 * Math.Min(1.0, speedRelevantObjectCount / 500.0) +
(speedRelevantObjectCount > 500 ? Math.Log10(speedRelevantObjectCount / 500.0) * 0.3 : 0.0);
speedRating *= Math.Cbrt(speedLengthBonus);
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
double baseAimPerformance = OsuStrainSkill.DifficultyToPerformance(aimRating);
double baseSpeedPerformance = OsuStrainSkill.DifficultyToPerformance(speedRating);
double baseFlashlightPerformance = 0.0;
@ -79,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
);
double starRating = basePerformance > 0.00001
? Math.Cbrt(OsuPerformanceCalculator.PERFORMANCE_BASE_MULTIPLIER) * 0.027 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4)
? Math.Cbrt(OsuPerformanceCalculator.PERFORMANCE_BASE_MULTIPLIER) * 0.026 * (Math.Cbrt(100000 / Math.Pow(2, 1 / 1.1) * basePerformance) + 4)
: 0;
double preempt = IBeatmapDifficultyInfo.DifficultyRange(beatmap.Difficulty.ApproachRate, 1800, 1200, 450) / clockRate;
@ -105,6 +122,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
SliderFactor = sliderFactor,
AimDifficultStrainCount = aimDifficultyStrainCount,
SpeedDifficultStrainCount = speedDifficultyStrainCount,
AimRelevantObjectCount = aimRelevantObjectCount,
SpeedRelevantObjectCount = speedRelevantObjectCount,
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
OverallDifficulty = (80 - hitWindowGreat) / 6,
DrainRate = drainRate,

View File

@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
{
public class OsuPerformanceCalculator : PerformanceCalculator
{
public const double PERFORMANCE_BASE_MULTIPLIER = 1.15; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things.
public const double PERFORMANCE_BASE_MULTIPLIER = 1.152; // This is being adjusted to keep the final pp value scaled around what it used to be when changing things.
private bool usingClassicSliderAccuracy;
@ -137,10 +137,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty
{
double aimValue = OsuStrainSkill.DifficultyToPerformance(attributes.AimDifficulty);
double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
aimValue *= lengthBonus;
if (effectiveMissCount > 0)
aimValue *= calculateMissPenalty(effectiveMissCount, attributes.AimDifficultStrainCount);
@ -153,7 +149,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (score.Mods.Any(h => h is OsuModRelax))
approachRateFactor = 0.0;
aimValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR.
aimValue *= 1.0 + approachRateFactor;
if (score.Mods.Any(m => m is OsuModBlinds))
aimValue *= 1.3 + (totalHits * (0.0016 / (1 + 2 * effectiveMissCount)) * Math.Pow(accuracy, 16)) * (1 - 0.003 * attributes.DrainRate * attributes.DrainRate);
@ -201,10 +197,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double speedValue = OsuStrainSkill.DifficultyToPerformance(attributes.SpeedDifficulty);
double lengthBonus = 0.95 + 0.4 * Math.Min(1.0, totalHits / 2000.0) +
(totalHits > 2000 ? Math.Log10(totalHits / 2000.0) * 0.5 : 0.0);
speedValue *= lengthBonus;
if (effectiveMissCount > 0)
speedValue *= calculateMissPenalty(effectiveMissCount, attributes.SpeedDifficultStrainCount);
@ -212,7 +204,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (attributes.ApproachRate > 10.33)
approachRateFactor = 0.3 * (attributes.ApproachRate - 10.33);
speedValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR.
speedValue *= 1.0 + approachRateFactor;
if (score.Mods.Any(m => m is OsuModBlinds))
{

View File

@ -57,6 +57,22 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
return difficulty;
}
/// <summary>
/// Returns the number of relevant objects weighted against the top strain.
/// </summary>
public double CountRelevantObjects()
{
double consistentTopStrain = DifficultyValue() / 10; // What would the top strain be if all strain values were identical
if (consistentTopStrain == 0)
return 0.0;
//Being consistently difficult for 1000 notes should be worth more than being consistently difficult for 100.
double totalStrains = ObjectStrains.Count;
double lengthFactor = 0.74 * Math.Pow(0.9987, totalStrains);
//// Use a weighted sum of all strains. Constants are arbitrary and give nice values
return ObjectStrains.Sum(s => (1.1 - lengthFactor)/ (1 + Math.Exp(-10 * (s / consistentTopStrain - 0.88 - lengthFactor / 4.0))));
}
public static double DifficultyToPerformance(double difficulty) => Math.Pow(5.0 * Math.Max(1.0, difficulty / 0.0675) - 4.0, 3.0) / 100000.0;
}
}