diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs index 3aec7c2872..7afb8fcf49 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointPiece.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -8,7 +9,6 @@ using osu.Framework.Graphics.Lines; using osu.Framework.Graphics.Shapes; using osu.Framework.Input.Events; using osu.Game.Graphics; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Objects; using osuTK; @@ -16,6 +16,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { public class PathControlPointPiece : BlueprintPiece { + public Action ControlPointsChanged; + private readonly Slider slider; private readonly int index; @@ -96,7 +98,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components if (isSegmentSeparatorWithPrevious) newControlPoints[index - 1] = newControlPoints[index]; - slider.Path = new SliderPath(slider.Path.Type, newControlPoints); + ControlPointsChanged?.Invoke(newControlPoints); return true; } 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 24fcc460d1..0385824b27 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs @@ -1,14 +1,18 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Osu.Objects; +using osuTK; namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components { public class PathControlPointVisualiser : CompositeDrawable { + public Action ControlPointsChanged; + private readonly Slider slider; private readonly Container pieces; @@ -25,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components base.Update(); while (slider.Path.ControlPoints.Length > pieces.Count) - pieces.Add(new PathControlPointPiece(slider, pieces.Count)); + pieces.Add(new PathControlPointPiece(slider, pieces.Count) { ControlPointsChanged = c => ControlPointsChanged?.Invoke(c) }); while (slider.Path.ControlPoints.Length < pieces.Count) pieces.Remove(pieces[pieces.Count - 1]); } diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs index e1478a062c..761c2961ea 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs @@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders bodyPiece = new SliderBodyPiece(), headCirclePiece = new HitCirclePiece(), tailCirclePiece = new HitCirclePiece(), - new PathControlPointVisualiser(HitObject), + new PathControlPointVisualiser(HitObject) { ControlPointsChanged = _ => updateSlider() }, }; setState(PlacementState.Initial); diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs index fdeffc6f8a..a62c3cbb9f 100644 --- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs +++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs @@ -1,7 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Allocation; using osu.Framework.Graphics; +using osu.Game.Rulesets.Edit; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; @@ -15,6 +19,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders protected readonly SliderCircleSelectionBlueprint HeadBlueprint; protected readonly SliderCircleSelectionBlueprint TailBlueprint; + [Resolved] + private HitObjectComposer composer { get; set; } + public SliderSelectionBlueprint(DrawableSlider slider) : base(slider) { @@ -25,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders BodyPiece = new SliderBodyPiece(), HeadBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.Start), TailBlueprint = CreateCircleSelectionBlueprint(slider, SliderPosition.End), - new PathControlPointVisualiser(sliderObject), + new PathControlPointVisualiser(sliderObject) { ControlPointsChanged = onNewControlPoints }, }; } @@ -36,6 +43,14 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders BodyPiece.UpdateFrom(HitObject); } + private void onNewControlPoints(Vector2[] controlPoints) + { + var unsnappedPath = new SliderPath(controlPoints.Length > 2 ? PathType.Bezier : PathType.Linear, controlPoints); + var snappedDistance = composer.GetSnappedDistance((float)unsnappedPath.Distance); + + HitObject.Path = new SliderPath(unsnappedPath.Type, controlPoints, snappedDistance); + } + public override Vector2 SelectionPoint => HeadBlueprint.SelectionPoint; protected virtual SliderCircleSelectionBlueprint CreateCircleSelectionBlueprint(DrawableSlider slider, SliderPosition position) => new SliderCircleSelectionBlueprint(slider, position);