mirror of
https://github.com/ppy/osu.git
synced 2024-12-05 02:53:21 +08:00
Merge 67560f1d4d
into be05f2a1c2
This commit is contained in:
commit
86ab77385d
@ -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>
|
||||
|
@ -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,
|
||||
|
@ -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))
|
||||
{
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user