mirror of
https://github.com/ppy/osu.git
synced 2025-01-13 02:32:55 +08:00
Merge pull request #10974 from peppy/editor-beat-snap-always
Fix editor not beat snapping when positional snap is unavailable
This commit is contained in:
commit
76919a5772
@ -78,9 +78,9 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||
|
||||
private double originalStartTime;
|
||||
|
||||
public override void UpdatePosition(SnapResult result)
|
||||
public override void UpdateTimeAndPosition(SnapResult result)
|
||||
{
|
||||
base.UpdatePosition(result);
|
||||
base.UpdateTimeAndPosition(result);
|
||||
|
||||
if (PlacementActive)
|
||||
{
|
||||
|
@ -48,9 +48,9 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||
return true;
|
||||
}
|
||||
|
||||
public override void UpdatePosition(SnapResult result)
|
||||
public override void UpdateTimeAndPosition(SnapResult result)
|
||||
{
|
||||
base.UpdatePosition(result);
|
||||
base.UpdateTimeAndPosition(result);
|
||||
|
||||
if (!PlacementActive)
|
||||
Column = result.Playfield as Column;
|
||||
|
@ -22,9 +22,9 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
||||
InternalChild = piece = new EditNotePiece { Origin = Anchor.Centre };
|
||||
}
|
||||
|
||||
public override void UpdatePosition(SnapResult result)
|
||||
public override void UpdateTimeAndPosition(SnapResult result)
|
||||
{
|
||||
base.UpdatePosition(result);
|
||||
base.UpdateTimeAndPosition(result);
|
||||
|
||||
if (result.Playfield != null)
|
||||
{
|
||||
|
@ -0,0 +1,41 @@
|
||||
// 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.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Osu.UI;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osuTK.Input;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneObjectBeatSnap : TestSceneOsuEditor
|
||||
{
|
||||
private OsuPlayfield playfield;
|
||||
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(Ruleset.Value, false);
|
||||
|
||||
public override void SetUpSteps()
|
||||
{
|
||||
base.SetUpSteps();
|
||||
AddStep("get playfield", () => playfield = Editor.ChildrenOfType<OsuPlayfield>().First());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBeatSnapHitCircle()
|
||||
{
|
||||
double firstTimingPointTime() => Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints.First().Time;
|
||||
|
||||
AddStep("seek some milliseconds forward", () => EditorClock.Seek(firstTimingPointTime() + 10));
|
||||
|
||||
AddStep("move mouse to centre", () => InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.Centre));
|
||||
AddStep("enter placement mode", () => InputManager.Key(Key.Number2));
|
||||
AddStep("place first object", () => InputManager.Click(MouseButton.Left));
|
||||
|
||||
AddAssert("ensure object snapped back to correct time", () => EditorBeatmap.HitObjects.First().StartTime == firstTimingPointTime());
|
||||
}
|
||||
}
|
||||
}
|
@ -25,6 +25,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
{
|
||||
base.SetUpSteps();
|
||||
AddStep("get playfield", () => playfield = Editor.ChildrenOfType<OsuPlayfield>().First());
|
||||
AddStep("seek to first control point", () => EditorClock.Seek(Beatmap.Value.Beatmap.ControlPointInfo.TimingPoints.First().Time));
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
@ -66,13 +67,13 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
||||
|
||||
AddStep("start slider placement", () => InputManager.Click(MouseButton.Left));
|
||||
|
||||
AddStep("move to place end", () => InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.Centre + new Vector2(playfield.ScreenSpaceDrawQuad.Width * 0.185f, 0)));
|
||||
AddStep("move to place end", () => InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.Centre + new Vector2(playfield.ScreenSpaceDrawQuad.Width * 0.225f, 0)));
|
||||
|
||||
AddStep("end slider placement", () => InputManager.Click(MouseButton.Right));
|
||||
|
||||
AddStep("enter circle placement mode", () => InputManager.Key(Key.Number2));
|
||||
|
||||
AddStep("move mouse slightly", () => InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.Centre + new Vector2(playfield.ScreenSpaceDrawQuad.Width * 0.20f, 0)));
|
||||
AddStep("move mouse slightly", () => InputManager.MoveMouseTo(playfield.ScreenSpaceDrawQuad.Centre + new Vector2(playfield.ScreenSpaceDrawQuad.Width * 0.235f, 0)));
|
||||
|
||||
AddStep("place second object", () => InputManager.Click(MouseButton.Left));
|
||||
|
||||
|
@ -45,9 +45,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles
|
||||
return base.OnMouseDown(e);
|
||||
}
|
||||
|
||||
public override void UpdatePosition(SnapResult result)
|
||||
public override void UpdateTimeAndPosition(SnapResult result)
|
||||
{
|
||||
base.UpdatePosition(result);
|
||||
base.UpdateTimeAndPosition(result);
|
||||
HitObject.Position = ToLocalSpace(result.ScreenSpacePosition);
|
||||
}
|
||||
}
|
||||
|
@ -67,9 +67,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
||||
inputManager = GetContainingInputManager();
|
||||
}
|
||||
|
||||
public override void UpdatePosition(SnapResult result)
|
||||
public override void UpdateTimeAndPosition(SnapResult result)
|
||||
{
|
||||
base.UpdatePosition(result);
|
||||
base.UpdateTimeAndPosition(result);
|
||||
|
||||
switch (state)
|
||||
{
|
||||
|
@ -43,10 +43,10 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
||||
return false;
|
||||
}
|
||||
|
||||
public override void UpdatePosition(SnapResult result)
|
||||
public override void UpdateTimeAndPosition(SnapResult result)
|
||||
{
|
||||
piece.Position = ToLocalSpace(result.ScreenSpacePosition);
|
||||
base.UpdatePosition(result);
|
||||
base.UpdateTimeAndPosition(result);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -68,9 +68,9 @@ namespace osu.Game.Rulesets.Taiko.Edit.Blueprints
|
||||
EndPlacement(true);
|
||||
}
|
||||
|
||||
public override void UpdatePosition(SnapResult result)
|
||||
public override void UpdateTimeAndPosition(SnapResult result)
|
||||
{
|
||||
base.UpdatePosition(result);
|
||||
base.UpdateTimeAndPosition(result);
|
||||
|
||||
if (PlacementActive)
|
||||
{
|
||||
|
@ -85,10 +85,10 @@ namespace osu.Game.Rulesets.Edit
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// Updates the position of this <see cref="PlacementBlueprint"/> to a new screen-space position.
|
||||
/// Updates the time and position of this <see cref="PlacementBlueprint"/> based on the provided snap information.
|
||||
/// </summary>
|
||||
/// <param name="result">The snap result information.</param>
|
||||
public virtual void UpdatePosition(SnapResult result)
|
||||
public virtual void UpdateTimeAndPosition(SnapResult result)
|
||||
{
|
||||
if (!PlacementActive)
|
||||
HitObject.StartTime = result.Time ?? EditorClock?.CurrentTime ?? Time.Current;
|
||||
|
@ -41,7 +41,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
private IEditorChangeHandler changeHandler { get; set; }
|
||||
|
||||
[Resolved]
|
||||
private EditorClock editorClock { get; set; }
|
||||
protected EditorClock EditorClock { get; private set; }
|
||||
|
||||
[Resolved]
|
||||
protected EditorBeatmap Beatmap { get; private set; }
|
||||
@ -170,7 +170,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
if (clickedBlueprint == null || SelectionHandler.SelectedBlueprints.FirstOrDefault(b => b.IsHovered) != clickedBlueprint)
|
||||
return false;
|
||||
|
||||
editorClock?.SeekTo(clickedBlueprint.HitObject.StartTime);
|
||||
EditorClock?.SeekTo(clickedBlueprint.HitObject.StartTime);
|
||||
return true;
|
||||
}
|
||||
|
||||
@ -381,7 +381,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
|
||||
case SelectionState.Selected:
|
||||
// if the editor is playing, we generally don't want to deselect objects even if outside the selection area.
|
||||
if (!editorClock.IsRunning && !isValidForSelection())
|
||||
if (!EditorClock.IsRunning && !isValidForSelection())
|
||||
blueprint.Deselect();
|
||||
break;
|
||||
}
|
||||
|
@ -157,7 +157,10 @@ namespace osu.Game.Screens.Edit.Compose.Components
|
||||
{
|
||||
var snapResult = Composer.SnapScreenSpacePositionToValidTime(inputManager.CurrentState.Mouse.Position);
|
||||
|
||||
currentPlacement.UpdatePosition(snapResult);
|
||||
// if no time was found from positional snapping, we should still quantize to the beat.
|
||||
snapResult.Time ??= Beatmap.SnapTime(EditorClock.CurrentTime, null);
|
||||
|
||||
currentPlacement.UpdateTimeAndPosition(snapResult);
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual
|
||||
{
|
||||
base.Update();
|
||||
|
||||
currentBlueprint.UpdatePosition(SnapForBlueprint(currentBlueprint));
|
||||
currentBlueprint.UpdateTimeAndPosition(SnapForBlueprint(currentBlueprint));
|
||||
}
|
||||
|
||||
protected virtual SnapResult SnapForBlueprint(PlacementBlueprint blueprint) =>
|
||||
@ -85,7 +85,7 @@ namespace osu.Game.Tests.Visual
|
||||
if (drawable is PlacementBlueprint blueprint)
|
||||
{
|
||||
blueprint.Show();
|
||||
blueprint.UpdatePosition(SnapForBlueprint(blueprint));
|
||||
blueprint.UpdateTimeAndPosition(SnapForBlueprint(blueprint));
|
||||
}
|
||||
}
|
||||
|
||||
|
Loading…
Reference in New Issue
Block a user