mirror of
https://github.com/ppy/osu.git
synced 2024-12-14 08:52:55 +08:00
base change of aim refactor, isolated
This commit is contained in:
parent
7f350fe5c5
commit
587cf09d2a
@ -12,20 +12,20 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
||||
{
|
||||
public class OsuDifficultyHitObject : DifficultyHitObject
|
||||
{
|
||||
private const int normalized_radius = 52;
|
||||
private const int normalized_radius = 50; // Change radius to 50 to make 100 the diameter. Easier for mental maths.
|
||||
|
||||
protected new OsuHitObject BaseObject => (OsuHitObject)base.BaseObject;
|
||||
|
||||
/// <summary>
|
||||
/// Milliseconds elapsed since the start time of the previous <see cref="OsuDifficultyHitObject"/>, with a minimum of 25ms to account for simultaneous <see cref="OsuDifficultyHitObject"/>s.
|
||||
/// </summary>
|
||||
public double StrainTime { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Normalized distance from the end position of the previous <see cref="OsuDifficultyHitObject"/> to the start position of this <see cref="OsuDifficultyHitObject"/>.
|
||||
/// </summary>
|
||||
public double JumpDistance { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Normalized Vector from the end position of the previous <see cref="OsuDifficultyHitObject"/> to the start position of this <see cref="OsuDifficultyHitObject"/>.
|
||||
/// </summary>
|
||||
public Vector2 JumpVector { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Normalized distance between the start and end position of the previous <see cref="OsuDifficultyHitObject"/>.
|
||||
/// </summary>
|
||||
@ -37,6 +37,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
||||
/// </summary>
|
||||
public double? Angle { get; private set; }
|
||||
|
||||
/// <summary>
|
||||
/// Milliseconds elapsed since the start time of the previous <see cref="OsuDifficultyHitObject"/>, with a minimum of 50ms.
|
||||
/// </summary>
|
||||
public readonly double StrainTime;
|
||||
|
||||
private readonly OsuHitObject lastLastObject;
|
||||
private readonly OsuHitObject lastObject;
|
||||
|
||||
@ -73,7 +78,10 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Preprocessing
|
||||
|
||||
// Don't need to jump to reach spinners
|
||||
if (!(BaseObject is Spinner))
|
||||
JumpDistance = (BaseObject.StackedPosition * scalingFactor - lastCursorPosition * scalingFactor).Length;
|
||||
{
|
||||
JumpVector = (BaseObject.StackedPosition * scalingFactor - lastCursorPosition * scalingFactor);
|
||||
JumpDistance = JumpVector.Length;
|
||||
}
|
||||
|
||||
if (lastLastObject != null)
|
||||
{
|
||||
|
@ -6,6 +6,8 @@ using osu.Game.Rulesets.Difficulty.Preprocessing;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Framework.Utils;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
||||
{
|
||||
@ -14,51 +16,97 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
||||
/// </summary>
|
||||
public class Aim : OsuStrainSkill
|
||||
{
|
||||
private const double angle_bonus_begin = Math.PI / 3;
|
||||
private const double timing_threshold = 107;
|
||||
|
||||
public Aim(Mod[] mods)
|
||||
: base(mods)
|
||||
{
|
||||
}
|
||||
|
||||
protected override double SkillMultiplier => 26.25;
|
||||
protected override int HistoryLength => 2;
|
||||
|
||||
protected override double SkillMultiplier => 24.75;
|
||||
protected override double StrainDecayBase => 0.15;
|
||||
|
||||
private const double wide_angle_multiplier = 1.0;
|
||||
private const double acute_angle_multiplier = 1.0;
|
||||
private const double rhythm_variance_multiplier = 1.0;
|
||||
|
||||
protected override double StrainValueOf(DifficultyHitObject current)
|
||||
{
|
||||
if (current.BaseObject is Spinner)
|
||||
if (current.BaseObject is Spinner || Previous.Count <= 1)
|
||||
return 0;
|
||||
|
||||
var osuCurrent = (OsuDifficultyHitObject)current;
|
||||
var osuCurrObj = (OsuDifficultyHitObject)current;
|
||||
var osuPrevObj = (OsuDifficultyHitObject)Previous[0];
|
||||
var osuLastObj = (OsuDifficultyHitObject)Previous[1];
|
||||
|
||||
double result = 0;
|
||||
var currVector = Vector2.Divide(osuCurrObj.JumpVector, (float)osuCurrObj.StrainTime);
|
||||
var prevVector = Vector2.Divide(osuPrevObj.JumpVector, (float)osuPrevObj.StrainTime);
|
||||
|
||||
if (Previous.Count > 0)
|
||||
// Start with regular velocity.
|
||||
double aimStrain = currVector.Length;
|
||||
|
||||
if (Precision.AlmostEquals(osuCurrObj.StrainTime, osuPrevObj.StrainTime, 10)) // Rhythms are the same.
|
||||
{
|
||||
var osuPrevious = (OsuDifficultyHitObject)Previous[0];
|
||||
|
||||
if (osuCurrent.Angle != null && osuCurrent.Angle.Value > angle_bonus_begin)
|
||||
if (osuCurrObj.Angle != null)
|
||||
{
|
||||
const double scale = 90;
|
||||
double angle = osuCurrObj.Angle.Value;
|
||||
|
||||
var angleBonus = Math.Sqrt(
|
||||
Math.Max(osuPrevious.JumpDistance - scale, 0)
|
||||
* Math.Pow(Math.Sin(osuCurrent.Angle.Value - angle_bonus_begin), 2)
|
||||
* Math.Max(osuCurrent.JumpDistance - scale, 0));
|
||||
result = 1.4 * applyDiminishingExp(Math.Max(0, angleBonus)) / Math.Max(timing_threshold, osuPrevious.StrainTime);
|
||||
// Rewarding angles, take the smaller velocity as base.
|
||||
double angleBonus = Math.Min(currVector.Length, prevVector.Length);
|
||||
|
||||
double wideAngleBonus = calcWideAngleBonus(angle);
|
||||
double acuteAngleBonus = calcAcuteAngleBonus(angle);
|
||||
|
||||
if (osuCurrObj.StrainTime > 100)
|
||||
acuteAngleBonus = 0;
|
||||
else
|
||||
{
|
||||
acuteAngleBonus *= Math.Min(2, Math.Pow((100 - osuCurrObj.StrainTime) / 15, 1.5));
|
||||
wideAngleBonus *= Math.Pow(osuCurrObj.StrainTime / 100, 6);
|
||||
}
|
||||
|
||||
if (acuteAngleBonus > wideAngleBonus)
|
||||
angleBonus = Math.Min(angleBonus, 150 / osuCurrObj.StrainTime) * Math.Min(1, Math.Pow(Math.Min(osuCurrObj.JumpDistance, osuPrevObj.JumpDistance) / 150, 2));
|
||||
|
||||
angleBonus *= Math.Max(acuteAngleBonus * acute_angle_multiplier, wideAngleBonus * wide_angle_multiplier);
|
||||
|
||||
// add in angle velocity.
|
||||
aimStrain += angleBonus;
|
||||
}
|
||||
}
|
||||
else // There is a rhythm change
|
||||
{
|
||||
// Rewarding rhythm, take the smaller velocity as base.
|
||||
double rhythmBonus = Math.Min(currVector.Length, prevVector.Length);
|
||||
|
||||
double jumpDistanceExp = applyDiminishingExp(osuCurrent.JumpDistance);
|
||||
double travelDistanceExp = applyDiminishingExp(osuCurrent.TravelDistance);
|
||||
if (osuCurrObj.StrainTime + 10 < osuPrevObj.StrainTime && osuPrevObj.StrainTime > osuLastObj.StrainTime + 10)
|
||||
// Don't want to reward for a rhythm change back to back (unless its a double, which is why this only checks for fast -> slow -> fast).
|
||||
rhythmBonus = 0;
|
||||
|
||||
return Math.Max(
|
||||
result + (jumpDistanceExp + travelDistanceExp + Math.Sqrt(travelDistanceExp * jumpDistanceExp)) / Math.Max(osuCurrent.StrainTime, timing_threshold),
|
||||
(Math.Sqrt(travelDistanceExp * jumpDistanceExp) + jumpDistanceExp + travelDistanceExp) / osuCurrent.StrainTime
|
||||
);
|
||||
aimStrain += rhythmBonus * rhythm_variance_multiplier; // add in rhythm velocity.
|
||||
}
|
||||
|
||||
return aimStrain;
|
||||
}
|
||||
|
||||
private double applyDiminishingExp(double val) => Math.Pow(val, 0.99);
|
||||
private double calcWideAngleBonus(double angle)
|
||||
{
|
||||
if (angle < Math.PI / 3)
|
||||
return 0;
|
||||
if (angle < 2 * Math.PI / 3)
|
||||
return Math.Pow(Math.Sin(1.5 * (angle - Math.PI / 3)), 2);
|
||||
|
||||
return 0.25 + 0.75 * Math.Pow(Math.Sin(1.5 * (Math.PI - angle)), 2);
|
||||
}
|
||||
|
||||
private double calcAcuteAngleBonus(double angle)
|
||||
{
|
||||
if (angle < Math.PI / 3)
|
||||
return 0.5 + 0.5 * Math.Pow(Math.Sin(1.5 * angle), 2);
|
||||
if (angle < 2 * Math.PI / 3)
|
||||
return Math.Pow(Math.Sin(1.5 * (2 * Math.PI / 3 - angle)), 2);
|
||||
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
||||
/// </summary>
|
||||
public class Speed : OsuStrainSkill
|
||||
{
|
||||
private const double single_spacing_threshold = 125;
|
||||
private const double single_spacing_threshold = 135;
|
||||
|
||||
private const double angle_bonus_begin = 5 * Math.PI / 6;
|
||||
private const double pi_over_4 = Math.PI / 4;
|
||||
@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
||||
|
||||
return (1 + (speedBonus - 1) * 0.75)
|
||||
* angleBonus
|
||||
* (0.95 + speedBonus * Math.Pow(distance / single_spacing_threshold, 3.5))
|
||||
* (0.95 + speedBonus * Math.Pow(distance / single_spacing_threshold, 3.0))
|
||||
/ strainTime;
|
||||
}
|
||||
}
|
||||
|
Loading…
Reference in New Issue
Block a user