From d36f5fb96f34cf22d84902d425a8d17583472ce1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 27 Mar 2020 18:03:02 +0900 Subject: [PATCH 01/21] Fix animated follow points not (re)animating after rewind --- .../Drawables/Connections/FollowPoint.cs | 4 ++- .../Connections/FollowPointConnection.cs | 12 ++++----- osu.Game/Skinning/IAnimationTimeReference.cs | 25 +++++++++++++++++++ osu.Game/Skinning/LegacySkinExtensions.cs | 23 ++++++++++++++++- 4 files changed, 55 insertions(+), 9 deletions(-) create mode 100644 osu.Game/Skinning/IAnimationTimeReference.cs diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs index 7e530ca047..8bb324d02e 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections /// /// A single follow point positioned between two adjacent s. /// - public class FollowPoint : Container + public class FollowPoint : Container, IAnimationTimeReference { private const float width = 8; @@ -45,5 +45,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections } }, confineMode: ConfineMode.NoScaling); } + + public double AnimationStartTime { get; set; } } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs index d0935e46f7..6f09bbcd57 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointConnection.cs @@ -116,6 +116,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections int point = 0; + ClearInternal(); + for (int d = (int)(spacing * 1.5); d < distance - spacing; d += spacing) { float fraction = (float)d / distance; @@ -126,13 +128,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections FollowPoint fp; - if (InternalChildren.Count > point) - { - fp = (FollowPoint)InternalChildren[point]; - fp.ClearTransforms(); - } - else - AddInternal(fp = new FollowPoint()); + AddInternal(fp = new FollowPoint()); fp.Position = pointStartPosition; fp.Rotation = rotation; @@ -142,6 +138,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections if (firstTransformStartTime == null) firstTransformStartTime = fadeInTime; + fp.AnimationStartTime = fadeInTime; + using (fp.BeginAbsoluteSequence(fadeInTime)) { fp.FadeIn(osuEnd.TimeFadeIn); diff --git a/osu.Game/Skinning/IAnimationTimeReference.cs b/osu.Game/Skinning/IAnimationTimeReference.cs new file mode 100644 index 0000000000..bcff10a24b --- /dev/null +++ b/osu.Game/Skinning/IAnimationTimeReference.cs @@ -0,0 +1,25 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Timing; + +namespace osu.Game.Skinning +{ + /// + /// Denotes an object which provides a reference time to start animations from. + /// + [Cached] + public interface IAnimationTimeReference + { + /// + /// The reference clock. + /// + IFrameBasedClock Clock { get; } + + /// + /// The time which animations should be started from, relative to . + /// + double AnimationStartTime { get; } + } +} diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index 52328d43b2..8765b161d4 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -3,10 +3,12 @@ using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Framework.Timing; namespace osu.Game.Skinning { @@ -22,7 +24,7 @@ namespace osu.Game.Skinning if (textures.Length > 0) { - var animation = new TextureAnimation + var animation = new SkinnableTextureAnimation { DefaultFrameLength = getFrameLength(source, applyConfigFrameRate, textures), Repeat = looping, @@ -53,6 +55,25 @@ namespace osu.Game.Skinning } } + public class SkinnableTextureAnimation : TextureAnimation + { + [Resolved(canBeNull: true)] + private IAnimationTimeReference timeReference { get; set; } + + public SkinnableTextureAnimation() + : base(false) + { + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + if (timeReference != null) + Clock = new FramedOffsetClock(timeReference.Clock) { Offset = -timeReference.AnimationStartTime }; + } + } + private const double default_frame_time = 1000 / 60d; private static double getFrameLength(ISkin source, bool applyConfigFrameRate, Texture[] textures) From 6e68b968f8afba0ebd5824fda4a94b9495fbb055 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 29 Mar 2020 23:52:50 +0900 Subject: [PATCH 02/21] Hide "retry" button on results screen after watching a replay --- osu.Game/Screens/Play/ReplayPlayer.cs | 3 +++ osu.Game/Screens/Ranking/ResultsScreen.cs | 29 +++++++++++++++-------- 2 files changed, 22 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index 74c853340d..0d2ddb7b01 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.cs @@ -3,6 +3,7 @@ using osu.Framework.Screens; using osu.Game.Scoring; +using osu.Game.Screens.Ranking; namespace osu.Game.Screens.Play { @@ -29,6 +30,8 @@ namespace osu.Game.Screens.Play this.Push(CreateResults(DrawableRuleset.ReplayScore.ScoreInfo)); } + protected override ResultsScreen CreateResults(ScoreInfo score) => new ResultsScreen(score, false); + protected override ScoreInfo CreateScore() => score.ScoreInfo; } } diff --git a/osu.Game/Screens/Ranking/ResultsScreen.cs b/osu.Game/Screens/Ranking/ResultsScreen.cs index d063d8749f..1c08b763fe 100644 --- a/osu.Game/Screens/Ranking/ResultsScreen.cs +++ b/osu.Game/Screens/Ranking/ResultsScreen.cs @@ -33,16 +33,21 @@ namespace osu.Game.Screens.Ranking public readonly ScoreInfo Score; + private readonly bool allowRetry; + private Drawable bottomPanel; - public ResultsScreen(ScoreInfo score) + public ResultsScreen(ScoreInfo score, bool allowRetry = true) { Score = score; + this.allowRetry = allowRetry; } [BackgroundDependencyLoader] private void load() { + FillFlowContainer buttons; + InternalChildren = new[] { new ResultsScrollContainer @@ -68,7 +73,7 @@ namespace osu.Game.Screens.Ranking RelativeSizeAxes = Axes.Both, Colour = Color4Extensions.FromHex("#333") }, - new FillFlowContainer + buttons = new FillFlowContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -78,7 +83,6 @@ namespace osu.Game.Screens.Ranking Children = new Drawable[] { new ReplayDownloadButton(Score) { Width = 300 }, - new RetryButton { Width = 300 }, } } } @@ -87,15 +91,20 @@ namespace osu.Game.Screens.Ranking if (player != null) { - AddInternal(new HotkeyRetryOverlay + if (allowRetry) { - Action = () => - { - if (!this.IsCurrentScreen()) return; + buttons.Add(new RetryButton { Width = 300 }); - player?.Restart(); - }, - }); + AddInternal(new HotkeyRetryOverlay + { + Action = () => + { + if (!this.IsCurrentScreen()) return; + + player?.Restart(); + }, + }); + } } } From 09d860d5f5701edaaa292f0797774d6758123952 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 11:52:11 +0900 Subject: [PATCH 03/21] Fix imports with no matching beatmap IDs still retaining a potentially invalid set ID --- osu.Game/Beatmaps/BeatmapManager.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index abb3f8ac42..40ffb40f52 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -87,7 +87,7 @@ namespace osu.Game.Beatmaps protected override bool ShouldDeleteArchive(string path) => Path.GetExtension(path)?.ToLowerInvariant() == ".osz"; - protected override Task Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive, CancellationToken cancellationToken = default) + protected override async Task Populate(BeatmapSetInfo beatmapSet, ArchiveReader archive, CancellationToken cancellationToken = default) { if (archive != null) beatmapSet.Beatmaps = createBeatmapDifficulties(beatmapSet.Files); @@ -103,7 +103,11 @@ namespace osu.Game.Beatmaps validateOnlineIds(beatmapSet); - return updateQueue.UpdateAsync(beatmapSet, cancellationToken); + await updateQueue.UpdateAsync(beatmapSet, cancellationToken); + + // ensure at least one beatmap was able to retrieve an online ID, else drop the set ID. + if (!beatmapSet.Beatmaps.Any(b => b.OnlineBeatmapID > 0)) + beatmapSet.OnlineBeatmapSetID = null; } protected override void PreImport(BeatmapSetInfo beatmapSet) From 7ecce713bb736069be7f1037df45770482d6f349 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 15:05:40 +0900 Subject: [PATCH 04/21] Keep provided IDs where possible if not online --- osu.Game/Beatmaps/BeatmapManager.cs | 13 ++++++++----- osu.Game/Online/API/APIRequest.cs | 4 ++-- osu.Game/Online/API/Requests/GetRankingsRequest.cs | 3 ++- osu.Game/Online/API/Requests/PaginatedAPIRequest.cs | 2 +- 4 files changed, 13 insertions(+), 9 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 40ffb40f52..797a5160c9 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -451,12 +451,15 @@ namespace osu.Game.Beatmaps var res = req.Result; - beatmap.Status = res.Status; - beatmap.BeatmapSet.Status = res.BeatmapSet.Status; - beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID; - beatmap.OnlineBeatmapID = res.OnlineBeatmapID; + if (res != null) + { + beatmap.Status = res.Status; + beatmap.BeatmapSet.Status = res.BeatmapSet.Status; + beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID; + beatmap.OnlineBeatmapID = res.OnlineBeatmapID; - LogForModel(set, $"Online retrieval mapped {beatmap} to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}."); + LogForModel(set, $"Online retrieval mapped {beatmap} to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}."); + } } catch (Exception e) { diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index 30c1018c1e..6a6c7b72a8 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -12,11 +12,11 @@ namespace osu.Game.Online.API /// An API request with a well-defined response type. /// /// Type of the response (used for deserialisation). - public abstract class APIRequest : APIRequest + public abstract class APIRequest : APIRequest where T : class { protected override WebRequest CreateWebRequest() => new OsuJsonWebRequest(Uri); - public T Result => ((OsuJsonWebRequest)WebRequest).ResponseObject; + public T Result => ((OsuJsonWebRequest)WebRequest)?.ResponseObject; protected APIRequest() { diff --git a/osu.Game/Online/API/Requests/GetRankingsRequest.cs b/osu.Game/Online/API/Requests/GetRankingsRequest.cs index 941691c4c1..1bbaa73bbb 100644 --- a/osu.Game/Online/API/Requests/GetRankingsRequest.cs +++ b/osu.Game/Online/API/Requests/GetRankingsRequest.cs @@ -6,7 +6,8 @@ using osu.Game.Rulesets; namespace osu.Game.Online.API.Requests { - public abstract class GetRankingsRequest : APIRequest + public abstract class GetRankingsRequest : APIRequest where TModel : class + { private readonly RulesetInfo ruleset; private readonly int page; diff --git a/osu.Game/Online/API/Requests/PaginatedAPIRequest.cs b/osu.Game/Online/API/Requests/PaginatedAPIRequest.cs index 52e12f04ee..bddc34a0dc 100644 --- a/osu.Game/Online/API/Requests/PaginatedAPIRequest.cs +++ b/osu.Game/Online/API/Requests/PaginatedAPIRequest.cs @@ -6,7 +6,7 @@ using osu.Framework.IO.Network; namespace osu.Game.Online.API.Requests { - public abstract class PaginatedAPIRequest : APIRequest + public abstract class PaginatedAPIRequest : APIRequest where T : class { private readonly int page; private readonly int itemsPerPage; From f71c8cb30ff8c11084cc48bbe40fbfe437dbd089 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 15:07:56 +0900 Subject: [PATCH 05/21] Only drop online set ID if beatmap IDs were stripped in online retrieval --- osu.Game/Beatmaps/BeatmapManager.cs | 14 +++++++++++--- 1 file changed, 11 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 797a5160c9..6542866936 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -103,11 +103,19 @@ namespace osu.Game.Beatmaps validateOnlineIds(beatmapSet); + bool hadOnlineBeatmapIDs = beatmapSet.Beatmaps.Any(b => b.OnlineBeatmapID > 0); + await updateQueue.UpdateAsync(beatmapSet, cancellationToken); - // ensure at least one beatmap was able to retrieve an online ID, else drop the set ID. - if (!beatmapSet.Beatmaps.Any(b => b.OnlineBeatmapID > 0)) - beatmapSet.OnlineBeatmapSetID = null; + // ensure at least one beatmap was able to retrieve or keep an online ID, else drop the set ID. + if (hadOnlineBeatmapIDs && !beatmapSet.Beatmaps.Any(b => b.OnlineBeatmapID > 0)) + { + if (beatmapSet.OnlineBeatmapSetID != null) + { + beatmapSet.OnlineBeatmapSetID = null; + LogForModel(beatmapSet, "Disassociating beatmap set ID due to loss of all beatmap IDs"); + } + } } protected override void PreImport(BeatmapSetInfo beatmapSet) From 812583a4cd6e714626f0132a0351b62c1eea99db Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 16:17:42 +0900 Subject: [PATCH 06/21] Remove stray newline --- osu.Game/Online/API/Requests/GetRankingsRequest.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/GetRankingsRequest.cs b/osu.Game/Online/API/Requests/GetRankingsRequest.cs index 1bbaa73bbb..ddc3298ca7 100644 --- a/osu.Game/Online/API/Requests/GetRankingsRequest.cs +++ b/osu.Game/Online/API/Requests/GetRankingsRequest.cs @@ -7,7 +7,6 @@ using osu.Game.Rulesets; namespace osu.Game.Online.API.Requests { public abstract class GetRankingsRequest : APIRequest where TModel : class - { private readonly RulesetInfo ruleset; private readonly int page; From 0044d00d07111399bbd12f0f4350bcb13a288f9b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 16:53:23 +0900 Subject: [PATCH 07/21] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 7e17f9da16..fd2532257b 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 3894c06994..fdf9703d79 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9cc9792ecf..a286d1d460 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -71,7 +71,7 @@ - + @@ -79,7 +79,7 @@ - + From 4406f441654726dd21c810349b0eeb6935ba7d65 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 17:26:35 +0900 Subject: [PATCH 08/21] Remove osu!catch GotoFrame usage --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 5 ++++- osu.Game/Skinning/LegacySkinExtensions.cs | 2 ++ 2 files changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index e361b29a9d..bc0311bd2d 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -9,6 +9,7 @@ using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; +using osu.Framework.Timing; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; @@ -379,7 +380,9 @@ namespace osu.Game.Rulesets.Catch.UI } currentCatcher.Show(); - (currentCatcher.Drawable as IAnimation)?.GotoFrame(0); + + if (currentCatcher.Drawable.Clock is FramedOffsetClock offsetClock) + offsetClock.Offset = -Time.Current; } private void beginTrail() diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index 8765b161d4..de0add6ba3 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -71,6 +71,8 @@ namespace osu.Game.Skinning if (timeReference != null) Clock = new FramedOffsetClock(timeReference.Clock) { Offset = -timeReference.AnimationStartTime }; + else + Clock = new FramedOffsetClock(Clock); } } From 43367dbe35c313f70156d5ad31d9fe508c69ef01 Mon Sep 17 00:00:00 2001 From: "dependabot-preview[bot]" <27856297+dependabot-preview[bot]@users.noreply.github.com> Date: Mon, 30 Mar 2020 08:49:50 +0000 Subject: [PATCH 09/21] Bump Microsoft.Build.Traversal from 2.0.24 to 2.0.32 Bumps [Microsoft.Build.Traversal](https://github.com/Microsoft/MSBuildSdks) from 2.0.24 to 2.0.32. - [Release notes](https://github.com/Microsoft/MSBuildSdks/releases) - [Changelog](https://github.com/microsoft/MSBuildSdks/blob/master/RELEASE.md) - [Commits](https://github.com/Microsoft/MSBuildSdks/compare/Microsoft.Build.Traversal.2.0.24...Microsoft.Build.Traversal.2.0.32) Signed-off-by: dependabot-preview[bot] --- global.json | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/global.json b/global.json index 6858d4044d..0223dc7330 100644 --- a/global.json +++ b/global.json @@ -5,6 +5,6 @@ "version": "3.1.100" }, "msbuild-sdks": { - "Microsoft.Build.Traversal": "2.0.24" + "Microsoft.Build.Traversal": "2.0.32" } } \ No newline at end of file From 113660b6219b7729f28d35d0136a9d0634a59f61 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 30 Mar 2020 18:56:35 +0900 Subject: [PATCH 10/21] Merge if statements --- osu.Game/Screens/Ranking/ResultsScreen.cs | 21 +++++++++------------ 1 file changed, 9 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Ranking/ResultsScreen.cs b/osu.Game/Screens/Ranking/ResultsScreen.cs index 1c08b763fe..cfba1e6e3e 100644 --- a/osu.Game/Screens/Ranking/ResultsScreen.cs +++ b/osu.Game/Screens/Ranking/ResultsScreen.cs @@ -89,22 +89,19 @@ namespace osu.Game.Screens.Ranking } }; - if (player != null) + if (player != null && allowRetry) { - if (allowRetry) + buttons.Add(new RetryButton { Width = 300 }); + + AddInternal(new HotkeyRetryOverlay { - buttons.Add(new RetryButton { Width = 300 }); - - AddInternal(new HotkeyRetryOverlay + Action = () => { - Action = () => - { - if (!this.IsCurrentScreen()) return; + if (!this.IsCurrentScreen()) return; - player?.Restart(); - }, - }); - } + player?.Restart(); + }, + }); } } From f96229c572e812cf2f7fc99b9dee05f62faf9a36 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 30 Mar 2020 13:21:22 +0300 Subject: [PATCH 11/21] Add support for HitCircleOverlayAboveNumber legacy skin property --- osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs | 5 +++++ osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs | 3 ++- 2 files changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 38ba4c5974..0480449d05 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -80,6 +80,11 @@ namespace osu.Game.Rulesets.Osu.Skinning return tex ?? skin.GetTexture($"hitcircle{name}"); } + + bool overlayAboveNumber = skin.GetConfig(OsuSkinConfiguration.HitCircleOverlayAboveNumber)?.Value ?? true; + + if (!overlayAboveNumber) + ChangeInternalChildDepth(hitCircleText, -float.MaxValue); } private void updateState(ValueChangedEvent state) diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs index 5d99960f10..c6920bd03e 100644 --- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs +++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs @@ -11,6 +11,7 @@ namespace osu.Game.Rulesets.Osu.Skinning SliderPathRadius, AllowSliderBallTint, CursorExpand, - CursorRotate + CursorRotate, + HitCircleOverlayAboveNumber } } From 9890544b3692df822dcc97b25fdfad7cd800b0e5 Mon Sep 17 00:00:00 2001 From: Andrei Zavatski Date: Mon, 30 Mar 2020 13:42:18 +0300 Subject: [PATCH 12/21] Move implementation to better place --- .../Skinning/LegacyMainCirclePiece.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs index 0480449d05..e7486ef9b0 100644 --- a/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/LegacyMainCirclePiece.cs @@ -62,6 +62,11 @@ namespace osu.Game.Rulesets.Osu.Skinning } }; + bool overlayAboveNumber = skin.GetConfig(OsuSkinConfiguration.HitCircleOverlayAboveNumber)?.Value ?? true; + + if (!overlayAboveNumber) + ChangeInternalChildDepth(hitCircleText, -float.MaxValue); + state.BindTo(drawableObject.State); state.BindValueChanged(updateState, true); @@ -80,11 +85,6 @@ namespace osu.Game.Rulesets.Osu.Skinning return tex ?? skin.GetTexture($"hitcircle{name}"); } - - bool overlayAboveNumber = skin.GetConfig(OsuSkinConfiguration.HitCircleOverlayAboveNumber)?.Value ?? true; - - if (!overlayAboveNumber) - ChangeInternalChildDepth(hitCircleText, -float.MaxValue); } private void updateState(ValueChangedEvent state) From 522bbc1e9c4a84209531fb5538b5d9a2ad799445 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Mon, 30 Mar 2020 21:37:20 +0200 Subject: [PATCH 13/21] Support widescreen per-layer storyboard masking --- .../Drawables/DrawableStoryboard.cs | 2 +- .../Drawables/DrawableStoryboardLayer.cs | 33 ++++++++++++++----- 2 files changed, 26 insertions(+), 9 deletions(-) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index bc6e01a729..c4d796e30b 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -50,7 +50,7 @@ namespace osu.Game.Storyboards.Drawables AddInternal(Content = new Container { - Size = new Vector2(640, 480), + RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, Origin = Anchor.Centre, }); diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs index def4eed2ca..2ada83c3b4 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardLayer.cs @@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers; namespace osu.Game.Storyboards.Drawables { - public class DrawableStoryboardLayer : LifetimeManagementContainer + public class DrawableStoryboardLayer : CompositeDrawable { public StoryboardLayer Layer { get; } public bool Enabled; @@ -23,17 +23,34 @@ namespace osu.Game.Storyboards.Drawables Origin = Anchor.Centre; Enabled = layer.VisibleWhenPassing; Masking = layer.Masking; + + InternalChild = new LayerElementContainer(layer); } - [BackgroundDependencyLoader] - private void load(CancellationToken? cancellationToken) + private class LayerElementContainer : LifetimeManagementContainer { - foreach (var element in Layer.Elements) - { - cancellationToken?.ThrowIfCancellationRequested(); + private readonly StoryboardLayer storyboardLayer; - if (element.IsDrawable) - AddInternal(element.CreateDrawable()); + public LayerElementContainer(StoryboardLayer layer) + { + storyboardLayer = layer; + + Width = 640; + Height = 480; + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + } + + [BackgroundDependencyLoader] + private void load(CancellationToken? cancellationToken) + { + foreach (var element in storyboardLayer.Elements) + { + cancellationToken?.ThrowIfCancellationRequested(); + + if (element.IsDrawable) + AddInternal(element.CreateDrawable()); + } } } } From 6d4f9247ea5e36d163c05b5fecc4b84f6a0447fc Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 31 Mar 2020 11:49:18 +0900 Subject: [PATCH 14/21] Revert "Remove osu!catch GotoFrame usage" This reverts commit 4406f441654726dd21c810349b0eeb6935ba7d65. --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 5 +---- osu.Game/Skinning/LegacySkinExtensions.cs | 2 -- 2 files changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index bc0311bd2d..e361b29a9d 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -9,7 +9,6 @@ using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; using osu.Framework.Input.Bindings; -using osu.Framework.Timing; using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; @@ -380,9 +379,7 @@ namespace osu.Game.Rulesets.Catch.UI } currentCatcher.Show(); - - if (currentCatcher.Drawable.Clock is FramedOffsetClock offsetClock) - offsetClock.Offset = -Time.Current; + (currentCatcher.Drawable as IAnimation)?.GotoFrame(0); } private void beginTrail() diff --git a/osu.Game/Skinning/LegacySkinExtensions.cs b/osu.Game/Skinning/LegacySkinExtensions.cs index de0add6ba3..8765b161d4 100644 --- a/osu.Game/Skinning/LegacySkinExtensions.cs +++ b/osu.Game/Skinning/LegacySkinExtensions.cs @@ -71,8 +71,6 @@ namespace osu.Game.Skinning if (timeReference != null) Clock = new FramedOffsetClock(timeReference.Clock) { Offset = -timeReference.AnimationStartTime }; - else - Clock = new FramedOffsetClock(Clock); } } From 89d8bf9780cc18aa039e7ec21e54b4d650b36601 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 31 Mar 2020 13:46:20 +0900 Subject: [PATCH 15/21] Fix catcher test resources being at wrong dpi definition --- ...t-catcher-fail.png => fruit-catcher-fail@2x.png} | Bin ...t-catcher-kiai.png => fruit-catcher-kiai@2x.png} | Bin 2 files changed, 0 insertions(+), 0 deletions(-) rename osu.Game.Rulesets.Catch.Tests/Resources/special-skin/{fruit-catcher-fail.png => fruit-catcher-fail@2x.png} (100%) rename osu.Game.Rulesets.Catch.Tests/Resources/special-skin/{fruit-catcher-kiai.png => fruit-catcher-kiai@2x.png} (100%) diff --git a/osu.Game.Rulesets.Catch.Tests/Resources/special-skin/fruit-catcher-fail.png b/osu.Game.Rulesets.Catch.Tests/Resources/special-skin/fruit-catcher-fail@2x.png similarity index 100% rename from osu.Game.Rulesets.Catch.Tests/Resources/special-skin/fruit-catcher-fail.png rename to osu.Game.Rulesets.Catch.Tests/Resources/special-skin/fruit-catcher-fail@2x.png diff --git a/osu.Game.Rulesets.Catch.Tests/Resources/special-skin/fruit-catcher-kiai.png b/osu.Game.Rulesets.Catch.Tests/Resources/special-skin/fruit-catcher-kiai@2x.png similarity index 100% rename from osu.Game.Rulesets.Catch.Tests/Resources/special-skin/fruit-catcher-kiai.png rename to osu.Game.Rulesets.Catch.Tests/Resources/special-skin/fruit-catcher-kiai@2x.png From 75e43acb1abfc893394c929b708cb0fbbab1add9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 31 Mar 2020 15:10:15 +0900 Subject: [PATCH 16/21] Add a legacy element to help with texture fallbacks --- .../Skinning/LegacyManiaColumnElement.cs | 41 +++++++++++++++++++ 1 file changed, 41 insertions(+) create mode 100644 osu.Game.Rulesets.Mania/Skinning/LegacyManiaColumnElement.cs diff --git a/osu.Game.Rulesets.Mania/Skinning/LegacyManiaColumnElement.cs b/osu.Game.Rulesets.Mania/Skinning/LegacyManiaColumnElement.cs new file mode 100644 index 0000000000..231a55a7e2 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Skinning/LegacyManiaColumnElement.cs @@ -0,0 +1,41 @@ +// 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 JetBrains.Annotations; +using osu.Framework.Allocation; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Mania.UI; + +namespace osu.Game.Rulesets.Mania.Skinning +{ + /// + /// A which is placed somewhere within a . + /// + public class LegacyManiaColumnElement : CompositeDrawable + { + [Resolved(CanBeNull = true)] + [CanBeNull] + protected ManiaStage Stage { get; private set; } + + [Resolved] + protected Column Column { get; private set; } + + /// + /// The column index to use for texture lookups, in the case of no user-provided configuration. + /// + protected int FallbackColumnIndex { get; private set; } + + [BackgroundDependencyLoader] + private void load() + { + if (Stage == null) + FallbackColumnIndex = Column.Index % 2 + 1; + else + { + int dist = Math.Min(Column.Index, Stage.Columns.Count - Column.Index - 1); + FallbackColumnIndex = dist % 2 + 1; + } + } + } +} From 8a998d600d13ae64d1e838deae92b7f432d30e56 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 31 Mar 2020 15:17:27 +0900 Subject: [PATCH 17/21] Fix relax mod pressing too many keys --- osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs index 6286c80d7c..9b0759d9d2 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.Osu.Mods void handleHitCircle(DrawableHitCircle circle) { - if (!circle.IsHovered) + if (!circle.HitArea.IsHovered) return; Debug.Assert(circle.HitObject.HitWindows != null); From bf1fc9f7a035acf9003acb3ac6b2e36a10873002 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 31 Mar 2020 15:18:50 +0900 Subject: [PATCH 18/21] Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index fd2532257b..6db4220fad 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,6 +52,6 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fdf9703d79..4163044273 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,7 +23,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index a286d1d460..17430e4b25 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -71,7 +71,7 @@ - + @@ -79,7 +79,7 @@ - + From 9602ab17b0c32fd6f4c30ba0e72f373f8c88bb92 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 31 Mar 2020 17:13:42 +0900 Subject: [PATCH 19/21] Fix replay imports failing for certain mod combinations --- osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs | 9 +++++++-- 1 file changed, 7 insertions(+), 2 deletions(-) diff --git a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs index c356dd246d..a4a560c8e4 100644 --- a/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs +++ b/osu.Game/Scoring/Legacy/LegacyScoreDecoder.cs @@ -28,10 +28,11 @@ namespace osu.Game.Scoring.Legacy { var score = new Score { - ScoreInfo = new ScoreInfo(), Replay = new Replay() }; + WorkingBeatmap workingBeatmap; + using (SerializationReader sr = new SerializationReader(stream)) { currentRuleset = GetRuleset(sr.ReadByte()); @@ -41,7 +42,7 @@ namespace osu.Game.Scoring.Legacy var version = sr.ReadInt32(); - var workingBeatmap = GetBeatmap(sr.ReadString()); + workingBeatmap = GetBeatmap(sr.ReadString()); if (workingBeatmap is DummyWorkingBeatmap) throw new BeatmapNotFoundException(); @@ -113,6 +114,10 @@ namespace osu.Game.Scoring.Legacy CalculateAccuracy(score.ScoreInfo); + // before returning for database import, we must restore the database-sourced BeatmapInfo. + // if not, the clone operation in GetPlayableBeatmap will cause a dereference and subsequent database exception. + score.ScoreInfo.Beatmap = workingBeatmap.BeatmapInfo; + return score; } From b7d73f96eaf24ab49f4d67f0903fd768f1dcf577 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 31 Mar 2020 18:33:00 +0900 Subject: [PATCH 20/21] Fix osu!catch catcher hit area being too large --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 8fa9c61b6f..13935e036b 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -37,10 +37,15 @@ namespace osu.Game.Rulesets.Catch.UI public CatcherAnimationState CurrentState { get; private set; } + /// + /// The width of the catcher which can receive fruit. Equivalent to "catchMargin" in osu-stable. + /// + private const float allowed_catch_range = 0.8f; + /// /// Width of the area that can be used to attempt catches during gameplay. /// - internal float CatchWidth => CatcherArea.CATCHER_SIZE * Math.Abs(Scale.X); + internal float CatchWidth => CatcherArea.CATCHER_SIZE * Math.Abs(Scale.X) * allowed_catch_range; protected bool Dashing { From 03b90fe2dbed5a7851e4a689e42edcc86968970c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 31 Mar 2020 19:01:49 +0900 Subject: [PATCH 21/21] Remove local application of same margin in CatchDifficultyCalculator --- .../Difficulty/CatchDifficultyCalculator.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs index 5880a227c2..4d9dbbbc5f 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs @@ -72,10 +72,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty protected override Skill[] CreateSkills(IBeatmap beatmap) { using (var catcher = new Catcher(beatmap.BeatmapInfo.BaseDifficulty)) - { halfCatcherWidth = catcher.CatchWidth * 0.5f; - halfCatcherWidth *= 0.8f; // We're only using 80% of the catcher's width to simulate imperfect gameplay. - } return new Skill[] {