Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion osu.Game/Localisation/DefaultRankDisplayStrings.cs
Original file line number Diff line number Diff line change
Expand Up @@ -16,4 +16,4 @@ public static class DefaultRankDisplayStrings

private static string getKey(string key) => $@"{prefix}:{key}";
}
}
}
30 changes: 27 additions & 3 deletions osu.Game/Screens/Play/HUD/DefaultRankDisplay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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<double?> lastSamplePlayback = null!;
private readonly IBindable<LocalUserPlayingState> userPlayingState = new Bindable<LocalUserPlayingState>();
private readonly IBindable<bool> holdingForHUD = new Bindable<bool>();
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()
Expand All @@ -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[]
{
Expand All @@ -61,6 +69,12 @@ private void load(SkinEditor? skinEditor, SessionStatics statics)
PlaySamples.Value = false;

lastSamplePlayback = statics.GetBindable<double?>(Static.LastRankChangeSamplePlaybackTime);

if (gameplayState != null)
userPlayingState.BindTo(gameplayState.PlayingState);

if (hudOverlay != null)
holdingForHUD.BindTo(hudOverlay.HoldingForHUD);
}

protected override void LoadComplete()
Expand All @@ -76,22 +90,32 @@ protected override void Update()

var currentRank = scoreProcessor.Rank.Value;

bool currentHiddenStatus = isHidden;
if (currentHiddenStatus != lastHiddenStatus)
updateDisplayStatus(currentHiddenStatus);

if (currentRank == displayedRank)
return;

if (Time.Current - lastChangeTime >= time_between_changes || scoreProcessor.HasCompleted.Value || currentRank == ScoreRank.F)
updateRank(currentRank);
}

private void updateDisplayStatus(bool currentHiddenStatus)
{
rankDisplay.Alpha = currentHiddenStatus ? 0 : 1;
lastHiddenStatus = currentHiddenStatus;
}

private void updateRank(ScoreRank rank)
{
rankDisplay.Rank = 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();
Expand Down
33 changes: 29 additions & 4 deletions osu.Game/Skinning/LegacyRankDisplay.cs
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand All @@ -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<double?> lastSamplePlayback = null!;
private readonly IBindable<LocalUserPlayingState> userPlayingState = new Bindable<LocalUserPlayingState>();
private readonly IBindable<bool> holdingForHUD = new Bindable<bool>();
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()
Expand All @@ -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[]
{
Expand All @@ -65,6 +74,12 @@ private void load(SkinEditor? skinEditor, SessionStatics statics)
PlaySamples.Value = false;

lastSamplePlayback = statics.GetBindable<double?>(Static.LastRankChangeSamplePlaybackTime);

if (gameplayState != null)
userPlayingState.BindTo(gameplayState.PlayingState);

if (hudOverlay != null)
holdingForHUD.BindTo(hudOverlay.HoldingForHUD);
}

protected override void LoadComplete()
Expand All @@ -80,20 +95,30 @@ protected override void Update()

var currentRank = scoreProcessor.Rank.Value;

bool currentHiddenStatus = isHidden;
if (currentHiddenStatus != lastHiddenStatus)
updateDisplayStatus(currentHiddenStatus);

if (currentRank == displayedRank)
return;

if (Time.Current - lastChangeTime >= time_between_changes || scoreProcessor.HasCompleted.Value || currentRank == ScoreRank.F)
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
{
Expand All @@ -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();
Expand Down
Loading