1
0
mirror of https://github.com/ppy/osu.git synced 2024-11-13 16:13:34 +08:00

Merge pull request #11857 from Syriiin/diffcalc/refactor/catch-clockrate-effects

Refactor catch Movement skill to not require explicit clockrate usage
This commit is contained in:
Dan Balasescu 2021-06-03 17:29:27 +09:00 committed by GitHub
commit 15b43beef1
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
12 changed files with 27 additions and 18 deletions

View File

@ -25,6 +25,6 @@ namespace osu.Game.Rulesets.EmptyFreeform
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) => new Skill[0]; protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[0];
} }
} }

View File

@ -25,6 +25,6 @@ namespace osu.Game.Rulesets.Pippidon
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) => new Skill[0]; protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[0];
} }
} }

View File

@ -25,6 +25,6 @@ namespace osu.Game.Rulesets.EmptyScrolling
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) => new Skill[0]; protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[0];
} }
} }

View File

@ -25,6 +25,6 @@ namespace osu.Game.Rulesets.Pippidon
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>(); protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate) => Enumerable.Empty<DifficultyHitObject>();
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) => new Skill[0]; protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[0];
} }
} }

View File

@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
} }
} }
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate)
{ {
halfCatcherWidth = Catcher.CalculateCatchWidth(beatmap.BeatmapInfo.BaseDifficulty) * 0.5f; halfCatcherWidth = Catcher.CalculateCatchWidth(beatmap.BeatmapInfo.BaseDifficulty) * 0.5f;
@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
return new Skill[] return new Skill[]
{ {
new Movement(mods, halfCatcherWidth), new Movement(mods, halfCatcherWidth, clockRate),
}; };
} }

View File

@ -24,8 +24,6 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Preprocessing
/// </summary> /// </summary>
public readonly double StrainTime; public readonly double StrainTime;
public readonly double ClockRate;
public CatchDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate, float halfCatcherWidth) public CatchDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate, float halfCatcherWidth)
: base(hitObject, lastObject, clockRate) : base(hitObject, lastObject, clockRate)
{ {
@ -37,7 +35,6 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Preprocessing
// Every strain interval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure // Every strain interval is hard capped at the equivalent of 375 BPM streaming speed as a safety measure
StrainTime = Math.Max(40, DeltaTime); StrainTime = Math.Max(40, DeltaTime);
ClockRate = clockRate;
} }
} }
} }

View File

@ -28,10 +28,21 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
private float lastDistanceMoved; private float lastDistanceMoved;
private double lastStrainTime; private double lastStrainTime;
public Movement(Mod[] mods, float halfCatcherWidth) /// <summary>
/// The speed multiplier applied to the player's catcher.
/// </summary>
private readonly double catcherSpeedMultiplier;
public Movement(Mod[] mods, float halfCatcherWidth, double clockRate)
: base(mods) : base(mods)
{ {
HalfCatcherWidth = halfCatcherWidth; HalfCatcherWidth = halfCatcherWidth;
// In catch, clockrate adjustments do not only affect the timings of hitobjects,
// but also the speed of the player's catcher, which has an impact on difficulty
// TODO: Support variable clockrates caused by mods such as ModTimeRamp
// (perhaps by using IApplicableToRate within the CatchDifficultyHitObject constructor to set a catcher speed for each object before processing)
catcherSpeedMultiplier = clockRate;
} }
protected override double StrainValueOf(DifficultyHitObject current) protected override double StrainValueOf(DifficultyHitObject current)
@ -48,7 +59,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
float distanceMoved = playerPosition - lastPlayerPosition.Value; float distanceMoved = playerPosition - lastPlayerPosition.Value;
double weightedStrainTime = catchCurrent.StrainTime + 13 + (3 / catchCurrent.ClockRate); double weightedStrainTime = catchCurrent.StrainTime + 13 + (3 / catcherSpeedMultiplier);
double distanceAddition = (Math.Pow(Math.Abs(distanceMoved), 1.3) / 510); double distanceAddition = (Math.Pow(Math.Abs(distanceMoved), 1.3) / 510);
double sqrtStrain = Math.Sqrt(weightedStrainTime); double sqrtStrain = Math.Sqrt(weightedStrainTime);
@ -81,7 +92,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty.Skills
playerPosition = catchCurrent.NormalizedPosition; playerPosition = catchCurrent.NormalizedPosition;
} }
distanceAddition *= 1.0 + edgeDashBonus * ((20 - catchCurrent.LastObject.DistanceToHyperDash) / 20) * Math.Pow((Math.Min(catchCurrent.StrainTime * catchCurrent.ClockRate, 265) / 265), 1.5); // Edge Dashes are easier at lower ms values distanceAddition *= 1.0 + edgeDashBonus * ((20 - catchCurrent.LastObject.DistanceToHyperDash) / 20) * Math.Pow((Math.Min(catchCurrent.StrainTime * catcherSpeedMultiplier, 265) / 265), 1.5); // Edge Dashes are easier at lower ms values
} }
lastPlayerPosition = playerPosition; lastPlayerPosition = playerPosition;

