1
0
mirror of https://github.com/ppy/osu.git synced 2026-06-03 18:03:55 +08:00

Extend Skill to include ObjectDifficulties (#36152)

* Extend `Skill` to include `ObjectDifficulties`

* Remove generic

* Change `ObjectDifficulties` to be modifiable by children skills

* Fix tests
This commit is contained in:
StanR
2025-12-28 18:56:55 +05:00
committed by GitHub
Unverified
parent d150e27381
commit a07d7ad4cb
5 changed files with 29 additions and 19 deletions
@@ -54,14 +54,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
public double RelevantNoteCount()
{
if (ObjectStrains.Count == 0)
if (ObjectDifficulties.Count == 0)
return 0;
double maxStrain = ObjectStrains.Max();
double maxStrain = ObjectDifficulties.Max();
if (maxStrain == 0)
return 0;
return ObjectStrains.Sum(strain => 1.0 / (1.0 + Math.Exp(-(strain / maxStrain * 12.0 - 6.0))));
return ObjectDifficulties.Sum(strain => 1.0 / (1.0 + Math.Exp(-(strain / maxStrain * 12.0 - 6.0))));
}
public double CountTopWeightedSliders(double difficultyValue)
@@ -186,10 +186,10 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
}
List<double> hitObjectStrainPeaks = combinePeaks(
rhythm.GetObjectStrains().ToList(),
reading.GetObjectStrains().ToList(),
colour.GetObjectStrains().ToList(),
stamina.GetObjectStrains().ToList()
rhythm.GetObjectDifficulties(),
reading.GetObjectDifficulties(),
colour.GetObjectDifficulties(),
stamina.GetObjectDifficulties()
);
if (hitObjectStrainPeaks.Count == 0)
@@ -211,7 +211,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
/// <summary>
/// Combines lists of peak strains from multiple skills into a list of single peak strains for each section.
/// </summary>
private List<double> combinePeaks(List<double> rhythmPeaks, List<double> readingPeaks, List<double> colourPeaks, List<double> staminaPeaks)
private List<double> combinePeaks(IReadOnlyList<double> rhythmPeaks, IReadOnlyList<double> readingPeaks, IReadOnlyList<double> colourPeaks, IReadOnlyList<double> staminaPeaks)
{
var combinedPeaks = new List<double>();
@@ -200,8 +200,9 @@ namespace osu.Game.Tests.NonVisual
{
}
public override void Process(DifficultyHitObject current)
protected override double ProcessInternal(DifficultyHitObject current)
{
return 0;
}
public override double DifficultyValue() => 1;
+14 -1
View File
@@ -20,6 +20,11 @@ namespace osu.Game.Rulesets.Difficulty.Skills
/// </summary>
protected IReadOnlyList<Mod> Mods => mods;
/// <summary>
/// List of calculated per-object difficulties, populated by Process
/// </summary>
protected readonly List<double> ObjectDifficulties = new List<double>();
private readonly Mod[] mods;
protected Skill(Mod[] mods)
@@ -31,11 +36,19 @@ namespace osu.Game.Rulesets.Difficulty.Skills
/// Process a <see cref="DifficultyHitObject"/>.
/// </summary>
/// <param name="current">The <see cref="DifficultyHitObject"/> to process.</param>
public abstract void Process(DifficultyHitObject current);
public void Process(DifficultyHitObject current)
{
double difficultyValue = ProcessInternal(current);
ObjectDifficulties.Add(difficultyValue);
}
protected abstract double ProcessInternal(DifficultyHitObject current);
/// <summary>
/// Returns the calculated difficulty value representing all <see cref="DifficultyHitObject"/>s that have been processed up to this point.
/// </summary>
public abstract double DifficultyValue();
public IReadOnlyList<double> GetObjectDifficulties() => ObjectDifficulties;
}
}
@@ -29,7 +29,6 @@ namespace osu.Game.Rulesets.Difficulty.Skills
private double currentSectionEnd;
private readonly List<double> strainPeaks = new List<double>();
protected readonly List<double> ObjectStrains = new List<double>(); // Store individual strains
protected StrainSkill(Mod[] mods)
: base(mods)
@@ -44,7 +43,7 @@ namespace osu.Game.Rulesets.Difficulty.Skills
/// <summary>
/// Process a <see cref="DifficultyHitObject"/> and update current strain values accordingly.
/// </summary>
public sealed override void Process(DifficultyHitObject current)
protected sealed override double ProcessInternal(DifficultyHitObject current)
{
// The first object doesn't generate a strain, so we begin with an incremented section end
if (current.Index == 0)
@@ -60,8 +59,7 @@ namespace osu.Game.Rulesets.Difficulty.Skills
double strain = StrainValueAt(current);
currentSectionPeak = Math.Max(strain, currentSectionPeak);
// Store the strain value for the object
ObjectStrains.Add(strain);
return strain;
}
/// <summary>
@@ -70,16 +68,16 @@ namespace osu.Game.Rulesets.Difficulty.Skills
/// </summary>
public virtual double CountTopWeightedStrains(double difficultyValue)
{
if (ObjectStrains.Count == 0)
if (ObjectDifficulties.Count == 0)
return 0.0;
double consistentTopStrain = difficultyValue * (1 - DecayWeight); // What would the top strain be if all strain values were identical
if (consistentTopStrain == 0)
return ObjectStrains.Count;
return ObjectDifficulties.Count;
// Use a weighted sum of all strains. Constants are arbitrary and give nice values
return ObjectStrains.Sum(s => 1.1 / (1 + Math.Exp(-10 * (s / consistentTopStrain - 0.88))));
return ObjectDifficulties.Sum(s => 1.1 / (1 + Math.Exp(-10 * (s / consistentTopStrain - 0.88))));
}
/// <summary>
@@ -116,8 +114,6 @@ namespace osu.Game.Rulesets.Difficulty.Skills
/// </summary>
public IEnumerable<double> GetCurrentStrainPeaks() => strainPeaks.Append(currentSectionPeak);
public IEnumerable<double> GetObjectStrains() => ObjectStrains;
/// <summary>
/// Returns the calculated difficulty value representing all <see cref="DifficultyHitObject"/>s that have been processed up to this point.
/// </summary>