1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-12 18:52:57 +08:00

added density aim multiplier

This commit is contained in:
Givikap120 2024-02-23 19:52:00 +02:00
parent 9e6ae3587a
commit 5d4c78239b
8 changed files with 44 additions and 55 deletions

View File

@ -18,8 +18,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
private const double overlap_multiplier = 0.8;
public static double CalculateDenstityOf(OsuDifficultyHitObject currObj)
public static double EvaluateDenstityOf(DifficultyHitObject current)
{
var currObj = (OsuDifficultyHitObject)current;
double density = 0;
double densityAnglesNerf = -2; // we have threshold of 2, so 2 or same angles won't be punished
@ -34,8 +35,7 @@ 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.
// For HD: it's not subtracting anything cuz it's multiplied by the aim difficulty anyways.
loopDifficulty *= logistic((loopObj.MinimumJumpDistance - 60) / 10);
loopDifficulty *= logistic((loopObj.MinimumJumpDistance - 30) / 10);
// Reduce density bonus for this object if they're too apart in time
// Nerf starts on 1500ms and reaches maximum (*=0) on 3000ms
@ -123,14 +123,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
return screenOverlapDifficulty;
}
public static double EvaluateDensityDifficultyOf(DifficultyHitObject current)
public static double EvaluateDifficultyOf(DifficultyHitObject current)
{
if (current.BaseObject is Spinner || current.Index == 0)
return 0;
var currObj = (OsuDifficultyHitObject)current;
double pastObjectDifficultyInfluence = CalculateDenstityOf(currObj);
double pastObjectDifficultyInfluence = EvaluateDenstityOf(current);
double screenOverlapDifficulty = CalculateOverlapDifficultyOf(currObj);
double difficulty = Math.Pow(4 * Math.Log(Math.Max(1, pastObjectDifficultyInfluence)), 2.3);

View File

@ -123,28 +123,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Evaluators
// https://www.desmos.com/calculator/hbj7swzlth
public static double GetDifficulty(double preempt)
{
double value = Math.Pow(3, 3 - 0.01 * preempt); // 1 for 300ms, 0.25 for 400ms, 0.0625 for 500ms
double value = Math.Pow(3.5, 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;
}
// This is very accurate on preempt > 300ms, breaking starting somewhere around 120ms
public static double GetPreempt(double difficulty)
{
double fixCoef = difficulty / GetDifficulty(highArCurveReversed(difficulty));
return highArCurveReversed(difficulty * fixCoef);
}
// This is an approximation cuz high AR curve is unsolvable
// https://www.desmos.com/calculator/n9vk18bcyh
private static double highArCurveReversed(double value)
{
double helperValue = value / Math.Pow(1 - Math.Pow(1.7, value - 2), 0.45);
double preempt = -(Math.Log(helperValue, 3) - 3) / 0.01;
return preempt;
}
// We are using mutiply and divide instead of add and subtract, so values won't be negative
// https://www.desmos.com/calculator/fv5xerwpd2
private static double softmin(double a, double b, double power = Math.E) => a * b / Math.Log(Math.Pow(power, a) + Math.Pow(power, b), power);

View File

@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (mods.Any(h => h is OsuModFlashlight))
baseFlashlightPerformance = Math.Pow(flashlightRating, 2.0) * 25.0;
double baseReadingLowARPerformance = Math.Pow(readingLowARRating, 2.5) * 17.0;
double baseReadingLowARPerformance = ReadingLowAR.DifficultyToPerformance(readingLowARRating);
double baseReadingHighARPerformance = OsuStrainSkill.DifficultyToPerformance(readingHighARRating);
double baseReadingARPerformance = Math.Pow(Math.Pow(baseReadingLowARPerformance, SUM_POWER) + Math.Pow(baseReadingHighARPerformance, SUM_POWER), 1.0 / SUM_POWER);

View File

@ -261,7 +261,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
if (score.Mods.Any(m => m is OsuModTouchDevice))
rawReading = Math.Pow(rawReading, 0.8);
double readingValue = Math.Pow(rawReading, 2.5) * 17.0;
double readingValue = ReadingLowAR.DifficultyToPerformance(rawReading);
// 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

@ -35,6 +35,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
/// </summary>
protected virtual double DifficultyMultiplier => DEFAULT_DIFFICULTY_MULTIPLIER;
protected virtual double StrainDecayBase => 0.15;
protected double StrainDecay(double ms) => Math.Pow(StrainDecayBase, ms / 1000);
protected OsuStrainSkill(Mod[] mods)
: base(mods)
{

View File

@ -16,18 +16,31 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
public class ReadingLowAR : GraphSkill
{
private readonly List<double> difficulties = new List<double>();
private double skillMultiplier => 2;
private double skillMultiplier => 1.3;
private double aimComponentMultiplier => 0.7;
//private double skillMultiplier => 2;
public ReadingLowAR(Mod[] mods)
: base(mods)
{
}
private double strainDecayBase => 0.15;
private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);
private double currentDensityAimStrain = 0;
public override void Process(DifficultyHitObject current)
{
double currentDifficulty = ReadingEvaluator.EvaluateDensityDifficultyOf(current) * skillMultiplier;
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;
difficulties.Add(currentDifficulty);
double densityReadingDifficulty = ReadingEvaluator.EvaluateDifficultyOf(current);
double totalDensityDifficulty = (currentDensityAimStrain + densityReadingDifficulty) * skillMultiplier;
difficulties.Add(totalDensityDifficulty);
if (current.Index == 0)
CurrentSectionEnd = Math.Ceiling(current.StartTime / SectionLength) * SectionLength;
@ -39,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
CurrentSectionEnd += SectionLength;
}
CurrentSectionPeak = Math.Max(currentDifficulty, CurrentSectionPeak);
CurrentSectionPeak = Math.Max(totalDensityDifficulty, CurrentSectionPeak);
}
private double reducedNoteCount => 5;
@ -71,6 +84,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
return difficulty;
}
public static double DifficultyToPerformance(double difficulty) => Math.Pow(difficulty, 3) * 10.0;
}
public class ReadingHidden : OsuStrainSkill
@ -82,15 +97,12 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
private double currentStrain;
private double skillMultiplier => 5;
private double strainDecayBase => 0.15;
private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);
protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => currentStrain * strainDecay(time - current.Previous(0).StartTime);
protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => currentStrain * StrainDecay(time - current.Previous(0).StartTime);
protected override double StrainValueAt(DifficultyHitObject current)
{
currentStrain *= strainDecay(current.DeltaTime);
currentStrain *= StrainDecay(current.DeltaTime);
// We're not using slider aim because we assuming that HD doesn't makes sliders harder (what is not true, but we will ignore this for now)
double hiddenDifficulty = AimEvaluator.EvaluateDifficultyOf(current, false);

View File

@ -29,12 +29,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
private readonly List<double> difficulties = new List<double>();
private int objectsCount = 0;
private double preempt = -1;
public override void Process(DifficultyHitObject current)
{
if (preempt < 0) preempt = ((OsuDifficultyHitObject)current).Preempt;
aimComponent.Process(current);
speedComponent.Process(current);
@ -97,17 +94,14 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
private bool adjustHighAR;
private double currentStrain;
private double skillMultiplier => 17.8;
private double defaultValueMultiplier => 30;
private double strainDecayBase => 0.15;
private double skillMultiplier => 17;
private double defaultValueMultiplier => 50;
private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);
protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => currentStrain * strainDecay(time - current.Previous(0).StartTime);
protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => currentStrain * StrainDecay(time - current.Previous(0).StartTime);
protected override double StrainValueAt(DifficultyHitObject current)
{
currentStrain *= strainDecay(current.DeltaTime);
currentStrain *= StrainDecay(current.DeltaTime);
double aimDifficulty = AimEvaluator.EvaluateDifficultyOf(current, true);
double readingDifficulty = ReadingHighAREvaluator.EvaluateDifficultyOf(current, adjustHighAR);
@ -122,8 +116,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
public class HighARSpeedComponent : OsuStrainSkill
{
private double skillMultiplier => 850;
private double strainDecayBase => 0.3;
private double skillMultiplier => 820;
protected override double StrainDecayBase => 0.3;
private double currentStrain;
private double currentRhythm;
@ -133,15 +127,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
{
}
private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);
protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => (currentStrain * currentRhythm) * strainDecay(time - current.Previous(0).StartTime);
protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => (currentStrain * currentRhythm) * StrainDecay(time - current.Previous(0).StartTime);
protected override double StrainValueAt(DifficultyHitObject current)
{
OsuDifficultyHitObject currODHO = (OsuDifficultyHitObject)current;
currentStrain *= strainDecay(currODHO.StrainTime);
currentStrain *= StrainDecay(currODHO.StrainTime);
double speedDifficulty = SpeedEvaluator.EvaluateDifficultyOf(current) * skillMultiplier;
speedDifficulty *= Math.Pow(ReadingHighAREvaluator.EvaluateDifficultyOf(current, false), 2);

View File

@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
public class Speed : OsuStrainSkill
{
private double skillMultiplier => 1375;
private double strainDecayBase => 0.3;
protected override double StrainDecayBase => 0.3;
private double currentStrain;
private double currentRhythm;
@ -32,15 +32,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
{
}
private double strainDecay(double ms) => Math.Pow(strainDecayBase, ms / 1000);
protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => (currentStrain * currentRhythm) * strainDecay(time - current.Previous(0).StartTime);
protected override double CalculateInitialStrain(double time, DifficultyHitObject current) => (currentStrain * currentRhythm) * StrainDecay(time - current.Previous(0).StartTime);
protected override double StrainValueAt(DifficultyHitObject current)
{
OsuDifficultyHitObject currODHO = (OsuDifficultyHitObject)current;
currentStrain *= strainDecay(currODHO.StrainTime);
currentStrain *= StrainDecay(currODHO.StrainTime);
currentStrain += SpeedEvaluator.EvaluateDifficultyOf(current) * skillMultiplier;
currentRhythm = currODHO.RhythmDifficulty;