diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs index 148cf79337..58fa04bb4c 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/SliderInputManager.cs @@ -5,11 +5,13 @@ using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Input; using osu.Framework.Input.Events; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Screens.Play; using osuTK; namespace osu.Game.Rulesets.Osu.Objects.Drawables @@ -21,6 +23,11 @@ public partial class SliderInputManager : Component, IRequireHighFrequencyMouseP /// public bool Tracking { get; private set; } + [Resolved] + private IGameplayClock? gameplayClock { get; set; } + + private readonly Stack<(double time, bool tracking)> trackingHistory = new Stack<(double, bool)>(); + /// /// The point in time after which we can accept any key for tracking. Before this time, we may need to restrict tracking to the key used to hit the head circle. /// @@ -208,6 +215,19 @@ private float getFollowRadius(bool expanded) /// Whether the current mouse position is valid to begin tracking. private void updateTracking(bool isValidTrackingPosition) { + if (gameplayClock?.IsRewinding == true) + { + while (trackingHistory.TryPeek(out var historyEntry) && Time.Current < historyEntry.time) + trackingHistory.Pop(); + + Debug.Assert(trackingHistory.Count > 0); + + Tracking = trackingHistory.Peek().tracking; + return; + } + + bool wasTracking = Tracking; + // from the point at which the head circle is hit, this will be non-null. // it may be null if the head circle was missed. OsuAction? headCircleHitAction = getInitialHitAction(); @@ -247,6 +267,9 @@ private void updateTracking(bool isValidTrackingPosition) && isValidTrackingPosition // valid action && validTrackingAction; + + if (wasTracking != Tracking) + trackingHistory.Push((Time.Current, Tracking)); } private OsuAction? getInitialHitAction() => slider.HeadCircle?.HitAction;