1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-07 07:43:16 +08:00

fix CI again

This commit is contained in:
Givikap120 2024-12-18 19:33:19 +02:00
parent 3b86aff28d
commit afce62be73
6 changed files with 49 additions and 91 deletions

View File

@ -31,6 +31,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
OsuDifficultyHitObject prevObj0 = currObj;
var readingObjects = currObj.ReadingObjects;
for (int i = 0; i < readingObjects.Count; i++)
{
var loopObj = readingObjects[i].HitObject;
@ -40,10 +41,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
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
if (applyDistanceNerf) loopDifficulty *= (DifficultyCalculationUtils.Logistic(-(loopObj.LazyJumpDistance - 80) / 10) + 0.2) / 1.2;
// Additional buff for long sliderbodies. OVERBUFFED ON PURPOSE
// Additional buff for long sliderbodies
if (applySliderbodyDensity && loopObj.BaseObject is Slider slider)
{
// In radiuses, with minimal of 1
@ -144,7 +145,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
var easierObject = sortedDifficulties[j];
// Get the overlap value
double overlapValue = 0;
double overlapValue;
// OverlapValues dict only contains prev objects, so be sure to use right object
if (harderObject.HitObject.Index > easierObject.HitObject.Index)
@ -171,6 +172,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
return overlap_multiplier * Math.Max(0, screenOverlapDifficulty);
}
public static double EvaluateDifficultyOf(DifficultyHitObject current)
{
if (current.BaseObject is Spinner || current.Index == 0)
@ -191,43 +193,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
return Math.Max(0, Math.Pow(difficulty, 1.37) - 1);
}
// Returns value from 0 to 1, where 0 is very predictable and 1 is very unpredictable
public static double EvaluateInpredictabilityOf(DifficultyHitObject current)
{
if (current.BaseObject is Spinner || current.Index == 0 || current.Previous(0).BaseObject is Spinner)
return 0;
var osuCurrObj = (OsuDifficultyHitObject)current;
var osuLastObj = (OsuDifficultyHitObject)current.Previous(0);
double currVelocity = osuCurrObj.LazyJumpDistance / osuCurrObj.StrainTime;
double prevVelocity = osuLastObj.LazyJumpDistance / osuLastObj.StrainTime;
double velocityChangeFactor = 0;
// https://www.desmos.com/calculator/kqxmqc8pkg
if (currVelocity > 0 || prevVelocity > 0)
{
double velocityChange = Math.Max(0,
Math.Min(
Math.Abs(prevVelocity - currVelocity) - 0.5 * Math.Min(currVelocity, prevVelocity),
Math.Max(((OsuHitObject)osuCurrObj.BaseObject).Radius / Math.Max(osuCurrObj.StrainTime, osuLastObj.StrainTime), Math.Min(currVelocity, prevVelocity))
)); // Stealed from xexxar
velocityChangeFactor = velocityChange / Math.Max(currVelocity, prevVelocity); // maxiumum is 0.4
velocityChangeFactor /= 0.4;
}
// Rhythm difference punishment for velocity and angle bonuses
double rhythmSimilarity = DifficultyCalculationUtils.GetRatio(osuCurrObj.StrainTime, osuLastObj.StrainTime);
// Make differentiation going from 1/4 to 1/2 and bigger difference
// To 1/3 to 1/2 and smaller difference
rhythmSimilarity = Math.Clamp(rhythmSimilarity, 0.5, 0.75);
rhythmSimilarity = 4 * (rhythmSimilarity - 0.5);
return velocityChangeFactor * rhythmSimilarity;
}
// This factor nerfs AR below 0 as extra safety measure
private static double getTimeNerfFactor(double deltaTime) => Math.Clamp(2 - deltaTime / (reading_window_size / 2), 0, 1);
@ -235,14 +200,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
private static double boundBinarySearch(List<OsuDifficultyHitObject.ReadingObject> arr, double target)
{
int low = 0;
int mid;
int high = arr.Count;
int result = -1;
while (low < high)
{
mid = low + (high - low) / 2;
int mid = low + (high - low) / 2;
if (arr[mid].HitObject.StartTime >= target)
{
@ -253,6 +217,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
}
if (result == -1) return 0;
return arr[result].Overlapness;
}
}

View File

@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
/// The difficulty corresponding to the reading skill. Low AR branch.
/// </summary>
[JsonProperty("reading_low_ar_difficulty")]
public double ReadingDifficultyLowAR { get; set; }
public double ReadingDifficultyLowAr { get; set; }
/// <summary>
/// The difficulty corresponding to the flashlight skill.

View File

@ -43,13 +43,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double speedNotes = skills.OfType<Speed>().First().RelevantNoteCount();
double flashlightRating = Math.Sqrt(skills.OfType<Flashlight>().First().DifficultyValue()) * difficulty_multiplier;
double readingLowARRating = Math.Sqrt(skills.OfType<ReadingLowAR>().First().DifficultyValue()) * difficulty_multiplier;
double readingLowARRating = Math.Sqrt(skills.OfType<ReadingLowAr>().First().DifficultyValue()) * difficulty_multiplier;
double sliderFactor = aimRating > 0 ? aimRatingNoSliders / aimRating : 1;
double aimDifficultyStrainCount = skills.OfType<Aim>().First().CountTopWeightedStrains();
double speedDifficultyStrainCount = skills.OfType<Speed>().First().CountTopWeightedStrains();
double lowArDifficultyStrainCount = skills.OfType<ReadingLowAR>().First().CountTopWeightedStrains();
double lowArDifficultyStrainCount = skills.OfType<ReadingLowAr>().First().CountTopWeightedStrains();
if (mods.Any(m => m is OsuModTouchDevice))
{
@ -70,15 +70,15 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double speedPerformance = OsuStrainSkill.DifficultyToPerformance(speedRating);
// Cognition
double readingLowARPerformance = ReadingLowAR.DifficultyToPerformance(readingLowARRating);
double readingARPerformance = readingLowARPerformance;
double readingLowArPerformance = ReadingLowAr.DifficultyToPerformance(readingLowARRating);
double readingArPerformance = readingLowArPerformance;
double potentialFlashlightPerformance = Flashlight.DifficultyToPerformance(flashlightRating);
double flashlightPerformance = mods.Any(h => h is OsuModFlashlight) ? potentialFlashlightPerformance : 0;
double flashlightARPerformance = Math.Pow(Math.Pow(flashlightPerformance, FL_SUM_POWER) + Math.Pow(readingARPerformance, FL_SUM_POWER), 1.0 / FL_SUM_POWER);
double flashlightArPerformance = Math.Pow(Math.Pow(flashlightPerformance, FL_SUM_POWER) + Math.Pow(readingArPerformance, FL_SUM_POWER), 1.0 / FL_SUM_POWER);
double cognitionPerformance = flashlightARPerformance;
double cognitionPerformance = flashlightArPerformance;
double mechanicalPerformance = Math.Pow(Math.Pow(aimPerformance, SUM_POWER) + Math.Pow(speedPerformance, SUM_POWER), 1.0 / SUM_POWER);
// Limit cognition by full memorisation difficulty, what is assumed to be mechanicalPerformance + flashlightPerformance
@ -109,7 +109,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
AimDifficulty = aimRating,
SpeedDifficulty = speedRating,
SpeedNoteCount = speedNotes,
ReadingDifficultyLowAR = readingLowARRating,
ReadingDifficultyLowAr = readingLowARRating,
FlashlightDifficulty = flashlightRating,
SliderFactor = sliderFactor,
AimDifficultStrainCount = aimDifficultyStrainCount,
@ -150,7 +150,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
new Aim(mods, false),
new Speed(mods),
new Flashlight(mods),
new ReadingLowAR(mods),
new ReadingLowAr(mods),
};
return skills.ToArray();

View File

@ -111,34 +111,31 @@ namespace osu.Game.Rulesets.Osu.Difficulty
effectiveMissCount = Math.Min(effectiveMissCount + countOk * okMultiplier + countMeh * mehMultiplier, totalHits);
}
double power = OsuDifficultyCalculator.SUM_POWER;
const double power = OsuDifficultyCalculator.SUM_POWER;
double aimValue = computeAimValue(score, osuAttributes);
double speedValue = computeSpeedValue(score, osuAttributes);
double mechanicalValue = Math.Pow(Math.Pow(aimValue, power) + Math.Pow(speedValue, power), 1.0 / power);
// Cognition
double lowARValue = computeReadingLowARValue(score, osuAttributes);
double readingARValue = lowARValue;
double lowArValue = computeReadingLowArValue(score, osuAttributes);
double flashlightValue = computeFlashlightValue(score, osuAttributes);
// Reduce AR reading bonus if FL is present
double flPower = OsuDifficultyCalculator.FL_SUM_POWER;
double flashlightARValue = score.Mods.Any(h => h is OsuModFlashlight) ?
Math.Pow(Math.Pow(flashlightValue, flPower) + Math.Pow(readingARValue, flPower), 1.0 / flPower) : readingARValue;
const double fl_power = OsuDifficultyCalculator.FL_SUM_POWER;
double cognitionValue = flashlightARValue;
double flashlightArValue = score.Mods.Any(h => h is OsuModFlashlight)
? Math.Pow(Math.Pow(flashlightValue, fl_power) + Math.Pow(lowArValue, fl_power), 1.0 / fl_power)
: lowArValue;
double cognitionValue = flashlightArValue;
cognitionValue = AdjustCognitionPerformance(cognitionValue, mechanicalValue, flashlightValue);
double accuracyValue = computeAccuracyValue(score, osuAttributes);
// Add cognition value without LP-sum cuz otherwise it makes balancing harder
double totalValue =
(Math.Pow(Math.Pow(mechanicalValue, power) + Math.Pow(accuracyValue, power), 1.0 / power)
+ cognitionValue) * multiplier;
double totalValue = (Math.Pow(Math.Pow(mechanicalValue, power) + Math.Pow(accuracyValue, power), 1.0 / power) + cognitionValue) * multiplier;
return new OsuPerformanceAttributes
{
@ -297,10 +294,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty
double visualBonus = 0.1 * DifficultyCalculationUtils.Logistic(attributes.ApproachRate - 8.0);
// Buff if OD is way lower than AR
double ARODDelta = Math.Max(0, attributes.OverallDifficulty - attributes.ApproachRate);
double ArOdDelta = Math.Max(0, attributes.OverallDifficulty - attributes.ApproachRate);
// This one is goes from 0.0 on delta=0 to 1.0 somewhere around delta=3.4
double deltaBonus = (1 - Math.Pow(0.95, Math.Pow(ARODDelta, 4)));
double deltaBonus = (1 - Math.Pow(0.95, Math.Pow(ArOdDelta, 4)));
// Nerf delta bonus on OD lower than 10 and 9
if (attributes.OverallDifficulty < 10)
@ -335,9 +332,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
return flashlightValue;
}
private double computeReadingLowARValue(ScoreInfo score, OsuDifficultyAttributes attributes)
private double computeReadingLowArValue(ScoreInfo score, OsuDifficultyAttributes attributes)
{
double readingValue = ReadingLowAR.DifficultyToPerformance(attributes.ReadingDifficultyLowAR);
double readingValue = ReadingLowAr.DifficultyToPerformance(attributes.ReadingDifficultyLowAr);
// Penalize misses by assessing # of misses relative to the total # of objects. Default a 3% reduction for any # of misses.
if (effectiveMissCount > 0)

View File

@ -189,7 +189,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
// Overlapness between current and prev to make streams have 0 buff
double instantOverlapness = 0;
prevObject.OverlapValues?.TryGetValue(loopObj.Index, out instantOverlapness);
prevObject.OverlapValues.TryGetValue(loopObj.Index, out instantOverlapness);
// Nerf overlaps on wide angles
double angleFactor = 1;
@ -230,6 +230,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
if (cumulativeTimeWithoutCurrent >= cumulativeTimeWithCurrent)
break;
}
cumulativeTimeWithCurrent += historicTimes[i];
}
@ -284,9 +285,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
private static double getAngleSimilarity(double angle1, double angle2)
{
double difference = Math.Abs(angle1 - angle2);
double threeshold = Math.PI / 12;
const double threeshold = Math.PI / 12;
if (difference > threeshold) return 0;
return 1 - difference / threeshold;
}
@ -297,18 +299,18 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
double distance = Vector2.Distance(odho1.StackedPosition, odho2.StackedPosition); // Distance func is kinda slow for some reason
double radius = odho1.BaseObject.Radius;
double distance_sqr = distance * distance;
double radius_sqr = radius * radius;
double distanceSqr = distance * distance;
double radiusSqr = radius * radius;
if (distance > radius * 2)
return 0;
double s1 = Math.Acos(distance / (2 * radius)) * radius_sqr; // Area of sector
double s2 = distance * Math.Sqrt(radius_sqr - distance_sqr / 4) / 2; // Area of triangle
double s1 = Math.Acos(distance / (2 * radius)) * radiusSqr; // Area of sector
double s2 = distance * Math.Sqrt(radiusSqr - distanceSqr / 4) / 2; // Area of triangle
double overlappingAreaNormalized = (s1 - s2) * 2 / (Math.PI * radius_sqr);
double overlappingAreaNormalized = (s1 - s2) * 2 / (Math.PI * radiusSqr);
// don't ask me how i get this value, looks oddly similar to PI - 3
// Don't ask me how I got this value, looks oddly similar to PI - 3
const double stack_distance_ratio = 0.1414213562373;
double perfectStackBuff = (stack_distance_ratio - distance / radius) / stack_distance_ratio; // scale from 0 on normal stack to 1 on perfect stack
@ -397,21 +399,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
OsuDifficultyHitObject? prevObj5 = (OsuDifficultyHitObject?)Previous(5);
// 3-3 repeat
double similarity3_1 = getGeneralSimilarity(this, prevObj2);
double similarity3_2 = getGeneralSimilarity(prevObj0, prevObj3);
double similarity3_3 = getGeneralSimilarity(prevObj1, prevObj4);
double similarityBy3 = getGeneralSimilarity(this, prevObj2) * getGeneralSimilarity(prevObj0, prevObj3) * getGeneralSimilarity(prevObj1, prevObj4);
double similarity3_total = similarity3_1 * similarity3_2 * similarity3_3;
// 4-4 repeat
double similarity4_1 = getGeneralSimilarity(this, prevObj3);
double similarity4_2 = getGeneralSimilarity(prevObj0, prevObj4);
double similarity4_3 = getGeneralSimilarity(prevObj1, prevObj5);
double similarity4_total = similarity4_1 * similarity4_2 * similarity4_3;
// 4-4 repeat, only first 3 are checked, this is enough
double similarityBy4 = getGeneralSimilarity(this, prevObj3) * getGeneralSimilarity(prevObj0, prevObj4) * getGeneralSimilarity(prevObj1, prevObj5);
// Bandaid to fix Rubik's Cube +EZ
double wideness = 0;
if (Angle!.Value > Math.PI * 0.5)
{
// Goes from 0 to 1 as angle increasing from 90 degrees to 180
@ -429,7 +424,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
double predictability = Math.Cos(Math.Min(Math.PI / 2, 6 * adjustedAngleDifference)) * rhythmFactor;
// Punish for big pattern similarity
return 1 - (1 - predictability) * (1 - Math.Max(similarity3_total, similarity4_total));
return 1 - (1 - predictability) * (1 - Math.Max(similarityBy3, similarityBy4));
}
private double getGeneralSimilarity(OsuDifficultyHitObject? o1, OsuDifficultyHitObject? o2)
@ -440,7 +435,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
if (o1.AngleSigned == null || o2.AngleSigned == null)
return o1.AngleSigned == o2.AngleSigned ? 1 : 0;
double timeSimilarity = 1 - getTimeDifference(o1.StrainTime, o2.StrainTime);
double angleDelta = Math.Abs((double)o1.AngleSigned - (double)o2.AngleSigned);

