using System.Collections.Generic; using System.Linq; namespace osu.Game.Beatmaps.ControlPoints { public class ControlPointInfo { /// /// All the control points. /// public readonly List ControlPoints = new List(); /// /// Finds the difficulty control point that is active at . /// /// The time to find the difficulty control point at. /// The difficulty control point. public DifficultyControlPoint DifficultyPointAt(double time) => ControlPoints.OfType().LastOrDefault(t => t.Time <= time) ?? new DifficultyControlPoint(); /// /// Finds the effect control point that is active at . /// /// The time to find the effect control point at. /// The effect control point. public EffectControlPoint EffectPointAt(double time) => ControlPoints.OfType().LastOrDefault(t => t.Time <= time) ?? new EffectControlPoint(); /// /// Finds the sound control point that is active at . /// /// The time to find the sound control point at. /// The sound control point. public SoundControlPoint SoundPointAt(double time) => ControlPoints.OfType().LastOrDefault(t => t.Time <= time) ?? new SoundControlPoint(); /// /// Finds the timing control point that is active at . /// /// The time to find the timing control point at. /// The timing control point. public TimingControlPoint TimingPointAt(double time) => ControlPoints.OfType().LastOrDefault(t => t.Time <= time) ?? new TimingControlPoint(); /// /// Finds the maximum BPM represented by any timing control point. /// public double BPMMaximum => 60000 / (ControlPoints.OfType().OrderBy(c => c.BeatLength).FirstOrDefault() ?? new TimingControlPoint()).BeatLength; /// /// Finds the minimum BPM represented by any timing control point. /// public double BPMMinimum => 60000 / (ControlPoints.OfType().OrderByDescending(c => c.BeatLength).FirstOrDefault() ?? new TimingControlPoint()).BeatLength; /// /// Finds the mode BPM (most common BPM) represented by the control points. /// public double BPMMode => 60000 / (ControlPoints.OfType().GroupBy(c => c.BeatLength).OrderByDescending(grp => grp.Count()).FirstOrDefault()?.FirstOrDefault() ?? new TimingControlPoint()).BeatLength; } }