diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/ReadingEvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/ReadingEvaluator.cs index 3df9491395..e14bb3c6b5 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/ReadingEvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/ReadingEvaluator.cs @@ -16,9 +16,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators { private const double reading_window_size = 3000; - private const double overlap_multiplier = 0.8; + private const double overlap_multiplier = 2; - public static double EvaluateDenstityOf(DifficultyHitObject current, bool applyDistanceNerf = true) + public static double EvaluateDensityOf(DifficultyHitObject current, bool applyDistanceNerf = true) { var currObj = (OsuDifficultyHitObject)current; double density = 0; @@ -100,13 +100,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators if (prevObj1.IsNotNull() && prevObj2.IsNotNull()) 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); prevAngleAdjust *= alternatingFactor; // Nerf if alternating prevAngleAdjust *= rhythmFactor; // Nerf if same rhythms - prevAngleAdjust *= acuteAngleFactor; + // prevAngleAdjust *= acuteAngleFactor; // no longer needed? angleDifference -= prevAngleAdjust; @@ -138,8 +138,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators return density; } - public static double CalculateOverlapDifficultyOf(OsuDifficultyHitObject currObj) + public static double EvaluateOverlapDifficultyOf(DifficultyHitObject current) { + var currObj = (OsuDifficultyHitObject)current; double screenOverlapDifficulty = 0; foreach (var loopObj in retrievePastVisibleObjects(currObj)) @@ -153,28 +154,31 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators screenOverlapDifficulty += lastOverlapness; } - return screenOverlapDifficulty; + return overlap_multiplier * Math.Max(0, screenOverlapDifficulty - 0.7); } public static double EvaluateDifficultyOf(DifficultyHitObject current) { if (current.BaseObject is Spinner || current.Index == 0) return 0; - var currObj = (OsuDifficultyHitObject)current; + double difficulty = Math.Pow(4 * Math.Log(Math.Max(1, EvaluateDensityOf(current))), 2.5); - double pastObjectDifficultyInfluence = EvaluateDenstityOf(current); - double screenOverlapDifficulty = CalculateOverlapDifficultyOf(currObj); - - double difficulty = Math.Pow(4 * Math.Log(Math.Max(1, pastObjectDifficultyInfluence)), 2.5); - - screenOverlapDifficulty = Math.Max(0, screenOverlapDifficulty - 0.75); // make overlap value =1 cost significantly less - - double overlapBonus = overlap_multiplier * screenOverlapDifficulty * difficulty; + double overlapBonus = EvaluateOverlapDifficultyOf(current) * difficulty; difficulty += overlapBonus; return difficulty; } + public static double EvaluateAimingDensityFactorOf(DifficultyHitObject current) + { + double difficulty = EvaluateDensityOf(current); + + double overlapBonus = EvaluateOverlapDifficultyOf(current) * difficulty; + difficulty += overlapBonus; + + return Math.Max(0, Math.Pow(difficulty, 1.5) - 1); + } + // Returns value from 0 to 1, where 0 is very predictable and 1 is very unpredictable public static double EvaluateInpredictabilityOf(DifficultyHitObject current) { @@ -295,7 +299,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators { var currObj = (OsuDifficultyHitObject)current; - double density = ReadingEvaluator.EvaluateDenstityOf(current, false); + double density = ReadingEvaluator.EvaluateDensityOf(current, false); // Consider that density matters only starting from 3rd note on the screen double densityFactor = Math.Max(0, density - 1) / 4; diff --git a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/ReadingHighAREvaluator.cs b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/ReadingHighAREvaluator.cs index 949860aa76..461337e65a 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Evaluators/ReadingHighAREvaluator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Evaluators/ReadingHighAREvaluator.cs @@ -123,7 +123,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators // https://www.desmos.com/calculator/hbj7swzlth public static double GetDifficulty(double preempt) { - double value = Math.Pow(3.5, 3 - 0.01 * preempt); // 1 for 300ms, 0.25 for 400ms, 0.0625 for 500ms + double value = Math.Pow(4, 3 - 0.01 * preempt); // 1 for 300ms, 0.25 for 400ms, 0.0625 for 500ms value = softmin(value, 2, 1.7); // use softmin to achieve full-memory cap, 2 times more than AR11 (300ms) return value; } diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs index a9640e5791..e18c865e73 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs @@ -130,12 +130,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty yield return (ATTRIB_ID_SLIDER_FACTOR, SliderFactor); yield return (ATTRIB_ID_SPEED_NOTE_COUNT, SpeedNoteCount); - yield return (ATTRIB_ID_READING_LOW_AR, ReadingDifficultyLowAR); - yield return (ATTRIB_ID_READING_HIGH_AR, ReadingDifficultyHighAR); - yield return (ATTRIB_ID_READING_SLIDERS, ReadingDifficultySliders); - - if (ShouldSerializeHiddenDifficulty()) - yield return (ATTRIB_ID_READING_HIDDEN, HiddenDifficulty); } public override void FromDatabaseAttributes(IReadOnlyDictionary values, IBeatmapOnlineInfo onlineInfo) @@ -150,10 +144,6 @@ namespace osu.Game.Rulesets.Osu.Difficulty SliderFactor = values[ATTRIB_ID_SLIDER_FACTOR]; SpeedNoteCount = values[ATTRIB_ID_SPEED_NOTE_COUNT]; - ReadingDifficultyLowAR = values[ATTRIB_ID_READING_LOW_AR]; - ReadingDifficultyHighAR = values[ATTRIB_ID_READING_HIGH_AR]; - ReadingDifficultySliders = values[ATTRIB_ID_READING_SLIDERS]; - HiddenDifficulty = values.GetValueOrDefault(ATTRIB_ID_READING_HIDDEN); FlashlightDifficulty = values.GetValueOrDefault(ATTRIB_ID_FLASHLIGHT); DrainRate = onlineInfo.DrainRate; diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index b16ad5a21f..848de57440 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -173,8 +173,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty new HiddenFlashlight(mods), }; - if (mods.Any(h => h is OsuModFlashlight)) - skills.Add(new Flashlight(mods)); + // Why adding flashlight one more time???? + //if (mods.Any(h => h is OsuModFlashlight)) + // skills.Add(new Flashlight(mods)); return skills.ToArray(); } diff --git a/osu.Game.Rulesets.Osu/Difficulty/Skills/Reading.cs b/osu.Game.Rulesets.Osu/Difficulty/Skills/Reading.cs index 6ad78696e4..7fd88e19b4 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/Skills/Reading.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/Skills/Reading.cs @@ -31,12 +31,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills public override void Process(DifficultyHitObject current) { - double densityFactor = Math.Max(0, Math.Pow(ReadingEvaluator.EvaluateDenstityOf(current), 1.5) - 1); - // double density = Math.Max(0, ReadingEvaluator.EvaluateDenstityOf(current)); - currentDensityAimStrain *= strainDecay(current.DeltaTime); - currentDensityAimStrain += densityFactor * AimEvaluator.EvaluateDifficultyOf(current, false) * aimComponentMultiplier; - double densityReadingDifficulty = ReadingEvaluator.EvaluateDifficultyOf(current); + double densityAimingFactor = ReadingEvaluator.EvaluateAimingDensityFactorOf(current); + + currentDensityAimStrain *= strainDecay(current.DeltaTime); + currentDensityAimStrain += densityAimingFactor * AimEvaluator.EvaluateDifficultyOf(current, false) * aimComponentMultiplier; + double totalDensityDifficulty = (currentDensityAimStrain + densityReadingDifficulty) * skillMultiplier; difficulties.Add(totalDensityDifficulty);