From 58dbc63c6e85fecf9f13aea709e1397bd790161b Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Sun, 8 Apr 2018 15:24:34 +0200 Subject: [PATCH 01/40] Add HardRock position mangling for CatchTheBeat --- .../Mods/CatchModHardRock.cs | 77 ++++++++++++++++++- 1 file changed, 76 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs index ed33bf7124..5dadec9b15 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs @@ -1,13 +1,88 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.MathUtils; +using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Mods; +using System; namespace osu.Game.Rulesets.Catch.Mods { - public class CatchModHardRock : ModHardRock + public class CatchModHardRock : ModHardRock, IApplicableToHitObject { public override double ScoreMultiplier => 1.12; public override bool Ranked => true; + + private float lastStartX; + private int lastStartTime; + + public void ApplyToHitObject(CatchHitObject hitObject) + { + // Code from Stable, we keep calculation on a scale of 0 to 512 + float position = hitObject.X * 512; + int startTime = (int)hitObject.StartTime; + + if (lastStartX == 0) + { + lastStartX = position; + lastStartTime = startTime; + return; + } + + float diff = lastStartX - position; + int timeDiff = startTime - lastStartTime; + + if (timeDiff > 1000) + { + lastStartX = position; + lastStartTime = startTime; + return; + } + + if (diff == 0) + { + bool right = RNG.NextBool(); + + float rand = Math.Min(20, (float)RNG.NextDouble(0, timeDiff / 4)); + + if (right) + { + if (position + rand <= 512) + position += rand; + else + position -= rand; + } + else + { + if (position - rand >= 0) + position -= rand; + else + position += rand; + } + + hitObject.X = position / 512; + + return; + } + + if (Math.Abs(diff) < timeDiff / 3) + { + if (diff > 0) + { + if (position - diff > 0) + position -= diff; + } + else + { + if (position - diff < 512) + position -= diff; + } + } + + hitObject.X = position / 512; + + lastStartX = position; + lastStartTime = startTime; + } } } From b40af0848f5cb2b4579ac30730bbd7606c3e5ee2 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Sun, 8 Apr 2018 15:52:40 +0200 Subject: [PATCH 02/40] White space --- osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs index 5dadec9b15..97b1645e85 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Catch.Mods { public override double ScoreMultiplier => 1.12; public override bool Ranked => true; - + private float lastStartX; private int lastStartTime; From 82d9504cbf866e601dd3e7c519113354f7433c36 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Mon, 9 Apr 2018 09:02:32 +0200 Subject: [PATCH 03/40] Changed relative position to [0, 1] --- osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs index 97b1645e85..1656a5c40b 100644 --- a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs +++ b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs @@ -3,6 +3,7 @@ using osu.Framework.MathUtils; using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.UI; using osu.Game.Rulesets.Mods; using System; @@ -18,8 +19,7 @@ namespace osu.Game.Rulesets.Catch.Mods public void ApplyToHitObject(CatchHitObject hitObject) { - // Code from Stable, we keep calculation on a scale of 0 to 512 - float position = hitObject.X * 512; + float position = hitObject.X; int startTime = (int)hitObject.StartTime; if (lastStartX == 0) @@ -43,11 +43,11 @@ namespace osu.Game.Rulesets.Catch.Mods { bool right = RNG.NextBool(); - float rand = Math.Min(20, (float)RNG.NextDouble(0, timeDiff / 4)); + float rand = Math.Min(20, (float)RNG.NextDouble(0, timeDiff / 4d)) / CatchPlayfield.BASE_WIDTH; if (right) { - if (position + rand <= 512) + if (position + rand <= 1) position += rand; else position -= rand; @@ -60,12 +60,12 @@ namespace osu.Game.Rulesets.Catch.Mods position += rand; } - hitObject.X = position / 512; + hitObject.X = position; return; } - if (Math.Abs(diff) < timeDiff / 3) + if (Math.Abs(diff) < timeDiff / 3d) { if (diff > 0) { @@ -74,12 +74,12 @@ namespace osu.Game.Rulesets.Catch.Mods } else { - if (position - diff < 512) + if (position - diff < 1) position -= diff; } } - hitObject.X = position / 512; + hitObject.X = position; lastStartX = position; lastStartTime = startTime; From 767ecb4422e9cdef40551d4c9b9aa56805080f63 Mon Sep 17 00:00:00 2001 From: Joseph Madamba Date: Tue, 10 Apr 2018 00:11:53 -0700 Subject: [PATCH 04/40] Fix rank status --- osu.Game/Beatmaps/RankStatus.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Beatmaps/RankStatus.cs b/osu.Game/Beatmaps/RankStatus.cs index 5ca358ddef..8792c088af 100644 --- a/osu.Game/Beatmaps/RankStatus.cs +++ b/osu.Game/Beatmaps/RankStatus.cs @@ -13,8 +13,7 @@ namespace osu.Game.Beatmaps Approved = 1, Loved = 8, Favourites = 2, - [Description("Mod Requests")] - ModRequests = 3, + Qualified = 3, Pending = 4, Graveyard = 5, [Description("My Maps")] From 9793137bfa7e4e54b346cd1cfd3d7f3b4c61b5fd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 11 Apr 2018 22:31:50 +0900 Subject: [PATCH 05/40] Add back app.manifest Resolves #2380 --- app.manifest | 46 ++++++++++++++++++++++++++++++++++++++++++++++ osu.Game.props | 3 +++ 2 files changed, 49 insertions(+) create mode 100644 app.manifest diff --git a/app.manifest b/app.manifest new file mode 100644 index 0000000000..d1c97498f4 --- /dev/null +++ b/app.manifest @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + true + + + + + + + + diff --git a/osu.Game.props b/osu.Game.props index 87edafb97f..ec859e64a5 100644 --- a/osu.Game.props +++ b/osu.Game.props @@ -3,6 +3,9 @@ 7 + + ..\app.manifest + osu.licenseheader From 461e063f1946e8459697fe7c1a4a468cf9de0f31 Mon Sep 17 00:00:00 2001 From: Joehu Date: Wed, 11 Apr 2018 22:50:39 -0700 Subject: [PATCH 06/40] Rename RankStatus to BeatmapSearchCategory --- osu.Game/Beatmaps/{RankStatus.cs => BeatmapSearchCategory.cs} | 2 +- osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs | 4 ++-- osu.Game/Overlays/Direct/FilterControl.cs | 2 +- osu.Game/Overlays/DirectOverlay.cs | 4 ++-- 4 files changed, 6 insertions(+), 6 deletions(-) rename osu.Game/Beatmaps/{RankStatus.cs => BeatmapSearchCategory.cs} (89%) diff --git a/osu.Game/Beatmaps/RankStatus.cs b/osu.Game/Beatmaps/BeatmapSearchCategory.cs similarity index 89% rename from osu.Game/Beatmaps/RankStatus.cs rename to osu.Game/Beatmaps/BeatmapSearchCategory.cs index 8792c088af..fdd284376f 100644 --- a/osu.Game/Beatmaps/RankStatus.cs +++ b/osu.Game/Beatmaps/BeatmapSearchCategory.cs @@ -5,7 +5,7 @@ using System.ComponentModel; namespace osu.Game.Beatmaps { - public enum RankStatus + public enum BeatmapSearchCategory { Any = 7, [Description("Ranked & Approved")] diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index c54d0ea556..2482aae170 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -13,12 +13,12 @@ namespace osu.Game.Online.API.Requests { private readonly string query; private readonly RulesetInfo ruleset; - private readonly RankStatus rankStatus; + private readonly BeatmapSearchCategory rankStatus; private readonly DirectSortCriteria sortCriteria; private readonly SortDirection direction; private string directionString => direction == SortDirection.Descending ? @"desc" : @"asc"; - public SearchBeatmapSetsRequest(string query, RulesetInfo ruleset, RankStatus rankStatus = RankStatus.Any, DirectSortCriteria sortCriteria = DirectSortCriteria.Ranked, SortDirection direction = SortDirection.Descending) + public SearchBeatmapSetsRequest(string query, RulesetInfo ruleset, BeatmapSearchCategory rankStatus = BeatmapSearchCategory.Any, DirectSortCriteria sortCriteria = DirectSortCriteria.Ranked, SortDirection direction = SortDirection.Descending) { this.query = System.Uri.EscapeDataString(query); this.ruleset = ruleset; diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index 84a09547aa..e861326b27 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -15,7 +15,7 @@ using osu.Game.Rulesets; namespace osu.Game.Overlays.Direct { - public class FilterControl : SearchableListFilterControl + public class FilterControl : SearchableListFilterControl { public readonly Bindable Ruleset = new Bindable(); private FillFlowContainer modeButtons; diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 8d8a4aebaa..208b237576 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -22,7 +22,7 @@ using OpenTK.Graphics; namespace osu.Game.Overlays { - public class DirectOverlay : SearchableListOverlay + public class DirectOverlay : SearchableListOverlay { private const float panel_padding = 10f; @@ -40,7 +40,7 @@ namespace osu.Game.Overlays protected override Color4 TrianglesColourDark => OsuColour.FromHex(@"3f5265"); protected override SearchableListHeader CreateHeader() => new Header(); - protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); + protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); private IEnumerable beatmapSets; From f18594887bce516cb975a0da572a336d7f403d3a Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 12 Apr 2018 07:49:23 -0700 Subject: [PATCH 07/40] Move enum to SearchBeatmapSetsRequest --- osu.Game/Beatmaps/BeatmapSearchCategory.cs | 22 ------------------- .../API/Requests/SearchBeatmapSetsRequest.cs | 16 ++++++++++++++ osu.Game/Overlays/Direct/FilterControl.cs | 1 + 3 files changed, 17 insertions(+), 22 deletions(-) delete mode 100644 osu.Game/Beatmaps/BeatmapSearchCategory.cs diff --git a/osu.Game/Beatmaps/BeatmapSearchCategory.cs b/osu.Game/Beatmaps/BeatmapSearchCategory.cs deleted file mode 100644 index fdd284376f..0000000000 --- a/osu.Game/Beatmaps/BeatmapSearchCategory.cs +++ /dev/null @@ -1,22 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System.ComponentModel; - -namespace osu.Game.Beatmaps -{ - public enum BeatmapSearchCategory - { - Any = 7, - [Description("Ranked & Approved")] - RankedApproved = 0, - Approved = 1, - Loved = 8, - Favourites = 2, - Qualified = 3, - Pending = 4, - Graveyard = 5, - [Description("My Maps")] - MyMaps = 6, - } -} diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index 2482aae170..52ed7218ad 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.ComponentModel; using osu.Game.Beatmaps; using osu.Game.Overlays; using osu.Game.Overlays.Direct; @@ -30,4 +31,19 @@ namespace osu.Game.Online.API.Requests // ReSharper disable once ImpureMethodCallOnReadonlyValueField protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.ID ?? 0}&s={(int)rankStatus}&sort={sortCriteria.ToString().ToLower()}_{directionString}"; } + + public enum BeatmapSearchCategory + { + Any = 7, + [Description("Ranked & Approved")] + RankedApproved = 0, + Approved = 1, + Loved = 8, + Favourites = 2, + Qualified = 3, + Pending = 4, + Graveyard = 5, + [Description("My Maps")] + MyMaps = 6, + } } diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index e861326b27..ddbac10ac8 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Online.API.Requests; using osu.Game.Overlays.SearchableList; using osu.Game.Rulesets; From df4b64effcc5418ce11940d7f9754afeaaafa883 Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 12 Apr 2018 08:03:19 -0700 Subject: [PATCH 08/40] Rename rankStatus to searchCategory --- osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index 52ed7218ad..1abb844c8d 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -14,22 +14,22 @@ namespace osu.Game.Online.API.Requests { private readonly string query; private readonly RulesetInfo ruleset; - private readonly BeatmapSearchCategory rankStatus; + private readonly BeatmapSearchCategory searchCategory; private readonly DirectSortCriteria sortCriteria; private readonly SortDirection direction; private string directionString => direction == SortDirection.Descending ? @"desc" : @"asc"; - public SearchBeatmapSetsRequest(string query, RulesetInfo ruleset, BeatmapSearchCategory rankStatus = BeatmapSearchCategory.Any, DirectSortCriteria sortCriteria = DirectSortCriteria.Ranked, SortDirection direction = SortDirection.Descending) + public SearchBeatmapSetsRequest(string query, RulesetInfo ruleset, BeatmapSearchCategory searchCategory = BeatmapSearchCategory.Any, DirectSortCriteria sortCriteria = DirectSortCriteria.Ranked, SortDirection direction = SortDirection.Descending) { this.query = System.Uri.EscapeDataString(query); this.ruleset = ruleset; - this.rankStatus = rankStatus; + this.searchCategory = searchCategory; this.sortCriteria = sortCriteria; this.direction = direction; } // ReSharper disable once ImpureMethodCallOnReadonlyValueField - protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.ID ?? 0}&s={(int)rankStatus}&sort={sortCriteria.ToString().ToLower()}_{directionString}"; + protected override string Target => $@"beatmapsets/search?q={query}&m={ruleset.ID ?? 0}&s={(int)searchCategory}&sort={sortCriteria.ToString().ToLower()}_{directionString}"; } public enum BeatmapSearchCategory From 463b189d2fcc1730b7bc276e50aa69c408c3a691 Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 12 Apr 2018 08:13:24 -0700 Subject: [PATCH 09/40] Remove unused using directives --- osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs | 1 - osu.Game/Overlays/Direct/FilterControl.cs | 1 - 2 files changed, 2 deletions(-) diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index 1abb844c8d..ed59ed53c2 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.ComponentModel; -using osu.Game.Beatmaps; using osu.Game.Overlays; using osu.Game.Overlays.Direct; using osu.Game.Rulesets; diff --git a/osu.Game/Overlays/Direct/FilterControl.cs b/osu.Game/Overlays/Direct/FilterControl.cs index ddbac10ac8..286eb8ecef 100644 --- a/osu.Game/Overlays/Direct/FilterControl.cs +++ b/osu.Game/Overlays/Direct/FilterControl.cs @@ -7,7 +7,6 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API.Requests; From e3cd0ef20045dfd16874760d9215b1515878614e Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Fri, 13 Apr 2018 11:09:49 +0200 Subject: [PATCH 10/40] Add right click scrolling in song select (and its option) --- osu.Game/Configuration/OsuConfigManager.cs | 5 +++- .../Sections/Gameplay/SongSelectSettings.cs | 5 ++++ osu.Game/Screens/Select/BeatmapCarousel.cs | 29 +++++++++++++++++++ 3 files changed, 38 insertions(+), 1 deletion(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 70260b349e..a3025a65f4 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -84,6 +84,8 @@ namespace osu.Game.Configuration Set(OsuSetting.Version, string.Empty); Set(OsuSetting.ScreenshotFormat, ScreenshotFormat.Jpg); + + Set(OsuSetting.SelectScrollRightClick, false); } public OsuConfigManager(Storage storage) : base(storage) @@ -128,6 +130,7 @@ namespace osu.Game.Configuration ShowConvertedBeatmaps, SpeedChangeVisualisation, Skin, - ScreenshotFormat + ScreenshotFormat, + SelectScrollRightClick } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs index 4bbd87c7e6..e8d65a1ed3 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs @@ -17,6 +17,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { Children = new Drawable[] { + new SettingsCheckbox + { + LabelText = "Right click to scroll", + Bindable = config.GetBindable(OsuSetting.SelectScrollRightClick), + }, new SettingsCheckbox { LabelText = "Show converted beatmaps", diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 15f4d5cf96..5c3518b46c 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -97,6 +97,9 @@ namespace osu.Game.Screens.Select private readonly Container scrollableContent; + + public Bindable RightClickScrollingEnabled = new Bindable(); + public Bindable RandomAlgorithm = new Bindable(); private readonly List previouslyVisitedRandomSets = new List(); private readonly Stack randomSelectedBeatmaps = new Stack(); @@ -121,6 +124,7 @@ namespace osu.Game.Screens.Select private void load(OsuConfigManager config) { config.BindWith(OsuSetting.RandomSelectAlgorithm, RandomAlgorithm); + config.BindWith(OsuSetting.SelectScrollRightClick, RightClickScrollingEnabled); } public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) @@ -398,6 +402,31 @@ namespace osu.Game.Screens.Select return true; } + private bool rightClickScrolling = false; + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + bool result = base.OnMouseDown(state, args); + + if (RightClickScrollingEnabled.Value && !result && args.Button == MouseButton.Right) + { + rightClickScrolling = true; + return true; + } + + return result; + } + + protected override bool OnMouseMove(InputState state) + { + if (state.Mouse.Buttons.Contains(MouseButton.Right) && rightClickScrolling) + ScrollTo((state.Mouse.Position.Y / DrawHeight) * scrollableContent.Height); + else + rightClickScrolling = false; + + return base.OnMouseMove(state); + } + protected override void Update() { base.Update(); From 1a2b1d4c98f9d18485704e7349ae9f8626688a3b Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Fri, 13 Apr 2018 11:32:33 +0200 Subject: [PATCH 11/40] Use the already existent RightMouseScrollbar field --- osu.Game/Screens/Select/BeatmapCarousel.cs | 28 +++------------------- 1 file changed, 3 insertions(+), 25 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 5c3518b46c..793759908d 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -125,6 +125,9 @@ namespace osu.Game.Screens.Select { config.BindWith(OsuSetting.RandomSelectAlgorithm, RandomAlgorithm); config.BindWith(OsuSetting.SelectScrollRightClick, RightClickScrollingEnabled); + + RightClickScrollingEnabled.ValueChanged += v => RightMouseScrollbar = v; + RightClickScrollingEnabled.TriggerChange(); } public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) @@ -402,31 +405,6 @@ namespace osu.Game.Screens.Select return true; } - private bool rightClickScrolling = false; - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - bool result = base.OnMouseDown(state, args); - - if (RightClickScrollingEnabled.Value && !result && args.Button == MouseButton.Right) - { - rightClickScrolling = true; - return true; - } - - return result; - } - - protected override bool OnMouseMove(InputState state) - { - if (state.Mouse.Buttons.Contains(MouseButton.Right) && rightClickScrolling) - ScrollTo((state.Mouse.Position.Y / DrawHeight) * scrollableContent.Height); - else - rightClickScrolling = false; - - return base.OnMouseMove(state); - } - protected override void Update() { base.Update(); From b23b0a445be8628db6d019a61912df1519429d36 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Fri, 13 Apr 2018 15:41:35 +0200 Subject: [PATCH 12/40] Add support for replay mods --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 40 +++++++++++ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 69 +++++++++++++++++++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 49 +++++++++++++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 40 +++++++++++ osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 3 + osu.Game/Beatmaps/Legacy/LegacyMods.cs | 43 ++++++++++++ osu.Game/OsuGame.cs | 1 + osu.Game/Rulesets/Ruleset.cs | 3 + .../Scoring/Legacy/LegacyScoreParser.cs | 5 +- 9 files changed, 252 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Beatmaps/Legacy/LegacyMods.cs diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 8930b09089..87de1aed97 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Replays.Types; +using osu.Game.Beatmaps.Legacy; namespace osu.Game.Rulesets.Catch { @@ -29,6 +30,45 @@ namespace osu.Game.Rulesets.Catch new KeyBinding(InputKey.Shift, CatchAction.Dash), }; + public override IEnumerable GetLegacyModsFor(LegacyMods mods) + { + if (mods.HasFlag(LegacyMods.NightCore)) + yield return new CatchModNightcore(); + else if (mods.HasFlag(LegacyMods.DoubleTime)) + yield return new CatchModDoubleTime(); + + + if (mods.HasFlag(LegacyMods.AutoPlay)) + yield return new CatchModAutoplay(); + + if (mods.HasFlag(LegacyMods.Easy)) + yield return new CatchModEasy(); + + if (mods.HasFlag(LegacyMods.FlashLight)) + yield return new CatchModFlashlight(); + + if (mods.HasFlag(LegacyMods.HalfTime)) + yield return new CatchModHalfTime(); + + if (mods.HasFlag(LegacyMods.HardRock)) + yield return new CatchModHardRock(); + + if (mods.HasFlag(LegacyMods.Hidden)) + yield return new CatchModHidden(); + + if (mods.HasFlag(LegacyMods.NoFail)) + yield return new CatchModNoFail(); + + if (mods.HasFlag(LegacyMods.Perfect)) + yield return new CatchModPerfect(); + + if (mods.HasFlag(LegacyMods.Relax)) + yield return new CatchModRelax(); + + if (mods.HasFlag(LegacyMods.SuddenDeath)) + yield return new CatchModSuddenDeath(); + } + public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 7f37f55d14..4bd243664b 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -14,6 +14,7 @@ using osu.Framework.Input.Bindings; using osu.Game.Graphics; using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Replays.Types; +using osu.Game.Beatmaps.Legacy; namespace osu.Game.Rulesets.Mania { @@ -21,6 +22,74 @@ namespace osu.Game.Rulesets.Mania { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaRulesetContainer(this, beatmap, isForCurrentRuleset); + public override IEnumerable GetLegacyModsFor(LegacyMods mods) + { + if (mods.HasFlag(LegacyMods.NightCore)) + yield return new ManiaModNightcore(); + else if (mods.HasFlag(LegacyMods.DoubleTime)) + yield return new ManiaModDoubleTime(); + + if (mods.HasFlag(LegacyMods.AutoPlay)) + yield return new ManiaModAutoplay(); + + if (mods.HasFlag(LegacyMods.Easy)) + yield return new ManiaModEasy(); + + if (mods.HasFlag(LegacyMods.FadeIn)) + yield return new ManiaModFadeIn(); + + if (mods.HasFlag(LegacyMods.FlashLight)) + yield return new ManiaModFlashlight(); + + if (mods.HasFlag(LegacyMods.HalfTime)) + yield return new ManiaModHalfTime(); + + if (mods.HasFlag(LegacyMods.HardRock)) + yield return new ManiaModHardRock(); + + if (mods.HasFlag(LegacyMods.Hidden)) + yield return new ManiaModHidden(); + + if (mods.HasFlag(LegacyMods.Key1)) + yield return new ManiaModKey1(); + + if (mods.HasFlag(LegacyMods.Key2)) + yield return new ManiaModKey2(); + + if (mods.HasFlag(LegacyMods.Key3)) + yield return new ManiaModKey3(); + + if (mods.HasFlag(LegacyMods.Key4)) + yield return new ManiaModKey4(); + + if (mods.HasFlag(LegacyMods.Key5)) + yield return new ManiaModKey5(); + + if (mods.HasFlag(LegacyMods.Key6)) + yield return new ManiaModKey6(); + + if (mods.HasFlag(LegacyMods.Key7)) + yield return new ManiaModKey7(); + + if (mods.HasFlag(LegacyMods.Key8)) + yield return new ManiaModKey8(); + + if (mods.HasFlag(LegacyMods.Key9)) + yield return new ManiaModKey9(); + + if (mods.HasFlag(LegacyMods.NoFail)) + yield return new ManiaModNoFail(); + + if (mods.HasFlag(LegacyMods.Perfect)) + yield return new ManiaModPerfect(); + + if (mods.HasFlag(LegacyMods.Random)) + yield return new ManiaModRandom(); + + if (mods.HasFlag(LegacyMods.SuddenDeath)) + yield return new ManiaModSuddenDeath(); + } + public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 37e6ec3817..7611f160ae 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -21,6 +21,7 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Replays.Types; +using osu.Game.Beatmaps.Legacy; namespace osu.Game.Rulesets.Osu { @@ -66,6 +67,54 @@ namespace osu.Game.Rulesets.Osu }; } + public override IEnumerable GetLegacyModsFor(LegacyMods mods) + { + if (mods.HasFlag(LegacyMods.NightCore)) + yield return new OsuModNightcore(); + else if (mods.HasFlag(LegacyMods.DoubleTime)) + yield return new OsuModDoubleTime(); + + + if (mods.HasFlag(LegacyMods.AutoPilot)) + yield return new OsuModAutopilot(); + + if (mods.HasFlag(LegacyMods.AutoPlay)) + yield return new OsuModAutoplay(); + + if (mods.HasFlag(LegacyMods.Easy)) + yield return new OsuModEasy(); + + if (mods.HasFlag(LegacyMods.FlashLight)) + yield return new OsuModFlashlight(); + + if (mods.HasFlag(LegacyMods.HalfTime)) + yield return new OsuModHalfTime(); + + if (mods.HasFlag(LegacyMods.HardRock)) + yield return new OsuModHardRock(); + + if (mods.HasFlag(LegacyMods.Hidden)) + yield return new OsuModHidden(); + + if (mods.HasFlag(LegacyMods.NoFail)) + yield return new OsuModNoFail(); + + if (mods.HasFlag(LegacyMods.Perfect)) + yield return new OsuModPerfect(); + + if (mods.HasFlag(LegacyMods.Relax)) + yield return new OsuModRelax(); + + if (mods.HasFlag(LegacyMods.SpunOut)) + yield return new OsuModSpunOut(); + + if (mods.HasFlag(LegacyMods.SuddenDeath)) + yield return new OsuModSuddenDeath(); + + if (mods.HasFlag(LegacyMods.TargetPractice)) + yield return new OsuModTarget(); + } + public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index cb5e020601..1881e84fb0 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -12,6 +12,7 @@ using osu.Framework.Graphics; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Taiko.Replays; +using osu.Game.Beatmaps.Legacy; namespace osu.Game.Rulesets.Taiko { @@ -31,6 +32,45 @@ namespace osu.Game.Rulesets.Taiko new KeyBinding(InputKey.MouseRight, TaikoAction.RightRim), }; + public override IEnumerable GetLegacyModsFor(LegacyMods mods) + { + if (mods.HasFlag(LegacyMods.NightCore)) + yield return new TaikoModNightcore(); + else if (mods.HasFlag(LegacyMods.DoubleTime)) + yield return new TaikoModDoubleTime(); + + + if (mods.HasFlag(LegacyMods.AutoPlay)) + yield return new TaikoModAutoplay(); + + if (mods.HasFlag(LegacyMods.Easy)) + yield return new TaikoModEasy(); + + if (mods.HasFlag(LegacyMods.FlashLight)) + yield return new TaikoModFlashlight(); + + if (mods.HasFlag(LegacyMods.HalfTime)) + yield return new TaikoModHalfTime(); + + if (mods.HasFlag(LegacyMods.HardRock)) + yield return new TaikoModHardRock(); + + if (mods.HasFlag(LegacyMods.Hidden)) + yield return new TaikoModHidden(); + + if (mods.HasFlag(LegacyMods.NoFail)) + yield return new TaikoModNoFail(); + + if (mods.HasFlag(LegacyMods.Perfect)) + yield return new TaikoModPerfect(); + + if (mods.HasFlag(LegacyMods.Relax)) + yield return new TaikoModRelax(); + + if (mods.HasFlag(LegacyMods.SuddenDeath)) + yield return new TaikoModSuddenDeath(); + } + public override IEnumerable GetModsFor(ModType type) { switch (type) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 0424ff84f1..4a33e5eb7e 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Textures; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; +using osu.Game.Beatmaps.Legacy; namespace osu.Game.Beatmaps { @@ -53,6 +54,8 @@ namespace osu.Game.Beatmaps { public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; + public override IEnumerable GetLegacyModsFor(LegacyMods mods) => new Mod[] { }; + public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) { throw new NotImplementedException(); diff --git a/osu.Game/Beatmaps/Legacy/LegacyMods.cs b/osu.Game/Beatmaps/Legacy/LegacyMods.cs new file mode 100644 index 0000000000..2ac7324778 --- /dev/null +++ b/osu.Game/Beatmaps/Legacy/LegacyMods.cs @@ -0,0 +1,43 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; + +namespace osu.Game.Beatmaps.Legacy +{ + [Flags] + public enum LegacyMods + { + None = 0, + NoFail = 1, + Easy = 2, + TouchDevice = 4, + Hidden = 8, + HardRock = 16, + SuddenDeath = 32, + DoubleTime = 64, + Relax = 128, + HalfTime = 256, + NightCore = 512, + FlashLight = 1024, + AutoPlay = 2048, + SpunOut = 4096, + AutoPilot = 8192, + Perfect = 16384, + Key4 = 32768, + Key5 = 65536, + Key6 = 131072, + Key7 = 262144, + Key8 = 524288, + keyMod = 1015808,// k4+k5+k6+k7+k8 + FadeIn = 1048576, + Random = 2097152, + Cinema = 4194304, + TargetPractice = 8388608, + Key9 = 16777216, + Coop = 33554432, + Key1 = 67108864, + Key3 = 134217728, + Key2 = 268435456, + } +} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index d1cf372067..6c35a2ecea 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -194,6 +194,7 @@ namespace osu.Game } Beatmap.Value = BeatmapManager.GetWorkingBeatmap(s.Beatmap); + Beatmap.Value.Mods.BindTo(new Bindable>(s.Mods)); menu.Push(new PlayerLoader(new ReplayPlayer(s.Replay))); } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index c2af4d566c..f2cf813d38 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -14,6 +14,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; +using osu.Game.Beatmaps.Legacy; namespace osu.Game.Rulesets { @@ -33,6 +34,8 @@ namespace osu.Game.Rulesets public abstract IEnumerable GetModsFor(ModType type); + public abstract IEnumerable GetLegacyModsFor(LegacyMods mods); + public Mod GetAutoplayMod() => GetAllMods().First(mod => mod is ModAutoplay); protected Ruleset(RulesetInfo rulesetInfo = null) diff --git a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs index 5ee009ba98..806e8d2fdb 100644 --- a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs @@ -9,6 +9,9 @@ using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Replays.Legacy; using osu.Game.Users; using SharpCompress.Compressors.LZMA; +using osu.Game.Beatmaps.Legacy; +using osu.Game.Rulesets.Mods; +using System.Linq; namespace osu.Game.Rulesets.Scoring.Legacy { @@ -64,7 +67,7 @@ namespace osu.Game.Rulesets.Scoring.Legacy /* score.Perfect = */ sr.ReadBoolean(); /* score.EnabledMods = (Mods)*/ - sr.ReadInt32(); + score.Mods = currentRuleset.GetLegacyModsFor((LegacyMods)sr.ReadInt32()).ToArray(); /* score.HpGraphString = */ sr.ReadString(); /* score.Date = */ From 73ba8e1c876d2e57bdda27e8c87ea0f39a63c4df Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Fri, 13 Apr 2018 16:10:01 +0200 Subject: [PATCH 13/40] CI: remove unused directive --- osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs index 806e8d2fdb..62d1cb3a32 100644 --- a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs @@ -10,7 +10,6 @@ using osu.Game.Rulesets.Replays.Legacy; using osu.Game.Users; using SharpCompress.Compressors.LZMA; using osu.Game.Beatmaps.Legacy; -using osu.Game.Rulesets.Mods; using System.Linq; namespace osu.Game.Rulesets.Scoring.Legacy From 3454ec1ca385d1725432d7322c98fc9dd1f6226f Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Sun, 15 Apr 2018 20:23:57 +0200 Subject: [PATCH 14/40] Set Value instead of BindTo --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 18dc9f4ea1..f69135e5c9 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -196,7 +196,7 @@ namespace osu.Game } Beatmap.Value = BeatmapManager.GetWorkingBeatmap(s.Beatmap); - Beatmap.Value.Mods.BindTo(new Bindable>(s.Mods)); + Beatmap.Value.Mods.Value = s.Mods; menu.Push(new PlayerLoader(new ReplayPlayer(s.Replay))); } From 6ca714d93b9e92d9f2869e31379a38fb6ab55e06 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sun, 15 Apr 2018 23:44:59 +0200 Subject: [PATCH 15/40] add badges to ProfileHeader --- osu.Game.Tests/Visual/TestCaseRankGraph.cs | 2 +- osu.Game.Tests/Visual/TestCaseUserProfile.cs | 61 ++++-- .../Overlays/Profile/Header/BadgeContainer.cs | 190 ++++++++++++++++++ .../Profile/{ => Header}/RankGraph.cs | 8 +- .../Profile/{ => Header}/SupporterIcon.cs | 4 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 22 +- osu.Game/Users/Badge.cs | 20 ++ osu.Game/Users/User.cs | 3 + osu.Game/Users/UserPanel.cs | 2 +- 9 files changed, 281 insertions(+), 31 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Header/BadgeContainer.cs rename osu.Game/Overlays/Profile/{ => Header}/RankGraph.cs (99%) rename osu.Game/Overlays/Profile/{ => Header}/SupporterIcon.cs (98%) create mode 100644 osu.Game/Users/Badge.cs diff --git a/osu.Game.Tests/Visual/TestCaseRankGraph.cs b/osu.Game.Tests/Visual/TestCaseRankGraph.cs index 45f6651537..f5558620ad 100644 --- a/osu.Game.Tests/Visual/TestCaseRankGraph.cs +++ b/osu.Game.Tests/Visual/TestCaseRankGraph.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Game.Overlays.Profile; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using OpenTK; @@ -11,6 +10,7 @@ using System.Collections.Generic; using System; using NUnit.Framework; using osu.Game.Graphics.UserInterface; +using osu.Game.Overlays.Profile.Header; using osu.Game.Users; namespace osu.Game.Tests.Visual diff --git a/osu.Game.Tests/Visual/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/TestCaseUserProfile.cs index b060b9f2f8..86af26098a 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfile.cs @@ -8,6 +8,7 @@ using NUnit.Framework; using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osu.Game.Overlays.Profile; +using osu.Game.Overlays.Profile.Header; using osu.Game.Users; namespace osu.Game.Tests.Visual @@ -23,6 +24,7 @@ namespace osu.Game.Tests.Visual typeof(UserProfileOverlay), typeof(RankGraph), typeof(LineGraph), + typeof(BadgeContainer) }; public TestCaseUserProfile() @@ -34,27 +36,24 @@ namespace osu.Game.Tests.Visual { base.LoadComplete(); - AddStep("Show offline dummy", () => profile.ShowUser(new User + AddStep("Show offline dummy", () => profile.ShowUser(createDummyUser(new Badge[0]), false)); + + AddStep("Show with badge", () => profile.ShowUser(createDummyUser(new[] { - Username = @"Somebody", - Id = 1, - Country = new Country { FullName = @"Alien" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg", - JoinDate = DateTimeOffset.Now.AddDays(-1), - LastVisit = DateTimeOffset.Now, - Age = 1, - ProfileOrder = new[] { "me" }, - Statistics = new UserStatistics + new Badge { - Ranks = new UserStatistics.UserRanks { Global = 2148, Country = 1 }, - PP = 4567.89m, - }, - RankHistory = new User.RankHistoryData - { - Mode = @"osu", - Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() + AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569), + Description = "Outstanding help by being a voluntary test subject.", + ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg" } - }, false)); + }), false)); + + AddStep("Show many badges", () => profile.ShowUser(createDummyUser(Enumerable.Range(0, 10).Select(i => new Badge + { + AwardedAt = DateTimeOffset.Now, + Description = i.ToString(), + ImageUrl = "Flags/__" + }).ToArray()), false)); checkSupporterTag(false); @@ -95,6 +94,32 @@ namespace osu.Game.Tests.Visual AddAssert("no supporter", () => profile.Header.SupporterTag.Alpha == 0); } + private User createDummyUser(Badge[] badges) + { + return new User + { + Username = @"Somebody", + Id = 1, + Country = new Country { FullName = @"Alien" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg", + JoinDate = DateTimeOffset.Now.AddDays(-1), + LastVisit = DateTimeOffset.Now, + Age = 1, + ProfileOrder = new[] { "me" }, + Statistics = new UserStatistics + { + Ranks = new UserStatistics.UserRanks { Global = 2148, Country = 1 }, + PP = 4567.89m, + }, + RankHistory = new User.RankHistoryData + { + Mode = @"osu", + Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() + }, + Badges = badges + }; + } + private class TestUserProfileOverlay : UserProfileOverlay { public new ProfileHeader Header => base.Header; diff --git a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs new file mode 100644 index 0000000000..b4d0705e50 --- /dev/null +++ b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs @@ -0,0 +1,190 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; +using osu.Framework.Input; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Users; +using OpenTK; + +namespace osu.Game.Overlays.Profile.Header +{ + public class BadgeContainer : Container + { + private const float outer_container_width = 98; + private const float outer_container_padding = 3; + private static readonly Vector2 badge_size = new Vector2(outer_container_width - outer_container_padding * 2, 46); + + private OsuSpriteText badgeCountText; + private FillFlowContainer badgeFlowContainer; + private FillFlowContainer outerBadgeContainer; + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Child = new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Masking = true, + CornerRadius = 4, + AutoSizeAxes = Axes.Both, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray3 + }, + outerBadgeContainer = new OuterBadgeContainer(onOuterHover, onOuterHoverLost) + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + Direction = FillDirection.Vertical, + Padding = new MarginPadding(outer_container_padding), + Width = outer_container_width, + AutoSizeAxes = Axes.Y, + Children = new Drawable[] + { + badgeCountText = new OsuSpriteText + { + Alpha = 0, + TextSize = 12, + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre, + Font = "Exo2.0-Regular" + }, + new Container + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + AutoSizeAxes = Axes.Both, + Child = badgeFlowContainer = new FillFlowContainer + { + Direction = FillDirection.Horizontal, + AutoSizeAxes = Axes.Both, + } + } + } + }, + } + }; + + Scheduler.AddDelayed(rotateBadges, 3000, true); + } + + private void rotateBadges() + { + if (outerBadgeContainer.IsHovered) return; + + visibleBadge = (visibleBadge + 1) % badgeCount; + + badgeFlowContainer.MoveToX(-badge_size.X * visibleBadge, 500, Easing.InOutQuad); + } + + private int visibleBadge; + private int badgeCount; + + public void ShowBadges(Badge[] badges) + { + switch (badges.Length) + { + case 0: + Hide(); + return; + case 1: + badgeCountText.Hide(); + break; + default: + badgeCountText.Show(); + badgeCountText.Text = $"{badges.Length} badges"; + break; + } + + Show(); + badgeCount = badges.Length; + visibleBadge = 0; + + foreach (var badge in badges) + { + LoadComponentAsync(new DrawableBadge(badge) + { + Size = badge_size, + }, badgeFlowContainer.Add); + } + } + + private void onOuterHover() + { + badgeFlowContainer.ClearTransforms(); + badgeFlowContainer.X = 0; + badgeFlowContainer.Direction = FillDirection.Full; + outerBadgeContainer.AutoSizeAxes = Axes.Both; + + badgeFlowContainer.MaximumSize = new Vector2(ChildSize.X, float.MaxValue); + } + + private void onOuterHoverLost() + { + rotateBadges(); + badgeFlowContainer.Direction = FillDirection.Horizontal; + outerBadgeContainer.AutoSizeAxes = Axes.Y; + outerBadgeContainer.Width = outer_container_width; + } + + private class OuterBadgeContainer : FillFlowContainer + { + private readonly Action hoverAction; + private readonly Action hoverLostAction; + + public OuterBadgeContainer(Action hoverAction, Action hoverLostAction) + { + this.hoverAction = hoverAction; + this.hoverLostAction = hoverLostAction; + } + + protected override bool OnHover(InputState state) + { + hoverAction(); + return true; + } + + protected override void OnHoverLost(InputState state) => hoverLostAction(); + } + + private class DrawableBadge : Container, IHasTooltip + { + private readonly Badge badge; + + public DrawableBadge(Badge badge) + { + this.badge = badge; + Padding = new MarginPadding(3); + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + Child = new Sprite + { + FillMode = FillMode.Fit, + RelativeSizeAxes = Axes.Both, + Texture = textures.Get(badge.ImageUrl), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + OnLoadComplete = d => d.FadeInFromZero(200) + }; + } + + public string TooltipText => badge.Description; + } + } +} diff --git a/osu.Game/Overlays/Profile/RankGraph.cs b/osu.Game/Overlays/Profile/Header/RankGraph.cs similarity index 99% rename from osu.Game/Overlays/Profile/RankGraph.cs rename to osu.Game/Overlays/Profile/Header/RankGraph.cs index 72dd4352f6..2c70507536 100644 --- a/osu.Game/Overlays/Profile/RankGraph.cs +++ b/osu.Game/Overlays/Profile/Header/RankGraph.cs @@ -2,9 +2,10 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Linq; -using OpenTK; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -14,10 +15,9 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using osu.Game.Users; -using System.Collections.Generic; -using osu.Framework.Configuration; +using OpenTK; -namespace osu.Game.Overlays.Profile +namespace osu.Game.Overlays.Profile.Header { public class RankGraph : Container { diff --git a/osu.Game/Overlays/Profile/SupporterIcon.cs b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs similarity index 98% rename from osu.Game/Overlays/Profile/SupporterIcon.cs rename to osu.Game/Overlays/Profile/Header/SupporterIcon.cs index e8d52bf50e..37ad63464c 100644 --- a/osu.Game/Overlays/Profile/SupporterIcon.cs +++ b/osu.Game/Overlays/Profile/Header/SupporterIcon.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using OpenTK; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -9,8 +8,9 @@ using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; +using OpenTK; -namespace osu.Game.Overlays.Profile +namespace osu.Game.Overlays.Profile.Header { public class SupporterIcon : CircularContainer, IHasTooltip { diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 4a88431cc4..189eaf0bdf 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -17,6 +17,7 @@ using osu.Framework.Graphics.Textures; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.Profile.Header; using osu.Game.Users; namespace osu.Game.Overlays.Profile @@ -35,6 +36,7 @@ namespace osu.Game.Overlays.Profile private readonly GradeBadge gradeSSPlus, gradeSS, gradeSPlus, gradeS, gradeA; private readonly Box colourBar; private readonly DrawableFlag countryFlag; + private readonly BadgeContainer badgeContainer; private const float cover_height = 350; private const float info_height = 150; @@ -42,6 +44,7 @@ namespace osu.Game.Overlays.Profile private const float avatar_size = 110; private const float level_position = 30; private const float level_height = 60; + private const float stats_width = 280; public ProfileHeader(User user) { @@ -66,9 +69,9 @@ namespace osu.Game.Overlays.Profile { Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, - X = UserProfileOverlay.CONTENT_X_MARGIN, - Y = -20, - AutoSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = UserProfileOverlay.CONTENT_X_MARGIN, Bottom = 20, Right = stats_width + UserProfileOverlay.CONTENT_X_MARGIN }, + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, Children = new Drawable[] { new UpdateableAvatar @@ -116,7 +119,14 @@ namespace osu.Game.Overlays.Profile Height = 20 } } - } + }, + badgeContainer = new BadgeContainer + { + RelativeSizeAxes = Axes.Both, + Origin = Anchor.BottomLeft, + Margin = new MarginPadding { Bottom = 5 }, + Alpha = 0, + }, } }, colourBar = new Box @@ -156,7 +166,7 @@ namespace osu.Game.Overlays.Profile { X = -UserProfileOverlay.CONTENT_X_MARGIN, RelativeSizeAxes = Axes.Y, - Width = 280, + Width = stats_width, Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Children = new Drawable[] @@ -417,6 +427,8 @@ namespace osu.Game.Overlays.Profile rankGraph.User.Value = user; } + + badgeContainer.ShowBadges(user.Badges); } private void tryAddInfoRightLine(FontAwesome icon, string str, string url = null) diff --git a/osu.Game/Users/Badge.cs b/osu.Game/Users/Badge.cs new file mode 100644 index 0000000000..25ef8ffdf4 --- /dev/null +++ b/osu.Game/Users/Badge.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using Newtonsoft.Json; + +namespace osu.Game.Users +{ + public class Badge + { + [JsonProperty("awarded_at")] + public DateTimeOffset AwardedAt; + + [JsonProperty("description")] + public string Description; + + [JsonProperty("image_url")] + public string ImageUrl; + } +} diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index 441e4ffd28..b983b639f0 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -137,6 +137,9 @@ namespace osu.Game.Users [JsonProperty(@"rankHistory")] public RankHistoryData RankHistory; + [JsonProperty("badges")] + public Badge[] Badges; + public override string ToString() => Username; } } diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 424d7b7a8f..bcb91c1955 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -17,7 +17,7 @@ using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osu.Framework.Graphics.Cursor; using osu.Game.Graphics.Containers; -using osu.Game.Overlays.Profile; +using osu.Game.Overlays.Profile.Header; namespace osu.Game.Users { From 1b9d54a6ad4bd555a965b769d7b7863c625d1509 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 16 Apr 2018 17:39:03 +0900 Subject: [PATCH 16/40] Fix various data races causing crashes or incorrect leaderboard states --- .../Select/Leaderboards/Leaderboard.cs | 79 +++++++++++-------- 1 file changed, 46 insertions(+), 33 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 3a6ab8f84b..a6bbbce9b9 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -39,8 +39,9 @@ namespace osu.Game.Screens.Select.Leaderboards private readonly LoadingAnimation loading; - private IEnumerable scores; + private ScheduledDelegate showScoresDelegate; + private IEnumerable scores; public IEnumerable Scores { get { return scores; } @@ -59,29 +60,34 @@ namespace osu.Game.Screens.Select.Leaderboards // ensure placeholder is hidden when displaying scores PlaceholderState = PlaceholderState.Successful; - // schedule because we may not be loaded yet (LoadComponentAsync complains). - Schedule(() => + var flow = scrollFlow = new FillFlowContainer { - LoadComponentAsync(new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(0f, 5f), - Padding = new MarginPadding { Top = 10, Bottom = 5 }, - ChildrenEnumerable = scores.Select((s, index) => new LeaderboardScore(s, index + 1) { Action = () => ScoreSelected?.Invoke(s) }) - }, f => - { - scrollContainer.Add(scrollFlow = f); + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(0f, 5f), + Padding = new MarginPadding { Top = 10, Bottom = 5 }, + ChildrenEnumerable = scores.Select((s, index) => new LeaderboardScore(s, index + 1) { Action = () => ScoreSelected?.Invoke(s) }) + }; - int i = 0; - foreach (var s in f.Children) - { - using (s.BeginDelayedSequence(i++ * 50, true)) - s.Show(); - } + // schedule because we may not be loaded yet (LoadComponentAsync complains). + showScoresDelegate?.Cancel(); + if (!IsLoaded) + showScoresDelegate = Schedule(showScores); + else + showScores(); - scrollContainer.ScrollTo(0f, false); - }); + void showScores() => LoadComponentAsync(flow, _ => + { + scrollContainer.Add(flow); + + int i = 0; + foreach (var s in flow.Children) + { + using (s.BeginDelayedSequence(i++ * 50, true)) + s.Show(); + } + + scrollContainer.ScrollTo(0f, false); }); } } @@ -249,26 +255,33 @@ namespace osu.Game.Screens.Select.Leaderboards PlaceholderState = PlaceholderState.Retrieving; loading.Show(); + var localBeatmap = Beatmap; + getScoresRequest = new GetScoresRequest(Beatmap, osuGame?.Ruleset.Value ?? Beatmap.Ruleset, Scope); - getScoresRequest.Success += r => + getScoresRequest.Success += r => Schedule(() => { + if (localBeatmap != Beatmap) + return; + Scores = r.Scores; PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; - }; - getScoresRequest.Failure += onUpdateFailed; + }); + + getScoresRequest.Failure += e => Schedule(() => + { + if (localBeatmap != Beatmap) + return; + + if (e is OperationCanceledException) + return; + + PlaceholderState = PlaceholderState.NetworkFailure; + Logger.Error(e, @"Couldn't fetch beatmap scores!"); + }); api.Queue(getScoresRequest); } - private void onUpdateFailed(Exception e) - { - if (e is OperationCanceledException) - return; - - PlaceholderState = PlaceholderState.NetworkFailure; - Logger.Error(e, @"Couldn't fetch beatmap scores!"); - } - private void replacePlaceholder(Placeholder placeholder) { var existingPlaceholder = placeholderContainer.Children.LastOrDefault() as Placeholder; From b9220a1e293c9eef775d6606e398d012c50180dc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 16 Apr 2018 17:39:55 +0900 Subject: [PATCH 17/40] Fix leaderboard placeholder sometimes disappearing indefinitely --- .../Screens/Select/Leaderboards/Leaderboard.cs | 15 ++++++++++----- 1 file changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index a6bbbce9b9..4d8d43f60a 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -282,24 +282,29 @@ namespace osu.Game.Screens.Select.Leaderboards api.Queue(getScoresRequest); } + private Placeholder currentPlaceholder; + private void replacePlaceholder(Placeholder placeholder) { - var existingPlaceholder = placeholderContainer.Children.LastOrDefault() as Placeholder; - - if (placeholder != null && placeholder.Equals(existingPlaceholder)) + if (placeholder != null && placeholder.Equals(currentPlaceholder)) return; - existingPlaceholder?.FadeOut(150, Easing.OutQuint).Expire(); + currentPlaceholder?.FadeOut(150, Easing.OutQuint).Expire(); if (placeholder == null) + { + currentPlaceholder = null; return; + } Scores = null; - placeholderContainer.Add(placeholder); + placeholderContainer.Child = placeholder; placeholder.ScaleTo(0.8f).Then().ScaleTo(1, fade_duration * 3, Easing.OutQuint); placeholder.FadeInFromZero(fade_duration, Easing.OutQuint); + + currentPlaceholder = placeholder; } protected override void Update() From 9af6ef18646d8700ab4be15a6748c8a6f9762c47 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 16 Apr 2018 17:48:49 +0900 Subject: [PATCH 18/40] Remove extra unneded safety --- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 4d8d43f60a..429e6a405d 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -255,23 +255,15 @@ namespace osu.Game.Screens.Select.Leaderboards PlaceholderState = PlaceholderState.Retrieving; loading.Show(); - var localBeatmap = Beatmap; - getScoresRequest = new GetScoresRequest(Beatmap, osuGame?.Ruleset.Value ?? Beatmap.Ruleset, Scope); getScoresRequest.Success += r => Schedule(() => { - if (localBeatmap != Beatmap) - return; - Scores = r.Scores; PlaceholderState = Scores.Any() ? PlaceholderState.Successful : PlaceholderState.NoScores; }); getScoresRequest.Failure += e => Schedule(() => { - if (localBeatmap != Beatmap) - return; - if (e is OperationCanceledException) return; From 9b36cf2066d499f9ca0c57cb7741cee6db6cfc7f Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Mon, 16 Apr 2018 14:14:40 +0200 Subject: [PATCH 19/40] Review changes --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 9 ++- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 8 +-- osu.Game.Rulesets.Osu/OsuRuleset.cs | 13 ++-- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 9 ++- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 - osu.Game/Beatmaps/Legacy/LegacyMods.cs | 59 +++++++++---------- osu.Game/Rulesets/Ruleset.cs | 7 ++- .../Scoring/Legacy/LegacyScoreParser.cs | 2 +- 8 files changed, 54 insertions(+), 55 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 87de1aed97..cfe0fc5cec 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -30,21 +30,20 @@ namespace osu.Game.Rulesets.Catch new KeyBinding(InputKey.Shift, CatchAction.Dash), }; - public override IEnumerable GetLegacyModsFor(LegacyMods mods) + public override IEnumerable ConvertLegacyMods(LegacyMods mods) { - if (mods.HasFlag(LegacyMods.NightCore)) + if (mods.HasFlag(LegacyMods.Nightcore)) yield return new CatchModNightcore(); else if (mods.HasFlag(LegacyMods.DoubleTime)) yield return new CatchModDoubleTime(); - - if (mods.HasFlag(LegacyMods.AutoPlay)) + if (mods.HasFlag(LegacyMods.Autoplay)) yield return new CatchModAutoplay(); if (mods.HasFlag(LegacyMods.Easy)) yield return new CatchModEasy(); - if (mods.HasFlag(LegacyMods.FlashLight)) + if (mods.HasFlag(LegacyMods.Flashlight)) yield return new CatchModFlashlight(); if (mods.HasFlag(LegacyMods.HalfTime)) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 4bd243664b..0546cbc174 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -22,14 +22,14 @@ namespace osu.Game.Rulesets.Mania { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) => new ManiaRulesetContainer(this, beatmap, isForCurrentRuleset); - public override IEnumerable GetLegacyModsFor(LegacyMods mods) + public override IEnumerable ConvertLegacyMods(LegacyMods mods) { - if (mods.HasFlag(LegacyMods.NightCore)) + if (mods.HasFlag(LegacyMods.Nightcore)) yield return new ManiaModNightcore(); else if (mods.HasFlag(LegacyMods.DoubleTime)) yield return new ManiaModDoubleTime(); - if (mods.HasFlag(LegacyMods.AutoPlay)) + if (mods.HasFlag(LegacyMods.Autoplay)) yield return new ManiaModAutoplay(); if (mods.HasFlag(LegacyMods.Easy)) @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Mania if (mods.HasFlag(LegacyMods.FadeIn)) yield return new ManiaModFadeIn(); - if (mods.HasFlag(LegacyMods.FlashLight)) + if (mods.HasFlag(LegacyMods.Flashlight)) yield return new ManiaModFlashlight(); if (mods.HasFlag(LegacyMods.HalfTime)) diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 7611f160ae..e0ecee97a3 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -67,24 +67,23 @@ namespace osu.Game.Rulesets.Osu }; } - public override IEnumerable GetLegacyModsFor(LegacyMods mods) + public override IEnumerable ConvertLegacyMods(LegacyMods mods) { - if (mods.HasFlag(LegacyMods.NightCore)) + if (mods.HasFlag(LegacyMods.Nightcore)) yield return new OsuModNightcore(); else if (mods.HasFlag(LegacyMods.DoubleTime)) yield return new OsuModDoubleTime(); - - if (mods.HasFlag(LegacyMods.AutoPilot)) + if (mods.HasFlag(LegacyMods.Autopilot)) yield return new OsuModAutopilot(); - if (mods.HasFlag(LegacyMods.AutoPlay)) + if (mods.HasFlag(LegacyMods.Autoplay)) yield return new OsuModAutoplay(); if (mods.HasFlag(LegacyMods.Easy)) yield return new OsuModEasy(); - if (mods.HasFlag(LegacyMods.FlashLight)) + if (mods.HasFlag(LegacyMods.Flashlight)) yield return new OsuModFlashlight(); if (mods.HasFlag(LegacyMods.HalfTime)) @@ -111,7 +110,7 @@ namespace osu.Game.Rulesets.Osu if (mods.HasFlag(LegacyMods.SuddenDeath)) yield return new OsuModSuddenDeath(); - if (mods.HasFlag(LegacyMods.TargetPractice)) + if (mods.HasFlag(LegacyMods.Target)) yield return new OsuModTarget(); } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 1881e84fb0..06a8e44a14 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -32,21 +32,20 @@ namespace osu.Game.Rulesets.Taiko new KeyBinding(InputKey.MouseRight, TaikoAction.RightRim), }; - public override IEnumerable GetLegacyModsFor(LegacyMods mods) + public override IEnumerable ConvertLegacyMods(LegacyMods mods) { - if (mods.HasFlag(LegacyMods.NightCore)) + if (mods.HasFlag(LegacyMods.Nightcore)) yield return new TaikoModNightcore(); else if (mods.HasFlag(LegacyMods.DoubleTime)) yield return new TaikoModDoubleTime(); - - if (mods.HasFlag(LegacyMods.AutoPlay)) + if (mods.HasFlag(LegacyMods.Autoplay)) yield return new TaikoModAutoplay(); if (mods.HasFlag(LegacyMods.Easy)) yield return new TaikoModEasy(); - if (mods.HasFlag(LegacyMods.FlashLight)) + if (mods.HasFlag(LegacyMods.Flashlight)) yield return new TaikoModFlashlight(); if (mods.HasFlag(LegacyMods.HalfTime)) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 4a33e5eb7e..48cee0d512 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -54,8 +54,6 @@ namespace osu.Game.Beatmaps { public override IEnumerable GetModsFor(ModType type) => new Mod[] { }; - public override IEnumerable GetLegacyModsFor(LegacyMods mods) => new Mod[] { }; - public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap, bool isForCurrentRuleset) { throw new NotImplementedException(); diff --git a/osu.Game/Beatmaps/Legacy/LegacyMods.cs b/osu.Game/Beatmaps/Legacy/LegacyMods.cs index 2ac7324778..0983610ba0 100644 --- a/osu.Game/Beatmaps/Legacy/LegacyMods.cs +++ b/osu.Game/Beatmaps/Legacy/LegacyMods.cs @@ -9,35 +9,34 @@ namespace osu.Game.Beatmaps.Legacy public enum LegacyMods { None = 0, - NoFail = 1, - Easy = 2, - TouchDevice = 4, - Hidden = 8, - HardRock = 16, - SuddenDeath = 32, - DoubleTime = 64, - Relax = 128, - HalfTime = 256, - NightCore = 512, - FlashLight = 1024, - AutoPlay = 2048, - SpunOut = 4096, - AutoPilot = 8192, - Perfect = 16384, - Key4 = 32768, - Key5 = 65536, - Key6 = 131072, - Key7 = 262144, - Key8 = 524288, - keyMod = 1015808,// k4+k5+k6+k7+k8 - FadeIn = 1048576, - Random = 2097152, - Cinema = 4194304, - TargetPractice = 8388608, - Key9 = 16777216, - Coop = 33554432, - Key1 = 67108864, - Key3 = 134217728, - Key2 = 268435456, + NoFail = 1 << 0, + Easy = 1 << 1, + TouchDevice = 1 << 2, + Hidden = 1 << 3, + HardRock = 1 << 4, + SuddenDeath = 1 << 5, + DoubleTime = 1 << 6, + Relax = 1 << 7, + HalfTime = 1 << 8, + Nightcore = 1 << 9, + Flashlight = 1 << 10, + Autoplay = 1 << 11, + SpunOut = 1 << 12, + Autopilot = 1 << 13, + Perfect = 1 << 14, + Key4 = 1 << 15, + Key5 = 1 << 16, + Key6 = 1 << 17, + Key7 = 1 << 18, + Key8 = 1 << 19, + FadeIn = 1 << 20, + Random = 1 << 21, + Cinema = 1 << 22, + Target = 1 << 23, + Key9 = 1 << 24, + KeyCoop = 1 << 25, + Key1 = 1 << 26, + Key3 = 1 << 27, + Key2 = 1 << 28, } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index f2cf813d38..cd1d030afe 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -34,7 +34,12 @@ namespace osu.Game.Rulesets public abstract IEnumerable GetModsFor(ModType type); - public abstract IEnumerable GetLegacyModsFor(LegacyMods mods); + /// + /// Converts mods from legacy enum values. Do not override if you're not a legacy ruleset. + /// + /// The legacy enum which will be converted + /// An enumerable of constructed s + public virtual IEnumerable ConvertLegacyMods(LegacyMods mods) => new Mod[] { }; public Mod GetAutoplayMod() => GetAllMods().First(mod => mod is ModAutoplay); diff --git a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs index 62d1cb3a32..239f200e29 100644 --- a/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs +++ b/osu.Game/Rulesets/Scoring/Legacy/LegacyScoreParser.cs @@ -66,7 +66,7 @@ namespace osu.Game.Rulesets.Scoring.Legacy /* score.Perfect = */ sr.ReadBoolean(); /* score.EnabledMods = (Mods)*/ - score.Mods = currentRuleset.GetLegacyModsFor((LegacyMods)sr.ReadInt32()).ToArray(); + score.Mods = currentRuleset.ConvertLegacyMods((LegacyMods)sr.ReadInt32()).ToArray(); /* score.HpGraphString = */ sr.ReadString(); /* score.Date = */ From 1feba556ebee972cd812795bd2e0a6135de154e6 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Mon, 16 Apr 2018 14:25:43 +0200 Subject: [PATCH 20/40] CI: unused directive --- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 48cee0d512..0424ff84f1 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics.Textures; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; -using osu.Game.Beatmaps.Legacy; namespace osu.Game.Beatmaps { From af0c49cca88d08c83cf02f88b8da8ae993935bfc Mon Sep 17 00:00:00 2001 From: jorolf Date: Mon, 16 Apr 2018 18:27:18 +0200 Subject: [PATCH 21/40] badge_size is the actual badge size now also fixes rotateBadges bug when hover is lost --- .../Overlays/Profile/Header/BadgeContainer.cs | 15 +++++++-------- 1 file changed, 7 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs index b4d0705e50..c22bba9a43 100644 --- a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs @@ -19,9 +19,8 @@ namespace osu.Game.Overlays.Profile.Header { public class BadgeContainer : Container { - private const float outer_container_width = 98; - private const float outer_container_padding = 3; - private static readonly Vector2 badge_size = new Vector2(outer_container_width - outer_container_padding * 2, 46); + private static readonly Vector2 badge_size = new Vector2(86, 40); + private static readonly MarginPadding outer_padding = new MarginPadding(3); private OsuSpriteText badgeCountText; private FillFlowContainer badgeFlowContainer; @@ -49,8 +48,8 @@ namespace osu.Game.Overlays.Profile.Header Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft, Direction = FillDirection.Vertical, - Padding = new MarginPadding(outer_container_padding), - Width = outer_container_width, + Padding = outer_padding, + Width = badge_size.X + outer_padding.TotalHorizontal * 2, AutoSizeAxes = Axes.Y, Children = new Drawable[] { @@ -117,7 +116,7 @@ namespace osu.Game.Overlays.Profile.Header { LoadComponentAsync(new DrawableBadge(badge) { - Size = badge_size, + Size = badge_size + outer_padding.Total, }, badgeFlowContainer.Add); } } @@ -134,10 +133,10 @@ namespace osu.Game.Overlays.Profile.Header private void onOuterHoverLost() { - rotateBadges(); + badgeFlowContainer.MoveToX(-badge_size.X * visibleBadge, 500, Easing.InOutQuad); badgeFlowContainer.Direction = FillDirection.Horizontal; outerBadgeContainer.AutoSizeAxes = Axes.Y; - outerBadgeContainer.Width = outer_container_width; + outerBadgeContainer.Width = badge_size.X + outer_padding.TotalHorizontal * 2; } private class OuterBadgeContainer : FillFlowContainer From 2a18b4c3f8b46da5417ec071d7d2da243ff85f0d Mon Sep 17 00:00:00 2001 From: jorolf Date: Mon, 16 Apr 2018 18:51:35 +0200 Subject: [PATCH 22/40] add a DRAWABLE_BADGE_SIZE const and center badges --- osu.Game.Tests/Visual/TestCaseUserProfile.cs | 2 +- .../Overlays/Profile/Header/BadgeContainer.cs | 16 +++++++++++----- 2 files changed, 12 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/TestCaseUserProfile.cs index 86af26098a..f691279093 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfile.cs @@ -52,7 +52,7 @@ namespace osu.Game.Tests.Visual { AwardedAt = DateTimeOffset.Now, Description = i.ToString(), - ImageUrl = "Flags/__" + ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg" }).ToArray()), false)); checkSupporterTag(false); diff --git a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs index c22bba9a43..7d8bdc6009 100644 --- a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs @@ -49,7 +49,7 @@ namespace osu.Game.Overlays.Profile.Header Origin = Anchor.BottomLeft, Direction = FillDirection.Vertical, Padding = outer_padding, - Width = badge_size.X + outer_padding.TotalHorizontal * 2, + Width = DrawableBadge.DRAWABLE_BADGE_SIZE.X + outer_padding.TotalHorizontal, AutoSizeAxes = Axes.Y, Children = new Drawable[] { @@ -68,6 +68,8 @@ namespace osu.Game.Overlays.Profile.Header AutoSizeAxes = Axes.Both, Child = badgeFlowContainer = new FillFlowContainer { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, } @@ -86,7 +88,7 @@ namespace osu.Game.Overlays.Profile.Header visibleBadge = (visibleBadge + 1) % badgeCount; - badgeFlowContainer.MoveToX(-badge_size.X * visibleBadge, 500, Easing.InOutQuad); + badgeFlowContainer.MoveToX(-DrawableBadge.DRAWABLE_BADGE_SIZE.X * visibleBadge, 500, Easing.InOutQuad); } private int visibleBadge; @@ -116,7 +118,8 @@ namespace osu.Game.Overlays.Profile.Header { LoadComponentAsync(new DrawableBadge(badge) { - Size = badge_size + outer_padding.Total, + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, }, badgeFlowContainer.Add); } } @@ -136,7 +139,7 @@ namespace osu.Game.Overlays.Profile.Header badgeFlowContainer.MoveToX(-badge_size.X * visibleBadge, 500, Easing.InOutQuad); badgeFlowContainer.Direction = FillDirection.Horizontal; outerBadgeContainer.AutoSizeAxes = Axes.Y; - outerBadgeContainer.Width = badge_size.X + outer_padding.TotalHorizontal * 2; + outerBadgeContainer.Width = DrawableBadge.DRAWABLE_BADGE_SIZE.X + outer_padding.TotalHorizontal; } private class OuterBadgeContainer : FillFlowContainer @@ -161,12 +164,15 @@ namespace osu.Game.Overlays.Profile.Header private class DrawableBadge : Container, IHasTooltip { + public static readonly Vector2 DRAWABLE_BADGE_SIZE = badge_size + outer_padding.Total; + private readonly Badge badge; public DrawableBadge(Badge badge) { this.badge = badge; - Padding = new MarginPadding(3); + Padding = outer_padding; + Size = DRAWABLE_BADGE_SIZE; } [BackgroundDependencyLoader] From 046412f962ed7b85f5279097fa2d595f6702aa8f Mon Sep 17 00:00:00 2001 From: jorolf Date: Mon, 16 Apr 2018 18:52:09 +0200 Subject: [PATCH 23/40] make hover lost transition instant (similar to hover transition) --- osu.Game/Overlays/Profile/Header/BadgeContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs index 7d8bdc6009..7bff7efa48 100644 --- a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs @@ -136,7 +136,7 @@ namespace osu.Game.Overlays.Profile.Header private void onOuterHoverLost() { - badgeFlowContainer.MoveToX(-badge_size.X * visibleBadge, 500, Easing.InOutQuad); + badgeFlowContainer.X = -DrawableBadge.DRAWABLE_BADGE_SIZE.X * visibleBadge; badgeFlowContainer.Direction = FillDirection.Horizontal; outerBadgeContainer.AutoSizeAxes = Axes.Y; outerBadgeContainer.Width = DrawableBadge.DRAWABLE_BADGE_SIZE.X + outer_padding.TotalHorizontal; From de9f15f620c827af040805e99f2de450f1c7c0e6 Mon Sep 17 00:00:00 2001 From: jorolf Date: Mon, 16 Apr 2018 19:22:11 +0200 Subject: [PATCH 24/40] add new test case and fix rotation not working --- .../Visual/TestCaseBadgeContainer.cs | 62 +++++++++++++++++ osu.Game.Tests/Visual/TestCaseUserProfile.cs | 68 ++++++++----------- .../Overlays/Profile/Header/BadgeContainer.cs | 5 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 3 +- 4 files changed, 92 insertions(+), 46 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseBadgeContainer.cs diff --git a/osu.Game.Tests/Visual/TestCaseBadgeContainer.cs b/osu.Game.Tests/Visual/TestCaseBadgeContainer.cs new file mode 100644 index 0000000000..8177e2e272 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseBadgeContainer.cs @@ -0,0 +1,62 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Collections.Generic; +using System.Linq; +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Game.Overlays.Profile.Header; +using osu.Game.Users; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseBadgeContainer : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(BadgeContainer) }; + + public TestCaseBadgeContainer() + { + BadgeContainer badgeContainer; + + Child = badgeContainer = new BadgeContainer + { + RelativeSizeAxes = Axes.Both + }; + + AddStep("Show 1 badge", () => badgeContainer.ShowBadges(new[] + { + new Badge + { + AwardedAt = DateTimeOffset.Now, + Description = "Appreciates compasses", + ImageUrl = "https://assets.ppy.sh/profile-badges/mg2018-1star.png", + } + })); + + AddStep("Show 2 badges", () => badgeContainer.ShowBadges(new[] + { + new Badge + { + AwardedAt = DateTimeOffset.Now, + Description = "Contributed to osu!lazer testing", + ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.png", + }, + new Badge + { + AwardedAt = DateTimeOffset.Now, + Description = "Appreciates compasses", + ImageUrl = "https://assets.ppy.sh/profile-badges/mg2018-1star.png", + } + })); + + AddStep("Show many badges", () => badgeContainer.ShowBadges(Enumerable.Range(1, 20).Select(i => new Badge + { + AwardedAt = DateTimeOffset.Now, + Description = $"Contributed to osu!lazer testing {i} times", + ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg", + }).ToArray())); + } + } +} diff --git a/osu.Game.Tests/Visual/TestCaseUserProfile.cs b/osu.Game.Tests/Visual/TestCaseUserProfile.cs index f691279093..0fdc01a974 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfile.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfile.cs @@ -36,24 +36,36 @@ namespace osu.Game.Tests.Visual { base.LoadComplete(); - AddStep("Show offline dummy", () => profile.ShowUser(createDummyUser(new Badge[0]), false)); - - AddStep("Show with badge", () => profile.ShowUser(createDummyUser(new[] + AddStep("Show offline dummy", () => profile.ShowUser(new User { - new Badge + Username = @"Somebody", + Id = 1, + Country = new Country { FullName = @"Alien" }, + CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg", + JoinDate = DateTimeOffset.Now.AddDays(-1), + LastVisit = DateTimeOffset.Now, + Age = 1, + ProfileOrder = new[] { "me" }, + Statistics = new UserStatistics { - AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569), - Description = "Outstanding help by being a voluntary test subject.", - ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg" + Ranks = new UserStatistics.UserRanks { Global = 2148, Country = 1 }, + PP = 4567.89m, + }, + RankHistory = new User.RankHistoryData + { + Mode = @"osu", + Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() + }, + Badges = new[] + { + new Badge + { + AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569), + Description = "Outstanding help by being a voluntary test subject.", + ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg" + } } - }), false)); - - AddStep("Show many badges", () => profile.ShowUser(createDummyUser(Enumerable.Range(0, 10).Select(i => new Badge - { - AwardedAt = DateTimeOffset.Now, - Description = i.ToString(), - ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg" - }).ToArray()), false)); + }, false)); checkSupporterTag(false); @@ -94,32 +106,6 @@ namespace osu.Game.Tests.Visual AddAssert("no supporter", () => profile.Header.SupporterTag.Alpha == 0); } - private User createDummyUser(Badge[] badges) - { - return new User - { - Username = @"Somebody", - Id = 1, - Country = new Country { FullName = @"Alien" }, - CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c1.jpg", - JoinDate = DateTimeOffset.Now.AddDays(-1), - LastVisit = DateTimeOffset.Now, - Age = 1, - ProfileOrder = new[] { "me" }, - Statistics = new UserStatistics - { - Ranks = new UserStatistics.UserRanks { Global = 2148, Country = 1 }, - PP = 4567.89m, - }, - RankHistory = new User.RankHistoryData - { - Mode = @"osu", - Data = Enumerable.Range(2345, 45).Concat(Enumerable.Range(2109, 40)).ToArray() - }, - Badges = badges - }; - } - private class TestUserProfileOverlay : UserProfileOverlay { public new ProfileHeader Header => base.Header; diff --git a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs index 7bff7efa48..a44940de1c 100644 --- a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs @@ -31,8 +31,6 @@ namespace osu.Game.Overlays.Profile.Header { Child = new Container { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, Masking = true, CornerRadius = 4, AutoSizeAxes = Axes.Both, @@ -68,8 +66,6 @@ namespace osu.Game.Overlays.Profile.Header AutoSizeAxes = Axes.Both, Child = badgeFlowContainer = new FillFlowContainer { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, Direction = FillDirection.Horizontal, AutoSizeAxes = Axes.Both, } @@ -114,6 +110,7 @@ namespace osu.Game.Overlays.Profile.Header badgeCount = badges.Length; visibleBadge = 0; + badgeFlowContainer.Clear(); foreach (var badge in badges) { LoadComponentAsync(new DrawableBadge(badge) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 189eaf0bdf..ec0e45d5ca 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -122,7 +122,8 @@ namespace osu.Game.Overlays.Profile }, badgeContainer = new BadgeContainer { - RelativeSizeAxes = Axes.Both, + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, Origin = Anchor.BottomLeft, Margin = new MarginPadding { Bottom = 5 }, Alpha = 0, From a827fb51bc05b340779f488a245ec3b8978eaaa1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Apr 2018 11:42:55 +0900 Subject: [PATCH 25/40] Simplify child definition --- osu.Game/Overlays/Profile/Header/BadgeContainer.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs index a44940de1c..291db45e97 100644 --- a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs @@ -180,12 +180,15 @@ namespace osu.Game.Overlays.Profile.Header FillMode = FillMode.Fit, RelativeSizeAxes = Axes.Both, Texture = textures.Get(badge.ImageUrl), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - OnLoadComplete = d => d.FadeInFromZero(200) }; } + protected override void LoadComplete() + { + base.LoadComplete(); + Child.FadeInFromZero(200); + } + public string TooltipText => badge.Description; } } From a27f39a55575411584f7bd02c444cfcaece7d6fa Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Apr 2018 11:57:06 +0900 Subject: [PATCH 26/40] Add documentation explaining intertwining logic --- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 429e6a405d..43f6f13db3 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -109,6 +109,10 @@ namespace osu.Game.Screens.Select.Leaderboards private PlaceholderState placeholderState; + /// + /// Update the placeholder visibility. + /// Setting this to anything other than PlaceholderState.Successful will cancel all existing retrieval requests and hide scores. + /// protected PlaceholderState PlaceholderState { get { return placeholderState; } From 188c8ce1e7582f3789827a7004831b35e932bc34 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Apr 2018 11:58:55 +0900 Subject: [PATCH 27/40] Remove unnecessary score nulling (already happens in PlaceholderState_Set) --- osu.Game/Screens/Select/Leaderboards/Leaderboard.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 43f6f13db3..9dae8fb273 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -293,8 +293,6 @@ namespace osu.Game.Screens.Select.Leaderboards return; } - Scores = null; - placeholderContainer.Child = placeholder; placeholder.ScaleTo(0.8f).Then().ScaleTo(1, fade_duration * 3, Easing.OutQuint); From 68a13a5fb50093930d815ae9585c278ff1fccfbd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Apr 2018 14:18:56 +0900 Subject: [PATCH 28/40] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 02d7a0fa47..f858902d16 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 02d7a0fa4798d197cd08570ee48951edbb7c7860 +Subproject commit f858902d167c42d000662cb3a1cd202d723ea182 From d5ce618d9bf32e4098d6a0a2c947981be7d59982 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Apr 2018 15:12:48 +0900 Subject: [PATCH 29/40] Update with framework changes --- osu.Game/Tests/Visual/OsuTestCase.cs | 22 ++++++++++------------ 1 file changed, 10 insertions(+), 12 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index decf0c9bdb..02f425c296 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using System.IO; using System.Reflection; using osu.Framework.Testing; @@ -10,28 +9,27 @@ namespace osu.Game.Tests.Visual { public abstract class OsuTestCase : TestCase { - public override void RunTest() - { - using (var host = new CleanRunHeadlessGameHost($"test-{Guid.NewGuid()}", realtime: false)) - host.Run(new OsuTestCaseTestRunner(this)); - } + protected override ITestCaseTestRunner CreateRunner() => new OsuTestCaseTestRunner(); - public class OsuTestCaseTestRunner : OsuGameBase + public class OsuTestCaseTestRunner : OsuGameBase, ITestCaseTestRunner { - private readonly OsuTestCase testCase; - protected override string MainResourceFile => File.Exists(base.MainResourceFile) ? base.MainResourceFile : Assembly.GetExecutingAssembly().Location; - public OsuTestCaseTestRunner(OsuTestCase testCase) + private readonly TestCaseTestRunner.TestRunner runner; + + public OsuTestCaseTestRunner() { - this.testCase = testCase; + runner = new TestCaseTestRunner.TestRunner(); } protected override void LoadComplete() { base.LoadComplete(); - Add(new TestCaseTestRunner.TestRunner(testCase)); + + Add(runner); } + + public void RunTestBlocking(TestCase test) => runner.RunTestBlocking(test); } } } From 560fcfc661e3a5917631bb472f1adda4276c636e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 18 Apr 2018 15:15:29 +0900 Subject: [PATCH 30/40] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index f858902d16..16e6a453db 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit f858902d167c42d000662cb3a1cd202d723ea182 +Subproject commit 16e6a453db9a8f4454238a2911eb5f1444b7ec2a From 1be2571d33b9561267398042b02d1f30dd25b600 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Apr 2018 16:04:02 +0900 Subject: [PATCH 31/40] Make BeatmapSetOverlay accept nulls everywhere --- .../Visual/TestCaseBeatmapScoresContainer.cs | 4 +- .../Visual/TestCaseBeatmapSetOverlay.cs | 27 +++++ osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/BeatmapSet/AuthorInfo.cs | 56 ++++++---- osu.Game/Overlays/BeatmapSet/BasicStats.cs | 27 ++++- osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs | 33 ++++-- .../{ => Buttons}/DownloadButton.cs | 2 +- .../{ => Buttons}/FavouriteButton.cs | 2 +- .../BeatmapSet/{ => Buttons}/HeaderButton.cs | 4 +- .../BeatmapSet/{ => Buttons}/PreviewButton.cs | 8 +- osu.Game/Overlays/BeatmapSet/Details.cs | 20 +++- osu.Game/Overlays/BeatmapSet/Header.cs | 36 +++++-- osu.Game/Overlays/BeatmapSet/Info.cs | 11 +- .../BeatmapSet/Scores/ScoresContainer.cs | 102 +++++++++++------- osu.Game/Overlays/BeatmapSet/SuccessRate.cs | 26 +++-- osu.Game/Overlays/BeatmapSetOverlay.cs | 43 +++----- osu.Game/Overlays/Direct/PlayButton.cs | 16 +-- .../Sections/BeatmapMetadataContainer.cs | 2 +- .../Carousel/DrawableCarouselBeatmapSet.cs | 2 +- .../Screens/Select/Details/AdvancedStats.cs | 8 +- .../Screens/Select/Details/FailRetryGraph.cs | 6 +- .../Screens/Select/Details/UserRatings.cs | 25 +++-- osu.Game/Users/UpdateableAvatar.cs | 22 ++-- 23 files changed, 322 insertions(+), 162 deletions(-) rename osu.Game/Overlays/BeatmapSet/{ => Buttons}/DownloadButton.cs (97%) rename osu.Game/Overlays/BeatmapSet/{ => Buttons}/FavouriteButton.cs (98%) rename osu.Game/Overlays/BeatmapSet/{ => Buttons}/HeaderButton.cs (94%) rename osu.Game/Overlays/BeatmapSet/{ => Buttons}/PreviewButton.cs (97%) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs index 6cb6a342a8..85f3364039 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs @@ -47,9 +47,7 @@ namespace osu.Game.Tests.Visual AddStep("scores pack 1", () => scoresContainer.Scores = scores); AddStep("scores pack 2", () => scoresContainer.Scores = anotherScores); AddStep("only top score", () => scoresContainer.Scores = new[] { topScore }); - AddStep("remove scores", scoresContainer.CleanAllScores); - AddStep("turn on loading", () => scoresContainer.IsLoading = true); - AddStep("turn off loading", () => scoresContainer.IsLoading = false); + AddStep("remove scores", () => scoresContainer.Scores = null); AddStep("resize to big", () => container.ResizeWidthTo(1, 300)); AddStep("resize to normal", () => container.ResizeWidthTo(0.8f, 300)); diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs b/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs index 69955a90c4..025562f75f 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapSetOverlay.cs @@ -8,6 +8,9 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Overlays; +using osu.Game.Overlays.BeatmapSet; +using osu.Game.Overlays.BeatmapSet.Buttons; +using osu.Game.Overlays.BeatmapSet.Scores; using osu.Game.Rulesets; using osu.Game.Users; @@ -18,6 +21,26 @@ namespace osu.Game.Tests.Visual { private readonly BeatmapSetOverlay overlay; + public override IReadOnlyList RequiredTypes => new[] + { + typeof(Header), + typeof(ClickableUsername), + typeof(DrawableScore), + typeof(DrawableTopScore), + typeof(ScoresContainer), + typeof(AuthorInfo), + typeof(BasicStats), + typeof(BeatmapPicker), + typeof(Details), + typeof(DownloadButton), + typeof(FavouriteButton), + typeof(Header), + typeof(HeaderButton), + typeof(Info), + typeof(PreviewButton), + typeof(SuccessRate), + }; + public TestCaseBeatmapSetOverlay() { Add(overlay = new BeatmapSetOverlay()); @@ -29,6 +52,10 @@ namespace osu.Game.Tests.Visual var mania = rulesets.GetRuleset(3); var taiko = rulesets.GetRuleset(1); + AddStep(@"show loading", () => overlay.ShowBeatmapSet(null)); + + AddStep(@"show online", () => overlay.FetchAndShowBeatmapSet(55)); + AddStep(@"show first", () => { overlay.ShowBeatmapSet(new BeatmapSetInfo diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f69135e5c9..578d88bd89 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -158,7 +158,7 @@ namespace osu.Game /// Show a beatmap set as an overlay. /// /// The set to display. - public void ShowBeatmapSet(int setId) => beatmapSetOverlay.ShowBeatmapSet(setId); + public void ShowBeatmapSet(int setId) => beatmapSetOverlay.FetchAndShowBeatmapSet(setId); /// /// Show a user's profile as an overlay. diff --git a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs index 8b19bca671..66e3148065 100644 --- a/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs +++ b/osu.Game/Overlays/BeatmapSet/AuthorInfo.cs @@ -23,9 +23,8 @@ namespace osu.Game.Overlays.BeatmapSet private readonly ClickableArea clickableArea; private readonly FillFlowContainer fields; - private UserProfileOverlay profile; - private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet { get { return beatmapSet; } @@ -34,28 +33,36 @@ namespace osu.Game.Overlays.BeatmapSet if (value == beatmapSet) return; beatmapSet = value; - var i = BeatmapSet.OnlineInfo; + updateDisplay(); + } + } - avatar.User = BeatmapSet.Metadata.Author; - clickableArea.Action = () => profile?.ShowUser(avatar.User); + private void updateDisplay() + { + avatar.User = BeatmapSet?.Metadata.Author; - fields.Children = new Drawable[] - { - new Field("made by", BeatmapSet.Metadata.Author.Username, @"Exo2.0-RegularItalic"), - new Field("submitted on", i.Submitted.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold") - { - Margin = new MarginPadding { Top = 5 }, - }, - }; + fields.Clear(); + if (BeatmapSet == null) + return; - if (i.Ranked.HasValue) + var online = BeatmapSet.OnlineInfo; + + fields.Children = new Drawable[] + { + new Field("made by", BeatmapSet.Metadata.Author.Username, @"Exo2.0-RegularItalic"), + new Field("submitted on", online.Submitted.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold") { - fields.Add(new Field("ranked on ", i.Ranked.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold")); - } - else if (i.LastUpdated.HasValue) - { - fields.Add(new Field("last updated on ", i.LastUpdated.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold")); - } + Margin = new MarginPadding { Top = 5 }, + }, + }; + + if (online.Ranked.HasValue) + { + fields.Add(new Field("ranked on ", online.Ranked.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold")); + } + else if (online.LastUpdated.HasValue) + { + fields.Add(new Field("last updated on ", online.LastUpdated.Value.ToString(@"MMM d, yyyy"), @"Exo2.0-Bold")); } } @@ -73,6 +80,7 @@ namespace osu.Game.Overlays.BeatmapSet Masking = true, Child = avatar = new UpdateableAvatar { + ShowGuestOnNull = false, Size = new Vector2(height), }, EdgeEffect = new EdgeEffectParameters @@ -95,8 +103,12 @@ namespace osu.Game.Overlays.BeatmapSet [BackgroundDependencyLoader(true)] private void load(UserProfileOverlay profile) { - this.profile = profile; - clickableArea.Action = () => profile?.ShowUser(avatar.User); + clickableArea.Action = () => + { + if (avatar.User != null) profile?.ShowUser(avatar.User); + }; + + updateDisplay(); } private class Field : FillFlowContainer diff --git a/osu.Game/Overlays/BeatmapSet/BasicStats.cs b/osu.Game/Overlays/BeatmapSet/BasicStats.cs index 8fd34914a7..a7b6b16dcc 100644 --- a/osu.Game/Overlays/BeatmapSet/BasicStats.cs +++ b/osu.Game/Overlays/BeatmapSet/BasicStats.cs @@ -18,6 +18,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly Statistic length, bpm, circleCount, sliderCount; private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet { get { return beatmapSet; } @@ -26,11 +27,12 @@ namespace osu.Game.Overlays.BeatmapSet if (value == beatmapSet) return; beatmapSet = value; - bpm.Value = BeatmapSet.OnlineInfo.BPM.ToString(@"0.##"); + updateDisplay(); } } private BeatmapInfo beatmap; + public BeatmapInfo Beatmap { get { return beatmap; } @@ -39,6 +41,22 @@ namespace osu.Game.Overlays.BeatmapSet if (value == beatmap) return; beatmap = value; + updateDisplay(); + } + } + + private void updateDisplay() + { + bpm.Value = BeatmapSet?.OnlineInfo.BPM.ToString(@"0.##") ?? "-"; + + if (beatmap == null) + { + length.Value = string.Empty; + circleCount.Value = string.Empty; + sliderCount.Value = string.Empty; + } + else + { length.Value = TimeSpan.FromSeconds(beatmap.OnlineInfo.Length).ToString(@"m\:ss"); circleCount.Value = beatmap.OnlineInfo.CircleCount.ToString(); sliderCount.Value = beatmap.OnlineInfo.SliderCount.ToString(); @@ -62,12 +80,19 @@ namespace osu.Game.Overlays.BeatmapSet }; } + [BackgroundDependencyLoader] + private void load() + { + updateDisplay(); + } + private class Statistic : Container, IHasTooltip { private readonly string name; private readonly OsuSpriteText value; public string TooltipText => name; + public string Value { get { return value.Text; } diff --git a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs index 87dc9b104b..6b75ac095d 100644 --- a/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs +++ b/osu.Game/Overlays/BeatmapSet/BeatmapPicker.cs @@ -41,9 +41,16 @@ namespace osu.Game.Overlays.BeatmapSet if (value == beatmapSet) return; beatmapSet = value; - Beatmap.Value = BeatmapSet.Beatmaps.First(); - plays.Value = BeatmapSet.OnlineInfo.PlayCount; - favourites.Value = BeatmapSet.OnlineInfo.FavouriteCount; + updateDisplay(); + } + } + + private void updateDisplay() + { + difficulties.Clear(); + + if (BeatmapSet != null) + { difficulties.ChildrenEnumerable = BeatmapSet.Beatmaps.OrderBy(beatmap => beatmap.StarDifficulty).Select(b => new DifficultySelectorButton(b) { State = DifficultySelectorState.NotSelected, @@ -53,14 +60,16 @@ namespace osu.Game.Overlays.BeatmapSet starRating.Text = beatmap.StarDifficulty.ToString("Star Difficulty 0.##"); starRating.FadeIn(100); }, - OnClicked = beatmap => - { - Beatmap.Value = beatmap; - }, + OnClicked = beatmap => { Beatmap.Value = beatmap; }, }); - - updateDifficultyButtons(); } + + starRating.FadeOut(100); + Beatmap.Value = BeatmapSet?.Beatmaps.FirstOrDefault(); + plays.Value = BeatmapSet?.OnlineInfo.PlayCount ?? 0; + favourites.Value = BeatmapSet?.OnlineInfo.FavouriteCount ?? 0; + + updateDifficultyButtons(); } public BeatmapPicker() @@ -140,6 +149,7 @@ namespace osu.Game.Overlays.BeatmapSet private void load(OsuColour colours) { starRating.Colour = colours.Yellow; + updateDisplay(); } protected override void LoadComplete() @@ -150,7 +160,10 @@ namespace osu.Game.Overlays.BeatmapSet Beatmap.TriggerChange(); } - private void showBeatmap(BeatmapInfo beatmap) => version.Text = beatmap.Version; + private void showBeatmap(BeatmapInfo beatmap) + { + version.Text = beatmap?.Version; + } private void updateDifficultyButtons() { diff --git a/osu.Game/Overlays/BeatmapSet/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs similarity index 97% rename from osu.Game/Overlays/BeatmapSet/DownloadButton.cs rename to osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs index 0c6414c718..c699ae2328 100644 --- a/osu.Game/Overlays/BeatmapSet/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs @@ -7,7 +7,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using OpenTK; -namespace osu.Game.Overlays.BeatmapSet +namespace osu.Game.Overlays.BeatmapSet.Buttons { public class DownloadButton : HeaderButton { diff --git a/osu.Game/Overlays/BeatmapSet/FavouriteButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs similarity index 98% rename from osu.Game/Overlays/BeatmapSet/FavouriteButton.cs rename to osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs index 29bc00038c..3821c96369 100644 --- a/osu.Game/Overlays/BeatmapSet/FavouriteButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/FavouriteButton.cs @@ -10,7 +10,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Backgrounds; using OpenTK; -namespace osu.Game.Overlays.BeatmapSet +namespace osu.Game.Overlays.BeatmapSet.Buttons { public class FavouriteButton : HeaderButton { diff --git a/osu.Game/Overlays/BeatmapSet/HeaderButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs similarity index 94% rename from osu.Game/Overlays/BeatmapSet/HeaderButton.cs rename to osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs index e1c4f5cc67..b46b5d2a0e 100644 --- a/osu.Game/Overlays/BeatmapSet/HeaderButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/HeaderButton.cs @@ -1,12 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; -using osu.Framework.Allocation; -namespace osu.Game.Overlays.BeatmapSet +namespace osu.Game.Overlays.BeatmapSet.Buttons { public class HeaderButton : TriangleButton { diff --git a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs similarity index 97% rename from osu.Game/Overlays/BeatmapSet/PreviewButton.cs rename to osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs index 6b5ffa57ad..08a99f1aea 100644 --- a/osu.Game/Overlays/BeatmapSet/PreviewButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/PreviewButton.cs @@ -3,6 +3,7 @@ using osu.Framework.Allocation; using osu.Framework.Audio.Track; +using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -11,12 +12,11 @@ using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Containers; +using osu.Game.Overlays.Direct; using OpenTK; using OpenTK.Graphics; -using osu.Game.Overlays.Direct; -using osu.Framework.Configuration; -namespace osu.Game.Overlays.BeatmapSet +namespace osu.Game.Overlays.BeatmapSet.Buttons { public class PreviewButton : OsuClickableContainer { @@ -85,6 +85,8 @@ namespace osu.Game.Overlays.BeatmapSet // prevent negative (potential infinite) width if a track without length was loaded progress.Width = preview.Length > 0 ? (float)(preview.CurrentTime / preview.Length) : 0f; } + else + progress.Width = 0; } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Overlays/BeatmapSet/Details.cs b/osu.Game/Overlays/BeatmapSet/Details.cs index 7f3b6d1584..5264caf936 100644 --- a/osu.Game/Overlays/BeatmapSet/Details.cs +++ b/osu.Game/Overlays/BeatmapSet/Details.cs @@ -1,11 +1,13 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Beatmaps; +using osu.Game.Overlays.BeatmapSet.Buttons; using osu.Game.Screens.Select.Details; using OpenTK; using OpenTK.Graphics; @@ -20,6 +22,7 @@ namespace osu.Game.Overlays.BeatmapSet private readonly UserRatings ratings; private BeatmapSetInfo beatmapSet; + public BeatmapSetInfo BeatmapSet { get { return beatmapSet; } @@ -33,19 +36,24 @@ namespace osu.Game.Overlays.BeatmapSet } private BeatmapInfo beatmap; + public BeatmapInfo Beatmap { get { return beatmap; } set { if (value == beatmap) return; - beatmap = value; - basic.Beatmap = advanced.Beatmap = Beatmap; - ratings.Metrics = Beatmap.Metrics; + basic.Beatmap = advanced.Beatmap = beatmap = value; + updateDisplay(); } } + private void updateDisplay() + { + ratings.Metrics = Beatmap?.Metrics; + } + public Details() { Width = BeatmapSetOverlay.RIGHT_WIDTH; @@ -88,6 +96,12 @@ namespace osu.Game.Overlays.BeatmapSet }; } + [BackgroundDependencyLoader] + private void load() + { + updateDisplay(); + } + public void StopPreview() => preview.Playing.Value = false; private class DetailBox : Container diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 755039e7bc..9b25d61f58 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -11,6 +11,7 @@ using osu.Game.Beatmaps; using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Overlays.BeatmapSet.Buttons; using OpenTK; using OpenTK.Graphics; @@ -18,7 +19,7 @@ namespace osu.Game.Overlays.BeatmapSet { public class Header : Container { - private const float transition_duration = 250; + private const float transition_duration = 200; private const float tabs_height = 50; private const float buttons_height = 45; private const float buttons_spacing = 5; @@ -34,12 +35,13 @@ namespace osu.Game.Overlays.BeatmapSet public Details Details; private BeatmapManager beatmaps; - private DelayedLoadWrapper cover; public readonly BeatmapPicker Picker; private BeatmapSetInfo beatmapSet; + private readonly FavouriteButton favouriteButton; + public BeatmapSetInfo BeatmapSet { get { return beatmapSet; } @@ -49,15 +51,26 @@ namespace osu.Game.Overlays.BeatmapSet beatmapSet = value; Picker.BeatmapSet = author.BeatmapSet = Details.BeatmapSet = BeatmapSet; - title.Text = BeatmapSet.Metadata.Title; - artist.Text = BeatmapSet.Metadata.Artist; - onlineStatusPill.Status = BeatmapSet.OnlineInfo.Status; - downloadButtonsContainer.FadeIn(); + updateDisplay(); + } + } + + private void updateDisplay() + { + title.Text = BeatmapSet?.Metadata.Title ?? string.Empty; + artist.Text = BeatmapSet?.Metadata.Artist ?? string.Empty; + onlineStatusPill.Status = BeatmapSet?.OnlineInfo.Status ?? BeatmapSetOnlineStatus.None; + + cover?.FadeOut(400, Easing.Out); + if (BeatmapSet != null) + { + downloadButtonsContainer.FadeIn(transition_duration); + favouriteButton.FadeIn(transition_duration); + noVideoButtons.FadeTo(BeatmapSet.OnlineInfo.HasVideo ? 0 : 1, transition_duration); videoButtons.FadeTo(BeatmapSet.OnlineInfo.HasVideo ? 1 : 0, transition_duration); - cover?.FadeOut(400, Easing.Out); coverContainer.Add(cover = new DelayedLoadWrapper( new BeatmapSetCover(BeatmapSet) { @@ -71,6 +84,11 @@ namespace osu.Game.Overlays.BeatmapSet RelativeSizeAxes = Axes.Both, }); } + else + { + downloadButtonsContainer.FadeOut(transition_duration); + favouriteButton.FadeOut(transition_duration); + } } public Header() @@ -166,7 +184,7 @@ namespace osu.Game.Overlays.BeatmapSet Margin = new MarginPadding { Top = 10 }, Children = new Drawable[] { - new FavouriteButton(), + favouriteButton = new FavouriteButton(), downloadButtonsContainer = new Container { RelativeSizeAxes = Axes.Both, @@ -238,6 +256,8 @@ namespace osu.Game.Overlays.BeatmapSet this.beatmaps = beatmaps; beatmaps.ItemAdded += handleBeatmapAdd; + + updateDisplay(); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 9a402515ae..cd0b7386e8 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -34,11 +34,16 @@ namespace osu.Game.Overlays.BeatmapSet if (value == beatmapSet) return; beatmapSet = value; - source.Text = BeatmapSet.Metadata.Source; - tags.Text = BeatmapSet.Metadata.Tags; + updateDisplay(); } } + private void updateDisplay() + { + source.Text = BeatmapSet?.Metadata.Source ?? string.Empty; + tags.Text = BeatmapSet?.Metadata.Tags ?? string.Empty; + } + public BeatmapInfo Beatmap { get { return successRate.Beatmap; } @@ -132,6 +137,8 @@ namespace osu.Game.Overlays.BeatmapSet successRateBackground.Colour = colours.GrayE; source.TextColour = description.TextColour = colours.Gray5; tags.TextColour = colours.BlueDark; + + updateDisplay(); } private class MetadataSection : FillFlowContainer diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index d5c5bd8ddd..185282bec9 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -2,15 +2,15 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API.Requests; using System.Collections.Generic; using System.Linq; +using osu.Framework.Allocation; +using osu.Game.Beatmaps; +using osu.Game.Online.API; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -22,49 +22,75 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly FillFlowContainer flow; private readonly DrawableTopScore topScore; private readonly LoadingAnimation loadingAnimation; - private readonly Box foreground; - private bool isLoading; - public bool IsLoading + private bool loading { - get { return isLoading; } - set - { - if (isLoading == value) return; - isLoading = value; - - foreground.FadeTo(isLoading ? 1 : 0, fade_duration); - loadingAnimation.FadeTo(isLoading ? 1 : 0, fade_duration); - } + set => loadingAnimation.FadeTo(value ? 1 : 0, fade_duration); } private IEnumerable scores; + private BeatmapInfo beatmap; + public IEnumerable Scores { get { return scores; } set { + getScoresRequest?.Cancel(); scores = value; - var scoresAmount = scores.Count(); - if (scoresAmount == 0) - { - CleanAllScores(); - return; - } - topScore.Score = scores.FirstOrDefault(); - topScore.Show(); - - flow.Clear(); - - if (scoresAmount < 2) - return; - - for (int i = 1; i < scoresAmount; i++) - flow.Add(new DrawableScore(i, scores.ElementAt(i))); + updateDisplay(); } } + private GetScoresRequest getScoresRequest; + private APIAccess api; + + public BeatmapInfo Beatmap + { + get => beatmap; + set + { + beatmap = value; + + Scores = null; + + if (beatmap?.OnlineBeatmapID.HasValue != true) + return; + + loading = true; + + getScoresRequest = new GetScoresRequest(beatmap, beatmap.Ruleset); + getScoresRequest.Success += r => Scores = r.Scores; + api.Queue(getScoresRequest); + } + } + + private void updateDisplay() + { + loading = false; + + var scoreCount = scores?.Count() ?? 0; + + if (scoreCount == 0) + { + topScore.Hide(); + flow.Clear(); + return; + } + + topScore.Score = scores.FirstOrDefault(); + topScore.Show(); + + flow.Clear(); + + if (scoreCount < 2) + return; + + for (int i = 1; i < scoreCount; i++) + flow.Add(new DrawableScore(i, scores.ElementAt(i))); + } + public ScoresContainer() { RelativeSizeAxes = Axes.X; @@ -93,23 +119,19 @@ namespace osu.Game.Overlays.BeatmapSet.Scores }, } }, - foreground = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.7f), - Alpha = 0, - }, loadingAnimation = new LoadingAnimation { Alpha = 0, + Margin = new MarginPadding(20) }, }; } - public void CleanAllScores() + [BackgroundDependencyLoader] + private void load(APIAccess api) { - topScore.Hide(); - flow.Clear(); + this.api = api; + updateDisplay(); } } } diff --git a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs index c64d3988a6..6572e520bd 100644 --- a/osu.Game/Overlays/BeatmapSet/SuccessRate.cs +++ b/osu.Game/Overlays/BeatmapSet/SuccessRate.cs @@ -29,18 +29,23 @@ namespace osu.Game.Overlays.BeatmapSet if (value == beatmap) return; beatmap = value; - int passCount = beatmap.OnlineInfo.PassCount; - int playCount = beatmap.OnlineInfo.PlayCount; - - var rate = playCount != 0 ? (float)passCount / playCount : 0; - successPercent.Text = rate.ToString("P0"); - successRate.Length = rate; - percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic); - - graph.Metrics = Beatmap.Metrics; + updateDisplay(); } } + private void updateDisplay() + { + int passCount = beatmap?.OnlineInfo.PassCount ?? 0; + int playCount = beatmap?.OnlineInfo.PlayCount ?? 0; + + var rate = playCount != 0 ? (float)passCount / playCount : 0; + successPercent.Text = rate.ToString("P0"); + successRate.Length = rate; + percentContainer.ResizeWidthTo(successRate.Length, 250, Easing.InOutCubic); + + graph.Metrics = beatmap?.Metrics; + } + public SuccessRate() { Children = new Drawable[] @@ -74,7 +79,6 @@ namespace osu.Game.Overlays.BeatmapSet { Anchor = Anchor.TopRight, Origin = Anchor.TopCentre, - Text = @"0%", TextSize = 13, }, }, @@ -103,6 +107,8 @@ namespace osu.Game.Overlays.BeatmapSet successRateLabel.Colour = successPercent.Colour = graphLabel.Colour = colours.Gray5; successRate.AccentColour = colours.Green; successRate.BackgroundColour = colours.GrayD; + + updateDisplay(); } protected override void UpdateAfterChildren() diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index d2cf0a6ef1..74550e3a9b 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -27,19 +27,31 @@ namespace osu.Game.Overlays private readonly Header header; private readonly Info info; - private readonly ScoresContainer scores; - private APIAccess api; private RulesetStore rulesets; - private GetScoresRequest getScoresRequest; private readonly ScrollContainer scroll; + private BeatmapSetInfo beatmapSet; + + public BeatmapSetInfo BeatmapSet + { + get => beatmapSet; + set + { + if (value == beatmapSet) + return; + + header.BeatmapSet = info.BeatmapSet = beatmapSet = value; + } + } + // receive input outside our bounds so we can trigger a close event on ourselves. public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true; public BeatmapSetOverlay() { + ScoresContainer scores; Waves.FirstWaveColour = OsuColour.Gray(0.4f); Waves.SecondWaveColour = OsuColour.Gray(0.3f); Waves.ThirdWaveColour = OsuColour.Gray(0.2f); @@ -88,31 +100,10 @@ namespace osu.Game.Overlays header.Picker.Beatmap.ValueChanged += b => { info.Beatmap = b; - updateScores(b); + scores.Beatmap = b; }; } - private void updateScores(BeatmapInfo beatmap) - { - getScoresRequest?.Cancel(); - - if (!beatmap.OnlineBeatmapID.HasValue) - { - scores.CleanAllScores(); - return; - } - - scores.IsLoading = true; - - getScoresRequest = new GetScoresRequest(beatmap, beatmap.Ruleset); - getScoresRequest.Success += r => - { - scores.Scores = r.Scores; - scores.IsLoading = false; - }; - api.Queue(getScoresRequest); - } - [BackgroundDependencyLoader] private void load(APIAccess api, RulesetStore rulesets) { @@ -139,7 +130,7 @@ namespace osu.Game.Overlays return true; } - public void ShowBeatmapSet(int beatmapSetId) + public void FetchAndShowBeatmapSet(int beatmapSetId) { // todo: display the overlay while we are loading here. we need to support setting BeatmapSet to null for this to work. var req = new GetBeatmapSetRequest(beatmapSetId); diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index 44e24d8157..4913b11ae1 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -78,12 +78,7 @@ namespace osu.Game.Overlays.Direct loadingAnimation = new LoadingAnimation(), }); - Playing.ValueChanged += playing => - { - icon.Icon = playing ? FontAwesome.fa_pause : FontAwesome.fa_play; - icon.FadeColour(playing || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); - updatePreviewTrack(playing); - }; + Playing.ValueChanged += updatePreviewTrack; } [BackgroundDependencyLoader] @@ -125,6 +120,15 @@ namespace osu.Game.Overlays.Direct private void updatePreviewTrack(bool playing) { + if (playing && BeatmapSet == null) + { + Playing.Value = false; + return; + } + + icon.Icon = playing ? FontAwesome.fa_pause : FontAwesome.fa_play; + icon.FadeColour(playing || IsHovered ? hoverColour : Color4.White, 120, Easing.InOutQuint); + if (playing) { if (Preview == null) diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs index da08c08179..97079c77f3 100644 --- a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs @@ -32,7 +32,7 @@ namespace osu.Game.Overlays.Profile.Sections { Action = () => { - if (beatmap.OnlineBeatmapSetID.HasValue) beatmapSetOverlay?.ShowBeatmapSet(beatmap.OnlineBeatmapSetID.Value); + if (beatmap.OnlineBeatmapSetID.HasValue) beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.OnlineBeatmapSetID.Value); }; Child = new FillFlowContainer diff --git a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs index ad7588edde..d554a22735 100644 --- a/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs +++ b/osu.Game/Screens/Select/Carousel/DrawableCarouselBeatmapSet.cs @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Select.Carousel restoreHiddenRequested = s => s.Beatmaps.ForEach(manager.Restore); dialogOverlay = overlay; if (beatmapOverlay != null) - viewDetails = beatmapOverlay.ShowBeatmapSet; + viewDetails = beatmapOverlay.FetchAndShowBeatmapSet; Children = new Drawable[] { diff --git a/osu.Game/Screens/Select/Details/AdvancedStats.cs b/osu.Game/Screens/Select/Details/AdvancedStats.cs index cad7ed7d81..852e4f190f 100644 --- a/osu.Game/Screens/Select/Details/AdvancedStats.cs +++ b/osu.Game/Screens/Select/Details/AdvancedStats.cs @@ -40,10 +40,10 @@ namespace osu.Game.Screens.Select.Details firstValue.Value = Beatmap?.BaseDifficulty?.CircleSize ?? 0; } - hpDrain.Value = beatmap.BaseDifficulty?.DrainRate ?? 0; - accuracy.Value = beatmap.BaseDifficulty?.OverallDifficulty ?? 0; - approachRate.Value = beatmap.BaseDifficulty?.ApproachRate ?? 0; - starDifficulty.Value = (float)beatmap.StarDifficulty; + hpDrain.Value = Beatmap?.BaseDifficulty?.DrainRate ?? 0; + accuracy.Value = Beatmap?.BaseDifficulty?.OverallDifficulty ?? 0; + approachRate.Value = Beatmap?.BaseDifficulty?.ApproachRate ?? 0; + starDifficulty.Value = (float)(Beatmap?.StarDifficulty ?? 0); } } diff --git a/osu.Game/Screens/Select/Details/FailRetryGraph.cs b/osu.Game/Screens/Select/Details/FailRetryGraph.cs index a33cee21ed..bf4eb07108 100644 --- a/osu.Game/Screens/Select/Details/FailRetryGraph.cs +++ b/osu.Game/Screens/Select/Details/FailRetryGraph.cs @@ -25,10 +25,10 @@ namespace osu.Game.Screens.Select.Details if (value == metrics) return; metrics = value; - var retries = Metrics.Retries; - var fails = Metrics.Fails; + var retries = Metrics?.Retries ?? new int[0]; + var fails = Metrics?.Fails ?? new int[0]; - float maxValue = fails.Zip(retries, (fail, retry) => fail + retry).Max(); + float maxValue = fails.Any() ? fails.Zip(retries, (fail, retry) => fail + retry).Max() : 0; failGraph.MaxValue = maxValue; retryGraph.MaxValue = maxValue; diff --git a/osu.Game/Screens/Select/Details/UserRatings.cs b/osu.Game/Screens/Select/Details/UserRatings.cs index bf50217048..787b22f965 100644 --- a/osu.Game/Screens/Select/Details/UserRatings.cs +++ b/osu.Game/Screens/Select/Details/UserRatings.cs @@ -21,6 +21,7 @@ namespace osu.Game.Screens.Select.Details private readonly BarGraph graph; private BeatmapMetrics metrics; + public BeatmapMetrics Metrics { get { return metrics; } @@ -31,15 +32,25 @@ namespace osu.Game.Screens.Select.Details const int rating_range = 10; - var ratings = Metrics.Ratings.Skip(1).Take(rating_range); // adjust for API returning weird empty data at 0. + if (metrics == null) + { + negativeRatings.Text = "0"; + positiveRatings.Text = "0"; + ratingsBar.Length = 0; + graph.Values = new float[rating_range]; + } + else + { + var ratings = Metrics.Ratings.Skip(1).Take(rating_range); // adjust for API returning weird empty data at 0. - var negativeCount = ratings.Take(rating_range / 2).Sum(); - var totalCount = ratings.Sum(); + var negativeCount = ratings.Take(rating_range / 2).Sum(); + var totalCount = ratings.Sum(); - negativeRatings.Text = negativeCount.ToString(); - positiveRatings.Text = (totalCount - negativeCount).ToString(); - ratingsBar.Length = totalCount == 0 ? 0 : (float)negativeCount / totalCount; - graph.Values = ratings.Take(rating_range).Select(r => (float)r); + negativeRatings.Text = negativeCount.ToString(); + positiveRatings.Text = (totalCount - negativeCount).ToString(); + ratingsBar.Length = totalCount == 0 ? 0 : (float)negativeCount / totalCount; + graph.Values = ratings.Take(rating_range).Select(r => (float)r); + } } } diff --git a/osu.Game/Users/UpdateableAvatar.cs b/osu.Game/Users/UpdateableAvatar.cs index 31455801da..6c0b841abf 100644 --- a/osu.Game/Users/UpdateableAvatar.cs +++ b/osu.Game/Users/UpdateableAvatar.cs @@ -15,6 +15,11 @@ namespace osu.Game.Users private User user; + /// + /// Whether to show a default guest representation on null user (as opposed to nothing). + /// + public bool ShowGuestOnNull = true; + public User User { get { return user; } @@ -40,13 +45,16 @@ namespace osu.Game.Users { displayedAvatar?.FadeOut(300); displayedAvatar?.Expire(); - Add(displayedAvatar = new DelayedLoadWrapper( - new Avatar(user) - { - RelativeSizeAxes = Axes.Both, - OnLoadComplete = d => d.FadeInFromZero(300, Easing.OutQuint), - }) - ); + if (user != null || ShowGuestOnNull) + { + Add(displayedAvatar = new DelayedLoadWrapper( + new Avatar(user) + { + RelativeSizeAxes = Axes.Both, + OnLoadComplete = d => d.FadeInFromZero(300, Easing.OutQuint), + }) + ); + } } } } From e395a471125bc360035062e25a62856859cd1d0a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 18 Apr 2018 19:26:54 +0900 Subject: [PATCH 32/40] Changes to naming and text --- osu.Game/Configuration/OsuConfigManager.cs | 4 ++-- .../Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs | 4 ++-- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 3 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index ebc674c900..3efaa02a31 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -86,7 +86,7 @@ namespace osu.Game.Configuration Set(OsuSetting.ScreenshotFormat, ScreenshotFormat.Jpg); Set(OsuSetting.ScreenshotCaptureMenuCursor, false); - Set(OsuSetting.SelectScrollRightClick, false); + Set(OsuSetting.SongSelectRightMouseScroll, false); } public OsuConfigManager(Storage storage) : base(storage) @@ -133,6 +133,6 @@ namespace osu.Game.Configuration Skin, ScreenshotFormat, ScreenshotCaptureMenuCursor, - SelectScrollRightClick + SongSelectRightMouseScroll } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs index c3d8022a63..7893d76fb8 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/SongSelectSettings.cs @@ -19,8 +19,8 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { new SettingsCheckbox { - LabelText = "Right click to scroll", - Bindable = config.GetBindable(OsuSetting.SelectScrollRightClick), + LabelText = "Right mouse drag to absolute scroll", + Bindable = config.GetBindable(OsuSetting.SongSelectRightMouseScroll), }, new SettingsCheckbox { diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index e88fec8106..3c9a14e1f4 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -125,7 +125,7 @@ namespace osu.Game.Screens.Select private void load(OsuConfigManager config) { config.BindWith(OsuSetting.RandomSelectAlgorithm, RandomAlgorithm); - config.BindWith(OsuSetting.SelectScrollRightClick, RightClickScrollingEnabled); + config.BindWith(OsuSetting.SongSelectRightMouseScroll, RightClickScrollingEnabled); RightClickScrollingEnabled.ValueChanged += v => RightMouseScrollbar = v; RightClickScrollingEnabled.TriggerChange(); From 278a878b09fc08d5a854f3d11c736738c90a31d4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Apr 2018 15:52:24 +0900 Subject: [PATCH 33/40] Add non-interactive deploy mode --- osu.Desktop.Deploy/Program.cs | 22 +++++++++++++++++----- 1 file changed, 17 insertions(+), 5 deletions(-) diff --git a/osu.Desktop.Deploy/Program.cs b/osu.Desktop.Deploy/Program.cs index 6095ce062d..8c460f03cf 100644 --- a/osu.Desktop.Deploy/Program.cs +++ b/osu.Desktop.Deploy/Program.cs @@ -57,8 +57,12 @@ namespace osu.Desktop.Deploy private static string codeSigningPassword; + private static bool interactive; + public static void Main(string[] args) { + interactive = args.Length == 0; + displayHeader(); findSolutionPath(); @@ -82,15 +86,15 @@ namespace osu.Desktop.Deploy string version = $"{verBase}{increment}"; Console.ForegroundColor = ConsoleColor.White; - Console.Write($"Ready to deploy {version}: "); - Console.ReadLine(); + Console.Write($"Ready to deploy {version}!"); + pauseIfInteractive(); sw.Start(); if (!string.IsNullOrEmpty(CodeSigningCertificate)) { Console.Write("Enter code signing password: "); - codeSigningPassword = readLineMasked(); + codeSigningPassword = args.Length > 0 ? args[0] : readLineMasked(); } write("Updating AssemblyInfo..."); @@ -124,7 +128,7 @@ namespace osu.Desktop.Deploy updateCsprojVersion("0.0.0"); write("Done!", ConsoleColor.White); - Console.ReadLine(); + pauseIfInteractive(); } private static void displayHeader() @@ -388,10 +392,18 @@ namespace osu.Desktop.Deploy Console.ForegroundColor = ConsoleColor.Red; Console.WriteLine($"FATAL ERROR: {message}"); - Console.ReadLine(); + pauseIfInteractive(); Environment.Exit(-1); } + private static void pauseIfInteractive() + { + if (interactive) + Console.ReadLine(); + else + Console.WriteLine(); + } + private static void write(string message, ConsoleColor col = ConsoleColor.Gray) { if (sw.ElapsedMilliseconds > 0) From 312068d7a29716ab1737c4aa86b4a3bee6153df4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Apr 2018 17:15:06 +0900 Subject: [PATCH 34/40] Add deploy config --- appveyor_deploy.yml | 28 ++++++++++++++++++++++++++++ 1 file changed, 28 insertions(+) create mode 100644 appveyor_deploy.yml diff --git a/appveyor_deploy.yml b/appveyor_deploy.yml new file mode 100644 index 0000000000..3887557fcb --- /dev/null +++ b/appveyor_deploy.yml @@ -0,0 +1,28 @@ +# 2017-09-14 +clone_depth: 1 +version: '{branch}-{build}' +image: Visual Studio 2017 +configuration: Debug +cache: + - packages -> **\packages.config +install: + - cmd: git submodule update --init --recursive --depth=5 +before_build: + - cmd: nuget restore -verbosity quiet +build: + project: osu.Desktop.Deploy/osu.Desktop.Deploy.csproj + verbosity: minimal +after_build: + - ps: iex ((New-Object Net.WebClient).DownloadString('https://raw.githubusercontent.com/appveyor/secure-file/master/install.ps1')) + - appveyor DownloadFile https://puu.sh/A6g5K/4d08705438.enc # signing certificate + - cmd: appveyor-tools\secure-file -decrypt 4d08705438.enc -secret %decode_secret% -out %HOMEPATH%\deanherbert.pfx + - appveyor DownloadFile https://puu.sh/A6g75/fdc6f19b04.enc # deploy configuration + - cmd: appveyor-tools\secure-file -decrypt fdc6f19b04.enc -secret %decode_secret% -out osu.Desktop.Deploy\bin\Debug\net461\osu.Desktop.Deploy.exe.config + - cd osu.Desktop.Deploy\bin\Debug\net461\ + - osu.Desktop.Deploy.exe %code_signing_password% +environment: + TargetFramework: net461 + decode_secret: + secure: i67IC2xj6DjjxmA6Oj2jing3+MwzLkq6CbGsjfZ7rdY= + code_signing_password: + secure: 34tLNqvjmmZEi97MLKfrnQ== From 8a243461a697d6cfcf1c8adec6167fb523b22775 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Apr 2018 17:42:06 +0900 Subject: [PATCH 35/40] Expose appveyor artifacts --- appveyor_deploy.yml | 2 ++ 1 file changed, 2 insertions(+) diff --git a/appveyor_deploy.yml b/appveyor_deploy.yml index 3887557fcb..cd241eb88f 100644 --- a/appveyor_deploy.yml +++ b/appveyor_deploy.yml @@ -26,3 +26,5 @@ environment: secure: i67IC2xj6DjjxmA6Oj2jing3+MwzLkq6CbGsjfZ7rdY= code_signing_password: secure: 34tLNqvjmmZEi97MLKfrnQ== +artifacts: + - path: 'Releases\*' \ No newline at end of file From 0356e5e6bf9a31ed35a3741d64d5649cf39093e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Apr 2018 21:00:22 +0900 Subject: [PATCH 36/40] Remove unused property --- osu.Game/Overlays/BeatmapSetOverlay.cs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSetOverlay.cs b/osu.Game/Overlays/BeatmapSetOverlay.cs index 74550e3a9b..366c34eae3 100644 --- a/osu.Game/Overlays/BeatmapSetOverlay.cs +++ b/osu.Game/Overlays/BeatmapSetOverlay.cs @@ -32,20 +32,6 @@ namespace osu.Game.Overlays private readonly ScrollContainer scroll; - private BeatmapSetInfo beatmapSet; - - public BeatmapSetInfo BeatmapSet - { - get => beatmapSet; - set - { - if (value == beatmapSet) - return; - - header.BeatmapSet = info.BeatmapSet = beatmapSet = value; - } - } - // receive input outside our bounds so we can trigger a close event on ourselves. public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => true; From 77af8ce556cde3b36c32fe7771404cb5daa87f30 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 19 Apr 2018 21:11:16 +0900 Subject: [PATCH 37/40] Add back online load test for BeatmapScoresContainer --- osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs | 4 ++++ 1 file changed, 4 insertions(+) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs index 85f3364039..5be7386238 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs @@ -14,6 +14,8 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Users; using System.Collections.Generic; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Visual { @@ -50,6 +52,8 @@ namespace osu.Game.Tests.Visual AddStep("remove scores", () => scoresContainer.Scores = null); AddStep("resize to big", () => container.ResizeWidthTo(1, 300)); AddStep("resize to normal", () => container.ResizeWidthTo(0.8f, 300)); + AddStep("online scores", () => scoresContainer.Beatmap = new BeatmapInfo { OnlineBeatmapSetID = 1, OnlineBeatmapID = 75, Ruleset = new OsuRuleset().RulesetInfo }); + scores = new[] { From 64709da5461d35d6e66ed02bc6f81c1940296b48 Mon Sep 17 00:00:00 2001 From: tgi74000 Date: Thu, 19 Apr 2018 14:46:42 +0200 Subject: [PATCH 38/40] Update profile header to osu-web changes --- osu.Game/Overlays/Profile/ProfileHeader.cs | 10 ++++++++-- osu.Game/Users/User.cs | 6 ++++++ 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index ec0e45d5ca..361804a367 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -350,7 +350,7 @@ namespace osu.Game.Overlays.Profile if (user.Country != null) { - infoTextLeft.AddText("from ", lightText); + infoTextLeft.AddText("From ", lightText); infoTextLeft.AddText(user.Country.FullName, boldItalic); countryFlag.Country = user.Country; } @@ -378,6 +378,10 @@ namespace osu.Game.Overlays.Profile infoTextLeft.AddText(string.Join(", ", user.PlayStyle), boldItalic); } + infoTextLeft.NewLine(); + infoTextLeft.AddText("Contributed ", lightText); + infoTextLeft.AddText($@"{user.PostCount} forum posts", boldItalic); + string websiteWithoutProtcol = user.Website; if (!string.IsNullOrEmpty(websiteWithoutProtcol)) { @@ -392,8 +396,10 @@ namespace osu.Game.Overlays.Profile infoTextRight.NewParagraph(); if (!string.IsNullOrEmpty(user.Twitter)) tryAddInfoRightLine(FontAwesome.fa_twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); - tryAddInfoRightLine(FontAwesome.fa_globe, websiteWithoutProtcol, user.Website); + tryAddInfoRightLine(FontAwesome.fa_question, user.Discord); tryAddInfoRightLine(FontAwesome.fa_skype, user.Skype, @"skype:" + user.Skype + @"?chat"); + tryAddInfoRightLine(FontAwesome.fa_lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); + tryAddInfoRightLine(FontAwesome.fa_globe, websiteWithoutProtcol, user.Website); if (user.Statistics != null) { diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index b983b639f0..e1f68e1ce8 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -98,9 +98,15 @@ namespace osu.Game.Users [JsonProperty(@"skype")] public string Skype; + [JsonProperty(@"discord")] + public string Discord; + [JsonProperty(@"website")] public string Website; + [JsonProperty(@"post_count")] + public int PostCount; + [JsonProperty(@"playstyle")] public string[] PlayStyle; From 8649ddc68b407ec12a0f84c1eeffdba101d296b1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Apr 2018 13:01:23 +0900 Subject: [PATCH 39/40] Make forum posts a web link --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 4 ++-- osu.Game/Overlays/Profile/ProfileHeader.cs | 6 +++--- 2 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 8e18dbd2f5..c39e9abf8b 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -61,9 +61,9 @@ namespace osu.Game.Graphics.Containers AddText(text.Substring(previousLinkEnd)); } - public void AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null) + public void AddLink(string text, string url, LinkAction linkType = LinkAction.External, string linkArgument = null, string tooltipText = null, Action creationParameters = null) { - AddInternal(new DrawableLinkCompiler(AddText(text).ToList()) + AddInternal(new DrawableLinkCompiler(AddText(text, creationParameters).ToList()) { TooltipText = tooltipText ?? (url != text ? url : string.Empty), Action = () => diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 361804a367..49a4f71fd8 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Profile { public class ProfileHeader : Container { - private readonly OsuTextFlowContainer infoTextLeft; + private readonly LinkFlowContainer infoTextLeft; private readonly LinkFlowContainer infoTextRight; private readonly FillFlowContainer scoreText, scoreNumberText; private readonly RankGraph rankGraph; @@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Profile } } }, - infoTextLeft = new OsuTextFlowContainer(t => t.TextSize = 14) + infoTextLeft = new LinkFlowContainer(t => t.TextSize = 14) { X = UserProfileOverlay.CONTENT_X_MARGIN, Y = cover_height + 20, @@ -380,7 +380,7 @@ namespace osu.Game.Overlays.Profile infoTextLeft.NewLine(); infoTextLeft.AddText("Contributed ", lightText); - infoTextLeft.AddText($@"{user.PostCount} forum posts", boldItalic); + infoTextLeft.AddLink($@"{user.PostCount} forum posts", url: $"https://osu.ppy.sh/users/{user.Id}/posts", creationParameters: boldItalic); string websiteWithoutProtcol = user.Website; if (!string.IsNullOrEmpty(websiteWithoutProtcol)) From a64ed142f07e6ddade0ea17110a1e92124d2c8c3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 20 Apr 2018 13:51:30 +0900 Subject: [PATCH 40/40] Use a more suiting icon for discord for now --- osu.Game/Overlays/Profile/ProfileHeader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 49a4f71fd8..4c411b3210 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -396,7 +396,7 @@ namespace osu.Game.Overlays.Profile infoTextRight.NewParagraph(); if (!string.IsNullOrEmpty(user.Twitter)) tryAddInfoRightLine(FontAwesome.fa_twitter, "@" + user.Twitter, $@"https://twitter.com/{user.Twitter}"); - tryAddInfoRightLine(FontAwesome.fa_question, user.Discord); + tryAddInfoRightLine(FontAwesome.fa_gamepad, user.Discord); tryAddInfoRightLine(FontAwesome.fa_skype, user.Skype, @"skype:" + user.Skype + @"?chat"); tryAddInfoRightLine(FontAwesome.fa_lastfm, user.Lastfm, $@"https://last.fm/users/{user.Lastfm}"); tryAddInfoRightLine(FontAwesome.fa_globe, websiteWithoutProtcol, user.Website);