mirror of https://github.com/ppy/osu
Fix switching direction when changing tracks with shuffle on restarting the same track
Closes https://github.com/ppy/osu/issues/30190.
This commit is contained in:
parent
0882f1bb70
commit
47cb696b69
|
@ -74,6 +74,7 @@ public partial class MusicController : CompositeDrawable
|
||||||
private readonly Bindable<RandomSelectAlgorithm> randomSelectAlgorithm = new Bindable<RandomSelectAlgorithm>();
|
private readonly Bindable<RandomSelectAlgorithm> randomSelectAlgorithm = new Bindable<RandomSelectAlgorithm>();
|
||||||
private readonly List<Live<BeatmapSetInfo>> previousRandomSets = new List<Live<BeatmapSetInfo>>();
|
private readonly List<Live<BeatmapSetInfo>> previousRandomSets = new List<Live<BeatmapSetInfo>>();
|
||||||
private int randomHistoryDirection;
|
private int randomHistoryDirection;
|
||||||
|
private int lastRandomTrackDirection;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio, OsuConfigManager configManager)
|
private void load(AudioManager audio, OsuConfigManager configManager)
|
||||||
|
@ -371,54 +372,69 @@ private bool next(bool allowProtectedTracks)
|
||||||
|
|
||||||
private Live<BeatmapSetInfo>? getNextRandom(int direction, bool allowProtectedTracks)
|
private Live<BeatmapSetInfo>? getNextRandom(int direction, bool allowProtectedTracks)
|
||||||
{
|
{
|
||||||
Live<BeatmapSetInfo> result;
|
try
|
||||||
|
|
||||||
var possibleSets = getBeatmapSets().Where(s => !s.Value.Protected || allowProtectedTracks).ToArray();
|
|
||||||
|
|
||||||
if (possibleSets.Length == 0)
|
|
||||||
return null;
|
|
||||||
|
|
||||||
// condition below checks if the signs of `randomHistoryDirection` and `direction` are opposite and not zero.
|
|
||||||
// if that is the case, it means that the user had previously chosen next track `randomHistoryDirection` times and wants to go back,
|
|
||||||
// or that the user had previously chosen previous track `randomHistoryDirection` times and wants to go forward.
|
|
||||||
// in both cases, it means that we have a history of previous random selections that we can rewind.
|
|
||||||
if (randomHistoryDirection * direction < 0)
|
|
||||||
{
|
{
|
||||||
Debug.Assert(Math.Abs(randomHistoryDirection) == previousRandomSets.Count);
|
Live<BeatmapSetInfo> result;
|
||||||
result = previousRandomSets[^1];
|
|
||||||
previousRandomSets.RemoveAt(previousRandomSets.Count - 1);
|
|
||||||
randomHistoryDirection += direction;
|
|
||||||
return result;
|
|
||||||
}
|
|
||||||
|
|
||||||
// if the early-return above didn't cover it, it means that we have no history to fall back on
|
var possibleSets = getBeatmapSets().Where(s => !s.Value.Protected || allowProtectedTracks).ToArray();
|
||||||
// and need to actually choose something random.
|
|
||||||
switch (randomSelectAlgorithm.Value)
|
|
||||||
{
|
|
||||||
case RandomSelectAlgorithm.Random:
|
|
||||||
result = possibleSets[RNG.Next(possibleSets.Length)];
|
|
||||||
break;
|
|
||||||
|
|
||||||
case RandomSelectAlgorithm.RandomPermutation:
|
if (possibleSets.Length == 0)
|
||||||
var notYetPlayedSets = possibleSets.Except(previousRandomSets).ToArray();
|
return null;
|
||||||
|
|
||||||
if (notYetPlayedSets.Length == 0)
|
// condition below checks if the signs of `randomHistoryDirection` and `direction` are opposite and not zero.
|
||||||
|
// if that is the case, it means that the user had previously chosen next track `randomHistoryDirection` times and wants to go back,
|
||||||
|
// or that the user had previously chosen previous track `randomHistoryDirection` times and wants to go forward.
|
||||||
|
// in both cases, it means that we have a history of previous random selections that we can rewind.
|
||||||
|
if (randomHistoryDirection * direction < 0)
|
||||||
|
{
|
||||||
|
Debug.Assert(Math.Abs(randomHistoryDirection) == previousRandomSets.Count);
|
||||||
|
|
||||||
|
// if the user has been shuffling backwards and now going forwards (or vice versa),
|
||||||
|
// the topmost item from history needs to be discarded because it's the *current* track.
|
||||||
|
if (direction * lastRandomTrackDirection < 0)
|
||||||
{
|
{
|
||||||
notYetPlayedSets = possibleSets;
|
previousRandomSets.RemoveAt(previousRandomSets.Count - 1);
|
||||||
previousRandomSets.Clear();
|
randomHistoryDirection += direction;
|
||||||
randomHistoryDirection = 0;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
result = notYetPlayedSets[RNG.Next(notYetPlayedSets.Length)];
|
result = previousRandomSets[^1];
|
||||||
break;
|
previousRandomSets.RemoveAt(previousRandomSets.Count - 1);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
|
||||||
default:
|
// if the early-return above didn't cover it, it means that we have no history to fall back on
|
||||||
throw new ArgumentOutOfRangeException(nameof(randomSelectAlgorithm), randomSelectAlgorithm.Value, "Unsupported random select algorithm");
|
// and need to actually choose something random.
|
||||||
|
switch (randomSelectAlgorithm.Value)
|
||||||
|
{
|
||||||
|
case RandomSelectAlgorithm.Random:
|
||||||
|
result = possibleSets[RNG.Next(possibleSets.Length)];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case RandomSelectAlgorithm.RandomPermutation:
|
||||||
|
var notYetPlayedSets = possibleSets.Except(previousRandomSets).ToArray();
|
||||||
|
|
||||||
|
if (notYetPlayedSets.Length == 0)
|
||||||
|
{
|
||||||
|
notYetPlayedSets = possibleSets;
|
||||||
|
previousRandomSets.Clear();
|
||||||
|
randomHistoryDirection = 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
result = notYetPlayedSets[RNG.Next(notYetPlayedSets.Length)];
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(randomSelectAlgorithm), randomSelectAlgorithm.Value, "Unsupported random select algorithm");
|
||||||
|
}
|
||||||
|
|
||||||
|
previousRandomSets.Add(result);
|
||||||
|
return result;
|
||||||
|
}
|
||||||
|
finally
|
||||||
|
{
|
||||||
|
randomHistoryDirection += direction;
|
||||||
|
lastRandomTrackDirection = direction;
|
||||||
}
|
}
|
||||||
|
|
||||||
previousRandomSets.Add(result);
|
|
||||||
randomHistoryDirection += direction;
|
|
||||||
return result;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private void restartTrack()
|
private void restartTrack()
|
||||||
|
|
Loading…
Reference in New Issue