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