1
0
mirror of https://github.com/ppy/osu.git synced 2025-02-13 02:13:21 +08:00

Fix behavioural change in interaction between grid & distance snap

This commit is contained in:
Bartłomiej Dach 2025-01-24 12:50:46 +01:00
parent 589035c534
commit b04144df54
No known key found for this signature in database
5 changed files with 26 additions and 15 deletions

View File

@ -52,10 +52,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles
public override SnapResult UpdateTimeAndPosition(Vector2 screenSpacePosition, double fallbackTime)
{
var result = composer?.TrySnapToNearbyObjects(screenSpacePosition, fallbackTime)
?? composer?.TrySnapToDistanceGrid(screenSpacePosition)
?? composer?.TrySnapToPositionGrid(screenSpacePosition)
?? new SnapResult(screenSpacePosition, fallbackTime);
var result = composer?.TrySnapToNearbyObjects(screenSpacePosition, fallbackTime);
result ??= composer?.TrySnapToDistanceGrid(screenSpacePosition);
if (composer?.TrySnapToPositionGrid(result?.ScreenSpacePosition ?? screenSpacePosition, result?.Time ?? fallbackTime) is SnapResult gridSnapResult)
result = gridSnapResult;
result ??= new SnapResult(screenSpacePosition, fallbackTime);
UpdateTimeAndPosition(result);
HitObject.Position = ToLocalSpace(result.ScreenSpacePosition);

View File

@ -9,6 +9,7 @@ using System.Collections.Specialized;
using System.Diagnostics;
using System.Linq;
using Humanizer;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@ -48,6 +49,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
public Action<List<PathControlPoint>> SplitControlPointsRequested;
[Resolved(CanBeNull = true)]
[CanBeNull]
private OsuHitObjectComposer positionSnapProvider { get; set; }
[Resolved(CanBeNull = true)]
@ -433,14 +435,17 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
{
// Special handling for selections containing head control point - the position of the hit object changes which means the snapped position and time have to be taken into account
Vector2 newHeadPosition = Parent!.ToScreenSpace(e.MousePosition + (dragStartPositions[0] - dragStartPositions[draggedControlPointIndex]));
SnapResult result = positionSnapProvider?.TrySnapToNearbyObjects(newHeadPosition, oldStartTime)
?? positionSnapProvider?.TrySnapToDistanceGrid(newHeadPosition)
?? positionSnapProvider?.TrySnapToPositionGrid(newHeadPosition);
Vector2 movementDelta = Parent!.ToLocalSpace(result?.ScreenSpacePosition ?? newHeadPosition) - hitObject.Position;
var result = positionSnapProvider?.TrySnapToNearbyObjects(newHeadPosition, oldStartTime);
result ??= positionSnapProvider?.TrySnapToDistanceGrid(newHeadPosition);
if (positionSnapProvider?.TrySnapToPositionGrid(result?.ScreenSpacePosition ?? newHeadPosition, result?.Time ?? oldStartTime) is SnapResult gridSnapResult)
result = gridSnapResult;
result ??= new SnapResult(newHeadPosition, oldStartTime);
Vector2 movementDelta = Parent!.ToLocalSpace(result.ScreenSpacePosition) - hitObject.Position;
hitObject.Position += movementDelta;
hitObject.StartTime = result?.Time ?? hitObject.StartTime;
hitObject.StartTime = result.Time ?? hitObject.StartTime;
for (int i = 1; i < hitObject.Path.ControlPoints.Count; i++)
{

View File

@ -108,10 +108,11 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
public override SnapResult UpdateTimeAndPosition(Vector2 screenSpacePosition, double fallbackTime)
{
var result = composer?.TrySnapToNearbyObjects(screenSpacePosition, fallbackTime)
?? composer?.TrySnapToDistanceGrid(screenSpacePosition)
?? composer?.TrySnapToPositionGrid(screenSpacePosition)
?? new SnapResult(screenSpacePosition, fallbackTime);
var result = composer?.TrySnapToNearbyObjects(screenSpacePosition, fallbackTime);
result ??= composer?.TrySnapToDistanceGrid(screenSpacePosition);
if (composer?.TrySnapToPositionGrid(result?.ScreenSpacePosition ?? screenSpacePosition, result?.Time ?? fallbackTime) is SnapResult gridSnapResult)
result = gridSnapResult;
result ??= new SnapResult(screenSpacePosition, fallbackTime);
UpdateTimeAndPosition(result);

View File

@ -60,7 +60,11 @@ namespace osu.Game.Rulesets.Osu.Edit
Vector2 movePosition = blueprints.First().originalSnapPositions.First() + distanceTravelled;
// Retrieve a snapped position.
var result = Composer.TrySnapToDistanceGrid(movePosition) ?? Composer.TrySnapToPositionGrid(movePosition) ?? new SnapResult(movePosition, null);
var result = Composer.TrySnapToNearbyObjects(movePosition);
result ??= Composer.TrySnapToDistanceGrid(movePosition);
if (Composer.TrySnapToPositionGrid(result?.ScreenSpacePosition ?? movePosition, result?.Time) is SnapResult gridSnapResult)
result = gridSnapResult;
result ??= new SnapResult(movePosition, null);
var referenceBlueprint = blueprints.First().blueprint;
bool moved = SelectionHandler.HandleMovement(new MoveSelectionEvent<HitObject>(referenceBlueprint, result.ScreenSpacePosition - referenceBlueprint.ScreenSpaceSelectionPoint));

View File

@ -261,7 +261,7 @@ namespace osu.Game.Rulesets.Osu.Edit
}
[CanBeNull]
public SnapResult TrySnapToPositionGrid(Vector2 screenSpacePosition)
public SnapResult TrySnapToPositionGrid(Vector2 screenSpacePosition, double? fallbackTime = null)
{
if (rectangularGridSnapToggle.Value != TernaryState.True)
return null;