diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs index 314bb31465..89dd7efbdf 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Speed.cs @@ -125,16 +125,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills return Math.Sqrt(4 + rhythmComplexitySum * rhythmMultiplier) / 2; } - private void setStrainValues(DifficultyHitObject current) + private double tapStrainOf(DifficultyHitObject current) { - // if (current.BaseObject is Spinner) - // { - // currentTapStrain *= strainDecay(current.DeltaTime); - // - // currentMovementStrain *= strainDecay(current.DeltaTime); - // - // return; - // } + if (current.BaseObject is Spinner) + { + return 0; + } var osuCurrent = (OsuDifficultyHitObject)current; @@ -161,16 +157,42 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills } } - // return (1 + (speedBonus - 1) * 0.75) * angleBonus * (0.95 + speedBonus * Math.Pow(distance / single_spacing_threshold, 3.5)) / osuCurrent.StrainTime; + return ((1 + (speedBonus - 1) * 0.75) * angleBonus * 0.95) / osuCurrent.StrainTime; + } - double tapStrain = ((1 + (speedBonus - 1) * 0.75) * 0.95) / osuCurrent.StrainTime; - double movementStrain = ((1 + (speedBonus - 1) * 0.75) * angleBonus * speedBonus * Math.Pow(distance / single_spacing_threshold, 3.5)) / osuCurrent.StrainTime; + private double movementStrainOf(DifficultyHitObject current) + { + if (current.BaseObject is Spinner) + { + return 0; + } - currentTapStrain *= strainDecay(current.DeltaTime); - currentTapStrain += tapStrain * skillMultiplier; + var osuCurrent = (OsuDifficultyHitObject)current; - currentMovementStrain *= strainDecay(current.DeltaTime); - currentMovementStrain += movementStrain * skillMultiplier; + double distance = Math.Min(single_spacing_threshold, osuCurrent.TravelDistance + osuCurrent.JumpDistance); + double deltaTime = Math.Max(max_speed_bonus, current.DeltaTime); + + double speedBonus = 1.0; + if (deltaTime < min_speed_bonus) + speedBonus = 1 + Math.Pow((min_speed_bonus - deltaTime) / speed_balancing_factor, 2); + + double angleBonus = 1.0; + + if (osuCurrent.Angle != null && osuCurrent.Angle.Value < angle_bonus_begin) + { + angleBonus = 1 + Math.Pow(Math.Sin(1.5 * (angle_bonus_begin - osuCurrent.Angle.Value)), 2) / 3.57; + + if (osuCurrent.Angle.Value < pi_over_2) + { + angleBonus = 1.28; + if (distance < 90 && osuCurrent.Angle.Value < pi_over_4) + angleBonus += (1 - angleBonus) * Math.Min((90 - distance) / 10, 1); + else if (distance < 90) + angleBonus += (1 - angleBonus) * Math.Min((90 - distance) / 10, 1) * Math.Sin((pi_over_2 - osuCurrent.Angle.Value) / pi_over_4); + } + } + + return ((1 + (speedBonus - 1) * 0.75) * angleBonus * speedBonus * Math.Pow(distance / single_spacing_threshold, 3.5)) / osuCurrent.StrainTime; } private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000); @@ -179,11 +201,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills protected override double StrainValueAt(DifficultyHitObject current) { - setStrainValues(current); + currentTapStrain *= strainDecay(current.DeltaTime); + currentTapStrain += tapStrainOf(current) * skillMultiplier; -// Console.WriteLine(currentMovementStrain + currentTapStrain); + currentMovementStrain *= strainDecay(current.DeltaTime); + currentMovementStrain += movementStrainOf(current) * skillMultiplier; - return currentMovementStrain + currentTapStrain * calculateRhythmBonus(current.StartTime); + return currentMovementStrain + currentTapStrain;// * calculateRhythmBonus(current.StartTime); } } }