From d437c1d7ec386e8ca72ab8ffb6f5e3a6f143e463 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Thu, 8 Feb 2018 23:28:42 +0300 Subject: [PATCH 01/18] Introduce PlayerBase class --- osu.Game/Screens/Play/Player.cs | 96 ++++----------------------- osu.Game/Screens/Play/PlayerBase.cs | 84 +++++++++++++++++++++++ osu.Game/Screens/Play/PlayerLoader.cs | 7 +- osu.Game/osu.Game.csproj | 1 + 4 files changed, 99 insertions(+), 89 deletions(-) create mode 100644 osu.Game/Screens/Play/PlayerBase.cs diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 72864482d5..0f15592b72 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -5,9 +5,6 @@ using System; using System.Linq; using System.Threading.Tasks; 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.Cursor; @@ -18,31 +15,23 @@ using osu.Framework.Threading; using osu.Framework.Timing; using osu.Game.Beatmaps; using osu.Game.Configuration; -using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Online.API; using osu.Game.Rulesets; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; -using osu.Game.Screens.Backgrounds; using osu.Game.Screens.Play.BreaksOverlay; using osu.Game.Screens.Ranking; -using osu.Game.Storyboards.Drawables; -using OpenTK; namespace osu.Game.Screens.Play { - public class Player : OsuScreen, IProvideCursor + public class Player : PlayerBase, IProvideCursor { - protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); - public override bool ShowOverlaysOnEnter => false; public Action RestartRequested; - public override bool AllowBeatmapRulesetChange => false; - public bool HasFailed { get; private set; } public bool AllowPause { get; set; } = true; @@ -67,39 +56,16 @@ namespace osu.Game.Screens.Play private ScoreProcessor scoreProcessor; protected RulesetContainer RulesetContainer; - #region User Settings - - private Bindable dimLevel; - private Bindable blurLevel; - private Bindable showStoryboard; - private Bindable mouseWheelDisabled; - private Bindable userAudioOffset; - - private SampleChannel sampleRestart; - - #endregion - - private Container storyboardContainer; - private DrawableStoryboard storyboard; - private HUDOverlay hudOverlay; private FailOverlay failOverlay; private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config, APIAccess api) + private void load(OsuConfigManager config, APIAccess api) { this.api = api; - dimLevel = config.GetBindable(OsuSetting.DimLevel); - blurLevel = config.GetBindable(OsuSetting.BlurLevel); - showStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); - - mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); - - sampleRestart = audio.Sample.Get(@"Gameplay/restart"); - WorkingBeatmap working = Beatmap.Value; Beatmap beatmap; @@ -150,15 +116,14 @@ namespace osu.Game.Screens.Play offsetClock = new FramedOffsetClock(decoupledClock); - userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); - userAudioOffset.ValueChanged += v => offsetClock.Offset = v; - userAudioOffset.TriggerChange(); + UserAudioOffset.ValueChanged += v => offsetClock.Offset = v; + UserAudioOffset.TriggerChange(); scoreProcessor = RulesetContainer.CreateScoreProcessor(); Children = new Drawable[] { - storyboardContainer = new Container + StoryboardContainer = new Container { RelativeSizeAxes = Axes.Both, Clock = offsetClock, @@ -219,8 +184,8 @@ namespace osu.Game.Screens.Play } }; - if (showStoryboard) - initializeStoryboard(false); + if (ShowStoryboard) + InitializeStoryboard(false); // Bind ScoreProcessor to ourselves scoreProcessor.AllJudged += onCompletion; @@ -239,22 +204,9 @@ namespace osu.Game.Screens.Play mod.ApplyToClock(adjustableSourceClock); } - private void initializeStoryboard(bool asyncLoad) - { - var beatmap = Beatmap.Value; - - storyboard = beatmap.Storyboard.CreateDrawable(Beatmap.Value); - storyboard.Masking = true; - - if (asyncLoad) - LoadComponentAsync(storyboard, storyboardContainer.Add); - else - storyboardContainer.Add(storyboard); - } - public void Restart() { - sampleRestart?.Play(); + SampleRestart?.Play(); ValidForResume = false; RestartRequested?.Invoke(); Exit(); @@ -310,10 +262,10 @@ namespace osu.Game.Screens.Play if (!loadedSuccessfully) return; - dimLevel.ValueChanged += _ => updateBackgroundElements(); - blurLevel.ValueChanged += _ => updateBackgroundElements(); - showStoryboard.ValueChanged += _ => updateBackgroundElements(); - updateBackgroundElements(); + DimLevel.ValueChanged += _ => UpdateBackgroundElements(); + BlurLevel.ValueChanged += _ => UpdateBackgroundElements(); + ShowStoryboard.ValueChanged += _ => UpdateBackgroundElements(); + UpdateBackgroundElements(); Content.Alpha = 0; Content @@ -368,28 +320,6 @@ namespace osu.Game.Screens.Play return true; } - private void updateBackgroundElements() - { - if (!IsCurrentScreen) return; - - const float duration = 800; - - var opacity = 1 - (float)dimLevel; - - if (showStoryboard && storyboard == null) - initializeStoryboard(true); - - var beatmap = Beatmap.Value; - var storyboardVisible = showStoryboard && beatmap.Storyboard.HasDrawable; - - storyboardContainer - .FadeColour(OsuColour.Gray(opacity), duration, Easing.OutQuint) - .FadeTo(storyboardVisible && opacity > 0 ? 1 : 0, duration, Easing.OutQuint); - - (Background as BackgroundScreenBeatmap)?.BlurTo(new Vector2((float)blurLevel.Value * 25), duration, Easing.OutQuint); - Background?.FadeTo(!storyboardVisible || beatmap.Background == null ? opacity : 0, duration, Easing.OutQuint); - } - private void fadeOut() { const float fade_out_duration = 250; @@ -402,6 +332,6 @@ namespace osu.Game.Screens.Play Background?.FadeTo(1f, fade_out_duration); } - protected override bool OnWheel(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused; + protected override bool OnWheel(InputState state) => MouseWheelDisabled.Value && !pauseContainer.IsPaused; } } diff --git a/osu.Game/Screens/Play/PlayerBase.cs b/osu.Game/Screens/Play/PlayerBase.cs new file mode 100644 index 0000000000..c5a7e52de7 --- /dev/null +++ b/osu.Game/Screens/Play/PlayerBase.cs @@ -0,0 +1,84 @@ +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.Game.Configuration; +using osu.Game.Graphics; +using osu.Game.Screens.Backgrounds; +using osu.Game.Storyboards.Drawables; +using OpenTK; + +namespace osu.Game.Screens.Play +{ + public abstract class PlayerBase : OsuScreen + { + protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); + public override bool AllowBeatmapRulesetChange => false; + + #region User Settings + + protected Bindable DimLevel; + protected Bindable BlurLevel; + protected Bindable ShowStoryboard; + protected Bindable MouseWheelDisabled; + protected Bindable UserAudioOffset; + + protected SampleChannel SampleRestart; + + #endregion + + protected DrawableStoryboard Storyboard; + protected Container StoryboardContainer; + + [BackgroundDependencyLoader] + private void load(AudioManager audio, OsuConfigManager config) + { + DimLevel = config.GetBindable(OsuSetting.DimLevel); + BlurLevel = config.GetBindable(OsuSetting.BlurLevel); + ShowStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); + + MouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); + + SampleRestart = audio.Sample.Get(@"Gameplay/restart"); + + UserAudioOffset = config.GetBindable(OsuSetting.AudioOffset); + } + + protected void UpdateBackgroundElements() + { + if (!IsCurrentScreen) return; + + const float duration = 800; + + var opacity = 1 - (float)DimLevel; + + if (ShowStoryboard && Storyboard == null) + InitializeStoryboard(true); + + var beatmap = Beatmap.Value; + var storyboardVisible = ShowStoryboard && beatmap.Storyboard.HasDrawable; + + StoryboardContainer + .FadeColour(OsuColour.Gray(opacity), duration, Easing.OutQuint) + .FadeTo(storyboardVisible && opacity > 0 ? 1 : 0, duration, Easing.OutQuint); + + (Background as BackgroundScreenBeatmap)?.BlurTo(new Vector2((float)BlurLevel.Value * 25), duration, Easing.OutQuint); + Background?.FadeTo(!storyboardVisible || beatmap.Background == null ? opacity : 0, duration, Easing.OutQuint); + } + + protected void InitializeStoryboard(bool asyncLoad) + { + var beatmap = Beatmap.Value; + + Storyboard = beatmap.Storyboard.CreateDrawable(Beatmap.Value); + Storyboard.Masking = true; + + if (asyncLoad) + LoadComponentAsync(Storyboard, StoryboardContainer.Add); + else + StoryboardContainer.Add(Storyboard); + } + } +} diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 2950990779..0c6368c714 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -9,7 +9,6 @@ using osu.Framework.Screens; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Screens.Backgrounds; using OpenTK; using osu.Framework.Localisation; using osu.Game.Screens.Menu; @@ -17,7 +16,7 @@ using osu.Game.Screens.Play.PlayerSettings; namespace osu.Game.Screens.Play { - public class PlayerLoader : OsuScreen + public class PlayerLoader : PlayerBase { private Player player; @@ -27,10 +26,6 @@ namespace osu.Game.Screens.Play private bool showOverlays = true; public override bool ShowOverlaysOnEnter => showOverlays; - public override bool AllowBeatmapRulesetChange => false; - - protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); - public PlayerLoader(Player player) { this.player = player; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6542160b97..cc5f5b92da 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -340,6 +340,7 @@ + From a860dd720893bf9f2eb950c64ef2d720477e7536 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Fri, 9 Feb 2018 00:06:24 +0300 Subject: [PATCH 02/18] =?UTF-8?q?Preview=20visual=20settings=20at=20the=20?= =?UTF-8?q?=E2=80=9Cloading=E2=80=9D=20screen?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit --- osu.Game/Screens/Play/Player.cs | 5 +---- osu.Game/Screens/Play/PlayerBase.cs | 13 ++++++++++++- osu.Game/Screens/Play/PlayerLoader.cs | 2 +- 3 files changed, 14 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 0f15592b72..8ebee96bae 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -262,10 +262,7 @@ namespace osu.Game.Screens.Play if (!loadedSuccessfully) return; - DimLevel.ValueChanged += _ => UpdateBackgroundElements(); - BlurLevel.ValueChanged += _ => UpdateBackgroundElements(); - ShowStoryboard.ValueChanged += _ => UpdateBackgroundElements(); - UpdateBackgroundElements(); + ConfigureBackgroundUpdate(); Content.Alpha = 0; Content diff --git a/osu.Game/Screens/Play/PlayerBase.cs b/osu.Game/Screens/Play/PlayerBase.cs index c5a7e52de7..b725b739c9 100644 --- a/osu.Game/Screens/Play/PlayerBase.cs +++ b/osu.Game/Screens/Play/PlayerBase.cs @@ -46,6 +46,14 @@ namespace osu.Game.Screens.Play UserAudioOffset = config.GetBindable(OsuSetting.AudioOffset); } + protected void ConfigureBackgroundUpdate() + { + DimLevel.ValueChanged += _ => UpdateBackgroundElements(); + BlurLevel.ValueChanged += _ => UpdateBackgroundElements(); + ShowStoryboard.ValueChanged += _ => UpdateBackgroundElements(); + UpdateBackgroundElements(); + } + protected void UpdateBackgroundElements() { if (!IsCurrentScreen) return; @@ -60,7 +68,7 @@ namespace osu.Game.Screens.Play var beatmap = Beatmap.Value; var storyboardVisible = ShowStoryboard && beatmap.Storyboard.HasDrawable; - StoryboardContainer + StoryboardContainer? .FadeColour(OsuColour.Gray(opacity), duration, Easing.OutQuint) .FadeTo(storyboardVisible && opacity > 0 ? 1 : 0, duration, Easing.OutQuint); @@ -70,6 +78,9 @@ namespace osu.Game.Screens.Play protected void InitializeStoryboard(bool asyncLoad) { + if (StoryboardContainer == null) + return; + var beatmap = Beatmap.Value; Storyboard = beatmap.Storyboard.CreateDrawable(Beatmap.Value); diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 0c6368c714..a4284efddb 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -88,7 +88,7 @@ namespace osu.Game.Screens.Play { base.OnEntering(last); - Background.FadeTo(0.4f, 250); + ConfigureBackgroundUpdate(); Content.ScaleTo(0.7f); From 4535e09607cda38faad7f4c146819b01de75a593 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Fri, 9 Feb 2018 00:36:31 +0300 Subject: [PATCH 03/18] Add missing license header --- osu.Game/Screens/Play/PlayerBase.cs | 5 ++++- 1 file changed, 4 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/PlayerBase.cs b/osu.Game/Screens/Play/PlayerBase.cs index b725b739c9..5f22645361 100644 --- a/osu.Game/Screens/Play/PlayerBase.cs +++ b/osu.Game/Screens/Play/PlayerBase.cs @@ -1,4 +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.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Configuration; From c57e8785e23a01145b395da7fea09854bdb10f4e Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Thu, 15 Feb 2018 23:57:53 +0300 Subject: [PATCH 04/18] Move all storyboard loading to Player itself --- osu.Game/Screens/Play/Player.cs | 56 +++++++++-- osu.Game/Screens/Play/PlayerBase.cs | 98 ------------------- osu.Game/Screens/Play/PlayerLoader.cs | 10 +- .../Play/ScreenWithBeatmapBackground.cs | 58 +++++++++++ osu.Game/osu.Game.csproj | 2 +- 5 files changed, 118 insertions(+), 106 deletions(-) delete mode 100644 osu.Game/Screens/Play/PlayerBase.cs create mode 100644 osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 8ebee96bae..38525b18b9 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -5,6 +5,8 @@ using System; using System.Linq; using System.Threading.Tasks; using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Audio.Sample; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Cursor; @@ -14,7 +16,7 @@ using osu.Framework.Screens; using osu.Framework.Threading; using osu.Framework.Timing; using osu.Game.Beatmaps; -using osu.Game.Configuration; +using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Online.API; using osu.Game.Rulesets; @@ -23,10 +25,11 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Screens.Play.BreaksOverlay; using osu.Game.Screens.Ranking; +using osu.Game.Storyboards.Drawables; namespace osu.Game.Screens.Play { - public class Player : PlayerBase, IProvideCursor + public class Player : ScreenWithBeatmapBackground, IProvideCursor { public override bool ShowOverlaysOnEnter => false; @@ -53,18 +56,24 @@ namespace osu.Game.Screens.Play private APIAccess api; + private SampleChannel sampleRestart; + private ScoreProcessor scoreProcessor; protected RulesetContainer RulesetContainer; private HUDOverlay hudOverlay; private FailOverlay failOverlay; + private DrawableStoryboard storyboard; + private Container storyboardContainer; + private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; [BackgroundDependencyLoader] - private void load(OsuConfigManager config, APIAccess api) + private void load(AudioManager audio, APIAccess api) { this.api = api; + sampleRestart = audio.Sample.Get(@"Gameplay/restart"); WorkingBeatmap working = Beatmap.Value; Beatmap beatmap; @@ -123,7 +132,7 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { - StoryboardContainer = new Container + storyboardContainer = new Container { RelativeSizeAxes = Axes.Both, Clock = offsetClock, @@ -185,7 +194,7 @@ namespace osu.Game.Screens.Play }; if (ShowStoryboard) - InitializeStoryboard(false); + initializeStoryboard(false); // Bind ScoreProcessor to ourselves scoreProcessor.AllJudged += onCompletion; @@ -206,7 +215,7 @@ namespace osu.Game.Screens.Play public void Restart() { - SampleRestart?.Play(); + sampleRestart?.Play(); ValidForResume = false; RestartRequested?.Invoke(); Exit(); @@ -330,5 +339,40 @@ namespace osu.Game.Screens.Play } protected override bool OnWheel(InputState state) => MouseWheelDisabled.Value && !pauseContainer.IsPaused; + + private void initializeStoryboard(bool asyncLoad) + { + if (storyboardContainer == null) + return; + + var beatmap = Beatmap.Value; + + storyboard = beatmap.Storyboard.CreateDrawable(Beatmap.Value); + storyboard.Masking = true; + + if (asyncLoad) + LoadComponentAsync(storyboard, storyboardContainer.Add); + else + storyboardContainer.Add(storyboard); + } + + protected override void UpdateBackgroundElements() + { + if (!IsCurrentScreen) return; + + base.UpdateBackgroundElements(); + + if (ShowStoryboard && storyboard == null) + initializeStoryboard(true); + + var beatmap = Beatmap.Value; + var storyboardVisible = ShowStoryboard && beatmap.Storyboard.HasDrawable; + + storyboardContainer? + .FadeColour(OsuColour.Gray(Opacity), Duration, Easing.OutQuint) + .FadeTo(storyboardVisible && Opacity > 0 ? 1 : 0, Duration, Easing.OutQuint); + + Background?.FadeTo(!storyboardVisible || beatmap.Background == null ? Opacity : 0, Duration, Easing.OutQuint); + } } } diff --git a/osu.Game/Screens/Play/PlayerBase.cs b/osu.Game/Screens/Play/PlayerBase.cs deleted file mode 100644 index 5f22645361..0000000000 --- a/osu.Game/Screens/Play/PlayerBase.cs +++ /dev/null @@ -1,98 +0,0 @@ -// 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.Audio; -using osu.Framework.Audio.Sample; -using osu.Framework.Configuration; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Configuration; -using osu.Game.Graphics; -using osu.Game.Screens.Backgrounds; -using osu.Game.Storyboards.Drawables; -using OpenTK; - -namespace osu.Game.Screens.Play -{ - public abstract class PlayerBase : OsuScreen - { - protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); - public override bool AllowBeatmapRulesetChange => false; - - #region User Settings - - protected Bindable DimLevel; - protected Bindable BlurLevel; - protected Bindable ShowStoryboard; - protected Bindable MouseWheelDisabled; - protected Bindable UserAudioOffset; - - protected SampleChannel SampleRestart; - - #endregion - - protected DrawableStoryboard Storyboard; - protected Container StoryboardContainer; - - [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuConfigManager config) - { - DimLevel = config.GetBindable(OsuSetting.DimLevel); - BlurLevel = config.GetBindable(OsuSetting.BlurLevel); - ShowStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); - - MouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); - - SampleRestart = audio.Sample.Get(@"Gameplay/restart"); - - UserAudioOffset = config.GetBindable(OsuSetting.AudioOffset); - } - - protected void ConfigureBackgroundUpdate() - { - DimLevel.ValueChanged += _ => UpdateBackgroundElements(); - BlurLevel.ValueChanged += _ => UpdateBackgroundElements(); - ShowStoryboard.ValueChanged += _ => UpdateBackgroundElements(); - UpdateBackgroundElements(); - } - - protected void UpdateBackgroundElements() - { - if (!IsCurrentScreen) return; - - const float duration = 800; - - var opacity = 1 - (float)DimLevel; - - if (ShowStoryboard && Storyboard == null) - InitializeStoryboard(true); - - var beatmap = Beatmap.Value; - var storyboardVisible = ShowStoryboard && beatmap.Storyboard.HasDrawable; - - StoryboardContainer? - .FadeColour(OsuColour.Gray(opacity), duration, Easing.OutQuint) - .FadeTo(storyboardVisible && opacity > 0 ? 1 : 0, duration, Easing.OutQuint); - - (Background as BackgroundScreenBeatmap)?.BlurTo(new Vector2((float)BlurLevel.Value * 25), duration, Easing.OutQuint); - Background?.FadeTo(!storyboardVisible || beatmap.Background == null ? opacity : 0, duration, Easing.OutQuint); - } - - protected void InitializeStoryboard(bool asyncLoad) - { - if (StoryboardContainer == null) - return; - - var beatmap = Beatmap.Value; - - Storyboard = beatmap.Storyboard.CreateDrawable(Beatmap.Value); - Storyboard.Masking = true; - - if (asyncLoad) - LoadComponentAsync(Storyboard, StoryboardContainer.Add); - else - StoryboardContainer.Add(Storyboard); - } - } -} diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index a4284efddb..fa5ed6365f 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -16,7 +16,7 @@ using osu.Game.Screens.Play.PlayerSettings; namespace osu.Game.Screens.Play { - public class PlayerLoader : PlayerBase + public class PlayerLoader : ScreenWithBeatmapBackground { private Player player; @@ -263,5 +263,13 @@ namespace osu.Game.Screens.Play }; } } + + protected override void UpdateBackgroundElements() + { + if (!IsCurrentScreen) return; + + base.UpdateBackgroundElements(); + Background?.FadeTo(Opacity, Duration, Easing.OutQuint); + } } } diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs new file mode 100644 index 0000000000..83346d677c --- /dev/null +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -0,0 +1,58 @@ +// 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.Game.Configuration; +using osu.Game.Screens.Backgrounds; +using OpenTK; + +namespace osu.Game.Screens.Play +{ + public abstract class ScreenWithBeatmapBackground : OsuScreen + { + protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); + public override bool AllowBeatmapRulesetChange => false; + + protected float Duration => 800; + protected float Opacity => 1 - (float)DimLevel; + + #region User Settings + + protected Bindable DimLevel; + protected Bindable BlurLevel; + protected Bindable ShowStoryboard; + protected Bindable MouseWheelDisabled; + protected Bindable UserAudioOffset; + + #endregion + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + DimLevel = config.GetBindable(OsuSetting.DimLevel); + BlurLevel = config.GetBindable(OsuSetting.BlurLevel); + ShowStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); + + MouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); + + UserAudioOffset = config.GetBindable(OsuSetting.AudioOffset); + } + + protected void ConfigureBackgroundUpdate() + { + DimLevel.ValueChanged += _ => UpdateBackgroundElements(); + BlurLevel.ValueChanged += _ => UpdateBackgroundElements(); + ShowStoryboard.ValueChanged += _ => UpdateBackgroundElements(); + UpdateBackgroundElements(); + } + + protected virtual void UpdateBackgroundElements() + { + if (!IsCurrentScreen) return; + + (Background as BackgroundScreenBeatmap)?.BlurTo(new Vector2((float)BlurLevel.Value * 25), Duration, Easing.OutQuint); + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index cc5f5b92da..b9ab6e7c59 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -340,7 +340,7 @@ - + From 9760f30ce97637256b963cac3267c9ef3d8542b5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Feb 2018 12:08:21 +0900 Subject: [PATCH 05/18] Tidy things up to make more sense --- osu.Game/Screens/Play/Player.cs | 9 +++++---- osu.Game/Screens/Play/PlayerLoader.cs | 8 -------- osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs | 9 ++++++--- 3 files changed, 11 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 96ae4c7872..467332dbb9 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -347,7 +347,7 @@ namespace osu.Game.Screens.Play var beatmap = Beatmap.Value; - storyboard = beatmap.Storyboard.CreateDrawable(Beatmap.Value); + storyboard = beatmap.Storyboard.CreateDrawable(); storyboard.Masking = true; if (asyncLoad) @@ -369,10 +369,11 @@ namespace osu.Game.Screens.Play var storyboardVisible = ShowStoryboard && beatmap.Storyboard.HasDrawable; storyboardContainer? - .FadeColour(OsuColour.Gray(Opacity), Duration, Easing.OutQuint) - .FadeTo(storyboardVisible && Opacity > 0 ? 1 : 0, Duration, Easing.OutQuint); + .FadeColour(OsuColour.Gray(BackgroundOpacity), BACKGROUND_FADE_DURATION, Easing.OutQuint) + .FadeTo(storyboardVisible && BackgroundOpacity > 0 ? 1 : 0, BACKGROUND_FADE_DURATION, Easing.OutQuint); - Background?.FadeTo(!storyboardVisible || beatmap.Background == null ? Opacity : 0, Duration, Easing.OutQuint); + if (storyboardVisible && beatmap.Storyboard.ReplacesBackground) + Background?.FadeTo(0, BACKGROUND_FADE_DURATION, Easing.OutQuint); } } } diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index fa5ed6365f..042b4fc744 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -263,13 +263,5 @@ namespace osu.Game.Screens.Play }; } } - - protected override void UpdateBackgroundElements() - { - if (!IsCurrentScreen) return; - - base.UpdateBackgroundElements(); - Background?.FadeTo(Opacity, Duration, Easing.OutQuint); - } } } diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs index 83346d677c..d83f7e087d 100644 --- a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -13,10 +13,12 @@ namespace osu.Game.Screens.Play public abstract class ScreenWithBeatmapBackground : OsuScreen { protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); + public override bool AllowBeatmapRulesetChange => false; - protected float Duration => 800; - protected float Opacity => 1 - (float)DimLevel; + protected const float BACKGROUND_FADE_DURATION = 800; + + protected float BackgroundOpacity => 1 - (float)DimLevel; #region User Settings @@ -52,7 +54,8 @@ namespace osu.Game.Screens.Play { if (!IsCurrentScreen) return; - (Background as BackgroundScreenBeatmap)?.BlurTo(new Vector2((float)BlurLevel.Value * 25), Duration, Easing.OutQuint); + Background?.FadeTo(BackgroundOpacity, BACKGROUND_FADE_DURATION, Easing.OutQuint); + (Background as BackgroundScreenBeatmap)?.BlurTo(new Vector2((float)BlurLevel.Value * 25), BACKGROUND_FADE_DURATION, Easing.OutQuint); } } } From fb724ca8a705ac6f093be9c96c7e2f30c41b5a07 Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 28 Feb 2018 08:32:30 +0530 Subject: [PATCH 06/18] Make song select ensure current beatmap is always playable in the active ruleset. - Add a to TestCasePlaySongSelect testing this scenario --- .../Visual/TestCasePlaySongSelect.cs | 38 ++++++++++++++--- osu.Game/Screens/Select/SongSelect.cs | 41 ++++++++++++++++++- 2 files changed, 72 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 13b2be9fdb..a4086ea2cd 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -10,6 +10,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions; using osu.Framework.MathUtils; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Database; using osu.Game.Rulesets; using osu.Game.Screens.Select; @@ -53,10 +54,14 @@ namespace osu.Game.Tests.Visual public WorkingBeatmap CurrentBeatmap => Beatmap.Value; public WorkingBeatmap CurrentBeatmapDetailsBeatmap => BeatmapDetails.Beatmap; public new BeatmapCarousel Carousel => base.Carousel; + + public void SetRuleset(RulesetInfo ruleset) => Ruleset.Value = ruleset; + + public int? RulesetID => Ruleset.Value.ID; } [BackgroundDependencyLoader] - private void load(OsuGameBase game) + private void load(OsuGameBase game, OsuConfigManager config) { TestSongSelect songSelect = null; @@ -113,6 +118,24 @@ namespace osu.Game.Tests.Visual AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; }); AddStep(@"Sort by Author", delegate { songSelect.FilterControl.Sort = SortMode.Author; }); AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.Sort = SortMode.Difficulty; }); + + AddWaitStep(5); + + AddStep(@"Set unplayable WorkingBeatmap", () => + { + var testMap = manager.GetAllUsableBeatmapSets().First().Beatmaps.First(b => b.RulesetID != 0); + songSelect.SetRuleset(rulesets.AvailableRulesets.First()); + game.Beatmap.Value = manager.GetWorkingBeatmap(testMap); + }); + AddAssert(@"WorkingBeatmap changed to playable ruleset", () => songSelect.RulesetID == 0 && game.Beatmap.Value.BeatmapInfo.RulesetID == 0); + AddStep(@"Disallow beatmap conversion", () => + { + config.GetBindable(OsuSetting.ShowConvertedBeatmaps).Value = false; + game.Beatmap.Value = manager.GetWorkingBeatmap(manager.GetAllUsableBeatmapSets().First().Beatmaps.First()); + }); + loadNewSongSelect(); + AddWaitStep(3); + AddAssert(@"Ruleset matches beatmap", () => songSelect.RulesetID == game.Beatmap.Value.BeatmapInfo.RulesetID); } private BeatmapSetInfo createTestBeatmapSet(int i) @@ -134,7 +157,8 @@ namespace osu.Game.Tests.Visual new BeatmapInfo { OnlineBeatmapID = 1234 + i, - Ruleset = rulesets.AvailableRulesets.First(), + Ruleset = rulesets.AvailableRulesets.ElementAt(0), + RulesetID = 0, Path = "normal.osu", Version = "Normal", BaseDifficulty = new BeatmapDifficulty @@ -145,8 +169,9 @@ namespace osu.Game.Tests.Visual new BeatmapInfo { OnlineBeatmapID = 1235 + i, - Ruleset = rulesets.AvailableRulesets.First(), - Path = "hard.osu", + Ruleset = rulesets.AvailableRulesets.First(r => r.ID != 0), + RulesetID = 1, + Path = "hard.taiko", Version = "Hard", BaseDifficulty = new BeatmapDifficulty { @@ -156,8 +181,9 @@ namespace osu.Game.Tests.Visual new BeatmapInfo { OnlineBeatmapID = 1236 + i, - Ruleset = rulesets.AvailableRulesets.First(), - Path = "insane.osu", + Ruleset = rulesets.AvailableRulesets.ElementAt(2), + RulesetID = 2, + Path = "insane.fruits", Version = "Insane", BaseDifficulty = new BeatmapDifficulty { diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index de6847d866..6e1d95d42e 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Linq; using System.Threading; using OpenTK; using OpenTK.Input; @@ -9,12 +10,14 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; +using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Framework.Screens; using osu.Framework.Threading; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Overlays; @@ -63,6 +66,8 @@ namespace osu.Game.Screens.Select private SampleChannel sampleChangeDifficulty; private SampleChannel sampleChangeBeatmap; + private Bindable rulesetConversionAllowed; + private CancellationTokenSource initialAddSetsTask; private DependencyContainer dependencies; @@ -179,7 +184,7 @@ 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, OsuConfigManager config) { dependencies.CacheAs(this); @@ -194,6 +199,8 @@ namespace osu.Game.Screens.Select if (this.beatmaps == null) this.beatmaps = beatmaps; + rulesetConversionAllowed = config.GetBindable(OsuSetting.ShowConvertedBeatmaps); + if (osu != null) Ruleset.BindTo(osu.Ruleset); @@ -217,7 +224,10 @@ namespace osu.Game.Screens.Select Beatmap.ValueChanged += b => { if (IsCurrentScreen) + { Carousel.SelectBeatmap(b?.BeatmapInfo); + ensurePlayableRuleset(); + } }; } @@ -316,6 +326,7 @@ namespace osu.Game.Screens.Select { base.OnEntering(last); + ensurePlayableRuleset(); Content.FadeInFromZero(250); FilterControl.Activate(); } @@ -441,6 +452,34 @@ namespace osu.Game.Screens.Select } } + private void ensurePlayableRuleset() + { + if (Beatmap.IsDefault) + // DummyBeatmap won't be playable anyway + return; + + bool conversionAllowed = rulesetConversionAllowed.Value; + int? currentRuleset = Ruleset.Value.ID; + int beatmapRuleset = Beatmap.Value.BeatmapInfo.RulesetID; + + if (currentRuleset == beatmapRuleset || conversionAllowed && beatmapRuleset == 0) + // Current beatmap is playable, nothing more to do + return; + + // Otherwise, first check if the current beatmapset has any playable beatmaps + BeatmapInfo beatmap = Beatmap.Value.BeatmapSetInfo.Beatmaps?.FirstOrDefault(b => b.RulesetID == currentRuleset || conversionAllowed && b.RulesetID == 0); + + // If it does then update the WorkingBeatmap + if (beatmap != null) + { + Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap); + return; + } + + // If it doesn't, then update the current ruleset so that the current beatmap is playable + Ruleset.Value = Beatmap.Value.BeatmapInfo.Ruleset; + } + private void onBeatmapSetAdded(BeatmapSetInfo s) => Carousel.UpdateBeatmapSet(s); private void onBeatmapSetRemoved(BeatmapSetInfo s) => Carousel.RemoveBeatmapSet(s); private void onBeatmapRestored(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); From a57dc154f9aa323c6ab367442c417b7bb48363ae Mon Sep 17 00:00:00 2001 From: naoey Date: Sat, 3 Mar 2018 19:54:54 +0530 Subject: [PATCH 07/18] More specific tests. --- .../Visual/TestCasePlaySongSelect.cs | 80 ++++++++++++++++--- osu.Game/Screens/Select/SongSelect.cs | 18 +++-- 2 files changed, 81 insertions(+), 17 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index d895080afe..8532962389 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -60,6 +60,14 @@ namespace osu.Game.Tests.Visual public void SetRuleset(RulesetInfo ruleset) => Ruleset.Value = ruleset; public int? RulesetID => Ruleset.Value.ID; + + protected override void Dispose(bool isDisposing) + { + base.Dispose(isDisposing); + + // Necessary while running tests because gc is moody and uncollected object interferes with OnEntering test + Beatmap.ValueChanged -= WorkingBeatmapChanged; + } } [BackgroundDependencyLoader] @@ -82,6 +90,7 @@ namespace osu.Game.Tests.Visual { if (deleteMaps) { + // TODO: check why this alone doesn't allow import test to run twice in the same session, probably because the delete op is not saved? manager.Delete(manager.GetAllUsableBeatmapSets()); game.Beatmap.SetDefault(); } @@ -93,6 +102,8 @@ namespace osu.Game.Tests.Visual } Add(songSelect = new TestSongSelect()); + + songSelect?.SetRuleset(rulesets.AvailableRulesets.First()); }); loadNewSongSelect(true); @@ -107,6 +118,36 @@ namespace osu.Game.Tests.Visual { for (int i = 0; i < 100; i += 10) manager.Import(createTestBeatmapSet(i)); + + // also import a set which has a single non - osu ruleset beatmap + manager.Import(new BeatmapSetInfo + { + OnlineBeatmapSetID = 1993, + Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), + Metadata = new BeatmapMetadata + { + OnlineBeatmapSetID = 1993, + // 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), + AuthorString = "Some Guy " + RNG.Next(0, 9), + }, + Beatmaps = new List + { + new BeatmapInfo + { + OnlineBeatmapID = 1994, + Ruleset = rulesets.AvailableRulesets.ElementAt(3), + RulesetID = 3, + Path = "normal.fruits", + Version = "Normal", + BaseDifficulty = new BeatmapDifficulty + { + OverallDifficulty = 3.5f, + } + }, + } + }); }); AddWaitStep(3); @@ -121,23 +162,44 @@ namespace osu.Game.Tests.Visual AddStep(@"Sort by Author", delegate { songSelect.FilterControl.Sort = SortMode.Author; }); AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.Sort = SortMode.Difficulty; }); - AddWaitStep(5); + // Test that song select sets a playable beatmap while entering + AddStep(@"Remove song select", () => + { + Remove(songSelect); + songSelect.Dispose(); + songSelect = null; + }); + AddStep(@"Set non-osu beatmap", () => game.Beatmap.Value = manager.GetWorkingBeatmap(manager.GetAllUsableBeatmapSets().First().Beatmaps.First(b => b.RulesetID != 0))); + AddAssert(@"Non-osu beatmap set", () => game.Beatmap.Value.BeatmapInfo.RulesetID != 0); + loadNewSongSelect(); + AddWaitStep(3); + AddAssert(@"osu beatmap set", () => game.Beatmap.Value.BeatmapInfo.RulesetID == 0); - AddStep(@"Set unplayable WorkingBeatmap", () => + // Test that song select changes WorkingBeatmap to be playable in current ruleset when updated externally + AddStep(@"Try set non-osu beatmap", () => { var testMap = manager.GetAllUsableBeatmapSets().First().Beatmaps.First(b => b.RulesetID != 0); songSelect.SetRuleset(rulesets.AvailableRulesets.First()); game.Beatmap.Value = manager.GetWorkingBeatmap(testMap); }); - AddAssert(@"WorkingBeatmap changed to playable ruleset", () => songSelect.RulesetID == 0 && game.Beatmap.Value.BeatmapInfo.RulesetID == 0); - AddStep(@"Disallow beatmap conversion", () => + AddAssert(@"Beatmap changed to osu", () => songSelect.RulesetID == 0 && game.Beatmap.Value.BeatmapInfo.RulesetID == 0); + + // Test that song select updates WorkingBeatmap when ruleset conversion is disabled + AddStep(@"Disable beatmap conversion", () => config.Set(OsuSetting.ShowConvertedBeatmaps, false)); + AddStep(@"Set osu beatmap taiko rs", () => { - config.GetBindable(OsuSetting.ShowConvertedBeatmaps).Value = false; - game.Beatmap.Value = manager.GetWorkingBeatmap(manager.GetAllUsableBeatmapSets().First().Beatmaps.First()); + game.Beatmap.Value = manager.GetWorkingBeatmap(manager.GetAllUsableBeatmapSets().First().Beatmaps.First(b => b.RulesetID == 0)); + songSelect.SetRuleset(rulesets.AvailableRulesets.First(r => r.ID == 1)); }); - loadNewSongSelect(); - AddWaitStep(3); - AddAssert(@"Ruleset matches beatmap", () => songSelect.RulesetID == game.Beatmap.Value.BeatmapInfo.RulesetID); + AddAssert(@"taiko beatmap set", () => songSelect.RulesetID == 1); + + // Test that song select changes the active ruleset when externally set beatmapset has no playable beatmaps + AddStep(@"Set fruits only beatmapset", () => + { + songSelect.SetRuleset(rulesets.AvailableRulesets.First()); + game.Beatmap.Value = manager.GetWorkingBeatmap(manager.QueryBeatmapSet(b => b.OnlineBeatmapSetID == 1993).Beatmaps.First()); + }); + AddAssert(@"Ruleset changed to fruits", () => songSelect.RulesetID == game.Beatmap.Value.BeatmapInfo.RulesetID); } private BeatmapSetInfo createTestBeatmapSet(int i) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 8033f8da8b..d4fd64dcd9 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -221,14 +221,7 @@ namespace osu.Game.Screens.Select Beatmap.DisabledChanged += disabled => Carousel.AllowSelection = !disabled; Beatmap.TriggerChange(); - Beatmap.ValueChanged += b => - { - if (IsCurrentScreen) - { - Carousel.SelectBeatmap(b?.BeatmapInfo); - ensurePlayableRuleset(); - } - }; + Beatmap.ValueChanged += WorkingBeatmapChanged; } public void Edit(BeatmapInfo beatmap) @@ -271,6 +264,15 @@ namespace osu.Game.Screens.Select // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. private BeatmapInfo beatmapNoDebounce; + protected void WorkingBeatmapChanged(WorkingBeatmap beatmap) + { + if (IsCurrentScreen) + { + Carousel.SelectBeatmap(beatmap?.BeatmapInfo); + ensurePlayableRuleset(); + } + } + /// /// selection has been changed as the result of interaction with the carousel. /// From 04f5563238d874c585d4414951300532eb602c8f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 19:37:26 +0900 Subject: [PATCH 08/18] Match HP drain harshness closer to stable Based on number of misses before fail on two arbitrary tests. Obviously not final, just making the game more playable for the time being. --- osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs | 10 ++++++---- 1 file changed, 6 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs index 67b96f1fd9..d41331e3bd 100644 --- a/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs +++ b/osu.Game.Rulesets.Osu/Scoring/OsuScoreProcessor.cs @@ -68,6 +68,8 @@ namespace osu.Game.Rulesets.Osu.Scoring score.Statistics[HitResult.Miss] = scoreResultCounts.GetOrDefault(HitResult.Miss); } + private const double harshness = 0.01; + protected override void OnNewJudgement(Judgement judgement) { base.OnNewJudgement(judgement); @@ -83,15 +85,15 @@ namespace osu.Game.Rulesets.Osu.Scoring switch (judgement.Result) { case HitResult.Great: - Health.Value += (10.2 - hpDrainRate) * 0.02; + Health.Value += (10.2 - hpDrainRate) * harshness; break; case HitResult.Good: - Health.Value += (8 - hpDrainRate) * 0.02; + Health.Value += (8 - hpDrainRate) * harshness; break; case HitResult.Meh: - Health.Value += (4 - hpDrainRate) * 0.02; + Health.Value += (4 - hpDrainRate) * harshness; break; /*case HitResult.SliderTick: @@ -99,7 +101,7 @@ namespace osu.Game.Rulesets.Osu.Scoring break;*/ case HitResult.Miss: - Health.Value -= hpDrainRate * 0.04; + Health.Value -= hpDrainRate * (harshness * 2); break; } } From 70a16667b69b329f901a54f4ef5e8d3a2a5bbc25 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Mar 2018 12:46:23 +0900 Subject: [PATCH 09/18] Fix difficulty calculator regression when applying mods --- osu.Game/Beatmaps/DifficultyCalculator.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Beatmaps/DifficultyCalculator.cs index 798268d05f..39817df6a6 100644 --- a/osu.Game/Beatmaps/DifficultyCalculator.cs +++ b/osu.Game/Beatmaps/DifficultyCalculator.cs @@ -41,12 +41,12 @@ namespace osu.Game.Beatmaps foreach (var mod in Mods.OfType()) mod.ApplyToDifficulty(Beatmap.BeatmapInfo.BaseDifficulty); + foreach (var h in Beatmap.HitObjects) + h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty); + foreach (var mod in mods.OfType>()) foreach (var obj in Beatmap.HitObjects) mod.ApplyToHitObject(obj); - - foreach (var h in Beatmap.HitObjects) - h.ApplyDefaults(Beatmap.ControlPointInfo, Beatmap.BeatmapInfo.BaseDifficulty); } protected virtual void PreprocessHitObjects() From 2cb197d0c452d27139eb3dd6e29d3193c40a6f62 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Thu, 8 Mar 2018 11:35:00 +0300 Subject: [PATCH 10/18] Replace ConfigureBackgroundUpdate with OnEntering --- osu.Game/Screens/Play/Player.cs | 2 -- osu.Game/Screens/Play/PlayerLoader.cs | 2 -- osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs | 4 +++- 3 files changed, 3 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 7ec72a0e0e..9b341fbfe5 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -277,8 +277,6 @@ namespace osu.Game.Screens.Play if (!loadedSuccessfully) return; - ConfigureBackgroundUpdate(); - Content.Alpha = 0; Content .ScaleTo(0.7f) diff --git a/osu.Game/Screens/Play/PlayerLoader.cs b/osu.Game/Screens/Play/PlayerLoader.cs index 042b4fc744..784dcf7657 100644 --- a/osu.Game/Screens/Play/PlayerLoader.cs +++ b/osu.Game/Screens/Play/PlayerLoader.cs @@ -88,8 +88,6 @@ namespace osu.Game.Screens.Play { base.OnEntering(last); - ConfigureBackgroundUpdate(); - Content.ScaleTo(0.7f); contentIn(); diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs index d83f7e087d..9942bf4ef5 100644 --- a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; +using osu.Framework.Screens; using osu.Game.Configuration; using osu.Game.Screens.Backgrounds; using OpenTK; @@ -42,8 +43,9 @@ namespace osu.Game.Screens.Play UserAudioOffset = config.GetBindable(OsuSetting.AudioOffset); } - protected void ConfigureBackgroundUpdate() + protected override void OnEntering(Screen last) { + base.OnEntering(last); DimLevel.ValueChanged += _ => UpdateBackgroundElements(); BlurLevel.ValueChanged += _ => UpdateBackgroundElements(); ShowStoryboard.ValueChanged += _ => UpdateBackgroundElements(); From 6d91889ca641258a9706c932d16d2aa836a8ba80 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Mar 2018 22:16:47 +0900 Subject: [PATCH 11/18] Move player-specific configuration bindables back to player --- osu.Game/Screens/Play/Player.cs | 16 ++++++++++++---- .../Screens/Play/ScreenWithBeatmapBackground.cs | 6 ------ 2 files changed, 12 insertions(+), 10 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 9b341fbfe5..d24ed53518 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -7,6 +7,7 @@ using System.Threading.Tasks; 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.Cursor; @@ -16,6 +17,7 @@ using osu.Framework.Screens; using osu.Framework.Threading; using osu.Framework.Timing; using osu.Game.Beatmaps; +using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Cursor; using osu.Game.Online.API; @@ -43,6 +45,9 @@ namespace osu.Game.Screens.Play public bool AllowLeadIn { get; set; } = true; public bool AllowResults { get; set; } = true; + private Bindable mouseWheelDisabled; + private Bindable userAudioOffset; + public int RestartCount; public CursorContainer Cursor => RulesetContainer.Cursor; @@ -75,11 +80,14 @@ namespace osu.Game.Screens.Play private bool loadedSuccessfully => RulesetContainer?.Objects.Any() == true; [BackgroundDependencyLoader] - private void load(AudioManager audio, APIAccess api) + private void load(AudioManager audio, APIAccess api, OsuConfigManager config) { this.api = api; sampleRestart = audio.Sample.Get(@"Gameplay/restart"); + mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); + userAudioOffset = config.GetBindable(OsuSetting.AudioOffset); + WorkingBeatmap working = Beatmap.Value; Beatmap beatmap; @@ -131,8 +139,8 @@ namespace osu.Game.Screens.Play // the final usable gameplay clock with user-set offsets applied. var offsetClock = new FramedOffsetClock(adjustableClock); - UserAudioOffset.ValueChanged += v => offsetClock.Offset = v; - UserAudioOffset.TriggerChange(); + userAudioOffset.ValueChanged += v => offsetClock.Offset = v; + userAudioOffset.TriggerChange(); scoreProcessor = RulesetContainer.CreateScoreProcessor(); @@ -342,7 +350,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 OnWheel(InputState state) => mouseWheelDisabled.Value && !pauseContainer.IsPaused; private void initializeStoryboard(bool asyncLoad) { diff --git a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs index 9942bf4ef5..8e963a94a8 100644 --- a/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs +++ b/osu.Game/Screens/Play/ScreenWithBeatmapBackground.cs @@ -26,8 +26,6 @@ namespace osu.Game.Screens.Play protected Bindable DimLevel; protected Bindable BlurLevel; protected Bindable ShowStoryboard; - protected Bindable MouseWheelDisabled; - protected Bindable UserAudioOffset; #endregion @@ -37,10 +35,6 @@ namespace osu.Game.Screens.Play DimLevel = config.GetBindable(OsuSetting.DimLevel); BlurLevel = config.GetBindable(OsuSetting.BlurLevel); ShowStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); - - MouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); - - UserAudioOffset = config.GetBindable(OsuSetting.AudioOffset); } protected override void OnEntering(Screen last) From 25fb527cc7bd7f1d1c3a855db9ca2281ee3175a3 Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 9 Mar 2018 15:51:00 +0530 Subject: [PATCH 12/18] Remove previous fix and move filtered logic to carousel. - Add an optional bool parameter to SelectBeatmap to skip selecting filtered maps --- osu.Game/Screens/Select/BeatmapCarousel.cs | 31 +++++++++++++-------- osu.Game/Screens/Select/SongSelect.cs | 32 ---------------------- 2 files changed, 20 insertions(+), 43 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 9793440348..02bad82ca9 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -169,20 +169,29 @@ namespace osu.Game.Screens.Select }); } - public void SelectBeatmap(BeatmapInfo beatmap) + /// + /// Selects a given beatmap on the carousel. + /// + /// The beatmap to select. + /// Whether to skip selecting filtered beatmaps. + /// True if a selection was made, false if it was skipped. + public bool SelectBeatmap(BeatmapInfo beatmap, bool skipFiltered = false) { if (beatmap?.Hidden != false) - return; + return false; - foreach (CarouselBeatmapSet group in beatmapSets) - { - var item = group.Beatmaps.FirstOrDefault(p => p.Beatmap.Equals(beatmap)); - if (item != null) - { - select(item); - return; - } - } + var group = beatmapSets.FirstOrDefault(s => s.BeatmapSet.OnlineBeatmapSetID == beatmap.BeatmapSet.OnlineBeatmapSetID); + + if (group == null || !skipFiltered && group.Filtered) + return false; + + var item = group.Beatmaps.FirstOrDefault(p => p.Beatmap.Equals(beatmap)); + + if (item == null || !skipFiltered && item.Filtered) + return false; + + select(item); + return true; } /// diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index d4fd64dcd9..2c8dcae3cf 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -267,10 +267,7 @@ namespace osu.Game.Screens.Select protected void WorkingBeatmapChanged(WorkingBeatmap beatmap) { if (IsCurrentScreen) - { Carousel.SelectBeatmap(beatmap?.BeatmapInfo); - ensurePlayableRuleset(); - } } /// @@ -328,7 +325,6 @@ namespace osu.Game.Screens.Select { base.OnEntering(last); - ensurePlayableRuleset(); Content.FadeInFromZero(250); FilterControl.Activate(); } @@ -456,34 +452,6 @@ namespace osu.Game.Screens.Select } } - private void ensurePlayableRuleset() - { - if (Beatmap.IsDefault) - // DummyBeatmap won't be playable anyway - return; - - bool conversionAllowed = rulesetConversionAllowed.Value; - int? currentRuleset = Ruleset.Value.ID; - int beatmapRuleset = Beatmap.Value.BeatmapInfo.RulesetID; - - if (currentRuleset == beatmapRuleset || conversionAllowed && beatmapRuleset == 0) - // Current beatmap is playable, nothing more to do - return; - - // Otherwise, first check if the current beatmapset has any playable beatmaps - BeatmapInfo beatmap = Beatmap.Value.BeatmapSetInfo.Beatmaps?.FirstOrDefault(b => b.RulesetID == currentRuleset || conversionAllowed && b.RulesetID == 0); - - // If it does then update the WorkingBeatmap - if (beatmap != null) - { - Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmap); - return; - } - - // If it doesn't, then update the current ruleset so that the current beatmap is playable - Ruleset.Value = Beatmap.Value.BeatmapInfo.Ruleset; - } - private void onBeatmapSetAdded(BeatmapSetInfo s) => Carousel.UpdateBeatmapSet(s); private void onBeatmapSetRemoved(BeatmapSetInfo s) => Carousel.RemoveBeatmapSet(s); private void onBeatmapRestored(BeatmapInfo b) => Carousel.UpdateBeatmapSet(beatmaps.QueryBeatmapSet(s => s.ID == b.BeatmapSetInfoID)); From d04f47718fa73622a6610897357dd3c9de8acdfb Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 9 Mar 2018 16:22:59 +0530 Subject: [PATCH 13/18] Make song select choose random when initial selection fails. - Revert TestCasePlaySongSelect to master --- .../Visual/TestCasePlaySongSelect.cs | 100 ++---------------- osu.Game/Screens/Select/BeatmapCarousel.cs | 32 ++++-- osu.Game/Screens/Select/SongSelect.cs | 25 ++--- 3 files changed, 37 insertions(+), 120 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index 8532962389..cede0160bc 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -11,7 +11,6 @@ using osu.Framework.Allocation; using osu.Framework.Extensions; using osu.Framework.MathUtils; using osu.Game.Beatmaps; -using osu.Game.Configuration; using osu.Game.Database; using osu.Game.Rulesets; using osu.Game.Screens.Select; @@ -56,22 +55,10 @@ namespace osu.Game.Tests.Visual public WorkingBeatmap CurrentBeatmap => Beatmap.Value; public WorkingBeatmap CurrentBeatmapDetailsBeatmap => BeatmapDetails.Beatmap; public new BeatmapCarousel Carousel => base.Carousel; - - public void SetRuleset(RulesetInfo ruleset) => Ruleset.Value = ruleset; - - public int? RulesetID => Ruleset.Value.ID; - - protected override void Dispose(bool isDisposing) - { - base.Dispose(isDisposing); - - // Necessary while running tests because gc is moody and uncollected object interferes with OnEntering test - Beatmap.ValueChanged -= WorkingBeatmapChanged; - } } [BackgroundDependencyLoader] - private void load(OsuGameBase game, OsuConfigManager config) + private void load(OsuGameBase game) { TestSongSelect songSelect = null; @@ -90,7 +77,6 @@ namespace osu.Game.Tests.Visual { if (deleteMaps) { - // TODO: check why this alone doesn't allow import test to run twice in the same session, probably because the delete op is not saved? manager.Delete(manager.GetAllUsableBeatmapSets()); game.Beatmap.SetDefault(); } @@ -102,8 +88,6 @@ namespace osu.Game.Tests.Visual } Add(songSelect = new TestSongSelect()); - - songSelect?.SetRuleset(rulesets.AvailableRulesets.First()); }); loadNewSongSelect(true); @@ -118,36 +102,6 @@ namespace osu.Game.Tests.Visual { for (int i = 0; i < 100; i += 10) manager.Import(createTestBeatmapSet(i)); - - // also import a set which has a single non - osu ruleset beatmap - manager.Import(new BeatmapSetInfo - { - OnlineBeatmapSetID = 1993, - Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), - Metadata = new BeatmapMetadata - { - OnlineBeatmapSetID = 1993, - // 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), - AuthorString = "Some Guy " + RNG.Next(0, 9), - }, - Beatmaps = new List - { - new BeatmapInfo - { - OnlineBeatmapID = 1994, - Ruleset = rulesets.AvailableRulesets.ElementAt(3), - RulesetID = 3, - Path = "normal.fruits", - Version = "Normal", - BaseDifficulty = new BeatmapDifficulty - { - OverallDifficulty = 3.5f, - } - }, - } - }); }); AddWaitStep(3); @@ -161,45 +115,6 @@ namespace osu.Game.Tests.Visual AddStep(@"Sort by Title", delegate { songSelect.FilterControl.Sort = SortMode.Title; }); AddStep(@"Sort by Author", delegate { songSelect.FilterControl.Sort = SortMode.Author; }); AddStep(@"Sort by Difficulty", delegate { songSelect.FilterControl.Sort = SortMode.Difficulty; }); - - // Test that song select sets a playable beatmap while entering - AddStep(@"Remove song select", () => - { - Remove(songSelect); - songSelect.Dispose(); - songSelect = null; - }); - AddStep(@"Set non-osu beatmap", () => game.Beatmap.Value = manager.GetWorkingBeatmap(manager.GetAllUsableBeatmapSets().First().Beatmaps.First(b => b.RulesetID != 0))); - AddAssert(@"Non-osu beatmap set", () => game.Beatmap.Value.BeatmapInfo.RulesetID != 0); - loadNewSongSelect(); - AddWaitStep(3); - AddAssert(@"osu beatmap set", () => game.Beatmap.Value.BeatmapInfo.RulesetID == 0); - - // Test that song select changes WorkingBeatmap to be playable in current ruleset when updated externally - AddStep(@"Try set non-osu beatmap", () => - { - var testMap = manager.GetAllUsableBeatmapSets().First().Beatmaps.First(b => b.RulesetID != 0); - songSelect.SetRuleset(rulesets.AvailableRulesets.First()); - game.Beatmap.Value = manager.GetWorkingBeatmap(testMap); - }); - AddAssert(@"Beatmap changed to osu", () => songSelect.RulesetID == 0 && game.Beatmap.Value.BeatmapInfo.RulesetID == 0); - - // Test that song select updates WorkingBeatmap when ruleset conversion is disabled - AddStep(@"Disable beatmap conversion", () => config.Set(OsuSetting.ShowConvertedBeatmaps, false)); - AddStep(@"Set osu beatmap taiko rs", () => - { - game.Beatmap.Value = manager.GetWorkingBeatmap(manager.GetAllUsableBeatmapSets().First().Beatmaps.First(b => b.RulesetID == 0)); - songSelect.SetRuleset(rulesets.AvailableRulesets.First(r => r.ID == 1)); - }); - AddAssert(@"taiko beatmap set", () => songSelect.RulesetID == 1); - - // Test that song select changes the active ruleset when externally set beatmapset has no playable beatmaps - AddStep(@"Set fruits only beatmapset", () => - { - songSelect.SetRuleset(rulesets.AvailableRulesets.First()); - game.Beatmap.Value = manager.GetWorkingBeatmap(manager.QueryBeatmapSet(b => b.OnlineBeatmapSetID == 1993).Beatmaps.First()); - }); - AddAssert(@"Ruleset changed to fruits", () => songSelect.RulesetID == game.Beatmap.Value.BeatmapInfo.RulesetID); } private BeatmapSetInfo createTestBeatmapSet(int i) @@ -221,8 +136,7 @@ namespace osu.Game.Tests.Visual new BeatmapInfo { OnlineBeatmapID = 1234 + i, - Ruleset = rulesets.AvailableRulesets.ElementAt(0), - RulesetID = 0, + Ruleset = rulesets.AvailableRulesets.First(), Path = "normal.osu", Version = "Normal", BaseDifficulty = new BeatmapDifficulty @@ -233,9 +147,8 @@ namespace osu.Game.Tests.Visual new BeatmapInfo { OnlineBeatmapID = 1235 + i, - Ruleset = rulesets.AvailableRulesets.First(r => r.ID != 0), - RulesetID = 1, - Path = "hard.taiko", + Ruleset = rulesets.AvailableRulesets.First(), + Path = "hard.osu", Version = "Hard", BaseDifficulty = new BeatmapDifficulty { @@ -245,9 +158,8 @@ namespace osu.Game.Tests.Visual new BeatmapInfo { OnlineBeatmapID = 1236 + i, - Ruleset = rulesets.AvailableRulesets.ElementAt(2), - RulesetID = 2, - Path = "insane.fruits", + Ruleset = rulesets.AvailableRulesets.First(), + Path = "insane.osu", Version = "Insane", BaseDifficulty = new BeatmapDifficulty { diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 02bad82ca9..287584bf2f 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -171,27 +171,41 @@ namespace osu.Game.Screens.Select /// /// Selects a given beatmap on the carousel. + /// + /// If skipFiltered is true, we will try to select another unfiltered beatmap in the same set. If the + /// entire set is filtered, no selection is made. /// /// The beatmap to select. /// Whether to skip selecting filtered beatmaps. - /// True if a selection was made, false if it was skipped. + /// True if a selection was made, False if it wasn't. public bool SelectBeatmap(BeatmapInfo beatmap, bool skipFiltered = false) { if (beatmap?.Hidden != false) return false; - var group = beatmapSets.FirstOrDefault(s => s.BeatmapSet.OnlineBeatmapSetID == beatmap.BeatmapSet.OnlineBeatmapSetID); + foreach (CarouselBeatmapSet set in beatmapSets) + { + if (skipFiltered && set.Filtered) + continue; - if (group == null || !skipFiltered && group.Filtered) - return false; + var item = set.Beatmaps.FirstOrDefault(p => p.Beatmap.Equals(beatmap)); - var item = group.Beatmaps.FirstOrDefault(p => p.Beatmap.Equals(beatmap)); + if (item == null) + // The beatmap that needs to be selected doesn't exist in this set + continue; - if (item == null || !skipFiltered && item.Filtered) - return false; + if (skipFiltered && item.Filtered) + // The beatmap exists in this set but is filtered, so look for the first unfiltered map in the set + item = set.Beatmaps.FirstOrDefault(b => !b.Filtered); - select(item); - return true; + if (item != null) + { + select(item); + return true; + } + } + + return false; } /// diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 2c8dcae3cf..461b17338d 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Linq; using System.Threading; using OpenTK; using OpenTK.Input; @@ -10,14 +9,12 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Audio.Track; -using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Input; using osu.Framework.Screens; using osu.Framework.Threading; using osu.Game.Beatmaps; -using osu.Game.Configuration; using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Overlays; @@ -66,8 +63,6 @@ namespace osu.Game.Screens.Select private SampleChannel sampleChangeDifficulty; private SampleChannel sampleChangeBeatmap; - private Bindable rulesetConversionAllowed; - private CancellationTokenSource initialAddSetsTask; private DependencyContainer dependencies; @@ -184,7 +179,7 @@ namespace osu.Game.Screens.Select } [BackgroundDependencyLoader(permitNulls: true)] - private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours, OsuConfigManager config) + private void load(BeatmapManager beatmaps, AudioManager audio, DialogOverlay dialog, OsuGame osu, OsuColour colours) { dependencies.CacheAs(this); @@ -199,8 +194,6 @@ namespace osu.Game.Screens.Select if (this.beatmaps == null) this.beatmaps = beatmaps; - rulesetConversionAllowed = config.GetBindable(OsuSetting.ShowConvertedBeatmaps); - if (osu != null) Ruleset.BindTo(osu.Ruleset); @@ -459,16 +452,14 @@ namespace osu.Game.Screens.Select private void carouselBeatmapsLoaded() { - if (!Beatmap.IsDefault && Beatmap.Value.BeatmapSetInfo?.DeletePending == false && Beatmap.Value.BeatmapSetInfo?.Protected == false) + if (!Beatmap.IsDefault && Beatmap.Value.BeatmapSetInfo?.DeletePending == false && Beatmap.Value.BeatmapSetInfo?.Protected == false && Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo, true)) + return; + + if (Carousel.SelectedBeatmapSet == null && !Carousel.SelectNextRandom()) { - Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo); - } - else if (Carousel.SelectedBeatmapSet == null) - { - if (!Carousel.SelectNextRandom()) - // in the case random selection failed, we want to trigger selectionChanged - // to show the dummy beatmap (we have nothing else to display). - carouselSelectionChanged(null); + // in the case random selection failed, we want to trigger selectionChanged + // to show the dummy beatmap (we have nothing else to display). + carouselSelectionChanged(null); } } From 2b0309b26d905a2c5a1448d6bdf4f74863374e15 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 9 Mar 2018 21:29:13 +0900 Subject: [PATCH 14/18] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 6372fb22c1..214035c3d4 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 6372fb22c1c85f600921a139849b8dedf71026d5 +Subproject commit 214035c3d4974a9507fef8670000cef8326f1f5e From 2c0488b1f17ac169632cc6e575318ddfd9d360e6 Mon Sep 17 00:00:00 2001 From: naoey Date: Fri, 9 Mar 2018 19:39:28 +0530 Subject: [PATCH 15/18] Invert bool, add test, and handle ruleset change. --- .../Visual/TestCaseBeatmapCarousel.cs | 42 ++++++++++++++++++- osu.Game/Screens/Select/BeatmapCarousel.cs | 10 ++--- osu.Game/Screens/Select/SongSelect.cs | 11 +++-- 3 files changed, 54 insertions(+), 9 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs index fe26366362..c68e548f44 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs @@ -12,6 +12,7 @@ using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Configuration; +using osu.Game.Rulesets; using osu.Game.Screens.Select; using osu.Game.Screens.Select.Carousel; using osu.Game.Screens.Select.Filter; @@ -22,6 +23,7 @@ namespace osu.Game.Tests.Visual public class TestCaseBeatmapCarousel : OsuTestCase { private TestBeatmapCarousel carousel; + private RulesetStore rulesets; public override IReadOnlyList RequiredTypes => new[] { @@ -46,8 +48,10 @@ namespace osu.Game.Tests.Visual private const int set_count = 5; [BackgroundDependencyLoader] - private void load() + private void load(RulesetStore rulesets) { + this.rulesets = rulesets; + Add(carousel = new TestBeatmapCarousel { RelativeSizeAxes = Axes.Both, @@ -75,6 +79,7 @@ namespace osu.Game.Tests.Visual testRemoveAll(); testEmptyTraversal(); testHiding(); + testSelectingFilteredRuleset(); } private void ensureRandomFetchSuccess() => @@ -363,6 +368,41 @@ namespace osu.Game.Tests.Visual } } + private void testSelectingFilteredRuleset() + { + var testMixed = createTestBeatmapSet(set_count + 1); + AddStep("add mixed ruleset beatmapset", () => + { + for (int i = 0; i <= 2; i++) + { + testMixed.Beatmaps[i].Ruleset = rulesets.AvailableRulesets.ElementAt(i); + testMixed.Beatmaps[i].RulesetID = i; + } + + carousel.UpdateBeatmapSet(testMixed); + }); + AddStep("filter to ruleset 0", () => + carousel.Filter(new FilterCriteria { Ruleset = rulesets.AvailableRulesets.ElementAt(0) }, false)); + AddStep("select filtered map skipping filtered", () => carousel.SelectBeatmap(testMixed.Beatmaps[1], false)); + AddAssert("unfiltered beatmap selected", () => carousel.SelectedBeatmap.Equals(testMixed.Beatmaps[0])); + + AddStep("remove mixed set", () => + { + carousel.RemoveBeatmapSet(testMixed); + testMixed = null; + }); + var testSingle = createTestBeatmapSet(set_count + 2); + testSingle.Beatmaps.ForEach(b => + { + b.Ruleset = rulesets.AvailableRulesets.ElementAt(1); + b.RulesetID = b.Ruleset.ID ?? 1; + }); + AddStep("add single ruleset beatmapset", () => carousel.UpdateBeatmapSet(testSingle)); + AddStep("select filtered map skipping filtered", () => carousel.SelectBeatmap(testSingle.Beatmaps[0], false)); + checkNoSelection(); + AddStep("remove single ruleset set", () => carousel.RemoveBeatmapSet(testSingle)); + } + private BeatmapSetInfo createTestBeatmapSet(int id) { return new BeatmapSetInfo diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 287584bf2f..c2bb155753 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -172,20 +172,20 @@ namespace osu.Game.Screens.Select /// /// Selects a given beatmap on the carousel. /// - /// If skipFiltered is true, we will try to select another unfiltered beatmap in the same set. If the + /// If bypassFilters is false, we will try to select another unfiltered beatmap in the same set. If the /// entire set is filtered, no selection is made. /// /// The beatmap to select. - /// Whether to skip selecting filtered beatmaps. + /// Whether to select the beatmap even if it is filtered (i.e., not visible on carousel). /// True if a selection was made, False if it wasn't. - public bool SelectBeatmap(BeatmapInfo beatmap, bool skipFiltered = false) + public bool SelectBeatmap(BeatmapInfo beatmap, bool bypassFilters = true) { if (beatmap?.Hidden != false) return false; foreach (CarouselBeatmapSet set in beatmapSets) { - if (skipFiltered && set.Filtered) + if (!bypassFilters && set.Filtered) continue; var item = set.Beatmaps.FirstOrDefault(p => p.Beatmap.Equals(beatmap)); @@ -194,7 +194,7 @@ namespace osu.Game.Screens.Select // The beatmap that needs to be selected doesn't exist in this set continue; - if (skipFiltered && item.Filtered) + if (!bypassFilters && item.Filtered) // The beatmap exists in this set but is filtered, so look for the first unfiltered map in the set item = set.Beatmaps.FirstOrDefault(b => !b.Filtered); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 461b17338d..b12ab69edd 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -259,8 +259,13 @@ namespace osu.Game.Screens.Select protected void WorkingBeatmapChanged(WorkingBeatmap beatmap) { - if (IsCurrentScreen) - Carousel.SelectBeatmap(beatmap?.BeatmapInfo); + if (IsCurrentScreen && !Carousel.SelectBeatmap(beatmap?.BeatmapInfo, false)) + // If selecting new beatmap without bypassing filters failed, there's possibly a ruleset mismatch + if (beatmap?.BeatmapInfo?.Ruleset != null && beatmap.BeatmapInfo.Ruleset != Ruleset.Value) + { + Ruleset.Value = beatmap.BeatmapInfo.Ruleset; + Carousel.SelectBeatmap(beatmap.BeatmapInfo); + } } /// @@ -452,7 +457,7 @@ namespace osu.Game.Screens.Select private void carouselBeatmapsLoaded() { - if (!Beatmap.IsDefault && Beatmap.Value.BeatmapSetInfo?.DeletePending == false && Beatmap.Value.BeatmapSetInfo?.Protected == false && Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo, true)) + if (!Beatmap.IsDefault && Beatmap.Value.BeatmapSetInfo?.DeletePending == false && Beatmap.Value.BeatmapSetInfo?.Protected == false && Carousel.SelectBeatmap(Beatmap.Value.BeatmapInfo, false)) return; if (Carousel.SelectedBeatmapSet == null && !Carousel.SelectNextRandom()) From 7cabc54f646094964bc8220e6d7cd094cf37cfaf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 10 Mar 2018 00:48:48 +0900 Subject: [PATCH 16/18] Fix major regression (framework revert) --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 214035c3d4..6915954abd 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 214035c3d4974a9507fef8670000cef8326f1f5e +Subproject commit 6915954abdba64e72f698aa58698b00159f3678d From 8ed5fce43a46b3c0f97fb939e6c24c371b2740dd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 10 Mar 2018 01:11:56 +0900 Subject: [PATCH 17/18] Split out the slider head into a separate drawable hitobject --- .../Objects/Drawables/DrawableSlider.cs | 9 ++---- .../Objects/Drawables/DrawableSliderHead.cs | 32 +++++++++++++++++++ .../Objects/Drawables/DrawableSliderTail.cs | 4 ++- .../osu.Game.Rulesets.Osu.csproj | 1 + 4 files changed, 38 insertions(+), 8 deletions(-) create mode 100644 osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index f715ed075c..5b9ed4d259 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -12,7 +12,6 @@ using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Osu.Judgements; using osu.Framework.Graphics.Primitives; using osu.Game.Configuration; -using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Osu.Objects.Drawables @@ -55,8 +54,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables AlwaysPresent = true, Alpha = 0 }, - HeadCircle = new DrawableHitCircle(s.HeadCircle) { Position = s.TailCircle.Position - s.Position }, - TailCircle = new DrawableSliderTail(s.TailCircle) { Position = s.TailCircle.Position - s.Position } + HeadCircle = new DrawableSliderHead(s, s.HeadCircle), + TailCircle = new DrawableSliderTail(s, s.TailCircle) }; components.Add(Body); @@ -103,10 +102,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables double completionProgress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1); - //todo: we probably want to reconsider this before adding scoring, but it looks and feels nice. - if (!HeadCircle.IsHit) - HeadCircle.Position = slider.CurvePositionAt(completionProgress); - foreach (var c in components.OfType()) c.UpdateProgress(completionProgress); foreach (var c in components.OfType()) c.UpdateSnakingPosition(slider.Curve.PositionAt(Body.SnakedStart ?? 0), slider.Curve.PositionAt(Body.SnakedEnd ?? 0)); foreach (var t in components.OfType()) t.Tracking = Ball.Tracking; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs new file mode 100644 index 0000000000..cf36d5fc14 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderHead.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Objects.Types; +using OpenTK; + +namespace osu.Game.Rulesets.Osu.Objects.Drawables +{ + public class DrawableSliderHead : DrawableHitCircle + { + private readonly Slider slider; + + public DrawableSliderHead(Slider slider, HitCircle h) + : base(h) + { + this.slider = slider; + + Position = HitObject.Position - slider.Position; + } + + protected override void Update() + { + base.Update(); + + double completionProgress = MathHelper.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1); + + //todo: we probably want to reconsider this before adding scoring, but it looks and feels nice. + if (!IsHit) + Position = slider.CurvePositionAt(completionProgress); + } + } +} diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs index b907aea8c3..b277e7df7a 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables public bool Tracking { get; set; } - public DrawableSliderTail(HitCircle hitCircle) + public DrawableSliderTail(Slider slider, HitCircle hitCircle) : base(hitCircle) { Origin = Anchor.Centre; @@ -25,6 +25,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables FillMode = FillMode.Fit; AlwaysPresent = true; + + Position = HitObject.Position - slider.Position; } protected override void CheckForJudgements(bool userTriggered, double timeOffset) diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index 8e8a01b009..92cac71ad3 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -87,6 +87,7 @@ + From db2a663234aea7180f577a807fb879c00f4d4908 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 11 Mar 2018 01:26:03 +0900 Subject: [PATCH 18/18] Use private instead of protected --- osu.Game/Screens/Select/SongSelect.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index b12ab69edd..ca8a1cae41 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -214,7 +214,7 @@ namespace osu.Game.Screens.Select Beatmap.DisabledChanged += disabled => Carousel.AllowSelection = !disabled; Beatmap.TriggerChange(); - Beatmap.ValueChanged += WorkingBeatmapChanged; + Beatmap.ValueChanged += workingBeatmapChanged; } public void Edit(BeatmapInfo beatmap) @@ -257,7 +257,7 @@ namespace osu.Game.Screens.Select // We need to keep track of the last selected beatmap ignoring debounce to play the correct selection sounds. private BeatmapInfo beatmapNoDebounce; - protected void WorkingBeatmapChanged(WorkingBeatmap beatmap) + private void workingBeatmapChanged(WorkingBeatmap beatmap) { if (IsCurrentScreen && !Carousel.SelectBeatmap(beatmap?.BeatmapInfo, false)) // If selecting new beatmap without bypassing filters failed, there's possibly a ruleset mismatch