diff --git a/.github/ISSUE_TEMPLATE/bug-issues.md b/.github/ISSUE_TEMPLATE/bug-issues.md new file mode 100644 index 0000000000..8d85c92fec --- /dev/null +++ b/.github/ISSUE_TEMPLATE/bug-issues.md @@ -0,0 +1,14 @@ +--- +name: Bug Report +about: For issues regarding encountered game bugs +--- + + + +**Describe your problem:** + +**Screenshots or videos showing encountered issue:** + +**osu!lazer version:** + +**Logs:** \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/crash-issues.md b/.github/ISSUE_TEMPLATE/crash-issues.md new file mode 100644 index 0000000000..849f042c1f --- /dev/null +++ b/.github/ISSUE_TEMPLATE/crash-issues.md @@ -0,0 +1,16 @@ +--- +name: Crash Report +about: For issues regarding game crashes or permanent freezes +--- + + + +**Describe your problem:** + +**Screenshots or videos showing encountered issue:** + +**osu!lazer version:** + +**Logs:** + +**Computer Specifications:** \ No newline at end of file diff --git a/.github/ISSUE_TEMPLATE/feature-request-issues.md b/.github/ISSUE_TEMPLATE/feature-request-issues.md new file mode 100644 index 0000000000..73c4f37a3e --- /dev/null +++ b/.github/ISSUE_TEMPLATE/feature-request-issues.md @@ -0,0 +1,10 @@ +--- +name: Feature Request +about: Let us know what you would like to see in the game! +--- + + + +**Describe the feature:** + +**Proposal designs of the feature:** diff --git a/.github/ISSUE_TEMPLATE/missing-for-live-issues.md b/.github/ISSUE_TEMPLATE/missing-for-live-issues.md new file mode 100644 index 0000000000..ae3cf20a8c --- /dev/null +++ b/.github/ISSUE_TEMPLATE/missing-for-live-issues.md @@ -0,0 +1,10 @@ +--- +name: Missing for Live +about: Let us know the features you need which are available in osu-stable but not lazer +--- + + + +**Describe the feature:** + +**Designs:** diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index 326791f506..b76f591239 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index a178748bd5..fed65c42af 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps ControlPoints = curveData.ControlPoints, PathType = curveData.PathType, Distance = curveData.Distance, - RepeatSamples = curveData.RepeatSamples, + NodeSamples = curveData.NodeSamples, RepeatCount = curveData.RepeatCount, X = (positionData?.X ?? 0) / CatchPlayfield.BASE_WIDTH, NewCombo = comboData?.NewCombo ?? false, diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index da581d9619..f1e131932b 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -152,7 +152,7 @@ namespace osu.Game.Rulesets.Catch.Objects set { Path.ControlPoints = value; } } - public List> RepeatSamples { get; set; } = new List>(); + public List> NodeSamples { get; set; } = new List>(); public PathType PathType { diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index bf75ebbff8..98ad086c66 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 5d8480d969..d86ebc9a09 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -247,7 +247,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps double segmentTime = (curveData.EndTime - HitObject.StartTime) / curveData.SpanCount(); int index = (int)(segmentTime == 0 ? 0 : (time - HitObject.StartTime) / segmentTime); - return curveData.RepeatSamples[index]; + return curveData.NodeSamples[index]; } } } diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index 37a8062d75..635004d2f6 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -470,7 +470,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy double segmentTime = (EndTime - HitObject.StartTime) / spanCount; int index = (int)(segmentTime == 0 ? 0 : (time - HitObject.StartTime) / segmentTime); - return curveData.RepeatSamples[index]; + return curveData.NodeSamples[index]; } /// diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs index 4c0385deda..0bd6bb5abc 100644 --- a/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs +++ b/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Osu.Tests }, Distance = 700, RepeatCount = repeats, - RepeatSamples = createEmptySamples(repeats), + NodeSamples = createEmptySamples(repeats), StackHeight = 10 }; @@ -148,7 +148,7 @@ namespace osu.Game.Rulesets.Osu.Tests }, Distance = distance, RepeatCount = repeats, - RepeatSamples = createEmptySamples(repeats), + NodeSamples = createEmptySamples(repeats), StackHeight = stackHeight }; @@ -169,7 +169,7 @@ namespace osu.Game.Rulesets.Osu.Tests }, Distance = 600, RepeatCount = repeats, - RepeatSamples = createEmptySamples(repeats) + NodeSamples = createEmptySamples(repeats) }; addSlider(slider, 2, 3); @@ -195,7 +195,7 @@ namespace osu.Game.Rulesets.Osu.Tests }, Distance = 793.4417, RepeatCount = repeats, - RepeatSamples = createEmptySamples(repeats) + NodeSamples = createEmptySamples(repeats) }; addSlider(slider, 2, 3); @@ -220,7 +220,7 @@ namespace osu.Game.Rulesets.Osu.Tests }, Distance = 480, RepeatCount = repeats, - RepeatSamples = createEmptySamples(repeats) + NodeSamples = createEmptySamples(repeats) }; addSlider(slider, 2, 3); @@ -246,7 +246,7 @@ namespace osu.Game.Rulesets.Osu.Tests }, Distance = 1000, RepeatCount = repeats, - RepeatSamples = createEmptySamples(repeats) + NodeSamples = createEmptySamples(repeats) }; addSlider(slider, 2, 3); @@ -274,7 +274,7 @@ namespace osu.Game.Rulesets.Osu.Tests }, Distance = 300, RepeatCount = repeats, - RepeatSamples = repeatSamples + NodeSamples = repeatSamples }; addSlider(slider, 3, 1); diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index 23c6150b6a..6117812f45 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs index 9f432fc31a..87c81cdd3b 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapConverter.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps ControlPoints = curveData.ControlPoints, PathType = curveData.PathType, Distance = curveData.Distance, - RepeatSamples = curveData.RepeatSamples, + NodeSamples = curveData.NodeSamples, RepeatCount = curveData.RepeatCount, Position = positionData?.Position ?? Vector2.Zero, NewCombo = comboData?.NewCombo ?? false, diff --git a/osu.Game.Rulesets.Osu/Objects/Slider.cs b/osu.Game.Rulesets.Osu/Objects/Slider.cs index b7240991d4..3680c38945 100644 --- a/osu.Game.Rulesets.Osu/Objects/Slider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Slider.cs @@ -111,7 +111,8 @@ namespace osu.Game.Rulesets.Osu.Objects /// internal float LazyTravelDistance; - public List> RepeatSamples { get; set; } = new List>(); + public List> NodeSamples { get; set; } = new List>(); + public int RepeatCount { get; set; } /// @@ -169,7 +170,7 @@ namespace osu.Game.Rulesets.Osu.Objects { StartTime = StartTime, Position = Position, - Samples = Samples, + Samples = getNodeSamples(0), SampleControlPoint = SampleControlPoint, IndexInCurrentCombo = IndexInCurrentCombo, ComboIndex = ComboIndex, @@ -249,11 +250,18 @@ namespace osu.Game.Rulesets.Osu.Objects Position = Position + Path.PositionAt(repeat % 2), StackHeight = StackHeight, Scale = Scale, - Samples = new List(RepeatSamples[repeatIndex]) + Samples = getNodeSamples(1 + repeatIndex) }); } } + private List getNodeSamples(int nodeIndex) + { + if (nodeIndex < NodeSamples.Count) + return NodeSamples[nodeIndex]; + return Samples; + } + public override Judgement CreateJudgement() => new OsuJudgement(); } } diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index 6ae9a018c5..3ba64398f3 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -4,7 +4,7 @@ - + diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index c2cde332e8..c4a84f416e 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -117,7 +117,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps if (!isForCurrentRuleset && tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength) { - List> allSamples = curveData != null ? curveData.RepeatSamples : new List>(new[] { samples }); + List> allSamples = curveData != null ? curveData.NodeSamples : new List>(new[] { samples }); int i = 0; for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index f1ae366ee1..464cfbf5e9 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -14,6 +14,7 @@ using osu.Game.Beatmaps.Formats; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Rulesets.Osu; using osu.Game.Rulesets.Osu.Beatmaps; using osu.Game.Skinning; @@ -333,5 +334,61 @@ namespace osu.Game.Tests.Beatmaps.Formats SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]); } + + [Test] + public void TestDecodeSliderSamples() + { + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; + using (var resStream = Resource.OpenResource("slider-samples.osu")) + using (var stream = new StreamReader(resStream)) + { + var hitObjects = decoder.Decode(stream).HitObjects; + + var slider1 = (ConvertSlider)hitObjects[0]; + + Assert.AreEqual(1, slider1.NodeSamples[0].Count); + Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[0][0].Name); + Assert.AreEqual(1, slider1.NodeSamples[1].Count); + Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[1][0].Name); + Assert.AreEqual(1, slider1.NodeSamples[2].Count); + Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[2][0].Name); + + var slider2 = (ConvertSlider)hitObjects[1]; + + Assert.AreEqual(2, slider2.NodeSamples[0].Count); + Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[0][0].Name); + Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[0][1].Name); + Assert.AreEqual(2, slider2.NodeSamples[1].Count); + Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[1][0].Name); + Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[1][1].Name); + Assert.AreEqual(2, slider2.NodeSamples[2].Count); + Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[2][0].Name); + Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[2][1].Name); + + var slider3 = (ConvertSlider)hitObjects[2]; + + Assert.AreEqual(2, slider3.NodeSamples[0].Count); + Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[0][0].Name); + Assert.AreEqual(SampleInfo.HIT_WHISTLE, slider3.NodeSamples[0][1].Name); + Assert.AreEqual(1, slider3.NodeSamples[1].Count); + Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[1][0].Name); + Assert.AreEqual(2, slider3.NodeSamples[2].Count); + Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[2][0].Name); + Assert.AreEqual(SampleInfo.HIT_CLAP, slider3.NodeSamples[2][1].Name); + } + } + + [Test] + public void TestDecodeHitObjectNullAdditionBank() + { + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; + using (var resStream = Resource.OpenResource("hitobject-no-addition-bank.osu")) + using (var stream = new StreamReader(resStream)) + { + var hitObjects = decoder.Decode(stream).HitObjects; + + Assert.AreEqual(hitObjects[0].Samples[0].Bank, hitObjects[0].Samples[1].Bank); + } + } } } diff --git a/osu.Game.Tests/Resources/hitobject-no-addition-bank.osu b/osu.Game.Tests/Resources/hitobject-no-addition-bank.osu new file mode 100644 index 0000000000..43d0b8cc16 --- /dev/null +++ b/osu.Game.Tests/Resources/hitobject-no-addition-bank.osu @@ -0,0 +1,4 @@ +osu file format v14 + +[HitObjects] +444,320,1000,5,2,3:0:1:0: \ No newline at end of file diff --git a/osu.Game.Tests/Resources/slider-samples.osu b/osu.Game.Tests/Resources/slider-samples.osu new file mode 100644 index 0000000000..7759a2e35f --- /dev/null +++ b/osu.Game.Tests/Resources/slider-samples.osu @@ -0,0 +1,23 @@ +osu file format v14 + +[General] +SampleSet: Normal + +[Difficulty] + +SliderMultiplier:1.6 +SliderTickRate:2 + +[TimingPoints] +24735,389.61038961039,4,1,1,25,1,0 + +[HitObjects] +// Unified: Normal, Normal, Normal +168,256,30579,6,0,B|248:320|320:248,2,160 + +// Unified: Normal+Clap, Normal+Clap, Normal+Clap +168,256,32137,6,8,B|248:320|320:248,2,160 + +// Nodal: Normal+Whistle, Normal, Normal+Clap +// Nodal sounds should override the unified clap sound +168,256,33696,6,8,B|248:320|320:248,2,160,2|0|8 \ No newline at end of file diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 520e0b8940..c0f0695ff8 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -5,7 +5,7 @@ - + diff --git a/osu.Game.Tournament.Tests/TestCaseSceneManager.cs b/osu.Game.Tournament.Tests/TestCaseSceneManager.cs index 13c00f081a..62e5f77802 100644 --- a/osu.Game.Tournament.Tests/TestCaseSceneManager.cs +++ b/osu.Game.Tournament.Tests/TestCaseSceneManager.cs @@ -74,7 +74,6 @@ namespace osu.Game.Tournament.Tests new VideoSprite(storage.GetStream("BG Logoless - OWC.m4v")) { Loop = true, - ShowLastFrameDuringHideCutoff = true, RelativeSizeAxes = Axes.Both, FillMode = FillMode.Fit, }, diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs index f5613e927f..67a3db7a00 100644 --- a/osu.Game/Rulesets/Objects/HitObject.cs +++ b/osu.Game/Rulesets/Objects/HitObject.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using Newtonsoft.Json; -using osu.Framework.Lists; using osu.Game.Audio; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -56,7 +55,7 @@ namespace osu.Game.Rulesets.Objects /// public HitWindows HitWindows { get; set; } - private readonly SortedList nestedHitObjects = new SortedList(compareObjects); + private readonly List nestedHitObjects = new List(); [JsonIgnore] public IReadOnlyList NestedHitObjects => nestedHitObjects; @@ -74,6 +73,8 @@ namespace osu.Game.Rulesets.Objects CreateNestedHitObjects(); + nestedHitObjects.Sort((h1, h2) => h1.StartTime.CompareTo(h2.StartTime)); + foreach (var h in nestedHitObjects) { h.HitWindows = HitWindows; @@ -114,7 +115,5 @@ namespace osu.Game.Rulesets.Objects /// /// protected virtual HitWindows CreateHitWindows() => new HitWindows(); - - private static int compareObjects(HitObject first, HitObject second) => first.StartTime.CompareTo(second.StartTime); } } diff --git a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs index 85efdca07b..c805c55ed1 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Catch/ConvertHitObjectParser.cs @@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { newCombo |= forceNewCombo; comboOffset += extraComboOffset; @@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Catch ControlPoints = controlPoints, Distance = length, PathType = pathType, - RepeatSamples = repeatSamples, + NodeSamples = nodeSamples, RepeatCount = repeatCount }; } diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs index 73f70d414f..3cc695447e 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertHitObjectParser.cs @@ -179,6 +179,9 @@ namespace osu.Game.Rulesets.Objects.Legacy nodeSamples.Add(convertSoundType(nodeSoundTypes[i], nodeBankInfos[i])); result = CreateSlider(pos, combo, comboOffset, points, length, pathType, repeatCount, nodeSamples); + + // The samples are played when the slider ends, which is the last node + result.Samples = nodeSamples[nodeSamples.Count - 1]; } else if (type.HasFlag(ConvertHitObjectType.Spinner)) { @@ -210,7 +213,9 @@ namespace osu.Game.Rulesets.Objects.Legacy } result.StartTime = Convert.ToDouble(split[2], CultureInfo.InvariantCulture) + Offset; - result.Samples = convertSoundType(soundType, bankInfo); + + if (result.Samples.Count == 0) + result.Samples = convertSoundType(soundType, bankInfo); FirstObject = false; @@ -240,7 +245,7 @@ namespace osu.Game.Rulesets.Objects.Legacy stringAddBank = null; bankInfo.Normal = stringBank; - bankInfo.Add = stringAddBank; + bankInfo.Add = string.IsNullOrEmpty(stringAddBank) ? stringBank : stringAddBank; if (split.Length > 2) bankInfo.CustomSampleBank = int.Parse(split[2]); @@ -270,9 +275,9 @@ namespace osu.Game.Rulesets.Objects.Legacy /// The slider length. /// The slider curve type. /// The slider repeat count. - /// The samples to be played when the repeat nodes are hit. This includes the head and tail of the slider. + /// The samples to be played when the slider nodes are hit. This includes the head and tail of the slider. /// The hit object. - protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> repeatSamples); + protected abstract HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples); /// /// Creates a legacy Spinner-type hit object. diff --git a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs index 6030bff427..b3d9f3c40c 100644 --- a/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs +++ b/osu.Game/Rulesets/Objects/Legacy/ConvertSlider.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Objects.Legacy public double Distance { get; set; } - public List> RepeatSamples { get; set; } + public List> NodeSamples { get; set; } public int RepeatCount { get; set; } public double EndTime => StartTime + this.SpanCount() * Distance / Velocity; diff --git a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs index 6f10880aa2..90b7f3d554 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Mania/ConvertHitObjectParser.cs @@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { return new ConvertSlider { @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Mania ControlPoints = controlPoints, Distance = length, PathType = pathType, - RepeatSamples = repeatSamples, + NodeSamples = nodeSamples, RepeatCount = repeatCount }; } diff --git a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs index 31c200eddc..bb41a147b0 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Osu/ConvertHitObjectParser.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu }; } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { newCombo |= forceNewCombo; comboOffset += extraComboOffset; @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Objects.Legacy.Osu ControlPoints = controlPoints, Distance = Math.Max(0, length), PathType = pathType, - RepeatSamples = repeatSamples, + NodeSamples = nodeSamples, RepeatCount = repeatCount }; } diff --git a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs index 0a244bb6c6..ae913b3bef 100644 --- a/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs +++ b/osu.Game/Rulesets/Objects/Legacy/Taiko/ConvertHitObjectParser.cs @@ -23,14 +23,14 @@ namespace osu.Game.Rulesets.Objects.Legacy.Taiko return new ConvertHit(); } - protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> repeatSamples) + protected override HitObject CreateSlider(Vector2 position, bool newCombo, int comboOffset, Vector2[] controlPoints, double length, PathType pathType, int repeatCount, List> nodeSamples) { return new ConvertSlider { ControlPoints = controlPoints, Distance = length, PathType = pathType, - RepeatSamples = repeatSamples, + NodeSamples = nodeSamples, RepeatCount = repeatCount }; } diff --git a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs index 7d918ff160..ea8784db47 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasRepeats.cs @@ -17,9 +17,15 @@ namespace osu.Game.Rulesets.Objects.Types int RepeatCount { get; } /// - /// The samples to be played when each repeat node is hit (0 -> first repeat node, 1 -> second repeat node, etc). + /// The samples to be played when each node of the is hit.
+ /// 0: The first node.
+ /// 1: The first repeat.
+ /// 2: The second repeat.
+ /// ...
+ /// n-1: The last repeat.
+ /// n: The last node. ///
- List> RepeatSamples { get; } + List> NodeSamples { get; } } public static class HasRepeatsExtensions diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs index 4b57e1e92d..11e9ecddc6 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/MarkerPart.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; +using osu.Framework.Threading; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Graphics; @@ -43,17 +44,23 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts return true; } + private ScheduledDelegate scheduledSeek; + /// /// Seeks the to the time closest to a position on the screen relative to the . /// /// The position in screen coordinates. private void seekToPosition(Vector2 screenPosition) { - if (Beatmap.Value == null) - return; + scheduledSeek?.Cancel(); + scheduledSeek = Schedule(() => + { + if (Beatmap.Value == null) + return; - float markerPos = MathHelper.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); - adjustableClock.Seek(markerPos / DrawWidth * Beatmap.Value.Track.Length); + float markerPos = MathHelper.Clamp(ToLocalSpace(screenPosition).X, 0, DrawWidth); + adjustableClock.Seek(markerPos / DrawWidth * Beatmap.Value.Track.Length); + }); } protected override void Update() diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 65c480b725..c9461ea504 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -11,7 +11,6 @@ - @@ -19,7 +18,7 @@ - + diff --git a/osu.sln b/osu.sln index c62fc02dba..f6ed7a5c42 100644 --- a/osu.sln +++ b/osu.sln @@ -31,8 +31,6 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Tournament", "osu. EndProject Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Tournament.Tests", "osu.Game.Tournament.Tests\osu.Game.Tournament.Tests.csproj", "{5789E78D-38F9-4072-AB7B-978F34B2C17F}" EndProject -Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Framework", "..\osu-framework\osu.Framework\osu.Framework.csproj", "{7A69A230-45A1-4444-8C43-A582E4F48C1E}" -EndProject Global GlobalSection(SolutionConfigurationPlatforms) = preSolution Debug|Any CPU = Debug|Any CPU @@ -95,10 +93,6 @@ Global {5789E78D-38F9-4072-AB7B-978F34B2C17F}.Debug|Any CPU.Build.0 = Debug|Any CPU {5789E78D-38F9-4072-AB7B-978F34B2C17F}.Release|Any CPU.ActiveCfg = Release|Any CPU {5789E78D-38F9-4072-AB7B-978F34B2C17F}.Release|Any CPU.Build.0 = Release|Any CPU - {7A69A230-45A1-4444-8C43-A582E4F48C1E}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {7A69A230-45A1-4444-8C43-A582E4F48C1E}.Debug|Any CPU.Build.0 = Debug|Any CPU - {7A69A230-45A1-4444-8C43-A582E4F48C1E}.Release|Any CPU.ActiveCfg = Release|Any CPU - {7A69A230-45A1-4444-8C43-A582E4F48C1E}.Release|Any CPU.Build.0 = Release|Any CPU EndGlobalSection GlobalSection(SolutionProperties) = preSolution HideSolutionNode = FALSE