Refactor catch Movement skill to not require explicit clockrate usage

In catch, rate adjustment mods do not only affect the timings of hitobjects, but also the speed of the player's catcher.

This catcher speed change has an impact on difficulty which is currently accounted for by using the clockrate directly in calculations.

Semantically this is a bad idea because clockrate adjustments are supposed to be fully accounted for in DifficultyHitObjects, but passing clockrate here for the purpose of being used as catcher speed doesn't make much sense, especially since it is copied in every DifficultyHitObject despite being the same value.

It makes more sense to account for this catch specific impact by handling rate adjustment mods in a catch specific way, or more specifically in a Movement skill specific way.
This commit is contained in:
Samuel Cattini-Schultz 2021-02-21 18:24:27 +11:00
parent 66643a97b0
commit 323e4ac26b
2 changed files with 13 additions and 5 deletions

View File

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

View File

@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using osu.Game.Rulesets.Catch.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Preprocessing;
using osu.Game.Rulesets.Difficulty.Skills;
@ -26,10 +27,20 @@ public class Movement : Skill
private float lastDistanceMoved;
private double lastStrainTime;
/// <summary>
/// The speed multiplier applied to the player's catcher.
/// </summary>
private readonly double catcherSpeedMultiplier;
public Movement(Mod[] mods, float halfCatcherWidth)
: base(mods)
{
HalfCatcherWidth = halfCatcherWidth;
// In catch, rate adjustment mods do not only affect the timings of hitobjects,
// but also the speed of the player's catcher, which has an impact on difficulty
var rateAdjustMod = mods.FirstOrDefault(m => m is ModRateAdjust);
catcherSpeedMultiplier = (rateAdjustMod as ModRateAdjust)?.SpeedChange.Value ?? 1;
}
protected override double StrainValueOf(DifficultyHitObject current)
@ -46,7 +57,7 @@ protected override double StrainValueOf(DifficultyHitObject current)
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 sqrtStrain = Math.Sqrt(weightedStrainTime);
@ -79,7 +90,7 @@ protected override double StrainValueOf(DifficultyHitObject current)
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;