Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Add TappingFactor and use it to nerf HD bonus on speed pp #31478

Open
wants to merge 9 commits into
base: pp-dev
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions osu.Game.Rulesets.Osu/Difficulty/Evaluators/SpeedEvaluator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,7 @@ public static class SpeedEvaluator
/// <item><description>and how easily they can be cheesed.</description></item>
/// </list>
/// </summary>
public static double EvaluateDifficultyOf(DifficultyHitObject current, IReadOnlyList<Mod> mods)
public static double EvaluateDifficultyOf(DifficultyHitObject current, bool withDistanceBonus, IReadOnlyList<Mod> mods)
{
if (current.BaseObject is Spinner)
return 0;
Expand Down Expand Up @@ -60,7 +60,7 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current, IReadOnly
// Max distance bonus is 1 * `distance_multiplier` at single_spacing_threshold
double distanceBonus = Math.Pow(distance / single_spacing_threshold, 3.95) * distance_multiplier;

if (mods.OfType<OsuModAutopilot>().Any())
if (!withDistanceBonus || mods.OfType<OsuModAutopilot>().Any())
distanceBonus = 0;

// Base difficulty with all bonuses
Expand Down
8 changes: 8 additions & 0 deletions osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs
Original file line number Diff line number Diff line change
Expand Up @@ -53,6 +53,14 @@ public class OsuDifficultyAttributes : DifficultyAttributes
[JsonProperty("slider_factor")]
public double SliderFactor { get; set; }

/// <summary>
/// Describes how much of <see cref="SpeedDifficulty"/> is contributed to by flow.
/// A value closer to 1.0 indicates most of <see cref="SpeedDifficulty"/> is contributed by tapping.
/// A value closer to 0.0 indicates most of <see cref="SpeedDifficulty"/> is contributed by flow.
/// </summary>
[JsonProperty("flow_factor")]
public double FlowFactor { get; set; }

[JsonProperty("aim_difficult_strain_count")]
public double AimDifficultStrainCount { get; set; }

Expand Down
8 changes: 6 additions & 2 deletions osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -39,14 +39,16 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat
double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
double aimRatingNoSliders = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
double speedRating = Math.Sqrt(skills[2].DifficultyValue()) * difficulty_multiplier;
double speedRatingNoFlow = Math.Sqrt(skills[3].DifficultyValue()) * difficulty_multiplier;
double speedNotes = ((Speed)skills[2]).RelevantNoteCount();
double difficultSliders = ((Aim)skills[0]).GetDifficultSliders();
double flashlightRating = 0.0;

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

double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
double flowFactor = speedRating > 0 ? Math.Pow(speedRatingNoFlow / speedRating, 3) : 1;

double aimDifficultyStrainCount = ((OsuStrainSkill)skills[0]).CountTopWeightedStrains();
double speedDifficultyStrainCount = ((OsuStrainSkill)skills[2]).CountTopWeightedStrains();
Expand Down Expand Up @@ -112,6 +114,7 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat
SpeedNoteCount = speedNotes,
FlashlightDifficulty = flashlightRating,
SliderFactor = sliderFactor,
FlowFactor = flowFactor,
AimDifficultStrainCount = aimDifficultyStrainCount,
SpeedDifficultStrainCount = speedDifficultyStrainCount,
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
Expand Down Expand Up @@ -150,7 +153,8 @@ protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clo
{
new Aim(mods, true),
new Aim(mods, false),
new Speed(mods)
new Speed(mods, false),
new Speed(mods, true),
};

if (mods.Any(h => h is OsuModFlashlight))
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -234,7 +234,7 @@ private double computeSpeedValue(ScoreInfo score, OsuDifficultyAttributes attrib
else if (score.Mods.Any(m => m is OsuModHidden || m is OsuModTraceable))
{
// We want to give more reward for lower AR when it comes to aim and HD. This nerfs high AR and buffs lower AR.
speedValue *= 1.0 + 0.04 * (12.0 - attributes.ApproachRate);
speedValue *= 1.0 + 0.08 * (12.0 - attributes.ApproachRate) * (1 - attributes.FlowFactor);
}

double speedHighDeviationMultiplier = calculateSpeedHighDeviationNerf(attributes);
Expand Down
9 changes: 7 additions & 2 deletions osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -23,19 +23,24 @@ public class Speed : OsuStrainSkill

protected override int ReducedSectionCount => 5;

public Speed(Mod[] mods)
public Speed(Mod[] mods, bool withoutFlow)
: base(mods)
{
this.withoutFlow = withoutFlow;
}

private readonly bool withoutFlow;

private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);

protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => (currentStrain * currentRhythm) * strainDecay(time - current.Previous(0).StartTime);

protected override double StrainValueAt(DifficultyHitObject current)
{
currentStrain *= strainDecay(((OsuDifficultyHitObject)current).StrainTime);
currentStrain += SpeedEvaluator.EvaluateDifficultyOf(current, Mods) * skillMultiplier;
currentStrain += SpeedEvaluator.EvaluateDifficultyOf(current, withoutFlow, Mods) * skillMultiplier;

if (withoutFlow) return currentStrain;

currentRhythm = RhythmEvaluator.EvaluateDifficultyOf(current);

Expand Down
Loading