From 99e28b6efa5a9bcfb6b6491ba58ffcc8da767a1d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 17:38:43 +0900 Subject: [PATCH 01/18] No reason for beatmap conversion tests to be internal --- osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs | 4 ++-- osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs | 4 ++-- osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs | 4 ++-- osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index 5b34e46247..14d913cffa 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Catch.Tests { - internal class CatchBeatmapConversionTest : BeatmapConversionTest + public class CatchBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Catch"; @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Catch.Tests protected override Ruleset CreateRuleset() => new CatchRuleset(); } - internal struct ConvertValue : IEquatable + public struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index 5ae899f6d6..f9e6531119 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Mania.Tests { - internal class ManiaBeatmapConversionTest : BeatmapConversionTest + public class ManiaBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; @@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Mania.Tests protected override Ruleset CreateRuleset() => new ManiaRuleset(); } - internal struct ConvertValue : IEquatable + public struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs index 386ae5eb05..1383256352 100644 --- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs @@ -13,7 +13,7 @@ using OpenTK; namespace osu.Game.Rulesets.Osu.Tests { - internal class OsuBeatmapConversionTest : BeatmapConversionTest + public class OsuBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Osu"; @@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Tests protected override Ruleset CreateRuleset() => new OsuRuleset(); } - internal struct ConvertValue : IEquatable + public struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs index 11586e340b..fb0b2040f4 100644 --- a/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko.Tests/TaikoBeatmapConversionTest.cs @@ -12,7 +12,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Taiko.Tests { - internal class TaikoBeatmapConversionTest : BeatmapConversionTest + public class TaikoBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko"; @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Taiko.Tests protected override Ruleset CreateRuleset() => new TaikoRuleset(); } - internal struct ConvertValue : IEquatable + public struct ConvertValue : IEquatable { /// /// A sane value to account for osu!stable using ints everwhere. From e94518697833fc60837078492607acadfbab79aa Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 17:59:52 +0900 Subject: [PATCH 02/18] Expose the beatmap converter --- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index cf4dda52a8..b95173e44d 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -25,6 +25,8 @@ namespace osu.Game.Tests.Beatmaps protected abstract string ResourceAssembly { get; } + protected IBeatmapConverter Converter { get; private set; } + protected void Test(string name) { var ourResult = convert(name); @@ -88,10 +90,11 @@ namespace osu.Game.Tests.Beatmaps var rulesetInstance = CreateRuleset(); beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo(); - var result = new ConvertResult(); - var converter = rulesetInstance.CreateBeatmapConverter(beatmap); + Converter = rulesetInstance.CreateBeatmapConverter(beatmap); - converter.ObjectConverted += (orig, converted) => + var result = new ConvertResult(); + + Converter.ObjectConverted += (orig, converted) => { converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty)); @@ -103,7 +106,7 @@ namespace osu.Game.Tests.Beatmaps result.Mappings.Add(mapping); }; - IBeatmap convertedBeatmap = converter.Convert(); + IBeatmap convertedBeatmap = Converter.Convert(); rulesetInstance.CreateBeatmapProcessor(convertedBeatmap)?.PostProcess(); return result; From 47ae962099fdb248c6fc547ecb85bd2ee01b6398 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 18:20:28 +0900 Subject: [PATCH 03/18] Output only one mapping failure per mapping --- .../Tests/Beatmaps/BeatmapConversionTest.cs | 20 +++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index b95173e44d..ff57ef41c5 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -43,14 +43,22 @@ namespace osu.Game.Tests.Beatmaps Assert.Fail($"A conversion did not generate any hitobjects, but should have, for hitobject at time: {expectedResult.Mappings[mappingCounter].StartTime}\n"); else if (mappingCounter >= expectedResult.Mappings.Count) Assert.Fail($"A conversion generated hitobjects, but should not have, for hitobject at time: {ourResult.Mappings[mappingCounter].StartTime}\n"); + else if (!expectedResult.Mappings[mappingCounter].Equals(ourResult.Mappings[mappingCounter])) + { + var expectedMapping = expectedResult.Mappings[mappingCounter]; + var ourMapping = ourResult.Mappings[mappingCounter]; + + Assert.Fail($"The conversion mapping differed for object at time {expectedMapping.StartTime}:\n" + + $"Expected {JsonConvert.SerializeObject(expectedMapping)}\n" + + $"Received: {JsonConvert.SerializeObject(ourMapping)}\n"); + } else { - var counter = mappingCounter; + var ourMapping = ourResult.Mappings[mappingCounter]; + var expectedMapping = expectedResult.Mappings[mappingCounter]; + Assert.Multiple(() => { - var ourMapping = ourResult.Mappings[counter]; - var expectedMapping = expectedResult.Mappings[counter]; - int objectCounter = 0; while (true) { @@ -62,10 +70,6 @@ namespace osu.Game.Tests.Beatmaps else if (objectCounter >= expectedMapping.Objects.Count) Assert.Fail($"The conversion generated a hitobject, but should not have, for hitobject at time: {ourMapping.StartTime}:\n" + $"Received: {JsonConvert.SerializeObject(ourMapping.Objects[objectCounter])}\n"); - else if (!expectedMapping.Equals(ourMapping)) - Assert.Fail($"The conversion mapping differed for object at time {expectedMapping.StartTime}:\n" - + $"Expected {JsonConvert.SerializeObject(expectedMapping)}\n" - + $"Received: {JsonConvert.SerializeObject(ourMapping)}\n"); else if (!expectedMapping.Objects[objectCounter].Equals(ourMapping.Objects[objectCounter])) { Assert.Fail($"The conversion generated differing hitobjects for object at time: {expectedMapping.StartTime}:\n" From afbf35b81416ec5e76c6425971ec6ca7677abf74 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 20:48:36 +0900 Subject: [PATCH 04/18] Add rng components to mania conversion tests --- .../ManiaBeatmapConversionTest.cs | 30 ++++++++++++++++++- .../MathUtils/FastRandom.cs | 18 ++++++----- 2 files changed, 40 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index f9e6531119..c13319ace9 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -5,6 +5,8 @@ using System; using System.Collections.Generic; using NUnit.Framework; using osu.Framework.MathUtils; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; @@ -12,7 +14,7 @@ using osu.Game.Tests.Beatmaps; namespace osu.Game.Rulesets.Mania.Tests { - public class ManiaBeatmapConversionTest : BeatmapConversionTest + public class ManiaBeatmapConversionTest : BeatmapConversionTest { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; @@ -33,9 +35,35 @@ namespace osu.Game.Rulesets.Mania.Tests }; } + protected override ManiaConvertMapping CreateConvertMapping() => new ManiaConvertMapping(Converter); + protected override Ruleset CreateRuleset() => new ManiaRuleset(); } + public class ManiaConvertMapping : ConvertMapping, IEquatable + { + public uint RandomW; + public uint RandomX; + public uint RandomY; + public uint RandomZ; + + public ManiaConvertMapping() + { + } + + public ManiaConvertMapping(IBeatmapConverter converter) + { + var maniaConverter = (ManiaBeatmapConverter)converter; + RandomW = maniaConverter.Random.W; + RandomX = maniaConverter.Random.X; + RandomY = maniaConverter.Random.Y; + RandomZ = maniaConverter.Random.Z; + } + + public bool Equals(ManiaConvertMapping other) => other != null && RandomW == other.RandomW && RandomX == other.RandomX && RandomY == other.RandomY && RandomZ == other.RandomZ; + public override bool Equals(ConvertMapping other) => base.Equals(other) && Equals(other as ManiaConvertMapping); + } + public struct ConvertValue : IEquatable { /// diff --git a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs b/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs index a3efd5c2bd..785cd5ab06 100644 --- a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs +++ b/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs @@ -15,11 +15,15 @@ namespace osu.Game.Rulesets.Mania.MathUtils private const uint y = 842502087; private const uint z = 3579807591; private const uint w = 273326509; - private uint _x, _y = y, _z = z, _w = w; + + internal uint X { get; private set; } + internal uint Y { get; private set; } = y; + internal uint Z { get; private set; } = z; + internal uint W { get; private set; } = w; public FastRandom(int seed) { - _x = (uint)seed; + X = (uint)seed; } public FastRandom() @@ -33,11 +37,11 @@ namespace osu.Game.Rulesets.Mania.MathUtils /// The random value. public uint NextUInt() { - uint t = _x ^ _x << 11; - _x = _y; - _y = _z; - _z = _w; - return _w = _w ^ _w >> 19 ^ t ^ t >> 8; + uint t = X ^ X << 11; + X = Y; + Y = Z; + Z = W; + return W = W ^ W >> 19 ^ t ^ t >> 8; } /// From 481546ec7a76ba80a6e5753f9e40f1c6d94a2b45 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 20:49:11 +0900 Subject: [PATCH 05/18] Fix drain time not being rounded to the second --- .../Beatmaps/Patterns/Legacy/PatternGenerator.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs index 930597c1ad..8ef942c683 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs @@ -103,17 +103,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy HitObject lastObject = OriginalBeatmap.HitObjects.LastOrDefault(); HitObject firstObject = OriginalBeatmap.HitObjects.FirstOrDefault(); - double drainTime = (lastObject?.StartTime ?? 0) - (firstObject?.StartTime ?? 0); - drainTime -= OriginalBeatmap.TotalBreakTime; + // Drain time in seconds + int drainTime = (int)(((lastObject?.StartTime ?? 0) - (firstObject?.StartTime ?? 0) - OriginalBeatmap.TotalBreakTime) / 1000); if (drainTime == 0) - drainTime = 10000000; - - // We need this in seconds - drainTime /= 1000; + drainTime = 100000; 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 = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + (double)OriginalBeatmap.HitObjects.Count() / drainTime * 9f) / 38f * 5f / 1.15; conversionDifficulty = Math.Min(conversionDifficulty.Value, 12); return conversionDifficulty.Value; From fe9aaf000c97abd7029a129331b14dc62b6bbc62 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 20:50:36 +0900 Subject: [PATCH 06/18] Fix missing conditional --- .../Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index b4160dc98b..1ea2863520 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && TotalColumns != 8) convertType |= PatternType.Mirror; - else + else if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP)) convertType |= PatternType.Gathered; } } From c1f7db80f17a013ba313aa3640fe4f21e2d9a604 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 20:52:09 +0900 Subject: [PATCH 07/18] Forgot to commit random change --- .../Beatmaps/ManiaBeatmapConverter.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 19fef9eb54..d76ae4f081 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -28,8 +28,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps public int TargetColumns; public readonly bool IsForCurrentRuleset; + // Internal for testing purposes + internal FastRandom Random { get; private set; } + private Pattern lastPattern = new Pattern(); - private FastRandom random; private ManiaBeatmap beatmap; @@ -62,7 +64,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty; int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate); - random = new FastRandom(seed); + Random = new FastRandom(seed); return base.ConvertBeatmap(original); } @@ -115,7 +117,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps /// The hit objects generated. private IEnumerable generateSpecific(HitObject original, IBeatmap originalBeatmap) { - var generator = new SpecificBeatmapPatternGenerator(random, original, beatmap, lastPattern, originalBeatmap); + var generator = new SpecificBeatmapPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap); Pattern newPattern = generator.Generate(); lastPattern = newPattern; @@ -138,14 +140,17 @@ namespace osu.Game.Rulesets.Mania.Beatmaps Patterns.PatternGenerator conversion = null; if (distanceData != null) - conversion = new DistanceObjectPatternGenerator(random, original, beatmap, lastPattern, originalBeatmap); + { + var generator = new DistanceObjectPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap); + conversion = generator; + } else if (endTimeData != null) - conversion = new EndTimeObjectPatternGenerator(random, original, beatmap, originalBeatmap); + 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, originalBeatmap); + conversion = new HitObjectPatternGenerator(Random, original, beatmap, lastPattern, lastTime, lastPosition, density, lastStair, originalBeatmap); recordNote(original.StartTime, positionData.Position); } From e51f96e181d1996d1da4ac4ce62e0e126e8c68e0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 20:52:36 +0900 Subject: [PATCH 08/18] Fix some notes not being recorded --- .../Beatmaps/ManiaBeatmapConverter.cs | 12 +++++ .../Legacy/DistanceObjectPatternGenerator.cs | 47 ++++++++++--------- 2 files changed, 36 insertions(+), 23 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index d76ae4f081..bc2c9943db 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -136,6 +136,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps var endTimeData = original as IHasEndTime; var distanceData = original as IHasDistance; var positionData = original as IHasPosition; + var repeatsData = original as IHasRepeats; Patterns.PatternGenerator conversion = null; @@ -143,9 +144,20 @@ namespace osu.Game.Rulesets.Mania.Beatmaps { var generator = new DistanceObjectPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap); conversion = generator; + + for (double time = original.StartTime; time <= generator.EndTime; time += generator.SegmentDuration) + { + recordNote(time, positionData?.Position ?? Vector2.Zero); + computeDensity(time); + } } else if (endTimeData != null) + { conversion = new EndTimeObjectPatternGenerator(Random, original, beatmap, originalBeatmap); + + recordNote(endTimeData.EndTime, new Vector2(256, 192)); + computeDensity(endTimeData.EndTime); + } else if (positionData != null) { computeDensity(original.StartTime); diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index f60958d581..a4275be504 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -24,8 +24,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy /// private const float osu_base_scoring_distance = 100; - private readonly double endTime; - private readonly double segmentDuration; + public readonly double EndTime; + public readonly double SegmentDuration; + private readonly int spanCount; private PatternType convertType; @@ -52,8 +53,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy // The duration of the osu! hit object double osuDuration = distance / osuVelocity; - endTime = hitObject.StartTime + osuDuration; - segmentDuration = (endTime - HitObject.StartTime) / spanCount; + EndTime = hitObject.StartTime + osuDuration; + SegmentDuration = (EndTime - HitObject.StartTime) / spanCount; } public override Pattern Generate() @@ -61,44 +62,44 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (TotalColumns == 1) { var pattern = new Pattern(); - addToPattern(pattern, 0, HitObject.StartTime, endTime); + addToPattern(pattern, 0, HitObject.StartTime, EndTime); return pattern; } if (spanCount > 1) { - if (segmentDuration <= 90) + if (SegmentDuration <= 90) return generateRandomHoldNotes(HitObject.StartTime, 1); - if (segmentDuration <= 120) + if (SegmentDuration <= 120) { convertType |= PatternType.ForceNotStack; return generateRandomNotes(HitObject.StartTime, spanCount + 1); } - if (segmentDuration <= 160) + if (SegmentDuration <= 160) return generateStair(HitObject.StartTime); - if (segmentDuration <= 200 && ConversionDifficulty > 3) + if (SegmentDuration <= 200 && ConversionDifficulty > 3) return generateRandomMultipleNotes(HitObject.StartTime); - double duration = endTime - HitObject.StartTime; + double duration = EndTime - HitObject.StartTime; if (duration >= 4000) return generateNRandomNotes(HitObject.StartTime, 0.23, 0, 0); - if (segmentDuration > 400 && spanCount < TotalColumns - 1 - RandomStart) + if (SegmentDuration > 400 && spanCount < TotalColumns - 1 - RandomStart) return generateTiledHoldNotes(HitObject.StartTime); return generateHoldAndNormalNotes(HitObject.StartTime); } - if (segmentDuration <= 110) + if (SegmentDuration <= 110) { if (PreviousPattern.ColumnWithObjects < TotalColumns) convertType |= PatternType.ForceNotStack; else convertType &= ~PatternType.ForceNotStack; - return generateRandomNotes(HitObject.StartTime, segmentDuration < 80 ? 1 : 2); + return generateRandomNotes(HitObject.StartTime, SegmentDuration < 80 ? 1 : 2); } if (ConversionDifficulty > 6.5) @@ -148,7 +149,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { while (pattern.ColumnHasObject(nextColumn) || PreviousPattern.ColumnHasObject(nextColumn)) //find available column nextColumn = Random.Next(RandomStart, TotalColumns); - addToPattern(pattern, nextColumn, startTime, endTime); + addToPattern(pattern, nextColumn, startTime, EndTime); } // This is can't be combined with the above loop due to RNG @@ -156,7 +157,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { while (pattern.ColumnHasObject(nextColumn)) nextColumn = Random.Next(RandomStart, TotalColumns); - addToPattern(pattern, nextColumn, startTime, endTime); + addToPattern(pattern, nextColumn, startTime, EndTime); } return pattern; @@ -193,7 +194,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy nextColumn = Random.Next(RandomStart, TotalColumns); lastColumn = nextColumn; - startTime += segmentDuration; + startTime += SegmentDuration; } return pattern; @@ -223,7 +224,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy for (int i = 0; i <= spanCount; i++) { addToPattern(pattern, column, startTime, startTime); - startTime += segmentDuration; + startTime += SegmentDuration; // Check if we're at the borders of the stage, and invert the pattern if so if (increasing) @@ -284,7 +285,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy addToPattern(pattern, nextColumn, startTime, startTime); nextColumn = Random.Next(RandomStart, TotalColumns); - startTime += segmentDuration; + startTime += SegmentDuration; } return pattern; @@ -372,8 +373,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy while (pattern.ColumnHasObject(nextColumn)) nextColumn = Random.Next(RandomStart, TotalColumns); - addToPattern(pattern, nextColumn, startTime, endTime); - startTime += segmentDuration; + addToPattern(pattern, nextColumn, startTime, EndTime); + startTime += SegmentDuration; } return pattern; @@ -402,7 +403,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy } // Create the hold note - addToPattern(pattern, holdColumn, startTime, endTime); + addToPattern(pattern, holdColumn, startTime, EndTime); int nextColumn = Random.Next(RandomStart, TotalColumns); int noteCount; @@ -434,7 +435,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy pattern.Add(rowPattern); rowPattern.Clear(); - startTime += segmentDuration; + startTime += SegmentDuration; } return pattern; @@ -452,7 +453,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy if (curveData == null) return HitObject.Samples; - double segmentTime = (endTime - HitObject.StartTime) / spanCount; + double segmentTime = (EndTime - HitObject.StartTime) / spanCount; int index = (int)(segmentTime == 0 ? 0 : (time - HitObject.StartTime) / segmentTime); return curveData.RepeatSamples[index]; From 5f5d797c1effc6ae2f9c96811ab6e5272ebdf347 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 21:06:35 +0900 Subject: [PATCH 09/18] Remove unused field --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index bc2c9943db..0f99f999da 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -136,7 +136,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps var endTimeData = original as IHasEndTime; var distanceData = original as IHasDistance; var positionData = original as IHasPosition; - var repeatsData = original as IHasRepeats; Patterns.PatternGenerator conversion = null; From 53a6d01304a3540f8a9f3684e471f683ad4c14a3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 21:06:54 +0900 Subject: [PATCH 10/18] Fix stair type not being flipped correctly --- .../Legacy/HitObjectPatternGenerator.cs | 199 +++++++++--------- 1 file changed, 100 insertions(+), 99 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index 1ea2863520..2210c76788 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -89,120 +89,121 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy public override Pattern Generate() { - if (TotalColumns == 1) + var pattern = new Pattern(); + + try { - var pattern = new Pattern(); - addToPattern(pattern, 0); - return pattern; - } - - int lastColumn = PreviousPattern.HitObjects.FirstOrDefault()?.Column ?? 0; - - if ((convertType & PatternType.Reverse) > 0 && PreviousPattern.HitObjects.Any()) - { - // Generate a new pattern by copying the last hit objects in reverse-column order - var pattern = new Pattern(); - - for (int i = RandomStart; i < TotalColumns; i++) - if (PreviousPattern.ColumnHasObject(i)) - addToPattern(pattern, RandomStart + TotalColumns - i - 1); - - return pattern; - } - - if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1 - // If we convert to 7K + 1, let's not overload the special key - && (TotalColumns != 8 || lastColumn != 0) - // Make sure the last column was not the centre column - && (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2)) - { - // Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object) - var pattern = new Pattern(); - - int column = RandomStart + TotalColumns - lastColumn - 1; - addToPattern(pattern, column); - - return pattern; - } - - if ((convertType & PatternType.ForceStack) > 0 && PreviousPattern.HitObjects.Any()) - { - // Generate a new pattern by placing on the already filled columns - var pattern = new Pattern(); - - for (int i = RandomStart; i < TotalColumns; i++) - if (PreviousPattern.ColumnHasObject(i)) - addToPattern(pattern, i); - - 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 == TotalColumns) + if (TotalColumns == 1) { - targetColumn = RandomStart; - StairType = PatternType.ReverseStair; + addToPattern(pattern, 0); + return pattern; } - addToPattern(pattern, targetColumn); - return pattern; - } + int lastColumn = PreviousPattern.HitObjects.FirstOrDefault()?.Column ?? 0; - 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) + if ((convertType & PatternType.Reverse) > 0 && PreviousPattern.HitObjects.Any()) { - targetColumn = TotalColumns - 1; - StairType = PatternType.Stair; + // Generate a new pattern by copying the last hit objects in reverse-column order + for (int i = RandomStart; i < TotalColumns; i++) + if (PreviousPattern.ColumnHasObject(i)) + addToPattern(pattern, RandomStart + TotalColumns - i - 1); + + return pattern; } - addToPattern(pattern, targetColumn); - return pattern; - } + if ((convertType & PatternType.Cycle) > 0 && PreviousPattern.HitObjects.Count() == 1 + // If we convert to 7K + 1, let's not overload the special key + && (TotalColumns != 8 || lastColumn != 0) + // Make sure the last column was not the centre column + && (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2)) + { + // Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object) + int column = RandomStart + TotalColumns - lastColumn - 1; + addToPattern(pattern, column); - if ((convertType & PatternType.KeepSingle) > 0) - return generateRandomNotes(1); + return pattern; + } + + if ((convertType & PatternType.ForceStack) > 0 && PreviousPattern.HitObjects.Any()) + { + // Generate a new pattern by placing on the already filled columns + for (int i = RandomStart; i < TotalColumns; i++) + if (PreviousPattern.ColumnHasObject(i)) + addToPattern(pattern, i); + + return pattern; + } + + if (PreviousPattern.HitObjects.Count() == 1) + { + if ((convertType & PatternType.Stair) > 0) + { + // Generate a new pattern by placing on the next column, cycling back to the start if there is no "next" + int targetColumn = lastColumn + 1; + if (targetColumn == TotalColumns) + targetColumn = RandomStart; + + addToPattern(pattern, targetColumn); + return pattern; + } + + if ((convertType & PatternType.ReverseStair) > 0) + { + // Generate a new pattern by placing on the previous column, cycling back to the end if there is no "previous" + int targetColumn = lastColumn - 1; + if (targetColumn == RandomStart - 1) + targetColumn = TotalColumns - 1; + + addToPattern(pattern, targetColumn); + return pattern; + } + } + + if ((convertType & PatternType.KeepSingle) > 0) + return pattern = generateRandomNotes(1); + + if ((convertType & PatternType.Mirror) > 0) + { + if (ConversionDifficulty > 6.5) + return pattern = generateRandomPatternWithMirrored(0.12, 0.38, 0.12); + if (ConversionDifficulty > 4) + return pattern = generateRandomPatternWithMirrored(0.12, 0.17, 0); + return pattern = generateRandomPatternWithMirrored(0.12, 0, 0); + } - if ((convertType & PatternType.Mirror) > 0) - { if (ConversionDifficulty > 6.5) - return generateRandomPatternWithMirrored(0.12, 0.38, 0.12); + { + if ((convertType & PatternType.LowProbability) > 0) + return pattern = generateRandomPattern(0.78, 0.42, 0, 0); + return pattern = generateRandomPattern(1, 0.62, 0, 0); + } + if (ConversionDifficulty > 4) - return generateRandomPatternWithMirrored(0.12, 0.17, 0); - return generateRandomPatternWithMirrored(0.12, 0, 0); - } + { + if ((convertType & PatternType.LowProbability) > 0) + return pattern = generateRandomPattern(0.35, 0.08, 0, 0); + return pattern = generateRandomPattern(0.52, 0.15, 0, 0); + } - if (ConversionDifficulty > 6.5) + if (ConversionDifficulty > 2) + { + if ((convertType & PatternType.LowProbability) > 0) + return pattern = generateRandomPattern(0.18, 0, 0, 0); + return pattern = generateRandomPattern(0.45, 0, 0, 0); + } + + return pattern = generateRandomPattern(0, 0, 0, 0); + } + finally { - if ((convertType & PatternType.LowProbability) > 0) - return generateRandomPattern(0.78, 0.42, 0, 0); - return generateRandomPattern(1, 0.62, 0, 0); + foreach (var obj in pattern.HitObjects) + { + if ((convertType & PatternType.Stair) > 0 && obj.Column == TotalColumns - 1) + StairType = PatternType.ReverseStair; + if ((convertType & PatternType.ReverseStair) > 0 && obj.Column == RandomStart) + StairType = PatternType.Stair; + } } - - 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); } /// From 2d59ae9354249a2e39930db38f1a74e24175bcbb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 22:08:24 +0900 Subject: [PATCH 11/18] Commit forgotten variable --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 0f99f999da..536b1a8552 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -102,7 +102,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps private double lastTime; private Vector2 lastPosition; - private PatternType lastStair; + private PatternType lastStair = PatternType.Stair; private void recordNote(double time, Vector2 position) { lastTime = time; From 55f0b3c42cc895ca859a3864c60714d973271647 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 22:10:57 +0900 Subject: [PATCH 12/18] Distance object generator should output a secondary pattern In osu!stable, only the hitobjects which ended at the distance object's EndTime would be considered for further pattern generation. Previously this generator was group _all_ objects including those that don't end at the object's EndTime, resulting in incorrect hitobject count for further pattern generation. --- .../Beatmaps/ManiaBeatmapConverter.cs | 29 +++++++++++++------ .../Legacy/DistanceObjectPatternGenerator.cs | 26 ++++++++++++++++- .../Legacy/EndTimeObjectPatternGenerator.cs | 7 ++++- .../Legacy/HitObjectPatternGenerator.cs | 8 ++++- .../Beatmaps/Patterns/PatternGenerator.cs | 7 +++-- 5 files changed, 62 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 536b1a8552..2c4c7b0f18 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -119,10 +119,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps { var generator = new SpecificBeatmapPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap); - Pattern newPattern = generator.Generate(); - lastPattern = newPattern; + foreach (var newPattern in generator.Generate()) + { + lastPattern = newPattern; - return newPattern.HitObjects; + foreach (var obj in newPattern.HitObjects) + yield return obj; + } } /// @@ -167,14 +170,17 @@ namespace osu.Game.Rulesets.Mania.Beatmaps } if (conversion == null) - return null; + yield break; - Pattern newPattern = conversion.Generate(); + foreach (var newPattern in conversion.Generate()) + { + lastPattern = conversion is EndTimeObjectPatternGenerator ? lastPattern : newPattern; + lastStair = (conversion as HitObjectPatternGenerator)?.StairType ?? lastStair; - lastPattern = conversion is EndTimeObjectPatternGenerator ? lastPattern : newPattern; - lastStair = (conversion as HitObjectPatternGenerator)?.StairType ?? lastStair; + foreach (var obj in newPattern.HitObjects) + yield return obj; - return newPattern.HitObjects; + } } /// @@ -187,7 +193,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps { } - public override Pattern Generate() + public override IEnumerable Generate() + { + yield return generate(); + } + + private Pattern generate() { var endTimeData = HitObject as IHasEndTime; var positionData = HitObject as IHasXPosition; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index a4275be504..e33af44df2 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -4,6 +4,7 @@ using System; using System.Collections.Generic; using System.Linq; +using osu.Framework.MathUtils; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.MathUtils; @@ -57,7 +58,30 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy SegmentDuration = (EndTime - HitObject.StartTime) / spanCount; } - public override Pattern Generate() + public override IEnumerable Generate() + { + var originalPattern = generate(); + + // We need to split the intermediate pattern into two new patterns: + // 1. A pattern containing all objects that do not end at our EndTime. + // 2. A pattern containing all objects that end at our EndTime. This will be used for further pattern generation. + var intermediatePattern = new Pattern(); + var endTimePattern = new Pattern(); + + foreach (var obj in originalPattern.HitObjects) + { + if (!Precision.AlmostEquals(EndTime, (obj as IHasEndTime)?.EndTime ?? obj.StartTime)) + intermediatePattern.Add(obj); + else + endTimePattern.Add(obj); + } + + + yield return intermediatePattern; + yield return endTimePattern; + } + + private Pattern generate() { if (TotalColumns == 1) { diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs index 3f34afee85..0f170e8540 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs @@ -24,7 +24,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy endTime = endtimeData?.EndTime ?? 0; } - public override Pattern Generate() + public override IEnumerable Generate() + { + yield return generate(); + } + + private Pattern generate() { var pattern = new Pattern(); diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index 2210c76788..0e839d87a2 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; using OpenTK; using osu.Game.Audio; @@ -87,7 +88,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy } } - public override Pattern Generate() + public override IEnumerable Generate() + { + yield return generate(); + } + + private Pattern generate() { var pattern = new Pattern(); diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs index 2bfcd52b6a..a42d57cdd1 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns @@ -42,9 +43,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns } /// - /// Generates the pattern for , filled with hit objects. + /// Generates the patterns for , each filled with hit objects. /// - /// The containing the hit objects. - public abstract Pattern Generate(); + /// The s containing the hit objects. + public abstract IEnumerable Generate(); } } From 8529cece4a65bc006d4946fabee4cab9e98c48c5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 20:17:19 +0900 Subject: [PATCH 13/18] Fix precision error --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 2c4c7b0f18..e21738f8c8 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps var generator = new DistanceObjectPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap); conversion = generator; - for (double time = original.StartTime; time <= generator.EndTime; time += generator.SegmentDuration) + for (double time = original.StartTime; !Precision.DefinitelyBigger(time, generator.EndTime); time += generator.SegmentDuration) { recordNote(time, positionData?.Position ?? Vector2.Zero); computeDensity(time); From 0625bfda301f8dfea9531d9c14c765bf9c66a855 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 20:17:49 +0900 Subject: [PATCH 14/18] Don't split single hitobject into multiple patterns --- .../Patterns/Legacy/DistanceObjectPatternGenerator.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index e33af44df2..e96ba19c80 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -62,6 +62,12 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy { var originalPattern = generate(); + if (originalPattern.HitObjects.Count() == 1) + { + yield return originalPattern; + yield break; + } + // We need to split the intermediate pattern into two new patterns: // 1. A pattern containing all objects that do not end at our EndTime. // 2. A pattern containing all objects that end at our EndTime. This will be used for further pattern generation. @@ -76,7 +82,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy endTimePattern.Add(obj); } - yield return intermediatePattern; yield return endTimePattern; } From f090e82b638a2dc0a6f82f76e803d79039028e43 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 18 Jun 2018 21:06:09 +0900 Subject: [PATCH 15/18] Fix inverted conditional --- .../Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index e96ba19c80..280c2f45d4 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -359,7 +359,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy break; } - bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP && sample.Name == SampleInfo.HIT_FINISH; + bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP || sample.Name == SampleInfo.HIT_FINISH; bool canGenerateTwoNotes = (convertType & PatternType.LowProbability) == 0; canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample); From a623155b9fbe87236acbafbcc0d302ac30cfde63 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 19 Jun 2018 13:51:53 +0900 Subject: [PATCH 16/18] Fix missing using --- osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index e21738f8c8..c15b303048 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -5,6 +5,7 @@ using osu.Game.Rulesets.Mania.Objects; using System; using System.Linq; using System.Collections.Generic; +using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; From 6cd9a22e265ad31688eadc4d41247a1b851c2a19 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 19 Jun 2018 13:52:14 +0900 Subject: [PATCH 17/18] Update testcase --- .../ManiaBeatmapConversionTest.cs | 1 - .../Beatmaps/basic-expected-conversion.json | 229 ++++++++++-------- 2 files changed, 129 insertions(+), 101 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs index c13319ace9..33ac1e00e4 100644 --- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs @@ -18,7 +18,6 @@ namespace osu.Game.Rulesets.Mania.Tests { protected override string ResourceAssembly => "osu.Game.Rulesets.Mania"; - [NonParallelizable] [TestCase("basic")] public new void Test(string name) { diff --git a/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/basic-expected-conversion.json b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/basic-expected-conversion.json index d593b2b052..753db99856 100644 --- a/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/basic-expected-conversion.json +++ b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/basic-expected-conversion.json @@ -1,103 +1,132 @@ { "Mappings": [{ - "StartTime": 500, - "Objects": [{ - "StartTime": 500, - "EndTime": 2500, - "Column": 0 - }, - { - "StartTime": 1500, - "EndTime": 2500, - "Column": 1 - } - ] - }, - { - "StartTime": 3000, - "Objects": [{ - "StartTime": 3000, - "EndTime": 4000, - "Column": 2 - }] - }, - { - "StartTime": 4500, - "Objects": [{ - "StartTime": 4500, - "EndTime": 5500, - "Column": 4 - }] - }, - { - "StartTime": 6000, - "Objects": [{ - "StartTime": 6000, - "EndTime": 6500, - "Column": 2 - }] - }, - { - "StartTime": 7000, - "Objects": [{ - "StartTime": 7000, - "EndTime": 8000, - "Column": 2 - }] - }, - { - "StartTime": 8500, - "Objects": [{ - "StartTime": 8500, - "EndTime": 11000, - "Column": 0 - }] - }, - { - "StartTime": 11500, - "Objects": [{ - "StartTime": 11500, - "EndTime": 12000, - "Column": 1 - }] - }, - { - "StartTime": 12500, - "Objects": [{ - "StartTime": 12500, - "EndTime": 16500, - "Column": 4 - }] - }, - { - "StartTime": 17000, - "Objects": [{ - "StartTime": 17000, - "EndTime": 18000, - "Column": 2 - }] - }, - { - "StartTime": 18500, - "Objects": [{ - "StartTime": 18500, - "EndTime": 19450, - "Column": 0 - }] - }, - { - "StartTime": 19875, - "Objects": [{ - "StartTime": 19875, - "EndTime": 23875, - "Column": 1 - }, - { - "StartTime": 19875, - "EndTime": 23875, - "Column": 0 - } - ] - } - ] + "RandomW": 2659373485, + "RandomX": 3579807591, + "RandomY": 273326509, + "RandomZ": 272969173, + "StartTime": 500.0, + "Objects": [{ + "StartTime": 500.0, + "EndTime": 2500.0, + "Column": 0 + }, { + "StartTime": 1500.0, + "EndTime": 2500.0, + "Column": 1 + }] + }, { + "RandomW": 3083803045, + "RandomX": 273326509, + "RandomY": 272969173, + "RandomZ": 2659373485, + "StartTime": 3000.0, + "Objects": [{ + "StartTime": 3000.0, + "EndTime": 4000.0, + "Column": 2 + }] + }, { + "RandomW": 4073554232, + "RandomX": 272969173, + "RandomY": 2659373485, + "RandomZ": 3083803045, + "StartTime": 4500.0, + "Objects": [{ + "StartTime": 4500.0, + "EndTime": 5500.0, + "Column": 4 + }] + }, { + "RandomW": 3420401969, + "RandomX": 2659373485, + "RandomY": 3083803045, + "RandomZ": 4073554232, + "StartTime": 6000.0, + "Objects": [{ + "StartTime": 6000.0, + "EndTime": 6500.0, + "Column": 2 + }] + }, { + "RandomW": 1129881182, + "RandomX": 3083803045, + "RandomY": 4073554232, + "RandomZ": 3420401969, + "StartTime": 7000.0, + "Objects": [{ + "StartTime": 7000.0, + "EndTime": 8000.0, + "Column": 2 + }] + }, { + "RandomW": 315568458, + "RandomX": 3420401969, + "RandomY": 1129881182, + "RandomZ": 2358617505, + "StartTime": 8500.0, + "Objects": [{ + "StartTime": 8500.0, + "EndTime": 11000.0, + "Column": 0 + }] + }, { + "RandomW": 548134043, + "RandomX": 1129881182, + "RandomY": 2358617505, + "RandomZ": 315568458, + "StartTime": 11500.0, + "Objects": [{ + "StartTime": 11500.0, + "EndTime": 12000.0, + "Column": 1 + }] + }, { + "RandomW": 3979422122, + "RandomX": 548134043, + "RandomY": 2810584254, + "RandomZ": 2250186050, + "StartTime": 12500.0, + "Objects": [{ + "StartTime": 12500.0, + "EndTime": 16500.0, + "Column": 4 + }] + }, { + "RandomW": 2466283411, + "RandomX": 2810584254, + "RandomY": 2250186050, + "RandomZ": 3979422122, + "StartTime": 17000.0, + "Objects": [{ + "StartTime": 17000.0, + "EndTime": 18000.0, + "Column": 2 + }] + }, { + "RandomW": 83157665, + "RandomX": 2250186050, + "RandomY": 3979422122, + "RandomZ": 2466283411, + "StartTime": 18500.0, + "Objects": [{ + "StartTime": 18500.0, + "EndTime": 19450.0, + "Column": 0 + }] + }, { + "RandomW": 2383087700, + "RandomX": 83157665, + "RandomY": 2055150192, + "RandomZ": 510071020, + "StartTime": 19875.0, + "Objects": [{ + "StartTime": 19875.0, + "EndTime": 23875.0, + "Column": 1 + }, { + "StartTime": 19875.0, + "EndTime": 23875.0, + "Column": 0 + }] + }] } \ No newline at end of file From a1d2092cc9ab5cfa0537d1f80aa9a09373d16920 Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Fri, 6 Jul 2018 13:29:40 +0900 Subject: [PATCH 18/18] Fix incorrect default drain time --- .../Beatmaps/Patterns/Legacy/PatternGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs index 8ef942c683..55081e5822 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs @@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy int drainTime = (int)(((lastObject?.StartTime ?? 0) - (firstObject?.StartTime ?? 0) - OriginalBeatmap.TotalBreakTime) / 1000); if (drainTime == 0) - drainTime = 100000; + drainTime = 10000; BeatmapDifficulty difficulty = OriginalBeatmap.BeatmapInfo.BaseDifficulty; conversionDifficulty = ((difficulty.DrainRate + MathHelper.Clamp(difficulty.ApproachRate, 4, 7)) / 1.5 + (double)OriginalBeatmap.HitObjects.Count() / drainTime * 9f) / 38f * 5f / 1.15;