Skip to content

Commit

Permalink
Difficulty factor + New length bonus based on it
Browse files Browse the repository at this point in the history
  • Loading branch information
TheDark98 committed Jan 14, 2025
1 parent b21c645 commit 3a6fef7
Show file tree
Hide file tree
Showing 5 changed files with 41 additions and 379 deletions.
12 changes: 12 additions & 0 deletions osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -20,6 +20,12 @@ public class OsuDifficultyAttributes : DifficultyAttributes
[JsonProperty("aim_difficulty")]
public double AimDifficulty { get; set; }

/// <summary>
/// The difficulty factor corresponding to the aim skill.
/// </summary>
[JsonProperty("aim_difficulty_factor")]
public double AimDifficultyFactor { get; set; }

/// <summary>
/// The number of <see cref="Slider"/>s weighted by difficulty.
/// </summary>
Expand All @@ -32,6 +38,12 @@ public class OsuDifficultyAttributes : DifficultyAttributes
[JsonProperty("speed_difficulty")]
public double SpeedDifficulty { get; set; }

/// <summary>
/// The difficulty factor corresponding to the speed skill.
/// </summary>
[JsonProperty("speed_difficulty_factor")]
public double SpeedDifficultyFactor { get; set; }

/// <summary>
/// The number of clickable objects weighted by difficulty.
/// Related to <see cref="SpeedDifficulty"/>
Expand Down
5 changes: 5 additions & 0 deletions osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -43,6 +43,9 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat
double difficultSliders = ((Aim)skills[0]).GetDifficultSliders();
double flashlightRating = 0.0;

double aimDifficultyFactor = skills[0].DifficultyFactor;
double speedDifficultyFactor = skills[2].DifficultyFactor;

if (mods.Any(h => h is OsuModFlashlight))
flashlightRating = Math.Sqrt(skills[3].DifficultyValue()) * difficulty_multiplier;

Expand Down Expand Up @@ -107,8 +110,10 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat
StarRating = starRating,
Mods = mods,
AimDifficulty = aimRating,
AimDifficultyFactor = aimDifficultyFactor,
AimDifficultSliderCount = difficultSliders,
SpeedDifficulty = speedRating,
SpeedDifficultyFactor = speedDifficultyFactor,
SpeedNoteCount = speedNotes,
FlashlightDifficulty = flashlightRating,
SliderFactor = sliderFactor,
Expand Down
46 changes: 20 additions & 26 deletions osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -4,6 +4,7 @@
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
using osu.Game.Rulesets.Osu.Difficulty.Skills;
using osu.Game.Rulesets.Osu.Mods;
Expand Down Expand Up @@ -31,6 +32,17 @@ public class OsuPerformanceCalculator : PerformanceCalculator
/// </summary>
private int countSliderTickMiss;


/// <summary>
/// We can have a base length bonus based only from the length of the map.
/// </summary>
private double lengthBonusBase;

/// <summary>
/// The bonus multiplier is a basic multiplier that indicate how strong the impact of Difficulty Factor is.
/// </summary>
private const double bonus_multiplier = 0.3;

/// <summary>
/// Amount of missed slider tails that don't break combo. Will only be correct on non-classic scores
/// </summary>
Expand Down Expand Up @@ -115,6 +127,8 @@ protected override PerformanceAttributes CreatePerformanceAttributes(ScoreInfo s

speedDeviation = calculateSpeedDeviation(osuAttributes);

lengthBonusBase = Math.Max((Math.Log(10.0 + totalHits / 1000.0) - 1.35) * 0.45 + 0.5, 1.0);

double aimValue = computeAimValue(score, osuAttributes);
double speedValue = computeSpeedValue(score, osuAttributes);
double accuracyValue = computeAccuracyValue(score, osuAttributes);
Expand Down Expand Up @@ -170,24 +184,13 @@ private double computeAimValue(ScoreInfo score, OsuDifficultyAttributes attribut

double aimValue = OsuStrainSkill.DifficultyToPerformance(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;
double approachRateBonus = score.Mods.Any(h => h is OsuModRelax) ? 0.0 : attributes.ApproachRate > 10.33 ? 0.3 * (attributes.ApproachRate - 10.33) : attributes.ApproachRate < 8.0 ? 0.05 * (8.0 - attributes.ApproachRate) : 0.0; //AR bonus for higher and lower AR

aimValue *= LengthBonusMultiplier(lengthBonusBase + approachRateBonus, attributes.AimDifficultyFactor, bonus_multiplier);

if (effectiveMissCount > 0)
aimValue *= calculateMissPenalty(effectiveMissCount, attributes.AimDifficultStrainCount);

double approachRateFactor = 0.0;
if (attributes.ApproachRate > 10.33)
approachRateFactor = 0.3 * (attributes.ApproachRate - 10.33);
else if (attributes.ApproachRate < 8.0)
approachRateFactor = 0.05 * (8.0 - attributes.ApproachRate);

if (score.Mods.Any(h => h is OsuModRelax))
approachRateFactor = 0.0;

aimValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR.

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);
else if (score.Mods.Any(m => m is OsuModHidden || m is OsuModTraceable))
Expand All @@ -210,22 +213,13 @@ private double computeSpeedValue(ScoreInfo score, OsuDifficultyAttributes attrib

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;
double approachRateBonus = score.Mods.Any(h => h is OsuModRelax) ? 0.0 : attributes.ApproachRate > 10.33 ? 0.3 * (attributes.ApproachRate - 10.33) : 0.0;

speedValue *= LengthBonusMultiplier(lengthBonusBase, attributes.SpeedDifficultyFactor, bonus_multiplier);

if (effectiveMissCount > 0)
speedValue *= calculateMissPenalty(effectiveMissCount, attributes.SpeedDifficultStrainCount);

double approachRateFactor = 0.0;
if (attributes.ApproachRate > 10.33)
approachRateFactor = 0.3 * (attributes.ApproachRate - 10.33);

if (score.Mods.Any(h => h is OsuModAutopilot))
approachRateFactor = 0.0;

speedValue *= 1.0 + approachRateFactor * lengthBonus; // Buff for longer maps with high AR.

if (score.Mods.Any(m => m is OsuModBlinds))
{
// Increasing the speed value by object count for Blinds isn't ideal, so the minimum buff is given.
Expand Down
Loading

0 comments on commit 3a6fef7

Please sign in to comment.