diff --git a/osu.Game/Localisation/PlayerLoaderStrings.cs b/osu.Game/Localisation/PlayerLoaderStrings.cs index f9d6f80676..8b429de873 100644 --- a/osu.Game/Localisation/PlayerLoaderStrings.cs +++ b/osu.Game/Localisation/PlayerLoaderStrings.cs @@ -43,6 +43,11 @@ Leaderboards may be reset."); public static LocalisableString QualifiedBeatmapDisclaimerContent => new TranslatableString(getKey(@"qualified_beatmap_disclaimer_content"), @"No performance points will be awarded. Leaderboards will be reset when the beatmap is ranked."); + /// + /// "Loading paused..." + /// + public static LocalisableString LoadingPaused => new TranslatableString(getKey(@"loading_paused"), @"Loading paused..."); + private static string getKey(string key) => $@"{prefix}:{key}"; } } diff --git a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs index f1df01b743..8e82cce0aa 100644 --- a/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs +++ b/osu.Game/Screens/Play/BeatmapMetadataDisplay.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Game.Beatmaps; @@ -15,6 +16,7 @@ using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; +using osu.Game.Localisation; using osu.Game.Resources.Localisation.Web; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play.HUD; @@ -32,6 +34,7 @@ namespace osu.Game.Screens.Play private readonly Bindable> mods; private readonly Drawable logoFacade; private LoadingSpinner loading; + private Drawable blockingLoadLayer; public IBindable> Mods => mods; @@ -46,6 +49,35 @@ namespace osu.Game.Screens.Play } } + private bool userBlocked; + + public bool UserBlocked + { + set + { + if (value == userBlocked) + return; + + userBlocked = value; + + if (userBlocked) + { + using (BeginDelayedSequence(500)) + { + blockingLoadLayer + // Slight delay to avoid this flashing briefly during multiplayer load and other scenarios where + // load may be blocked for a short period. + .FadeIn(300, Easing.Out) + .Then() + .FadeTo(0.6f, 1000, Easing.In) + .Loop(); + } + } + else + blockingLoadLayer.FadeOut(500, Easing.OutQuint); + } + } + public BeatmapMetadataDisplay(IWorkingBeatmap beatmap, Bindable> mods, Drawable logoFacade) { this.beatmap = beatmap; @@ -61,7 +93,7 @@ namespace osu.Game.Screens.Play private StarRatingDisplay starRatingDisplay; [BackgroundDependencyLoader] - private void load(BeatmapDifficultyCache difficultyCache) + private void load(BeatmapDifficultyCache difficultyCache, OsuColour colours) { var metadata = beatmap.BeatmapInfo.Metadata; @@ -117,7 +149,28 @@ namespace osu.Game.Screens.Play loading = new LoadingLayer(dimBackground: true) { BlockPositionalInput = false, - } + }, + blockingLoadLayer = new Container + { + RelativeSizeAxes = Axes.Both, + Alpha = 0, + Children = new Drawable[] + { + new Box + { + Colour = colours.PinkDarker, + Alpha = 0.5f, + RelativeSizeAxes = Axes.Both, + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = OsuFont.Style.Heading2, + Text = PlayerLoaderStrings.LoadingPaused + } + } + }, } }, versionFlow = new FillFlowContainer diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index d082ce6a57..d15b1a5a82 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -120,13 +120,6 @@ namespace osu.Game.Screens.Play } } - private bool readyForPush => - !playerConsumed - // don't push unless the player is completely loaded - && CurrentPlayer?.LoadState == LoadState.Ready - // don't push unless the player is ready to start gameplay - && ReadyForGameplay; - protected virtual bool ReadyForGameplay => // not ready if the user is hovering one of the panes (logo is excluded), unless they are idle. (IsHovered || osuLogo?.IsHovered == true || idleTracker.IsIdle.Value) @@ -490,6 +483,8 @@ namespace osu.Game.Screens.Play if (!this.IsCurrentScreen()) return; + MetadataInfo.UserBlocked = !ReadyForGameplay && CurrentPlayer?.LoadState == LoadState.Ready; + // We need to perform this check here rather than in OnHover as any number of children of VisualSettings // may also be handling the hover events. if (inputManager.HoveredDrawables.Contains(VisualSettings) || QuickRestart) @@ -654,6 +649,13 @@ namespace osu.Game.Screens.Play if (!this.IsCurrentScreen()) return; + bool readyForPush = + !playerConsumed + // don't push unless the player is completely loaded + && CurrentPlayer?.LoadState == LoadState.Ready + // don't push unless the player is ready to start gameplay + && ReadyForGameplay; + if (!readyForPush) { // as the pushDebounce below has a delay, we need to keep checking and cancel a future debounce