mirror of
https://github.com/ppy/osu.git
synced 2024-11-15 08:07:40 +08:00
66643a97b0
Although this isn't necessary for existing official rulesets and calculators, custom calculators can have use cases for accessing mods in difficulty calculation. For example, accounting for the effects of visual mods.
66 lines
2.5 KiB
C#
66 lines
2.5 KiB
C#
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
using System;
|
|
using osu.Game.Rulesets.Difficulty.Preprocessing;
|
|
using osu.Game.Rulesets.Difficulty.Skills;
|
|
using osu.Game.Rulesets.Mods;
|
|
using osu.Game.Rulesets.Osu.Difficulty.Preprocessing;
|
|
using osu.Game.Rulesets.Osu.Objects;
|
|
|
|
namespace osu.Game.Rulesets.Osu.Difficulty.Skills
|
|
{
|
|
/// <summary>
|
|
/// Represents the skill required to correctly aim at every object in the map with a uniform CircleSize and normalized distances.
|
|
/// </summary>
|
|
public class Aim : Skill
|
|
{
|
|
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 double StrainDecayBase => 0.15;
|
|
|
|
protected override double StrainValueOf(DifficultyHitObject current)
|
|
{
|
|
if (current.BaseObject is Spinner)
|
|
return 0;
|
|
|
|
var osuCurrent = (OsuDifficultyHitObject)current;
|
|
|
|
double result = 0;
|
|
|
|
if (Previous.Count > 0)
|
|
{
|
|
var osuPrevious = (OsuDifficultyHitObject)Previous[0];
|
|
|
|
if (osuCurrent.Angle != null && osuCurrent.Angle.Value > angle_bonus_begin)
|
|
{
|
|
const double scale = 90;
|
|
|
|
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.5 * applyDiminishingExp(Math.Max(0, angleBonus)) / Math.Max(timing_threshold, osuPrevious.StrainTime);
|
|
}
|
|
}
|
|
|
|
double jumpDistanceExp = applyDiminishingExp(osuCurrent.JumpDistance);
|
|
double travelDistanceExp = applyDiminishingExp(osuCurrent.TravelDistance);
|
|
|
|
return Math.Max(
|
|
result + (jumpDistanceExp + travelDistanceExp + Math.Sqrt(travelDistanceExp * jumpDistanceExp)) / Math.Max(osuCurrent.StrainTime, timing_threshold),
|
|
(Math.Sqrt(travelDistanceExp * jumpDistanceExp) + jumpDistanceExp + travelDistanceExp) / osuCurrent.StrainTime
|
|
);
|
|
}
|
|
|
|
private double applyDiminishingExp(double val) => Math.Pow(val, 0.99);
|
|
}
|
|
}
|