From a7bdaf75b0731125ddda2a5b7a3d84680279ceaf Mon Sep 17 00:00:00 2001 From: jorolf Date: Tue, 22 May 2018 13:05:15 +0200 Subject: [PATCH 01/34] Ensure badges are ordered correctly --- osu.Game/Overlays/Profile/Header/BadgeContainer.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs index 36a9a9b01a..c97a4de464 100644 --- a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs @@ -113,7 +113,11 @@ namespace osu.Game.Overlays.Profile.Header { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, - }, badgeFlowContainer.Add); + }, asyncBadge => + { + badgeFlowContainer.Add(asyncBadge); + badgeFlowContainer.ChangeChildDepth(asyncBadge, Array.IndexOf(badges, asyncBadge)); //Ensure the badges are ordered correctly + }); } } From 2ccffb9ac452b443c9cb09ccf44f158cd04031ee Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 28 May 2018 01:10:41 +0900 Subject: [PATCH 02/34] Add difficulty calculation mod types --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 94 ++++++++++++++++++++++++- osu.Game.Rulesets.Osu/OsuRuleset.cs | 44 +++++++++++- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 44 +++++++++++- osu.Game/Rulesets/Mods/ModType.cs | 1 + 4 files changed, 175 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 02ecb3afda..08fecacbab 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -96,6 +96,20 @@ namespace osu.Game.Rulesets.Mania yield return new ManiaModSuddenDeath(); } + private static readonly Mod[] key_mods = + { + new MultiMod(), + new ManiaModKey1(), + new ManiaModKey2(), + new ManiaModKey3(), + new ManiaModKey4(), + new ManiaModKey5(), + new ManiaModKey6(), + new ManiaModKey7(), + new ManiaModKey8(), + new ManiaModKey9(), + }; + public override IEnumerable GetModsFor(ModType type) { switch (type) @@ -114,7 +128,6 @@ namespace osu.Game.Rulesets.Mania }, }, }; - case ModType.DifficultyIncrease: return new Mod[] { @@ -145,7 +158,6 @@ namespace osu.Game.Rulesets.Mania }, new ManiaModFlashlight(), }; - case ModType.Special: return new Mod[] { @@ -176,7 +188,85 @@ namespace osu.Game.Rulesets.Mania }, }, }; + case ModType.DifficultyCalculation: + var mods = new List(); + foreach (var keyMod in key_mods) + { + mods.AddRange(new[] + { + keyMod, + new MultiMod + { + Mods = new[] + { + keyMod, + new ManiaModDoubleTime(), + } + }, + new MultiMod + { + Mods = new[] + { + keyMod, + new ManiaModHalfTime(), + } + }, + new MultiMod + { + Mods = new[] + { + keyMod, + new ManiaModEasy(), + } + }, + new MultiMod + { + Mods = new[] + { + keyMod, + new ManiaModHardRock(), + } + }, + new MultiMod + { + Mods = new[] + { + keyMod, + new ManiaModEasy(), + new ManiaModDoubleTime(), + } + }, + new MultiMod + { + Mods = new[] + { + keyMod, + new ManiaModEasy(), + new ManiaModHalfTime(), + } + }, + new MultiMod + { + Mods = new[] + { + keyMod, + new ManiaModHardRock(), + new ManiaModDoubleTime(), + } + }, + new MultiMod + { + Mods = new[] + { + keyMod, + new ManiaModHardRock(), + new ManiaModHalfTime(), + } + }, + }); + } + return mods.ToArray(); default: return new Mod[] { }; } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index c455bb2af6..31eff5493b 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -102,7 +102,6 @@ namespace osu.Game.Rulesets.Osu }, }, }; - case ModType.DifficultyIncrease: return new Mod[] { @@ -126,7 +125,6 @@ namespace osu.Game.Rulesets.Osu new OsuModHidden(), new OsuModFlashlight(), }; - case ModType.Special: return new Mod[] { @@ -143,7 +141,47 @@ namespace osu.Game.Rulesets.Osu }, new OsuModTarget(), }; - + case ModType.DifficultyCalculation: + return new Mod[] + { + new MultiMod(), + new OsuModDoubleTime(), + new OsuModHalfTime(), + new OsuModEasy(), + new OsuModHardRock(), + new MultiMod + { + Mods = new Mod[] + { + new OsuModEasy(), + new OsuModDoubleTime(), + } + }, + new MultiMod + { + Mods = new Mod[] + { + new OsuModEasy(), + new OsuModHalfTime(), + } + }, + new MultiMod + { + Mods = new Mod[] + { + new OsuModHardRock(), + new OsuModDoubleTime(), + } + }, + new MultiMod + { + Mods = new Mod[] + { + new OsuModHardRock(), + new OsuModHalfTime(), + } + }, + }; default: return new Mod[] { }; } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index abaa8db597..a249646285 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -93,7 +93,6 @@ namespace osu.Game.Rulesets.Taiko }, }, }; - case ModType.DifficultyIncrease: return new Mod[] { @@ -117,7 +116,6 @@ namespace osu.Game.Rulesets.Taiko new TaikoModHidden(), new TaikoModFlashlight(), }; - case ModType.Special: return new Mod[] { @@ -133,7 +131,47 @@ namespace osu.Game.Rulesets.Taiko }, }, }; - + case ModType.DifficultyCalculation: + return new Mod[] + { + new MultiMod(), + new TaikoModDoubleTime(), + new TaikoModHalfTime(), + new TaikoModEasy(), + new TaikoModHardRock(), + new MultiMod + { + Mods = new Mod[] + { + new TaikoModEasy(), + new TaikoModDoubleTime(), + } + }, + new MultiMod + { + Mods = new Mod[] + { + new TaikoModEasy(), + new TaikoModHalfTime(), + } + }, + new MultiMod + { + Mods = new Mod[] + { + new TaikoModHardRock(), + new TaikoModDoubleTime(), + } + }, + new MultiMod + { + Mods = new Mod[] + { + new TaikoModHardRock(), + new TaikoModHalfTime(), + } + }, + }; default: return new Mod[] { }; } diff --git a/osu.Game/Rulesets/Mods/ModType.cs b/osu.Game/Rulesets/Mods/ModType.cs index 1941724879..5619899c48 100644 --- a/osu.Game/Rulesets/Mods/ModType.cs +++ b/osu.Game/Rulesets/Mods/ModType.cs @@ -8,5 +8,6 @@ namespace osu.Game.Rulesets.Mods DifficultyReduction, DifficultyIncrease, Special, + DifficultyCalculation } } From 7b7236929a0e2166b94d6f66eb6bbdc0334eb588 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 06:08:39 -0300 Subject: [PATCH 03/34] Add BeatmapSetDownloadButton. --- .../UserInterface/BeatmapSetDownloadButton.cs | 83 +++++++++++++++++++ 1 file changed, 83 insertions(+) create mode 100644 osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs diff --git a/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs b/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs new file mode 100644 index 0000000000..091b0ddbd4 --- /dev/null +++ b/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs @@ -0,0 +1,83 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Input; +using osu.Game.Beatmaps; +using osu.Game.Graphics.Containers; +using osu.Game.Online.API; + +namespace osu.Game.Graphics.UserInterface +{ + public abstract class BeatmapSetDownloadButton : OsuClickableContainer + { + private readonly BeatmapSetInfo set; + private readonly bool noVideo; + private readonly BindableBool downloaded = new BindableBool(); + + private Action action; + public Action Action + { + get => action; + set => action = value; + } + + protected BeatmapSetDownloadButton(BeatmapSetInfo set, bool noVideo = false) + { + this.set = set; + this.noVideo = noVideo; + + downloaded.ValueChanged += e => + { + if (e) + Disable(); + else + Enable(); + }; + } + + [BackgroundDependencyLoader] + private void load(BeatmapManager beatmaps, APIAccess api) + { + beatmaps.ItemAdded += s => + { + if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) + downloaded.Value = true; + }; + + beatmaps.ItemRemoved += s => + { + if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) + downloaded.Value = false; + }; + + // initial downloaded value + downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Count() != 0; + + Action = () => + { + if (beatmaps.GetExistingDownload(set) != null) + { + AlreadyDownloading(); + return; + } + + beatmaps.Download(set, noVideo); + }; + } + + protected override bool OnClick(InputState state) + { + if (!downloaded.Value) + Action?.Invoke(); + return true; + } + + protected abstract void Enable(); + protected abstract void Disable(); + protected abstract void AlreadyDownloading(); + } +} From b332c22fe5c418438cd70fc72c1c6afe0a363062 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 06:29:35 -0300 Subject: [PATCH 04/34] Update DirectPanel to use BeatmapSetDownloadButton. --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 3 +-- osu.Game/Overlays/Direct/DirectListPanel.cs | 3 +-- osu.Game/Overlays/Direct/DirectPanel.cs | 16 -------------- osu.Game/Overlays/Direct/DownloadButton.cs | 21 ++++++++++++++++--- osu.Game/Overlays/DirectOverlay.cs | 23 +-------------------- 5 files changed, 21 insertions(+), 45 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index ed4630a8e7..723e9e8b35 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -166,14 +166,13 @@ namespace osu.Game.Overlays.Direct }, }, }, - new DownloadButton + new DownloadButton(SetInfo) { Size = new Vector2(30), Margin = new MarginPadding(horizontal_padding), Anchor = Anchor.CentreRight, Origin = Anchor.CentreRight, Colour = colours.Gray5, - Action = StartDownload }, }, }, diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 13398a4a32..c949e0d088 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -144,12 +144,11 @@ namespace osu.Game.Overlays.Direct }, }, }, - new DownloadButton + new DownloadButton(SetInfo) { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Size = new Vector2(height - vertical_padding * 2), - Action = StartDownload }, }, }, diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index df784252ce..e767f6ec83 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -147,22 +147,6 @@ namespace osu.Game.Overlays.Direct protected void ShowInformation() => beatmapSetOverlay?.ShowBeatmapSet(SetInfo); - protected void StartDownload() - { - if (beatmaps.GetExistingDownload(SetInfo) != null) - { - // we already have an active download running. - content.MoveToX(-5, 50, Easing.OutSine).Then() - .MoveToX(5, 100, Easing.InOutSine).Then() - .MoveToX(-5, 100, Easing.InOutSine).Then() - .MoveToX(0, 50, Easing.InSine).Then(); - - return; - } - - beatmaps.Download(SetInfo); - } - private void attachDownload(DownloadBeatmapSetRequest request) { if (request.BeatmapSet.OnlineBeatmapSetID != SetInfo.OnlineBeatmapSetID) diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index f01c9dac59..a6d7a4215d 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -3,17 +3,18 @@ using osu.Framework.Graphics; using osu.Framework.Input; +using osu.Game.Beatmaps; using osu.Game.Graphics; -using osu.Game.Graphics.Containers; +using osu.Game.Graphics.UserInterface; using OpenTK; namespace osu.Game.Overlays.Direct { - public class DownloadButton : OsuClickableContainer + public class DownloadButton : BeatmapSetDownloadButton { private readonly SpriteIcon icon; - public DownloadButton() + public DownloadButton(BeatmapSetInfo set, bool noVideo = false) : base(set, noVideo) { Children = new Drawable[] { @@ -49,5 +50,19 @@ namespace osu.Game.Overlays.Direct { icon.ScaleTo(1f, 500, Easing.OutElastic); } + + protected override void Enable() + { + this.FadeIn(200); + } + + protected override void Disable() + { + this.FadeOut(200); + } + + protected override void AlreadyDownloading() + { + } } } diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index f437546888..99f6de8559 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -28,7 +28,6 @@ namespace osu.Game.Overlays private APIAccess api; private RulesetStore rulesets; - private BeatmapManager beatmaps; private readonly FillFlowContainer resultCountsContainer; private readonly OsuSpriteText resultCountsText; @@ -181,20 +180,10 @@ namespace osu.Game.Overlays { this.api = api; this.rulesets = rulesets; - this.beatmaps = beatmaps; resultCountsContainer.Colour = colours.Yellow; - - beatmaps.ItemAdded += setAdded; } - private void setAdded(BeatmapSetInfo set) => Schedule(() => - { - // if a new map was imported, we should remove it from search results (download completed etc.) - panels?.FirstOrDefault(p => p.SetInfo.OnlineBeatmapSetID == set.OnlineBeatmapSetID)?.FadeOut(400).Expire(); - BeatmapSets = BeatmapSets?.Where(b => b.OnlineBeatmapSetID != set.OnlineBeatmapSetID); - }); - private void updateResultCounts() { resultCountsContainer.FadeTo(ResultAmounts == null ? 0f : 1f, 200, Easing.OutQuint); @@ -297,9 +286,7 @@ namespace osu.Game.Overlays { Task.Run(() => { - var onlineIds = response.Select(r => r.OnlineBeatmapSetID).ToList(); - var presentOnlineIds = beatmaps.QueryBeatmapSets(s => onlineIds.Contains(s.OnlineBeatmapSetID) && !s.DeletePending).Select(r => r.OnlineBeatmapSetID).ToList(); - var sets = response.Select(r => r.ToBeatmapSet(rulesets)).Where(b => !presentOnlineIds.Contains(b.OnlineBeatmapSetID)).ToList(); + var sets = response.Select(r => r.ToBeatmapSet(rulesets)).ToList(); // may not need scheduling; loads async internally. Schedule(() => @@ -323,14 +310,6 @@ namespace osu.Game.Overlays private int distinctCount(List list) => list.Distinct().ToArray().Length; - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - if (beatmaps != null) - beatmaps.ItemAdded -= setAdded; - } - public class ResultCounts { public readonly int Artists; From 7eeba2cf9a83934a13aade4fcaecf3b7e4206203 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 06:34:48 -0300 Subject: [PATCH 05/34] Unsubscribe from BeatmapManager events in Dispose. --- .../UserInterface/BeatmapSetDownloadButton.cs | 38 ++++++++++++++----- 1 file changed, 28 insertions(+), 10 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs b/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs index 091b0ddbd4..39bbc8216a 100644 --- a/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs +++ b/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs @@ -18,6 +18,8 @@ namespace osu.Game.Graphics.UserInterface private readonly bool noVideo; private readonly BindableBool downloaded = new BindableBool(); + private BeatmapManager beatmaps; + private Action action; public Action Action { @@ -42,17 +44,10 @@ namespace osu.Game.Graphics.UserInterface [BackgroundDependencyLoader] private void load(BeatmapManager beatmaps, APIAccess api) { - beatmaps.ItemAdded += s => - { - if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) - downloaded.Value = true; - }; + this.beatmaps = beatmaps; - beatmaps.ItemRemoved += s => - { - if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) - downloaded.Value = false; - }; + beatmaps.ItemAdded += setAdded; + beatmaps.ItemRemoved += setRemoved; // initial downloaded value downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Count() != 0; @@ -76,8 +71,31 @@ namespace osu.Game.Graphics.UserInterface return true; } + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + if (beatmaps != null) + { + beatmaps.ItemAdded -= setAdded; + beatmaps.ItemRemoved -= setRemoved; + } + } + protected abstract void Enable(); protected abstract void Disable(); protected abstract void AlreadyDownloading(); + + private void setAdded(BeatmapSetInfo s) + { + if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) + downloaded.Value = true; + } + + private void setRemoved(BeatmapSetInfo s) + { + if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) + downloaded.Value = false; + } } } From 416384956d1ac646b7c1fe48733652439f98abba Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 06:47:39 -0300 Subject: [PATCH 06/34] Use a protected Downloaded bindable instead of abstract methods. --- .../UserInterface/BeatmapSetDownloadButton.cs | 33 +++++-------------- osu.Game/Overlays/Direct/DownloadButton.cs | 22 +++++-------- 2 files changed, 17 insertions(+), 38 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs b/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs index 39bbc8216a..d55a133d18 100644 --- a/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs +++ b/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.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.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; @@ -16,29 +15,15 @@ namespace osu.Game.Graphics.UserInterface { private readonly BeatmapSetInfo set; private readonly bool noVideo; - private readonly BindableBool downloaded = new BindableBool(); private BeatmapManager beatmaps; - private Action action; - public Action Action - { - get => action; - set => action = value; - } + protected readonly BindableBool Downloaded = new BindableBool(); protected BeatmapSetDownloadButton(BeatmapSetInfo set, bool noVideo = false) { this.set = set; this.noVideo = noVideo; - - downloaded.ValueChanged += e => - { - if (e) - Disable(); - else - Enable(); - }; } [BackgroundDependencyLoader] @@ -49,8 +34,8 @@ namespace osu.Game.Graphics.UserInterface beatmaps.ItemAdded += setAdded; beatmaps.ItemRemoved += setRemoved; - // initial downloaded value - downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Count() != 0; + // initial value + Downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Count() != 0; Action = () => { @@ -66,7 +51,7 @@ namespace osu.Game.Graphics.UserInterface protected override bool OnClick(InputState state) { - if (!downloaded.Value) + if (Enabled.Value && !Downloaded.Value) Action?.Invoke(); return true; } @@ -82,20 +67,20 @@ namespace osu.Game.Graphics.UserInterface } } - protected abstract void Enable(); - protected abstract void Disable(); - protected abstract void AlreadyDownloading(); + protected virtual void AlreadyDownloading() + { + } private void setAdded(BeatmapSetInfo s) { if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) - downloaded.Value = true; + Downloaded.Value = true; } private void setRemoved(BeatmapSetInfo s) { if (s.OnlineBeatmapSetID == set.OnlineBeatmapSetID) - downloaded.Value = false; + Downloaded.Value = false; } } } diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index a6d7a4215d..1b072a4101 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -26,6 +26,14 @@ namespace osu.Game.Overlays.Direct Icon = FontAwesome.fa_osu_chevron_down_o, }, }; + + Downloaded.ValueChanged += e => + { + if (e) + this.FadeOut(200); + else + this.FadeIn(200); + }; } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) @@ -50,19 +58,5 @@ namespace osu.Game.Overlays.Direct { icon.ScaleTo(1f, 500, Easing.OutElastic); } - - protected override void Enable() - { - this.FadeIn(200); - } - - protected override void Disable() - { - this.FadeOut(200); - } - - protected override void AlreadyDownloading() - { - } } } From 4bdc1fb7816c17f5362585e25f6874e4fe590323 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 07:10:33 -0300 Subject: [PATCH 07/34] Remove unused using. --- osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs b/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs index d55a133d18..3b889746ab 100644 --- a/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs +++ b/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs @@ -7,7 +7,6 @@ using osu.Framework.Configuration; using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; -using osu.Game.Online.API; namespace osu.Game.Graphics.UserInterface { @@ -27,7 +26,7 @@ namespace osu.Game.Graphics.UserInterface } [BackgroundDependencyLoader] - private void load(BeatmapManager beatmaps, APIAccess api) + private void load(BeatmapManager beatmaps) { this.beatmaps = beatmaps; From 698a42f1454dc088004dcdeac29468d8ba8c449a Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 20:12:43 -0300 Subject: [PATCH 08/34] BeatmapSetDownloadButton -> BeatmapSetDownloader Allows it to integrate better with existing buttons, like HeaderButton. --- ...nloadButton.cs => BeatmapSetDownloader.cs} | 42 ++++++++----------- osu.Game/Overlays/Direct/DownloadButton.cs | 11 +++-- 2 files changed, 26 insertions(+), 27 deletions(-) rename osu.Game/Graphics/UserInterface/{BeatmapSetDownloadButton.cs => BeatmapSetDownloader.cs} (67%) diff --git a/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs b/osu.Game/Graphics/UserInterface/BeatmapSetDownloader.cs similarity index 67% rename from osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs rename to osu.Game/Graphics/UserInterface/BeatmapSetDownloader.cs index 3b889746ab..4fe1527283 100644 --- a/osu.Game/Graphics/UserInterface/BeatmapSetDownloadButton.cs +++ b/osu.Game/Graphics/UserInterface/BeatmapSetDownloader.cs @@ -1,25 +1,27 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; -using osu.Framework.Input; +using osu.Framework.Graphics; using osu.Game.Beatmaps; -using osu.Game.Graphics.Containers; namespace osu.Game.Graphics.UserInterface { - public abstract class BeatmapSetDownloadButton : OsuClickableContainer + public class BeatmapSetDownloader : Drawable { private readonly BeatmapSetInfo set; private readonly bool noVideo; private BeatmapManager beatmaps; - protected readonly BindableBool Downloaded = new BindableBool(); + public readonly BindableBool Downloaded = new BindableBool(); - protected BeatmapSetDownloadButton(BeatmapSetInfo set, bool noVideo = false) + public event Action OnAlreadyDownloading; + + public BeatmapSetDownloader(BeatmapSetInfo set, bool noVideo = false) { this.set = set; this.noVideo = noVideo; @@ -35,24 +37,6 @@ namespace osu.Game.Graphics.UserInterface // initial value Downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Count() != 0; - - Action = () => - { - if (beatmaps.GetExistingDownload(set) != null) - { - AlreadyDownloading(); - return; - } - - beatmaps.Download(set, noVideo); - }; - } - - protected override bool OnClick(InputState state) - { - if (Enabled.Value && !Downloaded.Value) - Action?.Invoke(); - return true; } protected override void Dispose(bool isDisposing) @@ -66,8 +50,18 @@ namespace osu.Game.Graphics.UserInterface } } - protected virtual void AlreadyDownloading() + public void Download() { + if (Downloaded.Value) + return; + + if (beatmaps.GetExistingDownload(set) != null) + { + OnAlreadyDownloading?.Invoke(); + return; + } + + beatmaps.Download(set, noVideo); } private void setAdded(BeatmapSetInfo s) diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index 1b072a4101..66bca9ed17 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -5,19 +5,22 @@ using osu.Framework.Graphics; using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using OpenTK; namespace osu.Game.Overlays.Direct { - public class DownloadButton : BeatmapSetDownloadButton + public class DownloadButton : OsuClickableContainer { private readonly SpriteIcon icon; - public DownloadButton(BeatmapSetInfo set, bool noVideo = false) : base(set, noVideo) + public DownloadButton(BeatmapSetInfo set, bool noVideo = false) { + BeatmapSetDownloader downloader; Children = new Drawable[] { + downloader = new BeatmapSetDownloader(set, noVideo), icon = new SpriteIcon { Anchor = Anchor.Centre, @@ -27,7 +30,9 @@ namespace osu.Game.Overlays.Direct }, }; - Downloaded.ValueChanged += e => + Action = downloader.Download; + + downloader.Downloaded.ValueChanged += e => { if (e) this.FadeOut(200); From 9377ffb784641d4d825b2472208cd03e11471a6f Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 20:27:34 -0300 Subject: [PATCH 09/34] Update BeatmapSetOverlay to use BeatmapSetDownloader. --- .../BeatmapSet/Buttons/DownloadButton.cs | 16 ++++- osu.Game/Overlays/BeatmapSet/Header.cs | 70 +++++-------------- osu.Game/Overlays/Direct/DownloadButton.cs | 4 +- 3 files changed, 36 insertions(+), 54 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs index c699ae2328..2dc0892704 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs @@ -3,18 +3,21 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; using OpenTK; namespace osu.Game.Overlays.BeatmapSet.Buttons { public class DownloadButton : HeaderButton { - public DownloadButton(string title, string subtitle) + public DownloadButton(string title, string subtitle, BeatmapSetInfo set, bool noVideo = false) { Width = 120; + BeatmapSetDownloader downloader; Add(new Container { Depth = -1, @@ -22,6 +25,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons Padding = new MarginPadding { Horizontal = 10 }, Children = new Drawable[] { + downloader = new BeatmapSetDownloader(set, noVideo), new FillFlowContainer { Anchor = Anchor.CentreLeft, @@ -54,6 +58,16 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons }, }, }); + + Action = downloader.Download; + + downloader.Downloaded.ValueChanged += d => + { + if (d) + this.FadeOut(200); + else + this.FadeIn(200); + }; } } } diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index 89c141ef17..a1ef82c995 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -35,8 +35,6 @@ namespace osu.Game.Overlays.BeatmapSet private readonly BeatmapSetOnlineStatusPill onlineStatusPill; public Details Details; - private BeatmapManager beatmaps; - public readonly BeatmapPicker Picker; private BeatmapSetInfo beatmapSet; @@ -68,8 +66,24 @@ namespace osu.Game.Overlays.BeatmapSet 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); + if (BeatmapSet.OnlineInfo.HasVideo) + { + videoButtons.Children = new[] + { + new DownloadButton("Download", "with Video", BeatmapSet), + new DownloadButton("Download", "without Video", BeatmapSet, true), + }; + + videoButtons.FadeIn(transition_duration); + noVideoButtons.FadeOut(transition_duration); + } + else + { + noVideoButtons.Child = new DownloadButton("Download", string.Empty, BeatmapSet); + + noVideoButtons.FadeIn(transition_duration); + videoButtons.FadeOut(transition_duration); + } } else { @@ -192,27 +206,12 @@ namespace osu.Game.Overlays.BeatmapSet { RelativeSizeAxes = Axes.Both, Alpha = 0f, - Child = new DownloadButton("Download", @"") - { - Action = () => download(false), - }, }, videoButtons = new FillFlowContainer { RelativeSizeAxes = Axes.Both, Spacing = new Vector2(buttons_spacing), Alpha = 0f, - Children = new[] - { - new DownloadButton("Download", "with Video") - { - Action = () => download(false), - }, - new DownloadButton("Download", "without Video") - { - Action = () => download(true), - }, - }, }, }, }, @@ -248,41 +247,10 @@ namespace osu.Game.Overlays.BeatmapSet } [BackgroundDependencyLoader] - private void load(OsuColour colours, BeatmapManager beatmaps) + private void load(OsuColour colours) { tabsBg.Colour = colours.Gray3; - this.beatmaps = beatmaps; - - beatmaps.ItemAdded += handleBeatmapAdd; - updateDisplay(); } - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - if (beatmaps != null) beatmaps.ItemAdded -= handleBeatmapAdd; - } - - private void handleBeatmapAdd(BeatmapSetInfo beatmap) => Schedule(() => - { - if (beatmap.OnlineBeatmapSetID == BeatmapSet?.OnlineBeatmapSetID) - downloadButtonsContainer.FadeOut(transition_duration); - }); - - private void download(bool noVideo) - { - if (beatmaps.GetExistingDownload(BeatmapSet) != null) - { - downloadButtonsContainer.MoveToX(-5, 50, Easing.OutSine).Then() - .MoveToX(5, 100, Easing.InOutSine).Then() - .MoveToX(-5, 100, Easing.InOutSine).Then() - .MoveToX(0, 50, Easing.InSine).Then(); - - return; - } - - beatmaps.Download(BeatmapSet, noVideo); - } } } diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index 66bca9ed17..e40b7ae0cb 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -32,9 +32,9 @@ namespace osu.Game.Overlays.Direct Action = downloader.Download; - downloader.Downloaded.ValueChanged += e => + downloader.Downloaded.ValueChanged += d => { - if (e) + if (d) this.FadeOut(200); else this.FadeIn(200); From 01c5060bcf0f5cb966d397711f82b937ebfba515 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 20:30:54 -0300 Subject: [PATCH 10/34] Move BeatmapSetDownloader to osu.Game.Beatmaps.Drawables --- .../Drawables}/BeatmapSetDownloader.cs | 3 +-- osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs | 2 +- osu.Game/Overlays/Direct/DownloadButton.cs | 2 +- 3 files changed, 3 insertions(+), 4 deletions(-) rename osu.Game/{Graphics/UserInterface => Beatmaps/Drawables}/BeatmapSetDownloader.cs (96%) diff --git a/osu.Game/Graphics/UserInterface/BeatmapSetDownloader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs similarity index 96% rename from osu.Game/Graphics/UserInterface/BeatmapSetDownloader.cs rename to osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs index 4fe1527283..e800eb5115 100644 --- a/osu.Game/Graphics/UserInterface/BeatmapSetDownloader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs @@ -6,9 +6,8 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Game.Beatmaps; -namespace osu.Game.Graphics.UserInterface +namespace osu.Game.Beatmaps.Drawables { public class BeatmapSetDownloader : Drawable { diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs index 2dc0892704..310bfe3372 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs @@ -4,9 +4,9 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using OpenTK; namespace osu.Game.Overlays.BeatmapSet.Buttons diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index e40b7ae0cb..a55a6507b9 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -4,9 +4,9 @@ using osu.Framework.Graphics; using osu.Framework.Input; using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Drawables; using osu.Game.Graphics; using osu.Game.Graphics.Containers; -using osu.Game.Graphics.UserInterface; using OpenTK; namespace osu.Game.Overlays.Direct From c524289b246a48e347f5031ca36647e09f23686d Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 21:01:15 -0300 Subject: [PATCH 11/34] Update DirectListPanel to properly handle hiding DownloadButton. --- osu.Game/Overlays/Direct/DirectListPanel.cs | 98 ++++++++++++++------- 1 file changed, 65 insertions(+), 33 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index c949e0d088..6e3483604b 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -12,28 +12,31 @@ using osu.Game.Graphics.Sprites; using osu.Framework.Allocation; using osu.Framework.Localisation; using osu.Framework.Graphics.Shapes; +using osu.Framework.Input; using osu.Game.Beatmaps; namespace osu.Game.Overlays.Direct { public class DirectListPanel : DirectPanel { + private const float transition_duration = 120; private const float horizontal_padding = 10; private const float vertical_padding = 5; private const float height = 70; + private PlayButton playButton; + private Box progressBar; + private Container downloadContainer; + + protected override PlayButton PlayButton => playButton; + protected override Box PreviewBar => progressBar; + public DirectListPanel(BeatmapSetInfo beatmap) : base(beatmap) { RelativeSizeAxes = Axes.X; Height = height; } - private PlayButton playButton; - private Box progressBar; - - protected override PlayButton PlayButton => playButton; - protected override Box PreviewBar => progressBar; - [BackgroundDependencyLoader] private void load(LocalisationEngine localisation, OsuColour colours) { @@ -59,7 +62,7 @@ namespace osu.Game.Overlays.Direct AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, LayoutEasing = Easing.OutQuint, - LayoutDuration = 120, + LayoutDuration = transition_duration, Spacing = new Vector2(10, 0), Children = new Drawable[] { @@ -104,52 +107,69 @@ namespace osu.Game.Overlays.Direct Anchor = Anchor.TopRight, Origin = Anchor.TopRight, AutoSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Margin = new MarginPadding { Right = height - vertical_padding * 2 + vertical_padding }, + Direction = FillDirection.Horizontal, + LayoutEasing = Easing.OutQuint, + LayoutDuration = transition_duration, Children = new Drawable[] { - new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0) + downloadContainer = new Container { - Margin = new MarginPadding { Right = 1 }, + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Alpha = 0, + Child = new DownloadButton(SetInfo) + { + Size = new Vector2(height - vertical_padding * 2), + Margin = new MarginPadding { Left = vertical_padding }, + }, }, - new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), new FillFlowContainer { Anchor = Anchor.TopRight, Origin = Anchor.TopRight, AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Children = new[] + Direction = FillDirection.Vertical, + Children = new Drawable[] { - new OsuSpriteText + new Statistic(FontAwesome.fa_play_circle, SetInfo.OnlineInfo?.PlayCount ?? 0) { - Text = "mapped by ", - TextSize = 14, + Margin = new MarginPadding { Right = 1 }, + }, + new Statistic(FontAwesome.fa_heart, SetInfo.OnlineInfo?.FavouriteCount ?? 0), + new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new[] + { + new OsuSpriteText + { + Text = "mapped by ", + TextSize = 14, + }, + new OsuSpriteText + { + Text = SetInfo.Metadata.Author.Username, + TextSize = 14, + Font = @"Exo2.0-SemiBoldItalic", + }, + }, }, new OsuSpriteText { - Text = SetInfo.Metadata.Author.Username, + Text = $"from {SetInfo.Metadata.Source}", + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, TextSize = 14, - Font = @"Exo2.0-SemiBoldItalic", + Alpha = string.IsNullOrEmpty(SetInfo.Metadata.Source) ? 0f : 1f, }, }, }, - new OsuSpriteText - { - Text = $"from {SetInfo.Metadata.Source}", - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - TextSize = 14, - Alpha = string.IsNullOrEmpty(SetInfo.Metadata.Source) ? 0f : 1f, - }, }, }, - new DownloadButton(SetInfo) - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - Size = new Vector2(height - vertical_padding * 2), - }, }, }, progressBar = new Box @@ -164,5 +184,17 @@ namespace osu.Game.Overlays.Direct }, }); } + + protected override bool OnHover(InputState state) + { + downloadContainer.FadeIn(transition_duration, Easing.InOutQuint); + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + downloadContainer.FadeOut(transition_duration, Easing.InOutQuint); + base.OnHoverLost(state); + } } } From 61e135841034da3b047a586bb2b3c9db4d8d67e0 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 21:07:17 -0300 Subject: [PATCH 12/34] Add OnAlreadyDownloading animations. --- osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs | 8 ++++++++ osu.Game/Overlays/Direct/DownloadButton.cs | 8 ++++++++ 2 files changed, 16 insertions(+) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs index 310bfe3372..cf7d3cda5a 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs @@ -68,6 +68,14 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons else this.FadeIn(200); }; + + downloader.OnAlreadyDownloading += () => + { + Content.MoveToX(-5, 50, Easing.OutSine).Then() + .MoveToX(5, 100, Easing.InOutSine).Then() + .MoveToX(-5, 100, Easing.InOutSine).Then() + .MoveToX(0, 50, Easing.InSine); + }; } } } diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index a55a6507b9..a621199916 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -39,6 +39,14 @@ namespace osu.Game.Overlays.Direct else this.FadeIn(200); }; + + downloader.OnAlreadyDownloading += () => + { + Content.MoveToX(-5, 50, Easing.OutSine).Then() + .MoveToX(5, 100, Easing.InOutSine).Then() + .MoveToX(-5, 100, Easing.InOutSine).Then() + .MoveToX(0, 50, Easing.InSine); + }; } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) From d8154f8cad5b243674c9c214e517021a0036596d Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 21:11:27 -0300 Subject: [PATCH 13/34] Fix BeatmapSetInfos with OnlineBeatmapSetID set to null being marked as downloaded. --- osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs index e800eb5115..cc4a9c6d15 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs @@ -35,7 +35,8 @@ namespace osu.Game.Beatmaps.Drawables beatmaps.ItemRemoved += setRemoved; // initial value - Downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Count() != 0; + if (set.OnlineBeatmapSetID != null) + Downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Count() != 0; } protected override void Dispose(bool isDisposing) From 4cf7a64636a0c354399dca8cc6fa93f81a00a3ea Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 22:26:52 -0300 Subject: [PATCH 14/34] Remove unused parameter. --- osu.Game/Overlays/DirectOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/DirectOverlay.cs b/osu.Game/Overlays/DirectOverlay.cs index 99f6de8559..b33f271986 100644 --- a/osu.Game/Overlays/DirectOverlay.cs +++ b/osu.Game/Overlays/DirectOverlay.cs @@ -176,7 +176,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuColour colours, APIAccess api, RulesetStore rulesets, BeatmapManager beatmaps) + private void load(OsuColour colours, APIAccess api, RulesetStore rulesets) { this.api = api; this.rulesets = rulesets; From 80951eae68f68449ce1d139f7284a5e9850f228a Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 5 Jun 2018 18:09:26 -0300 Subject: [PATCH 15/34] Inherit BeatmapSetDownloader from Component. --- osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs index cc4a9c6d15..779848dff6 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics; namespace osu.Game.Beatmaps.Drawables { - public class BeatmapSetDownloader : Drawable + public class BeatmapSetDownloader : Component { private readonly BeatmapSetInfo set; private readonly bool noVideo; From 8274623ad6f691d62bdf4eee28808e3afb9588bb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Jun 2018 14:07:50 +0900 Subject: [PATCH 16/34] Cleanup multi mod constructions --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 36 ++----------- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 69 +++++-------------------- osu.Game.Rulesets.Osu/OsuRuleset.cs | 36 ++----------- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 36 ++----------- osu.Game/Rulesets/Mods/MultiMod.cs | 12 ++++- 5 files changed, 37 insertions(+), 152 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 2325a8cad9..6a9f12e2f2 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -82,36 +82,15 @@ namespace osu.Game.Rulesets.Catch { new CatchModEasy(), new CatchModNoFail(), - new MultiMod - { - Mods = new Mod[] - { - new CatchModHalfTime(), - new CatchModDaycore(), - }, - }, + new MultiMod(new CatchModHalfTime(), new CatchModDaycore()) }; case ModType.DifficultyIncrease: return new Mod[] { new CatchModHardRock(), - new MultiMod - { - Mods = new Mod[] - { - new CatchModSuddenDeath(), - new CatchModPerfect(), - }, - }, - new MultiMod - { - Mods = new Mod[] - { - new CatchModDoubleTime(), - new CatchModNightcore(), - }, - }, + new MultiMod(new CatchModSuddenDeath(), new CatchModPerfect()), + new MultiMod(new CatchModDoubleTime(), new CatchModNightcore()), new CatchModHidden(), new CatchModFlashlight(), }; @@ -122,14 +101,7 @@ namespace osu.Game.Rulesets.Catch new CatchModRelax(), null, null, - new MultiMod - { - Mods = new Mod[] - { - new CatchModAutoplay(), - new ModCinema(), - }, - }, + new MultiMod(new CatchModAutoplay(), new ModCinema()), }; default: diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 08fecacbab..84cf9bc1d3 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -119,74 +119,33 @@ namespace osu.Game.Rulesets.Mania { new ManiaModEasy(), new ManiaModNoFail(), - new MultiMod - { - Mods = new Mod[] - { - new ManiaModHalfTime(), - new ManiaModDaycore(), - }, - }, + new MultiMod(new ManiaModHalfTime(), new ManiaModDaycore()), }; case ModType.DifficultyIncrease: return new Mod[] { new ManiaModHardRock(), - new MultiMod - { - Mods = new Mod[] - { - new ManiaModSuddenDeath(), - new ManiaModPerfect(), - }, - }, - new MultiMod - { - Mods = new Mod[] - { - new ManiaModDoubleTime(), - new ManiaModNightcore(), - }, - }, - new MultiMod - { - Mods = new Mod[] - { - new ManiaModFadeIn(), - new ManiaModHidden(), - } - }, + new MultiMod(new ManiaModSuddenDeath(), new ManiaModPerfect()), + new MultiMod(new ManiaModDoubleTime(), new ManiaModNightcore()), + new MultiMod(new ManiaModFadeIn(), new ManiaModHidden()), new ManiaModFlashlight(), }; case ModType.Special: return new Mod[] { - new MultiMod - { - Mods = new Mod[] - { - new ManiaModKey4(), - new ManiaModKey5(), - new ManiaModKey6(), - new ManiaModKey7(), - new ManiaModKey8(), - new ManiaModKey9(), - new ManiaModKey1(), - new ManiaModKey2(), - new ManiaModKey3(), - }, - }, + new MultiMod(new ManiaModKey4(), + new ManiaModKey5(), + new ManiaModKey6(), + new ManiaModKey7(), + new ManiaModKey8(), + new ManiaModKey9(), + new ManiaModKey1(), + new ManiaModKey2(), + new ManiaModKey3()), new ManiaModRandom(), new ManiaModDualStages(), new ManiaModMirror(), - new MultiMod - { - Mods = new Mod[] - { - new ManiaModAutoplay(), - new ModCinema(), - }, - }, + new MultiMod(new ManiaModAutoplay(), new ModCinema()), }; case ModType.DifficultyCalculation: var mods = new List(); diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 31eff5493b..29cdb6cfb2 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -93,35 +93,14 @@ namespace osu.Game.Rulesets.Osu { new OsuModEasy(), new OsuModNoFail(), - new MultiMod - { - Mods = new Mod[] - { - new OsuModHalfTime(), - new OsuModDaycore(), - }, - }, + new MultiMod(new OsuModHalfTime(), new OsuModDaycore()), }; case ModType.DifficultyIncrease: return new Mod[] { new OsuModHardRock(), - new MultiMod - { - Mods = new Mod[] - { - new OsuModSuddenDeath(), - new OsuModPerfect(), - }, - }, - new MultiMod - { - Mods = new Mod[] - { - new OsuModDoubleTime(), - new OsuModNightcore(), - }, - }, + new MultiMod(new OsuModSuddenDeath(), new OsuModPerfect()), + new MultiMod(new OsuModDoubleTime(), new OsuModNightcore()), new OsuModHidden(), new OsuModFlashlight(), }; @@ -131,14 +110,7 @@ namespace osu.Game.Rulesets.Osu new OsuModRelax(), new OsuModAutopilot(), new OsuModSpunOut(), - new MultiMod - { - Mods = new Mod[] - { - new OsuModAutoplay(), - new ModCinema(), - }, - }, + new MultiMod(new OsuModAutoplay(), new ModCinema()), new OsuModTarget(), }; case ModType.DifficultyCalculation: diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index a249646285..c8621066a8 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -84,35 +84,14 @@ namespace osu.Game.Rulesets.Taiko { new TaikoModEasy(), new TaikoModNoFail(), - new MultiMod - { - Mods = new Mod[] - { - new TaikoModHalfTime(), - new TaikoModDaycore(), - }, - }, + new MultiMod(new TaikoModHalfTime(), new TaikoModDaycore()), }; case ModType.DifficultyIncrease: return new Mod[] { new TaikoModHardRock(), - new MultiMod - { - Mods = new Mod[] - { - new TaikoModSuddenDeath(), - new TaikoModPerfect(), - }, - }, - new MultiMod - { - Mods = new Mod[] - { - new TaikoModDoubleTime(), - new TaikoModNightcore(), - }, - }, + new MultiMod(new TaikoModSuddenDeath(), new TaikoModPerfect()), + new MultiMod(new TaikoModDoubleTime(), new TaikoModDaycore()), new TaikoModHidden(), new TaikoModFlashlight(), }; @@ -122,14 +101,7 @@ namespace osu.Game.Rulesets.Taiko new TaikoModRelax(), null, null, - new MultiMod - { - Mods = new Mod[] - { - new TaikoModAutoplay(), - new ModCinema(), - }, - }, + new MultiMod(new TaikoModAutoplay(), new ModCinema()), }; case ModType.DifficultyCalculation: return new Mod[] diff --git a/osu.Game/Rulesets/Mods/MultiMod.cs b/osu.Game/Rulesets/Mods/MultiMod.cs index 3c90a4eedb..b65773e93f 100644 --- a/osu.Game/Rulesets/Mods/MultiMod.cs +++ b/osu.Game/Rulesets/Mods/MultiMod.cs @@ -1,6 +1,9 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Linq; + namespace osu.Game.Rulesets.Mods { public class MultiMod : Mod @@ -10,6 +13,13 @@ namespace osu.Game.Rulesets.Mods public override string Description => string.Empty; public override double ScoreMultiplier => 0; - public Mod[] Mods; + public Mod[] Mods { get; } + + public MultiMod(params Mod[] mods) + { + Mods = mods; + } + + public override Type[] IncompatibleMods => Mods.SelectMany(m => m.IncompatibleMods).ToArray(); } } From e19ca0c12011b86ca9cfb5093a04fe29e85172c2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Jun 2018 14:08:02 +0900 Subject: [PATCH 17/34] Add nomod mod type --- osu.Game/Rulesets/Mods/NoModMod.cs | 15 +++++++++++++++ 1 file changed, 15 insertions(+) create mode 100644 osu.Game/Rulesets/Mods/NoModMod.cs diff --git a/osu.Game/Rulesets/Mods/NoModMod.cs b/osu.Game/Rulesets/Mods/NoModMod.cs new file mode 100644 index 0000000000..dcab3538da --- /dev/null +++ b/osu.Game/Rulesets/Mods/NoModMod.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Mods +{ + /// + /// Indicates a type of mod that doesn't do anything. + /// + public sealed class NoModMod : Mod + { + public override string Name => "No Mod"; + public override string ShortenedName => "NM"; + public override double ScoreMultiplier => 1; + } +} From 35678237591c8ff22cb479c9f0c32130471e16cb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 14:18:38 +0900 Subject: [PATCH 18/34] Reverse order of exposed objects in HitObjectContainer Closes #2740. --- osu.Game.Rulesets.Mania/UI/Column.cs | 9 +++++++-- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 4 +--- osu.Game/Rulesets/Mods/ModHidden.cs | 3 +-- osu.Game/Rulesets/UI/HitObjectContainer.cs | 4 ++-- 4 files changed, 11 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 28cd1b6b39..ff1b8e506a 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -265,8 +265,13 @@ namespace osu.Game.Rulesets.Mania.UI if (action != Action) return false; - var hitObject = HitObjects.Objects.LastOrDefault(h => h.HitObject.StartTime > Time.Current) ?? HitObjects.Objects.FirstOrDefault(); - hitObject?.PlaySamples(); + var nextObject = + HitObjects.AliveObjects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ?? + // fallback to non-alive objects to find next off-screen object + HitObjects.Objects.FirstOrDefault(h => h.HitObject.StartTime > Time.Current) ?? + HitObjects.Objects.LastOrDefault(); + + nextObject?.PlaySamples(); return true; } diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index b63f85623e..f2d5631e93 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -64,9 +64,7 @@ namespace osu.Game.Rulesets.Osu.UI public override void PostProcess() { - connectionLayer.HitObjects = HitObjects.Objects - .Select(d => d.HitObject) - .OrderBy(h => h.StartTime).OfType(); + connectionLayer.HitObjects = HitObjects.Objects.Select(d => d.HitObject).OfType(); } private void onJudgement(DrawableHitObject judgedObject, Judgement judgement) diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index 45da628ce8..9b09f0bd6d 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -27,8 +27,7 @@ namespace osu.Game.Rulesets.Mods public virtual void ApplyToDrawableHitObjects(IEnumerable drawables) { - // todo: fix ordering of objects so we don't have to do this (#2740). - foreach (var d in drawables.Reverse().Skip(IncreaseFirstObjectVisibility ? 1 : 0)) + foreach (var d in drawables.Skip(IncreaseFirstObjectVisibility ? 1 : 0)) d.ApplyCustomUpdateState += ApplyHiddenState; } diff --git a/osu.Game/Rulesets/UI/HitObjectContainer.cs b/osu.Game/Rulesets/UI/HitObjectContainer.cs index 1b6841c9bd..af18d98561 100644 --- a/osu.Game/Rulesets/UI/HitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/HitObjectContainer.cs @@ -11,8 +11,8 @@ namespace osu.Game.Rulesets.UI { public class HitObjectContainer : CompositeDrawable { - public virtual IEnumerable Objects => InternalChildren.Cast(); - public virtual IEnumerable AliveObjects => AliveInternalChildren.Cast(); + public IEnumerable Objects => InternalChildren.Cast().OrderBy(h => h.HitObject.StartTime); + public IEnumerable AliveObjects => AliveInternalChildren.Cast().OrderBy(h => h.HitObject.StartTime); public virtual void Add(DrawableHitObject hitObject) => AddInternal(hitObject); public virtual bool Remove(DrawableHitObject hitObject) => RemoveInternal(hitObject); From df4c855aa202f1949c769dc289e11c34d637760b Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 6 Jun 2018 03:13:37 -0300 Subject: [PATCH 19/34] Manage subtitle inside of DownloadButton. --- osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs | 9 +++++++-- osu.Game/Overlays/BeatmapSet/Header.cs | 6 +++--- 2 files changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs index cf7d3cda5a..8c6c8dbaa1 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs @@ -13,10 +13,15 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons { public class DownloadButton : HeaderButton { - public DownloadButton(string title, string subtitle, BeatmapSetInfo set, bool noVideo = false) + public DownloadButton(BeatmapSetInfo set, bool noVideo = false) { Width = 120; + string subtitle = string.Empty; + + if (set.OnlineInfo.HasVideo) + subtitle = noVideo ? "without Video" : "with Video"; + BeatmapSetDownloader downloader; Add(new Container { @@ -36,7 +41,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons { new OsuSpriteText { - Text = title, + Text = "Download", TextSize = 13, Font = @"Exo2.0-Bold", }, diff --git a/osu.Game/Overlays/BeatmapSet/Header.cs b/osu.Game/Overlays/BeatmapSet/Header.cs index a1ef82c995..afba99f928 100644 --- a/osu.Game/Overlays/BeatmapSet/Header.cs +++ b/osu.Game/Overlays/BeatmapSet/Header.cs @@ -70,8 +70,8 @@ namespace osu.Game.Overlays.BeatmapSet { videoButtons.Children = new[] { - new DownloadButton("Download", "with Video", BeatmapSet), - new DownloadButton("Download", "without Video", BeatmapSet, true), + new DownloadButton(BeatmapSet), + new DownloadButton(BeatmapSet, true), }; videoButtons.FadeIn(transition_duration); @@ -79,7 +79,7 @@ namespace osu.Game.Overlays.BeatmapSet } else { - noVideoButtons.Child = new DownloadButton("Download", string.Empty, BeatmapSet); + noVideoButtons.Child = new DownloadButton(BeatmapSet); noVideoButtons.FadeIn(transition_duration); videoButtons.FadeOut(transition_duration); From 188272e15d0d4730d14a1e9faac0fcc3db08424c Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 6 Jun 2018 03:18:42 -0300 Subject: [PATCH 20/34] Replace OnAlreadyDownloading with returning a bool from Download. --- .../Drawables/BeatmapSetDownloader.cs | 12 ++++-------- .../BeatmapSet/Buttons/DownloadButton.cs | 19 ++++++++++--------- osu.Game/Overlays/Direct/DownloadButton.cs | 19 ++++++++++--------- 3 files changed, 24 insertions(+), 26 deletions(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs index 779848dff6..0a322f5b72 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs @@ -18,8 +18,6 @@ namespace osu.Game.Beatmaps.Drawables public readonly BindableBool Downloaded = new BindableBool(); - public event Action OnAlreadyDownloading; - public BeatmapSetDownloader(BeatmapSetInfo set, bool noVideo = false) { this.set = set; @@ -50,18 +48,16 @@ namespace osu.Game.Beatmaps.Drawables } } - public void Download() + public bool Download() { if (Downloaded.Value) - return; + return false; if (beatmaps.GetExistingDownload(set) != null) - { - OnAlreadyDownloading?.Invoke(); - return; - } + return false; beatmaps.Download(set, noVideo); + return true; } private void setAdded(BeatmapSetInfo s) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs index 8c6c8dbaa1..37fa562a73 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs @@ -64,7 +64,16 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons }, }); - Action = downloader.Download; + Action = () => + { + if (!downloader.Download()) + { + Content.MoveToX(-5, 50, Easing.OutSine).Then() + .MoveToX(5, 100, Easing.InOutSine).Then() + .MoveToX(-5, 100, Easing.InOutSine).Then() + .MoveToX(0, 50, Easing.InSine); + } + }; downloader.Downloaded.ValueChanged += d => { @@ -73,14 +82,6 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons else this.FadeIn(200); }; - - downloader.OnAlreadyDownloading += () => - { - Content.MoveToX(-5, 50, Easing.OutSine).Then() - .MoveToX(5, 100, Easing.InOutSine).Then() - .MoveToX(-5, 100, Easing.InOutSine).Then() - .MoveToX(0, 50, Easing.InSine); - }; } } } diff --git a/osu.Game/Overlays/Direct/DownloadButton.cs b/osu.Game/Overlays/Direct/DownloadButton.cs index a621199916..1ffa8dbd35 100644 --- a/osu.Game/Overlays/Direct/DownloadButton.cs +++ b/osu.Game/Overlays/Direct/DownloadButton.cs @@ -30,7 +30,16 @@ namespace osu.Game.Overlays.Direct }, }; - Action = downloader.Download; + Action = () => + { + if (!downloader.Download()) + { + Content.MoveToX(-5, 50, Easing.OutSine).Then() + .MoveToX(5, 100, Easing.InOutSine).Then() + .MoveToX(-5, 100, Easing.InOutSine).Then() + .MoveToX(0, 50, Easing.InSine); + } + }; downloader.Downloaded.ValueChanged += d => { @@ -39,14 +48,6 @@ namespace osu.Game.Overlays.Direct else this.FadeIn(200); }; - - downloader.OnAlreadyDownloading += () => - { - Content.MoveToX(-5, 50, Easing.OutSine).Then() - .MoveToX(5, 100, Easing.InOutSine).Then() - .MoveToX(-5, 100, Easing.InOutSine).Then() - .MoveToX(0, 50, Easing.InSine); - }; } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) From 7819be7957c3d78932f94dba178533760914d6f7 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 6 Jun 2018 03:28:07 -0300 Subject: [PATCH 21/34] Remove unused using. --- osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs index 0a322f5b72..df4847b5db 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.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.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; From 83ff47ec80ced52260d528ec0eccbf442896e704 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Jun 2018 16:20:17 +0900 Subject: [PATCH 22/34] Rewrite difficulty mod combinations --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 3 - .../Difficulty/ManiaDifficultyCalculator.cs | 18 +++ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 79 --------- osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs | 15 ++ .../Difficulty/OsuDifficultyCalculator.cs | 9 ++ osu.Game.Rulesets.Osu/OsuRuleset.cs | 41 ----- .../Difficulty/TaikoDifficultyCalculator.cs | 9 ++ osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 41 ----- ...DifficultyAdjustmentModCombinationsTest.cs | 152 ++++++++++++++++++ .../Difficulty/DifficultyCalculator.cs | 39 +++++ osu.Game/Rulesets/Mods/ModType.cs | 3 +- 11 files changed, 243 insertions(+), 166 deletions(-) create mode 100644 osu.Game.Tests/NonVisual/DifficultyAdjustmentModCombinationsTest.cs diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 6a9f12e2f2..d0180f1791 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -84,7 +84,6 @@ namespace osu.Game.Rulesets.Catch new CatchModNoFail(), new MultiMod(new CatchModHalfTime(), new CatchModDaycore()) }; - case ModType.DifficultyIncrease: return new Mod[] { @@ -94,7 +93,6 @@ namespace osu.Game.Rulesets.Catch new CatchModHidden(), new CatchModFlashlight(), }; - case ModType.Special: return new Mod[] { @@ -103,7 +101,6 @@ namespace osu.Game.Rulesets.Catch null, new MultiMod(new CatchModAutoplay(), new ModCinema()), }; - default: return new Mod[] { }; } diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs index 2517839355..ca2002b7c9 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs @@ -7,6 +7,7 @@ using System.Linq; using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Mods; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mods; @@ -141,5 +142,22 @@ namespace osu.Game.Rulesets.Mania.Difficulty return difficulty; } + + protected override Mod[] DifficultyAdjustmentMods => new Mod[] + { + new ManiaModDoubleTime(), + new ManiaModHalfTime(), + new ManiaModEasy(), + new ManiaModHardRock(), + new ManiaModKey1(), + new ManiaModKey2(), + new ManiaModKey3(), + new ManiaModKey4(), + new ManiaModKey5(), + new ManiaModKey6(), + new ManiaModKey7(), + new ManiaModKey8(), + new ManiaModKey9(), + }; } } diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 84cf9bc1d3..f6934484a2 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -147,85 +147,6 @@ namespace osu.Game.Rulesets.Mania new ManiaModMirror(), new MultiMod(new ManiaModAutoplay(), new ModCinema()), }; - case ModType.DifficultyCalculation: - var mods = new List(); - foreach (var keyMod in key_mods) - { - mods.AddRange(new[] - { - keyMod, - new MultiMod - { - Mods = new[] - { - keyMod, - new ManiaModDoubleTime(), - } - }, - new MultiMod - { - Mods = new[] - { - keyMod, - new ManiaModHalfTime(), - } - }, - new MultiMod - { - Mods = new[] - { - keyMod, - new ManiaModEasy(), - } - }, - new MultiMod - { - Mods = new[] - { - keyMod, - new ManiaModHardRock(), - } - }, - new MultiMod - { - Mods = new[] - { - keyMod, - new ManiaModEasy(), - new ManiaModDoubleTime(), - } - }, - new MultiMod - { - Mods = new[] - { - keyMod, - new ManiaModEasy(), - new ManiaModHalfTime(), - } - }, - new MultiMod - { - Mods = new[] - { - keyMod, - new ManiaModHardRock(), - new ManiaModDoubleTime(), - } - }, - new MultiMod - { - Mods = new[] - { - keyMod, - new ManiaModHardRock(), - new ManiaModHalfTime(), - } - }, - }); - } - - return mods.ToArray(); default: return new Mod[] { }; } diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs index e02db68a28..6bfe295c3d 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Linq; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mods; @@ -24,5 +26,18 @@ namespace osu.Game.Rulesets.Mania.Mods mbc.TargetColumns = KeyCount; } + + public override Type[] IncompatibleMods => new[] + { + typeof(ManiaModKey1), + typeof(ManiaModKey2), + typeof(ManiaModKey3), + typeof(ManiaModKey4), + typeof(ManiaModKey5), + typeof(ManiaModKey6), + typeof(ManiaModKey7), + typeof(ManiaModKey8), + typeof(ManiaModKey9), + }.Except(new[] { GetType() }).ToArray(); } } diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 3ed072a275..94d2afbf45 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -8,6 +8,7 @@ using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Difficulty.Preprocessing; using osu.Game.Rulesets.Osu.Difficulty.Skills; +using osu.Game.Rulesets.Osu.Mods; using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.Difficulty @@ -71,5 +72,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty return starRating; } + + protected override Mod[] DifficultyAdjustmentMods => new Mod[] + { + new OsuModDoubleTime(), + new OsuModHalfTime(), + new OsuModEasy(), + new OsuModHardRock(), + }; } } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 29cdb6cfb2..b920e889ce 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -113,47 +113,6 @@ namespace osu.Game.Rulesets.Osu new MultiMod(new OsuModAutoplay(), new ModCinema()), new OsuModTarget(), }; - case ModType.DifficultyCalculation: - return new Mod[] - { - new MultiMod(), - new OsuModDoubleTime(), - new OsuModHalfTime(), - new OsuModEasy(), - new OsuModHardRock(), - new MultiMod - { - Mods = new Mod[] - { - new OsuModEasy(), - new OsuModDoubleTime(), - } - }, - new MultiMod - { - Mods = new Mod[] - { - new OsuModEasy(), - new OsuModHalfTime(), - } - }, - new MultiMod - { - Mods = new Mod[] - { - new OsuModHardRock(), - new OsuModDoubleTime(), - } - }, - new MultiMod - { - Mods = new Mod[] - { - new OsuModHardRock(), - new OsuModHalfTime(), - } - }, - }; default: return new Mod[] { }; } diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index 57e1e65064..bb666eb528 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Taiko.Mods; using osu.Game.Rulesets.Taiko.Objects; namespace osu.Game.Rulesets.Taiko.Difficulty @@ -62,6 +63,14 @@ namespace osu.Game.Rulesets.Taiko.Difficulty return starRating; } + protected override Mod[] DifficultyAdjustmentMods => new Mod[] + { + new TaikoModDoubleTime(), + new TaikoModHalfTime(), + new TaikoModEasy(), + new TaikoModHardRock(), + }; + private bool calculateStrainValues() { // Traverse hitObjects in pairs to calculate the strain value of NextHitObject from the strain value of CurrentHitObject and environment. diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index c8621066a8..ccf28a2f12 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -103,47 +103,6 @@ namespace osu.Game.Rulesets.Taiko null, new MultiMod(new TaikoModAutoplay(), new ModCinema()), }; - case ModType.DifficultyCalculation: - return new Mod[] - { - new MultiMod(), - new TaikoModDoubleTime(), - new TaikoModHalfTime(), - new TaikoModEasy(), - new TaikoModHardRock(), - new MultiMod - { - Mods = new Mod[] - { - new TaikoModEasy(), - new TaikoModDoubleTime(), - } - }, - new MultiMod - { - Mods = new Mod[] - { - new TaikoModEasy(), - new TaikoModHalfTime(), - } - }, - new MultiMod - { - Mods = new Mod[] - { - new TaikoModHardRock(), - new TaikoModDoubleTime(), - } - }, - new MultiMod - { - Mods = new Mod[] - { - new TaikoModHardRock(), - new TaikoModHalfTime(), - } - }, - }; default: return new Mod[] { }; } diff --git a/osu.Game.Tests/NonVisual/DifficultyAdjustmentModCombinationsTest.cs b/osu.Game.Tests/NonVisual/DifficultyAdjustmentModCombinationsTest.cs new file mode 100644 index 0000000000..fd697ba3d3 --- /dev/null +++ b/osu.Game.Tests/NonVisual/DifficultyAdjustmentModCombinationsTest.cs @@ -0,0 +1,152 @@ +// 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 NUnit.Framework; +using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Tests.NonVisual +{ + [TestFixture] + public class DifficultyAdjustmentModCombinationsTest + { + [Test] + public void TestNoMods() + { + var combinations = new TestDifficultyCalculator().CreateDifficultyAdjustmentModCombinations(); + + Assert.AreEqual(1, combinations.Length); + Assert.IsTrue(combinations[0] is NoModMod); + } + + [Test] + public void TestSingleMod() + { + var combinations = new TestDifficultyCalculator(new ModA()).CreateDifficultyAdjustmentModCombinations(); + + Assert.AreEqual(2, combinations.Length); + Assert.IsTrue(combinations[0] is NoModMod); + Assert.IsTrue(combinations[1] is ModA); + } + + [Test] + public void TestDoubleMod() + { + var combinations = new TestDifficultyCalculator(new ModA(), new ModB()).CreateDifficultyAdjustmentModCombinations(); + + Assert.AreEqual(4, combinations.Length); + Assert.IsTrue(combinations[0] is NoModMod); + Assert.IsTrue(combinations[1] is ModA); + Assert.IsTrue(combinations[2] is MultiMod); + Assert.IsTrue(combinations[3] is ModB); + + Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA); + Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB); + } + + [Test] + public void TestIncompatibleMods() + { + var combinations = new TestDifficultyCalculator(new ModA(), new ModIncompatibleWithA()).CreateDifficultyAdjustmentModCombinations(); + + Assert.AreEqual(3, combinations.Length); + Assert.IsTrue(combinations[0] is NoModMod); + Assert.IsTrue(combinations[1] is ModA); + Assert.IsTrue(combinations[2] is ModIncompatibleWithA); + } + + [Test] + public void TestDoubleIncompatibleMods() + { + var combinations = new TestDifficultyCalculator(new ModA(), new ModB(), new ModIncompatibleWithA(), new ModIncompatibleWithAAndB()).CreateDifficultyAdjustmentModCombinations(); + + Assert.AreEqual(8, combinations.Length); + Assert.IsTrue(combinations[0] is NoModMod); + Assert.IsTrue(combinations[1] is ModA); + Assert.IsTrue(combinations[2] is MultiMod); + Assert.IsTrue(combinations[3] is ModB); + Assert.IsTrue(combinations[4] is MultiMod); + Assert.IsTrue(combinations[5] is ModIncompatibleWithA); + Assert.IsTrue(combinations[6] is MultiMod); + Assert.IsTrue(combinations[7] is ModIncompatibleWithAAndB); + + Assert.IsTrue(((MultiMod)combinations[2]).Mods[0] is ModA); + Assert.IsTrue(((MultiMod)combinations[2]).Mods[1] is ModB); + Assert.IsTrue(((MultiMod)combinations[4]).Mods[0] is ModB); + Assert.IsTrue(((MultiMod)combinations[4]).Mods[1] is ModIncompatibleWithA); + Assert.IsTrue(((MultiMod)combinations[6]).Mods[0] is ModIncompatibleWithA); + Assert.IsTrue(((MultiMod)combinations[6]).Mods[1] is ModIncompatibleWithAAndB); + } + + [Test] + public void TestIncompatibleThroughBaseType() + { + var combinations = new TestDifficultyCalculator(new ModAofA(), new ModIncompatibleWithAofA()).CreateDifficultyAdjustmentModCombinations(); + + Assert.AreEqual(3, combinations.Length); + Assert.IsTrue(combinations[0] is NoModMod); + Assert.IsTrue(combinations[1] is ModAofA); + Assert.IsTrue(combinations[2] is ModIncompatibleWithAofA); + } + + private class ModA : Mod + { + public override string Name => nameof(ModA); + public override string ShortenedName => nameof(ModA); + public override double ScoreMultiplier => 1; + + public override Type[] IncompatibleMods => new[] { typeof(ModIncompatibleWithA), typeof(ModIncompatibleWithAAndB) }; + } + + private class ModB : Mod + { + public override string Name => nameof(ModB); + public override string ShortenedName => nameof(ModB); + public override double ScoreMultiplier => 1; + + public override Type[] IncompatibleMods => new[] { typeof(ModIncompatibleWithAAndB) }; + } + + private class ModIncompatibleWithA : Mod + { + public override string Name => $"Incompatible With {nameof(ModA)}"; + public override string ShortenedName => $"Incompatible With {nameof(ModA)}"; + public override double ScoreMultiplier => 1; + + public override Type[] IncompatibleMods => new[] { typeof(ModA) }; + } + + private class ModAofA : ModA + { + } + + private class ModIncompatibleWithAofA : ModIncompatibleWithA + { + // Incompatible through base type + } + + private class ModIncompatibleWithAAndB : Mod + { + public override string Name => $"Incompatible With {nameof(ModA)} and {nameof(ModB)}"; + public override string ShortenedName => $"Incompatible With {nameof(ModA)} and {nameof(ModB)}"; + public override double ScoreMultiplier => 1; + + public override Type[] IncompatibleMods => new[] { typeof(ModA), typeof(ModB) }; + } + + private class TestDifficultyCalculator : DifficultyCalculator + { + public TestDifficultyCalculator(params Mod[] mods) + : base(null) + { + DifficultyAdjustmentMods = mods; + } + + public override double Calculate(Dictionary categoryDifficulty = null) => throw new NotImplementedException(); + + protected override Mod[] DifficultyAdjustmentMods { get; } + } + } +} diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 070bc7ddb0..31cd9dc6f5 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -1,6 +1,7 @@ // 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 osu.Framework.Extensions.IEnumerableExtensions; @@ -36,6 +37,44 @@ namespace osu.Game.Rulesets.Difficulty { } + /// + /// Creates all combinations which adjust the difficulty. + /// + public Mod[] CreateDifficultyAdjustmentModCombinations() + { + return createDifficultyAdjustmentModCombinations(Enumerable.Empty(), DifficultyAdjustmentMods).ToArray(); + + IEnumerable createDifficultyAdjustmentModCombinations(IEnumerable currentSet, Mod[] adjustmentSet, int currentSetCount = 0, int adjustmentSetStart = 0) + { + // Initial-case: Empty current set + if (currentSetCount == 0) + yield return new NoModMod(); + + if (currentSetCount == 1) + yield return currentSet.Single(); + + if (currentSetCount > 1) + yield return new MultiMod(currentSet.ToArray()); + + // Apply mods in the adjustment set recursively. Using the entire adjustment set would result in duplicate multi-mod mod + // combinations in further recursions, so a moving subset is used to eliminate this effect + for (int i = adjustmentSetStart; i < adjustmentSet.Length; i++) + { + var adjustmentMod = adjustmentSet[i]; + if (currentSet.Any(c => c.IncompatibleMods.Any(m => m.IsInstanceOfType(adjustmentMod)))) + continue; + + foreach (var combo in createDifficultyAdjustmentModCombinations(currentSet.Append(adjustmentMod), adjustmentSet, currentSetCount + 1, i + 1)) + yield return combo; + } + } + } + + /// + /// Retrieves all s which adjust the difficulty. + /// + protected virtual Mod[] DifficultyAdjustmentMods => Array.Empty(); + public abstract double Calculate(Dictionary categoryDifficulty = null); } } diff --git a/osu.Game/Rulesets/Mods/ModType.cs b/osu.Game/Rulesets/Mods/ModType.cs index 5619899c48..913ba23701 100644 --- a/osu.Game/Rulesets/Mods/ModType.cs +++ b/osu.Game/Rulesets/Mods/ModType.cs @@ -7,7 +7,6 @@ namespace osu.Game.Rulesets.Mods { DifficultyReduction, DifficultyIncrease, - Special, - DifficultyCalculation + Special } } From 0b4f5af52e31c5088fa1edba366bbb931d830e8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 03:17:12 +0900 Subject: [PATCH 23/34] Add setting to toggle standardised or exponential scoring display Also adjusts exponential scoring to be closer to stable. Log wasn't cutting it. --- osu.Game/Configuration/OsuConfigManager.cs | 6 +++++- .../Settings/Sections/Gameplay/GeneralSettings.cs | 6 ++++++ osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 11 ++++++++--- osu.Game/Screens/Play/Player.cs | 1 + 4 files changed, 20 insertions(+), 4 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 597960c352..f7fe424aa9 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -5,6 +5,7 @@ using osu.Framework.Configuration; using osu.Framework.Configuration.Tracking; using osu.Framework.Platform; using osu.Game.Overlays; +using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Select; namespace osu.Game.Configuration @@ -80,6 +81,8 @@ namespace osu.Game.Configuration Set(OsuSetting.FloatingComments, false); + Set(OsuSetting.ScoreDisplayMode, ScoringMode.Standardised); + Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential); Set(OsuSetting.IncreaseFirstObjectVisibility, true); @@ -147,6 +150,7 @@ namespace osu.Game.Configuration SongSelectRightMouseScroll, BeatmapSkins, BeatmapHitsounds, - IncreaseFirstObjectVisibility + IncreaseFirstObjectVisibility, + ScoreDisplayMode } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 647395cf69..9c8f5e2643 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Configuration; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Overlays.Settings.Sections.Gameplay { @@ -38,6 +39,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = "Always show key overlay", Bindable = config.GetBindable(OsuSetting.KeyOverlay) }, + new SettingsEnumDropdown + { + LabelText = "Score display mode", + Bindable = config.GetBindable(OsuSetting.ScoreDisplayMode) + } }; } } diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 345930ed04..0568101aa7 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -65,6 +65,11 @@ namespace osu.Game.Rulesets.Scoring /// public readonly BindableInt HighestCombo = new BindableInt(); + /// + /// The used to calculate scores. + /// + public readonly Bindable Mode = new Bindable(); + /// /// Whether all s have been processed. /// @@ -169,8 +174,6 @@ namespace osu.Game.Rulesets.Scoring private const double combo_portion = 0.7; private const double max_score = 1000000; - public readonly Bindable Mode = new Bindable(); - protected sealed override bool HasCompleted => JudgedHits == MaxHits; protected int MaxHits { get; private set; } @@ -202,6 +205,8 @@ namespace osu.Game.Rulesets.Scoring Mode.Value = ScoringMode.Exponential; Mode.Disabled = true; } + + Mode.ValueChanged += _ => updateScore(); } /// @@ -296,7 +301,7 @@ namespace osu.Game.Rulesets.Scoring TotalScore.Value = max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore; break; case ScoringMode.Exponential: - TotalScore.Value = (baseScore + bonusScore) * Math.Log(HighestCombo + 1, 2); + TotalScore.Value = (baseScore + bonusScore) * Math.Max(0, HighestCombo - 1) / 25f; break; } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index fe77f85a50..94d03be3c8 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -158,6 +158,7 @@ namespace osu.Game.Screens.Play userAudioOffset.TriggerChange(); ScoreProcessor = RulesetContainer.CreateScoreProcessor(); + ScoreProcessor.Mode.BindTo(config.GetBindable(OsuSetting.ScoreDisplayMode)); Children = new Drawable[] { From 0fae49ee21d28a24d9585f4e2cec830385463b4a Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Thu, 7 Jun 2018 20:47:27 -0300 Subject: [PATCH 24/34] Don't add a 'with Video' subtitle. --- osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs | 7 +------ 1 file changed, 1 insertion(+), 6 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs index 37fa562a73..4fce6a49fb 100644 --- a/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs +++ b/osu.Game/Overlays/BeatmapSet/Buttons/DownloadButton.cs @@ -17,11 +17,6 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons { Width = 120; - string subtitle = string.Empty; - - if (set.OnlineInfo.HasVideo) - subtitle = noVideo ? "without Video" : "with Video"; - BeatmapSetDownloader downloader; Add(new Container { @@ -47,7 +42,7 @@ namespace osu.Game.Overlays.BeatmapSet.Buttons }, new OsuSpriteText { - Text = subtitle, + Text = set.OnlineInfo.HasVideo && noVideo ? "without Video" : string.Empty, TextSize = 11, Font = @"Exo2.0-Bold", }, From 4dfc328117ef886489825ea5770b1e137dfe330b Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Fri, 8 Jun 2018 17:46:38 +0900 Subject: [PATCH 25/34] Remove unused array --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 14 -------------- 1 file changed, 14 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index f6934484a2..5f803e3406 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -96,20 +96,6 @@ namespace osu.Game.Rulesets.Mania yield return new ManiaModSuddenDeath(); } - private static readonly Mod[] key_mods = - { - new MultiMod(), - new ManiaModKey1(), - new ManiaModKey2(), - new ManiaModKey3(), - new ManiaModKey4(), - new ManiaModKey5(), - new ManiaModKey6(), - new ManiaModKey7(), - new ManiaModKey8(), - new ManiaModKey9(), - }; - public override IEnumerable GetModsFor(ModType type) { switch (type) From 59e5a8556f91b3a47a3d8088c1041331a3c243df Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 18:15:03 +0900 Subject: [PATCH 26/34] Fix volume control adjustment being extreme when precision scrolling --- osu.Game/Overlays/Volume/VolumeMeter.cs | 20 ++++++++++++++++++-- 1 file changed, 18 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 64106967f4..b2cf43704b 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -167,9 +167,25 @@ namespace osu.Game.Overlays.Volume private set => Bindable.Value = value; } - public void Increase() => Volume += 0.05f; + private const float adjust_step = 0.05f; - public void Decrease() => Volume -= 0.05f; + public void Increase() => adjust(1); + public void Decrease() => adjust(-1); + + private void adjust(int direction) + { + float amount = adjust_step * direction; + + var mouse = GetContainingInputManager().CurrentState.Mouse; + if (mouse.HasPreciseScroll) + { + float scrollDelta = mouse.ScrollDelta.Y; + if (scrollDelta != 0) + amount *= Math.Abs(scrollDelta / 10); + } + + Volume += amount; + } public bool OnPressed(GlobalAction action) { From 064e8190beebe798760b9fbb2de999fe1a8e8537 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 20:53:58 +0900 Subject: [PATCH 27/34] Add basic documentation --- osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs | 10 ++++++++++ 1 file changed, 10 insertions(+) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs index df4847b5db..63c5c8b6e6 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs @@ -8,6 +8,9 @@ using osu.Framework.Graphics; namespace osu.Game.Beatmaps.Drawables { + /// + /// A component to allow downloading of a beatmap set. Automatically handles state syncing between other instances. + /// public class BeatmapSetDownloader : Component { private readonly BeatmapSetInfo set; @@ -15,6 +18,9 @@ namespace osu.Game.Beatmaps.Drawables private BeatmapManager beatmaps; + /// + /// Whether the associated beatmap set has been downloading (by this instance or any other instance). + /// public readonly BindableBool Downloaded = new BindableBool(); public BeatmapSetDownloader(BeatmapSetInfo set, bool noVideo = false) @@ -47,6 +53,10 @@ namespace osu.Game.Beatmaps.Drawables } } + /// + /// Begin downloading the associated beatmap set. + /// + /// True if downloading began. False if an existing download is active or completed. public bool Download() { if (Downloaded.Value) From ecc0f5e5756a6401be39c3f4ea96df270c089087 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 20:54:09 +0900 Subject: [PATCH 28/34] Use Any() instead of Count() --- osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs index 63c5c8b6e6..6acb58e165 100644 --- a/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs +++ b/osu.Game/Beatmaps/Drawables/BeatmapSetDownloader.cs @@ -39,7 +39,7 @@ namespace osu.Game.Beatmaps.Drawables // initial value if (set.OnlineBeatmapSetID != null) - Downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Count() != 0; + Downloaded.Value = beatmaps.QueryBeatmapSets(s => s.OnlineBeatmapSetID == set.OnlineBeatmapSetID && !s.DeletePending).Any(); } protected override void Dispose(bool isDisposing) From 9bdb3113ce0883afd6c1be0aa7f84153af381de3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 21:05:28 +0900 Subject: [PATCH 29/34] Revert "Always update children when ruleset input manager is updated" This reverts commit 4eb7a349442680ace0fb534b4f8bf5a03903c1b0. --- osu.Game/Rulesets/UI/RulesetInputManager.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index b35616985a..58a66a5224 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -121,6 +121,8 @@ namespace osu.Game.Rulesets.UI /// private bool validState; + protected override bool RequiresChildrenUpdate => base.RequiresChildrenUpdate && validState; + private bool isAttached => replayInputHandler != null && !UseParentState; private const int max_catch_up_updates_per_frame = 50; From a880e626d87bd3f7344b7b1b6609526e18033688 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 21:20:15 +0900 Subject: [PATCH 30/34] Use for loop and SetLayoutPosition --- 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 c97a4de464..f968f94187 100644 --- a/osu.Game/Overlays/Profile/Header/BadgeContainer.cs +++ b/osu.Game/Overlays/Profile/Header/BadgeContainer.cs @@ -107,16 +107,19 @@ namespace osu.Game.Overlays.Profile.Header visibleBadge = 0; badgeFlowContainer.Clear(); - foreach (var badge in badges) + for (var index = 0; index < badges.Length; index++) { - LoadComponentAsync(new DrawableBadge(badge) + int displayIndex = index; + LoadComponentAsync(new DrawableBadge(badges[index]) { Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, }, asyncBadge => { badgeFlowContainer.Add(asyncBadge); - badgeFlowContainer.ChangeChildDepth(asyncBadge, Array.IndexOf(badges, asyncBadge)); //Ensure the badges are ordered correctly + + // load in stable order regardless of async load order. + badgeFlowContainer.SetLayoutPosition(asyncBadge, displayIndex); }); } } From fd4f61fc88da37317e060f4d810da0c2b713008b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 21:51:43 +0900 Subject: [PATCH 31/34] Update framework and other packages --- osu.Desktop/osu.Desktop.csproj | 4 ++-- osu.Game/osu.Game.csproj | 6 +++--- osu.TestProject.props | 2 +- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 0d4efc7eed..3cf95e9b3e 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -26,7 +26,7 @@ - + @@ -35,4 +35,4 @@ - + \ No newline at end of file diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 363fc7d7bb..e35b6dbe1b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -17,10 +17,10 @@ - - + + - + \ No newline at end of file diff --git a/osu.TestProject.props b/osu.TestProject.props index cf8276eee1..8f7128f8b7 100644 --- a/osu.TestProject.props +++ b/osu.TestProject.props @@ -13,7 +13,7 @@ - + From cc37a355d26836cf655c911f3953e1b30f2d614d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 10 Jun 2018 01:44:46 +0900 Subject: [PATCH 32/34] Add comment about matching stable scoring Also updated equation to be close to what is expected --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index 0568101aa7..b6ec0617f2 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -301,7 +301,8 @@ namespace osu.Game.Rulesets.Scoring TotalScore.Value = max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore; break; case ScoringMode.Exponential: - TotalScore.Value = (baseScore + bonusScore) * Math.Max(0, HighestCombo - 1) / 25f; + // should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1) + TotalScore.Value = bonusScore + baseScore * (1 + Math.Max(0, HighestCombo - 1) / 25); break; } } From 86fb9666b250f52e07a84b8248c98ab1c3560370 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 10 Jun 2018 01:45:05 +0900 Subject: [PATCH 33/34] Rename "Exponential" to "Classic" --- osu.Game/Rulesets/Scoring/ScoreProcessor.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs index b6ec0617f2..dd4120f2fb 100644 --- a/osu.Game/Rulesets/Scoring/ScoreProcessor.cs +++ b/osu.Game/Rulesets/Scoring/ScoreProcessor.cs @@ -202,7 +202,7 @@ namespace osu.Game.Rulesets.Scoring if (maxBaseScore == 0 || maxHighestCombo == 0) { - Mode.Value = ScoringMode.Exponential; + Mode.Value = ScoringMode.Classic; Mode.Disabled = true; } @@ -213,7 +213,7 @@ namespace osu.Game.Rulesets.Scoring /// Simulates an autoplay of s that will be judged by this /// by adding s for each in the . /// - /// This is required for to work, otherwise will be used. + /// This is required for to work, otherwise will be used. /// /// /// The containing the s that will be judged by this . @@ -300,7 +300,7 @@ namespace osu.Game.Rulesets.Scoring case ScoringMode.Standardised: TotalScore.Value = max_score * (base_portion * baseScore / maxBaseScore + combo_portion * HighestCombo / maxHighestCombo) + bonusScore; break; - case ScoringMode.Exponential: + case ScoringMode.Classic: // should emulate osu-stable's scoring as closely as we can (https://osu.ppy.sh/help/wiki/Score/ScoreV1) TotalScore.Value = bonusScore + baseScore * (1 + Math.Max(0, HighestCombo - 1) / 25); break; @@ -328,6 +328,6 @@ namespace osu.Game.Rulesets.Scoring public enum ScoringMode { Standardised, - Exponential + Classic } } From b9391b3c6bb8f84426767e7233d499cb633959f3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 18:18:24 +0900 Subject: [PATCH 34/34] Fix bindable not working under non-debug due to weak references --- osu.Game/Screens/Play/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 94d03be3c8..04148cd558 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -158,7 +158,7 @@ namespace osu.Game.Screens.Play userAudioOffset.TriggerChange(); ScoreProcessor = RulesetContainer.CreateScoreProcessor(); - ScoreProcessor.Mode.BindTo(config.GetBindable(OsuSetting.ScoreDisplayMode)); + config.BindWith(OsuSetting.ScoreDisplayMode, ScoreProcessor.Mode); Children = new Drawable[] {