View File

@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
// Sorting is done in CreateDifficultyHitObjects, since the full list of hitobjects is required. // Sorting is done in CreateDifficultyHitObjects, since the full list of hitobjects is required.
protected override IEnumerable<DifficultyHitObject> SortObjects(IEnumerable<DifficultyHitObject> input) => input; protected override IEnumerable<DifficultyHitObject> SortObjects(IEnumerable<DifficultyHitObject> input) => input;
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) => new Skill[] protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[]
{ {
new Strain(mods, ((ManiaBeatmap)beatmap).TotalColumns) new Strain(mods, ((ManiaBeatmap)beatmap).TotalColumns)
}; };

View File

@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
} }
} }
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) => new Skill[] protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[]
{ {
new Aim(mods), new Aim(mods),
new Speed(mods) new Speed(mods)

View File

@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
{ {
} }
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) => new Skill[] protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate) => new Skill[]
{ {
new Colour(mods), new Colour(mods),
new Rhythm(mods), new Rhythm(mods),

View File

@ -217,7 +217,7 @@ namespace osu.Game.Tests.NonVisual
throw new NotImplementedException(); throw new NotImplementedException();
} }
protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods) protected override Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate)
{ {
throw new NotImplementedException(); throw new NotImplementedException();
} }

View File

@ -59,7 +59,7 @@ namespace osu.Game.Rulesets.Difficulty
private DifficultyAttributes calculate(IBeatmap beatmap, Mod[] mods, double clockRate) private DifficultyAttributes calculate(IBeatmap beatmap, Mod[] mods, double clockRate)
{ {
var skills = CreateSkills(beatmap, mods); var skills = CreateSkills(beatmap, mods, clockRate);
if (!beatmap.HitObjects.Any()) if (!beatmap.HitObjects.Any())
return CreateDifficultyAttributes(beatmap, mods, skills, clockRate); return CreateDifficultyAttributes(beatmap, mods, skills, clockRate);
@ -180,7 +180,8 @@ namespace osu.Game.Rulesets.Difficulty
/// </summary> /// </summary>
/// <param name="beatmap">The <see cref="IBeatmap"/> whose difficulty will be calculated.</param> /// <param name="beatmap">The <see cref="IBeatmap"/> whose difficulty will be calculated.</param>
/// <param name="mods">Mods to calculate difficulty with.</param> /// <param name="mods">Mods to calculate difficulty with.</param>
/// <param name="clockRate">Clockrate to calculate difficulty with.</param>
/// <returns>The <see cref="Skill"/>s.</returns> /// <returns>The <see cref="Skill"/>s.</returns>
protected abstract Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods); protected abstract Skill[] CreateSkills(IBeatmap beatmap, Mod[] mods, double clockRate);
} }
} }