From 5ac3bb73ee2569b62f5a928606b16bfc2b969a9e Mon Sep 17 00:00:00 2001 From: Darius Wattimena Date: Mon, 18 Nov 2024 22:19:08 +0100 Subject: [PATCH 1/2] Adds an option to the catch editor to convert sliders to fruits --- .../JuiceStreamSelectionBlueprint.cs | 69 +++++++++++++++++++ 1 file changed, 69 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs index 3eb8d6c018..2f2ccae38b 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs @@ -10,10 +10,12 @@ using osu.Framework.Graphics.Primitives; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Bindings; using osu.Framework.Input.Events; +using osu.Framework.Utils; using osu.Game.Graphics.UserInterface; using osu.Game.Rulesets.Catch.Edit.Blueprints.Components; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Screens.Edit; using osuTK; using osuTK.Input; @@ -54,6 +56,12 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints [Resolved] private EditorBeatmap? editorBeatmap { get; set; } + [Resolved] + private IEditorChangeHandler? changeHandler { get; set; } + + [Resolved] + private BindableBeatDivisor? beatDivisor { get; set; } + public JuiceStreamSelectionBlueprint(JuiceStream hitObject) : base(hitObject) { @@ -119,6 +127,20 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints return base.OnMouseDown(e); } + protected override bool OnKeyDown(KeyDownEvent e) + { + if (!IsSelected) + return false; + + if (e.Key == Key.F && e.ControlPressed && e.ShiftPressed) + { + convertToFruits(); + return true; + } + + return false; + } + private void onDefaultsApplied(HitObject _) { computeObjectBounds(); @@ -168,6 +190,48 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints lastSliderPathVersion = HitObject.Path.Version.Value; } + private void convertToFruits() + { + if (editorBeatmap == null || beatDivisor == null) + return; + + var timingPoint = editorBeatmap.ControlPointInfo.TimingPointAt(HitObject.StartTime); + double streamSpacing = timingPoint.BeatLength / beatDivisor.Value; + + changeHandler?.BeginChange(); + + int i = 0; + double time = HitObject.StartTime; + + while (!Precision.DefinitelyBigger(time, HitObject.GetEndTime(), 1)) + { + // positionWithRepeats is a fractional number in the range of [0, HitObject.SpanCount()] + // and indicates how many fractional spans of a slider have passed up to time. + double positionWithRepeats = (time - HitObject.StartTime) / HitObject.Duration * HitObject.SpanCount(); + double pathPosition = positionWithRepeats - (int)positionWithRepeats; + // every second span is in the reverse direction - need to reverse the path position. + if (positionWithRepeats % 2 >= 1) + pathPosition = 1 - pathPosition; + + float fruitXValue = HitObject.OriginalX + HitObject.Path.PositionAt(pathPosition).X; + + editorBeatmap.Add(new Fruit + { + StartTime = time, + OriginalX = fruitXValue, + NewCombo = i == 0 && HitObject.NewCombo, + Samples = HitObject.Samples.Select(s => s.With()).ToList() + }); + + i += 1; + time = HitObject.StartTime + i * streamSpacing; + } + + editorBeatmap.Remove(HitObject); + + changeHandler?.EndChange(); + } + private IEnumerable getContextMenuItems() { yield return new OsuMenuItem("Add vertex", MenuItemType.Standard, () => @@ -177,6 +241,11 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints { Hotkey = new Hotkey(new KeyCombination(InputKey.Control, InputKey.MouseLeft)) }; + + yield return new OsuMenuItem("Convert to fruits", MenuItemType.Destructive, convertToFruits) + { + Hotkey = new Hotkey(new KeyCombination(InputKey.Control, InputKey.Shift, InputKey.F)) + }; } protected override void Dispose(bool isDisposing) From 00e3b20ff0bb3d6f001fc375034cef8406fab799 Mon Sep 17 00:00:00 2001 From: Darius Wattimena Date: Mon, 18 Nov 2024 22:30:15 +0100 Subject: [PATCH 2/2] Change text to stream instead of fruits as that is the term by catch mappers --- .../Edit/Blueprints/JuiceStreamSelectionBlueprint.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs index 2f2ccae38b..a61478f5d5 100644 --- a/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Catch/Edit/Blueprints/JuiceStreamSelectionBlueprint.cs @@ -134,7 +134,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints if (e.Key == Key.F && e.ControlPressed && e.ShiftPressed) { - convertToFruits(); + convertToStream(); return true; } @@ -190,7 +190,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints lastSliderPathVersion = HitObject.Path.Version.Value; } - private void convertToFruits() + private void convertToStream() { if (editorBeatmap == null || beatDivisor == null) return; @@ -242,7 +242,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints Hotkey = new Hotkey(new KeyCombination(InputKey.Control, InputKey.MouseLeft)) }; - yield return new OsuMenuItem("Convert to fruits", MenuItemType.Destructive, convertToFruits) + yield return new OsuMenuItem("Convert to stream", MenuItemType.Destructive, convertToStream) { Hotkey = new Hotkey(new KeyCombination(InputKey.Control, InputKey.Shift, InputKey.F)) };