diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs index 53784a7f08..0e1ede4d4c 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/HitCirclePlacementBlueprint.cs @@ -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); diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs index a3bb0b868a..189bb005a7 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -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> 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++) { diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index fd72f18b12..2d38e83b2e 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -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); diff --git a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs index 235368e552..5eff95adec 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuBlueprintContainer.cs @@ -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(referenceBlueprint, result.ScreenSpacePosition - referenceBlueprint.ScreenSpaceSelectionPoint)); diff --git a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs index 2a7ec79e55..194276baf9 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuHitObjectComposer.cs @@ -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;