1
0
mirror of https://github.com/ppy/osu.git synced 2024-12-13 08:32:57 +08:00

Merge pull request #19982 from OliBomby/fix-illegal-merge

Fixed 0 length merge being allowed
This commit is contained in:
Dean Herbert 2022-08-30 12:28:18 +09:00 committed by GitHub
commit 706ac3e44f
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
2 changed files with 50 additions and 2 deletions

View File

@ -3,9 +3,11 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Edit;
using osu.Game.Rulesets.Osu.Objects;
using osuTK;
using osuTK.Input;
@ -14,6 +16,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
{
public class TestSceneObjectMerging : TestSceneOsuEditor
{
private OsuSelectionHandler selectionHandler => Editor.ChildrenOfType<OsuSelectionHandler>().First();
[Test]
public void TestSimpleMerge()
{
@ -29,6 +33,9 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
EditorBeatmap.SelectedHitObjects.Add(circle2);
});
moveMouseToHitObject(1);
AddAssert("merge option available", () => selectionHandler.ContextMenuItems.Any(o => o.Text.Value == "Merge selection"));
mergeSelection();
AddAssert("slider created", () => circle1 is not null && circle2 is not null && sliderCreatedFor(
@ -174,6 +181,30 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
AddAssert("spinner not merged", () => EditorBeatmap.HitObjects.Contains(spinner));
}
[Test]
public void TestIllegalMerge()
{
HitCircle? circle1 = null;
HitCircle? circle2 = null;
AddStep("add two circles on the same position", () =>
{
circle1 = new HitCircle();
circle2 = new HitCircle { Position = circle1.Position + Vector2.UnitX, StartTime = 1 };
EditorClock.Seek(0);
EditorBeatmap.Add(circle1);
EditorBeatmap.Add(circle2);
EditorBeatmap.SelectedHitObjects.Add(circle1);
EditorBeatmap.SelectedHitObjects.Add(circle2);
});
moveMouseToHitObject(1);
AddAssert("merge option not available", () => selectionHandler.ContextMenuItems.Length > 0 && selectionHandler.ContextMenuItems.All(o => o.Text.Value != "Merge selection"));
mergeSelection();
AddAssert("circles not merged", () => circle1 is not null && circle2 is not null
&& EditorBeatmap.HitObjects.Contains(circle1) && EditorBeatmap.HitObjects.Contains(circle2));
}
private void mergeSelection()
{
AddStep("merge selection", () =>
@ -225,5 +256,17 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
return mergedSlider.Samples[0] is not null;
}
private void moveMouseToHitObject(int index)
{
AddStep($"hover mouse over hit object {index}", () =>
{
if (EditorBeatmap.HitObjects.Count <= index)
return;
Vector2 position = ((OsuHitObject)EditorBeatmap.HitObjects[index]).Position;
InputManager.MoveMouseTo(selectionHandler.ToScreenSpace(position));
});
}
}
}

View File

@ -358,7 +358,7 @@ namespace osu.Game.Rulesets.Osu.Edit
{
var mergeableObjects = selectedMergeableObjects;
if (mergeableObjects.Length < 2)
if (!canMerge(mergeableObjects))
return;
ChangeHandler?.BeginChange();
@ -445,8 +445,13 @@ namespace osu.Game.Rulesets.Osu.Edit
foreach (var item in base.GetContextMenuItemsForSelection(selection))
yield return item;
if (selectedMergeableObjects.Length > 1)
if (canMerge(selectedMergeableObjects))
yield return new OsuMenuItem("Merge selection", MenuItemType.Destructive, mergeSelection);
}
private bool canMerge(IReadOnlyList<OsuHitObject> objects) =>
objects.Count > 1
&& (objects.Any(h => h is Slider)
|| objects.Zip(objects.Skip(1), (h1, h2) => Precision.DefinitelyBigger(Vector2.DistanceSquared(h1.Position, h2.Position), 1)).Any(x => x));
}
}