diff --git a/osu.Game/Screens/Play/FailOverlay.cs b/osu.Game/Screens/Play/FailOverlay.cs index 1b9d81d33b..881791271b 100644 --- a/osu.Game/Screens/Play/FailOverlay.cs +++ b/osu.Game/Screens/Play/FailOverlay.cs @@ -5,8 +5,14 @@ using System; using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; +using osuTK; using osuTK.Graphics; using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; namespace osu.Game.Screens.Play { @@ -21,7 +27,41 @@ private void load(OsuColour colours) { AddButton("Retry", colours.YellowDark, () => OnRetry?.Invoke()); AddButton("Quit", new Color4(170, 27, 39, 255), () => OnQuit?.Invoke()); - AddButton("Save replay and Quit", colours.Blue, () => SaveReplay?.Invoke()); + // from #10339 maybe this is a better visual effect + Add(new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Height = TwoLayerButton.SIZE_EXTENDED.Y, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4Extensions.FromHex("#333") + }, + new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Spacing = new Vector2(5), + Padding = new MarginPadding(10), + Direction = FillDirection.Horizontal, + Children = new Drawable[] + { + new SaveFailedScoreButton() + { + OnSave = SaveReplay, + RelativeSizeAxes = Axes.Y, + Width = 300 + }, + } + } + } + }); } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index d38c10c071..8223ed1e3d 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -266,7 +266,7 @@ private void load(AudioManager audio, OsuConfigManager config, OsuGameBase game, }, FailOverlay = new FailOverlay { - SaveReplay = saveReplay, + SaveReplay = saveFailedReplay, OnRetry = Restart, OnQuit = () => PerformExit(true), }, @@ -1024,8 +1024,7 @@ public override bool OnExiting(ScreenExitEvent e) if (prepareScoreForDisplayTask == null) { Score.ScoreInfo.Passed = false; - // potentially should be ScoreRank.F instead? this is the best alternative for now. - Score.ScoreInfo.Rank = ScoreRank.D; + Score.ScoreInfo.Rank = ScoreRank.F; } // EndPlaying() is typically called from ReplayRecorder.Dispose(). Disposal is currently asynchronous. @@ -1044,20 +1043,20 @@ public override bool OnExiting(ScreenExitEvent e) return base.OnExiting(e); } - private void saveReplay() + private async void saveFailedReplay() { + Score.ScoreInfo.Passed = false; + Score.ScoreInfo.Rank = ScoreRank.F; var scoreCopy = Score.DeepClone(); try { - ImportScore(scoreCopy).ConfigureAwait(false); + await ImportScore(scoreCopy).ConfigureAwait(false); } catch (Exception ex) { Logger.Error(ex, @"Score import failed!"); } - - PerformExit(true); } /// diff --git a/osu.Game/Screens/Play/SaveFailedScoreButton.cs b/osu.Game/Screens/Play/SaveFailedScoreButton.cs new file mode 100644 index 0000000000..1c198421ab --- /dev/null +++ b/osu.Game/Screens/Play/SaveFailedScoreButton.cs @@ -0,0 +1,45 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Game.Graphics.UserInterface; +using osu.Game.Online; + +namespace osu.Game.Screens.Play +{ + public class SaveFailedScoreButton : DownloadButton + { + public Action? OnSave; + + [BackgroundDependencyLoader] + private void load() + { + State.BindValueChanged(updateTooltip, true); + Action = saveScore; + } + + private void saveScore() + { + if (State.Value != DownloadState.LocallyAvailable) + OnSave?.Invoke(); + + State.Value = DownloadState.LocallyAvailable; + } + + private void updateTooltip(ValueChangedEvent state) + { + switch (state.NewValue) + { + case DownloadState.LocallyAvailable: + TooltipText = @"Score saved"; + break; + + default: + TooltipText = @"Save score"; + break; + } + } + } +}