diff --git a/osu.Game/Localisation/DefaultRankDisplayStrings.cs b/osu.Game/Localisation/DefaultRankDisplayStrings.cs index 88e3b4309ab3..bd7b262ad5b6 100644 --- a/osu.Game/Localisation/DefaultRankDisplayStrings.cs +++ b/osu.Game/Localisation/DefaultRankDisplayStrings.cs @@ -16,4 +16,4 @@ public static class DefaultRankDisplayStrings private static string getKey(string key) => $@"{prefix}:{key}"; } -} \ No newline at end of file +} diff --git a/osu.Game/Screens/Play/HUD/DefaultRankDisplay.cs b/osu.Game/Screens/Play/HUD/DefaultRankDisplay.cs index d768fedca40d..cc4eb7d9fe8a 100644 --- a/osu.Game/Screens/Play/HUD/DefaultRankDisplay.cs +++ b/osu.Game/Screens/Play/HUD/DefaultRankDisplay.cs @@ -27,16 +27,24 @@ public partial class DefaultRankDisplay : CompositeDrawable, ISerialisableDrawab [SettingSource(typeof(DefaultRankDisplayStrings), nameof(DefaultRankDisplayStrings.PlaySamplesOnRankChange))] public BindableBool PlaySamples { get; set; } = new BindableBool(true); + [SettingSource(typeof(GameplaySettingsStrings), nameof(GameplaySettingsStrings.HideDuringGameplay))] + public BindableBool HideDuringGameplay { get; set; } = new BindableBool(); + private UpdateableRank rankDisplay = null!; private SkinnableSound rankDownSample = null!; private SkinnableSound rankUpSample = null!; private Bindable lastSamplePlayback = null!; + private readonly IBindable userPlayingState = new Bindable(); + private readonly IBindable holdingForHUD = new Bindable(); private double lastChangeTime; + private bool lastHiddenStatus; private ScoreRank? displayedRank; + private bool isHidden => HideDuringGameplay.Value && userPlayingState.Value == LocalUserPlayingState.Playing && !holdingForHUD.Value; + private const int time_between_changes = 1500; public DefaultRankDisplay() @@ -45,7 +53,7 @@ public DefaultRankDisplay() } [BackgroundDependencyLoader] - private void load(SkinEditor? skinEditor, SessionStatics statics) + private void load(SkinEditor? skinEditor, SessionStatics statics, GameplayState? gameplayState, HUDOverlay? hudOverlay) { InternalChildren = new Drawable[] { @@ -61,6 +69,12 @@ private void load(SkinEditor? skinEditor, SessionStatics statics) PlaySamples.Value = false; lastSamplePlayback = statics.GetBindable(Static.LastRankChangeSamplePlaybackTime); + + if (gameplayState != null) + userPlayingState.BindTo(gameplayState.PlayingState); + + if (hudOverlay != null) + holdingForHUD.BindTo(hudOverlay.HoldingForHUD); } protected override void LoadComplete() @@ -76,6 +90,10 @@ protected override void Update() var currentRank = scoreProcessor.Rank.Value; + bool currentHiddenStatus = isHidden; + if (currentHiddenStatus != lastHiddenStatus) + updateDisplayStatus(currentHiddenStatus); + if (currentRank == displayedRank) return; @@ -83,6 +101,12 @@ protected override void Update() updateRank(currentRank); } + private void updateDisplayStatus(bool currentHiddenStatus) + { + rankDisplay.Alpha = currentHiddenStatus ? 0 : 1; + lastHiddenStatus = currentHiddenStatus; + } + private void updateRank(ScoreRank rank) { rankDisplay.Rank = rank; @@ -90,8 +114,8 @@ private void updateRank(ScoreRank rank) // Check sample time separately to ensure two copies of the rank display don't both play samples on a change. bool enoughSampleTimeElapsed = !lastSamplePlayback.Value.HasValue || Time.Current - lastSamplePlayback.Value >= OsuGameBase.SAMPLE_DEBOUNCE_TIME; - // Also don't play rank-down sfx on quit/retry/initial update. - if (displayedRank != null && rank > ScoreRank.F && PlaySamples.Value && enoughSampleTimeElapsed) + // Also don't play rank-down sfx on quit/retry/initial update or being hidden. + if (displayedRank != null && rank > ScoreRank.F && PlaySamples.Value && enoughSampleTimeElapsed && !isHidden) { if (rank > displayedRank) rankUpSample.Play(); diff --git a/osu.Game/Skinning/LegacyRankDisplay.cs b/osu.Game/Skinning/LegacyRankDisplay.cs index 64376f0dbdb9..c169f4a906b2 100644 --- a/osu.Game/Skinning/LegacyRankDisplay.cs +++ b/osu.Game/Skinning/LegacyRankDisplay.cs @@ -12,6 +12,7 @@ using osu.Game.Overlays.SkinEditor; using osu.Game.Rulesets.Scoring; using osu.Game.Scoring; +using osu.Game.Screens.Play; using osuTK; namespace osu.Game.Skinning @@ -29,16 +30,24 @@ public partial class LegacyRankDisplay : CompositeDrawable, ISerialisableDrawabl [SettingSource(typeof(DefaultRankDisplayStrings), nameof(DefaultRankDisplayStrings.PlaySamplesOnRankChange))] public BindableBool PlaySamples { get; set; } = new BindableBool(true); + [SettingSource(typeof(GameplaySettingsStrings), nameof(GameplaySettingsStrings.HideDuringGameplay))] + public BindableBool HideDuringGameplay { get; set; } = new BindableBool(); + private readonly Sprite rankDisplay; private SkinnableSound rankDownSample = null!; private SkinnableSound rankUpSample = null!; private Bindable lastSamplePlayback = null!; + private readonly IBindable userPlayingState = new Bindable(); + private readonly IBindable holdingForHUD = new Bindable(); private double lastChangeTime; + private bool lastHiddenStatus; private ScoreRank? displayedRank; + private bool isHidden => HideDuringGameplay.Value && userPlayingState.Value == LocalUserPlayingState.Playing && !holdingForHUD.Value; + private const int time_between_changes = 1500; public LegacyRankDisplay() @@ -53,7 +62,7 @@ public LegacyRankDisplay() } [BackgroundDependencyLoader] - private void load(SkinEditor? skinEditor, SessionStatics statics) + private void load(SkinEditor? skinEditor, SessionStatics statics, GameplayState? gameplayState, HUDOverlay? hudOverlay) { AddRangeInternal(new Drawable[] { @@ -65,6 +74,12 @@ private void load(SkinEditor? skinEditor, SessionStatics statics) PlaySamples.Value = false; lastSamplePlayback = statics.GetBindable(Static.LastRankChangeSamplePlaybackTime); + + if (gameplayState != null) + userPlayingState.BindTo(gameplayState.PlayingState); + + if (hudOverlay != null) + holdingForHUD.BindTo(hudOverlay.HoldingForHUD); } protected override void LoadComplete() @@ -80,6 +95,10 @@ protected override void Update() var currentRank = scoreProcessor.Rank.Value; + bool currentHiddenStatus = isHidden; + if (currentHiddenStatus != lastHiddenStatus) + updateDisplayStatus(currentHiddenStatus); + if (currentRank == displayedRank) return; @@ -87,13 +106,19 @@ protected override void Update() updateRank(currentRank); } + private void updateDisplayStatus(bool currentHiddenStatus) + { + rankDisplay.Alpha = currentHiddenStatus ? 0 : 1; + lastHiddenStatus = currentHiddenStatus; + } + private void updateRank(ScoreRank rank) { var texture = source.GetTexture($"ranking-{rank}-small"); rankDisplay.Texture = texture; - if (texture != null && displayedRank != null) + if (texture != null && displayedRank != null && !isHidden) { var transientRank = new Sprite { @@ -114,8 +139,8 @@ private void updateRank(ScoreRank rank) // Check sample time separately to ensure two copies of the rank display don't both play samples on a change. bool enoughSampleTimeElapsed = !lastSamplePlayback.Value.HasValue || Time.Current - lastSamplePlayback.Value >= OsuGameBase.SAMPLE_DEBOUNCE_TIME; - // Also don't play rank-down sfx on quit/retry/initial update. - if (displayedRank != null && rank > ScoreRank.F && PlaySamples.Value && enoughSampleTimeElapsed) + // Also don't play rank-down sfx on quit/retry/initial update or being hidden. + if (displayedRank != null && rank > ScoreRank.F && PlaySamples.Value && enoughSampleTimeElapsed && !isHidden) { if (rank > displayedRank) rankUpSample.Play();