View File

@ -12,12 +12,12 @@ using osu.Game.Rulesets.Osu.Difficulty.Evaluators;
namespace osu.Game.Rulesets.Osu.Difficulty.Skills
{
public class ReadingLowAR : StrainSkill
public class ReadingLowAr : StrainSkill
{
private double skillMultiplier => 1.22;
private double aimComponentMultiplier => 0.4;
public ReadingLowAR(Mod[] mods)
public ReadingLowAr(Mod[] mods)
: base(mods)
{
}
@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
private double strainDecayBase => 0.15;
private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);
private double currentDensityAimStrain = 0;
private double currentDensityAimStrain;
protected override double StrainValueAt(DifficultyHitObject current)
{
@ -43,6 +43,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
private double reducedNoteCount => 5;
private double reducedNoteBaseline => 0.7;
public override double DifficultyValue()
{
// Sections with 0 difficulty are excluded to avoid worst-case time complexity of the following sort (e.g. /b/2351871).
@ -70,6 +71,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
return difficulty;
}
public static double DifficultyToPerformance(double difficulty) => Math.Max(
Math.Max(Math.Pow(difficulty, 1.5) * 20, Math.Pow(difficulty, 2) * 17.0),
Math.Max(Math.Pow(difficulty, 3) * 10.5, Math.Pow(difficulty, 4) * 6.00));