1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-24 17:00:45 +08:00

Account for alternating angles in reading angle factor (#36466)

This rework target is C-type nerf, as this map gets absurd amount of
reading pp, because angles are considered very unrepetitive. What
results in this score being worth absurd 1.4k pp.

This PR is up to heavy discussion because it can be made much more
general, touching more maps. So I wait on pp committee opinion on what
of the parts can be removed.

Current checks for angle to be nerfed:
- The smaller angle has to be very sharp: <20 degrees, full power on <5
degrees
- The larger angle has to be wide: >60 degrees, full power on >120
degrees

If pattern meets all the criteria - it would be considered repetitive.
For now practically no map meets this criteria to significant amount
except C-type.
This commit is contained in:
Givy120
2026-03-26 12:47:55 +02:00
committed by GitHub
Unverified
parent 0f37874aeb
commit b31d1b3a08
@@ -208,6 +208,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
int index = 0;
double currentTimeGap = 0;
OsuDifficultyHitObject loopObjPrev0 = current;
OsuDifficultyHitObject? loopObjPrev1 = null;
OsuDifficultyHitObject? loopObjPrev2 = null;
while (currentTimeGap < minimum_angle_relevancy_time)
{
var loopObj = (OsuDifficultyHitObject)current.Previous(index);
@@ -221,13 +225,34 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
if (loopObj.Angle.IsNotNull() && current.Angle.IsNotNull())
{
double angleDifference = Math.Abs(current.Angle.Value - loopObj.Angle.Value);
double angleDifferenceAlternating = Math.PI;
if (loopObjPrev0.Angle != null && loopObjPrev1?.Angle != null && loopObjPrev2?.Angle != null)
{
angleDifferenceAlternating = Math.Abs(loopObjPrev1.Angle.Value - loopObj.Angle.Value);
angleDifferenceAlternating += Math.Abs(loopObjPrev2.Angle.Value - loopObjPrev0.Angle.Value);
double weight = 1.0;
// Be sure that one of the angles is very sharp, when other is wide
weight *= DifficultyCalculationUtils.ReverseLerp(Math.Min(loopObj.Angle.Value, loopObjPrev0.Angle.Value) * 180 / Math.PI, 20, 5);
weight *= DifficultyCalculationUtils.ReverseLerp(Math.Max(loopObj.Angle.Value, loopObjPrev0.Angle.Value) * 180 / Math.PI, 60, 120);
// Lerp between max angle difference and rescaled alternating difference, with more harsh scaling compared to normal difference
angleDifferenceAlternating = double.Lerp(Math.PI, 0.1 * angleDifferenceAlternating, weight);
}
double stackFactor = DifficultyCalculationUtils.Smootherstep(loopObj.LazyJumpDistance, 0, OsuDifficultyHitObject.NORMALISED_RADIUS);
constantAngleCount += Math.Cos(3 * Math.Min(double.DegreesToRadians(30), angleDifference * stackFactor)) * longIntervalFactor;
constantAngleCount += Math.Cos(3 * Math.Min(double.DegreesToRadians(30), Math.Min(angleDifference, angleDifferenceAlternating) * stackFactor)) * longIntervalFactor;
}
currentTimeGap = current.StartTime - loopObj.StartTime;
index++;
loopObjPrev2 = loopObjPrev1;
loopObjPrev1 = loopObjPrev0;
loopObjPrev0 = loopObj;
}
return Math.Clamp(2 / constantAngleCount, 0.2, 1);