// Copyright (c) ppy Pty Ltd . 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.Mods; using osu.Game.Rulesets.Osu.Difficulty.Evaluators; using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; using System.Linq; namespace osu.Game.Rulesets.Osu.Difficulty.Skills { /// /// Represents the skill required to press keys with regards to keeping up with the speed at which objects need to be hit. /// public class Speed : OsuStrainSkill { private double skillMultiplier => 1.430; private double strainDecayBase => 0.3; private double currentStrain; private double currentRhythm; protected override int ReducedSectionCount => 5; public Speed(Mod[] mods) : base(mods) { } 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 StrainValueAt(DifficultyHitObject current) { currentStrain *= strainDecay(((OsuDifficultyHitObject)current).StrainTime); currentStrain += SpeedEvaluator.EvaluateDifficultyOf(current) * skillMultiplier; currentRhythm = RhythmEvaluator.EvaluateDifficultyOf(current); double totalStrain = currentStrain * currentRhythm; ObjectStrains.Add(totalStrain); return totalStrain; } public double RelevantNoteCount() { if (ObjectStrains.Count == 0) return 0; double maxStrain = ObjectStrains.Max(); if (maxStrain == 0) return 0; return ObjectStrains.Sum(strain => 1.0 / (1.0 + Math.Exp(-(strain / maxStrain * 12.0 - 6.0)))); } } }