From e232968ea72463bb974b4a5d055fa92c837bf0b5 Mon Sep 17 00:00:00 2001 From: smoogipooo Date: Mon, 22 May 2017 10:25:28 +0900 Subject: [PATCH] Fix line endings resulting in CI error. --- .../Legacy/HitObjectPatternGenerator.cs | 848 +++++++++--------- 1 file changed, 424 insertions(+), 424 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index 3de3d129bf..657ba968a2 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -1,425 +1,425 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Linq; -using OpenTK; -using osu.Game.Audio; -using osu.Game.Beatmaps; -using osu.Game.Beatmaps.Timing; -using osu.Game.Rulesets.Mania.MathUtils; -using osu.Game.Rulesets.Mania.Objects; -using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Objects.Types; - -namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy -{ - internal class HitObjectPatternGenerator : PatternGenerator - { - public PatternType StairType { get; private set; } - - private readonly PatternType convertType; - - public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair) - : base(random, hitObject, beatmap, previousPattern) - { - StairType = lastStair; - - ControlPoint overridePoint; - ControlPoint controlPoint = beatmap.TimingInfo.TimingPointAt(hitObject.StartTime, out overridePoint); - - var positionData = hitObject as IHasPosition; - - float positionSeparation = ((positionData?.Position ?? Vector2.Zero) - previousPosition).Length; - double timeSeparation = hitObject.StartTime - previousTime; - - double beatLength = controlPoint.BeatLength; - bool kiai = (overridePoint ?? controlPoint).KiaiMode; - - if (timeSeparation <= 125) - { - // More than 120 BPM - convertType |= PatternType.ForceNotStack; - } - - if (timeSeparation <= 80) - { - // More than 187 BPM - convertType |= PatternType.ForceNotStack | PatternType.KeepSingle; - } - else if (timeSeparation <= 95) - { - // More than 157 BPM - convertType |= PatternType.ForceNotStack | PatternType.KeepSingle | lastStair; - } - else if (timeSeparation <= 105) - { - // More than 140 BPM - convertType |= PatternType.ForceNotStack | PatternType.LowProbability; - } - else if (timeSeparation <= 125) - { - // More than 120 BPM - convertType |= PatternType.ForceNotStack; - } - else if (timeSeparation <= 135 && positionSeparation < 20) - { - // More than 111 BPM stream - convertType |= PatternType.Cycle | PatternType.KeepSingle; - } - else if (timeSeparation <= 150 & positionSeparation < 20) - { - // More than 100 BPM stream - convertType |= PatternType.ForceStack | PatternType.LowProbability; - } - else if (positionSeparation < 20 && density >= beatLength / 2.5) - { - // Low density stream - convertType |= PatternType.Reverse | PatternType.LowProbability; - } - else if (density < beatLength / 2.5 || kiai) - { - // High density - } - else - convertType |= PatternType.LowProbability; - } - - public override Pattern Generate() - { - int lastColumn = PreviousPattern.HitObjects.First().Column; - - if ((convertType & PatternType.Reverse) > 0 && PreviousPattern.HitObjects.Count() > 0) - { - // Generate a new pattern by copying the last hit objects in reverse-column order - var pattern = new Pattern(); - - int siblings = PreviousPattern.HitObjects.Count(h => h.Column >= RandomStart); - - for (int i = RandomStart; i < AvailableColumns; i++) - if (PreviousPattern.IsFilled(i)) - addToPattern(pattern, RandomStart + AvailableColumns - i - 1, siblings); - - return pattern; - } - - if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1 - // If we convert to 7K + 1, let's not overload the special key - && (AvailableColumns != 8 || lastColumn != 0) - // Make sure the last column was not the centre column - && (AvailableColumns % 2 == 0 || lastColumn != AvailableColumns / 2)) - { - // Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object) - var pattern = new Pattern(); - - int column = RandomStart + AvailableColumns - lastColumn - 1; - addToPattern(pattern, column); - - return pattern; - } - - if ((convertType & PatternType.ForceStack) > 0 && PreviousPattern.HitObjects.Count() > 0) - { - // Generate a new pattern by placing on the already filled columns - var pattern = new Pattern(); - - int siblings = PreviousPattern.HitObjects.Count(h => h.Column >= RandomStart); - - for (int i = RandomStart; i < AvailableColumns; i++) - if (PreviousPattern.IsFilled(i)) - addToPattern(pattern, i, siblings); - - return pattern; - } - - if ((convertType & PatternType.Stair) > 0 && PreviousPattern.HitObjects.Count() == 1) - { - // Generate a new pattern by placing on the next column, cycling back to the start if there is no "next" - var pattern = new Pattern(); - - int targetColumn = lastColumn + 1; - if (targetColumn == AvailableColumns) - { - targetColumn = RandomStart; - StairType = PatternType.ReverseStair; - } - - addToPattern(pattern, targetColumn); - return pattern; - } - - if ((convertType & PatternType.ReverseStair) > 0 && PreviousPattern.HitObjects.Count() == 1) - { - // Generate a new pattern by placing on the previous column, cycling back to the end if there is no "previous" - var pattern = new Pattern(); - - int targetColumn = lastColumn - 1; - if (targetColumn == RandomStart - 1) - { - targetColumn = AvailableColumns - 1; - StairType = PatternType.Stair; - } - - addToPattern(pattern, targetColumn); - return pattern; - } - - if ((convertType & PatternType.KeepSingle) > 0) - return generateRandomNotes(1); - - if ((convertType & PatternType.Mirror) > 0) - { - if (ConversionDifficulty > 6.5) - return generateRandomPatternWithMirrored(0.12, 0.38, 0.12); - if (ConversionDifficulty > 4) - return generateRandomPatternWithMirrored(0.12, 0.17, 0); - return generateRandomPatternWithMirrored(0.12, 0, 0); - } - - if (ConversionDifficulty > 6.5) - { - if ((convertType & PatternType.LowProbability) > 0) - return generateRandomPattern(0.78, 0.42, 0, 0); - return generateRandomPattern(1, 0.62, 0, 0); - } - - if (ConversionDifficulty > 4) - { - if ((convertType & PatternType.LowProbability) > 0) - return generateRandomPattern(0.35, 0.08, 0, 0); - return generateRandomPattern(0.52, 0.15, 0, 0); - } - - if (ConversionDifficulty > 2) - { - if ((convertType & PatternType.LowProbability) > 0) - return generateRandomPattern(0.18, 0, 0, 0); - return generateRandomPattern(0.45, 0, 0, 0); - } - - return generateRandomPattern(0, 0, 0, 0); - } - - /// - /// Generates random notes. - /// - /// This will generate as many as it can up to , accounting for - /// any stacks if is forcing no stacks. - /// - /// - /// The amount of notes to generate. - /// Custom siblings count if is not the number of siblings in this pattern. - /// The containing the hit objects. - private Pattern generateRandomNotes(int noteCount, int siblingsOverride = -1) - { - var pattern = new Pattern(); - - bool allowStacking = (convertType & PatternType.ForceNotStack) == 0; - - if (!allowStacking) - noteCount = Math.Min(noteCount, AvailableColumns - RandomStart - PreviousPattern.ColumnsFilled); - - int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true); - for (int i = 0; i < noteCount; i++) - { - while (pattern.IsFilled(nextColumn) || (PreviousPattern.IsFilled(nextColumn) && !allowStacking)) - { - if ((convertType & PatternType.Gathered) > 0) - { - nextColumn++; - if (nextColumn == AvailableColumns) - nextColumn = RandomStart; - } - else - nextColumn = Random.Next(RandomStart, AvailableColumns); - } - - addToPattern(pattern, nextColumn, siblingsOverride != -1 ? siblingsOverride : noteCount); - } - - return pattern; - } - - /// - /// Whether this hit object can generate a note in the special column. - /// - private bool hasSpecialColumn => HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP) && HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH); - - /// - /// Generates a random pattern. - /// - /// Probability for 2 notes to be generated. - /// Probability for 3 notes to be generated. - /// Probability for 4 notes to be generated. - /// Probability for 5 notes to be generated. - /// The containing the hit objects. - private Pattern generateRandomPattern(double p2, double p3, double p4, double p5) - { - var pattern = new Pattern(); - - int noteCount = getRandomNoteCount(p2, p3, p4, p5); - int siblings = noteCount; - - if (RandomStart > 0 && hasSpecialColumn) - { - siblings++; - addToPattern(pattern, 0, siblings); - } - - pattern.Add(generateRandomNotes(noteCount, siblings)); - - return pattern; - } - - /// - /// Generates a random pattern which has both normal and mirrored notes. - /// - /// The probability for a note to be added to the centre column. - /// Probability for 2 notes to be generated. - /// Probability for 3 notes to be generated. - /// The containing the hit objects. - private Pattern generateRandomPatternWithMirrored(double centreProbability, double p2, double p3) - { - var pattern = new Pattern(); - - bool addToCentre; - int noteCount = getRandomNoteCountMirrored(centreProbability, p2, p3, out addToCentre); - int siblings = noteCount; - - if (addToCentre) - siblings++; - if (RandomStart > 0 && hasSpecialColumn) - siblings++; - - int columnLimit = (AvailableColumns % 2 == 0 ? AvailableColumns : AvailableColumns - 1) / 2; - int nextColumn = Random.Next(RandomStart, columnLimit); - for (int i = 0; i < noteCount; i++) - { - while (pattern.IsFilled(nextColumn)) - nextColumn = Random.Next(RandomStart, columnLimit); - // Add normal note - addToPattern(pattern, nextColumn, siblings); - // Add mirrored note - addToPattern(pattern, RandomStart + AvailableColumns - nextColumn - 1); - } - - if (addToCentre) - addToPattern(pattern, AvailableColumns / 2, siblings); - - if (RandomStart > 0 && hasSpecialColumn) - addToPattern(pattern, 0, siblings); - - return pattern; - } - - /// - /// Generates a count of notes to be generated from a list of probabilities. - /// - /// Probability for 2 notes to be generated. - /// Probability for 3 notes to be generated. - /// Probability for 4 notes to be generated. - /// Probability for 5 notes to be generated. - /// The amount of notes to be generated. - private int getRandomNoteCount(double p2, double p3, double p4, double p5) - { - switch (AvailableColumns) - { - case 2: - p2 = 0; - p3 = 0; - p4 = 0; - p5 = 0; - break; - case 3: - p2 = Math.Max(p2, 0.1); - p3 = 0; - p4 = 0; - p5 = 0; - break; - case 4: - p2 = Math.Max(p2, 0.23); - p3 = Math.Max(p3, 0.04); - p4 = 0; - p5 = 0; - break; - case 5: - p3 = Math.Max(p3, 0.15); - p4 = Math.Max(p4, 0.03); - p5 = 0; - break; - } - - if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)) - p2 = 1; - - return GetRandomNoteCount(p2, p3, p4, p5); - } - - /// - /// Generates a count of notes to be generated from a list of probabilities. - /// - /// The probability for a note to be added to the centre column. - /// Probability for 2 notes to be generated. - /// Probability for 3 notes to be generated. - /// Whether to add a note to the centre column. - /// The amount of notes to be generated. The note to be added to the centre column will NOT be part of this count. - private int getRandomNoteCountMirrored(double centreProbability, double p2, double p3, out bool addToCentre) - { - addToCentre = false; - - if ((convertType & PatternType.ForceNotStack) > 0) - return getRandomNoteCount(p2 / 2, p2, (p2 + p3) / 2, p3); - - switch (AvailableColumns) - { - case 2: - centreProbability = 0; - p2 = 0; - p3 = 0; - break; - case 3: - centreProbability = Math.Max(centreProbability, 0.03); - p2 = Math.Max(p2, 0.1); - p3 = 0; - break; - case 4: - centreProbability = 0; - p2 = Math.Max(p2 * 2, 0.2); - p3 = 0; - break; - case 5: - centreProbability = Math.Max(centreProbability, 0.03); - p3 = 0; - break; - case 6: - centreProbability = 0; - p2 = Math.Max(p2 * 2, 0.5); - p3 = Math.Max(p3 * 2, 0.15); - break; - } - - double centreVal = Random.NextDouble(); - int noteCount = GetRandomNoteCount(p2, p3); - - addToCentre = AvailableColumns % 2 != 0 && noteCount != 3 && centreVal > 1 - centreProbability; - return noteCount; - } - - /// - /// Constructs and adds a note to a pattern. - /// - /// The pattern to add to. - /// The column to add the note to. - /// The number of children alongside this note (these will not be generated, but are used for volume calculations). - private void addToPattern(Pattern pattern, int column, int siblings = 1) - { - pattern.Add(new Note - { - StartTime = HitObject.StartTime, - Samples = HitObject.Samples, - Column = column, - Siblings = siblings - }); - } - } +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using OpenTK; +using osu.Game.Audio; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Timing; +using osu.Game.Rulesets.Mania.MathUtils; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; + +namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy +{ + internal class HitObjectPatternGenerator : PatternGenerator + { + public PatternType StairType { get; private set; } + + private readonly PatternType convertType; + + public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, Beatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair) + : base(random, hitObject, beatmap, previousPattern) + { + StairType = lastStair; + + ControlPoint overridePoint; + ControlPoint controlPoint = beatmap.TimingInfo.TimingPointAt(hitObject.StartTime, out overridePoint); + + var positionData = hitObject as IHasPosition; + + float positionSeparation = ((positionData?.Position ?? Vector2.Zero) - previousPosition).Length; + double timeSeparation = hitObject.StartTime - previousTime; + + double beatLength = controlPoint.BeatLength; + bool kiai = (overridePoint ?? controlPoint).KiaiMode; + + if (timeSeparation <= 125) + { + // More than 120 BPM + convertType |= PatternType.ForceNotStack; + } + + if (timeSeparation <= 80) + { + // More than 187 BPM + convertType |= PatternType.ForceNotStack | PatternType.KeepSingle; + } + else if (timeSeparation <= 95) + { + // More than 157 BPM + convertType |= PatternType.ForceNotStack | PatternType.KeepSingle | lastStair; + } + else if (timeSeparation <= 105) + { + // More than 140 BPM + convertType |= PatternType.ForceNotStack | PatternType.LowProbability; + } + else if (timeSeparation <= 125) + { + // More than 120 BPM + convertType |= PatternType.ForceNotStack; + } + else if (timeSeparation <= 135 && positionSeparation < 20) + { + // More than 111 BPM stream + convertType |= PatternType.Cycle | PatternType.KeepSingle; + } + else if (timeSeparation <= 150 & positionSeparation < 20) + { + // More than 100 BPM stream + convertType |= PatternType.ForceStack | PatternType.LowProbability; + } + else if (positionSeparation < 20 && density >= beatLength / 2.5) + { + // Low density stream + convertType |= PatternType.Reverse | PatternType.LowProbability; + } + else if (density < beatLength / 2.5 || kiai) + { + // High density + } + else + convertType |= PatternType.LowProbability; + } + + public override Pattern Generate() + { + int lastColumn = PreviousPattern.HitObjects.First().Column; + + if ((convertType & PatternType.Reverse) > 0 && PreviousPattern.HitObjects.Count() > 0) + { + // Generate a new pattern by copying the last hit objects in reverse-column order + var pattern = new Pattern(); + + int siblings = PreviousPattern.HitObjects.Count(h => h.Column >= RandomStart); + + for (int i = RandomStart; i < AvailableColumns; i++) + if (PreviousPattern.IsFilled(i)) + addToPattern(pattern, RandomStart + AvailableColumns - i - 1, siblings); + + return pattern; + } + + if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1 + // If we convert to 7K + 1, let's not overload the special key + && (AvailableColumns != 8 || lastColumn != 0) + // Make sure the last column was not the centre column + && (AvailableColumns % 2 == 0 || lastColumn != AvailableColumns / 2)) + { + // Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object) + var pattern = new Pattern(); + + int column = RandomStart + AvailableColumns - lastColumn - 1; + addToPattern(pattern, column); + + return pattern; + } + + if ((convertType & PatternType.ForceStack) > 0 && PreviousPattern.HitObjects.Count() > 0) + { + // Generate a new pattern by placing on the already filled columns + var pattern = new Pattern(); + + int siblings = PreviousPattern.HitObjects.Count(h => h.Column >= RandomStart); + + for (int i = RandomStart; i < AvailableColumns; i++) + if (PreviousPattern.IsFilled(i)) + addToPattern(pattern, i, siblings); + + return pattern; + } + + if ((convertType & PatternType.Stair) > 0 && PreviousPattern.HitObjects.Count() == 1) + { + // Generate a new pattern by placing on the next column, cycling back to the start if there is no "next" + var pattern = new Pattern(); + + int targetColumn = lastColumn + 1; + if (targetColumn == AvailableColumns) + { + targetColumn = RandomStart; + StairType = PatternType.ReverseStair; + } + + addToPattern(pattern, targetColumn); + return pattern; + } + + if ((convertType & PatternType.ReverseStair) > 0 && PreviousPattern.HitObjects.Count() == 1) + { + // Generate a new pattern by placing on the previous column, cycling back to the end if there is no "previous" + var pattern = new Pattern(); + + int targetColumn = lastColumn - 1; + if (targetColumn == RandomStart - 1) + { + targetColumn = AvailableColumns - 1; + StairType = PatternType.Stair; + } + + addToPattern(pattern, targetColumn); + return pattern; + } + + if ((convertType & PatternType.KeepSingle) > 0) + return generateRandomNotes(1); + + if ((convertType & PatternType.Mirror) > 0) + { + if (ConversionDifficulty > 6.5) + return generateRandomPatternWithMirrored(0.12, 0.38, 0.12); + if (ConversionDifficulty > 4) + return generateRandomPatternWithMirrored(0.12, 0.17, 0); + return generateRandomPatternWithMirrored(0.12, 0, 0); + } + + if (ConversionDifficulty > 6.5) + { + if ((convertType & PatternType.LowProbability) > 0) + return generateRandomPattern(0.78, 0.42, 0, 0); + return generateRandomPattern(1, 0.62, 0, 0); + } + + if (ConversionDifficulty > 4) + { + if ((convertType & PatternType.LowProbability) > 0) + return generateRandomPattern(0.35, 0.08, 0, 0); + return generateRandomPattern(0.52, 0.15, 0, 0); + } + + if (ConversionDifficulty > 2) + { + if ((convertType & PatternType.LowProbability) > 0) + return generateRandomPattern(0.18, 0, 0, 0); + return generateRandomPattern(0.45, 0, 0, 0); + } + + return generateRandomPattern(0, 0, 0, 0); + } + + /// + /// Generates random notes. + /// + /// This will generate as many as it can up to , accounting for + /// any stacks if is forcing no stacks. + /// + /// + /// The amount of notes to generate. + /// Custom siblings count if is not the number of siblings in this pattern. + /// The containing the hit objects. + private Pattern generateRandomNotes(int noteCount, int siblingsOverride = -1) + { + var pattern = new Pattern(); + + bool allowStacking = (convertType & PatternType.ForceNotStack) == 0; + + if (!allowStacking) + noteCount = Math.Min(noteCount, AvailableColumns - RandomStart - PreviousPattern.ColumnsFilled); + + int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true); + for (int i = 0; i < noteCount; i++) + { + while (pattern.IsFilled(nextColumn) || (PreviousPattern.IsFilled(nextColumn) && !allowStacking)) + { + if ((convertType & PatternType.Gathered) > 0) + { + nextColumn++; + if (nextColumn == AvailableColumns) + nextColumn = RandomStart; + } + else + nextColumn = Random.Next(RandomStart, AvailableColumns); + } + + addToPattern(pattern, nextColumn, siblingsOverride != -1 ? siblingsOverride : noteCount); + } + + return pattern; + } + + /// + /// Whether this hit object can generate a note in the special column. + /// + private bool hasSpecialColumn => HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP) && HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH); + + /// + /// Generates a random pattern. + /// + /// Probability for 2 notes to be generated. + /// Probability for 3 notes to be generated. + /// Probability for 4 notes to be generated. + /// Probability for 5 notes to be generated. + /// The containing the hit objects. + private Pattern generateRandomPattern(double p2, double p3, double p4, double p5) + { + var pattern = new Pattern(); + + int noteCount = getRandomNoteCount(p2, p3, p4, p5); + int siblings = noteCount; + + if (RandomStart > 0 && hasSpecialColumn) + { + siblings++; + addToPattern(pattern, 0, siblings); + } + + pattern.Add(generateRandomNotes(noteCount, siblings)); + + return pattern; + } + + /// + /// Generates a random pattern which has both normal and mirrored notes. + /// + /// The probability for a note to be added to the centre column. + /// Probability for 2 notes to be generated. + /// Probability for 3 notes to be generated. + /// The containing the hit objects. + private Pattern generateRandomPatternWithMirrored(double centreProbability, double p2, double p3) + { + var pattern = new Pattern(); + + bool addToCentre; + int noteCount = getRandomNoteCountMirrored(centreProbability, p2, p3, out addToCentre); + int siblings = noteCount; + + if (addToCentre) + siblings++; + if (RandomStart > 0 && hasSpecialColumn) + siblings++; + + int columnLimit = (AvailableColumns % 2 == 0 ? AvailableColumns : AvailableColumns - 1) / 2; + int nextColumn = Random.Next(RandomStart, columnLimit); + for (int i = 0; i < noteCount; i++) + { + while (pattern.IsFilled(nextColumn)) + nextColumn = Random.Next(RandomStart, columnLimit); + // Add normal note + addToPattern(pattern, nextColumn, siblings); + // Add mirrored note + addToPattern(pattern, RandomStart + AvailableColumns - nextColumn - 1); + } + + if (addToCentre) + addToPattern(pattern, AvailableColumns / 2, siblings); + + if (RandomStart > 0 && hasSpecialColumn) + addToPattern(pattern, 0, siblings); + + return pattern; + } + + /// + /// Generates a count of notes to be generated from a list of probabilities. + /// + /// Probability for 2 notes to be generated. + /// Probability for 3 notes to be generated. + /// Probability for 4 notes to be generated. + /// Probability for 5 notes to be generated. + /// The amount of notes to be generated. + private int getRandomNoteCount(double p2, double p3, double p4, double p5) + { + switch (AvailableColumns) + { + case 2: + p2 = 0; + p3 = 0; + p4 = 0; + p5 = 0; + break; + case 3: + p2 = Math.Max(p2, 0.1); + p3 = 0; + p4 = 0; + p5 = 0; + break; + case 4: + p2 = Math.Max(p2, 0.23); + p3 = Math.Max(p3, 0.04); + p4 = 0; + p5 = 0; + break; + case 5: + p3 = Math.Max(p3, 0.15); + p4 = Math.Max(p4, 0.03); + p5 = 0; + break; + } + + if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)) + p2 = 1; + + return GetRandomNoteCount(p2, p3, p4, p5); + } + + /// + /// Generates a count of notes to be generated from a list of probabilities. + /// + /// The probability for a note to be added to the centre column. + /// Probability for 2 notes to be generated. + /// Probability for 3 notes to be generated. + /// Whether to add a note to the centre column. + /// The amount of notes to be generated. The note to be added to the centre column will NOT be part of this count. + private int getRandomNoteCountMirrored(double centreProbability, double p2, double p3, out bool addToCentre) + { + addToCentre = false; + + if ((convertType & PatternType.ForceNotStack) > 0) + return getRandomNoteCount(p2 / 2, p2, (p2 + p3) / 2, p3); + + switch (AvailableColumns) + { + case 2: + centreProbability = 0; + p2 = 0; + p3 = 0; + break; + case 3: + centreProbability = Math.Max(centreProbability, 0.03); + p2 = Math.Max(p2, 0.1); + p3 = 0; + break; + case 4: + centreProbability = 0; + p2 = Math.Max(p2 * 2, 0.2); + p3 = 0; + break; + case 5: + centreProbability = Math.Max(centreProbability, 0.03); + p3 = 0; + break; + case 6: + centreProbability = 0; + p2 = Math.Max(p2 * 2, 0.5); + p3 = Math.Max(p3 * 2, 0.15); + break; + } + + double centreVal = Random.NextDouble(); + int noteCount = GetRandomNoteCount(p2, p3); + + addToCentre = AvailableColumns % 2 != 0 && noteCount != 3 && centreVal > 1 - centreProbability; + return noteCount; + } + + /// + /// Constructs and adds a note to a pattern. + /// + /// The pattern to add to. + /// The column to add the note to. + /// The number of children alongside this note (these will not be generated, but are used for volume calculations). + private void addToPattern(Pattern pattern, int column, int siblings = 1) + { + pattern.Add(new Note + { + StartTime = HitObject.StartTime, + Samples = HitObject.Samples, + Column = column, + Siblings = siblings + }); + } + } } \ No newline at end of file