1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-14 20:03:21 +08:00

Merge pull request #11552 from vmaggioli/zero-spinner-slider

Fix being able to set zero or negative hitobject duration via timeline
This commit is contained in:
Dan Balasescu 2021-02-08 14:52:35 +09:00 committed by GitHub
commit e8f08b09dc
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 63 additions and 5 deletions

View File

@ -0,0 +1,55 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using NUnit.Framework;
using osu.Framework.Graphics;
using osu.Framework.Testing;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.Edit.Compose.Components.Timeline;
using osuTK;
using osuTK.Input;
using static osu.Game.Screens.Edit.Compose.Components.Timeline.TimelineHitObjectBlueprint;
namespace osu.Game.Tests.Visual.Editing
{
public class TestSceneTimelineHitObjectBlueprint : TimelineTestScene
{
public override Drawable CreateTestComponent() => new TimelineBlueprintContainer(Composer);
[Test]
public void TestDisallowZeroDurationObjects()
{
DragBar dragBar;
AddStep("add spinner", () =>
{
EditorBeatmap.Clear();
EditorBeatmap.Add(new Spinner
{
Position = new Vector2(256, 256),
StartTime = 150,
Duration = 500
});
});
AddStep("hold down drag bar", () =>
{
// distinguishes between the actual drag bar and its "underlay shadow".
dragBar = this.ChildrenOfType<DragBar>().Single(bar => bar.HandlePositionalInput);
InputManager.MoveMouseTo(dragBar);
InputManager.PressButton(MouseButton.Left);
});
AddStep("try to drag bar past start", () =>
{
var blueprint = this.ChildrenOfType<TimelineHitObjectBlueprint>().Single();
InputManager.MoveMouseTo(blueprint.SelectionQuad.TopLeft - new Vector2(100, 0));
InputManager.ReleaseButton(MouseButton.Left);
});
AddAssert("object has non-zero duration", () => EditorBeatmap.HitObjects.OfType<IHasDuration>().Single().Duration > 0);
}
}
}

View File

@ -23,22 +23,24 @@ namespace osu.Game.Tests.Visual.Editing
protected HitObjectComposer Composer { get; private set; }
protected EditorBeatmap EditorBeatmap { get; private set; }
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
Beatmap.Value = new WaveformTestBeatmap(audio);
var playable = Beatmap.Value.GetPlayableBeatmap(Beatmap.Value.BeatmapInfo.Ruleset);
var editorBeatmap = new EditorBeatmap(playable);
EditorBeatmap = new EditorBeatmap(playable);
Dependencies.Cache(editorBeatmap);
Dependencies.CacheAs<IBeatSnapProvider>(editorBeatmap);
Dependencies.Cache(EditorBeatmap);
Dependencies.CacheAs<IBeatSnapProvider>(EditorBeatmap);
Composer = playable.BeatmapInfo.Ruleset.CreateInstance().CreateHitObjectComposer().With(d => d.Alpha = 0);
AddRange(new Drawable[]
{
editorBeatmap,
EditorBeatmap,
Composer,
new FillFlowContainer
{

View File

@ -13,6 +13,7 @@ using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Input.Events;
using osu.Framework.Utils;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
@ -387,7 +388,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
case IHasDuration endTimeHitObject:
var snappedTime = Math.Max(hitObject.StartTime, beatSnapProvider.SnapTime(time));
if (endTimeHitObject.EndTime == snappedTime)
if (endTimeHitObject.EndTime == snappedTime || Precision.AlmostEquals(snappedTime, hitObject.StartTime, beatmap.GetBeatLengthAtTime(snappedTime)))
return;
endTimeHitObject.Duration = snappedTime - hitObject.StartTime;