1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 21:27:24 +08:00

Fix slider tracking state not restoring correctly in all cases on rewind

This commit is contained in:
Bartłomiej Dach 2024-02-29 11:44:14 +01:00
parent 7b28a66fc0
commit d05b31933f
No known key found for this signature in database

View File

@ -5,11 +5,13 @@ using System;
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 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
/// </summary>
public bool Tracking { get; private set; }
[Resolved]
private IGameplayClock? gameplayClock { get; set; }
private readonly Stack<(double time, bool tracking)> trackingHistory = new Stack<(double, bool)>();
/// <summary>
/// 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 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
/// <param name="isValidTrackingPosition">Whether the current mouse position is valid to begin tracking.</param>
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 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
&& isValidTrackingPosition
// valid action
&& validTrackingAction;
if (wasTracking != Tracking)
trackingHistory.Push((Time.Current, Tracking));
}
private OsuAction? getInitialHitAction() => slider.HeadCircle?.HitAction;