1
0
mirror of https://github.com/ppy/osu.git synced 2025-01-13 12:53:11 +08:00

Merge pull request #21496 from peppy/fix-zero-length-spinners

Fix being able to place zero-length spinners
This commit is contained in:
Dean Herbert 2022-12-02 19:25:00 +09:00 committed by GitHub
commit 5a69656764
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
3 changed files with 20 additions and 9 deletions

View File

@ -4,6 +4,8 @@
#nullable disable #nullable disable
using System; using System;
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Graphics; using osu.Framework.Graphics;
using osu.Framework.Input.Events; using osu.Framework.Input.Events;
using osu.Game.Rulesets.Edit; using osu.Game.Rulesets.Edit;
@ -22,6 +24,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
private bool isPlacingEnd; private bool isPlacingEnd;
[Resolved(CanBeNull = true)]
[CanBeNull]
private IBeatSnapProvider beatSnapProvider { get; set; }
public SpinnerPlacementBlueprint() public SpinnerPlacementBlueprint()
: base(new Spinner { Position = OsuPlayfield.BASE_SIZE / 2 }) : base(new Spinner { Position = OsuPlayfield.BASE_SIZE / 2 })
{ {
@ -33,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
base.Update(); base.Update();
if (isPlacingEnd) if (isPlacingEnd)
HitObject.EndTime = Math.Max(HitObject.StartTime, EditorClock.CurrentTime); updateEndTimeFromCurrent();
piece.UpdateFrom(HitObject); piece.UpdateFrom(HitObject);
} }
@ -45,7 +51,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
if (e.Button != MouseButton.Right) if (e.Button != MouseButton.Right)
return false; return false;
HitObject.EndTime = EditorClock.CurrentTime; updateEndTimeFromCurrent();
EndPlacement(true); EndPlacement(true);
} }
else else
@ -61,5 +67,12 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Spinners
return true; return true;
} }
private void updateEndTimeFromCurrent()
{
HitObject.EndTime = beatSnapProvider == null
? Math.Max(HitObject.StartTime, EditorClock.CurrentTime)
: Math.Max(HitObject.StartTime + beatSnapProvider.GetBeatLengthAtTime(HitObject.StartTime), beatSnapProvider.SnapTime(EditorClock.CurrentTime));
}
} }
} }

View File

@ -1,14 +1,12 @@
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence. // 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. // See the LICENCE file in the repository root for full licence text.
#nullable disable
namespace osu.Game.Rulesets.Edit namespace osu.Game.Rulesets.Edit
{ {
public interface IBeatSnapProvider public interface IBeatSnapProvider
{ {
/// <summary> /// <summary>
/// Snaps a duration to the closest beat of a timing point applicable at the reference time. /// Snaps a duration to the closest beat of a timing point applicable at the reference time, factoring in the current <see cref="BeatDivisor"/>.
/// </summary> /// </summary>
/// <param name="time">The time to snap.</param> /// <param name="time">The time to snap.</param>
/// <param name="referenceTime">An optional reference point to use for timing point lookup.</param> /// <param name="referenceTime">An optional reference point to use for timing point lookup.</param>
@ -16,10 +14,10 @@ namespace osu.Game.Rulesets.Edit
double SnapTime(double time, double? referenceTime = null); double SnapTime(double time, double? referenceTime = null);
/// <summary> /// <summary>
/// Get the most appropriate beat length at a given time. /// Get the most appropriate beat length at a given time, pre-divided by <see cref="BeatDivisor"/>.
/// </summary> /// </summary>
/// <param name="referenceTime">A reference time used for lookup.</param> /// <param name="referenceTime">A reference time used for lookup.</param>
/// <returns>The most appropriate beat length.</returns> /// <returns>The most appropriate beat length, divided by <see cref="BeatDivisor"/>.</returns>
double GetBeatLengthAtTime(double referenceTime); double GetBeatLengthAtTime(double referenceTime);
/// <summary> /// <summary>

View File

@ -424,9 +424,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
break; break;
case IHasDuration endTimeHitObject: case IHasDuration endTimeHitObject:
double snappedTime = Math.Max(hitObject.StartTime, beatSnapProvider.SnapTime(time)); double snappedTime = Math.Max(hitObject.StartTime + beatSnapProvider.GetBeatLengthAtTime(hitObject.StartTime), beatSnapProvider.SnapTime(time));
if (endTimeHitObject.EndTime == snappedTime || Precision.AlmostEquals(snappedTime, hitObject.StartTime, beatmap.GetBeatLengthAtTime(snappedTime))) if (endTimeHitObject.EndTime == snappedTime)
return; return;
endTimeHitObject.Duration = snappedTime - hitObject.StartTime; endTimeHitObject.Duration = snappedTime - hitObject.StartTime;