diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 9922d4c8ad..4734e40803 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -77,7 +77,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps yield break; } - var objects = IsForCurrentRuleset ? generateSpecific(original) : generateConverted(original); + var objects = IsForCurrentRuleset ? generateSpecific(original, beatmap) : generateConverted(original, beatmap); if (objects == null) yield break; @@ -110,10 +110,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// Method that generates hit objects for osu!mania specific beatmaps. /// /// The original hit object. + /// The original beatmap. This is used to look-up any values dependent on a fully-loaded beatmap. /// The hit objects generated. - private IEnumerable generateSpecific(HitObject original) + private IEnumerable generateSpecific(HitObject original, Beatmap originalBeatmap) { - var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern); + var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern, originalBeatmap); Pattern newPattern = generator.Generate(); lastPattern = newPattern; @@ -125,26 +126,25 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// Method that generates hit objects for non-osu!mania beatmaps. /// /// The original hit object. + /// The original beatmap. This is used to look-up any values dependent on a fully-loaded beatmap. /// The hit objects generated. - private IEnumerable generateConverted(HitObject original) + private IEnumerable generateConverted(HitObject original, Beatmap originalBeatmap) { var endTimeData = original as IHasEndTime; var distanceData = original as IHasDistance; var positionData = original as IHasPosition; - // Following lines currently commented out to appease resharper - Patterns.PatternGenerator conversion = null; if (distanceData != null) - conversion = new DistanceObjectPatternGenerator(random, original, beatmap, lastPattern); + conversion = new DistanceObjectPatternGenerator(random, original, beatmap, lastPattern, originalBeatmap); else if (endTimeData != null) - conversion = new EndTimeObjectPatternGenerator(random, original, beatmap); + conversion = new EndTimeObjectPatternGenerator(random, original, beatmap, originalBeatmap); else if (positionData != null) { computeDensity(original.StartTime); - conversion = new HitObjectPatternGenerator(random, original, beatmap, lastPattern, lastTime, lastPosition, density, lastStair); + conversion = new HitObjectPatternGenerator(random, original, beatmap, lastPattern, lastTime, lastPosition, density, lastStair, originalBeatmap); recordNote(original.StartTime, positionData.Position); } @@ -153,10 +153,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps return null; Pattern newPattern = conversion.Generate(); - lastPattern = newPattern; - var stairPatternGenerator = conversion as HitObjectPatternGenerator; - lastStair = stairPatternGenerator?.StairType ?? lastStair; + lastPattern = conversion is EndTimeObjectPatternGenerator ? lastPattern : newPattern; + lastStair = (conversion as HitObjectPatternGenerator)?.StairType ?? lastStair; return newPattern.HitObjects; } @@ -166,8 +165,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// private class SpecificBeatmapPatternGenerator : Patterns.Legacy.PatternGenerator { - public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern) - : base(random, hitObject, beatmap, previousPattern) + public SpecificBeatmapPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, Beatmap originalBeatmap) + : base(random, hitObject, beatmap, previousPattern, originalBeatmap) { } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index a102781e70..28cf119833 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using System.Linq; using osu.Game.Audio; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.MathUtils; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -29,11 +30,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy private PatternType convertType; - public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern) - : base(random, hitObject, beatmap, previousPattern) + public DistanceObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, Beatmap originalBeatmap) + : base(random, hitObject, beatmap, previousPattern, originalBeatmap) { convertType = PatternType.None; - if (Beatmap.ControlPointInfo.EffectPointAt(hitObject.StartTime).KiaiMode) + if (!Beatmap.ControlPointInfo.EffectPointAt(hitObject.StartTime).KiaiMode) convertType = PatternType.LowProbability; var distanceData = hitObject as IHasDistance; @@ -305,19 +306,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy p4 = 0; break; case 3: - p2 = Math.Max(p2, 0.1); + p2 = Math.Min(p2, 0.1); p3 = 0; p4 = 0; break; case 4: - p2 = Math.Max(p2, 0.3); - p3 = Math.Max(p3, 0.04); + p2 = Math.Min(p2, 0.3); + p3 = Math.Min(p3, 0.04); p4 = 0; break; case 5: - p2 = Math.Max(p2, 0.34); - p3 = Math.Max(p3, 0.1); - p4 = Math.Max(p4, 0.03); + p2 = Math.Min(p2, 0.34); + p3 = Math.Min(p3, 0.1); + p4 = Math.Min(p4, 0.03); break; } @@ -396,17 +397,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy // Create the hold note addToPattern(pattern, holdColumn, startTime, endTime); - int noteCount = 1; + int nextColumn = Random.Next(RandomStart, TotalColumns); + int noteCount; if (ConversionDifficulty > 6.5) noteCount = GetRandomNoteCount(0.63, 0); else if (ConversionDifficulty > 4) noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0.12 : 0.45, 0); else if (ConversionDifficulty > 2.5) noteCount = GetRandomNoteCount(TotalColumns < 6 ? 0 : 0.24, 0); + else + noteCount = 0; noteCount = Math.Min(TotalColumns - 1, noteCount); bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP); - int nextColumn = Random.Next(RandomStart, TotalColumns); var rowPattern = new Pattern(); for (int i = 0; i <= spanCount; i++) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs index 278a4c4aab..ffbabba75a 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs @@ -7,6 +7,7 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using System.Linq; using osu.Game.Audio; +using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.Objects; namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy @@ -15,8 +16,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { private readonly double endTime; - public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap) - : base(random, hitObject, beatmap, new Pattern()) + public EndTimeObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Beatmap originalBeatmap) + : base(random, hitObject, beatmap, new Pattern(), originalBeatmap) { var endtimeData = HitObject as IHasEndTime; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index c4ef23a982..e126534c54 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -5,6 +5,7 @@ using System; using System.Linq; using OpenTK; using osu.Game.Audio; +using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Mania.MathUtils; using osu.Game.Rulesets.Mania.Objects; @@ -19,8 +20,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy private readonly PatternType convertType; - public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair) - : base(random, hitObject, beatmap, previousPattern) + public HitObjectPatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, double previousTime, Vector2 previousPosition, double density, PatternType lastStair, Beatmap originalBeatmap) + : base(random, hitObject, beatmap, previousPattern, originalBeatmap) { if (previousTime > hitObject.StartTime) throw new ArgumentOutOfRangeException(nameof(previousTime)); if (density < 0) throw new ArgumentOutOfRangeException(nameof(density)); @@ -308,20 +309,20 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy p5 = 0; break; case 3: - p2 = Math.Max(p2, 0.1); + p2 = Math.Min(p2, 0.1); p3 = 0; p4 = 0; p5 = 0; break; case 4: - p2 = Math.Max(p2, 0.23); - p3 = Math.Max(p3, 0.04); + p2 = Math.Min(p2, 0.23); + p3 = Math.Min(p3, 0.04); p4 = 0; p5 = 0; break; case 5: - p3 = Math.Max(p3, 0.15); - p4 = Math.Max(p4, 0.03); + p3 = Math.Min(p3, 0.15); + p4 = Math.Min(p4, 0.03); p5 = 0; break; } @@ -355,23 +356,23 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy p3 = 0; break; case 3: - centreProbability = Math.Max(centreProbability, 0.03); - p2 = Math.Max(p2, 0.1); + centreProbability = Math.Min(centreProbability, 0.03); + p2 = 0; p3 = 0; break; case 4: centreProbability = 0; - p2 = Math.Max(p2 * 2, 0.2); + p2 = Math.Min(p2 * 2, 0.2); p3 = 0; break; case 5: - centreProbability = Math.Max(centreProbability, 0.03); + centreProbability = Math.Min(centreProbability, 0.03); p3 = 0; break; case 6: centreProbability = 0; - p2 = Math.Max(p2 * 2, 0.5); - p3 = Math.Max(p3 * 2, 0.15); + p2 = Math.Min(p2 * 2, 0.5); + p3 = Math.Min(p3 * 2, 0.15); break; } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs index 5f98749f0c..501950cdcd 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs @@ -25,14 +25,20 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// protected readonly FastRandom Random; - protected PatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern) + /// + /// The beatmap which is being converted from. + /// + protected readonly Beatmap OriginalBeatmap; + + protected PatternGenerator(FastRandom random, HitObject hitObject, ManiaBeatmap beatmap, Pattern previousPattern, Beatmap originalBeatmap) : base(hitObject, beatmap, previousPattern) { if (random == null) throw new ArgumentNullException(nameof(random)); - if (beatmap == null) throw new ArgumentNullException(nameof(beatmap)); - if (previousPattern == null) throw new ArgumentNullException(nameof(previousPattern)); + if (originalBeatmap == null) throw new ArgumentNullException(nameof(originalBeatmap)); Random = random; + OriginalBeatmap = originalBeatmap; + RandomStart = TotalColumns == 8 ? 1 : 0; } @@ -94,17 +100,20 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (conversionDifficulty != null) return conversionDifficulty.Value; - HitObject lastObject = Beatmap.HitObjects.LastOrDefault(); - HitObject firstObject = Beatmap.HitObjects.FirstOrDefault(); + HitObject lastObject = OriginalBeatmap.HitObjects.LastOrDefault(); + HitObject firstObject = OriginalBeatmap.HitObjects.FirstOrDefault(); double drainTime = (lastObject?.StartTime ?? 0) - (firstObject?.StartTime ?? 0); - drainTime -= Beatmap.TotalBreakTime; + drainTime -= OriginalBeatmap.TotalBreakTime; if (drainTime == 0) - drainTime = 10000; + drainTime = 10000000; - BeatmapDifficulty difficulty = Beatmap.BeatmapInfo.BaseDifficulty; - conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + Beatmap.HitObjects.Count / drainTime * 9f) / 38f * 5f / 1.15; + // We need this in seconds + drainTime /= 1000; + + BeatmapDifficulty difficulty = OriginalBeatmap.BeatmapInfo.BaseDifficulty; + conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + OriginalBeatmap.HitObjects.Count / drainTime * 9f) / 38f * 5f / 1.15; conversionDifficulty = Math.Min(conversionDifficulty.Value, 12); return conversionDifficulty.Value; diff --git a/osu.Game.Rulesets.Mania/Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania/Tests/ManiaBeatmapConversionTest.cs index 2095addc72..9d55ab643d 100644 --- a/osu.Game.Rulesets.Mania/Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania/Tests/ManiaBeatmapConversionTest.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Mania.Tests private bool isForCurrentRuleset; [NonParallelizable] - [TestCase("basic", false), Ignore("See: https://github.com/ppy/osu/issues/2150")] + [TestCase("basic", false)] public void Test(string name, bool isForCurrentRuleset) { this.isForCurrentRuleset = isForCurrentRuleset;