using System; namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing { /// /// Stores colour compression information for a . /// public class TaikoDifficultyHitObjectColour { private const int max_repetition_interval = 16; private TaikoDifficultyHitObjectColour previous; /// /// True if the current colour is different from the previous colour. /// public bool Delta { get; private set; } /// /// How many notes are Delta repeated /// public int DeltaRunLength { get; private set; } /// /// How many notes between the current and previous identical . /// Negative number means that there is no repetition in range. /// If no repetition is found this will have a value of + 1. /// public int RepetitionInterval { get; private set; } /// /// Get the instance for the given hitObject. This is implemented /// as a static function instead of constructor to allow for reusing existing instances. /// TODO: findRepetitionInterval needs to be called a final time after all hitObjects have been processed. /// public static TaikoDifficultyHitObjectColour GetInstanceFor(TaikoDifficultyHitObject hitObject) { TaikoDifficultyHitObject lastObject = hitObject.PreviousNote(0); TaikoDifficultyHitObjectColour previous = lastObject?.Colour; bool delta = lastObject == null || hitObject.HitType != lastObject.HitType; if (previous != null && delta == previous.Delta) { previous.DeltaRunLength += 1; return previous; } // Calculate RepetitionInterval for previous previous?.FindRepetitionInterval(); return new TaikoDifficultyHitObjectColour() { Delta = delta, DeltaRunLength = 1, RepetitionInterval = max_repetition_interval + 1, previous = previous }; } /// /// Finds the closest previous that has the identical delta value /// and run length with the current instance, and returns the amount of notes between them. /// public void FindRepetitionInterval() { if (previous?.previous == null) { RepetitionInterval = max_repetition_interval + 1; return; } int interval = previous.DeltaRunLength; TaikoDifficultyHitObjectColour other = previous.previous; while (other != null && interval < max_repetition_interval) { interval += other.DeltaRunLength; if (other.Delta == Delta && other.DeltaRunLength == DeltaRunLength) { RepetitionInterval = Math.Min(interval, max_repetition_interval); return; } other = other.previous; } RepetitionInterval = max_repetition_interval + 1; } } }