// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; using osu.Game.Rulesets.Difficulty.Preprocessing; namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Rhythm.Data { /// /// Represents a group of s with no rhythm variation. /// public class SameRhythmGroupedHitObjects : IntervalGroupedHitObjects, IHasInterval { public TaikoDifficultyHitObject FirstHitObject => Children[0]; public SameRhythmGroupedHitObjects? Previous; /// /// of the first hit object. /// public double StartTime => Children[0].StartTime; /// /// The interval between the first and final hit object within this group. /// public double Duration => Children[^1].StartTime - Children[0].StartTime; /// /// The interval in ms of each hit object in this . This is only defined if there is /// more than two hit objects in this . /// public double? HitObjectInterval; /// /// The ratio of between this and the previous . In the /// case where one or both of the is undefined, this will have a value of 1. /// public double HitObjectIntervalRatio = 1; /// public double Interval { get; private set; } public SameRhythmGroupedHitObjects(SameRhythmGroupedHitObjects? previous, List data, ref int i) : base(data, ref i, 5) { Previous = previous; foreach (var hitObject in Children) { hitObject.Rhythm.SameRhythmGroupedHitObjects = this; // Pass the HitObjectInterval to each child. hitObject.HitObjectInterval = HitObjectInterval; } calculateIntervals(); } public static List GroupHitObjects(List data) { List flatPatterns = new List(); // Index does not need to be incremented, as it is handled within IntervalGroupedHitObjects's constructor. for (int i = 0; i < data.Count;) { SameRhythmGroupedHitObjects? previous = flatPatterns.Count > 0 ? flatPatterns[^1] : null; flatPatterns.Add(new SameRhythmGroupedHitObjects(previous, data, ref i)); } return flatPatterns; } private void calculateIntervals() { // Calculate the average interval between hitobjects, or null if there are fewer than two. HitObjectInterval = Children.Count < 2 ? null : (Children[^1].StartTime - Children[0].StartTime) / (Children.Count - 1); // If both the current and previous intervals are available, calculate the ratio. if (Previous?.HitObjectInterval != null && HitObjectInterval != null) { HitObjectIntervalRatio = HitObjectInterval.Value / Previous.HitObjectInterval.Value; } if (Previous == null) { return; } Interval = StartTime - Previous.StartTime; } } }