Merge branch 'master' into kps

This commit is contained in:
Dean Herbert
2022-08-20 15:24:58 +09:00
committed by GitHub
398 changed files with 5993 additions and 2636 deletions

View File

@ -26,7 +26,6 @@ using osu.Game.Extensions;
using osu.Game.Graphics.Containers;
using osu.Game.IO.Archives;
using osu.Game.Online.API;
using osu.Game.Online.Spectator;
using osu.Game.Overlays;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
@ -78,7 +77,7 @@ namespace osu.Game.Screens.Play
/// </summary>
protected virtual bool PauseOnFocusLost => true;
public Action RestartRequested;
public Action<bool> RestartRequested;
private bool isRestarting;
@ -101,9 +100,6 @@ namespace osu.Game.Screens.Play
[Resolved]
private MusicController musicController { get; set; }
[Resolved]
private SpectatorClient spectatorClient { get; set; }
public GameplayState GameplayState { get; private set; }
private Ruleset ruleset;
@ -253,6 +249,9 @@ namespace osu.Game.Screens.Play
// this is intentionally done in two stages to ensure things are in a loaded state before exposing the ruleset to skin sources.
GameplayClockContainer.Add(rulesetSkinProvider);
if (cancellationToken.IsCancellationRequested)
return;
rulesetSkinProvider.AddRange(new Drawable[]
{
failAnimationLayer = new FailAnimation(DrawableRuleset)
@ -268,7 +267,7 @@ namespace osu.Game.Screens.Play
FailOverlay = new FailOverlay
{
SaveReplay = prepareAndImportScore,
OnRetry = Restart,
OnRetry = () => Restart(),
OnQuit = () => PerformExit(true),
},
new HotkeyExitOverlay
@ -283,6 +282,9 @@ namespace osu.Game.Screens.Play
},
});
if (cancellationToken.IsCancellationRequested)
return;
if (Configuration.AllowRestart)
{
rulesetSkinProvider.Add(new HotkeyRetryOverlay
@ -292,7 +294,7 @@ namespace osu.Game.Screens.Play
if (!this.IsCurrentScreen()) return;
fadeOut(true);
Restart();
Restart(true);
},
});
}
@ -328,7 +330,7 @@ namespace osu.Game.Screens.Play
DrawableRuleset.HasReplayLoaded.BindValueChanged(_ => updateGameplayState());
// bind clock into components that require it
DrawableRuleset.IsPaused.BindTo(GameplayClockContainer.IsPaused);
((IBindable<bool>)DrawableRuleset.IsPaused).BindTo(GameplayClockContainer.IsPaused);
DrawableRuleset.NewResult += r =>
{
@ -369,6 +371,9 @@ namespace osu.Game.Screens.Play
IsBreakTime.BindTo(breakTracker.IsBreakTime);
IsBreakTime.BindValueChanged(onBreakTimeChanged, true);
if (Configuration.AutomaticallySkipIntro)
skipIntroOverlay.SkipWhenReady();
}
protected virtual GameplayClockContainer CreateGameplayClockContainer(WorkingBeatmap beatmap, double gameplayStart) => new MasterGameplayClockContainer(beatmap, gameplayStart);
@ -439,7 +444,7 @@ namespace osu.Game.Screens.Play
{
OnResume = Resume,
Retries = RestartCount,
OnRetry = Restart,
OnRetry = () => Restart(),
OnQuit = () => PerformExit(true),
},
},
@ -473,7 +478,7 @@ namespace osu.Game.Screens.Play
private void updateSampleDisabledState()
{
samplePlaybackDisabled.Value = DrawableRuleset.FrameStableClock.IsCatchingUp.Value || GameplayClockContainer.GameplayClock.IsPaused.Value;
samplePlaybackDisabled.Value = DrawableRuleset.FrameStableClock.IsCatchingUp.Value || GameplayClockContainer.IsPaused.Value;
}
private void updatePauseOnFocusLostState()
@ -646,7 +651,8 @@ namespace osu.Game.Screens.Play
/// Restart gameplay via a parent <see cref="PlayerLoader"/>.
/// <remarks>This can be called from a child screen in order to trigger the restart process.</remarks>
/// </summary>
public void Restart()
/// <param name="quickRestart">Whether a quick restart was requested (skipping intro etc.).</param>
public void Restart(bool quickRestart = false)
{
if (!Configuration.AllowRestart)
return;
@ -658,7 +664,7 @@ namespace osu.Game.Screens.Play
musicController.Stop();
sampleRestart?.Play();
RestartRequested?.Invoke();
RestartRequested?.Invoke(quickRestart);
PerformExit(false);
}
@ -838,7 +844,7 @@ namespace osu.Game.Screens.Play
failAnimationLayer.Start();
if (GameplayState.Mods.OfType<IApplicableFailOverride>().Any(m => m.RestartOnFail))
Restart();
Restart(true);
return true;
}
@ -875,7 +881,7 @@ namespace osu.Game.Screens.Play
private double? lastPauseActionTime;
protected bool PauseCooldownActive =>
lastPauseActionTime.HasValue && GameplayClockContainer.GameplayClock.CurrentTime < lastPauseActionTime + pause_cooldown;
lastPauseActionTime.HasValue && GameplayClockContainer.CurrentTime < lastPauseActionTime + pause_cooldown;
/// <summary>
/// A set of conditionals which defines whether the current game state and configuration allows for
@ -913,7 +919,7 @@ namespace osu.Game.Screens.Play
GameplayClockContainer.Stop();
PauseOverlay.Show();
lastPauseActionTime = GameplayClockContainer.GameplayClock.CurrentTime;
lastPauseActionTime = GameplayClockContainer.CurrentTime;
return true;
}
@ -1003,7 +1009,7 @@ namespace osu.Game.Screens.Play
/// </summary>
protected virtual void StartGameplay()
{
if (GameplayClockContainer.GameplayClock.IsRunning)
if (GameplayClockContainer.IsRunning)
throw new InvalidOperationException($"{nameof(StartGameplay)} should not be called when the gameplay clock is already running");
GameplayClockContainer.Reset(true);
@ -1030,11 +1036,6 @@ namespace osu.Game.Screens.Play
// if arriving here and the results screen preparation task hasn't run, it's safe to say the user has not completed the beatmap.
if (prepareScoreForDisplayTask == null)
ScoreProcessor.FailScore(Score.ScoreInfo);
// EndPlaying() is typically called from ReplayRecorder.Dispose(). Disposal is currently asynchronous.
// To resolve test failures, forcefully end playing synchronously when this screen exits.
// Todo: Replace this with a more permanent solution once osu-framework has a synchronous cleanup method.
spectatorClient.EndPlaying(GameplayState);
}
// GameplayClockContainer performs seeks / start / stop operations on the beatmap's track.