From d437c1d7ec386e8ca72ab8ffb6f5e3a6f143e463 Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Thu, 8 Feb 2018 23:28:42 +0300 Subject: [PATCH 01/67] 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/67] =?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/67] 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/67] 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/67] 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 e3a1b07172ec3253b1de7af5e450bcdfc48976c2 Mon Sep 17 00:00:00 2001 From: naoey Date: Sun, 25 Feb 2018 19:18:39 +0530 Subject: [PATCH 06/67] Create API request and reponse model. --- .../GetUserRecentActivitiesRequest.cs | 89 +++++++++++++++++++ .../PaginatedRecentActivityContainer.cs | 63 +++++++++++++ .../Profile/Sections/RecentSection.cs | 10 ++- osu.Game/Overlays/UserProfileOverlay.cs | 2 +- osu.Game/osu.Game.csproj | 4 +- 5 files changed, 165 insertions(+), 3 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs create mode 100644 osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs new file mode 100644 index 0000000000..cb7d0323f4 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -0,0 +1,89 @@ +using Newtonsoft.Json; +using osu.Game.Rulesets.Scoring; +using Humanizer; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +using osu.Game.Rulesets; +using osu.Game.Overlays.Profile.Sections.Recent; + +namespace osu.Game.Online.API.Requests +{ + public class GetUserRecentActivitiesRequest : APIRequest> + { + } + + public class RecentActivity + { + [JsonProperty("id")] + public int ID; + + [JsonProperty("created_at")] + 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("mode")] + public string Mode; + + [JsonProperty("beatmap")] + public RecentActivityBeatmap Beatmap; + + [JsonProperty("user")] + public RecentActivityUser User; + + 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; + } + } + + public enum RecentActivityType + { + Achievement, + BeatmapPlaycount, + BeatmapsetApprove, + BeatmapsetDelete, + BeatmapsetRevive, + BeatmapsetUpdate, + Medal, + Rank, + RankLost, + UserSupportAgain, + UserSupportFirst, + UserSupportGift, + UsernameChange, + } +} diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs new file mode 100644 index 0000000000..11b48ad68e --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -0,0 +1,63 @@ +using osu.Framework.Configuration; +using osu.Game.Online.API.Requests; +using osu.Game.Users; +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; + +namespace osu.Game.Overlays.Profile.Sections +{ + class PaginatedRecentActivityContainer : PaginatedContainer + { + public PaginatedRecentActivityContainer(Bindable user, string header, string missing) + : base(user, header, missing) + { + ItemsPerPage = 5; + } + + //protected override void ShowMore() + //{ + // base.ShowMore(); + + // var req = new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++ * ItemsPerPage); + + // req.Success += scores => + // { + // foreach (var s in scores) + // s.ApplyRuleset(Rulesets.GetRuleset(s.OnlineRulesetID)); + + // ShowMoreButton.FadeTo(scores.Count == ItemsPerPage ? 1 : 0); + // ShowMoreLoading.Hide(); + + // if (!scores.Any() && VisiblePages == 1) + // { + // MissingText.Show(); + // return; + // } + + // MissingText.Hide(); + + // foreach (OnlineScore score in scores) + // { + // DrawableProfileScore drawableScore; + + // switch (type) + // { + // default: + // drawableScore = new DrawablePerformanceScore(score, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null); + // break; + // case ScoreType.Recent: + // drawableScore = new DrawableTotalScore(score); + // break; + // } + + // ItemsContainer.Add(drawableScore); + // } + // }; + + // Api.Queue(req); + //} + } +} diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index 78b139efe8..757e2457d2 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -7,6 +7,14 @@ namespace osu.Game.Overlays.Profile.Sections { public override string Title => "Recent"; - public override string Identifier => "recent_activities"; + public override string Identifier => "recent_activity"; + + public RecentSection() + { + Children = new[] + { + new PaginatedRecentActivityContainer(User, @"Recent", @"This user hasn't done anything notable recently!"), + }; + } } } diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 59f940a19d..3bc12ccb24 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -82,7 +82,7 @@ namespace osu.Game.Overlays sections = new ProfileSection[] { //new AboutSection(), - //new RecentSection(), + new RecentSection(), new RanksSection(), //new MedalsSection(), new HistoricalSection(), diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6a06bf540b..ad9105f1e8 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -293,12 +293,14 @@ + 20180125143340_Settings.cs + @@ -936,4 +938,4 @@ - + \ No newline at end of file From 7e4bd363916f6c85b18b94807c3b83981c7f323f Mon Sep 17 00:00:00 2001 From: naoey Date: Sun, 25 Feb 2018 22:41:47 +0530 Subject: [PATCH 07/67] Create drawable and add response to profile. - Add missing JSON fields to response model - Add missing enum value --- .../GetUserRecentActivitiesRequest.cs | 21 +++- .../Sections/Recent/DrawableRecentActivity.cs | 117 ++++++++++++++++++ .../PaginatedRecentActivityContainer.cs | 59 ++++----- osu.Game/osu.Game.csproj | 1 + 4 files changed, 161 insertions(+), 37 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index cb7d0323f4..14997b070b 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -7,12 +7,21 @@ using System.Linq; using System.Text; using System.Threading.Tasks; using osu.Game.Rulesets; -using osu.Game.Overlays.Profile.Sections.Recent; namespace osu.Game.Online.API.Requests { public class GetUserRecentActivitiesRequest : APIRequest> { + private readonly long userId; + private readonly int offset; + + public GetUserRecentActivitiesRequest(long userId, int offset = 0) + { + this.userId = userId; + this.offset = offset; + } + + protected override string Target => $"users/{userId}/recent_activity?offset={offset}"; } public class RecentActivity @@ -42,6 +51,9 @@ namespace osu.Game.Online.API.Requests [JsonProperty("rank")] public int Rank; + [JsonProperty("count")] + public int Count; + [JsonProperty("mode")] public string Mode; @@ -51,6 +63,9 @@ namespace osu.Game.Online.API.Requests [JsonProperty("user")] public RecentActivityUser User; + [JsonProperty("achivementName")] + public string AchivementName; + public class RecentActivityBeatmap { [JsonProperty("title")] @@ -67,6 +82,9 @@ namespace osu.Game.Online.API.Requests [JsonProperty("url")] public string Url; + + [JsonProperty("previousUsername")] + public string PreviousUsername; } } @@ -78,6 +96,7 @@ namespace osu.Game.Online.API.Requests BeatmapsetDelete, BeatmapsetRevive, BeatmapsetUpdate, + BeatmapsetUpload, Medal, Rank, RankLost, diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs new file mode 100644 index 0000000000..e0f7a97140 --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -0,0 +1,117 @@ +using System; +using System.Collections.Generic; +using System.Linq; +using System.Text; +using System.Threading.Tasks; +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.Online.API.Requests; +using osu.Game.Screens.Select.Leaderboards; +using osu.Game.Users; + +namespace osu.Game.Overlays.Profile.Sections.Recent +{ + public class DrawableRecentActivity : DrawableProfileRow + { + private RecentActivity activity; + private User user; + + public DrawableRecentActivity(RecentActivity activity, User user) + { + this.activity = activity; + this.user = user; + } + + [BackgroundDependencyLoader] + private void load() + { + LeftFlowContainer.Add(new OsuSpriteText + { + Text = activityToString(), + }); + + RightFlowContainer.Add(new OsuSpriteText + { + Text = activity.CreatedAt.LocalDateTime.ToShortDateString(), + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + Font = "Exo2.0-RegularItalic", + TextSize = 12, + Colour = OsuColour.Gray(0xAA), + }); + } + + protected override Drawable CreateLeftVisual() + { + switch (activity.Type) + { + case RecentActivityType.Rank: + return new DrawableRank(activity.ScoreRank) + { + RelativeSizeAxes = Axes.Y, + Width = 60, + FillMode = FillMode.Fit, + }; + + default: + return new Container + { + RelativeSizeAxes = Axes.Y, + Width = 60, + FillMode = FillMode.Fit, + }; + } + } + + private string activityToString() + { + switch (activity.Type) + { + case RecentActivityType.Achievement: + return $"{activity.User.Username} unlocked the {activity.AchivementName} achievement!"; + + case RecentActivityType.BeatmapPlaycount: + return $"{activity.Beatmap.Title} has been played {activity.Count} times!"; + + case RecentActivityType.BeatmapsetDelete: + return $"{activity.Beatmap.Title} has been deleted."; + + case RecentActivityType.BeatmapsetRevive: + return $"{activity.Beatmap.Title} has been revived from eternal slumber by ${activity.User.Username}"; + + case RecentActivityType.BeatmapsetUpdate: + return $"{activity.User.Username} has updated the beatmap ${activity.Beatmap.Title}"; + + case RecentActivityType.BeatmapsetUpload: + return $"{activity.User.Username} has submitted a new beatmap ${activity.Beatmap.Title}"; + + case RecentActivityType.Medal: + return $"{activity.User.Username} has unlocked the {activity.AchivementName} medal!"; + + case RecentActivityType.Rank: + return $"{activity.User.Username} achieved rank #{activity.Rank} on {activity.Beatmap?.Title}"; + + case RecentActivityType.RankLost: + return $"{activity.User.Username} has lost first place on {activity.Beatmap.Title}!"; + + case RecentActivityType.UserSupportAgain: + return $"{activity.User.Username} has once again chosen to support osu! - thanks for your generosity!"; + + case RecentActivityType.UserSupportFirst: + return $"{activity.User.Username} has become an osu! supporter - thanks for your generosity!"; + + case RecentActivityType.UsernameChange: + return $"{activity.User.PreviousUsername} has changed their username to {activity.User.Username}"; + + case RecentActivityType.UserSupportGift: + return $"{activity.User.Username} has received the gift of osu! supporter!"; + + default: + return string.Empty; + } + } + } +} diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 11b48ad68e..307c06b744 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -1,5 +1,7 @@ using osu.Framework.Configuration; +using osu.Framework.Graphics; using osu.Game.Online.API.Requests; +using osu.Game.Overlays.Profile.Sections.Recent; using osu.Game.Users; using System; using System.Collections.Generic; @@ -17,47 +19,32 @@ namespace osu.Game.Overlays.Profile.Sections ItemsPerPage = 5; } - //protected override void ShowMore() - //{ - // base.ShowMore(); + protected override void ShowMore() + { + base.ShowMore(); - // var req = new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++ * ItemsPerPage); + var req = new GetUserRecentActivitiesRequest(User.Value.Id, VisiblePages++ * ItemsPerPage); - // req.Success += scores => - // { - // foreach (var s in scores) - // s.ApplyRuleset(Rulesets.GetRuleset(s.OnlineRulesetID)); + req.Success += activities => + { + ShowMoreButton.FadeTo(activities.Count == ItemsPerPage ? 1 : 0); + ShowMoreLoading.Hide(); - // ShowMoreButton.FadeTo(scores.Count == ItemsPerPage ? 1 : 0); - // ShowMoreLoading.Hide(); + if (!activities.Any() && VisiblePages == 1) + { + MissingText.Show(); + return; + } - // if (!scores.Any() && VisiblePages == 1) - // { - // MissingText.Show(); - // return; - // } + MissingText.Hide(); - // MissingText.Hide(); + foreach (RecentActivity activity in activities) + { + ItemsContainer.Add(new DrawableRecentActivity(activity, User)); + } + }; - // foreach (OnlineScore score in scores) - // { - // DrawableProfileScore drawableScore; - - // switch (type) - // { - // default: - // drawableScore = new DrawablePerformanceScore(score, includeWeight ? Math.Pow(0.95, ItemsContainer.Count) : (double?)null); - // break; - // case ScoreType.Recent: - // drawableScore = new DrawableTotalScore(score); - // break; - // } - - // ItemsContainer.Add(drawableScore); - // } - // }; - - // Api.Queue(req); - //} + Api.Queue(req); + } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index ad9105f1e8..cd40b42365 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -300,6 +300,7 @@ 20180125143340_Settings.cs + From bb40919f9ce2e8948ac73548cd075ac3024ce1d3 Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 00:36:55 +0530 Subject: [PATCH 08/67] Add link handling to recent activities. - Add a show user action to link handling --- .../Graphics/Containers/LinkFlowContainer.cs | 7 ++- osu.Game/Online/Chat/MessageFormatter.cs | 15 ++++++ .../Sections/Recent/DrawableRecentActivity.cs | 54 +++++++++++++------ osu.Game/Overlays/UserProfileOverlay.cs | 5 ++ 4 files changed, 64 insertions(+), 17 deletions(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 9f1b44af44..8edae7a976 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -23,14 +23,16 @@ namespace osu.Game.Graphics.Containers public override bool HandleMouseInput => true; private OsuGame game; + private UserProfileOverlay userProfile; private Action showNotImplementedError; [BackgroundDependencyLoader(true)] - private void load(OsuGame game, NotificationOverlay notifications) + private void load(OsuGame game, NotificationOverlay notifications, UserProfileOverlay userProfile) { // will be null in tests this.game = game; + this.userProfile = userProfile; showNotImplementedError = () => notifications?.Post(new SimpleNotification { @@ -90,6 +92,9 @@ namespace osu.Game.Graphics.Containers case LinkAction.External: Process.Start(url); break; + case LinkAction.OpenUserProfile: + userProfile?.ShowUser(Convert.ToInt64(linkArgument)); + break; default: throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action."); } diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 906f42d50e..3fdce3ec12 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -118,6 +118,8 @@ namespace osu.Game.Online.Chat case "beatmapsets": case "d": return new LinkDetails(LinkAction.OpenBeatmapSet, args[3]); + case "u": + return new LinkDetails(LinkAction.OpenUserProfile, args[3]); } } @@ -146,6 +148,9 @@ namespace osu.Game.Online.Chat case "spectate": linkType = LinkAction.Spectate; break; + case "u": + linkType = LinkAction.OpenUserProfile; + break; default: linkType = LinkAction.External; break; @@ -205,6 +210,15 @@ namespace osu.Game.Online.Chat return inputMessage; } + public static List GetLinks(string text) + { + var result = format(text); + + result.Links.Sort(); + + return result.Links; + } + public class MessageFormatterResult { public List Links = new List(); @@ -239,6 +253,7 @@ namespace osu.Game.Online.Chat OpenEditorTimestamp, JoinMultiplayerMatch, Spectate, + OpenUserProfile, } public class Link : IComparable diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index e0f7a97140..6abf68e3e9 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -7,10 +7,14 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; +using osu.Game.Graphics.Containers; using osu.Game.Graphics.Sprites; +using osu.Game.Online.API; using osu.Game.Online.API.Requests; +using osu.Game.Online.Chat; using osu.Game.Screens.Select.Leaderboards; using osu.Game.Users; +using static osu.Game.Online.API.Requests.RecentActivity; namespace osu.Game.Overlays.Profile.Sections.Recent { @@ -18,19 +22,31 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { private RecentActivity activity; private User user; + private APIAccess api; + + private string userLinkTemplate; + private string beatmapLinkTemplate; + + private LinkFlowContainer content; public DrawableRecentActivity(RecentActivity activity, User user) { this.activity = activity; this.user = user; + + userLinkTemplate = $"[{activity.User?.Username}]({urlToAbsolute(activity.User?.Url)})"; + beatmapLinkTemplate = $"[{activity.Beatmap?.Title}]({urlToAbsolute(activity.Beatmap?.Url)})"; } [BackgroundDependencyLoader] - private void load() + private void load(APIAccess api) { - LeftFlowContainer.Add(new OsuSpriteText + this.api = api; + + LeftFlowContainer.Add(content = new LinkFlowContainer { - Text = activityToString(), + AutoSizeAxes = Axes.Y, + RelativeSizeAxes = Axes.X, }); RightFlowContainer.Add(new OsuSpriteText @@ -42,6 +58,10 @@ namespace osu.Game.Overlays.Profile.Sections.Recent TextSize = 12, Colour = OsuColour.Gray(0xAA), }); + + string text = activityToString(); + + content.AddLinks(text, MessageFormatter.GetLinks(text)); } protected override Drawable CreateLeftVisual() @@ -66,48 +86,50 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } } + private string urlToAbsolute(string url) => $"{api?.Endpoint ?? @"https://osu.ppy.sh"}{url}"; + private string activityToString() { switch (activity.Type) { case RecentActivityType.Achievement: - return $"{activity.User.Username} unlocked the {activity.AchivementName} achievement!"; + return $"{userLinkTemplate} unlocked the {activity.AchivementName} achievement!"; case RecentActivityType.BeatmapPlaycount: - return $"{activity.Beatmap.Title} has been played {activity.Count} times!"; + return $"{beatmapLinkTemplate} has been played {activity.Count} times!"; case RecentActivityType.BeatmapsetDelete: - return $"{activity.Beatmap.Title} has been deleted."; + return $"{beatmapLinkTemplate} has been deleted."; case RecentActivityType.BeatmapsetRevive: - return $"{activity.Beatmap.Title} has been revived from eternal slumber by ${activity.User.Username}"; + return $"{beatmapLinkTemplate} has been revived from eternal slumber by ${userLinkTemplate}"; case RecentActivityType.BeatmapsetUpdate: - return $"{activity.User.Username} has updated the beatmap ${activity.Beatmap.Title}"; + return $"{userLinkTemplate} has updated the beatmap ${beatmapLinkTemplate}"; case RecentActivityType.BeatmapsetUpload: - return $"{activity.User.Username} has submitted a new beatmap ${activity.Beatmap.Title}"; + return $"{userLinkTemplate} has submitted a new beatmap ${beatmapLinkTemplate}"; case RecentActivityType.Medal: - return $"{activity.User.Username} has unlocked the {activity.AchivementName} medal!"; + return $"{userLinkTemplate} has unlocked the {activity.AchivementName} medal!"; case RecentActivityType.Rank: - return $"{activity.User.Username} achieved rank #{activity.Rank} on {activity.Beatmap?.Title}"; + return $"{userLinkTemplate} achieved rank #{activity.Rank} on {beatmapLinkTemplate}"; case RecentActivityType.RankLost: - return $"{activity.User.Username} has lost first place on {activity.Beatmap.Title}!"; + return $"{userLinkTemplate} has lost first place on {beatmapLinkTemplate}!"; case RecentActivityType.UserSupportAgain: - return $"{activity.User.Username} has once again chosen to support osu! - thanks for your generosity!"; + return $"{userLinkTemplate} has once again chosen to support osu! - thanks for your generosity!"; case RecentActivityType.UserSupportFirst: - return $"{activity.User.Username} has become an osu! supporter - thanks for your generosity!"; + return $"{userLinkTemplate} has become an osu! supporter - thanks for your generosity!"; case RecentActivityType.UsernameChange: - return $"{activity.User.PreviousUsername} has changed their username to {activity.User.Username}"; + return $"{activity.User.PreviousUsername} has changed their username to {userLinkTemplate}"; case RecentActivityType.UserSupportGift: - return $"{activity.User.Username} has received the gift of osu! supporter!"; + return $"{userLinkTemplate} has received the gift of osu! supporter!"; default: return string.Empty; diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 3bc12ccb24..39cb71ea27 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -73,6 +73,11 @@ namespace osu.Game.Overlays FadeEdgeEffectTo(0, DISAPPEAR_DURATION, Easing.Out); } + public void ShowUser(long userId) + { + ShowUser(new User { Id = userId }, true); + } + public void ShowUser(User user, bool fetchOnline = true) { userReq?.Cancel(); From 75fdca928e9d19ae12e2a8ce739cc9af42fda20b Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 00:58:20 +0530 Subject: [PATCH 09/67] Handle links correctly and don't re-open profile if the user is same. --- osu.Game/Online/Chat/MessageFormatter.cs | 4 ++-- .../Profile/Sections/Recent/DrawableRecentActivity.cs | 8 ++++---- osu.Game/Overlays/UserProfileOverlay.cs | 3 +++ 3 files changed, 9 insertions(+), 6 deletions(-) diff --git a/osu.Game/Online/Chat/MessageFormatter.cs b/osu.Game/Online/Chat/MessageFormatter.cs index 3fdce3ec12..9966f78435 100644 --- a/osu.Game/Online/Chat/MessageFormatter.cs +++ b/osu.Game/Online/Chat/MessageFormatter.cs @@ -210,13 +210,13 @@ namespace osu.Game.Online.Chat return inputMessage; } - public static List GetLinks(string text) + public static MessageFormatterResult FormatText(string text) { var result = format(text); result.Links.Sort(); - return result.Links; + return result; } public class MessageFormatterResult diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 6abf68e3e9..4d215467bb 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -34,8 +34,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent this.activity = activity; this.user = user; - userLinkTemplate = $"[{activity.User?.Username}]({urlToAbsolute(activity.User?.Url)})"; - beatmapLinkTemplate = $"[{activity.Beatmap?.Title}]({urlToAbsolute(activity.Beatmap?.Url)})"; + userLinkTemplate = $"[{urlToAbsolute(activity.User?.Url)} {activity.User?.Username}]"; + beatmapLinkTemplate = $"[{urlToAbsolute(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; } [BackgroundDependencyLoader] @@ -59,9 +59,9 @@ namespace osu.Game.Overlays.Profile.Sections.Recent Colour = OsuColour.Gray(0xAA), }); - string text = activityToString(); + var formatted = MessageFormatter.FormatText(activityToString()); - content.AddLinks(text, MessageFormatter.GetLinks(text)); + content.AddLinks(formatted.Text, formatted.Links); } protected override Drawable CreateLeftVisual() diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index 39cb71ea27..f19fc4062c 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -75,6 +75,9 @@ namespace osu.Game.Overlays public void ShowUser(long userId) { + if (userId == Header.User.Id) + return; + ShowUser(new User { Id = userId }, true); } From 1ad45b094178dc644ffcbc3ca808a2cb1c4ad0ac Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 01:16:46 +0530 Subject: [PATCH 10/67] R# fixes. --- .../GetUserRecentActivitiesRequest.cs | 4 ---- .../Sections/Recent/DrawableRecentActivity.cs | 19 +++++-------------- .../PaginatedRecentActivityContainer.cs | 11 +++-------- .../Profile/Sections/RecentSection.cs | 2 ++ osu.Game/Overlays/UserProfileOverlay.cs | 2 +- 5 files changed, 11 insertions(+), 27 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index 14997b070b..d52d0c884e 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -3,10 +3,6 @@ using osu.Game.Rulesets.Scoring; using Humanizer; using System; using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using osu.Game.Rulesets; namespace osu.Game.Online.API.Requests { diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 4d215467bb..940cd7f5ac 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -1,9 +1,4 @@ -using System; -using System.Collections.Generic; -using System.Linq; -using System.Text; -using System.Threading.Tasks; -using osu.Framework.Allocation; +using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; @@ -13,26 +8,22 @@ using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Online.Chat; using osu.Game.Screens.Select.Leaderboards; -using osu.Game.Users; -using static osu.Game.Online.API.Requests.RecentActivity; namespace osu.Game.Overlays.Profile.Sections.Recent { public class DrawableRecentActivity : DrawableProfileRow { - private RecentActivity activity; - private User user; private APIAccess api; - private string userLinkTemplate; - private string beatmapLinkTemplate; + private readonly RecentActivity activity; + private readonly string userLinkTemplate; + private readonly string beatmapLinkTemplate; private LinkFlowContainer content; - public DrawableRecentActivity(RecentActivity activity, User user) + public DrawableRecentActivity(RecentActivity activity) { this.activity = activity; - this.user = user; userLinkTemplate = $"[{urlToAbsolute(activity.User?.Url)} {activity.User?.Username}]"; beatmapLinkTemplate = $"[{urlToAbsolute(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 307c06b744..f1857096aa 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -1,17 +1,12 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Game.Online.API.Requests; -using osu.Game.Overlays.Profile.Sections.Recent; using osu.Game.Users; -using System; -using System.Collections.Generic; using System.Linq; -using System.Text; -using System.Threading.Tasks; -namespace osu.Game.Overlays.Profile.Sections +namespace osu.Game.Overlays.Profile.Sections.Recent { - class PaginatedRecentActivityContainer : PaginatedContainer + internal class PaginatedRecentActivityContainer : PaginatedContainer { public PaginatedRecentActivityContainer(Bindable user, string header, string missing) : base(user, header, missing) @@ -40,7 +35,7 @@ namespace osu.Game.Overlays.Profile.Sections foreach (RecentActivity activity in activities) { - ItemsContainer.Add(new DrawableRecentActivity(activity, User)); + ItemsContainer.Add(new DrawableRecentActivity(activity)); } }; diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index 757e2457d2..db97dca440 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.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 osu.Game.Overlays.Profile.Sections.Recent; + namespace osu.Game.Overlays.Profile.Sections { public class RecentSection : ProfileSection diff --git a/osu.Game/Overlays/UserProfileOverlay.cs b/osu.Game/Overlays/UserProfileOverlay.cs index f19fc4062c..f3fd7aeac5 100644 --- a/osu.Game/Overlays/UserProfileOverlay.cs +++ b/osu.Game/Overlays/UserProfileOverlay.cs @@ -78,7 +78,7 @@ namespace osu.Game.Overlays if (userId == Header.User.Id) return; - ShowUser(new User { Id = userId }, true); + ShowUser(new User { Id = userId }); } public void ShowUser(User user, bool fetchOnline = true) From 5724618b2a3f8109254246c493b00738fa1117df Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 09:38:37 +0530 Subject: [PATCH 11/67] Add license headers and sanitise open profile argument. --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 3 ++- .../Online/API/Requests/GetUserRecentActivitiesRequest.cs | 5 ++++- .../Profile/Sections/Recent/DrawableRecentActivity.cs | 5 ++++- .../Sections/Recent/PaginatedRecentActivityContainer.cs | 5 ++++- 4 files changed, 14 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index 8edae7a976..c16ccbce86 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -93,7 +93,8 @@ namespace osu.Game.Graphics.Containers Process.Start(url); break; case LinkAction.OpenUserProfile: - userProfile?.ShowUser(Convert.ToInt64(linkArgument)); + if (long.TryParse(linkArgument, out long userId)) + userProfile?.ShowUser(userId); break; default: throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action."); diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index d52d0c884e..451c39fdfe 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.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.Rulesets.Scoring; using Humanizer; using System; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 940cd7f5ac..901791d340 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.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.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index f1857096aa..3de005cf9b 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -1,4 +1,7 @@ -using osu.Framework.Configuration; +// 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.Online.API.Requests; using osu.Game.Users; From a20e4bc2c3494f37d14448f8ccb1d712dad5a0f5 Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 11:46:16 +0530 Subject: [PATCH 12/67] Fix typos and missing fields in JSON mappings. --- .../GetUserRecentActivitiesRequest.cs | 17 +++++++++++-- .../Sections/Recent/DrawableRecentActivity.cs | 25 ++++++++++++------- 2 files changed, 31 insertions(+), 11 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index 451c39fdfe..7926bd9d34 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -28,7 +28,7 @@ namespace osu.Game.Online.API.Requests [JsonProperty("id")] public int ID; - [JsonProperty("created_at")] + [JsonProperty("createdAt")] public DateTimeOffset CreatedAt; [JsonProperty] @@ -50,6 +50,9 @@ namespace osu.Game.Online.API.Requests [JsonProperty("rank")] public int Rank; + [JsonProperty("approval")] + public BeatmapApproval Approval; + [JsonProperty("count")] public int Count; @@ -59,10 +62,13 @@ namespace osu.Game.Online.API.Requests [JsonProperty("beatmap")] public RecentActivityBeatmap Beatmap; + [JsonProperty("beatmapset")] + public RecentActivityBeatmap Beatmapset; + [JsonProperty("user")] public RecentActivityUser User; - [JsonProperty("achivementName")] + [JsonProperty("achievementName")] public string AchivementName; public class RecentActivityBeatmap @@ -104,4 +110,11 @@ namespace osu.Game.Online.API.Requests UserSupportGift, UsernameChange, } + + public enum BeatmapApproval + { + Ranked, + Approved, + Qualified, + } } diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 901791d340..012418967f 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -21,6 +21,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent private readonly RecentActivity activity; private readonly string userLinkTemplate; private readonly string beatmapLinkTemplate; + private readonly string beatmapsetLinkTemplate; private LinkFlowContainer content; @@ -30,6 +31,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent userLinkTemplate = $"[{urlToAbsolute(activity.User?.Url)} {activity.User?.Username}]"; beatmapLinkTemplate = $"[{urlToAbsolute(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; + beatmapsetLinkTemplate = $"[{urlToAbsolute(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; } [BackgroundDependencyLoader] @@ -70,6 +72,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent FillMode = FillMode.Fit, }; + case RecentActivityType.Medal: + // TODO: add medal visual default: return new Container { @@ -92,26 +96,29 @@ namespace osu.Game.Overlays.Profile.Sections.Recent case RecentActivityType.BeatmapPlaycount: return $"{beatmapLinkTemplate} has been played {activity.Count} times!"; + case RecentActivityType.BeatmapsetApprove: + return $"{beatmapsetLinkTemplate} has been {activity.Approval.ToString().ToLowerInvariant()}!"; + case RecentActivityType.BeatmapsetDelete: - return $"{beatmapLinkTemplate} has been deleted."; + return $"{beatmapsetLinkTemplate} has been deleted."; case RecentActivityType.BeatmapsetRevive: - return $"{beatmapLinkTemplate} has been revived from eternal slumber by ${userLinkTemplate}"; + return $"{beatmapsetLinkTemplate} has been revived from eternal slumber by {userLinkTemplate}."; case RecentActivityType.BeatmapsetUpdate: - return $"{userLinkTemplate} has updated the beatmap ${beatmapLinkTemplate}"; + return $"{userLinkTemplate} has updated the beatmap {beatmapsetLinkTemplate}!"; case RecentActivityType.BeatmapsetUpload: - return $"{userLinkTemplate} has submitted a new beatmap ${beatmapLinkTemplate}"; + return $"{userLinkTemplate} has submitted a new beatmap {beatmapsetLinkTemplate}!"; case RecentActivityType.Medal: return $"{userLinkTemplate} has unlocked the {activity.AchivementName} medal!"; case RecentActivityType.Rank: - return $"{userLinkTemplate} achieved rank #{activity.Rank} on {beatmapLinkTemplate}"; + return $"{userLinkTemplate} achieved rank #{activity.Rank} on {beatmapLinkTemplate} ({activity.Mode}!)"; case RecentActivityType.RankLost: - return $"{userLinkTemplate} has lost first place on {beatmapLinkTemplate}!"; + return $"{userLinkTemplate} has lost first place on {beatmapLinkTemplate} ({activity.Mode}!)"; case RecentActivityType.UserSupportAgain: return $"{userLinkTemplate} has once again chosen to support osu! - thanks for your generosity!"; @@ -119,12 +126,12 @@ namespace osu.Game.Overlays.Profile.Sections.Recent case RecentActivityType.UserSupportFirst: return $"{userLinkTemplate} has become an osu! supporter - thanks for your generosity!"; - case RecentActivityType.UsernameChange: - return $"{activity.User.PreviousUsername} has changed their username to {userLinkTemplate}"; - case RecentActivityType.UserSupportGift: return $"{userLinkTemplate} has received the gift of osu! supporter!"; + case RecentActivityType.UsernameChange: + return $"{activity.User.PreviousUsername} has changed their username to {userLinkTemplate}!"; + default: return string.Empty; } From a77d1eedae0b2756e5ad7cb6ac96d87eb7c8d129 Mon Sep 17 00:00:00 2001 From: naoey Date: Mon, 26 Feb 2018 13:08:12 +0530 Subject: [PATCH 13/67] Fix achievements parsing and add badges to recent activity. --- .../GetUserRecentActivitiesRequest.cs | 14 ++++++- .../Sections/Recent/DrawableRecentActivity.cs | 15 ++++++-- .../Profile/Sections/Recent/MedalIcon.cs | 38 +++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 4 files changed, 62 insertions(+), 6 deletions(-) create mode 100644 osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs index 7926bd9d34..d1685b01f3 100644 --- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs +++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs @@ -68,8 +68,8 @@ namespace osu.Game.Online.API.Requests [JsonProperty("user")] public RecentActivityUser User; - [JsonProperty("achievementName")] - public string AchivementName; + [JsonProperty("achievement")] + public RecentActivityAchievement Achievement; public class RecentActivityBeatmap { @@ -91,6 +91,16 @@ namespace osu.Game.Online.API.Requests [JsonProperty("previousUsername")] public string PreviousUsername; } + + public class RecentActivityAchievement + { + [JsonProperty("slug")] + public string Slug; + + [JsonProperty("name")] + public string Name; + } + } public enum RecentActivityType diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 012418967f..282b2e242a 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -72,8 +72,14 @@ namespace osu.Game.Overlays.Profile.Sections.Recent FillMode = FillMode.Fit, }; - case RecentActivityType.Medal: - // TODO: add medal visual + case RecentActivityType.Achievement: + return new MedalIcon(activity.Achievement.Slug) + { + RelativeSizeAxes = Axes.Y, + Width = 60, + FillMode = FillMode.Fit, + }; + default: return new Container { @@ -91,7 +97,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent switch (activity.Type) { case RecentActivityType.Achievement: - return $"{userLinkTemplate} unlocked the {activity.AchivementName} achievement!"; + return $"{userLinkTemplate} unlocked the {activity.Achievement.Name} medal!"; case RecentActivityType.BeatmapPlaycount: return $"{beatmapLinkTemplate} has been played {activity.Count} times!"; @@ -112,7 +118,8 @@ namespace osu.Game.Overlays.Profile.Sections.Recent return $"{userLinkTemplate} has submitted a new beatmap {beatmapsetLinkTemplate}!"; case RecentActivityType.Medal: - return $"{userLinkTemplate} has unlocked the {activity.AchivementName} medal!"; + // apparently this shouldn't exist look at achievement instead (https://github.com/ppy/osu-web/blob/master/resources/assets/coffee/react/profile-page/recent-activity.coffee#L111) + return string.Empty; case RecentActivityType.Rank: return $"{userLinkTemplate} achieved rank #{activity.Rank} on {beatmapLinkTemplate} ({activity.Mode}!)"; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs new file mode 100644 index 0000000000..9ef2b89269 --- /dev/null +++ b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs @@ -0,0 +1,38 @@ +// 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.Containers; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Sprites; +using osu.Framework.Graphics.Textures; + +namespace osu.Game.Overlays.Profile.Sections.Recent +{ + internal class MedalIcon : Container + { + private readonly string slug; + private readonly Sprite sprite; + + private string url => $@"https://s.ppy.sh/images/medals-client/{slug}@2x.png"; + + public MedalIcon(string slug) + { + this.slug = slug; + + Child = sprite = new Sprite + { + Height = 40, + Width = 40, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }; + } + + [BackgroundDependencyLoader] + private void load(TextureStore textures) + { + sprite.Texture = textures.Get(url); + } + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index cd40b42365..e420ec6b71 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -301,6 +301,7 @@ + From 62913163e02ca776174bcb1f01388ce6b2c95f53 Mon Sep 17 00:00:00 2001 From: naoey Date: Tue, 27 Feb 2018 21:21:53 +0530 Subject: [PATCH 14/67] Fix long recent activity text overlapping timestamp. - Also remove unnecessary fallback from absolute URL helper --- .../Sections/Recent/DrawableRecentActivity.cs | 19 +++++++++++-------- 1 file changed, 11 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 282b2e242a..4785b1e8d3 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -19,19 +19,16 @@ namespace osu.Game.Overlays.Profile.Sections.Recent private APIAccess api; private readonly RecentActivity activity; - private readonly string userLinkTemplate; - private readonly string beatmapLinkTemplate; - private readonly string beatmapsetLinkTemplate; + + private string userLinkTemplate; + private string beatmapLinkTemplate; + private string beatmapsetLinkTemplate; private LinkFlowContainer content; public DrawableRecentActivity(RecentActivity activity) { this.activity = activity; - - userLinkTemplate = $"[{urlToAbsolute(activity.User?.Url)} {activity.User?.Username}]"; - beatmapLinkTemplate = $"[{urlToAbsolute(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; - beatmapsetLinkTemplate = $"[{urlToAbsolute(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; } [BackgroundDependencyLoader] @@ -39,6 +36,12 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { this.api = api; + userLinkTemplate = $"[{toAbsoluteUrl(activity.User?.Url)} {activity.User?.Username}]"; + beatmapLinkTemplate = $"[{toAbsoluteUrl(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; + beatmapsetLinkTemplate = $"[{toAbsoluteUrl(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; + + LeftFlowContainer.Padding = new MarginPadding { Left = 10, Right = 160 }; + LeftFlowContainer.Add(content = new LinkFlowContainer { AutoSizeAxes = Axes.Y, @@ -90,7 +93,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent } } - private string urlToAbsolute(string url) => $"{api?.Endpoint ?? @"https://osu.ppy.sh"}{url}"; + private string toAbsoluteUrl(string url) => $"{api.Endpoint}{url}"; private string activityToString() { From 2e535afb845bb1b6719d6df5611a771879c0d7de Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 28 Feb 2018 15:19:27 +0530 Subject: [PATCH 15/67] Remove redundant subsection title. - Also handle opening UserProfile in LinkFlowContainer similar to how beatmaps and channels are handled --- osu.Game/Graphics/Containers/LinkFlowContainer.cs | 6 ++---- osu.Game/OsuGame.cs | 6 ++++++ osu.Game/Overlays/Profile/Sections/RecentSection.cs | 2 +- 3 files changed, 9 insertions(+), 5 deletions(-) diff --git a/osu.Game/Graphics/Containers/LinkFlowContainer.cs b/osu.Game/Graphics/Containers/LinkFlowContainer.cs index c16ccbce86..1d231ada23 100644 --- a/osu.Game/Graphics/Containers/LinkFlowContainer.cs +++ b/osu.Game/Graphics/Containers/LinkFlowContainer.cs @@ -23,16 +23,14 @@ namespace osu.Game.Graphics.Containers public override bool HandleMouseInput => true; private OsuGame game; - private UserProfileOverlay userProfile; private Action showNotImplementedError; [BackgroundDependencyLoader(true)] - private void load(OsuGame game, NotificationOverlay notifications, UserProfileOverlay userProfile) + private void load(OsuGame game, NotificationOverlay notifications) { // will be null in tests this.game = game; - this.userProfile = userProfile; showNotImplementedError = () => notifications?.Post(new SimpleNotification { @@ -94,7 +92,7 @@ namespace osu.Game.Graphics.Containers break; case LinkAction.OpenUserProfile: if (long.TryParse(linkArgument, out long userId)) - userProfile?.ShowUser(userId); + game?.ShowUser(userId); break; default: throw new NotImplementedException($"This {nameof(LinkAction)} ({linkType.ToString()}) is missing an associated action."); diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 95eb88c5c8..cff7007fd5 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -154,6 +154,12 @@ namespace osu.Game /// The set to display. public void ShowBeatmapSet(int setId) => beatmapSetOverlay.ShowBeatmapSet(setId); + /// + /// Show a user's profile as an overlay. + /// + /// The user to display. + public void ShowUser(long userId) => userProfile.ShowUser(userId); + protected void LoadScore(Score s) { scoreLoad?.Cancel(); diff --git a/osu.Game/Overlays/Profile/Sections/RecentSection.cs b/osu.Game/Overlays/Profile/Sections/RecentSection.cs index db97dca440..84a941aa1a 100644 --- a/osu.Game/Overlays/Profile/Sections/RecentSection.cs +++ b/osu.Game/Overlays/Profile/Sections/RecentSection.cs @@ -15,7 +15,7 @@ namespace osu.Game.Overlays.Profile.Sections { Children = new[] { - new PaginatedRecentActivityContainer(User, @"Recent", @"This user hasn't done anything notable recently!"), + new PaginatedRecentActivityContainer(User, null, @"This user hasn't done anything notable recently!"), }; } } From 46dfb761c57e1804576760ce217ddf4a44544cba Mon Sep 17 00:00:00 2001 From: jorolf Date: Wed, 28 Feb 2018 16:14:52 +0100 Subject: [PATCH 16/67] basic volume meter and testcase --- .../Visual/TestCaseVolumeControl.cs | 29 +++ osu.Game.Tests/osu.Game.Tests.csproj | 1 + osu.Game/Overlays/Volume/MuteButton.cs | 58 ++++++ osu.Game/Overlays/Volume/VolumeMeter.cs | 193 ++++++++++++++++++ osu.Game/osu.Game.csproj | 2 + 5 files changed, 283 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseVolumeControl.cs create mode 100644 osu.Game/Overlays/Volume/MuteButton.cs create mode 100644 osu.Game/Overlays/Volume/VolumeMeter.cs diff --git a/osu.Game.Tests/Visual/TestCaseVolumeControl.cs b/osu.Game.Tests/Visual/TestCaseVolumeControl.cs new file mode 100644 index 0000000000..04390d6d19 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseVolumeControl.cs @@ -0,0 +1,29 @@ +using System; +using System.Collections.Generic; +using osu.Framework.Allocation; +using osu.Framework.Audio; +using osu.Framework.Graphics; +using osu.Framework.Testing; +using osu.Game.Graphics; +using osu.Game.Overlays.Volume; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseVolumeControl : TestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(VolumeMeter), typeof(MuteButton) }; + + [BackgroundDependencyLoader] + private void load(AudioManager audio, OsuColour colours) + { + VolumeMeter meter; + Add(meter = new VolumeMeter("MASTER", 125, colours.PinkDarker)); + Add(new MuteButton + { + Margin = new MarginPadding { Top = 200 } + }); + + meter.Bindable.BindTo(audio.Volume); + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 8301f1f734..63adbc8b43 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -162,6 +162,7 @@ + diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs new file mode 100644 index 0000000000..b45034c166 --- /dev/null +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -0,0 +1,58 @@ +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input; +using osu.Game.Graphics; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Overlays.Volume +{ + public class MuteButton : Container, IHasCurrentValue + { + public Bindable Current { get; } = new Bindable(); + + private Color4 hoveredColour, unhoveredColour; + + public MuteButton() + { + Masking = true; + BorderThickness = 3; + CornerRadius = 20; + Size = new Vector2(100, 40); + } + + [BackgroundDependencyLoader] + private void load(OsuColour colours) + { + hoveredColour = colours.YellowDark; + BorderColour = unhoveredColour = colours.Gray1.Opacity(0.9f); + + AddRange(new Drawable[] + { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = colours.Gray1, + Alpha = 0.9f, + }, + }); + } + + protected override bool OnHover(InputState state) + { + this.TransformTo("BorderColour", hoveredColour, 500, Easing.OutQuint); + return true; + } + + protected override void OnHoverLost(InputState state) + { + this.TransformTo("BorderColour", unhoveredColour, 500, Easing.OutQuint); + } + } +} diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs new file mode 100644 index 0000000000..3351dbed9a --- /dev/null +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -0,0 +1,193 @@ +using System; +using System.Globalization; +using osu.Framework.Allocation; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.Transforms; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Input.Bindings; +using osu.Framework.MathUtils; +using osu.Game.Graphics; +using osu.Game.Graphics.Sprites; +using osu.Game.Input.Bindings; +using OpenTK; +using OpenTK.Graphics; + +namespace osu.Game.Overlays.Volume +{ + public class VolumeMeter : Container, IKeyBindingHandler + { + private CircularProgress volumeCircle; + public BindableDouble Bindable { get; } = new BindableDouble(); + private readonly float circleSize; + private readonly Color4 meterColour; + private readonly string name; + + public VolumeMeter(string name, float circleSize, Color4 meterColour) + { + this.circleSize = circleSize; + this.meterColour = meterColour; + this.name = name; + + AutoSizeAxes = Axes.Both; + } + + [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 + } + } + }); + + + OsuSpriteText text, maxText; + CircularProgress bgProgress; + BufferedContainer maxGlow; + + Add(new CircularContainer + { + Masking = true, + Size = new Vector2(circleSize), + Children = new Drawable[] + { + new Box + { + 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) + }, + (volumeCircle = new CircularProgress + { + RelativeSizeAxes = Axes.Both, + InnerRadius = 0.05f, + Rotation = 180, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Size = new Vector2(0.8f) + }).WithEffect(new GlowEffect + { + Colour = meterColour, + Strength = 2 + }), + maxGlow = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = "Venera", + Text = "MAX", + TextSize = 0.16f * circleSize + }.WithEffect(new GlowEffect + { + Colour = meterColour, + PadExtent = true, + Strength = 2, + }), + text = new OsuSpriteText + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Font = "Venera", + TextSize = 0.16f * circleSize + } + } + }); + + Bindable.ValueChanged += newVolume => this.TransformTo("circleBindable", newVolume * 0.75, 250, Easing.OutQuint); + volumeCircle.Current.ValueChanged += newVolume => + { + if (newVolume > 0.745) + { + text.Alpha = 0; + maxGlow.Alpha = 1; //show "MAX" + } + else + { + text.Text = Math.Round(newVolume / 0.0075).ToString(CultureInfo.CurrentCulture); + text.Alpha = 1; + maxGlow.Alpha = 0; + } + }; + + bgProgress.Current.Value = 0.75f; + } + + /// + /// This is needed because doesn't support + /// + private double circleBindable + { + get => volumeCircle.Current; + set => volumeCircle.Current.Value = value; + } + + public double Volume + { + get => Bindable; + private set => Bindable.Value = value; + } + + public void Increase() + { + Volume += 0.05f; + } + + public void Decrease() + { + Volume -= 0.05f; + } + + public bool OnPressed(GlobalAction action) + { + if (!IsHovered) return false; + + switch (action) + { + case GlobalAction.DecreaseVolume: + Decrease(); + return true; + case GlobalAction.IncreaseVolume: + Increase(); + return true; + } + + return false; + } + + public bool OnReleased(GlobalAction action) => false; + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 4944613828..b94da5badb 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -330,6 +330,8 @@ + + From 26e50043b70a0c13eb769638fcccf08a7600529d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 3 Mar 2018 14:07:15 +0900 Subject: [PATCH 17/67] Fix parallax container during rewinds --- osu.Game/Graphics/Containers/ParallaxContainer.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Graphics/Containers/ParallaxContainer.cs b/osu.Game/Graphics/Containers/ParallaxContainer.cs index f4400b7df2..febe52d775 100644 --- a/osu.Game/Graphics/Containers/ParallaxContainer.cs +++ b/osu.Game/Graphics/Containers/ParallaxContainer.cs @@ -66,7 +66,7 @@ namespace osu.Game.Graphics.Containers { Vector2 offset = (input.CurrentState.Mouse == null ? Vector2.Zero : ToLocalSpace(input.CurrentState.Mouse.NativeState.Position) - DrawSize / 2) * ParallaxAmount; - content.Position = Interpolation.ValueAt(Clock.ElapsedFrameTime, content.Position, offset, 0, 1000, Easing.OutQuint); + content.Position = Interpolation.ValueAt(MathHelper.Clamp(Clock.ElapsedFrameTime, 0, 1000), content.Position, offset, 0, 1000, Easing.OutQuint); content.Scale = new Vector2(1 + ParallaxAmount); } From 659578e8fa8563b58ddda9e632f65ce443dafa70 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 4 Mar 2018 01:48:00 +0900 Subject: [PATCH 18/67] Add rewind support for storyboards --- osu.Game/Storyboards/Drawables/DrawableStoryboard.cs | 2 ++ osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs | 2 ++ osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs | 2 ++ 3 files changed, 6 insertions(+) diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs index aaeaaabd55..9da92d8cb4 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboard.cs @@ -33,6 +33,8 @@ namespace osu.Game.Storyboards.Drawables } } + public override bool RemoveCompletedTransforms => false; + private DependencyContainer dependencies; protected override IReadOnlyDependencyContainer CreateLocalDependencies(IReadOnlyDependencyContainer parent) => dependencies = new DependencyContainer(base.CreateLocalDependencies(parent)); diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs index ef782abbe5..0b84ff3297 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardAnimation.cs @@ -17,6 +17,8 @@ namespace osu.Game.Storyboards.Drawables public bool FlipH { get; set; } public bool FlipV { get; set; } + public override bool RemoveWhenNotAlive => false; + protected override Vector2 DrawScale => new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y); diff --git a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs index a39805f74e..c4b9a3d47e 100644 --- a/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs +++ b/osu.Game/Storyboards/Drawables/DrawableStoryboardSprite.cs @@ -17,6 +17,8 @@ namespace osu.Game.Storyboards.Drawables public bool FlipH { get; set; } public bool FlipV { get; set; } + public override bool RemoveWhenNotAlive => false; + protected override Vector2 DrawScale => new Vector2(FlipH ? -base.DrawScale.X : base.DrawScale.X, FlipV ? -base.DrawScale.Y : base.DrawScale.Y); From ea6e3938c039a27d29a13b17404fd8a582b197e7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 4 Mar 2018 03:00:13 +0900 Subject: [PATCH 19/67] Fix hard crash due to spinner spin requirement being zero Resolves #2133. --- osu.Game.Rulesets.Osu/Objects/Spinner.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs index 2f238bb74b..b30e4cb932 100644 --- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Spinner.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.Game.Beatmaps; using osu.Game.Rulesets.Objects.Types; using osu.Game.Beatmaps.ControlPoints; @@ -26,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Objects SpinsRequired = (int)(Duration / 1000 * BeatmapDifficulty.DifficultyRange(difficulty.OverallDifficulty, 3, 5, 7.5)); // spinning doesn't match 1:1 with stable, so let's fudge them easier for the time being. - SpinsRequired = (int)(SpinsRequired * 0.6); + SpinsRequired = (int)Math.Max(1, SpinsRequired * 0.6); } } } From 3a420ba8269920c45ba166076a14a82f6f6815da Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 19:08:35 +0100 Subject: [PATCH 20/67] add the volume overlay --- ...lumeControl.cs => TestCaseVolumePieces.cs} | 3 +- osu.Game.Tests/osu.Game.Tests.csproj | 2 +- .../UserInterface/Volume/VolumeMeter.cs | 108 ------------- osu.Game/OsuGame.cs | 6 +- osu.Game/Overlays/Volume/MuteButton.cs | 27 +++- .../Volume/VolumeControlReceptor.cs | 2 +- osu.Game/Overlays/Volume/VolumeMeter.cs | 4 +- .../VolumeOverlay.cs} | 145 +++++++++--------- osu.Game/osu.Game.csproj | 5 +- 9 files changed, 109 insertions(+), 193 deletions(-) rename osu.Game.Tests/Visual/{TestCaseVolumeControl.cs => TestCaseVolumePieces.cs} (90%) delete mode 100644 osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs rename osu.Game/{Graphics/UserInterface => Overlays}/Volume/VolumeControlReceptor.cs (90%) rename osu.Game/{Graphics/UserInterface/Volume/VolumeControl.cs => Overlays/VolumeOverlay.cs} (54%) diff --git a/osu.Game.Tests/Visual/TestCaseVolumeControl.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs similarity index 90% rename from osu.Game.Tests/Visual/TestCaseVolumeControl.cs rename to osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 04390d6d19..5a43574a9d 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumeControl.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -9,7 +9,7 @@ using osu.Game.Overlays.Volume; namespace osu.Game.Tests.Visual { - public class TestCaseVolumeControl : TestCase + public class TestCaseVolumePieces : TestCase { public override IReadOnlyList RequiredTypes => new[] { typeof(VolumeMeter), typeof(MuteButton) }; @@ -24,6 +24,7 @@ namespace osu.Game.Tests.Visual }); meter.Bindable.BindTo(audio.Volume); + } } } diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index dde04201f2..8cbeb6aab6 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -174,7 +174,7 @@ - + diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs deleted file mode 100644 index ef3702fdf3..0000000000 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeMeter.cs +++ /dev/null @@ -1,108 +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.Configuration; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Graphics.Sprites; -using OpenTK; -using OpenTK.Graphics; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Input.Bindings; -using osu.Game.Input.Bindings; - -namespace osu.Game.Graphics.UserInterface.Volume -{ - public class VolumeMeter : Container, IKeyBindingHandler - { - private readonly Box meterFill; - public BindableDouble Bindable { get; } = new BindableDouble(); - - public VolumeMeter(string meterName) - { - Size = new Vector2(40, 180); - Children = new Drawable[] - { - new Box - { - Colour = Color4.Black, - RelativeSizeAxes = Axes.Both - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Size = new Vector2(0.5f, 0.9f), - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Children = new Drawable[] - { - new Box - { - Colour = Color4.DarkGray, - RelativeSizeAxes = Axes.Both - }, - meterFill = new Box - { - Colour = Color4.White, - Scale = new Vector2(1, 0), - RelativeSizeAxes = Axes.Both, - Origin = Anchor.BottomCentre, - Anchor = Anchor.BottomCentre - } - } - }, - new OsuSpriteText - { - Text = meterName, - Anchor = Anchor.BottomCentre, - Origin = Anchor.TopCentre - } - }; - - Bindable.ValueChanged += delegate { updateFill(); }; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - updateFill(); - } - - public double Volume - { - get => Bindable.Value; - private set => Bindable.Value = value; - } - - public void Increase() - { - Volume += 0.05f; - } - - public void Decrease() - { - Volume -= 0.05f; - } - - private void updateFill() => meterFill.ScaleTo(new Vector2(1, (float)Volume), 300, Easing.OutQuint); - - public bool OnPressed(GlobalAction action) - { - if (!IsHovered) return false; - - switch (action) - { - case GlobalAction.DecreaseVolume: - Decrease(); - return true; - case GlobalAction.IncreaseVolume: - Increase(); - return true; - } - - return false; - } - - public bool OnReleased(GlobalAction action) => false; - } -} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index aeb23dccd7..a6f650d23d 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Overlays; using osu.Framework.Logging; -using osu.Game.Graphics.UserInterface.Volume; using osu.Framework.Allocation; using osu.Game.Overlays.Toolbar; using osu.Game.Screens; @@ -33,6 +32,7 @@ using osu.Game.Input.Bindings; using osu.Game.Rulesets.Mods; using osu.Game.Skinning; using OpenTK.Graphics; +using osu.Game.Overlays.Volume; namespace osu.Game { @@ -75,7 +75,7 @@ namespace osu.Game private OsuScreen screenStack; - private VolumeControl volume; + private VolumeOverlay volume; private OnScreenDisplay onscreenDisplay; private Bindable configRuleset; @@ -232,7 +232,7 @@ namespace osu.Game }, }, overlayContent.Add); - loadComponentSingleFile(volume = new VolumeControl(), Add); + loadComponentSingleFile(volume = new VolumeOverlay(), Add); loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add); //overlay elements diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index b45034c166..82e61c8f0b 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -18,13 +18,15 @@ namespace osu.Game.Overlays.Volume public Bindable Current { get; } = new Bindable(); private Color4 hoveredColour, unhoveredColour; + private const float width = 100; + public const float HEIGHT = 35; public MuteButton() { Masking = true; BorderThickness = 3; - CornerRadius = 20; - Size = new Vector2(100, 40); + CornerRadius = HEIGHT / 2; + Size = new Vector2(width, HEIGHT); } [BackgroundDependencyLoader] @@ -33,6 +35,8 @@ namespace osu.Game.Overlays.Volume hoveredColour = colours.YellowDark; BorderColour = unhoveredColour = colours.Gray1.Opacity(0.9f); + + SpriteIcon icon; AddRange(new Drawable[] { new Box @@ -41,7 +45,20 @@ namespace osu.Game.Overlays.Volume Colour = colours.Gray1, Alpha = 0.9f, }, + icon = new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Size = new Vector2(20), + } }); + + Current.ValueChanged += newValue => + { + icon.Icon = newValue ? FontAwesome.fa_volume_off : FontAwesome.fa_volume_up; + icon.Margin = new MarginPadding { Left = newValue ? width / 2 - 15 : width / 2 - 10 }; //Magic numbers to line up both icons because they're different widths + }; + Current.TriggerChange(); } protected override bool OnHover(InputState state) @@ -54,5 +71,11 @@ namespace osu.Game.Overlays.Volume { this.TransformTo("BorderColour", unhoveredColour, 500, Easing.OutQuint); } + + protected override bool OnClick(InputState state) + { + Current.Value = !Current.Value; + return true; + } } } diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs similarity index 90% rename from osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs rename to osu.Game/Overlays/Volume/VolumeControlReceptor.cs index 2328533665..a5be7dc445 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs +++ b/osu.Game/Overlays/Volume/VolumeControlReceptor.cs @@ -7,7 +7,7 @@ using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Game.Input.Bindings; -namespace osu.Game.Graphics.UserInterface.Volume +namespace osu.Game.Overlays.Volume { public class VolumeControlReceptor : Container, IKeyBindingHandler, IHandleGlobalInput { diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 3351dbed9a..92b5c3f0bd 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -128,9 +128,9 @@ namespace osu.Game.Overlays.Volume }); Bindable.ValueChanged += newVolume => this.TransformTo("circleBindable", newVolume * 0.75, 250, Easing.OutQuint); - volumeCircle.Current.ValueChanged += newVolume => + volumeCircle.Current.ValueChanged += newVolume => //by using this event we sync the meter with the text. newValue has to be divided by 0.75 to give the actual percentage { - if (newVolume > 0.745) + if (Precision.DefinitelyBigger(newVolume, 0.74)) { text.Alpha = 0; maxGlow.Alpha = 1; //show "MAX" diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs b/osu.Game/Overlays/VolumeOverlay.cs similarity index 54% rename from osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs rename to osu.Game/Overlays/VolumeOverlay.cs index ccf70af6ed..aa94667901 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControl.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -1,57 +1,87 @@ -// 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.Threading; -using OpenTK; +using osu.Framework.Allocation; using osu.Framework.Audio; -using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Colour; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Framework.Threading; +using osu.Game.Graphics; using osu.Game.Input.Bindings; +using osu.Game.Overlays.Volume; +using OpenTK; +using OpenTK.Graphics; -namespace osu.Game.Graphics.UserInterface.Volume +namespace osu.Game.Overlays { - public class VolumeControl : OverlayContainer + public class VolumeOverlay : OverlayContainer { - private readonly VolumeMeter volumeMeterMaster; - private readonly IconButton muteIcon; + private const float offset = 10; + + private VolumeMeter volumeMeterMaster; + private VolumeMeter volumeMeterEffect; + private VolumeMeter volumeMeterMusic; + private MuteButton muteButton; protected override bool BlockPassThroughMouse => false; - public VolumeControl() - { - AutoSizeAxes = Axes.Both; - Anchor = Anchor.BottomRight; - Origin = Anchor.BottomRight; + private readonly BindableDouble muteAdjustment = new BindableDouble(); - Children = new Drawable[] + [BackgroundDependencyLoader] + private void load(AudioManager audio, OsuColour colours) + { + RelativeSizeAxes = Axes.Both; + + AddRange(new Drawable[] { + new Box + { + RelativeSizeAxes = Axes.Y, + Width = 300, + Colour = new ColourInfo + { + TopLeft = Color4.Black.Opacity(0.5f), + BottomLeft = Color4.Black.Opacity(0.5f), + TopRight = Color4.Black.Opacity(0), + BottomRight = Color4.Black.Opacity(0), + } + }, new FillFlowContainer { + Direction = FillDirection.Vertical, AutoSizeAxes = Axes.Both, - Anchor = Anchor.BottomRight, - Origin = Anchor.BottomRight, - Margin = new MarginPadding { Left = 10, Right = 10, Top = 30, Bottom = 30 }, - Spacing = new Vector2(15, 0), + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Spacing = new Vector2(0, offset), + Margin = new MarginPadding { Left = offset }, Children = new Drawable[] { - new Container + volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.Blue) { - Size = new Vector2(IconButton.BUTTON_SIZE), - Child = muteIcon = new IconButton - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Icon = FontAwesome.fa_volume_up, - Action = () => Adjust(GlobalAction.ToggleMute), - } + Margin = new MarginPadding { Top = 100 + MuteButton.HEIGHT } //to counter the mute button and re-center the volume meters }, - volumeMeterMaster = new VolumeMeter("Master"), - volumeMeterEffect = new VolumeMeter("Effects"), - volumeMeterMusic = new VolumeMeter("Music") + volumeMeterMaster = new VolumeMeter("MASTER", 150, colours.Pink), + volumeMeterMusic = new VolumeMeter("MUSIC", 125, colours.Blue), + muteButton = new MuteButton + { + Margin = new MarginPadding { Top = 100 } + } } - } + }, + }); + + + volumeMeterMaster.Bindable.BindTo(audio.Volume); + volumeMeterEffect.Bindable.BindTo(audio.VolumeSample); + volumeMeterMusic.Bindable.BindTo(audio.VolumeTrack); + + muteButton.Current.ValueChanged += mute => + { + if (mute) + audio.AddAdjustment(AdjustableProperty.Volume, muteAdjustment); + else + audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment); }; } @@ -62,7 +92,13 @@ namespace osu.Game.Graphics.UserInterface.Volume volumeMeterMaster.Bindable.ValueChanged += _ => settingChanged(); volumeMeterEffect.Bindable.ValueChanged += _ => settingChanged(); volumeMeterMusic.Bindable.ValueChanged += _ => settingChanged(); - muted.ValueChanged += _ => settingChanged(); + muteButton.Current.ValueChanged += _ => settingChanged(); + } + + private void settingChanged() + { + Show(); + schedulePopOut(); } public bool Adjust(GlobalAction action) @@ -83,50 +119,15 @@ namespace osu.Game.Graphics.UserInterface.Volume return true; case GlobalAction.ToggleMute: Show(); - muted.Toggle(); + muteButton.Current.Value = !muteButton.Current; return true; } return false; } - private void settingChanged() - { - Show(); - schedulePopOut(); - } - - private readonly BindableDouble muteAdjustment = new BindableDouble(); - - private readonly BindableBool muted = new BindableBool(); - - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - volumeMeterMaster.Bindable.BindTo(audio.Volume); - volumeMeterEffect.Bindable.BindTo(audio.VolumeSample); - volumeMeterMusic.Bindable.BindTo(audio.VolumeTrack); - - muted.ValueChanged += mute => - { - if (mute) - { - audio.AddAdjustment(AdjustableProperty.Volume, muteAdjustment); - muteIcon.Icon = FontAwesome.fa_volume_off; - } - else - { - audio.RemoveAdjustment(AdjustableProperty.Volume, muteAdjustment); - muteIcon.Icon = FontAwesome.fa_volume_up; - } - }; - } - private ScheduledDelegate popOutDelegate; - private readonly VolumeMeter volumeMeterEffect; - private readonly VolumeMeter volumeMeterMusic; - protected override void PopIn() { ClearTransforms(); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 847b4469e5..e99fd16aef 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -351,7 +351,9 @@ + + @@ -471,9 +473,6 @@ - - - From 30b14473181fe3eb11f2207c61949c3f99b70731 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 4 Mar 2018 03:17:11 +0900 Subject: [PATCH 21/67] Fix skin file path lookup performance Move path mapping to the resource store, so caching can happen against the component's name rather than the skin path. Fixes regression of beatmap load time when a custom skin is selected. --- osu.Game/Skinning/LegacySkin.cs | 11 +++------- osu.Game/Skinning/SkinResourceStore.cs | 29 ++++++++++++++++++++++++++ osu.Game/osu.Game.csproj | 1 + 3 files changed, 33 insertions(+), 8 deletions(-) create mode 100644 osu.Game/Skinning/SkinResourceStore.cs diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 5f34ddc2b5..97e0bdb942 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -1,9 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; -using System.IO; -using System.Linq; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; @@ -22,16 +19,14 @@ namespace osu.Game.Skinning public LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager) : base(skin) { + storage = new SkinResourceStore(skin, storage); samples = audioManager.GetSampleManager(storage); textures = new TextureStore(new RawTextureLoaderStore(storage)); } - private string getPathForFile(string filename) => - SkinInfo.Files.FirstOrDefault(f => string.Equals(Path.GetFileNameWithoutExtension(f.Filename), filename, StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath; - public override Drawable GetDrawableComponent(string componentName) { - var texture = textures.Get(getPathForFile(componentName.Split('/').Last())); + var texture = textures.Get(componentName); if (texture == null) return null; return new Sprite @@ -42,6 +37,6 @@ namespace osu.Game.Skinning }; } - public override SampleChannel GetSample(string sampleName) => samples.Get(getPathForFile(sampleName.Split('/').Last())); + public override SampleChannel GetSample(string sampleName) => samples.Get(sampleName); } } diff --git a/osu.Game/Skinning/SkinResourceStore.cs b/osu.Game/Skinning/SkinResourceStore.cs new file mode 100644 index 0000000000..58da8ad19a --- /dev/null +++ b/osu.Game/Skinning/SkinResourceStore.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 System; +using System.IO; +using System.Linq; +using osu.Framework.IO.Stores; + +namespace osu.Game.Skinning +{ + public class SkinResourceStore : IResourceStore + { + private readonly SkinInfo skin; + private readonly IResourceStore underlyingStore; + + private string getPathForFile(string filename) => + skin.Files.FirstOrDefault(f => string.Equals(Path.GetFileNameWithoutExtension(f.Filename), filename.Split('/').Last(), StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath; + + public SkinResourceStore(SkinInfo skin, IResourceStore underlyingStore) + { + this.skin = skin; + this.underlyingStore = underlyingStore; + } + + public Stream GetStream(string name) => underlyingStore.GetStream(getPathForFile(name)); + + byte[] IResourceStore.Get(string name) => underlyingStore.Get(getPathForFile(name)); + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 37e304d62d..d4bd5a0013 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -870,6 +870,7 @@ + From ef63366d91028c93f1478618793abff7de97e29c Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 19:25:34 +0100 Subject: [PATCH 22/67] simplify VolumeMeter --- osu.Game/Overlays/Volume/VolumeMeter.cs | 30 ++++++++++--------------- osu.Game/Overlays/VolumeOverlay.cs | 3 ++- 2 files changed, 14 insertions(+), 19 deletions(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 92b5c3f0bd..525b4e315a 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -1,7 +1,9 @@ using System; using System.Globalization; +using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Configuration; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; @@ -65,7 +67,7 @@ namespace osu.Game.Overlays.Volume }); - OsuSpriteText text, maxText; + OsuSpriteText text; CircularProgress bgProgress; BufferedContainer maxGlow; @@ -104,26 +106,17 @@ namespace osu.Game.Overlays.Volume Colour = meterColour, Strength = 2 }), - maxGlow = new OsuSpriteText + maxGlow = (text = new OsuSpriteText { Anchor = Anchor.Centre, Origin = Anchor.Centre, Font = "Venera", - Text = "MAX", TextSize = 0.16f * circleSize - }.WithEffect(new GlowEffect + }).WithEffect(new GlowEffect { - Colour = meterColour, + Colour = Color4.Transparent, PadExtent = true, - Strength = 2, - }), - text = new OsuSpriteText - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - Font = "Venera", - TextSize = 0.16f * circleSize - } + }) } }); @@ -132,14 +125,14 @@ namespace osu.Game.Overlays.Volume { if (Precision.DefinitelyBigger(newVolume, 0.74)) { - text.Alpha = 0; - maxGlow.Alpha = 1; //show "MAX" + text.Text = "MAX"; + maxGlow.EffectColour = meterColour.Opacity(2f); } else { + if (text.Text == "MAX") + maxGlow.EffectColour = Color4.Transparent; text.Text = Math.Round(newVolume / 0.0075).ToString(CultureInfo.CurrentCulture); - text.Alpha = 1; - maxGlow.Alpha = 0; } }; @@ -149,6 +142,7 @@ namespace osu.Game.Overlays.Volume /// /// This is needed because doesn't support /// + [UsedImplicitly] private double circleBindable { get => volumeCircle.Current; diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index aa94667901..a8be219fc4 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -31,7 +31,8 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load(AudioManager audio, OsuColour colours) { - RelativeSizeAxes = Axes.Both; + AutoSizeAxes = Axes.X; + RelativeSizeAxes = Axes.Y; AddRange(new Drawable[] { From 8e0a524c4d6368469fe11072c0465409cf766b6b Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 19:31:29 +0100 Subject: [PATCH 23/67] change colours --- osu.Game/Overlays/VolumeOverlay.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index a8be219fc4..cc57b468fb 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -42,8 +42,8 @@ namespace osu.Game.Overlays Width = 300, Colour = new ColourInfo { - TopLeft = Color4.Black.Opacity(0.5f), - BottomLeft = Color4.Black.Opacity(0.5f), + TopLeft = Color4.Black.Opacity(0.75f), + BottomLeft = Color4.Black.Opacity(0.75f), TopRight = Color4.Black.Opacity(0), BottomRight = Color4.Black.Opacity(0), } @@ -58,12 +58,12 @@ namespace osu.Game.Overlays Margin = new MarginPadding { Left = offset }, Children = new Drawable[] { - volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.Blue) + volumeMeterEffect = new VolumeMeter("EFFECTS", 125, colours.BlueDarker) { Margin = new MarginPadding { Top = 100 + MuteButton.HEIGHT } //to counter the mute button and re-center the volume meters }, - volumeMeterMaster = new VolumeMeter("MASTER", 150, colours.Pink), - volumeMeterMusic = new VolumeMeter("MUSIC", 125, colours.Blue), + volumeMeterMaster = new VolumeMeter("MASTER", 150, colours.PinkDarker), + volumeMeterMusic = new VolumeMeter("MUSIC", 125, colours.BlueDarker), muteButton = new MuteButton { Margin = new MarginPadding { Top = 100 } From 9293ec635a44b4ca679fcea02048b5315f9ee8f5 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 19:49:38 +0100 Subject: [PATCH 24/67] add license headers and remove blank line --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 5 ++++- osu.Game/Overlays/Volume/MuteButton.cs | 5 ++++- osu.Game/Overlays/Volume/VolumeMeter.cs | 6 ++++-- osu.Game/Overlays/VolumeOverlay.cs | 5 ++++- 4 files changed, 16 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 5a43574a9d..1894470df9 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -1,4 +1,7 @@ -using System; +// 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.Allocation; using osu.Framework.Audio; diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index 82e61c8f0b..f056bf62ba 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.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.Configuration; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 525b4e315a..984ade9de0 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -1,4 +1,7 @@ -using System; +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; using System.Globalization; using JetBrains.Annotations; using osu.Framework.Allocation; @@ -66,7 +69,6 @@ namespace osu.Game.Overlays.Volume } }); - OsuSpriteText text; CircularProgress bgProgress; BufferedContainer maxGlow; diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index cc57b468fb..27c699e365 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.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.Configuration; using osu.Framework.Extensions.Color4Extensions; From 1cda58fe29b16dfb624fc2895bc0cc2772032f16 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 19:51:11 +0100 Subject: [PATCH 25/67] another blank line --- osu.Game/Overlays/Volume/MuteButton.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Overlays/Volume/MuteButton.cs b/osu.Game/Overlays/Volume/MuteButton.cs index f056bf62ba..adfc9c610f 100644 --- a/osu.Game/Overlays/Volume/MuteButton.cs +++ b/osu.Game/Overlays/Volume/MuteButton.cs @@ -38,7 +38,6 @@ namespace osu.Game.Overlays.Volume hoveredColour = colours.YellowDark; BorderColour = unhoveredColour = colours.Gray1.Opacity(0.9f); - SpriteIcon icon; AddRange(new Drawable[] { From ba80cd5f34823a8048928ea4d5eedd2caa4573c9 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 20:01:39 +0100 Subject: [PATCH 26/67] OsuColour can't be used in TestCases..? --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 1894470df9..5c97c3e368 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -7,8 +7,8 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Graphics; using osu.Framework.Testing; -using osu.Game.Graphics; using osu.Game.Overlays.Volume; +using OpenTK.Graphics; namespace osu.Game.Tests.Visual { @@ -17,10 +17,10 @@ namespace osu.Game.Tests.Visual public override IReadOnlyList RequiredTypes => new[] { typeof(VolumeMeter), typeof(MuteButton) }; [BackgroundDependencyLoader] - private void load(AudioManager audio, OsuColour colours) + private void load(AudioManager audio) { VolumeMeter meter; - Add(meter = new VolumeMeter("MASTER", 125, colours.PinkDarker)); + Add(meter = new VolumeMeter("MASTER", 125, Color4.Blue)); Add(new MuteButton { Margin = new MarginPadding { Top = 200 } From 033d06652095019b39c4c84b85b2183255e07129 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 20:03:24 +0100 Subject: [PATCH 27/67] blank line --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 5c97c3e368..db868c00d7 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -27,7 +27,6 @@ namespace osu.Game.Tests.Visual }); meter.Bindable.BindTo(audio.Volume); - } } } From bafcab1349266a40e8c4c36a2aaddebc05bb0e36 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 20:20:07 +0100 Subject: [PATCH 28/67] redo the test case --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 11 +++++------ 1 file changed, 5 insertions(+), 6 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index db868c00d7..7bfdca82c3 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -3,8 +3,6 @@ using System; using System.Collections.Generic; -using osu.Framework.Allocation; -using osu.Framework.Audio; using osu.Framework.Graphics; using osu.Framework.Testing; using osu.Game.Overlays.Volume; @@ -16,17 +14,18 @@ namespace osu.Game.Tests.Visual { public override IReadOnlyList RequiredTypes => new[] { typeof(VolumeMeter), typeof(MuteButton) }; - [BackgroundDependencyLoader] - private void load(AudioManager audio) + protected override void LoadComplete() { VolumeMeter meter; + MuteButton mute; Add(meter = new VolumeMeter("MASTER", 125, Color4.Blue)); - Add(new MuteButton + Add(mute = new MuteButton { Margin = new MarginPadding { Top = 200 } }); - meter.Bindable.BindTo(audio.Volume); + AddSliderStep("master volume", 0, 10, 0, i => meter.Bindable.Value = i * 0.1); + AddToggleStep("mute", b => mute.Current.Value = b); } } } From ec013dbee860fdd170889f81103adfdbd0c00241 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sat, 3 Mar 2018 21:55:19 +0100 Subject: [PATCH 29/67] remove blank line and try to get test case working --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 6 +++--- osu.Game/Overlays/VolumeOverlay.cs | 1 - 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 7bfdca82c3..5bacdf1f58 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -18,11 +18,11 @@ namespace osu.Game.Tests.Visual { VolumeMeter meter; MuteButton mute; - Add(meter = new VolumeMeter("MASTER", 125, Color4.Blue)); - Add(mute = new MuteButton + LoadComponentAsync(meter = new VolumeMeter("MASTER", 125, Color4.Blue), Add); + LoadComponentAsync(mute = new MuteButton { Margin = new MarginPadding { Top = 200 } - }); + }, Add); 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/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index 27c699e365..f764a83c7a 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -75,7 +75,6 @@ namespace osu.Game.Overlays }, }); - volumeMeterMaster.Bindable.BindTo(audio.Volume); volumeMeterEffect.Bindable.BindTo(audio.VolumeSample); volumeMeterMusic.Bindable.BindTo(audio.VolumeTrack); From bc0bc8d459dc3f38098527fef9794b5326424036 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 4 Mar 2018 21:57:24 +0900 Subject: [PATCH 30/67] Add legacy timing offsets These have been in release builds since January, but implemented in a hacky way. This brings them with a sane implementation. --- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 26 ++++++++++++++++--- 1 file changed, 22 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 3e7b36f324..7273fe999f 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -8,6 +8,7 @@ using OpenTK.Graphics; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Beatmaps.ControlPoints; +using osu.Framework; namespace osu.Game.Beatmaps.Formats { @@ -21,6 +22,8 @@ namespace osu.Game.Beatmaps.Formats private LegacySampleBank defaultSampleBank; private int defaultSampleVolume = 100; + private readonly int timeOffset; + public LegacyBeatmapDecoder() { } @@ -28,6 +31,14 @@ namespace osu.Game.Beatmaps.Formats public LegacyBeatmapDecoder(string header) { BeatmapVersion = int.Parse(header.Substring(17)); + + // BeatmapVersion 4 and lower had an incorrect offset (stable has this set as 24ms off) + timeOffset += BeatmapVersion < 5 ? 24 : 0; + + // lazer in general doesn't match stable. this is the result of user testing, albeit limited. + // only seems to be required on windows. + if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) + timeOffset += -22; } protected override void ParseBeatmap(StreamReader stream, Beatmap beatmap) @@ -102,7 +113,7 @@ namespace osu.Game.Beatmaps.Formats beatmap.BeatmapInfo.AudioLeadIn = int.Parse(pair.Value); break; case @"PreviewTime": - metadata.PreviewTime = int.Parse(pair.Value); + metadata.PreviewTime = getOffsetTime(int.Parse(pair.Value)); break; case @"Countdown": beatmap.BeatmapInfo.Countdown = int.Parse(pair.Value) == 1; @@ -257,8 +268,8 @@ namespace osu.Game.Beatmaps.Formats case EventType.Break: var breakEvent = new BreakPeriod { - StartTime = double.Parse(split[1], NumberFormatInfo.InvariantInfo), - EndTime = double.Parse(split[2], NumberFormatInfo.InvariantInfo) + StartTime = getOffsetTime(double.Parse(split[1], NumberFormatInfo.InvariantInfo)), + EndTime = getOffsetTime(double.Parse(split[2], NumberFormatInfo.InvariantInfo)) }; if (!breakEvent.HasEffect) @@ -273,7 +284,7 @@ namespace osu.Game.Beatmaps.Formats { string[] split = line.Split(','); - double time = double.Parse(split[0].Trim(), NumberFormatInfo.InvariantInfo); + double time = getOffsetTime(double.Parse(split[0].Trim(), NumberFormatInfo.InvariantInfo)); double beatLength = double.Parse(split[1].Trim(), NumberFormatInfo.InvariantInfo); double speedMultiplier = beatLength < 0 ? 100.0 / -beatLength : 1; @@ -396,7 +407,14 @@ namespace osu.Game.Beatmaps.Formats var obj = parser.Parse(line); if (obj != null) + { + obj.StartTime = getOffsetTime(obj.StartTime); beatmap.HitObjects.Add(obj); + } } + + private int getOffsetTime(int time) => time + timeOffset; + + private double getOffsetTime(double time) => time + timeOffset; } } From 0a571278c975c3f496b928afed9f576d88c52769 Mon Sep 17 00:00:00 2001 From: jorolf Date: Sun, 4 Mar 2018 14:03:53 +0100 Subject: [PATCH 31/67] change TestCase to OsuTestCase --- osu.Game.Tests/Visual/TestCaseVolumePieces.cs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs index 5bacdf1f58..cfbf7fdb4d 100644 --- a/osu.Game.Tests/Visual/TestCaseVolumePieces.cs +++ b/osu.Game.Tests/Visual/TestCaseVolumePieces.cs @@ -4,13 +4,12 @@ using System; using System.Collections.Generic; using osu.Framework.Graphics; -using osu.Framework.Testing; using osu.Game.Overlays.Volume; using OpenTK.Graphics; namespace osu.Game.Tests.Visual { - public class TestCaseVolumePieces : TestCase + public class TestCaseVolumePieces : OsuTestCase { public override IReadOnlyList RequiredTypes => new[] { typeof(VolumeMeter), typeof(MuteButton) }; @@ -18,11 +17,11 @@ namespace osu.Game.Tests.Visual { VolumeMeter meter; MuteButton mute; - LoadComponentAsync(meter = new VolumeMeter("MASTER", 125, Color4.Blue), Add); - LoadComponentAsync(mute = new MuteButton + Add(meter = new VolumeMeter("MASTER", 125, Color4.Blue)); + Add(mute = new MuteButton { Margin = new MarginPadding { Top = 200 } - }, Add); + }); AddSliderStep("master volume", 0, 10, 0, i => meter.Bindable.Value = i * 0.1); AddToggleStep("mute", b => mute.Current.Value = b); From e46f363fdc3ca492d8a0d1f4e68053276a49b491 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 4 Mar 2018 22:13:43 +0900 Subject: [PATCH 32/67] Fix failing unit test --- .../Formats/LegacyBeatmapDecoderTest.cs | 8 +++---- .../Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- .../Beatmaps/IO/OszArchiveReaderTest.cs | 2 +- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 24 ++++++++++++------- .../Tests/Beatmaps/BeatmapConversionTest.cs | 2 +- 5 files changed, 22 insertions(+), 16 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 21bbc4993c..2e774e0924 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -20,7 +20,7 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestDecodeBeatmapGeneral() { - var decoder = new LegacyBeatmapDecoder(); + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; using (var resStream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) using (var stream = new StreamReader(resStream)) { @@ -110,7 +110,7 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestDecodeBeatmapEvents() { - var decoder = new LegacyBeatmapDecoder(); + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; using (var resStream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) using (var stream = new StreamReader(resStream)) { @@ -128,7 +128,7 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestDecodeBeatmapTimingPoints() { - var decoder = new LegacyBeatmapDecoder(); + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; using (var resStream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) using (var stream = new StreamReader(resStream)) { @@ -187,7 +187,7 @@ namespace osu.Game.Tests.Beatmaps.Formats [Test] public void TestDecodeBeatmapHitObjects() { - var decoder = new LegacyBeatmapDecoder(); + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; using (var resStream = Resource.OpenResource("Soleily - Renatus (Gamu) [Insane].osu")) using (var stream = new StreamReader(resStream)) { diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 186bd44640..8168de091e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -159,7 +159,7 @@ namespace osu.Game.Tests.Beatmaps.Formats using (var sr = new StreamReader(stream)) { - var legacyDecoded = new LegacyBeatmapDecoder().DecodeBeatmap(sr); + var legacyDecoded = new LegacyBeatmapDecoder { ApplyOffsets = false }.DecodeBeatmap(sr); using (var ms = new MemoryStream()) using (var sw = new StreamWriter(ms)) using (var sr2 = new StreamReader(ms)) diff --git a/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs b/osu.Game.Tests/Beatmaps/IO/OszArchiveReaderTest.cs index 7a1c6d9b89..1f7246a119 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, meta.PreviewTime); + Assert.AreEqual(164471 + LegacyBeatmapDecoder.UniversalOffset, meta.PreviewTime); Assert.AreEqual(string.Empty, meta.Source); Assert.AreEqual("MBC7 Unisphere 地球ヤバイEP Chikyu Yabai", meta.Tags); Assert.AreEqual("Renatus", meta.Title); diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 7273fe999f..1d54bc4b0c 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -22,7 +22,18 @@ namespace osu.Game.Beatmaps.Formats private LegacySampleBank defaultSampleBank; private int defaultSampleVolume = 100; - private readonly int timeOffset; + /// + /// 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; public LegacyBeatmapDecoder() { @@ -33,12 +44,7 @@ namespace osu.Game.Beatmaps.Formats BeatmapVersion = int.Parse(header.Substring(17)); // BeatmapVersion 4 and lower had an incorrect offset (stable has this set as 24ms off) - timeOffset += BeatmapVersion < 5 ? 24 : 0; - - // lazer in general doesn't match stable. this is the result of user testing, albeit limited. - // only seems to be required on windows. - if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows) - timeOffset += -22; + offset += BeatmapVersion < 5 ? 24 : 0; } protected override void ParseBeatmap(StreamReader stream, Beatmap beatmap) @@ -413,8 +419,8 @@ namespace osu.Game.Beatmaps.Formats } } - private int getOffsetTime(int time) => time + timeOffset; + private int getOffsetTime(int time) => time + (ApplyOffsets ? offset : 0); - private double getOffsetTime(double time) => time + timeOffset; + private double getOffsetTime(double time) => time + (ApplyOffsets ? offset : 0); } } diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 596dbe84ba..a9b13e87bf 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -109,7 +109,7 @@ namespace osu.Game.Tests.Beatmaps private Beatmap getBeatmap(string name) { - var decoder = new LegacyBeatmapDecoder(); + var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false }; using (var resStream = openResource($"{resource_namespace}.{name}.osu")) using (var stream = new StreamReader(resStream)) return decoder.DecodeBeatmap(stream); From 49b8670dfc917f261a770308ec268d2c8203a8c4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 14:53:57 +0900 Subject: [PATCH 33/67] Fix beatmap conversion tests not properly constructing decoder --- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 596dbe84ba..7423005850 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -109,10 +109,9 @@ namespace osu.Game.Tests.Beatmaps private Beatmap getBeatmap(string name) { - var decoder = new LegacyBeatmapDecoder(); using (var resStream = openResource($"{resource_namespace}.{name}.osu")) using (var stream = new StreamReader(resStream)) - return decoder.DecodeBeatmap(stream); + return Decoder.GetDecoder(stream).DecodeBeatmap(stream); } private Stream openResource(string name) From 63155f169e500c5f92c9f46f167c0236d800da5f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 15:11:50 +0900 Subject: [PATCH 34/67] Fix incorrect taiko slider conversions due to beatlength adjustments Fixes ppy/osu#2152 . --- .../Beatmaps/TaikoBeatmapConverter.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs index e5fe288f20..9d6b5b5ce4 100644 --- a/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs +++ b/osu.Game.Rulesets.Taiko/Beatmaps/TaikoBeatmapConverter.cs @@ -101,16 +101,16 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps // The duration of the taiko hit object double taikoDuration = distance / taikoVelocity; - // For some reason, old osu! always uses speedAdjustment to determine the taiko velocity, but - // only uses it to determine osu! velocity if beatmap version < 8. Let's account for that here. - if (beatmap.BeatmapInfo.BeatmapVersion >= 8) - speedAdjustedBeatLength *= speedAdjustment; - // The velocity of the osu! hit object - calculated as the velocity of a slider double osuVelocity = osu_base_scoring_distance * beatmap.BeatmapInfo.BaseDifficulty.SliderMultiplier * legacy_velocity_multiplier / speedAdjustedBeatLength; // The duration of the osu! hit object double osuDuration = distance / osuVelocity; + // osu-stable always uses the speed-adjusted beatlength to determine the velocities, but + // only uses it for tick rate if beatmap version < 8 + if (beatmap.BeatmapInfo.BeatmapVersion >= 8) + speedAdjustedBeatLength *= speedAdjustment; + // If the drum roll is to be split into hit circles, assume the ticks are 1/8 spaced within the duration of one beat double tickSpacing = Math.Min(speedAdjustedBeatLength / beatmap.BeatmapInfo.BaseDifficulty.SliderTickRate, taikoDuration / spans); From d44dc1a4f928c3a64dc685789e9d21c4a5d680ec Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 16:01:05 +0900 Subject: [PATCH 35/67] Fix SliderMultiplier/SliderTickRate parsing inaccuracy --- osu.Game/Beatmaps/BeatmapDifficulty.cs | 4 ++-- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 4 ++-- 2 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapDifficulty.cs b/osu.Game/Beatmaps/BeatmapDifficulty.cs index 16e6692887..38b84b4b03 100644 --- a/osu.Game/Beatmaps/BeatmapDifficulty.cs +++ b/osu.Game/Beatmaps/BeatmapDifficulty.cs @@ -29,8 +29,8 @@ namespace osu.Game.Beatmaps set => approachRate = value; } - public float SliderMultiplier { get; set; } = 1; - public float SliderTickRate { get; set; } = 1; + public double SliderMultiplier { get; set; } = 1; + public double SliderTickRate { get; set; } = 1; /// /// Maps a difficulty value [0, 10] to a two-piece linear range of values. diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 3e7b36f324..6ca74ebedb 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -232,10 +232,10 @@ namespace osu.Game.Beatmaps.Formats difficulty.ApproachRate = float.Parse(pair.Value, NumberFormatInfo.InvariantInfo); break; case @"SliderMultiplier": - difficulty.SliderMultiplier = float.Parse(pair.Value, NumberFormatInfo.InvariantInfo); + difficulty.SliderMultiplier = double.Parse(pair.Value, NumberFormatInfo.InvariantInfo); break; case @"SliderTickRate": - difficulty.SliderTickRate = float.Parse(pair.Value, NumberFormatInfo.InvariantInfo); + difficulty.SliderTickRate = double.Parse(pair.Value, NumberFormatInfo.InvariantInfo); break; } } From 88c33e31e853f33a90dc80061bd2765aa676c130 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 16:01:45 +0900 Subject: [PATCH 36/67] Add slider conversion testcases --- ...nerating-drumroll-expected-conversion.json | 87 +++++++++++++++++++ .../Beatmaps/slider-generating-drumroll.osu | 25 ++++++ .../Tests/TaikoBeatmapConversionTest.cs | 3 +- .../osu.Game.Rulesets.Taiko.csproj | 2 + 4 files changed, 116 insertions(+), 1 deletion(-) create mode 100644 osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-expected-conversion.json create mode 100644 osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll.osu diff --git a/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-expected-conversion.json b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-expected-conversion.json new file mode 100644 index 0000000000..fc7d466c1b --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll-expected-conversion.json @@ -0,0 +1,87 @@ +{ + "Mappings": [{ + "StartTime": 6590, + "Objects": [{ + "StartTime": 6590, + "EndTime": 8320, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 8436, + "Objects": [{ + "StartTime": 8436, + "EndTime": 10166, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 10282, + "Objects": [{ + "StartTime": 10282, + "EndTime": 12012, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 12128, + "Objects": [{ + "StartTime": 12128, + "EndTime": 13858, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 41666, + "Objects": [{ + "StartTime": 41666, + "EndTime": 42589, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 62666, + "Objects": [{ + "StartTime": 62666, + "EndTime": 63127, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + }, + { + "StartTime": 208743, + "Objects": [{ + "StartTime": 208743, + "EndTime": 209204, + "IsRim": false, + "IsCentre": false, + "IsDrumRoll": true, + "IsSwell": false, + "IsStrong": false + }] + } + ] +} \ No newline at end of file diff --git a/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll.osu b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll.osu new file mode 100644 index 0000000000..4c493b47d4 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Resources/Testing/Beatmaps/slider-generating-drumroll.osu @@ -0,0 +1,25 @@ +osu file format v14 + +[Difficulty] +HPDrainRate:6 +CircleSize:4.2 +OverallDifficulty:9 +ApproachRate:9.8 +SliderMultiplier:1.87 +SliderTickRate:1 + +[TimingPoints] +6590,461.538461538462,4,2,2,15,1,0 +6590,-200,4,2,2,15,0,0 +49051,230.769230769231,4,2,1,15,1,0 +62666,-200,4,2,1,60,0,0 +197666,-100,4,2,1,85,0,1 + +[HitObjects] +88,104,6590,6,0,B|176:156|256:108|256:108|336:60|423:112,1,350.625,6|0,0:0|0:0,0:0:0:0: +396,213,8436,2,0,P|277:247|376:172,1,350.625,6|0,0:0|0:0,0:0:0:0: +472,220,10282,2,0,P|456:288|220:300,1,350.625,6|0,0:0|0:0,0:0:0:0: +277,200,12128,2,0,P|398:225|276:244,1,350.625,6|0,0:0|0:0,0:0:0:0: +268,229,41666,2,0,L|473:210,1,187,2|2,0:0|0:0,0:0:0:0: +133,342,62666,2,0,B|132:316|132:316|128:316|128:316|130:295|130:295|126:296|126:296|129:275|129:275|125:275|125:275|127:254|127:254|123:255|123:255|125:234|125:234|121:234|121:234|123:213|123:213|119:214|119:214|121:193|121:193|118:193|118:193|118:172,1,187,8|8,0:0|0:0,0:0:0:0: +481,338,208743,6,0,P|492:262|383:195,2,187,2|8|2,0:0|0:0|0:0,0:0:0:0: diff --git a/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs index 64f728a018..dd93c7df6a 100644 --- a/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs @@ -21,7 +21,8 @@ namespace osu.Game.Rulesets.Taiko.Tests private bool isForCurrentRuleset; [NonParallelizable] - [TestCase("basic", false), Ignore("See: https://github.com/ppy/osu/issues/2152")] + [TestCase("basic", false)] + [TestCase("slider-generating-drumroll", false)] public void Test(string name, bool isForCurrentRuleset) { this.isForCurrentRuleset = isForCurrentRuleset; diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 07d27455b8..8f0aa88e62 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -149,6 +149,8 @@ + + From a6b6c016d63ca0aa8f38f94e61ee814026460018 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 16:14:36 +0900 Subject: [PATCH 37/67] Fix beatmap decoder tests --- osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs | 2 +- osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs index 21bbc4993c..d1797e3a7d 100644 --- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs @@ -102,7 +102,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(4, difficulty.CircleSize); Assert.AreEqual(8, difficulty.OverallDifficulty); Assert.AreEqual(9, difficulty.ApproachRate); - Assert.AreEqual(1.8f, difficulty.SliderMultiplier); + Assert.AreEqual(1.8, difficulty.SliderMultiplier); Assert.AreEqual(2, difficulty.SliderTickRate); } } diff --git a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs index 186bd44640..fc47aff91e 100644 --- a/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs +++ b/osu.Game.Tests/Beatmaps/Formats/OsuJsonDecoderTest.cs @@ -85,7 +85,7 @@ namespace osu.Game.Tests.Beatmaps.Formats Assert.AreEqual(4, difficulty.CircleSize); Assert.AreEqual(8, difficulty.OverallDifficulty); Assert.AreEqual(9, difficulty.ApproachRate); - Assert.AreEqual(1.8f, difficulty.SliderMultiplier); + Assert.AreEqual(1.8, difficulty.SliderMultiplier); Assert.AreEqual(2, difficulty.SliderTickRate); } From c013f8326786bcedb9019c1cdf5cd6bef9d8b559 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 17:01:27 +0900 Subject: [PATCH 38/67] Restore IgnoreAttribute --- osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs b/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs index dd93c7df6a..385e041ace 100644 --- a/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs +++ b/osu.Game.Rulesets.Taiko/Tests/TaikoBeatmapConversionTest.cs @@ -21,7 +21,7 @@ namespace osu.Game.Rulesets.Taiko.Tests private bool isForCurrentRuleset; [NonParallelizable] - [TestCase("basic", false)] + [TestCase("basic", false), Ignore("See: https://github.com/ppy/osu/issues/2152")] [TestCase("slider-generating-drumroll", false)] public void Test(string name, bool isForCurrentRuleset) { From 7ce3e607224bcf981a4433154413e2975d9b923e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 21:17:26 +0900 Subject: [PATCH 39/67] Fix drumrolls giving GOOD judgements too one tick too late --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 29d464f614..f98e6b936e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -82,8 +82,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables return; int countHit = NestedHitObjects.Count(o => o.IsHit); - - if (countHit > HitObject.RequiredGoodHits) + if (countHit >= HitObject.RequiredGoodHits) { AddJudgement(new TaikoJudgement { Result = countHit >= HitObject.RequiredGreatHits ? HitResult.Great : HitResult.Good }); if (HitObject.IsStrong) From df84b238478bc354139e72303b56359fd339d9ab Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 21:19:04 +0900 Subject: [PATCH 40/67] Fix possible nullref when there are 0 drumroll ticks --- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index f98e6b936e..2735d28769 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (timeOffset < 0) return; - int countHit = NestedHitObjects.Count(o => o.IsHit); + int countHit = NestedHitObjects?.Count(o => o.IsHit) ?? 0; if (countHit >= HitObject.RequiredGoodHits) { AddJudgement(new TaikoJudgement { Result = countHit >= HitObject.RequiredGreatHits ? HitResult.Great : HitResult.Good }); From 02690e5f25135cbecfac4a1e65990d95f6f9ac0b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 5 Mar 2018 21:27:37 +0900 Subject: [PATCH 41/67] Move to private implementation --- osu.Game/Skinning/LegacySkin.cs | 24 ++++++++++++++++++++- osu.Game/Skinning/SkinResourceStore.cs | 29 -------------------------- osu.Game/osu.Game.csproj | 1 - 3 files changed, 23 insertions(+), 31 deletions(-) delete mode 100644 osu.Game/Skinning/SkinResourceStore.cs diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index 97e0bdb942..17fe6369a7 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.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.IO; +using System.Linq; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Graphics; @@ -19,7 +22,7 @@ namespace osu.Game.Skinning public LegacySkin(SkinInfo skin, IResourceStore storage, AudioManager audioManager) : base(skin) { - storage = new SkinResourceStore(skin, storage); + storage = new LegacySkinResourceStore(skin, storage); samples = audioManager.GetSampleManager(storage); textures = new TextureStore(new RawTextureLoaderStore(storage)); } @@ -38,5 +41,24 @@ namespace osu.Game.Skinning } public override SampleChannel GetSample(string sampleName) => samples.Get(sampleName); + + private class LegacySkinResourceStore : IResourceStore + { + private readonly SkinInfo skin; + private readonly IResourceStore underlyingStore; + + private string getPathForFile(string filename) => + skin.Files.FirstOrDefault(f => string.Equals(Path.GetFileNameWithoutExtension(f.Filename), filename.Split('/').Last(), StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath; + + public LegacySkinResourceStore(SkinInfo skin, IResourceStore underlyingStore) + { + this.skin = skin; + this.underlyingStore = underlyingStore; + } + + public Stream GetStream(string name) => underlyingStore.GetStream(getPathForFile(name)); + + byte[] IResourceStore.Get(string name) => underlyingStore.Get(getPathForFile(name)); + } } } diff --git a/osu.Game/Skinning/SkinResourceStore.cs b/osu.Game/Skinning/SkinResourceStore.cs deleted file mode 100644 index 58da8ad19a..0000000000 --- a/osu.Game/Skinning/SkinResourceStore.cs +++ /dev/null @@ -1,29 +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.IO; -using System.Linq; -using osu.Framework.IO.Stores; - -namespace osu.Game.Skinning -{ - public class SkinResourceStore : IResourceStore - { - private readonly SkinInfo skin; - private readonly IResourceStore underlyingStore; - - private string getPathForFile(string filename) => - skin.Files.FirstOrDefault(f => string.Equals(Path.GetFileNameWithoutExtension(f.Filename), filename.Split('/').Last(), StringComparison.InvariantCultureIgnoreCase))?.FileInfo.StoragePath; - - public SkinResourceStore(SkinInfo skin, IResourceStore underlyingStore) - { - this.skin = skin; - this.underlyingStore = underlyingStore; - } - - public Stream GetStream(string name) => underlyingStore.GetStream(getPathForFile(name)); - - byte[] IResourceStore.Get(string name) => underlyingStore.Get(getPathForFile(name)); - } -} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index d4bd5a0013..37e304d62d 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -870,7 +870,6 @@ - From 2a9fb2c2c60966fd64333abffdf3e7bea79e9d49 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 5 Mar 2018 21:40:26 +0900 Subject: [PATCH 42/67] Make NestedHitObjects lazily-constructed --- .../Objects/Drawables/DrawableDrumRoll.cs | 2 +- .../Objects/Drawables/DrawableHitObject.cs | 16 +++++++--------- .../OverlappingSpeedChangeVisualiser.cs | 2 +- .../SequentialSpeedChangeVisualiser.cs | 2 +- 4 files changed, 10 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 2735d28769..f98e6b936e 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables if (timeOffset < 0) return; - int countHit = NestedHitObjects?.Count(o => o.IsHit) ?? 0; + int countHit = NestedHitObjects.Count(o => o.IsHit); if (countHit >= HitObject.RequiredGoodHits) { AddJudgement(new TaikoJudgement { Result = countHit >= HitObject.RequiredGreatHits ? HitResult.Great : HitResult.Good }); diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 4c2683b389..394b6fa9fd 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -35,8 +35,9 @@ namespace osu.Game.Rulesets.Objects.Drawables protected virtual IEnumerable GetSamples() => HitObject.Samples; - private List nestedHitObjects; - public IReadOnlyList NestedHitObjects => nestedHitObjects; + private readonly Lazy> nestedHitObjects = new Lazy>(); + public bool HasNestedHitObjects => nestedHitObjects.IsValueCreated; + public IReadOnlyList NestedHitObjects => nestedHitObjects.Value; public event Action OnJudgement; public event Action OnJudgementRemoved; @@ -52,12 +53,12 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// Whether this and all of its nested s have been hit. /// - public bool IsHit => Judgements.Any(j => j.Final && j.IsHit) && (NestedHitObjects?.All(n => n.IsHit) ?? true); + public bool IsHit => Judgements.Any(j => j.Final && j.IsHit) && (!HasNestedHitObjects || NestedHitObjects.All(n => n.IsHit)); /// /// Whether this and all of its nested s have been judged. /// - public bool AllJudged => (!ProvidesJudgement || judgementFinalized) && (NestedHitObjects?.All(h => h.AllJudged) ?? true); + public bool AllJudged => (!ProvidesJudgement || judgementFinalized) && (!HasNestedHitObjects || NestedHitObjects.All(h => h.AllJudged)); /// /// Whether this can be judged. @@ -160,14 +161,11 @@ namespace osu.Game.Rulesets.Objects.Drawables protected virtual void AddNested(DrawableHitObject h) { - if (nestedHitObjects == null) - nestedHitObjects = new List(); - h.OnJudgement += (d, j) => OnJudgement?.Invoke(d, j); h.OnJudgementRemoved += (d, j) => OnJudgementRemoved?.Invoke(d, j); h.ApplyCustomUpdateState += (d, j) => ApplyCustomUpdateState?.Invoke(d, j); - nestedHitObjects.Add(h); + nestedHitObjects.Value.Add(h); } /// @@ -211,7 +209,7 @@ namespace osu.Game.Rulesets.Objects.Drawables if (AllJudged) return false; - if (NestedHitObjects != null) + if (HasNestedHitObjects) foreach (var d in NestedHitObjects) judgementOccurred |= d.UpdateJudgement(userTriggered); diff --git a/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs b/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs index 4cce90ee94..48c212efa7 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Visualisers var controlPoint = controlPointAt(obj.HitObject.StartTime); obj.LifetimeStart = obj.HitObject.StartTime - timeRange / controlPoint.Multiplier; - if (obj.NestedHitObjects != null) + if (obj.HasNestedHitObjects) { ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); ComputePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); diff --git a/osu.Game/Rulesets/UI/Scrolling/Visualisers/SequentialSpeedChangeVisualiser.cs b/osu.Game/Rulesets/UI/Scrolling/Visualisers/SequentialSpeedChangeVisualiser.cs index 94705426f8..1b7c3714d6 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Visualisers/SequentialSpeedChangeVisualiser.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Visualisers/SequentialSpeedChangeVisualiser.cs @@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Visualisers } } - if (obj.NestedHitObjects != null) + if (obj.HasNestedHitObjects) { ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); ComputePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); From c4c1b0b6ffb7d366e7d786d5ebb209b5e093f3c0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 01:39:01 +0900 Subject: [PATCH 43/67] Fix merge regression --- osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs index 7423005850..219d805bc1 100644 --- a/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs +++ b/osu.Game/Tests/Beatmaps/BeatmapConversionTest.cs @@ -111,7 +111,11 @@ namespace osu.Game.Tests.Beatmaps { using (var resStream = openResource($"{resource_namespace}.{name}.osu")) using (var stream = new StreamReader(resStream)) - return Decoder.GetDecoder(stream).DecodeBeatmap(stream); + { + var decoder = Decoder.GetDecoder(stream); + ((LegacyBeatmapDecoder)decoder).ApplyOffsets = false; + return decoder.DecodeBeatmap(stream); + } } private Stream openResource(string name) From 90828cca8fcf5b692564eafa5b43203165567bdb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 08:59:02 +0900 Subject: [PATCH 44/67] Fix left and right arrows keys in chat overlay not working Misplaced override. Resolves ppy/osu-framework#1444 --- osu.Game/Graphics/UserInterface/FocusedTextBox.cs | 2 -- osu.Game/Graphics/UserInterface/SearchTextBox.cs | 2 ++ 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs index 43a3f06236..6d9bf231c3 100644 --- a/osu.Game/Graphics/UserInterface/FocusedTextBox.cs +++ b/osu.Game/Graphics/UserInterface/FocusedTextBox.cs @@ -18,8 +18,6 @@ namespace osu.Game.Graphics.UserInterface public Action Exit; - public override bool HandleLeftRightArrows => false; - private bool focus; public bool HoldFocus { diff --git a/osu.Game/Graphics/UserInterface/SearchTextBox.cs b/osu.Game/Graphics/UserInterface/SearchTextBox.cs index 9398eb55f3..28d33bbacd 100644 --- a/osu.Game/Graphics/UserInterface/SearchTextBox.cs +++ b/osu.Game/Graphics/UserInterface/SearchTextBox.cs @@ -12,6 +12,8 @@ namespace osu.Game.Graphics.UserInterface { protected virtual bool AllowCommit => false; + public override bool HandleLeftRightArrows => false; + public SearchTextBox() { Height = 35; From 9669c5aee3fa3770bb9639fe3d600087fb0b90c0 Mon Sep 17 00:00:00 2001 From: naoey Date: Sun, 4 Mar 2018 00:01:47 +0530 Subject: [PATCH 45/67] Make locally used things local and rename method. --- .../Sections/Recent/DrawableRecentActivity.cs | 65 ++++++++++++------- 1 file changed, 40 insertions(+), 25 deletions(-) diff --git a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs index 4785b1e8d3..2dde8a3d54 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/DrawableRecentActivity.cs @@ -20,10 +20,6 @@ namespace osu.Game.Overlays.Profile.Sections.Recent private readonly RecentActivity activity; - private string userLinkTemplate; - private string beatmapLinkTemplate; - private string beatmapsetLinkTemplate; - private LinkFlowContainer content; public DrawableRecentActivity(RecentActivity activity) @@ -36,10 +32,6 @@ namespace osu.Game.Overlays.Profile.Sections.Recent { this.api = api; - userLinkTemplate = $"[{toAbsoluteUrl(activity.User?.Url)} {activity.User?.Username}]"; - beatmapLinkTemplate = $"[{toAbsoluteUrl(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; - beatmapsetLinkTemplate = $"[{toAbsoluteUrl(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; - LeftFlowContainer.Padding = new MarginPadding { Left = 10, Right = 160 }; LeftFlowContainer.Add(content = new LinkFlowContainer @@ -58,7 +50,7 @@ namespace osu.Game.Overlays.Profile.Sections.Recent Colour = OsuColour.Gray(0xAA), }); - var formatted = MessageFormatter.FormatText(activityToString()); + var formatted = createMessage(); content.AddLinks(formatted.Text, formatted.Links); } @@ -95,56 +87,79 @@ namespace osu.Game.Overlays.Profile.Sections.Recent private string toAbsoluteUrl(string url) => $"{api.Endpoint}{url}"; - private string activityToString() + private MessageFormatter.MessageFormatterResult createMessage() { + string userLinkTemplate() => $"[{toAbsoluteUrl(activity.User?.Url)} {activity.User?.Username}]"; + string beatmapLinkTemplate() => $"[{toAbsoluteUrl(activity.Beatmap?.Url)} {activity.Beatmap?.Title}]"; + string beatmapsetLinkTemplate() => $"[{toAbsoluteUrl(activity.Beatmapset?.Url)} {activity.Beatmapset?.Title}]"; + + string message; + switch (activity.Type) { case RecentActivityType.Achievement: - return $"{userLinkTemplate} unlocked the {activity.Achievement.Name} medal!"; + message = $"{userLinkTemplate()} unlocked the {activity.Achievement.Name} medal!"; + break; case RecentActivityType.BeatmapPlaycount: - return $"{beatmapLinkTemplate} has been played {activity.Count} times!"; + message = $"{beatmapLinkTemplate()} has been played {activity.Count} times!"; + break; case RecentActivityType.BeatmapsetApprove: - return $"{beatmapsetLinkTemplate} has been {activity.Approval.ToString().ToLowerInvariant()}!"; + message = $"{beatmapsetLinkTemplate()} has been {activity.Approval.ToString().ToLowerInvariant()}!"; + break; case RecentActivityType.BeatmapsetDelete: - return $"{beatmapsetLinkTemplate} has been deleted."; + message = $"{beatmapsetLinkTemplate()} has been deleted."; + break; case RecentActivityType.BeatmapsetRevive: - return $"{beatmapsetLinkTemplate} has been revived from eternal slumber by {userLinkTemplate}."; + message = $"{beatmapsetLinkTemplate()} has been revived from eternal slumber by {userLinkTemplate()}."; + break; case RecentActivityType.BeatmapsetUpdate: - return $"{userLinkTemplate} has updated the beatmap {beatmapsetLinkTemplate}!"; + message = $"{userLinkTemplate()} has updated the beatmap {beatmapsetLinkTemplate()}!"; + break; case RecentActivityType.BeatmapsetUpload: - return $"{userLinkTemplate} has submitted a new beatmap {beatmapsetLinkTemplate}!"; + message = $"{userLinkTemplate()} has submitted a new beatmap {beatmapsetLinkTemplate()}!"; + break; case RecentActivityType.Medal: // apparently this shouldn't exist look at achievement instead (https://github.com/ppy/osu-web/blob/master/resources/assets/coffee/react/profile-page/recent-activity.coffee#L111) - return string.Empty; + message = string.Empty; + break; case RecentActivityType.Rank: - return $"{userLinkTemplate} achieved rank #{activity.Rank} on {beatmapLinkTemplate} ({activity.Mode}!)"; + message = $"{userLinkTemplate()} achieved rank #{activity.Rank} on {beatmapLinkTemplate()} ({activity.Mode}!)"; + break; case RecentActivityType.RankLost: - return $"{userLinkTemplate} has lost first place on {beatmapLinkTemplate} ({activity.Mode}!)"; + message = $"{userLinkTemplate()} has lost first place on {beatmapLinkTemplate()} ({activity.Mode}!)"; + break; case RecentActivityType.UserSupportAgain: - return $"{userLinkTemplate} has once again chosen to support osu! - thanks for your generosity!"; + message = $"{userLinkTemplate()} has once again chosen to support osu! - thanks for your generosity!"; + break; case RecentActivityType.UserSupportFirst: - return $"{userLinkTemplate} has become an osu! supporter - thanks for your generosity!"; + message = $"{userLinkTemplate()} has become an osu! supporter - thanks for your generosity!"; + break; case RecentActivityType.UserSupportGift: - return $"{userLinkTemplate} has received the gift of osu! supporter!"; + message = $"{userLinkTemplate()} has received the gift of osu! supporter!"; + break; case RecentActivityType.UsernameChange: - return $"{activity.User.PreviousUsername} has changed their username to {userLinkTemplate}!"; + message = $"{activity.User?.PreviousUsername} has changed their username to {userLinkTemplate()}!"; + break; default: - return string.Empty; + message = string.Empty; + break; } + + return MessageFormatter.FormatText(message); } } } From 148551afa2874088f34319a20c0ed967d377a526 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 6 Mar 2018 14:12:37 +0900 Subject: [PATCH 46/67] osu!-side changes in-line with framework layout changes --- osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs | 2 +- osu.Game/Screens/Menu/FlowContainerWithOrigin.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs index 9f028490ef..5e92eead46 100644 --- a/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs +++ b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs @@ -12,6 +12,6 @@ namespace osu.Game.Graphics.Containers { protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); - protected override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); + public override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); } } diff --git a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs index 29ae35fca4..e61c309931 100644 --- a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs +++ b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs @@ -22,7 +22,7 @@ namespace osu.Game.Screens.Menu protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); - protected override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); + public override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); public override Anchor Origin => Anchor.Custom; From 27e0ed4ea8fb6299ddc8b8c54949fbd9bbf6dccc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 6 Mar 2018 14:16:17 +0900 Subject: [PATCH 47/67] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 71900dc350..adf1e9548d 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 71900dc350bcebbb60d912d4023a1d2a6bbbc3c1 +Subproject commit adf1e9548d1fff8717c87eedb358a3c2517358a8 From 78d73d4c11c40772221a75a9dd859a5e92aec1b9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 6 Mar 2018 17:20:58 +0900 Subject: [PATCH 48/67] Additional fixes for flow ordering after framework changes --- .../ReverseChildIDFillFlowContainer.cs | 4 --- .../Graphics/UserInterface/OsuTabControl.cs | 14 +++++++++ osu.Game/Overlays/Chat/ChatTabControl.cs | 4 +-- osu.Game/Overlays/Music/PlaylistList.cs | 20 +++++-------- osu.Game/Overlays/NotificationOverlay.cs | 5 ++-- .../Notifications/NotificationSection.cs | 7 +++-- .../Sections/Ranks/DrawableProfileScore.cs | 10 ++++--- osu.Game/Overlays/Settings/SettingsItem.cs | 3 +- .../Screens/Menu/FlowContainerWithOrigin.cs | 4 --- osu.Game/Screens/Select/Footer.cs | 30 +++++++++++-------- .../Select/Options/BeatmapOptionsOverlay.cs | 7 +++-- 11 files changed, 63 insertions(+), 45 deletions(-) diff --git a/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs index 5e92eead46..5803c8a5db 100644 --- a/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.cs +++ b/osu.Game/Graphics/Containers/ReverseChildIDFillFlowContainer.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.Collections.Generic; -using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -11,7 +9,5 @@ namespace osu.Game.Graphics.Containers public class ReverseChildIDFillFlowContainer : FillFlowContainer where T : Drawable { protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); - - public override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); } } diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 7ad9bc73a8..20385a7dae 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -9,6 +9,7 @@ using osu.Framework.Allocation; using osu.Framework.Extensions; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.UserInterface; @@ -56,6 +57,14 @@ namespace osu.Game.Graphics.UserInterface } } + protected override TabFillFlowContainer CreateTabFlow() => new OsuTabFillFlowContainer + { + Direction = FillDirection.Full, + RelativeSizeAxes = Axes.Both, + Depth = -1, + Masking = true + }; + public class OsuTabItem : TabItem, IHasAccentColour { protected readonly SpriteText Text; @@ -239,5 +248,10 @@ namespace osu.Game.Graphics.UserInterface } } } + + private class OsuTabFillFlowContainer : TabFillFlowContainer + { + protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); + } } } diff --git a/osu.Game/Overlays/Chat/ChatTabControl.cs b/osu.Game/Overlays/Chat/ChatTabControl.cs index f028590bb4..1d3dab249d 100644 --- a/osu.Game/Overlays/Chat/ChatTabControl.cs +++ b/osu.Game/Overlays/Chat/ChatTabControl.cs @@ -53,9 +53,9 @@ namespace osu.Game.Overlays.Chat protected override void AddTabItem(TabItem item, bool addToDropdown = true) { - if (selectorTab.Depth < float.MaxValue) + if (item != selectorTab && TabContainer.GetLayoutPosition(selectorTab) < float.MaxValue) // performTabSort might've made selectorTab's position wonky, fix it - TabContainer.ChangeChildDepth(selectorTab, float.MaxValue); + TabContainer.SetLayoutPosition(selectorTab, float.MaxValue); base.AddTabItem(item, addToDropdown); diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 31b7d0f9aa..03ce7fd88f 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -101,11 +101,10 @@ namespace osu.Game.Overlays.Music public void AddBeatmapSet(BeatmapSetInfo beatmapSet) { - items.Add(new PlaylistItem(beatmapSet) - { - OnSelect = set => OnSelect?.Invoke(set), - Depth = items.Count - }); + var newItem = new PlaylistItem(beatmapSet) { OnSelect = set => OnSelect?.Invoke(set) }; + + items.Add(newItem); + items.SetLayoutPosition(newItem, items.Count); } public void RemoveBeatmapSet(BeatmapSetInfo beatmapSet) @@ -197,7 +196,7 @@ namespace osu.Game.Overlays.Music { var itemsPos = items.ToLocalSpace(nativeDragPosition); - int srcIndex = (int)draggedItem.Depth; + int srcIndex = (int)items.GetLayoutPosition(draggedItem); // Find the last item with position < mouse position. Note we can't directly use // the item positions as they are being transformed @@ -219,15 +218,15 @@ namespace osu.Game.Overlays.Music if (srcIndex < dstIndex) { for (int i = srcIndex + 1; i <= dstIndex; i++) - items.ChangeChildDepth(items[i], i - 1); + items.SetLayoutPosition(items[i], i - 1); } else { for (int i = dstIndex; i < srcIndex; i++) - items.ChangeChildDepth(items[i], i + 1); + items.SetLayoutPosition(items[i], i + 1); } - items.ChangeChildDepth(draggedItem, dstIndex); + items.SetLayoutPosition(draggedItem, dstIndex); } private class ItemSearchContainer : FillFlowContainer, IHasFilterableChildren @@ -243,9 +242,6 @@ namespace osu.Game.Overlays.Music } } - // Compare with reversed ChildID and Depth - protected override int Compare(Drawable x, Drawable y) => base.Compare(y, x); - public IEnumerable FilterableChildren => Children; public ItemSearchContainer() diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 2f46bb4a71..48ad507d88 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -129,7 +129,6 @@ namespace osu.Game.Overlays public void Post(Notification notification) => postScheduler.Add(() => { ++runningDepth; - notification.Depth = notification.DisplayOnTop ? runningDepth : -runningDepth; notification.Closed += notificationClosed; @@ -138,7 +137,9 @@ namespace osu.Game.Overlays hasCompletionTarget.CompletionTarget = Post; var ourType = notification.GetType(); - sections.Children.FirstOrDefault(s => s.AcceptTypes.Any(accept => accept.IsAssignableFrom(ourType)))?.Add(notification); + + var section = sections.Children.FirstOrDefault(s => s.AcceptTypes.Any(accept => accept.IsAssignableFrom(ourType))); + section?.Add(notification, notification.DisplayOnTop ? -runningDepth : runningDepth); updateCounts(); }); diff --git a/osu.Game/Overlays/Notifications/NotificationSection.cs b/osu.Game/Overlays/Notifications/NotificationSection.cs index 13a69fbe3a..533f5326e3 100644 --- a/osu.Game/Overlays/Notifications/NotificationSection.cs +++ b/osu.Game/Overlays/Notifications/NotificationSection.cs @@ -25,10 +25,13 @@ namespace osu.Game.Overlays.Notifications private FlowContainer notifications; public int DisplayedCount => notifications.Count(n => !n.WasClosed); - public int UnreadCount => notifications.Count(n => !n.WasClosed && !n.Read); - public void Add(Notification notification) => notifications.Add(notification); + public void Add(Notification notification, float position) + { + notifications.Add(notification); + notifications.SetLayoutPosition(notification, position); + } public IEnumerable AcceptTypes; diff --git a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs index 51b202844a..bb1a409f2e 100644 --- a/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs +++ b/osu.Game/Overlays/Profile/Sections/Ranks/DrawableProfileScore.cs @@ -40,16 +40,18 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks [BackgroundDependencyLoader(true)] private void load(OsuColour colour) { - RightFlowContainer.Add(new OsuSpriteText + var text = new OsuSpriteText { Text = $"accuracy: {Score.Accuracy:P2}", Anchor = Anchor.TopRight, Origin = Anchor.TopRight, Colour = colour.GrayA, TextSize = 11, - Font = "Exo2.0-RegularItalic", - Depth = -1, - }); + Font = "Exo2.0-RegularItalic" + }; + + RightFlowContainer.Add(text); + RightFlowContainer.SetLayoutPosition(text, 1); LeftFlowContainer.Add(new BeatmapMetadataContainer(Score.Beatmap)); LeftFlowContainer.Add(new OsuSpriteText diff --git a/osu.Game/Overlays/Settings/SettingsItem.cs b/osu.Game/Overlays/Settings/SettingsItem.cs index 5afc415d83..cc290fe1bb 100644 --- a/osu.Game/Overlays/Settings/SettingsItem.cs +++ b/osu.Game/Overlays/Settings/SettingsItem.cs @@ -45,7 +45,8 @@ namespace osu.Game.Overlays.Settings if (text == null) { // construct lazily for cases where the label is not needed (may be provided by the Control). - Add(text = new OsuSpriteText { Depth = 1 }); + Add(text = new OsuSpriteText()); + FlowContent.SetLayoutPosition(text, -1); } text.Text = value; diff --git a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs index e61c309931..ae1e995373 100644 --- a/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs +++ b/osu.Game/Screens/Menu/FlowContainerWithOrigin.cs @@ -4,8 +4,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using OpenTK; -using System.Collections.Generic; -using System.Linq; namespace osu.Game.Screens.Menu { @@ -22,8 +20,6 @@ namespace osu.Game.Screens.Menu protected override int Compare(Drawable x, Drawable y) => CompareReverseChildID(x, y); - public override IEnumerable FlowingChildren => base.FlowingChildren.Reverse(); - public override Anchor Origin => Anchor.Custom; public override Vector2 OriginPosition diff --git a/osu.Game/Screens/Select/Footer.cs b/osu.Game/Screens/Select/Footer.cs index 21e6108489..be83d7b500 100644 --- a/osu.Game/Screens/Select/Footer.cs +++ b/osu.Game/Screens/Select/Footer.cs @@ -41,19 +41,25 @@ namespace osu.Game.Screens.Select /// Higher depth to be put on the left, and lower to be put on the right. /// Notice this is different to ! /// - public void AddButton(string text, Color4 colour, Action action, Key? hotkey = null, float depth = 0) => buttons.Add(new FooterButton + public void AddButton(string text, Color4 colour, Action action, Key? hotkey = null, float depth = 0) { - Text = text, - Height = play_song_select_button_height, - Width = play_song_select_button_width, - Depth = depth, - SelectedColour = colour, - DeselectedColour = colour.Opacity(0.5f), - Hotkey = hotkey, - Hovered = updateModeLight, - HoverLost = updateModeLight, - Action = action, - }); + var button = new FooterButton + { + Text = text, + Height = play_song_select_button_height, + Width = play_song_select_button_width, + Depth = depth, + SelectedColour = colour, + DeselectedColour = colour.Opacity(0.5f), + Hotkey = hotkey, + Hovered = updateModeLight, + HoverLost = updateModeLight, + Action = action, + }; + + buttons.Add(button); + buttons.SetLayoutPosition(button, -depth); + } private readonly List overlays = new List(); diff --git a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs index 2e8b2f9014..dee1ec4511 100644 --- a/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs +++ b/osu.Game/Screens/Select/Options/BeatmapOptionsOverlay.cs @@ -95,7 +95,7 @@ namespace osu.Game.Screens.Select.Options /// public void AddButton(string firstLine, string secondLine, FontAwesome icon, Color4 colour, Action action, Key? hotkey = null, float depth = 0) { - buttonsContainer.Add(new BeatmapOptionsButton + var button = new BeatmapOptionsButton { FirstLineText = firstLine, SecondLineText = secondLine, @@ -108,7 +108,10 @@ namespace osu.Game.Screens.Select.Options action?.Invoke(); }, HotKey = hotkey - }); + }; + + buttonsContainer.Add(button); + buttonsContainer.SetLayoutPosition(button, depth); } } } From 07bf8549ebffabfd40fdce3f3db3a756e90a4037 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 17:29:22 +0900 Subject: [PATCH 49/67] Fix arbitrary API request errors getting identified as timeouts --- osu.Game/Online/API/APIAccess.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Online/API/APIAccess.cs b/osu.Game/Online/API/APIAccess.cs index 90f3999ddd..1325179e0d 100644 --- a/osu.Game/Online/API/APIAccess.cs +++ b/osu.Game/Online/API/APIAccess.cs @@ -199,7 +199,7 @@ namespace osu.Game.Online.API } catch (WebException we) { - HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode ?? HttpStatusCode.RequestTimeout; + HttpStatusCode statusCode = (we.Response as HttpWebResponse)?.StatusCode ?? (we.Status == WebExceptionStatus.UnknownError ? HttpStatusCode.NotAcceptable : HttpStatusCode.RequestTimeout); switch (statusCode) { From e82cadc811de0413e6b566b2a6b8762c26f5ab55 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 17:29:58 +0900 Subject: [PATCH 50/67] Make LegacyID nullable The -1 default was getting stored to the database. --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 2 +- 5 files changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index d49e9c7c26..4dbe65b3ce 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -101,7 +101,7 @@ namespace osu.Game.Rulesets.Catch public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new CatchDifficultyCalculator(beatmap); - public override int LegacyID => 2; + public override int? LegacyID => 2; public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new CatchReplayFrame(); diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 3ad498e6ea..16b6888f2b 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.Mania public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new ManiaDifficultyCalculator(beatmap); - public override int LegacyID => 3; + public override int? LegacyID => 3; public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new ManiaReplayFrame(); diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 3f0aea5cb2..d407835a96 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -145,7 +145,7 @@ namespace osu.Game.Rulesets.Osu public override SettingsSubsection CreateSettings() => new OsuSettings(); - public override int LegacyID => 0; + public override int? LegacyID => 0; public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new OsuReplayFrame(); diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 713506e831..0a9719f27b 100644 --- a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs +++ b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs @@ -103,7 +103,7 @@ namespace osu.Game.Rulesets.Taiko public override DifficultyCalculator CreateDifficultyCalculator(Beatmap beatmap, Mod[] mods = null) => new TaikoDifficultyCalculator(beatmap); - public override int LegacyID => 1; + public override int? LegacyID => 1; public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new TaikoReplayFrame(); diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index f9b64995f9..cba849a491 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -64,7 +64,7 @@ namespace osu.Game.Rulesets /// /// Do not override this unless you are a legacy mode. /// - public virtual int LegacyID => -1; + public virtual int? LegacyID => null; /// /// A unique short name to reference this ruleset in online requests. From 7cf1d4450ac671f7c6a44e1d08b4c14ce7e0dbc6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 17:33:42 +0900 Subject: [PATCH 51/67] SliderTick transform improvements --- .../Objects/Drawables/DrawableSliderTick.cs | 16 ++++++++-------- 1 file changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index baa9eac1a3..c2d13e4e08 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -31,6 +31,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables BorderThickness = 2; BorderColour = Color4.White; + Alpha = 0; + Children = new Drawable[] { new Box @@ -50,10 +52,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables protected override void UpdatePreemptState() { - this.Animate( - d => d.FadeIn(ANIM_DURATION), - d => d.ScaleTo(0.5f).ScaleTo(1f, ANIM_DURATION * 4, Easing.OutElasticHalf) - ); + this.FadeOut().FadeIn(ANIM_DURATION); + this.ScaleTo(0.5f).ScaleTo(1f, ANIM_DURATION * 4, Easing.OutElasticHalf); } protected override void UpdateCurrentState(ArmedState state) @@ -64,12 +64,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables this.Delay(HitObject.TimePreempt).FadeOut(); break; case ArmedState.Miss: - this.FadeOut(ANIM_DURATION) - .FadeColour(Color4.Red, ANIM_DURATION / 2); + this.FadeOut(ANIM_DURATION); + this.FadeColour(Color4.Red, ANIM_DURATION / 2); break; case ArmedState.Hit: - this.FadeOut(ANIM_DURATION, Easing.OutQuint) - .ScaleTo(Scale * 1.5f, ANIM_DURATION, Easing.Out); + this.FadeOut(ANIM_DURATION, Easing.OutQuint); + this.ScaleTo(Scale * 1.5f, ANIM_DURATION, Easing.Out); break; } } From 4dfd3a61ccd8b0fb6871d29ef1f1269bd47f9a2a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 6 Mar 2018 18:40:39 +0900 Subject: [PATCH 52/67] Remove alpha setting --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index c2d13e4e08..058e3606f4 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -31,8 +31,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables BorderThickness = 2; BorderColour = Color4.White; - Alpha = 0; - Children = new Drawable[] { new Box From 08c469a8b3494446ea5d4d9e7294164a86cfc9f3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 13:22:08 +0900 Subject: [PATCH 53/67] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index adf1e9548d..6372fb22c1 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit adf1e9548d1fff8717c87eedb358a3c2517358a8 +Subproject commit 6372fb22c1c85f600921a139849b8dedf71026d5 From e2f9e237e8dc8e73174f62cf7fc35744041c86e6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:07:04 +0900 Subject: [PATCH 54/67] Use GradientHorizontal helper function --- osu.Game/Overlays/VolumeOverlay.cs | 8 +------- 1 file changed, 1 insertion(+), 7 deletions(-) diff --git a/osu.Game/Overlays/VolumeOverlay.cs b/osu.Game/Overlays/VolumeOverlay.cs index f764a83c7a..17a4b139b0 100644 --- a/osu.Game/Overlays/VolumeOverlay.cs +++ b/osu.Game/Overlays/VolumeOverlay.cs @@ -43,13 +43,7 @@ namespace osu.Game.Overlays { RelativeSizeAxes = Axes.Y, Width = 300, - Colour = new ColourInfo - { - TopLeft = Color4.Black.Opacity(0.75f), - BottomLeft = Color4.Black.Opacity(0.75f), - TopRight = Color4.Black.Opacity(0), - BottomRight = Color4.Black.Opacity(0), - } + Colour = ColourInfo.GradientHorizontal(Color4.Black.Opacity(0.75f), Color4.Black.Opacity(0)) }, new FillFlowContainer { From fac4cd6a32b63463163c6a91bd5490bf6149c525 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:19:31 +0900 Subject: [PATCH 55/67] Move to overlayContent --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index a6f650d23d..e2bc240e8c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -232,7 +232,7 @@ namespace osu.Game }, }, overlayContent.Add); - loadComponentSingleFile(volume = new VolumeOverlay(), Add); + loadComponentSingleFile(volume = new VolumeOverlay(), overlayContent.Add); loadComponentSingleFile(onscreenDisplay = new OnScreenDisplay(), Add); //overlay elements From 51a9dd038ee5c09b429706e71710c85bfb0e3b71 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:38:41 +0900 Subject: [PATCH 56/67] Add default bindable values --- osu.Game/Overlays/Volume/VolumeMeter.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 984ade9de0..c840eb790d 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -26,7 +26,7 @@ namespace osu.Game.Overlays.Volume public class VolumeMeter : Container, IKeyBindingHandler { private CircularProgress volumeCircle; - public BindableDouble Bindable { get; } = new BindableDouble(); + public BindableDouble Bindable { get; } = new BindableDouble { MinValue = 0, MaxValue = 1 }; private readonly float circleSize; private readonly Color4 meterColour; private readonly string name; From 05a13d4d393e10cdd87e06ebb9ef7c89cf8b7de8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:50:50 +0900 Subject: [PATCH 57/67] Improve the way bindings are done --- osu.Game/Overlays/Volume/VolumeMeter.cs | 46 +++++++++++++------------ 1 file changed, 24 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index c840eb790d..99ac4d3a79 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -3,7 +3,6 @@ using System; using System.Globalization; -using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Extensions.Color4Extensions; @@ -14,7 +13,6 @@ using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Transforms; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Bindings; -using osu.Framework.MathUtils; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using osu.Game.Input.Bindings; @@ -31,6 +29,9 @@ namespace osu.Game.Overlays.Volume private readonly Color4 meterColour; private readonly string name; + private OsuSpriteText text; + private BufferedContainer maxGlow; + public VolumeMeter(string name, float circleSize, Color4 meterColour) { this.circleSize = circleSize; @@ -69,9 +70,7 @@ namespace osu.Game.Overlays.Volume } }); - OsuSpriteText text; CircularProgress bgProgress; - BufferedContainer maxGlow; Add(new CircularContainer { @@ -122,33 +121,36 @@ namespace osu.Game.Overlays.Volume } }); - Bindable.ValueChanged += newVolume => this.TransformTo("circleBindable", newVolume * 0.75, 250, Easing.OutQuint); - volumeCircle.Current.ValueChanged += newVolume => //by using this event we sync the meter with the text. newValue has to be divided by 0.75 to give the actual percentage + Bindable.ValueChanged += newVolume => { this.TransformTo("DisplayVolume", newVolume, 400, Easing.OutQuint); }; + + bgProgress.Current.Value = 0.75f; + } + + private double displayVolume; + + /// + /// This is needed because doesn't support + /// + protected double DisplayVolume + { + get => displayVolume; + set { - if (Precision.DefinitelyBigger(newVolume, 0.74)) + displayVolume = value; + + if (displayVolume > 0.99f) { text.Text = "MAX"; maxGlow.EffectColour = meterColour.Opacity(2f); } else { - if (text.Text == "MAX") - maxGlow.EffectColour = Color4.Transparent; - text.Text = Math.Round(newVolume / 0.0075).ToString(CultureInfo.CurrentCulture); + maxGlow.EffectColour = Color4.Transparent; + text.Text = Math.Round(displayVolume * 100).ToString(CultureInfo.CurrentCulture); } - }; - bgProgress.Current.Value = 0.75f; - } - - /// - /// This is needed because doesn't support - /// - [UsedImplicitly] - private double circleBindable - { - get => volumeCircle.Current; - set => volumeCircle.Current.Value = value; + volumeCircle.Current.Value = displayVolume * 0.75f; + } } public double Volume From 96ea42d3ba8353c2b812108ce610e2322fe5298a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:51:34 +0900 Subject: [PATCH 58/67] Ensure initial value is set even if that value is zero --- osu.Game/Overlays/Volume/VolumeMeter.cs | 7 ++++++- 1 file changed, 6 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 99ac4d3a79..b9bd39163a 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -122,10 +122,15 @@ namespace osu.Game.Overlays.Volume }); Bindable.ValueChanged += newVolume => { this.TransformTo("DisplayVolume", newVolume, 400, Easing.OutQuint); }; - bgProgress.Current.Value = 0.75f; } + protected override void LoadComplete() + { + base.LoadComplete(); + Bindable.TriggerChange(); + } + private double displayVolume; /// From 4094ffbddd141ced057da4a9283931ac37ecf271 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:54:15 +0900 Subject: [PATCH 59/67] Remove unnecessary comment --- osu.Game/Overlays/Volume/VolumeMeter.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index b9bd39163a..056ba6aa8d 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -133,9 +133,6 @@ namespace osu.Game.Overlays.Volume private double displayVolume; - /// - /// This is needed because doesn't support - /// protected double DisplayVolume { get => displayVolume; From a71e5ce19c1f42eb2d0dc18e40d925644dad63d8 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 14:54:54 +0900 Subject: [PATCH 60/67] Tidy up --- osu.Game/Overlays/Volume/VolumeMeter.cs | 11 ++--------- 1 file changed, 2 insertions(+), 9 deletions(-) diff --git a/osu.Game/Overlays/Volume/VolumeMeter.cs b/osu.Game/Overlays/Volume/VolumeMeter.cs index 056ba6aa8d..64b9e513c4 100644 --- a/osu.Game/Overlays/Volume/VolumeMeter.cs +++ b/osu.Game/Overlays/Volume/VolumeMeter.cs @@ -10,7 +10,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Effects; using osu.Framework.Graphics.Shapes; -using osu.Framework.Graphics.Transforms; using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Bindings; using osu.Game.Graphics; @@ -161,15 +160,9 @@ namespace osu.Game.Overlays.Volume private set => Bindable.Value = value; } - public void Increase() - { - Volume += 0.05f; - } + public void Increase() => Volume += 0.05f; - public void Decrease() - { - Volume -= 0.05f; - } + public void Decrease() => Volume -= 0.05f; public bool OnPressed(GlobalAction action) { From 04f5563238d874c585d4414951300532eb602c8f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 7 Mar 2018 19:37:26 +0900 Subject: [PATCH 61/67] 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 3731cbe5eba7c729209d10bf38e272b51a9769bc Mon Sep 17 00:00:00 2001 From: pdrapoport Date: Wed, 7 Mar 2018 14:20:59 +0100 Subject: [PATCH 62/67] Removing "mouse wheel disabled" checkbox from visual settings gameplay menu --- osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs index 1a7b80ec9a..6c4d929c71 100644 --- a/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs +++ b/osu.Game/Screens/Play/PlayerSettings/VisualSettings.cs @@ -15,7 +15,6 @@ namespace osu.Game.Screens.Play.PlayerSettings private readonly PlayerSliderBar dimSliderBar; private readonly PlayerSliderBar blurSliderBar; private readonly PlayerCheckbox showStoryboardToggle; - private readonly PlayerCheckbox mouseWheelDisabledToggle; public VisualSettings() { @@ -35,8 +34,7 @@ namespace osu.Game.Screens.Play.PlayerSettings { Text = "Toggles:" }, - showStoryboardToggle = new PlayerCheckbox { LabelText = "Storyboards" }, - mouseWheelDisabledToggle = new PlayerCheckbox { LabelText = "Disable mouse wheel" } + showStoryboardToggle = new PlayerCheckbox { LabelText = "Storyboards" } }; } @@ -46,7 +44,6 @@ namespace osu.Game.Screens.Play.PlayerSettings dimSliderBar.Bindable = config.GetBindable(OsuSetting.DimLevel); blurSliderBar.Bindable = config.GetBindable(OsuSetting.BlurLevel); showStoryboardToggle.Bindable = config.GetBindable(OsuSetting.ShowStoryboard); - mouseWheelDisabledToggle.Bindable = config.GetBindable(OsuSetting.MouseDisableWheel); } } } From 983cefbe40b651961a9566a4fc22a651e611e6fa Mon Sep 17 00:00:00 2001 From: naoey Date: Wed, 7 Mar 2018 17:33:21 +0530 Subject: [PATCH 63/67] Add VisualTest. --- .../TestCaseUserProfileRecentSection.cs | 162 ++++++++++++++++++ osu.Game.Tests/osu.Game.Tests.csproj | 1 + .../Profile/Sections/Recent/MedalIcon.cs | 2 +- .../PaginatedRecentActivityContainer.cs | 2 +- 4 files changed, 165 insertions(+), 2 deletions(-) create mode 100644 osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs diff --git a/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs new file mode 100644 index 0000000000..23eb7f68f9 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs @@ -0,0 +1,162 @@ +// 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.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Online.API.Requests; +using osu.Game.Overlays.Profile.Sections; +using osu.Game.Overlays.Profile.Sections.Recent; +using System; +using System.Collections.Generic; +using System.Linq; + +namespace osu.Game.Tests.Visual +{ + [TestFixture] + public class TestCaseUserProfileRecentSection : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(RecentSection), + typeof(DrawableRecentActivity), + typeof(PaginatedRecentActivityContainer), + typeof(MedalIcon) + }; + + public TestCaseUserProfileRecentSection() + { + var flow = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + }; + + flow.AddRange(createDummyActivities().Select(a => new DrawableRecentActivity(a))); + + Add(new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(0.2f) + }); + + Add(new ScrollContainer + { + RelativeSizeAxes = Axes.Both, + Child = flow, + }); + } + + private IEnumerable createDummyActivities() + { + var dummyBeatmap = new RecentActivity.RecentActivityBeatmap + { + Title = @"Dummy beatmap", + Url = "/b/1337", + }; + + var dummyUser = new RecentActivity.RecentActivityUser + { + Username = "DummyReborn", + Url = "/u/666", + PreviousUsername = "Dummy", + }; + + return new[] + { + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.Achievement, + Achievement = new RecentActivity.RecentActivityAchievement + { + Name = @"Feelin' It", + Slug = @"all-secret-feelinit", + }, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapPlaycount, + Count = 1337, + Beatmap = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetApprove, + Approval = BeatmapApproval.Qualified, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetDelete, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetRevive, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetRevive, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetUpdate, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.BeatmapsetUpload, + Beatmapset = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.Rank, + Rank = 1, + Mode = "osu!", + Beatmap = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.RankLost, + Mode = "osu!", + Beatmap = dummyBeatmap, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.UsernameChange, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.UserSupportAgain, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.UserSupportFirst, + }, + new RecentActivity + { + User = dummyUser, + Type = RecentActivityType.UserSupportGift, + }, + }; + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 8cbeb6aab6..1cfa7bc111 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -173,6 +173,7 @@ + diff --git a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs index 9ef2b89269..6ffbe7193f 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/MedalIcon.cs @@ -9,7 +9,7 @@ using osu.Framework.Graphics.Textures; namespace osu.Game.Overlays.Profile.Sections.Recent { - internal class MedalIcon : Container + public class MedalIcon : Container { private readonly string slug; private readonly Sprite sprite; diff --git a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs index 3de005cf9b..d479627cde 100644 --- a/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs +++ b/osu.Game/Overlays/Profile/Sections/Recent/PaginatedRecentActivityContainer.cs @@ -9,7 +9,7 @@ using System.Linq; namespace osu.Game.Overlays.Profile.Sections.Recent { - internal class PaginatedRecentActivityContainer : PaginatedContainer + public class PaginatedRecentActivityContainer : PaginatedContainer { public PaginatedRecentActivityContainer(Bindable user, string header, string missing) : base(user, header, missing) From e55a503f79735df4abd83d867fb5db21db18fccb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Mar 2018 00:58:16 +0900 Subject: [PATCH 64/67] Tidy up test case --- .../TestCaseUserProfileRecentSection.cs | 35 +++++++++---------- 1 file changed, 17 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs index 23eb7f68f9..1f7a7e7165 100644 --- a/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs +++ b/osu.Game.Tests/Visual/TestCaseUserProfileRecentSection.cs @@ -28,26 +28,25 @@ namespace osu.Game.Tests.Visual public TestCaseUserProfileRecentSection() { - var flow = new FillFlowContainer + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Direction = FillDirection.Vertical, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = OsuColour.Gray(0.2f) + }, + new ScrollContainer + { + RelativeSizeAxes = Axes.Both, + Child = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Direction = FillDirection.Vertical, + ChildrenEnumerable = createDummyActivities().Select(a => new DrawableRecentActivity(a)) + }, + } }; - - flow.AddRange(createDummyActivities().Select(a => new DrawableRecentActivity(a))); - - Add(new Box - { - RelativeSizeAxes = Axes.Both, - Colour = OsuColour.Gray(0.2f) - }); - - Add(new ScrollContainer - { - RelativeSizeAxes = Axes.Both, - Child = flow, - }); } private IEnumerable createDummyActivities() From 70a16667b69b329f901a54f4ef5e8d3a2a5bbc25 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 8 Mar 2018 12:46:23 +0900 Subject: [PATCH 65/67] 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 66/67] 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 67/67] 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)