diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs index fd30a8d4ae..d40a108c5e 100644 --- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs @@ -21,6 +21,7 @@ namespace osu.Game.Rulesets.Catch.Tests [TestCase("basic")] [TestCase("spinner")] [TestCase("spinner-and-circles")] + [TestCase("slider")] public new void Test(string name) { base.Test(name); diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index ef7573c70b..61bb4335f3 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -55,6 +55,13 @@ namespace osu.Game.Rulesets.Catch.Objects var minDistanceFromEnd = Velocity * 0.01; + var tickSamples = Samples.Select(s => new SampleInfo + { + Bank = s.Bank, + Name = @"slidertick", + Volume = s.Volume + }).ToList(); + AddNested(new Fruit { Samples = Samples, @@ -62,15 +69,22 @@ namespace osu.Game.Rulesets.Catch.Objects X = X }); - double lastDropletTime = StartTime; + double lastTickTime = StartTime; for (int span = 0; span < this.SpanCount(); span++) { var spanStartTime = StartTime + span * spanDuration; var reversed = span % 2 == 1; - for (double d = 0; d <= length; d += tickDistance) + for (double d = tickDistance;; d += tickDistance) { + bool isLastTick = false; + if (d + minDistanceFromEnd >= length) + { + d = length; + isLastTick = true; + } + var timeProgress = d / length; var distanceProgress = reversed ? 1 - timeProgress : timeProgress; @@ -79,47 +93,42 @@ namespace osu.Game.Rulesets.Catch.Objects if (LegacyLastTickOffset != null) { // If we're the last tick, apply the legacy offset - if (span == this.SpanCount() - 1 && d + tickDistance > length) + if (span == this.SpanCount() - 1 && isLastTick) time = Math.Max(StartTime + Duration / 2, time - LegacyLastTickOffset.Value); } - double tinyTickInterval = time - lastDropletTime; - while (tinyTickInterval > 100) - tinyTickInterval /= 2; - - for (double t = lastDropletTime + tinyTickInterval; t < time; t += tinyTickInterval) + int tinyTickCount = 1; + double tinyTickInterval = time - lastTickTime; + while (tinyTickInterval > 100 && tinyTickCount < 10000) { + tinyTickInterval /= 2; + tinyTickCount *= 2; + } + + for (int tinyTickIndex = 0; tinyTickIndex < tinyTickCount - 1; tinyTickIndex++) + { + var t = lastTickTime + (tinyTickIndex + 1) * tinyTickInterval; double progress = reversed ? 1 - (t - spanStartTime) / spanDuration : (t - spanStartTime) / spanDuration; AddNested(new TinyDroplet { StartTime = t, X = X + Path.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH, - Samples = new List(Samples.Select(s => new SampleInfo - { - Bank = s.Bank, - Name = @"slidertick", - Volume = s.Volume - })) + Samples = tickSamples }); } - if (d > minDistanceFromEnd && Math.Abs(d - length) > minDistanceFromEnd) + lastTickTime = time; + + if (isLastTick) + break; + + AddNested(new Droplet { - AddNested(new Droplet - { - StartTime = time, - X = X + Path.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, - Samples = new List(Samples.Select(s => new SampleInfo - { - Bank = s.Bank, - Name = @"slidertick", - Volume = s.Volume - })) - }); - } - - lastDropletTime = time; + StartTime = time, + X = X + Path.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH, + Samples = tickSamples + }); } AddNested(new Fruit diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider-expected-conversion.json b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider-expected-conversion.json new file mode 100644 index 0000000000..58c52b6867 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider-expected-conversion.json @@ -0,0 +1 @@ +{"Mappings":[{"StartTime":19184.0,"Objects":[{"StartTime":19184.0,"Position":320.0},{"StartTime":19263.0,"Position":311.730255},{"StartTime":19343.0,"Position":324.6205},{"StartTime":19423.0,"Position":343.0907},{"StartTime":19503.0,"Position":372.2917},{"StartTime":19582.0,"Position":385.194733},{"StartTime":19662.0,"Position":379.0426},{"StartTime":19742.0,"Position":385.1066},{"StartTime":19822.0,"Position":391.624664},{"StartTime":19919.0,"Position":386.27832},{"StartTime":20016.0,"Position":380.117035},{"StartTime":20113.0,"Position":381.664154},{"StartTime":20247.0,"Position":370.872864}]}]} \ No newline at end of file diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider.osu b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider.osu new file mode 100644 index 0000000000..d48b2d7769 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider.osu @@ -0,0 +1,18 @@ +osu file format v14 + +[General] +Mode: 2 + +[Difficulty] +HPDrainRate:3 +CircleSize:2 +OverallDifficulty:4 +ApproachRate:4 +SliderMultiplier:0.9 +SliderTickRate:1 + +[TimingPoints] +35.4473684210527,638.298947368422,4,2,1,60,1,0 + +[HitObjects] +320,176,19184,2,8,P|384:168|368:232,1,150