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

Don't punish slider hit windows in difficulty calculations when slider head accuracy is in use #28267

Open
wants to merge 4 commits into
base: master
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
Original file line number Diff line number Diff line change
Expand Up @@ -50,7 +50,7 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat
return attributes;
}

protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, Mod[] mods, double clockRate)
{
CatchHitObject? lastObject = null;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -67,7 +67,7 @@ private static int maxComboForObject(HitObject hitObject)
return 1;
}

protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, Mod[] mods, double clockRate)
{
var sortedObjects = beatmap.HitObjects.ToArray();

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,12 @@
// See the LICENCE file in the repository root for full licence text.

using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Osu.Objects;

namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
Expand All @@ -16,7 +20,7 @@ public static class RhythmEvaluator
/// <summary>
/// Calculates a rhythm multiplier for the difficulty of the tap associated with historic data of the current <see cref="OsuDifficultyHitObject"/>.
/// </summary>
public static double EvaluateDifficultyOf(DifficultyHitObject current)
public static double EvaluateDifficultyOf(DifficultyHitObject current, IReadOnlyList<Mod> mods)
{
if (current.BaseObject is Spinner)
return 0;
Expand Down Expand Up @@ -67,7 +71,7 @@ public static double EvaluateDifficultyOf(DifficultyHitObject current)
}
else
{
if (currObj.BaseObject is Slider) // bpm change is into slider, this is easy acc window
if (currObj.BaseObject is Slider && mods.Any(m => m is OsuModClassic cl && cl.NoSliderHeadAccuracy.Value)) // bpm change is into slider, this is easy acc window without slider head accuracy
effectiveRatio *= 0.125;

if (prevObj.BaseObject is Slider) // bpm change was from a slider, this is easier typically than circle -> circle
Expand Down
4 changes: 2 additions & 2 deletions osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beat
return attributes;
}

protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, Mod[] mods, double clockRate)
{
List<DifficultyHitObject> objects = new List<DifficultyHitObject>();

Expand All @@ -122,7 +122,7 @@ protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(I
for (int i = 1; i < beatmap.HitObjects.Count; i++)
{
var lastLast = i > 1 ? beatmap.HitObjects[i - 2] : null;
objects.Add(new OsuDifficultyHitObject(beatmap.HitObjects[i], beatmap.HitObjects[i - 1], lastLast, clockRate, objects, objects.Count));
objects.Add(new OsuDifficultyHitObject(beatmap.HitObjects[i], beatmap.HitObjects[i - 1], lastLast, clockRate, objects, objects.Count, mods));
}

return objects;
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -5,6 +5,7 @@
using System.Collections.Generic;
using System.Linq;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Mods;
using osu.Game.Rulesets.Osu.Objects;
Expand Down Expand Up @@ -86,7 +87,7 @@ public class OsuDifficultyHitObject : DifficultyHitObject
private readonly OsuHitObject? lastLastObject;
private readonly OsuHitObject lastObject;

public OsuDifficultyHitObject(HitObject hitObject, HitObject lastObject, HitObject? lastLastObject, double clockRate, List<DifficultyHitObject> objects, int index)
public OsuDifficultyHitObject(HitObject hitObject, HitObject lastObject, HitObject? lastLastObject, double clockRate, List<DifficultyHitObject> objects, int index, IReadOnlyList<Mod> mods)
: base(hitObject, lastObject, clockRate, objects, index)
{
this.lastLastObject = lastLastObject as OsuHitObject;
Expand All @@ -95,7 +96,7 @@ public OsuDifficultyHitObject(HitObject hitObject, HitObject lastObject, HitObje
// Capped to 25ms to prevent difficulty calculation breaking from simultaneous objects.
StrainTime = Math.Max(DeltaTime, min_delta_time);

if (BaseObject is Slider sliderObject)
if (BaseObject is Slider sliderObject && mods.Any(m => m is OsuModClassic cl && cl.NoSliderHeadAccuracy.Value))
{
HitWindowGreat = 2 * sliderObject.HeadCircle.HitWindows.WindowFor(HitResult.Great) / clockRate;
}
Expand Down
2 changes: 1 addition & 1 deletion osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,7 +41,7 @@ protected override double StrainValueAt(DifficultyHitObject current)
currentStrain *= strainDecay(((OsuDifficultyHitObject)current).StrainTime);
currentStrain += SpeedEvaluator.EvaluateDifficultyOf(current) * skillMultiplier;

currentRhythm = RhythmEvaluator.EvaluateDifficultyOf(current);
currentRhythm = RhythmEvaluator.EvaluateDifficultyOf(current, Mods);

double totalStrain = currentStrain * currentRhythm;

Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -46,7 +46,7 @@ protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clo
new TaikoModHardRock(),
};

protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, Mod[] mods, double clockRate)
{
List<DifficultyHitObject> difficultyHitObjects = new List<DifficultyHitObject>();
List<TaikoDifficultyHitObject> centreObjects = new List<TaikoDifficultyHitObject>();
Expand Down
5 changes: 3 additions & 2 deletions osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ public IEnumerable<DifficultyAttributes> CalculateAllLegacyCombinations(Cancella
/// <summary>
/// Retrieves the <see cref="DifficultyHitObject"/>s to calculate against.
/// </summary>
private IEnumerable<DifficultyHitObject> getDifficultyHitObjects() => SortObjects(CreateDifficultyHitObjects(Beatmap, clockRate));
private IEnumerable<DifficultyHitObject> getDifficultyHitObjects() => SortObjects(CreateDifficultyHitObjects(Beatmap, playableMods, clockRate));

/// <summary>
/// Performs required tasks before every calculation.
Expand Down Expand Up @@ -277,9 +277,10 @@ static IEnumerable<Mod> createDifficultyAdjustmentModCombinations(ReadOnlyMemory
/// Enumerates <see cref="DifficultyHitObject"/>s to be processed from <see cref="HitObject"/>s in the <see cref="IBeatmap"/>.
/// </summary>
/// <param name="beatmap">The <see cref="IBeatmap"/> providing the <see cref="HitObject"/>s to enumerate.</param>
/// <param name="mods">The <see cref="Mod"/>s that difficulty was calculated with.</param>
/// <param name="clockRate">The rate at which the gameplay clock is run at.</param>
/// <returns>The enumerated <see cref="DifficultyHitObject"/>s.</returns>
protected abstract IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate);
protected abstract IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, Mod[] mods, double clockRate);

/// <summary>
/// Creates the <see cref="Skill"/>s to calculate the difficulty of an <see cref="IBeatmap"/>.
Expand Down
Loading