From eed0f3a1de4e277ad9e0513963ac56385d1abfcb Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 11 Mar 2018 21:02:14 +0100 Subject: [PATCH 001/262] Added setting to not hide the first object in Hidden mod --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 50 +++++++++++++--- osu.Game/Configuration/OsuConfigManager.cs | 5 +- .../Sections/Gameplay/GeneralSettings.cs | 5 ++ osu.Game/Rulesets/Mods/IReadFromConfig.cs | 15 +++++ osu.Game/Rulesets/UI/RulesetContainer.cs | 58 ++++++++++++------- osu.Game/osu.Game.csproj | 1 + 6 files changed, 102 insertions(+), 32 deletions(-) create mode 100644 osu.Game/Rulesets/Mods/IReadFromConfig.cs diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 4aeb76121a..02730e644e 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -7,32 +7,51 @@ using System.Linq; using osu.Framework.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Configuration; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects + public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects, IReadFromConfig { public override string Description => @"Play with no approach circles and fading notes for a slight score advantage."; public override double ScoreMultiplier => 1.06; private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; + private bool IncreaseFirstObjectVisibility = true; + private IEnumerable drawables; - public void ApplyToDrawableHitObjects(IEnumerable drawables) + private void applyMod() { - foreach (var d in drawables.OfType()) + if (IncreaseFirstObjectVisibility) { - d.ApplyCustomUpdateState += ApplyHiddenState; + foreach (var d in drawables.OfType()) + { + //Don't hide the first object + if (d.ChildID == 1) continue; + d.ApplyCustomUpdateState += ApplyHiddenState; - d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; - foreach (var h in d.HitObject.NestedHitObjects.OfType()) - h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; + d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; + foreach (var h in d.HitObject.NestedHitObjects.OfType()) + h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; + + } + } + else + { + foreach (var d in drawables.OfType()) + { + d.ApplyCustomUpdateState += ApplyHiddenState; + + d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; + foreach (var h in d.HitObject.NestedHitObjects.OfType()) + h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; + } } } - protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state) { if (!(drawable is DrawableOsuHitObject d)) @@ -83,5 +102,18 @@ namespace osu.Game.Rulesets.Osu.Mods break; } } + + public void ApplyToConfig(OsuConfigManager config) + { + IncreaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); + //This starts the process of applying the mod effects. We start it here since this is the last void called. + applyMod(); + } + + public void ApplyToDrawableHitObjects(IEnumerable drawables) + { + this.drawables = drawables; + } + } } diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 3d927ef67c..37a7da5515 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -78,6 +78,8 @@ namespace osu.Game.Configuration Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential); + Set(OsuSetting.IncreaseFirstObjectVisibility, true); + // Update Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); @@ -125,6 +127,7 @@ namespace osu.Game.Configuration Version, ShowConvertedBeatmaps, SpeedChangeVisualisation, - Skin + Skin, + IncreaseFirstObjectVisibility } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index b60b0d9531..1d2dc50105 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -38,6 +38,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = "Always show key overlay", Bindable = config.GetBindable(OsuSetting.KeyOverlay) }, + new SettingsCheckbox + { + LabelText = "Increase the first object's visibility in \"Hidden\" mod", + Bindable = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility) + }, }; } } diff --git a/osu.Game/Rulesets/Mods/IReadFromConfig.cs b/osu.Game/Rulesets/Mods/IReadFromConfig.cs new file mode 100644 index 0000000000..9452f5ee1e --- /dev/null +++ b/osu.Game/Rulesets/Mods/IReadFromConfig.cs @@ -0,0 +1,15 @@ +using osu.Framework.Allocation; +using osu.Game.Configuration; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace osu.Game.Rulesets.Mods +{ + public interface IReadFromConfig + { + void ApplyToConfig(OsuConfigManager config); + } +} diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 780bc5c86b..86429cd36c 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -67,6 +67,7 @@ namespace osu.Game.Rulesets.UI /// public readonly CursorContainer Cursor; + protected readonly Ruleset Ruleset; private IRulesetConfigManager rulesetConfig; @@ -89,11 +90,9 @@ namespace osu.Game.Rulesets.UI Cursor = CreateCursor(); } - [BackgroundDependencyLoader(true)] + [BackgroundDependencyLoader] private void load(OnScreenDisplay onScreenDisplay, SettingsStore settings) { - this.onScreenDisplay = onScreenDisplay; - rulesetConfig = CreateConfig(Ruleset, settings); if (rulesetConfig != null) @@ -101,6 +100,7 @@ namespace osu.Game.Rulesets.UI dependencies.Cache(rulesetConfig); onScreenDisplay?.BeginTracking(this, rulesetConfig); } + } public abstract ScoreProcessor CreateScoreProcessor(); @@ -167,6 +167,7 @@ namespace osu.Game.Rulesets.UI public abstract class RulesetContainer : RulesetContainer where TObject : HitObject { + public event Action OnJudgement; public event Action OnJudgementRemoved; @@ -195,10 +196,34 @@ namespace osu.Game.Rulesets.UI /// public readonly bool IsForCurrentRuleset; + public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(this); protected override Container Content => content; private Container content; + private IEnumerable mods; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + + KeyBindingInputManager.Add(content = new Container + { + RelativeSizeAxes = Axes.Both, + }); + + AddInternal(KeyBindingInputManager); + KeyBindingInputManager.Add(Playfield); + + if (Cursor != null) + KeyBindingInputManager.Add(Cursor); + + loadObjects(); + + // Apply mods + applyMods(Mods, config); + + } /// /// Whether to assume the beatmap passed into this is for the current ruleset. @@ -247,34 +272,19 @@ namespace osu.Game.Rulesets.UI KeyBindingInputManager.RelativeSizeAxes = Axes.Both; // Add mods, should always be the last thing applied to give full control to mods - applyMods(Mods); + // Mods are now added in the load() method, this method is still executed after the constructor + // so they are still added in last + } - [BackgroundDependencyLoader] - private void load() - { - KeyBindingInputManager.Add(content = new Container - { - RelativeSizeAxes = Axes.Both, - }); - AddInternal(KeyBindingInputManager); - KeyBindingInputManager.Add(Playfield); - - if (Cursor != null) - KeyBindingInputManager.Add(Cursor); - - loadObjects(); - } /// /// Applies the active mods to this RulesetContainer. /// /// - private void applyMods(IEnumerable mods) + private void applyMods(IEnumerable mods, OsuConfigManager config) { - if (mods == null) - return; foreach (var mod in mods.OfType>()) foreach (var obj in Beatmap.HitObjects) @@ -282,6 +292,10 @@ namespace osu.Game.Rulesets.UI foreach (var mod in mods.OfType>()) mod.ApplyToRulesetContainer(this); + + foreach (var mod in mods.OfType()) + mod.ApplyToConfig(config); + } public override void SetReplay(Replay replay) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d10f0085cc..74a3b94388 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -372,6 +372,7 @@ + From ea6434a7a07d840e61ed768e0a091e560ec7632f Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 11 Mar 2018 21:19:34 +0100 Subject: [PATCH 002/262] Why this line got deleted :thinking: --- osu.Game/Rulesets/UI/RulesetContainer.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 86429cd36c..03a3666cdd 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -93,6 +93,8 @@ namespace osu.Game.Rulesets.UI [BackgroundDependencyLoader] private void load(OnScreenDisplay onScreenDisplay, SettingsStore settings) { + this.onScreenDisplay = onScreenDisplay; + rulesetConfig = CreateConfig(Ruleset, settings); if (rulesetConfig != null) @@ -272,8 +274,9 @@ namespace osu.Game.Rulesets.UI KeyBindingInputManager.RelativeSizeAxes = Axes.Both; // Add mods, should always be the last thing applied to give full control to mods - // Mods are now added in the load() method, this method is still executed after the constructor - // so they are still added in last + // Mods are now added in the load() method because we need the OsuConfigManager + // for the IReadFromConfig implementations. Rhis method is still executed after the constructor, + // so the mods are still added in last } From 6a8bc067cd1a5ee9fbcfa67091244d7c32d2aa67 Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 11 Mar 2018 21:30:48 +0100 Subject: [PATCH 003/262] Add license header --- osu.Game/Rulesets/Mods/IReadFromConfig.cs | 9 +++------ 1 file changed, 3 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/Mods/IReadFromConfig.cs b/osu.Game/Rulesets/Mods/IReadFromConfig.cs index 9452f5ee1e..f891d42217 100644 --- a/osu.Game/Rulesets/Mods/IReadFromConfig.cs +++ b/osu.Game/Rulesets/Mods/IReadFromConfig.cs @@ -1,10 +1,7 @@ -using osu.Framework.Allocation; +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + using osu.Game.Configuration; -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; namespace osu.Game.Rulesets.Mods { From 9516bec13d048f04bc0113b5d607a80ed745bc9d Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 11 Mar 2018 21:45:15 +0100 Subject: [PATCH 004/262] Fix naming rule --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 02730e644e..4da3459b7f 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -21,12 +21,12 @@ namespace osu.Game.Rulesets.Osu.Mods private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; - private bool IncreaseFirstObjectVisibility = true; + private bool increaseFirstObjectVisibility = true; private IEnumerable drawables; private void applyMod() { - if (IncreaseFirstObjectVisibility) + if (increaseFirstObjectVisibility) { foreach (var d in drawables.OfType()) { @@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Osu.Mods public void ApplyToConfig(OsuConfigManager config) { - IncreaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); + increaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); //This starts the process of applying the mod effects. We start it here since this is the last void called. applyMod(); } From 802a6870c4ad1d8788b4988042d8efe5c652514a Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 11 Mar 2018 22:09:16 +0100 Subject: [PATCH 005/262] Chesterton's fence --- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 03a3666cdd..5e0bad9b74 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -90,7 +90,7 @@ namespace osu.Game.Rulesets.UI Cursor = CreateCursor(); } - [BackgroundDependencyLoader] + [BackgroundDependencyLoader(true)] private void load(OnScreenDisplay onScreenDisplay, SettingsStore settings) { this.onScreenDisplay = onScreenDisplay; From 6d9e78a3a3b94689e1892cc37dcc7d693eab92e9 Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 11 Mar 2018 22:40:49 +0100 Subject: [PATCH 006/262] Review changes --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 18 ++---------------- .../Sections/Gameplay/GeneralSettings.cs | 2 +- osu.Game/Rulesets/Mods/IReadFromConfig.cs | 2 +- osu.Game/Rulesets/UI/RulesetContainer.cs | 14 ++++---------- 4 files changed, 8 insertions(+), 28 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 4da3459b7f..7e5a629ca9 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -26,12 +26,10 @@ namespace osu.Game.Rulesets.Osu.Mods private void applyMod() { - if (increaseFirstObjectVisibility) - { foreach (var d in drawables.OfType()) { //Don't hide the first object - if (d.ChildID == 1) continue; + if (d.ChildID == 1 && increaseFirstObjectVisibility) continue; d.ApplyCustomUpdateState += ApplyHiddenState; d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; @@ -39,18 +37,6 @@ namespace osu.Game.Rulesets.Osu.Mods h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; } - } - else - { - foreach (var d in drawables.OfType()) - { - d.ApplyCustomUpdateState += ApplyHiddenState; - - d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; - foreach (var h in d.HitObject.NestedHitObjects.OfType()) - h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; - } - } } protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state) { @@ -103,7 +89,7 @@ namespace osu.Game.Rulesets.Osu.Mods } } - public void ApplyToConfig(OsuConfigManager config) + public void ReadFromConfig(OsuConfigManager config) { increaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); //This starts the process of applying the mod effects. We start it here since this is the last void called. diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 1d2dc50105..7501bd4150 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -40,7 +40,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }, new SettingsCheckbox { - LabelText = "Increase the first object's visibility in \"Hidden\" mod", + LabelText = "Show approach circle on first \"Hidden\" object", Bindable = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility) }, }; diff --git a/osu.Game/Rulesets/Mods/IReadFromConfig.cs b/osu.Game/Rulesets/Mods/IReadFromConfig.cs index f891d42217..708edcfdfb 100644 --- a/osu.Game/Rulesets/Mods/IReadFromConfig.cs +++ b/osu.Game/Rulesets/Mods/IReadFromConfig.cs @@ -7,6 +7,6 @@ namespace osu.Game.Rulesets.Mods { public interface IReadFromConfig { - void ApplyToConfig(OsuConfigManager config); + void ReadFromConfig(OsuConfigManager config); } } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 5e0bad9b74..f8c56b2bd2 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -67,7 +67,6 @@ namespace osu.Game.Rulesets.UI /// public readonly CursorContainer Cursor; - protected readonly Ruleset Ruleset; private IRulesetConfigManager rulesetConfig; @@ -102,7 +101,6 @@ namespace osu.Game.Rulesets.UI dependencies.Cache(rulesetConfig); onScreenDisplay?.BeginTracking(this, rulesetConfig); } - } public abstract ScoreProcessor CreateScoreProcessor(); @@ -169,7 +167,6 @@ namespace osu.Game.Rulesets.UI public abstract class RulesetContainer : RulesetContainer where TObject : HitObject { - public event Action OnJudgement; public event Action OnJudgementRemoved; @@ -198,7 +195,6 @@ namespace osu.Game.Rulesets.UI /// public readonly bool IsForCurrentRuleset; - public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(this); protected override Container Content => content; @@ -208,7 +204,6 @@ namespace osu.Game.Rulesets.UI [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - KeyBindingInputManager.Add(content = new Container { RelativeSizeAxes = Axes.Both, @@ -224,7 +219,6 @@ namespace osu.Game.Rulesets.UI // Apply mods applyMods(Mods, config); - } /// @@ -275,9 +269,8 @@ namespace osu.Game.Rulesets.UI // Add mods, should always be the last thing applied to give full control to mods // Mods are now added in the load() method because we need the OsuConfigManager - // for the IReadFromConfig implementations. Rhis method is still executed after the constructor, + // for the IReadFromConfig implementations. This method is still executed after the constructor, // so the mods are still added in last - } @@ -288,6 +281,8 @@ namespace osu.Game.Rulesets.UI /// private void applyMods(IEnumerable mods, OsuConfigManager config) { + if (mods == null) + return; foreach (var mod in mods.OfType>()) foreach (var obj in Beatmap.HitObjects) @@ -297,8 +292,7 @@ namespace osu.Game.Rulesets.UI mod.ApplyToRulesetContainer(this); foreach (var mod in mods.OfType()) - mod.ApplyToConfig(config); - + mod.ReadFromConfig(config); } public override void SetReplay(Replay replay) From 8a86766324e83f7e3f7550f8aab93984b9d6350b Mon Sep 17 00:00:00 2001 From: Vidalee Date: Tue, 13 Mar 2018 23:21:47 +0100 Subject: [PATCH 007/262] Changes requests --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 47 +++++++++------------- 1 file changed, 19 insertions(+), 28 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 7e5a629ca9..57f6389f78 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -11,6 +11,7 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Configuration; +using osu.Framework.Configuration; namespace osu.Game.Rulesets.Osu.Mods { @@ -18,26 +19,29 @@ namespace osu.Game.Rulesets.Osu.Mods { public override string Description => @"Play with no approach circles and fading notes for a slight score advantage."; public override double ScoreMultiplier => 1.06; - private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; - private bool increaseFirstObjectVisibility = true; - private IEnumerable drawables; + private Bindable increaseFirstObjectVisibility; - private void applyMod() + public void ReadFromConfig(OsuConfigManager config) { - foreach (var d in drawables.OfType()) - { - //Don't hide the first object - if (d.ChildID == 1 && increaseFirstObjectVisibility) continue; - d.ApplyCustomUpdateState += ApplyHiddenState; - - d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; - foreach (var h in d.HitObject.NestedHitObjects.OfType()) - h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; - - } + increaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); } + + public void ApplyToDrawableHitObjects(IEnumerable drawables) + { + foreach (var d in drawables.OfType()) + { + //Don't hide the first object ("drawables" are in a reverse order -> Last() ) + if (d == drawables.Last() && increaseFirstObjectVisibility) continue; + d.ApplyCustomUpdateState += ApplyHiddenState; + + d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; + foreach (var h in d.HitObject.NestedHitObjects.OfType()) + h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; + } + } + protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state) { if (!(drawable is DrawableOsuHitObject d)) @@ -88,18 +92,5 @@ namespace osu.Game.Rulesets.Osu.Mods break; } } - - public void ReadFromConfig(OsuConfigManager config) - { - increaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); - //This starts the process of applying the mod effects. We start it here since this is the last void called. - applyMod(); - } - - public void ApplyToDrawableHitObjects(IEnumerable drawables) - { - this.drawables = drawables; - } - } } From 92b47d87ba6cf003cce96c6fabe18bf67f02a8f6 Mon Sep 17 00:00:00 2001 From: Vidalee Date: Wed, 14 Mar 2018 23:14:03 +0100 Subject: [PATCH 008/262] makes more sense but not fixed --- osu.Game/Rulesets/UI/RulesetContainer.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index f8c56b2bd2..b945d887f7 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -202,8 +202,11 @@ namespace osu.Game.Rulesets.UI private IEnumerable mods; [BackgroundDependencyLoader] - private void load(OsuConfigManager config) + private void load(OsuConfigManager osuConfig) { + // Apply mods + applyMods(Mods, osuConfig); + KeyBindingInputManager.Add(content = new Container { RelativeSizeAxes = Axes.Both, @@ -216,9 +219,6 @@ namespace osu.Game.Rulesets.UI KeyBindingInputManager.Add(Cursor); loadObjects(); - - // Apply mods - applyMods(Mods, config); } /// @@ -284,15 +284,15 @@ namespace osu.Game.Rulesets.UI if (mods == null) return; + foreach (var mod in mods.OfType()) + mod.ReadFromConfig(config); + foreach (var mod in mods.OfType>()) foreach (var obj in Beatmap.HitObjects) mod.ApplyToHitObject(obj); foreach (var mod in mods.OfType>()) mod.ApplyToRulesetContainer(this); - - foreach (var mod in mods.OfType()) - mod.ReadFromConfig(config); } public override void SetReplay(Replay replay) From fea8f868d7e8ce63f51d1e5b8aeabc34fc94565c Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sat, 17 Mar 2018 13:22:58 +0100 Subject: [PATCH 009/262] Fixing hidden test bug --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 57f6389f78..b6b17166b1 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override double ScoreMultiplier => 1.06; private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; - private Bindable increaseFirstObjectVisibility; + private Bindable increaseFirstObjectVisibility = new Bindable(false); public void ReadFromConfig(OsuConfigManager config) { From 9252203916f7a2f1bd353e79547f9211206c18b2 Mon Sep 17 00:00:00 2001 From: Vidalee Date: Tue, 20 Mar 2018 18:23:41 +0100 Subject: [PATCH 010/262] build fix --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index b6b17166b1..8c4dac03a3 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override double ScoreMultiplier => 1.06; private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; - private Bindable increaseFirstObjectVisibility = new Bindable(false); + private Bindable increaseFirstObjectVisibility; public void ReadFromConfig(OsuConfigManager config) { @@ -30,10 +30,13 @@ namespace osu.Game.Rulesets.Osu.Mods public void ApplyToDrawableHitObjects(IEnumerable drawables) { + //In the Tests for hidden the ReadFromConfig() void isn't called -> the following bindable is null + //It's too much work to get the Dependency Injection on the Tests to get the config for just this mod, so I just make sure + //the bindable isn't null foreach (var d in drawables.OfType()) { //Don't hide the first object ("drawables" are in a reverse order -> Last() ) - if (d == drawables.Last() && increaseFirstObjectVisibility) continue; + if (d == drawables.Last() && (increaseFirstObjectVisibility == null || increaseFirstObjectVisibility)) continue; d.ApplyCustomUpdateState += ApplyHiddenState; d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; From 87b9ffced2ea92fa12506ae4c18dc7317806076b Mon Sep 17 00:00:00 2001 From: Vidalee Date: Tue, 20 Mar 2018 21:51:05 +0100 Subject: [PATCH 011/262] added description of the IReadFromConfig interface --- osu.Game/Rulesets/Mods/IReadFromConfig.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Rulesets/Mods/IReadFromConfig.cs b/osu.Game/Rulesets/Mods/IReadFromConfig.cs index 708edcfdfb..ec9fd00356 100644 --- a/osu.Game/Rulesets/Mods/IReadFromConfig.cs +++ b/osu.Game/Rulesets/Mods/IReadFromConfig.cs @@ -5,6 +5,9 @@ using osu.Game.Configuration; namespace osu.Game.Rulesets.Mods { + /// + /// An interface for mods that require reading access to the osu! configuration. + /// public interface IReadFromConfig { void ReadFromConfig(OsuConfigManager config); From 4068be1293d32d060cac90b15f6e360a11d34c8f Mon Sep 17 00:00:00 2001 From: Vidalee Date: Tue, 20 Mar 2018 21:54:44 +0100 Subject: [PATCH 012/262] cleared comment --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 8c4dac03a3..66eba5890a 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -30,12 +30,11 @@ namespace osu.Game.Rulesets.Osu.Mods public void ApplyToDrawableHitObjects(IEnumerable drawables) { - //In the Tests for hidden the ReadFromConfig() void isn't called -> the following bindable is null - //It's too much work to get the Dependency Injection on the Tests to get the config for just this mod, so I just make sure - //the bindable isn't null foreach (var d in drawables.OfType()) { //Don't hide the first object ("drawables" are in a reverse order -> Last() ) + //If increaseFirstObjectVisibility is null then we're exectuing one of the tests for the hidden mod. Since it's too much + //work for just this interface to work on this tests (DI of the config..), I just make sure to not throw a null exception if (d == drawables.Last() && (increaseFirstObjectVisibility == null || increaseFirstObjectVisibility)) continue; d.ApplyCustomUpdateState += ApplyHiddenState; From cdbe6bf22dcc1b64f609cb98ddc8926092a1630c Mon Sep 17 00:00:00 2001 From: Vidalee Date: Tue, 20 Mar 2018 21:55:35 +0100 Subject: [PATCH 013/262] cleared comment --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 66eba5890a..de2dc9f9b4 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Osu.Mods { foreach (var d in drawables.OfType()) { - //Don't hide the first object ("drawables" are in a reverse order -> Last() ) + //Don't hide the first object if the increaseFirstObjectVisibility is true ("drawables" are in a reverse order -> Last() ) //If increaseFirstObjectVisibility is null then we're exectuing one of the tests for the hidden mod. Since it's too much //work for just this interface to work on this tests (DI of the config..), I just make sure to not throw a null exception if (d == drawables.Last() && (increaseFirstObjectVisibility == null || increaseFirstObjectVisibility)) continue; From 8159e219fd310730331202c01b2edeb4e8325bab Mon Sep 17 00:00:00 2001 From: Vidalee Date: Tue, 20 Mar 2018 22:23:27 +0100 Subject: [PATCH 014/262] increaseFirstObjectVisibility now cannot be null --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 4 +--- 1 file changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index de2dc9f9b4..cd1d860f9f 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override double ScoreMultiplier => 1.06; private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; - private Bindable increaseFirstObjectVisibility; + private Bindable increaseFirstObjectVisibility = new Bindable(); public void ReadFromConfig(OsuConfigManager config) { @@ -33,8 +33,6 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var d in drawables.OfType()) { //Don't hide the first object if the increaseFirstObjectVisibility is true ("drawables" are in a reverse order -> Last() ) - //If increaseFirstObjectVisibility is null then we're exectuing one of the tests for the hidden mod. Since it's too much - //work for just this interface to work on this tests (DI of the config..), I just make sure to not throw a null exception if (d == drawables.Last() && (increaseFirstObjectVisibility == null || increaseFirstObjectVisibility)) continue; d.ApplyCustomUpdateState += ApplyHiddenState; From 505a7c14fca90ccff9340b252c93f274f5cc5964 Mon Sep 17 00:00:00 2001 From: Vidalee Date: Wed, 21 Mar 2018 21:14:17 +0100 Subject: [PATCH 015/262] was persuaded I changed the if statement... --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index cd1d860f9f..a599c70870 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var d in drawables.OfType()) { //Don't hide the first object if the increaseFirstObjectVisibility is true ("drawables" are in a reverse order -> Last() ) - if (d == drawables.Last() && (increaseFirstObjectVisibility == null || increaseFirstObjectVisibility)) continue; + if (d == drawables.Last() && increaseFirstObjectVisibility) continue; d.ApplyCustomUpdateState += ApplyHiddenState; d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; From 870ce8868cf3955754c266cec0da8fc754a91019 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 16:07:33 +0900 Subject: [PATCH 016/262] Make scrollabletimeline use gridcontainer --- .../Visual/TestCaseEditorComposeTimeline.cs | 3 +- .../Compose/Timeline/ScrollableTimeline.cs | 135 +++++++++--------- 2 files changed, 70 insertions(+), 68 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index d15ee32d8d..0e7ba5c900 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -34,7 +34,8 @@ namespace osu.Game.Tests.Visual { Anchor = Anchor.Centre, Origin = Anchor.Centre, - Size = new Vector2(1000, 100) + RelativeSizeAxes = Axes.X, + Size = new Vector2(0.8f, 100) } }; } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index c308b2b9f8..9ce4830e5a 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -33,82 +33,90 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Both, Colour = OsuColour.FromHex("111") }, - new FillFlowContainer + new GridContainer { RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Children = new Drawable[] + Content = new[] { - new Container + new Drawable[] { - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] + new Container { - new Box + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222") - }, - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Y, - Width = 160, - Padding = new MarginPadding { Horizontal = 15 }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 4), - Children = new[] + new Box { - hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" }, - hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" }, - waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222") + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Y, + Width = 160, + Padding = new MarginPadding { Horizontal = 15 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 4), + Children = new[] + { + hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" }, + hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" }, + waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } + } } } - } - }, - new Container - { - AutoSizeAxes = Axes.X, - RelativeSizeAxes = Axes.Y, - Children = new Drawable[] + }, + new Container { - new Box + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("333") - }, - new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Masking = true, - Children = new[] + new Box { - new TimelineButton + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("333") + }, + new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Masking = true, + Children = new[] { - RelativeSizeAxes = Axes.Y, - Height = 0.5f, - Icon = FontAwesome.fa_search_plus, - Action = () => timelineContainer.Zoom++ - }, - new TimelineButton - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Y, - Height = 0.5f, - Icon = FontAwesome.fa_search_minus, - Action = () => timelineContainer.Zoom-- - }, + new TimelineButton + { + RelativeSizeAxes = Axes.Y, + Height = 0.5f, + Icon = FontAwesome.fa_search_plus, + // Action = () => timelineContainer.Zoom++ + }, + new TimelineButton + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Y, + Height = 0.5f, + Icon = FontAwesome.fa_search_minus, + // Action = () => timelineContainer.Zoom-- + }, + } } } - } + }, + timelineContainer = new ScrollingTimelineContainer { RelativeSizeAxes = Axes.Both } }, - timelineContainer = new ScrollingTimelineContainer { RelativeSizeAxes = Axes.Y } + }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Distributed), } } }; @@ -120,12 +128,5 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline timelineContainer.Beatmap.BindTo(Beatmap); timelineContainer.WaveformVisible.BindTo(waveformCheckbox.Current); } - - protected override void Update() - { - base.Update(); - - timelineContainer.Size = new Vector2(DrawSize.X - timelineContainer.DrawPosition.X, 1); - } } } From e7aa1d9c38c500741ceb1da086a6aa73a5211c07 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 16:12:21 +0900 Subject: [PATCH 017/262] Temporarily remove zoom levels, simplify scrollingtimelinecontainer --- .../Timeline/ScrollingTimelineContainer.cs | 107 +----------------- 1 file changed, 3 insertions(+), 104 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index f71607a6cf..5195a85eac 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -1,12 +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 OpenTK; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Input; using osu.Game.Beatmaps; using osu.Game.Graphics; @@ -14,8 +11,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class ScrollingTimelineContainer : ScrollContainer { - public readonly Bindable HitObjectsVisible = new Bindable(); - public readonly Bindable HitSoundsVisible = new Bindable(); public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); @@ -26,6 +21,9 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { Masking = true; + Content.AutoSizeAxes = Axes.None; + Content.RelativeSizeAxes = Axes.Both; + Add(waveform = new BeatmapWaveformGraph { RelativeSizeAxes = Axes.Both, @@ -33,107 +31,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Depth = float.MaxValue }); - Content.AutoSizeAxes = Axes.None; - Content.RelativeSizeAxes = Axes.Both; - waveform.Beatmap.BindTo(Beatmap); WaveformVisible.ValueChanged += waveformVisibilityChanged; - - Zoom = 10; - } - - private float minZoom = 1; - /// - /// The minimum zoom level allowed. - /// - public float MinZoom - { - get { return minZoom; } - set - { - if (value <= 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (minZoom == value) - return; - minZoom = value; - - // Update the zoom level - Zoom = Zoom; - } - } - - private float maxZoom = 30; - /// - /// The maximum zoom level allowed. - /// - public float MaxZoom - { - get { return maxZoom; } - set - { - if (value <= 0) - throw new ArgumentOutOfRangeException(nameof(value)); - if (maxZoom == value) - return; - maxZoom = value; - - // Update the zoom level - Zoom = Zoom; - } - } - - private float zoom = 1; - /// - /// The current zoom level. - /// - public float Zoom - { - get { return zoom; } - set - { - value = MathHelper.Clamp(value, MinZoom, MaxZoom); - if (zoom == value) - return; - zoom = value; - - // Make the zoom target default to the center of the graph if it hasn't been set - if (relativeContentZoomTarget == null) - relativeContentZoomTarget = ToSpaceOfOtherDrawable(DrawSize / 2, Content).X / Content.DrawSize.X; - if (localZoomTarget == null) - localZoomTarget = DrawSize.X / 2; - - Content.ResizeWidthTo(Zoom); - - // Update the scroll position to focus on the zoom target - float scrollPos = Content.DrawSize.X * relativeContentZoomTarget.Value - localZoomTarget.Value; - ScrollTo(scrollPos, false); - - relativeContentZoomTarget = null; - localZoomTarget = null; - } - } - - /// - /// Zoom target as a relative position in the space. - /// - private float? relativeContentZoomTarget; - - /// - /// Zoom target as a position in our local space. - /// - private float? localZoomTarget; - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return base.OnWheel(state); - - relativeContentZoomTarget = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; - localZoomTarget = ToLocalSpace(state.Mouse.NativeState.Position).X; - - Zoom += state.Mouse.WheelDelta; - - return true; } private void waveformVisibilityChanged(bool visible) => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); From 9bb3e56bb3a22875f746175fee15640489713232 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 17:05:38 +0900 Subject: [PATCH 018/262] Implement half-width overflows --- .../Timeline/ScrollingTimelineContainer.cs | 28 +++++++++++++------ 1 file changed, 20 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 5195a85eac..e031e354db 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -14,6 +14,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); + private readonly Container waveformContainer; private readonly BeatmapWaveformGraph waveform; public ScrollingTimelineContainer() @@ -21,20 +22,31 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { Masking = true; - Content.AutoSizeAxes = Axes.None; - Content.RelativeSizeAxes = Axes.Both; - - Add(waveform = new BeatmapWaveformGraph + Child = waveformContainer = new Container { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue - }); + RelativeSizeAxes = Axes.Y, + Child = waveform = new BeatmapWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue + } + }; waveform.Beatmap.BindTo(Beatmap); WaveformVisible.ValueChanged += waveformVisibilityChanged; } + private float zoom = 10; + + protected override void Update() + { + base.Update(); + + waveformContainer.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; + waveformContainer.Width = DrawWidth * zoom; + } + private void waveformVisibilityChanged(bool visible) => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } } From e3af32ad2f0f581d56ce09c30849a632e6e830b7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 17:07:41 +0900 Subject: [PATCH 019/262] A bit of cleanup --- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index e031e354db..07896d63be 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -34,7 +34,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline }; waveform.Beatmap.BindTo(Beatmap); - WaveformVisible.ValueChanged += waveformVisibilityChanged; + + WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } private float zoom = 10; @@ -46,7 +47,5 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline waveformContainer.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; waveformContainer.Width = DrawWidth * zoom; } - - private void waveformVisibilityChanged(bool visible) => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } } From 074dee3a83a9d456378a91518f4daa8bb9b26e40 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 18:37:51 +0900 Subject: [PATCH 020/262] Re-implement mousewheel zoom --- .../Timeline/ScrollingTimelineContainer.cs | 73 +++++++++++++++++-- 1 file changed, 68 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 07896d63be..e4b19fc2c5 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -4,8 +4,12 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Input; +using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Graphics; +using OpenTK; namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { @@ -15,13 +19,15 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline public readonly Bindable Beatmap = new Bindable(); private readonly Container waveformContainer; - private readonly BeatmapWaveformGraph waveform; + + private float currentZoom = 10; public ScrollingTimelineContainer() : base(Direction.Horizontal) { Masking = true; + BeatmapWaveformGraph waveform; Child = waveformContainer = new Container { RelativeSizeAxes = Axes.Y, @@ -34,18 +40,75 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline }; waveform.Beatmap.BindTo(Beatmap); - + WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } - private float zoom = 10; - protected override void Update() { base.Update(); waveformContainer.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; - waveformContainer.Width = DrawWidth * zoom; + waveformContainer.Width = DrawWidth * currentZoom; + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + setZoomTarget(zoomTarget + state.Mouse.WheelDelta, waveformContainer.ToLocalSpace(state.Mouse.NativeState.Position).X); + return true; + } + + private float zoomTarget = 10; + private void setZoomTarget(float newZoom, float focusPoint) + { + zoomTarget = MathHelper.Clamp(newZoom, 1, 60); + transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); + } + + private void transformZoomTo(float newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, waveformContainer.DrawWidth, DrawWidth, Current), newZoom, duration, easing)); + + private class TransformZoom : Transform + { + private readonly float focusPoint; + private readonly float focusSize; + private readonly float sizeReference; + private readonly float scrollOffset; + + public TransformZoom(float focusPoint, float focusSize, float sizeReference, float scrollOffset) + { + this.focusPoint = focusPoint; + this.focusSize = focusSize; + this.sizeReference = sizeReference; + this.scrollOffset = scrollOffset; + } + + public override string TargetMember => nameof(currentZoom); + + private float valueAt(double time) + { + if (time < StartTime) return StartValue; + if (time >= EndTime) return EndValue; + + return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); + } + + protected override void Apply(ScrollingTimelineContainer d, double time) + { + float newZoom = valueAt(time); + + float focusOffset = focusPoint - scrollOffset; + float expectedWidth = sizeReference * newZoom; + float targetOffset = expectedWidth * (focusPoint / focusSize) - focusOffset; + + d.currentZoom = newZoom; + d.ScrollTo(targetOffset, false); + } + + protected override void ReadIntoStartValue(ScrollingTimelineContainer d) => StartValue = d.currentZoom; } } } From eff5eddbe97dac18b954d81aa32542988ab1e822 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 18:41:22 +0900 Subject: [PATCH 021/262] Make zoom an int again --- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index e4b19fc2c5..5e68b931a4 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -61,14 +61,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline return true; } - private float zoomTarget = 10; - private void setZoomTarget(float newZoom, float focusPoint) + private int zoomTarget = 10; + private void setZoomTarget(int newZoom, float focusPoint) { zoomTarget = MathHelper.Clamp(newZoom, 1, 60); transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); } - private void transformZoomTo(float newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) + private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, waveformContainer.DrawWidth, DrawWidth, Current), newZoom, duration, easing)); private class TransformZoom : Transform From 35e116cb1270dce0641d3856db21d7612d34961f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:04:07 +0900 Subject: [PATCH 022/262] Reduce ctor arguments --- .../Timeline/ScrollingTimelineContainer.cs | 41 +++++++++++++------ 1 file changed, 29 insertions(+), 12 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 5e68b931a4..a24bf7c909 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -69,21 +69,34 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) - => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, waveformContainer.DrawWidth, DrawWidth, Current), newZoom, duration, easing)); + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, waveformContainer.DrawWidth), newZoom, duration, easing)); private class TransformZoom : Transform { + /// + /// The focus point in the waveform, in absolute coordinates local to the waveform. + /// private readonly float focusPoint; - private readonly float focusSize; - private readonly float sizeReference; - private readonly float scrollOffset; - public TransformZoom(float focusPoint, float focusSize, float sizeReference, float scrollOffset) + /// + /// The size of the waveform. + /// + private readonly float waveformSize; + + /// + /// The scroll offset at the start time of the transform/ + /// + private float startScrollOffset; + + /// + /// Transforms to a new value. + /// + /// The focus point in the waveform, in absolute coordinates local to the waveform. + /// The size of the waveform. + public TransformZoom(float focusPoint, float waveformSize) { this.focusPoint = focusPoint; - this.focusSize = focusSize; - this.sizeReference = sizeReference; - this.scrollOffset = scrollOffset; + this.waveformSize = waveformSize; } public override string TargetMember => nameof(currentZoom); @@ -100,15 +113,19 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { float newZoom = valueAt(time); - float focusOffset = focusPoint - scrollOffset; - float expectedWidth = sizeReference * newZoom; - float targetOffset = expectedWidth * (focusPoint / focusSize) - focusOffset; + float focusOffset = focusPoint - startScrollOffset; + float expectedWidth = d.DrawWidth * newZoom; + float targetOffset = expectedWidth * (focusPoint / waveformSize) - focusOffset; d.currentZoom = newZoom; d.ScrollTo(targetOffset, false); } - protected override void ReadIntoStartValue(ScrollingTimelineContainer d) => StartValue = d.currentZoom; + protected override void ReadIntoStartValue(ScrollingTimelineContainer d) + { + startScrollOffset = d.Current; + StartValue = d.currentZoom; + } } } } From 8da3c2c52aa79ca631fcd12573bc443a61ac9d3a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:05:19 +0900 Subject: [PATCH 023/262] Expose zoom publicly again, re-enable zoom buttons --- .../Edit/Screens/Compose/Timeline/ScrollableTimeline.cs | 4 ++-- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 6 ++++++ 2 files changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 9ce4830e5a..31466e960f 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -94,7 +94,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Y, Height = 0.5f, Icon = FontAwesome.fa_search_plus, - // Action = () => timelineContainer.Zoom++ + Action = () => timelineContainer.Zoom++ }, new TimelineButton { @@ -103,7 +103,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Y, Height = 0.5f, Icon = FontAwesome.fa_search_minus, - // Action = () => timelineContainer.Zoom-- + Action = () => timelineContainer.Zoom-- }, } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index a24bf7c909..2fe5d09788 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -44,6 +44,12 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } + public int Zoom + { + get => zoomTarget; + set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), waveformContainer).X); + } + protected override void Update() { base.Update(); From 0141cbebbab43ab85b11d0377aadae6259483448 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:08:10 +0900 Subject: [PATCH 024/262] waveformContainer -> zoomedContent --- .../Timeline/ScrollingTimelineContainer.cs | 17 ++++++++++------- 1 file changed, 10 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 2fe5d09788..e48b625b8b 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -18,7 +18,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); - private readonly Container waveformContainer; + private readonly Container zoomedContent; private float currentZoom = 10; @@ -28,7 +28,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Masking = true; BeatmapWaveformGraph waveform; - Child = waveformContainer = new Container + Child = zoomedContent = new Container { RelativeSizeAxes = Axes.Y, Child = waveform = new BeatmapWaveformGraph @@ -44,18 +44,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } + /// + /// Gets or sets the content zoom of this . + /// public int Zoom { get => zoomTarget; - set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), waveformContainer).X); + set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); } protected override void Update() { base.Update(); - waveformContainer.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; - waveformContainer.Width = DrawWidth * currentZoom; + zoomedContent.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; + zoomedContent.Width = DrawWidth * currentZoom; } protected override bool OnWheel(InputState state) @@ -63,7 +66,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline if (!state.Keyboard.ControlPressed) return base.OnWheel(state); - setZoomTarget(zoomTarget + state.Mouse.WheelDelta, waveformContainer.ToLocalSpace(state.Mouse.NativeState.Position).X); + setZoomTarget(zoomTarget + state.Mouse.WheelDelta, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); return true; } @@ -75,7 +78,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) - => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, waveformContainer.DrawWidth), newZoom, duration, easing)); + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth), newZoom, duration, easing)); private class TransformZoom : Transform { From 9a9ed1d630d9aa01ecca4ae03251d3a75124c7b4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:30:54 +0900 Subject: [PATCH 025/262] Encapsulate zoom logic into a separate class --- .../Timeline/ScrollingTimelineContainer.cs | 115 ++--------------- .../Timeline/ZoomableScrollContainer.cs | 118 ++++++++++++++++++ 2 files changed, 125 insertions(+), 108 deletions(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index e48b625b8b..96dc54f1e9 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -3,40 +3,24 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Transforms; -using osu.Framework.Input; -using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Graphics; -using OpenTK; namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { - public class ScrollingTimelineContainer : ScrollContainer + public class ScrollingTimelineContainer : ZoomableScrollContainer { public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); - private readonly Container zoomedContent; - - private float currentZoom = 10; - public ScrollingTimelineContainer() - : base(Direction.Horizontal) { - Masking = true; - BeatmapWaveformGraph waveform; - Child = zoomedContent = new Container + Child = waveform = new BeatmapWaveformGraph { - RelativeSizeAxes = Axes.Y, - Child = waveform = new BeatmapWaveformGraph - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue - } + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue }; waveform.Beatmap.BindTo(Beatmap); @@ -44,97 +28,12 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } - /// - /// Gets or sets the content zoom of this . - /// - public int Zoom - { - get => zoomTarget; - set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); - } - protected override void Update() { base.Update(); - zoomedContent.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; - zoomedContent.Width = DrawWidth * currentZoom; - } - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return base.OnWheel(state); - - setZoomTarget(zoomTarget + state.Mouse.WheelDelta, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); - return true; - } - - private int zoomTarget = 10; - private void setZoomTarget(int newZoom, float focusPoint) - { - zoomTarget = MathHelper.Clamp(newZoom, 1, 60); - transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); - } - - private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) - => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth), newZoom, duration, easing)); - - private class TransformZoom : Transform - { - /// - /// The focus point in the waveform, in absolute coordinates local to the waveform. - /// - private readonly float focusPoint; - - /// - /// The size of the waveform. - /// - private readonly float waveformSize; - - /// - /// The scroll offset at the start time of the transform/ - /// - private float startScrollOffset; - - /// - /// Transforms to a new value. - /// - /// The focus point in the waveform, in absolute coordinates local to the waveform. - /// The size of the waveform. - public TransformZoom(float focusPoint, float waveformSize) - { - this.focusPoint = focusPoint; - this.waveformSize = waveformSize; - } - - public override string TargetMember => nameof(currentZoom); - - private float valueAt(double time) - { - if (time < StartTime) return StartValue; - if (time >= EndTime) return EndValue; - - return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); - } - - protected override void Apply(ScrollingTimelineContainer d, double time) - { - float newZoom = valueAt(time); - - float focusOffset = focusPoint - startScrollOffset; - float expectedWidth = d.DrawWidth * newZoom; - float targetOffset = expectedWidth * (focusPoint / waveformSize) - focusOffset; - - d.currentZoom = newZoom; - d.ScrollTo(targetOffset, false); - } - - protected override void ReadIntoStartValue(ScrollingTimelineContainer d) - { - startScrollOffset = d.Current; - StartValue = d.currentZoom; - } + // We want time = 0 to be at the centre of the container when scrolled to the start + Content.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; } } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs new file mode 100644 index 0000000000..05a2882f31 --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -0,0 +1,118 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Input; +using osu.Framework.MathUtils; +using OpenTK; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class ZoomableScrollContainer : ScrollContainer + { + private readonly Container zoomedContent; + protected override Container Content => zoomedContent; + + private float currentZoom = 10; + + public ZoomableScrollContainer() + : base(Direction.Horizontal) + { + base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y }); + } + + /// + /// Gets or sets the content zoom of this . + /// + public int Zoom + { + get => zoomTarget; + set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); + } + + protected override void Update() + { + base.Update(); + + zoomedContent.Width = DrawWidth * currentZoom; + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + setZoomTarget(zoomTarget + state.Mouse.WheelDelta, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); + return true; + } + + private int zoomTarget = 10; + private void setZoomTarget(int newZoom, float focusPoint) + { + zoomTarget = MathHelper.Clamp(newZoom, 1, 60); + transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); + } + + private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth), newZoom, duration, easing)); + + private class TransformZoom : Transform + { + /// + /// The focus point in the waveform, in absolute coordinates local to the waveform. + /// + private readonly float focusPoint; + + /// + /// The size of the waveform. + /// + private readonly float waveformSize; + + /// + /// The scroll offset at the start time of the transform/ + /// + private float startScrollOffset; + + /// + /// Transforms to a new value. + /// + /// The focus point in the waveform, in absolute coordinates local to the waveform. + /// The size of the waveform. + public TransformZoom(float focusPoint, float waveformSize) + { + this.focusPoint = focusPoint; + this.waveformSize = waveformSize; + } + + public override string TargetMember => nameof(currentZoom); + + private float valueAt(double time) + { + if (time < StartTime) return StartValue; + if (time >= EndTime) return EndValue; + + return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); + } + + protected override void Apply(ZoomableScrollContainer d, double time) + { + float newZoom = valueAt(time); + + float focusOffset = focusPoint - startScrollOffset; + float expectedWidth = d.DrawWidth * newZoom; + float targetOffset = expectedWidth * (focusPoint / waveformSize) - focusOffset; + + d.currentZoom = newZoom; + d.ScrollTo(targetOffset, false); + } + + protected override void ReadIntoStartValue(ZoomableScrollContainer d) + { + startScrollOffset = d.Current; + StartValue = d.currentZoom; + } + } + } +} From f41d31e1db2f2a1b2d4e398662cec4bddf8cca97 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:32:23 +0900 Subject: [PATCH 026/262] ScrollableTimeline -> TimelineContainer --- .../Visual/TestCaseEditorComposeTimeline.cs | 8 ++++---- osu.Game/Screens/Edit/Screens/Compose/Compose.cs | 6 +++--- ...crollableTimeline.cs => TimelineContainer.cs} | 16 ++++++++-------- 3 files changed, 15 insertions(+), 15 deletions(-) rename osu.Game/Screens/Edit/Screens/Compose/Timeline/{ScrollableTimeline.cs => TimelineContainer.cs} (90%) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index 0e7ba5c900..5323ac44b1 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -16,9 +16,9 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseEditorComposeTimeline : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(TimelineContainer), typeof(Timeline), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; - private readonly ScrollableTimeline timeline; + private readonly TimelineContainer timelineContainer; public TestCaseEditorComposeTimeline() { @@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual Origin = Anchor.TopCentre, State = Visibility.Visible }, - timeline = new ScrollableTimeline + timelineContainer = new TimelineContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase osuGame) { - timeline.Beatmap.BindTo(osuGame.Beatmap); + timelineContainer.Beatmap.BindTo(osuGame.Beatmap); } } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs index 91adc8324a..d04c4c9c0f 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { dependencies.Cache(beatDivisor); - ScrollableTimeline timeline; + TimelineContainer timelineContainer; Children = new Drawable[] { new GridContainer @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = 5 }, - Child = timeline = new ScrollableTimeline { RelativeSizeAxes = Axes.Both } + Child = timelineContainer = new TimelineContainer { RelativeSizeAxes = Axes.Both } }, new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both } }, @@ -97,7 +97,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose }, }; - timeline.Beatmap.BindTo(Beatmap); + timelineContainer.Beatmap.BindTo(Beatmap); var ruleset = Beatmap.Value.BeatmapInfo.Ruleset?.CreateInstance(); if (ruleset == null) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs similarity index 90% rename from osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs index 31466e960f..95a8937b9b 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs @@ -12,13 +12,13 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { - public class ScrollableTimeline : CompositeDrawable + public class TimelineContainer : CompositeDrawable { public readonly Bindable Beatmap = new Bindable(); - private readonly ScrollingTimelineContainer timelineContainer; + private readonly Timeline timeline; - public ScrollableTimeline() + public TimelineContainer() { Masking = true; CornerRadius = 5; @@ -94,7 +94,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Y, Height = 0.5f, Icon = FontAwesome.fa_search_plus, - Action = () => timelineContainer.Zoom++ + Action = () => timeline.Zoom++ }, new TimelineButton { @@ -103,13 +103,13 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline RelativeSizeAxes = Axes.Y, Height = 0.5f, Icon = FontAwesome.fa_search_minus, - Action = () => timelineContainer.Zoom-- + Action = () => timeline.Zoom-- }, } } } }, - timelineContainer = new ScrollingTimelineContainer { RelativeSizeAxes = Axes.Both } + timeline = new Timeline { RelativeSizeAxes = Axes.Both } }, }, ColumnDimensions = new[] @@ -125,8 +125,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline hitSoundsCheckbox.Current.Value = true; waveformCheckbox.Current.Value = true; - timelineContainer.Beatmap.BindTo(Beatmap); - timelineContainer.WaveformVisible.BindTo(waveformCheckbox.Current); + timeline.Beatmap.BindTo(Beatmap); + timeline.WaveformVisible.BindTo(waveformCheckbox.Current); } } } From a84536d343be59f40e2905ad947bcdd135fc5054 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:33:47 +0900 Subject: [PATCH 027/262] ScrollingTimelineContainer -> Timeline --- .../Timeline/{ScrollingTimelineContainer.cs => Timeline.cs} | 4 ++-- .../Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) rename osu.Game/Screens/Edit/Screens/Compose/Timeline/{ScrollingTimelineContainer.cs => Timeline.cs} (88%) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs similarity index 88% rename from osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index 96dc54f1e9..f1086e2cf6 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -8,12 +8,12 @@ using osu.Game.Graphics; namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { - public class ScrollingTimelineContainer : ZoomableScrollContainer + public class Timeline : ZoomableScrollContainer { public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); - public ScrollingTimelineContainer() + public Timeline() { BeatmapWaveformGraph waveform; Child = waveform = new BeatmapWaveformGraph diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index 05a2882f31..592419b336 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } /// - /// Gets or sets the content zoom of this . + /// Gets or sets the content zoom of this . /// public int Zoom { @@ -76,7 +76,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private float startScrollOffset; /// - /// Transforms to a new value. + /// Transforms to a new value. /// /// The focus point in the waveform, in absolute coordinates local to the waveform. /// The size of the waveform. From d9e795fb9f7a8ee7f372e84653ec3eb870b2b92d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 5 Apr 2018 19:40:03 +0900 Subject: [PATCH 028/262] TimelineContainer -> TimelineArea --- osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs | 8 ++++---- osu.Game/Screens/Edit/Screens/Compose/Compose.cs | 6 +++--- .../Timeline/{TimelineContainer.cs => TimelineArea.cs} | 4 ++-- .../Screens/Compose/Timeline/ZoomableScrollContainer.cs | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) rename osu.Game/Screens/Edit/Screens/Compose/Timeline/{TimelineContainer.cs => TimelineArea.cs} (96%) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index 5323ac44b1..8ffb54f2c7 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -16,9 +16,9 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseEditorComposeTimeline : OsuTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(TimelineContainer), typeof(Timeline), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; + public override IReadOnlyList RequiredTypes => new[] { typeof(TimelineArea), typeof(Timeline), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; - private readonly TimelineContainer timelineContainer; + private readonly TimelineArea timelineArea; public TestCaseEditorComposeTimeline() { @@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual Origin = Anchor.TopCentre, State = Visibility.Visible }, - timelineContainer = new TimelineContainer + timelineArea = new TimelineArea { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -43,7 +43,7 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase osuGame) { - timelineContainer.Beatmap.BindTo(osuGame.Beatmap); + timelineArea.Beatmap.BindTo(osuGame.Beatmap); } } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs index d04c4c9c0f..9306a3394c 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs @@ -31,7 +31,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { dependencies.Cache(beatDivisor); - TimelineContainer timelineContainer; + TimelineArea timelineArea; Children = new Drawable[] { new GridContainer @@ -68,7 +68,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = 5 }, - Child = timelineContainer = new TimelineContainer { RelativeSizeAxes = Axes.Both } + Child = timelineArea = new TimelineArea { RelativeSizeAxes = Axes.Both } }, new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both } }, @@ -97,7 +97,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose }, }; - timelineContainer.Beatmap.BindTo(Beatmap); + timelineArea.Beatmap.BindTo(Beatmap); var ruleset = Beatmap.Value.BeatmapInfo.Ruleset?.CreateInstance(); if (ruleset == null) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs similarity index 96% rename from osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs rename to osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs index 95a8937b9b..6793c30409 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs @@ -12,13 +12,13 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { - public class TimelineContainer : CompositeDrawable + public class TimelineArea : CompositeDrawable { public readonly Bindable Beatmap = new Bindable(); private readonly Timeline timeline; - public TimelineContainer() + public TimelineArea() { Masking = true; CornerRadius = 5; diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index 592419b336..a5be41bb9f 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -76,7 +76,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private float startScrollOffset; /// - /// Transforms to a new value. + /// Transforms to a new value. /// /// The focus point in the waveform, in absolute coordinates local to the waveform. /// The size of the waveform. From 9b060b1bdf496cb45c742c679b1681297d14d48f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 6 Apr 2018 15:51:40 +0900 Subject: [PATCH 029/262] Fix delay in value retrieval causing offsetting when zooming --- .../Timeline/ZoomableScrollContainer.cs | 18 ++++++++---------- 1 file changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index a5be41bb9f..194b689f10 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) - => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth), newZoom, duration, easing)); + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth, Current), newZoom, duration, easing)); private class TransformZoom : Transform { @@ -71,19 +71,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private readonly float waveformSize; /// - /// The scroll offset at the start time of the transform/ + /// The scroll offset at the start of the transform. /// - private float startScrollOffset; + private readonly float scrollOffset; /// /// Transforms to a new value. /// /// The focus point in the waveform, in absolute coordinates local to the waveform. /// The size of the waveform. - public TransformZoom(float focusPoint, float waveformSize) + /// The scroll offset at the start of the transform. + public TransformZoom(float focusPoint, float waveformSize, float scrollOffset) { this.focusPoint = focusPoint; this.waveformSize = waveformSize; + this.scrollOffset = scrollOffset; } public override string TargetMember => nameof(currentZoom); @@ -100,7 +102,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { float newZoom = valueAt(time); - float focusOffset = focusPoint - startScrollOffset; + float focusOffset = focusPoint - scrollOffset; float expectedWidth = d.DrawWidth * newZoom; float targetOffset = expectedWidth * (focusPoint / waveformSize) - focusOffset; @@ -108,11 +110,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline d.ScrollTo(targetOffset, false); } - protected override void ReadIntoStartValue(ZoomableScrollContainer d) - { - startScrollOffset = d.Current; - StartValue = d.currentZoom; - } + protected override void ReadIntoStartValue(ZoomableScrollContainer d) => StartValue = d.currentZoom; } } } From f07928446d59d1199101f522baf4838e29e3c01f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 6 Apr 2018 15:52:39 +0900 Subject: [PATCH 030/262] Remove instances of "waveform" --- .../Compose/Timeline/ZoomableScrollContainer.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index 194b689f10..ee5d336419 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -61,14 +61,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private class TransformZoom : Transform { /// - /// The focus point in the waveform, in absolute coordinates local to the waveform. + /// The focus point in absolute coordinates local to the content. /// private readonly float focusPoint; /// - /// The size of the waveform. + /// The size of the content. /// - private readonly float waveformSize; + private readonly float contentSize; /// /// The scroll offset at the start of the transform. @@ -78,13 +78,13 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline /// /// Transforms to a new value. /// - /// The focus point in the waveform, in absolute coordinates local to the waveform. - /// The size of the waveform. + /// The focus point in absolute coordinates local to the content. + /// The size of the content. /// The scroll offset at the start of the transform. - public TransformZoom(float focusPoint, float waveformSize, float scrollOffset) + public TransformZoom(float focusPoint, float contentSize, float scrollOffset) { this.focusPoint = focusPoint; - this.waveformSize = waveformSize; + this.contentSize = contentSize; this.scrollOffset = scrollOffset; } @@ -104,7 +104,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline float focusOffset = focusPoint - scrollOffset; float expectedWidth = d.DrawWidth * newZoom; - float targetOffset = expectedWidth * (focusPoint / waveformSize) - focusOffset; + float targetOffset = expectedWidth * (focusPoint / contentSize) - focusOffset; d.currentZoom = newZoom; d.ScrollTo(targetOffset, false); From 393c01ba90fbb45bb6d068bf1575cfbe512388dd Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 6 May 2018 12:38:25 +0200 Subject: [PATCH 031/262] Made the changes requested --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 24 ++----------- osu.Game/Rulesets/Mods/ModHidden.cs | 28 +++++++++++++++- osu.Game/Rulesets/UI/RulesetContainer.cs | 39 +++++++++++----------- 3 files changed, 48 insertions(+), 43 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 0edea5ac66..7652d47a36 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -15,34 +15,14 @@ using osu.Framework.Configuration; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects, IReadFromConfig + public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects { public override string Description => @"Play with no approach circles and fading circles/sliders."; public override double ScoreMultiplier => 1.06; private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; - private Bindable increaseFirstObjectVisibility = new Bindable(); - public void ReadFromConfig(OsuConfigManager config) - { - increaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); - } - - public void ApplyToDrawableHitObjects(IEnumerable drawables) - { - foreach (var d in drawables.OfType()) - { - //Don't hide the first object if the increaseFirstObjectVisibility is true ("drawables" are in a reverse order -> Last() ) - if (d == drawables.Last() && increaseFirstObjectVisibility) continue; - d.ApplyCustomUpdateState += ApplyHiddenState; - - d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; - foreach (var h in d.HitObject.NestedHitObjects.OfType()) - h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; - } - } - - protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state) + protected override void ApplyHiddenState(DrawableHitObject drawable, ArmedState state) { if (!(drawable is DrawableOsuHitObject d)) return; diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index b489a665d9..e80533b6cc 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -1,16 +1,42 @@ // 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.Configuration; +using osu.Game.Configuration; using osu.Game.Graphics; +using osu.Game.Rulesets.Objects.Drawables; +using System.Collections.Generic; +using System.Linq; namespace osu.Game.Rulesets.Mods { - public abstract class ModHidden : Mod + public abstract class ModHidden : Mod, IReadFromConfig { public override string Name => "Hidden"; public override string ShortenedName => "HD"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden; public override ModType Type => ModType.DifficultyIncrease; public override bool Ranked => true; + + protected Bindable increaseFirstObjectVisibility = new Bindable(); + + public void ReadFromConfig(OsuConfigManager config) + { + increaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); + } + + public void ApplyToDrawableHitObjects(IEnumerable drawables) + { + foreach (var d in drawables.OfType()) + { + if (d == drawables.Last() && increaseFirstObjectVisibility) + return; + + d.ApplyCustomUpdateState += ApplyHiddenState; + } + } + + protected virtual void ApplyHiddenState(DrawableHitObject hitObject, ArmedState state) { } } } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index e22e87dcc9..ce563b7e06 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -66,6 +66,7 @@ namespace osu.Game.Rulesets.UI /// The cursor provided by this . May be null if no cursor is provided. /// public readonly CursorContainer Cursor; + protected readonly Ruleset Ruleset; @@ -88,12 +89,11 @@ namespace osu.Game.Rulesets.UI Cursor = CreateCursor(); } - + [BackgroundDependencyLoader(true)] private void load(OnScreenDisplay onScreenDisplay, SettingsStore settings) { this.onScreenDisplay = onScreenDisplay; - rulesetConfig = CreateConfig(Ruleset, settings); if (rulesetConfig != null) @@ -101,6 +101,7 @@ namespace osu.Game.Rulesets.UI dependencies.Cache(rulesetConfig); onScreenDisplay?.BeginTracking(this, rulesetConfig); } + } public abstract ScoreProcessor CreateScoreProcessor(); @@ -130,7 +131,6 @@ namespace osu.Game.Rulesets.UI HasReplayLoaded.Value = ReplayInputManager.ReplayInputHandler != null; } - /// /// Creates the cursor. May be null if the doesn't provide a custom cursor. /// @@ -167,6 +167,7 @@ namespace osu.Game.Rulesets.UI public abstract class RulesetContainer : RulesetContainer where TObject : HitObject { + public event Action OnJudgement; public event Action OnJudgementRemoved; @@ -194,7 +195,7 @@ namespace osu.Game.Rulesets.UI /// Whether the specified beatmap is assumed to be specific to the current ruleset. /// public readonly bool IsForCurrentRuleset; - + public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(this); protected override Container Content => content; @@ -202,11 +203,8 @@ namespace osu.Game.Rulesets.UI private IEnumerable mods; [BackgroundDependencyLoader] - private void load(OsuConfigManager osuConfig) + private void load(OsuConfigManager config) { - // Apply mods - applyMods(Mods, osuConfig); - KeyBindingInputManager.Add(content = new Container { RelativeSizeAxes = Axes.Both, @@ -218,7 +216,11 @@ namespace osu.Game.Rulesets.UI if (Cursor != null) KeyBindingInputManager.Add(Cursor); + // Apply mods + applyMods(Mods, config); + loadObjects(); + } /// @@ -235,7 +237,6 @@ namespace osu.Game.Rulesets.UI WorkingBeatmap = workingBeatmap; IsForCurrentRuleset = isForCurrentRuleset; - // ReSharper disable once PossibleNullReferenceException Mods = workingBeatmap.Mods.Value; RelativeSizeAxes = Axes.Both; @@ -269,31 +270,29 @@ namespace osu.Game.Rulesets.UI KeyBindingInputManager.RelativeSizeAxes = Axes.Both; // Add mods, should always be the last thing applied to give full control to mods - // Mods are now added in the load() method because we need the OsuConfigManager - // for the IReadFromConfig implementations. This method is still executed after the constructor, - // so the mods are still added in last + // Mods are now added in the load() method, this method is still executed after the constructor + // so they are still added in last } - - /// /// Applies the active mods to this RulesetContainer. /// /// private void applyMods(IEnumerable mods, OsuConfigManager config) { - if (mods == null) + if(mods == null) + { return; - - foreach (var mod in mods.OfType()) - mod.ReadFromConfig(config); - + } foreach (var mod in mods.OfType>()) foreach (var obj in Beatmap.HitObjects) mod.ApplyToHitObject(obj); foreach (var mod in mods.OfType>()) mod.ApplyToRulesetContainer(this); + + foreach (var mod in mods.OfType()) + mod.ReadFromConfig(config); } public override void SetReplay(Replay replay) @@ -301,7 +300,7 @@ namespace osu.Game.Rulesets.UI base.SetReplay(replay); if (ReplayInputManager?.ReplayInputHandler != null) - ReplayInputManager.ReplayInputHandler.GamefieldToScreenSpace = Playfield.GamefieldToScreenSpace; + ReplayInputManager.ReplayInputHandler.ToScreenSpace = input => Playfield.ScaledContent.ToScreenSpace(input); } /// From 095f6e1530aee70c3f8e72063cfbfeea17c36dae Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 6 May 2018 12:49:15 +0200 Subject: [PATCH 032/262] Code sanity --- osu.Game/Rulesets/UI/RulesetContainer.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index ce563b7e06..ce65260edb 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -66,7 +66,6 @@ namespace osu.Game.Rulesets.UI /// The cursor provided by this . May be null if no cursor is provided. /// public readonly CursorContainer Cursor; - protected readonly Ruleset Ruleset; @@ -101,7 +100,6 @@ namespace osu.Game.Rulesets.UI dependencies.Cache(rulesetConfig); onScreenDisplay?.BeginTracking(this, rulesetConfig); } - } public abstract ScoreProcessor CreateScoreProcessor(); @@ -220,7 +218,6 @@ namespace osu.Game.Rulesets.UI applyMods(Mods, config); loadObjects(); - } /// From 008daf9a076da74b1f50eb7de9efb4a2f5baeb8f Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 6 May 2018 12:57:52 +0200 Subject: [PATCH 033/262] White space trimmed --- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index ce65260edb..3332ef6a77 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.UI Cursor = CreateCursor(); } - + [BackgroundDependencyLoader(true)] private void load(OnScreenDisplay onScreenDisplay, SettingsStore settings) { From af851022770611a685b9bcae74d5784eec304454 Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 6 May 2018 13:04:20 +0200 Subject: [PATCH 034/262] Should be ok now --- osu.Game/Rulesets/UI/RulesetContainer.cs | 6 ++++-- 1 file changed, 4 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 3332ef6a77..59b26e91de 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -67,6 +67,7 @@ namespace osu.Game.Rulesets.UI /// public readonly CursorContainer Cursor; + protected readonly Ruleset Ruleset; private IRulesetConfigManager rulesetConfig; @@ -165,7 +166,7 @@ namespace osu.Game.Rulesets.UI public abstract class RulesetContainer : RulesetContainer where TObject : HitObject { - + public event Action OnJudgement; public event Action OnJudgementRemoved; @@ -193,7 +194,7 @@ namespace osu.Game.Rulesets.UI /// Whether the specified beatmap is assumed to be specific to the current ruleset. /// public readonly bool IsForCurrentRuleset; - + public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(this); protected override Container Content => content; @@ -218,6 +219,7 @@ namespace osu.Game.Rulesets.UI applyMods(Mods, config); loadObjects(); + } /// From d36d9643eb5ae76e2e9bb7ca3a645402468b84f0 Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 6 May 2018 13:09:46 +0200 Subject: [PATCH 035/262] Missed one white space.. I guess my editor wasn't properly configured for this file --- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 59b26e91de..749fcb476c 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -289,7 +289,7 @@ namespace osu.Game.Rulesets.UI foreach (var mod in mods.OfType>()) mod.ApplyToRulesetContainer(this); - + foreach (var mod in mods.OfType()) mod.ReadFromConfig(config); } From c4e45e30ef2d64a544a5f38240badd03ea54aa44 Mon Sep 17 00:00:00 2001 From: Vidalee Date: Sun, 6 May 2018 13:18:12 +0200 Subject: [PATCH 036/262] Solving conflict --- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 749fcb476c..3ff67dcef9 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -299,7 +299,7 @@ namespace osu.Game.Rulesets.UI base.SetReplay(replay); if (ReplayInputManager?.ReplayInputHandler != null) - ReplayInputManager.ReplayInputHandler.ToScreenSpace = input => Playfield.ScaledContent.ToScreenSpace(input); + ReplayInputManager.ReplayInputHandler.GamefieldToScreenSpace = Playfield.GamefieldToScreenSpace; } /// From 16bcd6c3ed98595310fcd6265fd9072bd079b50d Mon Sep 17 00:00:00 2001 From: Vidalee Date: Tue, 8 May 2018 14:33:26 +0200 Subject: [PATCH 037/262] Appvtests (#1) * Resolving AppVeyor's errors --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 5 ----- osu.Game/Rulesets/Mods/ModHidden.cs | 9 ++++----- 2 files changed, 4 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index 7652d47a36..f7a9fda14f 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -2,16 +2,11 @@ // 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.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; -using osu.Game.Configuration; -using osu.Framework.Configuration; namespace osu.Game.Rulesets.Osu.Mods { diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index e80533b6cc..ab1911fe88 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.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.Framework.Allocation; using osu.Framework.Configuration; using osu.Game.Configuration; using osu.Game.Graphics; @@ -19,18 +18,18 @@ namespace osu.Game.Rulesets.Mods public override ModType Type => ModType.DifficultyIncrease; public override bool Ranked => true; - protected Bindable increaseFirstObjectVisibility = new Bindable(); + protected Bindable IncreaseFirstObjectVisibility = new Bindable(); public void ReadFromConfig(OsuConfigManager config) { - increaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); + IncreaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); } public void ApplyToDrawableHitObjects(IEnumerable drawables) { - foreach (var d in drawables.OfType()) + foreach (var d in drawables) { - if (d == drawables.Last() && increaseFirstObjectVisibility) + if (d == drawables.Last() && IncreaseFirstObjectVisibility) return; d.ApplyCustomUpdateState += ApplyHiddenState; From 2492e34d3fd8be6aaf3d3804b413901485de8b80 Mon Sep 17 00:00:00 2001 From: Vidalee Date: Thu, 17 May 2018 19:44:09 +0200 Subject: [PATCH 038/262] resolving codefactor styling issues --- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 0587d34c2e..1cad3c827b 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -166,7 +166,6 @@ namespace osu.Game.Rulesets.UI public abstract class RulesetContainer : RulesetContainer where TObject : HitObject { - public event Action OnJudgement; public event Action OnJudgementRemoved; @@ -214,7 +213,6 @@ namespace osu.Game.Rulesets.UI applyMods(Mods, config); loadObjects(); - } /// From bc3d195aa21361f86490c7bd86f1f099c94fc00b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 18 May 2018 13:05:58 +0900 Subject: [PATCH 039/262] Fix line endings --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 78 +++--- .../Screens/Compose/Timeline/TimelineArea.cs | 264 +++++++++--------- .../Timeline/ZoomableScrollContainer.cs | 232 +++++++-------- 3 files changed, 287 insertions(+), 287 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index f1086e2cf6..a9de155df8 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -1,39 +1,39 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Configuration; -using osu.Framework.Graphics; -using osu.Game.Beatmaps; -using osu.Game.Graphics; - -namespace osu.Game.Screens.Edit.Screens.Compose.Timeline -{ - public class Timeline : ZoomableScrollContainer - { - public readonly Bindable WaveformVisible = new Bindable(); - public readonly Bindable Beatmap = new Bindable(); - - public Timeline() - { - BeatmapWaveformGraph waveform; - Child = waveform = new BeatmapWaveformGraph - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222"), - Depth = float.MaxValue - }; - - waveform.Beatmap.BindTo(Beatmap); - - WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); - } - - protected override void Update() - { - base.Update(); - - // We want time = 0 to be at the centre of the container when scrolled to the start - Content.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; - } - } -} +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Game.Beatmaps; +using osu.Game.Graphics; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class Timeline : ZoomableScrollContainer + { + public readonly Bindable WaveformVisible = new Bindable(); + public readonly Bindable Beatmap = new Bindable(); + + public Timeline() + { + BeatmapWaveformGraph waveform; + Child = waveform = new BeatmapWaveformGraph + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222"), + Depth = float.MaxValue + }; + + waveform.Beatmap.BindTo(Beatmap); + + WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); + } + + protected override void Update() + { + base.Update(); + + // We want time = 0 to be at the centre of the container when scrolled to the start + Content.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; + } + } +} diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs index 6793c30409..9b6b0bd48d 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/TimelineArea.cs @@ -1,132 +1,132 @@ -// 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.Configuration; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; - -namespace osu.Game.Screens.Edit.Screens.Compose.Timeline -{ - public class TimelineArea : CompositeDrawable - { - public readonly Bindable Beatmap = new Bindable(); - - private readonly Timeline timeline; - - public TimelineArea() - { - Masking = true; - CornerRadius = 5; - - OsuCheckbox hitObjectsCheckbox; - OsuCheckbox hitSoundsCheckbox; - OsuCheckbox waveformCheckbox; - InternalChildren = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("111") - }, - new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222") - }, - new FillFlowContainer - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AutoSizeAxes = Axes.Y, - Width = 160, - Padding = new MarginPadding { Horizontal = 15 }, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 4), - Children = new[] - { - hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" }, - hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" }, - waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } - } - } - } - }, - new Container - { - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("333") - }, - new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Y, - AutoSizeAxes = Axes.X, - Masking = true, - Children = new[] - { - new TimelineButton - { - RelativeSizeAxes = Axes.Y, - Height = 0.5f, - Icon = FontAwesome.fa_search_plus, - Action = () => timeline.Zoom++ - }, - new TimelineButton - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.Y, - Height = 0.5f, - Icon = FontAwesome.fa_search_minus, - Action = () => timeline.Zoom-- - }, - } - } - } - }, - timeline = new Timeline { RelativeSizeAxes = Axes.Both } - }, - }, - ColumnDimensions = new[] - { - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.AutoSize), - new Dimension(GridSizeMode.Distributed), - } - } - }; - - hitObjectsCheckbox.Current.Value = true; - hitSoundsCheckbox.Current.Value = true; - waveformCheckbox.Current.Value = true; - - timeline.Beatmap.BindTo(Beatmap); - timeline.WaveformVisible.BindTo(waveformCheckbox.Current); - } - } -} +// 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.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Beatmaps; +using osu.Game.Graphics; +using osu.Game.Graphics.UserInterface; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class TimelineArea : CompositeDrawable + { + public readonly Bindable Beatmap = new Bindable(); + + private readonly Timeline timeline; + + public TimelineArea() + { + Masking = true; + CornerRadius = 5; + + OsuCheckbox hitObjectsCheckbox; + OsuCheckbox hitSoundsCheckbox; + OsuCheckbox waveformCheckbox; + InternalChildren = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("111") + }, + new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + new Container + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("222") + }, + new FillFlowContainer + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Y, + Width = 160, + Padding = new MarginPadding { Horizontal = 15 }, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 4), + Children = new[] + { + hitObjectsCheckbox = new OsuCheckbox { LabelText = "Hitobjects" }, + hitSoundsCheckbox = new OsuCheckbox { LabelText = "Hitsounds" }, + waveformCheckbox = new OsuCheckbox { LabelText = "Waveform" } + } + } + } + }, + new Container + { + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.FromHex("333") + }, + new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Y, + AutoSizeAxes = Axes.X, + Masking = true, + Children = new[] + { + new TimelineButton + { + RelativeSizeAxes = Axes.Y, + Height = 0.5f, + Icon = FontAwesome.fa_search_plus, + Action = () => timeline.Zoom++ + }, + new TimelineButton + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.Y, + Height = 0.5f, + Icon = FontAwesome.fa_search_minus, + Action = () => timeline.Zoom-- + }, + } + } + } + }, + timeline = new Timeline { RelativeSizeAxes = Axes.Both } + }, + }, + ColumnDimensions = new[] + { + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Distributed), + } + } + }; + + hitObjectsCheckbox.Current.Value = true; + hitSoundsCheckbox.Current.Value = true; + waveformCheckbox.Current.Value = true; + + timeline.Beatmap.BindTo(Beatmap); + timeline.WaveformVisible.BindTo(waveformCheckbox.Current); + } + } +} diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index ee5d336419..545caf5166 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -1,116 +1,116 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Transforms; -using osu.Framework.Input; -using osu.Framework.MathUtils; -using OpenTK; - -namespace osu.Game.Screens.Edit.Screens.Compose.Timeline -{ - public class ZoomableScrollContainer : ScrollContainer - { - private readonly Container zoomedContent; - protected override Container Content => zoomedContent; - - private float currentZoom = 10; - - public ZoomableScrollContainer() - : base(Direction.Horizontal) - { - base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y }); - } - - /// - /// Gets or sets the content zoom of this . - /// - public int Zoom - { - get => zoomTarget; - set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); - } - - protected override void Update() - { - base.Update(); - - zoomedContent.Width = DrawWidth * currentZoom; - } - - protected override bool OnWheel(InputState state) - { - if (!state.Keyboard.ControlPressed) - return base.OnWheel(state); - - setZoomTarget(zoomTarget + state.Mouse.WheelDelta, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); - return true; - } - - private int zoomTarget = 10; - private void setZoomTarget(int newZoom, float focusPoint) - { - zoomTarget = MathHelper.Clamp(newZoom, 1, 60); - transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); - } - - private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) - => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth, Current), newZoom, duration, easing)); - - private class TransformZoom : Transform - { - /// - /// The focus point in absolute coordinates local to the content. - /// - private readonly float focusPoint; - - /// - /// The size of the content. - /// - private readonly float contentSize; - - /// - /// The scroll offset at the start of the transform. - /// - private readonly float scrollOffset; - - /// - /// Transforms to a new value. - /// - /// The focus point in absolute coordinates local to the content. - /// The size of the content. - /// The scroll offset at the start of the transform. - public TransformZoom(float focusPoint, float contentSize, float scrollOffset) - { - this.focusPoint = focusPoint; - this.contentSize = contentSize; - this.scrollOffset = scrollOffset; - } - - public override string TargetMember => nameof(currentZoom); - - private float valueAt(double time) - { - if (time < StartTime) return StartValue; - if (time >= EndTime) return EndValue; - - return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); - } - - protected override void Apply(ZoomableScrollContainer d, double time) - { - float newZoom = valueAt(time); - - float focusOffset = focusPoint - scrollOffset; - float expectedWidth = d.DrawWidth * newZoom; - float targetOffset = expectedWidth * (focusPoint / contentSize) - focusOffset; - - d.currentZoom = newZoom; - d.ScrollTo(targetOffset, false); - } - - protected override void ReadIntoStartValue(ZoomableScrollContainer d) => StartValue = d.currentZoom; - } - } -} +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Input; +using osu.Framework.MathUtils; +using OpenTK; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class ZoomableScrollContainer : ScrollContainer + { + private readonly Container zoomedContent; + protected override Container Content => zoomedContent; + + private float currentZoom = 10; + + public ZoomableScrollContainer() + : base(Direction.Horizontal) + { + base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y }); + } + + /// + /// Gets or sets the content zoom of this . + /// + public int Zoom + { + get => zoomTarget; + set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); + } + + protected override void Update() + { + base.Update(); + + zoomedContent.Width = DrawWidth * currentZoom; + } + + protected override bool OnWheel(InputState state) + { + if (!state.Keyboard.ControlPressed) + return base.OnWheel(state); + + setZoomTarget(zoomTarget + state.Mouse.WheelDelta, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); + return true; + } + + private int zoomTarget = 10; + private void setZoomTarget(int newZoom, float focusPoint) + { + zoomTarget = MathHelper.Clamp(newZoom, 1, 60); + transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); + } + + private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) + => this.TransformTo(this.PopulateTransform(new TransformZoom(focusPoint, zoomedContent.DrawWidth, Current), newZoom, duration, easing)); + + private class TransformZoom : Transform + { + /// + /// The focus point in absolute coordinates local to the content. + /// + private readonly float focusPoint; + + /// + /// The size of the content. + /// + private readonly float contentSize; + + /// + /// The scroll offset at the start of the transform. + /// + private readonly float scrollOffset; + + /// + /// Transforms to a new value. + /// + /// The focus point in absolute coordinates local to the content. + /// The size of the content. + /// The scroll offset at the start of the transform. + public TransformZoom(float focusPoint, float contentSize, float scrollOffset) + { + this.focusPoint = focusPoint; + this.contentSize = contentSize; + this.scrollOffset = scrollOffset; + } + + public override string TargetMember => nameof(currentZoom); + + private float valueAt(double time) + { + if (time < StartTime) return StartValue; + if (time >= EndTime) return EndValue; + + return Interpolation.ValueAt(time, StartValue, EndValue, StartTime, EndTime, Easing); + } + + protected override void Apply(ZoomableScrollContainer d, double time) + { + float newZoom = valueAt(time); + + float focusOffset = focusPoint - scrollOffset; + float expectedWidth = d.DrawWidth * newZoom; + float targetOffset = expectedWidth * (focusPoint / contentSize) - focusOffset; + + d.currentZoom = newZoom; + d.ScrollTo(targetOffset, false); + } + + protected override void ReadIntoStartValue(ZoomableScrollContainer d) => StartValue = d.currentZoom; + } + } +} From 82607b3eb302f6c1689e84c3de226adf1bd679f8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 18 May 2018 17:53:09 +0900 Subject: [PATCH 040/262] Expose properties to control zoom --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 4 ++ .../Timeline/ZoomableScrollContainer.cs | 70 +++++++++++++++++-- 2 files changed, 68 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index a9de155df8..9801ba12a1 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -15,6 +15,10 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline public Timeline() { + ZoomDuration = 200; + ZoomEasing = Easing.OutQuint; + Zoom = 10; + BeatmapWaveformGraph waveform; Child = waveform = new BeatmapWaveformGraph { diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index 545caf5166..72faf657ce 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.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 osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Transforms; @@ -12,10 +13,21 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class ZoomableScrollContainer : ScrollContainer { + /// + /// The time to zoom into/out of a point. + /// All user scroll input will be overwritten during the zoom transform. + /// + public double ZoomDuration; + + /// + /// The easing with which to transform the zoom. + /// + public Easing ZoomEasing; + private readonly Container zoomedContent; protected override Container Content => zoomedContent; - private float currentZoom = 10; + private float currentZoom = 1; public ZoomableScrollContainer() : base(Direction.Horizontal) @@ -23,13 +35,59 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline base.Content.Add(zoomedContent = new Container { RelativeSizeAxes = Axes.Y }); } + private int minZoom = 1; + /// - /// Gets or sets the content zoom of this . + /// The minimum zoom level allowed. + /// + public int MinZoom + { + get => minZoom; + set + { + if (value < 1) + throw new ArgumentException($"{nameof(MinZoom)} must be >= 1.", nameof(value)); + minZoom = value; + + if (Zoom < value) + Zoom = value; + } + } + + private int maxZoom = 60; + + /// + /// The maximum zoom level allowed. + /// + public int MaxZoom + { + get => maxZoom; + set + { + if (value < 1) + throw new ArgumentException($"{nameof(MaxZoom)} must be >= 1.", nameof(value)); + maxZoom = value; + + if (Zoom > value) + Zoom = value; + } + } + + /// + /// Gets or sets the content zoom level of this . /// public int Zoom { get => zoomTarget; - set => setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); + set + { + value = MathHelper.Clamp(value, MinZoom, MaxZoom); + + if (IsLoaded) + setZoomTarget(value, ToSpaceOfOtherDrawable(new Vector2(DrawWidth / 2, 0), zoomedContent).X); + else + currentZoom = zoomTarget = value; + } } protected override void Update() @@ -48,11 +106,11 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline return true; } - private int zoomTarget = 10; + private int zoomTarget = 1; private void setZoomTarget(int newZoom, float focusPoint) { - zoomTarget = MathHelper.Clamp(newZoom, 1, 60); - transformZoomTo(zoomTarget, focusPoint, 200, Easing.OutQuint); + zoomTarget = MathHelper.Clamp(newZoom, MinZoom, MaxZoom); + transformZoomTo(zoomTarget, focusPoint, ZoomDuration, ZoomEasing); } private void transformZoomTo(int newZoom, float focusPoint, double duration = 0, Easing easing = Easing.None) From 757f89871819a1164e778ae544c3d6d81d7e79e9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 18 May 2018 17:53:19 +0900 Subject: [PATCH 041/262] Add testcase for zoomable scroll container --- .../Visual/TestCaseZoomableScrollContainer.cs | 142 ++++++++++++++++++ 1 file changed, 142 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs diff --git a/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs b/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs new file mode 100644 index 0000000000..06ec9ec63c --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs @@ -0,0 +1,142 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using NUnit.Framework; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; +using osu.Framework.Graphics.Shapes; +using osu.Framework.MathUtils; +using osu.Game.Graphics; +using osu.Game.Graphics.Cursor; +using osu.Game.Screens.Edit.Screens.Compose.Timeline; +using OpenTK; +using OpenTK.Graphics; +using OpenTK.Input; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseZoomableScrollContainer : ManualInputManagerTestCase + { + private readonly ZoomableScrollContainer scrollContainer; + private readonly Drawable innerBox; + + public TestCaseZoomableScrollContainer() + { + Children = new Drawable[] + { + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.X, + Height = 250, + Width = 0.75f, + Children = new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(30) + }, + scrollContainer = new ZoomableScrollContainer { RelativeSizeAxes = Axes.Both } + } + }, + new MenuCursor() + }; + + scrollContainer.Add(innerBox = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientHorizontal(new Color4(0.8f, 0.6f, 0.4f, 1f), new Color4(0.4f, 0.6f, 0.8f, 1f)) + }); + } + + [Test] + public void TestZoom0() + { + reset(); + AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); + AddAssert("Box width = 1x", () => Precision.AlmostEquals(boxQuad.Size, scrollQuad.Size)); + } + + [Test] + public void TestZoom10() + { + reset(); + AddStep("Set zoom = 10", () => scrollContainer.Zoom = 10); + AddAssert("Box at 1/2", () => Precision.AlmostEquals(boxQuad.Centre, scrollQuad.Centre)); + AddAssert("Box width = 10x", () => Precision.AlmostEquals(boxQuad.Size.X, 10 * scrollQuad.Size.X)); + } + + [Test] + public void TestMouseZoomInOnceOutOnce() + { + reset(); + + // Scroll in at 0.25 + AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y))); + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by 3", () => InputManager.ScrollBy(3)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddAssert("Box not at 0", () => !Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); + AddAssert("Box 1/4 at 1/4", () => Precision.AlmostEquals(boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X)); + + // Scroll out at 0.25 + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by -3", () => InputManager.ScrollBy(-3)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); + AddAssert("Box 1/4 at 1/4", () => Precision.AlmostEquals(boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X)); + } + + [Test] + public void TestMouseZoomInTwiceOutTwice() + { + reset(); + + // Scroll in at 0.25 + AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y))); + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by 1", () => InputManager.ScrollBy(1)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + + // Scroll in at 0.6 + AddStep("Move mouse to 0.75x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.75f * scrollQuad.Size.X, scrollQuad.Centre.Y))); + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by 1", () => InputManager.ScrollBy(1)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddAssert("Box not at 0", () => !Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); + + // Very hard to determine actual position, so approximate + AddAssert("Box at correct position (1)", () => Precision.DefinitelyBigger(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X)); + AddAssert("Box at correct position (2)", () => Precision.DefinitelyBigger(scrollQuad.TopLeft.X + 0.6f * scrollQuad.Size.X, boxQuad.TopLeft.X + 0.3f * boxQuad.Size.X)); + AddAssert("Box at correct position (3)", () => Precision.DefinitelyBigger(boxQuad.TopLeft.X + 0.6f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.6f * scrollQuad.Size.X)); + + // Scroll out at 0.6 + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by -1", () => InputManager.ScrollBy(-1)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + + // Scroll out at 0.25 + AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y))); + AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); + AddStep("Scroll by -1", () => InputManager.ScrollBy(-1)); + AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); + } + + private void reset() + { + AddStep("Reset", () => + { + scrollContainer.Zoom = 0; + scrollContainer.ScrollTo(0, false); + }); + } + + private Quad scrollQuad => scrollContainer.ScreenSpaceDrawQuad; + private Quad boxQuad => innerBox.ScreenSpaceDrawQuad; + } +} From f50c1c78a25a719f1b1c1cf4ac072a991013d8f0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 18 May 2018 18:14:12 +0900 Subject: [PATCH 042/262] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index fac688633b..8f007de13e 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit fac688633b8fcf34ae5d0514c26b03e217161eb4 +Subproject commit 8f007de13e4a1aed46cb35e5018448f809bd5e88 From f53164843d0d17d17282e041a501cf2bb527a618 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 May 2018 15:56:02 +0900 Subject: [PATCH 043/262] Reduce spacing changes --- osu.Game/Rulesets/UI/RulesetContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 1cad3c827b..c8582a740c 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -67,7 +67,6 @@ namespace osu.Game.Rulesets.UI /// public readonly CursorContainer Cursor; - protected readonly Ruleset Ruleset; private IRulesetConfigManager rulesetConfig; @@ -94,6 +93,7 @@ namespace osu.Game.Rulesets.UI private void load(OnScreenDisplay onScreenDisplay, SettingsStore settings) { this.onScreenDisplay = onScreenDisplay; + rulesetConfig = CreateConfig(Ruleset, settings); if (rulesetConfig != null) From 5ec349de78dad5c25ae274340b407a92734eb7e2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 May 2018 15:59:33 +0900 Subject: [PATCH 044/262] Reorder methods and remove useless comments --- osu.Game/Rulesets/UI/RulesetContainer.cs | 42 +++++++++++------------- 1 file changed, 19 insertions(+), 23 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index c8582a740c..f06365e04a 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -195,26 +195,6 @@ namespace osu.Game.Rulesets.UI private Container content; private IEnumerable mods; - [BackgroundDependencyLoader] - private void load(OsuConfigManager config) - { - KeyBindingInputManager.Add(content = new Container - { - RelativeSizeAxes = Axes.Both, - }); - - AddInternal(KeyBindingInputManager); - KeyBindingInputManager.Add(Playfield); - - if (Cursor != null) - KeyBindingInputManager.Add(Cursor); - - // Apply mods - applyMods(Mods, config); - - loadObjects(); - } - /// /// Whether to assume the beatmap passed into this is for the current ruleset. /// Creates a hit renderer for a beatmap. @@ -236,10 +216,26 @@ namespace osu.Game.Rulesets.UI KeyBindingInputManager = CreateInputManager(); KeyBindingInputManager.RelativeSizeAxes = Axes.Both; + } - // Add mods, should always be the last thing applied to give full control to mods - // Mods are now added in the load() method, this method is still executed after the constructor - // so they are still added in last + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + KeyBindingInputManager.Add(content = new Container + { + RelativeSizeAxes = Axes.Both, + }); + + AddInternal(KeyBindingInputManager); + KeyBindingInputManager.Add(Playfield); + + if (Cursor != null) + KeyBindingInputManager.Add(Cursor); + + // Apply mods + applyMods(Mods, config); + + loadObjects(); } /// From 9e17eb234223e2b9869b159f675f3466336b54b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 21 May 2018 16:03:08 +0900 Subject: [PATCH 045/262] Reword settings text to be ruleset agnostic --- osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 492b108a21..9b3c199b5c 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -40,7 +40,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay }, new SettingsCheckbox { - LabelText = "Show approach circle on first \"Hidden\" object", + LabelText = "Increase visibility of first object with \"Hidden\" mod", Bindable = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility) }, }; From a7bdaf75b0731125ddda2a5b7a3d84680279ceaf Mon Sep 17 00:00:00 2001 From: jorolf Date: Tue, 22 May 2018 13:05:15 +0200 Subject: [PATCH 046/262] 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 50e2871c89ff774048cc4b58cc91972e35397943 Mon Sep 17 00:00:00 2001 From: Vidalee Date: Tue, 22 May 2018 21:29:41 +0200 Subject: [PATCH 047/262] why this line was ommited --- osu.Game/Rulesets/Mods/ModHidden.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index ab1911fe88..5e06c81dff 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -33,6 +33,7 @@ namespace osu.Game.Rulesets.Mods return; d.ApplyCustomUpdateState += ApplyHiddenState; + d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; } } From 08e423ac5b9c85b77d158a8b4e8fccc32f806785 Mon Sep 17 00:00:00 2001 From: Vidalee Date: Tue, 22 May 2018 21:35:17 +0200 Subject: [PATCH 048/262] code sanity --- osu.Game/Rulesets/Mods/ModHidden.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index 5e06c81dff..da4f04049f 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Mods return; d.ApplyCustomUpdateState += ApplyHiddenState; - d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; + d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; } } From 7a31986812aaf0dd516bfee79fa9b6a808fae1ef Mon Sep 17 00:00:00 2001 From: Vidalee Date: Tue, 22 May 2018 22:39:55 +0200 Subject: [PATCH 049/262] resolving the lost code problem --- osu.Game/Rulesets/Mods/ModHidden.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index da4f04049f..ab1911fe88 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -33,7 +33,6 @@ namespace osu.Game.Rulesets.Mods return; d.ApplyCustomUpdateState += ApplyHiddenState; - d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; } } From 49f893d5e42b3712a7801ea329128bb2701538dd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 23 May 2018 12:00:11 +0900 Subject: [PATCH 050/262] Couple the timeline to the audio --- .../Visual/TestCaseEditorComposeTimeline.cs | 13 ++- .../Edit/Screens/Compose/Timeline/Timeline.cs | 80 +++++++++++++++++++ 2 files changed, 85 insertions(+), 8 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index 0776bc123e..aff7abe03d 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -14,14 +14,15 @@ using osu.Game.Screens.Edit.Screens.Compose.Timeline; namespace osu.Game.Tests.Visual { [TestFixture] - public class TestCaseEditorComposeTimeline : OsuTestCase + public class TestCaseEditorComposeTimeline : EditorClockTestCase { public override IReadOnlyList RequiredTypes => new[] { typeof(TimelineArea), typeof(Timeline), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; - private readonly TimelineArea timelineArea; - - public TestCaseEditorComposeTimeline() + [BackgroundDependencyLoader] + private void load(OsuGameBase osuGame) { + TimelineArea timelineArea; + Children = new Drawable[] { new MusicController @@ -38,11 +39,7 @@ namespace osu.Game.Tests.Visual Size = new Vector2(0.8f, 100) } }; - } - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) - { timelineArea.Beatmap.BindTo(osuGame.Beatmap); } } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index 9801ba12a1..e8d34b466c 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -1,8 +1,11 @@ // 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.Configuration; using osu.Framework.Graphics; +using osu.Framework.Input; +using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Graphics; @@ -13,6 +16,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline public readonly Bindable WaveformVisible = new Bindable(); public readonly Bindable Beatmap = new Bindable(); + private IAdjustableClock adjustableClock; + public Timeline() { ZoomDuration = 200; @@ -32,12 +37,87 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); } + [BackgroundDependencyLoader] + private void load(IAdjustableClock adjustableClock) + { + this.adjustableClock = adjustableClock; + } + + private bool handlingUserInput; + private bool trackWasPlaying; + protected override void Update() { base.Update(); // We want time = 0 to be at the centre of the container when scrolled to the start Content.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; + + if (!handlingUserInput) + ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); + else + adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + if (base.OnMouseDown(state, args)) + { + beginUserInput(); + return true; + } + + return false; + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + endUserInput(); + return base.OnMouseUp(state, args); + } + + private void beginUserInput() + { + handlingUserInput = true; + trackWasPlaying = adjustableClock.IsRunning; + adjustableClock.Stop(); + } + + private void endUserInput() + { + handlingUserInput = false; + if (trackWasPlaying) + adjustableClock.Start(); + } + + protected override ScrollbarContainer CreateScrollbar(Direction direction) => new TimelineScrollbar(this, direction); + + private class TimelineScrollbar : ScrollbarContainer + { + private readonly Timeline timeline; + + public TimelineScrollbar(Timeline timeline, Direction scrollDir) + : base(scrollDir) + { + this.timeline = timeline; + } + + protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) + { + if (base.OnMouseDown(state, args)) + { + timeline.beginUserInput(); + return true; + } + + return false; + } + + protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) + { + timeline.endUserInput(); + return base.OnMouseUp(state, args); + } } } } From f18677382c59446d4cdc307ed5969c5a4c2b71f7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 23 May 2018 12:00:23 +0900 Subject: [PATCH 051/262] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 8f007de13e..907265b750 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 8f007de13e4a1aed46cb35e5018448f809bd5e88 +Subproject commit 907265b7501964a09eb2cd89ec2257941183c65c From 6b0eeb343651bd50764199b3413c59dd946ae2df Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 23 May 2018 14:14:32 +0900 Subject: [PATCH 052/262] Rework seeking interactions to support smooth scrolling --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 53 ++++++++++++++++--- 1 file changed, 46 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index e8d34b466c..9dbaa1586d 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -43,20 +43,59 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline this.adjustableClock = adjustableClock; } - private bool handlingUserInput; + /// + /// The track's time in the previous frame. + /// + private double lastTrackTime; + + /// + /// Whether the user is currently dragging the timeline. + /// + private bool handlingDragInput; + + /// + /// Whether the track was playing before a user drag event. + /// private bool trackWasPlaying; protected override void Update() { base.Update(); - // We want time = 0 to be at the centre of the container when scrolled to the start + // The extrema of track time should be positioned at the centre of the container when scrolled to the start or end Content.Margin = new MarginPadding { Horizontal = DrawWidth / 2 }; - if (!handlingUserInput) - ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); - else + if (handlingDragInput) + { + // The user is dragging - the track should always follow the timeline adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); + } + else if (adjustableClock.IsRunning) + { + // If the user hasn't provided mouse input but the track is running, always follow the track + ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); + } + else + { + // The track isn't playing, so we want to smooth-scroll once more, and re-enable wheel scrolling + // There are two cases we have to be wary of: + // 1) The user scrolls on this timeline: We want the track to follow us + // 2) The user changes the track time through some other means (scrolling in the editor or overview timeline): We want to follow the track time + + // The simplest way to cover both cases is by checking that inter-frame track times are identical + if (adjustableClock.CurrentTime == lastTrackTime) + { + // The track hasn't been seeked externally + adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); + } + else + { + // The track has been seeked externally + ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); + } + } + + lastTrackTime = adjustableClock.CurrentTime; } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) @@ -78,14 +117,14 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private void beginUserInput() { - handlingUserInput = true; + handlingDragInput = true; trackWasPlaying = adjustableClock.IsRunning; adjustableClock.Stop(); } private void endUserInput() { - handlingUserInput = false; + handlingDragInput = false; if (trackWasPlaying) adjustableClock.Start(); } From a30f72b477d6353d0e785d94cd66aac6fefe50de Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 23 May 2018 14:32:00 +0900 Subject: [PATCH 053/262] Add helper methods for seeking/scrolling --- .../Screens/Edit/Screens/Compose/Timeline/Timeline.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index 9dbaa1586d..df615ad035 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -68,12 +68,12 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline if (handlingDragInput) { // The user is dragging - the track should always follow the timeline - adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); + seekTrackToCurrent(); } else if (adjustableClock.IsRunning) { // If the user hasn't provided mouse input but the track is running, always follow the track - ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); + scrollToTrackTime(); } else { @@ -86,16 +86,19 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline if (adjustableClock.CurrentTime == lastTrackTime) { // The track hasn't been seeked externally - adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); + seekTrackToCurrent(); } else { // The track has been seeked externally - ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); + scrollToTrackTime(); } } lastTrackTime = adjustableClock.CurrentTime; + + void seekTrackToCurrent() => adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); + void scrollToTrackTime() => ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) From 6c0c932c485590545326e05949597ef58c80f0b3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 23 May 2018 14:56:40 +0900 Subject: [PATCH 054/262] Reorder OsuGameBase methods --- osu.Game/OsuGameBase.cs | 27 +++++++++++++-------------- 1 file changed, 13 insertions(+), 14 deletions(-) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 487cb50c9a..5dba68b4c1 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -65,7 +65,8 @@ namespace osu.Game protected override Container Content => content; - public Bindable Beatmap { get; private set; } + public IBindable Beatmap { get; private set; } + private WorkingBeatmap lastBeatmap; private Bindable fpsDisplayVisible; @@ -204,6 +205,17 @@ namespace osu.Game dependencies.Cache(globalBinding); } + protected override void LoadComplete() + { + base.LoadComplete(); + + // TODO: This is temporary until we reimplement the local FPS display. + // It's just to allow end-users to access the framework FPS display without knowing the shortcut key. + fpsDisplayVisible = LocalConfig.GetBindable(OsuSetting.ShowFpsDisplay); + fpsDisplayVisible.ValueChanged += val => { FrameStatisticsMode = val ? FrameStatisticsMode.Minimal : FrameStatisticsMode.None; }; + fpsDisplayVisible.TriggerChange(); + } + private void runMigrations() { try @@ -225,19 +237,6 @@ namespace osu.Game } } - private WorkingBeatmap lastBeatmap; - - protected override void LoadComplete() - { - base.LoadComplete(); - - // TODO: This is temporary until we reimplement the local FPS display. - // It's just to allow end-users to access the framework FPS display without knowing the shortcut key. - fpsDisplayVisible = LocalConfig.GetBindable(OsuSetting.ShowFpsDisplay); - fpsDisplayVisible.ValueChanged += val => { FrameStatisticsMode = val ? FrameStatisticsMode.Minimal : FrameStatisticsMode.None; }; - fpsDisplayVisible.TriggerChange(); - } - public override void SetHost(GameHost host) { if (LocalConfig == null) From 8004b8af4d465af6c1eddfffdcb1c61dcac79e0b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 23 May 2018 17:37:39 +0900 Subject: [PATCH 055/262] Privatise the OsuGame beatmap, add local beatmap to OsuTestCase --- osu-framework | 2 +- .../UI/Cursor/GameplayCursor.cs | 6 +- .../Visual/TestCaseBeatmapInfoWedge.cs | 20 +++--- .../Visual/TestCaseEditorCompose.cs | 10 +-- .../Visual/TestCaseEditorComposeTimeline.cs | 11 +--- .../Visual/TestCaseEditorSeekSnapping.cs | 4 +- .../Visual/TestCaseEditorSummaryTimeline.cs | 9 +-- .../Visual/TestCaseHitObjectComposer.cs | 4 +- .../Visual/TestCaseMusicController.cs | 13 +--- .../Visual/TestCasePlaySongSelect.cs | 6 +- .../Visual/TestCasePlaybackControl.cs | 2 +- osu.Game.Tests/Visual/TestCasePlayerLoader.cs | 3 +- osu.Game.Tests/Visual/TestCaseReplay.cs | 5 +- osu.Game.Tests/Visual/TestCaseResults.cs | 16 ++--- osu.Game.Tests/Visual/TestCaseStoryboard.cs | 15 ++--- osu.Game.Tests/Visual/TestCaseWaveform.cs | 15 ++--- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 4 +- osu.Game/Beatmaps/GameBeatmap.cs | 26 ++++++++ osu.Game/Beatmaps/IGameBeatmap.cs | 14 ++++ .../Containers/BeatSyncedContainer.cs | 6 +- osu.Game/OsuGameBase.cs | 7 +- osu.Game/Overlays/Music/PlaylistList.cs | 4 +- osu.Game/Overlays/Music/PlaylistOverlay.cs | 26 ++++---- osu.Game/Overlays/MusicController.cs | 33 +++++----- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 6 +- .../Edit/Components/BottomBarContainer.cs | 6 +- .../Timelines/Summary/Parts/TimelinePart.cs | 9 ++- .../Timelines/Summary/SummaryTimeline.cs | 15 ++--- osu.Game/Screens/Edit/Editor.cs | 10 +-- .../Screens/Edit/Screens/Compose/Compose.cs | 5 +- .../Compose/Timeline/BeatmapWaveformGraph.cs | 4 +- .../Compose/Timeline/ScrollableTimeline.cs | 5 -- .../Timeline/ScrollingTimelineContainer.cs | 16 ++++- osu.Game/Screens/Edit/Screens/EditorScreen.cs | 9 ++- osu.Game/Screens/Menu/Intro.cs | 12 ++-- osu.Game/Screens/Menu/LogoVisualisation.cs | 6 +- osu.Game/Screens/Menu/MenuSideFlashes.cs | 6 +- osu.Game/Screens/OsuScreen.cs | 24 ++----- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Play/PlayerLoader.cs | 2 +- .../Play/ScreenWithBeatmapBackground.cs | 2 +- osu.Game/Screens/Ranking/Results.cs | 6 +- osu.Game/Screens/Select/PlaySongSelect.cs | 8 ++- osu.Game/Screens/Select/SongSelect.cs | 16 +++-- .../Drawables/DrawableStoryboardAnimation.cs | 5 +- .../Drawables/DrawableStoryboardSprite.cs | 5 +- osu.Game/Tests/Visual/EditorClockTestCase.cs | 17 +---- osu.Game/Tests/Visual/EditorTestCase.cs | 4 +- osu.Game/Tests/Visual/OsuTestCase.cs | 16 +++++ .../Tests/Visual/TestCasePerformancePoints.cs | 65 ++++++++++--------- osu.Game/Tests/Visual/TestCasePlayer.cs | 14 ++-- 51 files changed, 279 insertions(+), 277 deletions(-) create mode 100644 osu.Game/Beatmaps/GameBeatmap.cs create mode 100644 osu.Game/Beatmaps/IGameBeatmap.cs diff --git a/osu-framework b/osu-framework index eb076a3301..b36db536d9 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit eb076a3301231eb73917073499051e49a9b12978 +Subproject commit b36db536d96d75ef1be2d12d14245dcca91f2497 diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs index e7f17dd86b..d34ecfac22 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private Bindable cursorScale; private Bindable autoCursorScale; - private Bindable beatmap; + private IBindable beatmap; public OsuCursor() { @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor } [BackgroundDependencyLoader] - private void load(OsuConfigManager config, OsuGameBase game) + private void load(OsuConfigManager config, IGameBeatmap beatmap) { Child = cursorContainer = new SkinnableDrawable("cursor", _ => new CircularContainer { @@ -160,7 +160,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, }; - beatmap = game.Beatmap.GetBoundCopy(); + this.beatmap = beatmap.GetBoundCopy(); beatmap.ValueChanged += v => calculateScale(); cursorScale = config.GetBindable(OsuSetting.GameplayCursorSize); diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 0d3e08154f..328e1ef08e 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -6,7 +6,6 @@ using System.Linq; using NUnit.Framework; using OpenTK; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; @@ -29,14 +28,11 @@ namespace osu.Game.Tests.Visual private RulesetStore rulesets; private TestBeatmapInfoWedge infoWedge; private readonly List beatmaps = new List(); - private readonly Bindable beatmap = new Bindable(); [BackgroundDependencyLoader] - private void load(OsuGameBase game, RulesetStore rulesets) + private void load(RulesetStore rulesets) { this.rulesets = rulesets; - - beatmap.BindTo(game.Beatmap); } protected override void LoadComplete() @@ -53,11 +49,11 @@ namespace osu.Game.Tests.Visual AddStep("show", () => { infoWedge.State = Visibility.Visible; - infoWedge.UpdateBeatmap(beatmap); + infoWedge.UpdateBeatmap(Beatmap); }); // select part is redundant, but wait for load isn't - selectBeatmap(beatmap.Value.Beatmap); + selectBeatmap(Beatmap.Value.Beatmap); AddWaitStep(3); @@ -120,8 +116,8 @@ namespace osu.Game.Tests.Visual { selectNullBeatmap(); AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Text)); - AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Title); - AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == beatmap.Default.BeatmapInfo.Metadata.Artist); + AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Title); + AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Artist); AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any()); AddAssert("check no infolabels", () => !infoWedge.Info.InfoLabelContainer.Children.Any()); } @@ -133,7 +129,7 @@ namespace osu.Game.Tests.Visual AddStep($"select {b.Metadata.Title} beatmap", () => { infoBefore = infoWedge.Info; - infoWedge.UpdateBeatmap(beatmap.Value = new TestWorkingBeatmap(b)); + infoWedge.UpdateBeatmap(Beatmap.Value = new TestWorkingBeatmap(b)); }); AddUntilStep(() => infoWedge.Info != infoBefore, "wait for async load"); @@ -143,8 +139,8 @@ namespace osu.Game.Tests.Visual { AddStep("select null beatmap", () => { - beatmap.Value = beatmap.Default; - infoWedge.UpdateBeatmap(beatmap); + Beatmap.Value = Beatmap.Default; + infoWedge.UpdateBeatmap(Beatmap); }); } diff --git a/osu.Game.Tests/Visual/TestCaseEditorCompose.cs b/osu.Game.Tests/Visual/TestCaseEditorCompose.cs index 96a754a5ce..e7bcfbf500 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorCompose.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorCompose.cs @@ -17,14 +17,10 @@ namespace osu.Game.Tests.Visual public override IReadOnlyList RequiredTypes => new[] { typeof(Compose) }; [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) + private void load() { - osuGame.Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo); - - var compose = new Compose(); - compose.Beatmap.BindTo(osuGame.Beatmap); - - Child = compose; + Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo); + Child = new Compose(); } } } diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index a5053bafe8..81b491799b 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -5,7 +5,6 @@ using System; using System.Collections.Generic; using NUnit.Framework; using OpenTK; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; @@ -18,8 +17,6 @@ namespace osu.Game.Tests.Visual { public override IReadOnlyList RequiredTypes => new[] { typeof(ScrollableTimeline), typeof(ScrollingTimelineContainer), typeof(BeatmapWaveformGraph), typeof(TimelineButton) }; - private readonly ScrollableTimeline timeline; - public TestCaseEditorComposeTimeline() { Children = new Drawable[] @@ -30,7 +27,7 @@ namespace osu.Game.Tests.Visual Origin = Anchor.TopCentre, State = Visibility.Visible }, - timeline = new ScrollableTimeline + new ScrollableTimeline { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -38,11 +35,5 @@ namespace osu.Game.Tests.Visual } }; } - - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) - { - timeline.Beatmap.BindTo(osuGame.Beatmap); - } } } diff --git a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs index f037d70493..94b99d483c 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorSeekSnapping.cs @@ -30,7 +30,7 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) + private void load() { var testBeatmap = new Beatmap { @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual } }; - osuGame.Beatmap.Value = new TestWorkingBeatmap(testBeatmap); + Beatmap.Value = new TestWorkingBeatmap(testBeatmap); Child = new TimingPointVisualiser(testBeatmap, 5000) { Clock = Clock }; diff --git a/osu.Game.Tests/Visual/TestCaseEditorSummaryTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorSummaryTimeline.cs index d01c2d2b92..cafd1b6f1a 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorSummaryTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorSummaryTimeline.cs @@ -19,19 +19,16 @@ namespace osu.Game.Tests.Visual public override IReadOnlyList RequiredTypes => new[] { typeof(SummaryTimeline) }; [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) + private void load() { - osuGame.Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo); + Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo); - SummaryTimeline summaryTimeline; - Add(summaryTimeline = new SummaryTimeline + Add(new SummaryTimeline { Anchor = Anchor.Centre, Origin = Anchor.Centre, Size = new Vector2(500, 50) }); - - summaryTimeline.Beatmap.BindTo(osuGame.Beatmap); } } } diff --git a/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs b/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs index d0c46ecdd7..557d976073 100644 --- a/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs @@ -38,9 +38,9 @@ namespace osu.Game.Tests.Visual => dependencies = new DependencyContainer(parent); [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) + private void load() { - osuGame.Beatmap.Value = new TestWorkingBeatmap(new Beatmap + Beatmap.Value = new TestWorkingBeatmap(new Beatmap { HitObjects = new List { diff --git a/osu.Game.Tests/Visual/TestCaseMusicController.cs b/osu.Game.Tests/Visual/TestCaseMusicController.cs index 10c813b2f8..5ba0167f12 100644 --- a/osu.Game.Tests/Visual/TestCaseMusicController.cs +++ b/osu.Game.Tests/Visual/TestCaseMusicController.cs @@ -2,12 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using NUnit.Framework; -using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Timing; -using osu.Game.Beatmaps; using osu.Game.Overlays; namespace osu.Game.Tests.Visual @@ -15,8 +12,6 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseMusicController : OsuTestCase { - private readonly Bindable beatmapBacking = new Bindable(); - public TestCaseMusicController() { Clock = new FramedClock(); @@ -30,13 +25,7 @@ namespace osu.Game.Tests.Visual AddToggleStep(@"toggle visibility", state => mc.State = state ? Visibility.Visible : Visibility.Hidden); AddStep(@"show", () => mc.State = Visibility.Visible); - AddToggleStep(@"toggle beatmap lock", state => beatmapBacking.Disabled = state); - } - - [BackgroundDependencyLoader] - private void load(OsuGameBase game) - { - beatmapBacking.BindTo(game.Beatmap); + AddToggleStep(@"toggle beatmap lock", state => Beatmap.Disabled = state); } } } diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 8c52360db8..1371db78b5 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -58,7 +58,7 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(OsuGameBase game) + private void load() { TestSongSelect songSelect = null; @@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual dependencies.Cache(rulesets = new RulesetStore(factory)); dependencies.Cache(manager = new BeatmapManager(storage, factory, rulesets, null, null) { - DefaultBeatmap = defaultBeatmap = game.Beatmap.Default + DefaultBeatmap = defaultBeatmap = Beatmap.Default }); void loadNewSongSelect(bool deleteMaps = false) => AddStep("reload song select", () => @@ -78,7 +78,7 @@ namespace osu.Game.Tests.Visual if (deleteMaps) { manager.Delete(manager.GetAllUsableBeatmapSets()); - game.Beatmap.SetDefault(); + Beatmap.SetDefault(); } if (songSelect != null) diff --git a/osu.Game.Tests/Visual/TestCasePlaybackControl.cs b/osu.Game.Tests/Visual/TestCasePlaybackControl.cs index 24ebb534c1..4bed5bb595 100644 --- a/osu.Game.Tests/Visual/TestCasePlaybackControl.cs +++ b/osu.Game.Tests/Visual/TestCasePlaybackControl.cs @@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual Size = new Vector2(200,100) }; - playback.Beatmap.Value = new TestWorkingBeatmap(new Beatmap()); + Beatmap.Value = new TestWorkingBeatmap(new Beatmap()); Child = playback; } diff --git a/osu.Game.Tests/Visual/TestCasePlayerLoader.cs b/osu.Game.Tests/Visual/TestCasePlayerLoader.cs index 1e7618232d..52a9db080d 100644 --- a/osu.Game.Tests/Visual/TestCasePlayerLoader.cs +++ b/osu.Game.Tests/Visual/TestCasePlayerLoader.cs @@ -12,9 +12,10 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load(OsuGameBase game) { + Beatmap.Value = new DummyWorkingBeatmap(game); + AddStep("load dummy beatmap", () => Add(new PlayerLoader(new Player { - InitialBeatmap = new DummyWorkingBeatmap(game), AllowPause = false, AllowLeadIn = false, AllowResults = false, diff --git a/osu.Game.Tests/Visual/TestCaseReplay.cs b/osu.Game.Tests/Visual/TestCaseReplay.cs index 5bc16fe420..4bcbc924b8 100644 --- a/osu.Game.Tests/Visual/TestCaseReplay.cs +++ b/osu.Game.Tests/Visual/TestCaseReplay.cs @@ -26,10 +26,7 @@ namespace osu.Game.Tests.Visual // Reset the mods beatmap.Mods.Value = beatmap.Mods.Value.Where(m => !(m is ModAutoplay)); - return new ReplayPlayer(replay) - { - InitialBeatmap = beatmap - }; + return new ReplayPlayer(replay); } } } diff --git a/osu.Game.Tests/Visual/TestCaseResults.cs b/osu.Game.Tests/Visual/TestCaseResults.cs index 35e1db7c9e..ee36fb0afc 100644 --- a/osu.Game.Tests/Visual/TestCaseResults.cs +++ b/osu.Game.Tests/Visual/TestCaseResults.cs @@ -32,18 +32,13 @@ namespace osu.Game.Tests.Visual this.beatmaps = beatmaps; } - private WorkingBeatmap beatmap; - protected override void LoadComplete() { base.LoadComplete(); - if (beatmap == null) - { - var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0); - if (beatmapInfo != null) - beatmap = beatmaps.GetWorkingBeatmap(beatmapInfo); - } + var beatmapInfo = beatmaps.QueryBeatmap(b => b.RulesetID == 0); + if (beatmapInfo != null) + Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo); Add(new Results(new Score { @@ -63,10 +58,7 @@ namespace osu.Game.Tests.Visual { Username = "peppy", } - }) - { - InitialBeatmap = beatmap - }); + })); } } } diff --git a/osu.Game.Tests/Visual/TestCaseStoryboard.cs b/osu.Game.Tests/Visual/TestCaseStoryboard.cs index e721c5ced0..b63881ffa7 100644 --- a/osu.Game.Tests/Visual/TestCaseStoryboard.cs +++ b/osu.Game.Tests/Visual/TestCaseStoryboard.cs @@ -3,7 +3,6 @@ using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -18,8 +17,6 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseStoryboard : OsuTestCase { - private readonly Bindable beatmapBacking = new Bindable(); - private readonly Container storyboardContainer; private DrawableStoryboard storyboard; @@ -43,6 +40,7 @@ namespace osu.Game.Tests.Visual }, }, }); + Add(new MusicController { Origin = Anchor.TopRight, @@ -55,10 +53,9 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(OsuGameBase game) + private void load() { - beatmapBacking.BindTo(game.Beatmap); - beatmapBacking.ValueChanged += beatmapChanged; + Beatmap.ValueChanged += beatmapChanged; } private void beatmapChanged(WorkingBeatmap working) @@ -66,10 +63,10 @@ namespace osu.Game.Tests.Visual private void restart() { - var track = beatmapBacking.Value.Track; + var track = Beatmap.Value.Track; track.Reset(); - loadStoryboard(beatmapBacking.Value); + loadStoryboard(Beatmap); track.Start(); } @@ -81,7 +78,7 @@ namespace osu.Game.Tests.Visual var decoupledClock = new DecoupleableInterpolatingFramedClock { IsCoupled = true }; storyboardContainer.Clock = decoupledClock; - storyboard = working.Storyboard.CreateDrawable(beatmapBacking); + storyboard = working.Storyboard.CreateDrawable(Beatmap); storyboard.Passing = false; storyboardContainer.Add(storyboard); diff --git a/osu.Game.Tests/Visual/TestCaseWaveform.cs b/osu.Game.Tests/Visual/TestCaseWaveform.cs index 776adab0d1..b0966cf5c4 100644 --- a/osu.Game.Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game.Tests/Visual/TestCaseWaveform.cs @@ -5,11 +5,9 @@ using NUnit.Framework; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Screens.Edit.Screens.Compose.Timeline; @@ -19,9 +17,8 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseWaveform : OsuTestCase { - private readonly Bindable beatmapBacking = new Bindable(); - - public TestCaseWaveform() + [BackgroundDependencyLoader] + private void load() { FillFlowContainer flow; Child = flow = new FillFlowContainer @@ -46,10 +43,11 @@ namespace osu.Game.Tests.Visual var newDisplay = new BeatmapWaveformGraph { RelativeSizeAxes = Axes.Both, - Resolution = 1f / i + Resolution = 1f / i, + Beatmap = Beatmap }; - newDisplay.Beatmap.BindTo(beatmapBacking); + Beatmap.ValueChanged += b => newDisplay.Beatmap = b; flow.Add(new Container { @@ -83,8 +81,5 @@ namespace osu.Game.Tests.Visual }); } } - - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) => beatmapBacking.BindTo(osuGame.Beatmap); } } diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 8094abe5ed..ee1fc6aec3 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -17,7 +17,7 @@ namespace osu.Game.Beatmaps { private readonly OsuGameBase game; - public DummyWorkingBeatmap(OsuGameBase game) + public DummyWorkingBeatmap(OsuGameBase game = null) : base(new BeatmapInfo { Metadata = new BeatmapMetadata @@ -43,7 +43,7 @@ namespace osu.Game.Beatmaps protected override IBeatmap GetBeatmap() => new Beatmap(); - protected override Texture GetBackground() => game.Textures.Get(@"Backgrounds/bg4"); + protected override Texture GetBackground() => game?.Textures.Get(@"Backgrounds/bg4"); protected override Track GetTrack() => new TrackVirtual(); diff --git a/osu.Game/Beatmaps/GameBeatmap.cs b/osu.Game/Beatmaps/GameBeatmap.cs new file mode 100644 index 0000000000..ac31b16533 --- /dev/null +++ b/osu.Game/Beatmaps/GameBeatmap.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Configuration; + +namespace osu.Game.Beatmaps +{ + /// + /// A for the beatmap. + /// This should be used sparingly in-favour of . + /// + public class GameBeatmap : NonNullableBindable, IGameBeatmap + { + public GameBeatmap(WorkingBeatmap defaultValue) + : base(defaultValue) + { + } + + public GameBeatmap GetBoundCopy() + { + var copy = new GameBeatmap(Default); + copy.BindTo(this); + return copy; + } + } +} diff --git a/osu.Game/Beatmaps/IGameBeatmap.cs b/osu.Game/Beatmaps/IGameBeatmap.cs new file mode 100644 index 0000000000..89323c953b --- /dev/null +++ b/osu.Game/Beatmaps/IGameBeatmap.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Configuration; + +namespace osu.Game.Beatmaps +{ + /// + /// Read-only interface for the beatmap. + /// + public interface IGameBeatmap : IBindable + { + } +} diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index bf16af4706..92e38033a9 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -12,7 +12,7 @@ namespace osu.Game.Graphics.Containers { public class BeatSyncedContainer : Container { - protected readonly Bindable Beatmap = new Bindable(); + protected readonly IBindable Beatmap = new Bindable(); private int lastBeat; private TimingControlPoint lastTimingPoint; @@ -74,9 +74,9 @@ namespace osu.Game.Graphics.Containers } [BackgroundDependencyLoader] - private void load(OsuGameBase game) + private void load(IGameBeatmap beatmap) { - Beatmap.BindTo(game.Beatmap); + Beatmap.BindTo(beatmap); } protected virtual void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 5dba68b4c1..5546b5bcec 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -65,7 +65,7 @@ namespace osu.Game protected override Container Content => content; - public IBindable Beatmap { get; private set; } + protected GameBeatmap Beatmap; private WorkingBeatmap lastBeatmap; private Bindable fpsDisplayVisible; @@ -158,7 +158,7 @@ namespace osu.Game Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera-Light")); var defaultBeatmap = new DummyWorkingBeatmap(this); - Beatmap = new NonNullableBindable(defaultBeatmap); + Beatmap = new GameBeatmap(defaultBeatmap); BeatmapManager.DefaultBeatmap = defaultBeatmap; // tracks play so loud our samples can't keep up. @@ -186,6 +186,9 @@ namespace osu.Game lastBeatmap = b; }; + dependencies.Cache(Beatmap); + dependencies.CacheAs(Beatmap); + FileStore.Cleanup(); AddInternal(api); diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 8c8ff89420..27c0b393c6 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -73,13 +73,13 @@ namespace osu.Game.Overlays.Music } [BackgroundDependencyLoader] - private void load(BeatmapManager beatmaps, OsuGameBase osuGame) + private void load(BeatmapManager beatmaps, IGameBeatmap beatmap) { beatmaps.GetAllUsableBeatmapSets().ForEach(addBeatmapSet); beatmaps.ItemAdded += addBeatmapSet; beatmaps.ItemRemoved += removeBeatmapSet; - beatmapBacking.BindTo(osuGame.Beatmap); + beatmapBacking.BindTo(beatmap); beatmapBacking.ValueChanged += _ => updateSelectedSet(); } diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 76c2222f8b..79f2c29c43 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -4,7 +4,6 @@ using System; using System.Linq; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -21,17 +20,22 @@ namespace osu.Game.Overlays.Music private const float transition_duration = 600; private const float playlist_height = 510; + /// + /// Invoked when the order of an item in the list has changed. + /// The second parameter indicates the new index of the item. + /// public Action OrderChanged; + private GameBeatmap beatmap; private BeatmapManager beatmaps; + private FilterControl filter; private PlaylistList list; - private readonly Bindable beatmapBacking = new Bindable(); - [BackgroundDependencyLoader] - private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours) + private void load(OsuColour colours, GameBeatmap beatmap, BeatmapManager beatmaps) { + this.beatmap = beatmap.GetBoundCopy(); this.beatmaps = beatmaps; Children = new Drawable[] @@ -73,13 +77,11 @@ namespace osu.Game.Overlays.Music }, }; - beatmapBacking.BindTo(game.Beatmap); - filter.Search.OnCommit = (sender, newText) => { - BeatmapInfo beatmap = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); - if (beatmap != null) - beatmapBacking.Value = beatmaps.GetWorkingBeatmap(beatmap); + BeatmapInfo toSelect = list.FirstVisibleSet?.Beatmaps?.FirstOrDefault(); + if (toSelect != null) + beatmap.Value = beatmaps.GetWorkingBeatmap(toSelect); }; } @@ -102,13 +104,13 @@ namespace osu.Game.Overlays.Music private void itemSelected(BeatmapSetInfo set) { - if (set.ID == (beatmapBacking.Value?.BeatmapSetInfo?.ID ?? -1)) + if (set.ID == (beatmap.Value?.BeatmapSetInfo?.ID ?? -1)) { - beatmapBacking.Value?.Track?.Seek(0); + beatmap.Value?.Track?.Seek(0); return; } - beatmapBacking.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); + beatmap.Value = beatmaps.GetWorkingBeatmap(set.Beatmaps.First()); } } diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index fb4e278b0c..733b37cec0 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -6,7 +6,6 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; -using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -30,11 +29,8 @@ namespace osu.Game.Overlays public class MusicController : OsuFocusedOverlayContainer { private const float player_height = 130; - private const float transition_length = 800; - private const float progress_height = 10; - private const float bottom_black_area_height = 55; private Drawable background; @@ -49,16 +45,17 @@ namespace osu.Game.Overlays private PlaylistOverlay playlist; + private BeatmapManager beatmaps; private LocalisationEngine localisation; - private BeatmapManager beatmaps; - private readonly Bindable beatmapBacking = new Bindable(); private List beatmapSets; private BeatmapSetInfo currentSet; private Container dragContainer; private Container playerContainer; + private GameBeatmap beatmap; + public MusicController() { Width = 400; @@ -97,8 +94,9 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(OsuGameBase game, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation) + private void load(GameBeatmap beatmap, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation) { + this.beatmap = beatmap.GetBoundCopy(); this.beatmaps = beatmaps; this.localisation = localisation; @@ -224,8 +222,6 @@ namespace osu.Game.Overlays beatmaps.ItemAdded += handleBeatmapAdded; beatmaps.ItemRemoved += handleBeatmapRemoved; - beatmapBacking.BindTo(game.Beatmap); - playlist.StateChanged += s => playlistButton.FadeColour(s == Visibility.Visible ? colours.Yellow : Color4.White, 200, Easing.OutQuint); } @@ -240,9 +236,10 @@ namespace osu.Game.Overlays protected override void LoadComplete() { - beatmapBacking.ValueChanged += beatmapChanged; - beatmapBacking.DisabledChanged += beatmapDisabledChanged; - beatmapBacking.TriggerChange(); + beatmap.ValueChanged += beatmapChanged; + beatmap.DisabledChanged += beatmapDisabledChanged; + + beatmapChanged(beatmap.Value); base.LoadComplete(); } @@ -276,7 +273,7 @@ namespace osu.Game.Overlays playButton.Icon = track.IsRunning ? FontAwesome.fa_pause_circle_o : FontAwesome.fa_play_circle_o; - if (track.HasCompleted && !track.Looping && !beatmapBacking.Disabled && beatmapSets.Any()) + if (track.HasCompleted && !track.Looping && !beatmap.Disabled && beatmapSets.Any()) next(); } else @@ -289,7 +286,7 @@ namespace osu.Game.Overlays if (track == null) { - if (!beatmapBacking.Disabled) + if (!beatmap.Disabled) next(true); return; } @@ -307,8 +304,8 @@ namespace osu.Game.Overlays var playable = beatmapSets.TakeWhile(i => i.ID != current.BeatmapSetInfo.ID).LastOrDefault() ?? beatmapSets.LastOrDefault(); if (playable != null) { - beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking); - beatmapBacking.Value.Track.Restart(); + beatmap.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); + beatmap.Value.Track.Restart(); } } @@ -320,8 +317,8 @@ namespace osu.Game.Overlays var playable = beatmapSets.SkipWhile(i => i.ID != current.BeatmapSetInfo.ID).Skip(1).FirstOrDefault() ?? beatmapSets.FirstOrDefault(); if (playable != null) { - beatmapBacking.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmapBacking); - beatmapBacking.Value.Track.Restart(); + beatmap.Value = beatmaps.GetWorkingBeatmap(playable.Beatmaps.First(), beatmap.Value); + beatmap.Value.Track.Restart(); } } diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 5f1b9a6bad..443b4fd756 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Edit private RulesetContainer rulesetContainer; private readonly List layerContainers = new List(); - private readonly Bindable beatmap = new Bindable(); + private readonly IBindable beatmap = new Bindable(); protected HitObjectComposer(Ruleset ruleset) { @@ -38,9 +38,9 @@ namespace osu.Game.Rulesets.Edit } [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame, IFrameBasedClock framedClock) + private void load(IGameBeatmap beatmap, IFrameBasedClock framedClock) { - beatmap.BindTo(osuGame.Beatmap); + this.beatmap.BindTo(beatmap); try { diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index 399f9274a6..e3f5cc7a3c 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -17,7 +17,7 @@ namespace osu.Game.Screens.Edit.Components private const float corner_radius = 5; private const float contents_padding = 15; - public readonly Bindable Beatmap = new Bindable(); + protected readonly IBindable Beatmap = new Bindable(); protected Track Track => Beatmap.Value.Track; private readonly Drawable background; @@ -42,8 +42,10 @@ namespace osu.Game.Screens.Edit.Components } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(IGameBeatmap beatmap, OsuColour colours) { + Beatmap.BindTo(beatmap); + background.Colour = colours.Gray1; } } diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index c00e9ac4d5..0aeeef717e 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Allocation; using OpenTK; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -15,7 +16,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts /// public abstract class TimelinePart : CompositeDrawable { - public Bindable Beatmap = new Bindable(); + protected readonly IBindable Beatmap = new Bindable(); private readonly Container timeline; @@ -30,6 +31,12 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts }; } + [BackgroundDependencyLoader] + private void load(IGameBeatmap beatmap) + { + Beatmap.BindTo(beatmap); + } + private void updateRelativeChildSize() { // the track may not be loaded completely (only has a length once it is). diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs index 0301870588..77878288f9 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/SummaryTimeline.cs @@ -20,19 +20,17 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary [BackgroundDependencyLoader] private void load(OsuColour colours, IAdjustableClock adjustableClock) { - TimelinePart markerPart, controlPointPart, bookmarkPart, breakPart; - Children = new Drawable[] { - markerPart = new MarkerPart(adjustableClock) { RelativeSizeAxes = Axes.Both }, - controlPointPart = new ControlPointPart + new MarkerPart(adjustableClock) { RelativeSizeAxes = Axes.Both }, + new ControlPointPart { Anchor = Anchor.Centre, Origin = Anchor.BottomCentre, RelativeSizeAxes = Axes.Both, Height = 0.35f }, - bookmarkPart = new BookmarkPart + new BookmarkPart { Anchor = Anchor.Centre, Origin = Anchor.TopCentre, @@ -67,7 +65,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary }, } }, - breakPart = new BreakPart + new BreakPart { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -75,11 +73,6 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary Height = 0.25f } }; - - markerPart.Beatmap.BindTo(Beatmap); - controlPointPart.Beatmap.BindTo(Beatmap); - bookmarkPart.Beatmap.BindTo(Beatmap); - breakPart.Beatmap.BindTo(Beatmap); } } } diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index b657fe5597..eec7a29823 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -128,9 +128,9 @@ namespace osu.Game.Screens.Edit { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = 10 }, - Child = timeInfo = new TimeInfoContainer { RelativeSizeAxes = Axes.Both }, + Child = new TimeInfoContainer { RelativeSizeAxes = Axes.Both }, }, - timeline = new SummaryTimeline + new SummaryTimeline { RelativeSizeAxes = Axes.Both, }, @@ -138,7 +138,7 @@ namespace osu.Game.Screens.Edit { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Left = 10 }, - Child = playback = new PlaybackControl { RelativeSizeAxes = Axes.Both }, + Child = new PlaybackControl { RelativeSizeAxes = Axes.Both }, } }, } @@ -148,9 +148,6 @@ namespace osu.Game.Screens.Edit }, }; - timeInfo.Beatmap.BindTo(Beatmap); - timeline.Beatmap.BindTo(Beatmap); - playback.Beatmap.BindTo(Beatmap); menuBar.Mode.ValueChanged += onModeChanged; bottomBackground.Colour = colours.Gray2; @@ -178,7 +175,6 @@ namespace osu.Game.Screens.Edit break; } - currentScreen.Beatmap.BindTo(Beatmap); LoadComponentAsync(currentScreen, screenContainer.Add); } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs index fea4883144..b991f7c2c0 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Compose.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Compose.cs @@ -28,7 +28,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose if (beatDivisor != null) this.beatDivisor.BindTo(beatDivisor); - ScrollableTimeline timeline; Children = new Drawable[] { new GridContainer @@ -65,7 +64,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { Right = 5 }, - Child = timeline = new ScrollableTimeline { RelativeSizeAxes = Axes.Both } + Child = new ScrollableTimeline { RelativeSizeAxes = Axes.Both } }, new BeatDivisorControl(beatDivisor) { RelativeSizeAxes = Axes.Both } }, @@ -94,8 +93,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose }, }; - timeline.Beatmap.BindTo(Beatmap); - var ruleset = Beatmap.Value.BeatmapInfo.Ruleset?.CreateInstance(); if (ruleset == null) { diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs index 72dda24b62..136ceb47c4 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/BeatmapWaveformGraph.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.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; @@ -11,14 +10,13 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class BeatmapWaveformGraph : CompositeDrawable { - public readonly Bindable Beatmap = new Bindable(); + public WorkingBeatmap Beatmap { set => graph.Waveform = value.Waveform; } private readonly WaveformGraph graph; public BeatmapWaveformGraph() { InternalChild = graph = new WaveformGraph { RelativeSizeAxes = Axes.Both }; - Beatmap.ValueChanged += b => graph.Waveform = b.Waveform; } /// diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs index 3223c08c1f..3bebf78b17 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollableTimeline.cs @@ -2,11 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.UserInterface; @@ -14,8 +12,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { public class ScrollableTimeline : CompositeDrawable { - public readonly Bindable Beatmap = new Bindable(); - private readonly ScrollingTimelineContainer timelineContainer; public ScrollableTimeline() @@ -117,7 +113,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline hitSoundsCheckbox.Current.Value = true; waveformCheckbox.Current.Value = true; - timelineContainer.Beatmap.BindTo(Beatmap); timelineContainer.WaveformVisible.BindTo(waveformCheckbox.Current); } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 83aa86ba61..80fd83ea4e 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using osu.Framework.Allocation; using OpenTK; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -17,7 +18,8 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline public readonly Bindable HitObjectsVisible = new Bindable(); public readonly Bindable HitSoundsVisible = new Bindable(); public readonly Bindable WaveformVisible = new Bindable(); - public readonly Bindable Beatmap = new Bindable(); + + private readonly IBindable beatmap = new Bindable(); private readonly BeatmapWaveformGraph waveform; @@ -36,12 +38,22 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Content.AutoSizeAxes = Axes.None; Content.RelativeSizeAxes = Axes.Both; - waveform.Beatmap.BindTo(Beatmap); WaveformVisible.ValueChanged += waveformVisibilityChanged; Zoom = 10; } + [BackgroundDependencyLoader] + private void load(IGameBeatmap beatmap) + { + this.beatmap.BindTo(beatmap); + + beatmap.ValueChanged += beatmapChanged; + beatmapChanged(beatmap.Value); + } + + private void beatmapChanged(WorkingBeatmap beatmap) => waveform.Beatmap = beatmap; + private float minZoom = 1; /// /// The minimum zoom level allowed. diff --git a/osu.Game/Screens/Edit/Screens/EditorScreen.cs b/osu.Game/Screens/Edit/Screens/EditorScreen.cs index f70c462cd8..b7c0dee5e3 100644 --- a/osu.Game/Screens/Edit/Screens/EditorScreen.cs +++ b/osu.Game/Screens/Edit/Screens/EditorScreen.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 osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -13,7 +14,7 @@ namespace osu.Game.Screens.Edit.Screens /// public class EditorScreen : Container { - public readonly Bindable Beatmap = new Bindable(); + protected readonly IBindable Beatmap = new Bindable(); protected override Container Content => content; private readonly Container content; @@ -27,6 +28,12 @@ namespace osu.Game.Screens.Edit.Screens InternalChild = content = new Container { RelativeSizeAxes = Axes.Both }; } + [BackgroundDependencyLoader] + private void load(IGameBeatmap beatmap) + { + Beatmap.BindTo(beatmap); + } + protected override void LoadComplete() { base.LoadComplete(); diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index c174e2d470..7caad3d716 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -27,6 +27,8 @@ namespace osu.Game.Screens.Menu /// public bool DidLoadMenu; + private GameBeatmap beatmapBacking; + private MainMenu mainMenu; private SampleChannel welcome; private SampleChannel seeya; @@ -44,8 +46,10 @@ namespace osu.Game.Screens.Menu private WorkingBeatmap beatmap; [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game) + private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game, GameBeatmap beatmap) { + beatmapBacking = beatmap.GetBoundCopy(); + menuVoice = config.GetBindable(OsuSetting.MenuVoice); menuMusic = config.GetBindable(OsuSetting.MenuMusic); @@ -72,8 +76,8 @@ namespace osu.Game.Screens.Menu } } - beatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - track = beatmap.Track; + this.beatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); + track = this.beatmap.Track; welcome = audio.Sample.Get(@"welcome"); seeya = audio.Sample.Get(@"seeya"); @@ -83,7 +87,7 @@ namespace osu.Game.Screens.Menu { base.OnEntering(last); - Game.Beatmap.Value = beatmap; + beatmapBacking.Value = beatmap; if (menuVoice) welcome.Play(); diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 1f2cb915b3..9773ca0834 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -21,7 +21,7 @@ namespace osu.Game.Screens.Menu { public class LogoVisualisation : Drawable, IHasAccentColour { - private readonly Bindable beatmap = new Bindable(); + private readonly IBindable beatmap = new Bindable(); /// /// The number of bars to jump each update iteration. @@ -78,9 +78,9 @@ namespace osu.Game.Screens.Menu } [BackgroundDependencyLoader] - private void load(ShaderManager shaders, OsuGameBase game) + private void load(ShaderManager shaders, IGameBeatmap beatmap) { - beatmap.BindTo(game.Beatmap); + this.beatmap.BindTo(beatmap); shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); } diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs index fae3e72552..667be7d88d 100644 --- a/osu.Game/Screens/Menu/MenuSideFlashes.cs +++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs @@ -22,7 +22,7 @@ namespace osu.Game.Screens.Menu public override bool HandleKeyboardInput => false; public override bool HandleMouseInput => false; - private readonly Bindable beatmap = new Bindable(); + private readonly IBindable beatmap = new Bindable(); private readonly Box leftBox; private readonly Box rightBox; @@ -66,9 +66,9 @@ namespace osu.Game.Screens.Menu } [BackgroundDependencyLoader] - private void load(OsuGameBase game, OsuColour colours) + private void load(IGameBeatmap beatmap, OsuColour colours) { - beatmap.BindTo(game.Beatmap); + this.beatmap.BindTo(beatmap); // linear colour looks better in this case, so let's use it for now. Color4 gradientDark = colours.Blue.Opacity(0).ToLinear(); diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 4b1562291b..7042c43b70 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.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 osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -61,36 +60,21 @@ namespace osu.Game.Screens /// public virtual bool AllowBeatmapRulesetChange => true; - protected readonly Bindable Beatmap = new Bindable(); + protected readonly IBindable Beatmap = new Bindable(); protected virtual float BackgroundParallaxAmount => 1; private ParallaxContainer backgroundParallaxContainer; - public WorkingBeatmap InitialBeatmap - { - set - { - if (IsLoaded) throw new InvalidOperationException($"Cannot set {nameof(InitialBeatmap)} post-load."); - Beatmap.Value = value; - } - } - protected readonly Bindable Ruleset = new Bindable(); private SampleChannel sampleExit; [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuGameBase game, OsuGame osuGame, AudioManager audio) + private void load(IGameBeatmap beatmap, OsuGame osuGame, AudioManager audio) { - if (game != null) - { - //if we were given a beatmap at ctor time, we want to pass this on to the game-wide beatmap. - var localMap = Beatmap.Value; - Beatmap.BindTo(game.Beatmap); - if (localMap != null) - Beatmap.Value = localMap; - } + if (beatmap != null) + Beatmap.BindTo(beatmap); if (osuGame != null) { diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 0150d76251..fa6db09c06 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -117,7 +117,7 @@ namespace osu.Game.Screens.Play // let's try again forcing the beatmap's ruleset. ruleset = beatmap.BeatmapInfo.Ruleset; rulesetInstance = ruleset.CreateInstance(); - RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap); + RulesetContainer = rulesetInstance.CreateRulesetContainerWith(Beatmap.Value); } if (!RulesetContainer.Objects.Any()) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 734837a4f1..cd9d68e50a 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load() { - Add(info = new BeatmapMetadataDisplay(Beatmap) + Add(info = new BeatmapMetadataDisplay(Beatmap.Value) { Alpha = 0, Anchor = Anchor.Centre, diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs index 1ccc5e2fe8..7f18305b1c 100644 --- a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -13,7 +13,7 @@ namespace osu.Game.Screens.Play { public abstract class ScreenWithBeatmapBackground : OsuScreen { - protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); + protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value); public override bool AllowBeatmapRulesetChange => false; diff --git a/osu.Game/Screens/Ranking/Results.cs b/osu.Game/Screens/Ranking/Results.cs index 32161a0b8e..cd61a692b5 100644 --- a/osu.Game/Screens/Ranking/Results.cs +++ b/osu.Game/Screens/Ranking/Results.cs @@ -38,7 +38,7 @@ namespace osu.Game.Screens.Ranking private static readonly Vector2 background_blur = new Vector2(20); - protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); + protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap.Value); private const float overscan = 1.3f; @@ -272,10 +272,10 @@ namespace osu.Game.Screens.Ranking switch (mode) { case ResultMode.Summary: - currentPage = new ResultsPageScore(score, Beatmap); + currentPage = new ResultsPageScore(score, Beatmap.Value); break; case ResultMode.Ranking: - currentPage = new ResultsPageRanking(score, Beatmap); + currentPage = new ResultsPageRanking(score, Beatmap.Value); break; } diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index 7992930c45..f52a06bec0 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -30,6 +30,8 @@ namespace osu.Game.Screens.Select protected readonly BeatmapDetailArea BeatmapDetails; private bool removeAutoModOnResume; + private GameBeatmap beatmap; + public PlaySongSelect() { FooterPanels.Add(modSelect = new ModSelectOverlay @@ -53,8 +55,10 @@ namespace osu.Game.Screens.Select public readonly Bindable> SelectedMods = new Bindable>(new List()); [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame osu) + private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame osu, GameBeatmap beatmap) { + this.beatmap = beatmap.GetBoundCopy(); + if (osu != null) SelectedMods.BindTo(osu.SelectedMods); modSelect.SelectedMods.BindTo(SelectedMods); @@ -156,7 +160,7 @@ namespace osu.Game.Screens.Select } Beatmap.Value.Track.Looping = false; - Beatmap.Disabled = true; + beatmap.Disabled = true; sampleConfirm?.Play(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 4ffa9e2a90..11dfe4a3b4 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -65,6 +65,8 @@ namespace osu.Game.Screens.Select private CancellationTokenSource initialAddSetsTask; + private GameBeatmap beatmap; + private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent); @@ -179,8 +181,10 @@ namespace osu.Game.Screens.Select } [BackgroundDependencyLoader(permitNulls: true)] - private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours) + private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours, GameBeatmap beatmap) { + this.beatmap = beatmap.GetBoundCopy(); + dependencies.CacheAs(this); if (Footer != null) @@ -212,14 +216,14 @@ namespace osu.Game.Screens.Select Carousel.BeatmapSets = this.beatmaps.GetAllUsableBeatmapSets(); Beatmap.DisabledChanged += disabled => Carousel.AllowSelection = !disabled; - Beatmap.TriggerChange(); - Beatmap.ValueChanged += workingBeatmapChanged; + + workingBeatmapChanged(Beatmap.Value); } public void Edit(BeatmapInfo beatmap) { - Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap); + this.beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); Push(new Editor()); } @@ -283,7 +287,7 @@ namespace osu.Game.Screens.Select { bool preview = beatmap?.BeatmapSetInfoID != Beatmap.Value?.BeatmapInfo.BeatmapSetInfoID; - Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap); + this.beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); ensurePlayingSelected(preview); } @@ -370,7 +374,7 @@ namespace osu.Game.Screens.Select { if (Beatmap != null && !Beatmap.Value.BeatmapSetInfo.DeletePending) { - UpdateBeatmap(Beatmap); + UpdateBeatmap(Beatmap.Value); ensurePlayingSelected(); } diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs index 135b5e2b1e..253902fb81 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Textures; using System.Linq; +using osu.Game.Beatmaps; namespace osu.Game.Storyboards.Drawables { @@ -63,14 +64,14 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader] - private void load(OsuGameBase game, TextureStore textureStore) + private void load(IGameBeatmap beatmap, TextureStore textureStore) { var basePath = Animation.Path.ToLowerInvariant(); for (var frame = 0; frame < Animation.FrameCount; frame++) { var framePath = basePath.Replace(".", frame + "."); - var path = game.Beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename.ToLowerInvariant() == framePath)?.FileInfo.StoragePath; + var path = beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename.ToLowerInvariant() == framePath)?.FileInfo.StoragePath; if (path == null) continue; diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs index 9f22bebcc2..f3fb5e368a 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; using System.Linq; +using osu.Game.Beatmaps; namespace osu.Game.Storyboards.Drawables { @@ -62,10 +63,10 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader] - private void load(OsuGameBase game, TextureStore textureStore) + private void load(IGameBeatmap beatmap, TextureStore textureStore) { var spritePath = Sprite.Path.ToLowerInvariant(); - var path = game.Beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename.ToLowerInvariant() == spritePath)?.FileInfo.StoragePath; + var path = beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename.ToLowerInvariant() == spritePath)?.FileInfo.StoragePath; if (path == null) return; diff --git a/osu.Game/Tests/Visual/EditorClockTestCase.cs b/osu.Game/Tests/Visual/EditorClockTestCase.cs index 43b20f7021..ae061ef6db 100644 --- a/osu.Game/Tests/Visual/EditorClockTestCase.cs +++ b/osu.Game/Tests/Visual/EditorClockTestCase.cs @@ -25,24 +25,20 @@ namespace osu.Game.Tests.Visual protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent); - private OsuGameBase osuGame; - protected EditorClockTestCase() { Clock = new EditorClock(new ControlPointInfo(), BeatDivisor) { IsCoupled = false }; } [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) + private void load() { - this.osuGame = osuGame; - dependencies.Cache(BeatDivisor); dependencies.CacheAs(Clock); dependencies.CacheAs(Clock); - osuGame.Beatmap.ValueChanged += beatmapChanged; - beatmapChanged(osuGame.Beatmap.Value); + Beatmap.ValueChanged += beatmapChanged; + beatmapChanged(Beatmap.Value); } private void beatmapChanged(WorkingBeatmap working) @@ -68,12 +64,5 @@ namespace osu.Game.Tests.Visual return true; } - - protected override void Dispose(bool isDisposing) - { - osuGame.Beatmap.ValueChanged -= beatmapChanged; - - base.Dispose(isDisposing); - } } } diff --git a/osu.Game/Tests/Visual/EditorTestCase.cs b/osu.Game/Tests/Visual/EditorTestCase.cs index c0b72f56a4..2ab121fcc9 100644 --- a/osu.Game/Tests/Visual/EditorTestCase.cs +++ b/osu.Game/Tests/Visual/EditorTestCase.cs @@ -23,9 +23,9 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) + private void load() { - osuGame.Beatmap.Value = new TestWorkingBeatmap(ruleset.RulesetInfo); + Beatmap.Value = new TestWorkingBeatmap(ruleset.RulesetInfo); LoadComponentAsync(new Editor(), LoadScreen); } diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 2b677f1f42..e654b3aab1 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -3,12 +3,28 @@ using System.IO; using System.Reflection; +using osu.Framework.Allocation; using osu.Framework.Testing; +using osu.Game.Beatmaps; namespace osu.Game.Tests.Visual { public abstract class OsuTestCase : TestCase { + protected readonly GameBeatmap Beatmap = new GameBeatmap(new DummyWorkingBeatmap()); + + private DependencyContainer dependencies; + + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + => dependencies = new DependencyContainer(parent); + + [BackgroundDependencyLoader] + private void load() + { + dependencies.CacheAs(Beatmap); + dependencies.Cache(Beatmap); + } + protected override ITestCaseTestRunner CreateRunner() => new OsuTestCaseTestRunner(); public class OsuTestCaseTestRunner : OsuGameBase, ITestCaseTestRunner diff --git a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs index 51460ecb6d..b6d92f4ec5 100644 --- a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs +++ b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs @@ -50,7 +50,7 @@ namespace osu.Game.Tests.Visual new ScrollContainer { RelativeSizeAxes = Axes.Both, - Child = new BeatmapList(ruleset) + Child = new BeatmapList(ruleset, Beatmap) } } }, @@ -108,10 +108,12 @@ namespace osu.Game.Tests.Visual { private readonly Container beatmapDisplays; private readonly Ruleset ruleset; + private readonly GameBeatmap beatmapBindable; - public BeatmapList(Ruleset ruleset) + public BeatmapList(Ruleset ruleset, GameBeatmap beatmapBindable) { this.ruleset = ruleset; + this.beatmapBindable = beatmapBindable; RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; @@ -130,7 +132,7 @@ namespace osu.Game.Tests.Visual var sets = beatmaps.GetAllUsableBeatmapSets(); var allBeatmaps = sets.SelectMany(s => s.Beatmaps).Where(b => ruleset.LegacyID == null || b.RulesetID == ruleset.LegacyID); - allBeatmaps.ForEach(b => beatmapDisplays.Add(new BeatmapDisplay(b))); + allBeatmaps.ForEach(b => beatmapDisplays.Add(new BeatmapDisplay(b, beatmapBindable))); } private class BeatmapDisplay : CompositeDrawable, IHasTooltip @@ -138,27 +140,47 @@ namespace osu.Game.Tests.Visual private readonly OsuSpriteText text; private readonly BeatmapInfo beatmap; + private readonly GameBeatmap beatmapBindable; + private BeatmapManager beatmaps; - private OsuGameBase osuGame; private bool isSelected; public string TooltipText => text.Text; - public BeatmapDisplay(BeatmapInfo beatmap) + public BeatmapDisplay(BeatmapInfo beatmap, GameBeatmap beatmapBindable) { this.beatmap = beatmap; + this.beatmapBindable = beatmapBindable; AutoSizeAxes = Axes.Both; InternalChild = text = new OsuSpriteText(); + + this.beatmapBindable.ValueChanged += beatmapChanged; + } + + [BackgroundDependencyLoader] + private void load(BeatmapManager beatmaps) + { + this.beatmaps = beatmaps; + + var working = beatmaps.GetWorkingBeatmap(beatmap); + text.Text = $"{working.Metadata.Artist} - {working.Metadata.Title} ({working.Metadata.AuthorString}) [{working.BeatmapInfo.Version}]"; + } + + private void beatmapChanged(WorkingBeatmap newBeatmap) + { + if (isSelected) + this.FadeColour(Color4.White, 100); + isSelected = false; } protected override bool OnClick(InputState state) { - if (osuGame.Beatmap.Value.BeatmapInfo.ID == beatmap.ID) + if (beatmapBindable.Value.BeatmapInfo.ID == beatmap.ID) return false; - osuGame.Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap); + beatmapBindable.Value = beatmaps.GetWorkingBeatmap(beatmap); isSelected = true; return true; } @@ -177,25 +199,6 @@ namespace osu.Game.Tests.Visual return; this.FadeColour(Color4.White, 100); } - - [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame, BeatmapManager beatmaps) - { - this.osuGame = osuGame; - this.beatmaps = beatmaps; - - var working = beatmaps.GetWorkingBeatmap(beatmap); - text.Text = $"{working.Metadata.Artist} - {working.Metadata.Title} ({working.Metadata.AuthorString}) [{working.BeatmapInfo.Version}]"; - - osuGame.Beatmap.ValueChanged += beatmapChanged; - } - - private void beatmapChanged(WorkingBeatmap newBeatmap) - { - if (isSelected) - this.FadeColour(Color4.White, 100); - isSelected = false; - } } } @@ -204,7 +207,7 @@ namespace osu.Game.Tests.Visual private readonly FillFlowContainer scores; private APIAccess api; - private readonly Bindable currentBeatmap = new Bindable(); + private readonly IBindable currentBeatmap = new Bindable(); public PerformanceList() { @@ -220,7 +223,7 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame, APIAccess api) + private void load(IGameBeatmap beatmap, APIAccess api) { this.api = api; @@ -235,7 +238,7 @@ namespace osu.Game.Tests.Visual } currentBeatmap.ValueChanged += beatmapChanged; - currentBeatmap.BindTo(osuGame.Beatmap); + currentBeatmap.BindTo(beatmap); } private GetScoresRequest lastRequest; @@ -333,9 +336,9 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(OsuGameBase osuGame) + private void load(IGameBeatmap beatmap) { - osuGame.Beatmap.ValueChanged += beatmapChanged; + beatmap.ValueChanged += beatmapChanged; } private Cached informationCache = new Cached(); diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index bda438d906..04ac62f6cd 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -19,8 +19,6 @@ namespace osu.Game.Tests.Visual protected Player Player; - private TestWorkingBeatmap working; - protected TestCasePlayer(Ruleset ruleset) { this.ruleset = ruleset; @@ -65,13 +63,13 @@ namespace osu.Game.Tests.Visual { var beatmap = CreateBeatmap(r); - working = new TestWorkingBeatmap(beatmap); - working.Mods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) }; + Beatmap.Value = new TestWorkingBeatmap(beatmap); + Beatmap.Value.Mods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) }; if (Player != null) Remove(Player); - var player = CreatePlayer(working, r); + var player = CreatePlayer(Beatmap, r); LoadComponentAsync(player, LoadScreen); @@ -82,14 +80,12 @@ namespace osu.Game.Tests.Visual { base.Update(); - if (working != null) - // note that this will override any mod rate application - working.Track.Rate = Clock.Rate; + // note that this will override any mod rate application + Beatmap.Value.Track.Rate = Clock.Rate; } protected virtual Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset) => new Player { - InitialBeatmap = beatmap, AllowPause = false, AllowLeadIn = false, AllowResults = false, From a25462e10fc4d3841bda1edadd955552bbc0262e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 23 May 2018 18:52:09 +0900 Subject: [PATCH 056/262] Fix testcase audio + dependency overrides not working --- osu.Game/Beatmaps/GameBeatmap.cs | 34 ++++++++++++++++++++++++++-- osu.Game/OsuGameBase.cs | 25 +------------------- osu.Game/Tests/Visual/OsuTestCase.cs | 25 ++++++++++++++++---- 3 files changed, 53 insertions(+), 31 deletions(-) diff --git a/osu.Game/Beatmaps/GameBeatmap.cs b/osu.Game/Beatmaps/GameBeatmap.cs index ac31b16533..f432fa4a7c 100644 --- a/osu.Game/Beatmaps/GameBeatmap.cs +++ b/osu.Game/Beatmaps/GameBeatmap.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.Diagnostics; +using osu.Framework.Audio; using osu.Framework.Configuration; namespace osu.Game.Beatmaps @@ -11,14 +13,42 @@ namespace osu.Game.Beatmaps /// public class GameBeatmap : NonNullableBindable, IGameBeatmap { - public GameBeatmap(WorkingBeatmap defaultValue) + private readonly AudioManager audioManager; + + private WorkingBeatmap lastBeatmap; + + public GameBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) : base(defaultValue) { + this.audioManager = audioManager; + + ValueChanged += registerAudioTrack; + } + + private void registerAudioTrack(WorkingBeatmap beatmap) + { + var trackLoaded = lastBeatmap?.TrackLoaded ?? false; + + // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) + if (!trackLoaded || lastBeatmap?.Track != beatmap.Track) + { + if (trackLoaded) + { + Debug.Assert(lastBeatmap != null); + Debug.Assert(lastBeatmap.Track != null); + + lastBeatmap.RecycleTrack(); + } + + audioManager.Track.AddItem(beatmap.Track); + } + + lastBeatmap = beatmap; } public GameBeatmap GetBoundCopy() { - var copy = new GameBeatmap(Default); + var copy = new GameBeatmap(Default, audioManager); copy.BindTo(this); return copy; } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 5546b5bcec..97f7f5a21e 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Diagnostics; using System.IO; using System.Linq; using System.Reflection; @@ -66,7 +65,6 @@ namespace osu.Game protected override Container Content => content; protected GameBeatmap Beatmap; - private WorkingBeatmap lastBeatmap; private Bindable fpsDisplayVisible; @@ -158,34 +156,13 @@ namespace osu.Game Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera-Light")); var defaultBeatmap = new DummyWorkingBeatmap(this); - Beatmap = new GameBeatmap(defaultBeatmap); + Beatmap = new GameBeatmap(defaultBeatmap, Audio); BeatmapManager.DefaultBeatmap = defaultBeatmap; // tracks play so loud our samples can't keep up. // this adds a global reduction of track volume for the time being. Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8)); - Beatmap.ValueChanged += b => - { - var trackLoaded = lastBeatmap?.TrackLoaded ?? false; - - // compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo) - if (!trackLoaded || lastBeatmap?.Track != b.Track) - { - if (trackLoaded) - { - Debug.Assert(lastBeatmap != null); - Debug.Assert(lastBeatmap.Track != null); - - lastBeatmap.RecycleTrack(); - } - - Audio.Track.AddItem(b.Track); - } - - lastBeatmap = b; - }; - dependencies.Cache(Beatmap); dependencies.CacheAs(Beatmap); diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index e654b3aab1..e6d3407c42 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -4,6 +4,7 @@ using System.IO; using System.Reflection; using osu.Framework.Allocation; +using osu.Framework.Audio; using osu.Framework.Testing; using osu.Game.Beatmaps; @@ -11,18 +12,32 @@ namespace osu.Game.Tests.Visual { public abstract class OsuTestCase : TestCase { - protected readonly GameBeatmap Beatmap = new GameBeatmap(new DummyWorkingBeatmap()); + protected GameBeatmap Beatmap { get; private set; } private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(parent); - - [BackgroundDependencyLoader] - private void load() { + // The beatmap is constructed here rather than load() because our children get dependencies injected before our load() runs + Beatmap = new GameBeatmap(new DummyWorkingBeatmap(), parent.Get()); + + dependencies = new DependencyContainer(parent); + dependencies.CacheAs(Beatmap); dependencies.Cache(Beatmap); + + return dependencies; + } + + public override void Cleanup() + { + base.Cleanup(); + + if (Beatmap != null) + { + Beatmap.Disabled = true; + Beatmap.Value.Track.Stop(); + } } protected override ITestCaseTestRunner CreateRunner() => new OsuTestCaseTestRunner(); From a5d2d744479c39d9d8bcfb8a04d0888419993eb8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 23 May 2018 19:01:27 +0900 Subject: [PATCH 057/262] Remove whitespace --- osu.Game/Screens/Edit/Components/BottomBarContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index e3f5cc7a3c..81a5b24483 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -45,7 +45,6 @@ namespace osu.Game.Screens.Edit.Components private void load(IGameBeatmap beatmap, OsuColour colours) { Beatmap.BindTo(beatmap); - background.Colour = colours.Gray1; } } From 542eb848b0ae6e56b056f6d75dab6f8f390fb4b6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 24 May 2018 12:42:58 +0900 Subject: [PATCH 058/262] Fix GetBoundCopy on IGameBeatmap not working --- osu.Game/Beatmaps/GameBeatmap.cs | 8 +++++++- osu.Game/Beatmaps/IGameBeatmap.cs | 5 +++++ 2 files changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/GameBeatmap.cs b/osu.Game/Beatmaps/GameBeatmap.cs index f432fa4a7c..0b92fda7b7 100644 --- a/osu.Game/Beatmaps/GameBeatmap.cs +++ b/osu.Game/Beatmaps/GameBeatmap.cs @@ -46,7 +46,13 @@ namespace osu.Game.Beatmaps lastBeatmap = beatmap; } - public GameBeatmap GetBoundCopy() + IGameBeatmap IGameBeatmap.GetBoundCopy() => GetBoundCopy(); + + /// + /// Retrieve a new instance weakly bound to this . + /// If you are further binding to events of the retrieved , ensure a local reference is held. + /// + public new GameBeatmap GetBoundCopy() { var copy = new GameBeatmap(Default, audioManager); copy.BindTo(this); diff --git a/osu.Game/Beatmaps/IGameBeatmap.cs b/osu.Game/Beatmaps/IGameBeatmap.cs index 89323c953b..b2840f1c7e 100644 --- a/osu.Game/Beatmaps/IGameBeatmap.cs +++ b/osu.Game/Beatmaps/IGameBeatmap.cs @@ -10,5 +10,10 @@ namespace osu.Game.Beatmaps /// public interface IGameBeatmap : IBindable { + /// + /// Retrieve a new instance weakly bound to this . + /// If you are further binding to events of the retrieved , ensure a local reference is held. + /// + IGameBeatmap GetBoundCopy(); } } From 5a517bad630fd47f617358101548580cbe499f4f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 24 May 2018 12:53:32 +0900 Subject: [PATCH 059/262] Move beatmap cleanup to Dispose() --- osu.Game/Tests/Visual/OsuTestCase.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index e6d3407c42..06481fc89f 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -29,9 +29,9 @@ namespace osu.Game.Tests.Visual return dependencies; } - public override void Cleanup() + protected override void Dispose(bool isDisposing) { - base.Cleanup(); + base.Dispose(isDisposing); if (Beatmap != null) { From f1ac84d95bbd15d87cf518c18500185ff1c88c2c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 24 May 2018 13:03:25 +0900 Subject: [PATCH 060/262] Fix base.CreateLocalDependencies sometimes not being called --- osu.Game.Tests/Visual/TestCaseChatLink.cs | 3 ++- osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs | 2 +- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 3 ++- osu.Game.Tests/Visual/TestCasePlaybackControl.cs | 2 +- osu.Game.Tests/Visual/TestCaseSettings.cs | 3 ++- osu.Game/Screens/Edit/Editor.cs | 2 +- osu.Game/Screens/Select/SongSelect.cs | 3 ++- osu.Game/Tests/Visual/EditorClockTestCase.cs | 2 +- osu.Game/Tests/Visual/OsuTestCase.cs | 2 +- 9 files changed, 13 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseChatLink.cs b/osu.Game.Tests/Visual/TestCaseChatLink.cs index 89b1c52010..608691cdf6 100644 --- a/osu.Game.Tests/Visual/TestCaseChatLink.cs +++ b/osu.Game.Tests/Visual/TestCaseChatLink.cs @@ -36,7 +36,8 @@ namespace osu.Game.Tests.Visual }; private DependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent); + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); public TestCaseChatLink() { diff --git a/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs b/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs index 557d976073..0658de6576 100644 --- a/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs @@ -35,7 +35,7 @@ namespace osu.Game.Tests.Visual private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(parent); + => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 1371db78b5..b90e6c1ca7 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -48,7 +48,8 @@ namespace osu.Game.Tests.Visual typeof(DrawableCarouselBeatmapSet), }; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent); + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); private class TestSongSelect : PlaySongSelect { diff --git a/osu.Game.Tests/Visual/TestCasePlaybackControl.cs b/osu.Game.Tests/Visual/TestCasePlaybackControl.cs index 4bed5bb595..5c0c0cb220 100644 --- a/osu.Game.Tests/Visual/TestCasePlaybackControl.cs +++ b/osu.Game.Tests/Visual/TestCasePlaybackControl.cs @@ -18,7 +18,7 @@ namespace osu.Game.Tests.Visual private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(parent); + => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); [BackgroundDependencyLoader] private void load() diff --git a/osu.Game.Tests/Visual/TestCaseSettings.cs b/osu.Game.Tests/Visual/TestCaseSettings.cs index 5dad48c6d7..91dd35e148 100644 --- a/osu.Game.Tests/Visual/TestCaseSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseSettings.cs @@ -16,7 +16,8 @@ namespace osu.Game.Tests.Visual private DependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent); + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); public TestCaseSettings() { diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index eec7a29823..f1d244f2de 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -41,7 +41,7 @@ namespace osu.Game.Screens.Edit private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(parent); + => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); [BackgroundDependencyLoader] private void load(OsuColour colours) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 11dfe4a3b4..16b6a855f7 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -68,7 +68,8 @@ namespace osu.Game.Screens.Select private GameBeatmap beatmap; private DependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(parent); + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); protected SongSelect() { diff --git a/osu.Game/Tests/Visual/EditorClockTestCase.cs b/osu.Game/Tests/Visual/EditorClockTestCase.cs index ae061ef6db..0fe00d4ff3 100644 --- a/osu.Game/Tests/Visual/EditorClockTestCase.cs +++ b/osu.Game/Tests/Visual/EditorClockTestCase.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(parent); + => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); protected EditorClockTestCase() { diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 06481fc89f..c337563920 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -21,7 +21,7 @@ namespace osu.Game.Tests.Visual // The beatmap is constructed here rather than load() because our children get dependencies injected before our load() runs Beatmap = new GameBeatmap(new DummyWorkingBeatmap(), parent.Get()); - dependencies = new DependencyContainer(parent); + dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); dependencies.CacheAs(Beatmap); dependencies.Cache(Beatmap); From d4f68e0b673c9e258180d5290e016a3fb0e7d105 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 24 May 2018 14:26:53 +0900 Subject: [PATCH 061/262] Fix possible NaN values due to trackvirtual infinite length --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index df615ad035..3fdde1fc1d 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; +using osu.Framework.Audio.Track; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Input; @@ -97,8 +98,17 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline lastTrackTime = adjustableClock.CurrentTime; - void seekTrackToCurrent() => adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); - void scrollToTrackTime() => ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); + void seekTrackToCurrent() + { + if (!(Beatmap.Value.Track is TrackVirtual)) + adjustableClock.Seek(Current / Content.DrawWidth * Beatmap.Value.Track.Length); + } + + void scrollToTrackTime() + { + if (!(Beatmap.Value.Track is TrackVirtual)) + ScrollTo((float)(adjustableClock.CurrentTime / Beatmap.Value.Track.Length) * Content.DrawWidth, false); + } } protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) From b649025e861b14506754794e6416235b1e43d205 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 24 May 2018 14:36:48 +0900 Subject: [PATCH 062/262] beginUserDrag/endUserDrag --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index 3fdde1fc1d..0ae6cd6da2 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -115,7 +115,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { if (base.OnMouseDown(state, args)) { - beginUserInput(); + beginUserDrag(); return true; } @@ -124,18 +124,18 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - endUserInput(); + endUserDrag(); return base.OnMouseUp(state, args); } - private void beginUserInput() + private void beginUserDrag() { handlingDragInput = true; trackWasPlaying = adjustableClock.IsRunning; adjustableClock.Stop(); } - private void endUserInput() + private void endUserDrag() { handlingDragInput = false; if (trackWasPlaying) @@ -158,7 +158,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline { if (base.OnMouseDown(state, args)) { - timeline.beginUserInput(); + timeline.beginUserDrag(); return true; } @@ -167,7 +167,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) { - timeline.endUserInput(); + timeline.endUserDrag(); return base.OnMouseUp(state, args); } } From 3d1f0e50ed76573276a767c2feb54cf18c539e14 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 25 May 2018 10:54:53 +0900 Subject: [PATCH 063/262] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index b36db536d9..2893a3ec94 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit b36db536d96d75ef1be2d12d14245dcca91f2497 +Subproject commit 2893a3ec94b403bc11295fd435af0431dbe23b7a From 8ae2a3696f84c2b535542c5066909eb49d5b0a2f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 28 May 2018 03:00:21 +0900 Subject: [PATCH 064/262] Apply platform universal offset at player level --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 11 ++--------- osu.Game/Screens/Play/Player.cs | 7 ++++++- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 2aee419d20..a83ac26fb3 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -8,7 +8,6 @@ using System.Linq; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Beatmaps.ControlPoints; -using osu.Framework; namespace osu.Game.Beatmaps.Formats { @@ -28,23 +27,17 @@ namespace osu.Game.Beatmaps.Formats AddDecoder(@"osu file format v", m => new LegacyBeatmapDecoder(int.Parse(m.Split('v').Last()))); } - /// - /// lazer's audio timings in general doesn't match stable. this is the result of user testing, albeit limited. - /// This only seems to be required on windows. We need to eventually figure out why, with a bit of luck. - /// - public static int UniversalOffset => RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? -22 : 0; - /// /// Whether or not beatmap or runtime offsets should be applied. Defaults on; only disable for testing purposes. /// public bool ApplyOffsets = true; - private readonly int offset = UniversalOffset; + private readonly int offset; public LegacyBeatmapDecoder(int version = LATEST_VERSION) : base(version) { // BeatmapVersion 4 and lower had an incorrect offset (stable has this set as 24ms off) - offset += FormatVersion < 5 ? 24 : 0; + offset = FormatVersion < 5 ? 24 : 0; } protected override void ParseStreamInto(StreamReader stream, Beatmap beatmap) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9985a24cab..328a4021aa 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using System.Threading.Tasks; +using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; @@ -143,8 +144,12 @@ namespace osu.Game.Screens.Play adjustableClock.ProcessFrame(); + // Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited. + // This only seems to be required on windows. We need to eventually figure out why, with a bit of luck. + var offsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0 }; + // the final usable gameplay clock with user-set offsets applied. - var offsetClock = new FramedOffsetClock(adjustableClock); + offsetClock = new FramedOffsetClock(offsetClock); userAudioOffset.ValueChanged += v => offsetClock.Offset = v; userAudioOffset.TriggerChange(); From 3abfd4711dcc8b58bce7f6bab5e7755e4b9145c5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 28 May 2018 03:34:58 +0900 Subject: [PATCH 065/262] Fix wrong clock being seeked when unpausing --- osu.Game/Screens/Play/PauseContainer.cs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/PauseContainer.cs b/osu.Game/Screens/Play/PauseContainer.cs index bd334ad2e2..6262f71ddc 100644 --- a/osu.Game/Screens/Play/PauseContainer.cs +++ b/osu.Game/Screens/Play/PauseContainer.cs @@ -44,13 +44,18 @@ namespace osu.Game.Screens.Play public Action OnResume; public Action OnPause; - private readonly IAdjustableClock adjustableClock; private readonly FramedClock framedClock; + private readonly DecoupleableInterpolatingFramedClock decoupledClock; - public PauseContainer(FramedClock framedClock, IAdjustableClock adjustableClock) + /// + /// Creates a new . + /// + /// The gameplay clock. This is the clock that will process frames. + /// The seekable clock. This is the clock that will be paused and resumed. + public PauseContainer(FramedClock framedClock, DecoupleableInterpolatingFramedClock decoupledClock) { this.framedClock = framedClock; - this.adjustableClock = adjustableClock; + this.decoupledClock = decoupledClock; RelativeSizeAxes = Axes.Both; @@ -80,7 +85,7 @@ namespace osu.Game.Screens.Play if (IsPaused) return; // stop the seekable clock (stops the audio eventually) - adjustableClock.Stop(); + decoupledClock.Stop(); IsPaused = true; OnPause?.Invoke(); @@ -97,10 +102,10 @@ namespace osu.Game.Screens.Play IsResuming = false; lastPauseActionTime = Time.Current; - // seek back to the time of the framed clock. - // this accounts for the audio clock potentially taking time to enter a completely stopped state. - adjustableClock.Seek(framedClock.CurrentTime); - adjustableClock.Start(); + // Seeking the decoupled clock to its current time ensures that its source clock will be seeked to the same time + // This accounts for the audio clock source potentially taking time to enter a completely stopped state + decoupledClock.Seek(decoupledClock.CurrentTime); + decoupledClock.Start(); OnResume?.Invoke(); pauseOverlay.Hide(); From b267ec3178aa07109d940559538c451629846fa4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 28 May 2018 03:48:09 +0900 Subject: [PATCH 066/262] Fix failing test --- osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs index c6863d1cb5..f9b055ed55 100644 --- a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs @@ -58,7 +58,7 @@ namespace osu.Game.Tests.Beatmaps.IO Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile); Assert.AreEqual("Deif", meta.AuthorString); Assert.AreEqual("machinetop_background.jpg", meta.BackgroundFile); - Assert.AreEqual(164471 + LegacyBeatmapDecoder.UniversalOffset, meta.PreviewTime); + Assert.AreEqual(164471, meta.PreviewTime); Assert.AreEqual(string.Empty, meta.Source); Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", meta.Tags); Assert.AreEqual("Renatus", meta.Title); From 3a5228af4328b5fc6a9be5481e1fbe7115a21656 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 28 May 2018 17:55:41 +0900 Subject: [PATCH 067/262] Make GameBeatmap late-bind its AudioManager for ctor Beatmap access --- osu.Game/Beatmaps/GameBeatmap.cs | 33 ++++++++++++++++------- osu.Game/OsuGameBase.cs | 30 ++++++++++++++++++--- osu.Game/Tests/Visual/OsuTestCase.cs | 39 +++++++++++++++++++++------- 3 files changed, 79 insertions(+), 23 deletions(-) diff --git a/osu.Game/Beatmaps/GameBeatmap.cs b/osu.Game/Beatmaps/GameBeatmap.cs index 0b92fda7b7..ea19337c8c 100644 --- a/osu.Game/Beatmaps/GameBeatmap.cs +++ b/osu.Game/Beatmaps/GameBeatmap.cs @@ -1,8 +1,11 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Diagnostics; +using JetBrains.Annotations; using osu.Framework.Audio; +using osu.Framework.Audio.Track; using osu.Framework.Configuration; namespace osu.Game.Beatmaps @@ -11,18 +14,31 @@ namespace osu.Game.Beatmaps /// A for the beatmap. /// This should be used sparingly in-favour of . /// - public class GameBeatmap : NonNullableBindable, IGameBeatmap + public abstract class GameBeatmap : NonNullableBindable, IGameBeatmap { - private readonly AudioManager audioManager; - + private AudioManager audioManager; private WorkingBeatmap lastBeatmap; - public GameBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) + protected GameBeatmap(WorkingBeatmap defaultValue) : base(defaultValue) { + } + + /// + /// Registers an for s to be added to. + /// + /// The . + protected void RegisterAudioManager([NotNull] AudioManager audioManager) + { + if (this.audioManager != null) throw new InvalidOperationException($"Cannot register multiple {nameof(AudioManager)}s."); + this.audioManager = audioManager; ValueChanged += registerAudioTrack; + + // If the track has changed prior to this being called, let's register it + if (Value != Default) + registerAudioTrack(Value); } private void registerAudioTrack(WorkingBeatmap beatmap) @@ -46,17 +62,14 @@ namespace osu.Game.Beatmaps lastBeatmap = beatmap; } + [NotNull] IGameBeatmap IGameBeatmap.GetBoundCopy() => GetBoundCopy(); /// /// Retrieve a new instance weakly bound to this . /// If you are further binding to events of the retrieved , ensure a local reference is held. /// - public new GameBeatmap GetBoundCopy() - { - var copy = new GameBeatmap(Default, audioManager); - copy.BindTo(this); - return copy; - } + [NotNull] + public abstract GameBeatmap GetBoundCopy(); } } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 97f7f5a21e..ff0488a0ae 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -64,7 +64,8 @@ namespace osu.Game protected override Container Content => content; - protected GameBeatmap Beatmap; + private OsuGameBeatmap beatmap; + protected GameBeatmap Beatmap => beatmap; private Bindable fpsDisplayVisible; @@ -156,15 +157,15 @@ namespace osu.Game Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera-Light")); var defaultBeatmap = new DummyWorkingBeatmap(this); - Beatmap = new GameBeatmap(defaultBeatmap, Audio); + beatmap = new OsuGameBeatmap(defaultBeatmap, Audio); BeatmapManager.DefaultBeatmap = defaultBeatmap; // tracks play so loud our samples can't keep up. // this adds a global reduction of track volume for the time being. Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8)); - dependencies.Cache(Beatmap); - dependencies.CacheAs(Beatmap); + dependencies.CacheAs(beatmap); + dependencies.CacheAs(beatmap); FileStore.Cleanup(); @@ -235,5 +236,26 @@ namespace osu.Game } public string[] HandledExtensions => fileImporters.SelectMany(i => i.HandledExtensions).ToArray(); + + private class OsuGameBeatmap : GameBeatmap + { + public OsuGameBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) + : this(defaultValue) + { + RegisterAudioManager(audioManager); + } + + private OsuGameBeatmap(WorkingBeatmap defaultValue) + : base(defaultValue) + { + } + + public override GameBeatmap GetBoundCopy() + { + var copy = new OsuGameBeatmap(Default); + copy.BindTo(this); + return copy; + } + } } } diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index c337563920..ec1729ac5b 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -12,31 +12,35 @@ namespace osu.Game.Tests.Visual { public abstract class OsuTestCase : TestCase { - protected GameBeatmap Beatmap { get; private set; } + private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap()); + protected GameBeatmap Beatmap => beatmap; private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) { - // The beatmap is constructed here rather than load() because our children get dependencies injected before our load() runs - Beatmap = new GameBeatmap(new DummyWorkingBeatmap(), parent.Get()); - dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - dependencies.CacheAs(Beatmap); - dependencies.Cache(Beatmap); + dependencies.CacheAs(beatmap); + dependencies.CacheAs(beatmap); return dependencies; } + [BackgroundDependencyLoader] + private void load(AudioManager audioManager) + { + beatmap.SetAudioManager(audioManager); + } + protected override void Dispose(bool isDisposing) { base.Dispose(isDisposing); - if (Beatmap != null) + if (beatmap != null) { - Beatmap.Disabled = true; - Beatmap.Value.Track.Stop(); + beatmap.Disabled = true; + beatmap.Value.Track.Stop(); } } @@ -58,5 +62,22 @@ namespace osu.Game.Tests.Visual public void RunTestBlocking(TestCase test) => runner.RunTestBlocking(test); } + + private class OsuTestBeatmap : GameBeatmap + { + public OsuTestBeatmap(WorkingBeatmap defaultValue) + : base(defaultValue) + { + } + + public void SetAudioManager(AudioManager audioManager) => RegisterAudioManager(audioManager); + + public override GameBeatmap GetBoundCopy() + { + var copy = new OsuTestBeatmap(Default); + copy.BindTo(this); + return copy; + } + } } } From 2b3a6302706221035456fd37f4b2e57311a06109 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 28 May 2018 13:43:47 +0200 Subject: [PATCH 068/262] add OverlayActivation enum + fix Toolbar being toggleable when it shouldn't be able to + allow opening overlays in MenuState.Initial again --- .../Containers/OsuFocusedOverlayContainer.cs | 10 ++++-- osu.Game/OsuGame.cs | 22 ++++-------- osu.Game/Overlays/OverlayActivation.cs | 12 +++++++ osu.Game/Overlays/Toolbar/Toolbar.cs | 20 +++++++++++ osu.Game/Screens/Menu/ButtonSystem.cs | 20 ++++------- osu.Game/Screens/Menu/Disclaimer.cs | 4 ++- osu.Game/Screens/Menu/Intro.cs | 4 ++- osu.Game/Screens/Menu/MainMenu.cs | 6 +++- osu.Game/Screens/OsuScreen.cs | 35 +++++++++++++------ 9 files changed, 89 insertions(+), 44 deletions(-) create mode 100644 osu.Game/Overlays/OverlayActivation.cs diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 11a2034a8f..318632a403 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input; using OpenTK; using osu.Framework.Configuration; +using osu.Game.Overlays; namespace osu.Game.Graphics.Containers { @@ -16,13 +17,16 @@ namespace osu.Game.Graphics.Containers private SampleChannel samplePopIn; private SampleChannel samplePopOut; - private readonly BindableBool allowOpeningOverlays = new BindableBool(true); + /// + /// Defaults to so that the overlay works even if BDL couldn't pass an . + /// + private readonly Bindable allowOverlays = new Bindable(OverlayActivation.All); [BackgroundDependencyLoader(true)] private void load(OsuGame osuGame, AudioManager audio) { if (osuGame != null) - allowOpeningOverlays.BindTo(osuGame.AllowOpeningOverlays); + allowOverlays.BindTo(osuGame.AllowOverlays); samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in"); samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out"); @@ -52,7 +56,7 @@ namespace osu.Game.Graphics.Containers private void onStateChanged(Visibility visibility) { - if (allowOpeningOverlays) + if (allowOverlays == OverlayActivation.All) { switch (visibility) { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a43c1507b6..35f29c3fd1 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -77,8 +77,7 @@ namespace osu.Game public float ToolbarOffset => Toolbar.Position.Y + Toolbar.DrawHeight; - public readonly BindableBool HideOverlaysOnEnter = new BindableBool(); - public readonly BindableBool AllowOpeningOverlays = new BindableBool(true); + public readonly Bindable AllowOverlays = new Bindable(); private OsuScreen screenStack; @@ -368,20 +367,13 @@ namespace osu.Game settings.StateChanged += _ => updateScreenOffset(); notifications.StateChanged += _ => updateScreenOffset(); - notifications.Enabled.BindTo(AllowOpeningOverlays); + AllowOverlays.ValueChanged += state => notifications.Enabled.Value = state == OverlayActivation.All; + } - HideOverlaysOnEnter.ValueChanged += hide => - { - //central game screen change logic. - if (hide) - { - hideAllOverlays(); - musicController.State = Visibility.Hidden; - Toolbar.State = Visibility.Hidden; - } - else - Toolbar.State = Visibility.Visible; - }; + public void CloseAllOverlays() + { + hideAllOverlays(); + musicController.State = Visibility.Hidden; } private void forwardLoggedErrorsToNotifications() diff --git a/osu.Game/Overlays/OverlayActivation.cs b/osu.Game/Overlays/OverlayActivation.cs new file mode 100644 index 0000000000..735682ed57 --- /dev/null +++ b/osu.Game/Overlays/OverlayActivation.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Overlays +{ + public enum OverlayActivation + { + Disabled, + //UserTriggered, // currently there is no way to discern user action + All + } +} diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 424a457110..78739c03fe 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -10,6 +10,8 @@ using osu.Framework.Input; using osu.Game.Graphics; using OpenTK; using osu.Framework.Graphics.Shapes; +using osu.Framework.Allocation; +using osu.Framework.Configuration; namespace osu.Game.Overlays.Toolbar { @@ -29,6 +31,11 @@ namespace osu.Game.Overlays.Toolbar private const float alpha_hovering = 0.8f; private const float alpha_normal = 0.6f; + /// + /// Defaults to so that the overlay works even if BDL couldn't pass an . + /// + private readonly Bindable allowOverlays = new Bindable(OverlayActivation.All); + public Toolbar() { Children = new Drawable[] @@ -76,6 +83,19 @@ namespace osu.Game.Overlays.Toolbar Size = new Vector2(1, HEIGHT); } + [BackgroundDependencyLoader(true)] + private void load(OsuGame osuGame) + { + if (osuGame != null) + allowOverlays.BindTo(osuGame.AllowOverlays); + + StateChanged += visibility => + { + if (allowOverlays == OverlayActivation.Disabled) + State = Visibility.Hidden; + }; + } + public class ToolbarBackground : Container { private readonly Box solidBackground; diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 8b88204ed0..40e115364d 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -20,6 +20,7 @@ using osu.Game.Input.Bindings; using OpenTK; using OpenTK.Graphics; using OpenTK.Input; +using osu.Game.Overlays; namespace osu.Game.Screens.Menu { @@ -27,8 +28,7 @@ namespace osu.Game.Screens.Menu { public event Action StateChanged; - private readonly BindableBool hideOverlaysOnEnter = new BindableBool(); - private readonly BindableBool allowOpeningOverlays = new BindableBool(); + private readonly Bindable allowOverlays = new Bindable(); public Action OnEdit; public Action OnExit; @@ -137,10 +137,7 @@ namespace osu.Game.Screens.Menu private void load(AudioManager audio, OsuGame game) { if (game != null) - { - hideOverlaysOnEnter.BindTo(game.HideOverlaysOnEnter); - allowOpeningOverlays.BindTo(game.AllowOpeningOverlays); - } + allowOverlays.BindTo(game.AllowOverlays); sampleBack = audio.Sample.Get(@"Menu/button-back-select"); } @@ -332,19 +329,19 @@ namespace osu.Game.Screens.Menu case MenuState.Exit: case MenuState.Initial: logoTracking = false; + allowOverlays.Value = OverlayActivation.Disabled; logoDelayedAction = Scheduler.AddDelayed(() => { - hideOverlaysOnEnter.Value = true; - allowOpeningOverlays.Value = false; - logo.ClearTransforms(targetMember: nameof(Position)); logo.RelativePositionAxes = Axes.Both; logo.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo); logo.ScaleTo(1, 800, Easing.OutExpo); - }, 150); + if(state != MenuState.Exit) + allowOverlays.Value = OverlayActivation.All; + }, 150); break; case MenuState.TopLevel: case MenuState.Play: @@ -365,9 +362,6 @@ namespace osu.Game.Screens.Menu logoTracking = true; logo.Impact(); - - hideOverlaysOnEnter.Value = false; - allowOpeningOverlays.Value = true; }, 200); break; default: diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index b8cb7f2a4a..3671a54068 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -9,6 +9,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using OpenTK; using OpenTK.Graphics; +using osu.Game.Overlays; namespace osu.Game.Screens.Menu { @@ -19,7 +20,6 @@ namespace osu.Game.Screens.Menu private Color4 iconColour; protected override bool HideOverlaysOnEnter => true; - protected override bool AllowOpeningOverlays => false; public override bool CursorVisible => false; @@ -93,6 +93,8 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(intro = new Intro()); iconColour = colours.Yellow; + + AllowOverlays.Value = OverlayActivation.Disabled; } protected override void OnEntering(Screen last) diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index c174e2d470..aa89b86786 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -15,6 +15,7 @@ using osu.Game.IO.Archives; using osu.Game.Screens.Backgrounds; using OpenTK; using OpenTK.Graphics; +using osu.Game.Overlays; namespace osu.Game.Screens.Menu { @@ -32,7 +33,6 @@ namespace osu.Game.Screens.Menu private SampleChannel seeya; protected override bool HideOverlaysOnEnter => true; - protected override bool AllowOpeningOverlays => false; public override bool CursorVisible => false; @@ -77,6 +77,8 @@ namespace osu.Game.Screens.Menu welcome = audio.Sample.Get(@"welcome"); seeya = audio.Sample.Get(@"seeya"); + + AllowOverlays.Value = OverlayActivation.Disabled; } protected override void OnEntering(Screen last) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index d5f3b11467..728880b0f8 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -10,6 +10,7 @@ using osu.Framework.Input; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; +using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Charts; using osu.Game.Screens.Direct; @@ -25,7 +26,6 @@ namespace osu.Game.Screens.Menu private readonly ButtonSystem buttons; protected override bool HideOverlaysOnEnter => buttons.State == MenuState.Initial; - protected override bool AllowOpeningOverlays => buttons.State != MenuState.Initial; protected override bool AllowBackButton => buttons.State != MenuState.Initial; @@ -64,6 +64,8 @@ namespace osu.Game.Screens.Menu }, sideFlashes = new MenuSideFlashes(), }; + + buttons.StateChanged += state => UpdateOverlayStates?.Invoke(); } [BackgroundDependencyLoader(true)] @@ -78,6 +80,8 @@ namespace osu.Game.Screens.Menu } preloadSongSelect(); + + AllowOverlays.Value = OverlayActivation.Disabled; } private void preloadSongSelect() diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index cd9cbe119f..e48d72b6fc 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -18,6 +18,8 @@ using osu.Game.Rulesets; using osu.Game.Screens.Menu; using OpenTK; using OpenTK.Input; +using osu.Game.Overlays; +using osu.Framework.Graphics.Containers; namespace osu.Game.Screens { @@ -40,19 +42,23 @@ namespace osu.Game.Screens /// protected virtual BackgroundScreen CreateBackground() => null; - private readonly BindableBool hideOverlaysOnEnter = new BindableBool(); + private Action updateOverlayStates; /// - /// Whether overlays should be hidden when this screen is entered or resumed. + /// Allows manually updating visibility of all overlays if is not enough. + /// + protected Action UpdateOverlayStates => updateOverlayStates; + + /// + /// Whether all overlays should be hidden when this screen is entered or resumed. /// protected virtual bool HideOverlaysOnEnter => false; - private readonly BindableBool allowOpeningOverlays = new BindableBool(); - /// - /// Whether overlays should be able to be opened while this screen is active. + /// Whether overlays should be able to be opened. + /// It's bound at load which means changes at construction will potentially disappear. /// - protected virtual bool AllowOpeningOverlays => true; + protected readonly Bindable AllowOverlays = new Bindable(); /// /// Whether this allows the cursor to be displayed. @@ -103,8 +109,18 @@ namespace osu.Game.Screens if (osuGame != null) { Ruleset.BindTo(osuGame.Ruleset); - hideOverlaysOnEnter.BindTo(osuGame.HideOverlaysOnEnter); - allowOpeningOverlays.BindTo(osuGame.AllowOpeningOverlays); + AllowOverlays.BindTo(osuGame.AllowOverlays); + + updateOverlayStates = () => + { + if (HideOverlaysOnEnter) + { + osuGame.CloseAllOverlays(); + osuGame.Toolbar.State = Visibility.Hidden; + } + else + osuGame.Toolbar.State = Visibility.Visible; + }; } sampleExit = audio.Sample.Get(@"UI/screen-back"); @@ -236,8 +252,7 @@ namespace osu.Game.Screens if (backgroundParallaxContainer != null) backgroundParallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * BackgroundParallaxAmount; - hideOverlaysOnEnter.Value = HideOverlaysOnEnter; - allowOpeningOverlays.Value = AllowOpeningOverlays; + updateOverlayStates?.Invoke(); } private void onExitingLogo() From 9497db0b0bb38e35c73f6ab6db54d9d09cfc22c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 May 2018 20:21:25 +0900 Subject: [PATCH 069/262] Add a delay before the loading logo is displayed --- osu.Game/Screens/Loader.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index fb5c5ca84b..28b139c9f9 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -36,7 +36,13 @@ namespace osu.Game.Screens logo.Position = new Vector2(-40); logo.Scale = new Vector2(0.2f); - logo.FadeInFromZero(5000, Easing.OutQuint); + logo.Delay(500).FadeInFromZero(1000, Easing.OutQuint); + } + + protected override void LogoSuspending(OsuLogo logo) + { + base.LogoSuspending(logo); + logo.FadeOut(logo.Alpha * 1000); } private OsuScreen loadScreen; @@ -63,12 +69,6 @@ namespace osu.Game.Screens Push(loadScreen); } - protected override void LogoSuspending(OsuLogo logo) - { - base.LogoSuspending(logo); - logo.FadeOut(100); - } - [BackgroundDependencyLoader] private void load(OsuGameBase game) { From 9ea6ab28ea45ce90de2471f22a1b20de8ce44b5b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 30 May 2018 20:21:53 +0900 Subject: [PATCH 070/262] Fix intro potentially starting out-of-sync due to logo's outward animation --- osu.Game/Screens/Menu/Intro.cs | 48 ++++++++++++++++------------------ 1 file changed, 23 insertions(+), 25 deletions(-) diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index c174e2d470..5aca184d24 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -79,31 +79,6 @@ namespace osu.Game.Screens.Menu seeya = audio.Sample.Get(@"seeya"); } - protected override void OnEntering(Screen last) - { - base.OnEntering(last); - - Game.Beatmap.Value = beatmap; - - if (menuVoice) - welcome.Play(); - - Scheduler.AddDelayed(delegate - { - // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu. - if (menuMusic) - track.Start(); - - LoadComponentAsync(mainMenu = new MainMenu()); - - Scheduler.AddDelayed(delegate - { - DidLoadMenu = true; - Push(mainMenu); - }, delay_step_one); - }, delay_step_two); - } - private const double delay_step_one = 2300; private const double delay_step_two = 600; @@ -113,6 +88,29 @@ namespace osu.Game.Screens.Menu { base.LogoArriving(logo, resuming); + if (!resuming) + { + Game.Beatmap.Value = beatmap; + + if (menuVoice) + welcome.Play(); + + Scheduler.AddDelayed(delegate + { + // Only start the current track if it is the menu music. A beatmap's track is started when entering the Main Manu. + if (menuMusic) + track.Start(); + + LoadComponentAsync(mainMenu = new MainMenu()); + + Scheduler.AddDelayed(delegate + { + DidLoadMenu = true; + Push(mainMenu); + }, delay_step_one); + }, delay_step_two); + } + logo.RelativePositionAxes = Axes.Both; logo.Colour = Color4.White; logo.Ripple = false; From c161d8247479f401b0719b029459a9107ef3705f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 May 2018 17:14:04 +0900 Subject: [PATCH 071/262] Reduce the length of the fadeout animation --- osu.Game/Screens/Loader.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index 28b139c9f9..c8a80d470b 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens protected override void LogoSuspending(OsuLogo logo) { base.LogoSuspending(logo); - logo.FadeOut(logo.Alpha * 1000); + logo.FadeOut(logo.Alpha * 400); } private OsuScreen loadScreen; From 7487c82ec151b2b3a9fffc7adc260f87794ce182 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 May 2018 17:14:47 +0900 Subject: [PATCH 072/262] Stop the logo from beating --- osu.Game/Screens/Loader.cs | 1 + osu.Game/Screens/Menu/OsuLogo.cs | 4 ++++ osu.Game/Screens/OsuScreen.cs | 1 + 3 files changed, 6 insertions(+) diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index c8a80d470b..b8c1c31b8c 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -30,6 +30,7 @@ namespace osu.Game.Screens { base.LogoArriving(logo, resuming); + logo.BeatMatching = false; logo.Triangles = false; logo.Origin = Anchor.BottomRight; logo.Anchor = Anchor.BottomRight; diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 42a8dbd5da..16482b0e48 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -64,6 +64,8 @@ namespace osu.Game.Screens.Menu set { colourAndTriangles.FadeTo(value ? 1 : 0, transition_length, Easing.OutQuint); } } + public bool BeatMatching = true; + public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => logoContainer.ReceiveMouseInputAt(screenSpacePos); public bool Ripple @@ -264,6 +266,8 @@ namespace osu.Game.Screens.Menu { base.OnNewBeat(beatIndex, timingPoint, effectPoint, amplitudes); + if (!BeatMatching) return; + lastBeatIndex = beatIndex; var beatLength = timingPoint.BeatLength; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index db9807b9ab..7f68e5144b 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -225,6 +225,7 @@ namespace osu.Game.Screens logo.Anchor = Anchor.TopLeft; logo.Origin = Anchor.Centre; logo.RelativePositionAxes = Axes.None; + logo.BeatMatching = true; logo.Triangles = true; logo.Ripple = true; } From dfbcf4d7b7df2cde7194ea952a2eec221b81cd87 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 May 2018 17:29:59 +0900 Subject: [PATCH 073/262] Add tests --- .../Visual/TestCaseLoaderAnimation.cs | 101 ++++++++++++++++++ osu.Game/Screens/Loader.cs | 4 +- 2 files changed, 104 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs diff --git a/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs b/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs new file mode 100644 index 0000000000..066efb5116 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs @@ -0,0 +1,101 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Threading; +using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Game.Screens; +using osu.Game.Screens.Menu; +using OpenTK.Graphics; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseLoaderAnimation : OsuTestCase + { + private TestLoader loader; + + public TestCaseLoaderAnimation() + { + bool logoVisible = false; + + AddStep("almost instant display", () => Child = loader = new TestLoader(0.25f)); + AddUntilStep(() => + { + logoVisible = loader.Logo.Alpha > 0; + return !loader.IsCurrentScreen; + }, "loaded"); + AddAssert("logo not visible", () => !logoVisible); + + AddStep("short load", () => Child = loader = new TestLoader(0.8f)); + AddUntilStep(() => + { + logoVisible = loader.Logo.Alpha > 0; + return !loader.IsCurrentScreen; + }, "loaded"); + AddAssert("logo visible", () => logoVisible); + AddUntilStep(() => loader.Logo.Alpha == 0, "logo gone"); + + AddStep("longer load", () => Child = loader = new TestLoader(1.4f)); + AddUntilStep(() => + { + logoVisible = loader.Logo.Alpha > 0; + return !loader.IsCurrentScreen; + }, "loaded"); + AddAssert("logo visible", () => logoVisible); + AddUntilStep(() => loader.Logo.Alpha == 0, "logo gone"); + } + + private class TestLoader : Loader + { + private readonly float secondsDelay; + + public OsuLogo Logo; + + public TestLoader(float secondsDelay) + { + this.secondsDelay = secondsDelay; + } + + protected override void LogoArriving(OsuLogo logo, bool resuming) + { + Logo = logo; + base.LogoArriving(logo, resuming); + } + + protected override OsuScreen CreateLoadableScreen() => new TestScreen(secondsDelay); + + private class TestScreen : OsuScreen + { + private readonly float secondsDelay; + + public TestScreen(float secondsDelay) + { + this.secondsDelay = secondsDelay; + + Child = new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.DarkSlateGray, + Alpha = 0, + }; + } + + [BackgroundDependencyLoader] + private void load() + { + Thread.Sleep((int)(secondsDelay * 1000)); + } + + protected override void LogoArriving(OsuLogo logo, bool resuming) + { + base.LogoArriving(logo, resuming); + + Child.FadeInFromZero(200); + } + } + } + } +} diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index b8c1c31b8c..6335700a8f 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.cs @@ -49,12 +49,14 @@ namespace osu.Game.Screens private OsuScreen loadScreen; private ShaderPrecompiler precompiler; + protected virtual OsuScreen CreateLoadableScreen() => showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro(); + protected override void OnEntering(Screen last) { base.OnEntering(last); LoadComponentAsync(precompiler = new ShaderPrecompiler(loadIfReady), Add); - LoadComponentAsync(loadScreen = showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro(), s => loadIfReady()); + LoadComponentAsync(loadScreen = CreateLoadableScreen(), s => loadIfReady()); } private void loadIfReady() From 4eb7a349442680ace0fb534b4f8bf5a03903c1b0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 30 May 2018 21:49:49 +0900 Subject: [PATCH 074/262] Always update children when ruleset input manager is updated --- osu.Game/Rulesets/UI/RulesetInputManager.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 58a66a5224..b35616985a 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -121,8 +121,6 @@ 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 b68a5f5eabb589b787a844d96d0606915f44d55d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 May 2018 20:07:44 +0900 Subject: [PATCH 075/262] Tidy up Loader logic --- osu.Game/Screens/Loader.cs | 36 ++++++++++++++++-------------------- 1 file changed, 16 insertions(+), 20 deletions(-) diff --git a/osu.Game/Screens/Loader.cs b/osu.Game/Screens/Loader.cs index 6335700a8f..c3b3e747fd 100644 --- a/osu.Game/Screens/Loader.cs +++ b/osu.Game/Screens/Loader.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.Collections.Generic; using System.Linq; using osu.Framework.Allocation; @@ -46,30 +45,32 @@ namespace osu.Game.Screens logo.FadeOut(logo.Alpha * 400); } - private OsuScreen loadScreen; + private OsuScreen loadableScreen; private ShaderPrecompiler precompiler; protected virtual OsuScreen CreateLoadableScreen() => showDisclaimer ? (OsuScreen)new Disclaimer() : new Intro(); + protected virtual ShaderPrecompiler CreateShaderPrecompiler() => new ShaderPrecompiler(); + protected override void OnEntering(Screen last) { base.OnEntering(last); - LoadComponentAsync(precompiler = new ShaderPrecompiler(loadIfReady), Add); - LoadComponentAsync(loadScreen = CreateLoadableScreen(), s => loadIfReady()); + LoadComponentAsync(precompiler = CreateShaderPrecompiler(), Add); + LoadComponentAsync(loadableScreen = CreateLoadableScreen()); + + checkIfLoaded(); } - private void loadIfReady() + private void checkIfLoaded() { - if (ChildScreen == loadScreen) return; - - if (loadScreen.LoadState != LoadState.Ready) + if (loadableScreen.LoadState != LoadState.Ready || !precompiler.FinishedCompiling) + { + Schedule(checkIfLoaded); return; + } - if (!precompiler.FinishedCompiling) - return; - - Push(loadScreen); + Push(loadableScreen); } [BackgroundDependencyLoader] @@ -83,16 +84,10 @@ namespace osu.Game.Screens /// public class ShaderPrecompiler : Drawable { - private readonly Action onLoaded; private readonly List loadTargets = new List(); public bool FinishedCompiling { get; private set; } - public ShaderPrecompiler(Action onLoaded) - { - this.onLoaded = onLoaded; - } - [BackgroundDependencyLoader] private void load(ShaderManager manager) { @@ -106,16 +101,17 @@ namespace osu.Game.Screens loadTargets.Add(manager.Load(VertexShaderDescriptor.TEXTURE_3, FragmentShaderDescriptor.TEXTURE)); } + protected virtual bool AllLoaded => loadTargets.All(s => s.Loaded); + protected override void Update() { base.Update(); // if our target is null we are done. - if (loadTargets.All(s => s.Loaded)) + if (AllLoaded) { FinishedCompiling = true; Expire(); - onLoaded?.Invoke(); } } } From a6f2561be83855dd1075495cc8a44cf5bb173c70 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 31 May 2018 20:07:55 +0900 Subject: [PATCH 076/262] Fix automated testing --- .../Visual/TestCaseLoaderAnimation.cs | 76 +++++++++++-------- 1 file changed, 45 insertions(+), 31 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs b/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs index 066efb5116..600784f8db 100644 --- a/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs +++ b/osu.Game.Tests/Visual/TestCaseLoaderAnimation.cs @@ -1,9 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Threading; using NUnit.Framework; -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Screens; @@ -17,46 +15,53 @@ namespace osu.Game.Tests.Visual { private TestLoader loader; - public TestCaseLoaderAnimation() + protected override void LoadComplete() { - bool logoVisible = false; + base.LoadComplete(); - AddStep("almost instant display", () => Child = loader = new TestLoader(0.25f)); + // required to preload the logo in a headless run (so it doesn't delay the loading itself). + Add(new OsuLogo()); + + bool logoVisible = false; + AddStep("almost instant display", () => Child = loader = new TestLoader(250)); AddUntilStep(() => { - logoVisible = loader.Logo.Alpha > 0; - return !loader.IsCurrentScreen; + logoVisible = loader.Logo?.Alpha > 0; + return loader.Logo != null && loader.ScreenLoaded; }, "loaded"); AddAssert("logo not visible", () => !logoVisible); - AddStep("short load", () => Child = loader = new TestLoader(0.8f)); + AddStep("short load", () => Child = loader = new TestLoader(800)); AddUntilStep(() => { - logoVisible = loader.Logo.Alpha > 0; - return !loader.IsCurrentScreen; + logoVisible = loader.Logo?.Alpha > 0; + return loader.Logo != null && loader.ScreenLoaded; }, "loaded"); AddAssert("logo visible", () => logoVisible); - AddUntilStep(() => loader.Logo.Alpha == 0, "logo gone"); + AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone"); - AddStep("longer load", () => Child = loader = new TestLoader(1.4f)); + AddStep("longer load", () => Child = loader = new TestLoader(1400)); AddUntilStep(() => { - logoVisible = loader.Logo.Alpha > 0; - return !loader.IsCurrentScreen; + logoVisible = loader.Logo?.Alpha > 0; + return loader.Logo != null && loader.ScreenLoaded; }, "loaded"); AddAssert("logo visible", () => logoVisible); - AddUntilStep(() => loader.Logo.Alpha == 0, "logo gone"); + AddUntilStep(() => loader.Logo?.Alpha == 0, "logo gone"); } private class TestLoader : Loader { - private readonly float secondsDelay; + private readonly double delay; public OsuLogo Logo; + private TestScreen screen; - public TestLoader(float secondsDelay) + public bool ScreenLoaded => screen.IsCurrentScreen; + + public TestLoader(double delay) { - this.secondsDelay = secondsDelay; + this.delay = delay; } protected override void LogoArriving(OsuLogo logo, bool resuming) @@ -65,16 +70,32 @@ namespace osu.Game.Tests.Visual base.LogoArriving(logo, resuming); } - protected override OsuScreen CreateLoadableScreen() => new TestScreen(secondsDelay); + protected override OsuScreen CreateLoadableScreen() => screen = new TestScreen(); + protected override ShaderPrecompiler CreateShaderPrecompiler() => new TestShaderPrecompiler(delay); + + private class TestShaderPrecompiler : ShaderPrecompiler + { + private readonly double delay; + private double startTime; + + public TestShaderPrecompiler(double delay) + { + this.delay = delay; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + startTime = Time.Current; + } + + protected override bool AllLoaded => Time.Current > startTime + delay; + } private class TestScreen : OsuScreen { - private readonly float secondsDelay; - - public TestScreen(float secondsDelay) + public TestScreen() { - this.secondsDelay = secondsDelay; - Child = new Box { RelativeSizeAxes = Axes.Both, @@ -83,16 +104,9 @@ namespace osu.Game.Tests.Visual }; } - [BackgroundDependencyLoader] - private void load() - { - Thread.Sleep((int)(secondsDelay * 1000)); - } - protected override void LogoArriving(OsuLogo logo, bool resuming) { base.LogoArriving(logo, resuming); - Child.FadeInFromZero(200); } } From b4d621a2cb15f54ad4103bc17da019e0533db160 Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 31 May 2018 10:21:22 -0700 Subject: [PATCH 077/262] Add link colour to beatmap source --- osu.Game/Overlays/BeatmapSet/Info.cs | 4 ++-- osu.Game/Screens/Select/BeatmapDetails.cs | 7 ++----- 2 files changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index cd0b7386e8..e10294bbce 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -135,8 +135,8 @@ namespace osu.Game.Overlays.BeatmapSet private void load(OsuColour colours) { successRateBackground.Colour = colours.GrayE; - source.TextColour = description.TextColour = colours.Gray5; - tags.TextColour = colours.BlueDark; + description.TextColour = colours.Gray5; + source.TextColour = tags.TextColour = colours.BlueDark; updateDisplay(); } diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index ca36f94eda..69f3cf0ae6 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -124,10 +124,7 @@ namespace osu.Game.Screens.Select { TextColour = Color4.White.Opacity(0.75f), }, - source = new MetadataSection("Source") - { - TextColour = Color4.White.Opacity(0.75f), - }, + source = new MetadataSection("Source"), tags = new MetadataSection("Tags"), }, }, @@ -167,7 +164,7 @@ namespace osu.Game.Screens.Select private void load(OsuColour colours, APIAccess api) { this.api = api; - tags.TextColour = colours.Yellow; + source.TextColour = tags.TextColour = colours.Yellow; } protected override void UpdateAfterChildren() From 8dd36ee1a98a54ccf4ede99a4f829b1fc6b2ed19 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 1 Jun 2018 06:08:57 -0300 Subject: [PATCH 078/262] Default Max to null in ParticipantCount. --- osu.Game/Screens/Multi/Components/ParticipantCount.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Multi/Components/ParticipantCount.cs b/osu.Game/Screens/Multi/Components/ParticipantCount.cs index e47a529ff8..2e9183d047 100644 --- a/osu.Game/Screens/Multi/Components/ParticipantCount.cs +++ b/osu.Game/Screens/Multi/Components/ParticipantCount.cs @@ -62,6 +62,8 @@ namespace osu.Game.Screens.Multi.Components Font = @"Exo2.0-Light" }, }; + + Max = null; } } } From 5c2a2e394e2bff3b8a2a014c75c26218822423e2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 1 Jun 2018 18:03:16 +0900 Subject: [PATCH 079/262] Fix incorrect async logic in BeatmapInfoWedge Closes #2653. Alternative to #2657. --- .../Visual/TestCaseBeatmapInfoWedge.cs | 6 +- osu.Game/Screens/Select/BeatmapInfoWedge.cs | 66 +++++++++++-------- osu.Game/Screens/Select/SongSelect.cs | 2 +- 3 files changed, 42 insertions(+), 32 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs index 0d3e08154f..996c3b8695 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapInfoWedge.cs @@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual AddStep("show", () => { infoWedge.State = Visibility.Visible; - infoWedge.UpdateBeatmap(beatmap); + infoWedge.Beatmap = beatmap; }); // select part is redundant, but wait for load isn't @@ -133,7 +133,7 @@ namespace osu.Game.Tests.Visual AddStep($"select {b.Metadata.Title} beatmap", () => { infoBefore = infoWedge.Info; - infoWedge.UpdateBeatmap(beatmap.Value = new TestWorkingBeatmap(b)); + infoWedge.Beatmap = beatmap.Value = new TestWorkingBeatmap(b); }); AddUntilStep(() => infoWedge.Info != infoBefore, "wait for async load"); @@ -144,7 +144,7 @@ namespace osu.Game.Tests.Visual AddStep("select null beatmap", () => { beatmap.Value = beatmap.Default; - infoWedge.UpdateBeatmap(beatmap); + infoWedge.Beatmap = beatmap; }); } diff --git a/osu.Game/Screens/Select/BeatmapInfoWedge.cs b/osu.Game/Screens/Select/BeatmapInfoWedge.cs index 97f6371cb2..7950018554 100644 --- a/osu.Game/Screens/Select/BeatmapInfoWedge.cs +++ b/osu.Game/Screens/Select/BeatmapInfoWedge.cs @@ -57,7 +57,7 @@ namespace osu.Game.Screens.Select { if (osuGame != null) ruleset.BindTo(osuGame.Ruleset); - ruleset.ValueChanged += updateRuleset; + ruleset.ValueChanged += _ => updateDisplay(); } protected override bool BlockPassThroughMouse => false; @@ -78,66 +78,76 @@ namespace osu.Game.Screens.Select private WorkingBeatmap beatmap; - public void UpdateBeatmap(WorkingBeatmap beatmap) + public WorkingBeatmap Beatmap { - this.beatmap = beatmap; - loadBeatmap(); + get => beatmap; + set + { + if (beatmap == value) return; + + beatmap = value; + updateDisplay(); + } } - private void updateRuleset(RulesetInfo ruleset) => loadBeatmap(); + private BufferedWedgeInfo loadingInfo; - private void loadBeatmap() + private void updateDisplay() { - void updateState() + void removeOldInfo() { State = beatmap == null ? Visibility.Hidden : Visibility.Visible; Info?.FadeOut(250); Info?.Expire(); + Info = null; } if (beatmap == null) { - updateState(); + removeOldInfo(); return; } - LoadComponentAsync(new BufferedWedgeInfo(beatmap, ruleset.Value) + LoadComponentAsync(loadingInfo = new BufferedWedgeInfo(beatmap, ruleset.Value) { Shear = -Shear, - Depth = Info?.Depth + 1 ?? 0, - }, newInfo => + Depth = Info?.Depth + 1 ?? 0 + }, loaded => { - updateState(); - Add(Info = newInfo); + // ensure we are the most recent loaded wedge. + if (loaded != loadingInfo) return; + + removeOldInfo(); + Add(Info = loaded); }); } public class BufferedWedgeInfo : BufferedContainer { - private readonly WorkingBeatmap working; public OsuSpriteText VersionLabel { get; private set; } public OsuSpriteText TitleLabel { get; private set; } public OsuSpriteText ArtistLabel { get; private set; } public FillFlowContainer MapperContainer { get; private set; } public FillFlowContainer InfoLabelContainer { get; private set; } + private UnicodeBindableString titleBinding; private UnicodeBindableString artistBinding; + private readonly WorkingBeatmap beatmap; private readonly RulesetInfo ruleset; - public BufferedWedgeInfo(WorkingBeatmap working, RulesetInfo userRuleset) + public BufferedWedgeInfo(WorkingBeatmap beatmap, RulesetInfo userRuleset) { - this.working = working; - - ruleset = userRuleset ?? working.BeatmapInfo.Ruleset; + this.beatmap = beatmap; + ruleset = userRuleset ?? beatmap.BeatmapInfo.Ruleset; } [BackgroundDependencyLoader] private void load(LocalisationEngine localisation) { - var beatmapInfo = working.BeatmapInfo; - var metadata = beatmapInfo.Metadata ?? working.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); + var beatmapInfo = beatmap.BeatmapInfo; + var metadata = beatmapInfo.Metadata ?? beatmap.BeatmapSetInfo?.Metadata ?? new BeatmapMetadata(); PixelSnapping = true; CacheDrawnFrameBuffer = true; @@ -165,7 +175,7 @@ namespace osu.Game.Screens.Select Children = new[] { // Zoomed-in and cropped beatmap background - new BeatmapBackgroundSprite(working) + new BeatmapBackgroundSprite(beatmap) { RelativeSizeAxes = Axes.Both, Anchor = Anchor.Centre, @@ -248,27 +258,27 @@ namespace osu.Game.Screens.Select private InfoLabel[] getInfoLabels() { - var beatmap = working.Beatmap; + var b = beatmap.Beatmap; List labels = new List(); - if (beatmap?.HitObjects?.Any() == true) + if (b?.HitObjects?.Any() == true) { - HitObject lastObject = beatmap.HitObjects.LastOrDefault(); + HitObject lastObject = b.HitObjects.LastOrDefault(); double endTime = (lastObject as IHasEndTime)?.EndTime ?? lastObject?.StartTime ?? 0; labels.Add(new InfoLabel(new BeatmapStatistic { Name = "Length", Icon = FontAwesome.fa_clock_o, - Content = TimeSpan.FromMilliseconds(endTime - beatmap.HitObjects.First().StartTime).ToString(@"m\:ss"), + Content = TimeSpan.FromMilliseconds(endTime - b.HitObjects.First().StartTime).ToString(@"m\:ss"), })); labels.Add(new InfoLabel(new BeatmapStatistic { Name = "BPM", Icon = FontAwesome.fa_circle, - Content = getBPMRange(beatmap), + Content = getBPMRange(b), })); IBeatmap playableBeatmap; @@ -276,12 +286,12 @@ namespace osu.Game.Screens.Select try { // Try to get the beatmap with the user's ruleset - playableBeatmap = working.GetPlayableBeatmap(ruleset); + playableBeatmap = beatmap.GetPlayableBeatmap(ruleset); } catch (BeatmapInvalidForRulesetException) { // Can't be converted to the user's ruleset, so use the beatmap's own ruleset - playableBeatmap = working.GetPlayableBeatmap(working.BeatmapInfo.Ruleset); + playableBeatmap = beatmap.GetPlayableBeatmap(beatmap.BeatmapInfo.Ruleset); } labels.AddRange(playableBeatmap.GetStatistics().Select(s => new InfoLabel(s))); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index e1271aebc4..41ba38cb0f 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -430,7 +430,7 @@ namespace osu.Game.Screens.Select backgroundModeBeatmap.FadeTo(1, 250); } - beatmapInfoWedge.UpdateBeatmap(beatmap); + beatmapInfoWedge.Beatmap = beatmap; } private void ensurePlayingSelected(bool preview = false) From cc32adf51fb008e5e9573397c5c320cb8e3ea075 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Fri, 1 Jun 2018 14:28:24 -0300 Subject: [PATCH 080/262] Move max text updating into updateMax. --- .../Multi/Components/ParticipantCount.cs | 38 ++++++++++++------- 1 file changed, 24 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Multi/Components/ParticipantCount.cs b/osu.Game/Screens/Multi/Components/ParticipantCount.cs index 2e9183d047..e7183cbd92 100644 --- a/osu.Game/Screens/Multi/Components/ParticipantCount.cs +++ b/osu.Game/Screens/Multi/Components/ParticipantCount.cs @@ -12,28 +12,23 @@ namespace osu.Game.Screens.Multi.Components private const float text_size = 30; private const float transition_duration = 100; - private readonly OsuSpriteText count, slash, max; + private readonly OsuSpriteText count, slash, maxText; public int Count { set => count.Text = value.ToString(); } + private int? max; public int? Max { + get => max; set { - if (value == null) - { - slash.FadeOut(transition_duration); - max.FadeOut(transition_duration); - } - else - { - slash.FadeIn(transition_duration); - max.Text = value.ToString(); - max.FadeIn(transition_duration); - } + if (value == max) return; + max = value; + + updateMax(); } } @@ -56,14 +51,29 @@ namespace osu.Game.Screens.Multi.Components TextSize = text_size, Font = @"Exo2.0-Light" }, - max = new OsuSpriteText + maxText = new OsuSpriteText { TextSize = text_size, Font = @"Exo2.0-Light" }, }; - Max = null; + updateMax(); + } + + private void updateMax() + { + if (Max == null) + { + slash.FadeOut(transition_duration); + maxText.FadeOut(transition_duration); + } + else + { + slash.FadeIn(transition_duration); + maxText.Text = Max.ToString(); + maxText.FadeIn(transition_duration); + } } } } From 5d1421c0e9b97a8d1bdbd4e422fddb6a6777dfc1 Mon Sep 17 00:00:00 2001 From: Joehu Date: Fri, 1 Jun 2018 15:31:25 -0700 Subject: [PATCH 081/262] Fix visual settings expand button colour --- .../Play/PlayerSettings/PlayerSettingsGroup.cs | 15 ++++++++++++--- 1 file changed, 12 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index 0ffcdf94a6..cdde11c5f8 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -50,11 +50,11 @@ namespace osu.Game.Screens.Play.PlayerSettings content.ResizeHeightTo(0, transition_duration, Easing.OutQuint); } - button.FadeColour(expanded ? buttonActiveColour : Color4.White, 200, Easing.OutQuint); + button.FadeColour(expanded ? expandedColour : Color4.White, 200, Easing.OutQuint); } } - private Color4 buttonActiveColour; + private Color4 expandedColour; protected PlayerSettingsGroup() { @@ -130,7 +130,16 @@ namespace osu.Game.Screens.Play.PlayerSettings [BackgroundDependencyLoader] private void load(OsuColour colours) { - button.Colour = buttonActiveColour = colours.Yellow; + if (expanded) + { + button.Colour = colours.Yellow; + } + else + { + button.Colour = Color4.White; + } + + expandedColour = colours.Yellow; } protected override Container Content => content; From 8d3de3affbba360fe7d8d755d8a71c07899dcd79 Mon Sep 17 00:00:00 2001 From: Joehu Date: Fri, 1 Jun 2018 15:58:05 -0700 Subject: [PATCH 082/262] Use '?:' expression instead --- .../Screens/Play/PlayerSettings/PlayerSettingsGroup.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index cdde11c5f8..967cfd7fa0 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -130,14 +130,7 @@ namespace osu.Game.Screens.Play.PlayerSettings [BackgroundDependencyLoader] private void load(OsuColour colours) { - if (expanded) - { - button.Colour = colours.Yellow; - } - else - { - button.Colour = Color4.White; - } + button.FadeColour(expanded ? colours.Yellow : Color4.White); expandedColour = colours.Yellow; } From a0c643fae50982f78040a64c219fe5fdb44bfa47 Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Sat, 2 Jun 2018 11:25:49 +0200 Subject: [PATCH 083/262] Fix SongProgressInfo timespan formatting --- osu.Game/Screens/Play/SongProgressInfo.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/SongProgressInfo.cs b/osu.Game/Screens/Play/SongProgressInfo.cs index b79c212ade..3156a646db 100644 --- a/osu.Game/Screens/Play/SongProgressInfo.cs +++ b/osu.Game/Screens/Play/SongProgressInfo.cs @@ -92,6 +92,6 @@ namespace osu.Game.Screens.Play } } - private string formatTime(TimeSpan timeSpan) => $"{(timeSpan < TimeSpan.Zero ? "-" : "")}{timeSpan.Duration().TotalMinutes:N0}:{timeSpan.Duration().Seconds:D2}"; + private string formatTime(TimeSpan timeSpan) => $"{(timeSpan < TimeSpan.Zero ? "-" : "")}{Math.Floor(timeSpan.Duration().TotalMinutes)}:{timeSpan.Duration().Seconds:D2}"; } } From d287e32fafb32f4d29817a4810f55643a8d870c3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 2 Jun 2018 22:20:17 +0900 Subject: [PATCH 084/262] Update project build configurations to target netcoreapp2.1 --- ...p2_0_.xml => VisualTests__netcoreapp2_1_.xml} | 6 +++--- ...tcoreapp2_0_.xml => osu___netcoreapp2_1_.xml} | 6 +++--- .vscode/launch.json | 16 ++++++++-------- .vscode/tasks.json | 10 +++++----- osu-framework | 2 +- osu.Desktop/osu.Desktop.csproj | 2 +- .../.vscode/launch.json | 8 ++++---- osu.Game.Rulesets.Catch.Tests/.vscode/tasks.json | 6 +++--- .../osu.Game.Rulesets.Catch.Tests.csproj | 2 +- .../.vscode/launch.json | 8 ++++---- osu.Game.Rulesets.Mania.Tests/.vscode/tasks.json | 6 +++--- .../osu.Game.Rulesets.Mania.Tests.csproj | 2 +- osu.Game.Rulesets.Osu.Tests/.vscode/launch.json | 8 ++++---- osu.Game.Rulesets.Osu.Tests/.vscode/tasks.json | 6 +++--- .../osu.Game.Rulesets.Osu.Tests.csproj | 2 +- .../.vscode/launch.json | 8 ++++---- osu.Game.Rulesets.Taiko.Tests/.vscode/tasks.json | 6 +++--- .../osu.Game.Rulesets.Taiko.Tests.csproj | 2 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- 19 files changed, 54 insertions(+), 54 deletions(-) rename .idea/.idea.osu/.idea/runConfigurations/{VisualTests__netcoreapp2_0_.xml => VisualTests__netcoreapp2_1_.xml} (82%) rename .idea/.idea.osu/.idea/runConfigurations/{osu___netcoreapp2_0_.xml => osu___netcoreapp2_1_.xml} (82%) diff --git a/.idea/.idea.osu/.idea/runConfigurations/VisualTests__netcoreapp2_0_.xml b/.idea/.idea.osu/.idea/runConfigurations/VisualTests__netcoreapp2_1_.xml similarity index 82% rename from .idea/.idea.osu/.idea/runConfigurations/VisualTests__netcoreapp2_0_.xml rename to .idea/.idea.osu/.idea/runConfigurations/VisualTests__netcoreapp2_1_.xml index 08b4e38667..2d3a848922 100644 --- a/.idea/.idea.osu/.idea/runConfigurations/VisualTests__netcoreapp2_0_.xml +++ b/.idea/.idea.osu/.idea/runConfigurations/VisualTests__netcoreapp2_1_.xml @@ -1,6 +1,6 @@ - - \ No newline at end of file diff --git a/.idea/.idea.osu/.idea/runConfigurations/osu___netcoreapp2_0_.xml b/.idea/.idea.osu/.idea/runConfigurations/osu___netcoreapp2_1_.xml similarity index 82% rename from .idea/.idea.osu/.idea/runConfigurations/osu___netcoreapp2_0_.xml rename to .idea/.idea.osu/.idea/runConfigurations/osu___netcoreapp2_1_.xml index 2f5c137631..36efe211c6 100644 --- a/.idea/.idea.osu/.idea/runConfigurations/osu___netcoreapp2_0_.xml +++ b/.idea/.idea.osu/.idea/runConfigurations/osu___netcoreapp2_1_.xml @@ -1,6 +1,6 @@ - - \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index 32c82685c0..b9bb75d5bb 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -58,12 +58,12 @@ "console": "internalConsole" }, { - "name": "VisualTests (Debug, netcoreapp2.0)", + "name": "VisualTests (Debug, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.0/osu.Game.Tests.dll" + "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build tests (Debug, dotnet)", @@ -71,12 +71,12 @@ "console": "internalConsole" }, { - "name": "VisualTests (Release, netcoreapp2.0)", + "name": "VisualTests (Release, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.0/osu.Game.Tests.dll" + "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1/osu.Game.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build tests (Release, dotnet)", @@ -84,12 +84,12 @@ "console": "internalConsole" }, { - "name": "osu! (Debug, netcoreapp2.0)", + "name": "osu! (Debug, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.0/osu!.dll", + "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll", ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build osu! (Debug, dotnet)", @@ -97,12 +97,12 @@ "console": "internalConsole" }, { - "name": "osu! (Release, netcoreapp2.0)", + "name": "osu! (Release, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.0/osu!.dll", + "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/osu!.dll", ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build osu! (Release, dotnet)", diff --git a/.vscode/tasks.json b/.vscode/tasks.json index 0908ff6108..bebad750ca 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -38,7 +38,7 @@ "build", "--no-restore", "osu.Desktop", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:GenerateFullPaths=true", "/m", "/verbosity:m" @@ -54,7 +54,7 @@ "build", "--no-restore", "osu.Desktop", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:Configuration=Release", "/p:GenerateFullPaths=true", "/m", @@ -71,7 +71,7 @@ "build", "--no-restore", "osu.Game.Tests", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:GenerateFullPaths=true", "/m", "/verbosity:m" @@ -87,7 +87,7 @@ "build", "--no-restore", "osu.Game.Tests", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:Configuration=Release", "/p:GenerateFullPaths=true", "/m", @@ -106,7 +106,7 @@ "problemMatcher": [] }, { - "label": "Restore (netcoreapp2.0)", + "label": "Restore (netcoreapp2.1)", "type": "shell", "command": "dotnet", "args": [ diff --git a/osu-framework b/osu-framework index 804a4b81b8..39aae99f5c 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 804a4b81b89cb4569af5221e6fa2296d559c28fb +Subproject commit 39aae99f5c21ac9c9f8003cb4dedea345c38c78c diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index af027da2fc..6b464ae4fe 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -1,7 +1,7 @@  - net471;netcoreapp2.0 + net471;netcoreapp2.1 WinExe AnyCPU true diff --git a/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json b/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json index eb80f4474c..c5005adfa5 100644 --- a/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json @@ -30,12 +30,12 @@ "console": "internalConsole" }, { - "name": "VisualTests (Debug, netcoreapp2.0)", + "name": "VisualTests (Debug, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Catch.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Debug, dotnet)", @@ -43,12 +43,12 @@ "console": "internalConsole" }, { - "name": "VisualTests (Release, netcoreapp2.0)", + "name": "VisualTests (Release, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Catch.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, dotnet)", diff --git a/osu.Game.Rulesets.Catch.Tests/.vscode/tasks.json b/osu.Game.Rulesets.Catch.Tests/.vscode/tasks.json index 41ae88f425..6c6d562512 100644 --- a/osu.Game.Rulesets.Catch.Tests/.vscode/tasks.json +++ b/osu.Game.Rulesets.Catch.Tests/.vscode/tasks.json @@ -40,7 +40,7 @@ "build", "--no-restore", "osu.Game.Rulesets.Catch.Tests.csproj", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:GenerateFullPaths=true", "/m", "/verbosity:m" @@ -56,7 +56,7 @@ "build", "--no-restore", "osu.Game.Rulesets.Catch.Tests.csproj", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:Configuration=Release", "/p:GenerateFullPaths=true", "/m", @@ -75,7 +75,7 @@ "problemMatcher": [] }, { - "label": "Restore (netcoreapp2.0)", + "label": "Restore (netcoreapp2.1)", "type": "shell", "command": "dotnet", "args": [ diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj index 3797edde61..93fa2c4d67 100644 --- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj +++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj @@ -2,7 +2,7 @@ WinExe - netcoreapp2.0;net471 + netcoreapp2.1;net471 diff --git a/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json b/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json index fceb403f30..637a5de1b5 100644 --- a/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json @@ -30,12 +30,12 @@ "console": "internalConsole" }, { - "name": "VisualTests (Debug, netcoreapp2.0)", + "name": "VisualTests (Debug, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Mania.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Debug, dotnet)", @@ -43,12 +43,12 @@ "console": "internalConsole" }, { - "name": "VisualTests (Release, netcoreapp2.0)", + "name": "VisualTests (Release, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Mania.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, dotnet)", diff --git a/osu.Game.Rulesets.Mania.Tests/.vscode/tasks.json b/osu.Game.Rulesets.Mania.Tests/.vscode/tasks.json index b04b068b0d..7fc2f7b2ef 100644 --- a/osu.Game.Rulesets.Mania.Tests/.vscode/tasks.json +++ b/osu.Game.Rulesets.Mania.Tests/.vscode/tasks.json @@ -40,7 +40,7 @@ "build", "--no-restore", "osu.Game.Rulesets.Mania.Tests.csproj", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:GenerateFullPaths=true", "/m", "/verbosity:m" @@ -56,7 +56,7 @@ "build", "--no-restore", "osu.Game.Rulesets.Mania.Tests.csproj", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:Configuration=Release", "/p:GenerateFullPaths=true", "/m", @@ -75,7 +75,7 @@ "problemMatcher": [] }, { - "label": "Restore (netcoreapp2.0)", + "label": "Restore (netcoreapp2.1)", "type": "shell", "command": "dotnet", "args": [ diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj index e90155568e..77504fdc3c 100644 --- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj +++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj @@ -2,7 +2,7 @@ WinExe - netcoreapp2.0;net471 + netcoreapp2.1;net471 diff --git a/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json b/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json index 714fb6db6f..65c801cef4 100644 --- a/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json @@ -30,12 +30,12 @@ "console": "internalConsole" }, { - "name": "VisualTests (Debug, netcoreapp2.0)", + "name": "VisualTests (Debug, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Osu.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Debug, dotnet)", @@ -43,12 +43,12 @@ "console": "internalConsole" }, { - "name": "VisualTests (Release, netcoreapp2.0)", + "name": "VisualTests (Release, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Osu.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, dotnet)", diff --git a/osu.Game.Rulesets.Osu.Tests/.vscode/tasks.json b/osu.Game.Rulesets.Osu.Tests/.vscode/tasks.json index 657fe07e1a..62cf51382f 100644 --- a/osu.Game.Rulesets.Osu.Tests/.vscode/tasks.json +++ b/osu.Game.Rulesets.Osu.Tests/.vscode/tasks.json @@ -40,7 +40,7 @@ "build", "--no-restore", "osu.Game.Rulesets.Osu.Tests.csproj", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:GenerateFullPaths=true", "/m", "/verbosity:m" @@ -56,7 +56,7 @@ "build", "--no-restore", "osu.Game.Rulesets.Osu.Tests.csproj", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:Configuration=Release", "/p:GenerateFullPaths=true", "/m", @@ -75,7 +75,7 @@ "problemMatcher": [] }, { - "label": "Restore (netcoreapp2.0)", + "label": "Restore (netcoreapp2.1)", "type": "shell", "command": "dotnet", "args": [ diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj index 1695ceacee..c5d9b26145 100644 --- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj +++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj @@ -2,7 +2,7 @@ WinExe - netcoreapp2.0;net471 + netcoreapp2.1;net471 diff --git a/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json b/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json index e1df54e99b..dbb1ab28e2 100644 --- a/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json @@ -30,12 +30,12 @@ "console": "internalConsole" }, { - "name": "VisualTests (Debug, netcoreapp2.0)", + "name": "VisualTests (Debug, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Taiko.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Debug, dotnet)", @@ -43,12 +43,12 @@ "console": "internalConsole" }, { - "name": "VisualTests (Release, netcoreapp2.0)", + "name": "VisualTests (Release, netcoreapp2.1)", "type": "coreclr", "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.0/osu.Game.Rulesets.Taiko.Tests.dll" + "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, dotnet)", diff --git a/osu.Game.Rulesets.Taiko.Tests/.vscode/tasks.json b/osu.Game.Rulesets.Taiko.Tests/.vscode/tasks.json index 8bdbcd8e8e..7c8beed00f 100644 --- a/osu.Game.Rulesets.Taiko.Tests/.vscode/tasks.json +++ b/osu.Game.Rulesets.Taiko.Tests/.vscode/tasks.json @@ -40,7 +40,7 @@ "build", "--no-restore", "osu.Game.Rulesets.Taiko.Tests.csproj", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:GenerateFullPaths=true", "/m", "/verbosity:m" @@ -56,7 +56,7 @@ "build", "--no-restore", "osu.Game.Rulesets.Taiko.Tests.csproj", - "/p:TargetFramework=netcoreapp2.0", + "/p:TargetFramework=netcoreapp2.1", "/p:Configuration=Release", "/p:GenerateFullPaths=true", "/m", @@ -75,7 +75,7 @@ "problemMatcher": [] }, { - "label": "Restore (netcoreapp2.0)", + "label": "Restore (netcoreapp2.1)", "type": "shell", "command": "dotnet", "args": [ diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj index 1221584a2b..dea34d25e7 100644 --- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj +++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj @@ -2,7 +2,7 @@ WinExe - netcoreapp2.0;net471 + netcoreapp2.1;net471 diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 057c2c2de1..532915100b 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -2,7 +2,7 @@ WinExe - netcoreapp2.0;net471 + netcoreapp2.1;net471 From 6781807e23ab428d6b0e849048f597ae3fdb77e8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 3 Jun 2018 00:28:10 +0900 Subject: [PATCH 085/262] Remove unnecessary EF tools references --- osu.Desktop/osu.Desktop.csproj | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 6b464ae4fe..b8efd76506 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -20,8 +20,6 @@ osu.Desktop.Program - - @@ -38,8 +36,4 @@ - - - - \ No newline at end of file From 88628812c64da355b1008282ba7375e96e795239 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 3 Jun 2018 00:28:29 +0900 Subject: [PATCH 086/262] Logexceptions when loading ruleset DLLs --- osu.Game/Rulesets/RulesetStore.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index 1847b63658..8d267f48e9 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using System.Reflection; +using osu.Framework.Logging; using osu.Game.Database; namespace osu.Game.Rulesets @@ -114,8 +115,9 @@ namespace osu.Game.Rulesets var assembly = Assembly.LoadFrom(file); loaded_assemblies[assembly] = assembly.GetTypes().First(t => t.IsPublic && t.IsSubclassOf(typeof(Ruleset))); } - catch (Exception) + catch (Exception e) { + Logger.Error(e, "Failed to load ruleset"); } } } From 64eda2754724e473597dc2b252fb9be2933a3fbe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 3 Jun 2018 02:28:11 +0900 Subject: [PATCH 087/262] Update framework --- osu-framework | 2 +- osu.Game/Overlays/KeyBinding/KeyBindingRow.cs | 4 ++-- osu.Game/Screens/Edit/Editor.cs | 4 ++-- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 6 +++--- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Tests/Visual/EditorClockTestCase.cs | 4 ++-- 6 files changed, 11 insertions(+), 11 deletions(-) diff --git a/osu-framework b/osu-framework index 39aae99f5c..b963ce8250 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 39aae99f5c21ac9c9f8003cb4dedea345c38c78c +Subproject commit b963ce82505bc953db0a0763679e1ec80a060811 diff --git a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs index 7406a9ec4f..ffe1560627 100644 --- a/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs +++ b/osu.Game/Overlays/KeyBinding/KeyBindingRow.cs @@ -180,7 +180,7 @@ namespace osu.Game.Overlays.KeyBinding return true; } - protected override bool OnWheel(InputState state) + protected override bool OnScroll(InputState state) { if (HasFocus) { @@ -192,7 +192,7 @@ namespace osu.Game.Overlays.KeyBinding } } - return base.OnWheel(state); + return base.OnScroll(state); } protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) diff --git a/osu.Game/Screens/Edit/Editor.cs b/osu.Game/Screens/Edit/Editor.cs index be08fffc77..b71d3aee18 100644 --- a/osu.Game/Screens/Edit/Editor.cs +++ b/osu.Game/Screens/Edit/Editor.cs @@ -182,9 +182,9 @@ namespace osu.Game.Screens.Edit LoadComponentAsync(currentScreen, screenContainer.Add); } - protected override bool OnWheel(InputState state) + protected override bool OnScroll(InputState state) { - if (state.Mouse.WheelDelta > 0) + if (state.Mouse.ScrollDelta.X + state.Mouse.ScrollDelta.Y > 0) clock.SeekBackward(true); else clock.SeekForward(true); diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 83aa86ba61..2902e74e00 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -123,15 +123,15 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline /// private float? localZoomTarget; - protected override bool OnWheel(InputState state) + protected override bool OnScroll(InputState state) { if (!state.Keyboard.ControlPressed) - return base.OnWheel(state); + return base.OnScroll(state); relativeContentZoomTarget = Content.ToLocalSpace(state.Mouse.NativeState.Position).X / Content.DrawSize.X; localZoomTarget = ToLocalSpace(state.Mouse.NativeState.Position).X; - Zoom += state.Mouse.WheelDelta; + Zoom += state.Mouse.ScrollDelta.Y; return true; } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9985a24cab..c93e4b7b40 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -364,7 +364,7 @@ namespace osu.Game.Screens.Play Background?.FadeTo(1f, fade_out_duration); } - protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused; + protected override bool OnScroll(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused; private void initializeStoryboard(bool asyncLoad) { diff --git a/osu.Game/Tests/Visual/EditorClockTestCase.cs b/osu.Game/Tests/Visual/EditorClockTestCase.cs index 85d3684530..1ce7023be0 100644 --- a/osu.Game/Tests/Visual/EditorClockTestCase.cs +++ b/osu.Game/Tests/Visual/EditorClockTestCase.cs @@ -59,9 +59,9 @@ namespace osu.Game.Tests.Visual Clock.ProcessFrame(); } - protected override bool OnWheel(InputState state) + protected override bool OnScroll(InputState state) { - if (state.Mouse.WheelDelta > 0) + if (state.Mouse.ScrollDelta.Y > 0) Clock.SeekBackward(true); else Clock.SeekForward(true); From ea3d97a757ae48791bdb0acd53382a188442b9b2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 3 Jun 2018 02:36:56 +0900 Subject: [PATCH 088/262] Update appveyor to support netcore2.1 --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 69bc762f4c..314faa617a 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ clone_depth: 1 version: '{branch}-{build}' -image: Visual Studio 2017 +image: Visual Studio 2017 preview configuration: Debug cache: - C:\ProgramData\chocolatey\bin -> appveyor.yml From dc2a004c8741aa043ffa7c549d275dc5a8e65e47 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 2 Jun 2018 12:04:58 -0700 Subject: [PATCH 089/262] Remove link colours for all unlinked text --- osu.Game/Overlays/BeatmapSet/Info.cs | 3 +-- osu.Game/Screens/Select/BeatmapDetails.cs | 10 +++------- 2 files changed, 4 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index e10294bbce..35a66b1272 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -135,8 +135,7 @@ namespace osu.Game.Overlays.BeatmapSet private void load(OsuColour colours) { successRateBackground.Colour = colours.GrayE; - description.TextColour = colours.Gray5; - source.TextColour = tags.TextColour = colours.BlueDark; + description.TextColour = source.TextColour = tags.TextColour = colours.Gray5; updateDisplay(); } diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 69f3cf0ae6..013674b397 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -6,7 +6,6 @@ using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using System.Linq; @@ -120,10 +119,7 @@ namespace osu.Game.Screens.Select Margin = new MarginPadding { Top = spacing * 2 }, Children = new[] { - description = new MetadataSection("Description") - { - TextColour = Color4.White.Opacity(0.75f), - }, + description = new MetadataSection("Description"), source = new MetadataSection("Source"), tags = new MetadataSection("Tags"), }, @@ -161,10 +157,10 @@ namespace osu.Game.Screens.Select } [BackgroundDependencyLoader] - private void load(OsuColour colours, APIAccess api) + private void load(APIAccess api) { this.api = api; - source.TextColour = tags.TextColour = colours.Yellow; + description.TextColour = source.TextColour = tags.TextColour = Color4.White.Opacity(0.75f); } protected override void UpdateAfterChildren() From 0f13acf67e4af21539a04e7a265b1e0d0bacdbcf Mon Sep 17 00:00:00 2001 From: Joehu Date: Sat, 2 Jun 2018 12:52:31 -0700 Subject: [PATCH 090/262] Use updateExpanded method --- .../Screens/Play/PlayerSettings/PlayerSettingsGroup.cs | 8 +++++--- 1 file changed, 5 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs index 967cfd7fa0..cff3eca895 100644 --- a/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs +++ b/osu.Game/Screens/Play/PlayerSettings/PlayerSettingsGroup.cs @@ -50,7 +50,7 @@ namespace osu.Game.Screens.Play.PlayerSettings content.ResizeHeightTo(0, transition_duration, Easing.OutQuint); } - button.FadeColour(expanded ? expandedColour : Color4.White, 200, Easing.OutQuint); + updateExpanded(); } } @@ -130,11 +130,13 @@ namespace osu.Game.Screens.Play.PlayerSettings [BackgroundDependencyLoader] private void load(OsuColour colours) { - button.FadeColour(expanded ? colours.Yellow : Color4.White); - expandedColour = colours.Yellow; + + updateExpanded(); } + private void updateExpanded() => button.FadeColour(expanded ? expandedColour : Color4.White, 200, Easing.InOutQuint); + protected override Container Content => content; protected override bool OnHover(InputState state) => true; From 2ccffb9ac452b443c9cb09ccf44f158cd04031ee Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 28 May 2018 01:10:41 +0900 Subject: [PATCH 091/262] 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 645f6efce78edc8699f9d47443c86cdca3a3b1cf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 3 Jun 2018 13:01:52 +0900 Subject: [PATCH 092/262] Fix web request failures not being correctly handled at an APIRequest level --- osu.Game/Beatmaps/BeatmapManager.cs | 2 +- osu.Game/Online/API/APIRequest.cs | 1 + 2 files changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index efc0279aa0..806bcc4132 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -170,7 +170,7 @@ namespace osu.Game.Beatmaps { if (error is OperationCanceledException) return; - downloadNotification.State = ProgressNotificationState.Completed; + downloadNotification.State = ProgressNotificationState.Cancelled; Logger.Error(error, "Beatmap download failed!"); currentDownloads.Remove(request); }; diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index 9af142b9e8..dfd181b98a 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -73,6 +73,7 @@ namespace osu.Game.Online.API throw new TimeoutException(@"API request timeout hit"); WebRequest = CreateWebRequest(); + WebRequest.Failed += Fail; WebRequest.AllowRetryOnTimeout = false; WebRequest.AddHeader("Authorization", $"Bearer {api.AccessToken}"); From 707af0209732ef29de79d4417c2aab9892ff8f89 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sun, 3 Jun 2018 11:30:58 +0200 Subject: [PATCH 093/262] apply feedback -don't directly set AllowOverlay Bindable this should be done specifically where needed -remove AllowOverlay Bindable from ButtonSystem -remove unnecessary xmldoc --- .../Containers/OsuFocusedOverlayContainer.cs | 3 --- osu.Game/Overlays/Toolbar/Toolbar.cs | 3 --- osu.Game/Screens/Menu/ButtonSystem.cs | 13 +------------ osu.Game/Screens/Menu/Disclaimer.cs | 3 +-- osu.Game/Screens/Menu/Intro.cs | 3 +-- osu.Game/Screens/Menu/MainMenu.cs | 3 --- osu.Game/Screens/OsuScreen.cs | 11 +++++++---- 7 files changed, 10 insertions(+), 29 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 318632a403..e9c02e84ec 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -17,9 +17,6 @@ namespace osu.Game.Graphics.Containers private SampleChannel samplePopIn; private SampleChannel samplePopOut; - /// - /// Defaults to so that the overlay works even if BDL couldn't pass an . - /// private readonly Bindable allowOverlays = new Bindable(OverlayActivation.All); [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 78739c03fe..032ea01700 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -31,9 +31,6 @@ namespace osu.Game.Overlays.Toolbar private const float alpha_hovering = 0.8f; private const float alpha_normal = 0.6f; - /// - /// Defaults to so that the overlay works even if BDL couldn't pass an . - /// private readonly Bindable allowOverlays = new Bindable(OverlayActivation.All); public Toolbar() diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 40e115364d..bbbe918279 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -8,7 +8,6 @@ using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -20,7 +19,6 @@ using osu.Game.Input.Bindings; using OpenTK; using OpenTK.Graphics; using OpenTK.Input; -using osu.Game.Overlays; namespace osu.Game.Screens.Menu { @@ -28,8 +26,6 @@ namespace osu.Game.Screens.Menu { public event Action StateChanged; - private readonly Bindable allowOverlays = new Bindable(); - public Action OnEdit; public Action OnExit; public Action OnDirect; @@ -134,11 +130,8 @@ namespace osu.Game.Screens.Menu } [BackgroundDependencyLoader(true)] - private void load(AudioManager audio, OsuGame game) + private void load(AudioManager audio) { - if (game != null) - allowOverlays.BindTo(game.AllowOverlays); - sampleBack = audio.Sample.Get(@"Menu/button-back-select"); } @@ -329,7 +322,6 @@ namespace osu.Game.Screens.Menu case MenuState.Exit: case MenuState.Initial: logoTracking = false; - allowOverlays.Value = OverlayActivation.Disabled; logoDelayedAction = Scheduler.AddDelayed(() => { @@ -338,9 +330,6 @@ namespace osu.Game.Screens.Menu logo.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo); logo.ScaleTo(1, 800, Easing.OutExpo); - - if(state != MenuState.Exit) - allowOverlays.Value = OverlayActivation.All; }, 150); break; case MenuState.TopLevel: diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index 3671a54068..2436f0a940 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -20,6 +20,7 @@ namespace osu.Game.Screens.Menu private Color4 iconColour; protected override bool HideOverlaysOnEnter => true; + protected override OverlayActivation OverlayActivationLevel => OverlayActivation.Disabled; public override bool CursorVisible => false; @@ -93,8 +94,6 @@ namespace osu.Game.Screens.Menu LoadComponentAsync(intro = new Intro()); iconColour = colours.Yellow; - - AllowOverlays.Value = OverlayActivation.Disabled; } protected override void OnEntering(Screen last) diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index aa89b86786..494c92c698 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -33,6 +33,7 @@ namespace osu.Game.Screens.Menu private SampleChannel seeya; protected override bool HideOverlaysOnEnter => true; + protected override OverlayActivation OverlayActivationLevel => OverlayActivation.Disabled; public override bool CursorVisible => false; @@ -77,8 +78,6 @@ namespace osu.Game.Screens.Menu welcome = audio.Sample.Get(@"welcome"); seeya = audio.Sample.Get(@"seeya"); - - AllowOverlays.Value = OverlayActivation.Disabled; } protected override void OnEntering(Screen last) diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 728880b0f8..8eddaaee93 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -10,7 +10,6 @@ using osu.Framework.Input; using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Graphics.Containers; -using osu.Game.Overlays; using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Charts; using osu.Game.Screens.Direct; @@ -80,8 +79,6 @@ namespace osu.Game.Screens.Menu } preloadSongSelect(); - - AllowOverlays.Value = OverlayActivation.Disabled; } private void preloadSongSelect() diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index e48d72b6fc..0bff75f53b 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -54,11 +54,12 @@ namespace osu.Game.Screens /// protected virtual bool HideOverlaysOnEnter => false; + private readonly Bindable allowOverlays = new Bindable(); + /// - /// Whether overlays should be able to be opened. - /// It's bound at load which means changes at construction will potentially disappear. + /// Whether overlays should be able to be opened once this screen is entered or resumed. /// - protected readonly Bindable AllowOverlays = new Bindable(); + protected virtual OverlayActivation OverlayActivationLevel => OverlayActivation.All; /// /// Whether this allows the cursor to be displayed. @@ -109,7 +110,7 @@ namespace osu.Game.Screens if (osuGame != null) { Ruleset.BindTo(osuGame.Ruleset); - AllowOverlays.BindTo(osuGame.AllowOverlays); + allowOverlays.BindTo(osuGame.AllowOverlays); updateOverlayStates = () => { @@ -252,6 +253,8 @@ namespace osu.Game.Screens if (backgroundParallaxContainer != null) backgroundParallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * BackgroundParallaxAmount; + allowOverlays.Value = OverlayActivationLevel; + updateOverlayStates?.Invoke(); } From 2afe0feb245b34ca0c5862ec84dda8d12d44518c Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sun, 3 Jun 2018 12:02:43 +0200 Subject: [PATCH 094/262] remove white space I think --- osu.Game/Screens/OsuScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 8a36645145..e705b6f298 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -257,7 +257,7 @@ namespace osu.Game.Screens backgroundParallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * BackgroundParallaxAmount; allowOverlays.Value = OverlayActivationLevel; - + updateOverlayStates?.Invoke(); } From 3795a55808a2f4e591f9f0982efc2c53973b8ec1 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 3 Jun 2018 03:26:59 +0900 Subject: [PATCH 095/262] Fix menu flashes not extending to the edge of screen during parallax --- osu.Game/Screens/Menu/MenuSideFlashes.cs | 55 +++++++++++++----------- 1 file changed, 29 insertions(+), 26 deletions(-) diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs index fae3e72552..c321c98b24 100644 --- a/osu.Game/Screens/Menu/MenuSideFlashes.cs +++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs @@ -24,8 +24,8 @@ namespace osu.Game.Screens.Menu private readonly Bindable beatmap = new Bindable(); - private readonly Box leftBox; - private readonly Box rightBox; + private Box leftBox; + private Box rightBox; private const float amplitude_dead_zone = 0.25f; private const float alpha_multiplier = (1 - amplitude_dead_zone) / 0.55f; @@ -42,27 +42,6 @@ namespace osu.Game.Screens.Menu RelativeSizeAxes = Axes.Both; Anchor = Anchor.Centre; Origin = Anchor.Centre; - Children = new Drawable[] - { - leftBox = new Box - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Y, - Width = box_width, - Alpha = 0, - Blending = BlendingMode.Additive, - }, - rightBox = new Box - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - RelativeSizeAxes = Axes.Y, - Width = box_width, - Alpha = 0, - Blending = BlendingMode.Additive, - } - }; } [BackgroundDependencyLoader] @@ -72,10 +51,34 @@ namespace osu.Game.Screens.Menu // linear colour looks better in this case, so let's use it for now. Color4 gradientDark = colours.Blue.Opacity(0).ToLinear(); - Color4 gradientLight = colours.Blue.Opacity(0.3f).ToLinear(); + Color4 gradientLight = colours.Blue.Opacity(0.6f).ToLinear(); - leftBox.Colour = ColourInfo.GradientHorizontal(gradientLight, gradientDark); - rightBox.Colour = ColourInfo.GradientHorizontal(gradientDark, gradientLight); + Children = new Drawable[] + { + leftBox = new Box + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + RelativeSizeAxes = Axes.Y, + Width = box_width * 2, + // align off-screen to make sure our edges don't become visible during parallax. + X = -box_width, + Alpha = 0, + Blending = BlendingMode.Additive, + Colour = ColourInfo.GradientHorizontal(gradientLight, gradientDark) + }, + rightBox = new Box + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.Y, + Width = box_width * 2, + X = box_width, + Alpha = 0, + Blending = BlendingMode.Additive, + Colour = ColourInfo.GradientHorizontal(gradientDark, gradientLight) + } + }; } protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, TrackAmplitudes amplitudes) From ed1918cd43984e68e23da1bfd03f7f7375d1ba7f Mon Sep 17 00:00:00 2001 From: ekrctb Date: Sun, 3 Jun 2018 23:10:44 +0900 Subject: [PATCH 096/262] Wait for loading beatmaps --- .../Visual/TestCaseBeatmapCarousel.cs | 19 +++++++++++++------ 1 file changed, 13 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs index f819e882d9..4679fca855 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs @@ -65,11 +65,7 @@ namespace osu.Game.Tests.Visual carousel.SelectionChanged = s => currentSelection = s; - AddStep("Load Beatmaps", () => { carousel.BeatmapSets = beatmapSets; }); - - bool changed = false; - carousel.BeatmapSetsChanged = () => changed = true; - AddUntilStep(() => changed, "Wait for load"); + loadBeatmaps(beatmapSets); testTraversal(); testFiltering(); @@ -84,6 +80,17 @@ namespace osu.Game.Tests.Visual testCarouselRootIsRandom(); } + private void loadBeatmaps(List beatmapSets) + { + bool changed = false; + AddStep($"Load {beatmapSets.Count} Beatmaps", () => + { + carousel.BeatmapSetsChanged = () => changed = true; + carousel.BeatmapSets = beatmapSets; + }); + AddUntilStep(() => changed, "Wait for load"); + } + private void ensureRandomFetchSuccess() => AddAssert("ensure prev random fetch worked", () => selectedSets.Peek() == carousel.SelectedBeatmapSet); @@ -423,7 +430,7 @@ namespace osu.Game.Tests.Visual for (int i = 1; i <= 50; i++) beatmapSets.Add(createTestBeatmapSet(i)); - AddStep("Load 50 Beatmaps", () => { carousel.BeatmapSets = beatmapSets; }); + loadBeatmaps(beatmapSets); advanceSelection(direction: 1, diff: false); checkNonmatchingFilter(); checkNonmatchingFilter(); From 5c713ac2ababa6eb8f9b2db9ae8cb2a6d3cb9007 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sun, 3 Jun 2018 07:51:57 -0700 Subject: [PATCH 097/262] Use default colour in MetadataSection --- osu.Game/Overlays/BeatmapSet/Info.cs | 3 +-- osu.Game/Screens/Select/BeatmapDetails.cs | 7 ++++++- 2 files changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index 35a66b1272..e962c885ba 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -135,7 +135,6 @@ namespace osu.Game.Overlays.BeatmapSet private void load(OsuColour colours) { successRateBackground.Colour = colours.GrayE; - description.TextColour = source.TextColour = tags.TextColour = colours.Gray5; updateDisplay(); } @@ -194,7 +193,7 @@ namespace osu.Game.Overlays.BeatmapSet [BackgroundDependencyLoader] private void load(OsuColour colours) { - header.Colour = colours.Gray5; + header.Colour = textFlow.Colour = colours.Gray5; } } } diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 013674b397..68e308783e 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -160,7 +160,6 @@ namespace osu.Game.Screens.Select private void load(APIAccess api) { this.api = api; - description.TextColour = source.TextColour = tags.TextColour = Color4.White.Opacity(0.75f); } protected override void UpdateAfterChildren() @@ -374,6 +373,12 @@ namespace osu.Game.Screens.Select get { return textFlow.Colour; } set { textFlow.Colour = value; } } + + [BackgroundDependencyLoader] + private void load() + { + textFlow.Colour = Color4.White.Opacity(0.75f); + } } private class DimmedLoadingAnimation : VisibilityContainer From 7101533926317b26f22ef91f8bfba4d3273f3815 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sun, 3 Jun 2018 08:02:57 -0700 Subject: [PATCH 098/262] Remove 'description' field --- osu.Game/Overlays/BeatmapSet/Info.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index e962c885ba..53216ad666 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.BeatmapSet private const float metadata_width = 225; private const float spacing = 20; - private readonly MetadataSection description, source, tags; + private readonly MetadataSection source, tags; private readonly Box successRateBackground; private readonly SuccessRate successRate; @@ -83,7 +83,7 @@ namespace osu.Game.Overlays.BeatmapSet Child = new Container { RelativeSizeAxes = Axes.Both, - Child = description = new MetadataSection("Description"), + Child = new MetadataSection("Description"), }, }, new Container From 3a823d6c254c1f4560b0a29b0785697b03f31fce Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 4 Jun 2018 02:07:02 +0900 Subject: [PATCH 099/262] Fix multiple issues causing database reset to fail --- osu.Game/Database/DatabaseContextFactory.cs | 41 ++++++++++++++------- osu.Game/Database/OsuDbContext.cs | 17 +++++++-- osu.Game/OsuGameBase.cs | 4 +- 3 files changed, 44 insertions(+), 18 deletions(-) diff --git a/osu.Game/Database/DatabaseContextFactory.cs b/osu.Game/Database/DatabaseContextFactory.cs index a1d371f431..b5378b1311 100644 --- a/osu.Game/Database/DatabaseContextFactory.cs +++ b/osu.Game/Database/DatabaseContextFactory.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.Linq; using System.Threading; using Microsoft.EntityFrameworkCore.Storage; @@ -46,20 +47,35 @@ namespace osu.Game.Database public DatabaseWriteUsage GetForWrite(bool withTransaction = true) { Monitor.Enter(writeLock); + OsuDbContext context; - if (currentWriteTransaction == null && withTransaction) + try { - // this mitigates the fact that changes on tracked entities will not be rolled back with the transaction by ensuring write operations are always executed in isolated contexts. - // if this results in sub-optimal efficiency, we may need to look into removing Database-level transactions in favour of running SaveChanges where we currently commit the transaction. - if (threadContexts.IsValueCreated) - recycleThreadContexts(); + if (currentWriteTransaction == null && withTransaction) + { + // this mitigates the fact that changes on tracked entities will not be rolled back with the transaction by ensuring write operations are always executed in isolated contexts. + // if this results in sub-optimal efficiency, we may need to look into removing Database-level transactions in favour of running SaveChanges where we currently commit the transaction. + if (threadContexts.IsValueCreated) + recycleThreadContexts(); - currentWriteTransaction = threadContexts.Value.Database.BeginTransaction(); + context = threadContexts.Value; + currentWriteTransaction = context.Database.BeginTransaction(); + } + else + { + context = threadContexts.Value; + } + } + catch (Exception e) + { + // retrieval of a context could trigger a fatal error. + Monitor.Exit(writeLock); + throw; } Interlocked.Increment(ref currentWriteUsages); - return new DatabaseWriteUsage(threadContexts.Value, usageCompleted) { IsTransactionLeader = currentWriteTransaction != null && currentWriteUsages == 1 }; + return new DatabaseWriteUsage(context, usageCompleted) { IsTransactionLeader = currentWriteTransaction != null && currentWriteUsages == 1 }; } private void usageCompleted(DatabaseWriteUsage usage) @@ -100,19 +116,18 @@ namespace osu.Game.Database private void recycleThreadContexts() => threadContexts = new ThreadLocal(CreateContext); - protected virtual OsuDbContext CreateContext() + protected virtual OsuDbContext CreateContext() => new OsuDbContext(host.Storage.GetDatabaseConnectionString(database_name)) { - var ctx = new OsuDbContext(host.Storage.GetDatabaseConnectionString(database_name)); - ctx.Database.AutoTransactionsEnabled = false; - - return ctx; - } + Database = { AutoTransactionsEnabled = false } + }; public void ResetDatabase() { lock (writeLock) { recycleThreadContexts(); + GC.Collect(); + GC.WaitForPendingFinalizers(); host.Storage.DeleteDatabase(database_name); } } diff --git a/osu.Game/Database/OsuDbContext.cs b/osu.Game/Database/OsuDbContext.cs index 7758b3eb25..4b0de57c4c 100644 --- a/osu.Game/Database/OsuDbContext.cs +++ b/osu.Game/Database/OsuDbContext.cs @@ -58,11 +58,20 @@ namespace osu.Game.Database this.connectionString = connectionString; var connection = Database.GetDbConnection(); - connection.Open(); - using (var cmd = connection.CreateCommand()) + try { - cmd.CommandText = "PRAGMA journal_mode=WAL;"; - cmd.ExecuteNonQuery(); + connection.Open(); + + using (var cmd = connection.CreateCommand()) + { + cmd.CommandText = "PRAGMA journal_mode=WAL;"; + cmd.ExecuteNonQuery(); + } + } + catch (Exception e) + { + connection.Close(); + throw; } } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index b9d32a6322..f6b3935689 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -211,15 +211,17 @@ namespace osu.Game using (var db = contextFactory.GetForWrite(false)) db.Context.Migrate(); } - catch (MigrationFailedException e) + catch (Exception e) { Logger.Error(e.InnerException ?? e, "Migration failed! We'll be starting with a fresh database.", LoggingTarget.Database); // if we failed, let's delete the database and start fresh. // todo: we probably want a better (non-destructive) migrations/recovery process at a later point than this. contextFactory.ResetDatabase(); + Logger.Log("Database purged successfully.", LoggingTarget.Database, LogLevel.Important); + // only run once more, then hard bail. using (var db = contextFactory.GetForWrite(false)) db.Context.Migrate(); } From bd7c9cd8bffcf880518b0cc8159a3f32ab5f2fc6 Mon Sep 17 00:00:00 2001 From: Joehu Date: Sun, 3 Jun 2018 17:41:34 -0700 Subject: [PATCH 100/262] Set 'Colour' when creating 'textFlow' --- osu.Game/Screens/Select/BeatmapDetails.cs | 14 +------------- 1 file changed, 1 insertion(+), 13 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index 68e308783e..f1bd2b945f 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -356,7 +356,7 @@ namespace osu.Game.Screens.Select { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Colour = textFlow.Colour, + Colour = Color4.White.Opacity(0.75f), Text = text }, loaded => { @@ -367,18 +367,6 @@ namespace osu.Game.Screens.Select this.FadeIn(transition_duration); }); } - - public Color4 TextColour - { - get { return textFlow.Colour; } - set { textFlow.Colour = value; } - } - - [BackgroundDependencyLoader] - private void load() - { - textFlow.Colour = Color4.White.Opacity(0.75f); - } } private class DimmedLoadingAnimation : VisibilityContainer From db4c26e1ab5371ea7307f3c1e8c358143eef39d1 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sun, 3 Jun 2018 22:22:44 -0300 Subject: [PATCH 101/262] Rewrite ScoreComponentLabel. --- .../Select/Leaderboards/LeaderboardScore.cs | 74 ++++++++++++------- 1 file changed, 49 insertions(+), 25 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index baab973ae5..c39c4e43d3 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -142,6 +142,8 @@ namespace osu.Game.Screens.Select.Leaderboards { flagBadgeContainer = new Container { + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, Size = new Vector2(87f, 20f), Masking = true, Children = new Drawable[] @@ -155,10 +157,12 @@ namespace osu.Game.Screens.Select.Leaderboards }, new FillFlowContainer { + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(10f, 0f), - Margin = new MarginPadding { Left = edge_margin, }, + Margin = new MarginPadding { Left = edge_margin }, Children = new Drawable[] { maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString()), @@ -307,35 +311,55 @@ namespace osu.Game.Screens.Select.Leaderboards private class ScoreComponentLabel : Container { + private const float icon_size = 20; + + private readonly FillFlowContainer content; + + protected override Container Content => content; + public ScoreComponentLabel(FontAwesome icon, string value) { - Anchor = Anchor.CentreLeft; - Origin = Anchor.CentreLeft; - Size = new Vector2(60f, 20f); - Padding = new MarginPadding { Top = 10f, }; + AutoSizeAxes = Axes.Y; + Width = 60; - Children = new Drawable[] + InternalChild = content = new FillFlowContainer { - new SpriteIcon + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] { - Origin = Anchor.Centre, - Icon = FontAwesome.fa_square, - Colour = OsuColour.FromHex(@"3087ac"), - Rotation = 45, - Size = new Vector2(20), - Shadow = true, - }, - new SpriteIcon - { - Origin = Anchor.Centre, - Icon = icon, - Colour = OsuColour.FromHex(@"a4edff"), - Size = new Vector2(14), - }, - new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa")) - { - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 15, }, + new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Children = new[] + { + new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(icon_size), + Rotation = 45, + Colour = OsuColour.FromHex(@"3087ac"), + Icon = FontAwesome.fa_square, + Shadow = true, + }, + new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(icon_size - 6), + Colour = OsuColour.FromHex(@"a4edff"), + Icon = icon, + }, + }, + }, + new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa")) + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + }, }, }; } From a7bab14b303b70e59aa333519a7db16601b312ff Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Sun, 3 Jun 2018 22:26:30 -0300 Subject: [PATCH 102/262] Add tooltip to ScoreComponentLabel. --- .../Select/Leaderboards/LeaderboardScore.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index c39c4e43d3..19732107c7 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Game.Graphics; @@ -165,8 +166,8 @@ namespace osu.Game.Screens.Select.Leaderboards Margin = new MarginPadding { Left = edge_margin }, Children = new Drawable[] { - maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString()), - accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy)), + maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString(), "Max Combo"), + accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy), "Accuracy"), }, }, }, @@ -309,20 +310,24 @@ namespace osu.Game.Screens.Select.Leaderboards } } - private class ScoreComponentLabel : Container + private class ScoreComponentLabel : Container, IHasTooltip { private const float icon_size = 20; + private readonly string name; private readonly FillFlowContainer content; - protected override Container Content => content; + public override bool Contains(Vector2 screenSpacePos) => content.Contains(screenSpacePos); - public ScoreComponentLabel(FontAwesome icon, string value) + public string TooltipText => name; + + public ScoreComponentLabel(FontAwesome icon, string value, string name) { + this.name = name; AutoSizeAxes = Axes.Y; Width = 60; - InternalChild = content = new FillFlowContainer + Child = content = new FillFlowContainer { AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, From 4b828b104817cfade7e3c24747ca6f769d0a98e0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 4 Jun 2018 10:37:24 +0900 Subject: [PATCH 103/262] Fix incorrect release build vscode configurations --- osu.Game.Rulesets.Catch.Tests/.vscode/launch.json | 4 ++-- osu.Game.Rulesets.Mania.Tests/.vscode/launch.json | 4 ++-- osu.Game.Rulesets.Osu.Tests/.vscode/launch.json | 4 ++-- osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json | 4 ++-- 4 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json b/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json index c5005adfa5..2a82d65014 100644 --- a/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json @@ -22,7 +22,7 @@ }, "type": "mono", "request": "launch", - "program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Catch.Tests.exe", + "program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Catch.Tests.exe", "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, msbuild)", "runtimeExecutable": null, @@ -48,7 +48,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll" + "${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, dotnet)", diff --git a/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json b/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json index 637a5de1b5..bc41d4ccf9 100644 --- a/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json @@ -22,7 +22,7 @@ }, "type": "mono", "request": "launch", - "program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Mania.Tests.exe", + "program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Mania.Tests.exe", "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, msbuild)", "runtimeExecutable": null, @@ -48,7 +48,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll" + "${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, dotnet)", diff --git a/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json b/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json index 65c801cef4..13aba025fd 100644 --- a/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json @@ -22,7 +22,7 @@ }, "type": "mono", "request": "launch", - "program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Osu.Tests.exe", + "program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Osu.Tests.exe", "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, msbuild)", "runtimeExecutable": null, @@ -48,7 +48,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll" + "${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, dotnet)", diff --git a/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json b/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json index dbb1ab28e2..df49e177dc 100644 --- a/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json +++ b/osu.Game.Rulesets.Taiko.Tests/.vscode/launch.json @@ -22,7 +22,7 @@ }, "type": "mono", "request": "launch", - "program": "${workspaceRoot}/bin/Debug/net471/osu.Game.Rulesets.Taiko.Tests.exe", + "program": "${workspaceRoot}/bin/Release/net471/osu.Game.Rulesets.Taiko.Tests.exe", "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, msbuild)", "runtimeExecutable": null, @@ -48,7 +48,7 @@ "request": "launch", "program": "dotnet", "args": [ - "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll" + "${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Taiko.Tests.dll" ], "cwd": "${workspaceRoot}", "preLaunchTask": "Build (Release, dotnet)", From 0f7b23d765a1724105c7b3a14d77bfe96a3e327c Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Mon, 4 Jun 2018 11:11:07 +0900 Subject: [PATCH 104/262] Add param explanatory blurb to xmldoc --- osu.Game/Beatmaps/GameBeatmap.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Beatmaps/GameBeatmap.cs b/osu.Game/Beatmaps/GameBeatmap.cs index ea19337c8c..e470dd8ac5 100644 --- a/osu.Game/Beatmaps/GameBeatmap.cs +++ b/osu.Game/Beatmaps/GameBeatmap.cs @@ -27,7 +27,7 @@ namespace osu.Game.Beatmaps /// /// Registers an for s to be added to. /// - /// The . + /// The to register. protected void RegisterAudioManager([NotNull] AudioManager audioManager) { if (this.audioManager != null) throw new InvalidOperationException($"Cannot register multiple {nameof(AudioManager)}s."); From 7b7236929a0e2166b94d6f66eb6bbdc0334eb588 Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 06:08:39 -0300 Subject: [PATCH 105/262] 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 106/262] 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 107/262] 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 108/262] 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 109/262] 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 b84441ab879271de900099b4b23a2c2bc1099db7 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Mon, 4 Jun 2018 22:25:18 +0900 Subject: [PATCH 110/262] Fix TestImportOverIPC --- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 9 +++++---- 1 file changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 586217a05f..645c76f265 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -264,7 +264,8 @@ namespace osu.Game.Tests.Beatmaps.IO private string createTemporaryBeatmap() { - var temp = new FileInfo(osz_path).CopyTo(Path.GetTempFileName(), true).FullName; + var temp = Path.GetTempFileName() + Guid.NewGuid() + ".osz"; + File.Copy(osz_path, temp, true); Assert.IsTrue(File.Exists(temp)); return temp; } @@ -344,12 +345,12 @@ namespace osu.Game.Tests.Beatmaps.IO private void waitForOrAssert(Func result, string failureMessage, int timeout = 60000) { - Action waitAction = () => + Task task = Task.Run(() => { while (!result()) Thread.Sleep(200); - }; + }); - Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout), failureMessage); + Assert.IsTrue(task.Wait(timeout), failureMessage); } } } From 698a42f1454dc088004dcdeac29468d8ba8c449a Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Mon, 4 Jun 2018 20:12:43 -0300 Subject: [PATCH 111/262] 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 112/262] 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 113/262] 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 114/262] 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 115/262] 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 116/262] 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 117/262] 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 3b03a25ea5d70d63a4f38530276187ca4d7acc22 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Jun 2018 11:28:51 +0900 Subject: [PATCH 118/262] Fix beatmaps with subfolders importing incorrectly on windows Closes #2718. --- osu.Game/Database/ArchiveModelManager.cs | 3 ++- osu.Game/IO/Archives/LegacyFilesystemReader.cs | 6 +++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game/Database/ArchiveModelManager.cs b/osu.Game/Database/ArchiveModelManager.cs index 7741fe9ab3..cbf0df3227 100644 --- a/osu.Game/Database/ArchiveModelManager.cs +++ b/osu.Game/Database/ArchiveModelManager.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.IO; using System.Linq; using Microsoft.EntityFrameworkCore; +using osu.Framework.IO.File; using osu.Framework.Logging; using osu.Framework.Platform; using osu.Game.IO; @@ -364,7 +365,7 @@ namespace osu.Game.Database using (Stream s = reader.GetStream(file)) fileInfos.Add(new TFileModel { - Filename = file, + Filename = FileSafety.PathSanitise(file), FileInfo = files.Add(s) }); diff --git a/osu.Game/IO/Archives/LegacyFilesystemReader.cs b/osu.Game/IO/Archives/LegacyFilesystemReader.cs index 7871f1439a..fc52cb10dd 100644 --- a/osu.Game/IO/Archives/LegacyFilesystemReader.cs +++ b/osu.Game/IO/Archives/LegacyFilesystemReader.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using System.IO; using System.Linq; -using osu.Framework.IO.File; namespace osu.Game.IO.Archives { @@ -15,7 +14,8 @@ namespace osu.Game.IO.Archives { private readonly string path; - public LegacyFilesystemReader(string path) : base(Path.GetFileName(path)) + public LegacyFilesystemReader(string path) + : base(Path.GetFileName(path)) { this.path = path; } @@ -27,7 +27,7 @@ namespace osu.Game.IO.Archives // no-op } - public override IEnumerable Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(f => FileSafety.GetRelativePath(f, path)).ToArray(); + public override IEnumerable Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(f => f.Replace(path, string.Empty).Trim(Path.DirectorySeparatorChar)).ToArray(); public override Stream GetUnderlyingStream() => null; } From 601ef3b6f70e2190793b6e66ea864ee5451c0e62 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 4 Jun 2018 20:01:55 +0900 Subject: [PATCH 119/262] Consume osu.Framework via nuget --- osu-framework | 1 - osu.Desktop.Deploy/osu.Desktop.Deploy.csproj | 4 +--- osu.Desktop/osu.Desktop.csproj | 2 +- osu.Game/OsuGameBase.cs | 4 ++-- osu.Game/Tests/Visual/OsuTestCase.cs | 4 ---- osu.Game/osu.Game.csproj | 2 +- osu.TestProject.props | 3 +-- osu.sln | 6 ------ 8 files changed, 6 insertions(+), 20 deletions(-) delete mode 160000 osu-framework diff --git a/osu-framework b/osu-framework deleted file mode 160000 index b963ce8250..0000000000 --- a/osu-framework +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b963ce82505bc953db0a0763679e1ec80a060811 diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj index 063fb89918..e5944187b3 100644 --- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj +++ b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj @@ -6,12 +6,10 @@ AnyCPU true - - - + diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index b8efd76506..a3b4c5d195 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -20,7 +20,6 @@ osu.Desktop.Program - @@ -31,6 +30,7 @@ + diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index b9d32a6322..fcc2d42321 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -59,8 +59,6 @@ namespace osu.Game protected MenuCursorContainer MenuCursorContainer; - protected override string MainResourceFile => @"osu.Game.Resources.dll"; - private Container content; protected override Container Content => content; @@ -100,6 +98,8 @@ namespace osu.Game [BackgroundDependencyLoader] private void load() { + Resources.AddStore(new DllResourceStore(@"osu.Game.Resources.dll")); + dependencies.Cache(contextFactory = new DatabaseContextFactory(Host)); dependencies.Cache(new LargeTextureStore(new RawTextureLoaderStore(new NamespacedResourceStore(Resources, @"Textures")))); diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 2b677f1f42..fa441d8012 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -1,8 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.IO; -using System.Reflection; using osu.Framework.Testing; namespace osu.Game.Tests.Visual @@ -13,8 +11,6 @@ namespace osu.Game.Tests.Visual public class OsuTestCaseTestRunner : OsuGameBase, ITestCaseTestRunner { - protected override string MainResourceFile => File.Exists(base.MainResourceFile) ? base.MainResourceFile : Assembly.GetExecutingAssembly().Location; - private TestCaseTestRunner.TestRunner runner; protected override void LoadAsyncComplete() diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index afb656a260..55ee87dcb3 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -11,7 +11,6 @@ - @@ -19,6 +18,7 @@ + diff --git a/osu.TestProject.props b/osu.TestProject.props index afdf895eac..b51ca13ed5 100644 --- a/osu.TestProject.props +++ b/osu.TestProject.props @@ -7,7 +7,6 @@ - @@ -18,7 +17,7 @@ - + VisualTestRunner.cs diff --git a/osu.sln b/osu.sln index 5c4b644489..b8ef7de9ea 100644 --- a/osu.sln +++ b/osu.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 15.0.27004.2006 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game", "osu.Game\osu.Game.csproj", "{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Framework", "osu-framework\osu.Framework\osu.Framework.csproj", "{C76BF5B3-985E-4D39-95FE-97C9C879B83A}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Resources", "osu-resources\osu.Game.Resources\osu.Game.Resources.csproj", "{D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Osu", "osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj", "{C92A607B-1FDD-4954-9F92-03FF547D9080}" @@ -41,10 +39,6 @@ Global {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Debug|Any CPU.Build.0 = Debug|Any CPU {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Release|Any CPU.Build.0 = Release|Any CPU - {C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Release|Any CPU.Build.0 = Release|Any CPU {D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}.Debug|Any CPU.Build.0 = Debug|Any CPU {D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}.Release|Any CPU.ActiveCfg = Release|Any CPU From 115595251d289fad981dbde2d361df74e9c13a7c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Jun 2018 15:02:34 +0900 Subject: [PATCH 120/262] Remove unnecessary reference in osu.Desktop --- osu.Desktop/osu.Desktop.csproj | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index a3b4c5d195..766f36fa74 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -30,7 +30,6 @@ - From 9af9b1c937362101fc3091c52fa9ee64417e7563 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Jun 2018 19:41:07 +0900 Subject: [PATCH 121/262] Remove framework submodule reference completely --- .gitmodules | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/.gitmodules b/.gitmodules index ee1cc80880..f1c4f5d172 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "osu-framework"] - path = osu-framework - url = https://github.com/ppy/osu-framework [submodule "osu-resources"] path = osu-resources - url = https://github.com/ppy/osu-resources + url = https://github.com/ppy/osu-resources \ No newline at end of file From 59277de0df9b6b2c5ef75fbe35cc0fc087d170fd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Jun 2018 19:45:25 +0900 Subject: [PATCH 122/262] Remove osu.Desktop.Deploy --- osu.Desktop.Deploy/App.config | 21 - osu.Desktop.Deploy/GitHubObject.cs | 16 - osu.Desktop.Deploy/GitHubRelease.cs | 28 -- osu.Desktop.Deploy/Program.cs | 471 ------------------- osu.Desktop.Deploy/osu.Desktop.Deploy.csproj | 19 - osu.sln | 4 - 6 files changed, 559 deletions(-) delete mode 100644 osu.Desktop.Deploy/App.config delete mode 100644 osu.Desktop.Deploy/GitHubObject.cs delete mode 100644 osu.Desktop.Deploy/GitHubRelease.cs delete mode 100644 osu.Desktop.Deploy/Program.cs delete mode 100644 osu.Desktop.Deploy/osu.Desktop.Deploy.csproj diff --git a/osu.Desktop.Deploy/App.config b/osu.Desktop.Deploy/App.config deleted file mode 100644 index 9ec53d5a31..0000000000 --- a/osu.Desktop.Deploy/App.config +++ /dev/null @@ -1,21 +0,0 @@ - - - - - - - - - - - - - - - - - - \ No newline at end of file diff --git a/osu.Desktop.Deploy/GitHubObject.cs b/osu.Desktop.Deploy/GitHubObject.cs deleted file mode 100644 index 02ff16fa69..0000000000 --- a/osu.Desktop.Deploy/GitHubObject.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using Newtonsoft.Json; - -namespace osu.Desktop.Deploy -{ - public class GitHubObject - { - [JsonProperty(@"id")] - public int Id; - - [JsonProperty(@"name")] - public string Name; - } -} diff --git a/osu.Desktop.Deploy/GitHubRelease.cs b/osu.Desktop.Deploy/GitHubRelease.cs deleted file mode 100644 index faf312d4f7..0000000000 --- a/osu.Desktop.Deploy/GitHubRelease.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using Newtonsoft.Json; - -namespace osu.Desktop.Deploy -{ - public class GitHubRelease - { - [JsonProperty(@"id")] - public int Id; - - [JsonProperty(@"tag_name")] - public string TagName => $"v{Name}"; - - [JsonProperty(@"name")] - public string Name; - - [JsonProperty(@"draft")] - public bool Draft; - - [JsonProperty(@"prerelease")] - public bool PreRelease; - - [JsonProperty(@"upload_url")] - public string UploadUrl; - } -} diff --git a/osu.Desktop.Deploy/Program.cs b/osu.Desktop.Deploy/Program.cs deleted file mode 100644 index a1c2a8aef2..0000000000 --- a/osu.Desktop.Deploy/Program.cs +++ /dev/null @@ -1,471 +0,0 @@ -// 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.Configuration; -using System.Diagnostics; -using System.IO; -using System.Linq; -using System.Management.Automation; -using Newtonsoft.Json; -using osu.Framework.IO.Network; -using FileWebRequest = osu.Framework.IO.Network.FileWebRequest; -using WebRequest = osu.Framework.IO.Network.WebRequest; - -namespace osu.Desktop.Deploy -{ - internal static class Program - { - private static string packages => Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.UserProfile), ".nuget", "packages"); - private static string nugetPath => Path.Combine(packages, @"nuget.commandline\4.5.1\tools\NuGet.exe"); - private static string squirrelPath => Path.Combine(packages, @"squirrel.windows\1.8.0\tools\Squirrel.exe"); - private const string msbuild_path = @"C:\Program Files (x86)\Microsoft Visual Studio\2017\Community\MSBuild\15.0\Bin\MSBuild.exe"; - - public static string StagingFolder = ConfigurationManager.AppSettings["StagingFolder"]; - public static string ReleasesFolder = ConfigurationManager.AppSettings["ReleasesFolder"]; - public static string GitHubAccessToken = ConfigurationManager.AppSettings["GitHubAccessToken"]; - public static string GitHubUsername = ConfigurationManager.AppSettings["GitHubUsername"]; - public static string GitHubRepoName = ConfigurationManager.AppSettings["GitHubRepoName"]; - public static string SolutionName = ConfigurationManager.AppSettings["SolutionName"]; - public static string ProjectName = ConfigurationManager.AppSettings["ProjectName"]; - public static string NuSpecName = ConfigurationManager.AppSettings["NuSpecName"]; - public static string TargetNames = ConfigurationManager.AppSettings["TargetName"]; - public static string PackageName = ConfigurationManager.AppSettings["PackageName"]; - public static string IconName = ConfigurationManager.AppSettings["IconName"]; - public static string CodeSigningCertificate = ConfigurationManager.AppSettings["CodeSigningCertificate"]; - - public static string GitHubApiEndpoint => $"https://api.github.com/repos/{GitHubUsername}/{GitHubRepoName}/releases"; - public static string GitHubReleasePage => $"https://github.com/{GitHubUsername}/{GitHubRepoName}/releases"; - - /// - /// How many previous build deltas we want to keep when publishing. - /// - private const int keep_delta_count = 4; - - private static string codeSigningCmd => string.IsNullOrEmpty(codeSigningPassword) ? "" : $"-n \"/a /f {codeSigningCertPath} /p {codeSigningPassword} /t http://timestamp.comodoca.com/authenticode\""; - - private static string homeDir => Environment.GetFolderPath(Environment.SpecialFolder.UserProfile); - private static string codeSigningCertPath => Path.Combine(homeDir, CodeSigningCertificate); - private static string solutionPath => Environment.CurrentDirectory; - private static string stagingPath => Path.Combine(solutionPath, StagingFolder); - private static string iconPath => Path.Combine(solutionPath, ProjectName, IconName); - - private static string nupkgFilename(string ver) => $"{PackageName}.{ver}.nupkg"; - private static string nupkgDistroFilename(string ver) => $"{PackageName}-{ver}-full.nupkg"; - - private static readonly Stopwatch sw = new Stopwatch(); - - private static string codeSigningPassword; - - private static bool interactive; - - public static void Main(string[] args) - { - interactive = args.Length == 0; - - displayHeader(); - - findSolutionPath(); - - if (!Directory.Exists(ReleasesFolder)) - { - write("WARNING: No release directory found. Make sure you want this!", ConsoleColor.Yellow); - Directory.CreateDirectory(ReleasesFolder); - } - - checkGitHubReleases(); - - refreshDirectory(StagingFolder); - - //increment build number until we have a unique one. - string verBase = DateTime.Now.ToString("yyyy.Mdd."); - int increment = 0; - while (Directory.GetFiles(ReleasesFolder, $"*{verBase}{increment}*").Any()) - increment++; - - string version = $"{verBase}{increment}"; - - Console.ForegroundColor = ConsoleColor.White; - Console.Write($"Ready to deploy {version}!"); - pauseIfInteractive(); - - sw.Start(); - - if (!string.IsNullOrEmpty(CodeSigningCertificate)) - { - Console.Write("Enter code signing password: "); - codeSigningPassword = args.Length > 0 ? args[0] : readLineMasked(); - } - - write("Updating AssemblyInfo..."); - updateCsprojVersion(version); - updateAppveyorVersion(version); - - write("Running build process..."); - foreach (string targetName in TargetNames.Split(',')) - runCommand(msbuild_path, $"/v:quiet /m /t:{targetName.Replace('.', '_')} /p:OutputPath={stagingPath};Targets=\"Clean;Build\";Configuration=Release {SolutionName}.sln"); - - write("Creating NuGet deployment package..."); - runCommand(nugetPath, $"pack {NuSpecName} -Version {version} -Properties Configuration=Deploy -OutputDirectory {stagingPath} -BasePath {stagingPath}"); - - //prune once before checking for files so we can avoid erroring on files which aren't even needed for this build. - pruneReleases(); - - checkReleaseFiles(); - - write("Running squirrel build..."); - runCommand(squirrelPath, $"--releasify {stagingPath}\\{nupkgFilename(version)} --framework-version=net471 --setupIcon {iconPath} --icon {iconPath} {codeSigningCmd} --no-msi"); - - //prune again to clean up before upload. - pruneReleases(); - - //rename setup to install. - File.Copy(Path.Combine(ReleasesFolder, "Setup.exe"), Path.Combine(ReleasesFolder, "install.exe"), true); - File.Delete(Path.Combine(ReleasesFolder, "Setup.exe")); - - uploadBuild(version); - - //reset assemblyinfo. - updateCsprojVersion("0.0.0"); - - write("Done!", ConsoleColor.White); - pauseIfInteractive(); - } - - private static void displayHeader() - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine(); - Console.WriteLine(" Please note that OSU! and PPY are registered trademarks and as such covered by trademark law."); - Console.WriteLine(" Do not distribute builds of this project publicly that make use of these."); - Console.ResetColor(); - Console.WriteLine(); - } - - /// - /// Ensure we have all the files in the release directory which are expected to be there. - /// This should have been accounted for in earlier steps, and just serves as a verification step. - /// - private static void checkReleaseFiles() - { - if (!canGitHub) return; - - var releaseLines = getReleaseLines(); - - //ensure we have all files necessary - foreach (var l in releaseLines) - if (!File.Exists(Path.Combine(ReleasesFolder, l.Filename))) - error($"Local file missing {l.Filename}"); - } - - private static IEnumerable getReleaseLines() => File.ReadAllLines(Path.Combine(ReleasesFolder, "RELEASES")).Select(l => new ReleaseLine(l)); - - private static void pruneReleases() - { - if (!canGitHub) return; - - write("Pruning RELEASES..."); - - var releaseLines = getReleaseLines().ToList(); - - var fulls = releaseLines.Where(l => l.Filename.Contains("-full")).Reverse().Skip(1); - - //remove any FULL releases (except most recent) - foreach (var l in fulls) - { - write($"- Removing old release {l.Filename}", ConsoleColor.Yellow); - File.Delete(Path.Combine(ReleasesFolder, l.Filename)); - releaseLines.Remove(l); - } - - //remove excess deltas - var deltas = releaseLines.Where(l => l.Filename.Contains("-delta")).ToArray(); - if (deltas.Length > keep_delta_count) - { - foreach (var l in deltas.Take(deltas.Length - keep_delta_count)) - { - write($"- Removing old delta {l.Filename}", ConsoleColor.Yellow); - File.Delete(Path.Combine(ReleasesFolder, l.Filename)); - releaseLines.Remove(l); - } - } - - var lines = new List(); - releaseLines.ForEach(l => lines.Add(l.ToString())); - File.WriteAllLines(Path.Combine(ReleasesFolder, "RELEASES"), lines); - } - - private static void uploadBuild(string version) - { - if (!canGitHub || string.IsNullOrEmpty(CodeSigningCertificate)) - return; - - write("Publishing to GitHub..."); - - write($"- Creating release {version}...", ConsoleColor.Yellow); - var req = new JsonWebRequest($"{GitHubApiEndpoint}") - { - Method = HttpMethod.POST, - }; - req.AddRaw(JsonConvert.SerializeObject(new GitHubRelease - { - Name = version, - Draft = true, - PreRelease = true - })); - req.AuthenticatedBlockingPerform(); - - var assetUploadUrl = req.ResponseObject.UploadUrl.Replace("{?name,label}", "?name={0}"); - foreach (var a in Directory.GetFiles(ReleasesFolder).Reverse()) //reverse to upload RELEASES first. - { - write($"- Adding asset {a}...", ConsoleColor.Yellow); - var upload = new WebRequest(assetUploadUrl, Path.GetFileName(a)) - { - Method = HttpMethod.POST, - Timeout = 240000, - ContentType = "application/octet-stream", - }; - - upload.AddRaw(File.ReadAllBytes(a)); - upload.AuthenticatedBlockingPerform(); - } - - openGitHubReleasePage(); - } - - private static void openGitHubReleasePage() => Process.Start(GitHubReleasePage); - - private static bool canGitHub => !string.IsNullOrEmpty(GitHubAccessToken); - - private static void checkGitHubReleases() - { - if (!canGitHub) return; - - write("Checking GitHub releases..."); - var req = new JsonWebRequest>($"{GitHubApiEndpoint}"); - req.AuthenticatedBlockingPerform(); - - var lastRelease = req.ResponseObject.FirstOrDefault(); - - if (lastRelease == null) - return; - - if (lastRelease.Draft) - { - openGitHubReleasePage(); - error("There's a pending draft release! You probably don't want to push a build with this present."); - } - - //there's a previous release for this project. - var assetReq = new JsonWebRequest>($"{GitHubApiEndpoint}/{lastRelease.Id}/assets"); - assetReq.AuthenticatedBlockingPerform(); - var assets = assetReq.ResponseObject; - - //make sure our RELEASES file is the same as the last build on the server. - var releaseAsset = assets.FirstOrDefault(a => a.Name == "RELEASES"); - - //if we don't have a RELEASES asset then the previous release likely wasn't a Squirrel one. - if (releaseAsset == null) return; - - write($"Last GitHub release was {lastRelease.Name}."); - - bool requireDownload = false; - - if (!File.Exists(Path.Combine(ReleasesFolder, nupkgDistroFilename(lastRelease.Name)))) - { - write("Last version's package not found locally.", ConsoleColor.Red); - requireDownload = true; - } - else - { - var lastReleases = new RawFileWebRequest($"{GitHubApiEndpoint}/assets/{releaseAsset.Id}"); - lastReleases.AuthenticatedBlockingPerform(); - if (File.ReadAllText(Path.Combine(ReleasesFolder, "RELEASES")) != lastReleases.ResponseString) - { - write("Server's RELEASES differed from ours.", ConsoleColor.Red); - requireDownload = true; - } - } - - if (!requireDownload) return; - - write("Refreshing local releases directory..."); - refreshDirectory(ReleasesFolder); - - foreach (var a in assets) - { - if (a.Name.EndsWith(".exe")) continue; - - write($"- Downloading {a.Name}...", ConsoleColor.Yellow); - new FileWebRequest(Path.Combine(ReleasesFolder, a.Name), $"{GitHubApiEndpoint}/assets/{a.Id}").AuthenticatedBlockingPerform(); - } - } - - private static void refreshDirectory(string directory) - { - if (Directory.Exists(directory)) - Directory.Delete(directory, true); - Directory.CreateDirectory(directory); - } - - private static void updateCsprojVersion(string version) - { - var toUpdate = new[] { "", "" }; - string file = Path.Combine(ProjectName, $"{ProjectName}.csproj"); - - var l1 = File.ReadAllLines(file); - List l2 = new List(); - foreach (var l in l1) - { - string line = l; - - foreach (var tag in toUpdate) - { - int startIndex = l.IndexOf(tag, StringComparison.InvariantCulture); - if (startIndex == -1) - continue; - startIndex += tag.Length; - - int endIndex = l.IndexOf("<", startIndex, StringComparison.InvariantCulture); - line = $"{l.Substring(0, startIndex)}{version}{l.Substring(endIndex)}"; - } - - l2.Add(line); - } - - File.WriteAllLines(file, l2); - } - - /// - /// Find the base path of the active solution (git checkout location) - /// - private static void findSolutionPath() - { - string path = Path.GetDirectoryName(Environment.CommandLine.Replace("\"", "").Trim()); - - if (string.IsNullOrEmpty(path)) - path = Environment.CurrentDirectory; - - while (!File.Exists(Path.Combine(path, $"{SolutionName}.sln"))) - path = path.Remove(path.LastIndexOf(Path.DirectorySeparatorChar)); - path += Path.DirectorySeparatorChar; - - Environment.CurrentDirectory = path; - } - - private static bool runCommand(string command, string args) - { - var psi = new ProcessStartInfo(command, args) - { - WorkingDirectory = solutionPath, - CreateNoWindow = true, - RedirectStandardOutput = true, - RedirectStandardError = true, - UseShellExecute = false, - WindowStyle = ProcessWindowStyle.Hidden - }; - - Process p = Process.Start(psi); - if (p == null) return false; - - string output = p.StandardOutput.ReadToEnd(); - output += p.StandardError.ReadToEnd(); - - if (p.ExitCode == 0) return true; - - write(output); - error($"Command {command} {args} failed!"); - return false; - } - - private static string readLineMasked() - { - var fg = Console.ForegroundColor; - Console.ForegroundColor = Console.BackgroundColor; - var ret = Console.ReadLine(); - Console.ForegroundColor = fg; - - return ret; - } - - private static void error(string message) - { - Console.ForegroundColor = ConsoleColor.Red; - Console.WriteLine($"FATAL ERROR: {message}"); - - pauseIfInteractive(); - Environment.Exit(-1); - } - - private static void pauseIfInteractive() - { - if (interactive) - Console.ReadLine(); - else - Console.WriteLine(); - } - - private static bool updateAppveyorVersion(string version) - { - try - { - using (PowerShell ps = PowerShell.Create()) - { - ps.AddScript($"Update-AppveyorBuild -Version \"{version}\""); - ps.Invoke(); - } - return true; - } - catch - { - // we don't have appveyor and don't care - } - - return false; - } - - private static void write(string message, ConsoleColor col = ConsoleColor.Gray) - { - if (sw.ElapsedMilliseconds > 0) - { - Console.ForegroundColor = ConsoleColor.Green; - Console.Write(sw.ElapsedMilliseconds.ToString().PadRight(8)); - } - Console.ForegroundColor = col; - Console.WriteLine(message); - } - - public static void AuthenticatedBlockingPerform(this WebRequest r) - { - r.AddHeader("Authorization", $"token {GitHubAccessToken}"); - r.Perform(); - } - } - - internal class RawFileWebRequest : WebRequest - { - public RawFileWebRequest(string url) : base(url) - { - } - - protected override string Accept => "application/octet-stream"; - } - - internal class ReleaseLine - { - public string Hash; - public string Filename; - public int Filesize; - - public ReleaseLine(string line) - { - var split = line.Split(' '); - Hash = split[0]; - Filename = split[1]; - Filesize = int.Parse(split[2]); - } - - public override string ToString() => $"{Hash} {Filename} {Filesize}"; - } -} diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj deleted file mode 100644 index 063fb89918..0000000000 --- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj +++ /dev/null @@ -1,19 +0,0 @@ - - - - net471 - Exe - AnyCPU - true - - - - - - - - - - - - \ No newline at end of file diff --git a/osu.sln b/osu.sln index 5c4b644489..3646679539 100644 --- a/osu.sln +++ b/osu.sln @@ -17,8 +17,6 @@ Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Taiko", " EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Mania", "osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj", "{48F4582B-7687-4621-9CBE-5C24197CB536}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Desktop.Deploy", "osu.Desktop.Deploy\osu.Desktop.Deploy.csproj", "{BAEA2F74-0315-4667-84E0-ACAC0B4BF785}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Tests", "osu.Game.Tests\osu.Game.Tests.csproj", "{54377672-20B1-40AF-8087-5CF73BF3953A}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Desktop", "osu.Desktop\osu.Desktop.csproj", "{419659FD-72EA-4678-9EB8-B22A746CED70}" @@ -65,8 +63,6 @@ Global {48F4582B-7687-4621-9CBE-5C24197CB536}.Debug|Any CPU.Build.0 = Debug|Any CPU {48F4582B-7687-4621-9CBE-5C24197CB536}.Release|Any CPU.ActiveCfg = Release|Any CPU {48F4582B-7687-4621-9CBE-5C24197CB536}.Release|Any CPU.Build.0 = Release|Any CPU - {BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {BAEA2F74-0315-4667-84E0-ACAC0B4BF785}.Release|Any CPU.ActiveCfg = Release|Any CPU {54377672-20B1-40AF-8087-5CF73BF3953A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {54377672-20B1-40AF-8087-5CF73BF3953A}.Debug|Any CPU.Build.0 = Debug|Any CPU {54377672-20B1-40AF-8087-5CF73BF3953A}.Release|Any CPU.ActiveCfg = Release|Any CPU From fe35c0220aac02167943f28703522f94ed156d2c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 5 Jun 2018 18:52:39 +0900 Subject: [PATCH 123/262] Update deploy script --- appveyor.yml | 2 +- appveyor_deploy.yml | 34 +++++++++++++++++----------------- 2 files changed, 18 insertions(+), 18 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 314faa617a..69bc762f4c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ clone_depth: 1 version: '{branch}-{build}' -image: Visual Studio 2017 preview +image: Visual Studio 2017 configuration: Debug cache: - C:\ProgramData\chocolatey\bin -> appveyor.yml diff --git a/appveyor_deploy.yml b/appveyor_deploy.yml index cadebd9d11..64ad927574 100644 --- a/appveyor_deploy.yml +++ b/appveyor_deploy.yml @@ -1,29 +1,26 @@ -branches: - only: - - release -skip_tags: true -skip_branch_with_pr: true clone_depth: 1 -version: '{branch}-{build}' +version: '{build}' +skip_non_tags: true image: Visual Studio 2017 -configuration: Debug cache: - - packages -> **\packages.config + - '%USERPROFILE%\.nuget\packages -> **\*.csproj' install: - - cmd: git submodule update --init --recursive --depth=5 + - git clone https://github.com/ppy/osu-deploy before_build: + - ps: if($env:appveyor_repo_tag -eq 'True') { Update-AppveyorBuild -Version $env:appveyor_repo_tag_name } + - cmd: git submodule update --init --recursive --depth=5 - cmd: nuget restore -verbosity quiet -build: - project: osu.Desktop.Deploy/osu.Desktop.Deploy.csproj - verbosity: minimal -after_build: +build_script: - 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\net471\osu.Desktop.Deploy.exe.config - - cd osu.Desktop.Deploy\bin\Debug\net471\ - - osu.Desktop.Deploy.exe %code_signing_password% + - cd osu-deploy + - nuget restore -verbosity quiet + - msbuild osu.Desktop.Deploy.csproj + - cmd: ..\appveyor-tools\secure-file -decrypt ..\fdc6f19b04.enc -secret %decode_secret% -out bin\Debug\net471\osu.Desktop.Deploy.exe.config + - cd bin\Debug\net471\ + - osu.Desktop.Deploy.exe %code_signing_password% %APPVEYOR_REPO_TAG_NAME% environment: TargetFramework: net471 decode_secret: @@ -31,4 +28,7 @@ environment: code_signing_password: secure: 34tLNqvjmmZEi97MLKfrnQ== artifacts: - - path: 'Releases\*' \ No newline at end of file + - path: 'Releases\*' +deploy: + - provider: Environment + name: github \ No newline at end of file From 80951eae68f68449ce1d139f7284a5e9850f228a Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Tue, 5 Jun 2018 18:09:26 -0300 Subject: [PATCH 124/262] 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 1dd5bdcf72adc661febf0e39e1acf022488a9a36 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 12:32:59 +0900 Subject: [PATCH 125/262] Move setting to new "mods" section --- .../Sections/Gameplay/GeneralSettings.cs | 5 ---- .../Sections/Gameplay/ModsSettings.cs | 26 +++++++++++++++++++ .../Settings/Sections/GameplaySection.cs | 3 ++- 3 files changed, 28 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 9b3c199b5c..647395cf69 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -38,11 +38,6 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = "Always show key overlay", Bindable = config.GetBindable(OsuSetting.KeyOverlay) }, - new SettingsCheckbox - { - LabelText = "Increase visibility of first object with \"Hidden\" mod", - Bindable = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility) - }, }; } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs new file mode 100644 index 0000000000..a9cefa81da --- /dev/null +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs @@ -0,0 +1,26 @@ +// 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.Game.Configuration; + +namespace osu.Game.Overlays.Settings.Sections.Gameplay +{ + public class ModsSettings : SettingsSubsection + { + protected override string Header => "Mods"; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new[] + { + new SettingsCheckbox + { + LabelText = "Increase visibility of first object with \"Hidden\" mod", + Bindable = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility) + }, + }; + } + } +} diff --git a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs index 3851a73901..8add0b01ec 100644 --- a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs +++ b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs @@ -21,7 +21,8 @@ namespace osu.Game.Overlays.Settings.Sections { new GeneralSettings(), new SongSelectSettings(), - new ScrollingSettings() + new ScrollingSettings(), + new ModsSettings(), }; } From f253828d4930b572d93c8f983a3bf8061ce3e4f3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 13:51:51 +0900 Subject: [PATCH 126/262] Fix regressions --- osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 19 ++++++++++++++++++- 1 file changed, 18 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index f7a9fda14f..4220b72b16 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -2,21 +2,38 @@ // 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.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Osu.Objects; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects + public class OsuModHidden : ModHidden { public override string Description => @"Play with no approach circles and fading circles/sliders."; public override double ScoreMultiplier => 1.06; private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; + public override void ApplyToDrawableHitObjects(IEnumerable drawables) + { + void adjustFadeIn(OsuHitObject h) => h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; + + foreach (var d in drawables.OfType()) + { + adjustFadeIn(d.HitObject); + foreach (var h in d.HitObject.NestedHitObjects.OfType()) + adjustFadeIn(h); + } + + base.ApplyToDrawableHitObjects(drawables); + } + protected override void ApplyHiddenState(DrawableHitObject drawable, ArmedState state) { if (!(drawable is DrawableOsuHitObject d)) From a5679f7bf58a9475743b868651f3918c90d5a882 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 14:04:20 +0900 Subject: [PATCH 127/262] Improve readability of code --- osu.Game/Rulesets/Mods/ModHidden.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index ab1911fe88..45da628ce8 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -10,7 +10,7 @@ using System.Linq; namespace osu.Game.Rulesets.Mods { - public abstract class ModHidden : Mod, IReadFromConfig + public abstract class ModHidden : Mod, IReadFromConfig, IApplicableToDrawableHitObjects { public override string Name => "Hidden"; public override string ShortenedName => "HD"; @@ -25,15 +25,11 @@ namespace osu.Game.Rulesets.Mods IncreaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); } - public void ApplyToDrawableHitObjects(IEnumerable drawables) + public virtual void ApplyToDrawableHitObjects(IEnumerable drawables) { - foreach (var d in drawables) - { - if (d == drawables.Last() && IncreaseFirstObjectVisibility) - return; - + // todo: fix ordering of objects so we don't have to do this (#2740). + foreach (var d in drawables.Reverse().Skip(IncreaseFirstObjectVisibility ? 1 : 0)) d.ApplyCustomUpdateState += ApplyHiddenState; - } } protected virtual void ApplyHiddenState(DrawableHitObject hitObject, ArmedState state) { } From 8274623ad6f691d62bdf4eee28808e3afb9588bb Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Jun 2018 14:07:50 +0900 Subject: [PATCH 128/262] 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 129/262] 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 d3cd267036758cc75b6f9c7ab0fffca233ecd2e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 14:20:51 +0900 Subject: [PATCH 130/262] Formatting fixes --- osu.Game/Rulesets/UI/RulesetContainer.cs | 5 +++-- 1 file changed, 3 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index f06365e04a..384b71cccc 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -57,6 +57,7 @@ namespace osu.Game.Rulesets.UI public abstract IEnumerable Objects { get; } private readonly Lazy playfield; + /// /// The playfield. /// @@ -250,8 +251,8 @@ namespace osu.Game.Rulesets.UI foreach (var mod in mods.OfType>()) mod.ApplyToRulesetContainer(this); - foreach (var mod in mods.OfType()) - mod.ReadFromConfig(config); + foreach (var mod in mods.OfType()) + mod.ReadFromConfig(config); } public override void SetReplay(Replay replay) From 35678237591c8ff22cb479c9f0c32130471e16cb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 14:18:38 +0900 Subject: [PATCH 131/262] 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 86be1bef6b8856be4306cbaf3dcc763685096c77 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 15:10:09 +0900 Subject: [PATCH 132/262] Use UserTriggered in Player --- .../Containers/OsuFocusedOverlayContainer.cs | 20 +++++++++---------- osu.Game/Overlays/OverlayActivation.cs | 2 +- osu.Game/Screens/Play/Player.cs | 3 +++ 3 files changed, 13 insertions(+), 12 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index e9c02e84ec..51a9706ea4 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -53,20 +53,18 @@ namespace osu.Game.Graphics.Containers private void onStateChanged(Visibility visibility) { - if (allowOverlays == OverlayActivation.All) + switch (visibility) { - switch (visibility) - { - case Visibility.Visible: + case Visibility.Visible: + if (allowOverlays != OverlayActivation.Disabled) samplePopIn?.Play(); - break; - case Visibility.Hidden: - samplePopOut?.Play(); - break; - } + else + State = Visibility.Hidden; + break; + case Visibility.Hidden: + samplePopOut?.Play(); + break; } - else - State = Visibility.Hidden; } } } diff --git a/osu.Game/Overlays/OverlayActivation.cs b/osu.Game/Overlays/OverlayActivation.cs index 735682ed57..da4e153ce9 100644 --- a/osu.Game/Overlays/OverlayActivation.cs +++ b/osu.Game/Overlays/OverlayActivation.cs @@ -6,7 +6,7 @@ namespace osu.Game.Overlays public enum OverlayActivation { Disabled, - //UserTriggered, // currently there is no way to discern user action + UserTriggered, All } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index c93e4b7b40..6e0f6cb1c5 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -21,6 +21,7 @@ using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Online.API; +using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; @@ -37,6 +38,8 @@ namespace osu.Game.Screens.Play protected override bool HideOverlaysOnEnter => true; + protected override OverlayActivation OverlayActivationLevel => OverlayActivation.UserTriggered; + public Action RestartRequested; public bool HasFailed { get; private set; } From df4c855aa202f1949c769dc289e11c34d637760b Mon Sep 17 00:00:00 2001 From: DrabWeb Date: Wed, 6 Jun 2018 03:13:37 -0300 Subject: [PATCH 133/262] 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 134/262] 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 135/262] 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 d1fd09ed4767a3a3bd94493343057fc94ecd9071 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 15:49:27 +0900 Subject: [PATCH 136/262] Rename variables --- osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs | 6 +++--- osu.Game/OsuGame.cs | 2 +- osu.Game/Overlays/Toolbar/Toolbar.cs | 2 +- osu.Game/Screens/OsuScreen.cs | 2 +- 4 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 51a9706ea4..0186a170c9 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -17,13 +17,13 @@ namespace osu.Game.Graphics.Containers private SampleChannel samplePopIn; private SampleChannel samplePopOut; - private readonly Bindable allowOverlays = new Bindable(OverlayActivation.All); + protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.All); [BackgroundDependencyLoader(true)] private void load(OsuGame osuGame, AudioManager audio) { if (osuGame != null) - allowOverlays.BindTo(osuGame.AllowOverlays); + OverlayActivationMode.BindTo(osuGame.OverlayActivationMode); samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in"); samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out"); @@ -56,7 +56,7 @@ namespace osu.Game.Graphics.Containers switch (visibility) { case Visibility.Visible: - if (allowOverlays != OverlayActivation.Disabled) + if (OverlayActivationMode != OverlayActivation.Disabled) samplePopIn?.Play(); else State = Visibility.Hidden; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 35f29c3fd1..5c256ed5c8 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -77,7 +77,7 @@ namespace osu.Game public float ToolbarOffset => Toolbar.Position.Y + Toolbar.DrawHeight; - public readonly Bindable AllowOverlays = new Bindable(); + public readonly Bindable OverlayActivationMode = new Bindable(); private OsuScreen screenStack; diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 032ea01700..1eaf748011 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -84,7 +84,7 @@ namespace osu.Game.Overlays.Toolbar private void load(OsuGame osuGame) { if (osuGame != null) - allowOverlays.BindTo(osuGame.AllowOverlays); + allowOverlays.BindTo(osuGame.OverlayActivationMode); StateChanged += visibility => { diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index a6e32cda7b..ba9c65e42d 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -110,7 +110,7 @@ namespace osu.Game.Screens if (osuGame != null) { Ruleset.BindTo(osuGame.Ruleset); - allowOverlays.BindTo(osuGame.AllowOverlays); + allowOverlays.BindTo(osuGame.OverlayActivationMode); updateOverlayStates = () => { From 9e25e02696de1d38735abb8590ff6ef72e34d1f7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 15:49:58 +0900 Subject: [PATCH 137/262] Ensure notifications don't appear during UserTriggered mode Closes #2640. --- osu.Game/OsuGame.cs | 2 - osu.Game/Overlays/NotificationOverlay.cs | 49 +++++++++++------------- 2 files changed, 23 insertions(+), 28 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 5c256ed5c8..68c50dafab 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -366,8 +366,6 @@ namespace osu.Game settings.StateChanged += _ => updateScreenOffset(); notifications.StateChanged += _ => updateScreenOffset(); - - AllowOverlays.ValueChanged += state => notifications.Enabled.Value = state == OverlayActivation.All; } public void CloseAllOverlays() diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 09b6022ac5..3dc8f5ec15 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -22,11 +22,6 @@ namespace osu.Game.Overlays public const float TRANSITION_LENGTH = 600; - /// - /// Whether posted notifications should be processed. - /// - public readonly BindableBool Enabled = new BindableBool(true); - private FlowContainer sections; /// @@ -34,27 +29,6 @@ namespace osu.Game.Overlays /// public Func GetToolbarHeight; - public NotificationOverlay() - { - ScheduledDelegate notificationsEnabler = null; - Enabled.ValueChanged += v => - { - if (!IsLoaded) - { - processingPosts = v; - return; - } - - notificationsEnabler?.Cancel(); - - if (v) - // we want a slight delay before toggling notifications on to avoid the user becoming overwhelmed. - notificationsEnabler = Scheduler.AddDelayed(() => processingPosts = true, 1000); - else - processingPosts = false; - }; - } - [BackgroundDependencyLoader] private void load() { @@ -103,6 +77,29 @@ namespace osu.Game.Overlays }; } + private ScheduledDelegate notificationsEnabler; + private void updateProcessingMode() + { + bool enabled = OverlayActivationMode == OverlayActivation.All || State == Visibility.Visible; + + notificationsEnabler?.Cancel(); + + if (enabled) + // we want a slight delay before toggling notifications on to avoid the user becoming overwhelmed. + notificationsEnabler = Scheduler.AddDelayed(() => processingPosts = true, State == Visibility.Visible ? 0 : 1000); + else + processingPosts = false; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + StateChanged += _ => updateProcessingMode(); + OverlayActivationMode.ValueChanged += _ => updateProcessingMode(); + OverlayActivationMode.TriggerChange(); + } + private int totalCount => sections.Select(c => c.DisplayedCount).Sum(); private int unreadCount => sections.Select(c => c.UnreadCount).Sum(); From 55921efffb5ab4533078a554c9483afb2064b584 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 16:17:51 +0900 Subject: [PATCH 138/262] Rewrite much state logic --- osu.Game/OsuGame.cs | 42 ++++++++++++++++----------- osu.Game/Screens/Menu/ButtonSystem.cs | 11 ++++++- osu.Game/Screens/Menu/Disclaimer.cs | 2 +- osu.Game/Screens/Menu/Intro.cs | 2 +- osu.Game/Screens/Menu/MainMenu.cs | 2 -- osu.Game/Screens/OsuScreen.cs | 16 +++------- osu.Game/Screens/Play/Player.cs | 2 +- 7 files changed, 42 insertions(+), 35 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 68c50dafab..36c76851c6 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -93,6 +93,8 @@ namespace osu.Game private SettingsOverlay settings; + private readonly List overlays = new List(); + // todo: move this to SongSelect once Screen has the ability to unsuspend. public readonly Bindable> SelectedMods = new Bindable>(new List()); @@ -105,6 +107,17 @@ namespace osu.Game public void ToggleDirect() => direct.ToggleVisibility(); + /// + /// Close all game-wide overlays. + /// + /// Whether the toolbar should also be hidden. + public void CloseAllOverlays(bool toolbar = true) + { + foreach (var o in overlays) + o.State = Visibility.Hidden; + if (toolbar) Toolbar.State = Visibility.Hidden; + } + private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => @@ -250,7 +263,7 @@ namespace osu.Game Depth = -5, OnHome = delegate { - hideAllOverlays(); + CloseAllOverlays(false); intro?.ChildScreen?.MakeCurrent(); }, }, overlayContent.Add); @@ -307,6 +320,8 @@ namespace osu.Game // ensure only one of these overlays are open at once. var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct }; + overlays.AddRange(singleDisplayOverlays); + foreach (var overlay in singleDisplayOverlays) { overlay.StateChanged += state => @@ -322,6 +337,8 @@ namespace osu.Game } var singleDisplaySideOverlays = new OverlayContainer[] { settings, notifications }; + overlays.AddRange(singleDisplaySideOverlays); + foreach (var overlay in singleDisplaySideOverlays) { overlay.StateChanged += state => @@ -338,6 +355,8 @@ namespace osu.Game // eventually informational overlays should be displayed in a stack, but for now let's only allow one to stay open at a time. var informationalOverlays = new OverlayContainer[] { beatmapSetOverlay, userProfile }; + overlays.AddRange(informationalOverlays); + foreach (var overlay in informationalOverlays) { overlay.StateChanged += state => @@ -352,6 +371,11 @@ namespace osu.Game }; } + OverlayActivationMode.ValueChanged += v => + { + if (v != OverlayActivation.All) CloseAllOverlays(); + }; + void updateScreenOffset() { float offset = 0; @@ -368,12 +392,6 @@ namespace osu.Game notifications.StateChanged += _ => updateScreenOffset(); } - public void CloseAllOverlays() - { - hideAllOverlays(); - musicController.State = Visibility.Hidden; - } - private void forwardLoggedErrorsToNotifications() { int recentErrorCount = 0; @@ -488,16 +506,6 @@ namespace osu.Game private OsuScreen currentScreen; private FrameworkConfigManager frameworkConfig; - private void hideAllOverlays() - { - settings.State = Visibility.Hidden; - chat.State = Visibility.Hidden; - direct.State = Visibility.Hidden; - social.State = Visibility.Hidden; - userProfile.State = Visibility.Hidden; - notifications.State = Visibility.Hidden; - } - protected override bool OnExiting() { if (screenStack.ChildScreen == null) return false; diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index a0f2fc45cd..7235a96e15 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -16,6 +16,7 @@ using osu.Framework.Input.Bindings; using osu.Framework.Threading; using osu.Game.Graphics; using osu.Game.Input.Bindings; +using osu.Game.Overlays; using OpenTK; using OpenTK.Graphics; using OpenTK.Input; @@ -129,9 +130,12 @@ namespace osu.Game.Screens.Menu buttonFlow.AddRange(buttonsTopLevel); } + private OsuGame game; + [BackgroundDependencyLoader(true)] - private void load(AudioManager audio) + private void load(AudioManager audio, OsuGame game) { + this.game = game; sampleBack = audio.Sample.Get(@"Menu/button-back-select"); } @@ -321,6 +325,8 @@ namespace osu.Game.Screens.Menu { logoTracking = false; + game.OverlayActivationMode.Value = state == MenuState.Exit ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; + logo.ClearTransforms(targetMember: nameof(Position)); logo.RelativePositionAxes = Axes.Both; @@ -352,6 +358,9 @@ namespace osu.Game.Screens.Menu if (impact) logo.Impact(); + + game.OverlayActivationMode.Value = OverlayActivation.All; + game.Toolbar.State = Visibility.Visible; }, 200); break; default: diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index 2436f0a940..0c70dbf570 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -20,7 +20,7 @@ namespace osu.Game.Screens.Menu private Color4 iconColour; protected override bool HideOverlaysOnEnter => true; - protected override OverlayActivation OverlayActivationLevel => OverlayActivation.Disabled; + protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled; public override bool CursorVisible => false; diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index d58f0e95b5..c5bd345a31 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -33,7 +33,7 @@ namespace osu.Game.Screens.Menu private SampleChannel seeya; protected override bool HideOverlaysOnEnter => true; - protected override OverlayActivation OverlayActivationLevel => OverlayActivation.Disabled; + protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled; public override bool CursorVisible => false; diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index 8eddaaee93..cbdd8b4e8b 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -63,8 +63,6 @@ namespace osu.Game.Screens.Menu }, sideFlashes = new MenuSideFlashes(), }; - - buttons.StateChanged += state => UpdateOverlayStates?.Invoke(); } [BackgroundDependencyLoader(true)] diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index ba9c65e42d..d98aac8f84 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -44,22 +44,17 @@ namespace osu.Game.Screens private Action updateOverlayStates; - /// - /// Allows manually updating visibility of all overlays if is not enough. - /// - protected Action UpdateOverlayStates => updateOverlayStates; - /// /// Whether all overlays should be hidden when this screen is entered or resumed. /// protected virtual bool HideOverlaysOnEnter => false; - private readonly Bindable allowOverlays = new Bindable(); + protected readonly Bindable OverlayActivationMode = new Bindable(); /// /// Whether overlays should be able to be opened once this screen is entered or resumed. /// - protected virtual OverlayActivation OverlayActivationLevel => OverlayActivation.All; + protected virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; /// /// Whether this allows the cursor to be displayed. @@ -110,15 +105,12 @@ namespace osu.Game.Screens if (osuGame != null) { Ruleset.BindTo(osuGame.Ruleset); - allowOverlays.BindTo(osuGame.OverlayActivationMode); + OverlayActivationMode.BindTo(osuGame.OverlayActivationMode); updateOverlayStates = () => { if (HideOverlaysOnEnter) - { osuGame.CloseAllOverlays(); - osuGame.Toolbar.State = Visibility.Hidden; - } else osuGame.Toolbar.State = Visibility.Visible; }; @@ -257,7 +249,7 @@ namespace osu.Game.Screens if (backgroundParallaxContainer != null) backgroundParallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * BackgroundParallaxAmount; - allowOverlays.Value = OverlayActivationLevel; + OverlayActivationMode.Value = InitialOverlayActivationMode; updateOverlayStates?.Invoke(); } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 6e0f6cb1c5..54f65e3991 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -38,7 +38,7 @@ namespace osu.Game.Screens.Play protected override bool HideOverlaysOnEnter => true; - protected override OverlayActivation OverlayActivationLevel => OverlayActivation.UserTriggered; + protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; public Action RestartRequested; From 83ff47ec80ced52260d528ec0eccbf442896e704 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Jun 2018 16:20:17 +0900 Subject: [PATCH 139/262] 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 aaaa8a3b7c8b77c8f9adb421a414c0e2ebce90e9 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Wed, 6 Jun 2018 09:55:16 +0200 Subject: [PATCH 140/262] match Bindable names --- osu.Game/Overlays/Toolbar/Toolbar.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 1eaf748011..48d0674b3d 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -31,7 +31,7 @@ namespace osu.Game.Overlays.Toolbar private const float alpha_hovering = 0.8f; private const float alpha_normal = 0.6f; - private readonly Bindable allowOverlays = new Bindable(OverlayActivation.All); + private readonly Bindable overlayActivationMode = new Bindable(OverlayActivation.All); public Toolbar() { @@ -84,11 +84,11 @@ namespace osu.Game.Overlays.Toolbar private void load(OsuGame osuGame) { if (osuGame != null) - allowOverlays.BindTo(osuGame.OverlayActivationMode); + overlayActivationMode.BindTo(osuGame.OverlayActivationMode); StateChanged += visibility => { - if (allowOverlays == OverlayActivation.Disabled) + if (overlayActivationMode == OverlayActivation.Disabled) State = Visibility.Hidden; }; } From 9306fec4982e9b347481fd371ac2346a1c270bb7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 18:21:03 +0900 Subject: [PATCH 141/262] Fix missing null checks --- osu.Game/Screens/Menu/ButtonSystem.cs | 24 ++++++++++++++---------- 1 file changed, 14 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 7235a96e15..42e25aad43 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -322,17 +322,18 @@ namespace osu.Game.Screens.Menu case MenuState.Initial: logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => - { - logoTracking = false; + { + logoTracking = false; - game.OverlayActivationMode.Value = state == MenuState.Exit ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; + if (game != null) + game.OverlayActivationMode.Value = state == MenuState.Exit ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; - logo.ClearTransforms(targetMember: nameof(Position)); - logo.RelativePositionAxes = Axes.Both; + logo.ClearTransforms(targetMember: nameof(Position)); + logo.RelativePositionAxes = Axes.Both; - logo.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo); - logo.ScaleTo(1, 800, Easing.OutExpo); - }, buttonArea.Alpha * 150); + logo.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo); + logo.ScaleTo(1, 800, Easing.OutExpo); + }, buttonArea.Alpha * 150); break; case MenuState.TopLevel: case MenuState.Play: @@ -359,8 +360,11 @@ namespace osu.Game.Screens.Menu if (impact) logo.Impact(); - game.OverlayActivationMode.Value = OverlayActivation.All; - game.Toolbar.State = Visibility.Visible; + if (game != null) + { + game.OverlayActivationMode.Value = OverlayActivation.All; + game.Toolbar.State = Visibility.Visible; + } }, 200); break; default: From 0a97b8ae2506c74c68b8fcf869a38c97c93993f8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 18:33:10 +0900 Subject: [PATCH 142/262] Implement DebugUtils locally Has been removed from framework --- osu.Game/OsuGameBase.cs | 2 +- osu.Game/Overlays/Settings/SettingsFooter.cs | 2 +- osu.Game/Utils/DebugUtils.cs | 21 ++++++++++++++++++++ 3 files changed, 23 insertions(+), 2 deletions(-) create mode 100644 osu.Game/Utils/DebugUtils.cs diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index fcc2d42321..f170f1c00f 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -10,7 +10,6 @@ using System.Reflection; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Configuration; -using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.IO.Stores; @@ -31,6 +30,7 @@ using osu.Game.IO; using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; +using DebugUtils = osu.Game.Utils.DebugUtils; namespace osu.Game { diff --git a/osu.Game/Overlays/Settings/SettingsFooter.cs b/osu.Game/Overlays/Settings/SettingsFooter.cs index 900f03fe7b..909fc20446 100644 --- a/osu.Game/Overlays/Settings/SettingsFooter.cs +++ b/osu.Game/Overlays/Settings/SettingsFooter.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -12,6 +11,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Rulesets; using OpenTK; using OpenTK.Graphics; +using DebugUtils = osu.Game.Utils.DebugUtils; namespace osu.Game.Overlays.Settings { diff --git a/osu.Game/Utils/DebugUtils.cs b/osu.Game/Utils/DebugUtils.cs new file mode 100644 index 0000000000..191662c690 --- /dev/null +++ b/osu.Game/Utils/DebugUtils.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Utils +{ + public static class DebugUtils + { + public static bool IsDebug + { + get + { + // ReSharper disable once RedundantAssignment + bool isDebug = false; + // Debug.Assert conditions are only evaluated in debug mode + System.Diagnostics.Debug.Assert(isDebug = true); + // ReSharper disable once ConditionIsAlwaysTrueOrFalse + return isDebug; + } + } + } +} From aeeb03ff9cfaa77037a177137f612562539a8d80 Mon Sep 17 00:00:00 2001 From: ekrctb Date: Wed, 6 Jun 2018 18:36:43 +0900 Subject: [PATCH 143/262] simpler temporary path generation --- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 645c76f265..1c9696901c 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -264,7 +264,7 @@ namespace osu.Game.Tests.Beatmaps.IO private string createTemporaryBeatmap() { - var temp = Path.GetTempFileName() + Guid.NewGuid() + ".osz"; + var temp = Path.GetTempFileName() + ".osz"; File.Copy(osz_path, temp, true); Assert.IsTrue(File.Exists(temp)); return temp; From 72cc53aded4395589606f15747a53c6f0bb3ddad Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Jun 2018 20:16:20 +0900 Subject: [PATCH 144/262] Rename GameBeatmap -> BindableBeatmap --- .../UI/Cursor/GameplayCursor.cs | 2 +- .../{GameBeatmap.cs => BindableBeatmap.cs} | 14 ++++++------- .../{IGameBeatmap.cs => IBindableBeatmap.cs} | 8 ++++---- .../Containers/BeatSyncedContainer.cs | 2 +- osu.Game/OsuGameBase.cs | 20 +++++++++---------- osu.Game/Overlays/Music/PlaylistList.cs | 2 +- osu.Game/Overlays/Music/PlaylistOverlay.cs | 4 ++-- osu.Game/Overlays/MusicController.cs | 4 ++-- osu.Game/Rulesets/Edit/HitObjectComposer.cs | 2 +- .../Edit/Components/BottomBarContainer.cs | 2 +- .../Timelines/Summary/Parts/TimelinePart.cs | 2 +- .../Timeline/ScrollingTimelineContainer.cs | 2 +- osu.Game/Screens/Edit/Screens/EditorScreen.cs | 2 +- osu.Game/Screens/Menu/Intro.cs | 4 ++-- osu.Game/Screens/Menu/LogoVisualisation.cs | 2 +- osu.Game/Screens/Menu/MenuSideFlashes.cs | 2 +- osu.Game/Screens/OsuScreen.cs | 2 +- osu.Game/Screens/Select/PlaySongSelect.cs | 4 ++-- osu.Game/Screens/Select/SongSelect.cs | 4 ++-- .../Drawables/DrawableStoryboardAnimation.cs | 2 +- .../Drawables/DrawableStoryboardSprite.cs | 2 +- osu.Game/Tests/Visual/OsuTestCase.cs | 10 +++++----- .../Tests/Visual/TestCasePerformancePoints.cs | 12 +++++------ 23 files changed, 55 insertions(+), 55 deletions(-) rename osu.Game/Beatmaps/{GameBeatmap.cs => BindableBeatmap.cs} (79%) rename osu.Game/Beatmaps/{IGameBeatmap.cs => IBindableBeatmap.cs} (60%) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs index d34ecfac22..b6e639ea52 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor } [BackgroundDependencyLoader] - private void load(OsuConfigManager config, IGameBeatmap beatmap) + private void load(OsuConfigManager config, IBindableBeatmap beatmap) { Child = cursorContainer = new SkinnableDrawable("cursor", _ => new CircularContainer { diff --git a/osu.Game/Beatmaps/GameBeatmap.cs b/osu.Game/Beatmaps/BindableBeatmap.cs similarity index 79% rename from osu.Game/Beatmaps/GameBeatmap.cs rename to osu.Game/Beatmaps/BindableBeatmap.cs index e470dd8ac5..34d9cd3d25 100644 --- a/osu.Game/Beatmaps/GameBeatmap.cs +++ b/osu.Game/Beatmaps/BindableBeatmap.cs @@ -12,14 +12,14 @@ namespace osu.Game.Beatmaps { /// /// A for the beatmap. - /// This should be used sparingly in-favour of . + /// This should be used sparingly in-favour of . /// - public abstract class GameBeatmap : NonNullableBindable, IGameBeatmap + public abstract class BindableBeatmap : NonNullableBindable, IBindableBeatmap { private AudioManager audioManager; private WorkingBeatmap lastBeatmap; - protected GameBeatmap(WorkingBeatmap defaultValue) + protected BindableBeatmap(WorkingBeatmap defaultValue) : base(defaultValue) { } @@ -63,13 +63,13 @@ namespace osu.Game.Beatmaps } [NotNull] - IGameBeatmap IGameBeatmap.GetBoundCopy() => GetBoundCopy(); + IBindableBeatmap IBindableBeatmap.GetBoundCopy() => GetBoundCopy(); /// - /// Retrieve a new instance weakly bound to this . - /// If you are further binding to events of the retrieved , ensure a local reference is held. + /// Retrieve a new instance weakly bound to this . + /// If you are further binding to events of the retrieved , ensure a local reference is held. /// [NotNull] - public abstract GameBeatmap GetBoundCopy(); + public abstract BindableBeatmap GetBoundCopy(); } } diff --git a/osu.Game/Beatmaps/IGameBeatmap.cs b/osu.Game/Beatmaps/IBindableBeatmap.cs similarity index 60% rename from osu.Game/Beatmaps/IGameBeatmap.cs rename to osu.Game/Beatmaps/IBindableBeatmap.cs index b2840f1c7e..329c0b6a3c 100644 --- a/osu.Game/Beatmaps/IGameBeatmap.cs +++ b/osu.Game/Beatmaps/IBindableBeatmap.cs @@ -8,12 +8,12 @@ namespace osu.Game.Beatmaps /// /// Read-only interface for the beatmap. /// - public interface IGameBeatmap : IBindable + public interface IBindableBeatmap : IBindable { /// - /// Retrieve a new instance weakly bound to this . - /// If you are further binding to events of the retrieved , ensure a local reference is held. + /// Retrieve a new instance weakly bound to this . + /// If you are further binding to events of the retrieved , ensure a local reference is held. /// - IGameBeatmap GetBoundCopy(); + IBindableBeatmap GetBoundCopy(); } } diff --git a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs index 92e38033a9..f0d49af988 100644 --- a/osu.Game/Graphics/Containers/BeatSyncedContainer.cs +++ b/osu.Game/Graphics/Containers/BeatSyncedContainer.cs @@ -74,7 +74,7 @@ namespace osu.Game.Graphics.Containers } [BackgroundDependencyLoader] - private void load(IGameBeatmap beatmap) + private void load(IBindableBeatmap beatmap) { Beatmap.BindTo(beatmap); } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index b258c059d9..395ae1bea9 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -64,8 +64,8 @@ namespace osu.Game protected override Container Content => content; - private OsuGameBeatmap beatmap; - protected GameBeatmap Beatmap => beatmap; + private OsuBindableBeatmap beatmap; + protected BindableBeatmap Beatmap => beatmap; private Bindable fpsDisplayVisible; @@ -157,15 +157,15 @@ namespace osu.Game Fonts.AddStore(new GlyphStore(Resources, @"Fonts/Venera-Light")); var defaultBeatmap = new DummyWorkingBeatmap(this); - beatmap = new OsuGameBeatmap(defaultBeatmap, Audio); + beatmap = new OsuBindableBeatmap(defaultBeatmap, Audio); BeatmapManager.DefaultBeatmap = defaultBeatmap; // tracks play so loud our samples can't keep up. // this adds a global reduction of track volume for the time being. Audio.Track.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8)); - dependencies.CacheAs(beatmap); - dependencies.CacheAs(beatmap); + dependencies.CacheAs(beatmap); + dependencies.CacheAs(beatmap); FileStore.Cleanup(); @@ -237,22 +237,22 @@ namespace osu.Game public string[] HandledExtensions => fileImporters.SelectMany(i => i.HandledExtensions).ToArray(); - private class OsuGameBeatmap : GameBeatmap + private class OsuBindableBeatmap : BindableBeatmap { - public OsuGameBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) + public OsuBindableBeatmap(WorkingBeatmap defaultValue, AudioManager audioManager) : this(defaultValue) { RegisterAudioManager(audioManager); } - private OsuGameBeatmap(WorkingBeatmap defaultValue) + private OsuBindableBeatmap(WorkingBeatmap defaultValue) : base(defaultValue) { } - public override GameBeatmap GetBoundCopy() + public override BindableBeatmap GetBoundCopy() { - var copy = new OsuGameBeatmap(Default); + var copy = new OsuBindableBeatmap(Default); copy.BindTo(this); return copy; } diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index ce1dd42015..19ce0cf932 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -73,7 +73,7 @@ namespace osu.Game.Overlays.Music } [BackgroundDependencyLoader] - private void load(BeatmapManager beatmaps, IGameBeatmap beatmap) + private void load(BeatmapManager beatmaps, IBindableBeatmap beatmap) { beatmaps.GetAllUsableBeatmapSets().ForEach(addBeatmapSet); beatmaps.ItemAdded += addBeatmapSet; diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 5efe347ba5..440ac15791 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -26,14 +26,14 @@ namespace osu.Game.Overlays.Music /// public Action OrderChanged; - private GameBeatmap beatmap; + private BindableBeatmap beatmap; private BeatmapManager beatmaps; private FilterControl filter; private PlaylistList list; [BackgroundDependencyLoader] - private void load(OsuColour colours, GameBeatmap beatmap, BeatmapManager beatmaps) + private void load(OsuColour colours, BindableBeatmap beatmap, BeatmapManager beatmaps) { this.beatmap = beatmap.GetBoundCopy(); this.beatmaps = beatmaps; diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 733b37cec0..2ef48f9ffa 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -54,7 +54,7 @@ namespace osu.Game.Overlays private Container dragContainer; private Container playerContainer; - private GameBeatmap beatmap; + private BindableBeatmap beatmap; public MusicController() { @@ -94,7 +94,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(GameBeatmap beatmap, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation) + private void load(BindableBeatmap beatmap, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation) { this.beatmap = beatmap.GetBoundCopy(); this.beatmaps = beatmaps; diff --git a/osu.Game/Rulesets/Edit/HitObjectComposer.cs b/osu.Game/Rulesets/Edit/HitObjectComposer.cs index 443b4fd756..0c91c9f548 100644 --- a/osu.Game/Rulesets/Edit/HitObjectComposer.cs +++ b/osu.Game/Rulesets/Edit/HitObjectComposer.cs @@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Edit } [BackgroundDependencyLoader] - private void load(IGameBeatmap beatmap, IFrameBasedClock framedClock) + private void load(IBindableBeatmap beatmap, IFrameBasedClock framedClock) { this.beatmap.BindTo(beatmap); diff --git a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs index 81a5b24483..caf9ba27ff 100644 --- a/osu.Game/Screens/Edit/Components/BottomBarContainer.cs +++ b/osu.Game/Screens/Edit/Components/BottomBarContainer.cs @@ -42,7 +42,7 @@ namespace osu.Game.Screens.Edit.Components } [BackgroundDependencyLoader] - private void load(IGameBeatmap beatmap, OsuColour colours) + private void load(IBindableBeatmap beatmap, OsuColour colours) { Beatmap.BindTo(beatmap); background.Colour = colours.Gray1; diff --git a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs index 0aeeef717e..07d9398d38 100644 --- a/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs +++ b/osu.Game/Screens/Edit/Components/Timelines/Summary/Parts/TimelinePart.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.Edit.Components.Timelines.Summary.Parts } [BackgroundDependencyLoader] - private void load(IGameBeatmap beatmap) + private void load(IBindableBeatmap beatmap) { Beatmap.BindTo(beatmap); } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index 5f2e8525a6..dfc6b41432 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -44,7 +44,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline } [BackgroundDependencyLoader] - private void load(IGameBeatmap beatmap) + private void load(IBindableBeatmap beatmap) { this.beatmap.BindTo(beatmap); diff --git a/osu.Game/Screens/Edit/Screens/EditorScreen.cs b/osu.Game/Screens/Edit/Screens/EditorScreen.cs index b7c0dee5e3..f8402b9a9f 100644 --- a/osu.Game/Screens/Edit/Screens/EditorScreen.cs +++ b/osu.Game/Screens/Edit/Screens/EditorScreen.cs @@ -29,7 +29,7 @@ namespace osu.Game.Screens.Edit.Screens } [BackgroundDependencyLoader] - private void load(IGameBeatmap beatmap) + private void load(IBindableBeatmap beatmap) { Beatmap.BindTo(beatmap); } diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index 927884f6d5..0f374c7d4d 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Menu /// public bool DidLoadMenu; - private GameBeatmap beatmapBacking; + private BindableBeatmap beatmapBacking; private MainMenu mainMenu; private SampleChannel welcome; @@ -46,7 +46,7 @@ namespace osu.Game.Screens.Menu private WorkingBeatmap beatmap; [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game, GameBeatmap beatmap) + private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game, BindableBeatmap beatmap) { beatmapBacking = beatmap.GetBoundCopy(); diff --git a/osu.Game/Screens/Menu/LogoVisualisation.cs b/osu.Game/Screens/Menu/LogoVisualisation.cs index 9773ca0834..fb6130fa36 100644 --- a/osu.Game/Screens/Menu/LogoVisualisation.cs +++ b/osu.Game/Screens/Menu/LogoVisualisation.cs @@ -78,7 +78,7 @@ namespace osu.Game.Screens.Menu } [BackgroundDependencyLoader] - private void load(ShaderManager shaders, IGameBeatmap beatmap) + private void load(ShaderManager shaders, IBindableBeatmap beatmap) { this.beatmap.BindTo(beatmap); shader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, FragmentShaderDescriptor.TEXTURE_ROUNDED); diff --git a/osu.Game/Screens/Menu/MenuSideFlashes.cs b/osu.Game/Screens/Menu/MenuSideFlashes.cs index 4b65fb86f5..7d46aad089 100644 --- a/osu.Game/Screens/Menu/MenuSideFlashes.cs +++ b/osu.Game/Screens/Menu/MenuSideFlashes.cs @@ -45,7 +45,7 @@ namespace osu.Game.Screens.Menu } [BackgroundDependencyLoader] - private void load(IGameBeatmap beatmap, OsuColour colours) + private void load(IBindableBeatmap beatmap, OsuColour colours) { this.beatmap.BindTo(beatmap); diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 3494efb362..56d241d2c8 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -79,7 +79,7 @@ namespace osu.Game.Screens private SampleChannel sampleExit; [BackgroundDependencyLoader(permitNulls: true)] - private void load(IGameBeatmap beatmap, OsuGame osuGame, AudioManager audio) + private void load(IBindableBeatmap beatmap, OsuGame osuGame, AudioManager audio) { if (beatmap != null) Beatmap.BindTo(beatmap); diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index a026857210..b73beb80a0 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -30,7 +30,7 @@ namespace osu.Game.Screens.Select protected readonly BeatmapDetailArea BeatmapDetails; private bool removeAutoModOnResume; - private GameBeatmap beatmap; + private BindableBeatmap beatmap; public PlaySongSelect() { @@ -55,7 +55,7 @@ namespace osu.Game.Screens.Select public readonly Bindable> SelectedMods = new Bindable>(new List()); [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame osu, GameBeatmap beatmap) + private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame osu, BindableBeatmap beatmap) { this.beatmap = beatmap.GetBoundCopy(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index f0403d8b24..52880418b8 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -62,7 +62,7 @@ namespace osu.Game.Screens.Select private SampleChannel sampleChangeDifficulty; private SampleChannel sampleChangeBeatmap; - private GameBeatmap beatmap; + private BindableBeatmap beatmap; private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) @@ -179,7 +179,7 @@ namespace osu.Game.Screens.Select } [BackgroundDependencyLoader(permitNulls: true)] - private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours, GameBeatmap beatmap) + private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours, BindableBeatmap beatmap) { this.beatmap = beatmap.GetBoundCopy(); diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs index 253902fb81..d15f3053a3 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs @@ -64,7 +64,7 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader] - private void load(IGameBeatmap beatmap, TextureStore textureStore) + private void load(IBindableBeatmap beatmap, TextureStore textureStore) { var basePath = Animation.Path.ToLowerInvariant(); for (var frame = 0; frame < Animation.FrameCount; frame++) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs index f3fb5e368a..efbb3de253 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs @@ -63,7 +63,7 @@ namespace osu.Game.Storyboards.Drawables } [BackgroundDependencyLoader] - private void load(IGameBeatmap beatmap, TextureStore textureStore) + private void load(IBindableBeatmap beatmap, TextureStore textureStore) { var spritePath = Sprite.Path.ToLowerInvariant(); var path = beatmap.Value.BeatmapSetInfo.Files.FirstOrDefault(f => f.Filename.ToLowerInvariant() == spritePath)?.FileInfo.StoragePath; diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index ec1729ac5b..f98aca4dff 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -13,7 +13,7 @@ namespace osu.Game.Tests.Visual public abstract class OsuTestCase : TestCase { private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap()); - protected GameBeatmap Beatmap => beatmap; + protected BindableBeatmap Beatmap => beatmap; private DependencyContainer dependencies; @@ -21,8 +21,8 @@ namespace osu.Game.Tests.Visual { dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - dependencies.CacheAs(beatmap); - dependencies.CacheAs(beatmap); + dependencies.CacheAs(beatmap); + dependencies.CacheAs(beatmap); return dependencies; } @@ -63,7 +63,7 @@ namespace osu.Game.Tests.Visual public void RunTestBlocking(TestCase test) => runner.RunTestBlocking(test); } - private class OsuTestBeatmap : GameBeatmap + private class OsuTestBeatmap : BindableBeatmap { public OsuTestBeatmap(WorkingBeatmap defaultValue) : base(defaultValue) @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual public void SetAudioManager(AudioManager audioManager) => RegisterAudioManager(audioManager); - public override GameBeatmap GetBoundCopy() + public override BindableBeatmap GetBoundCopy() { var copy = new OsuTestBeatmap(Default); copy.BindTo(this); diff --git a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs index b6d92f4ec5..dfae8fbc1d 100644 --- a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs +++ b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs @@ -108,9 +108,9 @@ namespace osu.Game.Tests.Visual { private readonly Container beatmapDisplays; private readonly Ruleset ruleset; - private readonly GameBeatmap beatmapBindable; + private readonly BindableBeatmap beatmapBindable; - public BeatmapList(Ruleset ruleset, GameBeatmap beatmapBindable) + public BeatmapList(Ruleset ruleset, BindableBeatmap beatmapBindable) { this.ruleset = ruleset; this.beatmapBindable = beatmapBindable; @@ -140,7 +140,7 @@ namespace osu.Game.Tests.Visual private readonly OsuSpriteText text; private readonly BeatmapInfo beatmap; - private readonly GameBeatmap beatmapBindable; + private readonly BindableBeatmap beatmapBindable; private BeatmapManager beatmaps; @@ -148,7 +148,7 @@ namespace osu.Game.Tests.Visual public string TooltipText => text.Text; - public BeatmapDisplay(BeatmapInfo beatmap, GameBeatmap beatmapBindable) + public BeatmapDisplay(BeatmapInfo beatmap, BindableBeatmap beatmapBindable) { this.beatmap = beatmap; this.beatmapBindable = beatmapBindable; @@ -223,7 +223,7 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(IGameBeatmap beatmap, APIAccess api) + private void load(IBindableBeatmap beatmap, APIAccess api) { this.api = api; @@ -336,7 +336,7 @@ namespace osu.Game.Tests.Visual } [BackgroundDependencyLoader] - private void load(IGameBeatmap beatmap) + private void load(IBindableBeatmap beatmap) { beatmap.ValueChanged += beatmapChanged; } From ff60f69f47be9a5703d2790956e379b7ff1a4ecd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Jun 2018 20:19:30 +0900 Subject: [PATCH 145/262] Explicitly construct local beatmaps rather than using GetBoundCopy --- osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs | 4 ++-- osu.Game/Overlays/Music/PlaylistOverlay.cs | 5 +++-- osu.Game/Overlays/MusicController.cs | 5 +++-- osu.Game/Screens/Menu/Intro.cs | 12 ++++++------ 4 files changed, 14 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs index b6e639ea52..240d8dc396 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private Bindable cursorScale; private Bindable autoCursorScale; - private IBindable beatmap; + private readonly IBindable beatmap = new Bindable(); public OsuCursor() { @@ -160,7 +160,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor RelativeSizeAxes = Axes.Both, }; - this.beatmap = beatmap.GetBoundCopy(); + this.beatmap.BindTo(beatmap); beatmap.ValueChanged += v => calculateScale(); cursorScale = config.GetBindable(OsuSetting.GameplayCursorSize); diff --git a/osu.Game/Overlays/Music/PlaylistOverlay.cs b/osu.Game/Overlays/Music/PlaylistOverlay.cs index 440ac15791..b74e7e1178 100644 --- a/osu.Game/Overlays/Music/PlaylistOverlay.cs +++ b/osu.Game/Overlays/Music/PlaylistOverlay.cs @@ -4,6 +4,7 @@ using System; using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -26,7 +27,7 @@ namespace osu.Game.Overlays.Music /// public Action OrderChanged; - private BindableBeatmap beatmap; + private readonly Bindable beatmap = new Bindable(); private BeatmapManager beatmaps; private FilterControl filter; @@ -35,7 +36,7 @@ namespace osu.Game.Overlays.Music [BackgroundDependencyLoader] private void load(OsuColour colours, BindableBeatmap beatmap, BeatmapManager beatmaps) { - this.beatmap = beatmap.GetBoundCopy(); + this.beatmap.BindTo(beatmap); this.beatmaps = beatmaps; Children = new Drawable[] diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 2ef48f9ffa..18e5379224 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; +using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -54,7 +55,7 @@ namespace osu.Game.Overlays private Container dragContainer; private Container playerContainer; - private BindableBeatmap beatmap; + private readonly Bindable beatmap = new Bindable(); public MusicController() { @@ -96,7 +97,7 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load(BindableBeatmap beatmap, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation) { - this.beatmap = beatmap.GetBoundCopy(); + this.beatmap.BindTo(beatmap); this.beatmaps = beatmaps; this.localisation = localisation; diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index 0f374c7d4d..b0472ae705 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -27,7 +27,7 @@ namespace osu.Game.Screens.Menu /// public bool DidLoadMenu; - private BindableBeatmap beatmapBacking; + private readonly Bindable beatmap = new Bindable(); private MainMenu mainMenu; private SampleChannel welcome; @@ -43,12 +43,12 @@ namespace osu.Game.Screens.Menu private Bindable menuVoice; private Bindable menuMusic; private Track track; - private WorkingBeatmap beatmap; + private WorkingBeatmap introBeatmap; [BackgroundDependencyLoader] private void load(AudioManager audio, OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game, BindableBeatmap beatmap) { - beatmapBacking = beatmap.GetBoundCopy(); + this.beatmap.BindTo(beatmap); menuVoice = config.GetBindable(OsuSetting.MenuVoice); menuMusic = config.GetBindable(OsuSetting.MenuMusic); @@ -76,8 +76,8 @@ namespace osu.Game.Screens.Menu } } - this.beatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); - track = this.beatmap.Track; + introBeatmap = beatmaps.GetWorkingBeatmap(setInfo.Beatmaps[0]); + track = introBeatmap.Track; welcome = audio.Sample.Get(@"welcome"); seeya = audio.Sample.Get(@"seeya"); @@ -94,7 +94,7 @@ namespace osu.Game.Screens.Menu if (!resuming) { - beatmapBacking.Value = beatmap; + beatmap.Value = introBeatmap; if (menuVoice) welcome.Play(); From e77084bec446f947a053a249336054a175f1ffad Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Jun 2018 20:19:53 +0900 Subject: [PATCH 146/262] Give OsuScreen a mutable BindableBeatmap --- osu.Game/Screens/OsuScreen.cs | 6 +++--- osu.Game/Screens/Select/PlaySongSelect.cs | 8 ++------ osu.Game/Screens/Select/SongSelect.cs | 12 ++++-------- 3 files changed, 9 insertions(+), 17 deletions(-) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 56d241d2c8..bfe1778f39 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -68,7 +68,7 @@ namespace osu.Game.Screens /// public virtual bool AllowBeatmapRulesetChange => true; - protected readonly IBindable Beatmap = new Bindable(); + protected readonly Bindable Beatmap = new Bindable(); protected virtual float BackgroundParallaxAmount => 1; @@ -78,8 +78,8 @@ namespace osu.Game.Screens private SampleChannel sampleExit; - [BackgroundDependencyLoader(permitNulls: true)] - private void load(IBindableBeatmap beatmap, OsuGame osuGame, AudioManager audio) + [BackgroundDependencyLoader(true)] + private void load(BindableBeatmap beatmap, OsuGame osuGame, AudioManager audio) { if (beatmap != null) Beatmap.BindTo(beatmap); diff --git a/osu.Game/Screens/Select/PlaySongSelect.cs b/osu.Game/Screens/Select/PlaySongSelect.cs index b73beb80a0..8ce40fcfa0 100644 --- a/osu.Game/Screens/Select/PlaySongSelect.cs +++ b/osu.Game/Screens/Select/PlaySongSelect.cs @@ -30,8 +30,6 @@ namespace osu.Game.Screens.Select protected readonly BeatmapDetailArea BeatmapDetails; private bool removeAutoModOnResume; - private BindableBeatmap beatmap; - public PlaySongSelect() { FooterPanels.Add(modSelect = new ModSelectOverlay @@ -55,10 +53,8 @@ namespace osu.Game.Screens.Select public readonly Bindable> SelectedMods = new Bindable>(new List()); [BackgroundDependencyLoader(true)] - private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame osu, BindableBeatmap beatmap) + private void load(OsuColour colours, AudioManager audio, BeatmapManager beatmaps, DialogOverlay dialogOverlay, OsuGame osu) { - this.beatmap = beatmap.GetBoundCopy(); - if (osu != null) SelectedMods.BindTo(osu.SelectedMods); modSelect.SelectedMods.BindTo(SelectedMods); @@ -160,7 +156,7 @@ namespace osu.Game.Screens.Select } Beatmap.Value.Track.Looping = false; - beatmap.Disabled = true; + Beatmap.Disabled = true; sampleConfirm?.Play(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 52880418b8..b04ffecf48 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -62,8 +62,6 @@ namespace osu.Game.Screens.Select private SampleChannel sampleChangeDifficulty; private SampleChannel sampleChangeBeatmap; - private BindableBeatmap beatmap; - private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); @@ -178,11 +176,9 @@ namespace osu.Game.Screens.Select } } - [BackgroundDependencyLoader(permitNulls: true)] - private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours, BindableBeatmap beatmap) + [BackgroundDependencyLoader(true)] + private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours) { - this.beatmap = beatmap.GetBoundCopy(); - dependencies.CacheAs(this); if (Footer != null) @@ -219,7 +215,7 @@ namespace osu.Game.Screens.Select public void Edit(BeatmapInfo beatmap) { - this.beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); + Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); Push(new Editor()); } @@ -285,7 +281,7 @@ namespace osu.Game.Screens.Select { bool preview = beatmap?.BeatmapSetInfoID != Beatmap.Value?.BeatmapInfo.BeatmapSetInfoID; - this.beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); + Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap, Beatmap.Value); ensurePlayingSelected(preview); } From f2ac5b8b2d7704835bf0283caaef949bed8d02f4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Jun 2018 20:21:47 +0900 Subject: [PATCH 147/262] CreatePlayer shouldn't receive a beatmap --- osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs | 6 +++--- osu.Game.Tests/Visual/TestCaseAutoplay.cs | 5 ++--- osu.Game.Tests/Visual/TestCaseReplay.cs | 9 ++++----- osu.Game/Tests/Visual/TestCasePlayer.cs | 4 ++-- 4 files changed, 11 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs index 097750d7e0..34e07170bd 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs @@ -53,10 +53,10 @@ namespace osu.Game.Rulesets.Catch.Tests return beatmap; } - protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset) + protected override Player CreatePlayer(Ruleset ruleset) { - beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); - return base.CreatePlayer(beatmap, ruleset); + Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); + return base.CreatePlayer(ruleset); } } } diff --git a/osu.Game.Tests/Visual/TestCaseAutoplay.cs b/osu.Game.Tests/Visual/TestCaseAutoplay.cs index a009027627..4abfec4371 100644 --- a/osu.Game.Tests/Visual/TestCaseAutoplay.cs +++ b/osu.Game.Tests/Visual/TestCaseAutoplay.cs @@ -3,7 +3,6 @@ using System.ComponentModel; using System.Linq; -using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Play; @@ -13,9 +12,9 @@ namespace osu.Game.Tests.Visual [Description("Player instantiated with an autoplay mod.")] public class TestCaseAutoplay : TestCasePlayer { - protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset) + protected override Player CreatePlayer(Ruleset ruleset) { - beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); + Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); return new ScoreAccessiblePlayer { AllowPause = false, diff --git a/osu.Game.Tests/Visual/TestCaseReplay.cs b/osu.Game.Tests/Visual/TestCaseReplay.cs index 4bcbc924b8..1f2d99a7d8 100644 --- a/osu.Game.Tests/Visual/TestCaseReplay.cs +++ b/osu.Game.Tests/Visual/TestCaseReplay.cs @@ -3,7 +3,6 @@ using System.ComponentModel; using System.Linq; -using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Screens.Play; @@ -13,18 +12,18 @@ namespace osu.Game.Tests.Visual [Description("Player instantiated with a replay.")] public class TestCaseReplay : TestCasePlayer { - protected override Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset) + protected override Player CreatePlayer(Ruleset ruleset) { // We create a dummy RulesetContainer just to get the replay - we don't want to use mods here // to simulate setting a replay rather than having the replay already set for us - beatmap.Mods.Value = beatmap.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); - var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(beatmap); + Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }); + var dummyRulesetContainer = ruleset.CreateRulesetContainerWith(Beatmap.Value); // We have the replay var replay = dummyRulesetContainer.Replay; // Reset the mods - beatmap.Mods.Value = beatmap.Mods.Value.Where(m => !(m is ModAutoplay)); + Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Where(m => !(m is ModAutoplay)); return new ReplayPlayer(replay); } diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index be6468e308..3cdc496ee1 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -71,7 +71,7 @@ namespace osu.Game.Tests.Visual if (Player != null) Remove(Player); - var player = CreatePlayer(Beatmap, r); + var player = CreatePlayer(r); LoadComponentAsync(player, LoadScreen); @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Visual Beatmap.Value.Track.Rate = Clock.Rate; } - protected virtual Player CreatePlayer(WorkingBeatmap beatmap, Ruleset ruleset) => new Player + protected virtual Player CreatePlayer(Ruleset ruleset) => new Player { AllowPause = false, AllowLeadIn = false, From ebcfe97ccf3013d7c401f6fd4e8a1b5f5b41ffa2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Jun 2018 20:25:40 +0900 Subject: [PATCH 148/262] Expose Dependencies from base OsuTestCase --- .../TestCaseManiaPlayfield.cs | 7 +------ osu.Game.Tests/Visual/TestCaseChatLink.cs | 6 +----- osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs | 9 ++------- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 8 ++------ osu.Game.Tests/Visual/TestCasePlaybackControl.cs | 9 ++------- osu.Game.Tests/Visual/TestCaseSettings.cs | 7 +------ osu.Game/Tests/Visual/EditorClockTestCase.cs | 11 +++-------- osu.Game/Tests/Visual/OsuTestCase.cs | 10 +++++----- 8 files changed, 17 insertions(+), 50 deletions(-) diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseManiaPlayfield.cs b/osu.Game.Rulesets.Mania.Tests/TestCaseManiaPlayfield.cs index dff2b2d56a..b064d82a23 100644 --- a/osu.Game.Rulesets.Mania.Tests/TestCaseManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania.Tests/TestCaseManiaPlayfield.cs @@ -98,17 +98,12 @@ namespace osu.Game.Rulesets.Mania.Tests }); } - private DependencyContainer dependencies; - - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - [BackgroundDependencyLoader] private void load(RulesetStore rulesets, SettingsStore settings) { maniaRuleset = rulesets.GetRuleset(3); - dependencies.Cache(new ManiaConfigManager(settings, maniaRuleset, 4)); + Dependencies.Cache(new ManiaConfigManager(settings, maniaRuleset, 4)); } private ManiaPlayfield createPlayfield(int cols, bool inverted = false) diff --git a/osu.Game.Tests/Visual/TestCaseChatLink.cs b/osu.Game.Tests/Visual/TestCaseChatLink.cs index 608691cdf6..12a7ee9c12 100644 --- a/osu.Game.Tests/Visual/TestCaseChatLink.cs +++ b/osu.Game.Tests/Visual/TestCaseChatLink.cs @@ -35,10 +35,6 @@ namespace osu.Game.Tests.Visual typeof(MessageFormatter) }; - private DependencyContainer dependencies; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - public TestCaseChatLink() { Add(textContainer = new TestChatLineContainer @@ -54,7 +50,7 @@ namespace osu.Game.Tests.Visual private void load(OsuColour colours) { linkColour = colours.Blue; - dependencies.Cache(new ChatOverlay + Dependencies.Cache(new ChatOverlay { AvailableChannels = { diff --git a/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs b/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs index 0658de6576..5df371dd09 100644 --- a/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs +++ b/osu.Game.Tests/Visual/TestCaseHitObjectComposer.cs @@ -32,11 +32,6 @@ namespace osu.Game.Tests.Visual typeof(NotNullAttribute) }; - private DependencyContainer dependencies; - - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - [BackgroundDependencyLoader] private void load() { @@ -63,8 +58,8 @@ namespace osu.Game.Tests.Visual }); var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; - dependencies.CacheAs(clock); - dependencies.CacheAs(clock); + Dependencies.CacheAs(clock); + Dependencies.CacheAs(clock); Child = new OsuHitObjectComposer(new OsuRuleset()); } diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index b90e6c1ca7..10121738f1 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -27,7 +27,6 @@ namespace osu.Game.Tests.Visual private RulesetStore rulesets; - private DependencyContainer dependencies; private WorkingBeatmap defaultBeatmap; public override IReadOnlyList RequiredTypes => new[] @@ -48,9 +47,6 @@ namespace osu.Game.Tests.Visual typeof(DrawableCarouselBeatmapSet), }; - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - private class TestSongSelect : PlaySongSelect { public WorkingBeatmap CurrentBeatmap => Beatmap.Value; @@ -68,8 +64,8 @@ namespace osu.Game.Tests.Visual // this is by no means clean. should be replacing inside of OsuGameBase somehow. IDatabaseContextFactory factory = new SingletonContextFactory(new OsuDbContext()); - dependencies.Cache(rulesets = new RulesetStore(factory)); - dependencies.Cache(manager = new BeatmapManager(storage, factory, rulesets, null, null) + Dependencies.Cache(rulesets = new RulesetStore(factory)); + Dependencies.Cache(manager = new BeatmapManager(storage, factory, rulesets, null, null) { DefaultBeatmap = defaultBeatmap = Beatmap.Default }); diff --git a/osu.Game.Tests/Visual/TestCasePlaybackControl.cs b/osu.Game.Tests/Visual/TestCasePlaybackControl.cs index 5c0c0cb220..36fb1bcedd 100644 --- a/osu.Game.Tests/Visual/TestCasePlaybackControl.cs +++ b/osu.Game.Tests/Visual/TestCasePlaybackControl.cs @@ -15,17 +15,12 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCasePlaybackControl : OsuTestCase { - private DependencyContainer dependencies; - - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - [BackgroundDependencyLoader] private void load() { var clock = new DecoupleableInterpolatingFramedClock { IsCoupled = false }; - dependencies.CacheAs(clock); - dependencies.CacheAs(clock); + Dependencies.CacheAs(clock); + Dependencies.CacheAs(clock); var playback = new PlaybackControl { diff --git a/osu.Game.Tests/Visual/TestCaseSettings.cs b/osu.Game.Tests/Visual/TestCaseSettings.cs index 91dd35e148..c942342168 100644 --- a/osu.Game.Tests/Visual/TestCaseSettings.cs +++ b/osu.Game.Tests/Visual/TestCaseSettings.cs @@ -14,11 +14,6 @@ namespace osu.Game.Tests.Visual private readonly SettingsOverlay settings; private readonly DialogOverlay dialogOverlay; - private DependencyContainer dependencies; - - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - public TestCaseSettings() { settings = new MainSettings @@ -34,7 +29,7 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load() { - dependencies.Cache(dialogOverlay); + Dependencies.Cache(dialogOverlay); Add(settings); } diff --git a/osu.Game/Tests/Visual/EditorClockTestCase.cs b/osu.Game/Tests/Visual/EditorClockTestCase.cs index 0a0d641c0e..0363fa75ba 100644 --- a/osu.Game/Tests/Visual/EditorClockTestCase.cs +++ b/osu.Game/Tests/Visual/EditorClockTestCase.cs @@ -20,11 +20,6 @@ namespace osu.Game.Tests.Visual protected readonly BindableBeatDivisor BeatDivisor = new BindableBeatDivisor(); protected readonly EditorClock Clock; - private DependencyContainer dependencies; - - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - protected EditorClockTestCase() { Clock = new EditorClock(new ControlPointInfo(), 5000, BeatDivisor) { IsCoupled = false }; @@ -33,9 +28,9 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load() { - dependencies.Cache(BeatDivisor); - dependencies.CacheAs(Clock); - dependencies.CacheAs(Clock); + Dependencies.Cache(BeatDivisor); + Dependencies.CacheAs(Clock); + Dependencies.CacheAs(Clock); Beatmap.ValueChanged += beatmapChanged; beatmapChanged(Beatmap.Value); diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index f98aca4dff..f8c6219134 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -15,16 +15,16 @@ namespace osu.Game.Tests.Visual private readonly OsuTestBeatmap beatmap = new OsuTestBeatmap(new DummyWorkingBeatmap()); protected BindableBeatmap Beatmap => beatmap; - private DependencyContainer dependencies; + protected DependencyContainer Dependencies { get; private set; } protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) { - dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + Dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - dependencies.CacheAs(beatmap); - dependencies.CacheAs(beatmap); + Dependencies.CacheAs(beatmap); + Dependencies.CacheAs(beatmap); - return dependencies; + return Dependencies; } [BackgroundDependencyLoader] From 18fc63bac25db72bb994550bde22b52f63d92f29 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 6 Jun 2018 20:32:37 +0900 Subject: [PATCH 149/262] Add back removed using --- osu.Game/Screens/OsuScreen.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index c2da8ea6f3..61018f9e08 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.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 Microsoft.EntityFrameworkCore.Internal; using osu.Framework.Allocation; using osu.Framework.Audio; From c756a89dafb7a4e37c5f5e90a086b8babf78225d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 20:55:42 +0900 Subject: [PATCH 150/262] Standardise path --- osu.Game/IO/Archives/LegacyFilesystemReader.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/IO/Archives/LegacyFilesystemReader.cs b/osu.Game/IO/Archives/LegacyFilesystemReader.cs index fc52cb10dd..dcaaf41c77 100644 --- a/osu.Game/IO/Archives/LegacyFilesystemReader.cs +++ b/osu.Game/IO/Archives/LegacyFilesystemReader.cs @@ -17,14 +17,14 @@ namespace osu.Game.IO.Archives public LegacyFilesystemReader(string path) : base(Path.GetFileName(path)) { - this.path = path; + // re-get full path to standardise with Directory.GetFiles return values below. + this.path = Path.GetFullPath(path); } public override Stream GetStream(string name) => File.OpenRead(Path.Combine(path, name)); public override void Dispose() { - // no-op } public override IEnumerable Filenames => Directory.GetFiles(path, "*", SearchOption.AllDirectories).Select(f => f.Replace(path, string.Empty).Trim(Path.DirectorySeparatorChar)).ToArray(); From 00b4a2519f172671ae6db67283dda9f5e51b6596 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 21:10:18 +0900 Subject: [PATCH 151/262] Update framework --- osu.Desktop.Deploy/osu.Desktop.Deploy.csproj | 2 +- osu.Game/osu.Game.csproj | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj index e5944187b3..f6cf023e0d 100644 --- a/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj +++ b/osu.Desktop.Deploy/osu.Desktop.Deploy.csproj @@ -9,7 +9,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 55ee87dcb3..2300ba6a72 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From 2ec1fcd245abd637fd9d44d91264d8feb2f2fd74 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 21:29:45 +0900 Subject: [PATCH 152/262] Fix incorrect using --- osu.Desktop/Overlays/VersionManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index b984c0bbba..d061aa8423 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using osu.Framework.Allocation; -using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -14,6 +13,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; +using osu.Game.Utils; using OpenTK; using OpenTK.Graphics; From 2eb59830c13b608b2aeef1f5d2b8d28fb7276e5a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 21:31:58 +0900 Subject: [PATCH 153/262] Fix vs version --- appveyor.yml | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/appveyor.yml b/appveyor.yml index 314faa617a..69bc762f4c 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -1,6 +1,6 @@ clone_depth: 1 version: '{branch}-{build}' -image: Visual Studio 2017 preview +image: Visual Studio 2017 configuration: Debug cache: - C:\ProgramData\chocolatey\bin -> appveyor.yml From 576acaa630f52cc0aac76e7e0f42304be0906c2a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 21:54:45 +0900 Subject: [PATCH 154/262] Merge upstream master into external-deploy --- .gitmodules | 5 +- osu-framework | 1 - osu.Desktop/Overlays/VersionManager.cs | 2 +- osu.Desktop/osu.Desktop.csproj | 1 - osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 19 ++-- .../Beatmaps/IO/ImportBeatmapTest.cs | 9 +- osu.Game/Configuration/OsuConfigManager.cs | 5 +- .../Containers/OsuFocusedOverlayContainer.cs | 25 +++--- osu.Game/OsuGame.cs | 54 ++++++----- osu.Game/OsuGameBase.cs | 6 +- osu.Game/Overlays/BeatmapSet/Info.cs | 8 +- osu.Game/Overlays/NotificationOverlay.cs | 49 +++++----- osu.Game/Overlays/OverlayActivation.cs | 12 +++ .../Sections/Gameplay/ModsSettings.cs | 26 ++++++ .../Settings/Sections/GameplaySection.cs | 3 +- osu.Game/Overlays/Settings/SettingsFooter.cs | 2 +- osu.Game/Overlays/Toolbar/Toolbar.cs | 17 ++++ osu.Game/Rulesets/Mods/IReadFromConfig.cs | 15 ++++ osu.Game/Rulesets/Mods/ModHidden.cs | 23 ++++- osu.Game/Rulesets/UI/RulesetContainer.cs | 16 ++-- osu.Game/Rulesets/UI/RulesetInputManager.cs | 2 - osu.Game/Screens/Menu/ButtonSystem.cs | 39 ++++---- osu.Game/Screens/Menu/Disclaimer.cs | 3 +- osu.Game/Screens/Menu/Intro.cs | 3 +- osu.Game/Screens/Menu/MainMenu.cs | 1 - osu.Game/Screens/OsuScreen.cs | 28 ++++-- osu.Game/Screens/Play/Player.cs | 3 + osu.Game/Screens/Select/BeatmapDetails.cs | 22 +---- .../Select/Leaderboards/LeaderboardScore.cs | 89 ++++++++++++------- osu.Game/Tests/Visual/OsuTestCase.cs | 4 - osu.Game/Utils/DebugUtils.cs | 21 +++++ osu.Game/osu.Game.csproj | 2 +- osu.TestProject.props | 3 +- osu.sln | 6 -- 34 files changed, 323 insertions(+), 201 deletions(-) delete mode 160000 osu-framework create mode 100644 osu.Game/Overlays/OverlayActivation.cs create mode 100644 osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs create mode 100644 osu.Game/Rulesets/Mods/IReadFromConfig.cs create mode 100644 osu.Game/Utils/DebugUtils.cs diff --git a/.gitmodules b/.gitmodules index ee1cc80880..f1c4f5d172 100644 --- a/.gitmodules +++ b/.gitmodules @@ -1,6 +1,3 @@ -[submodule "osu-framework"] - path = osu-framework - url = https://github.com/ppy/osu-framework [submodule "osu-resources"] path = osu-resources - url = https://github.com/ppy/osu-resources + url = https://github.com/ppy/osu-resources \ No newline at end of file diff --git a/osu-framework b/osu-framework deleted file mode 160000 index b963ce8250..0000000000 --- a/osu-framework +++ /dev/null @@ -1 +0,0 @@ -Subproject commit b963ce82505bc953db0a0763679e1ec80a060811 diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index b984c0bbba..d061aa8423 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -3,7 +3,6 @@ using System.Diagnostics; using osu.Framework.Allocation; -using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -14,6 +13,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Overlays; using osu.Game.Overlays.Notifications; +using osu.Game.Utils; using OpenTK; using OpenTK.Graphics; diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index b8efd76506..766f36fa74 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -20,7 +20,6 @@ osu.Desktop.Program - diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs index e72d667c0b..4220b72b16 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -7,33 +7,34 @@ using System.Linq; using osu.Framework.Graphics; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Mods { - public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects + public class OsuModHidden : ModHidden { public override string Description => @"Play with no approach circles and fading circles/sliders."; public override double ScoreMultiplier => 1.06; - private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; - public void ApplyToDrawableHitObjects(IEnumerable drawables) + public override void ApplyToDrawableHitObjects(IEnumerable drawables) { + void adjustFadeIn(OsuHitObject h) => h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; + foreach (var d in drawables.OfType()) { - d.ApplyCustomUpdateState += ApplyHiddenState; - - d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; + adjustFadeIn(d.HitObject); foreach (var h in d.HitObject.NestedHitObjects.OfType()) - h.TimeFadein = h.TimePreempt * fade_in_duration_multiplier; + adjustFadeIn(h); } + + base.ApplyToDrawableHitObjects(drawables); } - protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state) + protected override void ApplyHiddenState(DrawableHitObject drawable, ArmedState state) { if (!(drawable is DrawableOsuHitObject d)) return; diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 586217a05f..1c9696901c 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -264,7 +264,8 @@ namespace osu.Game.Tests.Beatmaps.IO private string createTemporaryBeatmap() { - var temp = new FileInfo(osz_path).CopyTo(Path.GetTempFileName(), true).FullName; + var temp = Path.GetTempFileName() + ".osz"; + File.Copy(osz_path, temp, true); Assert.IsTrue(File.Exists(temp)); return temp; } @@ -344,12 +345,12 @@ namespace osu.Game.Tests.Beatmaps.IO private void waitForOrAssert(Func result, string failureMessage, int timeout = 60000) { - Action waitAction = () => + Task task = Task.Run(() => { while (!result()) Thread.Sleep(200); - }; + }); - Assert.IsTrue(waitAction.BeginInvoke(null, null).AsyncWaitHandle.WaitOne(timeout), failureMessage); + Assert.IsTrue(task.Wait(timeout), failureMessage); } } } diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index b3082e49de..597960c352 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -82,6 +82,8 @@ namespace osu.Game.Configuration Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential); + Set(OsuSetting.IncreaseFirstObjectVisibility, true); + // Update Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); @@ -144,6 +146,7 @@ namespace osu.Game.Configuration ScreenshotCaptureMenuCursor, SongSelectRightMouseScroll, BeatmapSkins, - BeatmapHitsounds + BeatmapHitsounds, + IncreaseFirstObjectVisibility } } diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 11a2034a8f..0186a170c9 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -8,6 +8,7 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input; using OpenTK; using osu.Framework.Configuration; +using osu.Game.Overlays; namespace osu.Game.Graphics.Containers { @@ -16,13 +17,13 @@ namespace osu.Game.Graphics.Containers private SampleChannel samplePopIn; private SampleChannel samplePopOut; - private readonly BindableBool allowOpeningOverlays = new BindableBool(true); + protected readonly Bindable OverlayActivationMode = new Bindable(OverlayActivation.All); [BackgroundDependencyLoader(true)] private void load(OsuGame osuGame, AudioManager audio) { if (osuGame != null) - allowOpeningOverlays.BindTo(osuGame.AllowOpeningOverlays); + OverlayActivationMode.BindTo(osuGame.OverlayActivationMode); samplePopIn = audio.Sample.Get(@"UI/overlay-pop-in"); samplePopOut = audio.Sample.Get(@"UI/overlay-pop-out"); @@ -52,20 +53,18 @@ namespace osu.Game.Graphics.Containers private void onStateChanged(Visibility visibility) { - if (allowOpeningOverlays) + switch (visibility) { - switch (visibility) - { - case Visibility.Visible: + case Visibility.Visible: + if (OverlayActivationMode != OverlayActivation.Disabled) samplePopIn?.Play(); - break; - case Visibility.Hidden: - samplePopOut?.Play(); - break; - } + else + State = Visibility.Hidden; + break; + case Visibility.Hidden: + samplePopOut?.Play(); + break; } - else - State = Visibility.Hidden; } } } diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a43c1507b6..36c76851c6 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -77,8 +77,7 @@ namespace osu.Game public float ToolbarOffset => Toolbar.Position.Y + Toolbar.DrawHeight; - public readonly BindableBool HideOverlaysOnEnter = new BindableBool(); - public readonly BindableBool AllowOpeningOverlays = new BindableBool(true); + public readonly Bindable OverlayActivationMode = new Bindable(); private OsuScreen screenStack; @@ -94,6 +93,8 @@ namespace osu.Game private SettingsOverlay settings; + private readonly List overlays = new List(); + // todo: move this to SongSelect once Screen has the ability to unsuspend. public readonly Bindable> SelectedMods = new Bindable>(new List()); @@ -106,6 +107,17 @@ namespace osu.Game public void ToggleDirect() => direct.ToggleVisibility(); + /// + /// Close all game-wide overlays. + /// + /// Whether the toolbar should also be hidden. + public void CloseAllOverlays(bool toolbar = true) + { + foreach (var o in overlays) + o.State = Visibility.Hidden; + if (toolbar) Toolbar.State = Visibility.Hidden; + } + private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => @@ -251,7 +263,7 @@ namespace osu.Game Depth = -5, OnHome = delegate { - hideAllOverlays(); + CloseAllOverlays(false); intro?.ChildScreen?.MakeCurrent(); }, }, overlayContent.Add); @@ -308,6 +320,8 @@ namespace osu.Game // ensure only one of these overlays are open at once. var singleDisplayOverlays = new OverlayContainer[] { chat, social, direct }; + overlays.AddRange(singleDisplayOverlays); + foreach (var overlay in singleDisplayOverlays) { overlay.StateChanged += state => @@ -323,6 +337,8 @@ namespace osu.Game } var singleDisplaySideOverlays = new OverlayContainer[] { settings, notifications }; + overlays.AddRange(singleDisplaySideOverlays); + foreach (var overlay in singleDisplaySideOverlays) { overlay.StateChanged += state => @@ -339,6 +355,8 @@ namespace osu.Game // eventually informational overlays should be displayed in a stack, but for now let's only allow one to stay open at a time. var informationalOverlays = new OverlayContainer[] { beatmapSetOverlay, userProfile }; + overlays.AddRange(informationalOverlays); + foreach (var overlay in informationalOverlays) { overlay.StateChanged += state => @@ -353,6 +371,11 @@ namespace osu.Game }; } + OverlayActivationMode.ValueChanged += v => + { + if (v != OverlayActivation.All) CloseAllOverlays(); + }; + void updateScreenOffset() { float offset = 0; @@ -367,21 +390,6 @@ namespace osu.Game settings.StateChanged += _ => updateScreenOffset(); notifications.StateChanged += _ => updateScreenOffset(); - - notifications.Enabled.BindTo(AllowOpeningOverlays); - - HideOverlaysOnEnter.ValueChanged += hide => - { - //central game screen change logic. - if (hide) - { - hideAllOverlays(); - musicController.State = Visibility.Hidden; - Toolbar.State = Visibility.Hidden; - } - else - Toolbar.State = Visibility.Visible; - }; } private void forwardLoggedErrorsToNotifications() @@ -498,16 +506,6 @@ namespace osu.Game private OsuScreen currentScreen; private FrameworkConfigManager frameworkConfig; - private void hideAllOverlays() - { - settings.State = Visibility.Hidden; - chat.State = Visibility.Hidden; - direct.State = Visibility.Hidden; - social.State = Visibility.Hidden; - userProfile.State = Visibility.Hidden; - notifications.State = Visibility.Hidden; - } - protected override bool OnExiting() { if (screenStack.ChildScreen == null) return false; diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index b9d32a6322..f170f1c00f 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -10,7 +10,6 @@ using System.Reflection; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Configuration; -using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.IO.Stores; @@ -31,6 +30,7 @@ using osu.Game.IO; using osu.Game.Rulesets; using osu.Game.Rulesets.Scoring; using osu.Game.Skinning; +using DebugUtils = osu.Game.Utils.DebugUtils; namespace osu.Game { @@ -59,8 +59,6 @@ namespace osu.Game protected MenuCursorContainer MenuCursorContainer; - protected override string MainResourceFile => @"osu.Game.Resources.dll"; - private Container content; protected override Container Content => content; @@ -100,6 +98,8 @@ namespace osu.Game [BackgroundDependencyLoader] private void load() { + Resources.AddStore(new DllResourceStore(@"osu.Game.Resources.dll")); + dependencies.Cache(contextFactory = new DatabaseContextFactory(Host)); dependencies.Cache(new LargeTextureStore(new RawTextureLoaderStore(new NamespacedResourceStore(Resources, @"Textures")))); diff --git a/osu.Game/Overlays/BeatmapSet/Info.cs b/osu.Game/Overlays/BeatmapSet/Info.cs index cd0b7386e8..53216ad666 100644 --- a/osu.Game/Overlays/BeatmapSet/Info.cs +++ b/osu.Game/Overlays/BeatmapSet/Info.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays.BeatmapSet private const float metadata_width = 225; private const float spacing = 20; - private readonly MetadataSection description, source, tags; + private readonly MetadataSection source, tags; private readonly Box successRateBackground; private readonly SuccessRate successRate; @@ -83,7 +83,7 @@ namespace osu.Game.Overlays.BeatmapSet Child = new Container { RelativeSizeAxes = Axes.Both, - Child = description = new MetadataSection("Description"), + Child = new MetadataSection("Description"), }, }, new Container @@ -135,8 +135,6 @@ namespace osu.Game.Overlays.BeatmapSet private void load(OsuColour colours) { successRateBackground.Colour = colours.GrayE; - source.TextColour = description.TextColour = colours.Gray5; - tags.TextColour = colours.BlueDark; updateDisplay(); } @@ -195,7 +193,7 @@ namespace osu.Game.Overlays.BeatmapSet [BackgroundDependencyLoader] private void load(OsuColour colours) { - header.Colour = colours.Gray5; + header.Colour = textFlow.Colour = colours.Gray5; } } } diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 09b6022ac5..3dc8f5ec15 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -22,11 +22,6 @@ namespace osu.Game.Overlays public const float TRANSITION_LENGTH = 600; - /// - /// Whether posted notifications should be processed. - /// - public readonly BindableBool Enabled = new BindableBool(true); - private FlowContainer sections; /// @@ -34,27 +29,6 @@ namespace osu.Game.Overlays /// public Func GetToolbarHeight; - public NotificationOverlay() - { - ScheduledDelegate notificationsEnabler = null; - Enabled.ValueChanged += v => - { - if (!IsLoaded) - { - processingPosts = v; - return; - } - - notificationsEnabler?.Cancel(); - - if (v) - // we want a slight delay before toggling notifications on to avoid the user becoming overwhelmed. - notificationsEnabler = Scheduler.AddDelayed(() => processingPosts = true, 1000); - else - processingPosts = false; - }; - } - [BackgroundDependencyLoader] private void load() { @@ -103,6 +77,29 @@ namespace osu.Game.Overlays }; } + private ScheduledDelegate notificationsEnabler; + private void updateProcessingMode() + { + bool enabled = OverlayActivationMode == OverlayActivation.All || State == Visibility.Visible; + + notificationsEnabler?.Cancel(); + + if (enabled) + // we want a slight delay before toggling notifications on to avoid the user becoming overwhelmed. + notificationsEnabler = Scheduler.AddDelayed(() => processingPosts = true, State == Visibility.Visible ? 0 : 1000); + else + processingPosts = false; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + StateChanged += _ => updateProcessingMode(); + OverlayActivationMode.ValueChanged += _ => updateProcessingMode(); + OverlayActivationMode.TriggerChange(); + } + private int totalCount => sections.Select(c => c.DisplayedCount).Sum(); private int unreadCount => sections.Select(c => c.UnreadCount).Sum(); diff --git a/osu.Game/Overlays/OverlayActivation.cs b/osu.Game/Overlays/OverlayActivation.cs new file mode 100644 index 0000000000..da4e153ce9 --- /dev/null +++ b/osu.Game/Overlays/OverlayActivation.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Overlays +{ + public enum OverlayActivation + { + Disabled, + UserTriggered, + All + } +} diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs new file mode 100644 index 0000000000..a9cefa81da --- /dev/null +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/ModsSettings.cs @@ -0,0 +1,26 @@ +// 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.Game.Configuration; + +namespace osu.Game.Overlays.Settings.Sections.Gameplay +{ + public class ModsSettings : SettingsSubsection + { + protected override string Header => "Mods"; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new[] + { + new SettingsCheckbox + { + LabelText = "Increase visibility of first object with \"Hidden\" mod", + Bindable = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility) + }, + }; + } + } +} diff --git a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs index 3851a73901..8add0b01ec 100644 --- a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs +++ b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs @@ -21,7 +21,8 @@ namespace osu.Game.Overlays.Settings.Sections { new GeneralSettings(), new SongSelectSettings(), - new ScrollingSettings() + new ScrollingSettings(), + new ModsSettings(), }; } diff --git a/osu.Game/Overlays/Settings/SettingsFooter.cs b/osu.Game/Overlays/Settings/SettingsFooter.cs index 900f03fe7b..909fc20446 100644 --- a/osu.Game/Overlays/Settings/SettingsFooter.cs +++ b/osu.Game/Overlays/Settings/SettingsFooter.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using osu.Framework.Allocation; -using osu.Framework.Development; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -12,6 +11,7 @@ using osu.Game.Graphics.Sprites; using osu.Game.Rulesets; using OpenTK; using OpenTK.Graphics; +using DebugUtils = osu.Game.Utils.DebugUtils; namespace osu.Game.Overlays.Settings { diff --git a/osu.Game/Overlays/Toolbar/Toolbar.cs b/osu.Game/Overlays/Toolbar/Toolbar.cs index 424a457110..48d0674b3d 100644 --- a/osu.Game/Overlays/Toolbar/Toolbar.cs +++ b/osu.Game/Overlays/Toolbar/Toolbar.cs @@ -10,6 +10,8 @@ using osu.Framework.Input; using osu.Game.Graphics; using OpenTK; using osu.Framework.Graphics.Shapes; +using osu.Framework.Allocation; +using osu.Framework.Configuration; namespace osu.Game.Overlays.Toolbar { @@ -29,6 +31,8 @@ namespace osu.Game.Overlays.Toolbar private const float alpha_hovering = 0.8f; private const float alpha_normal = 0.6f; + private readonly Bindable overlayActivationMode = new Bindable(OverlayActivation.All); + public Toolbar() { Children = new Drawable[] @@ -76,6 +80,19 @@ namespace osu.Game.Overlays.Toolbar Size = new Vector2(1, HEIGHT); } + [BackgroundDependencyLoader(true)] + private void load(OsuGame osuGame) + { + if (osuGame != null) + overlayActivationMode.BindTo(osuGame.OverlayActivationMode); + + StateChanged += visibility => + { + if (overlayActivationMode == OverlayActivation.Disabled) + State = Visibility.Hidden; + }; + } + public class ToolbarBackground : Container { private readonly Box solidBackground; diff --git a/osu.Game/Rulesets/Mods/IReadFromConfig.cs b/osu.Game/Rulesets/Mods/IReadFromConfig.cs new file mode 100644 index 0000000000..93c9ae0c34 --- /dev/null +++ b/osu.Game/Rulesets/Mods/IReadFromConfig.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 + +using osu.Game.Configuration; + +namespace osu.Game.Rulesets.Mods +{ + /// + /// An interface for mods that require reading access to the osu! configuration. + /// + public interface IReadFromConfig + { + void ReadFromConfig(OsuConfigManager config); + } +} diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs index b489a665d9..45da628ce8 100644 --- a/osu.Game/Rulesets/Mods/ModHidden.cs +++ b/osu.Game/Rulesets/Mods/ModHidden.cs @@ -1,16 +1,37 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Configuration; +using osu.Game.Configuration; using osu.Game.Graphics; +using osu.Game.Rulesets.Objects.Drawables; +using System.Collections.Generic; +using System.Linq; namespace osu.Game.Rulesets.Mods { - public abstract class ModHidden : Mod + public abstract class ModHidden : Mod, IReadFromConfig, IApplicableToDrawableHitObjects { public override string Name => "Hidden"; public override string ShortenedName => "HD"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden; public override ModType Type => ModType.DifficultyIncrease; public override bool Ranked => true; + + protected Bindable IncreaseFirstObjectVisibility = new Bindable(); + + public void ReadFromConfig(OsuConfigManager config) + { + IncreaseFirstObjectVisibility = config.GetBindable(OsuSetting.IncreaseFirstObjectVisibility); + } + + 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)) + d.ApplyCustomUpdateState += ApplyHiddenState; + } + + protected virtual void ApplyHiddenState(DrawableHitObject hitObject, ArmedState state) { } } } diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index e42e74c245..384b71cccc 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -57,6 +57,7 @@ namespace osu.Game.Rulesets.UI public abstract IEnumerable Objects { get; } private readonly Lazy playfield; + /// /// The playfield. /// @@ -130,7 +131,6 @@ namespace osu.Game.Rulesets.UI HasReplayLoaded.Value = ReplayInputManager.ReplayInputHandler != null; } - /// /// Creates the cursor. May be null if the doesn't provide a custom cursor. /// @@ -194,6 +194,7 @@ namespace osu.Game.Rulesets.UI protected override Container Content => content; private Container content; + private IEnumerable mods; /// /// Whether to assume the beatmap passed into this is for the current ruleset. @@ -216,13 +217,10 @@ namespace osu.Game.Rulesets.UI KeyBindingInputManager = CreateInputManager(); KeyBindingInputManager.RelativeSizeAxes = Axes.Both; - - // Add mods, should always be the last thing applied to give full control to mods - applyMods(Mods); } [BackgroundDependencyLoader] - private void load() + private void load(OsuConfigManager config) { KeyBindingInputManager.Add(content = new Container { @@ -235,6 +233,9 @@ namespace osu.Game.Rulesets.UI if (Cursor != null) KeyBindingInputManager.Add(Cursor); + // Apply mods + applyMods(Mods, config); + loadObjects(); } @@ -242,13 +243,16 @@ namespace osu.Game.Rulesets.UI /// Applies the active mods to this RulesetContainer. /// /// - private void applyMods(IEnumerable mods) + private void applyMods(IEnumerable mods, OsuConfigManager config) { if (mods == null) return; foreach (var mod in mods.OfType>()) mod.ApplyToRulesetContainer(this); + + foreach (var mod in mods.OfType()) + mod.ReadFromConfig(config); } public override void SetReplay(Replay replay) diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs index 58a66a5224..b35616985a 100644 --- a/osu.Game/Rulesets/UI/RulesetInputManager.cs +++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs @@ -121,8 +121,6 @@ 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; diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index f212bfabf3..42e25aad43 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -8,7 +8,6 @@ using osu.Framework; using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; @@ -17,6 +16,7 @@ using osu.Framework.Input.Bindings; using osu.Framework.Threading; using osu.Game.Graphics; using osu.Game.Input.Bindings; +using osu.Game.Overlays; using OpenTK; using OpenTK.Graphics; using OpenTK.Input; @@ -27,9 +27,6 @@ namespace osu.Game.Screens.Menu { public event Action StateChanged; - private readonly BindableBool hideOverlaysOnEnter = new BindableBool(); - private readonly BindableBool allowOpeningOverlays = new BindableBool(); - public Action OnEdit; public Action OnExit; public Action OnDirect; @@ -133,15 +130,12 @@ namespace osu.Game.Screens.Menu buttonFlow.AddRange(buttonsTopLevel); } + private OsuGame game; + [BackgroundDependencyLoader(true)] private void load(AudioManager audio, OsuGame game) { - if (game != null) - { - hideOverlaysOnEnter.BindTo(game.HideOverlaysOnEnter); - allowOpeningOverlays.BindTo(game.AllowOpeningOverlays); - } - + this.game = game; sampleBack = audio.Sample.Get(@"Menu/button-back-select"); } @@ -328,18 +322,18 @@ namespace osu.Game.Screens.Menu case MenuState.Initial: logoDelayedAction?.Cancel(); logoDelayedAction = Scheduler.AddDelayed(() => - { - logoTracking = false; + { + logoTracking = false; - hideOverlaysOnEnter.Value = true; - allowOpeningOverlays.Value = false; + if (game != null) + game.OverlayActivationMode.Value = state == MenuState.Exit ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; - logo.ClearTransforms(targetMember: nameof(Position)); - logo.RelativePositionAxes = Axes.Both; + logo.ClearTransforms(targetMember: nameof(Position)); + logo.RelativePositionAxes = Axes.Both; - logo.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo); - logo.ScaleTo(1, 800, Easing.OutExpo); - }, buttonArea.Alpha * 150); + logo.MoveTo(new Vector2(0.5f), 800, Easing.OutExpo); + logo.ScaleTo(1, 800, Easing.OutExpo); + }, buttonArea.Alpha * 150); break; case MenuState.TopLevel: case MenuState.Play: @@ -366,8 +360,11 @@ namespace osu.Game.Screens.Menu if (impact) logo.Impact(); - hideOverlaysOnEnter.Value = false; - allowOpeningOverlays.Value = true; + if (game != null) + { + game.OverlayActivationMode.Value = OverlayActivation.All; + game.Toolbar.State = Visibility.Visible; + } }, 200); break; default: diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index b8cb7f2a4a..0c70dbf570 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -9,6 +9,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using OpenTK; using OpenTK.Graphics; +using osu.Game.Overlays; namespace osu.Game.Screens.Menu { @@ -19,7 +20,7 @@ namespace osu.Game.Screens.Menu private Color4 iconColour; protected override bool HideOverlaysOnEnter => true; - protected override bool AllowOpeningOverlays => false; + protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled; public override bool CursorVisible => false; diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index 5aca184d24..c5bd345a31 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -15,6 +15,7 @@ using osu.Game.IO.Archives; using osu.Game.Screens.Backgrounds; using OpenTK; using OpenTK.Graphics; +using osu.Game.Overlays; namespace osu.Game.Screens.Menu { @@ -32,7 +33,7 @@ namespace osu.Game.Screens.Menu private SampleChannel seeya; protected override bool HideOverlaysOnEnter => true; - protected override bool AllowOpeningOverlays => false; + protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.Disabled; public override bool CursorVisible => false; diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs index d5f3b11467..cbdd8b4e8b 100644 --- a/osu.Game/Screens/Menu/MainMenu.cs +++ b/osu.Game/Screens/Menu/MainMenu.cs @@ -25,7 +25,6 @@ namespace osu.Game.Screens.Menu private readonly ButtonSystem buttons; protected override bool HideOverlaysOnEnter => buttons.State == MenuState.Initial; - protected override bool AllowOpeningOverlays => buttons.State != MenuState.Initial; protected override bool AllowBackButton => buttons.State != MenuState.Initial; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 7f68e5144b..d98aac8f84 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -18,6 +18,8 @@ using osu.Game.Rulesets; using osu.Game.Screens.Menu; using OpenTK; using OpenTK.Input; +using osu.Game.Overlays; +using osu.Framework.Graphics.Containers; namespace osu.Game.Screens { @@ -40,19 +42,19 @@ namespace osu.Game.Screens /// protected virtual BackgroundScreen CreateBackground() => null; - private readonly BindableBool hideOverlaysOnEnter = new BindableBool(); + private Action updateOverlayStates; /// - /// Whether overlays should be hidden when this screen is entered or resumed. + /// Whether all overlays should be hidden when this screen is entered or resumed. /// protected virtual bool HideOverlaysOnEnter => false; - private readonly BindableBool allowOpeningOverlays = new BindableBool(); + protected readonly Bindable OverlayActivationMode = new Bindable(); /// - /// Whether overlays should be able to be opened while this screen is active. + /// Whether overlays should be able to be opened once this screen is entered or resumed. /// - protected virtual bool AllowOpeningOverlays => true; + protected virtual OverlayActivation InitialOverlayActivationMode => OverlayActivation.All; /// /// Whether this allows the cursor to be displayed. @@ -103,8 +105,15 @@ namespace osu.Game.Screens if (osuGame != null) { Ruleset.BindTo(osuGame.Ruleset); - hideOverlaysOnEnter.BindTo(osuGame.HideOverlaysOnEnter); - allowOpeningOverlays.BindTo(osuGame.AllowOpeningOverlays); + OverlayActivationMode.BindTo(osuGame.OverlayActivationMode); + + updateOverlayStates = () => + { + if (HideOverlaysOnEnter) + osuGame.CloseAllOverlays(); + else + osuGame.Toolbar.State = Visibility.Visible; + }; } sampleExit = audio.Sample.Get(@"UI/screen-back"); @@ -240,8 +249,9 @@ namespace osu.Game.Screens if (backgroundParallaxContainer != null) backgroundParallaxContainer.ParallaxAmount = ParallaxContainer.DEFAULT_PARALLAX_AMOUNT * BackgroundParallaxAmount; - hideOverlaysOnEnter.Value = HideOverlaysOnEnter; - allowOpeningOverlays.Value = AllowOpeningOverlays; + OverlayActivationMode.Value = InitialOverlayActivationMode; + + updateOverlayStates?.Invoke(); } private void onExitingLogo() diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index c93e4b7b40..54f65e3991 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -21,6 +21,7 @@ using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Online.API; +using osu.Game.Overlays; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; @@ -37,6 +38,8 @@ namespace osu.Game.Screens.Play protected override bool HideOverlaysOnEnter => true; + protected override OverlayActivation InitialOverlayActivationMode => OverlayActivation.UserTriggered; + public Action RestartRequested; public bool HasFailed { get; private set; } diff --git a/osu.Game/Screens/Select/BeatmapDetails.cs b/osu.Game/Screens/Select/BeatmapDetails.cs index ca36f94eda..f1bd2b945f 100644 --- a/osu.Game/Screens/Select/BeatmapDetails.cs +++ b/osu.Game/Screens/Select/BeatmapDetails.cs @@ -6,7 +6,6 @@ using OpenTK.Graphics; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Graphics.UserInterface; using System.Linq; @@ -120,14 +119,8 @@ namespace osu.Game.Screens.Select Margin = new MarginPadding { Top = spacing * 2 }, Children = new[] { - description = new MetadataSection("Description") - { - TextColour = Color4.White.Opacity(0.75f), - }, - source = new MetadataSection("Source") - { - TextColour = Color4.White.Opacity(0.75f), - }, + description = new MetadataSection("Description"), + source = new MetadataSection("Source"), tags = new MetadataSection("Tags"), }, }, @@ -164,10 +157,9 @@ namespace osu.Game.Screens.Select } [BackgroundDependencyLoader] - private void load(OsuColour colours, APIAccess api) + private void load(APIAccess api) { this.api = api; - tags.TextColour = colours.Yellow; } protected override void UpdateAfterChildren() @@ -364,7 +356,7 @@ namespace osu.Game.Screens.Select { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Colour = textFlow.Colour, + Colour = Color4.White.Opacity(0.75f), Text = text }, loaded => { @@ -375,12 +367,6 @@ namespace osu.Game.Screens.Select this.FadeIn(transition_duration); }); } - - public Color4 TextColour - { - get { return textFlow.Colour; } - set { textFlow.Colour = value; } - } } private class DimmedLoadingAnimation : VisibilityContainer diff --git a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs index baab973ae5..19732107c7 100644 --- a/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs +++ b/osu.Game/Screens/Select/Leaderboards/LeaderboardScore.cs @@ -8,6 +8,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Game.Graphics; @@ -142,6 +143,8 @@ namespace osu.Game.Screens.Select.Leaderboards { flagBadgeContainer = new Container { + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, Size = new Vector2(87f, 20f), Masking = true, Children = new Drawable[] @@ -155,14 +158,16 @@ namespace osu.Game.Screens.Select.Leaderboards }, new FillFlowContainer { + Origin = Anchor.BottomLeft, + Anchor = Anchor.BottomLeft, AutoSizeAxes = Axes.Both, Direction = FillDirection.Horizontal, Spacing = new Vector2(10f, 0f), - Margin = new MarginPadding { Left = edge_margin, }, + Margin = new MarginPadding { Left = edge_margin }, Children = new Drawable[] { - maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString()), - accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy)), + maxCombo = new ScoreComponentLabel(FontAwesome.fa_link, Score.MaxCombo.ToString(), "Max Combo"), + accuracy = new ScoreComponentLabel(FontAwesome.fa_crosshairs, string.Format(Score.Accuracy % 1 == 0 ? @"{0:P0}" : @"{0:P2}", Score.Accuracy), "Accuracy"), }, }, }, @@ -305,37 +310,61 @@ namespace osu.Game.Screens.Select.Leaderboards } } - private class ScoreComponentLabel : Container + private class ScoreComponentLabel : Container, IHasTooltip { - public ScoreComponentLabel(FontAwesome icon, string value) - { - Anchor = Anchor.CentreLeft; - Origin = Anchor.CentreLeft; - Size = new Vector2(60f, 20f); - Padding = new MarginPadding { Top = 10f, }; + private const float icon_size = 20; - Children = new Drawable[] + private readonly string name; + private readonly FillFlowContainer content; + + public override bool Contains(Vector2 screenSpacePos) => content.Contains(screenSpacePos); + + public string TooltipText => name; + + public ScoreComponentLabel(FontAwesome icon, string value, string name) + { + this.name = name; + AutoSizeAxes = Axes.Y; + Width = 60; + + Child = content = new FillFlowContainer { - new SpriteIcon + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Children = new Drawable[] { - Origin = Anchor.Centre, - Icon = FontAwesome.fa_square, - Colour = OsuColour.FromHex(@"3087ac"), - Rotation = 45, - Size = new Vector2(20), - Shadow = true, - }, - new SpriteIcon - { - Origin = Anchor.Centre, - Icon = icon, - Colour = OsuColour.FromHex(@"a4edff"), - Size = new Vector2(14), - }, - new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa")) - { - Origin = Anchor.CentreLeft, - Margin = new MarginPadding { Left = 15, }, + new Container + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + AutoSizeAxes = Axes.Both, + Children = new[] + { + new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(icon_size), + Rotation = 45, + Colour = OsuColour.FromHex(@"3087ac"), + Icon = FontAwesome.fa_square, + Shadow = true, + }, + new SpriteIcon + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(icon_size - 6), + Colour = OsuColour.FromHex(@"a4edff"), + Icon = icon, + }, + }, + }, + new GlowingSpriteText(value, @"Exo2.0-Bold", 17, Color4.White, OsuColour.FromHex(@"83ccfa")) + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + }, }, }; } diff --git a/osu.Game/Tests/Visual/OsuTestCase.cs b/osu.Game/Tests/Visual/OsuTestCase.cs index 2b677f1f42..fa441d8012 100644 --- a/osu.Game/Tests/Visual/OsuTestCase.cs +++ b/osu.Game/Tests/Visual/OsuTestCase.cs @@ -1,8 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.IO; -using System.Reflection; using osu.Framework.Testing; namespace osu.Game.Tests.Visual @@ -13,8 +11,6 @@ namespace osu.Game.Tests.Visual public class OsuTestCaseTestRunner : OsuGameBase, ITestCaseTestRunner { - protected override string MainResourceFile => File.Exists(base.MainResourceFile) ? base.MainResourceFile : Assembly.GetExecutingAssembly().Location; - private TestCaseTestRunner.TestRunner runner; protected override void LoadAsyncComplete() diff --git a/osu.Game/Utils/DebugUtils.cs b/osu.Game/Utils/DebugUtils.cs new file mode 100644 index 0000000000..191662c690 --- /dev/null +++ b/osu.Game/Utils/DebugUtils.cs @@ -0,0 +1,21 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Utils +{ + public static class DebugUtils + { + public static bool IsDebug + { + get + { + // ReSharper disable once RedundantAssignment + bool isDebug = false; + // Debug.Assert conditions are only evaluated in debug mode + System.Diagnostics.Debug.Assert(isDebug = true); + // ReSharper disable once ConditionIsAlwaysTrueOrFalse + return isDebug; + } + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index afb656a260..2300ba6a72 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -11,7 +11,6 @@ - @@ -19,6 +18,7 @@ + diff --git a/osu.TestProject.props b/osu.TestProject.props index afdf895eac..b51ca13ed5 100644 --- a/osu.TestProject.props +++ b/osu.TestProject.props @@ -7,7 +7,6 @@ - @@ -18,7 +17,7 @@ - + VisualTestRunner.cs diff --git a/osu.sln b/osu.sln index 3646679539..bf1b6d60e1 100644 --- a/osu.sln +++ b/osu.sln @@ -5,8 +5,6 @@ VisualStudioVersion = 15.0.27004.2006 MinimumVisualStudioVersion = 10.0.40219.1 Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game", "osu.Game\osu.Game.csproj", "{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}" EndProject -Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Framework", "osu-framework\osu.Framework\osu.Framework.csproj", "{C76BF5B3-985E-4D39-95FE-97C9C879B83A}" -EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Resources", "osu-resources\osu.Game.Resources\osu.Game.Resources.csproj", "{D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}" EndProject Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Osu", "osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj", "{C92A607B-1FDD-4954-9F92-03FF547D9080}" @@ -39,10 +37,6 @@ Global {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Debug|Any CPU.Build.0 = Debug|Any CPU {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Release|Any CPU.ActiveCfg = Release|Any CPU {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Release|Any CPU.Build.0 = Release|Any CPU - {C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Debug|Any CPU.ActiveCfg = Debug|Any CPU - {C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Debug|Any CPU.Build.0 = Debug|Any CPU - {C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Release|Any CPU.ActiveCfg = Release|Any CPU - {C76BF5B3-985E-4D39-95FE-97C9C879B83A}.Release|Any CPU.Build.0 = Release|Any CPU {D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}.Debug|Any CPU.ActiveCfg = Debug|Any CPU {D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}.Debug|Any CPU.Build.0 = Debug|Any CPU {D9A367C9-4C1A-489F-9B05-A0CEA2B53B58}.Release|Any CPU.ActiveCfg = Release|Any CPU From fa1106affe12f22341838fd91631bfa74c4d6038 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 21:57:53 +0900 Subject: [PATCH 155/262] Disable caches --- appveyor.yml | 5 ----- appveyor_deploy.yml | 2 -- 2 files changed, 7 deletions(-) diff --git a/appveyor.yml b/appveyor.yml index 69bc762f4c..ac6d6ebff8 100644 --- a/appveyor.yml +++ b/appveyor.yml @@ -2,11 +2,6 @@ clone_depth: 1 version: '{branch}-{build}' image: Visual Studio 2017 configuration: Debug -cache: - - C:\ProgramData\chocolatey\bin -> appveyor.yml - - C:\ProgramData\chocolatey\lib -> appveyor.yml - - inspectcode -> appveyor.yml - - packages -> **\packages.config install: - cmd: git submodule update --init --recursive --depth=5 - cmd: choco install resharper-clt -y diff --git a/appveyor_deploy.yml b/appveyor_deploy.yml index 64ad927574..0247714cdf 100644 --- a/appveyor_deploy.yml +++ b/appveyor_deploy.yml @@ -2,8 +2,6 @@ clone_depth: 1 version: '{build}' skip_non_tags: true image: Visual Studio 2017 -cache: - - '%USERPROFILE%\.nuget\packages -> **\*.csproj' install: - git clone https://github.com/ppy/osu-deploy before_build: From a60c888ae5295a3596d869db5c613c94b39df2fb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 6 Jun 2018 22:05:25 +0900 Subject: [PATCH 156/262] Add comment about reasoning for local context variable --- osu.Game/Database/DatabaseContextFactory.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Database/DatabaseContextFactory.cs b/osu.Game/Database/DatabaseContextFactory.cs index b5378b1311..5160239c38 100644 --- a/osu.Game/Database/DatabaseContextFactory.cs +++ b/osu.Game/Database/DatabaseContextFactory.cs @@ -63,6 +63,7 @@ namespace osu.Game.Database } else { + // we want to try-catch the retrieval of the context because it could throw an error (in CreateContext). context = threadContexts.Value; } } From f491a18d40800455fa22e7102671fc84b72d882a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Jun 2018 01:49:34 +0900 Subject: [PATCH 157/262] Fix notifications not showing at main osu! logo on menu --- osu.Game/Screens/Menu/ButtonSystem.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 42e25aad43..81abc4cd3d 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -326,7 +326,10 @@ namespace osu.Game.Screens.Menu logoTracking = false; if (game != null) - game.OverlayActivationMode.Value = state == MenuState.Exit ? OverlayActivation.Disabled : OverlayActivation.UserTriggered; + { + game.OverlayActivationMode.Value = state == MenuState.Exit ? OverlayActivation.Disabled : OverlayActivation.All; + game.Toolbar.Hide(); + } logo.ClearTransforms(targetMember: nameof(Position)); logo.RelativePositionAxes = Axes.Both; From fdf212085266331f37ef8e215b6e7b2871357964 Mon Sep 17 00:00:00 2001 From: jai_ Date: Wed, 6 Jun 2018 18:08:43 +0100 Subject: [PATCH 158/262] Update notfication now points to new changelog page --- osu.Desktop/Overlays/VersionManager.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs index d061aa8423..26e80b3f48 100644 --- a/osu.Desktop/Overlays/VersionManager.cs +++ b/osu.Desktop/Overlays/VersionManager.cs @@ -118,7 +118,7 @@ namespace osu.Desktop.Overlays Icon = FontAwesome.fa_check_square; Activated = delegate { - Process.Start($"https://github.com/ppy/osu/releases/tag/v{version}"); + Process.Start($"https://osu.ppy.sh/home/changelog/{version}"); return true; }; } From dc10277d500b3a514d5566da32bde8a01d06464e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Jun 2018 11:16:26 +0900 Subject: [PATCH 159/262] Thicker bar lines and new design colour --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs index 2147c5a761..d0fc6aa3d6 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs @@ -5,6 +5,7 @@ using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Objects.Drawables; +using OpenTK.Graphics; namespace osu.Game.Rulesets.Mania.Objects.Drawables { @@ -28,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables : base(barLine) { RelativeSizeAxes = Axes.X; - Height = 1; + Height = 2f; AddInternal(new Box { @@ -36,6 +37,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre, RelativeSizeAxes = Axes.Both, + Colour = new Color4(255, 204, 33, 255), }); bool isMajor = barLine.BeatIndex % (int)barLine.ControlPoint.TimeSignature == 0; From 81a3a8a1a4fb1b7eae217e3d97971adb09e4468b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Jun 2018 11:19:36 +0900 Subject: [PATCH 160/262] Add corner radius --- osu.Game.Rulesets.Mania/UI/Column.cs | 28 +++++++++++++++++------- osu.Game.Rulesets.Mania/UI/ManiaStage.cs | 10 ++++----- 2 files changed, 25 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 28cd1b6b39..bdc8107e2a 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -33,6 +33,7 @@ namespace osu.Game.Rulesets.Mania.UI public ManiaAction Action; private readonly Box background; + private readonly Box backgroundOverlay; private readonly Container hitTargetBar; private readonly Container keyIcon; @@ -42,22 +43,32 @@ namespace osu.Game.Rulesets.Mania.UI protected override Container Content => content; private readonly Container content; - private const float opacity_released = 0.1f; - private const float opacity_pressed = 0.25f; - public Column() : base(ScrollingDirection.Up) { RelativeSizeAxes = Axes.Y; Width = column_width; + Masking = true; + CornerRadius = 5; + InternalChildren = new Drawable[] { background = new Box { Name = "Background", RelativeSizeAxes = Axes.Both, - Alpha = opacity_released + Alpha = 0.3f + }, + backgroundOverlay = new Box + { + Name = "Background Gradient Overlay", + RelativeSizeAxes = Axes.Both, + // Height = 0.5f, (doesn't work) + // Anchor = Anchor.BottomLeft, + // Origin = Anchor.BottomLeft, + Blending = BlendingMode.Additive, + Alpha = 0 }, new Container { @@ -182,6 +193,7 @@ namespace osu.Game.Rulesets.Mania.UI accentColour = value; background.Colour = accentColour; + backgroundOverlay.Colour = ColourInfo.GradientVertical(accentColour.Opacity(0.3f), accentColour.Opacity(0)); hitTargetBar.EdgeEffect = new EdgeEffectParameters { @@ -223,8 +235,8 @@ namespace osu.Game.Rulesets.Mania.UI { if (action == Action) { - background.FadeTo(opacity_pressed, 50, Easing.OutQuint); - keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint); + backgroundOverlay.FadeTo(1, 50, Easing.OutQuint).Then().FadeTo(0.5f, 250, Easing.OutQuint); + keyIcon.ScaleTo(1.4f, 50, Easing.OutQuint).Then().ScaleTo(1.3f, 250, Easing.OutQuint); } return false; @@ -234,8 +246,8 @@ namespace osu.Game.Rulesets.Mania.UI { if (action == Action) { - background.FadeTo(opacity_released, 800, Easing.OutQuart); - keyIcon.ScaleTo(1f, 400, Easing.OutQuart); + backgroundOverlay.FadeTo(0, 250, Easing.OutQuint); + keyIcon.ScaleTo(1f, 125, Easing.OutQuint); } return false; diff --git a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs index 605794c795..cb93613c7d 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs @@ -9,7 +9,6 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Game.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Objects; @@ -78,6 +77,7 @@ namespace osu.Game.Rulesets.Mania.UI RelativeSizeAxes = Axes.Y, AutoSizeAxes = Axes.X, Masking = true, + CornerRadius = 5, Children = new Drawable[] { new Box @@ -183,15 +183,15 @@ namespace osu.Game.Rulesets.Mania.UI } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load() { normalColumnColours = new List { - colours.RedDark, - colours.GreenDark + new Color4(94, 0, 57, 255), + new Color4(6, 84, 0, 255) }; - specialColumnColour = colours.BlueDark; + specialColumnColour = new Color4(0, 48, 63, 255); // Set the special column + colour + key foreach (var column in Columns) From d516a0a05c22c4511c331eb89d7c230f5ec41c68 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 7 Jun 2018 13:42:31 +0900 Subject: [PATCH 161/262] Store platform offset clock in variable for visibility --- osu.Game/Screens/Play/Player.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 879bc7a707..9832c430be 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -149,10 +149,10 @@ namespace osu.Game.Screens.Play // Lazer's audio timings in general doesn't match stable. This is the result of user testing, albeit limited. // This only seems to be required on windows. We need to eventually figure out why, with a bit of luck. - var offsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0 }; + var platformOffsetClock = new FramedOffsetClock(adjustableClock) { Offset = RuntimeInfo.OS == RuntimeInfo.Platform.Windows ? 22 : 0 }; // the final usable gameplay clock with user-set offsets applied. - offsetClock = new FramedOffsetClock(offsetClock); + var offsetClock = new FramedOffsetClock(platformOffsetClock); userAudioOffset.ValueChanged += v => offsetClock.Offset = v; userAudioOffset.TriggerChange(); From 56ea1c1d6325a533cbeda6c2dfdbaf97abf9c8ad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Jun 2018 12:20:35 +0900 Subject: [PATCH 162/262] Adjust hold note visibility and glow composition --- .../Objects/Drawables/DrawableHoldNote.cs | 23 ++----------------- .../Objects/Drawables/DrawableNote.cs | 23 ++++++++++--------- .../Objects/Drawables/Pieces/BodyPiece.cs | 4 ++-- 3 files changed, 16 insertions(+), 34 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index f7de503fb3..104425a3ac 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -23,7 +23,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly DrawableNote head; private readonly DrawableNote tail; - private readonly GlowPiece glowPiece; private readonly BodyPiece bodyPiece; private readonly Container fullHeightContainer; @@ -45,17 +44,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables InternalChildren = new Drawable[] { - // The hit object itself cannot be used for various elements because the tail overshoots it - // So a specialized container that is updated to contain the tail height is used - fullHeightContainer = new Container - { - RelativeSizeAxes = Axes.X, - Child = glowPiece = new GlowPiece() - }, bodyPiece = new BodyPiece { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, }, tickContainer = new Container @@ -92,7 +82,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { base.AccentColour = value; - glowPiece.AccentColour = value; bodyPiece.AccentColour = value; head.AccentColour = value; tail.AccentColour = value; @@ -121,12 +110,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables base.Update(); // Make the body piece not lie under the head note - bodyPiece.Y = head.Height; - bodyPiece.Height = DrawHeight - head.Height; - - // Make the fullHeightContainer "contain" the height of the tail note, keeping in mind - // that the tail note overshoots the height of this hit object - fullHeightContainer.Height = DrawHeight + tail.Height; + bodyPiece.Y = head.Height / 2; + bodyPiece.Height = DrawHeight - head.Height / 2 + tail.Height / 2; } public bool OnPressed(ManiaAction action) @@ -175,8 +160,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables : base(holdNote.HitObject.Head, action) { this.holdNote = holdNote; - - GlowPiece.Alpha = 0; } public override bool OnPressed(ManiaAction action) @@ -219,8 +202,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables : base(holdNote.HitObject.Tail, action) { this.holdNote = holdNote; - - GlowPiece.Alpha = 0; } protected override void CheckForJudgements(bool userTriggered, double timeOffset) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 0340e6bba3..856fc97a87 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -1,8 +1,10 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Extensions.Color4Extensions; using OpenTK.Graphics; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; @@ -16,9 +18,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// public class DrawableNote : DrawableManiaHitObject, IKeyBindingHandler { - protected readonly GlowPiece GlowPiece; - - private readonly LaneGlowPiece laneGlowPiece; private readonly NotePiece headPiece; public DrawableNote(Note hitObject, ManiaAction action) @@ -27,14 +26,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables RelativeSizeAxes = Axes.X; AutoSizeAxes = Axes.Y; + CornerRadius = 5; + Masking = true; + InternalChildren = new Drawable[] { - laneGlowPiece = new LaneGlowPiece - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre - }, - GlowPiece = new GlowPiece(), headPiece = new NotePiece { Anchor = Anchor.TopCentre, @@ -49,9 +45,14 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables set { base.AccentColour = value; - laneGlowPiece.AccentColour = AccentColour; - GlowPiece.AccentColour = AccentColour; headPiece.AccentColour = AccentColour; + + EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = AccentColour.Lighten(1f).Opacity(0.6f), + Radius = 10, + }; } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs index 17644a78a5..d18cb57421 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs @@ -123,8 +123,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces if (!IsLoaded) return; - foreground.Colour = AccentColour.Opacity(0.4f); - background.Colour = AccentColour.Opacity(0.2f); + foreground.Colour = AccentColour.Opacity(0.8f); + background.Colour = AccentColour.Opacity(0.5f); subtractionCache.Invalidate(); } From dff4b360b7f1145140f15e59f4e8fabcf0578e1b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Jun 2018 14:27:39 +0900 Subject: [PATCH 163/262] Fix ticks not getting accent colour --- .../Objects/Drawables/DrawableHoldNote.cs | 15 +++------------ 1 file changed, 3 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 104425a3ac..adf84ceb7c 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -36,10 +36,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables /// private bool hasBroken; + private readonly Container tickContainer; + public DrawableHoldNote(HoldNote hitObject, ManiaAction action) : base(hitObject, action) { - Container tickContainer; RelativeSizeAxes = Axes.X; InternalChildren = new Drawable[] @@ -85,17 +86,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables bodyPiece.AccentColour = value; head.AccentColour = value; tail.AccentColour = value; - } - } - - protected override void UpdateState(ArmedState state) - { - switch (state) - { - case ArmedState.Hit: - // Good enough for now, we just want them to have a lifetime end - this.Delay(2000).Expire(); - break; + tickContainer.ForEach(t=>t.AccentColour=value); } } From f9449e841a0daa727e8d1520033909c99f37da19 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Jun 2018 14:27:59 +0900 Subject: [PATCH 164/262] Improve overall visual clarity and explosion effects --- .../Objects/Drawables/DrawableHoldNote.cs | 13 +----- .../Objects/Drawables/DrawableHoldNoteTick.cs | 10 ----- .../Drawables/DrawableManiaHitObject.cs | 13 ++++++ .../Objects/Drawables/DrawableNote.cs | 12 ------ .../Objects/Drawables/Pieces/BodyPiece.cs | 4 +- .../Objects/Drawables/Pieces/NotePiece.cs | 4 +- osu.Game.Rulesets.Mania/UI/Column.cs | 8 ++-- osu.Game.Rulesets.Mania/UI/HitExplosion.cs | 42 ++++++++++--------- 8 files changed, 44 insertions(+), 62 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index adf84ceb7c..04c03c1247 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -2,7 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Linq; -using osu.Game.Rulesets.Objects.Drawables; +using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using OpenTK.Graphics; @@ -24,7 +24,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables private readonly DrawableNote tail; private readonly BodyPiece bodyPiece; - private readonly Container fullHeightContainer; /// /// Time at which the user started holding this hold note. Null if the user is not holding this hold note. @@ -168,11 +167,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables return true; } - - protected override void UpdateState(ArmedState state) - { - // The holdnote keeps scrolling through for now, so having the head disappear looks weird - } } /// @@ -225,11 +219,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables }); } - protected override void UpdateState(ArmedState state) - { - // The holdnote keeps scrolling through, so having the tail disappear looks weird - } - public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down public override bool OnReleased(ManiaAction action) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 74c17ad0fb..d84024fa15 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -87,16 +87,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables AddJudgement(new HoldNoteTickJudgement { Result = HitResult.Perfect }); } - protected override void UpdateState(ArmedState state) - { - switch (State.Value) - { - case ArmedState.Hit: - AccentColour = Color4.Green; - break; - } - } - protected override void Update() { if (AllJudged) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index db1fec40de..fbf1ee8460 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -27,5 +27,18 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (action != null) Action = action.Value; } + + protected override void UpdateState(ArmedState state) + { + switch (state) + { + case ArmedState.Miss: + this.FadeOut(150, Easing.In).Expire(); + break; + case ArmedState.Hit: + this.FadeOut(150, Easing.OutQuint).Expire(); + break; + } + } } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 856fc97a87..3de0a9c5cc 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -8,7 +8,6 @@ using osu.Framework.Graphics.Containers; using osu.Framework.Input.Bindings; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; -using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Mania.Objects.Drawables @@ -72,17 +71,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables AddJudgement(new ManiaJudgement { Result = result }); } - protected override void UpdateState(ArmedState state) - { - switch (state) - { - case ArmedState.Hit: - case ArmedState.Miss: - this.FadeOut(100).Expire(); - break; - } - } - public virtual bool OnPressed(ManiaAction action) { if (action != Action) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs index d18cb57421..4ab2da208a 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs @@ -123,8 +123,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces if (!IsLoaded) return; - foreground.Colour = AccentColour.Opacity(0.8f); - background.Colour = AccentColour.Opacity(0.5f); + foreground.Colour = AccentColour.Opacity(0.9f); + background.Colour = AccentColour.Opacity(0.6f); subtractionCache.Invalidate(); } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/NotePiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/NotePiece.cs index e23b24508b..9ebeb91e0c 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/NotePiece.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/NotePiece.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces /// internal class NotePiece : Container, IHasAccentColour { - private const float head_height = 10; + public const float NOTE_HEIGHT = 10; private const float head_colour_height = 6; private readonly Box colouredBox; @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces public NotePiece() { RelativeSizeAxes = Axes.X; - Height = head_height; + Height = NOTE_HEIGHT; Children = new[] { diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index bdc8107e2a..dee113c82f 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -64,9 +64,9 @@ namespace osu.Game.Rulesets.Mania.UI { Name = "Background Gradient Overlay", RelativeSizeAxes = Axes.Both, - // Height = 0.5f, (doesn't work) - // Anchor = Anchor.BottomLeft, - // Origin = Anchor.BottomLeft, + Height = 0.5f, + Anchor = Anchor.TopLeft, + Origin = Anchor.TopLeft, Blending = BlendingMode.Additive, Alpha = 0 }, @@ -193,7 +193,7 @@ namespace osu.Game.Rulesets.Mania.UI accentColour = value; background.Colour = accentColour; - backgroundOverlay.Colour = ColourInfo.GradientVertical(accentColour.Opacity(0.3f), accentColour.Opacity(0)); + backgroundOverlay.Colour = ColourInfo.GradientVertical(accentColour.Opacity(0.6f), accentColour.Opacity(0)); hitTargetBar.EdgeEffect = new EdgeEffectParameters { diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs index f01dfc0db1..7d94d9113e 100644 --- a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs @@ -1,19 +1,22 @@ // 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.Extensions.Color4Extensions; using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.MathUtils; using osu.Game.Rulesets.Mania.Objects.Drawables; +using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using osu.Game.Rulesets.Objects.Drawables; +using OpenTK; namespace osu.Game.Rulesets.Mania.UI { internal class HitExplosion : CompositeDrawable { - private readonly Box inner; + private readonly CircularContainer circle; public HitExplosion(DrawableHitObject judgedObject) { @@ -22,33 +25,32 @@ namespace osu.Game.Rulesets.Mania.UI Anchor = Anchor.TopCentre; Origin = Anchor.Centre; - RelativeSizeAxes = Axes.Both; - Size = new Vector2(isTick ? 0.5f : 1); - FillMode = FillMode.Fit; + RelativeSizeAxes = Axes.X; + Y = NotePiece.NOTE_HEIGHT / 2; + Height = NotePiece.NOTE_HEIGHT; - Blending = BlendingMode.Additive; + // scale roughly in-line with visual appearance of notes + Scale = new Vector2(isTick ? 0.4f : 0.8f); - Color4 accent = isTick ? Color4.White : judgedObject.AccentColour; - - InternalChild = new CircularContainer + InternalChild = circle = new CircularContainer { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, Masking = true, - BorderThickness = 1, - BorderColour = accent, + // we want our size to be very small so the glow dominates it. + Size = new Vector2(0.1f), EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, - Colour = accent, - Radius = 10, - Hollow = true + Colour = Interpolation.ValueAt(0.1f, judgedObject.AccentColour, Color4.White, 0, 1), + Radius = 100, }, - Child = inner = new Box + Child = new Box { + Alpha = 0, RelativeSizeAxes = Axes.Both, - Colour = accent, - Alpha = 1, - AlwaysPresent = true, + AlwaysPresent = true } }; } @@ -57,8 +59,8 @@ namespace osu.Game.Rulesets.Mania.UI { base.LoadComplete(); - this.ScaleTo(2f, 600, Easing.OutQuint).FadeOut(500); - inner.FadeOut(250); + circle.ResizeTo(circle.Size * new Vector2(4, 20), 1000, Easing.OutQuint); + this.FadeIn(16).Then().FadeOut(500, Easing.OutQuint); Expire(true); } From 5e9a1961cb0f34897cb27106b7c8e8076621a8bf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Jun 2018 11:33:39 +0900 Subject: [PATCH 165/262] Greatly increase the playfield scroll speed adjust step It was so small previously that I believe many people didn't even realise it was working. --- osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index 6f86d20295..231892bdd9 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.UI.Scrolling /// /// The step increase/decrease of the span of time visible by the length of the scrolling axes. /// - private const double time_span_step = 50; + private const double time_span_step = 500; /// /// The span of time that is visible by the length of the scrolling axes. @@ -88,10 +88,10 @@ namespace osu.Game.Rulesets.UI.Scrolling switch (args.Key) { case Key.Minus: - this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange + time_span_step, 200, Easing.OutQuint); + this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange + time_span_step, 600, Easing.OutQuint); break; case Key.Plus: - this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange - time_span_step, 200, Easing.OutQuint); + this.TransformBindableTo(VisibleTimeRange, VisibleTimeRange - time_span_step, 600, Easing.OutQuint); break; } } From e73442c8622679aeff7efe8639e788f09922829a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Jun 2018 15:02:54 +0900 Subject: [PATCH 166/262] Remove net471 build configurations This doesn't actually remove the targets just yet (that will require a bit more work), but rather remove the target options from our IDE configurations to reduce accidental usage of net471/mono. --- .../RulesetTests__catch_.xml | 10 +-- .../RulesetTests__mania_.xml | 10 +-- .../runConfigurations/RulesetTests__osu__.xml | 10 +-- .../RulesetTests__taiko_.xml | 10 +-- .../VisualTests__net471_.xml | 18 ----- .../.idea/runConfigurations/osu___net471_.xml | 18 ----- .vscode/launch.json | 72 +++---------------- .vscode/tasks.json | 44 ++---------- 8 files changed, 24 insertions(+), 168 deletions(-) delete mode 100644 .idea/.idea.osu/.idea/runConfigurations/VisualTests__net471_.xml delete mode 100644 .idea/.idea.osu/.idea/runConfigurations/osu___net471_.xml diff --git a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__catch_.xml b/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__catch_.xml index be69e92748..1c988fe6fd 100644 --- a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__catch_.xml +++ b/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__catch_.xml @@ -1,21 +1,17 @@ - diff --git a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__mania_.xml b/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__mania_.xml index da968b54b7..d7bb0f90f1 100644 --- a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__mania_.xml +++ b/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__mania_.xml @@ -1,21 +1,17 @@ - diff --git a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__osu__.xml b/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__osu__.xml index f2b8155e37..997ac6b078 100644 --- a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__osu__.xml +++ b/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__osu__.xml @@ -1,21 +1,17 @@ - diff --git a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__taiko_.xml b/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__taiko_.xml index 941455f8b4..b7a070174c 100644 --- a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__taiko_.xml +++ b/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__taiko_.xml @@ -1,21 +1,17 @@ - diff --git a/.idea/.idea.osu/.idea/runConfigurations/VisualTests__net471_.xml b/.idea/.idea.osu/.idea/runConfigurations/VisualTests__net471_.xml deleted file mode 100644 index 20a15f985f..0000000000 --- a/.idea/.idea.osu/.idea/runConfigurations/VisualTests__net471_.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - \ No newline at end of file diff --git a/.idea/.idea.osu/.idea/runConfigurations/osu___net471_.xml b/.idea/.idea.osu/.idea/runConfigurations/osu___net471_.xml deleted file mode 100644 index 7196e486d2..0000000000 --- a/.idea/.idea.osu/.idea/runConfigurations/osu___net471_.xml +++ /dev/null @@ -1,18 +0,0 @@ - - - - \ No newline at end of file diff --git a/.vscode/launch.json b/.vscode/launch.json index b9bb75d5bb..ed67fa92cc 100644 --- a/.vscode/launch.json +++ b/.vscode/launch.json @@ -2,63 +2,7 @@ "version": "0.2.0", "configurations": [ { - "name": "VisualTests (Debug, net471)", - "windows": { - "type": "clr" - }, - "type": "mono", - "request": "launch", - "program": "${workspaceRoot}/osu.Game.Tests/bin/Debug/net471/osu.Game.Tests.exe", - "cwd": "${workspaceRoot}", - "preLaunchTask": "Build (Debug, msbuild)", - "runtimeExecutable": null, - "env": {}, - "console": "internalConsole" - }, - { - "name": "VisualTests (Release, net471)", - "windows": { - "type": "clr" - }, - "type": "mono", - "request": "launch", - "program": "${workspaceRoot}/osu.Game.Tests/bin/Release/net471/osu.Game.Tests.exe", - "cwd": "${workspaceRoot}", - "preLaunchTask": "Build (Release, msbuild)", - "runtimeExecutable": null, - "env": {}, - "console": "internalConsole" - }, - { - "name": "osu! (Debug, net471)", - "windows": { - "type": "clr" - }, - "type": "mono", - "request": "launch", - "program": "${workspaceRoot}/osu.Desktop/bin/Debug/net471/osu!.exe", - "cwd": "${workspaceRoot}", - "preLaunchTask": "Build (Debug, msbuild)", - "runtimeExecutable": null, - "env": {}, - "console": "internalConsole" - }, - { - "name": "osu! (Release, net471)", - "windows": { - "type": "clr" - }, - "type": "mono", - "request": "launch", - "program": "${workspaceRoot}/osu.Desktop/bin/Release/net471/osu!.exe", - "cwd": "${workspaceRoot}", - "preLaunchTask": "Build (Release, msbuild)", - "runtimeExecutable": null, - "env": {}, - "console": "internalConsole" - }, - { - "name": "VisualTests (Debug, netcoreapp2.1)", + "name": "VisualTests (Debug)", "type": "coreclr", "request": "launch", "program": "dotnet", @@ -66,12 +10,12 @@ "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tests.dll" ], "cwd": "${workspaceRoot}", - "preLaunchTask": "Build tests (Debug, dotnet)", + "preLaunchTask": "Build tests (Debug)", "env": {}, "console": "internalConsole" }, { - "name": "VisualTests (Release, netcoreapp2.1)", + "name": "VisualTests (Release)", "type": "coreclr", "request": "launch", "program": "dotnet", @@ -79,12 +23,12 @@ "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1/osu.Game.Tests.dll" ], "cwd": "${workspaceRoot}", - "preLaunchTask": "Build tests (Release, dotnet)", + "preLaunchTask": "Build tests (Release)", "env": {}, "console": "internalConsole" }, { - "name": "osu! (Debug, netcoreapp2.1)", + "name": "osu! (Debug)", "type": "coreclr", "request": "launch", "program": "dotnet", @@ -92,12 +36,12 @@ "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll", ], "cwd": "${workspaceRoot}", - "preLaunchTask": "Build osu! (Debug, dotnet)", + "preLaunchTask": "Build osu! (Debug)", "env": {}, "console": "internalConsole" }, { - "name": "osu! (Release, netcoreapp2.1)", + "name": "osu! (Release)", "type": "coreclr", "request": "launch", "program": "dotnet", @@ -105,7 +49,7 @@ "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/osu!.dll", ], "cwd": "${workspaceRoot}", - "preLaunchTask": "Build osu! (Release, dotnet)", + "preLaunchTask": "Build osu! (Release)", "env": {}, "console": "internalConsole" } diff --git a/.vscode/tasks.json b/.vscode/tasks.json index bebad750ca..188f20b69f 100644 --- a/.vscode/tasks.json +++ b/.vscode/tasks.json @@ -4,34 +4,7 @@ "version": "2.0.0", "tasks": [ { - "label": "Build (Debug, msbuild)", - "type": "shell", - "command": "msbuild", - "args": [ - "/p:TargetFramework=net471", - "/p:GenerateFullPaths=true", - "/m", - "/verbosity:m" - ], - "group": "build", - "problemMatcher": "$msCompile" - }, - { - "label": "Build (Release, msbuild)", - "type": "shell", - "command": "msbuild", - "args": [ - "/p:Configuration=Release", - "/p:TargetFramework=net471", - "/p:GenerateFullPaths=true", - "/m", - "/verbosity:m" - ], - "group": "build", - "problemMatcher": "$msCompile" - }, - { - "label": "Build osu! (Debug, dotnet)", + "label": "Build osu! (Debug)", "type": "shell", "command": "dotnet", "args": [ @@ -47,7 +20,7 @@ "problemMatcher": "$msCompile" }, { - "label": "Build osu! (Release, dotnet)", + "label": "Build osu! (Release)", "type": "shell", "command": "dotnet", "args": [ @@ -64,7 +37,7 @@ "problemMatcher": "$msCompile" }, { - "label": "Build tests (Debug, dotnet)", + "label": "Build tests (Debug)", "type": "shell", "command": "dotnet", "args": [ @@ -80,7 +53,7 @@ "problemMatcher": "$msCompile" }, { - "label": "Build tests (Release, dotnet)", + "label": "Build tests (Release)", "type": "shell", "command": "dotnet", "args": [ @@ -96,15 +69,6 @@ "group": "build", "problemMatcher": "$msCompile" }, - { - "label": "Restore (net471)", - "type": "shell", - "command": "nuget", - "args": [ - "restore" - ], - "problemMatcher": [] - }, { "label": "Restore (netcoreapp2.1)", "type": "shell", From 8d0161c2fc60b263f20e3dc3bbf3244449b35f95 Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Thu, 7 Jun 2018 15:07:15 +0900 Subject: [PATCH 167/262] Refactoring --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs | 2 +- .../Objects/Drawables/DrawableHoldNoteTick.cs | 1 - osu.Game.Rulesets.Mania/UI/HitExplosion.cs | 1 - 3 files changed, 1 insertion(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 04c03c1247..e008fa952e 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -85,7 +85,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables bodyPiece.AccentColour = value; head.AccentColour = value; tail.AccentColour = value; - tickContainer.ForEach(t=>t.AccentColour=value); + tickContainer.ForEach(t => t.AccentColour = value); } } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index d84024fa15..5df6079efa 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -8,7 +8,6 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Mania.Judgements; -using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Scoring; diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs index 7d94d9113e..f19c3a811b 100644 --- a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.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.Framework.Extensions.Color4Extensions; using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; From 475fb065591e031300728cbc98dd8522083d9105 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 7 Jun 2018 16:46:54 +0900 Subject: [PATCH 168/262] Use new bind method --- osu.Game/Overlays/MusicController.cs | 7 ++----- .../Screens/Compose/Timeline/ScrollingTimelineContainer.cs | 4 +--- osu.Game/Screens/Select/SongSelect.cs | 6 ++---- osu.Game/Tests/Visual/EditorClockTestCase.cs | 3 +-- osu.Game/osu.Game.csproj | 2 +- 5 files changed, 7 insertions(+), 15 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index 18e5379224..d96bb40165 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -237,11 +237,8 @@ namespace osu.Game.Overlays protected override void LoadComplete() { - beatmap.ValueChanged += beatmapChanged; - beatmap.DisabledChanged += beatmapDisabledChanged; - - beatmapChanged(beatmap.Value); - + beatmap.BindValueChanged(beatmapChanged, true); + beatmap.BindDisabledChanged(beatmapDisabledChanged, true); base.LoadComplete(); } diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs index dfc6b41432..cc51ae1096 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ScrollingTimelineContainer.cs @@ -47,9 +47,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private void load(IBindableBeatmap beatmap) { this.beatmap.BindTo(beatmap); - - beatmap.ValueChanged += beatmapChanged; - beatmapChanged(beatmap.Value); + this.beatmap.BindValueChanged(beatmapChanged, true); } private void beatmapChanged(WorkingBeatmap beatmap) => waveform.Beatmap = beatmap; diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index b04ffecf48..70b473bcd9 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -207,10 +207,8 @@ namespace osu.Game.Screens.Select Carousel.BeatmapSets = this.beatmaps.GetAllUsableBeatmapSetsEnumerable(); - Beatmap.DisabledChanged += disabled => Carousel.AllowSelection = !disabled; - Beatmap.ValueChanged += workingBeatmapChanged; - - workingBeatmapChanged(Beatmap.Value); + Beatmap.BindDisabledChanged(disabled => Carousel.AllowSelection = !disabled, true); + Beatmap.BindValueChanged(workingBeatmapChanged); } public void Edit(BeatmapInfo beatmap) diff --git a/osu.Game/Tests/Visual/EditorClockTestCase.cs b/osu.Game/Tests/Visual/EditorClockTestCase.cs index 0363fa75ba..08dc6a3bbd 100644 --- a/osu.Game/Tests/Visual/EditorClockTestCase.cs +++ b/osu.Game/Tests/Visual/EditorClockTestCase.cs @@ -32,8 +32,7 @@ namespace osu.Game.Tests.Visual Dependencies.CacheAs(Clock); Dependencies.CacheAs(Clock); - Beatmap.ValueChanged += beatmapChanged; - beatmapChanged(Beatmap.Value); + Beatmap.BindValueChanged(beatmapChanged, true); } private void beatmapChanged(WorkingBeatmap working) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2300ba6a72..1e97fb6a68 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -18,7 +18,7 @@ - + From b3cab35a2c1c5831d38c7688dfc8c2441e084a0c Mon Sep 17 00:00:00 2001 From: rootyElf Date: Thu, 7 Jun 2018 15:46:31 +0100 Subject: [PATCH 169/262] Update EntityFramework libraries Updated Microsoft.EntityFrameworkCore.Sqlite and Microsoft.EntityFrameworkCore.Sqlite.Core to 2.1.0 to enable the app to run on arm linux platforms. This also updates SQLitePCLRaw.lib.e_sqlite3.linux from 1.1.7 to 1.1.11. While 1.1.7 only provides native libraries for linux-x64 and linux-x86, 1.1.11 adds alpine-x64, linux-arm, linux-arm64, linux-armel and linux-musl-x64. --- osu.Game/osu.Game.csproj | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 1e97fb6a68..363fc7d7bb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -15,12 +15,12 @@ - - + + - + - \ No newline at end of file + From 95bc3127995a1d89e06680baa9ff6d6e72923b61 Mon Sep 17 00:00:00 2001 From: rootyElf Date: Thu, 7 Jun 2018 15:48:06 +0100 Subject: [PATCH 170/262] Update EntityFramework libraries --- osu.Desktop/osu.Desktop.csproj | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj index 766f36fa74..0d4efc7eed 100644 --- a/osu.Desktop/osu.Desktop.csproj +++ b/osu.Desktop/osu.Desktop.csproj @@ -29,10 +29,10 @@ - + - \ No newline at end of file + From 8aaaa42c5036ac33d5de157ae256cb55b15277ba Mon Sep 17 00:00:00 2001 From: rootyElf Date: Thu, 7 Jun 2018 15:51:09 +0100 Subject: [PATCH 171/262] Update EntityFramework libraries --- osu.TestProject.props | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.TestProject.props b/osu.TestProject.props index b51ca13ed5..cf8276eee1 100644 --- a/osu.TestProject.props +++ b/osu.TestProject.props @@ -11,7 +11,7 @@ - + @@ -25,4 +25,4 @@ false - \ No newline at end of file + From 0b4f5af52e31c5088fa1edba366bbb931d830e8e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 03:17:12 +0900 Subject: [PATCH 172/262] 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 173/262] 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 8cc31aca541db1a002177a1467f5e30a6ebe0a78 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 11:41:54 +0900 Subject: [PATCH 174/262] Reorganise API requests and response classes They were previously breaking the two-class-per-file rule. --- .../Visual/TestCaseBeatmapScoresContainer.cs | 30 ++--- .../TestCaseUserProfileRecentSection.cs | 37 +++--- .../API/Requests/GetBeatmapDetailsRequest.cs | 28 +--- .../API/Requests/GetBeatmapSetRequest.cs | 4 +- .../Online/API/Requests/GetScoresRequest.cs | 121 +----------------- .../API/Requests/GetUserBeatmapsRequest.cs | 3 +- .../GetUserMostPlayedBeatmapsRequest.cs | 30 +---- .../GetUserRecentActivitiesRequest.cs | 87 +------------ .../API/Requests/GetUserScoresRequest.cs | 3 +- .../Online/API/Requests/GetUsersRequest.cs | 11 +- .../Requests/Responses/APIBeatmapMetrics.cs | 29 +++++ .../APIBeatmapSet.cs} | 6 +- .../Requests/Responses/APIRecentActivity.cs | 89 +++++++++++++ .../Online/API/Requests/Responses/APIScore.cs | 117 +++++++++++++++++ .../API/Requests/Responses/APIScores.cs | 14 ++ .../Online/API/Requests/Responses/APIUser.cs | 14 ++ .../Responses/APIUserMostPlayedBeatmap.cs | 30 +++++ .../API/Requests/SearchBeatmapSetsRequest.cs | 3 +- .../BeatmapSet/Scores/DrawableScore.cs | 4 +- .../BeatmapSet/Scores/DrawableTopScore.cs | 6 +- .../BeatmapSet/Scores/ScoresContainer.cs | 5 +- .../Sections/Ranks/PaginatedScoreContainer.cs | 3 +- .../Sections/Recent/DrawableRecentActivity.cs | 5 +- .../PaginatedRecentActivityContainer.cs | 3 +- 24 files changed, 366 insertions(+), 316 deletions(-) create mode 100644 osu.Game/Online/API/Requests/Responses/APIBeatmapMetrics.cs rename osu.Game/Online/API/Requests/{APIResponseBeatmapSet.cs => Responses/APIBeatmapSet.cs} (97%) create mode 100644 osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIScore.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIScores.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIUser.cs create mode 100644 osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs index 5be7386238..3f63bacfa6 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs @@ -6,7 +6,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Framework.MathUtils; using osu.Game.Graphics; -using osu.Game.Online.API.Requests; using osu.Game.Overlays.BeatmapSet.Scores; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; @@ -15,6 +14,7 @@ using osu.Game.Users; using System.Collections.Generic; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Rulesets.Osu; namespace osu.Game.Tests.Visual @@ -22,9 +22,9 @@ namespace osu.Game.Tests.Visual [System.ComponentModel.Description("in BeatmapOverlay")] public class TestCaseBeatmapScoresContainer : OsuTestCase { - private readonly IEnumerable scores; - private readonly IEnumerable anotherScores; - private readonly OnlineScore topScore; + private readonly IEnumerable scores; + private readonly IEnumerable anotherScores; + private readonly APIScore topScore; private readonly Box background; public TestCaseBeatmapScoresContainer() @@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual scores = new[] { - new OnlineScore + new APIScore { User = new User { @@ -80,7 +80,7 @@ namespace osu.Game.Tests.Visual TotalScore = 1234567890, Accuracy = 1, }, - new OnlineScore + new APIScore { User = new User { @@ -102,7 +102,7 @@ namespace osu.Game.Tests.Visual TotalScore = 1234789, Accuracy = 0.9997, }, - new OnlineScore + new APIScore { User = new User { @@ -123,7 +123,7 @@ namespace osu.Game.Tests.Visual TotalScore = 12345678, Accuracy = 0.9854, }, - new OnlineScore + new APIScore { User = new User { @@ -143,7 +143,7 @@ namespace osu.Game.Tests.Visual TotalScore = 1234567, Accuracy = 0.8765, }, - new OnlineScore + new APIScore { User = new User { @@ -169,7 +169,7 @@ namespace osu.Game.Tests.Visual anotherScores = new[] { - new OnlineScore + new APIScore { User = new User { @@ -191,7 +191,7 @@ namespace osu.Game.Tests.Visual TotalScore = 1234789, Accuracy = 0.9997, }, - new OnlineScore + new APIScore { User = new User { @@ -214,7 +214,7 @@ namespace osu.Game.Tests.Visual TotalScore = 1234567890, Accuracy = 1, }, - new OnlineScore + new APIScore { User = new User { @@ -230,7 +230,7 @@ namespace osu.Game.Tests.Visual TotalScore = 123456, Accuracy = 0.6543, }, - new OnlineScore + new APIScore { User = new User { @@ -251,7 +251,7 @@ namespace osu.Game.Tests.Visual TotalScore = 12345678, Accuracy = 0.9854, }, - new OnlineScore + new APIScore { User = new User { @@ -279,7 +279,7 @@ namespace osu.Game.Tests.Visual s.Statistics.Add(HitResult.Meh, RNG.Next(2000)); } - topScore = new OnlineScore + topScore = new APIScore { User = new User { diff --git a/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs index f625bc0150..b14606780d 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs @@ -12,6 +12,7 @@ using osu.Game.Overlays.Profile.Sections.Recent; using System; using System.Collections.Generic; using System.Linq; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Tests.Visual { @@ -49,15 +50,15 @@ namespace osu.Game.Tests.Visual }; } - private IEnumerable createDummyActivities() + private IEnumerable createDummyActivities() { - var dummyBeatmap = new RecentActivity.RecentActivityBeatmap + var dummyBeatmap = new APIRecentActivity.RecentActivityBeatmap { Title = @"Dummy beatmap", Url = "/b/1337", }; - var dummyUser = new RecentActivity.RecentActivityUser + var dummyUser = new APIRecentActivity.RecentActivityUser { Username = "DummyReborn", Url = "/u/666", @@ -66,61 +67,61 @@ namespace osu.Game.Tests.Visual return new[] { - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.Achievement, - Achievement = new RecentActivity.RecentActivityAchievement + Achievement = new APIRecentActivity.RecentActivityAchievement { Name = @"Feelin' It", Slug = @"all-secret-feelinit", }, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapPlaycount, Count = 1337, Beatmap = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetApprove, Approval = BeatmapApproval.Qualified, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetDelete, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetRevive, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetRevive, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetUpdate, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.BeatmapsetUpload, Beatmapset = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.Rank, @@ -128,29 +129,29 @@ namespace osu.Game.Tests.Visual Mode = "osu!", Beatmap = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.RankLost, Mode = "osu!", Beatmap = dummyBeatmap, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.UsernameChange, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.UserSupportAgain, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.UserSupportFirst, }, - new RecentActivity + new APIRecentActivity { User = dummyUser, Type = RecentActivityType.UserSupportGift, diff --git a/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs index b853da7e76..ab840d054f 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.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 Newtonsoft.Json; using osu.Game.Beatmaps; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetBeatmapDetailsRequest : APIRequest + public class GetBeatmapDetailsRequest : APIRequest { private readonly BeatmapInfo beatmap; @@ -19,28 +19,4 @@ namespace osu.Game.Online.API.Requests protected override string Target => $@"beatmaps/{lookupString}"; } - - public class GetBeatmapDetailsResponse : BeatmapMetrics - { - //the online API returns some metrics as a nested object. - [JsonProperty(@"failtimes")] - private BeatmapMetrics failTimes - { - set - { - Fails = value.Fails; - Retries = value.Retries; - } - } - - //and other metrics in the beatmap set. - [JsonProperty(@"beatmapset")] - private BeatmapMetrics beatmapSet - { - set - { - Ratings = value.Ratings; - } - } - } } diff --git a/osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs index 37dd77af46..d04e069cd6 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapSetRequest.cs @@ -1,9 +1,11 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Game.Online.API.Requests.Responses; + namespace osu.Game.Online.API.Requests { - public class GetBeatmapSetRequest : APIRequest + public class GetBeatmapSetRequest : APIRequest { private readonly int id; private readonly BeatmapSetLookupType type; diff --git a/osu.Game/Online/API/Requests/GetScoresRequest.cs b/osu.Game/Online/API/Requests/GetScoresRequest.cs index cff6fd4ea5..3be5b91a0d 100644 --- a/osu.Game/Online/API/Requests/GetScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetScoresRequest.cs @@ -2,20 +2,15 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; -using System.Linq; -using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets; -using osu.Game.Users; -using osu.Game.Rulesets.Replays; -using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Select.Leaderboards; using osu.Framework.IO.Network; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetScoresRequest : APIRequest + public class GetScoresRequest : APIRequest { private readonly BeatmapInfo beatmap; private readonly LeaderboardScope scope; @@ -36,9 +31,9 @@ namespace osu.Game.Online.API.Requests Success += onSuccess; } - private void onSuccess(GetScoresResponse r) + private void onSuccess(APIScores r) { - foreach (OnlineScore score in r.Scores) + foreach (APIScore score in r.Scores) score.ApplyBeatmap(beatmap); } @@ -55,112 +50,4 @@ namespace osu.Game.Online.API.Requests protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}/scores"; } - - public class GetScoresResponse - { - [JsonProperty(@"scores")] - public IEnumerable Scores; - } - - public class OnlineScore : Score - { - [JsonProperty(@"score")] - private double totalScore - { - set { TotalScore = value; } - } - - [JsonProperty(@"max_combo")] - private int maxCombo - { - set { MaxCombo = value; } - } - - [JsonProperty(@"user")] - private User user - { - set { User = value; } - } - - [JsonProperty(@"replay_data")] - private Replay replay - { - set { Replay = value; } - } - - [JsonProperty(@"mode_int")] - public int OnlineRulesetID { get; set; } - - [JsonProperty(@"score_id")] - private long onlineScoreID - { - set { OnlineScoreID = value; } - } - - [JsonProperty(@"created_at")] - private DateTimeOffset date - { - set { Date = value; } - } - - [JsonProperty(@"beatmap")] - private BeatmapInfo beatmap - { - set { Beatmap = value; } - } - - [JsonProperty(@"beatmapset")] - private BeatmapMetadata metadata - { - set { Beatmap.Metadata = value; } - } - - [JsonProperty(@"statistics")] - private Dictionary jsonStats - { - set - { - foreach (var kvp in value) - { - HitResult newKey; - switch (kvp.Key) - { - case @"count_300": - newKey = HitResult.Great; - break; - case @"count_100": - newKey = HitResult.Good; - break; - case @"count_50": - newKey = HitResult.Meh; - break; - case @"count_miss": - newKey = HitResult.Miss; - break; - default: - continue; - } - - Statistics.Add(newKey, kvp.Value); - } - } - } - - [JsonProperty(@"mods")] - private string[] modStrings { get; set; } - - public void ApplyBeatmap(BeatmapInfo beatmap) - { - Beatmap = beatmap; - ApplyRuleset(beatmap.Ruleset); - } - - public void ApplyRuleset(RulesetInfo ruleset) - { - Ruleset = ruleset; - - // Evaluate the mod string - Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); - } - } } diff --git a/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs b/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs index 48e9babd97..b847a954f6 100644 --- a/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserBeatmapsRequest.cs @@ -3,10 +3,11 @@ using Humanizer; using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetUserBeatmapsRequest : APIRequest> + public class GetUserBeatmapsRequest : APIRequest> { private readonly long userId; private readonly int offset; diff --git a/osu.Game/Online/API/Requests/GetUserMostPlayedBeatmapsRequest.cs b/osu.Game/Online/API/Requests/GetUserMostPlayedBeatmapsRequest.cs index 106f3d4fb1..9a54aafa82 100644 --- a/osu.Game/Online/API/Requests/GetUserMostPlayedBeatmapsRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserMostPlayedBeatmapsRequest.cs @@ -1,14 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using Newtonsoft.Json; -using osu.Game.Beatmaps; -using osu.Game.Rulesets; using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetUserMostPlayedBeatmapsRequest : APIRequest> + public class GetUserMostPlayedBeatmapsRequest : APIRequest> { private readonly long userId; private readonly int offset; @@ -21,28 +19,4 @@ namespace osu.Game.Online.API.Requests protected override string Target => $@"users/{userId}/beatmapsets/most_played?offset={offset}"; } - - public class MostPlayedBeatmap - { - [JsonProperty("beatmap_id")] - public int BeatmapID; - - [JsonProperty("count")] - public int PlayCount; - - [JsonProperty] - private BeatmapInfo beatmap; - - [JsonProperty] - private APIResponseBeatmapSet beatmapSet; - - public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets) - { - BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets); - beatmap.BeatmapSet = setInfo; - beatmap.OnlineBeatmapSetID = setInfo.OnlineBeatmapSetID; - beatmap.Metadata = setInfo.Metadata; - return beatmap; - } - } } diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index ded0e4f80d..e1cad1a532 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -1,15 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using Newtonsoft.Json; -using osu.Game.Rulesets.Scoring; -using Humanizer; -using System; using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetUserRecentActivitiesRequest : APIRequest> + public class GetUserRecentActivitiesRequest : APIRequest> { private readonly long userId; private readonly int offset; @@ -23,86 +20,6 @@ namespace osu.Game.Online.API.Requests protected override string Target => $"users/{userId}/recent_activity?offset={offset}"; } - public class RecentActivity - { - [JsonProperty("id")] - public int ID; - - [JsonProperty("createdAt")] - public DateTimeOffset CreatedAt; - - [JsonProperty] - private string type - { - set => Type = (RecentActivityType)Enum.Parse(typeof(RecentActivityType), value.Pascalize()); - } - - public RecentActivityType Type; - - [JsonProperty] - private string scoreRank - { - set => ScoreRank = (ScoreRank)Enum.Parse(typeof(ScoreRank), value); - } - - public ScoreRank ScoreRank; - - [JsonProperty("rank")] - public int Rank; - - [JsonProperty("approval")] - public BeatmapApproval Approval; - - [JsonProperty("count")] - public int Count; - - [JsonProperty("mode")] - public string Mode; - - [JsonProperty("beatmap")] - public RecentActivityBeatmap Beatmap; - - [JsonProperty("beatmapset")] - public RecentActivityBeatmap Beatmapset; - - [JsonProperty("user")] - public RecentActivityUser User; - - [JsonProperty("achievement")] - public RecentActivityAchievement Achievement; - - public class RecentActivityBeatmap - { - [JsonProperty("title")] - public string Title; - - [JsonProperty("url")] - public string Url; - } - - public class RecentActivityUser - { - [JsonProperty("username")] - public string Username; - - [JsonProperty("url")] - public string Url; - - [JsonProperty("previousUsername")] - public string PreviousUsername; - } - - public class RecentActivityAchievement - { - [JsonProperty("slug")] - public string Slug; - - [JsonProperty("name")] - public string Name; - } - - } - public enum RecentActivityType { Achievement, diff --git a/osu.Game/Online/API/Requests/GetUserScoresRequest.cs b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs index 7757f529e0..ea14135a61 100644 --- a/osu.Game/Online/API/Requests/GetUserScoresRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserScoresRequest.cs @@ -2,10 +2,11 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetUserScoresRequest : APIRequest> + public class GetUserScoresRequest : APIRequest> { private readonly long userId; private readonly ScoreType type; diff --git a/osu.Game/Online/API/Requests/GetUsersRequest.cs b/osu.Game/Online/API/Requests/GetUsersRequest.cs index 575d0464aa..17dd9263c9 100644 --- a/osu.Game/Online/API/Requests/GetUsersRequest.cs +++ b/osu.Game/Online/API/Requests/GetUsersRequest.cs @@ -2,19 +2,12 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using Newtonsoft.Json; -using osu.Game.Users; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Online.API.Requests { - public class GetUsersRequest : APIRequest> + public class GetUsersRequest : APIRequest> { protected override string Target => @"rankings/osu/performance"; } - - public class RankingEntry - { - [JsonProperty] - public User User; - } } diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapMetrics.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapMetrics.cs new file mode 100644 index 0000000000..e67c60cb91 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapMetrics.cs @@ -0,0 +1,29 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; +using osu.Game.Beatmaps; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIBeatmapMetrics : BeatmapMetrics + { + //the online API returns some metrics as a nested object. + [JsonProperty(@"failtimes")] + private BeatmapMetrics failTimes + { + set + { + Fails = value.Fails; + Retries = value.Retries; + } + } + + //and other metrics in the beatmap set. + [JsonProperty(@"beatmapset")] + private BeatmapMetrics beatmapSet + { + set => Ratings = value.Ratings; + } + } +} diff --git a/osu.Game/Online/API/Requests/APIResponseBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs similarity index 97% rename from osu.Game/Online/API/Requests/APIResponseBeatmapSet.cs rename to osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index 44c1216959..cbe3b929fd 100644 --- a/osu.Game/Online/API/Requests/APIResponseBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -1,16 +1,16 @@ // 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 Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets; -using System; -namespace osu.Game.Online.API.Requests +namespace osu.Game.Online.API.Requests.Responses { - public class APIResponseBeatmapSet : BeatmapMetadata // todo: this is a bit wrong... + public class APIBeatmapSet : BeatmapMetadata // todo: this is a bit wrong... { [JsonProperty(@"covers")] private BeatmapSetOnlineCovers covers { get; set; } diff --git a/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs new file mode 100644 index 0000000000..2c65a37cf8 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIRecentActivity.cs @@ -0,0 +1,89 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using Humanizer; +using Newtonsoft.Json; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIRecentActivity + { + [JsonProperty("id")] + public int ID; + + [JsonProperty("createdAt")] + public DateTimeOffset CreatedAt; + + [JsonProperty] + private string type + { + set => Type = (RecentActivityType)Enum.Parse(typeof(RecentActivityType), value.Pascalize()); + } + + public RecentActivityType Type; + + [JsonProperty] + private string scoreRank + { + set => ScoreRank = (ScoreRank)Enum.Parse(typeof(ScoreRank), value); + } + + public ScoreRank ScoreRank; + + [JsonProperty("rank")] + public int Rank; + + [JsonProperty("approval")] + public BeatmapApproval Approval; + + [JsonProperty("count")] + public int Count; + + [JsonProperty("mode")] + public string Mode; + + [JsonProperty("beatmap")] + public RecentActivityBeatmap Beatmap; + + [JsonProperty("beatmapset")] + public RecentActivityBeatmap Beatmapset; + + [JsonProperty("user")] + public RecentActivityUser User; + + [JsonProperty("achievement")] + public RecentActivityAchievement Achievement; + + public class RecentActivityBeatmap + { + [JsonProperty("title")] + public string Title; + + [JsonProperty("url")] + public string Url; + } + + public class RecentActivityUser + { + [JsonProperty("username")] + public string Username; + + [JsonProperty("url")] + public string Url; + + [JsonProperty("previousUsername")] + public string PreviousUsername; + } + + public class RecentActivityAchievement + { + [JsonProperty("slug")] + public string Slug; + + [JsonProperty("name")] + public string Name; + } + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIScore.cs b/osu.Game/Online/API/Requests/Responses/APIScore.cs new file mode 100644 index 0000000000..a398bf46ee --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIScore.cs @@ -0,0 +1,117 @@ +// 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 Newtonsoft.Json; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; +using osu.Game.Rulesets.Replays; +using osu.Game.Rulesets.Scoring; +using osu.Game.Users; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIScore : Score + { + [JsonProperty(@"score")] + private double totalScore + { + set => TotalScore = value; + } + + [JsonProperty(@"max_combo")] + private int maxCombo + { + set => MaxCombo = value; + } + + [JsonProperty(@"user")] + private User user + { + set => User = value; + } + + [JsonProperty(@"replay_data")] + private Replay replay + { + set => Replay = value; + } + + [JsonProperty(@"mode_int")] + public int OnlineRulesetID { get; set; } + + [JsonProperty(@"score_id")] + private long onlineScoreID + { + set => OnlineScoreID = value; + } + + [JsonProperty(@"created_at")] + private DateTimeOffset date + { + set => Date = value; + } + + [JsonProperty(@"beatmap")] + private BeatmapInfo beatmap + { + set => Beatmap = value; + } + + [JsonProperty(@"beatmapset")] + private BeatmapMetadata metadata + { + set => Beatmap.Metadata = value; + } + + [JsonProperty(@"statistics")] + private Dictionary jsonStats + { + set + { + foreach (var kvp in value) + { + HitResult newKey; + switch (kvp.Key) + { + case @"count_300": + newKey = HitResult.Great; + break; + case @"count_100": + newKey = HitResult.Good; + break; + case @"count_50": + newKey = HitResult.Meh; + break; + case @"count_miss": + newKey = HitResult.Miss; + break; + default: + continue; + } + + Statistics.Add(newKey, kvp.Value); + } + } + } + + [JsonProperty(@"mods")] + private string[] modStrings { get; set; } + + public void ApplyBeatmap(BeatmapInfo beatmap) + { + Beatmap = beatmap; + ApplyRuleset(beatmap.Ruleset); + } + + public void ApplyRuleset(RulesetInfo ruleset) + { + Ruleset = ruleset; + + // Evaluate the mod string + Mods = Ruleset.CreateInstance().GetAllMods().Where(mod => modStrings.Contains(mod.ShortenedName)).ToArray(); + } + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIScores.cs b/osu.Game/Online/API/Requests/Responses/APIScores.cs new file mode 100644 index 0000000000..b4213db253 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIScores.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using Newtonsoft.Json; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIScores + { + [JsonProperty(@"scores")] + public IEnumerable Scores; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIUser.cs b/osu.Game/Online/API/Requests/Responses/APIUser.cs new file mode 100644 index 0000000000..54c8451456 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIUser.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; +using osu.Game.Users; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIUser + { + [JsonProperty] + public User User; + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs new file mode 100644 index 0000000000..26f80321bc --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs @@ -0,0 +1,30 @@ +using Newtonsoft.Json; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIUserMostPlayedBeatmap + { + [JsonProperty("beatmap_id")] + public int BeatmapID; + + [JsonProperty("count")] + public int PlayCount; + + [JsonProperty] + private BeatmapInfo beatmap; + + [JsonProperty] + private APIBeatmapSet beatmapSet; + + public BeatmapInfo GetBeatmapInfo(RulesetStore rulesets) + { + BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets); + beatmap.BeatmapSet = setInfo; + beatmap.OnlineBeatmapSetID = setInfo.OnlineBeatmapSetID; + beatmap.Metadata = setInfo.Metadata; + return beatmap; + } + } +} diff --git a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs index d68314f8fc..2a154d1230 100644 --- a/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs +++ b/osu.Game/Online/API/Requests/SearchBeatmapSetsRequest.cs @@ -3,13 +3,14 @@ using System.Collections.Generic; using System.ComponentModel; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays; using osu.Game.Overlays.Direct; using osu.Game.Rulesets; namespace osu.Game.Online.API.Requests { - public class SearchBeatmapSetsRequest : APIRequest> + public class SearchBeatmapSetsRequest : APIRequest> { private readonly string query; private readonly RulesetInfo ruleset; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs index 10e689698d..fc8b3a6800 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableScore.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly Box background; - public DrawableScore(int index, OnlineScore score) + public DrawableScore(int index, APIScore score) { ScoreModsContainer modsContainer; diff --git a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs index 8ac79eabb4..b3ceffd35e 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/DrawableTopScore.cs @@ -11,7 +11,7 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Input; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Overlays.Profile.Sections.Ranks; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; @@ -42,8 +42,8 @@ namespace osu.Game.Overlays.BeatmapSet.Scores private readonly InfoColumn statistics; private readonly ScoreModsContainer modsContainer; - private OnlineScore score; - public OnlineScore Score + private APIScore score; + public APIScore Score { get { return score; } set diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs index 185282bec9..626de14c98 100644 --- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs +++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs @@ -11,6 +11,7 @@ using System.Linq; using osu.Framework.Allocation; using osu.Game.Beatmaps; using osu.Game.Online.API; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.BeatmapSet.Scores { @@ -28,10 +29,10 @@ namespace osu.Game.Overlays.BeatmapSet.Scores set => loadingAnimation.FadeTo(value ? 1 : 0, fade_duration); } - private IEnumerable scores; + private IEnumerable scores; private BeatmapInfo beatmap; - public IEnumerable Scores + public IEnumerable Scores { get { return scores; } set diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs index 87df84e2e5..707de0a10f 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/PaginatedScoreContainer.cs @@ -8,6 +8,7 @@ using osu.Game.Online.API.Requests; using osu.Game.Users; using System; using System.Linq; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections.Ranks { @@ -49,7 +50,7 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks MissingText.Hide(); - foreach (OnlineScore score in scores) + foreach (APIScore score in scores) { DrawableProfileScore drawableScore; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 721cc30b61..046c1b1a33 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -8,6 +8,7 @@ using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Online.API.Requests.Responses; using osu.Game.Online.Chat; using osu.Game.Screens.Select.Leaderboards; @@ -17,11 +18,11 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { private APIAccess api; - private readonly RecentActivity activity; + private readonly APIRecentActivity activity; private LinkFlowContainer content; - public DrawableRecentActivity(RecentActivity activity) + public DrawableRecentActivity(APIRecentActivity activity) { this.activity = activity; } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 8c1108b115..ee2f2f5973 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -6,6 +6,7 @@ using osu.Framework.Graphics; using osu.Game.Online.API.Requests; using osu.Game.Users; using System.Linq; +using osu.Game.Online.API.Requests.Responses; namespace osu.Game.Overlays.Profile.Sections.Recent { @@ -36,7 +37,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent MissingText.Hide(); - foreach (RecentActivity activity in activities) + foreach (APIRecentActivity activity in activities) { ItemsContainer.Add(new DrawableRecentActivity(activity)); } From 1716975a37c53baa661e34b306bee0b5d6102a5d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 12:04:33 +0900 Subject: [PATCH 175/262] Move out APIBeatmap --- .../API/Requests/Responses/APIBeatmap.cs | 78 +++++++++++++++++++ .../API/Requests/Responses/APIBeatmapSet.cs | 74 +----------------- 2 files changed, 81 insertions(+), 71 deletions(-) create mode 100644 osu.Game/Online/API/Requests/Responses/APIBeatmap.cs diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs new file mode 100644 index 0000000000..f75d320a46 --- /dev/null +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -0,0 +1,78 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; +using osu.Game.Beatmaps; +using osu.Game.Rulesets; + +namespace osu.Game.Online.API.Requests.Responses +{ + public class APIBeatmap : BeatmapMetadata + { + [JsonProperty(@"id")] + private int onlineBeatmapID { get; set; } + + [JsonProperty(@"playcount")] + private int playCount { get; set; } + + [JsonProperty(@"passcount")] + private int passCount { get; set; } + + [JsonProperty(@"mode_int")] + private int ruleset { get; set; } + + [JsonProperty(@"difficulty_rating")] + private double starDifficulty { get; set; } + + [JsonProperty(@"drain")] + private float drainRate { get; set; } + + [JsonProperty(@"cs")] + private float circleSize { get; set; } + + [JsonProperty(@"ar")] + private float approachRate { get; set; } + + [JsonProperty(@"accuracy")] + private float overallDifficulty { get; set; } + + [JsonProperty(@"total_length")] + private double length { get; set; } + + [JsonProperty(@"count_circles")] + private int circleCount { get; set; } + + [JsonProperty(@"count_sliders")] + private int sliderCount { get; set; } + + [JsonProperty(@"version")] + private string version { get; set; } + + public BeatmapInfo ToBeatmap(RulesetStore rulesets) + { + return new BeatmapInfo + { + Metadata = this, + Ruleset = rulesets.GetRuleset(ruleset), + StarDifficulty = starDifficulty, + OnlineBeatmapID = onlineBeatmapID, + Version = version, + BaseDifficulty = new BeatmapDifficulty + { + DrainRate = drainRate, + CircleSize = circleSize, + ApproachRate = approachRate, + OverallDifficulty = overallDifficulty, + }, + OnlineInfo = new BeatmapOnlineInfo + { + PlayCount = playCount, + PassCount = passCount, + Length = length, + CircleCount = circleCount, + SliderCount = sliderCount, + }, + }; + } + } +} diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index cbe3b929fd..f57de016a2 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -46,12 +46,13 @@ namespace osu.Game.Online.API.Requests.Responses private DateTimeOffset lastUpdated { get; set; } [JsonProperty(@"user_id")] - private long creatorId { + private long creatorId + { set { Author.Id = value; } } [JsonProperty(@"beatmaps")] - private IEnumerable beatmaps { get; set; } + private IEnumerable beatmaps { get; set; } public BeatmapSetInfo ToBeatmapSet(RulesetStore rulesets) { @@ -76,74 +77,5 @@ namespace osu.Game.Online.API.Requests.Responses Beatmaps = beatmaps?.Select(b => b.ToBeatmap(rulesets)).ToList(), }; } - - private class APIResponseBeatmap : BeatmapMetadata - { - [JsonProperty(@"id")] - private int onlineBeatmapID { get; set; } - - [JsonProperty(@"playcount")] - private int playCount { get; set; } - - [JsonProperty(@"passcount")] - private int passCount { get; set; } - - [JsonProperty(@"mode_int")] - private int ruleset { get; set; } - - [JsonProperty(@"difficulty_rating")] - private double starDifficulty { get; set; } - - [JsonProperty(@"drain")] - private float drainRate { get; set; } - - [JsonProperty(@"cs")] - private float circleSize { get; set; } - - [JsonProperty(@"ar")] - private float approachRate { get; set; } - - [JsonProperty(@"accuracy")] - private float overallDifficulty { get; set; } - - [JsonProperty(@"total_length")] - private double length { get; set; } - - [JsonProperty(@"count_circles")] - private int circleCount { get; set; } - - [JsonProperty(@"count_sliders")] - private int sliderCount { get; set; } - - [JsonProperty(@"version")] - private string version { get; set; } - - public BeatmapInfo ToBeatmap(RulesetStore rulesets) - { - return new BeatmapInfo - { - Metadata = this, - Ruleset = rulesets.GetRuleset(ruleset), - StarDifficulty = starDifficulty, - OnlineBeatmapID = onlineBeatmapID, - Version = version, - BaseDifficulty = new BeatmapDifficulty - { - DrainRate = drainRate, - CircleSize = circleSize, - ApproachRate = approachRate, - OverallDifficulty = overallDifficulty, - }, - OnlineInfo = new BeatmapOnlineInfo - { - PlayCount = playCount, - PassCount = passCount, - Length = length, - CircleCount = circleCount, - SliderCount = sliderCount, - }, - }; - } - } } } From b45354ce97c5944bce29cfc35294f9e10ceae70d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 12:06:58 +0900 Subject: [PATCH 176/262] Add missing header --- .../API/Requests/Responses/APIUserMostPlayedBeatmap.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs index 26f80321bc..d49613eab7 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs @@ -1,4 +1,7 @@ -using Newtonsoft.Json; +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using Newtonsoft.Json; using osu.Game.Beatmaps; using osu.Game.Rulesets; From d1e9dba4aa46ae45ec391a5d00dd827a12effa13 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 12:21:12 +0900 Subject: [PATCH 177/262] Move beatmap lookup ability to new request --- .../API/Requests/GetBeatmapDetailsRequest.cs | 4 +--- .../Online/API/Requests/GetBeatmapRequest.cs | 22 +++++++++++++++++++ 2 files changed, 23 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetBeatmapRequest.cs diff --git a/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs index ab840d054f..e3865be5fb 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapDetailsRequest.cs @@ -10,13 +10,11 @@ namespace osu.Game.Online.API.Requests { private readonly BeatmapInfo beatmap; - private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.Hash}&filename={System.Uri.EscapeUriString(beatmap.Path)}"; - public GetBeatmapDetailsRequest(BeatmapInfo beatmap) { this.beatmap = beatmap; } - protected override string Target => $@"beatmaps/{lookupString}"; + protected override string Target => $@"beatmaps/{beatmap.OnlineBeatmapID}"; } } diff --git a/osu.Game/Online/API/Requests/GetBeatmapRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapRequest.cs new file mode 100644 index 0000000000..9958d252ab --- /dev/null +++ b/osu.Game/Online/API/Requests/GetBeatmapRequest.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; +using osu.Game.Online.API.Requests.Responses; + +namespace osu.Game.Online.API.Requests +{ + public class GetBeatmapRequest : APIRequest + { + private readonly BeatmapInfo beatmap; + + private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.Hash}&filename={System.Uri.EscapeUriString(beatmap.Path)}"; + + public GetBeatmapRequest(BeatmapInfo beatmap) + { + this.beatmap = beatmap; + } + + protected override string Target => $@"beatmaps/{lookupString}"; + } +} From 8220e0c79ab20a81b15785924b044b24085bbae0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 12:46:34 +0900 Subject: [PATCH 178/262] Remove OnlineBeatmapSetID from BeatmapMetadata --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- .../Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs | 11 +++++++---- osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs | 2 -- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 1 - osu.Game/Beatmaps/BeatmapManager.cs | 11 +++++------ osu.Game/Beatmaps/BeatmapMetadata.cs | 13 +------------ osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 1 - .../Online/API/Requests/Responses/APIBeatmap.cs | 8 ++++++-- .../Online/API/Requests/Responses/APIBeatmapSet.cs | 9 +++++++++ 10 files changed, 30 insertions(+), 30 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 4985aa9365..6a7a4eeaf7 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(string.Empty, metadata.Source); Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", metadata.Tags); Assert.AreEqual(557821, beatmapInfo.OnlineBeatmapID); - Assert.AreEqual(241526, metadata.OnlineBeatmapSetID); + Assert.AreEqual(241526, beatmapInfo.OnlineBeatmapSetID); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 489c38c420..053485273f 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -28,7 +28,7 @@ namespace osu.Game.Tests.Beatmaps.Formats { var beatmap = decodeAsJson(normal); var meta = beatmap.BeatmapInfo.Metadata; - Assert.AreEqual(241526, meta.OnlineBeatmapSetID); + Assert.AreEqual(241526, beatmap.BeatmapInfo.OnlineBeatmapSetID); Assert.AreEqual("Soleily", meta.Artist); Assert.AreEqual("Soleily", meta.ArtistUnicode); Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile); diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs index f9b055ed55..665229f8c3 100644 --- a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs @@ -48,11 +48,14 @@ namespace osu.Game.Tests.Beatmaps.IO { var reader = new ZipArchiveReader(osz); - BeatmapMetadata meta; - using (var stream = new StreamReader(reader.GetStream("Soleily - Renatus (Deif) [Platter].osu"))) - meta = Decoder.GetDecoder(stream).Decode(stream).Metadata; + Beatmap beatmap; - Assert.AreEqual(241526, meta.OnlineBeatmapSetID); + using (var stream = new StreamReader(reader.GetStream("Soleily - Renatus (Deif) [Platter].osu"))) + beatmap = Decoder.GetDecoder(stream).Decode(stream); + + var meta = beatmap.Metadata; + + Assert.AreEqual(241526, beatmap.BeatmapInfo.OnlineBeatmapSetID); Assert.AreEqual("Soleily", meta.Artist); Assert.AreEqual("Soleily", meta.ArtistUnicode); Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile); diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs index 4679fca855..6d2b37d981 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs @@ -449,7 +449,6 @@ namespace osu.Game.Tests.Visual Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), Metadata = new BeatmapMetadata { - OnlineBeatmapSetID = id, // Create random metadata, then we can check if sorting works based on these Artist = $"peppy{id.ToString().PadLeft(6, '0')}", Title = $"test set #{id}!", @@ -503,7 +502,6 @@ namespace osu.Game.Tests.Visual Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), Metadata = new BeatmapMetadata { - OnlineBeatmapSetID = id, // Create random metadata, then we can check if sorting works based on these Artist = $"peppy{id.ToString().PadLeft(6, '0')}", Title = $"test set #{id}!", diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 10121738f1..dab7f7e037 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -122,7 +122,6 @@ namespace osu.Game.Tests.Visual Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), Metadata = new BeatmapMetadata { - OnlineBeatmapSetID = 1234 + i, // Create random metadata, then we can check if sorting works based on these Artist = "MONACA " + RNG.Next(0, 9), Title = "Black Song " + RNG.Next(0, 9), diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 806bcc4132..589c00638f 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -306,22 +306,22 @@ namespace osu.Game.Beatmaps return hashable.ComputeSHA2Hash(); } - protected override BeatmapSetInfo CreateModel(ArchiveReader reader) + protected override BeatmapSetInfo CreateModel(ArchiveReader reader) { // let's make sure there are actually .osu files to import. string mapName = reader.Filenames.FirstOrDefault(f => f.EndsWith(".osu")); if (string.IsNullOrEmpty(mapName)) throw new InvalidOperationException("No beatmap files found in this beatmap archive."); - BeatmapMetadata metadata; + Beatmap beatmap; using (var stream = new StreamReader(reader.GetStream(mapName))) - metadata = Decoder.GetDecoder(stream).Decode(stream).Metadata; + beatmap = Decoder.GetDecoder(stream).Decode(stream); return new BeatmapSetInfo { - OnlineBeatmapSetID = metadata.OnlineBeatmapSetID, + OnlineBeatmapSetID = beatmap.BeatmapInfo.OnlineBeatmapSetID, Beatmaps = new List(), Hash = computeBeatmapSetHash(reader), - Metadata = metadata + Metadata = beatmap.Metadata }; } @@ -350,7 +350,6 @@ namespace osu.Game.Beatmaps // ensure we have the same online set ID as the set itself. beatmap.BeatmapInfo.OnlineBeatmapSetID = model.OnlineBeatmapSetID; - beatmap.BeatmapInfo.Metadata.OnlineBeatmapSetID = model.OnlineBeatmapSetID; // check that no existing beatmap exists that is imported with the same online beatmap ID. if so, give it precedence. if (beatmap.BeatmapInfo.OnlineBeatmapID.HasValue && QueryBeatmap(b => b.OnlineBeatmapID.Value == beatmap.BeatmapInfo.OnlineBeatmapID.Value) != null) diff --git a/osu.Game/Beatmaps/BeatmapMetadata.cs b/osu.Game/Beatmaps/BeatmapMetadata.cs index 34147c18d2..6c1bcd0531 100644 --- a/osu.Game/Beatmaps/BeatmapMetadata.cs +++ b/osu.Game/Beatmaps/BeatmapMetadata.cs @@ -17,16 +17,6 @@ namespace osu.Game.Beatmaps [JsonIgnore] public int ID { get; set; } - private int? onlineBeatmapSetID; - - [NotMapped] - [JsonProperty(@"id")] - public int? OnlineBeatmapSetID - { - get { return onlineBeatmapSetID; } - set { onlineBeatmapSetID = value > 0 ? value : null; } - } - public string Title { get; set; } public string TitleUnicode { get; set; } public string Artist { get; set; } @@ -82,8 +72,7 @@ namespace osu.Game.Beatmaps if (other == null) return false; - return onlineBeatmapSetID == other.onlineBeatmapSetID - && Title == other.Title + return Title == other.Title && TitleUnicode == other.TitleUnicode && Artist == other.Artist && ArtistUnicode == other.ArtistUnicode diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index a83ac26fb3..ee2c608fd7 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -208,7 +208,6 @@ namespace osu.Game.Beatmaps.Formats break; case @"BeatmapSetID": beatmap.BeatmapInfo.OnlineBeatmapSetID = int.Parse(pair.Value); - metadata.OnlineBeatmapSetID = int.Parse(pair.Value); break; } } diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index f75d320a46..01a4453657 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -10,7 +10,10 @@ namespace osu.Game.Online.API.Requests.Responses public class APIBeatmap : BeatmapMetadata { [JsonProperty(@"id")] - private int onlineBeatmapID { get; set; } + public int OnlineBeatmapID { get; set; } + + [JsonProperty(@"beatmapset_id")] + public int OnlineBeatmapSetID { get; set; } [JsonProperty(@"playcount")] private int playCount { get; set; } @@ -55,7 +58,8 @@ namespace osu.Game.Online.API.Requests.Responses Metadata = this, Ruleset = rulesets.GetRuleset(ruleset), StarDifficulty = starDifficulty, - OnlineBeatmapID = onlineBeatmapID, + OnlineBeatmapID = OnlineBeatmapID, + OnlineBeatmapSetID = OnlineBeatmapSetID, Version = version, BaseDifficulty = new BeatmapDifficulty { diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs index f57de016a2..3b6bb565b0 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmapSet.cs @@ -15,6 +15,15 @@ namespace osu.Game.Online.API.Requests.Responses [JsonProperty(@"covers")] private BeatmapSetOnlineCovers covers { get; set; } + private int? onlineBeatmapSetID; + + [JsonProperty(@"id")] + public int? OnlineBeatmapSetID + { + get { return onlineBeatmapSetID; } + set { onlineBeatmapSetID = value > 0 ? value : null; } + } + [JsonProperty(@"preview_url")] private string preview { get; set; } From b265f02d56025665f86b216e9b08e277b32b5c2c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 14:37:27 +0900 Subject: [PATCH 179/262] Add comment about scheduled invocation --- osu.Game/Online/API/APIRequest.cs | 13 +++++++++++++ 1 file changed, 13 insertions(+) diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index dfd181b98a..c89f8ce292 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -24,6 +24,10 @@ namespace osu.Game.Online.API Success?.Invoke(((JsonWebRequest)WebRequest).ResponseObject); } + /// + /// Invoked on successful completion of an API request. + /// This will be scheduled to the API's internal scheduler (run on update thread automatically). + /// public new event APISuccessHandler Success; } @@ -52,7 +56,16 @@ namespace osu.Game.Online.API protected APIAccess API; protected WebRequest WebRequest; + /// + /// Invoked on successful completion of an API request. + /// This will be scheduled to the API's internal scheduler (run on update thread automatically). + /// public event APISuccessHandler Success; + + /// + /// Invoked on failure to complete an API request. + /// This will be scheduled to the API's internal scheduler (run on update thread automatically). + /// public event APIFailureHandler Failure; private bool cancelled; From 21c8ef576c50bccea501e36743d6c0b5fc5edbe4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 14:37:48 +0900 Subject: [PATCH 180/262] Expose result for synchronous consumption --- osu.Game/Online/API/APIRequest.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/API/APIRequest.cs b/osu.Game/Online/API/APIRequest.cs index c89f8ce292..adbedb2aac 100644 --- a/osu.Game/Online/API/APIRequest.cs +++ b/osu.Game/Online/API/APIRequest.cs @@ -14,15 +14,14 @@ namespace osu.Game.Online.API { protected override WebRequest CreateWebRequest() => new JsonWebRequest(Uri); + public T Result => ((JsonWebRequest)WebRequest).ResponseObject; + protected APIRequest() { base.Success += onSuccess; } - private void onSuccess() - { - Success?.Invoke(((JsonWebRequest)WebRequest).ResponseObject); - } + private void onSuccess() => Success?.Invoke(Result); /// /// Invoked on successful completion of an API request. From e8455dc1e41ca92d0f9d1118af1187da88aba740 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 14:38:04 +0900 Subject: [PATCH 181/262] Fix incorrect hash usage --- osu.Game/Online/API/Requests/GetBeatmapRequest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/Requests/GetBeatmapRequest.cs b/osu.Game/Online/API/Requests/GetBeatmapRequest.cs index 9958d252ab..9d254ce29d 100644 --- a/osu.Game/Online/API/Requests/GetBeatmapRequest.cs +++ b/osu.Game/Online/API/Requests/GetBeatmapRequest.cs @@ -10,7 +10,7 @@ namespace osu.Game.Online.API.Requests { private readonly BeatmapInfo beatmap; - private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.Hash}&filename={System.Uri.EscapeUriString(beatmap.Path)}"; + private string lookupString => beatmap.OnlineBeatmapID > 0 ? beatmap.OnlineBeatmapID.ToString() : $@"lookup?checksum={beatmap.MD5Hash}&filename={System.Uri.EscapeUriString(beatmap.Path)}"; public GetBeatmapRequest(BeatmapInfo beatmap) { From 955a78e76d491e438c4f54b4e26f21381faf2826 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 15:26:27 +0900 Subject: [PATCH 182/262] Remove OnlineBeatmapSetID from BeatmapInfo It should now be retrieved via the linked BeatmapSetInfo --- .../Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- .../Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs | 2 +- .../Visual/TestCaseBeatmapScoresContainer.cs | 2 +- osu.Game/Beatmaps/BeatmapInfo.cs | 14 ++------------ osu.Game/Beatmaps/BeatmapManager.cs | 9 +++------ osu.Game/Beatmaps/BeatmapSetInfo.cs | 6 +++--- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 6 ++++-- .../Online/API/Requests/Responses/APIBeatmap.cs | 5 ++++- .../Requests/Responses/APIUserMostPlayedBeatmap.cs | 1 - .../Profile/Sections/BeatmapMetadataContainer.cs | 2 +- 11 files changed, 21 insertions(+), 30 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 6a7a4eeaf7..1628423fe8 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(string.Empty, metadata.Source); Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", metadata.Tags); Assert.AreEqual(557821, beatmapInfo.OnlineBeatmapID); - Assert.AreEqual(241526, beatmapInfo.OnlineBeatmapSetID); + Assert.AreEqual(241526, beatmapInfo.BeatmapSet.OnlineBeatmapSetID); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 053485273f..b834be71f1 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -28,7 +28,7 @@ namespace osu.Game.Tests.Beatmaps.Formats { var beatmap = decodeAsJson(normal); var meta = beatmap.BeatmapInfo.Metadata; - Assert.AreEqual(241526, beatmap.BeatmapInfo.OnlineBeatmapSetID); + Assert.AreEqual(241526, beatmap.BeatmapInfo.BeatmapSet.OnlineBeatmapSetID); Assert.AreEqual("Soleily", meta.Artist); Assert.AreEqual("Soleily", meta.ArtistUnicode); Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile); diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs index 665229f8c3..0039516c0c 100644 --- a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs @@ -55,7 +55,7 @@ namespace osu.Game.Tests.Beatmaps.IO var meta = beatmap.Metadata; - Assert.AreEqual(241526, beatmap.BeatmapInfo.OnlineBeatmapSetID); + Assert.AreEqual(241526, beatmap.BeatmapInfo.BeatmapSet.OnlineBeatmapSetID); Assert.AreEqual("Soleily", meta.Artist); Assert.AreEqual("Soleily", meta.ArtistUnicode); Assert.AreEqual("03. Renatus - Soleily 192kbps.mp3", meta.AudioFile); diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs index 3f63bacfa6..d3098864f4 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapScoresContainer.cs @@ -52,7 +52,7 @@ 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 }); + AddStep("online scores", () => scoresContainer.Beatmap = new BeatmapInfo { OnlineBeatmapID = 75, Ruleset = new OsuRuleset().RulesetInfo }); scores = new[] diff --git a/osu.Game/Beatmaps/BeatmapInfo.cs b/osu.Game/Beatmaps/BeatmapInfo.cs index 40d62103a8..3afc3c4d32 100644 --- a/osu.Game/Beatmaps/BeatmapInfo.cs +++ b/osu.Game/Beatmaps/BeatmapInfo.cs @@ -23,7 +23,6 @@ namespace osu.Game.Beatmaps public int BeatmapVersion; private int? onlineBeatmapID; - private int? onlineBeatmapSetID; [JsonProperty("id")] public int? OnlineBeatmapID @@ -32,19 +31,10 @@ namespace osu.Game.Beatmaps set { onlineBeatmapID = value > 0 ? value : null; } } - [JsonProperty("beatmapset_id")] - [NotMapped] - public int? OnlineBeatmapSetID - { - get { return onlineBeatmapSetID; } - set { onlineBeatmapSetID = value > 0 ? value : null; } - } - [JsonIgnore] public int BeatmapSetInfoID { get; set; } [Required] - [JsonIgnore] public BeatmapSetInfo BeatmapSet { get; set; } public BeatmapMetadata Metadata { get; set; } @@ -141,8 +131,8 @@ namespace osu.Game.Beatmaps (Metadata ?? BeatmapSet.Metadata).AudioFile == (other.Metadata ?? other.BeatmapSet.Metadata).AudioFile; public bool BackgroundEquals(BeatmapInfo other) => other != null && BeatmapSet != null && other.BeatmapSet != null && - BeatmapSet.Hash == other.BeatmapSet.Hash && - (Metadata ?? BeatmapSet.Metadata).BackgroundFile == (other.Metadata ?? other.BeatmapSet.Metadata).BackgroundFile; + BeatmapSet.Hash == other.BeatmapSet.Hash && + (Metadata ?? BeatmapSet.Metadata).BackgroundFile == (other.Metadata ?? other.BeatmapSet.Metadata).BackgroundFile; /// /// Returns a shallow-clone of this . diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 589c00638f..526f2488ea 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -81,7 +81,7 @@ namespace osu.Game.Beatmaps protected override void Populate(BeatmapSetInfo model, ArchiveReader archive) { - model.Beatmaps = createBeatmapDifficulties(model, archive); + model.Beatmaps = createBeatmapDifficulties(archive); // remove metadata from difficulties where it matches the set foreach (BeatmapInfo b in model.Beatmaps) @@ -318,7 +318,7 @@ namespace osu.Game.Beatmaps return new BeatmapSetInfo { - OnlineBeatmapSetID = beatmap.BeatmapInfo.OnlineBeatmapSetID, + OnlineBeatmapSetID = beatmap.BeatmapInfo.BeatmapSet.OnlineBeatmapSetID, Beatmaps = new List(), Hash = computeBeatmapSetHash(reader), Metadata = beatmap.Metadata @@ -328,7 +328,7 @@ namespace osu.Game.Beatmaps /// /// Create all required s for the provided archive. /// - private List createBeatmapDifficulties(BeatmapSetInfo model, ArchiveReader reader) + private List createBeatmapDifficulties(ArchiveReader reader) { var beatmapInfos = new List(); @@ -348,9 +348,6 @@ namespace osu.Game.Beatmaps beatmap.BeatmapInfo.Hash = ms.ComputeSHA2Hash(); beatmap.BeatmapInfo.MD5Hash = ms.ComputeMD5Hash(); - // ensure we have the same online set ID as the set itself. - beatmap.BeatmapInfo.OnlineBeatmapSetID = model.OnlineBeatmapSetID; - // check that no existing beatmap exists that is imported with the same online beatmap ID. if so, give it precedence. if (beatmap.BeatmapInfo.OnlineBeatmapID.HasValue && QueryBeatmap(b => b.OnlineBeatmapID.Value == beatmap.BeatmapInfo.OnlineBeatmapID.Value) != null) beatmap.BeatmapInfo.OnlineBeatmapID = null; diff --git a/osu.Game/Beatmaps/BeatmapSetInfo.cs b/osu.Game/Beatmaps/BeatmapSetInfo.cs index fa08c6cb68..ed8fbdbb26 100644 --- a/osu.Game/Beatmaps/BeatmapSetInfo.cs +++ b/osu.Game/Beatmaps/BeatmapSetInfo.cs @@ -22,18 +22,18 @@ namespace osu.Game.Beatmaps [NotMapped] public BeatmapSetOnlineInfo OnlineInfo { get; set; } - public double MaxStarDifficulty => Beatmaps.Max(b => b.StarDifficulty); + public double MaxStarDifficulty => Beatmaps?.Max(b => b.StarDifficulty) ?? 0; [NotMapped] public bool DeletePending { get; set; } public string Hash { get; set; } - public string StoryboardFile => Files.FirstOrDefault(f => f.Filename.EndsWith(".osb"))?.Filename; + public string StoryboardFile => Files?.FirstOrDefault(f => f.Filename.EndsWith(".osb"))?.Filename; public List Files { get; set; } - public override string ToString() => Metadata.ToString(); + public override string ToString() => Metadata?.ToString() ?? base.ToString(); public bool Protected { get; set; } } diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index ee2c608fd7..581207607a 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -34,7 +34,8 @@ namespace osu.Game.Beatmaps.Formats private readonly int offset; - public LegacyBeatmapDecoder(int version = LATEST_VERSION) : base(version) + public LegacyBeatmapDecoder(int version = LATEST_VERSION) + : base(version) { // BeatmapVersion 4 and lower had an incorrect offset (stable has this set as 24ms off) offset = FormatVersion < 5 ? 24 : 0; @@ -135,6 +136,7 @@ namespace osu.Game.Beatmaps.Formats parser = new Rulesets.Objects.Legacy.Mania.ConvertHitObjectParser(); break; } + break; case @"LetterboxInBreaks": beatmap.BeatmapInfo.LetterboxInBreaks = int.Parse(pair.Value) == 1; @@ -207,7 +209,7 @@ namespace osu.Game.Beatmaps.Formats beatmap.BeatmapInfo.OnlineBeatmapID = int.Parse(pair.Value); break; case @"BeatmapSetID": - beatmap.BeatmapInfo.OnlineBeatmapSetID = int.Parse(pair.Value); + beatmap.BeatmapInfo.BeatmapSet = new BeatmapSetInfo { OnlineBeatmapSetID = int.Parse(pair.Value) }; break; } } diff --git a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs index 01a4453657..99e4392374 100644 --- a/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIBeatmap.cs @@ -59,7 +59,10 @@ namespace osu.Game.Online.API.Requests.Responses Ruleset = rulesets.GetRuleset(ruleset), StarDifficulty = starDifficulty, OnlineBeatmapID = OnlineBeatmapID, - OnlineBeatmapSetID = OnlineBeatmapSetID, + BeatmapSet = new BeatmapSetInfo + { + OnlineBeatmapSetID = OnlineBeatmapSetID, + }, Version = version, BaseDifficulty = new BeatmapDifficulty { diff --git a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs index d49613eab7..8a5aea9e97 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUserMostPlayedBeatmap.cs @@ -25,7 +25,6 @@ namespace osu.Game.Online.API.Requests.Responses { BeatmapSetInfo setInfo = beatmapSet.ToBeatmapSet(rulesets); beatmap.BeatmapSet = setInfo; - beatmap.OnlineBeatmapSetID = setInfo.OnlineBeatmapSetID; beatmap.Metadata = setInfo.Metadata; return beatmap; } diff --git a/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs b/osu.Game/Overlays/Profile/Sections/BeatmapMetadataContainer.cs index 97079c77f3..359bfc7564 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?.FetchAndShowBeatmapSet(beatmap.OnlineBeatmapSetID.Value); + if (beatmap.BeatmapSet?.OnlineBeatmapSetID != null) beatmapSetOverlay?.FetchAndShowBeatmapSet(beatmap.BeatmapSet.OnlineBeatmapSetID.Value); }; Child = new FillFlowContainer From a775d00bd87bc96c75e31ab4890db3d20b99b5d2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 15:59:45 +0900 Subject: [PATCH 183/262] Add online fetch support for online IDs --- osu.Game/Beatmaps/BeatmapManager.cs | 69 +++++++++++++++++++++++------ 1 file changed, 55 insertions(+), 14 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 526f2488ea..895b47d62b 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -83,10 +83,29 @@ namespace osu.Game.Beatmaps { model.Beatmaps = createBeatmapDifficulties(archive); - // remove metadata from difficulties where it matches the set foreach (BeatmapInfo b in model.Beatmaps) + { + // remove metadata from difficulties where it matches the set if (model.Metadata.Equals(b.Metadata)) b.Metadata = null; + + // by setting the model here, we can update the noline set id below. + b.BeatmapSet = model; + + fetchAndPopulateOnlineIDs(b); + } + + // check if a set already exists with the same online id, delete if it does. + if (model.OnlineBeatmapSetID != null) + { + var existingOnlineId = beatmaps.ConsumableItems.FirstOrDefault(b => b.OnlineBeatmapSetID == model.OnlineBeatmapSetID); + if (existingOnlineId != null) + { + Delete(existingOnlineId); + beatmaps.PurgeDeletable(s => s.ID == existingOnlineId.ID); + Logger.Log($"Found existing beatmap set with same OnlineBeatmapSetID ({model.OnlineBeatmapSetID}). It has been purged.", LoggingTarget.Database); + } + } } protected override BeatmapSetInfo CheckForExisting(BeatmapSetInfo model) @@ -99,18 +118,6 @@ namespace osu.Game.Beatmaps return existingHashMatch; } - // check if a set already exists with the same online id - if (model.OnlineBeatmapSetID != null) - { - var existingOnlineId = beatmaps.ConsumableItems.FirstOrDefault(b => b.OnlineBeatmapSetID == model.OnlineBeatmapSetID); - if (existingOnlineId != null) - { - Delete(existingOnlineId); - beatmaps.PurgeDeletable(s => s.ID == existingOnlineId.ID); - Logger.Log($"Found existing beatmap set with same OnlineBeatmapSetID ({model.OnlineBeatmapSetID}). It has been purged.", LoggingTarget.Database); - } - } - return null; } @@ -318,7 +325,7 @@ namespace osu.Game.Beatmaps return new BeatmapSetInfo { - OnlineBeatmapSetID = beatmap.BeatmapInfo.BeatmapSet.OnlineBeatmapSetID, + OnlineBeatmapSetID = beatmap.BeatmapInfo.BeatmapSet?.OnlineBeatmapSetID, Beatmaps = new List(), Hash = computeBeatmapSetHash(reader), Metadata = beatmap.Metadata @@ -372,6 +379,40 @@ namespace osu.Game.Beatmaps return beatmapInfos; } + /// + /// Query the API to populate mising OnlineBeatmapID / OnlineBeatmapSetID properties. + /// + /// The beatmap to populate. + /// Whether to re-query if the provided beatmap already has populated values. + /// True if population was successful. + private bool fetchAndPopulateOnlineIDs(BeatmapInfo beatmap, bool force = false) + { + if (!force && beatmap.OnlineBeatmapID != null && beatmap.BeatmapSet.OnlineBeatmapSetID != null) + return true; + + Logger.Log("Attempting online lookup for IDs...", LoggingTarget.Database); + + try + { + var req = new GetBeatmapRequest(beatmap); + + req.Perform(api); + + var res = req.Result; + + Logger.Log($"Successfully mapped to {res.OnlineBeatmapSetID} / {res.OnlineBeatmapID}.", LoggingTarget.Database); + + beatmap.BeatmapSet.OnlineBeatmapSetID = res.OnlineBeatmapSetID; + beatmap.OnlineBeatmapID = res.OnlineBeatmapID; + return true; + } + catch (Exception e) + { + Logger.Log($"Failed ({e})", LoggingTarget.Database); + return false; + } + } + /// /// A dummy WorkingBeatmap for the purpose of retrieving a beatmap for star difficulty calculation. /// From e1bc0fa552256ee256b12ce62865ebc832986023 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 8 Jun 2018 15:59:59 +0900 Subject: [PATCH 184/262] Fix csproj file ending line --- osu.Game/osu.Game.csproj | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 363fc7d7bb..f5ff1fbd53 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -23,4 +23,4 @@ - + \ No newline at end of file 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 185/262] 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 186/262] 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 187/262] 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 188/262] 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 189/262] 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 190/262] 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 191/262] 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 192/262] 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 193/262] 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 b219c171159e67601351441f317dfe751e656a89 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 12:57:26 +0900 Subject: [PATCH 194/262] Move dependency creation under ctor --- osu.Game/Rulesets/UI/RulesetContainer.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 384b71cccc..561e77b0c9 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -73,11 +73,6 @@ namespace osu.Game.Rulesets.UI private IRulesetConfigManager rulesetConfig; private OnScreenDisplay onScreenDisplay; - private DependencyContainer dependencies; - - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - /// /// A visual representation of a . /// @@ -104,6 +99,11 @@ namespace osu.Game.Rulesets.UI } } + private DependencyContainer dependencies; + + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + public abstract ScoreProcessor CreateScoreProcessor(); /// From 63ec36b3be32b58af43a5e5a99ebc875b9ad5f68 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 12:57:56 +0900 Subject: [PATCH 195/262] Explicitly handle null settings case + add annotations --- osu.Game/Rulesets/UI/RulesetContainer.cs | 16 ++++++++++------ 1 file changed, 10 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 561e77b0c9..f604e876e7 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using JetBrains.Annotations; using osu.Framework.Configuration; using osu.Framework.Graphics.Cursor; using osu.Framework.Input; @@ -86,16 +87,19 @@ namespace osu.Game.Rulesets.UI } [BackgroundDependencyLoader(true)] - private void load(OnScreenDisplay onScreenDisplay, SettingsStore settings) + private void load([CanBeNull] OnScreenDisplay onScreenDisplay, [CanBeNull] SettingsStore settings) { this.onScreenDisplay = onScreenDisplay; - rulesetConfig = CreateConfig(Ruleset, settings); - - if (rulesetConfig != null) + if (settings != null) { - dependencies.Cache(rulesetConfig); - onScreenDisplay?.BeginTracking(this, rulesetConfig); + rulesetConfig = CreateConfig(Ruleset, settings); + + if (rulesetConfig != null) + { + dependencies.Cache(rulesetConfig); + onScreenDisplay?.BeginTracking(this, rulesetConfig); + } } } From 22e8a0bb6ec70a12890e39f98b122528fb81aee6 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 13:13:36 +0900 Subject: [PATCH 196/262] Make ruleset config manager variants nullable --- osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs | 2 +- osu.Game/Configuration/DatabasedConfigManager.cs | 4 ++-- osu.Game/Rulesets/Configuration/RulesetConfigManager.cs | 3 ++- 3 files changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs index ea5f590bd1..d9e360081d 100644 --- a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs +++ b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Mania.Configuration { public class ManiaConfigManager : RulesetConfigManager { - public ManiaConfigManager(SettingsStore settings, RulesetInfo ruleset, int variant) + public ManiaConfigManager(SettingsStore settings, RulesetInfo ruleset, int? variant = null) : base(settings, ruleset, variant) { } diff --git a/osu.Game/Configuration/DatabasedConfigManager.cs b/osu.Game/Configuration/DatabasedConfigManager.cs index 0ef0589dff..0ede6de0f2 100644 --- a/osu.Game/Configuration/DatabasedConfigManager.cs +++ b/osu.Game/Configuration/DatabasedConfigManager.cs @@ -13,13 +13,13 @@ namespace osu.Game.Configuration { private readonly SettingsStore settings; - private readonly int variant; + private readonly int? variant; private readonly List databasedSettings; private readonly RulesetInfo ruleset; - protected DatabasedConfigManager(SettingsStore settings, RulesetInfo ruleset = null, int variant = 0) + protected DatabasedConfigManager(SettingsStore settings, RulesetInfo ruleset = null, int? variant = null) { this.settings = settings; this.ruleset = ruleset; diff --git a/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs index 4ecf1eefb2..74cece5154 100644 --- a/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs +++ b/osu.Game/Rulesets/Configuration/RulesetConfigManager.cs @@ -8,7 +8,8 @@ namespace osu.Game.Rulesets.Configuration public abstract class RulesetConfigManager : DatabasedConfigManager, IRulesetConfigManager where T : struct { - protected RulesetConfigManager(SettingsStore settings, RulesetInfo ruleset, int variant) : base(settings, ruleset, variant) + protected RulesetConfigManager(SettingsStore settings, RulesetInfo ruleset, int? variant = null) + : base(settings, ruleset, variant) { } } From eca016ec6c8a54bf37ebf1afcb6b70ba8980d563 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 13:17:08 +0900 Subject: [PATCH 197/262] Move ruleset config managers to Ruleset --- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 5 +++++ osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs | 5 ----- osu.Game/Rulesets/Ruleset.cs | 8 ++++++++ osu.Game/Rulesets/UI/RulesetContainer.cs | 4 +--- 4 files changed, 14 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 5f803e3406..e671a3fb14 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -15,8 +15,11 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Replays.Types; using osu.Game.Beatmaps.Legacy; +using osu.Game.Configuration; +using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Configuration; using osu.Game.Rulesets.Mania.Difficulty; using osu.Game.Rulesets.Scoring; @@ -150,6 +153,8 @@ namespace osu.Game.Rulesets.Mania public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new ManiaReplayFrame(); + public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new ManiaConfigManager(settings, RulesetInfo); + public ManiaRuleset(RulesetInfo rulesetInfo = null) : base(rulesetInfo) { diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 7123aab901..a3145d6035 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -10,12 +10,9 @@ using osu.Framework.Input; using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Configuration; using osu.Game.Input.Handlers; -using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Mania.Beatmaps; using osu.Game.Rulesets.Mania.Mods; -using osu.Game.Rulesets.Mania.Configuration; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Replays; @@ -103,7 +100,5 @@ namespace osu.Game.Rulesets.Mania.UI protected override Vector2 PlayfieldArea => new Vector2(1, 0.8f); protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay); - - protected override IRulesetConfigManager CreateConfig(Ruleset ruleset, SettingsStore settings) => new ManiaConfigManager(settings, Ruleset.RulesetInfo, Variant); } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 395eeab419..f7f9d59dc6 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -15,6 +15,8 @@ using osu.Game.Rulesets.Replays.Types; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Beatmaps.Legacy; +using osu.Game.Configuration; +using osu.Game.Rulesets.Configuration; using osu.Game.Rulesets.Difficulty; namespace osu.Game.Rulesets @@ -71,6 +73,12 @@ namespace osu.Game.Rulesets public virtual SettingsSubsection CreateSettings() => null; + /// + /// Creates the for this . + /// + /// The to store the settings. + public virtual IRulesetConfigManager CreateConfig(SettingsStore settings) => null; + /// /// Do not override this unless you are a legacy mode. /// diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index f604e876e7..875745edfb 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -93,7 +93,7 @@ namespace osu.Game.Rulesets.UI if (settings != null) { - rulesetConfig = CreateConfig(Ruleset, settings); + rulesetConfig = Ruleset.CreateConfig(settings); if (rulesetConfig != null) { @@ -140,8 +140,6 @@ namespace osu.Game.Rulesets.UI /// protected virtual CursorContainer CreateCursor() => null; - protected virtual IRulesetConfigManager CreateConfig(Ruleset ruleset, SettingsStore settings) => null; - /// /// Creates a Playfield. /// From f4fbf27d42877f4c769186e972e09f40f41866e3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 13:28:50 +0900 Subject: [PATCH 198/262] Give ruleset settings a ruleset-specific config manager --- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- osu.Game.Rulesets.Osu/UI/OsuSettings.cs | 7 +++- .../Settings/RulesetSettingsSubsection.cs | 36 +++++++++++++++++++ osu.Game/Rulesets/Ruleset.cs | 2 +- 4 files changed, 44 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index b920e889ce..6ab75d008f 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -130,7 +130,7 @@ namespace osu.Game.Rulesets.Osu public override string ShortName => "osu"; - public override SettingsSubsection CreateSettings() => new OsuSettings(); + public override RulesetSettingsSubsection CreateSettings() => new OsuSettings(this); public override int? LegacyID => 0; diff --git a/osu.Game.Rulesets.Osu/UI/OsuSettings.cs b/osu.Game.Rulesets.Osu/UI/OsuSettings.cs index 31ad6701fd..25c009b117 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuSettings.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuSettings.cs @@ -8,10 +8,15 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Rulesets.Osu.UI { - public class OsuSettings : SettingsSubsection + public class OsuSettings : RulesetSettingsSubsection { protected override string Header => "osu!"; + public OsuSettings(Ruleset ruleset) + : base(ruleset) + { + } + [BackgroundDependencyLoader] private void load(OsuConfigManager config) { diff --git a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs new file mode 100644 index 0000000000..8f8c18d1f0 --- /dev/null +++ b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs @@ -0,0 +1,36 @@ +// 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.Game.Configuration; +using osu.Game.Rulesets; + +namespace osu.Game.Overlays.Settings +{ + /// + /// A which provides subclasses with the + /// from the 's . + /// + public abstract class RulesetSettingsSubsection : SettingsSubsection + { + private readonly Ruleset ruleset; + + protected RulesetSettingsSubsection(Ruleset ruleset) + { + this.ruleset = ruleset; + } + + private DependencyContainer dependencies; + + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + { + dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + + var config = ruleset.CreateConfig(dependencies.Get()); + if (config != null) + dependencies.Cache(config); + + return dependencies; + } + } +} diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index f7f9d59dc6..a39e8bb8d4 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets public abstract string Description { get; } - public virtual SettingsSubsection CreateSettings() => null; + public virtual RulesetSettingsSubsection CreateSettings() => null; /// /// Creates the for this . From be01dbae3ac4635706caf82cc4be9e19533e00d7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 14:36:56 +0900 Subject: [PATCH 199/262] Move ruleset dependency caching to CreateLocalDependencies In some cases we may want to refer to the cached configmanager dependency from subclasses. This prevents injection errors when doing so. --- osu.Game/Rulesets/UI/RulesetContainer.cs | 16 +++++++--------- 1 file changed, 7 insertions(+), 9 deletions(-) diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 875745edfb..a7005f1d5e 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -13,7 +13,6 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; -using JetBrains.Annotations; using osu.Framework.Configuration; using osu.Framework.Graphics.Cursor; using osu.Framework.Input; @@ -86,11 +85,13 @@ namespace osu.Game.Rulesets.UI Cursor = CreateCursor(); } - [BackgroundDependencyLoader(true)] - private void load([CanBeNull] OnScreenDisplay onScreenDisplay, [CanBeNull] SettingsStore settings) + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) { - this.onScreenDisplay = onScreenDisplay; + var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + onScreenDisplay = dependencies.Get(); + + var settings = dependencies.Get(); if (settings != null) { rulesetConfig = Ruleset.CreateConfig(settings); @@ -101,13 +102,10 @@ namespace osu.Game.Rulesets.UI onScreenDisplay?.BeginTracking(this, rulesetConfig); } } + + return dependencies; } - private DependencyContainer dependencies; - - protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) - => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - public abstract ScoreProcessor CreateScoreProcessor(); /// From 14b75309944a02d0ad8ff7622603ec0d4dbdb235 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 15:07:42 +0900 Subject: [PATCH 200/262] Use a global ruleset config cache --- osu.Game/OsuGameBase.cs | 3 ++ .../Settings/RulesetSettingsSubsection.cs | 3 +- osu.Game/Rulesets/RulesetConfigCache.cs | 43 +++++++++++++++++++ osu.Game/Rulesets/UI/RulesetContainer.cs | 13 ++---- 4 files changed, 51 insertions(+), 11 deletions(-) create mode 100644 osu.Game/Rulesets/RulesetConfigCache.cs diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index b968d7d4d0..a5779a2293 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -56,6 +56,8 @@ namespace osu.Game protected SettingsStore SettingsStore; + protected RulesetConfigCache RulesetConfigCache; + protected MenuCursorContainer MenuCursorContainer; private Container content; @@ -123,6 +125,7 @@ namespace osu.Game dependencies.Cache(ScoreStore = new ScoreStore(Host.Storage, contextFactory, Host, BeatmapManager, RulesetStore)); dependencies.Cache(KeyBindingStore = new KeyBindingStore(contextFactory, RulesetStore)); dependencies.Cache(SettingsStore = new SettingsStore(contextFactory)); + dependencies.Cache(RulesetConfigCache = new RulesetConfigCache(SettingsStore)); dependencies.Cache(new OsuColour()); fileImporters.Add(BeatmapManager); diff --git a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs index 8f8c18d1f0..05104018cd 100644 --- a/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs +++ b/osu.Game/Overlays/Settings/RulesetSettingsSubsection.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; -using osu.Game.Configuration; using osu.Game.Rulesets; namespace osu.Game.Overlays.Settings @@ -26,7 +25,7 @@ namespace osu.Game.Overlays.Settings { dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); - var config = ruleset.CreateConfig(dependencies.Get()); + var config = dependencies.Get().GetConfigFor(ruleset); if (config != null) dependencies.Cache(config); diff --git a/osu.Game/Rulesets/RulesetConfigCache.cs b/osu.Game/Rulesets/RulesetConfigCache.cs new file mode 100644 index 0000000000..52c40465f3 --- /dev/null +++ b/osu.Game/Rulesets/RulesetConfigCache.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; +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Game.Configuration; +using osu.Game.Rulesets.Configuration; + +namespace osu.Game.Rulesets +{ + /// + /// A cache that provides a single per-ruleset + /// This is done to support referring to and updating ruleset configs from multiple locations in the absence of inter-config bindings. + /// + public class RulesetConfigCache : Component + { + private readonly Dictionary configCache = new Dictionary(); + private readonly SettingsStore settingsStore; + + public RulesetConfigCache(SettingsStore settingsStore) + { + this.settingsStore = settingsStore; + } + + /// + /// Retrieves the for a . + /// + /// The to retrieve the for. + /// The defined by , null if doesn't define one. + /// If doesn't have a valid . + public IRulesetConfigManager GetConfigFor(Ruleset ruleset) + { + if (ruleset.RulesetInfo.ID == null) + throw new InvalidOperationException("The provided ruleset doesn't have a valid id."); + + if (configCache.TryGetValue(ruleset.RulesetInfo.ID.Value, out var existing)) + return existing; + + return configCache[ruleset.RulesetInfo.ID.Value] = ruleset.CreateConfig(settingsStore); + } + } +} diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index a7005f1d5e..15383946e8 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -91,16 +91,11 @@ namespace osu.Game.Rulesets.UI onScreenDisplay = dependencies.Get(); - var settings = dependencies.Get(); - if (settings != null) + rulesetConfig = dependencies.Get().GetConfigFor(Ruleset); + if (rulesetConfig != null) { - rulesetConfig = Ruleset.CreateConfig(settings); - - if (rulesetConfig != null) - { - dependencies.Cache(rulesetConfig); - onScreenDisplay?.BeginTracking(this, rulesetConfig); - } + dependencies.Cache(rulesetConfig); + onScreenDisplay?.BeginTracking(this, rulesetConfig); } return dependencies; From b51e714ae5d5997bcc952ba8dc6cd53acf08c318 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 15:44:59 +0900 Subject: [PATCH 201/262] Fix xmldoc --- osu.Game/Rulesets/RulesetConfigCache.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/RulesetConfigCache.cs b/osu.Game/Rulesets/RulesetConfigCache.cs index 52c40465f3..7e83ba0961 100644 --- a/osu.Game/Rulesets/RulesetConfigCache.cs +++ b/osu.Game/Rulesets/RulesetConfigCache.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Configuration; namespace osu.Game.Rulesets { /// - /// A cache that provides a single per-ruleset + /// A cache that provides a single per-ruleset. /// This is done to support referring to and updating ruleset configs from multiple locations in the absence of inter-config bindings. /// public class RulesetConfigCache : Component From b9391b3c6bb8f84426767e7233d499cb633959f3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 18:18:24 +0900 Subject: [PATCH 202/262] 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[] { From 8f3215f5a0b251f29e4863e50b396e91624e33e3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 20:42:04 +0900 Subject: [PATCH 203/262] Make sure taiko hitexplosions expire and get removed --- osu.Game.Rulesets.Taiko/UI/HitExplosion.cs | 4 +++- osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs | 4 +++- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs index ee2c1d5ad5..4dd0ba4d3d 100644 --- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs @@ -18,6 +18,8 @@ namespace osu.Game.Rulesets.Taiko.UI /// internal class HitExplosion : CircularContainer { + public override bool RemoveWhenNotAlive => true; + public readonly DrawableHitObject JudgedObject; private readonly Box innerFill; @@ -66,7 +68,7 @@ namespace osu.Game.Rulesets.Taiko.UI this.ScaleTo(3f, 1000, Easing.OutQuint); this.FadeOut(500); - Expire(); + Expire(true); } /// diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs index ac3cf8305a..287d59972a 100644 --- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs +++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs @@ -14,6 +14,8 @@ namespace osu.Game.Rulesets.Taiko.UI { public class KiaiHitExplosion : CircularContainer { + public override bool RemoveWhenNotAlive => true; + public readonly DrawableHitObject JudgedObject; private readonly bool isRim; @@ -62,7 +64,7 @@ namespace osu.Game.Rulesets.Taiko.UI this.ScaleTo(new Vector2(1, 3f), 500, Easing.OutQuint); this.FadeOut(250); - Expire(); + Expire(true); } } } From 22dfe46572b2f73a0fbb790688d41a8a78d873d5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 11 Jun 2018 21:45:19 +0900 Subject: [PATCH 204/262] Make taiko hitobject properly unproxy when rewound --- .../Objects/Drawables/DrawableHit.cs | 4 ++ .../Objects/Drawables/DrawableSwell.cs | 20 +++---- .../Drawables/DrawableTaikoHitObject.cs | 60 +++++++++++++++++-- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 20 +------ 4 files changed, 70 insertions(+), 34 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index d923b2dcdf..cca2753524 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -86,6 +86,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables switch (State.Value) { case ArmedState.Idle: + UnproxyContent(); this.Delay(HitObject.HitWindows.HalfWindowFor(HitResult.Miss)).Expire(); break; case ArmedState.Miss: @@ -93,6 +94,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables .Expire(); break; case ArmedState.Hit: + if (X >= -0.05f) + ProxyContent(); + var flash = circlePiece?.FlashBox; if (flash != null) { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 33cc29bccf..1f571544d8 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -20,12 +20,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { public class DrawableSwell : DrawableTaikoHitObject { - /// - /// Invoked when the swell has reached the hit target, i.e. when CurrentTime >= StartTime. - /// This is only ever invoked once. - /// - public event Action OnStart; - private const float target_ring_thick_border = 1.4f; private const float target_ring_thin_border = 1f; private const float target_ring_scale = 5f; @@ -40,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// private int userHits; - private bool hasStarted; + private bool hasProxied; private readonly SwellSymbolPiece symbol; public DrawableSwell(Swell swell) @@ -48,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables { FillMode = FillMode.Fit; - AddInternal(bodyContainer = new Container + Content.Add(bodyContainer = new Container { RelativeSizeAxes = Axes.Both, Depth = 1, @@ -177,6 +171,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables switch (state) { + case ArmedState.Idle: + hasProxied = false; + UnproxyContent(); + break; case ArmedState.Hit: bodyContainer.Delay(untilJudgement).ScaleTo(1.4f, out_transition_time); break; @@ -195,10 +193,10 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables X = Math.Max(0, X); double t = Math.Min(HitObject.StartTime, Time.Current); - if (t == HitObject.StartTime && !hasStarted) + if (t == HitObject.StartTime && !hasProxied) { - OnStart?.Invoke(); - hasStarted = true; + ProxyContent(); + hasProxied = true; } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index 971fd8854d..c07ee3a0fd 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -9,10 +9,62 @@ using OpenTK; using System.Linq; using osu.Game.Audio; using System.Collections.Generic; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Primitives; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public abstract class DrawableTaikoHitObject : DrawableHitObject, IKeyBindingHandler + public abstract class DrawableTaikoHitObject : DrawableHitObject, IKeyBindingHandler + { + protected readonly Container Content; + public readonly Container ProxiedContent; + + private readonly Container nonProxiedContent; + + protected DrawableTaikoHitObject(TaikoHitObject hitObject) + : base(hitObject) + { + InternalChildren = new[] + { + nonProxiedContent = new Container + { + RelativeSizeAxes = Axes.Both, + Child = Content = new Container { RelativeSizeAxes = Axes.Both } + }, + ProxiedContent = new Container { RelativeSizeAxes = Axes.Both } + }; + } + + /// + /// is proxied into an upper layer. We don't want to get masked away otherwise would too. + /// + protected override bool ComputeIsMaskedAway(RectangleF maskingBounds) => false; + + /// + /// Moves to a layer proxied above the playfield. + /// + protected void ProxyContent() + { + nonProxiedContent.Remove(Content); + ProxiedContent.Remove(Content); + ProxiedContent.Add(Content); + } + + /// + /// Moves to the normal hitobject layer. + /// + protected void UnproxyContent() + { + ProxiedContent.Remove(Content); + nonProxiedContent.Remove(Content); + nonProxiedContent.Add(Content); + } + + public abstract bool OnPressed(TaikoAction action); + public virtual bool OnReleased(TaikoAction action) => false; + } + + public abstract class DrawableTaikoHitObject : DrawableTaikoHitObject where TaikoHitType : TaikoHitObject { public override Vector2 OriginPosition => new Vector2(DrawHeight / 2); @@ -34,7 +86,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables RelativeSizeAxes = Axes.Both; Size = BaseSize = new Vector2(HitObject.IsStrong ? TaikoHitObject.DEFAULT_STRONG_SIZE : TaikoHitObject.DEFAULT_SIZE); - InternalChild = MainPiece = CreateMainPiece(); + Content.Add(MainPiece = CreateMainPiece()); MainPiece.KiaiMode = HitObject.Kiai; } @@ -44,9 +96,5 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected override string SampleNamespace => "Taiko"; protected virtual TaikoPiece CreateMainPiece() => new CirclePiece(); - - public abstract bool OnPressed(TaikoAction action); - - public virtual bool OnReleased(TaikoAction action) => false; } } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 417a7c2581..c638f807fe 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -216,10 +216,9 @@ namespace osu.Game.Rulesets.Taiko.UI if (barline != null) barlineContainer.Add(barline.CreateProxy()); - // Swells should be moved at the very top of the playfield when they reach the hit target - var swell = h as DrawableSwell; - if (swell != null) - swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy()); + var taikoObject = h as DrawableTaikoHitObject; + if (taikoObject != null) + topLevelHitContainer.Add(taikoObject.ProxiedContent.CreateProxy()); } internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) @@ -244,19 +243,6 @@ namespace osu.Game.Rulesets.Taiko.UI hitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == judgedObject)?.VisualiseSecondHit(); else { - if (judgedObject.X >= -0.05f && judgedObject is DrawableHit) - { - // If we're far enough away from the left stage, we should bring outselves in front of it - // Todo: The following try-catch is temporary for replay rewinding support - try - { - topLevelHitContainer.Add(judgedObject.CreateProxy()); - } - catch - { - } - } - hitExplosionContainer.Add(new HitExplosion(judgedObject, isRim)); if (judgedObject.HitObject.Kiai) From 1b12820de9e8529df794cc3d1396ba9e4d954c29 Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Mon, 11 Jun 2018 21:54:11 +0900 Subject: [PATCH 205/262] Restore a removed comment --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs index cca2753524..519b56a3ed 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs @@ -94,6 +94,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables .Expire(); break; case ArmedState.Hit: + // If we're far enough away from the left stage, we should bring outselves in front of it if (X >= -0.05f) ProxyContent(); From 7651819fb0ea29f7f636cdd4e4e42fcfa680e24b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jun 2018 12:53:53 +0900 Subject: [PATCH 206/262] Add same change to mania's hit explosions --- osu.Game.Rulesets.Mania/UI/HitExplosion.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs index f19c3a811b..bf8db63137 100644 --- a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs @@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Mania.UI { internal class HitExplosion : CompositeDrawable { + public override bool RemoveWhenNotAlive => true; + private readonly CircularContainer circle; public HitExplosion(DrawableHitObject judgedObject) From b90cdfbfd166aeb8fc26ad1bf8f51ff8d1c9b3d1 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jun 2018 14:33:33 +0900 Subject: [PATCH 207/262] Remove unused variable --- osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index 0a2e549509..c0557982fb 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -19,8 +19,6 @@ namespace osu.Game.Tests.Visual public TestCaseEditorComposeTimeline() { - TimelineArea timelineArea; - Children = new Drawable[] { new MusicController From 6ceac8ab0a316437d1dfed2c133927e2496c71f3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 24 May 2018 15:23:59 +0900 Subject: [PATCH 208/262] Add a centre marker to the timeline --- .../Visual/TestCaseEditorComposeTimeline.cs | 9 +++- .../Screens/Compose/Timeline/CentreMarker.cs | 52 +++++++++++++++++++ .../Edit/Screens/Compose/Timeline/Timeline.cs | 6 +++ 3 files changed, 66 insertions(+), 1 deletion(-) create mode 100644 osu.Game/Screens/Edit/Screens/Compose/Timeline/CentreMarker.cs diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index c0557982fb..d731ef973a 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -15,7 +15,14 @@ namespace osu.Game.Tests.Visual [TestFixture] public class TestCaseEditorComposeTimeline : EditorClockTestCase { - public override IReadOnlyList RequiredTypes => new[] { typeof(TimelineArea), typeof(Timeline), typeof(TimelineButton) }; + public override IReadOnlyList RequiredTypes => new[] + { + typeof(TimelineArea), + typeof(Timeline), + typeof(BeatmapWaveformGraph), + typeof(TimelineButton), + typeof(CentreMarker) + }; public TestCaseEditorComposeTimeline() { diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/CentreMarker.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/CentreMarker.cs new file mode 100644 index 0000000000..8e932f307d --- /dev/null +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/CentreMarker.cs @@ -0,0 +1,52 @@ +// 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.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using OpenTK; + +namespace osu.Game.Screens.Edit.Screens.Compose.Timeline +{ + public class CentreMarker : CompositeDrawable + { + private const float triangle_width = 20; + private const float triangle_height = 10; + private const float bar_width = 2; + + public CentreMarker() + { + RelativeSizeAxes = Axes.Y; + Size = new Vector2(20, 1); + + Anchor = Anchor.Centre; + Origin = Anchor.Centre; + + InternalChildren = new Drawable[] + { + new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Y, + Width = bar_width, + }, + new Triangle + { + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, + Size = new Vector2(triangle_width, triangle_height), + Scale = new Vector2(1, -1) + } + }; + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + Colour = colours.Red; + } + } +} diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index daf67ed7f0..d5f47f5e04 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -41,6 +41,12 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline Depth = float.MaxValue }; + // We don't want the centre marker to scroll + AddInternal(new CentreMarker()); + + // Make sure that the scrollbar is above the centre marker + ChangeInternalChildDepth(Scrollbar, -1); + WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); Beatmap.BindTo(beatmap); From 7dfe171869ed7b0596c30620f55ea834636628c2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jun 2018 14:31:12 +0900 Subject: [PATCH 209/262] Fix rebase error --- osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index d731ef973a..a89c5767fc 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -19,7 +19,6 @@ namespace osu.Game.Tests.Visual { typeof(TimelineArea), typeof(Timeline), - typeof(BeatmapWaveformGraph), typeof(TimelineButton), typeof(CentreMarker) }; From aaf2f66594527f0d912bedaf72e79c22e4916b5c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jun 2018 15:49:42 +0900 Subject: [PATCH 210/262] Make scrolling only zoom the timeline --- .../Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index 035e6a0804..ed26c28c80 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -99,10 +99,9 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline protected override bool OnScroll(InputState state) { - if (!state.Keyboard.ControlPressed) + if (state.Mouse.HasPreciseScroll) return base.OnScroll(state); - - setZoomTarget(zoomTarget + state.Mouse.ScrollDelta.X, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); + setZoomTarget(zoomTarget + state.Mouse.ScrollDelta.Y, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); return true; } From 3b396e38caf1211eb3b6645f81b22e86092b7904 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jun 2018 15:51:48 +0900 Subject: [PATCH 211/262] Hide the scrollbar --- .../Edit/Screens/Compose/Timeline/Timeline.cs | 31 +------------------ 1 file changed, 1 insertion(+), 30 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index daf67ed7f0..3bd7a0b96b 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -25,6 +25,7 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline ZoomDuration = 200; ZoomEasing = Easing.OutQuint; Zoom = 10; + ScrollbarVisible = false; } private WaveformGraph waveform; @@ -150,35 +151,5 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline if (trackWasPlaying) adjustableClock.Start(); } - - protected override ScrollbarContainer CreateScrollbar(Direction direction) => new TimelineScrollbar(this, direction); - - private class TimelineScrollbar : ScrollbarContainer - { - private readonly Timeline timeline; - - public TimelineScrollbar(Timeline timeline, Direction scrollDir) - : base(scrollDir) - { - this.timeline = timeline; - } - - protected override bool OnMouseDown(InputState state, MouseDownEventArgs args) - { - if (base.OnMouseDown(state, args)) - { - timeline.beginUserDrag(); - return true; - } - - return false; - } - - protected override bool OnMouseUp(InputState state, MouseUpEventArgs args) - { - timeline.endUserDrag(); - return base.OnMouseUp(state, args); - } - } } } From 34f23359bb773c8997e8e34a1e65d31374e679d9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jun 2018 16:20:31 +0900 Subject: [PATCH 212/262] Fix unit tests --- .../Visual/TestCaseZoomableScrollContainer.cs | 24 +++++-------------- 1 file changed, 6 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs b/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs index 70dd67cdbd..0d6526b637 100644 --- a/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs @@ -77,16 +77,12 @@ namespace osu.Game.Tests.Visual // Scroll in at 0.25 AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y))); - AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); - AddStep("Scroll by 3", () => InputManager.ScrollBy(new Vector2(3, 0))); - AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddStep("Scroll by 3", () => InputManager.ScrollBy(new Vector2(0, 3))); AddAssert("Box not at 0", () => !Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); AddAssert("Box 1/4 at 1/4", () => Precision.AlmostEquals(boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X)); // Scroll out at 0.25 - AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); - AddStep("Scroll by -3", () => InputManager.ScrollBy(new Vector2(-3, 0))); - AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddStep("Scroll by -3", () => InputManager.ScrollBy(new Vector2(0, -3))); AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); AddAssert("Box 1/4 at 1/4", () => Precision.AlmostEquals(boxQuad.TopLeft.X + 0.25f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X)); } @@ -98,15 +94,11 @@ namespace osu.Game.Tests.Visual // Scroll in at 0.25 AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y))); - AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); - AddStep("Scroll by 1", () => InputManager.ScrollBy(new Vector2(1, 0))); - AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddStep("Scroll by 1", () => InputManager.ScrollBy(new Vector2(0, 1))); // Scroll in at 0.6 AddStep("Move mouse to 0.75x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.75f * scrollQuad.Size.X, scrollQuad.Centre.Y))); - AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); - AddStep("Scroll by 1", () => InputManager.ScrollBy(new Vector2(1, 0))); - AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddStep("Scroll by 1", () => InputManager.ScrollBy(new Vector2(0, 1))); AddAssert("Box not at 0", () => !Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); // Very hard to determine actual position, so approximate @@ -115,15 +107,11 @@ namespace osu.Game.Tests.Visual AddAssert("Box at correct position (3)", () => Precision.DefinitelyBigger(boxQuad.TopLeft.X + 0.6f * boxQuad.Size.X, scrollQuad.TopLeft.X + 0.6f * scrollQuad.Size.X)); // Scroll out at 0.6 - AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); - AddStep("Scroll by -1", () => InputManager.ScrollBy(new Vector2(-1, 0))); - AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddStep("Scroll by -1", () => InputManager.ScrollBy(new Vector2(0, -1))); // Scroll out at 0.25 AddStep("Move mouse to 0.25x", () => InputManager.MoveMouseTo(new Vector2(scrollQuad.TopLeft.X + 0.25f * scrollQuad.Size.X, scrollQuad.Centre.Y))); - AddStep("Press ctrl", () => InputManager.PressKey(Key.LControl)); - AddStep("Scroll by -1", () => InputManager.ScrollBy(new Vector2(-1, 0))); - AddStep("Release ctrl", () => InputManager.ReleaseKey(Key.LControl)); + AddStep("Scroll by -1", () => InputManager.ScrollBy(new Vector2(0, -1))); AddAssert("Box at 0", () => Precision.AlmostEquals(boxQuad.TopLeft, scrollQuad.TopLeft)); } From 93d2b5c4dea32f93186e877697cb95cf806e902b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jun 2018 16:20:38 +0900 Subject: [PATCH 213/262] Adjust precision for failing test --- osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs b/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs index 0d6526b637..7fe59979a1 100644 --- a/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs @@ -66,7 +66,7 @@ namespace osu.Game.Tests.Visual { reset(); AddStep("Set zoom = 10", () => scrollContainer.Zoom = 10); - AddAssert("Box at 1/2", () => Precision.AlmostEquals(boxQuad.Centre, scrollQuad.Centre)); + AddAssert("Box at 1/2", () => Precision.AlmostEquals(boxQuad.Centre, scrollQuad.Centre, 1)); AddAssert("Box width = 10x", () => Precision.AlmostEquals(boxQuad.Size.X, 10 * scrollQuad.Size.X)); } From ac1990c093a9f69eabdbe49af90182794466ee3c Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Tue, 12 Jun 2018 16:36:46 +0900 Subject: [PATCH 214/262] Remove unused using --- osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs b/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs index 7fe59979a1..8bd1b79a84 100644 --- a/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs +++ b/osu.Game.Tests/Visual/TestCaseZoomableScrollContainer.cs @@ -13,7 +13,6 @@ using osu.Game.Graphics.Cursor; using osu.Game.Screens.Edit.Screens.Compose.Timeline; using OpenTK; using OpenTK.Graphics; -using OpenTK.Input; namespace osu.Game.Tests.Visual { From c70c7a476bf492d6f157fabc36406093bf0eafc3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jun 2018 17:59:59 +0900 Subject: [PATCH 215/262] Always display the key counter during replay/autoplay --- osu.Game/Screens/Play/KeyCounterCollection.cs | 12 ++++++++---- osu.Game/Screens/Play/Player.cs | 13 +++++++------ osu.Game/Screens/Play/ReplayPlayer.cs | 7 +++++++ 3 files changed, 22 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterCollection.cs index 8cbb9986e5..8b579f41ac 100644 --- a/osu.Game/Screens/Play/KeyCounterCollection.cs +++ b/osu.Game/Screens/Play/KeyCounterCollection.cs @@ -18,7 +18,8 @@ namespace osu.Game.Screens.Play { private const int duration = 100; - private Bindable showKeyCounter; + public readonly Bindable Visible = new Bindable(true); + private readonly Bindable alwaysVisible = new Bindable(); public KeyCounterCollection() { @@ -46,9 +47,10 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - showKeyCounter = config.GetBindable(OsuSetting.KeyOverlay); - showKeyCounter.ValueChanged += keyCounterVisibility => this.FadeTo(keyCounterVisibility ? 1 : 0, duration); - showKeyCounter.TriggerChange(); + config.BindWith(OsuSetting.KeyOverlay, alwaysVisible); + + Visible.BindValueChanged(_ => updateVisibility()); + alwaysVisible.BindValueChanged(_ => updateVisibility(), true); } //further: change default values here and in KeyCounter if needed, instead of passing them in every constructor @@ -111,6 +113,8 @@ namespace osu.Game.Screens.Play } } + private void updateVisibility() => this.FadeTo(Visible.Value || alwaysVisible.Value ? 1 : 0, duration); + public override bool HandleKeyboardInput => receptor == null; public override bool HandleMouseInput => receptor == null; diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 04148cd558..5fd85ce6e7 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -77,7 +77,7 @@ namespace osu.Game.Screens.Play protected ScoreProcessor ScoreProcessor; protected RulesetContainer RulesetContainer; - private HUDOverlay hudOverlay; + protected HUDOverlay HudOverlay; private FailOverlay failOverlay; private DrawableStoryboard storyboard; @@ -170,9 +170,9 @@ namespace osu.Game.Screens.Play OnPause = () => { pauseContainer.Retries = RestartCount; - hudOverlay.KeyCounter.IsCounting = pauseContainer.IsPaused; + HudOverlay.KeyCounter.IsCounting = pauseContainer.IsPaused; }, - OnResume = () => hudOverlay.KeyCounter.IsCounting = true, + OnResume = () => HudOverlay.KeyCounter.IsCounting = true, Children = new[] { storyboardContainer = new Container @@ -193,7 +193,7 @@ namespace osu.Game.Screens.Play Breaks = beatmap.Breaks }, RulesetContainer.Cursor?.CreateProxy() ?? new Container(), - hudOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, offsetClock, adjustableClock) + HudOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, offsetClock, adjustableClock) { Clock = Clock, // hud overlay doesn't want to use the audio clock directly ProcessCustomClock = false, @@ -228,7 +228,8 @@ namespace osu.Game.Screens.Play } }; - hudOverlay.HoldToQuit.Action = Exit; + HudOverlay.HoldToQuit.Action = Exit; + HudOverlay.KeyCounter.Visible.Value = RulesetContainer.HasReplayLoaded; if (ShowStoryboard) initializeStoryboard(false); @@ -368,7 +369,7 @@ namespace osu.Game.Screens.Play RulesetContainer?.FadeOut(fade_out_duration); Content.FadeOut(fade_out_duration); - hudOverlay?.ScaleTo(0.7f, fade_out_duration * 3, Easing.In); + HudOverlay?.ScaleTo(0.7f, fade_out_duration * 3, Easing.In); Background?.FadeTo(1f, fade_out_duration); } diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index 6e2a2e4c9c..16f8a4b361 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.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 osu.Framework.Allocation; using osu.Game.Rulesets.Replays; namespace osu.Game.Screens.Play @@ -14,6 +15,12 @@ namespace osu.Game.Screens.Play Replay = replay; } + [BackgroundDependencyLoader] + private void load() + { + HudOverlay.KeyCounter.Visible.Value = true; + } + protected override void LoadComplete() { base.LoadComplete(); From bcfb092e53709f65391d6c7294b0f3c2762c4c2e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 12 Jun 2018 18:03:45 +0900 Subject: [PATCH 216/262] Change step to 200 --- osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index 231892bdd9..830214803c 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.UI.Scrolling /// /// The step increase/decrease of the span of time visible by the length of the scrolling axes. /// - private const double time_span_step = 500; + private const double time_span_step = 200; /// /// The span of time that is visible by the length of the scrolling axes. From 67aa52fb1d79851e1049eea82f6bc4a942dd040f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jun 2018 19:34:49 +0900 Subject: [PATCH 217/262] Use bindable binding --- osu.Game/Screens/Play/Player.cs | 2 +- osu.Game/Screens/Play/ReplayPlayer.cs | 7 ------- 2 files changed, 1 insertion(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 5fd85ce6e7..7e0321d81d 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -229,7 +229,7 @@ namespace osu.Game.Screens.Play }; HudOverlay.HoldToQuit.Action = Exit; - HudOverlay.KeyCounter.Visible.Value = RulesetContainer.HasReplayLoaded; + HudOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded); if (ShowStoryboard) initializeStoryboard(false); diff --git a/osu.Game/Screens/Play/ReplayPlayer.cs b/osu.Game/Screens/Play/ReplayPlayer.cs index 16f8a4b361..6e2a2e4c9c 100644 --- a/osu.Game/Screens/Play/ReplayPlayer.cs +++ b/osu.Game/Screens/Play/ReplayPlayer.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.Framework.Allocation; using osu.Game.Rulesets.Replays; namespace osu.Game.Screens.Play @@ -15,12 +14,6 @@ namespace osu.Game.Screens.Play Replay = replay; } - [BackgroundDependencyLoader] - private void load() - { - HudOverlay.KeyCounter.Visible.Value = true; - } - protected override void LoadComplete() { base.LoadComplete(); From ca3186f34c7b2507fef6e0900e61e5c7e9746c82 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 12 Jun 2018 19:51:35 +0900 Subject: [PATCH 218/262] Create dependencies before children are loaded --- osu.Game/Tests/Visual/EditorClockTestCase.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game/Tests/Visual/EditorClockTestCase.cs b/osu.Game/Tests/Visual/EditorClockTestCase.cs index 08dc6a3bbd..521b51529e 100644 --- a/osu.Game/Tests/Visual/EditorClockTestCase.cs +++ b/osu.Game/Tests/Visual/EditorClockTestCase.cs @@ -25,13 +25,20 @@ namespace osu.Game.Tests.Visual Clock = new EditorClock(new ControlPointInfo(), 5000, BeatDivisor) { IsCoupled = false }; } + protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) + { + var dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); + + dependencies.Cache(BeatDivisor); + dependencies.CacheAs(Clock); + dependencies.CacheAs(Clock); + + return dependencies; + } + [BackgroundDependencyLoader] private void load() { - Dependencies.Cache(BeatDivisor); - Dependencies.CacheAs(Clock); - Dependencies.CacheAs(Clock); - Beatmap.BindValueChanged(beatmapChanged, true); } From 2a5a52422320cbe39cbcf03614919528c92da78f Mon Sep 17 00:00:00 2001 From: FreezyLemon Date: Tue, 12 Jun 2018 20:37:01 +0200 Subject: [PATCH 219/262] delete COMPILING.md --- COMPILING.md | 36 ------------------------------------ 1 file changed, 36 deletions(-) delete mode 100644 COMPILING.md diff --git a/COMPILING.md b/COMPILING.md deleted file mode 100644 index bfcbf6bc2c..0000000000 --- a/COMPILING.md +++ /dev/null @@ -1,36 +0,0 @@ -# Linux -### 1. Requirements: -Mono >= 5.4.0 (>= 5.8.0 recommended) -Please check [here](http://www.mono-project.com/download/) for stable or [here](http://www.mono-project.com/download/alpha/) for an alpha release. -NuGet >= 4.4.0 -msbuild -git - -### 2. Cloning project -Clone the entire repository with submodules using -``` -git clone https://github.com/ppy/osu --recursive -``` -Then restore NuGet packages from the repository -``` -nuget restore -``` -### 3. Compiling -Simply run `msbuild` where `osu.sln` is located, this will create all binaries in `osu/osu.Desktop/bin/Debug`. -### 4. Optimizing -If you want additional performance you can change build type to Release with -``` -msbuild -p:Configuration=Release -``` -Additionally, mono provides an AOT utility which attempts to precompile binaries. You can utilize that by running -``` -mono --aot ./osu\!.exe -``` -### 5. Troubleshooting -You may run into trouble with NuGet versioning, as the one in packaging system is almost always out of date. Simply run -``` -nuget -sudo nuget update -self -``` -**Warning** NuGet creates few config files when it's run for the first time. -Do not run NuGet as root on the first run or you might run into very peculiar issues. From d9e7a324c0c892a1299bdd7764978b9c7596a792 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Jun 2018 11:30:22 +0900 Subject: [PATCH 220/262] Revert HudOverlay to private field --- osu.Game/Screens/Play/Player.cs | 14 +++++++------- 1 file changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 7e0321d81d..a2ed01f5a7 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -77,7 +77,7 @@ namespace osu.Game.Screens.Play protected ScoreProcessor ScoreProcessor; protected RulesetContainer RulesetContainer; - protected HUDOverlay HudOverlay; + private HUDOverlay hudOverlay; private FailOverlay failOverlay; private DrawableStoryboard storyboard; @@ -170,9 +170,9 @@ namespace osu.Game.Screens.Play OnPause = () => { pauseContainer.Retries = RestartCount; - HudOverlay.KeyCounter.IsCounting = pauseContainer.IsPaused; + hudOverlay.KeyCounter.IsCounting = pauseContainer.IsPaused; }, - OnResume = () => HudOverlay.KeyCounter.IsCounting = true, + OnResume = () => hudOverlay.KeyCounter.IsCounting = true, Children = new[] { storyboardContainer = new Container @@ -193,7 +193,7 @@ namespace osu.Game.Screens.Play Breaks = beatmap.Breaks }, RulesetContainer.Cursor?.CreateProxy() ?? new Container(), - HudOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, offsetClock, adjustableClock) + hudOverlay = new HUDOverlay(ScoreProcessor, RulesetContainer, working, offsetClock, adjustableClock) { Clock = Clock, // hud overlay doesn't want to use the audio clock directly ProcessCustomClock = false, @@ -228,8 +228,8 @@ namespace osu.Game.Screens.Play } }; - HudOverlay.HoldToQuit.Action = Exit; - HudOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded); + hudOverlay.HoldToQuit.Action = Exit; + hudOverlay.KeyCounter.Visible.BindTo(RulesetContainer.HasReplayLoaded); if (ShowStoryboard) initializeStoryboard(false); @@ -369,7 +369,7 @@ namespace osu.Game.Screens.Play RulesetContainer?.FadeOut(fade_out_duration); Content.FadeOut(fade_out_duration); - HudOverlay?.ScaleTo(0.7f, fade_out_duration * 3, Easing.In); + hudOverlay?.ScaleTo(0.7f, fade_out_duration * 3, Easing.In); Background?.FadeTo(1f, fade_out_duration); } From a7ed3ea80b59f5d09143094eae2036f74c1c4d8c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Jun 2018 11:38:15 +0900 Subject: [PATCH 221/262] Rename alwaysVisible to explain where it comes from --- osu.Game/Screens/Play/KeyCounterCollection.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/KeyCounterCollection.cs b/osu.Game/Screens/Play/KeyCounterCollection.cs index 8b579f41ac..114ea83ba6 100644 --- a/osu.Game/Screens/Play/KeyCounterCollection.cs +++ b/osu.Game/Screens/Play/KeyCounterCollection.cs @@ -19,7 +19,7 @@ namespace osu.Game.Screens.Play private const int duration = 100; public readonly Bindable Visible = new Bindable(true); - private readonly Bindable alwaysVisible = new Bindable(); + private readonly Bindable configVisibility = new Bindable(); public KeyCounterCollection() { @@ -47,10 +47,10 @@ namespace osu.Game.Screens.Play [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - config.BindWith(OsuSetting.KeyOverlay, alwaysVisible); + config.BindWith(OsuSetting.KeyOverlay, configVisibility); Visible.BindValueChanged(_ => updateVisibility()); - alwaysVisible.BindValueChanged(_ => updateVisibility(), true); + configVisibility.BindValueChanged(_ => updateVisibility(), true); } //further: change default values here and in KeyCounter if needed, instead of passing them in every constructor @@ -113,7 +113,7 @@ namespace osu.Game.Screens.Play } } - private void updateVisibility() => this.FadeTo(Visible.Value || alwaysVisible.Value ? 1 : 0, duration); + private void updateVisibility() => this.FadeTo(Visible.Value || configVisibility.Value ? 1 : 0, duration); public override bool HandleKeyboardInput => receptor == null; public override bool HandleMouseInput => receptor == null; From b182635aae9b160bdc77775a7cea0d4203d56548 Mon Sep 17 00:00:00 2001 From: Joehu Date: Tue, 12 Jun 2018 20:21:37 -0700 Subject: [PATCH 222/262] Fix taiko nightcore regression --- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index ccf28a2f12..225461fd6f 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -91,7 +91,7 @@ namespace osu.Game.Rulesets.Taiko { new TaikoModHardRock(), new MultiMod(new TaikoModSuddenDeath(), new TaikoModPerfect()), - new MultiMod(new TaikoModDoubleTime(), new TaikoModDaycore()), + new MultiMod(new TaikoModDoubleTime(), new TaikoModNightcore()), new TaikoModHidden(), new TaikoModFlashlight(), }; From f4cb0d7d8daf7abd57ec9d50daae1e6d8fba5d74 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Jun 2018 14:16:58 +0900 Subject: [PATCH 223/262] Fix memory leak due to incorrect binding --- osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs index 240d8dc396..35146dfe29 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs @@ -161,7 +161,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor }; this.beatmap.BindTo(beatmap); - beatmap.ValueChanged += v => calculateScale(); + this.beatmap.ValueChanged += v => calculateScale(); cursorScale = config.GetBindable(OsuSetting.GameplayCursorSize); cursorScale.ValueChanged += v => calculateScale(); From 14f5c814a69b66237840ede64c389f99c56409c2 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Jun 2018 15:12:10 +0900 Subject: [PATCH 224/262] Add test for WorkingBeatmap leakage --- osu.Game/Tests/Visual/TestCasePlayer.cs | 34 ++++++++++++++++++++++--- 1 file changed, 30 insertions(+), 4 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index 3cdc496ee1..55fb9c483b 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -1,9 +1,12 @@ // 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.Graphics.Shapes; +using osu.Framework.Lists; +using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -43,6 +46,7 @@ namespace osu.Game.Tests.Visual Player p = null; AddStep(ruleset.RulesetInfo.Name, () => p = loadPlayerFor(ruleset)); AddUntilStep(() => ContinueCondition(p)); + } else { @@ -51,6 +55,20 @@ namespace osu.Game.Tests.Visual Player p = null; AddStep(r.Name, () => p = loadPlayerFor(r)); AddUntilStep(() => ContinueCondition(p)); + AddAssert("no leaked beatmaps", () => + { + p = null; + + GC.Collect(); + GC.WaitForPendingFinalizers(); + int count = 0; + + workingWeakReferences.ForEachAlive(_ => count++); + + Logger.Log($"reference count {count}"); + + return count == 1; + }); } } } @@ -59,21 +77,29 @@ namespace osu.Game.Tests.Visual protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); + private readonly WeakList workingWeakReferences = new WeakList(); + private Player loadPlayerFor(RulesetInfo ri) => loadPlayerFor(ri.CreateInstance()); private Player loadPlayerFor(Ruleset r) { var beatmap = CreateBeatmap(r); + var working = new TestWorkingBeatmap(beatmap); - Beatmap.Value = new TestWorkingBeatmap(beatmap); + workingWeakReferences.Add(working); + + Beatmap.Value = working; Beatmap.Value.Mods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) }; - if (Player != null) - Remove(Player); + Player?.Exit(); var player = CreatePlayer(r); - LoadComponentAsync(player, LoadScreen); + LoadComponentAsync(player, p => + { + Player = p; + LoadScreen(p); + }); return player; } From 39738a997eab5c7a085c44633883c9bbab155b9a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Jun 2018 15:26:05 +0900 Subject: [PATCH 225/262] Add check for player screens too --- osu.Game/Tests/Visual/TestCasePlayer.cs | 14 ++++++++++++-- 1 file changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index 55fb9c483b..beaa6bb43a 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -6,7 +6,6 @@ using System.Linq; using osu.Framework.Allocation; using osu.Framework.Graphics.Shapes; using osu.Framework.Lists; -using osu.Framework.Logging; using osu.Game.Beatmaps; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; @@ -55,6 +54,7 @@ namespace osu.Game.Tests.Visual Player p = null; AddStep(r.Name, () => p = loadPlayerFor(r)); AddUntilStep(() => ContinueCondition(p)); + AddAssert("no leaked beatmaps", () => { p = null; @@ -64,9 +64,16 @@ namespace osu.Game.Tests.Visual int count = 0; workingWeakReferences.ForEachAlive(_ => count++); + return count == 1; + }); - Logger.Log($"reference count {count}"); + AddAssert("no leaked players", () => + { + GC.Collect(); + GC.WaitForPendingFinalizers(); + int count = 0; + playerWeakReferences.ForEachAlive(_ => count++); return count == 1; }); } @@ -78,6 +85,7 @@ namespace osu.Game.Tests.Visual protected virtual IBeatmap CreateBeatmap(Ruleset ruleset) => new TestBeatmap(ruleset.RulesetInfo); private readonly WeakList workingWeakReferences = new WeakList(); + private readonly WeakList playerWeakReferences = new WeakList(); private Player loadPlayerFor(RulesetInfo ri) => loadPlayerFor(ri.CreateInstance()); @@ -95,6 +103,8 @@ namespace osu.Game.Tests.Visual var player = CreatePlayer(r); + playerWeakReferences.Add(player); + LoadComponentAsync(player, p => { Player = p; From 0fdb04f57dcbba6077f8e04020bed92e6678aa08 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Jun 2018 15:43:00 +0900 Subject: [PATCH 226/262] Fix empty line --- osu.Game/Tests/Visual/TestCasePlayer.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index beaa6bb43a..20c9646aa3 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -45,7 +45,6 @@ namespace osu.Game.Tests.Visual Player p = null; AddStep(ruleset.RulesetInfo.Name, () => p = loadPlayerFor(ruleset)); AddUntilStep(() => ContinueCondition(p)); - } else { From b318b770d4ea82efdb6f24b11f1cf131af77d2bd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 13 Jun 2018 19:18:11 +0900 Subject: [PATCH 227/262] Fix pixellation of volume meter progress bars --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 13 +- osu.Game/Overlays/Volume/VolumeMeter.cs | 200 +++++++++++------- 2 files changed, 139 insertions(+), 74 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 449f48b7d7..3c5b91ccd2 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -5,6 +5,7 @@ using System; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Game.Overlays.Volume; +using OpenTK; using OpenTK.Graphics; namespace osu.Game.Tests.Visual @@ -17,13 +18,21 @@ namespace osu.Game.Tests.Visual { VolumeMeter meter; MuteButton mute; - Add(meter = new VolumeMeter("MASTER", 125, Color4.Blue)); + Add(meter = new VolumeMeter("MASTER", 125, Color4.Blue) { Position = new Vector2(10) }); + AddSliderStep("master volume", 0, 10, 0, i => meter.Bindable.Value = i * 0.1); + + Add(new VolumeMeter("BIG", 250, Color4.Red) + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Position = new Vector2(10), + }); + Add(mute = new MuteButton { Margin = new MarginPadding { Top = 200 } }); - AddSliderStep("master volume", 0, 10, 0, i => meter.Bindable.Value = i * 0.1); AddToggleStep("mute", b => mute.Current.Value = b); } } diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index b2cf43704b..0e43945f8c 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -24,6 +24,8 @@ namespace osu.Game.Overlays.Volume public class VolumeMeter : Container, IKeyBindingHandler { private CircularProgress volumeCircle; + private CircularProgress volumeCircleGlow; + public BindableDouble Bindable { get; } = new BindableDouble { MinValue = 0, MaxValue = 1 }; private readonly float circleSize; private readonly Color4 meterColour; @@ -44,90 +46,143 @@ namespace osu.Game.Overlays.Volume [BackgroundDependencyLoader] private void load(OsuColour colours) { - Add(new Container - { - Size = new Vector2(120, 20), - CornerRadius = 10, - Masking = true, - Margin = new MarginPadding { Left = circleSize + 10 }, - Origin = Anchor.CentreLeft, - Anchor = Anchor.CentreLeft, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = colours.Gray1, - Alpha = 0.9f, - }, - new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = "Exo2.0-Bold", - Text = name - } - } - }); + Color4 backgroundColour = colours.Gray1; CircularProgress bgProgress; - Add(new CircularContainer + const float progress_start_radius = 0.75f; + const float progress_size = 0.03f; + const float progress_end_radius = progress_start_radius + progress_size; + + const float blur_amount = 5; + + Children = new Drawable[] { - Masking = true, - Size = new Vector2(circleSize), - Children = new Drawable[] + new Container { - new Box + Size = new Vector2(circleSize), + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Colour = colours.Gray1, - Alpha = 0.9f, - }, - bgProgress = new CircularProgress - { - RelativeSizeAxes = Axes.Both, - InnerRadius = 0.05f, - Rotation = 180, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Colour = colours.Gray2, - Size = new Vector2(0.8f) - }, - new Container - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Size = new Vector2(0.8f), - Padding = new MarginPadding(-Blur.KernelSize(5)), - Rotation = 180, - Child = (volumeCircle = new CircularProgress + new BufferedContainer { + Alpha = 0.9f, RelativeSizeAxes = Axes.Both, - InnerRadius = 0.05f, + Children = new Drawable[] + { + new Circle + { + RelativeSizeAxes = Axes.Both, + Colour = backgroundColour, + }, + new CircularContainer + { + Masking = true, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Size = new Vector2(progress_end_radius), + Children = new Drawable[] + { + bgProgress = new CircularProgress + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Rotation = 180, + Colour = backgroundColour, + }, + new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Name = "Progress under covers for smoothing", + RelativeSizeAxes = Axes.Both, + Rotation = 180, + Child = volumeCircle = new CircularProgress + { + RelativeSizeAxes = Axes.Both, + } + }, + } + }, + new Circle + { + Name = "Inner Cover", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Colour = backgroundColour, + Size = new Vector2(progress_start_radius), + }, + new Container + { + Name = "Progress overlay for glow", + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Size = new Vector2(progress_start_radius + progress_size / 1.5f), + Rotation = 180, + Padding = new MarginPadding(-Blur.KernelSize(blur_amount)), + Child = (volumeCircleGlow = new CircularProgress + { + RelativeSizeAxes = Axes.Both, + InnerRadius = progress_size * 0.8f, + }).WithEffect(new GlowEffect + { + Colour = meterColour, + BlurSigma = new Vector2(blur_amount), + Strength = 5, + PadExtent = true + }), + }, + }, + }, + maxGlow = (text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = "Venera", + TextSize = 0.16f * circleSize }).WithEffect(new GlowEffect { - Colour = meterColour, - Strength = 2, - PadExtent = true - }), - }, - maxGlow = (text = new OsuSpriteText + Colour = Color4.Transparent, + PadExtent = true, + }) + } + }, + new Container + { + Size = new Vector2(120, 20), + CornerRadius = 10, + Masking = true, + Margin = new MarginPadding { Left = circleSize + 10 }, + Origin = Anchor.CentreLeft, + Anchor = Anchor.CentreLeft, + Children = new Drawable[] { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = "Venera", - TextSize = 0.16f * circleSize - }).WithEffect(new GlowEffect - { - Colour = Color4.Transparent, - PadExtent = true, - }) + new Box + { + Alpha = 0.9f, + RelativeSizeAxes = Axes.Both, + Colour = backgroundColour, + }, + new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = "Exo2.0-Bold", + Text = name + } + } } - }); - - Bindable.ValueChanged += newVolume => { this.TransformTo("DisplayVolume", newVolume, 400, Easing.OutQuint); }; + }; + Bindable.ValueChanged += newVolume => + { + this.TransformTo("DisplayVolume", + newVolume, + 400, + Easing.OutQuint); + }; bgProgress.Current.Value = 0.75f; } @@ -158,6 +213,7 @@ namespace osu.Game.Overlays.Volume } volumeCircle.Current.Value = displayVolume * 0.75f; + volumeCircleGlow.Current.Value = displayVolume * 0.75f; } } From 1431ee1867f6f4ca4f648158a316853f3c580d16 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 14:46:25 +0900 Subject: [PATCH 228/262] Remove unused method --- osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs | 4 ---- 1 file changed, 4 deletions(-) diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index 31cd9dc6f5..a9bf5b1797 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -33,10 +33,6 @@ namespace osu.Game.Rulesets.Difficulty TimeRate = clock.Rate; } - protected virtual void PreprocessHitObjects() - { - } - /// /// Creates all combinations which adjust the difficulty. /// From b7a06b95944fdde0083c7f3f14bfed2132bcc074 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 15:32:07 +0900 Subject: [PATCH 229/262] Restructure of DifficultyCalculator to cleanup mod + attribute handling --- .../Difficulty/DifficultyAttributes.cs | 19 +++++++ .../Difficulty/DifficultyCalculator.cs | 51 ++++++++++++++----- osu.Game/Rulesets/Ruleset.cs | 2 +- 3 files changed, 59 insertions(+), 13 deletions(-) create mode 100644 osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs diff --git a/osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs b/osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs new file mode 100644 index 0000000000..1fdebd586f --- /dev/null +++ b/osu.Game/Rulesets/Difficulty/DifficultyAttributes.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Difficulty +{ + public class DifficultyAttributes + { + public readonly Mod[] Mods; + public readonly double StarRating; + + public DifficultyAttributes(Mod[] mods, double starRating) + { + Mods = mods; + StarRating = starRating; + } + } +} diff --git a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs index a9bf5b1797..8f9651ab09 100644 --- a/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/DifficultyCalculator.cs @@ -13,24 +13,44 @@ namespace osu.Game.Rulesets.Difficulty { public abstract class DifficultyCalculator { - protected readonly IBeatmap Beatmap; - protected readonly Mod[] Mods; + private readonly Ruleset ruleset; + private readonly WorkingBeatmap beatmap; - protected double TimeRate { get; private set; } = 1; - - protected DifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) + protected DifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) { - Beatmap = beatmap; - Mods = mods ?? new Mod[0]; - - ApplyMods(Mods); + this.ruleset = ruleset; + this.beatmap = beatmap; } - protected virtual void ApplyMods(Mod[] mods) + /// + /// Calculates the difficulty of the beatmap using a specific mod combination. + /// + /// The mods that should be applied to the beatmap. + /// A structure describing the difficulty of the beatmap. + public DifficultyAttributes Calculate(params Mod[] mods) { + beatmap.Mods.Value = mods; + IBeatmap playableBeatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo); + var clock = new StopwatchClock(); mods.OfType().ForEach(m => m.ApplyToClock(clock)); - TimeRate = clock.Rate; + + return Calculate(playableBeatmap, mods, clock.Rate); + } + + /// + /// Calculates the difficulty of the beatmap using all mod combinations applicable to the beatmap. + /// + /// A collection of structures describing the difficulty of the beatmap for each mod combination. + public IEnumerable CalculateAll() + { + foreach (var combination in CreateDifficultyAdjustmentModCombinations()) + { + if (combination is MultiMod multi) + yield return Calculate(multi.Mods); + else + yield return Calculate(combination); + } } /// @@ -71,6 +91,13 @@ namespace osu.Game.Rulesets.Difficulty /// protected virtual Mod[] DifficultyAdjustmentMods => Array.Empty(); - public abstract double Calculate(Dictionary categoryDifficulty = null); + /// + /// Calculates the difficulty of a using a specific combination. + /// + /// The to compute the difficulty for. + /// The s that should be applied. + /// The rate of time in . + /// A structure containing the difficulty attributes. + protected abstract DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate); } } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index a39e8bb8d4..cdc1c44306 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -61,7 +61,7 @@ namespace osu.Game.Rulesets public virtual IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => null; - public abstract DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null); + public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); public virtual PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => null; From 47fc18d7c48bc7e5b5f4dce262fc76ee28626372 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 15:36:49 +0900 Subject: [PATCH 230/262] Adjust OsuDifficultyCalculator in-line with changes --- .../Difficulty/OsuDifficultyAttributes.cs | 19 ++++++++++++ .../Difficulty/OsuDifficultyCalculator.cs | 30 +++++++------------ osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- 3 files changed, 31 insertions(+), 20 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs new file mode 100644 index 0000000000..5650bc395a --- /dev/null +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Difficulty +{ + public class OsuDifficultyAttributes : DifficultyAttributes + { + public double AimStrain { get; set; } + public double SpeedStrain { get; set; } + + public OsuDifficultyAttributes(Mod[] mods, double starRating) + : base(mods, starRating) + { + } + } +} diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs index 94d2afbf45..400afbc043 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyCalculator.cs @@ -2,7 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Collections.Generic; +using System.Linq; using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; @@ -18,31 +18,26 @@ namespace osu.Game.Rulesets.Osu.Difficulty private const int section_length = 400; private const double difficulty_multiplier = 0.0675; - public OsuDifficultyCalculator(IBeatmap beatmap) - : base(beatmap) + public OsuDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) + : base(ruleset, beatmap) { } - public OsuDifficultyCalculator(IBeatmap beatmap, Mod[] mods) - : base(beatmap, mods) + protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate) { - } - - public override double Calculate(Dictionary categoryDifficulty = null) - { - OsuDifficultyBeatmap beatmap = new OsuDifficultyBeatmap((List)Beatmap.HitObjects, TimeRate); + OsuDifficultyBeatmap difficultyBeatmap = new OsuDifficultyBeatmap(beatmap.HitObjects.Cast().ToList(), timeRate); Skill[] skills = { new Aim(), new Speed() }; - double sectionLength = section_length * TimeRate; + double sectionLength = section_length * timeRate; // The first object doesn't generate a strain, so we begin with an incremented section end double currentSectionEnd = 2 * sectionLength; - foreach (OsuDifficultyHitObject h in beatmap) + foreach (OsuDifficultyHitObject h in difficultyBeatmap) { while (h.BaseObject.StartTime > currentSectionEnd) { @@ -61,16 +56,13 @@ namespace osu.Game.Rulesets.Osu.Difficulty double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier; double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier; - double starRating = aimRating + speedRating + Math.Abs(aimRating - speedRating) / 2; - if (categoryDifficulty != null) + return new OsuDifficultyAttributes(mods, starRating) { - categoryDifficulty.Add("Aim", aimRating); - categoryDifficulty.Add("Speed", speedRating); - } - - return starRating; + AimStrain = aimRating, + SpeedStrain = speedRating + }; } protected override Mod[] DifficultyAdjustmentMods => new Mod[] diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 6ab75d008f..49468392f5 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -120,7 +120,7 @@ namespace osu.Game.Rulesets.Osu public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_osu_o }; - public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new OsuDifficultyCalculator(beatmap, mods); + public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(this, beatmap); public override PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => new OsuPerformanceCalculator(this, beatmap, score); From 33c7ce1bec1a51a70b9a2da9629ef3182132bc32 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 15:47:42 +0900 Subject: [PATCH 231/262] Adjust TaikoDifficultyCalculator in-line with changes --- .../Difficulty/TaikoDifficultyCalculator.cs | 59 ++++++++----------- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- 2 files changed, 24 insertions(+), 37 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs index bb666eb528..473c205293 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs @@ -27,54 +27,33 @@ namespace osu.Game.Rulesets.Taiko.Difficulty /// private const double decay_weight = 0.9; - /// - /// HitObjects are stored as a member variable. - /// - private readonly List difficultyHitObjects = new List(); - - public TaikoDifficultyCalculator(IBeatmap beatmap) - : base(beatmap) + public TaikoDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) + : base(ruleset, beatmap) { } - public TaikoDifficultyCalculator(IBeatmap beatmap, Mod[] mods) - : base(beatmap, mods) + protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate) { - } + var difficultyHitObjects = new List(); - public override double Calculate(Dictionary categoryDifficulty = null) - { - // Fill our custom DifficultyHitObject class, that carries additional information - difficultyHitObjects.Clear(); - - foreach (var hitObject in Beatmap.HitObjects) + foreach (var hitObject in beatmap.HitObjects) difficultyHitObjects.Add(new TaikoHitObjectDifficulty((TaikoHitObject)hitObject)); // Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure. difficultyHitObjects.Sort((a, b) => a.BaseHitObject.StartTime.CompareTo(b.BaseHitObject.StartTime)); - if (!calculateStrainValues()) return 0; + if (!calculateStrainValues(difficultyHitObjects, timeRate)) + return new DifficultyAttributes(mods, 0); - double starRating = calculateDifficulty() * star_scaling_factor; + double starRating = calculateDifficulty(difficultyHitObjects, timeRate) * star_scaling_factor; - if (categoryDifficulty != null) - categoryDifficulty["Strain"] = starRating; - - return starRating; + return new DifficultyAttributes(mods, starRating); } - protected override Mod[] DifficultyAdjustmentMods => new Mod[] - { - new TaikoModDoubleTime(), - new TaikoModHalfTime(), - new TaikoModEasy(), - new TaikoModHardRock(), - }; - - private bool calculateStrainValues() + private bool calculateStrainValues(List objects, double timeRate) { // Traverse hitObjects in pairs to calculate the strain value of NextHitObject from the strain value of CurrentHitObject and environment. - using (List.Enumerator hitObjectsEnumerator = difficultyHitObjects.GetEnumerator()) + using (var hitObjectsEnumerator = objects.GetEnumerator()) { if (!hitObjectsEnumerator.MoveNext()) return false; @@ -84,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty while (hitObjectsEnumerator.MoveNext()) { var next = hitObjectsEnumerator.Current; - next?.CalculateStrains(current, TimeRate); + next?.CalculateStrains(current, timeRate); current = next; } @@ -92,9 +71,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty } } - private double calculateDifficulty() + private double calculateDifficulty(List objects, double timeRate) { - double actualStrainStep = strain_step * TimeRate; + double actualStrainStep = strain_step * timeRate; // Find the highest strain value within each strain step List highestStrains = new List(); @@ -102,7 +81,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty double maximumStrain = 0; // We need to keep track of the maximum strain in the current interval TaikoHitObjectDifficulty previousHitObject = null; - foreach (var hitObject in difficultyHitObjects) + foreach (var hitObject in objects) { // While we are beyond the current interval push the currently available maximum to our strain list while (hitObject.BaseHitObject.StartTime > intervalEndTime) @@ -144,5 +123,13 @@ namespace osu.Game.Rulesets.Taiko.Difficulty return difficulty; } + + protected override Mod[] DifficultyAdjustmentMods => new Mod[] + { + new TaikoModDoubleTime(), + new TaikoModHalfTime(), + new TaikoModEasy(), + new TaikoModHardRock(), + }; } } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 225461fd6f..1b34ab68bd 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.Taiko public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_taiko_o }; - public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap, mods); + public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap); public override PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => new TaikoPerformanceCalculator(this, beatmap, score); From 6ff06d4757f4bb00f94bb7870235b4b18bd9b920 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 15:48:56 +0900 Subject: [PATCH 232/262] Adjust CatchDifficultyCalculator in-line with changes --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- .../Difficulty/CatchDifficultyCalculator.cs | 7 ++++--- 2 files changed, 5 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index d0180f1791..fc6e23c884 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -112,7 +112,7 @@ namespace osu.Game.Rulesets.Catch public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o }; - public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new CatchDifficultyCalculator(beatmap); + public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(this, beatmap); public override int? LegacyID => 2; diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs index f8351b7519..562374087e 100644 --- a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs @@ -1,18 +1,19 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; using osu.Game.Beatmaps; using osu.Game.Rulesets.Difficulty; +using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Catch.Difficulty { public class CatchDifficultyCalculator : DifficultyCalculator { - public CatchDifficultyCalculator(IBeatmap beatmap) : base(beatmap) + public CatchDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) + : base(ruleset, beatmap) { } - public override double Calculate(Dictionary categoryDifficulty = null) => 0; + protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate) => new DifficultyAttributes(mods, 0); } } From 966099fabc209b34f2ac2bcc7881b0639eb465f0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 15:54:05 +0900 Subject: [PATCH 233/262] Adjust ManiaDifficultyCalculator in-line with changes --- .../Difficulty/ManiaDifficultyCalculator.cs | 47 +++++++------------ osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- 2 files changed, 18 insertions(+), 31 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs index ca2002b7c9..9c091ac31a 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs @@ -29,47 +29,33 @@ namespace osu.Game.Rulesets.Mania.Difficulty /// private const double decay_weight = 0.9; - /// - /// HitObjects are stored as a member variable. - /// - private readonly List difficultyHitObjects = new List(); - - public ManiaDifficultyCalculator(IBeatmap beatmap) - : base(beatmap) + public ManiaDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) + : base(ruleset, beatmap) { } - public ManiaDifficultyCalculator(IBeatmap beatmap, Mod[] mods) - : base(beatmap, mods) + protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate) { - } + var difficultyHitObjects = new List(); - public override double Calculate(Dictionary categoryDifficulty = null) - { - // Fill our custom DifficultyHitObject class, that carries additional information - difficultyHitObjects.Clear(); - - int columnCount = (Beatmap as ManiaBeatmap)?.TotalColumns ?? 7; + int columnCount = ((ManiaBeatmap)beatmap).TotalColumns; // Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure. // Note: Stable sort is done so that the ordering of hitobjects with equal start times doesn't change - difficultyHitObjects.AddRange(Beatmap.HitObjects.Select(h => new ManiaHitObjectDifficulty((ManiaHitObject)h, columnCount)).OrderBy(h => h.BaseHitObject.StartTime)); + difficultyHitObjects.AddRange(beatmap.HitObjects.Select(h => new ManiaHitObjectDifficulty((ManiaHitObject)h, columnCount)).OrderBy(h => h.BaseHitObject.StartTime)); - if (!calculateStrainValues()) - return 0; + if (!calculateStrainValues(difficultyHitObjects, timeRate)) + return new DifficultyAttributes(mods, 0); - double starRating = calculateDifficulty() * star_scaling_factor; + double starRating = calculateDifficulty(difficultyHitObjects, timeRate) * star_scaling_factor; - if (categoryDifficulty != null) - categoryDifficulty["Strain"] = starRating; - - return starRating; + return new DifficultyAttributes(mods, starRating); } - private bool calculateStrainValues() + private bool calculateStrainValues(List objects, double timeRate) { // Traverse hitObjects in pairs to calculate the strain value of NextHitObject from the strain value of CurrentHitObject and environment. - using (List.Enumerator hitObjectsEnumerator = difficultyHitObjects.GetEnumerator()) + using (var hitObjectsEnumerator = objects.GetEnumerator()) { if (!hitObjectsEnumerator.MoveNext()) return false; @@ -80,7 +66,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty while (hitObjectsEnumerator.MoveNext()) { var next = hitObjectsEnumerator.Current; - next?.CalculateStrains(current, TimeRate); + next?.CalculateStrains(current, timeRate); current = next; } @@ -88,9 +74,9 @@ namespace osu.Game.Rulesets.Mania.Difficulty } } - private double calculateDifficulty() + private double calculateDifficulty(List objects, double timeRate) { - double actualStrainStep = strain_step * TimeRate; + double actualStrainStep = strain_step * timeRate; // Find the highest strain value within each strain step List highestStrains = new List(); @@ -98,7 +84,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty double maximumStrain = 0; // We need to keep track of the maximum strain in the current interval ManiaHitObjectDifficulty previousHitObject = null; - foreach (var hitObject in difficultyHitObjects) + foreach (var hitObject in objects) { // While we are beyond the current interval push the currently available maximum to our strain list while (hitObject.BaseHitObject.StartTime > intervalEndTime) @@ -159,5 +145,6 @@ namespace osu.Game.Rulesets.Mania.Difficulty new ManiaModKey8(), new ManiaModKey9(), }; + } } diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index e671a3fb14..1b7a8f77b3 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Mania public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o }; - public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => new ManiaDifficultyCalculator(beatmap, mods); + public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(this, beatmap); public override int? LegacyID => 3; From 540b43313eba0932a1be122c2469d586409b3d1c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 15:57:06 +0900 Subject: [PATCH 234/262] Remove PP test cases (osu-tools/osu-server should be used instead) --- .../TestCasePerformancePoints.cs | 16 - .../TestCasePerformancePoints.cs | 16 - .../TestCasePerformancePoints.cs | 16 - .../TestCasePerformancePoints.cs | 16 - .../Tests/Visual/TestCasePerformancePoints.cs | 403 ------------------ 5 files changed, 467 deletions(-) delete mode 100644 osu.Game.Rulesets.Catch.Tests/TestCasePerformancePoints.cs delete mode 100644 osu.Game.Rulesets.Mania.Tests/TestCasePerformancePoints.cs delete mode 100644 osu.Game.Rulesets.Osu.Tests/TestCasePerformancePoints.cs delete mode 100644 osu.Game.Rulesets.Taiko.Tests/TestCasePerformancePoints.cs delete mode 100644 osu.Game/Tests/Visual/TestCasePerformancePoints.cs diff --git a/osu.Game.Rulesets.Catch.Tests/TestCasePerformancePoints.cs b/osu.Game.Rulesets.Catch.Tests/TestCasePerformancePoints.cs deleted file mode 100644 index 9512cf2061..0000000000 --- a/osu.Game.Rulesets.Catch.Tests/TestCasePerformancePoints.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using NUnit.Framework; - -namespace osu.Game.Rulesets.Catch.Tests -{ - [TestFixture] - public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints - { - public TestCasePerformancePoints() - : base(new CatchRuleset()) - { - } - } -} diff --git a/osu.Game.Rulesets.Mania.Tests/TestCasePerformancePoints.cs b/osu.Game.Rulesets.Mania.Tests/TestCasePerformancePoints.cs deleted file mode 100644 index c15a6dd688..0000000000 --- a/osu.Game.Rulesets.Mania.Tests/TestCasePerformancePoints.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using NUnit.Framework; - -namespace osu.Game.Rulesets.Mania.Tests -{ - [TestFixture] - public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints - { - public TestCasePerformancePoints() - : base(new ManiaRuleset()) - { - } - } -} diff --git a/osu.Game.Rulesets.Osu.Tests/TestCasePerformancePoints.cs b/osu.Game.Rulesets.Osu.Tests/TestCasePerformancePoints.cs deleted file mode 100644 index 63026fe316..0000000000 --- a/osu.Game.Rulesets.Osu.Tests/TestCasePerformancePoints.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using NUnit.Framework; - -namespace osu.Game.Rulesets.Osu.Tests -{ - [TestFixture] - public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints - { - public TestCasePerformancePoints() - : base(new OsuRuleset()) - { - } - } -} diff --git a/osu.Game.Rulesets.Taiko.Tests/TestCasePerformancePoints.cs b/osu.Game.Rulesets.Taiko.Tests/TestCasePerformancePoints.cs deleted file mode 100644 index 2fd9161d13..0000000000 --- a/osu.Game.Rulesets.Taiko.Tests/TestCasePerformancePoints.cs +++ /dev/null @@ -1,16 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using NUnit.Framework; - -namespace osu.Game.Rulesets.Taiko.Tests -{ - [TestFixture] - public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints - { - public TestCasePerformancePoints() - : base(new TaikoRuleset()) - { - } - } -} diff --git a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs b/osu.Game/Tests/Visual/TestCasePerformancePoints.cs deleted file mode 100644 index dfae8fbc1d..0000000000 --- a/osu.Game/Tests/Visual/TestCasePerformancePoints.cs +++ /dev/null @@ -1,403 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System.Collections.Generic; -using System.Linq; -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Allocation; -using osu.Framework.Caching; -using osu.Framework.Configuration; -using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Cursor; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Input; -using osu.Game.Beatmaps; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using osu.Game.Online.API; -using osu.Game.Online.API.Requests; -using osu.Game.Rulesets; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Scoring; - -namespace osu.Game.Tests.Visual -{ - public abstract class TestCasePerformancePoints : OsuTestCase - { - protected TestCasePerformancePoints(Ruleset ruleset) - { - Child = new GridContainer - { - RelativeSizeAxes = Axes.Both, - Content = new[] - { - new Drawable[] - { - new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.5f, - }, - new ScrollContainer - { - RelativeSizeAxes = Axes.Both, - Child = new BeatmapList(ruleset, Beatmap) - } - } - }, - null, - new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.5f, - }, - new ScrollContainer - { - RelativeSizeAxes = Axes.Both, - Child = new StarRatingGrid() - } - } - }, - null, - new Container - { - RelativeSizeAxes = Axes.Both, - Children = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black, - Alpha = 0.5f, - }, - new ScrollContainer - { - RelativeSizeAxes = Axes.Both, - Child = new PerformanceList() - } - } - }, - } - }, - ColumnDimensions = new[] - { - new Dimension(), - new Dimension(GridSizeMode.Absolute, 20), - new Dimension(), - new Dimension(GridSizeMode.Absolute, 20) - } - }; - } - - private class BeatmapList : CompositeDrawable - { - private readonly Container beatmapDisplays; - private readonly Ruleset ruleset; - private readonly BindableBeatmap beatmapBindable; - - public BeatmapList(Ruleset ruleset, BindableBeatmap beatmapBindable) - { - this.ruleset = ruleset; - this.beatmapBindable = beatmapBindable; - - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - InternalChild = beatmapDisplays = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 4) - }; - } - - [BackgroundDependencyLoader] - private void load(BeatmapManager beatmaps) - { - var sets = beatmaps.GetAllUsableBeatmapSets(); - var allBeatmaps = sets.SelectMany(s => s.Beatmaps).Where(b => ruleset.LegacyID == null || b.RulesetID == ruleset.LegacyID); - - allBeatmaps.ForEach(b => beatmapDisplays.Add(new BeatmapDisplay(b, beatmapBindable))); - } - - private class BeatmapDisplay : CompositeDrawable, IHasTooltip - { - private readonly OsuSpriteText text; - private readonly BeatmapInfo beatmap; - - private readonly BindableBeatmap beatmapBindable; - - private BeatmapManager beatmaps; - - private bool isSelected; - - public string TooltipText => text.Text; - - public BeatmapDisplay(BeatmapInfo beatmap, BindableBeatmap beatmapBindable) - { - this.beatmap = beatmap; - this.beatmapBindable = beatmapBindable; - - AutoSizeAxes = Axes.Both; - InternalChild = text = new OsuSpriteText(); - - this.beatmapBindable.ValueChanged += beatmapChanged; - } - - [BackgroundDependencyLoader] - private void load(BeatmapManager beatmaps) - { - this.beatmaps = beatmaps; - - var working = beatmaps.GetWorkingBeatmap(beatmap); - text.Text = $"{working.Metadata.Artist} - {working.Metadata.Title} ({working.Metadata.AuthorString}) [{working.BeatmapInfo.Version}]"; - } - - private void beatmapChanged(WorkingBeatmap newBeatmap) - { - if (isSelected) - this.FadeColour(Color4.White, 100); - isSelected = false; - } - - protected override bool OnClick(InputState state) - { - if (beatmapBindable.Value.BeatmapInfo.ID == beatmap.ID) - return false; - - beatmapBindable.Value = beatmaps.GetWorkingBeatmap(beatmap); - isSelected = true; - return true; - } - - protected override bool OnHover(InputState state) - { - if (isSelected) - return false; - this.FadeColour(Color4.Yellow, 100); - return true; - } - - protected override void OnHoverLost(InputState state) - { - if (isSelected) - return; - this.FadeColour(Color4.White, 100); - } - } - } - - private class PerformanceList : CompositeDrawable - { - private readonly FillFlowContainer scores; - private APIAccess api; - - private readonly IBindable currentBeatmap = new Bindable(); - - public PerformanceList() - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - InternalChild = scores = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 4) - }; - } - - [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap, APIAccess api) - { - this.api = api; - - if (!api.IsLoggedIn) - { - InternalChild = new OsuSpriteText - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Text = "Please sign in to see online scores", - }; - } - - currentBeatmap.ValueChanged += beatmapChanged; - currentBeatmap.BindTo(beatmap); - } - - private GetScoresRequest lastRequest; - private void beatmapChanged(WorkingBeatmap newBeatmap) - { - if (!IsAlive) return; - - lastRequest?.Cancel(); - scores.Clear(); - - if (!api.IsLoggedIn) - return; - - lastRequest = new GetScoresRequest(newBeatmap.BeatmapInfo, newBeatmap.BeatmapInfo.Ruleset); - lastRequest.Success += res => res.Scores.ForEach(s => scores.Add(new PerformanceDisplay(s, newBeatmap.Beatmap))); - api.Queue(lastRequest); - } - - private class PerformanceDisplay : CompositeDrawable - { - private readonly OsuSpriteText text; - - private readonly Score score; - private readonly IBeatmap beatmap; - - public PerformanceDisplay(Score score, IBeatmap beatmap) - { - this.score = score; - this.beatmap = beatmap; - - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - InternalChild = text = new OsuSpriteText(); - } - - [BackgroundDependencyLoader] - private void load() - { - var ruleset = beatmap.BeatmapInfo.Ruleset.CreateInstance(); - var calculator = ruleset.CreatePerformanceCalculator(beatmap, score); - if (calculator == null) - return; - - var attributes = new Dictionary(); - double performance = calculator.Calculate(attributes); - - text.Text = $"{score.User.Username} -> online: {score.PP:n2}pp | local: {performance:n2}pp"; - } - } - } - - private class StarRatingGrid : CompositeDrawable - { - private readonly FillFlowContainer modFlow; - private readonly OsuSpriteText totalText; - private readonly FillFlowContainer categoryTexts; - - public StarRatingGrid() - { - RelativeSizeAxes = Axes.X; - AutoSizeAxes = Axes.Y; - InternalChild = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Children = new Drawable[] - { - modFlow = new FillFlowContainer - { - Name = "Checkbox flow", - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(4, 4) - }, - new FillFlowContainer - { - Name = "Information display", - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Spacing = new Vector2(0, 4), - Direction = FillDirection.Vertical, - Children = new Drawable[] - { - totalText = new OsuSpriteText { TextSize = 24 }, - categoryTexts = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical - } - } - } - } - }; - } - - [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap) - { - beatmap.ValueChanged += beatmapChanged; - } - - private Cached informationCache = new Cached(); - - private Ruleset ruleset; - private WorkingBeatmap beatmap; - - private void beatmapChanged(WorkingBeatmap newBeatmap) - { - beatmap = newBeatmap; - - modFlow.Clear(); - - ruleset = newBeatmap.BeatmapInfo.Ruleset.CreateInstance(); - foreach (var mod in ruleset.GetAllMods()) - { - var checkBox = new OsuCheckbox - { - RelativeSizeAxes = Axes.None, - Width = 50, - LabelText = mod.ShortenedName - }; - - checkBox.Current.ValueChanged += v => informationCache.Invalidate(); - modFlow.Add(checkBox); - } - - informationCache.Invalidate(); - } - - protected override void Update() - { - base.Update(); - - if (ruleset == null) - return; - - if (!informationCache.IsValid) - { - totalText.Text = string.Empty; - categoryTexts.Clear(); - - var allMods = ruleset.GetAllMods().ToList(); - Mod[] activeMods = modFlow.Where(c => c.Current.Value).Select(c => allMods.First(m => m.ShortenedName == c.LabelText)).ToArray(); - - var diffCalc = ruleset.CreateDifficultyCalculator(beatmap.Beatmap, activeMods); - if (diffCalc != null) - { - var categories = new Dictionary(); - double totalSr = diffCalc.Calculate(categories); - - totalText.Text = $"Star rating: {totalSr:n2}"; - foreach (var kvp in categories) - categoryTexts.Add(new OsuSpriteText { Text = $"{kvp.Key}: {kvp.Value:n2}" }); - } - - informationCache.Validate(); - } - } - } - } -} From 8f7334874ca3ff149c6e2cc10f0e0cd667f8c40e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 16:04:48 +0900 Subject: [PATCH 235/262] Fix up performance calculators --- .../Difficulty/ManiaPerformanceCalculator.cs | 4 ++-- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- .../Difficulty/OsuPerformanceCalculator.cs | 8 +++++--- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- .../Difficulty/TaikoPerformanceCalculator.cs | 6 +++--- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- .../DifficultyAdjustmentModCombinationsTest.cs | 8 ++++---- osu.Game/Beatmaps/BeatmapManager.cs | 3 +-- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- .../Rulesets/Difficulty/PerformanceCalculator.cs | 12 ++++++------ osu.Game/Rulesets/Ruleset.cs | 2 +- 11 files changed, 26 insertions(+), 25 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs index 93652f7610..b6089b830b 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty private int countMeh; private int countMiss; - public ManiaPerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) + public ManiaPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, Score score) : base(ruleset, beatmap, score) { } @@ -82,7 +82,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty private double computeStrainValue() { // Obtain strain difficulty - double strainValue = Math.Pow(5 * Math.Max(1, Attributes["Strain"] / 0.2) - 4.0, 2.2) / 135.0; + double strainValue = Math.Pow(5 * Math.Max(1, Attributes.StarRating / 0.2) - 4.0, 2.2) / 135.0; // Longer maps are worth more strainValue *= 1.0 + 0.1 * Math.Min(1.0, totalHits / 1500.0); diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 1b7a8f77b3..ac5fbfdde0 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania { public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new ManiaRulesetContainer(this, beatmap); public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap); - public override PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => new ManiaPerformanceCalculator(this, beatmap, score); + public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, Score score) => new ManiaPerformanceCalculator(this, beatmap, score); public override IEnumerable ConvertLegacyMods(LegacyMods mods) { diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs index 57cf962fa7..3ab3cc879a 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuPerformanceCalculator.cs @@ -15,6 +15,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty { public class OsuPerformanceCalculator : PerformanceCalculator { + public new OsuDifficultyAttributes Attributes => (OsuDifficultyAttributes)base.Attributes; + private readonly int countHitCircles; private readonly int beatmapMaxCombo; @@ -37,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty private int countMeh; private int countMiss; - public OsuPerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) + public OsuPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, Score score) : base(ruleset, beatmap, score) { countHitCircles = Beatmap.HitObjects.Count(h => h is HitCircle); @@ -102,7 +104,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty private double computeAimValue() { - double aimValue = Math.Pow(5.0f * Math.Max(1.0f, Attributes["Aim"] / 0.0675f) - 4.0f, 3.0f) / 100000.0f; + double aimValue = Math.Pow(5.0f * Math.Max(1.0f, Attributes.AimStrain / 0.0675f) - 4.0f, 3.0f) / 100000.0f; // Longer maps are worth more double lengthBonus = 0.95f + 0.4f * Math.Min(1.0f, totalHits / 2000.0f) + @@ -151,7 +153,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty private double computeSpeedValue() { - double speedValue = Math.Pow(5.0f * Math.Max(1.0f, Attributes["Speed"] / 0.0675f) - 4.0f, 3.0f) / 100000.0f; + double speedValue = Math.Pow(5.0f * Math.Max(1.0f, Attributes.SpeedStrain / 0.0675f) - 4.0f, 3.0f) / 100000.0f; // Longer maps are worth more speedValue *= 0.95f + 0.4f * Math.Min(1.0f, totalHits / 2000.0f) + diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 49468392f5..ce80537b93 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Osu public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(this, beatmap); - public override PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => new OsuPerformanceCalculator(this, beatmap, score); + public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, Score score) => new OsuPerformanceCalculator(this, beatmap, score); public override HitObjectComposer CreateHitObjectComposer() => new OsuHitObjectComposer(this); diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs index 6b1a25d667..53cfb4fd0f 100644 --- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs +++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs @@ -22,10 +22,10 @@ namespace osu.Game.Rulesets.Taiko.Difficulty private int countMeh; private int countMiss; - public TaikoPerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) + public TaikoPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, Score score) : base(ruleset, beatmap, score) { - beatmapMaxCombo = beatmap.HitObjects.Count(h => h is Hit); + beatmapMaxCombo = Beatmap.HitObjects.Count(h => h is Hit); } public override double Calculate(Dictionary categoryDifficulty = null) @@ -68,7 +68,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty private double computeStrainValue() { - double strainValue = Math.Pow(5.0 * Math.Max(1.0, Attributes["Strain"] / 0.0075) - 4.0, 2.0) / 100000.0; + double strainValue = Math.Pow(5.0 * Math.Max(1.0, Attributes.StarRating / 0.0075) - 4.0, 2.0) / 100000.0; // Longer maps are worth more double lengthBonus = 1 + 0.1f * Math.Min(1.0, totalHits / 1500.0); diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 1b34ab68bd..7b4978694b 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Taiko public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new TaikoDifficultyCalculator(this, beatmap); - public override PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => new TaikoPerformanceCalculator(this, beatmap, score); + public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, Score score) => new TaikoPerformanceCalculator(this, beatmap, score); public override int? LegacyID => 1; diff --git a/osu.Game.Tests/NonVisual/DifficultyAdjustmentModCombinationsTest.cs b/osu.Game.Tests/NonVisual/DifficultyAdjustmentModCombinationsTest.cs index fd697ba3d3..49494b65b9 100644 --- a/osu.Game.Tests/NonVisual/DifficultyAdjustmentModCombinationsTest.cs +++ b/osu.Game.Tests/NonVisual/DifficultyAdjustmentModCombinationsTest.cs @@ -2,8 +2,8 @@ // 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.Beatmaps; using osu.Game.Rulesets.Difficulty; using osu.Game.Rulesets.Mods; @@ -139,14 +139,14 @@ namespace osu.Game.Tests.NonVisual private class TestDifficultyCalculator : DifficultyCalculator { public TestDifficultyCalculator(params Mod[] mods) - : base(null) + : base(null, null) { DifficultyAdjustmentMods = mods; } - public override double Calculate(Dictionary categoryDifficulty = null) => throw new NotImplementedException(); - protected override Mod[] DifficultyAdjustmentMods { get; } + + protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate) => throw new NotImplementedException(); } } } diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index 895b47d62b..5e3b66646b 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -366,8 +366,7 @@ namespace osu.Game.Beatmaps if (ruleset != null) { // TODO: this should be done in a better place once we actually need to dynamically update it. - var converted = new DummyConversionBeatmap(beatmap).GetPlayableBeatmap(ruleset); - beatmap.BeatmapInfo.StarDifficulty = ruleset.CreateInstance().CreateDifficultyCalculator(converted).Calculate(); + beatmap.BeatmapInfo.StarDifficulty = ruleset.CreateInstance().CreateDifficultyCalculator(new DummyConversionBeatmap(beatmap)).Calculate().StarRating; } else beatmap.BeatmapInfo.StarDifficulty = 0; diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index ee1fc6aec3..265c6832b2 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -62,7 +62,7 @@ namespace osu.Game.Beatmaps public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new DummyBeatmapConverter { Beatmap = beatmap }; - public override DifficultyCalculator CreateDifficultyCalculator(IBeatmap beatmap, Mod[] mods = null) => null; + public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => null; public override string Description => "dummy"; diff --git a/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs b/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs index 07d9c80061..ba783ee87b 100644 --- a/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs +++ b/osu.Game/Rulesets/Difficulty/PerformanceCalculator.cs @@ -13,8 +13,7 @@ namespace osu.Game.Rulesets.Difficulty { public abstract class PerformanceCalculator { - private readonly Dictionary attributes = new Dictionary(); - protected IDictionary Attributes => attributes; + protected readonly DifficultyAttributes Attributes; protected readonly Ruleset Ruleset; protected readonly IBeatmap Beatmap; @@ -22,14 +21,15 @@ namespace osu.Game.Rulesets.Difficulty protected double TimeRate { get; private set; } = 1; - protected PerformanceCalculator(Ruleset ruleset, IBeatmap beatmap, Score score) + protected PerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, Score score) { Ruleset = ruleset; - Beatmap = beatmap; Score = score; - var diffCalc = ruleset.CreateDifficultyCalculator(beatmap, score.Mods); - diffCalc.Calculate(attributes); + beatmap.Mods.Value = score.Mods; + Beatmap = beatmap.GetPlayableBeatmap(ruleset.RulesetInfo); + + Attributes = ruleset.CreateDifficultyCalculator(beatmap).Calculate(score.Mods); ApplyMods(score.Mods); } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index cdc1c44306..f818523a3d 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -63,7 +63,7 @@ namespace osu.Game.Rulesets public abstract DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap); - public virtual PerformanceCalculator CreatePerformanceCalculator(IBeatmap beatmap, Score score) => null; + public virtual PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, Score score) => null; public virtual HitObjectComposer CreateHitObjectComposer() => null; From af218b3d8dd16b6ae9762c122b6fcd757ec44d8f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 16:13:21 +0900 Subject: [PATCH 236/262] No need to use properties --- osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs index 5650bc395a..50a259ae55 100644 --- a/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs +++ b/osu.Game.Rulesets.Osu/Difficulty/OsuDifficultyAttributes.cs @@ -8,8 +8,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty { public class OsuDifficultyAttributes : DifficultyAttributes { - public double AimStrain { get; set; } - public double SpeedStrain { get; set; } + public double AimStrain; + public double SpeedStrain; public OsuDifficultyAttributes(Mod[] mods, double starRating) : base(mods, starRating) From c41a50bf24635c94c719eefcde8272d4147eda4e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 14 Jun 2018 16:39:31 +0900 Subject: [PATCH 237/262] Fix combos ending with JuiceStreams never leaving the catcher's plate Closes #2634. --- osu.Game.Rulesets.Catch/Objects/JuiceStream.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index ae799875a9..b2d8e3f8a5 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -124,6 +124,9 @@ namespace osu.Game.Rulesets.Catch.Objects X = X + Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH }); } + + if (NestedHitObjects.LastOrDefault() is IHasComboInformation lastNested) + lastNested.LastInCombo = LastInCombo; } public double EndTime => StartTime + this.SpanCount() * Curve.Distance / Velocity; From 08b9cf75e964fd3665d3aa67ccb8e4ceff5b7e6b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 17:04:31 +0900 Subject: [PATCH 238/262] Don't compute keymod difficulties for mania-specific beatmaps These don't affect the number of keys in the beatmap at all for mania-specific beatmaps. --- .../Difficulty/ManiaDifficultyCalculator.cs | 49 +++++++++++++------ 1 file changed, 34 insertions(+), 15 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs index 9c091ac31a..520b9c1152 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs @@ -29,9 +29,12 @@ namespace osu.Game.Rulesets.Mania.Difficulty /// private const double decay_weight = 0.9; + private readonly bool isForCurrentRuleset; + public ManiaDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) : base(ruleset, beatmap) { + isForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(new ManiaRuleset().RulesetInfo); } protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate) @@ -129,22 +132,38 @@ namespace osu.Game.Rulesets.Mania.Difficulty return difficulty; } - protected override Mod[] DifficultyAdjustmentMods => new Mod[] + protected override Mod[] DifficultyAdjustmentMods { - 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(), - }; + get + { + if (isForCurrentRuleset) + { + return new Mod[] + { + new ManiaModDoubleTime(), + new ManiaModHalfTime(), + new ManiaModEasy(), + new ManiaModHardRock(), + }; + } + return 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(), + }; + } + } } } From b25a6a33ccdde95af2a05739661b211cf0d7a3fd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 19:37:21 +0900 Subject: [PATCH 239/262] Fix 1K breaking hitcircle / slider conversions --- .../Patterns/Legacy/DistanceObjectPatternGenerator.cs | 7 +++++++ .../Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs | 7 +++++++ 2 files changed, 14 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index afa9bdbbd7..f60958d581 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -58,6 +58,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy public override Pattern Generate() { + if (TotalColumns == 1) + { + var pattern = new Pattern(); + addToPattern(pattern, 0, HitObject.StartTime, endTime); + return pattern; + } + if (spanCount > 1) { if (segmentDuration <= 90) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index cec3e18ad6..c72005e3ad 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -81,6 +81,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy public override Pattern Generate() { + if (TotalColumns == 1) + { + var pattern = new Pattern(); + addToPattern(pattern, 0); + return pattern; + } + int lastColumn = PreviousPattern.HitObjects.FirstOrDefault()?.Column ?? 0; if ((convertType & PatternType.Reverse) > 0 && PreviousPattern.HitObjects.Any()) From a3bf16e481bc5489ba809ef97e6326c565b0fc97 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 19:37:32 +0900 Subject: [PATCH 240/262] Fix missing convert type --- .../Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index c72005e3ad..339a1b4e77 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -77,6 +77,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy } else convertType |= PatternType.LowProbability; + + if ((convertType & PatternType.KeepSingle) == 0) + { + if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && TotalColumns != 8) + convertType |= PatternType.Mirror; + else + convertType |= PatternType.Gathered; + } } public override Pattern Generate() From fd84afb89bfa052f9a13139721d74b8932fe1c0e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 19:38:48 +0900 Subject: [PATCH 241/262] Fix non-inverted calculation --- .../Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs index 339a1b4e77..b4160dc98b 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs @@ -361,7 +361,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy addToCentre = false; if ((convertType & PatternType.ForceNotStack) > 0) - return getRandomNoteCount(p2 / 2, p2, (p2 + p3) / 2, p3); + return getRandomNoteCount(1 / 2f + p2 / 2, p2, (p2 + p3) / 2, p3); switch (TotalColumns) { From 5e66b021085c1214da2c350ebe96688c5aabf0f2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 18:38:27 +0900 Subject: [PATCH 242/262] Process beatmap before generating mappings --- .../Tests/Beatmaps/BeatmapConversionTest.cs | 21 ++++++++++++------- 1 file changed, 14 insertions(+), 7 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 7470f6ebed..c5f74af770 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -84,19 +84,26 @@ namespace osu.Game.Tests.Beatmaps beatmap.BeatmapInfo.Ruleset = beatmap.BeatmapInfo.RulesetID == rulesetInstance.RulesetInfo.ID ? rulesetInstance.RulesetInfo : new RulesetInfo(); var result = new ConvertResult(); - var converter = rulesetInstance.CreateBeatmapConverter(beatmap); + + List>> conversions = new List>>(); + converter.ObjectConverted += (orig, converted) => { + conversions.Add(new KeyValuePair>(orig, converted)); converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty)); - - var mapping = new ConvertMapping { StartTime = orig.StartTime }; - foreach (var obj in converted) - mapping.Objects.AddRange(CreateConvertValue(obj)); - result.Mappings.Add(mapping); }; - converter.Convert(); + IBeatmap convertedBeatmap = converter.Convert(); + rulesetInstance.CreateBeatmapProcessor(convertedBeatmap).PostProcess(); + + foreach (var pair in conversions) + { + var mapping = new ConvertMapping { StartTime = pair.Key.StartTime }; + foreach (var obj in pair.Value) + mapping.Objects.AddRange(CreateConvertValue(obj)); + result.Mappings.Add(mapping); + } return result; } From 8d0e7abdd62c977ffc53d408430faf967604ced3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 21:17:27 +0900 Subject: [PATCH 243/262] Some rulesets don't have a beatmap processor --- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index c5f74af770..4b0da3a14b 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -86,7 +86,7 @@ namespace osu.Game.Tests.Beatmaps var result = new ConvertResult(); var converter = rulesetInstance.CreateBeatmapConverter(beatmap); - List>> conversions = new List>>(); + var conversions = new List>>(); converter.ObjectConverted += (orig, converted) => { @@ -95,7 +95,7 @@ namespace osu.Game.Tests.Beatmaps }; IBeatmap convertedBeatmap = converter.Convert(); - rulesetInstance.CreateBeatmapProcessor(convertedBeatmap).PostProcess(); + rulesetInstance.CreateBeatmapProcessor(convertedBeatmap)?.PostProcess(); foreach (var pair in conversions) { From 024d2abfe09ea3c1200a587ebcef17311d738238 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 20:26:55 +0900 Subject: [PATCH 244/262] Always generate mappings/convert values as soon as objects are converted # Conflicts: # osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs --- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 16 +++++----------- 1 file changed, 5 insertions(+), 11 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 4b0da3a14b..424ebe0cf3 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -86,25 +86,19 @@ namespace osu.Game.Tests.Beatmaps var result = new ConvertResult(); var converter = rulesetInstance.CreateBeatmapConverter(beatmap); - var conversions = new List>>(); - converter.ObjectConverted += (orig, converted) => { - conversions.Add(new KeyValuePair>(orig, converted)); converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty)); + + var mapping = new ConvertMapping { StartTime = orig.StartTime }; + foreach (var obj in converted) + mapping.Objects.AddRange(CreateConvertValue(obj)); + result.Mappings.Add(mapping); }; IBeatmap convertedBeatmap = converter.Convert(); rulesetInstance.CreateBeatmapProcessor(convertedBeatmap)?.PostProcess(); - foreach (var pair in conversions) - { - var mapping = new ConvertMapping { StartTime = pair.Key.StartTime }; - foreach (var obj in pair.Value) - mapping.Objects.AddRange(CreateConvertValue(obj)); - result.Mappings.Add(mapping); - } - return result; } From b99b520656dc8ae9cda7fc5ef1da13801e2ae858 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 20:28:29 +0900 Subject: [PATCH 245/262] Allow convertmapping to be extended --- .../Tests/Beatmaps/BeatmapConversionTest.cs | 68 +++++++++++++++---- 1 file changed, 54 insertions(+), 14 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 424ebe0cf3..9f15949f7b 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -16,7 +16,8 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Tests.Beatmaps { [TestFixture] - public abstract class BeatmapConversionTest + public abstract class BeatmapConversionTest + where TConvertMapping : ConvertMapping, IEquatable, new() where TConvertValue : IEquatable { private const string resource_namespace = "Testing.Beatmaps"; @@ -59,9 +60,13 @@ namespace osu.Game.Tests.Beatmaps else if (objectCounter >= expectedMapping.Objects.Count) Assert.Fail($"The conversion generated a hitobject, but should not have, for hitobject at time: {ourMapping.StartTime}:\n" + $"Received: {JsonConvert.SerializeObject(ourMapping.Objects[objectCounter])}\n"); - else if (!EqualityComparer.Default.Equals(expectedMapping.Objects[objectCounter], ourMapping.Objects[objectCounter])) + else if (!expectedMapping.Equals(ourMapping)) + Assert.Fail($"The conversion mapping differed for object at time {expectedMapping.StartTime}:\n" + + $"Expected {JsonConvert.SerializeObject(expectedMapping)}\n" + + $"Received: {JsonConvert.SerializeObject(ourMapping)}"); + else if (!expectedMapping.Objects[objectCounter].Equals(ourMapping.Objects[objectCounter])) { - Assert.Fail($"The conversion generated differing hitobjects for object at time: {expectedMapping.StartTime}\n" + Assert.Fail($"The conversion generated differing hitobjects for object at time: {expectedMapping.StartTime}:\n" + $"Expected: {JsonConvert.SerializeObject(expectedMapping.Objects[objectCounter])}\n" + $"Received: {JsonConvert.SerializeObject(ourMapping.Objects[objectCounter])}\n"); } @@ -90,7 +95,9 @@ namespace osu.Game.Tests.Beatmaps { converted.ForEach(h => h.ApplyDefaults(beatmap.ControlPointInfo, beatmap.BeatmapInfo.BaseDifficulty)); - var mapping = new ConvertMapping { StartTime = orig.StartTime }; + var mapping = CreateConvertMapping(); + mapping.StartTime = orig.StartTime; + foreach (var obj in converted) mapping.Objects.AddRange(CreateConvertValue(obj)); result.Mappings.Add(mapping); @@ -129,21 +136,54 @@ namespace osu.Game.Tests.Beatmaps return Assembly.LoadFrom(Path.Combine(localPath, $"{ResourceAssembly}.dll")).GetManifestResourceStream($@"{ResourceAssembly}.Resources.{name}"); } - protected abstract IEnumerable CreateConvertValue(HitObject hitObject); - protected abstract Ruleset CreateRuleset(); + /// + /// Creates the conversion mapping for a . A conversion mapping stores important information about the conversion process. + /// This is generated _after_ the has been converted. + /// + /// This should be used to validate the integrity of the conversion process after a conversion has occurred. + /// + /// + protected virtual TConvertMapping CreateConvertMapping() => new TConvertMapping(); - private class ConvertMapping - { - [JsonProperty] - public double StartTime; - [JsonProperty] - public List Objects = new List(); - } + /// + /// Creates the conversion value for a . A conversion value stores information about the converted . + /// + /// This should be used to validate the integrity of the converted . + /// + /// + /// The converted . + protected abstract IEnumerable CreateConvertValue(HitObject hitObject); + + /// + /// Creates the applicable to this . + /// + /// + protected abstract Ruleset CreateRuleset(); private class ConvertResult { [JsonProperty] - public List Mappings = new List(); + public List Mappings = new List(); } } + + public abstract class BeatmapConversionTest : BeatmapConversionTest, TConvertValue> + where TConvertValue : IEquatable + { + } + + public class ConvertMapping : IEquatable> + where TConvertValue : IEquatable + { + [JsonProperty] + public double StartTime; + + [JsonIgnore] + public List Objects = new List(); + + [JsonProperty("Objects")] + private List setObjects { set => Objects = value; } + + public virtual bool Equals(ConvertMapping other) => StartTime.Equals(other?.StartTime); + } } From a4d236408378ea34fd93af06e6c77d775072c59e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 14 Jun 2018 21:29:08 +0900 Subject: [PATCH 246/262] Add one more newline --- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 9f15949f7b..cf4dda52a8 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -63,7 +63,7 @@ namespace osu.Game.Tests.Beatmaps else if (!expectedMapping.Equals(ourMapping)) Assert.Fail($"The conversion mapping differed for object at time {expectedMapping.StartTime}:\n" + $"Expected {JsonConvert.SerializeObject(expectedMapping)}\n" - + $"Received: {JsonConvert.SerializeObject(ourMapping)}"); + + $"Received: {JsonConvert.SerializeObject(ourMapping)}\n"); else if (!expectedMapping.Objects[objectCounter].Equals(ourMapping.Objects[objectCounter])) { Assert.Fail($"The conversion generated differing hitobjects for object at time: {expectedMapping.StartTime}:\n" From 4a19f22b3d798201734ac71859204cddb815fc37 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jun 2018 13:38:42 +0900 Subject: [PATCH 247/262] Remove custom migration exception This was hiding the true error message from ever hitting logs. Made to help disagnose #2711. --- osu.Game/Database/OsuDbContext.cs | 20 +------------------- 1 file changed, 1 insertion(+), 19 deletions(-) diff --git a/osu.Game/Database/OsuDbContext.cs b/osu.Game/Database/OsuDbContext.cs index 4b0de57c4c..bf57644caf 100644 --- a/osu.Game/Database/OsuDbContext.cs +++ b/osu.Game/Database/OsuDbContext.cs @@ -181,24 +181,6 @@ namespace osu.Game.Database } } - public void Migrate() - { - try - { - Database.Migrate(); - } - catch (Exception e) - { - throw new MigrationFailedException(e); - } - } - } - - public class MigrationFailedException : Exception - { - public MigrationFailedException(Exception exception) - : base("sqlite-net migration failed", exception) - { - } + public void Migrate() => Database.Migrate(); } } From 069d939e292bc072423fe8852d2ae003e80ebfe9 Mon Sep 17 00:00:00 2001 From: Joehu Date: Thu, 14 Jun 2018 21:53:01 -0700 Subject: [PATCH 248/262] Remove "from" prefix from sources on direct panels --- osu.Game/Overlays/Direct/DirectGridPanel.cs | 2 +- osu.Game/Overlays/Direct/DirectListPanel.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Direct/DirectGridPanel.cs b/osu.Game/Overlays/Direct/DirectGridPanel.cs index 723e9e8b35..e286837746 100644 --- a/osu.Game/Overlays/Direct/DirectGridPanel.cs +++ b/osu.Game/Overlays/Direct/DirectGridPanel.cs @@ -149,7 +149,7 @@ namespace osu.Game.Overlays.Direct { new OsuSpriteText { - Text = $"{SetInfo.Metadata.Source}", + Text = SetInfo.Metadata.Source, TextSize = 14, Shadow = false, Colour = colours.Gray5, diff --git a/osu.Game/Overlays/Direct/DirectListPanel.cs b/osu.Game/Overlays/Direct/DirectListPanel.cs index 6e3483604b..812a0e2073 100644 --- a/osu.Game/Overlays/Direct/DirectListPanel.cs +++ b/osu.Game/Overlays/Direct/DirectListPanel.cs @@ -160,7 +160,7 @@ namespace osu.Game.Overlays.Direct }, new OsuSpriteText { - Text = $"from {SetInfo.Metadata.Source}", + Text = SetInfo.Metadata.Source, Anchor = Anchor.TopRight, Origin = Anchor.TopRight, TextSize = 14, From 149d94116bef6b2cbe96aba8901922fb2de7c53c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jun 2018 15:44:47 +0900 Subject: [PATCH 249/262] Fix droplets not bouncing off catcher's plate immediately --- .../Drawable/DrawableCatchHitObject.cs | 2 + .../Objects/Drawable/DrawableDroplet.cs | 2 + osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 63 +++++++++++-------- 3 files changed, 40 insertions(+), 27 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index 3dbda708e5..e3564b5967 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -42,6 +42,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public virtual bool CanBePlated => false; + public virtual bool StaysOnPlate => CanBePlated; + protected DrawableCatchHitObject(CatchHitObject hitObject) : base(hitObject) { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index a19d67ebbe..5c8a7c4a7c 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -13,6 +13,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { private Pulp pulp; + public override bool StaysOnPlate => false; + public DrawableDroplet(Droplet h) : base(h) { diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index d8c7b5130d..b62e9997d4 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -48,6 +48,16 @@ namespace osu.Game.Rulesets.Catch.UI public void OnJudgement(DrawableCatchHitObject fruit, Judgement judgement) { + void runAfterLoaded(Action action) + { + // this is required to make this run after the last caught fruit runs UpdateState at least once. + // TODO: find a better alternative + if (lastPlateableFruit.IsLoaded) + action(); + else + lastPlateableFruit.OnLoadComplete = _ => action(); + } + if (judgement.IsHit && fruit.CanBePlated) { var caughtFruit = (DrawableCatchHitObject)GetVisualRepresentation?.Invoke(fruit.HitObject); @@ -63,21 +73,17 @@ namespace osu.Game.Rulesets.Catch.UI caughtFruit.LifetimeEnd = double.MaxValue; MovableCatcher.Add(caughtFruit); - lastPlateableFruit = caughtFruit; + + if (!fruit.StaysOnPlate) + runAfterLoaded(() => MovableCatcher.Explode(caughtFruit)); + } if (fruit.HitObject.LastInCombo) { if (judgement.IsHit) - { - // this is required to make this run after the last caught fruit runs UpdateState at least once. - // TODO: find a better alternative - if (lastPlateableFruit.IsLoaded) - MovableCatcher.Explode(); - else - lastPlateableFruit.OnLoadComplete = _ => { MovableCatcher.Explode(); }; - } + runAfterLoaded(() => MovableCatcher.Explode()); else MovableCatcher.Drop(); } @@ -378,28 +384,31 @@ namespace osu.Game.Rulesets.Catch.UI var fruit = caughtFruit.ToArray(); foreach (var f in fruit) + Explode(f); + } + + public void Explode(DrawableHitObject fruit) + { + var originalX = fruit.X * Scale.X; + + if (ExplodingFruitTarget != null) { - var originalX = f.X * Scale.X; + fruit.Anchor = Anchor.TopLeft; + fruit.Position = caughtFruit.ToSpaceOfOtherDrawable(fruit.DrawPosition, ExplodingFruitTarget); - if (ExplodingFruitTarget != null) - { - f.Anchor = Anchor.TopLeft; - f.Position = caughtFruit.ToSpaceOfOtherDrawable(f.DrawPosition, ExplodingFruitTarget); + caughtFruit.Remove(fruit); - caughtFruit.Remove(f); - - ExplodingFruitTarget.Add(f); - } - - f.MoveToY(f.Y - 50, 250, Easing.OutSine) - .Then() - .MoveToY(f.Y + 50, 500, Easing.InSine); - - f.MoveToX(f.X + originalX * 6, 1000); - f.FadeOut(750); - - f.Expire(); + ExplodingFruitTarget.Add(fruit); } + + fruit.MoveToY(fruit.Y - 50, 250, Easing.OutSine) + .Then() + .MoveToY(fruit.Y + 50, 500, Easing.InSine); + + fruit.MoveToX(fruit.X + originalX * 6, 1000); + fruit.FadeOut(750); + + fruit.Expire(); } private class CatcherSprite : Sprite From 1c27ef644a53340f8d3883128789ae71bbc6cb8a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jun 2018 16:12:11 +0900 Subject: [PATCH 250/262] Fix music controller drag activating from anywhere on the screen --- osu.Game/Overlays/MusicController.cs | 61 +++++++++++++++------------- 1 file changed, 32 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/MusicController.cs b/osu.Game/Overlays/MusicController.cs index d96bb40165..a57d5fd183 100644 --- a/osu.Game/Overlays/MusicController.cs +++ b/osu.Game/Overlays/MusicController.cs @@ -66,34 +66,6 @@ namespace osu.Game.Overlays AlwaysPresent = true; } - private Vector2 dragStart; - - protected override bool OnDragStart(InputState state) - { - base.OnDragStart(state); - dragStart = state.Mouse.Position; - return true; - } - - protected override bool OnDrag(InputState state) - { - if (base.OnDrag(state)) return true; - - Vector2 change = state.Mouse.Position - dragStart; - - // Diminish the drag distance as we go further to simulate "rubber band" feeling. - change *= change.Length <= 0 ? 0 : (float)Math.Pow(change.Length, 0.7f) / change.Length; - - dragContainer.MoveTo(change); - return true; - } - - protected override bool OnDragEnd(InputState state) - { - dragContainer.MoveTo(Vector2.Zero, 800, Easing.OutElastic); - return base.OnDragEnd(state); - } - [BackgroundDependencyLoader] private void load(BindableBeatmap beatmap, BeatmapManager beatmaps, OsuColour colours, LocalisationEngine localisation) { @@ -103,7 +75,7 @@ namespace osu.Game.Overlays Children = new Drawable[] { - dragContainer = new Container + dragContainer = new DragContainer { Anchor = Anchor.Centre, Origin = Anchor.Centre, @@ -470,5 +442,36 @@ namespace osu.Game.Overlays sprite.Texture = beatmap?.Background ?? textures.Get(@"Backgrounds/bg4"); } } + + private class DragContainer : Container + { + private Vector2 dragStart; + + protected override bool OnDragStart(InputState state) + { + base.OnDragStart(state); + dragStart = state.Mouse.Position; + return true; + } + + protected override bool OnDrag(InputState state) + { + if (base.OnDrag(state)) return true; + + Vector2 change = state.Mouse.Position - dragStart; + + // Diminish the drag distance as we go further to simulate "rubber band" feeling. + change *= change.Length <= 0 ? 0 : (float)Math.Pow(change.Length, 0.7f) / change.Length; + + this.MoveTo(change); + return true; + } + + protected override bool OnDragEnd(InputState state) + { + this.MoveTo(Vector2.Zero, 800, Easing.OutElastic); + return base.OnDragEnd(state); + } + } } } From a2950b1d80d6efeece366c6be4b807a88d434dc6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 15 Jun 2018 16:12:18 +0900 Subject: [PATCH 251/262] Fix incorrect comment --- osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 0186a170c9..062f8d27aa 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -33,7 +33,7 @@ namespace osu.Game.Graphics.Containers /// /// Whether mouse input should be blocked screen-wide while this overlay is visible. - /// Performing mouse actions outside of the valid extents will hide the overlay but pass the events through. + /// Performing mouse actions outside of the valid extents will hide the overlay and block the input. /// public virtual bool BlockScreenWideMouse => BlockPassThroughMouse; From aaf3ef240e4e40a49768bf051ed8157ad1e5894e Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Fri, 15 Jun 2018 17:07:07 +0900 Subject: [PATCH 252/262] Remove easily-confused comment --- osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 062f8d27aa..0528f7b3ae 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -33,7 +33,7 @@ namespace osu.Game.Graphics.Containers /// /// Whether mouse input should be blocked screen-wide while this overlay is visible. - /// Performing mouse actions outside of the valid extents will hide the overlay and block the input. + /// Performing mouse actions outside of the valid extents will hide the overlay. /// public virtual bool BlockScreenWideMouse => BlockPassThroughMouse; From 457531910294897c15cdfbc5337672d138c0ef1d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sun, 17 Jun 2018 17:56:46 +0900 Subject: [PATCH 253/262] Privatise the proxied content --- .../Objects/Drawables/DrawableTaikoHitObject.cs | 17 +++++++++++------ osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 +- 2 files changed, 12 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index c07ee3a0fd..e712d62a26 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public abstract class DrawableTaikoHitObject : DrawableHitObject, IKeyBindingHandler { protected readonly Container Content; - public readonly Container ProxiedContent; + private readonly Container proxiedContent; private readonly Container nonProxiedContent; @@ -31,12 +31,12 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables RelativeSizeAxes = Axes.Both, Child = Content = new Container { RelativeSizeAxes = Axes.Both } }, - ProxiedContent = new Container { RelativeSizeAxes = Axes.Both } + proxiedContent = new Container { RelativeSizeAxes = Axes.Both } }; } /// - /// is proxied into an upper layer. We don't want to get masked away otherwise would too. + /// is proxied into an upper layer. We don't want to get masked away otherwise would too. /// protected override bool ComputeIsMaskedAway(RectangleF maskingBounds) => false; @@ -46,8 +46,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected void ProxyContent() { nonProxiedContent.Remove(Content); - ProxiedContent.Remove(Content); - ProxiedContent.Add(Content); + proxiedContent.Remove(Content); + proxiedContent.Add(Content); } /// @@ -55,11 +55,16 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// protected void UnproxyContent() { - ProxiedContent.Remove(Content); + proxiedContent.Remove(Content); nonProxiedContent.Remove(Content); nonProxiedContent.Add(Content); } + /// + /// Creates a proxy for the content of this . + /// + public Drawable CreateProxiedContent() => proxiedContent.CreateProxy(); + public abstract bool OnPressed(TaikoAction action); public virtual bool OnReleased(TaikoAction action) => false; } diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index c638f807fe..7fdd3cd1e2 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -218,7 +218,7 @@ namespace osu.Game.Rulesets.Taiko.UI var taikoObject = h as DrawableTaikoHitObject; if (taikoObject != null) - topLevelHitContainer.Add(taikoObject.ProxiedContent.CreateProxy()); + topLevelHitContainer.Add(taikoObject.CreateProxiedContent()); } internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) From 0a99d21938a252071189eab06d40f909d098e138 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sun, 17 Jun 2018 18:01:28 +0900 Subject: [PATCH 254/262] Use the passed-in ruleset --- osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs index 520b9c1152..5d5adb8e66 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty public ManiaDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap) : base(ruleset, beatmap) { - isForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(new ManiaRuleset().RulesetInfo); + isForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(ruleset.RulesetInfo); } protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate) From 6c100caba763b333cd099e37033c70e02cac224b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 15:09:03 +0900 Subject: [PATCH 255/262] Use existing instance of beatmap rather than adding more resources --- .../Beatmaps/IO/ImportBeatmapTest.cs | 4 +- osu.Game.Tests/Visual/TestCaseWaveform.cs | 16 +----- osu.Game.Tests/WaveformTestBeatmap.cs | 55 +++++++++++++++++++ 3 files changed, 60 insertions(+), 15 deletions(-) create mode 100644 osu.Game.Tests/WaveformTestBeatmap.cs diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 1c9696901c..616ba132fd 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -19,7 +19,7 @@ namespace osu.Game.Tests.Beatmaps.IO [TestFixture] public class ImportBeatmapTest { - private const string osz_path = @"../../../../osu-resources/osu.Game.Resources/Beatmaps/241526 Soleily - Renatus.osz"; + public const string TEST_OSZ_PATH = @"../../../../osu-resources/osu.Game.Resources/Beatmaps/241526 Soleily - Renatus.osz"; [Test] public void TestImportWhenClosed() @@ -265,7 +265,7 @@ namespace osu.Game.Tests.Beatmaps.IO private string createTemporaryBeatmap() { var temp = Path.GetTempFileName() + ".osz"; - File.Copy(osz_path, temp, true); + File.Copy(TEST_OSZ_PATH, temp, true); Assert.IsTrue(File.Exists(temp)); return temp; } diff --git a/osu.Game.Tests/Visual/TestCaseWaveform.cs b/osu.Game.Tests/Visual/TestCaseWaveform.cs index 983b98016e..46d46863ad 100644 --- a/osu.Game.Tests/Visual/TestCaseWaveform.cs +++ b/osu.Game.Tests/Visual/TestCaseWaveform.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics.Audio; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Sprites; -using osu.Game.Overlays; namespace osu.Game.Tests.Visual { @@ -20,22 +19,14 @@ namespace osu.Game.Tests.Visual [BackgroundDependencyLoader] private void load() { + Beatmap.Value = new WaveformTestBeatmap(); + FillFlowContainer flow; Child = flow = new FillFlowContainer { RelativeSizeAxes = Axes.Both, Direction = FillDirection.Vertical, Spacing = new Vector2(0, 10), - Children = new Drawable[] - { - new MusicController - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - Y = 100, - State = Visibility.Visible - }, - } }; for (int i = 1; i <= 16; i *= 2) @@ -44,10 +35,9 @@ namespace osu.Game.Tests.Visual { RelativeSizeAxes = Axes.Both, Resolution = 1f / i, + Waveform = Beatmap.Value.Waveform, }; - Beatmap.ValueChanged += b => newDisplay.Waveform = b.Waveform; - flow.Add(new Container { RelativeSizeAxes = Axes.X, diff --git a/osu.Game.Tests/WaveformTestBeatmap.cs b/osu.Game.Tests/WaveformTestBeatmap.cs new file mode 100644 index 0000000000..17aa7db14d --- /dev/null +++ b/osu.Game.Tests/WaveformTestBeatmap.cs @@ -0,0 +1,55 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.IO; +using System.Linq; +using osu.Framework.Audio.Track; +using osu.Framework.Graphics.Textures; +using osu.Game.Beatmaps; +using osu.Game.Beatmaps.Formats; +using osu.Game.IO.Archives; +using osu.Game.Tests.Beatmaps.IO; + +namespace osu.Game.Tests +{ + /// + /// A that is used for testcases that include waveforms. + /// + public class WaveformTestBeatmap : WorkingBeatmap + { + private readonly ZipArchiveReader reader; + private readonly FileStream stream; + + public WaveformTestBeatmap() + : base(new BeatmapInfo()) + { + stream = File.OpenRead(ImportBeatmapTest.TEST_OSZ_PATH); + reader = new ZipArchiveReader(stream); + } + + public override void Dispose() + { + base.Dispose(); + stream?.Dispose(); + reader?.Dispose(); + } + + protected override IBeatmap GetBeatmap() => createTestBeatmap(); + + protected override Texture GetBackground() => null; + + protected override Waveform GetWaveform() => new Waveform(getAudioStream()); + + protected override Track GetTrack() => new TrackBass(getAudioStream()); + + private Stream getAudioStream() => reader.GetStream(reader.Filenames.First(f => f.EndsWith(".mp3"))); + private Stream getBeatmapStream() => reader.GetStream(reader.Filenames.First(f => f.EndsWith(".osu"))); + + private Beatmap createTestBeatmap() + { + using (var beatmapStream = getBeatmapStream()) + using (var beatmapReader = new StreamReader(beatmapStream)) + return Decoder.GetDecoder(beatmapReader).Decode(beatmapReader); + } + } +} From 0695615c6a21ff53e11c6e53ef52147841304b66 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 13 Jun 2018 15:10:08 +0900 Subject: [PATCH 256/262] Remove MusicController from compose timeline testcase --- .../Visual/TestCaseEditorComposeTimeline.cs | 104 +++++++++++++++++- 1 file changed, 98 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index c0557982fb..bb0e6156f6 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -4,11 +4,17 @@ using System; using System.Collections.Generic; using NUnit.Framework; +using osu.Framework.Allocation; +using osu.Framework.Configuration; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Game.Overlays; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Timing; +using osu.Game.Beatmaps; using osu.Game.Screens.Edit.Screens.Compose.Timeline; +using OpenTK.Graphics; namespace osu.Game.Tests.Visual { @@ -17,15 +23,23 @@ namespace osu.Game.Tests.Visual { public override IReadOnlyList RequiredTypes => new[] { typeof(TimelineArea), typeof(Timeline), typeof(TimelineButton) }; - public TestCaseEditorComposeTimeline() + [BackgroundDependencyLoader] + private void load() { + Beatmap.Value = new WaveformTestBeatmap(); + Children = new Drawable[] { - new MusicController + new FillFlowContainer { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - State = Visibility.Visible + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 5), + Children = new Drawable[] + { + new StartStopButton(), + new AudioVisualiser(), + } }, new TimelineArea { @@ -36,5 +50,83 @@ namespace osu.Game.Tests.Visual } }; } + + private class AudioVisualiser : CompositeDrawable + { + private readonly Drawable marker; + + private readonly IBindable beatmap = new Bindable(); + private IAdjustableClock adjustableClock; + + public AudioVisualiser() + { + Size = new Vector2(250, 25); + + InternalChildren = new[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0.25f, + }, + marker = new Box + { + RelativePositionAxes = Axes.X, + RelativeSizeAxes = Axes.Y, + Width = 2, + } + }; + } + + [BackgroundDependencyLoader] + private void load(IAdjustableClock adjustableClock, IBindableBeatmap beatmap) + { + this.adjustableClock = adjustableClock; + this.beatmap.BindTo(beatmap); + } + + protected override void Update() + { + base.Update(); + marker.X = (float)(adjustableClock.CurrentTime / beatmap.Value.Track.Length); + } + } + + private class StartStopButton : Button + { + private IAdjustableClock adjustableClock; + private bool started; + + public StartStopButton() + { + BackgroundColour = Color4.SlateGray; + Size = new Vector2(100, 50); + Text = "Start"; + + Action = onClick; + } + + [BackgroundDependencyLoader] + private void load(IAdjustableClock adjustableClock) + { + this.adjustableClock = adjustableClock; + } + + private void onClick() + { + if (started) + { + adjustableClock.Stop(); + Text = "Start"; + } + else + { + adjustableClock.Start(); + Text = "Stop"; + } + + started = !started; + } + } } } From 08f172ba982f8c4880a516dc565e373b3f7d0ab0 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 15 Jun 2018 15:38:19 +0900 Subject: [PATCH 257/262] Make testcase work on appveyor (no BASS) --- osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs index bb0e6156f6..5aa17bca7d 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorComposeTimeline.cs @@ -88,7 +88,9 @@ namespace osu.Game.Tests.Visual protected override void Update() { base.Update(); - marker.X = (float)(adjustableClock.CurrentTime / beatmap.Value.Track.Length); + + if (beatmap.Value.Track.IsLoaded) + marker.X = (float)(adjustableClock.CurrentTime / beatmap.Value.Track.Length); } } From 5b344525e1889e6c4fbd8a5cedccc812827a314e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jun 2018 00:27:18 +0900 Subject: [PATCH 258/262] Move proxy state check to base class --- .../Objects/Drawables/DrawableSwell.cs | 7 +------ .../Objects/Drawables/DrawableTaikoHitObject.cs | 12 ++++++++++-- 2 files changed, 11 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 1f571544d8..df36a475d6 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -34,7 +34,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// private int userHits; - private bool hasProxied; private readonly SwellSymbolPiece symbol; public DrawableSwell(Swell swell) @@ -172,7 +171,6 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables switch (state) { case ArmedState.Idle: - hasProxied = false; UnproxyContent(); break; case ArmedState.Hit: @@ -193,11 +191,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables X = Math.Max(0, X); double t = Math.Min(HitObject.StartTime, Time.Current); - if (t == HitObject.StartTime && !hasProxied) - { + if (t == HitObject.StartTime) ProxyContent(); - hasProxied = true; - } } private bool? lastWasCentre; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index e712d62a26..a6d61f1a5a 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -40,23 +40,31 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// protected override bool ComputeIsMaskedAway(RectangleF maskingBounds) => false; + private bool isProxied; + /// /// Moves to a layer proxied above the playfield. + /// Does nothing is content is already proxied. /// protected void ProxyContent() { + if (isProxied) return; + isProxied = true; + nonProxiedContent.Remove(Content); - proxiedContent.Remove(Content); proxiedContent.Add(Content); } /// /// Moves to the normal hitobject layer. + /// Does nothing is content is not currently proxied. /// protected void UnproxyContent() { + if (!isProxied) return; + isProxied = false; + proxiedContent.Remove(Content); - nonProxiedContent.Remove(Content); nonProxiedContent.Add(Content); } From 6fa72c510f2b0229267053a4d7e460f69ce0f309 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jun 2018 00:48:35 +0900 Subject: [PATCH 259/262] Avoid listing the base mods twice --- .../Difficulty/ManiaDifficultyCalculator.cs | 23 ++++++++----------- 1 file changed, 10 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs index 5d5adb8e66..5fa113224d 100644 --- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs +++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs @@ -136,23 +136,20 @@ namespace osu.Game.Rulesets.Mania.Difficulty { get { - if (isForCurrentRuleset) - { - return new Mod[] - { - new ManiaModDoubleTime(), - new ManiaModHalfTime(), - new ManiaModEasy(), - new ManiaModHardRock(), - }; - } - - return new Mod[] + var mods = new Mod[] { new ManiaModDoubleTime(), new ManiaModHalfTime(), new ManiaModEasy(), new ManiaModHardRock(), + }; + + if (isForCurrentRuleset) + return mods; + + // if we are a convert, we can be played in any key mod. + return mods.Concat(new Mod[] + { new ManiaModKey1(), new ManiaModKey2(), new ManiaModKey3(), @@ -162,7 +159,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty new ManiaModKey7(), new ManiaModKey8(), new ManiaModKey9(), - }; + }).ToArray(); } } } From 31f9d0161df4b9f2fd19e6a7e9304f52766d2154 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jun 2018 03:03:09 +0900 Subject: [PATCH 260/262] Add a comment about precision scroll behaviour --- .../Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs index ed26c28c80..0bfea68e50 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/ZoomableScrollContainer.cs @@ -100,7 +100,9 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline protected override bool OnScroll(InputState state) { if (state.Mouse.HasPreciseScroll) + // for now, we don't support zoom when using a precision scroll device. this needs gesture support. return base.OnScroll(state); + setZoomTarget(zoomTarget + state.Mouse.ScrollDelta.Y, zoomedContent.ToLocalSpace(state.Mouse.NativeState.Position).X); return true; } From bec6e3083ec27fd25205a343470f0c9c6ad7a43b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jun 2018 03:19:21 +0900 Subject: [PATCH 261/262] Remove scrollbar depth change as scrollbar is hidden now --- osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index 489233e256..36f76b013a 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -45,9 +45,6 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline // We don't want the centre marker to scroll AddInternal(new CentreMarker()); - // Make sure that the scrollbar is above the centre marker - ChangeInternalChildDepth(Scrollbar, -1); - WaveformVisible.ValueChanged += visible => waveform.FadeTo(visible ? 1 : 0, 200, Easing.OutQuint); Beatmap.BindTo(beatmap); From b1d059a67dbe34b17d6389b3a97b33a463ecc0ba Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 18 Jun 2018 04:31:47 +0900 Subject: [PATCH 262/262] Add some colours to the compose-mode timeline --- .../Screens/Edit/Screens/Compose/Timeline/Timeline.cs | 8 ++++++-- 1 file changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs index 36f76b013a..e993d36551 100644 --- a/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Screens/Compose/Timeline/Timeline.cs @@ -4,6 +4,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.Audio; using osu.Framework.Input; @@ -31,14 +32,17 @@ namespace osu.Game.Screens.Edit.Screens.Compose.Timeline private WaveformGraph waveform; [BackgroundDependencyLoader] - private void load(IBindableBeatmap beatmap, IAdjustableClock adjustableClock) + private void load(IBindableBeatmap beatmap, IAdjustableClock adjustableClock, OsuColour colours) { this.adjustableClock = adjustableClock; Child = waveform = new WaveformGraph { RelativeSizeAxes = Axes.Both, - Colour = OsuColour.FromHex("222"), + Colour = colours.Blue.Opacity(0.2f), + LowColour = colours.BlueLighter, + MidColour = colours.BlueDark, + HighColour = colours.BlueDarker, Depth = float.MaxValue };