mirror of
https://github.com/ppy/osu.git
synced 2025-03-15 14:47:18 +08:00
Increased stability
Now low AR difficulty won't drop with lowering AR
This commit is contained in:
parent
5e35121b14
commit
5e2f3e3918
@ -22,16 +22,19 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
|
|||||||
{
|
{
|
||||||
var currObj = (OsuDifficultyHitObject)current;
|
var currObj = (OsuDifficultyHitObject)current;
|
||||||
double density = 0;
|
double density = 0;
|
||||||
double densityAnglesNerf = -2; // we have threshold of 2, so 2 or same angles won't be punished
|
double densityAnglesNerf = -2.5; // we have threshold of 2.5
|
||||||
|
|
||||||
OsuDifficultyHitObject? prevObj0 = null;
|
OsuDifficultyHitObject? prevObj0 = null;
|
||||||
OsuDifficultyHitObject? prevObj1 = null;
|
OsuDifficultyHitObject? prevObj1 = null;
|
||||||
OsuDifficultyHitObject? prevObj2 = null;
|
OsuDifficultyHitObject? prevObj2 = null;
|
||||||
|
|
||||||
double prevConstantAngle = 0;
|
double prevConstantAngle = 1;
|
||||||
|
|
||||||
foreach (var loopObj in retrievePastVisibleObjects(currObj).Reverse())
|
foreach (var loopObj in retrievePastVisibleObjects(currObj).Reverse())
|
||||||
{
|
{
|
||||||
|
if (loopObj.Index < 1)
|
||||||
|
continue; // Don't look on the first object of the map
|
||||||
|
|
||||||
double loopDifficulty = currObj.OpacityAt(loopObj.BaseObject.StartTime, false);
|
double loopDifficulty = currObj.OpacityAt(loopObj.BaseObject.StartTime, false);
|
||||||
|
|
||||||
// Small distances means objects may be cheesed, so it doesn't matter whether they are arranged confusingly.
|
// Small distances means objects may be cheesed, so it doesn't matter whether they are arranged confusingly.
|
||||||
@ -43,10 +46,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
|
|||||||
loopDifficulty *= getTimeNerfFactor(timeBetweenCurrAndLoopObj);
|
loopDifficulty *= getTimeNerfFactor(timeBetweenCurrAndLoopObj);
|
||||||
|
|
||||||
if (prevObj0.IsNull())
|
if (prevObj0.IsNull())
|
||||||
{
|
prevObj0 = (OsuDifficultyHitObject)loopObj.Previous(0);
|
||||||
prevObj0 = loopObj;
|
|
||||||
continue;
|
if (prevObj1.IsNull())
|
||||||
}
|
prevObj1 = (OsuDifficultyHitObject?)loopObj.Previous(1);
|
||||||
|
|
||||||
|
if (prevObj2.IsNull())
|
||||||
|
prevObj2 = (OsuDifficultyHitObject?)loopObj.Previous(2);
|
||||||
|
|
||||||
// Only if next object is slower, representing break from many notes in a row
|
// Only if next object is slower, representing break from many notes in a row
|
||||||
if (loopObj.StrainTime > prevObj0.StrainTime)
|
if (loopObj.StrainTime > prevObj0.StrainTime)
|
||||||
@ -67,35 +73,42 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
|
|||||||
|
|
||||||
// Angles nerf
|
// Angles nerf
|
||||||
|
|
||||||
if (loopObj.Angle.IsNotNull() && prevObj0.Angle.IsNotNull())
|
if (loopObj.Angle.IsNotNull() && prevObj0.IsNotNull() && prevObj0.Angle.IsNotNull())
|
||||||
{
|
{
|
||||||
double angleDifference = Math.Abs(prevObj0.Angle.Value - loopObj.Angle.Value);
|
double angleDifference = Math.Abs(prevObj0.Angle.Value - loopObj.Angle.Value);
|
||||||
|
|
||||||
|
// assume worst-case if no angles
|
||||||
|
double angleDifference1 = 0;
|
||||||
|
double angleDifference2 = 0;
|
||||||
|
|
||||||
// Nerf alternating angles case
|
// Nerf alternating angles case
|
||||||
if (prevObj1.IsNotNull() && prevObj2.IsNotNull() && prevObj1.Angle.IsNotNull() && prevObj2.Angle.IsNotNull())
|
if (prevObj1.IsNotNull() && prevObj2.IsNotNull() && prevObj1.Angle.IsNotNull() && prevObj2.Angle.IsNotNull())
|
||||||
{
|
{
|
||||||
// Normalized difference
|
// Normalized difference
|
||||||
double angleDifference1 = Math.Abs(prevObj1.Angle.Value - loopObj.Angle.Value) / Math.PI;
|
angleDifference1 = Math.Abs(prevObj1.Angle.Value - loopObj.Angle.Value) / Math.PI;
|
||||||
double angleDifference2 = Math.Abs(prevObj2.Angle.Value - prevObj0.Angle.Value) / Math.PI;
|
angleDifference2 = Math.Abs(prevObj2.Angle.Value - prevObj0.Angle.Value) / Math.PI;
|
||||||
|
}
|
||||||
|
|
||||||
// Will be close to 1 if angleDifference1 and angleDifference2 was both close to 0
|
// Will be close to 1 if angleDifference1 and angleDifference2 was both close to 0
|
||||||
double alternatingFactor = Math.Pow((1 - angleDifference1) * (1 - angleDifference2), 2);
|
double alternatingFactor = Math.Pow((1 - angleDifference1) * (1 - angleDifference2), 2);
|
||||||
|
|
||||||
// Be sure to nerf only same rhythms
|
// Be sure to nerf only same rhythms
|
||||||
double rhythmFactor = 1 - getRhythmDifference(loopObj.StrainTime, prevObj0.StrainTime); // 0 on different rhythm, 1 on same rhythm
|
double rhythmFactor = 1 - getRhythmDifference(loopObj.StrainTime, prevObj0.StrainTime); // 0 on different rhythm, 1 on same rhythm
|
||||||
|
|
||||||
|
if (prevObj1.IsNotNull())
|
||||||
rhythmFactor *= 1 - getRhythmDifference(prevObj0.StrainTime, prevObj1.StrainTime);
|
rhythmFactor *= 1 - getRhythmDifference(prevObj0.StrainTime, prevObj1.StrainTime);
|
||||||
|
if (prevObj1.IsNotNull() && prevObj2.IsNotNull())
|
||||||
rhythmFactor *= 1 - getRhythmDifference(prevObj1.StrainTime, prevObj2.StrainTime);
|
rhythmFactor *= 1 - getRhythmDifference(prevObj1.StrainTime, prevObj2.StrainTime);
|
||||||
|
|
||||||
double acuteAngleFactor = 1 - Math.Min(loopObj.Angle.Value, prevObj0.Angle.Value) / Math.PI;
|
double acuteAngleFactor = 1 - Math.Min(loopObj.Angle.Value, prevObj0.Angle.Value) / Math.PI;
|
||||||
|
|
||||||
double prevAngleAdjust = Math.Max(angleDifference - angleDifference1, 0);
|
double prevAngleAdjust = Math.Max(angleDifference - angleDifference1, 0);
|
||||||
|
|
||||||
prevAngleAdjust *= alternatingFactor; // Nerf if alternating
|
prevAngleAdjust *= alternatingFactor; // Nerf if alternating
|
||||||
prevAngleAdjust *= rhythmFactor; // Nerf if same rhythms
|
prevAngleAdjust *= rhythmFactor; // Nerf if same rhythms
|
||||||
prevAngleAdjust *= acuteAngleFactor;
|
prevAngleAdjust *= acuteAngleFactor;
|
||||||
|
|
||||||
angleDifference -= prevAngleAdjust;
|
angleDifference -= prevAngleAdjust;
|
||||||
}
|
|
||||||
|
|
||||||
// Reduce angles nerf if objects are too apart in time
|
// Reduce angles nerf if objects are too apart in time
|
||||||
// Angle nerf is starting being reduced from 200ms (150BPM jump) and it reduced to 0 on 2000ms
|
// Angle nerf is starting being reduced from 200ms (150BPM jump) and it reduced to 0 on 2000ms
|
||||||
@ -110,6 +123,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
|
|||||||
densityAnglesNerf += Math.Min(currentAngleNerf, loopDifficulty);
|
densityAnglesNerf += Math.Min(currentAngleNerf, loopDifficulty);
|
||||||
prevConstantAngle = currConstantAngle;
|
prevConstantAngle = currConstantAngle;
|
||||||
}
|
}
|
||||||
|
else // Assume worst-case if no angles
|
||||||
|
{
|
||||||
|
densityAnglesNerf += loopDifficulty;
|
||||||
|
}
|
||||||
|
|
||||||
prevObj2 = prevObj1;
|
prevObj2 = prevObj1;
|
||||||
prevObj1 = prevObj0;
|
prevObj1 = prevObj0;
|
||||||
|
Loading…
x
Reference in New Issue
Block a user