From f00676e6ee8121a6344bd04f3b4814711319429b Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sun, 24 Dec 2017 20:25:23 +0100 Subject: [PATCH 001/206] initial commit to allow filtering / selecting different tabs / etc still wip tho bleh bleh --- osu.Game/Overlays/Social/FilterControl.cs | 2 +- osu.Game/Overlays/Social/Header.cs | 4 +- osu.Game/Overlays/SocialOverlay.cs | 167 +++++++++++++++------- 3 files changed, 119 insertions(+), 54 deletions(-) diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index cf4097643e..03acd9bf13 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Social public enum SocialSortCriteria { Rank, - //Location, + Location, //[Description("Time Zone")] //TimeZone, //[Description("World Map")] diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs index 2674854327..e15b16085b 100644 --- a/osu.Game/Overlays/Social/Header.cs +++ b/osu.Game/Overlays/Social/Header.cs @@ -55,8 +55,8 @@ namespace osu.Game.Overlays.Social { [Description("Online Players")] OnlinePlayers, - //[Description("Online Friends")] - //OnlineFriends, + [Description("Online Friends")] + OnlineFriends, //[Description("Online Team Members")] //OnlineTeamMembers, //[Description("Chat Channels")] diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 954a838461..84469c5e40 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -9,19 +9,23 @@ using OpenTK.Graphics; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Graphics; -using osu.Game.Graphics.Cursor; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.API.Requests; using osu.Game.Overlays.SearchableList; using osu.Game.Overlays.Social; using osu.Game.Users; +using osu.Framework.Configuration; +using osu.Framework.Threading; +using System.Threading.Tasks; namespace osu.Game.Overlays { - public class SocialOverlay : SearchableListOverlay, IOnlineComponent + public class SocialOverlay : SearchableListOverlay { - private readonly FillFlowContainer panelFlow; + private APIAccess api; + + private FillFlowContainer panels; protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b"); protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51"); @@ -30,28 +34,19 @@ namespace osu.Game.Overlays protected override SearchableListHeader CreateHeader() => new Header(); protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); - private IEnumerable users; private readonly LoadingAnimation loading; + private IEnumerable users; + public IEnumerable Users { get { return users; } set { - if (users?.Equals(value) ?? false) return; - users = value; + if (users?.Equals(value) ?? false) + return; - if (users == null) - panelFlow.Clear(); - else - { - panelFlow.ChildrenEnumerable = users.Select(u => - { - var p = new UserPanel(u) { Width = 300 }; - p.Status.BindTo(u.Status); - return p; - }); - } + users = value?.ToList(); } } @@ -62,59 +57,129 @@ namespace osu.Game.Overlays ThirdWaveColour = OsuColour.FromHex(@"9b2b6e"); FourthWaveColour = OsuColour.FromHex(@"6d214d"); - ScrollFlow.Children = new[] + Add(loading = new LoadingAnimation()); + + Filter.DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels; + + // TODO sort our list in some way (either locally or with API call) + //Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += rankStatus => Scheduler.AddOnce(updateSearch); + + Header.Tabs.Current.ValueChanged += tab => { - new OsuContextMenuContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Child = panelFlow = new FillFlowContainer - { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Margin = new MarginPadding { Top = 20 }, - Spacing = new Vector2(10f), - } - }, + currentQuery.Value = string.Empty; + Filter.Tabs.Current.Value = (SocialSortCriteria)Header.Tabs.Current.Value; + Scheduler.AddOnce(updateSearch); }; - Add(loading = new LoadingAnimation()); + currentQuery.ValueChanged += v => + { + queryChangedDebounce?.Cancel(); + + if (string.IsNullOrEmpty(v)) + Scheduler.AddOnce(updateSearch); + else + { + Users = null; + queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500); + } + }; + + currentQuery.BindTo(Filter.Search.Current); + + Filter.Tabs.Current.ValueChanged += sortCriteria => Scheduler.AddOnce(updateSearch); + + Scheduler.AddOnce(updateSearch); // so it displays something once it's first opened } [BackgroundDependencyLoader] private void load(APIAccess api) { - if (Users == null) - reloadUsers(api); + this.api = api; } - private void reloadUsers(APIAccess api) + private void recreatePanels(PanelDisplayStyle displayStyle) { - Users = null; + if (Users == null) + return; - // no this is not the correct data source, but it's something. - var request = new GetUsersRequest(); - request.Success += res => + if (panels != null) { - Users = res.Select(e => e.User); - loading.Hide(); + panels.FadeOut(200); + panels.Expire(); + panels = null; + } + + var newPanels = new FillFlowContainer + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Spacing = new Vector2(10f), + Margin = new MarginPadding { Top = 10 }, + ChildrenEnumerable = Users.Select(u => + { + UserPanel panel = new UserPanel(u); + switch (displayStyle) + { + case PanelDisplayStyle.Grid: + panel.Width = 300; + break; + default: + panel.RelativeSizeAxes = Axes.X; + break; + } + panel.Status.BindTo(u.Status); + return panel; + }) }; - api.Queue(request); - loading.Show(); + LoadComponentAsync(newPanels, p => + { + if (panels != null) + ScrollFlow.Remove(panels); + + ScrollFlow.Add(panels = newPanels); + }); } - public void APIStateChanged(APIAccess api, APIState state) + private GetUsersRequest getUsersRequest; + + private readonly Bindable currentQuery = new Bindable(); + + private ScheduledDelegate queryChangedDebounce; + + private void updateSearch() { - switch (state) + queryChangedDebounce?.Cancel(); + + if (!IsLoaded) + return; + + Users = null; + loading.Hide(); + getUsersRequest?.Cancel(); + + if (api == null || api.State == APIState.Offline) + return; + + getUsersRequest = new GetUsersRequest(); // TODO filter/sort values?!? + + getUsersRequest.Success += response => { - case APIState.Online: - reloadUsers(api); - break; - default: - Users = null; - break; - } + Task.Run(() => + { + var newUsers = response.Select(r => r.User); + + Schedule(() => + { + Users = newUsers; + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); + loading.Hide(); + }); + }); + }; + + loading.Show(); + api.Queue(getUsersRequest); } } From e2a1b18a2c32108f386422366c737377021d4978 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 25 Dec 2017 14:17:35 +0100 Subject: [PATCH 002/206] fix selecting different tab causing filter to change by itself and minor cleanup --- osu.Game/Overlays/SocialOverlay.cs | 15 +++++---------- 1 file changed, 5 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 84469c5e40..39b644e469 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -64,12 +64,7 @@ namespace osu.Game.Overlays // TODO sort our list in some way (either locally or with API call) //Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += rankStatus => Scheduler.AddOnce(updateSearch); - Header.Tabs.Current.ValueChanged += tab => - { - currentQuery.Value = string.Empty; - Filter.Tabs.Current.Value = (SocialSortCriteria)Header.Tabs.Current.Value; - Scheduler.AddOnce(updateSearch); - }; + Header.Tabs.Current.ValueChanged += _ => Scheduler.AddOnce(updateSearch); currentQuery.ValueChanged += v => { @@ -86,7 +81,7 @@ namespace osu.Game.Overlays currentQuery.BindTo(Filter.Search.Current); - Filter.Tabs.Current.ValueChanged += sortCriteria => Scheduler.AddOnce(updateSearch); + Filter.Tabs.Current.ValueChanged += _ => Scheduler.AddOnce(updateSearch); Scheduler.AddOnce(updateSearch); // so it displays something once it's first opened } @@ -99,9 +94,6 @@ namespace osu.Game.Overlays private void recreatePanels(PanelDisplayStyle displayStyle) { - if (Users == null) - return; - if (panels != null) { panels.FadeOut(200); @@ -109,6 +101,9 @@ namespace osu.Game.Overlays panels = null; } + if (Users == null) + return; + var newPanels = new FillFlowContainer { RelativeSizeAxes = Axes.X, From 0fe78bee6ec1e81c17764982ab90e5a530196395 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 25 Dec 2017 16:11:50 +0100 Subject: [PATCH 003/206] center user panels --- osu.Game/Overlays/SocialOverlay.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 39b644e469..051cf5d6d2 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -112,7 +112,11 @@ namespace osu.Game.Overlays Margin = new MarginPadding { Top = 10 }, ChildrenEnumerable = Users.Select(u => { - UserPanel panel = new UserPanel(u); + UserPanel panel = new UserPanel(u) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + }; switch (displayStyle) { case PanelDisplayStyle.Grid: From 044e4d0acddffaffc1055f9042eaacea365e4b0b Mon Sep 17 00:00:00 2001 From: ColdVolcano Date: Mon, 25 Dec 2017 19:11:49 -0600 Subject: [PATCH 004/206] Add blur to background in Player --- osu.Game/Configuration/OsuConfigManager.cs | 2 ++ .../Sections/Gameplay/GeneralSettings.cs | 6 ++++++ osu.Game/Screens/Play/Player.cs | 20 ++++++++++++------- 3 files changed, 21 insertions(+), 7 deletions(-) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index f4c7bdb586..d359a0a2d6 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -65,6 +65,7 @@ namespace osu.Game.Configuration // Gameplay Set(OsuSetting.DimLevel, 0.3, 0, 1, 0.01); + Set(OsuSetting.BlurLevel, 0, 0, 1, 0.01); Set(OsuSetting.ShowInterface, true); Set(OsuSetting.KeyOverlay, false); @@ -90,6 +91,7 @@ namespace osu.Game.Configuration GameplayCursorSize, AutoCursorSize, DimLevel, + BlurLevel, ShowStoryboard, KeyOverlay, FloatingComments, diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 8ec6af5cd0..95d127a55f 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -22,6 +22,12 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay Bindable = config.GetBindable(OsuSetting.DimLevel), KeyboardStep = 0.1f }, + new SettingsSlider + { + LabelText = "Background blur", + Bindable = config.GetBindable(OsuSetting.BlurLevel), + KeyboardStep = 0.1f + }, new SettingsCheckbox { LabelText = "Show score overlay", diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 340fc39d52..8430acbc73 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -65,6 +65,7 @@ namespace osu.Game.Screens.Play #region User Settings private Bindable dimLevel; + private Bindable blurLevel; private Bindable showStoryboard; private Bindable mouseWheelDisabled; private Bindable userAudioOffset; @@ -74,7 +75,7 @@ namespace osu.Game.Screens.Play #endregion private BreakOverlay breakOverlay; - private Container storyboardContainer; + private BufferedContainer storyboardContainer; private DrawableStoryboard storyboard; private HUDOverlay hudOverlay; @@ -88,6 +89,7 @@ namespace osu.Game.Screens.Play this.api = api; dimLevel = config.GetBindable(OsuSetting.DimLevel); + blurLevel = config.GetBindable(OsuSetting.BlurLevel); showStoryboard = config.GetBindable(OsuSetting.ShowStoryboard); mouseWheelDisabled = config.GetBindable(OsuSetting.MouseDisableWheel); @@ -147,7 +149,7 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { - storyboardContainer = new Container + storyboardContainer = new BufferedContainer { RelativeSizeAxes = Axes.Both, Clock = offsetClock, @@ -309,9 +311,9 @@ namespace osu.Game.Screens.Play if (!loadedSuccessfully) return; - (Background as BackgroundScreenBeatmap)?.BlurTo(Vector2.Zero, 1000, Easing.OutQuint); + dimLevel.ValueChanged += backgroundLevel_ValueChanged; + blurLevel.ValueChanged += backgroundLevel_ValueChanged; - dimLevel.ValueChanged += dimLevel_ValueChanged; showStoryboard.ValueChanged += showStoryboard_ValueChanged; updateBackgroundElements(); @@ -368,7 +370,7 @@ namespace osu.Game.Screens.Play return true; } - private void dimLevel_ValueChanged(double newValue) + private void backgroundLevel_ValueChanged(double newValue) => updateBackgroundElements(); private void showStoryboard_ValueChanged(bool newValue) @@ -377,6 +379,7 @@ namespace osu.Game.Screens.Play private void updateBackgroundElements() { var opacity = 1 - (float)dimLevel; + var blur = new Vector2((float)blurLevel.Value * 25); if (showStoryboard && storyboard == null) initializeStoryboard(true); @@ -385,14 +388,17 @@ namespace osu.Game.Screens.Play var storyboardVisible = showStoryboard && beatmap.Storyboard.HasDrawable; storyboardContainer.FadeColour(new Color4(opacity, opacity, opacity, 1), 800); - storyboardContainer.FadeTo(storyboardVisible && opacity > 0 ? 1 : 0); + storyboardContainer.FadeTo(storyboardVisible && opacity > 0 ? 1 : 0, 800, Easing.OutQuint); + storyboardContainer.BlurTo(blur, 800, Easing.OutQuint); Background?.FadeTo(!storyboardVisible || beatmap.Background == null ? opacity : 0, 800, Easing.OutQuint); + (Background as BackgroundScreenBeatmap)?.BlurTo(blur, 800, Easing.OutQuint); } private void fadeOut() { - dimLevel.ValueChanged -= dimLevel_ValueChanged; + dimLevel.ValueChanged -= backgroundLevel_ValueChanged; + blurLevel.ValueChanged -= backgroundLevel_ValueChanged; showStoryboard.ValueChanged -= showStoryboard_ValueChanged; const float fade_out_duration = 250; From bc90793b1c59da7ca83bb9a5ca4b6ae1fcd62c72 Mon Sep 17 00:00:00 2001 From: ColdVolcano Date: Mon, 25 Dec 2017 19:18:57 -0600 Subject: [PATCH 005/206] Trim whitespace --- osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 95d127a55f..0808c18b6f 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -27,7 +27,7 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = "Background blur", Bindable = config.GetBindable(OsuSetting.BlurLevel), KeyboardStep = 0.1f - }, + }, new SettingsCheckbox { LabelText = "Show score overlay", From 66f076815f8fa82e4938e369cdb81e7118989a45 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Thu, 28 Dec 2017 19:32:06 +0100 Subject: [PATCH 006/206] query friends endpoint to fetch friendlist --- .../Online/API/Requests/GetFriendsRequest.cs | 13 +++++ osu.Game/Overlays/Social/FilterControl.cs | 2 +- osu.Game/Overlays/SocialOverlay.cs | 58 ++++++++++++------- osu.Game/osu.Game.csproj | 1 + 4 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 osu.Game/Online/API/Requests/GetFriendsRequest.cs diff --git a/osu.Game/Online/API/Requests/GetFriendsRequest.cs b/osu.Game/Online/API/Requests/GetFriendsRequest.cs new file mode 100644 index 0000000000..a06471fd74 --- /dev/null +++ b/osu.Game/Online/API/Requests/GetFriendsRequest.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Users; + +namespace osu.Game.Online.API.Requests +{ + public class GetFriendsRequest : APIRequest> + { + protected override string Target => @"friends"; + } +} diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index 03acd9bf13..cf4097643e 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays.Social public enum SocialSortCriteria { Rank, - Location, + //Location, //[Description("Time Zone")] //TimeZone, //[Description("World Map")] diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 051cf5d6d2..3d62775c84 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -64,7 +64,7 @@ namespace osu.Game.Overlays // TODO sort our list in some way (either locally or with API call) //Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += rankStatus => Scheduler.AddOnce(updateSearch); - Header.Tabs.Current.ValueChanged += _ => Scheduler.AddOnce(updateSearch); + Header.Tabs.Current.ValueChanged += tab => Scheduler.AddOnce(updateSearch); currentQuery.ValueChanged += v => { @@ -81,7 +81,7 @@ namespace osu.Game.Overlays currentQuery.BindTo(Filter.Search.Current); - Filter.Tabs.Current.ValueChanged += _ => Scheduler.AddOnce(updateSearch); + Filter.Tabs.Current.ValueChanged += sortCriteria => Scheduler.AddOnce(updateSearch); Scheduler.AddOnce(updateSearch); // so it displays something once it's first opened } @@ -141,6 +141,7 @@ namespace osu.Game.Overlays } private GetUsersRequest getUsersRequest; + private GetFriendsRequest getFriendsRequest; private readonly Bindable currentQuery = new Bindable(); @@ -155,33 +156,50 @@ namespace osu.Game.Overlays Users = null; loading.Hide(); - getUsersRequest?.Cancel(); + clearRequests(); if (api == null || api.State == APIState.Offline) return; - getUsersRequest = new GetUsersRequest(); // TODO filter/sort values?!? - - getUsersRequest.Success += response => + switch (Header.Tabs.Current.Value) { - Task.Run(() => - { - var newUsers = response.Select(r => r.User); - - Schedule(() => - { - Users = newUsers; - recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); - loading.Hide(); - }); - }); - }; - + case SocialTab.OnlinePlayers: + getUsersRequest = new GetUsersRequest(); // TODO filter??? + getUsersRequest.Success += response => finishRequest(response.Select(r => r.User)); + queueRequest(getUsersRequest); + break; + case SocialTab.OnlineFriends: + getFriendsRequest = new GetFriendsRequest(); // TODO filter??? + getFriendsRequest.Success += finishRequest; + queueRequest(getFriendsRequest); + break; + } loading.Show(); - api.Queue(getUsersRequest); } + + private void clearRequests() + { + getUsersRequest?.Cancel(); + getFriendsRequest?.Cancel(); + } + + private void finishRequest(IEnumerable newUsers) + { + Task.Run(() => + { + Schedule(() => + { + Users = newUsers; + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); + loading.Hide(); + }); + }); + } + + private void queueRequest(APIRequest request) => api.Queue(request); } + public enum SortDirection { Descending, diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 94678106bf..29deea5771 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -268,6 +268,7 @@ + From 53cd47a192cfc051279c358c5f4d52864e98cc56 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Thu, 28 Dec 2017 19:34:49 +0100 Subject: [PATCH 007/206] Updated submodule osu-resources --- osu-resources | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-resources b/osu-resources index 4287ee8043..e01f71160f 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit 4287ee8043fb1419017359bc3a5db5dc06bc643f +Subproject commit e01f71160fb9b3167efcd177c7d7dba9e5d36604 From 7ecc693e3492296ace03aa0e37d271e3b92349ac Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Thu, 28 Dec 2017 19:35:29 +0100 Subject: [PATCH 008/206] Updated submodule osu-framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 08f85f9bf9..10cae790c6 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 08f85f9bf9a7376aec8dfcde8c7c96d267d8c295 +Subproject commit 10cae790c6f1d559c326f9438958d0b012d61dc6 From 3845c7ac7de3f17ea64aa225037915f71280baf4 Mon Sep 17 00:00:00 2001 From: ColdVolcano Date: Thu, 28 Dec 2017 14:31:34 -0600 Subject: [PATCH 009/206] Remove bluring of storyboard --- osu.Game/Screens/Play/Player.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 8430acbc73..8b94f41686 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -75,7 +75,7 @@ namespace osu.Game.Screens.Play #endregion private BreakOverlay breakOverlay; - private BufferedContainer storyboardContainer; + private Container storyboardContainer; private DrawableStoryboard storyboard; private HUDOverlay hudOverlay; @@ -149,7 +149,7 @@ namespace osu.Game.Screens.Play Children = new Drawable[] { - storyboardContainer = new BufferedContainer + storyboardContainer = new Container { RelativeSizeAxes = Axes.Both, Clock = offsetClock, @@ -389,7 +389,6 @@ namespace osu.Game.Screens.Play storyboardContainer.FadeColour(new Color4(opacity, opacity, opacity, 1), 800); storyboardContainer.FadeTo(storyboardVisible && opacity > 0 ? 1 : 0, 800, Easing.OutQuint); - storyboardContainer.BlurTo(blur, 800, Easing.OutQuint); Background?.FadeTo(!storyboardVisible || beatmap.Background == null ? opacity : 0, 800, Easing.OutQuint); (Background as BackgroundScreenBeatmap)?.BlurTo(blur, 800, Easing.OutQuint); From df62ca14b7f67007216e0d1726342cd7d2da57ee Mon Sep 17 00:00:00 2001 From: ColdVolcano Date: Fri, 29 Dec 2017 23:41:36 -0600 Subject: [PATCH 010/206] Don't unbind when not necessary --- osu.Game/Screens/Play/Player.cs | 17 +++-------------- 1 file changed, 3 insertions(+), 14 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 8b94f41686..5346de2bb7 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -311,10 +311,9 @@ namespace osu.Game.Screens.Play if (!loadedSuccessfully) return; - dimLevel.ValueChanged += backgroundLevel_ValueChanged; - blurLevel.ValueChanged += backgroundLevel_ValueChanged; - - showStoryboard.ValueChanged += showStoryboard_ValueChanged; + dimLevel.ValueChanged += value => updateBackgroundElements(); + blurLevel.ValueChanged += value => updateBackgroundElements(); + showStoryboard.ValueChanged += value => updateBackgroundElements(); updateBackgroundElements(); Content.Alpha = 0; @@ -370,12 +369,6 @@ namespace osu.Game.Screens.Play return true; } - private void backgroundLevel_ValueChanged(double newValue) - => updateBackgroundElements(); - - private void showStoryboard_ValueChanged(bool newValue) - => updateBackgroundElements(); - private void updateBackgroundElements() { var opacity = 1 - (float)dimLevel; @@ -396,10 +389,6 @@ namespace osu.Game.Screens.Play private void fadeOut() { - dimLevel.ValueChanged -= backgroundLevel_ValueChanged; - blurLevel.ValueChanged -= backgroundLevel_ValueChanged; - showStoryboard.ValueChanged -= showStoryboard_ValueChanged; - const float fade_out_duration = 250; RulesetContainer?.FadeOut(fade_out_duration); From 8a02900c014be3b2117fef243aa099e0d7deff14 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 30 Dec 2017 11:33:06 +0100 Subject: [PATCH 011/206] changed titles from social tabs --- osu.Game/Overlays/Social/Header.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs index e15b16085b..94368d9786 100644 --- a/osu.Game/Overlays/Social/Header.cs +++ b/osu.Game/Overlays/Social/Header.cs @@ -53,9 +53,9 @@ namespace osu.Game.Overlays.Social public enum SocialTab { - [Description("Online Players")] + [Description("Players")] OnlinePlayers, - [Description("Online Friends")] + [Description("Friends")] OnlineFriends, //[Description("Online Team Members")] //OnlineTeamMembers, From 72af5bf67242133655655777e487e3f9ae1521e1 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 30 Dec 2017 11:51:49 +0100 Subject: [PATCH 012/206] simplify socialoverlay user request structure --- osu.Game/Overlays/SocialOverlay.cs | 23 ++++++----------------- 1 file changed, 6 insertions(+), 17 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 3d62775c84..219672b76d 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -140,8 +140,7 @@ namespace osu.Game.Overlays }); } - private GetUsersRequest getUsersRequest; - private GetFriendsRequest getFriendsRequest; + private APIRequest getUsersRequest; private readonly Bindable currentQuery = new Bindable(); @@ -156,7 +155,7 @@ namespace osu.Game.Overlays Users = null; loading.Hide(); - clearRequests(); + getUsersRequest?.Cancel(); if (api == null || api.State == APIState.Offline) return; @@ -165,24 +164,17 @@ namespace osu.Game.Overlays { case SocialTab.OnlinePlayers: getUsersRequest = new GetUsersRequest(); // TODO filter??? - getUsersRequest.Success += response => finishRequest(response.Select(r => r.User)); - queueRequest(getUsersRequest); + ((GetUsersRequest)getUsersRequest).Success += response => finishRequest(response.Select(r => r.User)); break; case SocialTab.OnlineFriends: - getFriendsRequest = new GetFriendsRequest(); // TODO filter??? - getFriendsRequest.Success += finishRequest; - queueRequest(getFriendsRequest); + getUsersRequest = new GetFriendsRequest(); // TODO filter??? + ((GetFriendsRequest)getUsersRequest).Success += finishRequest; break; } + api.Queue(getUsersRequest); loading.Show(); } - private void clearRequests() - { - getUsersRequest?.Cancel(); - getFriendsRequest?.Cancel(); - } - private void finishRequest(IEnumerable newUsers) { Task.Run(() => @@ -195,11 +187,8 @@ namespace osu.Game.Overlays }); }); } - - private void queueRequest(APIRequest request) => api.Queue(request); } - public enum SortDirection { Descending, From d37ba2c9a4b51853de432cba3f1d1992f8a7001c Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 30 Dec 2017 11:54:03 +0100 Subject: [PATCH 013/206] disable searching/filtering with textbox it doesn't do anything except from creating unnecessary requests for now --- osu.Game/Overlays/SocialOverlay.cs | 22 +++++++++++----------- 1 file changed, 11 insertions(+), 11 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 219672b76d..a65e2f9e77 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -66,18 +66,18 @@ namespace osu.Game.Overlays Header.Tabs.Current.ValueChanged += tab => Scheduler.AddOnce(updateSearch); - currentQuery.ValueChanged += v => - { - queryChangedDebounce?.Cancel(); + //currentQuery.ValueChanged += v => + //{ + // queryChangedDebounce?.Cancel(); - if (string.IsNullOrEmpty(v)) - Scheduler.AddOnce(updateSearch); - else - { - Users = null; - queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500); - } - }; + // if (string.IsNullOrEmpty(v)) + // Scheduler.AddOnce(updateSearch); + // else + // { + // Users = null; + // queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500); + // } + //}; currentQuery.BindTo(Filter.Search.Current); From 760d2aff4bdbd73f33ac10a9ed0858048657220f Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 30 Dec 2017 12:56:18 +0100 Subject: [PATCH 014/206] readd IOnlineComponent to be able to react to APIState changes --- osu.Game/Overlays/SocialOverlay.cs | 17 ++++++++++++++++- 1 file changed, 16 insertions(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index a65e2f9e77..3dafecc6df 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -21,7 +21,7 @@ using System.Threading.Tasks; namespace osu.Game.Overlays { - public class SocialOverlay : SearchableListOverlay + public class SocialOverlay : SearchableListOverlay, IOnlineComponent { private APIAccess api; @@ -90,6 +90,7 @@ namespace osu.Game.Overlays private void load(APIAccess api) { this.api = api; + api.Register(this); } private void recreatePanels(PanelDisplayStyle displayStyle) @@ -187,6 +188,20 @@ namespace osu.Game.Overlays }); }); } + + public void APIStateChanged(APIAccess api, APIState state) + { + switch (state) + { + case APIState.Online: + Scheduler.AddOnce(updateSearch); + break; + default: + Users = null; + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); + break; + } + } } public enum SortDirection From f03e064c430479080fc2dc70d37e4050505584a5 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 30 Dec 2017 12:57:32 +0100 Subject: [PATCH 015/206] remove unnecessary update --- osu.Game/Overlays/SocialOverlay.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 3dafecc6df..d2f56f4061 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -82,8 +82,6 @@ namespace osu.Game.Overlays currentQuery.BindTo(Filter.Search.Current); Filter.Tabs.Current.ValueChanged += sortCriteria => Scheduler.AddOnce(updateSearch); - - Scheduler.AddOnce(updateSearch); // so it displays something once it's first opened } [BackgroundDependencyLoader] From d032790e192a66c9ef0e72269584e0bcb9e2c7da Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Sun, 31 Dec 2017 03:10:54 +0200 Subject: [PATCH 016/206] Doesn't allow randomizer to select invisible maps --- osu.Game/Screens/Select/BeatmapCarousel.cs | 13 +++++++------ 1 file changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index b343998e11..95b025f91e 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -231,8 +231,8 @@ namespace osu.Game.Screens.Select public void SelectNextRandom() { - var visible = beatmapSets.Where(s => !s.Filtered).ToList(); - if (!visible.Any()) + var visibleSets = beatmapSets.Where(s => !s.Filtered).ToList(); + if (!visibleSets.Any()) return; if (selectedBeatmap != null) @@ -249,20 +249,21 @@ namespace osu.Game.Screens.Select if (RandomAlgorithm == RandomSelectAlgorithm.RandomPermutation) { - var notYetVisitedSets = visible.Except(previouslyVisitedRandomSets).ToList(); + var notYetVisitedSets = visibleSets.Except(previouslyVisitedRandomSets).ToList(); if (!notYetVisitedSets.Any()) { previouslyVisitedRandomSets.Clear(); - notYetVisitedSets = visible; + notYetVisitedSets = visibleSets; } set = notYetVisitedSets.ElementAt(RNG.Next(notYetVisitedSets.Count)); previouslyVisitedRandomSets.Add(set); } else - set = visible.ElementAt(RNG.Next(visible.Count)); + set = visibleSets.ElementAt(RNG.Next(visibleSets.Count)); - select(set.Beatmaps.Skip(RNG.Next(set.Beatmaps.Count())).FirstOrDefault()); + var visibleBeatmaps = set.Beatmaps.Where(s => !s.Filtered).ToList(); + select(visibleBeatmaps.Skip(RNG.Next(visibleBeatmaps.Count())).FirstOrDefault()); } public void SelectPreviousRandom() From 987a6403da0744c925330f31e3efd253c11fb84c Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Sun, 31 Dec 2017 03:25:43 +0200 Subject: [PATCH 017/206] Faster count for AppVeyor --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 95b025f91e..adaaddaf78 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -263,7 +263,7 @@ namespace osu.Game.Screens.Select set = visibleSets.ElementAt(RNG.Next(visibleSets.Count)); var visibleBeatmaps = set.Beatmaps.Where(s => !s.Filtered).ToList(); - select(visibleBeatmaps.Skip(RNG.Next(visibleBeatmaps.Count())).FirstOrDefault()); + select(visibleBeatmaps.Skip(RNG.Next(visibleBeatmaps.Count)).FirstOrDefault()); } public void SelectPreviousRandom() From 5abf93038b1d1deeb58a77ebcf5bb2b6943c600e Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Sun, 31 Dec 2017 14:47:27 +0200 Subject: [PATCH 018/206] Reset only visible sets for more randomized feel --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index adaaddaf78..b3db33401b 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -252,7 +252,7 @@ namespace osu.Game.Screens.Select var notYetVisitedSets = visibleSets.Except(previouslyVisitedRandomSets).ToList(); if (!notYetVisitedSets.Any()) { - previouslyVisitedRandomSets.Clear(); + previouslyVisitedRandomSets.RemoveAll(s => visibleSets.Contains(s)); notYetVisitedSets = visibleSets; } From 3ba5dce052224276e96ca5de1cc8c731e0f434ff Mon Sep 17 00:00:00 2001 From: Shawdooow Date: Sun, 31 Dec 2017 11:15:14 -0500 Subject: [PATCH 019/206] new Approach to approach rate --- .../Beatmaps/OsuBeatmapProcessor.cs | 5 ++++- osu.Game.Rulesets.Osu/Mods/OsuMod.cs | 8 +++----- .../Drawables/Connections/FollowPointRenderer.cs | 8 ++++---- .../Objects/Drawables/DrawableHitCircle.cs | 6 +++--- .../Objects/Drawables/DrawableOsuHitObject.cs | 13 ++++++------- .../Objects/Drawables/DrawableSpinner.cs | 4 ++-- .../Objects/Drawables/Pieces/SliderBody.cs | 2 +- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 10 ++++++++++ osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs | 15 ++++++++------- 9 files changed, 41 insertions(+), 30 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index 31b374f71d..e8742d24a6 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -37,7 +37,6 @@ namespace osu.Game.Rulesets.Osu.Beatmaps private void applyStacking(Beatmap beatmap) { const int stack_distance = 3; - float stackThreshold = DrawableOsuHitObject.TIME_PREEMPT * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; // Reset stacking for (int i = 0; i <= beatmap.HitObjects.Count - 1; i++) @@ -58,6 +57,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps continue; double endTime = (stackBaseObject as IHasEndTime)?.EndTime ?? stackBaseObject.StartTime; + float stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; if (objectN.StartTime - endTime > stackThreshold) //We are no longer within stacking range of the next object. @@ -112,6 +112,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps if (objectN is Spinner) continue; double endTime = (objectN as IHasEndTime)?.EndTime ?? objectN.StartTime; + float stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; if (objectI.StartTime - endTime > stackThreshold) //We are no longer within stacking range of the previous object. @@ -165,6 +166,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps OsuHitObject objectN = beatmap.HitObjects[n]; if (objectN is Spinner) continue; + float stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; + if (objectI.StartTime - objectN.StartTime > stackThreshold) //We are no longer within stacking range of the previous object. break; diff --git a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs index 7b1f80f439..dd01ef9af7 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs @@ -36,14 +36,12 @@ namespace osu.Game.Rulesets.Osu.Mods private const double fade_in_duration_multiplier = 0.4; private const double fade_out_duration_multiplier = 0.3; - private float preEmpt => DrawableOsuHitObject.TIME_PREEMPT; - public void ApplyToDrawableHitObjects(IEnumerable drawables) { foreach (var d in drawables.OfType()) { d.ApplyCustomUpdateState += ApplyHiddenState; - d.FadeInDuration = preEmpt * fade_in_duration_multiplier; + d.FadeInDuration = d.HitObject.TimePreempt * fade_in_duration_multiplier; } } @@ -52,8 +50,8 @@ namespace osu.Game.Rulesets.Osu.Mods if (!(drawable is DrawableOsuHitObject d)) return; - var fadeOutStartTime = d.HitObject.StartTime - preEmpt + d.FadeInDuration; - var fadeOutDuration = preEmpt * fade_out_duration_multiplier; + var fadeOutStartTime = d.HitObject.StartTime - d.HitObject.TimePreempt + d.FadeInDuration; + var fadeOutDuration = d.HitObject.TimePreempt * fade_out_duration_multiplier; // new duration from completed fade in to end (before fading out) var longFadeDuration = ((d.HitObject as IHasEndTime)?.EndTime ?? d.HitObject.StartTime) - fadeOutStartTime; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs index fca9187047..60ee10193f 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPointRenderer.cs @@ -96,12 +96,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections using (fp.BeginAbsoluteSequence(fadeInTime)) { - fp.FadeIn(DrawableOsuHitObject.TIME_FADEIN); - fp.ScaleTo(1, DrawableOsuHitObject.TIME_FADEIN, Easing.Out); + fp.FadeIn(currHitObject.TimeFadein); + fp.ScaleTo(1, currHitObject.TimeFadein, Easing.Out); - fp.MoveTo(pointEndPosition, DrawableOsuHitObject.TIME_FADEIN, Easing.Out); + fp.MoveTo(pointEndPosition, currHitObject.TimeFadein, Easing.Out); - fp.Delay(fadeOutTime - fadeInTime).FadeOut(DrawableOsuHitObject.TIME_FADEIN); + fp.Delay(fadeOutTime - fadeInTime).FadeOut(currHitObject.TimeFadein); } fp.Expire(true); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 6220bbd120..bb405ea7fd 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -88,8 +88,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { base.UpdatePreemptState(); - ApproachCircle.FadeIn(Math.Min(FadeInDuration * 2, TIME_PREEMPT)); - ApproachCircle.ScaleTo(1.1f, TIME_PREEMPT); + ApproachCircle.FadeIn(Math.Min(FadeInDuration * 2, HitObject.TimePreempt)); + ApproachCircle.ScaleTo(1.1f, HitObject.TimePreempt); } protected override void UpdateCurrentState(ArmedState state) @@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables switch (state) { case ArmedState.Idle: - this.Delay(TIME_PREEMPT).FadeOut(500); + this.Delay(HitObject.TimePreempt).FadeOut(500); Expire(true); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index f5f0300ae1..1a8ec68df2 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -10,26 +10,25 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { public class DrawableOsuHitObject : DrawableHitObject { - public const float TIME_PREEMPT = 600; - public const float TIME_FADEIN = 400; - /// /// The number of milliseconds used to fade in. /// - public virtual double FadeInDuration { get; set; } = TIME_FADEIN; + public virtual double FadeInDuration { get; set; } - public override bool IsPresent => base.IsPresent || State.Value == ArmedState.Idle && Time.Current >= HitObject.StartTime - TIME_PREEMPT; + public override bool IsPresent => base.IsPresent || State.Value == ArmedState.Idle && Time.Current >= HitObject.StartTime - HitObject.TimePreempt; protected DrawableOsuHitObject(OsuHitObject hitObject) : base(hitObject) { + FadeInDuration = hitObject.TimeFadein; + AccentColour = HitObject.ComboColour; Alpha = 0; } protected sealed override void UpdateState(ArmedState state) { - double transformTime = HitObject.StartTime - TIME_PREEMPT; + double transformTime = HitObject.StartTime - HitObject.TimePreempt; base.ApplyTransformsAt(transformTime, true); base.ClearTransformsAfter(transformTime, true); @@ -38,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { UpdatePreemptState(); - using (BeginDelayedSequence(TIME_PREEMPT + (Judgements.FirstOrDefault()?.TimeOffset ?? 0), true)) + using (BeginDelayedSequence(HitObject.TimePreempt + (Judgements.FirstOrDefault()?.TimeOffset ?? 0), true)) UpdateCurrentState(state); } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 5351ad50c4..e471ad4e9b 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -191,14 +191,14 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables base.UpdatePreemptState(); circleContainer.ScaleTo(spinner.Scale * 0.3f); - circleContainer.ScaleTo(spinner.Scale, TIME_PREEMPT / 1.4f, Easing.OutQuint); + circleContainer.ScaleTo(spinner.Scale, HitObject.TimePreempt / 1.4f, Easing.OutQuint); Disc.RotateTo(-720); symbol.RotateTo(-720); mainContainer .ScaleTo(0) - .ScaleTo(spinner.Scale * circle.DrawHeight / DrawHeight * 1.4f, TIME_PREEMPT - 150, Easing.OutQuint) + .ScaleTo(spinner.Scale * circle.DrawHeight / DrawHeight * 1.4f, HitObject.TimePreempt - 150, Easing.OutQuint) .Then() .ScaleTo(1, 500, Easing.OutQuint); } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs index 75c2c15084..4914ec07c0 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Pieces/SliderBody.cs @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces public void UpdateProgress(double progress, int repeat) { double start = 0; - double end = snakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - DrawableOsuHitObject.TIME_PREEMPT)) / DrawableOsuHitObject.TIME_FADEIN, 0, 1) : 1; + double end = snakingIn ? MathHelper.Clamp((Time.Current - (slider.StartTime - slider.TimePreempt)) / slider.TimeFadein, 0, 1) : 1; if (repeat >= slider.RepeatCount - 1) { diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index a3a6527b31..0a96d6367a 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -20,6 +20,9 @@ namespace osu.Game.Rulesets.Osu.Objects private const double hit_window_100 = 80; private const double hit_window_300 = 30; + public float TimePreempt = 600; + public float TimeFadein = 400; + public Vector2 Position { get; set; } public float X => Position.X; public float Y => Position.Y; @@ -72,6 +75,13 @@ namespace osu.Game.Rulesets.Osu.Objects { base.ApplyDefaultsToSelf(controlPointInfo, difficulty); + if (difficulty.ApproachRate >= 5) + TimePreempt = 1200 - (difficulty.ApproachRate - 5) * 150; + else + TimePreempt = 1800 - difficulty.ApproachRate * 120; + TimeFadein = TimePreempt / 3; + + Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2; } } diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index ba774e887f..a4c345f96c 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -9,6 +9,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables; using System; using System.Diagnostics; using osu.Framework.Graphics; +using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; @@ -133,7 +134,7 @@ namespace osu.Game.Rulesets.Osu.Replays // Do some nice easing for cursor movements if (Frames.Count > 0) { - moveToHitObject(h.StartTime, startPosition, h.Radius, easing); + moveToHitObject(h, startPosition, easing); } // Add frames to click the hitobject @@ -191,12 +192,12 @@ namespace osu.Game.Rulesets.Osu.Replays } } - private void moveToHitObject(double targetTime, Vector2 targetPos, double hitObjectRadius, Easing easing) + private void moveToHitObject(OsuHitObject h, Vector2 targetPos, Easing easing) { ReplayFrame lastFrame = Frames[Frames.Count - 1]; // Wait until Auto could "see and react" to the next note. - double waitTime = targetTime - Math.Max(0.0, DrawableOsuHitObject.TIME_PREEMPT - reactionTime); + double waitTime = h.StartTime - Math.Max(0.0, h.TimePreempt - reactionTime); if (waitTime > lastFrame.Time) { lastFrame = new ReplayFrame(waitTime, lastFrame.MouseX, lastFrame.MouseY, lastFrame.ButtonState); @@ -205,17 +206,17 @@ namespace osu.Game.Rulesets.Osu.Replays Vector2 lastPosition = lastFrame.Position; - double timeDifference = ApplyModsToTime(targetTime - lastFrame.Time); + double timeDifference = ApplyModsToTime(h.StartTime - lastFrame.Time); // Only "snap" to hitcircles if they are far enough apart. As the time between hitcircles gets shorter the snapping threshold goes up. if (timeDifference > 0 && // Sanity checks - ((lastPosition - targetPos).Length > hitObjectRadius * (1.5 + 100.0 / timeDifference) || // Either the distance is big enough + ((lastPosition - targetPos).Length > h.Radius * (1.5 + 100.0 / timeDifference) || // Either the distance is big enough timeDifference >= 266)) // ... or the beats are slow enough to tap anyway. { // Perform eased movement - for (double time = lastFrame.Time + FrameDelay; time < targetTime; time += FrameDelay) + for (double time = lastFrame.Time + FrameDelay; time < h.StartTime; time += FrameDelay) { - Vector2 currentPosition = Interpolation.ValueAt(time, lastPosition, targetPos, lastFrame.Time, targetTime, easing); + Vector2 currentPosition = Interpolation.ValueAt(time, lastPosition, targetPos, lastFrame.Time, h.StartTime, easing); AddFrameToReplay(new ReplayFrame((int)time, currentPosition.X, currentPosition.Y, lastFrame.ButtonState)); } From 064758b96d9eac2bd9be26be6ff6ea84e52594ee Mon Sep 17 00:00:00 2001 From: Shawdooow Date: Sun, 31 Dec 2017 11:30:58 -0500 Subject: [PATCH 020/206] fixes --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs | 1 - osu.Game.Rulesets.Osu/Mods/OsuMod.cs | 4 ++-- .../Objects/Drawables/DrawableHitCircle.cs | 2 +- .../Objects/Drawables/DrawableOsuHitObject.cs | 9 +-------- .../Objects/Drawables/DrawableSlider.cs | 10 ++-------- .../Objects/Drawables/DrawableSpinner.cs | 2 +- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 2 +- osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs | 2 -- 8 files changed, 8 insertions(+), 24 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index e8742d24a6..8ed6573d41 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -5,7 +5,6 @@ using osu.Framework.Graphics; using osu.Game.Beatmaps; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.Objects.Drawables; namespace osu.Game.Rulesets.Osu.Beatmaps { diff --git a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs index dd01ef9af7..ba21cd8a10 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var d in drawables.OfType()) { d.ApplyCustomUpdateState += ApplyHiddenState; - d.FadeInDuration = d.HitObject.TimePreempt * fade_in_duration_multiplier; + d.HitObject.TimeFadein = d.HitObject.TimePreempt * (float)fade_in_duration_multiplier; } } @@ -50,7 +50,7 @@ namespace osu.Game.Rulesets.Osu.Mods if (!(drawable is DrawableOsuHitObject d)) return; - var fadeOutStartTime = d.HitObject.StartTime - d.HitObject.TimePreempt + d.FadeInDuration; + var fadeOutStartTime = d.HitObject.StartTime - d.HitObject.TimePreempt + d.HitObject.TimeFadein; var fadeOutDuration = d.HitObject.TimePreempt * fade_out_duration_multiplier; // new duration from completed fade in to end (before fading out) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index bb405ea7fd..6ecfd82e89 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { base.UpdatePreemptState(); - ApproachCircle.FadeIn(Math.Min(FadeInDuration * 2, HitObject.TimePreempt)); + ApproachCircle.FadeIn(Math.Min(HitObject.TimeFadein * 2, HitObject.TimePreempt)); ApproachCircle.ScaleTo(1.1f, HitObject.TimePreempt); } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs index 1a8ec68df2..788ca43a0d 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuHitObject.cs @@ -10,18 +10,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { public class DrawableOsuHitObject : DrawableHitObject { - /// - /// The number of milliseconds used to fade in. - /// - public virtual double FadeInDuration { get; set; } - public override bool IsPresent => base.IsPresent || State.Value == ArmedState.Idle && Time.Current >= HitObject.StartTime - HitObject.TimePreempt; protected DrawableOsuHitObject(OsuHitObject hitObject) : base(hitObject) { - FadeInDuration = hitObject.TimeFadein; - AccentColour = HitObject.ComboColour; Alpha = 0; } @@ -42,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables } } - protected virtual void UpdatePreemptState() => this.FadeIn(FadeInDuration); + protected virtual void UpdatePreemptState() => this.FadeIn(HitObject.TimeFadein); protected virtual void UpdateCurrentState(ArmedState state) { diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 5a8bcae277..f604ca6ccd 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -71,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables foreach (var tick in s.NestedHitObjects.OfType()) { var repeatStartTime = s.StartTime + tick.RepeatIndex * repeatDuration; - var fadeInTime = repeatStartTime + (tick.StartTime - repeatStartTime) / 2 - (tick.RepeatIndex == 0 ? FadeInDuration : FadeInDuration / 2); + var fadeInTime = repeatStartTime + (tick.StartTime - repeatStartTime) / 2 - (tick.RepeatIndex == 0 ? HitObject.TimeFadein : HitObject.TimeFadein / 2); var fadeOutTime = repeatStartTime + repeatDuration; var drawableTick = new DrawableSliderTick(tick) @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables foreach (var repeatPoint in s.NestedHitObjects.OfType()) { var repeatStartTime = s.StartTime + repeatPoint.RepeatIndex * repeatDuration; - var fadeInTime = repeatStartTime + (repeatPoint.StartTime - repeatStartTime) / 2 - (repeatPoint.RepeatIndex == 0 ? FadeInDuration : FadeInDuration / 2); + var fadeInTime = repeatStartTime + (repeatPoint.StartTime - repeatStartTime) / 2 - (repeatPoint.RepeatIndex == 0 ? HitObject.TimeFadein : HitObject.TimeFadein / 2); var fadeOutTime = repeatStartTime + repeatDuration; var drawableRepeatPoint = new DrawableRepeatPoint(repeatPoint, this) @@ -106,12 +106,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables private int currentRepeat; public bool Tracking; - public override double FadeInDuration - { - get { return base.FadeInDuration; } - set { InitialCircle.FadeInDuration = base.FadeInDuration = value; } - } - protected override void Update() { base.Update(); diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index e471ad4e9b..1e2ec0a112 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -167,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { Disc.Tracking = OsuActionInputManager.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton); if (!spmCounter.IsPresent && Disc.Tracking) - spmCounter.FadeIn(FadeInDuration); + spmCounter.FadeIn(HitObject.TimeFadein); base.Update(); } diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index 0a96d6367a..1c0f64322f 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -79,7 +79,7 @@ namespace osu.Game.Rulesets.Osu.Objects TimePreempt = 1200 - (difficulty.ApproachRate - 5) * 150; else TimePreempt = 1800 - difficulty.ApproachRate * 120; - TimeFadein = TimePreempt / 3; + TimeFadein = TimePreempt * 0.66f; Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2; diff --git a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs index a4c345f96c..29820883e9 100644 --- a/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs +++ b/osu.Game.Rulesets.Osu/Replays/OsuAutoGenerator.cs @@ -5,11 +5,9 @@ using OpenTK; using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Osu.Objects; -using osu.Game.Rulesets.Osu.Objects.Drawables; using System; using System.Diagnostics; using osu.Framework.Graphics; -using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; From 1502fde1b047580e83fbc3713615e5b744a9c9a7 Mon Sep 17 00:00:00 2001 From: Shawdooow Date: Sun, 31 Dec 2017 12:04:31 -0500 Subject: [PATCH 021/206] fix slider start circles --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index f604ca6ccd..c7034bc5be 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -58,7 +58,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables Scale = s.Scale, ComboColour = s.ComboColour, Samples = s.Samples, - SampleControlPoint = s.SampleControlPoint + SampleControlPoint = s.SampleControlPoint, + TimePreempt = s.TimePreempt, + TimeFadein = s.TimeFadein }) }; From 8957d82c894e38a598dc600edf96cffc013a33f9 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 1 Jan 2018 13:54:59 +0100 Subject: [PATCH 022/206] Updated submodule osu-framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 10cae790c6..6134dafccb 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 10cae790c6f1d559c326f9438958d0b012d61dc6 +Subproject commit 6134dafccb3368dac96d837537325c04b89fb8ee From 1df79c2f1b984018f4b4e7a14bdda4f85b5e45ff Mon Sep 17 00:00:00 2001 From: Shawdooow Date: Mon, 1 Jan 2018 10:30:09 -0500 Subject: [PATCH 023/206] Move stackThreshold up where possible --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs | 5 ++--- 1 file changed, 2 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index 8ed6573d41..ed19381243 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -99,6 +99,8 @@ namespace osu.Game.Rulesets.Osu.Beatmaps OsuHitObject objectI = beatmap.HitObjects[i]; if (objectI.StackHeight != 0 || objectI is Spinner) continue; + float stackThreshold = objectI.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; + /* If this object is a hitcircle, then we enter this "special" case. * It either ends with a stack of hitcircles only, or a stack of hitcircles that are underneath a slider. * Any other case is handled by the "is Slider" code below this. @@ -111,7 +113,6 @@ namespace osu.Game.Rulesets.Osu.Beatmaps if (objectN is Spinner) continue; double endTime = (objectN as IHasEndTime)?.EndTime ?? objectN.StartTime; - float stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; if (objectI.StartTime - endTime > stackThreshold) //We are no longer within stacking range of the previous object. @@ -165,8 +166,6 @@ namespace osu.Game.Rulesets.Osu.Beatmaps OsuHitObject objectN = beatmap.HitObjects[n]; if (objectN is Spinner) continue; - float stackThreshold = objectN.TimePreempt * beatmap.BeatmapInfo?.StackLeniency ?? 0.7f; - if (objectI.StartTime - objectN.StartTime > stackThreshold) //We are no longer within stacking range of the previous object. break; From e0beefdfd5b81113da47d6a005156693a6e094b0 Mon Sep 17 00:00:00 2001 From: Shawdooow Date: Mon, 1 Jan 2018 10:30:55 -0500 Subject: [PATCH 024/206] make this a float --- osu.Game.Rulesets.Osu/Mods/OsuMod.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs index ba21cd8a10..8bd3c5f92d 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Mods public override string Description => @"Play with no approach circles and fading notes for a slight score advantage."; public override double ScoreMultiplier => 1.06; - private const double fade_in_duration_multiplier = 0.4; + private const float fade_in_duration_multiplier = 0.4f; private const double fade_out_duration_multiplier = 0.3; public void ApplyToDrawableHitObjects(IEnumerable drawables) @@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Osu.Mods foreach (var d in drawables.OfType()) { d.ApplyCustomUpdateState += ApplyHiddenState; - d.HitObject.TimeFadein = d.HitObject.TimePreempt * (float)fade_in_duration_multiplier; + d.HitObject.TimeFadein = d.HitObject.TimePreempt * fade_in_duration_multiplier; } } From a00f92dcb459eb1354bd691b0f1e4c13151e5cc0 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 2 Jan 2018 17:18:49 +0100 Subject: [PATCH 025/206] change unnecessary cast --- osu.Game/Overlays/SocialOverlay.cs | 11 ++++++----- 1 file changed, 6 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index d2f56f4061..024e3aee73 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -162,15 +162,16 @@ namespace osu.Game.Overlays switch (Header.Tabs.Current.Value) { case SocialTab.OnlinePlayers: - getUsersRequest = new GetUsersRequest(); // TODO filter??? - ((GetUsersRequest)getUsersRequest).Success += response => finishRequest(response.Select(r => r.User)); + var userRequest = new GetUsersRequest(); // TODO filter??? + userRequest.Success += response => finishRequest(response.Select(r => r.User)); + api.Queue(getUsersRequest = userRequest); break; case SocialTab.OnlineFriends: - getUsersRequest = new GetFriendsRequest(); // TODO filter??? - ((GetFriendsRequest)getUsersRequest).Success += finishRequest; + var friendRequest = new GetFriendsRequest(); // TODO filter??? + friendRequest.Success += finishRequest; + api.Queue(getUsersRequest = friendRequest); break; } - api.Queue(getUsersRequest); loading.Show(); } From 313dfd4d46a9b05d72cbaab2679baebe6b3cc616 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 2 Jan 2018 17:22:12 +0100 Subject: [PATCH 026/206] remove unnecessary task + rename method --- osu.Game/Overlays/SocialOverlay.cs | 17 +++++++---------- 1 file changed, 7 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 024e3aee73..b72fddc908 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -163,28 +163,25 @@ namespace osu.Game.Overlays { case SocialTab.OnlinePlayers: var userRequest = new GetUsersRequest(); // TODO filter??? - userRequest.Success += response => finishRequest(response.Select(r => r.User)); + userRequest.Success += response => updateUsers(response.Select(r => r.User)); api.Queue(getUsersRequest = userRequest); break; case SocialTab.OnlineFriends: var friendRequest = new GetFriendsRequest(); // TODO filter??? - friendRequest.Success += finishRequest; + friendRequest.Success += updateUsers; api.Queue(getUsersRequest = friendRequest); break; } loading.Show(); } - private void finishRequest(IEnumerable newUsers) + private void updateUsers(IEnumerable newUsers) { - Task.Run(() => + Schedule(() => { - Schedule(() => - { - Users = newUsers; - recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); - loading.Hide(); - }); + Users = newUsers; + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); + loading.Hide(); }); } From 52c2ba49cf32415b875f3b62f32ffd0258b7cbe8 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 2 Jan 2018 17:42:44 +0100 Subject: [PATCH 027/206] make loading indicator more visible by deleting panels preemptively --- osu.Game/Overlays/SocialOverlay.cs | 21 +++++++++++++-------- 1 file changed, 13 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index b72fddc908..d9cbdf37c8 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -93,12 +93,7 @@ namespace osu.Game.Overlays private void recreatePanels(PanelDisplayStyle displayStyle) { - if (panels != null) - { - panels.FadeOut(200); - panels.Expire(); - panels = null; - } + clearPanels(); if (Users == null) return; @@ -139,6 +134,15 @@ namespace osu.Game.Overlays }); } + private void clearPanels() + { + if (panels != null) + { + panels.Expire(); + panels = null; + } + } + private APIRequest getUsersRequest; private readonly Bindable currentQuery = new Bindable(); @@ -153,10 +157,11 @@ namespace osu.Game.Overlays return; Users = null; + clearPanels(); loading.Hide(); getUsersRequest?.Cancel(); - if (api == null || api.State == APIState.Offline) + if (api?.IsLoggedIn == false) return; switch (Header.Tabs.Current.Value) @@ -180,8 +185,8 @@ namespace osu.Game.Overlays Schedule(() => { Users = newUsers; - recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); loading.Hide(); + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); }); } From 699902234b395294f36dea482568ff1c1ac3507e Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 2 Jan 2018 17:58:11 +0100 Subject: [PATCH 028/206] remove unused code --- osu.Game/Overlays/SocialOverlay.cs | 11 ++++------- 1 file changed, 4 insertions(+), 7 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index d9cbdf37c8..979ce2c851 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -15,9 +15,6 @@ using osu.Game.Online.API.Requests; using osu.Game.Overlays.SearchableList; using osu.Game.Overlays.Social; using osu.Game.Users; -using osu.Framework.Configuration; -using osu.Framework.Threading; -using System.Threading.Tasks; namespace osu.Game.Overlays { @@ -79,7 +76,7 @@ namespace osu.Game.Overlays // } //}; - currentQuery.BindTo(Filter.Search.Current); + //currentQuery.BindTo(Filter.Search.Current); Filter.Tabs.Current.ValueChanged += sortCriteria => Scheduler.AddOnce(updateSearch); } @@ -145,13 +142,13 @@ namespace osu.Game.Overlays private APIRequest getUsersRequest; - private readonly Bindable currentQuery = new Bindable(); + //private readonly Bindable currentQuery = new Bindable(); - private ScheduledDelegate queryChangedDebounce; + //private ScheduledDelegate queryChangedDebounce; private void updateSearch() { - queryChangedDebounce?.Cancel(); + //queryChangedDebounce?.Cancel(); if (!IsLoaded) return; From c92345cf214cf42798cc6c57a7ab10ab5801bc56 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 31 Dec 2017 22:09:07 +0900 Subject: [PATCH 029/206] Give fruit a border From 31865b4d9668952551d6c14a012b563366083d13 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Jan 2018 15:12:27 +0900 Subject: [PATCH 030/206] Rename conflicting variable --- osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs | 2 +- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs | 2 +- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs index 31b374f71d..6328d88758 100644 --- a/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Osu/Beatmaps/OsuBeatmapProcessor.cs @@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count; } - obj.ComboIndex = comboIndex++; + obj.IndexInCurrentCombo = comboIndex++; obj.ComboColour = beatmap.ComboColors[colourIndex]; } } diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs index 72ca9b37a8..b350cd1656 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs @@ -48,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables }, number = new NumberPiece { - Text = (HitObject.ComboIndex + 1).ToString(), + Text = (HitObject.IndexInCurrentCombo + 1).ToString(), }, ring = new RingPiece(), flash = new FlashPiece(), diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs index 5a8bcae277..6217418293 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs @@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { StartTime = s.StartTime, Position = s.StackedPosition, - ComboIndex = s.ComboIndex, + IndexInCurrentCombo = s.IndexInCurrentCombo, Scale = s.Scale, ComboColour = s.ComboColour, Samples = s.Samples, diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index a3a6527b31..5b32f4525c 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Objects public Color4 ComboColour { get; set; } = Color4.Gray; public virtual bool NewCombo { get; set; } - public int ComboIndex { get; set; } + public int IndexInCurrentCombo { get; set; } public double HitWindowFor(HitResult result) { From 02131d75d4e14cf653fef363eca677b62e86bead Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Jan 2018 16:31:57 +0900 Subject: [PATCH 031/206] Let fruits know what index they are in the beatmap to draw a visual representation --- .../Beatmaps/CatchBeatmapProcessor.cs | 6 ++---- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 14 +++++++++++++- 2 files changed, 15 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index 9901dbde18..bed15ef74a 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps if (beatmap.ComboColors.Count == 0) return; - int comboIndex = 0; + int index = 0; int colourIndex = 0; CatchHitObject lastObj = null; @@ -31,12 +31,10 @@ namespace osu.Game.Rulesets.Catch.Beatmaps if (obj.NewCombo) { if (lastObj != null) lastObj.LastInCombo = true; - - comboIndex = 0; colourIndex = (colourIndex + 1) % beatmap.ComboColors.Count; } - obj.ComboIndex = comboIndex++; + obj.IndexInBeatmap = index++; obj.ComboColour = beatmap.ComboColors[colourIndex]; lastObj = obj; diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index 9952e85c70..bda9f70032 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -16,7 +16,10 @@ namespace osu.Game.Rulesets.Catch.Objects public float X { get; set; } public Color4 ComboColour { get; set; } = Color4.Gray; - public int ComboIndex { get; set; } + + public int IndexInBeatmap { get; set; } + + public virtual FruitVisualRepresentation VisualRepresentation => (FruitVisualRepresentation)(IndexInBeatmap % 4); public virtual bool NewCombo { get; set; } @@ -44,4 +47,13 @@ namespace osu.Game.Rulesets.Catch.Objects Scale = 1.0f - 0.7f * (difficulty.CircleSize - 5) / 5; } } + + public enum FruitVisualRepresentation + { + Pear, + Grape, + Apple, + Orange, + Banana // banananananannaanana + } } From fd34b36e1a4ee837731ba462811e51f682b2d991 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Jan 2018 16:32:09 +0900 Subject: [PATCH 032/206] Add fruit drawable testcase --- .../Tests/TestCaseFruitObjects.cs | 65 +++++++++++++++++++ .../osu.Game.Rulesets.Catch.csproj | 1 + 2 files changed, 66 insertions(+) create mode 100644 osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs new file mode 100644 index 0000000000..45a6c1c808 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs @@ -0,0 +1,65 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Tests.Visual; +using OpenTK; + +namespace osu.Game.Rulesets.Catch.Tests +{ + public class TestCaseFruitObjects : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(CatchHitObject), + typeof(Fruit), + typeof(DrawableCatchHitObject), + typeof(DrawableFruit), + }; + + public TestCaseFruitObjects() + { + Add(new GridContainer + { + RelativeSizeAxes = Axes.Both, + Content = new[] + { + new Drawable[] + { + createDrawable(0), + createDrawable(1), + }, + new Drawable[] + { + createDrawable(2), + createDrawable(3), + }, + } + }); + } + + protected override void Update() + { + base.Update(); + } + + private DrawableFruit createDrawable(int index) => new DrawableFruit(new Fruit + { + StartTime = 1000000, + IndexInBeatmap = index + }) + { + Anchor = Anchor.Centre, + RelativePositionAxes = Axes.Both, + Position = Vector2.Zero, + Alpha = 1, + LifetimeStart = double.NegativeInfinity, + LifetimeEnd = double.PositiveInfinity, + }; + } +} diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 16c909e063..b15f05bb09 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -64,6 +64,7 @@ + From cf1f84cc323d87362228a324981839677c9d9d7e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 31 Dec 2017 22:09:07 +0900 Subject: [PATCH 033/206] Give fruit a border --- .../Objects/Drawable/DrawableFruit.cs | 30 ++++++++++++++++++- 1 file changed, 29 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 9f46bbd3a4..dbb0ca71cc 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -4,15 +4,19 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.MathUtils; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; using OpenTK.Graphics; +using System; namespace osu.Game.Rulesets.Catch.Objects.Drawable { public class DrawableFruit : DrawableCatchHitObject { + private Circle border; + public DrawableFruit(Fruit h) : base(h) { @@ -69,7 +73,25 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable AccentColour = AccentColour, }, } - } + }, + border = new Circle + { + Size = new Vector2(Pulp.PULP_SIZE * 3.5f), + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + BorderColour = AccentColour, + BorderThickness = 3, + Children = new Framework.Graphics.Drawable[] + { + new Box + { + AlwaysPresent = true, + Colour = AccentColour, + Alpha = 0, + RelativeSizeAxes = Axes.Both + } + } + }, }; if (HitObject.HyperDash) @@ -86,5 +108,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable }); } } + + protected override void Update() + { + base.Update(); + border.Alpha = (float)MathHelper.Clamp((HitObject.StartTime - Time.Current) / 1000, 0, 1); + } } } From 921ca6956d1ec892df11debdf31d23590540f72a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Jan 2018 18:26:54 +0900 Subject: [PATCH 034/206] Improve fruit visuals --- .../Objects/CatchHitObject.cs | 38 ++- .../Objects/Drawable/DrawableDroplet.cs | 4 +- .../Objects/Drawable/DrawableFruit.cs | 234 ++++++++++++++---- .../Objects/Drawable/Pieces/Pulp.cs | 11 +- .../Tests/TestCaseFruitObjects.cs | 18 +- 5 files changed, 235 insertions(+), 70 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index bda9f70032..f36459dc76 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects; @@ -15,7 +16,36 @@ namespace osu.Game.Rulesets.Catch.Objects public float X { get; set; } - public Color4 ComboColour { get; set; } = Color4.Gray; + public Color4 ComboColour + { + get + { + switch (VisualRepresentation) + { + default: + case FruitVisualRepresentation.Triforce: + return new Color4(17, 136, 170, 255); + case FruitVisualRepresentation.Grape: + return new Color4(204, 102, 0, 255); + case FruitVisualRepresentation.DPad: + return new Color4(121, 9, 13, 255); + case FruitVisualRepresentation.Pineapple: + return new Color4(102, 136, 0, 255); + case FruitVisualRepresentation.Banana: + switch (RNG.Next(0, 3)) + { + default: + return new Color4(255, 240, 0, 255); + case 1: + return new Color4(255, 192, 0, 255); + case 2: + return new Color4(214, 221, 28, 255); + } + } + } + + set { } + } public int IndexInBeatmap { get; set; } @@ -50,10 +80,10 @@ namespace osu.Game.Rulesets.Catch.Objects public enum FruitVisualRepresentation { - Pear, + Triforce, Grape, - Apple, - Orange, + DPad, + Pineapple, Banana // banananananannaanana } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index 2b2a8e7f8d..9fdc4f9cd7 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -14,9 +14,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable : base(h) { Origin = Anchor.Centre; - - Size = new Vector2(Pulp.PULP_SIZE); - + Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS); AccentColour = h.ComboColour; Masking = false; } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index dbb0ca71cc..e1b2b23f71 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -1,15 +1,15 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework.Allocation; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.MathUtils; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; using OpenTK.Graphics; -using System; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -22,65 +22,33 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { Origin = Anchor.Centre; - Size = new Vector2(Pulp.PULP_SIZE * 2.2f, Pulp.PULP_SIZE * 2.8f); + Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS); AccentColour = HitObject.ComboColour; Masking = false; - Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; + //Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; } [BackgroundDependencyLoader] private void load() { - Children = new Framework.Graphics.Drawable[] + Children = new[] { - //todo: share this more - new BufferedContainer - { - RelativeSizeAxes = Axes.Both, - CacheDrawnFrameBuffer = true, - Children = new Framework.Graphics.Drawable[] - { - new Pulp - { - RelativePositionAxes = Axes.Both, - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre, - AccentColour = AccentColour, - Scale = new Vector2(0.6f), - }, - new Pulp - { - RelativePositionAxes = Axes.Both, - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - AccentColour = AccentColour, - Y = -0.08f - }, - new Pulp - { - RelativePositionAxes = Axes.Both, - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreRight, - AccentColour = AccentColour, - Y = -0.08f - }, - new Pulp - { - RelativePositionAxes = Axes.Both, - Anchor = Anchor.BottomCentre, - Origin = Anchor.BottomCentre, - AccentColour = AccentColour, - }, - } - }, + createPulp(HitObject.VisualRepresentation), border = new Circle { - Size = new Vector2(Pulp.PULP_SIZE * 3.5f), + EdgeEffect = new EdgeEffectParameters + { + Hollow = true, + Type = EdgeEffectType.Glow, + Radius = 4, + Colour = AccentColour.Darken(1).Opacity(0.8f) + }, + Size = new Vector2(Height * 1.5f), Anchor = Anchor.Centre, Origin = Anchor.Centre, - BorderColour = AccentColour, - BorderThickness = 3, + BorderColour = Color4.White, + BorderThickness = 2.5f, Children = new Framework.Graphics.Drawable[] { new Box @@ -104,11 +72,179 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable AccentColour = Color4.Red, Blending = BlendingMode.Additive, Alpha = 0.5f, - Scale = new Vector2(2) + Scale = new Vector2(1.333f) }); } } + private Framework.Graphics.Drawable createPulp(FruitVisualRepresentation representation) + { + const float large_pulp_3 = 13f; + const float distance_from_centre_3 = 0.23f; + + const float large_pulp_4 = large_pulp_3 * 0.925f; + const float distance_from_centre_4 = distance_from_centre_3 / 0.925f; + + const float small_pulp = large_pulp_3 / 2; + + Vector2 positionAt(float angle, float distance) => new Vector2( + distance * (float)Math.Sin(angle * Math.PI / 180), + distance * (float)Math.Cos(angle * Math.PI / 180)); + + switch (representation) + { + default: + return new Container { }; + case FruitVisualRepresentation.DPad: + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Framework.Graphics.Drawable[] + { + new Pulp + { + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, + AccentColour = AccentColour, + Size = new Vector2(small_pulp), + Y = 0.05f, + }, + new Pulp + { + AccentColour = AccentColour, + Size = new Vector2(large_pulp_4), + Position = positionAt(0, distance_from_centre_4), + }, + new Pulp + { + AccentColour = AccentColour, + Size = new Vector2(large_pulp_4), + Position = positionAt(90, distance_from_centre_4), + }, + new Pulp + { + AccentColour = AccentColour, + Size = new Vector2(large_pulp_4), + Position = positionAt(180, distance_from_centre_4), + }, + new Pulp + { + Size = new Vector2(large_pulp_4), + AccentColour = AccentColour, + Position = positionAt(270, distance_from_centre_4), + }, + } + }; + case FruitVisualRepresentation.Pineapple: + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Framework.Graphics.Drawable[] + { + new Pulp + { + Anchor = Anchor.TopCentre, + Origin = Anchor.BottomCentre, + AccentColour = AccentColour, + Size = new Vector2(small_pulp), + Y = 0.1f, + }, + new Pulp + { + AccentColour = AccentColour, + Size = new Vector2(large_pulp_4), + Position = positionAt(45, distance_from_centre_4), + }, + new Pulp + { + AccentColour = AccentColour, + Size = new Vector2(large_pulp_4), + Position = positionAt(135, distance_from_centre_4), + }, + new Pulp + { + AccentColour = AccentColour, + Size = new Vector2(large_pulp_4), + Position = positionAt(225, distance_from_centre_4), + }, + new Pulp + { + Size = new Vector2(large_pulp_4), + AccentColour = AccentColour, + Position = positionAt(315, distance_from_centre_4), + }, + } + }; + case FruitVisualRepresentation.Triforce: + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Framework.Graphics.Drawable[] + { + new Pulp + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + AccentColour = AccentColour, + Size = new Vector2(small_pulp), + Y = -0.1f, + }, + new Pulp + { + AccentColour = AccentColour, + Size = new Vector2(large_pulp_3), + Position = positionAt(60, distance_from_centre_3), + }, + new Pulp + { + AccentColour = AccentColour, + Size = new Vector2(large_pulp_3), + Position = positionAt(180, distance_from_centre_3), + }, + new Pulp + { + Size = new Vector2(large_pulp_3), + AccentColour = AccentColour, + Position = positionAt(300, distance_from_centre_3), + }, + } + }; + case FruitVisualRepresentation.Grape: + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Framework.Graphics.Drawable[] + { + new Pulp + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + AccentColour = AccentColour, + Size = new Vector2(small_pulp), + }, + new Pulp + { + AccentColour = AccentColour, + Size = new Vector2(large_pulp_3), + Position = positionAt(0, distance_from_centre_3), + }, + new Pulp + { + AccentColour = AccentColour, + Size = new Vector2(large_pulp_3), + Position = positionAt(120, distance_from_centre_3), + }, + new Pulp + { + Size = new Vector2(large_pulp_3), + AccentColour = AccentColour, + Position = positionAt(240, distance_from_centre_3), + }, + } + }; + } + } + protected override void Update() { base.Update(); diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs index 2de266b3f0..22f64c61a0 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs @@ -6,18 +6,17 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics; -using OpenTK; using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces { public class Pulp : Circle, IHasAccentColour { - public const float PULP_SIZE = (float)CatchHitObject.OBJECT_RADIUS / 2.2f; - public Pulp() { - Size = new Vector2(PULP_SIZE); + RelativePositionAxes = Axes.Both; + Anchor = Anchor.Centre; + Origin = Anchor.Centre; Blending = BlendingMode.Additive; Colour = Color4.White.Opacity(0.9f); @@ -34,8 +33,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces EdgeEffect = new EdgeEffectParameters { Type = EdgeEffectType.Glow, - Radius = 5, - Colour = accentColour.Lighten(100), + Radius = 8, + Colour = accentColour.Darken(0.2f).Opacity(0.75f) }; } } diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs index 45a6c1c808..975795863f 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs @@ -7,6 +7,7 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using osu.Game.Tests.Visual; using OpenTK; @@ -18,8 +19,11 @@ namespace osu.Game.Rulesets.Catch.Tests { typeof(CatchHitObject), typeof(Fruit), + typeof(Droplet), typeof(DrawableCatchHitObject), typeof(DrawableFruit), + typeof(DrawableDroplet), + typeof(Pulp), }; public TestCaseFruitObjects() @@ -33,25 +37,23 @@ namespace osu.Game.Rulesets.Catch.Tests { createDrawable(0), createDrawable(1), + createDrawable(2), }, new Drawable[] { - createDrawable(2), createDrawable(3), + createDrawable(4), + createDrawable(5), }, } }); } - protected override void Update() - { - base.Update(); - } - private DrawableFruit createDrawable(int index) => new DrawableFruit(new Fruit { - StartTime = 1000000, - IndexInBeatmap = index + StartTime = 1000000000000, + IndexInBeatmap = index, + Scale = 1.5f, }) { Anchor = Anchor.Centre, From b137c3b2caa021c656e9af88b2c6d13dac26501d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Jan 2018 18:35:43 +0900 Subject: [PATCH 035/206] Adjust ticks size --- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index 9fdc4f9cd7..73c91c0130 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable : base(h) { Origin = Anchor.Centre; - Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS); + Size = new Vector2((float)CatchHitObject.OBJECT_RADIUS) / 4; AccentColour = h.ComboColour; Masking = false; } @@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Child = new Pulp { AccentColour = AccentColour, - Scale = new Vector2(0.8f), + Size = Size }; } } From 4ee845fea8ea3c9113ed60868ea873e035770d13 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Jan 2018 18:38:29 +0900 Subject: [PATCH 036/206] Adjust border thickness and fade out rate of border --- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index e1b2b23f71..40f58fd5ea 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -42,13 +42,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Hollow = true, Type = EdgeEffectType.Glow, Radius = 4, - Colour = AccentColour.Darken(1).Opacity(0.8f) + Colour = AccentColour.Darken(1).Opacity(0.6f) }, Size = new Vector2(Height * 1.5f), Anchor = Anchor.Centre, Origin = Anchor.Centre, BorderColour = Color4.White, - BorderThickness = 2.5f, + BorderThickness = 4f, Children = new Framework.Graphics.Drawable[] { new Box @@ -248,7 +248,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected override void Update() { base.Update(); - border.Alpha = (float)MathHelper.Clamp((HitObject.StartTime - Time.Current) / 1000, 0, 1); + + border.Alpha = (float)MathHelper.Clamp((HitObject.StartTime - Time.Current) / 500, 0, 1); } } } From 9bde8d3da1055c11e67b1670f71d0fd9247da929 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Jan 2018 20:52:01 +0900 Subject: [PATCH 037/206] Move combo colouring to test case --- .../Objects/CatchHitObject.cs | 32 +--------- .../Tests/TestCaseFruitObjects.cs | 59 +++++++++++++++---- 2 files changed, 48 insertions(+), 43 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index f36459dc76..e5f8ad5402 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; using osu.Game.Rulesets.Objects; @@ -16,36 +15,7 @@ namespace osu.Game.Rulesets.Catch.Objects public float X { get; set; } - public Color4 ComboColour - { - get - { - switch (VisualRepresentation) - { - default: - case FruitVisualRepresentation.Triforce: - return new Color4(17, 136, 170, 255); - case FruitVisualRepresentation.Grape: - return new Color4(204, 102, 0, 255); - case FruitVisualRepresentation.DPad: - return new Color4(121, 9, 13, 255); - case FruitVisualRepresentation.Pineapple: - return new Color4(102, 136, 0, 255); - case FruitVisualRepresentation.Banana: - switch (RNG.Next(0, 3)) - { - default: - return new Color4(255, 240, 0, 255); - case 1: - return new Color4(255, 192, 0, 255); - case 2: - return new Color4(214, 221, 28, 255); - } - } - } - - set { } - } + public Color4 ComboColour { get; set; } public int IndexInBeatmap { get; set; } diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs index 975795863f..0b7bc3b186 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs @@ -5,11 +5,13 @@ using System; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.MathUtils; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using osu.Game.Tests.Visual; using OpenTK; +using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Tests { @@ -49,19 +51,52 @@ namespace osu.Game.Rulesets.Catch.Tests }); } - private DrawableFruit createDrawable(int index) => new DrawableFruit(new Fruit + private DrawableFruit createDrawable(int index) { - StartTime = 1000000000000, - IndexInBeatmap = index, - Scale = 1.5f, - }) + var fruit = new Fruit + { + StartTime = 1000000000000, + IndexInBeatmap = index, + Scale = 1.5f, + }; + + fruit.ComboColour = colourForRrepesentation(fruit.VisualRepresentation); + + return new DrawableFruit(fruit) + { + Anchor = Anchor.Centre, + RelativePositionAxes = Axes.Both, + Position = Vector2.Zero, + Alpha = 1, + LifetimeStart = double.NegativeInfinity, + LifetimeEnd = double.PositiveInfinity, + }; + } + + private Color4 colourForRrepesentation(FruitVisualRepresentation representation) { - Anchor = Anchor.Centre, - RelativePositionAxes = Axes.Both, - Position = Vector2.Zero, - Alpha = 1, - LifetimeStart = double.NegativeInfinity, - LifetimeEnd = double.PositiveInfinity, - }; + switch (representation) + { + default: + case FruitVisualRepresentation.Triforce: + return new Color4(17, 136, 170, 255); + case FruitVisualRepresentation.Grape: + return new Color4(204, 102, 0, 255); + case FruitVisualRepresentation.DPad: + return new Color4(121, 9, 13, 255); + case FruitVisualRepresentation.Pineapple: + return new Color4(102, 136, 0, 255); + case FruitVisualRepresentation.Banana: + switch (RNG.Next(0, 3)) + { + default: + return new Color4(255, 240, 0, 255); + case 1: + return new Color4(255, 192, 0, 255); + case 2: + return new Color4(214, 221, 28, 255); + } + } + } } } From b03cbaca7749008a639a95c30dfb56a3ead92327 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Jan 2018 20:52:11 +0900 Subject: [PATCH 038/206] Add back random rotation --- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 40f58fd5ea..df8ce2a43e 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -7,6 +7,7 @@ using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.MathUtils; using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces; using OpenTK; using OpenTK.Graphics; @@ -26,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable AccentColour = HitObject.ComboColour; Masking = false; - //Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; + Rotation = (float)(RNG.NextDouble() - 0.5f) * 40; } [BackgroundDependencyLoader] From 3c0631852108bd4a9e019c2a4d2596516fddf539 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Jan 2018 20:55:52 +0900 Subject: [PATCH 039/206] Improve the look of hyperdash fruit --- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index df8ce2a43e..92d38f1f60 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -40,10 +40,10 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { EdgeEffect = new EdgeEffectParameters { - Hollow = true, + Hollow = !HitObject.HyperDash, Type = EdgeEffectType.Glow, Radius = 4, - Colour = AccentColour.Darken(1).Opacity(0.6f) + Colour = HitObject.HyperDash ? Color4.Red : AccentColour.Darken(1).Opacity(0.6f) }, Size = new Vector2(Height * 1.5f), Anchor = Anchor.Centre, @@ -95,7 +95,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable switch (representation) { default: - return new Container { }; + return new Container(); case FruitVisualRepresentation.DPad: return new Container { From 843e9c53c0cda8146b2622dafa49e6ebd738197f Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Wed, 3 Jan 2018 15:38:43 +0200 Subject: [PATCH 040/206] Add test cases for new randomizer behaviour --- .../Visual/TestCaseBeatmapCarousel.cs | 57 +++++++++++++++++++ 1 file changed, 57 insertions(+) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs index c09b987407..8a0bd31678 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs @@ -128,6 +128,20 @@ namespace osu.Game.Tests.Visual selectedSets.Pop(); }); + private bool selectedBeatmapVisible() + { + var currentlySelected = carousel.Items.FirstOrDefault(s => s.Item is CarouselBeatmap && s.Item.State == CarouselItemState.Selected); + if (currentlySelected == null) + return true; + return !currentlySelected.Item.Filtered; + } + + private void checkInvisibleDifficultiesUnselectable() + { + nextRandom(); + AddAssert("Selection is visible", selectedBeatmapVisible); + } + /// /// Test keyboard traversal /// @@ -222,6 +236,15 @@ namespace osu.Game.Tests.Visual nextRandom(); AddAssert("ensure repeat", () => selectedSets.Contains(carousel.SelectedBeatmapSet)); + + AddStep("Add set with 100 difficulties", () => carousel.UpdateBeatmapSet(createTestBeatmapSetWith100Difficulties(set_count + 1))); + AddStep("Filter Extra", () => carousel.Filter(new FilterCriteria { SearchText = "Extra 10" }, false)); + checkInvisibleDifficultiesUnselectable(); + checkInvisibleDifficultiesUnselectable(); + checkInvisibleDifficultiesUnselectable(); + checkInvisibleDifficultiesUnselectable(); + checkInvisibleDifficultiesUnselectable(); + AddStep("Un-filter", () => carousel.Filter(new FilterCriteria(), false)); } /// @@ -384,6 +407,40 @@ namespace osu.Game.Tests.Visual }; } + private BeatmapSetInfo createTestBeatmapSetWith100Difficulties(int i) + { + var toReturn = new BeatmapSetInfo + { + ID = i, + OnlineBeatmapSetID = i, + Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), + Metadata = new BeatmapMetadata + { + OnlineBeatmapSetID = i, + // Create random metadata, then we can check if sorting works based on these + Artist = $"peppy{i.ToString().PadLeft(6, '0')}", + Title = $"test set #{i}!", + AuthorString = string.Concat(Enumerable.Repeat((char)('z' - Math.Min(25, i - 1)), 5)) + }, + Beatmaps = new List(), + }; + for (int b = 1; b < 101; b++) + { + toReturn.Beatmaps.Add(new BeatmapInfo + { + OnlineBeatmapID = b * 10, + Path = $"extra{b}.osu", + Version = $"Extra {b}", + StarDifficulty = 2, + BaseDifficulty = new BeatmapDifficulty + { + OverallDifficulty = 3.5f, + } + }); + } + return toReturn; + } + private class TestBeatmapCarousel : BeatmapCarousel { public new List Items => base.Items; From 1a8471bc3744c62c5f118af7faade21c13c6c13b Mon Sep 17 00:00:00 2001 From: Endrik Tombak Date: Wed, 3 Jan 2018 15:58:09 +0200 Subject: [PATCH 041/206] Replace not Filtered with Visible --- osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs index 8a0bd31678..c6581c0f34 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs @@ -133,7 +133,7 @@ namespace osu.Game.Tests.Visual var currentlySelected = carousel.Items.FirstOrDefault(s => s.Item is CarouselBeatmap && s.Item.State == CarouselItemState.Selected); if (currentlySelected == null) return true; - return !currentlySelected.Item.Filtered; + return currentlySelected.Item.Visible; } private void checkInvisibleDifficultiesUnselectable() From 23f3cb646799637e4bea2fb1beaf1342baec515d Mon Sep 17 00:00:00 2001 From: Shawdooow Date: Wed, 3 Jan 2018 10:01:28 -0500 Subject: [PATCH 042/206] address review --- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 7 ++----- 1 file changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index 1c0f64322f..feffb1ccf2 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -75,11 +75,8 @@ namespace osu.Game.Rulesets.Osu.Objects { base.ApplyDefaultsToSelf(controlPointInfo, difficulty); - if (difficulty.ApproachRate >= 5) - TimePreempt = 1200 - (difficulty.ApproachRate - 5) * 150; - else - TimePreempt = 1800 - difficulty.ApproachRate * 120; - TimeFadein = TimePreempt * 0.66f; + TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450); + TimeFadein = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1200, 800, 300); Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2; From 94f81a178433484be6fdd5abaa4e271808e622e6 Mon Sep 17 00:00:00 2001 From: Shawdooow Date: Wed, 3 Jan 2018 10:04:36 -0500 Subject: [PATCH 043/206] fix --- osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs index 7ed8854665..df5cb18a02 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs @@ -190,15 +190,15 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { base.UpdatePreemptState(); - circleContainer.ScaleTo(spinner.Scale * 0.3f); - circleContainer.ScaleTo(spinner.Scale, HitObject.TimePreempt / 1.4f, Easing.OutQuint); + circleContainer.ScaleTo(Spinner.Scale * 0.3f); + circleContainer.ScaleTo(Spinner.Scale, HitObject.TimePreempt / 1.4f, Easing.OutQuint); Disc.RotateTo(-720); symbol.RotateTo(-720); mainContainer .ScaleTo(0) - .ScaleTo(spinner.Scale * circle.DrawHeight / DrawHeight * 1.4f, HitObject.TimePreempt - 150, Easing.OutQuint) + .ScaleTo(Spinner.Scale * circle.DrawHeight / DrawHeight * 1.4f, HitObject.TimePreempt - 150, Easing.OutQuint) .Then() .ScaleTo(1, 500, Easing.OutQuint); } From 0e361aefebba2fc1d44d56313c7fc4b258a14756 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Wed, 3 Jan 2018 17:52:11 +0100 Subject: [PATCH 044/206] added new tabs and sort criteria --- osu.Game/Overlays/Social/FilterControl.cs | 2 ++ osu.Game/Overlays/Social/Header.cs | 6 ++++-- 2 files changed, 6 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index cf4097643e..a4d623892d 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -21,7 +21,9 @@ namespace osu.Game.Overlays.Social public enum SocialSortCriteria { + Relevance, Rank, + Name, //Location, //[Description("Time Zone")] //TimeZone, diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs index 94368d9786..7dd8222b0b 100644 --- a/osu.Game/Overlays/Social/Header.cs +++ b/osu.Game/Overlays/Social/Header.cs @@ -18,6 +18,7 @@ namespace osu.Game.Overlays.Social protected override Color4 BackgroundColour => OsuColour.FromHex(@"38202e"); protected override float TabStripWidth => 438; + protected override SocialTab DefaultTab => SocialTab.OnlinePlayers; protected override FontAwesome Icon => FontAwesome.fa_users; @@ -53,10 +54,11 @@ namespace osu.Game.Overlays.Social public enum SocialTab { + Search, [Description("Players")] - OnlinePlayers, + OnlinePlayers = SocialSortCriteria.Rank, [Description("Friends")] - OnlineFriends, + OnlineFriends = SocialSortCriteria.Name, //[Description("Online Team Members")] //OnlineTeamMembers, //[Description("Chat Channels")] From 988f6ac90128845153b30976b84f4dd62396898a Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Wed, 3 Jan 2018 17:53:50 +0100 Subject: [PATCH 045/206] fix SortDirection default to descending when retrieved data is ascending --- osu.Game.Tests/Visual/TestCaseSocial.cs | 9 +++++++++ osu.Game/Overlays/SocialOverlay.cs | 2 +- 2 files changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseSocial.cs b/osu.Game.Tests/Visual/TestCaseSocial.cs index ff0707c8ab..3f418174c7 100644 --- a/osu.Game.Tests/Visual/TestCaseSocial.cs +++ b/osu.Game.Tests/Visual/TestCaseSocial.cs @@ -1,13 +1,22 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using osu.Game.Overlays; +using osu.Game.Overlays.Social; using osu.Game.Users; namespace osu.Game.Tests.Visual { public class TestCaseSocial : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(FilterControl), + typeof(SocialOverlay) + }; + public TestCaseSocial() { SocialOverlay s = new SocialOverlay diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 979ce2c851..a0c4c2b18f 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -204,7 +204,7 @@ namespace osu.Game.Overlays public enum SortDirection { - Descending, Ascending, + Descending } } From 9d29adce27c5501bc89afbf7e1dcc7c64dee1281 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Wed, 3 Jan 2018 17:54:20 +0100 Subject: [PATCH 046/206] bring social tab+filter behaviour closer to direct --- osu.Game/Overlays/SocialOverlay.cs | 65 ++++++++++++++++++++---------- 1 file changed, 43 insertions(+), 22 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index a0c4c2b18f..c4ed14022e 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -21,7 +21,7 @@ namespace osu.Game.Overlays public class SocialOverlay : SearchableListOverlay, IOnlineComponent { private APIAccess api; - + private readonly LoadingAnimation loading; private FillFlowContainer panels; protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b"); @@ -31,10 +31,7 @@ namespace osu.Game.Overlays protected override SearchableListHeader CreateHeader() => new Header(); protected override SearchableListFilterControl CreateFilterControl() => new FilterControl(); - private readonly LoadingAnimation loading; - private IEnumerable users; - public IEnumerable Users { get { return users; } @@ -56,12 +53,38 @@ namespace osu.Game.Overlays Add(loading = new LoadingAnimation()); + Filter.Search.Current.ValueChanged += text => + { + if (text != string.Empty) + { + Header.Tabs.Current.Value = SocialTab.Search; + + if (Filter.Tabs.Current.Value == SocialSortCriteria.Rank) + Filter.Tabs.Current.Value = SocialSortCriteria.Relevance; + } + else + { + Header.Tabs.Current.Value = SocialTab.OnlinePlayers; + + if (Filter.Tabs.Current.Value == SocialSortCriteria.Relevance) + Filter.Tabs.Current.Value = SocialSortCriteria.Rank; + } + }; + Filter.DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels; // TODO sort our list in some way (either locally or with API call) - //Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += rankStatus => Scheduler.AddOnce(updateSearch); + //Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += sortOrder => Scheduler.AddOnce(updateSearch); - Header.Tabs.Current.ValueChanged += tab => Scheduler.AddOnce(updateSearch); + Header.Tabs.Current.ValueChanged += tab => + { + if (tab != SocialTab.Search) + { + //currentQuery.Value = string.Empty; + Filter.Tabs.Current.Value = (SocialSortCriteria)Header.Tabs.Current.Value; + Scheduler.AddOnce(updateSearch); + } + }; //currentQuery.ValueChanged += v => //{ @@ -70,15 +93,18 @@ namespace osu.Game.Overlays // if (string.IsNullOrEmpty(v)) // Scheduler.AddOnce(updateSearch); // else - // { - // Users = null; // queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500); - // } //}; //currentQuery.BindTo(Filter.Search.Current); - Filter.Tabs.Current.ValueChanged += sortCriteria => Scheduler.AddOnce(updateSearch); + Filter.Tabs.Current.ValueChanged += sortCriteria => + { + if (Header.Tabs.Current.Value != SocialTab.Search && sortCriteria != (SocialSortCriteria)Header.Tabs.Current.Value) + Header.Tabs.Current.Value = SocialTab.Search; + + Scheduler.AddOnce(updateSearch); + }; } [BackgroundDependencyLoader] @@ -122,19 +148,14 @@ namespace osu.Game.Overlays }) }; - LoadComponentAsync(newPanels, p => - { - if (panels != null) - ScrollFlow.Remove(panels); - - ScrollFlow.Add(panels = newPanels); - }); + LoadComponentAsync(newPanels, p => ScrollFlow.Add(panels = newPanels)); } private void clearPanels() { if (panels != null) { + ScrollFlow.Remove(panels); panels.Expire(); panels = null; } @@ -163,16 +184,16 @@ namespace osu.Game.Overlays switch (Header.Tabs.Current.Value) { - case SocialTab.OnlinePlayers: - var userRequest = new GetUsersRequest(); // TODO filter??? - userRequest.Success += response => updateUsers(response.Select(r => r.User)); - api.Queue(getUsersRequest = userRequest); - break; case SocialTab.OnlineFriends: var friendRequest = new GetFriendsRequest(); // TODO filter??? friendRequest.Success += updateUsers; api.Queue(getUsersRequest = friendRequest); break; + default: + var userRequest = new GetUsersRequest(); // TODO filter??? + userRequest.Success += response => updateUsers(response.Select(r => r.User)); + api.Queue(getUsersRequest = userRequest); + break; } loading.Show(); } From 9b70578af621783aabe280495047d12a11021d65 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Wed, 3 Jan 2018 19:01:10 +0100 Subject: [PATCH 047/206] enabled Location as filter tab forgot it QQ --- osu.Game/Overlays/Social/FilterControl.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index a4d623892d..bb60aaac51 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays.Social Relevance, Rank, Name, - //Location, + Location, //[Description("Time Zone")] //TimeZone, //[Description("World Map")] From 5f1d360a69cae565db6783ef6402a87eb255cccb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 15:21:33 +0900 Subject: [PATCH 048/206] Fix incorrect file header --- osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs index 0b7bc3b186..e7ad7135df 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using System.Collections.Generic; From 996a72b279f9355046b13ba836831f82633e78ca Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 15:25:12 +0900 Subject: [PATCH 049/206] Degrade yearin header --- osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs index e7ad7135df..92d96e3135 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . +// Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; From 5253ee5c0872dc52ddf6c579c6775b9960ee3447 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 15:34:57 +0900 Subject: [PATCH 050/206] Ignore ruleset test --- osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs index 92d96e3135..c4fea5ff75 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.MathUtils; @@ -15,6 +16,7 @@ using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Tests { + [Ignore("getting CI working")] public class TestCaseFruitObjects : OsuTestCase { public override IReadOnlyList RequiredTypes => new[] From 697efba5e2175aef9f275571c7ef9c6a25a08e40 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 15:55:35 +0900 Subject: [PATCH 051/206] Replace .OfType with .Cast --- osu.Game/Rulesets/UI/Playfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index b4a26344d5..5c32aeac73 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.UI public class HitObjectContainer : CompositeDrawable { - public virtual IEnumerable Objects => InternalChildren.OfType(); + public virtual IEnumerable Objects => InternalChildren.Cast(); public virtual void Add(DrawableHitObject hitObject) => AddInternal(hitObject); public virtual bool Remove(DrawableHitObject hitObject) => RemoveInternal(hitObject); } From d0c9d71ee79bdb0f5ef786de3eba25276aa7905a Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Thu, 4 Jan 2018 08:15:11 +0100 Subject: [PATCH 052/206] fix covers not showing in user panels --- osu.Game/Users/User.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/Users/User.cs b/osu.Game/Users/User.cs index 5c0e5f1f95..d4bdc05337 100644 --- a/osu.Game/Users/User.cs +++ b/osu.Game/Users/User.cs @@ -39,10 +39,14 @@ namespace osu.Game.Users public string AvatarUrl; [JsonProperty(@"cover_url")] - public string CoverUrl; + public string CoverUrl + { + get { return Cover?.Url; } + set { Cover = new UserCover { Url = value }; } + } - //[JsonProperty(@"cover")] - //public UserCover Cover; + [JsonProperty(@"cover")] + public UserCover Cover; public class UserCover { From 7beb4c3507b0dc13ace923c909b0325eabd2d4ca Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 16:21:15 +0900 Subject: [PATCH 053/206] Initial implementation of a new scrolling hitobject container --- .../Visual/TestCaseScrollingHitObjects.cs | 104 ++++++++++++++++++ osu.Game.Tests/osu.Game.Tests.csproj | 1 + 2 files changed, 105 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs new file mode 100644 index 0000000000..2827f70ebe --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -0,0 +1,104 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using OpenTK; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Shapes; +using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseScrollingHitObjects : OsuTestCase + { + public TestCaseScrollingHitObjects() + { + AddStep("Vertically-scrolling", () => createPlayfield(Direction.Vertical)); + AddStep("Horizontally-scrolling", () => createPlayfield(Direction.Horizontal)); + + AddStep("Add hitobject", addHitObject); + } + + private TestPlayfield playfield; + private void createPlayfield(Direction scrollingDirection) + { + if (playfield != null) + Remove(playfield); + Add(playfield = new TestPlayfield(scrollingDirection)); + } + + private void addHitObject() + { + playfield.Add(new TestDrawableHitObject(new HitObject { StartTime = Time.Current + 5000 }) + { + Anchor = playfield.ScrollingDirection == Direction.Horizontal ? Anchor.CentreRight : Anchor.BottomCentre + }); + } + + private class ScrollingHitObjectContainer : Playfield.HitObjectContainer + { + public double TimeRange = 5000; + + private readonly Direction scrollingDirection; + + public ScrollingHitObjectContainer(Direction scrollingDirection) + { + this.scrollingDirection = scrollingDirection; + + RelativeSizeAxes = Axes.Both; + } + + protected override void Update() + { + base.Update(); + + foreach (var obj in Objects) + { + var relativePosition = (Time.Current - obj.HitObject.StartTime) / TimeRange; + + // Todo: We may need to consider scale here + var finalPosition = (float)relativePosition * DrawSize; + + switch (scrollingDirection) + { + case Direction.Horizontal: + obj.X = finalPosition.X; + break; + case Direction.Vertical: + obj.Y = finalPosition.Y; + break; + } + } + } + } + + private class TestPlayfield : Playfield + { + public readonly Direction ScrollingDirection; + + public TestPlayfield(Direction scrollingDirection) + { + ScrollingDirection = scrollingDirection; + + HitObjects = new ScrollingHitObjectContainer(scrollingDirection); + } + } + + private class TestDrawableHitObject : DrawableHitObject + { + public TestDrawableHitObject(HitObject hitObject) + : base(hitObject) + { + Origin = Anchor.Centre; + AutoSizeAxes = Axes.Both; + + Add(new Box { Size = new Vector2(75) }); + } + + protected override void UpdateState(ArmedState state) + { + } + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 8c04874e75..f47a03990a 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -141,6 +141,7 @@ + From f45752c652de311ae32f5a23fcbae165e928126b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 3 Jan 2018 21:31:16 +0900 Subject: [PATCH 054/206] Fix catcher's catchable width being half of what it should --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 2bb0f3cd18..988ca1c36e 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -190,15 +190,15 @@ namespace osu.Game.Rulesets.Catch.UI /// Whether the catch is possible. public bool AttemptCatch(CatchHitObject fruit) { - const double relative_catcher_width = CATCHER_SIZE / 2; + double halfCatcherWidth = CATCHER_SIZE * Math.Abs(Scale.X) * 0.5f; // this stuff wil disappear once we move fruit to non-relative coordinate space in the future. var catchObjectPosition = fruit.X * CatchPlayfield.BASE_WIDTH; var catcherPosition = Position.X * CatchPlayfield.BASE_WIDTH; var validCatch = - catchObjectPosition >= catcherPosition - relative_catcher_width / 2 && - catchObjectPosition <= catcherPosition + relative_catcher_width / 2; + catchObjectPosition >= catcherPosition - halfCatcherWidth && + catchObjectPosition <= catcherPosition + halfCatcherWidth; if (validCatch && fruit.HyperDash) { From 152b846cff2089e59805ad24a8117b5582758ae0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 16:28:36 +0900 Subject: [PATCH 055/206] Fix incorrect scaling of hitobjects in catch --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 9 ++++++--- osu.Game/Rulesets/UI/Playfield.cs | 6 ++++++ 2 files changed, 12 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 76dbfa77c6..c1f535ba6b 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly CatcherArea catcherArea; public CatchPlayfield(BeatmapDifficulty difficulty) - : base(Axes.Y) + : base(Axes.Y, BASE_WIDTH) { Container explodingFruitContainer; @@ -32,7 +32,10 @@ namespace osu.Game.Rulesets.Catch.UI Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; - InternalChildren = new Drawable[] + ScaledContent.Anchor = Anchor.BottomLeft; + ScaledContent.Origin = Anchor.BottomLeft; + + ScaledContent.AddRange(new Drawable[] { content = new Container { @@ -48,7 +51,7 @@ namespace osu.Game.Rulesets.Catch.UI Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, } - }; + }); } public bool CheckIfWeCanCatch(CatchHitObject obj) => catcherArea.AttemptCatch(obj); diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index b4a26344d5..6752bf5c29 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -110,6 +110,12 @@ namespace osu.Game.Rulesets.UI //dividing by the customwidth will effectively scale our content to the required container size. protected override Vector2 DrawScale => CustomWidth.HasValue ? new Vector2(DrawSize.X / CustomWidth.Value) : base.DrawScale; + + protected override void Update() + { + base.Update(); + RelativeChildSize = new Vector2(DrawScale.X, base.RelativeChildSize.Y); + } } } } From c8ec27c4dea1a050d964decb2322c8e29ebee6d7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 16:31:41 +0900 Subject: [PATCH 056/206] Remove redundant prefix --- osu.Game/Rulesets/UI/Playfield.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 6752bf5c29..8a4cbcb49c 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -114,7 +114,7 @@ namespace osu.Game.Rulesets.UI protected override void Update() { base.Update(); - RelativeChildSize = new Vector2(DrawScale.X, base.RelativeChildSize.Y); + RelativeChildSize = new Vector2(DrawScale.X, RelativeChildSize.Y); } } } From 2b79ad879f7df53567eec7845b89aaeea46ce076 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 16:37:48 +0900 Subject: [PATCH 057/206] Add a way to access alive hitobjects --- osu.Game/Rulesets/UI/Playfield.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 5c32aeac73..61014b5550 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -97,6 +97,8 @@ namespace osu.Game.Rulesets.UI public class HitObjectContainer : CompositeDrawable { public virtual IEnumerable Objects => InternalChildren.Cast(); + public virtual IEnumerable AliveObjects => AliveInternalChildren.Cast(); + public virtual void Add(DrawableHitObject hitObject) => AddInternal(hitObject); public virtual bool Remove(DrawableHitObject hitObject) => RemoveInternal(hitObject); } From b968040963a5c33ced93f7d8cdd28e8a96de77e7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 16:38:07 +0900 Subject: [PATCH 058/206] General improvements to testcase --- .../Visual/TestCaseScrollingHitObjects.cs | 33 ++++++++++++------- 1 file changed, 22 insertions(+), 11 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index 2827f70ebe..7b462b5cac 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -1,6 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +using System; +using System.Collections.Generic; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; @@ -12,27 +14,36 @@ namespace osu.Game.Tests.Visual { public class TestCaseScrollingHitObjects : OsuTestCase { + public override IReadOnlyList RequiredTypes => new[] { typeof(Playfield) }; + + private List playfields = new List(); + public TestCaseScrollingHitObjects() { - AddStep("Vertically-scrolling", () => createPlayfield(Direction.Vertical)); - AddStep("Horizontally-scrolling", () => createPlayfield(Direction.Horizontal)); + playfields.Add(new TestPlayfield(Direction.Vertical)); + playfields.Add(new TestPlayfield(Direction.Horizontal)); - AddStep("Add hitobject", addHitObject); + AddRange(playfields); } - private TestPlayfield playfield; - private void createPlayfield(Direction scrollingDirection) + protected override void LoadComplete() { - if (playfield != null) - Remove(playfield); - Add(playfield = new TestPlayfield(scrollingDirection)); + base.LoadComplete(); + + for (int i = 0; i <= 5000; i += 1000) + addHitObject(Time.Current + i); + + Scheduler.AddDelayed(() => addHitObject(Time.Current + 5000), 1000, true); } - private void addHitObject() + private void addHitObject(double time) { - playfield.Add(new TestDrawableHitObject(new HitObject { StartTime = Time.Current + 5000 }) + playfields.ForEach(p => { - Anchor = playfield.ScrollingDirection == Direction.Horizontal ? Anchor.CentreRight : Anchor.BottomCentre + p.Add(new TestDrawableHitObject(new HitObject { StartTime = time }) + { + Anchor = p.ScrollingDirection == Direction.Horizontal ? Anchor.CentreRight : Anchor.BottomCentre + }); }); } From 210fd290e53d4b0b869c1482022b8ac02e209453 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 16:38:20 +0900 Subject: [PATCH 059/206] Use the new AliveObjects --- osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index 7b462b5cac..f5b0a964a3 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -64,7 +64,7 @@ namespace osu.Game.Tests.Visual { base.Update(); - foreach (var obj in Objects) + foreach (var obj in AliveObjects) { var relativePosition = (Time.Current - obj.HitObject.StartTime) / TimeRange; From c067ee5fbe4b12dbd5d03502a3891f8a0fce5500 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 16:38:43 +0900 Subject: [PATCH 060/206] Move position calculation to UpdateAfterChildren Because we want this to occur after lifetimes have been evaluated. --- osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index f5b0a964a3..03b95042b2 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -60,9 +60,9 @@ namespace osu.Game.Tests.Visual RelativeSizeAxes = Axes.Both; } - protected override void Update() + protected override void UpdateAfterChildren() { - base.Update(); + base.UpdateAfterChildren(); foreach (var obj in AliveObjects) { From 90839e6d56f3ad6528cfb67745614b00c68e507b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 17:07:16 +0900 Subject: [PATCH 061/206] Test case improvements with TimeRange testing --- .../Visual/TestCaseScrollingHitObjects.cs | 43 +++++++++++++++++-- 1 file changed, 39 insertions(+), 4 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index 03b95042b2..346ded046e 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -3,12 +3,15 @@ using System; using System.Collections.Generic; +using osu.Framework.Configuration; using OpenTK; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; +using OpenTK.Graphics; namespace osu.Game.Tests.Visual { @@ -16,14 +19,37 @@ namespace osu.Game.Tests.Visual { public override IReadOnlyList RequiredTypes => new[] { typeof(Playfield) }; - private List playfields = new List(); + private readonly List playfields = new List(); public TestCaseScrollingHitObjects() { playfields.Add(new TestPlayfield(Direction.Vertical)); playfields.Add(new TestPlayfield(Direction.Horizontal)); - AddRange(playfields); + Add(new Container + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Size = new Vector2(0.85f), + Masking = true, + BorderColour = Color4.White, + BorderThickness = 2, + MaskingSmoothness = 1, + Children = new Drawable[] + { + new Box + { + Name = "Background", + RelativeSizeAxes = Axes.Both, + Alpha = 0.35f, + }, + playfields[0], + playfields[1] + } + }); + + AddSliderStep("Time range", 100, 10000, 5000, v => playfields.ForEach(p => p.TimeRange.Value = v)); } protected override void LoadComplete() @@ -49,7 +75,11 @@ namespace osu.Game.Tests.Visual private class ScrollingHitObjectContainer : Playfield.HitObjectContainer { - public double TimeRange = 5000; + public readonly BindableDouble TimeRange = new BindableDouble + { + MinValue = 0, + MaxValue = double.MaxValue + }; private readonly Direction scrollingDirection; @@ -86,13 +116,18 @@ namespace osu.Game.Tests.Visual private class TestPlayfield : Playfield { + public readonly BindableDouble TimeRange = new BindableDouble(5000); + public readonly Direction ScrollingDirection; public TestPlayfield(Direction scrollingDirection) { ScrollingDirection = scrollingDirection; - HitObjects = new ScrollingHitObjectContainer(scrollingDirection); + var scrollingHitObjects = new ScrollingHitObjectContainer(scrollingDirection); + scrollingHitObjects.TimeRange.BindTo(TimeRange); + + HitObjects = scrollingHitObjects; } } From 722cad3674051f9bae650cb1249fff4b636a83ae Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 17:25:51 +0900 Subject: [PATCH 062/206] Caught fruit sit behind plate --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 988ca1c36e..37970cfcdb 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -84,12 +84,12 @@ namespace osu.Game.Rulesets.Catch.UI Children = new Drawable[] { - createCatcherSprite(), caughtFruit = new Container { Anchor = Anchor.TopCentre, Origin = Anchor.BottomCentre, - } + }, + createCatcherSprite(), }; } From 5125abf68199713e9253caed0d02b4ef2a59e1a4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 17:27:17 +0900 Subject: [PATCH 063/206] Better plate alignment and stacking logic --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 16 +++++++++++----- 1 file changed, 11 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 37970cfcdb..5f91b75919 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Catch.UI fruit.Position = new Vector2(MovableCatcher.ToLocalSpace(absolutePosition).X - MovableCatcher.DrawSize.X / 2, 0); fruit.Anchor = Anchor.TopCentre; - fruit.Origin = Anchor.BottomCentre; + fruit.Origin = Anchor.Centre; fruit.Scale *= 0.7f; fruit.LifetimeEnd = double.MaxValue; @@ -167,12 +167,18 @@ namespace osu.Game.Rulesets.Catch.UI /// The fruit that was caught. public void Add(DrawableHitObject fruit) { - float distance = fruit.DrawSize.X / 2 * fruit.Scale.X; + float ourRadius = fruit.DrawSize.X / 2 * fruit.Scale.X; + float theirRadius = 0; - while (caughtFruit.Any(f => f.LifetimeEnd == double.MaxValue && Vector2Extensions.DistanceSquared(f.Position, fruit.Position) < distance * distance)) + const float allowance = 6; + + while (caughtFruit.Any(f => + f.LifetimeEnd == double.MaxValue && + Vector2Extensions.Distance(f.Position, fruit.Position) < (ourRadius + (theirRadius = (f.DrawSize.X / 2 * f.Scale.X))) / (allowance / 2))) { - fruit.X += RNG.Next(-5, 5); - fruit.Y -= RNG.Next(0, 5); + float diff = (ourRadius + theirRadius) / allowance; + fruit.X += (RNG.NextSingle() - 0.5f) * 2 * diff; + fruit.Y -= RNG.NextSingle() * diff; } caughtFruit.Add(fruit); From 0bbc15d24a6ba299aa5f3785a1b508f5210b5f3c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 17:51:34 +0900 Subject: [PATCH 064/206] Clamp fruit to plate --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 5f91b75919..262ea67742 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -174,13 +174,15 @@ namespace osu.Game.Rulesets.Catch.UI while (caughtFruit.Any(f => f.LifetimeEnd == double.MaxValue && - Vector2Extensions.Distance(f.Position, fruit.Position) < (ourRadius + (theirRadius = (f.DrawSize.X / 2 * f.Scale.X))) / (allowance / 2))) + Vector2Extensions.Distance(f.Position, fruit.Position) < (ourRadius + (theirRadius = f.DrawSize.X / 2 * f.Scale.X)) / (allowance / 2))) { float diff = (ourRadius + theirRadius) / allowance; fruit.X += (RNG.NextSingle() - 0.5f) * 2 * diff; fruit.Y -= RNG.NextSingle() * diff; } + fruit.X = MathHelper.Clamp(fruit.X, -CATCHER_SIZE / 2, CATCHER_SIZE / 2); + caughtFruit.Add(fruit); var catchObject = (CatchHitObject)fruit.HitObject; From f28053b2fcaf1f6ce01c6d5ae42bf304732c0b87 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 18:13:59 +0900 Subject: [PATCH 065/206] Drop fruit when last in combo is not caught Also cleans up judgement handling a bit --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 15 +---- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 66 +++++++++++++++----- 2 files changed, 53 insertions(+), 28 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 76dbfa77c6..c4458dbe9b 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -3,7 +3,6 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.UI; -using OpenTK; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; @@ -63,18 +62,6 @@ namespace osu.Game.Rulesets.Catch.UI fruit.CheckPosition = CheckIfWeCanCatch; } - public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) - { - if (judgement.IsHit) - { - Vector2 screenPosition = judgedObject.ScreenSpaceDrawQuad.Centre; - - // todo: don't do this - (judgedObject.Parent as Container)?.Remove(judgedObject); - (judgedObject.Parent as Container)?.Remove(judgedObject); - - catcherArea.Add(judgedObject, screenPosition); - } - } + public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) => catcherArea.OnJudgement((DrawableCatchHitObject)judgedObject, judgement); } } diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 2bb0f3cd18..63405dce5e 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -12,6 +12,8 @@ using osu.Framework.Input.Bindings; using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using OpenTK; using OpenTK.Graphics; @@ -39,17 +41,30 @@ namespace osu.Game.Rulesets.Catch.UI }; } - public void Add(DrawableHitObject fruit, Vector2 absolutePosition) + public void OnJudgement(DrawableCatchHitObject fruit, Judgement judgement) { - fruit.RelativePositionAxes = Axes.None; - fruit.Position = new Vector2(MovableCatcher.ToLocalSpace(absolutePosition).X - MovableCatcher.DrawSize.X / 2, 0); + if (judgement.IsHit) + { + var screenSpacePosition = fruit.ScreenSpaceDrawQuad.Centre; - fruit.Anchor = Anchor.TopCentre; - fruit.Origin = Anchor.BottomCentre; - fruit.Scale *= 0.7f; - fruit.LifetimeEnd = double.MaxValue; + fruit.RelativePositionAxes = Axes.None; + fruit.Position = new Vector2(MovableCatcher.ToLocalSpace(screenSpacePosition).X - MovableCatcher.DrawSize.X / 2, 0); - MovableCatcher.Add(fruit); + fruit.Anchor = Anchor.TopCentre; + fruit.Origin = Anchor.Centre; + fruit.Scale *= 0.7f; + fruit.LifetimeEnd = double.MaxValue; + + MovableCatcher.Add(fruit); + } + + if (fruit.HitObject.LastInCombo) + { + if (judgement.IsHit) + MovableCatcher.Explode(); + else + MovableCatcher.Drop(); + } } public bool AttemptCatch(CatchHitObject obj) => MovableCatcher.AttemptCatch(obj); @@ -176,11 +191,6 @@ namespace osu.Game.Rulesets.Catch.UI } caughtFruit.Add(fruit); - - var catchObject = (CatchHitObject)fruit.HitObject; - - if (catchObject.LastInCombo) - explode(); } /// @@ -309,7 +319,35 @@ namespace osu.Game.Rulesets.Catch.UI X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * BASE_SPEED * dashModifier, 0, 1); } - private void explode() + /// + /// Drop any fruit off the plate. + /// + public void Drop() + { + var fruit = caughtFruit.ToArray(); + + foreach (var f in fruit) + { + if (ExplodingFruitTarget != null) + { + f.Anchor = Anchor.TopLeft; + f.Position = caughtFruit.ToSpaceOfOtherDrawable(f.DrawPosition, ExplodingFruitTarget); + + caughtFruit.Remove(f); + + ExplodingFruitTarget.Add(f); + } + + f.MoveToY(f.Y + 75, 750, Easing.InSine); + f.FadeOut(750); + f.Expire(); + } + } + + /// + /// Explode any fruit off the plate. + /// + public void Explode() { var fruit = caughtFruit.ToArray(); From 5bd489863c19249a395c228122d281b3bdcd3408 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 18:20:23 +0900 Subject: [PATCH 066/206] Rename enum --- osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs | 4 ++-- osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs | 4 ++-- osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs | 4 ++-- 3 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs index e5f8ad5402..f1df1c57f4 100644 --- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs @@ -50,9 +50,9 @@ namespace osu.Game.Rulesets.Catch.Objects public enum FruitVisualRepresentation { - Triforce, + Pear, Grape, - DPad, + Raspberry, Pineapple, Banana // banananananannaanana } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index 92d38f1f60..6a71a2f162 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { default: return new Container(); - case FruitVisualRepresentation.DPad: + case FruitVisualRepresentation.Raspberry: return new Container { RelativeSizeAxes = Axes.Both, @@ -176,7 +176,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable }, } }; - case FruitVisualRepresentation.Triforce: + case FruitVisualRepresentation.Pear: return new Container { RelativeSizeAxes = Axes.Both, diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs index c4fea5ff75..50cb1b150c 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs @@ -80,11 +80,11 @@ namespace osu.Game.Rulesets.Catch.Tests switch (representation) { default: - case FruitVisualRepresentation.Triforce: + case FruitVisualRepresentation.Pear: return new Color4(17, 136, 170, 255); case FruitVisualRepresentation.Grape: return new Color4(204, 102, 0, 255); - case FruitVisualRepresentation.DPad: + case FruitVisualRepresentation.Raspberry: return new Color4(121, 9, 13, 255); case FruitVisualRepresentation.Pineapple: return new Color4(102, 136, 0, 255); From 22fc9601eee461eed5304dd75c2c6f32395a0394 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 18:33:57 +0900 Subject: [PATCH 067/206] Add back missing code --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 63405dce5e..c266106f58 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -47,6 +47,11 @@ namespace osu.Game.Rulesets.Catch.UI { var screenSpacePosition = fruit.ScreenSpaceDrawQuad.Centre; + // remove the fruit from its current parent. + // todo: make this less ugly, somehow. + (fruit.Parent as Container)?.Remove(fruit); + (fruit.Parent as Container)?.Remove(fruit); + fruit.RelativePositionAxes = Axes.None; fruit.Position = new Vector2(MovableCatcher.ToLocalSpace(screenSpacePosition).X - MovableCatcher.DrawSize.X / 2, 0); From 0c5ab98965558a96b80d0efcda631ae0408407dc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 18:35:33 +0900 Subject: [PATCH 068/206] Make MultiplierControlPoint's StartTime variable --- osu.Game/Rulesets/Timing/MultiplierControlPoint.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs b/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs index 4f1a85cf2d..8b8bbae9d5 100644 --- a/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs +++ b/osu.Game/Rulesets/Timing/MultiplierControlPoint.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Timing /// /// The time in milliseconds at which this starts. /// - public readonly double StartTime; + public double StartTime; /// /// The multiplier which this provides. From b11f4ab8341c7cbcb3ae28b6cf88c88e98cec0b7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 18:35:48 +0900 Subject: [PATCH 069/206] Implement control points --- .../Visual/TestCaseScrollingHitObjects.cs | 94 +++++++++++++++++-- 1 file changed, 87 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index 346ded046e..d226203b3b 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -8,8 +8,10 @@ using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; +using osu.Framework.Lists; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Timing; using osu.Game.Rulesets.UI; using OpenTK.Graphics; @@ -26,6 +28,8 @@ namespace osu.Game.Tests.Visual playfields.Add(new TestPlayfield(Direction.Vertical)); playfields.Add(new TestPlayfield(Direction.Horizontal)); + playfields.ForEach(p => p.HitObjects.ControlPoints.Add(new MultiplierControlPoint(double.MinValue))); + Add(new Container { Anchor = Anchor.Centre, @@ -50,6 +54,7 @@ namespace osu.Game.Tests.Visual }); AddSliderStep("Time range", 100, 10000, 5000, v => playfields.ForEach(p => p.TimeRange.Value = v)); + AddStep("Add control point", () => addControlPoint(Time.Current + 5000)); } protected override void LoadComplete() @@ -66,13 +71,35 @@ namespace osu.Game.Tests.Visual { playfields.ForEach(p => { - p.Add(new TestDrawableHitObject(new HitObject { StartTime = time }) + p.Add(new TestDrawableHitObject(time) { Anchor = p.ScrollingDirection == Direction.Horizontal ? Anchor.CentreRight : Anchor.BottomCentre }); }); } + private void addControlPoint(double time) + { + playfields.ForEach(p => + { + p.HitObjects.ControlPoints.AddRange(new[] + { + new MultiplierControlPoint(time) { DifficultyPoint = { SpeedMultiplier = 3 } }, + new MultiplierControlPoint(time + 2000) { DifficultyPoint = { SpeedMultiplier = 2 } }, + new MultiplierControlPoint(time + 3000) { DifficultyPoint = { SpeedMultiplier = 1 } }, + }); + + TestDrawableControlPoint createDrawablePoint(double t) => new TestDrawableControlPoint(t) + { + Anchor = p.ScrollingDirection == Direction.Horizontal ? Anchor.CentreRight : Anchor.BottomCentre + }; + + p.Add(createDrawablePoint(time)); + p.Add(createDrawablePoint(time + 2000)); + p.Add(createDrawablePoint(time + 3000)); + }); + } + private class ScrollingHitObjectContainer : Playfield.HitObjectContainer { public readonly BindableDouble TimeRange = new BindableDouble @@ -81,6 +108,8 @@ namespace osu.Game.Tests.Visual MaxValue = double.MaxValue }; + public readonly SortedList ControlPoints = new SortedList(); + private readonly Direction scrollingDirection; public ScrollingHitObjectContainer(Direction scrollingDirection) @@ -94,9 +123,11 @@ namespace osu.Game.Tests.Visual { base.UpdateAfterChildren(); + var currentMultiplier = controlPointAt(Time.Current); + foreach (var obj in AliveObjects) { - var relativePosition = (Time.Current - obj.HitObject.StartTime) / TimeRange; + var relativePosition = (Time.Current - obj.HitObject.StartTime) / (TimeRange / currentMultiplier.Multiplier); // Todo: We may need to consider scale here var finalPosition = (float)relativePosition * DrawSize; @@ -112,6 +143,24 @@ namespace osu.Game.Tests.Visual } } } + + private readonly MultiplierControlPoint searchingPoint = new MultiplierControlPoint(); + private MultiplierControlPoint controlPointAt(double time) + { + if (ControlPoints.Count == 0) + return new MultiplierControlPoint(double.MinValue); + + if (time < ControlPoints[0].StartTime) + return ControlPoints[0]; + + searchingPoint.StartTime = time; + + int index = ControlPoints.BinarySearch(searchingPoint); + if (index < 0) + index = ~index - 1; + + return ControlPoints[index]; + } } private class TestPlayfield : Playfield @@ -120,21 +169,52 @@ namespace osu.Game.Tests.Visual public readonly Direction ScrollingDirection; + public new ScrollingHitObjectContainer HitObjects => (ScrollingHitObjectContainer)base.HitObjects; + public TestPlayfield(Direction scrollingDirection) { ScrollingDirection = scrollingDirection; - var scrollingHitObjects = new ScrollingHitObjectContainer(scrollingDirection); - scrollingHitObjects.TimeRange.BindTo(TimeRange); + base.HitObjects = new ScrollingHitObjectContainer(scrollingDirection); + HitObjects.TimeRange.BindTo(TimeRange); + } + } - HitObjects = scrollingHitObjects; + private class TestDrawableControlPoint : DrawableHitObject + { + private readonly Box box; + + public TestDrawableControlPoint(double time) + : base(new HitObject { StartTime = time }) + { + Origin = Anchor.Centre; + + Add(box = new Box + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + } + + protected override void Update() + { + base.Update(); + + RelativeSizeAxes = (Anchor & Anchor.x2) > 0 ? Axes.Y : Axes.X; + Size = new Vector2(1); + + box.Size = DrawSize; + } + + protected override void UpdateState(ArmedState state) + { } } private class TestDrawableHitObject : DrawableHitObject { - public TestDrawableHitObject(HitObject hitObject) - : base(hitObject) + public TestDrawableHitObject(double time) + : base(new HitObject { StartTime = time }) { Origin = Anchor.Centre; AutoSizeAxes = Axes.Both; From f34131f8f444a99e4088776a5fd107b3fd6d4f51 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 18:50:17 +0900 Subject: [PATCH 070/206] Initial game-wide replacement of scrolling playfields --- .../Drawable/DrawableCatchHitObject.cs | 5 +- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 4 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 1 - .../Mods/IGenerateSpeedAdjustments.cs | 23 -- .../Mods/ManiaModGravity.cs | 48 ---- .../Drawables/DrawableManiaHitObject.cs | 4 +- .../Tests/TestCaseManiaPlayfield.cs | 33 +-- .../Timing/GravityScrollingContainer.cs | 60 ----- .../Timing/ManiaSpeedAdjustmentContainer.cs | 29 --- .../Timing/ScrollingAlgorithm.cs | 17 -- osu.Game.Rulesets.Mania/UI/Column.cs | 2 +- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 2 +- .../UI/ManiaRulesetContainer.cs | 4 - .../osu.Game.Rulesets.Mania.csproj | 5 - .../Objects/Drawables/DrawableBarLine.cs | 2 +- .../Drawables/DrawableTaikoHitObject.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 +- .../Visual/TestCaseScrollingHitObjects.cs | 66 +----- .../Visual/TestCaseScrollingPlayfield.cs | 219 ------------------ osu.Game.Tests/osu.Game.Tests.csproj | 1 - .../Drawables/DrawableScrollingHitObject.cs | 67 ------ .../Timing/LinearScrollingContainer.cs | 28 --- .../Rulesets/Timing/ScrollingContainer.cs | 93 -------- .../Timing/SpeedAdjustmentContainer.cs | 114 --------- osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 165 ++++--------- .../Rulesets/UI/ScrollingRulesetContainer.cs | 9 +- osu.Game/osu.Game.csproj | 4 - 27 files changed, 61 insertions(+), 948 deletions(-) delete mode 100644 osu.Game.Rulesets.Mania/Mods/IGenerateSpeedAdjustments.cs delete mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs delete mode 100644 osu.Game.Rulesets.Mania/Timing/GravityScrollingContainer.cs delete mode 100644 osu.Game.Rulesets.Mania/Timing/ManiaSpeedAdjustmentContainer.cs delete mode 100644 osu.Game.Rulesets.Mania/Timing/ScrollingAlgorithm.cs delete mode 100644 osu.Game.Tests/Visual/TestCaseScrollingPlayfield.cs delete mode 100644 osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs delete mode 100644 osu.Game/Rulesets/Timing/LinearScrollingContainer.cs delete mode 100644 osu.Game/Rulesets/Timing/ScrollingContainer.cs delete mode 100644 osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index a617b65676..8954f9fe9e 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -24,14 +24,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable } } - public abstract class DrawableCatchHitObject : DrawableScrollingHitObject + public abstract class DrawableCatchHitObject : DrawableHitObject { protected DrawableCatchHitObject(CatchHitObject hitObject) : base(hitObject) { - RelativePositionAxes = Axes.Both; + RelativePositionAxes = Axes.X; X = hitObject.X; - Y = (float)HitObject.StartTime; } public Func CheckPosition; diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 76dbfa77c6..322d1d91af 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -23,12 +23,10 @@ namespace osu.Game.Rulesets.Catch.UI private readonly CatcherArea catcherArea; public CatchPlayfield(BeatmapDifficulty difficulty) - : base(Axes.Y) + : base(Direction.Vertical) { Container explodingFruitContainer; - Reversed.Value = true; - Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 070c7b09d1..4765f25808 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -95,7 +95,6 @@ namespace osu.Game.Rulesets.Mania new ModCinema(), }, }, - new ManiaModGravity() }; default: diff --git a/osu.Game.Rulesets.Mania/Mods/IGenerateSpeedAdjustments.cs b/osu.Game.Rulesets.Mania/Mods/IGenerateSpeedAdjustments.cs deleted file mode 100644 index 954ee3f481..0000000000 --- a/osu.Game.Rulesets.Mania/Mods/IGenerateSpeedAdjustments.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System.Collections.Generic; -using osu.Game.Rulesets.Mania.UI; -using osu.Game.Rulesets.Timing; - -namespace osu.Game.Rulesets.Mania.Mods -{ - /// - /// A type of mod which generates speed adjustments that scroll the hit objects and bar lines. - /// - internal interface IGenerateSpeedAdjustments - { - /// - /// Applies this mod to a hit renderer. - /// - /// The hit renderer to apply to. - /// The per-column list of speed adjustments for hit objects. - /// The list of speed adjustments for bar lines. - void ApplyToRulesetContainer(ManiaRulesetContainer rulesetContainer, ref List[] hitObjectTimingChanges, ref List barlineTimingChanges); - } -} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs deleted file mode 100644 index 70270af6c9..0000000000 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs +++ /dev/null @@ -1,48 +0,0 @@ -// Copyright (c) 2007-2017 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.Game.Rulesets.Mania.Objects; -using osu.Game.Rulesets.Mania.UI; -using osu.Game.Rulesets.Mods; -using osu.Game.Graphics; -using osu.Game.Rulesets.Mania.Timing; -using osu.Game.Rulesets.Timing; -using osu.Game.Rulesets.Mania.Objects.Drawables; - -namespace osu.Game.Rulesets.Mania.Mods -{ - public class ManiaModGravity : Mod, IGenerateSpeedAdjustments - { - public override string Name => "Gravity"; - public override string ShortenedName => "GR"; - - public override double ScoreMultiplier => 0; - - public override FontAwesome Icon => FontAwesome.fa_sort_desc; - - public void ApplyToRulesetContainer(ManiaRulesetContainer rulesetContainer, ref List[] hitObjectTimingChanges, ref List barlineTimingChanges) - { - // We have to generate one speed adjustment per hit object for gravity - foreach (ManiaHitObject obj in rulesetContainer.Objects.OfType()) - { - MultiplierControlPoint controlPoint = rulesetContainer.CreateControlPointAt(obj.StartTime); - // Beat length has too large of an effect for gravity, so we'll force it to a constant value for now - controlPoint.TimingPoint.BeatLength = 1000; - - hitObjectTimingChanges[obj.Column].Add(new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Gravity)); - } - - // Like with hit objects, we need to generate one speed adjustment per bar line - foreach (DrawableBarLine barLine in rulesetContainer.BarLines) - { - var controlPoint = rulesetContainer.CreateControlPointAt(barLine.HitObject.StartTime); - // Beat length has too large of an effect for gravity, so we'll force it to a constant value for now - controlPoint.TimingPoint.BeatLength = 1000; - - barlineTimingChanges.Add(new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Gravity)); - } - } - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 6354c6ff77..385f18a4f9 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -1,13 +1,12 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Graphics; using OpenTK.Graphics; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Mania.Objects.Drawables { - public abstract class DrawableManiaHitObject : DrawableScrollingHitObject + public abstract class DrawableManiaHitObject : DrawableHitObject where TObject : ManiaHitObject { /// @@ -20,7 +19,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null) : base(hitObject) { - RelativePositionAxes = Axes.Y; HitObject = hitObject; if (action != null) diff --git a/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs index b5890b289f..6615b39274 100644 --- a/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/Tests/TestCaseManiaPlayfield.cs @@ -5,16 +5,13 @@ using System; using System.Linq; using NUnit.Framework; using osu.Framework.Allocation; -using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; using osu.Framework.Timing; using osu.Game.Rulesets.Mania.Judgements; using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; -using osu.Game.Rulesets.Mania.Timing; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Timing; using osu.Game.Tests.Visual; namespace osu.Game.Rulesets.Mania.Tests @@ -44,10 +41,10 @@ namespace osu.Game.Rulesets.Mania.Tests AddStep("Right special style", () => createPlayfield(8, SpecialColumnPosition.Right)); AddStep("Reversed", () => createPlayfield(4, SpecialColumnPosition.Normal, true)); - AddStep("Notes with input", () => createPlayfieldWithNotes(false)); - AddStep("Notes with input (reversed)", () => createPlayfieldWithNotes(false, true)); - AddStep("Notes with gravity", () => createPlayfieldWithNotes(true)); - AddStep("Notes with gravity (reversed)", () => createPlayfieldWithNotes(true, true)); + AddStep("Notes with input", () => createPlayfieldWithNotes()); + AddStep("Notes with input (reversed)", () => createPlayfieldWithNotes(true)); + AddStep("Notes with gravity", () => createPlayfieldWithNotes()); + AddStep("Notes with gravity (reversed)", () => createPlayfieldWithNotes(true)); AddStep("Hit explosion", () => { @@ -70,11 +67,6 @@ namespace osu.Game.Rulesets.Mania.Tests maniaRuleset = rulesets.GetRuleset(3); } - private SpeedAdjustmentContainer createTimingChange(double time, bool gravity) => new ManiaSpeedAdjustmentContainer(new MultiplierControlPoint(time) - { - TimingPoint = { BeatLength = 1000 } - }, gravity ? ScrollingAlgorithm.Gravity : ScrollingAlgorithm.Basic); - private ManiaPlayfield createPlayfield(int cols, SpecialColumnPosition specialPos, bool inverted = false) { Clear(); @@ -95,7 +87,7 @@ namespace osu.Game.Rulesets.Mania.Tests return playfield; } - private void createPlayfieldWithNotes(bool gravity, bool inverted = false) + private void createPlayfieldWithNotes(bool inverted = false) { Clear(); @@ -114,23 +106,14 @@ namespace osu.Game.Rulesets.Mania.Tests playfield.Inverted.Value = inverted; - if (!gravity) - playfield.Columns.ForEach(c => c.Add(createTimingChange(0, false))); - for (double t = start_time; t <= start_time + duration; t += 100) { - if (gravity) - playfield.Columns.ElementAt(0).Add(createTimingChange(t, true)); - playfield.Add(new DrawableNote(new Note { StartTime = t, Column = 0 }, ManiaAction.Key1)); - if (gravity) - playfield.Columns.ElementAt(3).Add(createTimingChange(t, true)); - playfield.Add(new DrawableNote(new Note { StartTime = t, @@ -138,9 +121,6 @@ namespace osu.Game.Rulesets.Mania.Tests }, ManiaAction.Key4)); } - if (gravity) - playfield.Columns.ElementAt(1).Add(createTimingChange(start_time, true)); - playfield.Add(new DrawableHoldNote(new HoldNote { StartTime = start_time, @@ -148,9 +128,6 @@ namespace osu.Game.Rulesets.Mania.Tests Column = 1 }, ManiaAction.Key2)); - if (gravity) - playfield.Columns.ElementAt(2).Add(createTimingChange(start_time, true)); - playfield.Add(new DrawableHoldNote(new HoldNote { StartTime = start_time, diff --git a/osu.Game.Rulesets.Mania/Timing/GravityScrollingContainer.cs b/osu.Game.Rulesets.Mania/Timing/GravityScrollingContainer.cs deleted file mode 100644 index 699acc477b..0000000000 --- a/osu.Game.Rulesets.Mania/Timing/GravityScrollingContainer.cs +++ /dev/null @@ -1,60 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Rulesets.Timing; - -namespace osu.Game.Rulesets.Mania.Timing -{ - /// - /// A that emulates a form of gravity where hit objects speed up over time. - /// - internal class GravityScrollingContainer : ScrollingContainer - { - private readonly MultiplierControlPoint controlPoint; - - public GravityScrollingContainer(MultiplierControlPoint controlPoint) - { - this.controlPoint = controlPoint; - } - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - - // The gravity-adjusted start position - float startPos = (float)computeGravityTime(controlPoint.StartTime); - // The gravity-adjusted end position - float endPos = (float)computeGravityTime(controlPoint.StartTime + RelativeChildSize.Y); - - Y = startPos; - Height = endPos - startPos; - } - - /// - /// Applies gravity to a time value based on the current time. - /// - /// The time value gravity should be applied to. - /// The time after gravity is applied to . - private double computeGravityTime(double time) - { - double relativeTime = relativeTimeAt(time); - - // The sign of the relative time, this is used to apply backwards acceleration leading into startTime - double sign = relativeTime < 0 ? -1 : 1; - - return VisibleTimeRange - acceleration * relativeTime * relativeTime * sign; - } - - /// - /// The acceleration due to "gravity" of the content of this container. - /// - private double acceleration => 1 / VisibleTimeRange; - - /// - /// Computes the current time relative to , accounting for . - /// - /// The non-offset time. - /// The current time relative to - . - private double relativeTimeAt(double time) => Time.Current - time + VisibleTimeRange; - } -} diff --git a/osu.Game.Rulesets.Mania/Timing/ManiaSpeedAdjustmentContainer.cs b/osu.Game.Rulesets.Mania/Timing/ManiaSpeedAdjustmentContainer.cs deleted file mode 100644 index 321b4ee92b..0000000000 --- a/osu.Game.Rulesets.Mania/Timing/ManiaSpeedAdjustmentContainer.cs +++ /dev/null @@ -1,29 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Rulesets.Timing; - -namespace osu.Game.Rulesets.Mania.Timing -{ - public class ManiaSpeedAdjustmentContainer : SpeedAdjustmentContainer - { - private readonly ScrollingAlgorithm scrollingAlgorithm; - - public ManiaSpeedAdjustmentContainer(MultiplierControlPoint timingSection, ScrollingAlgorithm scrollingAlgorithm) - : base(timingSection) - { - this.scrollingAlgorithm = scrollingAlgorithm; - } - - protected override ScrollingContainer CreateScrollingContainer() - { - switch (scrollingAlgorithm) - { - default: - return base.CreateScrollingContainer(); - case ScrollingAlgorithm.Gravity: - return new GravityScrollingContainer(ControlPoint); - } - } - } -} \ No newline at end of file diff --git a/osu.Game.Rulesets.Mania/Timing/ScrollingAlgorithm.cs b/osu.Game.Rulesets.Mania/Timing/ScrollingAlgorithm.cs deleted file mode 100644 index 72e096f5aa..0000000000 --- a/osu.Game.Rulesets.Mania/Timing/ScrollingAlgorithm.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -namespace osu.Game.Rulesets.Mania.Timing -{ - public enum ScrollingAlgorithm - { - /// - /// Basic scrolling algorithm based on the timing section time. This is the default algorithm. - /// - Basic, - /// - /// Emulating a form of gravity where hit objects speed up over time. - /// - Gravity - } -} diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 2d553f8639..048b3ef9f9 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Mania.UI private const float opacity_pressed = 0.25f; public Column() - : base(Axes.Y) + : base(Direction.Vertical) { Width = column_width; diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 6c164a34f0..549b0f2ee6 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Mania.UI private readonly int columnCount; public ManiaPlayfield(int columnCount) - : base(Axes.Y) + : base(Direction.Vertical) { this.columnCount = columnCount; diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index 61446a31b6..db9475b31e 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -17,12 +17,10 @@ using osu.Game.Rulesets.Mania.Objects; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Game.Rulesets.Mania.Replays; using osu.Game.Rulesets.Mania.Scoring; -using osu.Game.Rulesets.Mania.Timing; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Timing; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mania.UI @@ -121,8 +119,6 @@ namespace osu.Game.Rulesets.Mania.UI protected override Vector2 GetPlayfieldAspectAdjust() => new Vector2(1, 0.8f); - protected override SpeedAdjustmentContainer CreateSpeedAdjustmentContainer(MultiplierControlPoint controlPoint) => new ManiaSpeedAdjustmentContainer(controlPoint, ScrollingAlgorithm.Basic); - protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay, this); } } diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index 3393774a9c..4445f24cd8 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -62,7 +62,6 @@ - @@ -88,8 +87,6 @@ - - @@ -97,9 +94,7 @@ - - diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs index b30b3a1aca..97fa91a94b 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables /// /// A line that scrolls alongside hit objects in the playfield and visualises control points. /// - public class DrawableBarLine : DrawableScrollingHitObject + public class DrawableBarLine : DrawableHitObject { /// /// The width of the line tracker. diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs index cc7dd2fa0f..5cda186086 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableTaikoHitObject.cs @@ -12,7 +12,7 @@ using System.Collections.Generic; namespace osu.Game.Rulesets.Taiko.Objects.Drawables { - public abstract class DrawableTaikoHitObject : DrawableScrollingHitObject, IKeyBindingHandler + public abstract class DrawableTaikoHitObject : DrawableHitObject, IKeyBindingHandler where TaikoHitType : TaikoHitObject { public override Vector2 OriginPosition => new Vector2(DrawHeight / 2); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 3fdbd056ce..5e1fa7e490 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Box background; public TaikoPlayfield(ControlPointInfo controlPoints) - : base(Axes.X) + : base(Direction.Horizontal) { AddRangeInternal(new Drawable[] { diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index d226203b3b..01387791a1 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -8,7 +8,6 @@ using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; -using osu.Framework.Lists; using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; @@ -100,68 +99,7 @@ namespace osu.Game.Tests.Visual }); } - private class ScrollingHitObjectContainer : Playfield.HitObjectContainer - { - public readonly BindableDouble TimeRange = new BindableDouble - { - MinValue = 0, - MaxValue = double.MaxValue - }; - public readonly SortedList ControlPoints = new SortedList(); - - private readonly Direction scrollingDirection; - - public ScrollingHitObjectContainer(Direction scrollingDirection) - { - this.scrollingDirection = scrollingDirection; - - RelativeSizeAxes = Axes.Both; - } - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - - var currentMultiplier = controlPointAt(Time.Current); - - foreach (var obj in AliveObjects) - { - var relativePosition = (Time.Current - obj.HitObject.StartTime) / (TimeRange / currentMultiplier.Multiplier); - - // Todo: We may need to consider scale here - var finalPosition = (float)relativePosition * DrawSize; - - switch (scrollingDirection) - { - case Direction.Horizontal: - obj.X = finalPosition.X; - break; - case Direction.Vertical: - obj.Y = finalPosition.Y; - break; - } - } - } - - private readonly MultiplierControlPoint searchingPoint = new MultiplierControlPoint(); - private MultiplierControlPoint controlPointAt(double time) - { - if (ControlPoints.Count == 0) - return new MultiplierControlPoint(double.MinValue); - - if (time < ControlPoints[0].StartTime) - return ControlPoints[0]; - - searchingPoint.StartTime = time; - - int index = ControlPoints.BinarySearch(searchingPoint); - if (index < 0) - index = ~index - 1; - - return ControlPoints[index]; - } - } private class TestPlayfield : Playfield { @@ -169,13 +107,13 @@ namespace osu.Game.Tests.Visual public readonly Direction ScrollingDirection; - public new ScrollingHitObjectContainer HitObjects => (ScrollingHitObjectContainer)base.HitObjects; + public new ScrollingPlayfield.ScrollingHitObjectContainer HitObjects => (ScrollingPlayfield.ScrollingHitObjectContainer)base.HitObjects; public TestPlayfield(Direction scrollingDirection) { ScrollingDirection = scrollingDirection; - base.HitObjects = new ScrollingHitObjectContainer(scrollingDirection); + base.HitObjects = new ScrollingPlayfield.ScrollingHitObjectContainer(scrollingDirection); HitObjects.TimeRange.BindTo(TimeRange); } } diff --git a/osu.Game.Tests/Visual/TestCaseScrollingPlayfield.cs b/osu.Game.Tests/Visual/TestCaseScrollingPlayfield.cs deleted file mode 100644 index 40fb22af1e..0000000000 --- a/osu.Game.Tests/Visual/TestCaseScrollingPlayfield.cs +++ /dev/null @@ -1,219 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Collections.Generic; -using NUnit.Framework; -using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; -using osu.Framework.Input; -using osu.Framework.Timing; -using osu.Game.Beatmaps; -using osu.Game.Beatmaps.ControlPoints; -using osu.Game.Rulesets.Judgements; -using osu.Game.Rulesets.Objects; -using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Timing; -using osu.Game.Rulesets.UI; -using osu.Game.Tests.Beatmaps; -using OpenTK; - -namespace osu.Game.Tests.Visual -{ - /// - /// The most minimal implementation of a playfield with scrolling hit objects. - /// - [TestFixture] - public class TestCaseScrollingPlayfield : OsuTestCase - { - public TestCaseScrollingPlayfield() - { - Clock = new FramedClock(); - - var objects = new List(); - - int time = 1500; - for (int i = 0; i < 50; i++) - { - objects.Add(new TestHitObject { StartTime = time }); - - time += 500; - } - - Beatmap b = new Beatmap - { - HitObjects = objects, - BeatmapInfo = new BeatmapInfo - { - BaseDifficulty = new BeatmapDifficulty(), - Metadata = new BeatmapMetadata() - } - }; - - WorkingBeatmap beatmap = new TestWorkingBeatmap(b); - - TestRulesetContainer horizontalRulesetContainer; - Add(horizontalRulesetContainer = new TestRulesetContainer(Axes.X, beatmap, true)); - - TestRulesetContainer verticalRulesetContainer; - Add(verticalRulesetContainer = new TestRulesetContainer(Axes.Y, beatmap, true)); - - AddStep("Reverse direction", () => - { - horizontalRulesetContainer.Playfield.Reverse(); - verticalRulesetContainer.Playfield.Reverse(); - }); - } - - [Test] - public void TestSpeedAdjustmentOrdering() - { - var hitObjectContainer = new ScrollingPlayfield.ScrollingHitObjectContainer(Axes.X); - - var speedAdjustments = new[] - { - new SpeedAdjustmentContainer(new MultiplierControlPoint()), - new SpeedAdjustmentContainer(new MultiplierControlPoint(1000) - { - TimingPoint = new TimingControlPoint { BeatLength = 500 } - }), - new SpeedAdjustmentContainer(new MultiplierControlPoint(2000) - { - TimingPoint = new TimingControlPoint { BeatLength = 1000 }, - DifficultyPoint = new DifficultyControlPoint { SpeedMultiplier = 2} - }), - new SpeedAdjustmentContainer(new MultiplierControlPoint(3000) - { - TimingPoint = new TimingControlPoint { BeatLength = 1000 }, - DifficultyPoint = new DifficultyControlPoint { SpeedMultiplier = 1} - }), - }; - - var hitObjects = new[] - { - new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = -1000 }), - new DrawableTestHitObject(Axes.X, new TestHitObject()), - new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 1000 }), - new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 2000 }), - new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 3000 }), - new DrawableTestHitObject(Axes.X, new TestHitObject { StartTime = 4000 }), - }; - - hitObjects.ForEach(h => hitObjectContainer.Add(h)); - speedAdjustments.ForEach(hitObjectContainer.AddSpeedAdjustment); - - // The 0th index in hitObjectContainer.SpeedAdjustments is the "default" control point - // Check multiplier of the default speed adjustment - Assert.AreEqual(1, hitObjectContainer.SpeedAdjustments[0].ControlPoint.Multiplier); - Assert.AreEqual(1, speedAdjustments[0].ControlPoint.Multiplier); - Assert.AreEqual(2, speedAdjustments[1].ControlPoint.Multiplier); - Assert.AreEqual(2, speedAdjustments[2].ControlPoint.Multiplier); - Assert.AreEqual(1, speedAdjustments[3].ControlPoint.Multiplier); - - // Check insertion of hit objects - Assert.IsTrue(hitObjectContainer.SpeedAdjustments[4].Contains(hitObjects[0])); - Assert.IsTrue(hitObjectContainer.SpeedAdjustments[3].Contains(hitObjects[1])); - Assert.IsTrue(hitObjectContainer.SpeedAdjustments[2].Contains(hitObjects[2])); - Assert.IsTrue(hitObjectContainer.SpeedAdjustments[1].Contains(hitObjects[3])); - Assert.IsTrue(hitObjectContainer.SpeedAdjustments[0].Contains(hitObjects[4])); - Assert.IsTrue(hitObjectContainer.SpeedAdjustments[0].Contains(hitObjects[5])); - - hitObjectContainer.RemoveSpeedAdjustment(hitObjectContainer.SpeedAdjustments[3]); - - // The hit object contained in this speed adjustment should be resorted into the one occuring before it - - Assert.IsTrue(hitObjectContainer.SpeedAdjustments[3].Contains(hitObjects[1])); - } - - private class TestRulesetContainer : ScrollingRulesetContainer - { - private readonly Axes scrollingAxes; - - public TestRulesetContainer(Axes scrollingAxes, WorkingBeatmap beatmap, bool isForCurrentRuleset) - : base(null, beatmap, isForCurrentRuleset) - { - this.scrollingAxes = scrollingAxes; - } - - public new TestPlayfield Playfield => base.Playfield; - - public override ScoreProcessor CreateScoreProcessor() => new TestScoreProcessor(); - - public override PassThroughInputManager CreateInputManager() => new PassThroughInputManager(); - - protected override BeatmapConverter CreateBeatmapConverter() => new TestBeatmapConverter(); - - protected override Playfield CreatePlayfield() => new TestPlayfield(scrollingAxes); - - protected override DrawableHitObject GetVisualRepresentation(TestHitObject h) => new DrawableTestHitObject(scrollingAxes, h); - } - - private class TestScoreProcessor : ScoreProcessor - { - protected override void OnNewJudgement(Judgement judgement) - { - } - } - - private class TestBeatmapConverter : BeatmapConverter - { - protected override IEnumerable ValidConversionTypes => new[] { typeof(HitObject) }; - - protected override IEnumerable ConvertHitObject(HitObject original, Beatmap beatmap) - { - yield return original as TestHitObject; - } - } - - private class DrawableTestHitObject : DrawableScrollingHitObject - { - public DrawableTestHitObject(Axes scrollingAxes, TestHitObject hitObject) - : base(hitObject) - { - Anchor = scrollingAxes == Axes.Y ? Anchor.TopCentre : Anchor.CentreLeft; - Origin = Anchor.Centre; - - AutoSizeAxes = Axes.Both; - - Add(new Circle - { - Size = new Vector2(50) - }); - } - - protected override void UpdateState(ArmedState state) - { - } - } - - private class TestPlayfield : ScrollingPlayfield - { - protected override Container Content => content; - private readonly Container content; - - public TestPlayfield(Axes scrollingAxes) - : base(scrollingAxes) - { - InternalChildren = new Drawable[] - { - new Box - { - RelativeSizeAxes = Axes.Both, - Alpha = 0.2f - }, - content = new Container { RelativeSizeAxes = Axes.Both } - }; - } - - public void Reverse() => Reversed.Toggle(); - } - - - private class TestHitObject : HitObject - { - } - } -} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index f47a03990a..2eb79f6b35 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -142,7 +142,6 @@ - diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs deleted file mode 100644 index 538bb826ad..0000000000 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableScrollingHitObject.cs +++ /dev/null @@ -1,67 +0,0 @@ -// Copyright (c) 2007-2017 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.Rulesets.Objects.Types; - -namespace osu.Game.Rulesets.Objects.Drawables -{ - /// - /// A basic class that overrides and implements . - /// This object does not need to have its set to be able to scroll, as this will - /// will be set by the scrolling container that contains it. - /// - public abstract class DrawableScrollingHitObject : DrawableHitObject, IScrollingHitObject - where TObject : HitObject - { - public BindableDouble LifetimeOffset { get; } = new BindableDouble(); - - Axes IScrollingHitObject.ScrollingAxes - { - set - { - RelativePositionAxes |= value; - - if ((value & Axes.X) > 0) - X = (float)HitObject.StartTime; - if ((value & Axes.Y) > 0) - Y = (float)HitObject.StartTime; - } - } - - public override bool RemoveWhenNotAlive => false; - protected override bool RequiresChildrenUpdate => true; - - protected DrawableScrollingHitObject(TObject hitObject) - : base(hitObject) - { - } - - private double? lifetimeStart; - public override double LifetimeStart - { - get { return lifetimeStart ?? HitObject.StartTime - LifetimeOffset; } - set { lifetimeStart = value; } - } - - private double? lifetimeEnd; - public override double LifetimeEnd - { - get - { - var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; - return lifetimeEnd ?? endTime + LifetimeOffset; - } - set { lifetimeEnd = value; } - } - - protected override void AddNested(DrawableHitObject h) - { - var scrollingHitObject = h as IScrollingHitObject; - scrollingHitObject?.LifetimeOffset.BindTo(LifetimeOffset); - - base.AddNested(h); - } - } -} \ No newline at end of file diff --git a/osu.Game/Rulesets/Timing/LinearScrollingContainer.cs b/osu.Game/Rulesets/Timing/LinearScrollingContainer.cs deleted file mode 100644 index b093cf3303..0000000000 --- a/osu.Game/Rulesets/Timing/LinearScrollingContainer.cs +++ /dev/null @@ -1,28 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Framework.Graphics; - -namespace osu.Game.Rulesets.Timing -{ - /// - /// A which scrolls linearly relative to the start time. - /// - public class LinearScrollingContainer : ScrollingContainer - { - private readonly MultiplierControlPoint controlPoint; - - public LinearScrollingContainer(MultiplierControlPoint controlPoint) - { - this.controlPoint = controlPoint; - } - - protected override void Update() - { - base.Update(); - - if ((ScrollingAxes & Axes.X) > 0) X = (float)(controlPoint.StartTime - Time.Current); - if ((ScrollingAxes & Axes.Y) > 0) Y = (float)(controlPoint.StartTime - Time.Current); - } - } -} diff --git a/osu.Game/Rulesets/Timing/ScrollingContainer.cs b/osu.Game/Rulesets/Timing/ScrollingContainer.cs deleted file mode 100644 index eac596297a..0000000000 --- a/osu.Game/Rulesets/Timing/ScrollingContainer.cs +++ /dev/null @@ -1,93 +0,0 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Linq; -using osu.Framework.Caching; -using osu.Framework.Configuration; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Game.Rulesets.Objects.Drawables; -using OpenTK; -using osu.Game.Rulesets.Objects.Types; - -namespace osu.Game.Rulesets.Timing -{ - /// - /// A container that scrolls relative to the current time. Will autosize to the total duration of all contained hit objects along the scrolling axes. - /// - public abstract class ScrollingContainer : Container - { - /// - /// Gets or sets the range of time that is visible by the length of the scrolling axes. - /// - public readonly BindableDouble VisibleTimeRange = new BindableDouble { Default = 1000 }; - - /// - /// The axes through which this scrolls. This is set by the . - /// - internal Axes ScrollingAxes; - - public override bool RemoveWhenNotAlive => false; - protected override bool RequiresChildrenUpdate => true; - - /// - /// The control point that defines the speed adjustments for this container. This is set by the . - /// - internal MultiplierControlPoint ControlPoint; - - private Cached durationBacking; - - /// - /// Creates a new . - /// - protected ScrollingContainer() - { - RelativeSizeAxes = Axes.Both; - RelativePositionAxes = Axes.Both; - } - - protected override int Compare(Drawable x, Drawable y) - { - var hX = (DrawableHitObject)x; - var hY = (DrawableHitObject)y; - - int result = hY.HitObject.StartTime.CompareTo(hX.HitObject.StartTime); - if (result != 0) - return result; - return base.Compare(y, x); - } - - public override void Add(DrawableHitObject drawable) - { - durationBacking.Invalidate(); - base.Add(drawable); - } - - public override bool Remove(DrawableHitObject drawable) - { - durationBacking.Invalidate(); - return base.Remove(drawable); - } - - // Todo: This may underestimate the size of the hit object in some cases, but won't be too much of a problem for now - private double computeDuration() => Math.Max(0, Children.Select(c => (c.HitObject as IHasEndTime)?.EndTime ?? c.HitObject.StartTime).DefaultIfEmpty().Max() - ControlPoint.StartTime) + 1000; - - /// - /// An approximate total duration of this scrolling container. - /// - public double Duration => durationBacking.IsValid ? durationBacking : (durationBacking.Value = computeDuration()); - - protected override void Update() - { - base.Update(); - - RelativeChildOffset = new Vector2((ScrollingAxes & Axes.X) > 0 ? (float)ControlPoint.StartTime : 0, (ScrollingAxes & Axes.Y) > 0 ? (float)ControlPoint.StartTime : 0); - - // We want our size and position-space along the scrolling axes to span our duration to completely enclose all the hit objects - Size = new Vector2((ScrollingAxes & Axes.X) > 0 ? (float)Duration : Size.X, (ScrollingAxes & Axes.Y) > 0 ? (float)Duration : Size.Y); - // And we need to make sure the hit object's position-space doesn't change due to our resizing - RelativeChildSize = Size; - } - } -} diff --git a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs b/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs deleted file mode 100644 index 81e3a5c70e..0000000000 --- a/osu.Game/Rulesets/Timing/SpeedAdjustmentContainer.cs +++ /dev/null @@ -1,114 +0,0 @@ -// Copyright (c) 2007-2017 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.Rulesets.Objects.Drawables; -using OpenTK; - -namespace osu.Game.Rulesets.Timing -{ - /// - /// A container that provides the speed adjustments defined by s to affect the scroll speed - /// of container s. - /// - public class SpeedAdjustmentContainer : Container - { - /// - /// Gets or sets the range of time that is visible by the length of the scrolling axes. - /// - public readonly Bindable VisibleTimeRange = new Bindable { Default = 1000 }; - - /// - /// Whether to reverse the scrolling direction is reversed. - /// - public readonly BindableBool Reversed = new BindableBool(); - - protected override Container Content => content; - private readonly Container content; - - /// - /// The axes which the content of this container will scroll through. - /// - public Axes ScrollingAxes - { - get { return scrollingContainer.ScrollingAxes; } - set { scrollingContainer.ScrollingAxes = value; } - } - - public override bool RemoveWhenNotAlive => false; - protected override bool RequiresChildrenUpdate => true; - - /// - /// The that defines the speed adjustments. - /// - public readonly MultiplierControlPoint ControlPoint; - - private readonly ScrollingContainer scrollingContainer; - - /// - /// Creates a new . - /// - /// The that defines the speed adjustments. - public SpeedAdjustmentContainer(MultiplierControlPoint controlPoint) - { - ControlPoint = controlPoint; - RelativeSizeAxes = Axes.Both; - - scrollingContainer = CreateScrollingContainer(); - scrollingContainer.ControlPoint = ControlPoint; - scrollingContainer.VisibleTimeRange.BindTo(VisibleTimeRange); - - AddInternal(content = scrollingContainer); - } - - protected override void Update() - { - float multiplier = (float)ControlPoint.Multiplier; - - // The speed adjustment happens by modifying our size by the multiplier while maintaining the visible time range as the relatve size for our children - Size = new Vector2((ScrollingAxes & Axes.X) > 0 ? multiplier : 1, (ScrollingAxes & Axes.Y) > 0 ? multiplier : 1); - - if (Reversed) - { - RelativeChildSize = new Vector2((ScrollingAxes & Axes.X) > 0 ? (float)-VisibleTimeRange : 1, (ScrollingAxes & Axes.Y) > 0 ? (float)-VisibleTimeRange : 1); - RelativeChildOffset = new Vector2((ScrollingAxes & Axes.X) > 0 ? (float)VisibleTimeRange : 0, (ScrollingAxes & Axes.Y) > 0 ? (float)VisibleTimeRange : 0); - Origin = Anchor = Anchor.BottomRight; - } - else - { - RelativeChildSize = new Vector2((ScrollingAxes & Axes.X) > 0 ? (float)VisibleTimeRange : 1, (ScrollingAxes & Axes.Y) > 0 ? (float)VisibleTimeRange : 1); - RelativeChildOffset = Vector2.Zero; - Origin = Anchor = Anchor.TopLeft; - } - } - - public override double LifetimeStart => ControlPoint.StartTime - VisibleTimeRange; - public override double LifetimeEnd => ControlPoint.StartTime + scrollingContainer.Duration + VisibleTimeRange; - - public override void Add(DrawableHitObject drawable) - { - var scrollingHitObject = drawable as IScrollingHitObject; - - if (scrollingHitObject != null) - { - scrollingHitObject.LifetimeOffset.BindTo(VisibleTimeRange); - scrollingHitObject.ScrollingAxes = ScrollingAxes; - } - - base.Add(drawable); - } - - /// - /// Whether a point in time falls within this s affecting timespan. - /// - public bool CanContain(double startTime) => ControlPoint.StartTime <= startTime; - - /// - /// Creates the which contains the scrolling s of this container. - /// - /// The . - protected virtual ScrollingContainer CreateScrollingContainer() => new LinearScrollingContainer(ControlPoint); - } -} diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 395248b2fd..56959240a8 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -1,15 +1,13 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using System.Collections.Generic; -using System.Linq; using OpenTK.Input; using osu.Framework.Configuration; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Transforms; using osu.Framework.Input; +using osu.Framework.Lists; using osu.Framework.MathUtils; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; @@ -50,11 +48,6 @@ namespace osu.Game.Rulesets.UI MaxValue = time_span_max }; - /// - /// Whether to reverse the scrolling direction is reversed. Note that this does _not_ invert the hit objects. - /// - protected readonly BindableBool Reversed = new BindableBool(); - /// /// The container that contains the s and s. /// @@ -65,12 +58,11 @@ namespace osu.Game.Rulesets.UI /// /// The axes on which s in this container should scroll. /// Whether we want our internal coordinate system to be scaled to a specified width - protected ScrollingPlayfield(Axes scrollingAxes, float? customWidth = null) + protected ScrollingPlayfield(Direction scrollingDirection, float? customWidth = null) : base(customWidth) { - base.HitObjects = HitObjects = new ScrollingHitObjectContainer(scrollingAxes) { RelativeSizeAxes = Axes.Both }; - HitObjects.VisibleTimeRange.BindTo(VisibleTimeRange); - HitObjects.Reversed.BindTo(Reversed); + base.HitObjects = HitObjects = new ScrollingHitObjectContainer(scrollingDirection) { RelativeSizeAxes = Axes.Both }; + HitObjects.TimeRange.BindTo(VisibleTimeRange); } private List nestedPlayfields; @@ -131,135 +123,66 @@ namespace osu.Game.Rulesets.UI protected override void ReadIntoStartValue(ScrollingPlayfield d) => StartValue = d.VisibleTimeRange.Value; } - /// - /// A container that provides the foundation for sorting s into s. - /// public class ScrollingHitObjectContainer : HitObjectContainer { - /// - /// Gets or sets the range of time that is visible by the length of the scrolling axes. - /// For example, only hit objects with start time less than or equal to 1000 will be visible with = 1000. - /// - public readonly BindableDouble VisibleTimeRange = new BindableDouble { Default = 1000 }; - - /// - /// Whether to reverse the scrolling direction is reversed. - /// - public readonly BindableBool Reversed = new BindableBool(); - - private readonly SortedContainer speedAdjustments; - public IReadOnlyList SpeedAdjustments => speedAdjustments; - - private readonly SpeedAdjustmentContainer defaultSpeedAdjustment; - - private readonly Axes scrollingAxes; - - /// - /// Creates a new . - /// - /// The axes upon which hit objects should appear to scroll inside this container. - public ScrollingHitObjectContainer(Axes scrollingAxes) + public readonly BindableDouble TimeRange = new BindableDouble { - this.scrollingAxes = scrollingAxes; + MinValue = 0, + MaxValue = double.MaxValue + }; - AddInternal(speedAdjustments = new SortedContainer { RelativeSizeAxes = Axes.Both }); + public readonly SortedList ControlPoints = new SortedList(); - // Default speed adjustment - AddSpeedAdjustment(defaultSpeedAdjustment = new SpeedAdjustmentContainer(new MultiplierControlPoint(0))); + private readonly Direction scrollingDirection; + + public ScrollingHitObjectContainer(Direction scrollingDirection) + { + this.scrollingDirection = scrollingDirection; + + RelativeSizeAxes = Axes.Both; } - /// - /// Adds a to this container, re-sorting all hit objects - /// in the last that occurred (time-wise) before it. - /// - /// The . - public void AddSpeedAdjustment(SpeedAdjustmentContainer speedAdjustment) + protected override void UpdateAfterChildren() { - speedAdjustment.ScrollingAxes = scrollingAxes; - speedAdjustment.VisibleTimeRange.BindTo(VisibleTimeRange); - speedAdjustment.Reversed.BindTo(Reversed); + base.UpdateAfterChildren(); - if (speedAdjustments.Count > 0) + var currentMultiplier = controlPointAt(Time.Current); + + foreach (var obj in AliveObjects) { - // We need to re-sort all hit objects in the speed adjustment container prior to figure out if they - // should now lie within this one - var existingAdjustment = adjustmentContainerAt(speedAdjustment.ControlPoint.StartTime); - for (int i = 0; i < existingAdjustment.Count; i++) + var relativePosition = (Time.Current - obj.HitObject.StartTime) / (TimeRange / currentMultiplier.Multiplier); + + // Todo: We may need to consider scale here + var finalPosition = (float)relativePosition * DrawSize; + + switch (scrollingDirection) { - DrawableHitObject hitObject = existingAdjustment[i]; - - if (!speedAdjustment.CanContain(hitObject.HitObject.StartTime)) - continue; - - existingAdjustment.Remove(hitObject); - speedAdjustment.Add(hitObject); - - i--; + case Direction.Horizontal: + obj.X = finalPosition.X; + break; + case Direction.Vertical: + obj.Y = finalPosition.Y; + break; } } - - speedAdjustments.Add(speedAdjustment); } - /// - /// Removes a from this container, re-sorting all hit objects - /// which it contained into new s. - /// - /// The to remove. - public void RemoveSpeedAdjustment(SpeedAdjustmentContainer speedAdjustment) + private readonly MultiplierControlPoint searchingPoint = new MultiplierControlPoint(); + private MultiplierControlPoint controlPointAt(double time) { - if (speedAdjustment == defaultSpeedAdjustment) - throw new InvalidOperationException($"The default {nameof(SpeedAdjustmentContainer)} must not be removed."); + if (ControlPoints.Count == 0) + return new MultiplierControlPoint(double.MinValue); - if (!speedAdjustments.Remove(speedAdjustment)) - return; + if (time < ControlPoints[0].StartTime) + return ControlPoints[0]; - while (speedAdjustment.Count > 0) - { - DrawableHitObject hitObject = speedAdjustment[0]; + searchingPoint.StartTime = time; - speedAdjustment.Remove(hitObject); - Add(hitObject); - } - } + int index = ControlPoints.BinarySearch(searchingPoint); + if (index < 0) + index = ~index - 1; - public override IEnumerable Objects => speedAdjustments.SelectMany(s => s.Children); - - /// - /// Adds a hit object to this . The hit objects will be queued to be processed - /// new s are added to this . - /// - /// The hit object to add. - public override void Add(DrawableHitObject hitObject) - { - if (!(hitObject is IScrollingHitObject)) - throw new InvalidOperationException($"Hit objects added to a {nameof(ScrollingHitObjectContainer)} must implement {nameof(IScrollingHitObject)}."); - - adjustmentContainerAt(hitObject.HitObject.StartTime).Add(hitObject); - } - - public override bool Remove(DrawableHitObject hitObject) => speedAdjustments.Any(s => s.Remove(hitObject)); - - /// - /// Finds the which provides the speed adjustment active at a time. - /// If there is no active at the time, then the first (time-wise) speed adjustment is returned. - /// - /// The time to find the active at. - /// The active at . Null if there are no speed adjustments. - private SpeedAdjustmentContainer adjustmentContainerAt(double time) => speedAdjustments.FirstOrDefault(c => c.CanContain(time)) ?? defaultSpeedAdjustment; - - private class SortedContainer : Container - { - protected override int Compare(Drawable x, Drawable y) - { - var sX = (SpeedAdjustmentContainer)x; - var sY = (SpeedAdjustmentContainer)y; - - int result = sY.ControlPoint.StartTime.CompareTo(sX.ControlPoint.StartTime); - if (result != 0) - return result; - return base.Compare(y, x); - } + return ControlPoints[index]; } } } diff --git a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs index f1b8838fa9..9d98382a8b 100644 --- a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs @@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.UI private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield) { - playfield.HitObjects.AddSpeedAdjustment(CreateSpeedAdjustmentContainer(controlPoint)); + playfield.HitObjects.ControlPoints.Add(controlPoint); playfield.NestedPlayfields.ForEach(p => applySpeedAdjustment(controlPoint, p)); } @@ -108,12 +108,5 @@ namespace osu.Game.Rulesets.UI return new MultiplierControlPoint(time, DefaultControlPoints[index].DeepClone()); } - - /// - /// Creates a that facilitates the movement of hit objects. - /// - /// The that provides the speed adjustments for the hitobjects. - /// The . - protected virtual SpeedAdjustmentContainer CreateSpeedAdjustmentContainer(MultiplierControlPoint controlPoint) => new SpeedAdjustmentContainer(controlPoint); } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 519e214495..2369724f6b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -614,7 +614,6 @@ - @@ -665,10 +664,7 @@ - - - From 651e24e3cc497c647f782e94fef948dbc75d35a5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 19:17:40 +0900 Subject: [PATCH 071/206] Implement proper scrolling directions --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 2 +- osu.Game.Rulesets.Mania/UI/Column.cs | 2 +- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 +- .../Visual/TestCaseScrollingHitObjects.cs | 16 ++++++------ osu.Game/Rulesets/UI/ScrollingDirection.cs | 25 +++++++++++++++++++ osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 24 +++++++++++------- osu.Game/osu.Game.csproj | 1 + 8 files changed, 53 insertions(+), 21 deletions(-) create mode 100644 osu.Game/Rulesets/UI/ScrollingDirection.cs diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 322d1d91af..2f7d7449c8 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly CatcherArea catcherArea; public CatchPlayfield(BeatmapDifficulty difficulty) - : base(Direction.Vertical) + : base(ScrollingDirection.Down) { Container explodingFruitContainer; diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 048b3ef9f9..a0768e48a2 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Mania.UI private const float opacity_pressed = 0.25f; public Column() - : base(Direction.Vertical) + : base(ScrollingDirection.Down) { Width = column_width; diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 549b0f2ee6..161dd9ec22 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Mania.UI private readonly int columnCount; public ManiaPlayfield(int columnCount) - : base(Direction.Vertical) + : base(ScrollingDirection.Down) { this.columnCount = columnCount; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 5e1fa7e490..8c55fe009f 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -56,7 +56,7 @@ namespace osu.Game.Rulesets.Taiko.UI private readonly Box background; public TaikoPlayfield(ControlPointInfo controlPoints) - : base(Direction.Horizontal) + : base(ScrollingDirection.Left) { AddRangeInternal(new Drawable[] { diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index 01387791a1..b05efbde5c 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -24,8 +24,8 @@ namespace osu.Game.Tests.Visual public TestCaseScrollingHitObjects() { - playfields.Add(new TestPlayfield(Direction.Vertical)); - playfields.Add(new TestPlayfield(Direction.Horizontal)); + playfields.Add(new TestPlayfield(ScrollingDirection.Down)); + playfields.Add(new TestPlayfield(ScrollingDirection.Right)); playfields.ForEach(p => p.HitObjects.ControlPoints.Add(new MultiplierControlPoint(double.MinValue))); @@ -72,7 +72,7 @@ namespace osu.Game.Tests.Visual { p.Add(new TestDrawableHitObject(time) { - Anchor = p.ScrollingDirection == Direction.Horizontal ? Anchor.CentreRight : Anchor.BottomCentre + Anchor = p.Direction == ScrollingDirection.Right ? Anchor.CentreRight : Anchor.BottomCentre }); }); } @@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual TestDrawableControlPoint createDrawablePoint(double t) => new TestDrawableControlPoint(t) { - Anchor = p.ScrollingDirection == Direction.Horizontal ? Anchor.CentreRight : Anchor.BottomCentre + Anchor = p.Direction == ScrollingDirection.Right ? Anchor.CentreRight : Anchor.BottomCentre }; p.Add(createDrawablePoint(time)); @@ -105,15 +105,15 @@ namespace osu.Game.Tests.Visual { public readonly BindableDouble TimeRange = new BindableDouble(5000); - public readonly Direction ScrollingDirection; + public readonly ScrollingDirection Direction; public new ScrollingPlayfield.ScrollingHitObjectContainer HitObjects => (ScrollingPlayfield.ScrollingHitObjectContainer)base.HitObjects; - public TestPlayfield(Direction scrollingDirection) + public TestPlayfield(ScrollingDirection direction) { - ScrollingDirection = scrollingDirection; + Direction = direction; - base.HitObjects = new ScrollingPlayfield.ScrollingHitObjectContainer(scrollingDirection); + base.HitObjects = new ScrollingPlayfield.ScrollingHitObjectContainer(direction); HitObjects.TimeRange.BindTo(TimeRange); } } diff --git a/osu.Game/Rulesets/UI/ScrollingDirection.cs b/osu.Game/Rulesets/UI/ScrollingDirection.cs new file mode 100644 index 0000000000..29d63499ee --- /dev/null +++ b/osu.Game/Rulesets/UI/ScrollingDirection.cs @@ -0,0 +1,25 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +namespace osu.Game.Rulesets.UI +{ + public enum ScrollingDirection + { + /// + /// Hitobjects will scroll vertically from the bottom of the hitobject container. + /// + Up, + /// + /// Hitobjects will scroll vertically from the top of the hitobject container. + /// + Down, + /// + /// Hitobjects will scroll horizontally from the right of the hitobject container. + /// + Left, + /// + /// Hitobjects will scroll horizontally from the left of the hitobject container. + /// + Right + } +} diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index 56959240a8..f391d01ac9 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -58,10 +58,10 @@ namespace osu.Game.Rulesets.UI /// /// The axes on which s in this container should scroll. /// Whether we want our internal coordinate system to be scaled to a specified width - protected ScrollingPlayfield(Direction scrollingDirection, float? customWidth = null) + protected ScrollingPlayfield(ScrollingDirection direction, float? customWidth = null) : base(customWidth) { - base.HitObjects = HitObjects = new ScrollingHitObjectContainer(scrollingDirection) { RelativeSizeAxes = Axes.Both }; + base.HitObjects = HitObjects = new ScrollingHitObjectContainer(direction) { RelativeSizeAxes = Axes.Both }; HitObjects.TimeRange.BindTo(VisibleTimeRange); } @@ -133,11 +133,11 @@ namespace osu.Game.Rulesets.UI public readonly SortedList ControlPoints = new SortedList(); - private readonly Direction scrollingDirection; + private readonly ScrollingDirection direction; - public ScrollingHitObjectContainer(Direction scrollingDirection) + public ScrollingHitObjectContainer(ScrollingDirection direction) { - this.scrollingDirection = scrollingDirection; + this.direction = direction; RelativeSizeAxes = Axes.Both; } @@ -155,14 +155,20 @@ namespace osu.Game.Rulesets.UI // Todo: We may need to consider scale here var finalPosition = (float)relativePosition * DrawSize; - switch (scrollingDirection) + switch (direction) { - case Direction.Horizontal: - obj.X = finalPosition.X; + case ScrollingDirection.Up: + obj.Y = -finalPosition.Y; break; - case Direction.Vertical: + case ScrollingDirection.Down: obj.Y = finalPosition.Y; break; + case ScrollingDirection.Left: + obj.X = -finalPosition.X; + break; + case ScrollingDirection.Right: + obj.X = finalPosition.X; + break; } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 2369724f6b..c5c1004663 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -314,6 +314,7 @@ + From e0c921ff5c7426c6115c9f690eb749dcb2405b15 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 19:20:43 +0900 Subject: [PATCH 072/206] Split out ScrollingHitObjectContainer into new file --- .../Visual/TestCaseScrollingHitObjects.cs | 4 +- .../UI/ScrollingHitObjectContainer.cs | 79 +++++++++++++++++++ osu.Game/Rulesets/UI/ScrollingPlayfield.cs | 71 ----------------- osu.Game/osu.Game.csproj | 1 + 4 files changed, 82 insertions(+), 73 deletions(-) create mode 100644 osu.Game/Rulesets/UI/ScrollingHitObjectContainer.cs diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index b05efbde5c..71c1295ebb 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -107,13 +107,13 @@ namespace osu.Game.Tests.Visual public readonly ScrollingDirection Direction; - public new ScrollingPlayfield.ScrollingHitObjectContainer HitObjects => (ScrollingPlayfield.ScrollingHitObjectContainer)base.HitObjects; + public new ScrollingHitObjectContainer HitObjects => (ScrollingHitObjectContainer)base.HitObjects; public TestPlayfield(ScrollingDirection direction) { Direction = direction; - base.HitObjects = new ScrollingPlayfield.ScrollingHitObjectContainer(direction); + base.HitObjects = new ScrollingHitObjectContainer(direction); HitObjects.TimeRange.BindTo(TimeRange); } } diff --git a/osu.Game/Rulesets/UI/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/ScrollingHitObjectContainer.cs new file mode 100644 index 0000000000..61184ac53f --- /dev/null +++ b/osu.Game/Rulesets/UI/ScrollingHitObjectContainer.cs @@ -0,0 +1,79 @@ +// Copyright (c) 2007-2017 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.Lists; +using osu.Game.Rulesets.Timing; + +namespace osu.Game.Rulesets.UI +{ + public class ScrollingHitObjectContainer : Playfield.HitObjectContainer + { + public readonly BindableDouble TimeRange = new BindableDouble + { + MinValue = 0, + MaxValue = double.MaxValue + }; + + public readonly SortedList ControlPoints = new SortedList(); + + private readonly ScrollingDirection direction; + + public ScrollingHitObjectContainer(ScrollingDirection direction) + { + this.direction = direction; + + RelativeSizeAxes = Axes.Both; + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + var currentMultiplier = controlPointAt(Time.Current); + + foreach (var obj in AliveObjects) + { + var relativePosition = (Time.Current - obj.HitObject.StartTime) / (TimeRange / currentMultiplier.Multiplier); + + // Todo: We may need to consider scale here + var finalPosition = (float)relativePosition * DrawSize; + + switch (direction) + { + case ScrollingDirection.Up: + obj.Y = -finalPosition.Y; + break; + case ScrollingDirection.Down: + obj.Y = finalPosition.Y; + break; + case ScrollingDirection.Left: + obj.X = -finalPosition.X; + break; + case ScrollingDirection.Right: + obj.X = finalPosition.X; + break; + } + } + } + + private readonly MultiplierControlPoint searchingPoint = new MultiplierControlPoint(); + private MultiplierControlPoint controlPointAt(double time) + { + if (ControlPoints.Count == 0) + return new MultiplierControlPoint(double.MinValue); + + if (time < ControlPoints[0].StartTime) + return ControlPoints[0]; + + searchingPoint.StartTime = time; + + int index = ControlPoints.BinarySearch(searchingPoint); + if (index < 0) + index = ~index - 1; + + return ControlPoints[index]; + } + } +} diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs index f391d01ac9..5492f9e272 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/ScrollingPlayfield.cs @@ -7,10 +7,8 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Transforms; using osu.Framework.Input; -using osu.Framework.Lists; using osu.Framework.MathUtils; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Timing; namespace osu.Game.Rulesets.UI { @@ -122,74 +120,5 @@ namespace osu.Game.Rulesets.UI protected override void Apply(ScrollingPlayfield d, double time) => d.VisibleTimeRange.Value = valueAt(time); protected override void ReadIntoStartValue(ScrollingPlayfield d) => StartValue = d.VisibleTimeRange.Value; } - - public class ScrollingHitObjectContainer : HitObjectContainer - { - public readonly BindableDouble TimeRange = new BindableDouble - { - MinValue = 0, - MaxValue = double.MaxValue - }; - - public readonly SortedList ControlPoints = new SortedList(); - - private readonly ScrollingDirection direction; - - public ScrollingHitObjectContainer(ScrollingDirection direction) - { - this.direction = direction; - - RelativeSizeAxes = Axes.Both; - } - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - - var currentMultiplier = controlPointAt(Time.Current); - - foreach (var obj in AliveObjects) - { - var relativePosition = (Time.Current - obj.HitObject.StartTime) / (TimeRange / currentMultiplier.Multiplier); - - // Todo: We may need to consider scale here - var finalPosition = (float)relativePosition * DrawSize; - - switch (direction) - { - case ScrollingDirection.Up: - obj.Y = -finalPosition.Y; - break; - case ScrollingDirection.Down: - obj.Y = finalPosition.Y; - break; - case ScrollingDirection.Left: - obj.X = -finalPosition.X; - break; - case ScrollingDirection.Right: - obj.X = finalPosition.X; - break; - } - } - } - - private readonly MultiplierControlPoint searchingPoint = new MultiplierControlPoint(); - private MultiplierControlPoint controlPointAt(double time) - { - if (ControlPoints.Count == 0) - return new MultiplierControlPoint(double.MinValue); - - if (time < ControlPoints[0].StartTime) - return ControlPoints[0]; - - searchingPoint.StartTime = time; - - int index = ControlPoints.BinarySearch(searchingPoint); - if (index < 0) - index = ~index - 1; - - return ControlPoints[index]; - } - } } } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index c5c1004663..9cf7d72d1b 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -315,6 +315,7 @@ + From a7aab21a29b5d0cc268141933b4146a8f7b7fbf5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 19:22:15 +0900 Subject: [PATCH 073/206] Re-namespace files --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs | 1 + osu.Game.Rulesets.Mania/UI/Column.cs | 2 +- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 2 +- osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs | 1 + osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 +- osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs | 1 + osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs | 1 + .../Rulesets/UI/{ => Scrolling}/ScrollingDirection.cs | 2 +- .../UI/{ => Scrolling}/ScrollingHitObjectContainer.cs | 2 +- .../Rulesets/UI/{ => Scrolling}/ScrollingPlayfield.cs | 4 ++-- .../UI/{ => Scrolling}/ScrollingRulesetContainer.cs | 2 +- osu.Game/osu.Game.csproj | 8 ++++---- 13 files changed, 17 insertions(+), 13 deletions(-) rename osu.Game/Rulesets/UI/{ => Scrolling}/ScrollingDirection.cs (92%) rename osu.Game/Rulesets/UI/{ => Scrolling}/ScrollingHitObjectContainer.cs (95%) rename osu.Game/Rulesets/UI/{ => Scrolling}/ScrollingPlayfield.cs (97%) rename osu.Game/Rulesets/UI/{ => Scrolling}/ScrollingRulesetContainer.cs (97%) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 2f7d7449c8..1ea05f8ff6 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; -using osu.Game.Rulesets.UI; using OpenTK; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; @@ -10,6 +9,7 @@ using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Catch.UI { diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index 3ed9090098..e9f1a26e69 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets.Catch.Scoring; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; +using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Catch.UI { diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index a0768e48a2..81997d3705 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -12,8 +12,8 @@ using osu.Game.Graphics; using osu.Game.Rulesets.Objects.Drawables; using System; using osu.Framework.Input.Bindings; -using osu.Game.Rulesets.UI; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Mania.UI { diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 161dd9ec22..cc028a85ee 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -3,7 +3,6 @@ using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects; -using osu.Game.Rulesets.UI; using OpenTK; using OpenTK.Graphics; using osu.Framework.Graphics.Containers; @@ -17,6 +16,7 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Mania.UI { diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs index db9475b31e..55bae45ab2 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs @@ -22,6 +22,7 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; +using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Mania.UI { diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 8c55fe009f..007c637659 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Shapes; using osu.Game.Rulesets.Taiko.Objects; -using osu.Game.Rulesets.UI; using OpenTK; using OpenTK.Graphics; using osu.Game.Rulesets.Taiko.Judgements; @@ -17,6 +16,7 @@ using System.Linq; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Taiko.Objects.Drawables; using osu.Game.Beatmaps.ControlPoints; +using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Taiko.UI { diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs index 614b446181..cef51c664f 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoRulesetContainer.cs @@ -17,6 +17,7 @@ using osu.Game.Rulesets.Taiko.Replays; using OpenTK; using System.Linq; using osu.Framework.Input; +using osu.Game.Rulesets.UI.Scrolling; namespace osu.Game.Rulesets.Taiko.UI { diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index 71c1295ebb..7e332c7310 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -12,6 +12,7 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; using osu.Game.Rulesets.UI; +using osu.Game.Rulesets.UI.Scrolling; using OpenTK.Graphics; namespace osu.Game.Tests.Visual diff --git a/osu.Game/Rulesets/UI/ScrollingDirection.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingDirection.cs similarity index 92% rename from osu.Game/Rulesets/UI/ScrollingDirection.cs rename to osu.Game/Rulesets/UI/Scrolling/ScrollingDirection.cs index 29d63499ee..d89795f4d3 100644 --- a/osu.Game/Rulesets/UI/ScrollingDirection.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingDirection.cs @@ -1,7 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE -namespace osu.Game.Rulesets.UI +namespace osu.Game.Rulesets.UI.Scrolling { public enum ScrollingDirection { diff --git a/osu.Game/Rulesets/UI/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs similarity index 95% rename from osu.Game/Rulesets/UI/ScrollingHitObjectContainer.cs rename to osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 61184ac53f..4c11c53a89 100644 --- a/osu.Game/Rulesets/UI/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -6,7 +6,7 @@ using osu.Framework.Graphics; using osu.Framework.Lists; using osu.Game.Rulesets.Timing; -namespace osu.Game.Rulesets.UI +namespace osu.Game.Rulesets.UI.Scrolling { public class ScrollingHitObjectContainer : Playfield.HitObjectContainer { diff --git a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs similarity index 97% rename from osu.Game/Rulesets/UI/ScrollingPlayfield.cs rename to osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index 5492f9e272..899048531f 100644 --- a/osu.Game/Rulesets/UI/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -2,15 +2,15 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using OpenTK.Input; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Transforms; using osu.Framework.Input; using osu.Framework.MathUtils; using osu.Game.Rulesets.Objects.Drawables; +using OpenTK.Input; -namespace osu.Game.Rulesets.UI +namespace osu.Game.Rulesets.UI.Scrolling { /// /// A type of specialized towards scrolling s. diff --git a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs similarity index 97% rename from osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs rename to osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs index 9d98382a8b..73c3848f69 100644 --- a/osu.Game/Rulesets/UI/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs @@ -13,7 +13,7 @@ using osu.Game.Rulesets.Objects; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; -namespace osu.Game.Rulesets.UI +namespace osu.Game.Rulesets.UI.Scrolling { /// /// A type of that supports a . diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 9cf7d72d1b..a1912487e9 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -314,8 +314,10 @@ - - + + + + @@ -671,8 +673,6 @@ - - From bf64b8fc6966e496aadf8a747ccc47ef93d3fc29 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Thu, 4 Jan 2018 11:41:06 +0100 Subject: [PATCH 074/206] added hover effects to panels in social at least partially QQ --- osu.Game.Tests/Visual/TestCaseSocial.cs | 6 ++- osu.Game/Overlays/Social/SocialGridPanel.cs | 15 ++++++ osu.Game/Overlays/Social/SocialListPanel.cs | 16 ++++++ osu.Game/Overlays/Social/SocialPanel.cs | 60 +++++++++++++++++++++ osu.Game/Overlays/SocialOverlay.cs | 30 ++++++----- osu.Game/Users/UpdateableAvatar.cs | 2 +- osu.Game/Users/UserPanel.cs | 8 +-- osu.Game/osu.Game.csproj | 3 ++ 8 files changed, 123 insertions(+), 17 deletions(-) create mode 100644 osu.Game/Overlays/Social/SocialGridPanel.cs create mode 100644 osu.Game/Overlays/Social/SocialListPanel.cs create mode 100644 osu.Game/Overlays/Social/SocialPanel.cs diff --git a/osu.Game.Tests/Visual/TestCaseSocial.cs b/osu.Game.Tests/Visual/TestCaseSocial.cs index 3f418174c7..631f08254f 100644 --- a/osu.Game.Tests/Visual/TestCaseSocial.cs +++ b/osu.Game.Tests/Visual/TestCaseSocial.cs @@ -13,8 +13,12 @@ namespace osu.Game.Tests.Visual { public override IReadOnlyList RequiredTypes => new[] { + typeof(UserPanel), + typeof(SocialPanel), typeof(FilterControl), - typeof(SocialOverlay) + typeof(SocialOverlay), + typeof(SocialGridPanel), + typeof(SocialListPanel) }; public TestCaseSocial() diff --git a/osu.Game/Overlays/Social/SocialGridPanel.cs b/osu.Game/Overlays/Social/SocialGridPanel.cs new file mode 100644 index 0000000000..b2c6b75ab2 --- /dev/null +++ b/osu.Game/Overlays/Social/SocialGridPanel.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Users; + +namespace osu.Game.Overlays.Social +{ + public class SocialGridPanel : SocialPanel + { + public SocialGridPanel(User user) : base(user) + { + Width = 300; + } + } +} diff --git a/osu.Game/Overlays/Social/SocialListPanel.cs b/osu.Game/Overlays/Social/SocialListPanel.cs new file mode 100644 index 0000000000..f65fbe8142 --- /dev/null +++ b/osu.Game/Overlays/Social/SocialListPanel.cs @@ -0,0 +1,16 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Game.Users; + +namespace osu.Game.Overlays.Social +{ + public class SocialListPanel : SocialPanel + { + public SocialListPanel(User user) : base(user) + { + RelativeSizeAxes = Axes.X; + } + } +} diff --git a/osu.Game/Overlays/Social/SocialPanel.cs b/osu.Game/Overlays/Social/SocialPanel.cs new file mode 100644 index 0000000000..234640482e --- /dev/null +++ b/osu.Game/Overlays/Social/SocialPanel.cs @@ -0,0 +1,60 @@ +// Copyright (c) 2007-2017 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using OpenTK; +using OpenTK.Graphics; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Input; +using osu.Game.Users; + +namespace osu.Game.Overlays.Social +{ + public class SocialPanel : UserPanel + { + private const double hover_transition_time = 400; + + public SocialPanel(User user) : base(user) + { + } + + private readonly EdgeEffectParameters edgeEffectNormal = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Offset = new Vector2(0f, 1f), + Radius = 2f, + Colour = Color4.Black.Opacity(0.25f), + }; + + private readonly EdgeEffectParameters edgeEffectHovered = new EdgeEffectParameters + { + Type = EdgeEffectType.Shadow, + Offset = new Vector2(0f, 5f), + Radius = 10f, + Colour = Color4.Black.Opacity(0.3f), + }; + + protected override bool OnHover(InputState state) + { + TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint); + //Content.MoveToY(-4, hover_transition_time, Easing.OutQuint); + + return base.OnHover(state); + } + + protected override void OnHoverLost(InputState state) + { + TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint); + //Content.MoveToY(0, hover_transition_time, Easing.OutQuint); + + base.OnHoverLost(state); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + this.FadeInFromZero(200, Easing.Out); + } + } +} diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index c4ed14022e..823e264ebe 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -22,7 +22,7 @@ namespace osu.Game.Overlays { private APIAccess api; private readonly LoadingAnimation loading; - private FillFlowContainer panels; + private FillFlowContainer panels; protected override Color4 BackgroundColour => OsuColour.FromHex(@"60284b"); protected override Color4 TrianglesColourLight => OsuColour.FromHex(@"672b51"); @@ -121,7 +121,7 @@ namespace osu.Game.Overlays if (Users == null) return; - var newPanels = new FillFlowContainer + var newPanels = new FillFlowContainer { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, @@ -129,18 +129,18 @@ namespace osu.Game.Overlays Margin = new MarginPadding { Top = 10 }, ChildrenEnumerable = Users.Select(u => { - UserPanel panel = new UserPanel(u) - { - Anchor = Anchor.TopCentre, - Origin = Anchor.TopCentre - }; + SocialPanel panel; switch (displayStyle) { case PanelDisplayStyle.Grid: - panel.Width = 300; + panel = new SocialGridPanel(u) + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre + }; break; default: - panel.RelativeSizeAxes = Axes.X; + panel = new SocialListPanel(u); break; } panel.Status.BindTo(u.Status); @@ -148,14 +148,20 @@ namespace osu.Game.Overlays }) }; - LoadComponentAsync(newPanels, p => ScrollFlow.Add(panels = newPanels)); + LoadComponentAsync(newPanels, p => + { + if(panels != null) + ScrollFlow.Remove(panels); + + ScrollFlow.Add(panels = newPanels); + }); } private void clearPanels() { if (panels != null) { - ScrollFlow.Remove(panels); + panels.FadeOut(200); panels.Expire(); panels = null; } @@ -185,7 +191,7 @@ namespace osu.Game.Overlays switch (Header.Tabs.Current.Value) { case SocialTab.OnlineFriends: - var friendRequest = new GetFriendsRequest(); // TODO filter??? + var friendRequest = new GetFriendsRequest(); friendRequest.Success += updateUsers; api.Queue(getUsersRequest = friendRequest); break; diff --git a/osu.Game/Users/UpdateableAvatar.cs b/osu.Game/Users/UpdateableAvatar.cs index d55c0caad7..455856a6d4 100644 --- a/osu.Game/Users/UpdateableAvatar.cs +++ b/osu.Game/Users/UpdateableAvatar.cs @@ -44,7 +44,7 @@ namespace osu.Game.Users new Avatar(user) { RelativeSizeAxes = Axes.Both, - OnLoadComplete = d => d.FadeInFromZero(200), + OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out), }) ); } diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index e0a4e3184d..6690c38eca 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -65,8 +65,8 @@ namespace osu.Game.Users Anchor = Anchor.Centre, Origin = Anchor.Centre, FillMode = FillMode.Fill, - OnLoadComplete = d => d.FadeInFromZero(200), - }, 0) { RelativeSizeAxes = Axes.Both }, + OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out) + }, 300) { RelativeSizeAxes = Axes.Both }, new Box { RelativeSizeAxes = Axes.Both, @@ -76,7 +76,7 @@ namespace osu.Game.Users { RelativeSizeAxes = Axes.X, AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Top = content_padding, Left = content_padding, Right = content_padding }, + Padding = new MarginPadding { Top = content_padding, Horizontal = content_padding }, Children = new Drawable[] { new UpdateableAvatar @@ -167,11 +167,13 @@ namespace osu.Game.Users }; if (user.IsSupporter) + { infoContainer.Add(new SupporterIcon { RelativeSizeAxes = Axes.Y, Width = 20f, }); + } } [BackgroundDependencyLoader(permitNulls: true)] diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 49978693b3..dfc2120b89 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -311,6 +311,9 @@ + + + From 844c428fa7ead72a64422800feadc96fe95915ae Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Thu, 4 Jan 2018 11:49:03 +0100 Subject: [PATCH 075/206] Updated submodule osu-framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 6134dafccb..66421b8944 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 6134dafccb3368dac96d837537325c04b89fb8ee +Subproject commit 66421b894444cb9c4b792f9b93a786dcff5589dd From dcc4e863ab69795a1eb42d0594667624021da98b Mon Sep 17 00:00:00 2001 From: james58899 Date: Thu, 4 Jan 2018 19:04:52 +0800 Subject: [PATCH 076/206] move variables to StoryboardDecoder --- .../Beatmaps/Formats/LegacyBeatmapDecoder.cs | 23 ------------ osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 27 ++++---------- .../Formats/LegacyStoryboardDecoder.cs | 35 +++++++++++++++++++ 3 files changed, 42 insertions(+), 43 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index ea29e480ec..31678fd3b1 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -8,7 +8,6 @@ using OpenTK.Graphics; using osu.Game.Beatmaps.Timing; using osu.Game.Rulesets.Objects.Legacy; using osu.Game.Beatmaps.ControlPoints; -using System.Collections.Generic; namespace osu.Game.Beatmaps.Formats { @@ -82,9 +81,6 @@ namespace osu.Game.Beatmaps.Formats case Section.HitObjects: handleHitObjects(line); break; - case Section.Variables: - handleVariables(line); - break; } } @@ -242,8 +238,6 @@ namespace osu.Game.Beatmaps.Formats private void handleEvents(string line) { - DecodeVariables(ref line); - string[] split = line.Split(','); EventType type; @@ -400,22 +394,5 @@ namespace osu.Game.Beatmaps.Formats if (obj != null) beatmap.HitObjects.Add(obj); } - - private void handleVariables(string line) - { - var pair = splitKeyVal(line, '='); - Variables[pair.Key] = pair.Value; - } - - private KeyValuePair splitKeyVal(string line, char separator) - { - var split = line.Trim().Split(new[] { separator }, 2); - - return new KeyValuePair - ( - split[0].Trim(), - split.Length > 1 ? split[1].Trim() : string.Empty - ); - } } } diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index e5ced5f772..faad03e7d9 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -29,7 +29,6 @@ namespace osu.Game.Beatmaps.Formats } protected int BeatmapVersion; - protected readonly Dictionary Variables = new Dictionary(); public override Decoder GetStoryboardDecoder() => new LegacyStoryboardDecoder(BeatmapVersion); @@ -82,27 +81,15 @@ namespace osu.Game.Beatmaps.Formats protected abstract void ProcessSection(Section section, string line); - /// - /// Decodes any beatmap variables present in a line into their real values. - /// - /// The line which may contains variables. - protected void DecodeVariables(ref string line) + protected KeyValuePair splitKeyVal(string line, char separator) { - while (line.IndexOf('$') >= 0) - { - string origLine = line; - string[] split = line.Split(','); - for (int i = 0; i < split.Length; i++) - { - var item = split[i]; - if (item.StartsWith("$") && Variables.ContainsKey(item)) - split[i] = Variables[item]; - } + var split = line.Trim().Split(new[] { separator }, 2); - line = string.Join(",", split); - if (line == origLine) - break; - } + return new KeyValuePair + ( + split[0].Trim(), + split.Length > 1 ? split[1].Trim() : string.Empty + ); } protected enum Section diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 168f37e44e..40f2695f28 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using System.Globalization; using System.IO; using OpenTK; @@ -19,6 +20,8 @@ namespace osu.Game.Beatmaps.Formats private StoryboardSprite storyboardSprite; private CommandTimelineGroup timelineGroup; + private readonly Dictionary Variables = new Dictionary(); + public LegacyStoryboardDecoder() { } @@ -47,6 +50,9 @@ namespace osu.Game.Beatmaps.Formats case Section.Events: handleEvents(line); break; + case Section.Variables: + handleVariables(line); + break; } } @@ -266,6 +272,35 @@ namespace osu.Game.Beatmaps.Formats throw new InvalidDataException($@"Unknown origin: {value}"); } + private void handleVariables(string line) + { + var pair = splitKeyVal(line, '='); + Variables[pair.Key] = pair.Value; + } + + /// + /// Decodes any beatmap variables present in a line into their real values. + /// + /// The line which may contains variables. + private void DecodeVariables(ref string line) + { + while (line.IndexOf('$') >= 0) + { + string origLine = line; + string[] split = line.Split(','); + for (int i = 0; i < split.Length; i++) + { + var item = split[i]; + if (item.StartsWith("$") && Variables.ContainsKey(item)) + split[i] = Variables[item]; + } + + line = string.Join(",", split); + if (line == origLine) + break; + } + } + private string cleanFilename(string path) => FileSafety.PathSanitise(path.Trim('\"')); } } From 0158246ba148ab5a0e18e4caca528943f40bf032 Mon Sep 17 00:00:00 2001 From: james58899 Date: Thu, 4 Jan 2018 19:23:00 +0800 Subject: [PATCH 077/206] AppVeyor --- osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs | 10 +++++----- osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 2 +- .../Beatmaps/Formats/LegacyStoryboardDecoder.cs | 14 +++++++------- 3 files changed, 13 insertions(+), 13 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs index 31678fd3b1..83d70d832d 100644 --- a/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyBeatmapDecoder.cs @@ -86,7 +86,7 @@ namespace osu.Game.Beatmaps.Formats private void handleGeneral(string line) { - var pair = splitKeyVal(line, ':'); + var pair = SplitKeyVal(line, ':'); var metadata = beatmap.BeatmapInfo.Metadata; switch (pair.Key) @@ -145,7 +145,7 @@ namespace osu.Game.Beatmaps.Formats private void handleEditor(string line) { - var pair = splitKeyVal(line, ':'); + var pair = SplitKeyVal(line, ':'); switch (pair.Key) { @@ -169,7 +169,7 @@ namespace osu.Game.Beatmaps.Formats private void handleMetadata(string line) { - var pair = splitKeyVal(line, ':'); + var pair = SplitKeyVal(line, ':'); var metadata = beatmap.BeatmapInfo.Metadata; switch (pair.Key) @@ -210,7 +210,7 @@ namespace osu.Game.Beatmaps.Formats private void handleDifficulty(string line) { - var pair = splitKeyVal(line, ':'); + var pair = SplitKeyVal(line, ':'); var difficulty = beatmap.BeatmapInfo.BaseDifficulty; switch (pair.Key) @@ -353,7 +353,7 @@ namespace osu.Game.Beatmaps.Formats private void handleColours(string line) { - var pair = splitKeyVal(line, ':'); + var pair = SplitKeyVal(line, ':'); string[] split = pair.Value.Split(','); diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index faad03e7d9..214f7ccb8b 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -81,7 +81,7 @@ namespace osu.Game.Beatmaps.Formats protected abstract void ProcessSection(Section section, string line); - protected KeyValuePair splitKeyVal(string line, char separator) + protected KeyValuePair SplitKeyVal(string line, char separator) { var split = line.Trim().Split(new[] { separator }, 2); diff --git a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs index 40f2695f28..ed4992d532 100644 --- a/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyStoryboardDecoder.cs @@ -20,7 +20,7 @@ namespace osu.Game.Beatmaps.Formats private StoryboardSprite storyboardSprite; private CommandTimelineGroup timelineGroup; - private readonly Dictionary Variables = new Dictionary(); + private readonly Dictionary variables = new Dictionary(); public LegacyStoryboardDecoder() { @@ -65,7 +65,7 @@ namespace osu.Game.Beatmaps.Formats line = line.Substring(1); } - DecodeVariables(ref line); + decodeVariables(ref line); string[] split = line.Split(','); @@ -274,15 +274,15 @@ namespace osu.Game.Beatmaps.Formats private void handleVariables(string line) { - var pair = splitKeyVal(line, '='); - Variables[pair.Key] = pair.Value; + var pair = SplitKeyVal(line, '='); + variables[pair.Key] = pair.Value; } /// /// Decodes any beatmap variables present in a line into their real values. /// /// The line which may contains variables. - private void DecodeVariables(ref string line) + private void decodeVariables(ref string line) { while (line.IndexOf('$') >= 0) { @@ -291,8 +291,8 @@ namespace osu.Game.Beatmaps.Formats for (int i = 0; i < split.Length; i++) { var item = split[i]; - if (item.StartsWith("$") && Variables.ContainsKey(item)) - split[i] = Variables[item]; + if (item.StartsWith("$") && variables.ContainsKey(item)) + split[i] = variables[item]; } line = string.Join(",", split); From 585df22c88f0c8d83587f17f870afa5da8e9ac8f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 20:56:18 +0900 Subject: [PATCH 078/206] Add a way to calculate length of IHasEndTime objects --- .../Scrolling/ScrollingHitObjectContainer.cs | 26 +++++++++++++++++-- 1 file changed, 24 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 4c11c53a89..36b885c84b 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -4,7 +4,9 @@ using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Lists; +using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; +using OpenTK; namespace osu.Game.Rulesets.UI.Scrolling { @@ -35,9 +37,8 @@ namespace osu.Game.Rulesets.UI.Scrolling foreach (var obj in AliveObjects) { - var relativePosition = (Time.Current - obj.HitObject.StartTime) / (TimeRange / currentMultiplier.Multiplier); - // Todo: We may need to consider scale here + var relativePosition = (Time.Current - obj.HitObject.StartTime) * currentMultiplier.Multiplier / TimeRange; var finalPosition = (float)relativePosition * DrawSize; switch (direction) @@ -55,6 +56,27 @@ namespace osu.Game.Rulesets.UI.Scrolling obj.X = finalPosition.X; break; } + + if (!(obj.HitObject is IHasEndTime endTime)) + continue; + + // Todo: We may need to consider scale here + var relativeEndPosition = (Time.Current - endTime.EndTime) * currentMultiplier.Multiplier / TimeRange; + var finalEndPosition = (float)relativeEndPosition * DrawSize; + + float length = Vector2.Distance(finalPosition, finalEndPosition); + + switch (direction) + { + case ScrollingDirection.Up: + case ScrollingDirection.Down: + obj.Height = length; + break; + case ScrollingDirection.Left: + case ScrollingDirection.Right: + obj.Width = length; + break; + } } } From 4fee76ba0b8b2496f1812cebc5610de88b40ae1d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 20:56:28 +0900 Subject: [PATCH 079/206] Fix drumroll lengths --- 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 f5bafefd0b..88184d5fcf 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -34,7 +34,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public DrawableDrumRoll(DrumRoll drumRoll) : base(drumRoll) { - Width = (float)HitObject.Duration; + RelativeSizeAxes = Axes.Y; Container tickContainer; MainPiece.Add(tickContainer = new Container From add68ff068577a1f14ac4e9841c56316b8074336 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 21:45:29 +0900 Subject: [PATCH 080/206] Fix swells not stopping at the hit position --- osu-framework | 2 +- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs | 2 +- .../Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs | 7 +++++-- 3 files changed, 7 insertions(+), 4 deletions(-) diff --git a/osu-framework b/osu-framework index 6134dafccb..067fdb8f5b 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 6134dafccb3368dac96d837537325c04b89fb8ee +Subproject commit 067fdb8f5b0594be1cd30e6bbd43f2ea749904ec diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs index 26e6585fb9..c8e5913fd2 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs @@ -192,7 +192,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables Size = BaseSize * Parent.RelativeChildSize; // Make the swell stop at the hit target - X = (float)Math.Max(Time.Current, HitObject.StartTime); + X = Math.Max(0, X); double t = Math.Min(HitObject.StartTime, Time.Current); if (t == HitObject.StartTime && !hasStarted) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 36b885c84b..4011e7ffd1 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -29,9 +29,12 @@ namespace osu.Game.Rulesets.UI.Scrolling RelativeSizeAxes = Axes.Both; } - protected override void UpdateAfterChildren() + protected override void UpdateAfterChildrenLife() { - base.UpdateAfterChildren(); + base.UpdateAfterChildrenLife(); + + // We need to calculate this as soon as possible so that hitobjects + // get the final say in their positions var currentMultiplier = controlPointAt(Time.Current); From e0e84ff37011d69a5e0f521bb83f6566c478c7cf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 22:05:20 +0900 Subject: [PATCH 081/206] Fix mania playfield scrolling hitobjects in the wrong direction --- osu.Game.Rulesets.Mania/UI/Column.cs | 2 +- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 81997d3705..0910f9f37d 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Mania.UI private const float opacity_pressed = 0.25f; public Column() - : base(ScrollingDirection.Down) + : base(ScrollingDirection.Up) { Width = column_width; diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index cc028a85ee..edb640a537 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Mania.UI private readonly int columnCount; public ManiaPlayfield(int columnCount) - : base(ScrollingDirection.Down) + : base(ScrollingDirection.Up) { this.columnCount = columnCount; From ce94c825d18be7f32ab0ba8235bf01d7ad4b2aa2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 4 Jan 2018 22:05:38 +0900 Subject: [PATCH 082/206] Fix length of hold notes --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 41d817a746..48e1332597 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -42,8 +42,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables public DrawableHoldNote(HoldNote hitObject, ManiaAction action) : base(hitObject, action) { - RelativeSizeAxes = Axes.Both; - Height = (float)HitObject.Duration; + RelativeSizeAxes = Axes.X; AddRange(new Drawable[] { From ddc9edab5423899579c1f50ff0909e1a34e7ac2f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 2 Jan 2018 14:33:28 +0900 Subject: [PATCH 083/206] Make OsuSliderBar support both float and double values --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 15 +++++++++++---- 1 file changed, 11 insertions(+), 4 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index fd75269610..4ff65dea93 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -32,11 +32,18 @@ namespace osu.Game.Graphics.UserInterface get { var bindableDouble = CurrentNumber as BindableNumber; - if (bindableDouble != null) + var bindableFloat = CurrentNumber as BindableNumber; + var floatValue = bindableDouble?.Value ?? bindableFloat?.Value ?? null; + + if (floatValue != null) { - if (bindableDouble.MaxValue == 1 && (bindableDouble.MinValue == 0 || bindableDouble.MinValue == -1)) - return bindableDouble.Value.ToString(@"P0"); - return bindableDouble.Value.ToString(@"n1"); + var floatMinValue = bindableDouble?.MinValue ?? bindableFloat?.MinValue ?? null; + var floatMaxValue = bindableDouble?.MaxValue ?? bindableFloat?.MaxValue ?? null; + + if (floatMaxValue == 1 && (floatMinValue == 0 || floatMinValue == -1)) + return floatValue.Value.ToString(@"P0"); + + return floatValue.Value.ToString(@"n1"); } var bindableInt = CurrentNumber as BindableNumber; From 08af3e6303e3e95064c8b5d6e6717aa1f377fd2f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 2 Jan 2018 14:34:50 +0900 Subject: [PATCH 084/206] Make OsuSliderBar formatting support variable number of digits --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index 4ff65dea93..bbbe710313 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Globalization; using OpenTK; using OpenTK.Graphics; using osu.Framework.Allocation; @@ -27,6 +28,11 @@ namespace osu.Game.Graphics.UserInterface private readonly Box leftBox; private readonly Box rightBox; + /// + /// The amount of decimal digits to display for s with floating point values. + /// + public int TooltipDecimalDigits = 1; + public virtual string TooltipText { get @@ -43,7 +49,10 @@ namespace osu.Game.Graphics.UserInterface if (floatMaxValue == 1 && (floatMinValue == 0 || floatMinValue == -1)) return floatValue.Value.ToString(@"P0"); - return floatValue.Value.ToString(@"n1"); + var nfi = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone(); + nfi.NumberDecimalDigits = TooltipDecimalDigits; + + return string.Format(nfi, "{0:F}", floatValue.Value); } var bindableInt = CurrentNumber as BindableNumber; From eaa2a007e779e8003698a8037409a1ab90f0f64d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 2 Jan 2018 16:12:15 +0900 Subject: [PATCH 085/206] Cleanup --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index bbbe710313..c282ed96d6 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -39,12 +39,12 @@ namespace osu.Game.Graphics.UserInterface { var bindableDouble = CurrentNumber as BindableNumber; var bindableFloat = CurrentNumber as BindableNumber; - var floatValue = bindableDouble?.Value ?? bindableFloat?.Value ?? null; + var floatValue = bindableDouble?.Value ?? bindableFloat?.Value; if (floatValue != null) { - var floatMinValue = bindableDouble?.MinValue ?? bindableFloat?.MinValue ?? null; - var floatMaxValue = bindableDouble?.MaxValue ?? bindableFloat?.MaxValue ?? null; + var floatMinValue = bindableDouble?.MinValue ?? bindableFloat.MinValue; + var floatMaxValue = bindableDouble?.MaxValue ?? bindableFloat.MaxValue; if (floatMaxValue == 1 && (floatMinValue == 0 || floatMinValue == -1)) return floatValue.Value.ToString(@"P0"); From b84f83cf165cc746308fbb44f94e3c53e6e436f8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 2 Jan 2018 16:12:48 +0900 Subject: [PATCH 086/206] Trigger a value changed event when the number of digits changes --- .../Graphics/UserInterface/OsuSliderBar.cs | 18 +++++++++++++++++- 1 file changed, 17 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index c282ed96d6..a5fb2de395 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -28,10 +28,26 @@ namespace osu.Game.Graphics.UserInterface private readonly Box leftBox; private readonly Box rightBox; + private int tooltipDecimalDigits = 1; /// /// The amount of decimal digits to display for s with floating point values. /// - public int TooltipDecimalDigits = 1; + public int TooltipDecimalDigits + { + get => tooltipDecimalDigits; + set + { + if (tooltipDecimalDigits == value) + return; + tooltipDecimalDigits = value; + + if (IsLoaded) + { + // Some users may want to see the updated ToolTipText + Current.TriggerChange(); + } + } + } public virtual string TooltipText { From cbf48524385b9c920f1736880ce01175b49a1c79 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 2 Jan 2018 17:00:38 +0900 Subject: [PATCH 087/206] Expose a NumberFormatInfo for more extensibility --- .../Graphics/UserInterface/OsuSliderBar.cs | 31 ++++++++++--------- 1 file changed, 17 insertions(+), 14 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index a5fb2de395..701a9d4460 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -28,18 +28,15 @@ namespace osu.Game.Graphics.UserInterface private readonly Box leftBox; private readonly Box rightBox; - private int tooltipDecimalDigits = 1; - /// - /// The amount of decimal digits to display for s with floating point values. - /// - public int TooltipDecimalDigits + private NumberFormatInfo format; + public NumberFormatInfo Format { - get => tooltipDecimalDigits; + get => format ?? (format = createDefaultFormat()); set { - if (tooltipDecimalDigits == value) + if (format == value) return; - tooltipDecimalDigits = value; + format = value; if (IsLoaded) { @@ -63,17 +60,14 @@ namespace osu.Game.Graphics.UserInterface var floatMaxValue = bindableDouble?.MaxValue ?? bindableFloat.MaxValue; if (floatMaxValue == 1 && (floatMinValue == 0 || floatMinValue == -1)) - return floatValue.Value.ToString(@"P0"); + return floatValue.Value.ToString("P", Format); - var nfi = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone(); - nfi.NumberDecimalDigits = TooltipDecimalDigits; - - return string.Format(nfi, "{0:F}", floatValue.Value); + return floatValue.Value.ToString("F", Format); } var bindableInt = CurrentNumber as BindableNumber; if (bindableInt != null) - return bindableInt.Value.ToString(@"n0"); + return bindableInt.Value.ToString("N0"); return Current.Value.ToString(); } @@ -137,6 +131,15 @@ namespace osu.Game.Graphics.UserInterface AccentColour = colours.Pink; } + private NumberFormatInfo createDefaultFormat() + { + var nfi = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone(); + nfi.PercentDecimalDigits = 0; + nfi.NumberDecimalDigits = 1; + + return nfi; + } + protected override bool OnHover(InputState state) { Nub.Glowing = true; From 76f4bb1ca08d9257f1dbac24493f4a83d4d15dbf Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 2 Jan 2018 17:00:51 +0900 Subject: [PATCH 088/206] Add automated test cases --- .../Visual/TestCaseSliderBarPercentage.cs | 123 +++++++++++++ .../Visual/TestCaseSliderBarPrecision.cs | 172 ++++++++++++++++++ osu.Game.Tests/osu.Game.Tests.csproj | 2 + 3 files changed, 297 insertions(+) create mode 100644 osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs create mode 100644 osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs diff --git a/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs b/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs new file mode 100644 index 0000000000..5c4d545348 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs @@ -0,0 +1,123 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Graphics; +using osu.Framework.Configuration; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using OpenTK; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseSliderBarPercentage : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(OsuSliderBar<>) }; + + private readonly BindableFloat floatValue; + private readonly BindableDouble doubleValue; + + private readonly TestSliderBar floatSliderBar; + private readonly TestSliderBar doubleSliderBar; + + public TestCaseSliderBarPercentage() + { + floatValue = new BindableFloat + { + MinValue = -1, + MaxValue = 1, + }; + + doubleValue = new BindableDouble + { + MinValue = -1, + MaxValue = 1 + }; + + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + Width = 300, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + floatSliderBar = new TestSliderBar { RelativeSizeAxes = Axes.X }, + doubleSliderBar = new TestSliderBar { RelativeSizeAxes = Axes.X } + } + }; + + floatSliderBar.Current.BindTo(floatValue); + doubleSliderBar.Current.BindTo(doubleValue); + + floatValue.ValueChanged += setValue; + doubleValue.ValueChanged += setValue; + + AddStep("Digits = 0", () => setPercentageDigits(0)); + AddStep("Value = 0", () => setValue(0)); + AddAssert("Check 0%", () => checkExact(0)); + + AddStep("Value = 0.5", () => setValue(0.5)); + AddAssert("Check 50%", () => checkExact(0.5m)); + + AddStep("Value = 0.54", () => setValue(0.54)); + AddAssert("Check 54%", () => checkExact(0.54m)); + + AddStep("Value = 0.544", () => setValue(0.544)); + AddAssert("Check 54%", () => checkExact(0.54m)); + + AddStep("Value = 0.548", () => setValue(0.548)); + AddAssert("Check 55%", () => checkExact(0.55m)); + + AddStep("Digits = 1", () => setPercentageDigits(1)); + AddAssert("Check 54.8%", () => checkExact(0.548m)); + + AddSliderStep("Percentage", -1.0, 1.0, 0.0, setValue); + AddSliderStep("Digits", 0, 7, 1, setPercentageDigits); + } + + private bool checkExact(decimal percentage) + { + string expectedValue = percentage.ToString("P", floatSliderBar.Format); + return floatSliderBar.TooltipText == expectedValue && doubleSliderBar.TooltipText == expectedValue; + } + + private void setValue(T value) + { + floatValue.Value = Convert.ToSingle(value); + doubleValue.Value = Convert.ToDouble(value); + } + + private void setPercentageDigits(int digits) + { + floatSliderBar.Format.PercentDecimalDigits = digits; + doubleSliderBar.Format.PercentDecimalDigits = digits; + + // Make sure that the text referenced in TestSliderBar is updated + // This doesn't break any assertions if missing, but breaks the visual display + floatSliderBar.Current.TriggerChange(); + doubleSliderBar.Current.TriggerChange(); + } + + private class TestSliderBar : OsuSliderBar + where T : struct, IEquatable + { + public TestSliderBar() + { + SpriteText valueText; + AddInternal(valueText = new OsuSpriteText + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, + X = 5, + Text = TooltipText + }); + + Current.ValueChanged += v => valueText.Text = TooltipText; + } + } + } +} diff --git a/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs b/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs new file mode 100644 index 0000000000..928ba0d825 --- /dev/null +++ b/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs @@ -0,0 +1,172 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Framework.Configuration; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Graphics.Sprites; +using osu.Game.Graphics.UserInterface; +using OpenTK; + +namespace osu.Game.Tests.Visual +{ + public class TestCaseSliderBarPrecision : OsuTestCase + { + public override IReadOnlyList RequiredTypes => new[] { typeof(OsuSliderBar<>) }; + + private readonly BindableInt intValue; + private readonly BindableFloat floatValue; + private readonly BindableDouble doubleValue; + + private readonly TestSliderBar intSliderBar; + private readonly TestSliderBar floatSliderBar; + private readonly TestSliderBar doubleSliderBar; + + public TestCaseSliderBarPrecision() + { + intValue = new BindableInt + { + MinValue = -1000, + MaxValue = 1000, + }; + + floatValue = new BindableFloat + { + MinValue = -1000, + MaxValue = 1000, + }; + + doubleValue = new BindableDouble + { + MinValue = -1000, + MaxValue = 1000 + }; + + Child = new FillFlowContainer + { + AutoSizeAxes = Axes.Y, + Width = 300, + Direction = FillDirection.Vertical, + Spacing = new Vector2(0, 20), + Children = new Drawable[] + { + intSliderBar = new TestSliderBar { RelativeSizeAxes = Axes.X }, + floatSliderBar = new TestSliderBar { RelativeSizeAxes = Axes.X }, + doubleSliderBar = new TestSliderBar { RelativeSizeAxes = Axes.X } + } + }; + + intSliderBar.Current.BindTo(intValue); + floatSliderBar.Current.BindTo(floatValue); + doubleSliderBar.Current.BindTo(doubleValue); + + intValue.ValueChanged += setValue; + floatValue.ValueChanged += setValue; + doubleValue.ValueChanged += setValue; + + AddStep("Value = 0", () => setValue(0)); + AddStep("Digits = 0", () => setDecimalDigits(0)); + AddAssert("Check all 0", () => checkExact("0")); + + AddStep("Digits = 3", () => setDecimalDigits(3)); + AddAssert("Check 0.000", () => checkExact(0.000m)); + + AddStep("Value = 0.5", () => setValue(0.5)); + AddAssert("Check 0.500", () => checkExact(0.500m)); + + AddStep("Value = 123.4567", () => setValue(123.4567)); + AddAssert("Check 123.457", () => checkExact(123.457m)); + + AddStep("Value = 765.4312", () => setValue(765.4312)); + AddAssert("Check 765.431", () => checkExact(765.431m)); + + AddStep("Value = -12.3456", () => setValue(-12.3456)); + AddAssert("Check -12.346", () => checkExact(-12.346m)); + AddStep("Digits = 1", () => setDecimalDigits(1)); + AddAssert("Check -12.3", () => checkExact(-12.3m)); + AddStep("Digits = 0", () => setDecimalDigits(0)); + AddAssert("Check -12", () => checkExact(-12m)); + + AddStep("Value = -12.8", () => setValue(-12.8)); + AddAssert("Check -13", () => checkExact(-13m)); + AddStep("Digits = 1", () => setDecimalDigits(1)); + AddAssert("Check -12.8", () => checkExact(-12.8m)); + + AddSliderStep("Digits", 0, 7, 1, setDecimalDigits); + } + + /// + /// Checks whether all sliderbar tooltips display an exact value. + /// + /// The expected value that should be displayed. + private bool checkExact(string value) + => intSliderBar.TooltipText == value + && floatSliderBar.TooltipText == value + && doubleSliderBar.TooltipText == value; + + /// + /// Checks whether all sliderbar tooltips display an exact value. + /// + /// The expected value that should be displayed. + private bool checkExact(decimal value) + { + var expectedDecimal = value.ToString(intSliderBar.Format); + + return intSliderBar.TooltipText == Convert.ToInt32(value).ToString("N0") + && floatSliderBar.TooltipText == expectedDecimal + && doubleSliderBar.TooltipText == expectedDecimal; + } + + /// + /// Checks whether all floating-point sliderbar tooltips have a certain number of decimal digits. + /// + /// The expected number of decimal digits. + private bool checkDecimalDigits(int decimals) + => checkDecimalDigits(decimals, floatSliderBar.TooltipText) + && checkDecimalDigits(decimals, doubleSliderBar.TooltipText); + + private bool checkDecimalDigits(int decimals, string value) + => value.Length - value.IndexOf(intSliderBar.Format.NumberDecimalSeparator, StringComparison.InvariantCulture) - 1 == decimals; + + private void setValue(T value) + { + intValue.Value = Convert.ToInt32(value); + floatValue.Value = Convert.ToSingle(value); + doubleValue.Value = Convert.ToDouble(value); + } + + private void setDecimalDigits(int digits) + { + intSliderBar.Format.NumberDecimalDigits = digits; + floatSliderBar.Format.NumberDecimalDigits = digits; + doubleSliderBar.Format.NumberDecimalDigits = digits; + + // Make sure that the text referenced in TestSliderBar is updated + // This doesn't break any assertions if missing, but breaks the visual display + intSliderBar.Current.TriggerChange(); + floatSliderBar.Current.TriggerChange(); + doubleSliderBar.Current.TriggerChange(); + } + + private class TestSliderBar : OsuSliderBar + where T : struct, IEquatable + { + public TestSliderBar() + { + SpriteText valueText; + AddInternal(valueText = new OsuSpriteText + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreLeft, + X = 5, + Text = TooltipText + }); + + Current.ValueChanged += v => valueText.Text = TooltipText; + } + } + } +} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 8c04874e75..53d971a0b3 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -132,6 +132,8 @@ + + From b84da31174403e3790d39d2afa92a742b8686742 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 2 Jan 2018 23:20:58 +0900 Subject: [PATCH 089/206] Change in-line with framework --- osu.Game/Overlays/OnScreenDisplay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index ce0feeb4c6..9a35551645 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -139,7 +139,7 @@ namespace osu.Game.Overlays private readonly List references = new List(); - private void trackSetting(Bindable bindable, Bindable.BindableValueChanged action) + private void trackSetting(Bindable bindable, Action action) { // we need to keep references as we bind references.Add(bindable); From 1571c10c4255213282df82ef686b77ea34900a85 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 5 Jan 2018 14:37:32 +0900 Subject: [PATCH 090/206] Fix up replay settings sliderbar formatting --- osu.Game/Overlays/Settings/SettingsSlider.cs | 13 +++++++++++-- .../Screens/Play/ReplaySettings/PlaybackSettings.cs | 1 + 2 files changed, 12 insertions(+), 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/SettingsSlider.cs b/osu.Game/Overlays/Settings/SettingsSlider.cs index 49d73f77ec..db6e5e3f2e 100644 --- a/osu.Game/Overlays/Settings/SettingsSlider.cs +++ b/osu.Game/Overlays/Settings/SettingsSlider.cs @@ -2,9 +2,9 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Globalization; using osu.Framework.Allocation; using osu.Framework.Graphics; -using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Settings @@ -16,7 +16,7 @@ namespace osu.Game.Overlays.Settings public class SettingsSlider : SettingsItem where T : struct, IEquatable - where U : SliderBar, new() + where U : OsuSliderBar, new() { protected override Drawable CreateControl() => new U { @@ -24,6 +24,15 @@ namespace osu.Game.Overlays.Settings RelativeSizeAxes = Axes.X }; + /// + /// The format that will be used for the tooltip when the sliderbar is hovered. + /// + public NumberFormatInfo Format + { + get => ((U)Control).Format; + set => ((U)Control).Format = value; + } + public float KeyboardStep; [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs b/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs index 3109552532..a7b03c3742 100644 --- a/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs +++ b/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs @@ -59,6 +59,7 @@ namespace osu.Game.Screens.Play.ReplaySettings } }; + sliderbar.Format.NumberDecimalDigits = 2; sliderbar.Bindable.ValueChanged += rateMultiplier => multiplierText.Text = $"{rateMultiplier}x"; } From d2b135d2a81545202b25a9d7e8a625318c1d9b85 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 5 Jan 2018 15:48:19 +0900 Subject: [PATCH 091/206] Give hitobjects lifetimes --- .../UI/Scrolling/ScrollingHitObjectContainer.cs | 13 ++++++++++++- 1 file changed, 12 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 4011e7ffd1..7382d46dec 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -29,11 +29,22 @@ namespace osu.Game.Rulesets.UI.Scrolling RelativeSizeAxes = Axes.Both; } + protected override bool UpdateChildrenLife() + { + foreach (var obj in Objects) + { + obj.LifetimeStart = obj.HitObject.StartTime - TimeRange - 1000; + obj.LifetimeEnd = ((obj.HitObject as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime + TimeRange) + 1000; + } + + return base.UpdateChildrenLife(); + } + protected override void UpdateAfterChildrenLife() { base.UpdateAfterChildrenLife(); - // We need to calculate this as soon as possible so that hitobjects + // We need to calculate this as soon as possible after lifetimes so that hitobjects // get the final say in their positions var currentMultiplier = controlPointAt(Time.Current); From 5d12682e83335bae9725465c46495bbe17c6457b Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 5 Jan 2018 20:17:02 +0900 Subject: [PATCH 092/206] Initial implementation of the new (old) mania scrolling calculations --- .../Scrolling/ScrollingHitObjectContainer.cs | 46 +++++++++---------- .../UI/Scrolling/ScrollingRulesetContainer.cs | 10 ++-- 2 files changed, 27 insertions(+), 29 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 7382d46dec..8c3e1162e3 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Lists; @@ -33,8 +34,8 @@ namespace osu.Game.Rulesets.UI.Scrolling { foreach (var obj in Objects) { - obj.LifetimeStart = obj.HitObject.StartTime - TimeRange - 1000; - obj.LifetimeEnd = ((obj.HitObject as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime + TimeRange) + 1000; + obj.LifetimeStart = obj.HitObject.StartTime - TimeRange * 2; + obj.LifetimeEnd = ((obj.HitObject as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime) + TimeRange * 2; } return base.UpdateChildrenLife(); @@ -47,27 +48,25 @@ namespace osu.Game.Rulesets.UI.Scrolling // We need to calculate this as soon as possible after lifetimes so that hitobjects // get the final say in their positions - var currentMultiplier = controlPointAt(Time.Current); + var timelinePosition = positionAt(Time.Current); foreach (var obj in AliveObjects) { - // Todo: We may need to consider scale here - var relativePosition = (Time.Current - obj.HitObject.StartTime) * currentMultiplier.Multiplier / TimeRange; - var finalPosition = (float)relativePosition * DrawSize; + var finalPosition = positionAt(obj.HitObject.StartTime); switch (direction) { case ScrollingDirection.Up: - obj.Y = -finalPosition.Y; + obj.Y = finalPosition.Y - timelinePosition.Y; break; case ScrollingDirection.Down: - obj.Y = finalPosition.Y; + obj.Y = -finalPosition.Y + timelinePosition.Y; break; case ScrollingDirection.Left: - obj.X = -finalPosition.X; + obj.X = finalPosition.X - timelinePosition.X; break; case ScrollingDirection.Right: - obj.X = finalPosition.X; + obj.X = -finalPosition.X + timelinePosition.X; break; } @@ -75,8 +74,7 @@ namespace osu.Game.Rulesets.UI.Scrolling continue; // Todo: We may need to consider scale here - var relativeEndPosition = (Time.Current - endTime.EndTime) * currentMultiplier.Multiplier / TimeRange; - var finalEndPosition = (float)relativeEndPosition * DrawSize; + var finalEndPosition = positionAt(endTime.EndTime); float length = Vector2.Distance(finalPosition, finalEndPosition); @@ -94,22 +92,24 @@ namespace osu.Game.Rulesets.UI.Scrolling } } - private readonly MultiplierControlPoint searchingPoint = new MultiplierControlPoint(); - private MultiplierControlPoint controlPointAt(double time) + private Vector2 positionAt(double time) { - if (ControlPoints.Count == 0) - return new MultiplierControlPoint(double.MinValue); + float length = 0; + for (int i = 0; i < ControlPoints.Count; i++) + { + var current = ControlPoints[i]; + var next = i < ControlPoints.Count - 1 ? ControlPoints[i + 1] : null; - if (time < ControlPoints[0].StartTime) - return ControlPoints[0]; + if (i > 0 && current.StartTime > time) + continue; - searchingPoint.StartTime = time; + // Duration of the current control point + var currentDuration = (next?.StartTime ?? double.PositiveInfinity) - current.StartTime; - int index = ControlPoints.BinarySearch(searchingPoint); - if (index < 0) - index = ~index - 1; + length += (float)(Math.Min(currentDuration, time - current.StartTime) * current.Multiplier / TimeRange); + } - return ControlPoints[index]; + return length * DrawSize; } } } diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs index 73c3848f69..418013bcc1 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs @@ -70,12 +70,10 @@ namespace osu.Game.Rulesets.UI.Scrolling // Perform some post processing of the timing changes timingChanges = timingChanges - // Collapse sections after the last hit object - .Where(s => s.StartTime <= lastObjectTime) - // Collapse sections with the same start time - .GroupBy(s => s.StartTime).Select(g => g.Last()).OrderBy(s => s.StartTime) - // Collapse sections with the same beat length - .GroupBy(s => s.TimingPoint.BeatLength * s.DifficultyPoint.SpeedMultiplier).Select(g => g.First()); + // Collapse sections after the last hit object + .Where(s => s.StartTime <= lastObjectTime) + // Collapse sections with the same start time + .GroupBy(s => s.StartTime).Select(g => g.Last()).OrderBy(s => s.StartTime); DefaultControlPoints.AddRange(timingChanges); From 7526225282f8aa912e51bb7b1a5fa23af8f07260 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 5 Jan 2018 20:56:21 +0900 Subject: [PATCH 093/206] Use DP for most of the code to avoid unnecessary computations --- .../Visual/TestCaseScrollingHitObjects.cs | 11 +- .../Scrolling/ScrollingHitObjectContainer.cs | 105 ++++++++++++------ .../UI/Scrolling/ScrollingRulesetContainer.cs | 2 +- 3 files changed, 79 insertions(+), 39 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index 7e332c7310..591bf4fadd 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -28,7 +28,7 @@ namespace osu.Game.Tests.Visual playfields.Add(new TestPlayfield(ScrollingDirection.Down)); playfields.Add(new TestPlayfield(ScrollingDirection.Right)); - playfields.ForEach(p => p.HitObjects.ControlPoints.Add(new MultiplierControlPoint(double.MinValue))); + playfields.ForEach(p => p.HitObjects.AddControlPoint(new MultiplierControlPoint(double.MinValue))); Add(new Container { @@ -82,12 +82,9 @@ namespace osu.Game.Tests.Visual { playfields.ForEach(p => { - p.HitObjects.ControlPoints.AddRange(new[] - { - new MultiplierControlPoint(time) { DifficultyPoint = { SpeedMultiplier = 3 } }, - new MultiplierControlPoint(time + 2000) { DifficultyPoint = { SpeedMultiplier = 2 } }, - new MultiplierControlPoint(time + 3000) { DifficultyPoint = { SpeedMultiplier = 1 } }, - }); + p.HitObjects.AddControlPoint(new MultiplierControlPoint(time) { DifficultyPoint = { SpeedMultiplier = 3 } }); + p.HitObjects.AddControlPoint(new MultiplierControlPoint(time + 2000) { DifficultyPoint = { SpeedMultiplier = 2 } }); + p.HitObjects.AddControlPoint(new MultiplierControlPoint(time + 3000) { DifficultyPoint = { SpeedMultiplier = 1 } }); TestDrawableControlPoint createDrawablePoint(double t) => new TestDrawableControlPoint(t) { diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 8c3e1162e3..7bd5ab8f10 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -2,9 +2,12 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; +using osu.Framework.Caching; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Lists; +using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; using OpenTK; @@ -19,26 +22,86 @@ namespace osu.Game.Rulesets.UI.Scrolling MaxValue = double.MaxValue }; - public readonly SortedList ControlPoints = new SortedList(); - private readonly ScrollingDirection direction; + private Cached positionCache = new Cached(); + public ScrollingHitObjectContainer(ScrollingDirection direction) { this.direction = direction; RelativeSizeAxes = Axes.Both; + + TimeRange.ValueChanged += v => positionCache.Invalidate(); } - protected override bool UpdateChildrenLife() + public override void Add(DrawableHitObject hitObject) { + positionCache.Invalidate(); + base.Add(hitObject); + } + + public override bool Remove(DrawableHitObject hitObject) + { + var result = base.Remove(hitObject); + if (result) + positionCache.Invalidate(); + return result; + } + + private readonly SortedList controlPoints = new SortedList(); + + public void AddControlPoint(MultiplierControlPoint controlPoint) + { + controlPoints.Add(controlPoint); + positionCache.Invalidate(); + } + + public bool RemoveControlPoint(MultiplierControlPoint controlPoint) + { + var result = controlPoints.Remove(controlPoint); + if (result) + positionCache.Invalidate(); + return result; + } + + private readonly Dictionary hitObjectPositions = new Dictionary(); + + protected override void Update() + { + base.Update(); + + if (positionCache.IsValid) + return; + foreach (var obj in Objects) { - obj.LifetimeStart = obj.HitObject.StartTime - TimeRange * 2; - obj.LifetimeEnd = ((obj.HitObject as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime) + TimeRange * 2; + var startPosition = hitObjectPositions[obj] = positionAt(obj.HitObject.StartTime); + + obj.LifetimeStart = obj.HitObject.StartTime - TimeRange - 1000; + obj.LifetimeEnd = ((obj.HitObject as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime) + TimeRange + 1000; + + if (!(obj.HitObject is IHasEndTime endTime)) + continue; + + var endPosition = positionAt(endTime.EndTime); + + float length = Vector2.Distance(startPosition, endPosition); + + switch (direction) + { + case ScrollingDirection.Up: + case ScrollingDirection.Down: + obj.Height = length; + break; + case ScrollingDirection.Left: + case ScrollingDirection.Right: + obj.Width = length; + break; + } } - return base.UpdateChildrenLife(); + positionCache.Validate(); } protected override void UpdateAfterChildrenLife() @@ -52,7 +115,7 @@ namespace osu.Game.Rulesets.UI.Scrolling foreach (var obj in AliveObjects) { - var finalPosition = positionAt(obj.HitObject.StartTime); + var finalPosition = hitObjectPositions[obj]; switch (direction) { @@ -69,36 +132,16 @@ namespace osu.Game.Rulesets.UI.Scrolling obj.X = -finalPosition.X + timelinePosition.X; break; } - - if (!(obj.HitObject is IHasEndTime endTime)) - continue; - - // Todo: We may need to consider scale here - var finalEndPosition = positionAt(endTime.EndTime); - - float length = Vector2.Distance(finalPosition, finalEndPosition); - - switch (direction) - { - case ScrollingDirection.Up: - case ScrollingDirection.Down: - obj.Height = length; - break; - case ScrollingDirection.Left: - case ScrollingDirection.Right: - obj.Width = length; - break; - } } } private Vector2 positionAt(double time) { - float length = 0; - for (int i = 0; i < ControlPoints.Count; i++) + double length = 0; + for (int i = 0; i < controlPoints.Count; i++) { - var current = ControlPoints[i]; - var next = i < ControlPoints.Count - 1 ? ControlPoints[i + 1] : null; + var current = controlPoints[i]; + var next = i < controlPoints.Count - 1 ? controlPoints[i + 1] : null; if (i > 0 && current.StartTime > time) continue; diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs index 418013bcc1..8990710a9d 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.UI.Scrolling private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield) { - playfield.HitObjects.ControlPoints.Add(controlPoint); + playfield.HitObjects.AddControlPoint(controlPoint); playfield.NestedPlayfields.ForEach(p => applySpeedAdjustment(controlPoint, p)); } From c9692a44f9b044a2100d7a86b250b2aa7f9c0bfe Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 5 Jan 2018 21:04:21 +0900 Subject: [PATCH 094/206] Fix framework licence headers in osu project --- osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs | 2 +- osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs b/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs index 5c4d545348..ce32dbe889 100644 --- a/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs +++ b/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using System.Collections.Generic; diff --git a/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs b/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs index 928ba0d825..c4b3a63bf2 100644 --- a/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs +++ b/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using System.Collections.Generic; From 140a09ba3db8efb7faddd2043285b435356a4dad Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Fri, 5 Jan 2018 19:13:54 +0100 Subject: [PATCH 095/206] fix requests not cancelling properly + formatting --- .../Screens/Select/Leaderboards/Leaderboard.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs index 6c0301f01f..6be6523175 100644 --- a/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs +++ b/osu.Game/Screens/Select/Leaderboards/Leaderboard.cs @@ -93,7 +93,8 @@ namespace osu.Game.Screens.Select.Leaderboards get { return scope; } set { - if (value == scope) return; + if (value == scope) + return; scope = value; updateScores(); @@ -107,8 +108,6 @@ namespace osu.Game.Screens.Select.Leaderboards get { return placeholderState; } set { - if (value == placeholderState) return; - if (value != PlaceholderState.Successful) { getScoresRequest?.Cancel(); @@ -116,6 +115,9 @@ namespace osu.Game.Screens.Select.Leaderboards Scores = null; } + if (value == placeholderState) + return; + switch (placeholderState = value) { case PlaceholderState.NetworkFailure: @@ -171,7 +173,8 @@ namespace osu.Game.Screens.Select.Leaderboards get { return beatmap; } set { - if (beatmap == value) return; + if (beatmap == value) + return; beatmap = value; Scores = null; @@ -259,7 +262,8 @@ namespace osu.Game.Screens.Select.Leaderboards private void onUpdateFailed(Exception e) { - if (e is OperationCanceledException) return; + if (e is OperationCanceledException) + return; PlaceholderState = PlaceholderState.NetworkFailure; Logger.Error(e, @"Couldn't fetch beatmap scores!"); @@ -294,7 +298,8 @@ namespace osu.Game.Screens.Select.Leaderboards if (!scrollContainer.IsScrolledToEnd()) fadeStart -= LeaderboardScore.HEIGHT; - if (scrollFlow == null) return; + if (scrollFlow == null) + return; foreach (var c in scrollFlow.Children) { From 57b44b8c29808fca00a10b4766ea7ebed6b1ed2a Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 6 Jan 2018 10:40:18 +0100 Subject: [PATCH 096/206] fix new panels appearing too soon --- osu.Game/Overlays/SocialOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 823e264ebe..fb111a64d2 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -153,7 +153,7 @@ namespace osu.Game.Overlays if(panels != null) ScrollFlow.Remove(panels); - ScrollFlow.Add(panels = newPanels); + Scheduler.AddDelayed(() => ScrollFlow.Add(panels = newPanels), 200); }); } From 82dcb033deaaee2bacc2476b01da2812b46217e1 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 6 Jan 2018 10:47:56 +0100 Subject: [PATCH 097/206] update submodules --- osu-framework | 2 +- osu-resources | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu-framework b/osu-framework index 66421b8944..80bcb82ef8 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 66421b894444cb9c4b792f9b93a786dcff5589dd +Subproject commit 80bcb82ef8d2e1af1ce077f4a037b6d279ad9e74 diff --git a/osu-resources b/osu-resources index e01f71160f..7724abdf1d 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit e01f71160fb9b3167efcd177c7d7dba9e5d36604 +Subproject commit 7724abdf1d7c9705ba2e3989a9c604e17ccdc871 From a61666d2a732727317f22290a3c85f02b2067440 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 6 Jan 2018 10:54:53 +0100 Subject: [PATCH 098/206] update licence headers --- osu.Game/Online/API/Requests/GetFriendsRequest.cs | 2 +- osu.Game/Overlays/Social/SocialGridPanel.cs | 2 +- osu.Game/Overlays/Social/SocialListPanel.cs | 2 +- osu.Game/Overlays/Social/SocialPanel.cs | 2 +- 4 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Online/API/Requests/GetFriendsRequest.cs b/osu.Game/Online/API/Requests/GetFriendsRequest.cs index a06471fd74..5bc3d8e39e 100644 --- a/osu.Game/Online/API/Requests/GetFriendsRequest.cs +++ b/osu.Game/Online/API/Requests/GetFriendsRequest.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; diff --git a/osu.Game/Overlays/Social/SocialGridPanel.cs b/osu.Game/Overlays/Social/SocialGridPanel.cs index b2c6b75ab2..f9fbce123d 100644 --- a/osu.Game/Overlays/Social/SocialGridPanel.cs +++ b/osu.Game/Overlays/Social/SocialGridPanel.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Game.Users; diff --git a/osu.Game/Overlays/Social/SocialListPanel.cs b/osu.Game/Overlays/Social/SocialListPanel.cs index f65fbe8142..0f102005d6 100644 --- a/osu.Game/Overlays/Social/SocialListPanel.cs +++ b/osu.Game/Overlays/Social/SocialListPanel.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; diff --git a/osu.Game/Overlays/Social/SocialPanel.cs b/osu.Game/Overlays/Social/SocialPanel.cs index 234640482e..2e0b7e6df2 100644 --- a/osu.Game/Overlays/Social/SocialPanel.cs +++ b/osu.Game/Overlays/Social/SocialPanel.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using OpenTK; From d9866a2052b5bbcc42d8537b754cc3f9e19521c6 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 6 Jan 2018 11:27:17 +0100 Subject: [PATCH 099/206] fix hover effects on social panels --- osu.Game/Overlays/Social/SocialPanel.cs | 8 +- osu.Game/Users/UserPanel.cs | 212 ++++++++++++------------ 2 files changed, 114 insertions(+), 106 deletions(-) diff --git a/osu.Game/Overlays/Social/SocialPanel.cs b/osu.Game/Overlays/Social/SocialPanel.cs index 2e0b7e6df2..54fb88f929 100644 --- a/osu.Game/Overlays/Social/SocialPanel.cs +++ b/osu.Game/Overlays/Social/SocialPanel.cs @@ -37,16 +37,16 @@ namespace osu.Game.Overlays.Social protected override bool OnHover(InputState state) { - TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint); - //Content.MoveToY(-4, hover_transition_time, Easing.OutQuint); + Content.TweenEdgeEffectTo(edgeEffectHovered, hover_transition_time, Easing.OutQuint); + Content.MoveToY(-4, hover_transition_time, Easing.OutQuint); return base.OnHover(state); } protected override void OnHoverLost(InputState state) { - TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint); - //Content.MoveToY(0, hover_transition_time, Easing.OutQuint); + Content.TweenEdgeEffectTo(edgeEffectNormal, hover_transition_time, Easing.OutQuint); + Content.MoveToY(0, hover_transition_time, Easing.OutQuint); base.OnHoverLost(state); } diff --git a/osu.Game/Users/UserPanel.cs b/osu.Game/Users/UserPanel.cs index 839c62ea40..c62ba392b8 100644 --- a/osu.Game/Users/UserPanel.cs +++ b/osu.Game/Users/UserPanel.cs @@ -28,9 +28,12 @@ namespace osu.Game.Users private const float content_padding = 10; private const float status_height = 30; - private readonly Container statusBar; - private readonly Box statusBg; - private readonly OsuSpriteText statusMessage; + private Container statusBar; + private Box statusBg; + private OsuSpriteText statusMessage; + + private Container content; + protected override Container Content => content; public readonly Bindable Status = new Bindable(); @@ -45,126 +48,138 @@ namespace osu.Game.Users this.user = user; + Height = height - status_height; + } + + [BackgroundDependencyLoader(permitNulls: true)] + private void load(OsuColour colours, UserProfileOverlay profile) + { + if (colours == null) + throw new ArgumentNullException(nameof(colours)); + FillFlowContainer infoContainer; - Height = height - status_height; - Masking = true; - CornerRadius = 5; - EdgeEffect = new EdgeEffectParameters + AddInternal(content = new Container { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.25f), - Radius = 4, - }; - - Children = new Drawable[] - { - new DelayedLoadWrapper(new UserCoverBackground(user) + RelativeSizeAxes = Axes.Both, + Masking = true, + CornerRadius = 5, + EdgeEffect = new EdgeEffectParameters { - RelativeSizeAxes = Axes.Both, - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - FillMode = FillMode.Fill, - OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out) - }, 300) { RelativeSizeAxes = Axes.Both }, - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4.Black.Opacity(0.7f), + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.25f), + Radius = 4, }, - new Container + + Children = new Drawable[] { - RelativeSizeAxes = Axes.X, - AutoSizeAxes = Axes.Y, - Padding = new MarginPadding { Top = content_padding, Horizontal = content_padding }, - Children = new Drawable[] + new DelayedLoadWrapper(new UserCoverBackground(user) { - new UpdateableAvatar + RelativeSizeAxes = Axes.Both, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + FillMode = FillMode.Fill, + OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out) + }, 300) { RelativeSizeAxes = Axes.Both }, + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4.Black.Opacity(0.7f), + }, + new Container + { + RelativeSizeAxes = Axes.X, + AutoSizeAxes = Axes.Y, + Padding = new MarginPadding { Top = content_padding, Horizontal = content_padding }, + Children = new Drawable[] { - Size = new Vector2(height - status_height - content_padding * 2), - User = user, - Masking = true, - CornerRadius = 5, - EdgeEffect = new EdgeEffectParameters + new UpdateableAvatar { - Type = EdgeEffectType.Shadow, - Colour = Color4.Black.Opacity(0.25f), - Radius = 4, - }, - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = height - status_height - content_padding }, - Children = new Drawable[] - { - new OsuSpriteText + Size = new Vector2(height - status_height - content_padding * 2), + User = user, + Masking = true, + CornerRadius = 5, + EdgeEffect = new EdgeEffectParameters { - Text = user.Username, - TextSize = 18, - Font = @"Exo2.0-SemiBoldItalic", + Type = EdgeEffectType.Shadow, + Colour = Color4.Black.Opacity(0.25f), + Radius = 4, }, - infoContainer = new FillFlowContainer + }, + new Container + { + RelativeSizeAxes = Axes.Both, + Padding = new MarginPadding { Left = height - status_height - content_padding }, + Children = new Drawable[] { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - AutoSizeAxes = Axes.X, - Height = 20f, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(5f, 0f), - Children = new Drawable[] + new OsuSpriteText { - new DrawableFlag(user.Country) + Text = user.Username, + TextSize = 18, + Font = @"Exo2.0-SemiBoldItalic", + }, + infoContainer = new FillFlowContainer + { + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + AutoSizeAxes = Axes.X, + Height = 20f, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(5f, 0f), + Children = new Drawable[] { - Width = 30f, - RelativeSizeAxes = Axes.Y, + new DrawableFlag(user.Country) + { + Width = 30f, + RelativeSizeAxes = Axes.Y, + }, }, }, }, }, }, }, - }, - statusBar = new Container - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft, - RelativeSizeAxes = Axes.X, - Alpha = 0f, - Children = new Drawable[] + statusBar = new Container { - statusBg = new Box + Anchor = Anchor.BottomLeft, + Origin = Anchor.BottomLeft, + RelativeSizeAxes = Axes.X, + Alpha = 0f, + Children = new Drawable[] { - RelativeSizeAxes = Axes.Both, - Alpha = 0.5f, - }, - new FillFlowContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - AutoSizeAxes = Axes.Both, - Spacing = new Vector2(5f, 0f), - Children = new Drawable[] + statusBg = new Box { - new SpriteIcon + RelativeSizeAxes = Axes.Both, + Alpha = 0.5f, + }, + new FillFlowContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + AutoSizeAxes = Axes.Both, + Spacing = new Vector2(5f, 0f), + Children = new Drawable[] { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Icon = FontAwesome.fa_circle_o, - Shadow = true, - Size = new Vector2(14), - }, - statusMessage = new OsuSpriteText - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - Font = @"Exo2.0-Semibold", + new SpriteIcon + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Icon = FontAwesome.fa_circle_o, + Shadow = true, + Size = new Vector2(14), + }, + statusMessage = new OsuSpriteText + { + Anchor = Anchor.CentreLeft, + Origin = Anchor.CentreLeft, + Font = @"Exo2.0-Semibold", + }, }, }, }, }, - }, - }; + } + }); if (user.IsSupporter) { @@ -174,13 +189,6 @@ namespace osu.Game.Users Width = 20f, }); } - } - - [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuColour colours, UserProfileOverlay profile) - { - if (colours == null) - throw new ArgumentNullException(nameof(colours)); Status.ValueChanged += displayStatus; Status.ValueChanged += status => statusBg.FadeColour(status?.GetAppropriateColour(colours) ?? colours.Gray5, 500, Easing.OutQuint); From 98fd4f6ff2afae42c569efcb886738e193c06932 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sun, 7 Jan 2018 11:33:59 +0900 Subject: [PATCH 100/206] Fix up precision + sizing issues --- .../Scrolling/ScrollingHitObjectContainer.cs | 35 +++++++++++-------- 1 file changed, 20 insertions(+), 15 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 7bd5ab8f10..e0df4321a8 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -10,7 +10,6 @@ using osu.Framework.Lists; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; -using OpenTK; namespace osu.Game.Rulesets.UI.Scrolling { @@ -65,7 +64,15 @@ namespace osu.Game.Rulesets.UI.Scrolling return result; } - private readonly Dictionary hitObjectPositions = new Dictionary(); + public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) + { + if ((invalidation & (Invalidation.RequiredParentSizeToFit | Invalidation.DrawInfo)) > 0) + positionCache.Invalidate(); + + return base.Invalidate(invalidation, source, shallPropagate); + } + + private readonly Dictionary hitObjectPositions = new Dictionary(); protected override void Update() { @@ -84,19 +91,17 @@ namespace osu.Game.Rulesets.UI.Scrolling if (!(obj.HitObject is IHasEndTime endTime)) continue; - var endPosition = positionAt(endTime.EndTime); - - float length = Vector2.Distance(startPosition, endPosition); + var length = positionAt(endTime.EndTime) - startPosition; switch (direction) { case ScrollingDirection.Up: case ScrollingDirection.Down: - obj.Height = length; + obj.Height = (float)(length * DrawHeight); break; case ScrollingDirection.Left: case ScrollingDirection.Right: - obj.Width = length; + obj.Width = (float)(length * DrawWidth); break; } } @@ -115,27 +120,27 @@ namespace osu.Game.Rulesets.UI.Scrolling foreach (var obj in AliveObjects) { - var finalPosition = hitObjectPositions[obj]; + var finalPosition = hitObjectPositions[obj] - timelinePosition; switch (direction) { case ScrollingDirection.Up: - obj.Y = finalPosition.Y - timelinePosition.Y; + obj.Y = (float)(finalPosition * DrawHeight); break; case ScrollingDirection.Down: - obj.Y = -finalPosition.Y + timelinePosition.Y; + obj.Y = (float)(-finalPosition * DrawHeight); break; case ScrollingDirection.Left: - obj.X = finalPosition.X - timelinePosition.X; + obj.X = (float)(finalPosition * DrawWidth); break; case ScrollingDirection.Right: - obj.X = -finalPosition.X + timelinePosition.X; + obj.X = (float)(-finalPosition * DrawWidth); break; } } } - private Vector2 positionAt(double time) + private double positionAt(double time) { double length = 0; for (int i = 0; i < controlPoints.Count; i++) @@ -149,10 +154,10 @@ namespace osu.Game.Rulesets.UI.Scrolling // Duration of the current control point var currentDuration = (next?.StartTime ?? double.PositiveInfinity) - current.StartTime; - length += (float)(Math.Min(currentDuration, time - current.StartTime) * current.Multiplier / TimeRange); + length += Math.Min(currentDuration, time - current.StartTime) * current.Multiplier / TimeRange; } - return length * DrawSize; + return length; } } } From 2d345b2f80e88eebdecb1847fd0ae1203c31a2f2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sun, 7 Jan 2018 11:43:31 +0900 Subject: [PATCH 101/206] Fix mania hold note tick positioning --- .../Objects/Drawables/DrawableHoldNoteTick.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 8ed5d2b924..68f6721694 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -32,6 +32,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; + RelativePositionAxes = Axes.Y; Y = (float)HitObject.StartTime; RelativeSizeAxes = Axes.X; From f660eff4d491d3633796f41943c2d7ec14395016 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 7 Jan 2018 11:57:33 +0900 Subject: [PATCH 102/206] FIx incorrect licence header template --- osu.sln.DotSettings | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings index 20007e3306..8767e5374a 100644 --- a/osu.sln.DotSettings +++ b/osu.sln.DotSettings @@ -598,7 +598,7 @@ </TypePattern> </Patterns> Copyright (c) 2007-$CURRENT_YEAR$ ppy Pty Ltd <contact@ppy.sh>. -Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" /> <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" /> From 117ab8a26d32c5277cb1c585c73fdc726d0f1d38 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sun, 7 Jan 2018 12:47:09 +0900 Subject: [PATCH 103/206] Split out scrolling algorithm --- .../Visual/TestCaseScrollingHitObjects.cs | 6 +- osu.Game/Rulesets/UI/HitObjectContainer.cs | 19 +++ osu.Game/Rulesets/UI/Playfield.cs | 22 ++-- .../Algorithms/GlobalScrollingAlgorithm.cs | 98 +++++++++++++++ .../Algorithms/IScrollingAlgorithm.cs | 15 +++ .../GlobalScrollingHitObjectContainer.cs | 17 +++ .../Scrolling/ScrollingHitObjectContainer.cs | 115 +++++------------- .../UI/Scrolling/ScrollingPlayfield.cs | 16 ++- osu.Game/osu.Game.csproj | 4 + 9 files changed, 205 insertions(+), 107 deletions(-) create mode 100644 osu.Game/Rulesets/UI/HitObjectContainer.cs create mode 100644 osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs create mode 100644 osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs create mode 100644 osu.Game/Rulesets/UI/Scrolling/GlobalScrollingHitObjectContainer.cs diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index 591bf4fadd..4f2e895e9d 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -99,19 +99,17 @@ namespace osu.Game.Tests.Visual - private class TestPlayfield : Playfield + private class TestPlayfield : ScrollingPlayfield { public readonly BindableDouble TimeRange = new BindableDouble(5000); public readonly ScrollingDirection Direction; - public new ScrollingHitObjectContainer HitObjects => (ScrollingHitObjectContainer)base.HitObjects; - public TestPlayfield(ScrollingDirection direction) + : base(direction) { Direction = direction; - base.HitObjects = new ScrollingHitObjectContainer(direction); HitObjects.TimeRange.BindTo(TimeRange); } } diff --git a/osu.Game/Rulesets/UI/HitObjectContainer.cs b/osu.Game/Rulesets/UI/HitObjectContainer.cs new file mode 100644 index 0000000000..e7843c86ca --- /dev/null +++ b/osu.Game/Rulesets/UI/HitObjectContainer.cs @@ -0,0 +1,19 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using System.Collections.Generic; +using System.Linq; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.UI +{ + public class HitObjectContainer : CompositeDrawable + { + public virtual IEnumerable Objects => InternalChildren.Cast(); + public virtual IEnumerable AliveObjects => AliveInternalChildren.Cast(); + + public virtual void Add(DrawableHitObject hitObject) => AddInternal(hitObject); + public virtual bool Remove(DrawableHitObject hitObject) => RemoveInternal(hitObject); + } +} diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 61014b5550..91ea3ade2a 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -8,8 +8,6 @@ using osu.Game.Rulesets.Objects.Drawables; using OpenTK; using osu.Game.Rulesets.Judgements; using osu.Framework.Allocation; -using System.Collections.Generic; -using System.Linq; namespace osu.Game.Rulesets.UI { @@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.UI /// /// The HitObjects contained in this Playfield. /// - public HitObjectContainer HitObjects { get; protected set; } + public readonly HitObjectContainer HitObjects; public Container ScaledContent; @@ -52,10 +50,8 @@ namespace osu.Game.Rulesets.UI } }); - HitObjects = new HitObjectContainer - { - RelativeSizeAxes = Axes.Both, - }; + HitObjects = CreateHitObjectContainer(); + HitObjects.RelativeSizeAxes = Axes.Both; } [BackgroundDependencyLoader] @@ -94,14 +90,10 @@ namespace osu.Game.Rulesets.UI /// The that occurred. public virtual void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { } - public class HitObjectContainer : CompositeDrawable - { - public virtual IEnumerable Objects => InternalChildren.Cast(); - public virtual IEnumerable AliveObjects => AliveInternalChildren.Cast(); - - public virtual void Add(DrawableHitObject hitObject) => AddInternal(hitObject); - public virtual bool Remove(DrawableHitObject hitObject) => RemoveInternal(hitObject); - } + /// + /// Creates the container that will be used to contain the s. + /// + protected virtual HitObjectContainer CreateHitObjectContainer() => new HitObjectContainer(); private class ScaledContainer : Container { diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs new file mode 100644 index 0000000000..0a69d00377 --- /dev/null +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs @@ -0,0 +1,98 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using System; +using System.Collections.Generic; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Timing; +using OpenTK; + +namespace osu.Game.Rulesets.UI.Scrolling.Algorithms +{ + public class GlobalScrollingAlgorithm : IScrollingAlgorithm + { + private readonly Dictionary hitObjectPositions = new Dictionary(); + + private readonly IReadOnlyList controlPoints; + + public GlobalScrollingAlgorithm(IReadOnlyList controlPoints) + { + this.controlPoints = controlPoints; + } + + public void ComputeInitialStates(IEnumerable hitObjects, ScrollingDirection direction, double timeRange, Vector2 length) + { + foreach (var obj in hitObjects) + { + var startPosition = hitObjectPositions[obj] = positionAt(obj.HitObject.StartTime, timeRange); + + obj.LifetimeStart = obj.HitObject.StartTime - timeRange - 1000; + obj.LifetimeEnd = ((obj.HitObject as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime) + timeRange + 1000; + + if (!(obj.HitObject is IHasEndTime endTime)) + continue; + + var diff = positionAt(endTime.EndTime, timeRange) - startPosition; + + switch (direction) + { + case ScrollingDirection.Up: + case ScrollingDirection.Down: + obj.Height = (float)(diff * length.Y); + break; + case ScrollingDirection.Left: + case ScrollingDirection.Right: + obj.Width = (float)(diff * length.X); + break; + } + } + } + + public void ComputePositions(IEnumerable hitObjects, ScrollingDirection direction, double currentTime, double timeRange, Vector2 length) + { + var timelinePosition = positionAt(currentTime, timeRange); + + foreach (var obj in hitObjects) + { + var finalPosition = hitObjectPositions[obj] - timelinePosition; + + switch (direction) + { + case ScrollingDirection.Up: + obj.Y = (float)(finalPosition * length.Y); + break; + case ScrollingDirection.Down: + obj.Y = (float)(-finalPosition * length.Y); + break; + case ScrollingDirection.Left: + obj.X = (float)(finalPosition * length.X); + break; + case ScrollingDirection.Right: + obj.X = (float)(-finalPosition * length.X); + break; + } + } + } + + private double positionAt(double time, double timeRange) + { + double length = 0; + for (int i = 0; i < controlPoints.Count; i++) + { + var current = controlPoints[i]; + var next = i < controlPoints.Count - 1 ? controlPoints[i + 1] : null; + + if (i > 0 && current.StartTime > time) + continue; + + // Duration of the current control point + var currentDuration = (next?.StartTime ?? double.PositiveInfinity) - current.StartTime; + + length += Math.Min(currentDuration, time - current.StartTime) * current.Multiplier / timeRange; + } + + return length; + } + } +} diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs new file mode 100644 index 0000000000..2621ae7d6f --- /dev/null +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Rulesets.Objects.Drawables; +using OpenTK; + +namespace osu.Game.Rulesets.UI.Scrolling.Algorithms +{ + public interface IScrollingAlgorithm + { + void ComputeInitialStates(IEnumerable hitObjects, ScrollingDirection direction, double timeRange, Vector2 length); + void ComputePositions(IEnumerable hitObjects, ScrollingDirection direction, double currentTime, double timeRange, Vector2 length); + } +} diff --git a/osu.Game/Rulesets/UI/Scrolling/GlobalScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/GlobalScrollingHitObjectContainer.cs new file mode 100644 index 0000000000..23dff01940 --- /dev/null +++ b/osu.Game/Rulesets/UI/Scrolling/GlobalScrollingHitObjectContainer.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using osu.Game.Rulesets.UI.Scrolling.Algorithms; + +namespace osu.Game.Rulesets.UI.Scrolling +{ + public class GlobalScrollingHitObjectContainer : ScrollingHitObjectContainer + { + public GlobalScrollingHitObjectContainer(ScrollingDirection direction) + : base(direction) + { + } + + protected override IScrollingAlgorithm CreateScrollingAlgorithm() => new GlobalScrollingAlgorithm(ControlPoints); + } +} diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index e0df4321a8..e1d8fe8d59 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -1,19 +1,17 @@ // Copyright (c) 2007-2017 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.Caching; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Lists; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; +using osu.Game.Rulesets.UI.Scrolling.Algorithms; namespace osu.Game.Rulesets.UI.Scrolling { - public class ScrollingHitObjectContainer : Playfield.HitObjectContainer + public abstract class ScrollingHitObjectContainer : HitObjectContainer { public readonly BindableDouble TimeRange = new BindableDouble { @@ -21,22 +19,32 @@ namespace osu.Game.Rulesets.UI.Scrolling MaxValue = double.MaxValue }; + protected readonly SortedList ControlPoints = new SortedList(); + private readonly ScrollingDirection direction; - private Cached positionCache = new Cached(); + private Cached initialStateCache = new Cached(); - public ScrollingHitObjectContainer(ScrollingDirection direction) + protected ScrollingHitObjectContainer(ScrollingDirection direction) { this.direction = direction; RelativeSizeAxes = Axes.Both; - TimeRange.ValueChanged += v => positionCache.Invalidate(); + TimeRange.ValueChanged += v => initialStateCache.Invalidate(); + } + + private IScrollingAlgorithm scrollingAlgorithm; + protected override void LoadComplete() + { + base.LoadComplete(); + + scrollingAlgorithm = CreateScrollingAlgorithm(); } public override void Add(DrawableHitObject hitObject) { - positionCache.Invalidate(); + initialStateCache.Invalidate(); base.Add(hitObject); } @@ -44,69 +52,42 @@ namespace osu.Game.Rulesets.UI.Scrolling { var result = base.Remove(hitObject); if (result) - positionCache.Invalidate(); + initialStateCache.Invalidate(); return result; } - private readonly SortedList controlPoints = new SortedList(); - public void AddControlPoint(MultiplierControlPoint controlPoint) { - controlPoints.Add(controlPoint); - positionCache.Invalidate(); + ControlPoints.Add(controlPoint); + initialStateCache.Invalidate(); } public bool RemoveControlPoint(MultiplierControlPoint controlPoint) { - var result = controlPoints.Remove(controlPoint); + var result = ControlPoints.Remove(controlPoint); if (result) - positionCache.Invalidate(); + initialStateCache.Invalidate(); return result; } public override bool Invalidate(Invalidation invalidation = Invalidation.All, Drawable source = null, bool shallPropagate = true) { if ((invalidation & (Invalidation.RequiredParentSizeToFit | Invalidation.DrawInfo)) > 0) - positionCache.Invalidate(); + initialStateCache.Invalidate(); return base.Invalidate(invalidation, source, shallPropagate); } - private readonly Dictionary hitObjectPositions = new Dictionary(); - protected override void Update() { base.Update(); - if (positionCache.IsValid) + if (initialStateCache.IsValid) return; - foreach (var obj in Objects) - { - var startPosition = hitObjectPositions[obj] = positionAt(obj.HitObject.StartTime); + scrollingAlgorithm.ComputeInitialStates(Objects, direction, TimeRange, DrawSize); - obj.LifetimeStart = obj.HitObject.StartTime - TimeRange - 1000; - obj.LifetimeEnd = ((obj.HitObject as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime) + TimeRange + 1000; - - if (!(obj.HitObject is IHasEndTime endTime)) - continue; - - var length = positionAt(endTime.EndTime) - startPosition; - - switch (direction) - { - case ScrollingDirection.Up: - case ScrollingDirection.Down: - obj.Height = (float)(length * DrawHeight); - break; - case ScrollingDirection.Left: - case ScrollingDirection.Right: - obj.Width = (float)(length * DrawWidth); - break; - } - } - - positionCache.Validate(); + initialStateCache.Validate(); } protected override void UpdateAfterChildrenLife() @@ -116,48 +97,12 @@ namespace osu.Game.Rulesets.UI.Scrolling // We need to calculate this as soon as possible after lifetimes so that hitobjects // get the final say in their positions - var timelinePosition = positionAt(Time.Current); - - foreach (var obj in AliveObjects) - { - var finalPosition = hitObjectPositions[obj] - timelinePosition; - - switch (direction) - { - case ScrollingDirection.Up: - obj.Y = (float)(finalPosition * DrawHeight); - break; - case ScrollingDirection.Down: - obj.Y = (float)(-finalPosition * DrawHeight); - break; - case ScrollingDirection.Left: - obj.X = (float)(finalPosition * DrawWidth); - break; - case ScrollingDirection.Right: - obj.X = (float)(-finalPosition * DrawWidth); - break; - } - } + scrollingAlgorithm.ComputePositions(AliveObjects, direction, Time.Current, TimeRange, DrawSize); } - private double positionAt(double time) - { - double length = 0; - for (int i = 0; i < controlPoints.Count; i++) - { - var current = controlPoints[i]; - var next = i < controlPoints.Count - 1 ? controlPoints[i + 1] : null; - - if (i > 0 && current.StartTime > time) - continue; - - // Duration of the current control point - var currentDuration = (next?.StartTime ?? double.PositiveInfinity) - current.StartTime; - - length += Math.Min(currentDuration, time - current.StartTime) * current.Multiplier / TimeRange; - } - - return length; - } + /// + /// Creates the algorithm that will process the positions of the s. + /// + protected abstract IScrollingAlgorithm CreateScrollingAlgorithm(); } } diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index 899048531f..f560d8eaa6 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.UI.Scrolling /// /// A type of specialized towards scrolling s. /// - public class ScrollingPlayfield : Playfield + public abstract class ScrollingPlayfield : Playfield { /// /// The default span of time visible by the length of the scrolling axes. @@ -49,7 +49,9 @@ namespace osu.Game.Rulesets.UI.Scrolling /// /// The container that contains the s and s. /// - public new readonly ScrollingHitObjectContainer HitObjects; + public new ScrollingHitObjectContainer HitObjects => (ScrollingHitObjectContainer)base.HitObjects; + + private readonly ScrollingDirection direction; /// /// Creates a new . @@ -59,7 +61,7 @@ namespace osu.Game.Rulesets.UI.Scrolling protected ScrollingPlayfield(ScrollingDirection direction, float? customWidth = null) : base(customWidth) { - base.HitObjects = HitObjects = new ScrollingHitObjectContainer(direction) { RelativeSizeAxes = Axes.Both }; + this.direction = direction; HitObjects.TimeRange.BindTo(VisibleTimeRange); } @@ -105,6 +107,14 @@ namespace osu.Game.Rulesets.UI.Scrolling this.TransformTo(this.PopulateTransform(new TransformVisibleTimeRange(), newTimeRange, duration, easing)); } + protected sealed override HitObjectContainer CreateHitObjectContainer() => CreateScrollingHitObjectContainer(); + + /// + /// Creates the that will handle the scrolling of the s. + /// + /// + protected virtual ScrollingHitObjectContainer CreateScrollingHitObjectContainer() => new GlobalScrollingHitObjectContainer(direction); + private class TransformVisibleTimeRange : Transform { private double valueAt(double time) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 6d8ce3c1b6..a33cf73934 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -315,6 +315,10 @@ + + + + From 4ab3b0d76be328d8141305930eba63d4f3384bb2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sun, 7 Jan 2018 13:24:09 +0900 Subject: [PATCH 104/206] Implement local scrolling hit object container --- .../Algorithms/LocalScrollingAlgorithm.cs | 79 +++++++++++++++++++ .../LocalScrollingHitObjectContainer.cs | 17 ++++ osu.Game/osu.Game.csproj | 2 + 3 files changed, 98 insertions(+) create mode 100644 osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs create mode 100644 osu.Game/Rulesets/UI/Scrolling/LocalScrollingHitObjectContainer.cs diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs new file mode 100644 index 0000000000..ddd06a3725 --- /dev/null +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs @@ -0,0 +1,79 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using System.Collections.Generic; +using osu.Framework.Lists; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Timing; +using OpenTK; + +namespace osu.Game.Rulesets.UI.Scrolling.Algorithms +{ + public class LocalScrollingAlgorithm : IScrollingAlgorithm + { + private readonly Dictionary hitObjectPositions = new Dictionary(); + + private readonly SortedList controlPoints; + + public LocalScrollingAlgorithm(SortedList controlPoints) + { + this.controlPoints = controlPoints; + } + + public void ComputeInitialStates(IEnumerable hitObjects, ScrollingDirection direction, double timeRange, Vector2 length) + { + foreach (var obj in hitObjects) + { + var controlPoint = controlPointAt(obj.HitObject.StartTime); + + obj.LifetimeStart = obj.HitObject.StartTime - timeRange / controlPoint.Multiplier; + obj.LifetimeEnd = ((obj as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime) + timeRange / controlPoint.Multiplier; + } + } + + public void ComputePositions(IEnumerable hitObjects, ScrollingDirection direction, double currentTime, double timeRange, Vector2 length) + { + foreach (var obj in hitObjects) + { + var controlPoint = controlPointAt(obj.HitObject.StartTime); + + var position = (obj.HitObject.StartTime - currentTime) * controlPoint.Multiplier / timeRange; + + switch (direction) + { + case ScrollingDirection.Up: + obj.Y = (float)(position * length.Y); + break; + case ScrollingDirection.Down: + obj.Y = (float)(-position * length.Y); + break; + case ScrollingDirection.Left: + obj.X = (float)(position * length.X); + break; + case ScrollingDirection.Right: + obj.X = (float)(-position * length.X); + break; + } + } + } + + private readonly MultiplierControlPoint searchPoint = new MultiplierControlPoint(); + private MultiplierControlPoint controlPointAt(double time) + { + if (controlPoints.Count == 0) + return new MultiplierControlPoint(double.NegativeInfinity); + + if (time < controlPoints[0].StartTime) + return controlPoints[0]; + + searchPoint.StartTime = time; + int index = controlPoints.BinarySearch(searchPoint); + + if (index < 0) + index = ~index - 1; + + return controlPoints[index]; + } + } +} diff --git a/osu.Game/Rulesets/UI/Scrolling/LocalScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/LocalScrollingHitObjectContainer.cs new file mode 100644 index 0000000000..ceef688cbc --- /dev/null +++ b/osu.Game/Rulesets/UI/Scrolling/LocalScrollingHitObjectContainer.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using osu.Game.Rulesets.UI.Scrolling.Algorithms; + +namespace osu.Game.Rulesets.UI.Scrolling +{ + public class LocalScrollingHitObjectContainer : ScrollingHitObjectContainer + { + public LocalScrollingHitObjectContainer(ScrollingDirection direction) + : base(direction) + { + } + + protected override IScrollingAlgorithm CreateScrollingAlgorithm() => new LocalScrollingAlgorithm(ControlPoints); + } +} diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index a33cf73934..327b87d5de 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -318,7 +318,9 @@ + + From 006b63eb42c54450e7f74bbb7096c46c01e0d915 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sun, 7 Jan 2018 09:05:36 +0100 Subject: [PATCH 105/206] remove unnecessary change of spinner end sequence it wasn't really visible anyways *shrug* --- osu.Game.Rulesets.Osu/Mods/OsuMod.cs | 15 --------------- 1 file changed, 15 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs index 3f9bfc0f41..a76b543368 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs @@ -86,23 +86,8 @@ namespace osu.Game.Rulesets.Osu.Mods spinner.Background.Hide(); using (spinner.BeginAbsoluteSequence(fadeOutStartTime + longFadeDuration, true)) - { spinner.FadeOut(fadeOutDuration); - // speed up the end sequence accordingly - switch (state) - { - case ArmedState.Hit: - spinner.ScaleTo(spinner.Scale * 1.2f, fadeOutDuration * 2, Easing.Out); - break; - case ArmedState.Miss: - spinner.ScaleTo(spinner.Scale * 0.8f, fadeOutDuration * 2, Easing.In); - break; - } - - spinner.Expire(); - } - break; } } From 54c0197eb0f315c62a22a7ef35b7916ac666363e Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sun, 7 Jan 2018 09:08:26 +0100 Subject: [PATCH 106/206] remove early fadeout of sliderball on hidden it shouldn't have been done because it makes fast sliders unplayable as they never appear in the first place, ooops --- osu.Game.Rulesets.Osu/Mods/OsuMod.cs | 8 -------- 1 file changed, 8 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs index a76b543368..bd2f8090ed 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs @@ -70,14 +70,7 @@ namespace osu.Game.Rulesets.Osu.Mods break; case DrawableSlider slider: using (slider.BeginAbsoluteSequence(fadeOutStartTime, true)) - { slider.Body.FadeOut(longFadeDuration, Easing.Out); - - // delay a bit less to let the sliderball fade out peacefully instead of having a hard cut - using (slider.BeginDelayedSequence(longFadeDuration - fadeOutDuration, true)) - slider.Ball.FadeOut(fadeOutDuration); - } - break; case DrawableSpinner spinner: // hide elements we don't care about. @@ -87,7 +80,6 @@ namespace osu.Game.Rulesets.Osu.Mods using (spinner.BeginAbsoluteSequence(fadeOutStartTime + longFadeDuration, true)) spinner.FadeOut(fadeOutDuration); - break; } } From c4d1922c8bbf653a563f8a0854bfff3f7f1e5c78 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 8 Jan 2018 11:34:37 +0900 Subject: [PATCH 107/206] Add scrolling algorithm to global settings --- osu.Game/Configuration/OsuConfigManager.cs | 5 +++- .../Configuration/ScrollingAlgorithmType.cs | 15 +++++++++++ .../Sections/Gameplay/ScrollingSettings.cs | 26 ++++++++++++++++++ .../Settings/Sections/GameplaySection.cs | 3 ++- osu.Game/Rulesets/UI/Playfield.cs | 8 +++--- .../Algorithms/LocalScrollingAlgorithm.cs | 2 +- .../GlobalScrollingHitObjectContainer.cs | 17 ------------ .../LocalScrollingHitObjectContainer.cs | 17 ------------ .../Scrolling/ScrollingHitObjectContainer.cs | 27 +++++++++++-------- .../UI/Scrolling/ScrollingPlayfield.cs | 14 +++++----- osu.Game/osu.Game.csproj | 4 +-- 11 files changed, 77 insertions(+), 61 deletions(-) create mode 100644 osu.Game/Configuration/ScrollingAlgorithmType.cs create mode 100644 osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs delete mode 100644 osu.Game/Rulesets/UI/Scrolling/GlobalScrollingHitObjectContainer.cs delete mode 100644 osu.Game/Rulesets/UI/Scrolling/LocalScrollingHitObjectContainer.cs diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index f4c7bdb586..4ff4105b77 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -71,6 +71,8 @@ namespace osu.Game.Configuration Set(OsuSetting.FloatingComments, false); + Set(OsuSetting.ScrollingAlgorithm, ScrollingAlgorithmType.Global); + // Update Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); @@ -114,6 +116,7 @@ namespace osu.Game.Configuration ShowFpsDisplay, ChatDisplayHeight, Version, - ShowConvertedBeatmaps + ShowConvertedBeatmaps, + ScrollingAlgorithm } } diff --git a/osu.Game/Configuration/ScrollingAlgorithmType.cs b/osu.Game/Configuration/ScrollingAlgorithmType.cs new file mode 100644 index 0000000000..b4a2b8a4a3 --- /dev/null +++ b/osu.Game/Configuration/ScrollingAlgorithmType.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using System.ComponentModel; + +namespace osu.Game.Configuration +{ + public enum ScrollingAlgorithmType + { + [Description("Global")] + Global, + [Description("Local")] + Local + } +} diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs new file mode 100644 index 0000000000..b2a2a25da7 --- /dev/null +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE + +using osu.Framework.Allocation; +using osu.Game.Configuration; + +namespace osu.Game.Overlays.Settings.Sections.Gameplay +{ + public class ScrollingSettings : SettingsSubsection + { + protected override string Header => "Scrolling"; + + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + Children = new[] + { + new SettingsEnumDropdown + { + LabelText = "Scrolling algorithm", + Bindable = config.GetBindable(OsuSetting.ScrollingAlgorithm), + } + }; + } + } +} diff --git a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs index 035a3c7a13..8b05bfe8de 100644 --- a/osu.Game/Overlays/Settings/Sections/GameplaySection.cs +++ b/osu.Game/Overlays/Settings/Sections/GameplaySection.cs @@ -21,6 +21,7 @@ namespace osu.Game.Overlays.Settings.Sections { new GeneralSettings(), new SongSelectSettings(), + new ScrollingSettings() }; } @@ -35,4 +36,4 @@ namespace osu.Game.Overlays.Settings.Sections } } } -} \ No newline at end of file +} diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 91ea3ade2a..0f8a650718 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.UI /// /// The HitObjects contained in this Playfield. /// - public readonly HitObjectContainer HitObjects; + public HitObjectContainer HitObjects { get; private set; } public Container ScaledContent; @@ -49,14 +49,14 @@ namespace osu.Game.Rulesets.UI } } }); - - HitObjects = CreateHitObjectContainer(); - HitObjects.RelativeSizeAxes = Axes.Both; } [BackgroundDependencyLoader] private void load() { + HitObjects = CreateHitObjectContainer(); + HitObjects.RelativeSizeAxes = Axes.Both; + Add(HitObjects); } diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs index ddd06a3725..be8612ca96 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms var controlPoint = controlPointAt(obj.HitObject.StartTime); obj.LifetimeStart = obj.HitObject.StartTime - timeRange / controlPoint.Multiplier; - obj.LifetimeEnd = ((obj as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime) + timeRange / controlPoint.Multiplier; + obj.LifetimeEnd = ((obj.HitObject as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime) + timeRange / controlPoint.Multiplier; } } diff --git a/osu.Game/Rulesets/UI/Scrolling/GlobalScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/GlobalScrollingHitObjectContainer.cs deleted file mode 100644 index 23dff01940..0000000000 --- a/osu.Game/Rulesets/UI/Scrolling/GlobalScrollingHitObjectContainer.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE - -using osu.Game.Rulesets.UI.Scrolling.Algorithms; - -namespace osu.Game.Rulesets.UI.Scrolling -{ - public class GlobalScrollingHitObjectContainer : ScrollingHitObjectContainer - { - public GlobalScrollingHitObjectContainer(ScrollingDirection direction) - : base(direction) - { - } - - protected override IScrollingAlgorithm CreateScrollingAlgorithm() => new GlobalScrollingAlgorithm(ControlPoints); - } -} diff --git a/osu.Game/Rulesets/UI/Scrolling/LocalScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/LocalScrollingHitObjectContainer.cs deleted file mode 100644 index ceef688cbc..0000000000 --- a/osu.Game/Rulesets/UI/Scrolling/LocalScrollingHitObjectContainer.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE - -using osu.Game.Rulesets.UI.Scrolling.Algorithms; - -namespace osu.Game.Rulesets.UI.Scrolling -{ - public class LocalScrollingHitObjectContainer : ScrollingHitObjectContainer - { - public LocalScrollingHitObjectContainer(ScrollingDirection direction) - : base(direction) - { - } - - protected override IScrollingAlgorithm CreateScrollingAlgorithm() => new LocalScrollingAlgorithm(ControlPoints); - } -} diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index e1d8fe8d59..67f2e8aee0 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -1,17 +1,19 @@ // Copyright (c) 2007-2017 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Allocation; using osu.Framework.Caching; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Lists; +using osu.Game.Configuration; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; using osu.Game.Rulesets.UI.Scrolling.Algorithms; namespace osu.Game.Rulesets.UI.Scrolling { - public abstract class ScrollingHitObjectContainer : HitObjectContainer + public class ScrollingHitObjectContainer : HitObjectContainer { public readonly BindableDouble TimeRange = new BindableDouble { @@ -25,7 +27,7 @@ namespace osu.Game.Rulesets.UI.Scrolling private Cached initialStateCache = new Cached(); - protected ScrollingHitObjectContainer(ScrollingDirection direction) + public ScrollingHitObjectContainer(ScrollingDirection direction) { this.direction = direction; @@ -35,11 +37,19 @@ namespace osu.Game.Rulesets.UI.Scrolling } private IScrollingAlgorithm scrollingAlgorithm; - protected override void LoadComplete() - { - base.LoadComplete(); - scrollingAlgorithm = CreateScrollingAlgorithm(); + [BackgroundDependencyLoader] + private void load(OsuConfigManager config) + { + switch (config.Get(OsuSetting.ScrollingAlgorithm)) + { + case ScrollingAlgorithmType.Global: + scrollingAlgorithm = new GlobalScrollingAlgorithm(ControlPoints); + break; + case ScrollingAlgorithmType.Local: + scrollingAlgorithm = new LocalScrollingAlgorithm(ControlPoints); + break; + } } public override void Add(DrawableHitObject hitObject) @@ -99,10 +109,5 @@ namespace osu.Game.Rulesets.UI.Scrolling scrollingAlgorithm.ComputePositions(AliveObjects, direction, Time.Current, TimeRange, DrawSize); } - - /// - /// Creates the algorithm that will process the positions of the s. - /// - protected abstract IScrollingAlgorithm CreateScrollingAlgorithm(); } } diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index f560d8eaa6..8669339294 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; using osu.Framework.Graphics.Transforms; @@ -62,6 +63,11 @@ namespace osu.Game.Rulesets.UI.Scrolling : base(customWidth) { this.direction = direction; + } + + [BackgroundDependencyLoader] + private void load() + { HitObjects.TimeRange.BindTo(VisibleTimeRange); } @@ -107,13 +113,7 @@ namespace osu.Game.Rulesets.UI.Scrolling this.TransformTo(this.PopulateTransform(new TransformVisibleTimeRange(), newTimeRange, duration, easing)); } - protected sealed override HitObjectContainer CreateHitObjectContainer() => CreateScrollingHitObjectContainer(); - - /// - /// Creates the that will handle the scrolling of the s. - /// - /// - protected virtual ScrollingHitObjectContainer CreateScrollingHitObjectContainer() => new GlobalScrollingHitObjectContainer(direction); + protected sealed override HitObjectContainer CreateHitObjectContainer() => new ScrollingHitObjectContainer(direction); private class TransformVisibleTimeRange : Transform { diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 327b87d5de..45183de092 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -265,6 +265,7 @@ + @@ -310,6 +311,7 @@ + @@ -319,8 +321,6 @@ - - From f6c168be27568d460ff39d57bb76480faf06ef3c Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Mon, 8 Jan 2018 18:21:18 +0100 Subject: [PATCH 108/206] add skip cutscene as "in game" keybinding --- .../Bindings/GlobalKeyBindingInputManager.cs | 13 +++++++++++- .../KeyBinding/GlobalKeyBindingsSection.cs | 20 +++++++++++++++---- osu.Game/Screens/Play/SkipButton.cs | 17 ++++++++-------- 3 files changed, 37 insertions(+), 13 deletions(-) diff --git a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs index bf492af776..f5e54775fb 100644 --- a/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs +++ b/osu.Game/Input/Bindings/GlobalKeyBindingInputManager.cs @@ -20,7 +20,9 @@ namespace osu.Game.Input.Bindings handler = game; } - public override IEnumerable DefaultKeyBindings => new[] + public override IEnumerable DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings); + + public IEnumerable GlobalKeyBindings => new[] { new KeyBinding(InputKey.F8, GlobalAction.ToggleChat), new KeyBinding(InputKey.F9, GlobalAction.ToggleSocial), @@ -33,6 +35,11 @@ namespace osu.Game.Input.Bindings new KeyBinding(new[] { InputKey.MouseWheelDown }, GlobalAction.DecreaseVolume), }; + public IEnumerable InGameKeyBindings => new[] + { + new KeyBinding(InputKey.Space, GlobalAction.SkipCutscene) + }; + protected override IEnumerable KeyBindingInputQueue => handler == null ? base.KeyBindingInputQueue : new[] { handler }.Concat(base.KeyBindingInputQueue); } @@ -55,5 +62,9 @@ namespace osu.Game.Input.Bindings IncreaseVolume, [Description("Decrease Volume")] DecreaseVolume, + + // In-Game Keybindings + [Description("Skip Cutscene")] + SkipCutscene } } diff --git a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs index 8ec0a44d9b..f5b3096404 100644 --- a/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs +++ b/osu.Game/Overlays/KeyBinding/GlobalKeyBindingsSection.cs @@ -1,8 +1,8 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Input.Bindings; using osu.Game.Graphics; +using osu.Game.Input.Bindings; using osu.Game.Overlays.Settings; namespace osu.Game.Overlays.KeyBinding @@ -12,19 +12,31 @@ namespace osu.Game.Overlays.KeyBinding public override FontAwesome Icon => FontAwesome.fa_osu_hot; public override string Header => "Global"; - public GlobalKeyBindingsSection(KeyBindingContainer manager) + public GlobalKeyBindingsSection(GlobalKeyBindingInputManager manager) { Add(new DefaultBindingsSubsection(manager)); + Add(new InGameKeyBindingsSubsection(manager)); } + private class DefaultBindingsSubsection : KeyBindingsSubsection { protected override string Header => string.Empty; - public DefaultBindingsSubsection(KeyBindingContainer manager) + public DefaultBindingsSubsection(GlobalKeyBindingInputManager manager) : base(null) { - Defaults = manager.DefaultKeyBindings; + Defaults = manager.GlobalKeyBindings; + } + } + + private class InGameKeyBindingsSubsection : KeyBindingsSubsection + { + protected override string Header => "In Game"; + + public InGameKeyBindingsSubsection(GlobalKeyBindingInputManager manager) : base(null) + { + Defaults = manager.InGameKeyBindings; } } } diff --git a/osu.Game/Screens/Play/SkipButton.cs b/osu.Game/Screens/Play/SkipButton.cs index 0001aa0e76..55b2e21c53 100644 --- a/osu.Game/Screens/Play/SkipButton.cs +++ b/osu.Game/Screens/Play/SkipButton.cs @@ -14,13 +14,14 @@ using osu.Game.Graphics.Sprites; using osu.Game.Screens.Ranking; using OpenTK; using OpenTK.Graphics; -using OpenTK.Input; using osu.Framework.Graphics.Shapes; using osu.Game.Graphics.Containers; +using osu.Framework.Input.Bindings; +using osu.Game.Input.Bindings; namespace osu.Game.Screens.Play { - public class SkipButton : Container + public class SkipButton : Container, IKeyBindingHandler { private readonly double startTime; public IAdjustableClock AudioClock; @@ -117,20 +118,20 @@ namespace osu.Game.Screens.Play remainingTimeBox.ResizeWidthTo((float)Math.Max(0, 1 - (Time.Current - displayTime) / (beginFadeTime - displayTime)), 120, Easing.OutQuint); } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) + public bool OnPressed(GlobalAction action) { - if (args.Repeat) return false; - - switch (args.Key) + switch (action) { - case Key.Space: + case GlobalAction.SkipCutscene: button.TriggerOnClick(); return true; } - return base.OnKeyDown(state, args); + return false; } + public bool OnReleased(GlobalAction action) => false; + private class FadeContainer : Container, IStateful { public event Action StateChanged; From a3f05ca9ecd8bda3928c4061822e788f3ba50b60 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 9 Jan 2018 12:43:10 +0900 Subject: [PATCH 109/206] Avoid unnecessary use of linq --- osu.Game/Screens/Select/BeatmapCarousel.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/BeatmapCarousel.cs b/osu.Game/Screens/Select/BeatmapCarousel.cs index 11f0b6d138..c0767cc07a 100644 --- a/osu.Game/Screens/Select/BeatmapCarousel.cs +++ b/osu.Game/Screens/Select/BeatmapCarousel.cs @@ -267,7 +267,7 @@ namespace osu.Game.Screens.Select set = visibleSets.ElementAt(RNG.Next(visibleSets.Count)); var visibleBeatmaps = set.Beatmaps.Where(s => !s.Filtered).ToList(); - select(visibleBeatmaps.Skip(RNG.Next(visibleBeatmaps.Count)).FirstOrDefault()); + select(visibleBeatmaps[RNG.Next(visibleBeatmaps.Count)]); return true; } From 722eb2515ff2d3c9dda99408f1b3cb30cafef44f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 9 Jan 2018 12:44:52 +0900 Subject: [PATCH 110/206] Improve variable names --- .../Visual/TestCaseBeatmapCarousel.cs | 36 +++++++++---------- 1 file changed, 18 insertions(+), 18 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs index 586d9f85ed..4a65d12977 100644 --- a/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs +++ b/osu.Game.Tests/Visual/TestCaseBeatmapCarousel.cs @@ -237,7 +237,7 @@ namespace osu.Game.Tests.Visual nextRandom(); AddAssert("ensure repeat", () => selectedSets.Contains(carousel.SelectedBeatmapSet)); - AddStep("Add set with 100 difficulties", () => carousel.UpdateBeatmapSet(createTestBeatmapSetWith100Difficulties(set_count + 1))); + AddStep("Add set with 100 difficulties", () => carousel.UpdateBeatmapSet(createTestBeatmapSetWithManyDifficulties(set_count + 1))); AddStep("Filter Extra", () => carousel.Filter(new FilterCriteria { SearchText = "Extra 10" }, false)); checkInvisibleDifficultiesUnselectable(); checkInvisibleDifficultiesUnselectable(); @@ -353,26 +353,26 @@ namespace osu.Game.Tests.Visual } } - private BeatmapSetInfo createTestBeatmapSet(int i) + private BeatmapSetInfo createTestBeatmapSet(int id) { return new BeatmapSetInfo { - ID = i, - OnlineBeatmapSetID = i, + ID = id, + OnlineBeatmapSetID = id, Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), Metadata = new BeatmapMetadata { - OnlineBeatmapSetID = i, + OnlineBeatmapSetID = id, // Create random metadata, then we can check if sorting works based on these - Artist = $"peppy{i.ToString().PadLeft(6, '0')}", - Title = $"test set #{i}!", - AuthorString = string.Concat(Enumerable.Repeat((char)('z' - Math.Min(25, i - 1)), 5)) + Artist = $"peppy{id.ToString().PadLeft(6, '0')}", + Title = $"test set #{id}!", + AuthorString = string.Concat(Enumerable.Repeat((char)('z' - Math.Min(25, id - 1)), 5)) }, Beatmaps = new List(new[] { new BeatmapInfo { - OnlineBeatmapID = i * 10, + OnlineBeatmapID = id * 10, Path = "normal.osu", Version = "Normal", StarDifficulty = 2, @@ -383,7 +383,7 @@ namespace osu.Game.Tests.Visual }, new BeatmapInfo { - OnlineBeatmapID = i * 10 + 1, + OnlineBeatmapID = id * 10 + 1, Path = "hard.osu", Version = "Hard", StarDifficulty = 5, @@ -394,7 +394,7 @@ namespace osu.Game.Tests.Visual }, new BeatmapInfo { - OnlineBeatmapID = i * 10 + 2, + OnlineBeatmapID = id * 10 + 2, Path = "insane.osu", Version = "Insane", StarDifficulty = 6, @@ -407,20 +407,20 @@ namespace osu.Game.Tests.Visual }; } - private BeatmapSetInfo createTestBeatmapSetWith100Difficulties(int i) + private BeatmapSetInfo createTestBeatmapSetWithManyDifficulties(int id) { var toReturn = new BeatmapSetInfo { - ID = i, - OnlineBeatmapSetID = i, + ID = id, + OnlineBeatmapSetID = id, Hash = new MemoryStream(Encoding.UTF8.GetBytes(Guid.NewGuid().ToString())).ComputeMD5Hash(), Metadata = new BeatmapMetadata { - OnlineBeatmapSetID = i, + OnlineBeatmapSetID = id, // Create random metadata, then we can check if sorting works based on these - Artist = $"peppy{i.ToString().PadLeft(6, '0')}", - Title = $"test set #{i}!", - AuthorString = string.Concat(Enumerable.Repeat((char)('z' - Math.Min(25, i - 1)), 5)) + Artist = $"peppy{id.ToString().PadLeft(6, '0')}", + Title = $"test set #{id}!", + AuthorString = string.Concat(Enumerable.Repeat((char)('z' - Math.Min(25, id - 1)), 5)) }, Beatmaps = new List(), }; From b8bb0a52e39d91180dfad5ca4b3651b01deaa05d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 9 Jan 2018 13:41:57 +0900 Subject: [PATCH 111/206] Move mod implementations to individual files --- osu.Game.Rulesets.Catch/Mods/CatchMod.cs | 69 ------ .../Mods/CatchModDaycore.cs | 12 ++ .../Mods/CatchModDoubleTime.cs | 12 ++ osu.Game.Rulesets.Catch/Mods/CatchModEasy.cs | 11 + .../Mods/CatchModFlashlight.cs | 12 ++ .../Mods/CatchModHalfTime.cs | 12 ++ .../Mods/CatchModHardRock.cs | 13 ++ .../Mods/CatchModHidden.cs | 13 ++ .../Mods/CatchModNightcore.cs | 12 ++ .../Mods/CatchModNoFail.cs | 11 + .../Mods/CatchModPerfect.cs | 11 + osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs | 12 ++ .../Mods/CatchModSuddenDeath.cs | 11 + .../osu.Game.Rulesets.Catch.csproj | 13 +- osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs | 29 +++ osu.Game.Rulesets.Mania/Mods/ManiaMod.cs | 197 ------------------ .../Mods/ManiaModAutoplay.cs | 24 +++ .../Mods/ManiaModDaycore.cs | 12 ++ .../Mods/ManiaModDoubleTime.cs | 12 ++ osu.Game.Rulesets.Mania/Mods/ManiaModEasy.cs | 11 + .../Mods/ManiaModFadeIn.cs | 20 ++ .../Mods/ManiaModFlashlight.cs | 14 ++ .../Mods/ManiaModGravity.cs | 14 +- .../Mods/ManiaModHalfTime.cs | 12 ++ .../Mods/ManiaModHardRock.cs | 12 ++ .../Mods/ManiaModHidden.cs | 15 ++ osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs | 11 + osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs | 11 + osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs | 11 + osu.Game.Rulesets.Mania/Mods/ManiaModKey4.cs | 11 + osu.Game.Rulesets.Mania/Mods/ManiaModKey5.cs | 11 + osu.Game.Rulesets.Mania/Mods/ManiaModKey6.cs | 11 + osu.Game.Rulesets.Mania/Mods/ManiaModKey7.cs | 11 + osu.Game.Rulesets.Mania/Mods/ManiaModKey8.cs | 11 + osu.Game.Rulesets.Mania/Mods/ManiaModKey9.cs | 11 + .../Mods/ManiaModKeyCoop.cs | 16 ++ .../Mods/ManiaModNightcore.cs | 12 ++ .../Mods/ManiaModNoFail.cs | 11 + .../Mods/ManiaModPerfect.cs | 11 + .../Mods/ManiaModRandom.cs | 31 +++ .../Mods/ManiaModSuddenDeath.cs | 11 + .../osu.Game.Rulesets.Mania.csproj | 26 ++- osu.Game.Rulesets.Osu/Mods/OsuMod.cs | 189 ----------------- osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs | 20 ++ osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs | 26 +++ osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs | 12 ++ .../Mods/OsuModDoubleTime.cs | 12 ++ osu.Game.Rulesets.Osu/Mods/OsuModEasy.cs | 11 + .../Mods/OsuModFlashlight.cs | 12 ++ osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs | 12 ++ osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs | 32 +++ osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs | 79 +++++++ osu.Game.Rulesets.Osu/Mods/OsuModNightcore.cs | 12 ++ osu.Game.Rulesets.Osu/Mods/OsuModNoFail.cs | 14 ++ osu.Game.Rulesets.Osu/Mods/OsuModPerfect.cs | 11 + osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs | 15 ++ osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs | 20 ++ .../Mods/OsuModSuddenDeath.cs | 14 ++ osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs | 17 ++ .../osu.Game.Rulesets.Osu.csproj | 17 +- osu.Game.Rulesets.Taiko/Mods/TaikoMod.cs | 83 -------- .../Mods/TaikoModAutoplay.cs | 24 +++ .../Mods/TaikoModDaycore.cs | 12 ++ .../Mods/TaikoModDoubleTime.cs | 12 ++ osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs | 11 + .../Mods/TaikoModFlashlight.cs | 12 ++ .../Mods/TaikoModHalfTime.cs | 12 ++ .../Mods/TaikoModHardRock.cs | 13 ++ .../Mods/TaikoModHidden.cs | 13 ++ .../Mods/TaikoModNightcore.cs | 12 ++ .../Mods/TaikoModNoFail.cs | 11 + .../Mods/TaikoModPerfect.cs | 11 + osu.Game.Rulesets.Taiko/Mods/TaikoModRelax.cs | 12 ++ .../Mods/TaikoModSuddenDeath.cs | 11 + .../osu.Game.Rulesets.Taiko.csproj | 14 +- 75 files changed, 1052 insertions(+), 549 deletions(-) delete mode 100644 osu.Game.Rulesets.Catch/Mods/CatchMod.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModEasy.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModNoFail.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModSuddenDeath.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs delete mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaMod.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModEasy.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModKey4.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModKey5.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModKey6.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModKey7.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModKey8.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModKey9.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModKeyCoop.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModNoFail.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModPerfect.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs create mode 100644 osu.Game.Rulesets.Mania/Mods/ManiaModSuddenDeath.cs delete mode 100644 osu.Game.Rulesets.Osu/Mods/OsuMod.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModDoubleTime.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModEasy.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModNightcore.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModNoFail.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModPerfect.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs create mode 100644 osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs delete mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoMod.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModDaycore.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModDoubleTime.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModHalfTime.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModHidden.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModNightcore.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModNoFail.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModPerfect.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModRelax.cs create mode 100644 osu.Game.Rulesets.Taiko/Mods/TaikoModSuddenDeath.cs diff --git a/osu.Game.Rulesets.Catch/Mods/CatchMod.cs b/osu.Game.Rulesets.Catch/Mods/CatchMod.cs deleted file mode 100644 index d243ee69e3..0000000000 --- a/osu.Game.Rulesets.Catch/Mods/CatchMod.cs +++ /dev/null @@ -1,69 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Rulesets.Mods; - -namespace osu.Game.Rulesets.Catch.Mods -{ - public class CatchModNoFail : ModNoFail - { - - } - - public class CatchModEasy : ModEasy - { - - } - - public class CatchModHidden : ModHidden - { - public override string Description => @"Play with fading notes for a slight score advantage."; - public override double ScoreMultiplier => 1.06; - } - - public class CatchModHardRock : ModHardRock - { - public override double ScoreMultiplier => 1.12; - public override bool Ranked => true; - } - - public class CatchModSuddenDeath : ModSuddenDeath - { - - } - - public class CatchModDaycore : ModDaycore - { - public override double ScoreMultiplier => 0.5; - } - - public class CatchModDoubleTime : ModDoubleTime - { - public override double ScoreMultiplier => 1.06; - } - - public class CatchModRelax : ModRelax - { - public override string Description => @"Use the mouse to control the catcher."; - } - - public class CatchModHalfTime : ModHalfTime - { - public override double ScoreMultiplier => 0.5; - } - - public class CatchModNightcore : ModNightcore - { - public override double ScoreMultiplier => 1.06; - } - - public class CatchModFlashlight : ModFlashlight - { - public override double ScoreMultiplier => 1.12; - } - - public class CatchModPerfect : ModPerfect - { - - } -} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs new file mode 100644 index 0000000000..124af06d56 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModDaycore : ModDaycore + { + public override double ScoreMultiplier => 0.5; + } +} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs new file mode 100644 index 0000000000..7a7eeed719 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModDoubleTime : ModDoubleTime + { + public override double ScoreMultiplier => 1.06; + } +} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModEasy.cs b/osu.Game.Rulesets.Catch/Mods/CatchModEasy.cs new file mode 100644 index 0000000000..5c025bdea0 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModEasy.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModEasy : ModEasy + { + } +} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs new file mode 100644 index 0000000000..424f14ad02 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModFlashlight : ModFlashlight + { + public override double ScoreMultiplier => 1.12; + } +} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs new file mode 100644 index 0000000000..303fa6011d --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModHalfTime : ModHalfTime + { + public override double ScoreMultiplier => 0.5; + } +} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs new file mode 100644 index 0000000000..ed33bf7124 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModHardRock : ModHardRock + { + public override double ScoreMultiplier => 1.12; + public override bool Ranked => true; + } +} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs new file mode 100644 index 0000000000..981ebda9eb --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModHidden : ModHidden + { + public override string Description => @"Play with fading notes for a slight score advantage."; + public override double ScoreMultiplier => 1.06; + } +} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs b/osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs new file mode 100644 index 0000000000..b53cac0d7c --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModNightcore : ModNightcore + { + public override double ScoreMultiplier => 1.06; + } +} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModNoFail.cs b/osu.Game.Rulesets.Catch/Mods/CatchModNoFail.cs new file mode 100644 index 0000000000..afb2d83720 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModNoFail.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModNoFail : ModNoFail + { + } +} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs b/osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs new file mode 100644 index 0000000000..bc0dd10f6c --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModPerfect : ModPerfect + { + } +} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs b/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs new file mode 100644 index 0000000000..de0b6bc614 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModRelax : ModRelax + { + public override string Description => @"Use the mouse to control the catcher."; + } +} diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModSuddenDeath.cs b/osu.Game.Rulesets.Catch/Mods/CatchModSuddenDeath.cs new file mode 100644 index 0000000000..1e778e5305 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModSuddenDeath.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModSuddenDeath : ModSuddenDeath + { + } +} diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 16c909e063..6c42c4341f 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -49,6 +49,17 @@ + + + + + + + + + + + @@ -71,7 +82,7 @@ - + diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs new file mode 100644 index 0000000000..e6711923ff --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.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 osu.Game.Beatmaps; +using osu.Game.Rulesets.Mania.Beatmaps; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public abstract class ManiaKeyMod : Mod, IApplicableMod, IApplicableToBeatmapConverter + { + public override string ShortenedName => Name; + public abstract int KeyCount { get; } + public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier + public override bool Ranked => true; + + public void ApplyToBeatmapConverter(BeatmapConverter beatmapConverter) + { + var mbc = (ManiaBeatmapConverter)beatmapConverter; + + // Although this can work, for now let's not allow keymods for mania-specific beatmaps + if (mbc.IsForCurrentRuleset) + return; + + mbc.TargetColumns = KeyCount; + } + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs deleted file mode 100644 index 4cfc4cdd2a..0000000000 --- a/osu.Game.Rulesets.Mania/Mods/ManiaMod.cs +++ /dev/null @@ -1,197 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Graphics; -using osu.Game.Rulesets.Mods; -using System; -using System.Linq; -using osu.Framework.Extensions.IEnumerableExtensions; -using osu.Framework.MathUtils; -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Mania.Beatmaps; -using osu.Game.Rulesets.Mania.Objects; -using osu.Game.Rulesets.Mania.Replays; -using osu.Game.Rulesets.Mania.UI; -using osu.Game.Rulesets.Scoring; -using osu.Game.Users; -using osu.Game.Rulesets.UI; - -namespace osu.Game.Rulesets.Mania.Mods -{ - public class ManiaModNoFail : ModNoFail - { - - } - - public class ManiaModEasy : ModEasy - { - - } - - public class ManiaModHidden : ModHidden - { - public override string Description => @"The notes fade out before you hit them!"; - public override double ScoreMultiplier => 1.0; - public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) }; - } - - public class ManiaModHardRock : ModHardRock - { - public override double ScoreMultiplier => 1.0; - } - - public class ManiaModSuddenDeath : ModSuddenDeath - { - - } - - public class ManiaModDaycore : ModDaycore - { - public override double ScoreMultiplier => 0.3; - } - - public class ManiaModDoubleTime : ModDoubleTime - { - public override double ScoreMultiplier => 1.0; - } - - public class ManiaModHalfTime : ModHalfTime - { - public override double ScoreMultiplier => 0.3; - } - - public class ManiaModNightcore : ModNightcore - { - public override double ScoreMultiplier => 1.0; - } - - public class ManiaModFlashlight : ModFlashlight - { - public override double ScoreMultiplier => 1.0; - public override Type[] IncompatibleMods => new[] { typeof(ModHidden) }; - } - - public class ManiaModPerfect : ModPerfect - { - - } - - public class ManiaModFadeIn : Mod - { - public override string Name => "FadeIn"; - public override string ShortenedName => "FI"; - public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden; - public override ModType Type => ModType.DifficultyIncrease; - public override double ScoreMultiplier => 1; - public override bool Ranked => true; - public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) }; - } - - public class ManiaModRandom : Mod, IApplicableToRulesetContainer - { - public override string Name => "Random"; - public override string ShortenedName => "RD"; - public override FontAwesome Icon => FontAwesome.fa_osu_dice; - public override string Description => @"Shuffle around the notes!"; - public override double ScoreMultiplier => 1; - - public void ApplyToRulesetContainer(RulesetContainer rulesetContainer) - { - int availableColumns = ((ManiaRulesetContainer)rulesetContainer).Beatmap.TotalColumns; - var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList(); - - rulesetContainer.Objects.OfType().ForEach(h => h.Column = shuffledColumns[h.Column]); - } - } - - public abstract class ManiaKeyMod : Mod, IApplicableMod, IApplicableToBeatmapConverter - { - public override string ShortenedName => Name; - public abstract int KeyCount { get; } - public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier - public override bool Ranked => true; - - public void ApplyToBeatmapConverter(BeatmapConverter beatmapConverter) - { - var mbc = (ManiaBeatmapConverter)beatmapConverter; - - // Although this can work, for now let's not allow keymods for mania-specific beatmaps - if (mbc.IsForCurrentRuleset) - return; - - mbc.TargetColumns = KeyCount; - } - } - - public class ManiaModKey1 : ManiaKeyMod - { - public override int KeyCount => 1; - public override string Name => "1K"; - } - - public class ManiaModKey2 : ManiaKeyMod - { - public override int KeyCount => 2; - public override string Name => "2K"; - } - - public class ManiaModKey3 : ManiaKeyMod - { - public override int KeyCount => 3; - public override string Name => "3K"; - } - - public class ManiaModKey4 : ManiaKeyMod - { - public override int KeyCount => 4; - public override string Name => "4K"; - } - - public class ManiaModKey5 : ManiaKeyMod - { - public override int KeyCount => 5; - public override string Name => "5K"; - } - - public class ManiaModKey6 : ManiaKeyMod - { - public override int KeyCount => 6; - public override string Name => "6K"; - } - - public class ManiaModKey7 : ManiaKeyMod - { - public override int KeyCount => 7; - public override string Name => "7K"; - } - - public class ManiaModKey8 : ManiaKeyMod - { - public override int KeyCount => 8; - public override string Name => "8K"; - } - - public class ManiaModKey9 : ManiaKeyMod - { - public override int KeyCount => 9; - public override string Name => "9K"; - } - - public class ManiaModKeyCoop : Mod - { - public override string Name => "KeyCoop"; - public override string ShortenedName => "2P"; - public override string Description => @"Double the key amount, double the fun!"; - public override double ScoreMultiplier => 1; - public override bool Ranked => true; - } - - public class ManiaModAutoplay : ModAutoplay - { - protected override Score CreateReplayScore(Beatmap beatmap) => new Score - { - User = new User { Username = "osu!topus!" }, - Replay = new ManiaAutoGenerator(beatmap).Generate(), - }; - } -} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs new file mode 100644 index 0000000000..3c5179cef0 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mania.Replays; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; +using osu.Game.Users; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModAutoplay : ModAutoplay + { + protected override Score CreateReplayScore(Beatmap beatmap) + { + return new Score + { + User = new User { Username = "osu!topus!" }, + Replay = new ManiaAutoGenerator(beatmap).Generate(), + }; + } + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs new file mode 100644 index 0000000000..7c7dc5e4f7 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModDaycore : ModDaycore + { + public override double ScoreMultiplier => 0.3; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs new file mode 100644 index 0000000000..64ce86e748 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModDoubleTime : ModDoubleTime + { + public override double ScoreMultiplier => 1.0; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModEasy.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModEasy.cs new file mode 100644 index 0000000000..1faed5e1c0 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModEasy.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModEasy : ModEasy + { + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs new file mode 100644 index 0000000000..03442507d6 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Graphics; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModFadeIn : Mod + { + public override string Name => "FadeIn"; + public override string ShortenedName => "FI"; + public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden; + public override ModType Type => ModType.DifficultyIncrease; + public override double ScoreMultiplier => 1; + public override bool Ranked => true; + public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) }; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs new file mode 100644 index 0000000000..89eb02268e --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModFlashlight : ModFlashlight + { + public override double ScoreMultiplier => 1.0; + public override Type[] IncompatibleMods => new[] { typeof(ModHidden) }; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs index 8b61d33f21..9d158cf3bb 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModGravity.cs @@ -3,13 +3,12 @@ using System.Collections.Generic; using System.Linq; +using osu.Game.Graphics; using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mania.Timing; using osu.Game.Rulesets.Mania.UI; using osu.Game.Rulesets.Mods; -using osu.Game.Graphics; -using osu.Game.Rulesets.Mania.Timing; using osu.Game.Rulesets.Timing; -using osu.Game.Rulesets.Mania.Objects.Drawables; namespace osu.Game.Rulesets.Mania.Mods { @@ -22,12 +21,13 @@ namespace osu.Game.Rulesets.Mania.Mods public override FontAwesome Icon => FontAwesome.fa_sort_desc; - public void ApplyToRulesetContainer(ManiaRulesetContainer rulesetContainer, ref List[] hitObjectTimingChanges, ref List barlineTimingChanges) + public void ApplyToRulesetContainer(ManiaRulesetContainer rulesetContainer, ref List[] hitObjectTimingChanges, + ref List barlineTimingChanges) { // We have to generate one speed adjustment per hit object for gravity - foreach (ManiaHitObject obj in rulesetContainer.Objects.OfType()) + foreach (var obj in rulesetContainer.Objects.OfType()) { - MultiplierControlPoint controlPoint = rulesetContainer.CreateControlPointAt(obj.StartTime); + var controlPoint = rulesetContainer.CreateControlPointAt(obj.StartTime); // Beat length has too large of an effect for gravity, so we'll force it to a constant value for now controlPoint.TimingPoint.BeatLength = 1000; @@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Mania.Mods } // Like with hit objects, we need to generate one speed adjustment per bar line - foreach (DrawableBarLine barLine in rulesetContainer.BarLines) + foreach (var barLine in rulesetContainer.BarLines) { var controlPoint = rulesetContainer.CreateControlPointAt(barLine.HitObject.StartTime); // Beat length has too large of an effect for gravity, so we'll force it to a constant value for now diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs new file mode 100644 index 0000000000..2f8404609f --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModHalfTime : ModHalfTime + { + public override double ScoreMultiplier => 0.3; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs new file mode 100644 index 0000000000..91edbaf0cf --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModHardRock : ModHardRock + { + public override double ScoreMultiplier => 1.0; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs new file mode 100644 index 0000000000..c2fc07da89 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModHidden : ModHidden + { + public override string Description => @"The notes fade out before you hit them!"; + public override double ScoreMultiplier => 1.0; + public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight) }; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs new file mode 100644 index 0000000000..8a6943d99b --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModKey1 : ManiaKeyMod + { + public override int KeyCount => 1; + public override string Name => "1K"; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs new file mode 100644 index 0000000000..553827ac1c --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModKey2 : ManiaKeyMod + { + public override int KeyCount => 2; + public override string Name => "2K"; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs new file mode 100644 index 0000000000..ef048c848e --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModKey3 : ManiaKeyMod + { + public override int KeyCount => 3; + public override string Name => "3K"; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey4.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey4.cs new file mode 100644 index 0000000000..9c713d920f --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey4.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModKey4 : ManiaKeyMod + { + public override int KeyCount => 4; + public override string Name => "4K"; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey5.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey5.cs new file mode 100644 index 0000000000..a83faf4627 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey5.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModKey5 : ManiaKeyMod + { + public override int KeyCount => 5; + public override string Name => "5K"; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey6.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey6.cs new file mode 100644 index 0000000000..d7df901048 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey6.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModKey6 : ManiaKeyMod + { + public override int KeyCount => 6; + public override string Name => "6K"; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey7.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey7.cs new file mode 100644 index 0000000000..4a3f9857e5 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey7.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModKey7 : ManiaKeyMod + { + public override int KeyCount => 7; + public override string Name => "7K"; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey8.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey8.cs new file mode 100644 index 0000000000..22c301fb7a --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey8.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModKey8 : ManiaKeyMod + { + public override int KeyCount => 8; + public override string Name => "8K"; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey9.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey9.cs new file mode 100644 index 0000000000..b2a0bc4ddf --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey9.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModKey9 : ManiaKeyMod + { + public override int KeyCount => 9; + public override string Name => "9K"; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKeyCoop.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKeyCoop.cs new file mode 100644 index 0000000000..893e81f165 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKeyCoop.cs @@ -0,0 +1,16 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModKeyCoop : Mod + { + public override string Name => "KeyCoop"; + public override string ShortenedName => "2P"; + public override string Description => @"Double the key amount, double the fun!"; + public override double ScoreMultiplier => 1; + public override bool Ranked => true; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs new file mode 100644 index 0000000000..a977eef5e3 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModNightcore : ModNightcore + { + public override double ScoreMultiplier => 1.0; + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModNoFail.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModNoFail.cs new file mode 100644 index 0000000000..c9c50f9919 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModNoFail.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModNoFail : ModNoFail + { + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPerfect.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPerfect.cs new file mode 100644 index 0000000000..2c0bd5f8c3 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPerfect.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModPerfect : ModPerfect + { + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs new file mode 100644 index 0000000000..a6cbad44d7 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs @@ -0,0 +1,31 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Linq; +using osu.Framework.Extensions.IEnumerableExtensions; +using osu.Framework.MathUtils; +using osu.Game.Graphics; +using osu.Game.Rulesets.Mania.Objects; +using osu.Game.Rulesets.Mania.UI; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.UI; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModRandom : Mod, IApplicableToRulesetContainer + { + public override string Name => "Random"; + public override string ShortenedName => "RD"; + public override FontAwesome Icon => FontAwesome.fa_osu_dice; + public override string Description => @"Shuffle around the notes!"; + public override double ScoreMultiplier => 1; + + public void ApplyToRulesetContainer(RulesetContainer rulesetContainer) + { + var availableColumns = ((ManiaRulesetContainer)rulesetContainer).Beatmap.TotalColumns; + var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList(); + + rulesetContainer.Objects.OfType().ForEach(h => h.Column = shuffledColumns[h.Column]); + } + } +} diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModSuddenDeath.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModSuddenDeath.cs new file mode 100644 index 0000000000..9edf131195 --- /dev/null +++ b/osu.Game.Rulesets.Mania/Mods/ManiaModSuddenDeath.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Mania.Mods +{ + public class ManiaModSuddenDeath : ModSuddenDeath + { + } +} diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index e9a572835b..11f354ec7d 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -65,6 +65,30 @@ + + + + + + + + + + + + + + + + + + + + + + + + @@ -98,7 +122,7 @@ - + diff --git a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs b/osu.Game.Rulesets.Osu/Mods/OsuMod.cs deleted file mode 100644 index bd2f8090ed..0000000000 --- a/osu.Game.Rulesets.Osu/Mods/OsuMod.cs +++ /dev/null @@ -1,189 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Beatmaps; -using osu.Game.Graphics; -using osu.Game.Rulesets.Osu.Replays; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Osu.Objects; -using System; -using System.Collections.Generic; -using System.Linq; -using osu.Game.Rulesets.Osu.UI; -using osu.Game.Rulesets.Scoring; -using OpenTK; -using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Osu.Objects.Drawables; -using osu.Framework.Graphics; -using osu.Game.Rulesets.Objects.Types; - -namespace osu.Game.Rulesets.Osu.Mods -{ - public class OsuModNoFail : ModNoFail - { - public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray(); - } - - public class OsuModEasy : ModEasy - { - } - - public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects - { - public override string Description => @"Play with no approach circles and fading notes for a slight score advantage."; - public override double ScoreMultiplier => 1.06; - - private const double fade_in_duration_multiplier = 0.4; - private const double fade_out_duration_multiplier = 0.3; - - private float preEmpt => DrawableOsuHitObject.TIME_PREEMPT; - - public void ApplyToDrawableHitObjects(IEnumerable drawables) - { - foreach (var d in drawables.OfType()) - { - d.ApplyCustomUpdateState += ApplyHiddenState; - d.FadeInDuration = preEmpt * fade_in_duration_multiplier; - } - } - - protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state) - { - if (!(drawable is DrawableOsuHitObject d)) - return; - - var fadeOutStartTime = d.HitObject.StartTime - preEmpt + d.FadeInDuration; - var fadeOutDuration = preEmpt * fade_out_duration_multiplier; - - // new duration from completed fade in to end (before fading out) - var longFadeDuration = ((d.HitObject as IHasEndTime)?.EndTime ?? d.HitObject.StartTime) - fadeOutStartTime; - - switch (drawable) - { - case DrawableHitCircle circle: - // we don't want to see the approach circle - circle.ApproachCircle.Hide(); - - // fade out immediately after fade in. - using (drawable.BeginAbsoluteSequence(fadeOutStartTime, true)) - circle.FadeOut(fadeOutDuration); - break; - case DrawableSlider slider: - using (slider.BeginAbsoluteSequence(fadeOutStartTime, true)) - slider.Body.FadeOut(longFadeDuration, Easing.Out); - break; - case DrawableSpinner spinner: - // hide elements we don't care about. - spinner.Disc.Hide(); - spinner.Ticks.Hide(); - spinner.Background.Hide(); - - using (spinner.BeginAbsoluteSequence(fadeOutStartTime + longFadeDuration, true)) - spinner.FadeOut(fadeOutDuration); - break; - } - } - } - - public class OsuModHardRock : ModHardRock, IApplicableToHitObject - { - public override double ScoreMultiplier => 1.06; - public override bool Ranked => true; - - public void ApplyToHitObject(OsuHitObject hitObject) - { - hitObject.Position = new Vector2(hitObject.Position.X, OsuPlayfield.BASE_SIZE.Y - hitObject.Y); - - var slider = hitObject as Slider; - if (slider == null) - return; - - var newControlPoints = new List(); - slider.ControlPoints.ForEach(c => newControlPoints.Add(new Vector2(c.X, OsuPlayfield.BASE_SIZE.Y - c.Y))); - - slider.ControlPoints = newControlPoints; - slider.Curve?.Calculate(); // Recalculate the slider curve - } - } - - public class OsuModSuddenDeath : ModSuddenDeath - { - public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray(); - } - - public class OsuModDaycore : ModDaycore - { - public override double ScoreMultiplier => 0.5; - } - - public class OsuModDoubleTime : ModDoubleTime - { - public override double ScoreMultiplier => 1.12; - } - - public class OsuModRelax : ModRelax - { - public override string Description => "You don't need to click.\nGive your clicking/tapping finger a break from the heat of things."; - public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray(); - } - - public class OsuModHalfTime : ModHalfTime - { - public override double ScoreMultiplier => 0.5; - } - - public class OsuModNightcore : ModNightcore - { - public override double ScoreMultiplier => 1.12; - } - - public class OsuModFlashlight : ModFlashlight - { - public override double ScoreMultiplier => 1.12; - } - - public class OsuModPerfect : ModPerfect - { - } - - public class OsuModSpunOut : Mod - { - public override string Name => "Spun Out"; - public override string ShortenedName => "SO"; - public override FontAwesome Icon => FontAwesome.fa_osu_mod_spunout; - public override string Description => @"Spinners will be automatically completed"; - public override double ScoreMultiplier => 0.9; - public override bool Ranked => true; - public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot) }; - } - - public class OsuModAutopilot : Mod - { - public override string Name => "Autopilot"; - public override string ShortenedName => "AP"; - public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot; - public override string Description => @"Automatic cursor movement - just follow the rhythm."; - public override double ScoreMultiplier => 0; - public override bool Ranked => false; - public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) }; - } - - public class OsuModAutoplay : ModAutoplay - { - public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModSpunOut) }).ToArray(); - - protected override Score CreateReplayScore(Beatmap beatmap) => new Score - { - Replay = new OsuAutoGenerator(beatmap).Generate() - }; - } - - public class OsuModTarget : Mod - { - public override string Name => "Target"; - public override string ShortenedName => "TP"; - public override FontAwesome Icon => FontAwesome.fa_osu_mod_target; - public override string Description => @""; - public override double ScoreMultiplier => 1; - } -} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs new file mode 100644 index 0000000000..0c842143e4 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutopilot.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Graphics; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModAutopilot : Mod + { + public override string Name => "Autopilot"; + public override string ShortenedName => "AP"; + public override FontAwesome Icon => FontAwesome.fa_osu_mod_autopilot; + public override string Description => @"Automatic cursor movement - just follow the rhythm."; + public override double ScoreMultiplier => 0; + public override bool Ranked => false; + public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) }; + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs b/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs new file mode 100644 index 0000000000..42fe95356d --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModAutoplay.cs @@ -0,0 +1,26 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.Replays; +using osu.Game.Rulesets.Scoring; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModAutoplay : ModAutoplay + { + public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot), typeof(OsuModSpunOut) }).ToArray(); + + protected override Score CreateReplayScore(Beatmap beatmap) + { + return new Score + { + Replay = new OsuAutoGenerator(beatmap).Generate() + }; + } + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs new file mode 100644 index 0000000000..eb90338e2f --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDaycore.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModDaycore : ModDaycore + { + public override double ScoreMultiplier => 0.5; + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModDoubleTime.cs b/osu.Game.Rulesets.Osu/Mods/OsuModDoubleTime.cs new file mode 100644 index 0000000000..5a835aac75 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModDoubleTime.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModDoubleTime : ModDoubleTime + { + public override double ScoreMultiplier => 1.12; + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModEasy.cs b/osu.Game.Rulesets.Osu/Mods/OsuModEasy.cs new file mode 100644 index 0000000000..80c83bf5d8 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModEasy.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModEasy : ModEasy + { + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs new file mode 100644 index 0000000000..342c53b41f --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModFlashlight.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModFlashlight : ModFlashlight + { + public override double ScoreMultiplier => 1.12; + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs new file mode 100644 index 0000000000..7d009b0344 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHalfTime.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModHalfTime : ModHalfTime + { + public override double ScoreMultiplier => 0.5; + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs new file mode 100644 index 0000000000..dfbe9ad021 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHardRock.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Objects; +using osu.Game.Rulesets.Osu.UI; +using OpenTK; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModHardRock : ModHardRock, IApplicableToHitObject + { + public override double ScoreMultiplier => 1.06; + public override bool Ranked => true; + + public void ApplyToHitObject(OsuHitObject hitObject) + { + hitObject.Position = new Vector2(hitObject.Position.X, OsuPlayfield.BASE_SIZE.Y - hitObject.Y); + + var slider = hitObject as Slider; + if (slider == null) + return; + + var newControlPoints = new List(); + slider.ControlPoints.ForEach(c => newControlPoints.Add(new Vector2(c.X, OsuPlayfield.BASE_SIZE.Y - c.Y))); + + slider.ControlPoints = newControlPoints; + slider.Curve?.Calculate(); // Recalculate the slider curve + } + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs new file mode 100644 index 0000000000..0356ba9aca --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModHidden.cs @@ -0,0 +1,79 @@ +// 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.Game.Rulesets.Mods; +using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; +using osu.Game.Rulesets.Osu.Objects.Drawables; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModHidden : ModHidden, IApplicableToDrawableHitObjects + { + public override string Description => @"Play with no approach circles and fading notes for a slight score advantage."; + public override double ScoreMultiplier => 1.06; + + private const double fade_in_duration_multiplier = 0.4; + private const double fade_out_duration_multiplier = 0.3; + + private float preEmpt => DrawableOsuHitObject.TIME_PREEMPT; + + public void ApplyToDrawableHitObjects(IEnumerable drawables) + { + foreach (var d in drawables.OfType()) + { + d.ApplyCustomUpdateState += ApplyHiddenState; + d.FadeInDuration = preEmpt * fade_in_duration_multiplier; + } + } + + protected void ApplyHiddenState(DrawableHitObject drawable, ArmedState state) + { + if (!(drawable is DrawableOsuHitObject d)) + return; + + var fadeOutStartTime = d.HitObject.StartTime - preEmpt + d.FadeInDuration; + var fadeOutDuration = preEmpt * fade_out_duration_multiplier; + + // new duration from completed fade in to end (before fading out) + var longFadeDuration = ((d.HitObject as IHasEndTime)?.EndTime ?? d.HitObject.StartTime) - fadeOutStartTime; + + switch (drawable) + { + case DrawableHitCircle circle: + // we don't want to see the approach circle + circle.ApproachCircle.Hide(); + + // fade out immediately after fade in. + using (drawable.BeginAbsoluteSequence(fadeOutStartTime, true)) + { + circle.FadeOut(fadeOutDuration); + } + + break; + case DrawableSlider slider: + using (slider.BeginAbsoluteSequence(fadeOutStartTime, true)) + { + slider.Body.FadeOut(longFadeDuration, Easing.Out); + } + + break; + case DrawableSpinner spinner: + // hide elements we don't care about. + spinner.Disc.Hide(); + spinner.Ticks.Hide(); + spinner.Background.Hide(); + + using (spinner.BeginAbsoluteSequence(fadeOutStartTime + longFadeDuration, true)) + { + spinner.FadeOut(fadeOutDuration); + } + + break; + } + } + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModNightcore.cs b/osu.Game.Rulesets.Osu/Mods/OsuModNightcore.cs new file mode 100644 index 0000000000..aa0acff68d --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModNightcore.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModNightcore : ModNightcore + { + public override double ScoreMultiplier => 1.12; + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModNoFail.cs b/osu.Game.Rulesets.Osu/Mods/OsuModNoFail.cs new file mode 100644 index 0000000000..f94ee484fc --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModNoFail.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModNoFail : ModNoFail + { + public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray(); + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModPerfect.cs b/osu.Game.Rulesets.Osu/Mods/OsuModPerfect.cs new file mode 100644 index 0000000000..886048cd30 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModPerfect.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModPerfect : ModPerfect + { + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs new file mode 100644 index 0000000000..057916c04b --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModRelax.cs @@ -0,0 +1,15 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModRelax : ModRelax + { + public override string Description => "You don't need to click.\nGive your clicking/tapping finger a break from the heat of things."; + public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray(); + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs new file mode 100644 index 0000000000..18b212f781 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs @@ -0,0 +1,20 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using osu.Game.Graphics; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModSpunOut : Mod + { + public override string Name => "Spun Out"; + public override string ShortenedName => "SO"; + public override FontAwesome Icon => FontAwesome.fa_osu_mod_spunout; + public override string Description => @"Spinners will be automatically completed"; + public override double ScoreMultiplier => 0.9; + public override bool Ranked => true; + public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot) }; + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs new file mode 100644 index 0000000000..797e0af0ad --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModSuddenDeath.cs @@ -0,0 +1,14 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System; +using System.Linq; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModSuddenDeath : ModSuddenDeath + { + public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray(); + } +} diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs new file mode 100644 index 0000000000..b2b5130be3 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Mods/OsuModTarget.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Graphics; +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Osu.Mods +{ + public class OsuModTarget : Mod + { + public override string Name => "Target"; + public override string ShortenedName => "TP"; + public override FontAwesome Icon => FontAwesome.fa_osu_mod_target; + public override string Description => @""; + public override double ScoreMultiplier => 1; + } +} diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj index 05dec5a20d..7d6001359a 100644 --- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj +++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj @@ -51,6 +51,21 @@ + + + + + + + + + + + + + + + @@ -108,7 +123,7 @@ - + diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoMod.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoMod.cs deleted file mode 100644 index 8d13954cf4..0000000000 --- a/osu.Game.Rulesets.Taiko/Mods/TaikoMod.cs +++ /dev/null @@ -1,83 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using osu.Game.Beatmaps; -using osu.Game.Rulesets.Mods; -using osu.Game.Rulesets.Scoring; -using osu.Game.Rulesets.Taiko.Objects; -using osu.Game.Rulesets.Taiko.Replays; -using osu.Game.Users; - -namespace osu.Game.Rulesets.Taiko.Mods -{ - public class TaikoModNoFail : ModNoFail - { - - } - - public class TaikoModEasy : ModEasy - { - - } - - public class TaikoModHidden : ModHidden - { - public override string Description => @"The notes fade out before you hit them!"; - public override double ScoreMultiplier => 1.06; - } - - public class TaikoModHardRock : ModHardRock - { - public override double ScoreMultiplier => 1.06; - public override bool Ranked => true; - } - - public class TaikoModSuddenDeath : ModSuddenDeath - { - - } - - public class TaikoModDaycore : ModDaycore - { - public override double ScoreMultiplier => 0.5; - } - - public class TaikoModDoubleTime : ModDoubleTime - { - public override double ScoreMultiplier => 1.12; - } - - public class TaikoModRelax : ModRelax - { - public override string Description => @"Relax! You will no longer get dizzyfied by ninja-like spinners, demanding drumrolls or unexpected katu's."; - } - - public class TaikoModHalfTime : ModHalfTime - { - public override double ScoreMultiplier => 0.5; - } - - public class TaikoModNightcore : ModNightcore - { - public override double ScoreMultiplier => 1.12; - } - - public class TaikoModFlashlight : ModFlashlight - { - public override double ScoreMultiplier => 1.12; - } - - public class TaikoModPerfect : ModPerfect - { - - } - - public class TaikoModAutoplay : ModAutoplay - { - protected override Score CreateReplayScore(Beatmap beatmap) => new Score - { - User = new User { Username = "mekkadosu!" }, - Replay = new TaikoAutoGenerator(beatmap).Generate(), - }; - } -} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs new file mode 100644 index 0000000000..239f0d5a6b --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModAutoplay.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; +using osu.Game.Rulesets.Taiko.Objects; +using osu.Game.Rulesets.Taiko.Replays; +using osu.Game.Users; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModAutoplay : ModAutoplay + { + protected override Score CreateReplayScore(Beatmap beatmap) + { + return new Score + { + User = new User { Username = "mekkadosu!" }, + Replay = new TaikoAutoGenerator(beatmap).Generate(), + }; + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModDaycore.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModDaycore.cs new file mode 100644 index 0000000000..c50878c6a3 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModDaycore.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModDaycore : ModDaycore + { + public override double ScoreMultiplier => 0.5; + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModDoubleTime.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModDoubleTime.cs new file mode 100644 index 0000000000..2ae52b4549 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModDoubleTime.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModDoubleTime : ModDoubleTime + { + public override double ScoreMultiplier => 1.12; + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs new file mode 100644 index 0000000000..1c5e43f411 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModEasy.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModEasy : ModEasy + { + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs new file mode 100644 index 0000000000..a2c6d7f9e0 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModFlashlight.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModFlashlight : ModFlashlight + { + public override double ScoreMultiplier => 1.12; + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModHalfTime.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModHalfTime.cs new file mode 100644 index 0000000000..9813f8b78e --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModHalfTime.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModHalfTime : ModHalfTime + { + public override double ScoreMultiplier => 0.5; + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs new file mode 100644 index 0000000000..ba304c41d8 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModHardRock.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModHardRock : ModHardRock + { + public override double ScoreMultiplier => 1.06; + public override bool Ranked => true; + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModHidden.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModHidden.cs new file mode 100644 index 0000000000..b0ad43b851 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModHidden.cs @@ -0,0 +1,13 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModHidden : ModHidden + { + public override string Description => @"The notes fade out before you hit them!"; + public override double ScoreMultiplier => 1.06; + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModNightcore.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModNightcore.cs new file mode 100644 index 0000000000..0504b7c5b6 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModNightcore.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModNightcore : ModNightcore + { + public override double ScoreMultiplier => 1.12; + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModNoFail.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModNoFail.cs new file mode 100644 index 0000000000..3e10f58bbd --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModNoFail.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModNoFail : ModNoFail + { + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModPerfect.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModPerfect.cs new file mode 100644 index 0000000000..7388283d41 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModPerfect.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModPerfect : ModPerfect + { + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModRelax.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModRelax.cs new file mode 100644 index 0000000000..ec2385bfba --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModRelax.cs @@ -0,0 +1,12 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModRelax : ModRelax + { + public override string Description => @"Relax! You will no longer get dizzyfied by ninja-like spinners, demanding drumrolls or unexpected katu's."; + } +} diff --git a/osu.Game.Rulesets.Taiko/Mods/TaikoModSuddenDeath.cs b/osu.Game.Rulesets.Taiko/Mods/TaikoModSuddenDeath.cs new file mode 100644 index 0000000000..129d181616 --- /dev/null +++ b/osu.Game.Rulesets.Taiko/Mods/TaikoModSuddenDeath.cs @@ -0,0 +1,11 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Mods; + +namespace osu.Game.Rulesets.Taiko.Mods +{ + public class TaikoModSuddenDeath : ModSuddenDeath + { + } +} diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj index 1aed86f8f9..36ac9384cf 100644 --- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj +++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj @@ -49,6 +49,18 @@ + + + + + + + + + + + + @@ -94,7 +106,7 @@ - + From 2518d16a77f97f7ecb5fbcc4e0932b1212ab613a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 9 Jan 2018 21:34:25 +0900 Subject: [PATCH 112/206] Denote unused variable --- osu.Game/Screens/Play/Player.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 87a7c7dd59..f700bf1a03 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -318,9 +318,9 @@ namespace osu.Game.Screens.Play if (!loadedSuccessfully) return; - dimLevel.ValueChanged += value => updateBackgroundElements(); - blurLevel.ValueChanged += value => updateBackgroundElements(); - showStoryboard.ValueChanged += value => updateBackgroundElements(); + dimLevel.ValueChanged += _ => updateBackgroundElements(); + blurLevel.ValueChanged += _ => updateBackgroundElements(); + showStoryboard.ValueChanged += _ => updateBackgroundElements(); updateBackgroundElements(); Content.Alpha = 0; From fcb197f7b6230c26af195c4e1da5347618d81250 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 9 Jan 2018 22:21:15 +0900 Subject: [PATCH 113/206] Simplify logic --- .../Backgrounds/BackgroundScreenBeatmap.cs | 13 ++++--------- osu.Game/Screens/Play/Player.cs | 15 +++++++++------ 2 files changed, 13 insertions(+), 15 deletions(-) diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index dd76ac5421..1ce84289b2 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.Transforms; using OpenTK; using osu.Game.Beatmaps; using osu.Game.Graphics.Backgrounds; @@ -19,10 +20,7 @@ namespace osu.Game.Screens.Backgrounds public WorkingBeatmap Beatmap { - get - { - return beatmap; - } + get { return beatmap; } set { if (beatmap == value && beatmap != null) @@ -56,11 +54,8 @@ namespace osu.Game.Screens.Backgrounds Beatmap = beatmap; } - public void BlurTo(Vector2 sigma, double duration, Easing easing = Easing.None) - { - background?.BlurTo(sigma, duration, easing); - blurTarget = sigma; - } + public TransformSequence BlurTo(Vector2 sigma, double duration, Easing easing = Easing.None) + => background?.BlurTo(blurTarget = sigma, duration, easing); public override bool Equals(BackgroundScreen other) { diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f700bf1a03..79ae8fca30 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -24,10 +24,10 @@ using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Ranking; using osu.Framework.Audio.Sample; using osu.Game.Beatmaps; +using osu.Game.Graphics; using osu.Game.Online.API; using osu.Game.Screens.Play.BreaksOverlay; using osu.Game.Storyboards.Drawables; -using OpenTK.Graphics; namespace osu.Game.Screens.Play { @@ -378,8 +378,9 @@ namespace osu.Game.Screens.Play private void updateBackgroundElements() { + const float duration = 800; + var opacity = 1 - (float)dimLevel; - var blur = new Vector2((float)blurLevel.Value * 25); if (showStoryboard && storyboard == null) initializeStoryboard(true); @@ -387,11 +388,13 @@ namespace osu.Game.Screens.Play var beatmap = Beatmap.Value; var storyboardVisible = showStoryboard && beatmap.Storyboard.HasDrawable; - storyboardContainer.FadeColour(new Color4(opacity, opacity, opacity, 1), 800); - storyboardContainer.FadeTo(storyboardVisible && opacity > 0 ? 1 : 0, 800, Easing.OutQuint); + 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, 800, Easing.OutQuint); - (Background as BackgroundScreenBeatmap)?.BlurTo(blur, 800, Easing.OutQuint); + (Background as BackgroundScreenBeatmap)? + .BlurTo(new Vector2((float)blurLevel.Value * 25), duration, Easing.OutQuint)? + .FadeTo(!storyboardVisible || beatmap.Background == null ? opacity : 0, duration, Easing.OutQuint); } private void fadeOut() From c4490b5fe812b819dae0f218091c03e27caefd84 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 9 Jan 2018 22:24:12 +0900 Subject: [PATCH 114/206] Fix incorrect licence header --- osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs index 50cb1b150c..d406231cc9 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseFruitObjects.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; From 44d821172ab2d60069e95c9986d94eda5f7b1e07 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 9 Jan 2018 16:29:12 +0100 Subject: [PATCH 115/206] tidying up --- osu.Game/Overlays/Social/FilterControl.cs | 1 - osu.Game/Overlays/Social/Header.cs | 13 +++-- osu.Game/Overlays/SocialOverlay.cs | 59 ++++++++++------------- 3 files changed, 31 insertions(+), 42 deletions(-) diff --git a/osu.Game/Overlays/Social/FilterControl.cs b/osu.Game/Overlays/Social/FilterControl.cs index c05c3eb530..382b3fd0e7 100644 --- a/osu.Game/Overlays/Social/FilterControl.cs +++ b/osu.Game/Overlays/Social/FilterControl.cs @@ -21,7 +21,6 @@ namespace osu.Game.Overlays.Social public enum SocialSortCriteria { - Relevance, Rank, Name, Location, diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs index 5d243ad36f..0767e0aec0 100644 --- a/osu.Game/Overlays/Social/Header.cs +++ b/osu.Game/Overlays/Social/Header.cs @@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Social protected override Color4 BackgroundColour => OsuColour.FromHex(@"38202e"); protected override float TabStripWidth => 438; - protected override SocialTab DefaultTab => SocialTab.OnlinePlayers; + protected override SocialTab DefaultTab => SocialTab.AllPlayers; protected override FontAwesome Icon => FontAwesome.fa_users; protected override Drawable CreateHeaderText() @@ -54,13 +54,12 @@ namespace osu.Game.Overlays.Social public enum SocialTab { - Search, - [Description("Players")] - OnlinePlayers = SocialSortCriteria.Rank, + [Description("All Players")] + AllPlayers = SocialSortCriteria.Rank, [Description("Friends")] - OnlineFriends = SocialSortCriteria.Name, - //[Description("Online Team Members")] - //OnlineTeamMembers, + Friends = SocialSortCriteria.Name, + //[Description("Team Members")] + //TeamMembers, //[Description("Chat Channels")] //ChatChannels, } diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 95e588942c..6fffd37456 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -55,37 +55,35 @@ namespace osu.Game.Overlays Filter.Search.Current.ValueChanged += text => { - if (text != string.Empty) + if (!string.IsNullOrEmpty(text)) { - Header.Tabs.Current.Value = SocialTab.Search; + // force searching in players until searching for friends is supported + Header.Tabs.Current.Value = SocialTab.AllPlayers; - if (Filter.Tabs.Current.Value == SocialSortCriteria.Rank) - Filter.Tabs.Current.Value = SocialSortCriteria.Relevance; - } - else - { - Header.Tabs.Current.Value = SocialTab.OnlinePlayers; - - if (Filter.Tabs.Current.Value == SocialSortCriteria.Relevance) + if (Filter.Tabs.Current.Value != SocialSortCriteria.Rank) Filter.Tabs.Current.Value = SocialSortCriteria.Rank; } }; - Filter.DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels; - - // TODO sort our list in some way (either locally or with API call) - //Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += sortOrder => Scheduler.AddOnce(updateSearch); - Header.Tabs.Current.ValueChanged += tab => { - if (tab != SocialTab.Search) - { - //currentQuery.Value = string.Empty; - Filter.Tabs.Current.Value = (SocialSortCriteria)Header.Tabs.Current.Value; - Scheduler.AddOnce(updateSearch); - } + //currentQuery.Value = string.Empty; + Filter.Tabs.Current.Value = (SocialSortCriteria)Header.Tabs.Current.Value; + Scheduler.AddOnce(updateSearch); }; + Filter.Tabs.Current.ValueChanged += sortCriteria => + { + // force searching in players until searching for friends is supported + if (Header.Tabs.Current.Value != SocialTab.AllPlayers && sortCriteria != (SocialSortCriteria)Header.Tabs.Current.Value) + Header.Tabs.Current.Value = SocialTab.AllPlayers; + + Scheduler.AddOnce(updateSearch); + }; + + Filter.DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels; + Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += sortOrder => Scheduler.AddOnce(updateSearch); + //currentQuery.ValueChanged += v => //{ // queryChangedDebounce?.Cancel(); @@ -97,14 +95,6 @@ namespace osu.Game.Overlays //}; //currentQuery.BindTo(Filter.Search.Current); - - Filter.Tabs.Current.ValueChanged += sortCriteria => - { - if (Header.Tabs.Current.Value != SocialTab.Search && sortCriteria != (SocialSortCriteria)Header.Tabs.Current.Value) - Header.Tabs.Current.Value = SocialTab.Search; - - Scheduler.AddOnce(updateSearch); - }; } [BackgroundDependencyLoader] @@ -148,11 +138,12 @@ namespace osu.Game.Overlays }) }; - LoadComponentAsync(newPanels, p => + LoadComponentAsync(newPanels, f => { if(panels != null) ScrollFlow.Remove(panels); + // delay new panels so they don't get added before the old ones are gone Scheduler.AddDelayed(() => ScrollFlow.Add(panels = newPanels), 200); }); } @@ -190,13 +181,13 @@ namespace osu.Game.Overlays switch (Header.Tabs.Current.Value) { - case SocialTab.OnlineFriends: - var friendRequest = new GetFriendsRequest(); + case SocialTab.Friends: + var friendRequest = new GetFriendsRequest(); // TODO filter arguments? friendRequest.Success += updateUsers; api.Queue(getUsersRequest = friendRequest); break; default: - var userRequest = new GetUsersRequest(); // TODO filter??? + var userRequest = new GetUsersRequest(); // TODO filter arguments! userRequest.Success += response => updateUsers(response.Select(r => r.User)); api.Queue(getUsersRequest = userRequest); break; @@ -223,7 +214,7 @@ namespace osu.Game.Overlays break; default: Users = null; - recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); + clearPanels(); break; } } From 4ce125478a533646cb5c48c4652cae99abd729c6 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Tue, 9 Jan 2018 19:03:23 +0100 Subject: [PATCH 116/206] remove unnecessary Schedules one was bugging out when rapidly switching display styles and the other was... unnecessary --- osu.Game/Overlays/SocialOverlay.cs | 12 ++++-------- 1 file changed, 4 insertions(+), 8 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 6fffd37456..8d91ae0c18 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -143,8 +143,7 @@ namespace osu.Game.Overlays if(panels != null) ScrollFlow.Remove(panels); - // delay new panels so they don't get added before the old ones are gone - Scheduler.AddDelayed(() => ScrollFlow.Add(panels = newPanels), 200); + ScrollFlow.Add(panels = newPanels); }); } @@ -197,12 +196,9 @@ namespace osu.Game.Overlays private void updateUsers(IEnumerable newUsers) { - Schedule(() => - { - Users = newUsers; - loading.Hide(); - recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); - }); + Users = newUsers; + loading.Hide(); + recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); } public void APIStateChanged(APIAccess api, APIState state) From 9ec8f130a694c785878cf5b17716f94e73c06a97 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 10 Jan 2018 13:24:26 +0900 Subject: [PATCH 117/206] Ensure changes are only applied when we are the current screen --- osu.Game/Screens/Play/Player.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 79ae8fca30..c24b5e0d2a 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -378,6 +378,8 @@ namespace osu.Game.Screens.Play private void updateBackgroundElements() { + if (!IsCurrentScreen) return; + const float duration = 800; var opacity = 1 - (float)dimLevel; From 17e7f75aca98dc5dc826b35bd29202c9bba841dc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 10 Jan 2018 15:41:13 +0900 Subject: [PATCH 118/206] More osu!-side bindable fixes --- osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs | 2 +- osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs | 2 +- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 4 ++-- osu.Game/Overlays/Settings/SettingsSlider.cs | 4 ++-- osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs | 2 +- 5 files changed, 7 insertions(+), 7 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs b/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs index ce32dbe889..8a64f7c9a4 100644 --- a/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs +++ b/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs @@ -103,7 +103,7 @@ namespace osu.Game.Tests.Visual } private class TestSliderBar : OsuSliderBar - where T : struct, IEquatable + where T : struct, IEquatable, IComparable, IConvertible { public TestSliderBar() { diff --git a/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs b/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs index c4b3a63bf2..af2b9be351 100644 --- a/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs +++ b/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs @@ -152,7 +152,7 @@ namespace osu.Game.Tests.Visual } private class TestSliderBar : OsuSliderBar - where T : struct, IEquatable + where T : struct, IEquatable, IComparable, IConvertible { public TestSliderBar() { diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index e3d9a89bf7..d42efe6678 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -18,7 +18,7 @@ using osu.Framework.Graphics.Shapes; namespace osu.Game.Graphics.UserInterface { public class OsuSliderBar : SliderBar, IHasTooltip, IHasAccentColour - where T : struct, IEquatable + where T : struct, IEquatable, IComparable, IConvertible { private SampleChannel sample; private double lastSampleTime; @@ -69,7 +69,7 @@ namespace osu.Game.Graphics.UserInterface if (bindableInt != null) return bindableInt.Value.ToString("N0"); - return Current.Value.ToString(); + return Current.Value.ToString(CultureInfo.InvariantCulture); } } diff --git a/osu.Game/Overlays/Settings/SettingsSlider.cs b/osu.Game/Overlays/Settings/SettingsSlider.cs index 43f1fa6a02..56aa77a24f 100644 --- a/osu.Game/Overlays/Settings/SettingsSlider.cs +++ b/osu.Game/Overlays/Settings/SettingsSlider.cs @@ -10,12 +10,12 @@ using osu.Game.Graphics.UserInterface; namespace osu.Game.Overlays.Settings { public class SettingsSlider : SettingsSlider> - where T : struct, IEquatable + where T : struct, IEquatable, IComparable, IConvertible { } public class SettingsSlider : SettingsItem - where T : struct, IEquatable + where T : struct, IEquatable, IComparable, IConvertible where U : OsuSliderBar, new() { protected override Drawable CreateControl() => new U diff --git a/osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs b/osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs index e6e909183d..724f28dadf 100644 --- a/osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs +++ b/osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs @@ -11,7 +11,7 @@ using osu.Game.Overlays.Settings; namespace osu.Game.Screens.Play.ReplaySettings { public class ReplaySliderBar : SettingsSlider - where T : struct, IEquatable + where T : struct, IEquatable, IComparable, IConvertible { protected override Drawable CreateControl() => new Sliderbar { From 58626e3b304ab8de44fbd5cef86d8fc145e6a573 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 10 Jan 2018 16:58:10 +0900 Subject: [PATCH 119/206] Allow rulesets to create their own instantiation info --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- .../Tests/TestCaseCatchPlayer.cs | 2 +- .../Tests/TestCaseCatchStacker.cs | 2 +- .../Tests/TestCaseHyperdash.cs | 2 +- .../Tests/TestCasePerformancePoints.cs | 2 +- osu.Game.Rulesets.Mania/ManiaRuleset.cs | 2 +- .../Tests/TestCasePerformancePoints.cs | 2 +- osu.Game.Rulesets.Osu/OsuRuleset.cs | 2 +- .../Tests/TestCasePerformancePoints.cs | 2 +- osu.Game.Rulesets.Taiko/TaikoRuleset.cs | 2 +- .../Tests/TestCasePerformancePoints.cs | 2 +- osu.Game.Tests/Visual/TestCaseGamefield.cs | 8 ++-- osu.Game/Beatmaps/DummyWorkingBeatmap.cs | 2 +- osu.Game/Rulesets/Ruleset.cs | 16 +++++++- osu.Game/Rulesets/RulesetStore.cs | 27 +++----------- osu.Game/Tests/Visual/TestCasePlayer.cs | 37 ++++++++++--------- 16 files changed, 54 insertions(+), 58 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 35410a7a77..37525470c2 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 int LegacyID => 2; - public CatchRuleset(RulesetInfo rulesetInfo) + public CatchRuleset(RulesetInfo rulesetInfo = null) : base(rulesetInfo) { } diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs index cadf5b36b0..dbd5e5b36c 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchPlayer.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Catch.Tests [Ignore("getting CI working")] public class TestCaseCatchPlayer : Game.Tests.Visual.TestCasePlayer { - public TestCaseCatchPlayer() : base(typeof(CatchRuleset)) + public TestCaseCatchPlayer() : base(new CatchRuleset()) { } } diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs index fca07408b3..b9fa38f74e 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseCatchStacker.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Catch.Tests public class TestCaseCatchStacker : Game.Tests.Visual.TestCasePlayer { public TestCaseCatchStacker() - : base(typeof(CatchRuleset)) + : base(new CatchRuleset()) { } diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseHyperdash.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseHyperdash.cs index fd8309c2dc..59659b3d0d 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseHyperdash.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseHyperdash.cs @@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Catch.Tests public class TestCaseHyperdash : Game.Tests.Visual.TestCasePlayer { public TestCaseHyperdash() - : base(typeof(CatchRuleset)) + : base(new CatchRuleset()) { } diff --git a/osu.Game.Rulesets.Catch/Tests/TestCasePerformancePoints.cs b/osu.Game.Rulesets.Catch/Tests/TestCasePerformancePoints.cs index 0c66d8d80a..725eb5cf76 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCasePerformancePoints.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCasePerformancePoints.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Catch.Tests public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints { public TestCasePerformancePoints() - : base(new CatchRuleset(new RulesetInfo())) + : base(new CatchRuleset()) { } } diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs index 95708e4d11..b553879ef3 100644 --- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs +++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs @@ -113,7 +113,7 @@ namespace osu.Game.Rulesets.Mania public override int LegacyID => 3; - public ManiaRuleset(RulesetInfo rulesetInfo) + public ManiaRuleset(RulesetInfo rulesetInfo = null) : base(rulesetInfo) { } diff --git a/osu.Game.Rulesets.Mania/Tests/TestCasePerformancePoints.cs b/osu.Game.Rulesets.Mania/Tests/TestCasePerformancePoints.cs index f611ae6f43..c76816db6a 100644 --- a/osu.Game.Rulesets.Mania/Tests/TestCasePerformancePoints.cs +++ b/osu.Game.Rulesets.Mania/Tests/TestCasePerformancePoints.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Mania.Tests public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints { public TestCasePerformancePoints() - : base(new ManiaRuleset(new RulesetInfo())) + : base(new ManiaRuleset()) { } } diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 1ba32f474d..b38f95694f 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 int LegacyID => 0; - public OsuRuleset(RulesetInfo rulesetInfo) + public OsuRuleset(RulesetInfo rulesetInfo = null) : base(rulesetInfo) { } diff --git a/osu.Game.Rulesets.Osu/Tests/TestCasePerformancePoints.cs b/osu.Game.Rulesets.Osu/Tests/TestCasePerformancePoints.cs index 4b3277a4e2..500347c874 100644 --- a/osu.Game.Rulesets.Osu/Tests/TestCasePerformancePoints.cs +++ b/osu.Game.Rulesets.Osu/Tests/TestCasePerformancePoints.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Osu.Tests public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints { public TestCasePerformancePoints() - : base(new OsuRuleset(new RulesetInfo())) + : base(new OsuRuleset()) { } } diff --git a/osu.Game.Rulesets.Taiko/TaikoRuleset.cs b/osu.Game.Rulesets.Taiko/TaikoRuleset.cs index 940fdf4fc9..50cc80db50 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 int LegacyID => 1; - public TaikoRuleset(RulesetInfo rulesetInfo) + public TaikoRuleset(RulesetInfo rulesetInfo = null) : base(rulesetInfo) { } diff --git a/osu.Game.Rulesets.Taiko/Tests/TestCasePerformancePoints.cs b/osu.Game.Rulesets.Taiko/Tests/TestCasePerformancePoints.cs index 639483b196..3d2d97b6d3 100644 --- a/osu.Game.Rulesets.Taiko/Tests/TestCasePerformancePoints.cs +++ b/osu.Game.Rulesets.Taiko/Tests/TestCasePerformancePoints.cs @@ -9,7 +9,7 @@ namespace osu.Game.Rulesets.Taiko.Tests public class TestCasePerformancePoints : Game.Tests.Visual.TestCasePerformancePoints { public TestCasePerformancePoints() - : base(new TaikoRuleset(new RulesetInfo())) + : base(new TaikoRuleset()) { } } diff --git a/osu.Game.Tests/Visual/TestCaseGamefield.cs b/osu.Game.Tests/Visual/TestCaseGamefield.cs index 0eebd29ffe..44f46dea18 100644 --- a/osu.Game.Tests/Visual/TestCaseGamefield.cs +++ b/osu.Game.Tests/Visual/TestCaseGamefield.cs @@ -56,25 +56,25 @@ namespace osu.Game.Tests.Visual Clock = new FramedClock(), Children = new Drawable[] { - new OsuRulesetContainer(new OsuRuleset(new RulesetInfo()), beatmap, false) + new OsuRulesetContainer(new OsuRuleset(), beatmap, false) { Scale = new Vector2(0.5f), Anchor = Anchor.TopLeft, Origin = Anchor.TopLeft }, - new TaikoRulesetContainer(new TaikoRuleset(new RulesetInfo()),beatmap, false) + new TaikoRulesetContainer(new TaikoRuleset(),beatmap, false) { Scale = new Vector2(0.5f), Anchor = Anchor.TopRight, Origin = Anchor.TopRight }, - new CatchRulesetContainer(new CatchRuleset(new RulesetInfo()),beatmap, false) + new CatchRulesetContainer(new CatchRuleset(),beatmap, false) { Scale = new Vector2(0.5f), Anchor = Anchor.BottomLeft, Origin = Anchor.BottomLeft }, - new ManiaRulesetContainer(new ManiaRuleset(new RulesetInfo()),beatmap, false) + new ManiaRulesetContainer(new ManiaRuleset(),beatmap, false) { Scale = new Vector2(0.5f), Anchor = Anchor.BottomRight, diff --git a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs index 0ae6637167..f4a3dacd53 100644 --- a/osu.Game/Beatmaps/DummyWorkingBeatmap.cs +++ b/osu.Game/Beatmaps/DummyWorkingBeatmap.cs @@ -64,7 +64,7 @@ namespace osu.Game.Beatmaps public override string ShortName => "dummy"; - public DummyRuleset(RulesetInfo rulesetInfo) + public DummyRuleset(RulesetInfo rulesetInfo = null) : base(rulesetInfo) { } diff --git a/osu.Game/Rulesets/Ruleset.cs b/osu.Game/Rulesets/Ruleset.cs index 6c5c272eac..4f256621fb 100644 --- a/osu.Game/Rulesets/Ruleset.cs +++ b/osu.Game/Rulesets/Ruleset.cs @@ -34,9 +34,9 @@ namespace osu.Game.Rulesets public Mod GetAutoplayMod() => GetAllMods().First(mod => mod is ModAutoplay); - protected Ruleset(RulesetInfo rulesetInfo) + protected Ruleset(RulesetInfo rulesetInfo = null) { - RulesetInfo = rulesetInfo; + RulesetInfo = rulesetInfo ?? createRulesetInfo(); } /// @@ -88,5 +88,17 @@ namespace osu.Game.Rulesets /// The variant. /// A descriptive name of the variant. public virtual string GetVariantName(int variant) => string.Empty; + + /// + /// Create a ruleset info based on this ruleset. + /// + /// A filled . + private RulesetInfo createRulesetInfo() => new RulesetInfo + { + Name = Description, + ShortName = ShortName, + InstantiationInfo = GetType().AssemblyQualifiedName, + ID = LegacyID + }; } } diff --git a/osu.Game/Rulesets/RulesetStore.cs b/osu.Game/Rulesets/RulesetStore.cs index 76a4c99b86..01e3b6848f 100644 --- a/osu.Game/Rulesets/RulesetStore.cs +++ b/osu.Game/Rulesets/RulesetStore.cs @@ -58,30 +58,21 @@ namespace osu.Game.Rulesets { var context = GetContext(); - var instances = loaded_assemblies.Values.Select(r => (Ruleset)Activator.CreateInstance(r, new RulesetInfo())).ToList(); + var instances = loaded_assemblies.Values.Select(r => (Ruleset)Activator.CreateInstance(r, (RulesetInfo)null)).ToList(); //add all legacy modes in correct order foreach (var r in instances.Where(r => r.LegacyID >= 0).OrderBy(r => r.LegacyID)) { - var rulesetInfo = createRulesetInfo(r); - if (context.RulesetInfo.SingleOrDefault(rsi => rsi.ID == rulesetInfo.ID) == null) - { - context.RulesetInfo.Add(rulesetInfo); - } + if (context.RulesetInfo.SingleOrDefault(rsi => rsi.ID == r.RulesetInfo.ID) == null) + context.RulesetInfo.Add(r.RulesetInfo); } context.SaveChanges(); //add any other modes foreach (var r in instances.Where(r => r.LegacyID < 0)) - { - var us = createRulesetInfo(r); - - var existing = context.RulesetInfo.FirstOrDefault(ri => ri.InstantiationInfo == us.InstantiationInfo); - - if (existing == null) - context.RulesetInfo.Add(us); - } + if (context.RulesetInfo.FirstOrDefault(ri => ri.InstantiationInfo == r.RulesetInfo.InstantiationInfo) == null) + context.RulesetInfo.Add(r.RulesetInfo); context.SaveChanges(); @@ -124,13 +115,5 @@ namespace osu.Game.Rulesets { } } - - private RulesetInfo createRulesetInfo(Ruleset ruleset) => new RulesetInfo - { - Name = ruleset.Description, - ShortName = ruleset.ShortName, - InstantiationInfo = ruleset.GetType().AssemblyQualifiedName, - ID = ruleset.LegacyID - }; } } diff --git a/osu.Game/Tests/Visual/TestCasePlayer.cs b/osu.Game/Tests/Visual/TestCasePlayer.cs index 72c1fc7369..181ed5e0e6 100644 --- a/osu.Game/Tests/Visual/TestCasePlayer.cs +++ b/osu.Game/Tests/Visual/TestCasePlayer.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using System.IO; using System.Linq; using System.Text; @@ -18,24 +17,19 @@ namespace osu.Game.Tests.Visual { public abstract class TestCasePlayer : ScreenTestCase { - private readonly Type ruleset; + private readonly Ruleset ruleset; protected Player Player; private TestWorkingBeatmap working; - /// - /// Create a TestCase which runs through the Player screen. - /// - /// An optional ruleset type which we want to target. If not provided we'll allow all rulesets to be tested. - protected TestCasePlayer(Type ruleset) + protected TestCasePlayer(Ruleset ruleset) { this.ruleset = ruleset; } protected TestCasePlayer() { - } [BackgroundDependencyLoader] @@ -48,14 +42,21 @@ namespace osu.Game.Tests.Visual Depth = int.MaxValue }); - string instantiation = ruleset?.AssemblyQualifiedName; - - foreach (var r in rulesets.AvailableRulesets.Where(rs => instantiation == null || rs.InstantiationInfo == instantiation)) + if (ruleset != null) { Player p = null; - AddStep(r.Name, () => p = loadPlayerFor(r)); + AddStep(ruleset.RulesetInfo.Name, () => p = loadPlayerFor(ruleset)); AddUntilStep(() => p.IsLoaded); } + else + { + foreach (var r in rulesets.AvailableRulesets) + { + Player p = null; + AddStep(r.Name, () => p = loadPlayerFor(r)); + AddUntilStep(() => p.IsLoaded); + } + } } protected virtual Beatmap CreateBeatmap() @@ -69,21 +70,21 @@ namespace osu.Game.Tests.Visual return beatmap; } - private Player loadPlayerFor(RulesetInfo r) + private Player loadPlayerFor(RulesetInfo ri) => loadPlayerFor(ri.CreateInstance()); + + private Player loadPlayerFor(Ruleset r) { var beatmap = CreateBeatmap(); - beatmap.BeatmapInfo.Ruleset = r; - - var instance = r.CreateInstance(); + beatmap.BeatmapInfo.Ruleset = r.RulesetInfo; working = new TestWorkingBeatmap(beatmap); - working.Mods.Value = new[] { instance.GetAllMods().First(m => m is ModNoFail) }; + working.Mods.Value = new[] { r.GetAllMods().First(m => m is ModNoFail) }; if (Player != null) Remove(Player); - var player = CreatePlayer(working, instance); + var player = CreatePlayer(working, r); LoadComponentAsync(player, LoadScreen); From c010b48b2984e1c625505a778d904a2c3b0b79c7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 10 Jan 2018 17:29:16 +0900 Subject: [PATCH 120/206] Remove number format specified from OsuSliderBar, override ToolTipText Better/cleaner solution. --- .../Visual/TestCaseSliderBarPercentage.cs | 123 ------------- .../Visual/TestCaseSliderBarPrecision.cs | 172 ------------------ osu.Game.Tests/osu.Game.Tests.csproj | 2 - .../Graphics/UserInterface/OsuSliderBar.cs | 22 +-- osu.Game/Overlays/Settings/SettingsSlider.cs | 10 - .../Play/ReplaySettings/PlaybackSettings.cs | 2 +- .../Play/ReplaySettings/ReplaySliderBar.cs | 2 + 7 files changed, 5 insertions(+), 328 deletions(-) delete mode 100644 osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs delete mode 100644 osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs diff --git a/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs b/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs deleted file mode 100644 index 8a64f7c9a4..0000000000 --- a/osu.Game.Tests/Visual/TestCaseSliderBarPercentage.cs +++ /dev/null @@ -1,123 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Collections.Generic; -using osu.Framework.Graphics; -using osu.Framework.Configuration; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using OpenTK; - -namespace osu.Game.Tests.Visual -{ - public class TestCaseSliderBarPercentage : OsuTestCase - { - public override IReadOnlyList RequiredTypes => new[] { typeof(OsuSliderBar<>) }; - - private readonly BindableFloat floatValue; - private readonly BindableDouble doubleValue; - - private readonly TestSliderBar floatSliderBar; - private readonly TestSliderBar doubleSliderBar; - - public TestCaseSliderBarPercentage() - { - floatValue = new BindableFloat - { - MinValue = -1, - MaxValue = 1, - }; - - doubleValue = new BindableDouble - { - MinValue = -1, - MaxValue = 1 - }; - - Child = new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - Width = 300, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Children = new Drawable[] - { - floatSliderBar = new TestSliderBar { RelativeSizeAxes = Axes.X }, - doubleSliderBar = new TestSliderBar { RelativeSizeAxes = Axes.X } - } - }; - - floatSliderBar.Current.BindTo(floatValue); - doubleSliderBar.Current.BindTo(doubleValue); - - floatValue.ValueChanged += setValue; - doubleValue.ValueChanged += setValue; - - AddStep("Digits = 0", () => setPercentageDigits(0)); - AddStep("Value = 0", () => setValue(0)); - AddAssert("Check 0%", () => checkExact(0)); - - AddStep("Value = 0.5", () => setValue(0.5)); - AddAssert("Check 50%", () => checkExact(0.5m)); - - AddStep("Value = 0.54", () => setValue(0.54)); - AddAssert("Check 54%", () => checkExact(0.54m)); - - AddStep("Value = 0.544", () => setValue(0.544)); - AddAssert("Check 54%", () => checkExact(0.54m)); - - AddStep("Value = 0.548", () => setValue(0.548)); - AddAssert("Check 55%", () => checkExact(0.55m)); - - AddStep("Digits = 1", () => setPercentageDigits(1)); - AddAssert("Check 54.8%", () => checkExact(0.548m)); - - AddSliderStep("Percentage", -1.0, 1.0, 0.0, setValue); - AddSliderStep("Digits", 0, 7, 1, setPercentageDigits); - } - - private bool checkExact(decimal percentage) - { - string expectedValue = percentage.ToString("P", floatSliderBar.Format); - return floatSliderBar.TooltipText == expectedValue && doubleSliderBar.TooltipText == expectedValue; - } - - private void setValue(T value) - { - floatValue.Value = Convert.ToSingle(value); - doubleValue.Value = Convert.ToDouble(value); - } - - private void setPercentageDigits(int digits) - { - floatSliderBar.Format.PercentDecimalDigits = digits; - doubleSliderBar.Format.PercentDecimalDigits = digits; - - // Make sure that the text referenced in TestSliderBar is updated - // This doesn't break any assertions if missing, but breaks the visual display - floatSliderBar.Current.TriggerChange(); - doubleSliderBar.Current.TriggerChange(); - } - - private class TestSliderBar : OsuSliderBar - where T : struct, IEquatable, IComparable, IConvertible - { - public TestSliderBar() - { - SpriteText valueText; - AddInternal(valueText = new OsuSpriteText - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreLeft, - X = 5, - Text = TooltipText - }); - - Current.ValueChanged += v => valueText.Text = TooltipText; - } - } - } -} diff --git a/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs b/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs deleted file mode 100644 index af2b9be351..0000000000 --- a/osu.Game.Tests/Visual/TestCaseSliderBarPrecision.cs +++ /dev/null @@ -1,172 +0,0 @@ -// Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - -using System; -using System.Collections.Generic; -using osu.Framework.Configuration; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Sprites; -using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; -using OpenTK; - -namespace osu.Game.Tests.Visual -{ - public class TestCaseSliderBarPrecision : OsuTestCase - { - public override IReadOnlyList RequiredTypes => new[] { typeof(OsuSliderBar<>) }; - - private readonly BindableInt intValue; - private readonly BindableFloat floatValue; - private readonly BindableDouble doubleValue; - - private readonly TestSliderBar intSliderBar; - private readonly TestSliderBar floatSliderBar; - private readonly TestSliderBar doubleSliderBar; - - public TestCaseSliderBarPrecision() - { - intValue = new BindableInt - { - MinValue = -1000, - MaxValue = 1000, - }; - - floatValue = new BindableFloat - { - MinValue = -1000, - MaxValue = 1000, - }; - - doubleValue = new BindableDouble - { - MinValue = -1000, - MaxValue = 1000 - }; - - Child = new FillFlowContainer - { - AutoSizeAxes = Axes.Y, - Width = 300, - Direction = FillDirection.Vertical, - Spacing = new Vector2(0, 20), - Children = new Drawable[] - { - intSliderBar = new TestSliderBar { RelativeSizeAxes = Axes.X }, - floatSliderBar = new TestSliderBar { RelativeSizeAxes = Axes.X }, - doubleSliderBar = new TestSliderBar { RelativeSizeAxes = Axes.X } - } - }; - - intSliderBar.Current.BindTo(intValue); - floatSliderBar.Current.BindTo(floatValue); - doubleSliderBar.Current.BindTo(doubleValue); - - intValue.ValueChanged += setValue; - floatValue.ValueChanged += setValue; - doubleValue.ValueChanged += setValue; - - AddStep("Value = 0", () => setValue(0)); - AddStep("Digits = 0", () => setDecimalDigits(0)); - AddAssert("Check all 0", () => checkExact("0")); - - AddStep("Digits = 3", () => setDecimalDigits(3)); - AddAssert("Check 0.000", () => checkExact(0.000m)); - - AddStep("Value = 0.5", () => setValue(0.5)); - AddAssert("Check 0.500", () => checkExact(0.500m)); - - AddStep("Value = 123.4567", () => setValue(123.4567)); - AddAssert("Check 123.457", () => checkExact(123.457m)); - - AddStep("Value = 765.4312", () => setValue(765.4312)); - AddAssert("Check 765.431", () => checkExact(765.431m)); - - AddStep("Value = -12.3456", () => setValue(-12.3456)); - AddAssert("Check -12.346", () => checkExact(-12.346m)); - AddStep("Digits = 1", () => setDecimalDigits(1)); - AddAssert("Check -12.3", () => checkExact(-12.3m)); - AddStep("Digits = 0", () => setDecimalDigits(0)); - AddAssert("Check -12", () => checkExact(-12m)); - - AddStep("Value = -12.8", () => setValue(-12.8)); - AddAssert("Check -13", () => checkExact(-13m)); - AddStep("Digits = 1", () => setDecimalDigits(1)); - AddAssert("Check -12.8", () => checkExact(-12.8m)); - - AddSliderStep("Digits", 0, 7, 1, setDecimalDigits); - } - - /// - /// Checks whether all sliderbar tooltips display an exact value. - /// - /// The expected value that should be displayed. - private bool checkExact(string value) - => intSliderBar.TooltipText == value - && floatSliderBar.TooltipText == value - && doubleSliderBar.TooltipText == value; - - /// - /// Checks whether all sliderbar tooltips display an exact value. - /// - /// The expected value that should be displayed. - private bool checkExact(decimal value) - { - var expectedDecimal = value.ToString(intSliderBar.Format); - - return intSliderBar.TooltipText == Convert.ToInt32(value).ToString("N0") - && floatSliderBar.TooltipText == expectedDecimal - && doubleSliderBar.TooltipText == expectedDecimal; - } - - /// - /// Checks whether all floating-point sliderbar tooltips have a certain number of decimal digits. - /// - /// The expected number of decimal digits. - private bool checkDecimalDigits(int decimals) - => checkDecimalDigits(decimals, floatSliderBar.TooltipText) - && checkDecimalDigits(decimals, doubleSliderBar.TooltipText); - - private bool checkDecimalDigits(int decimals, string value) - => value.Length - value.IndexOf(intSliderBar.Format.NumberDecimalSeparator, StringComparison.InvariantCulture) - 1 == decimals; - - private void setValue(T value) - { - intValue.Value = Convert.ToInt32(value); - floatValue.Value = Convert.ToSingle(value); - doubleValue.Value = Convert.ToDouble(value); - } - - private void setDecimalDigits(int digits) - { - intSliderBar.Format.NumberDecimalDigits = digits; - floatSliderBar.Format.NumberDecimalDigits = digits; - doubleSliderBar.Format.NumberDecimalDigits = digits; - - // Make sure that the text referenced in TestSliderBar is updated - // This doesn't break any assertions if missing, but breaks the visual display - intSliderBar.Current.TriggerChange(); - floatSliderBar.Current.TriggerChange(); - doubleSliderBar.Current.TriggerChange(); - } - - private class TestSliderBar : OsuSliderBar - where T : struct, IEquatable, IComparable, IConvertible - { - public TestSliderBar() - { - SpriteText valueText; - AddInternal(valueText = new OsuSpriteText - { - Anchor = Anchor.CentreRight, - Origin = Anchor.CentreLeft, - X = 5, - Text = TooltipText - }); - - Current.ValueChanged += v => valueText.Text = TooltipText; - } - } - } -} diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj index 53d971a0b3..8c04874e75 100644 --- a/osu.Game.Tests/osu.Game.Tests.csproj +++ b/osu.Game.Tests/osu.Game.Tests.csproj @@ -132,8 +132,6 @@ - - diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index d42efe6678..f574ac13f7 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -28,24 +28,6 @@ namespace osu.Game.Graphics.UserInterface private readonly Box leftBox; private readonly Box rightBox; - private NumberFormatInfo format; - public NumberFormatInfo Format - { - get => format ?? (format = createDefaultFormat()); - set - { - if (format == value) - return; - format = value; - - if (IsLoaded) - { - // Some users may want to see the updated ToolTipText - Current.TriggerChange(); - } - } - } - public virtual string TooltipText { get @@ -60,9 +42,9 @@ namespace osu.Game.Graphics.UserInterface var floatMaxValue = bindableDouble?.MaxValue ?? bindableFloat.MaxValue; if (floatMaxValue == 1 && (floatMinValue == 0 || floatMinValue == -1)) - return floatValue.Value.ToString("P", Format); + return floatValue.Value.ToString("P0"); - return floatValue.Value.ToString("F", Format); + return floatValue.Value.ToString("N1"); } var bindableInt = CurrentNumber as BindableNumber; diff --git a/osu.Game/Overlays/Settings/SettingsSlider.cs b/osu.Game/Overlays/Settings/SettingsSlider.cs index 56aa77a24f..708d9437a5 100644 --- a/osu.Game/Overlays/Settings/SettingsSlider.cs +++ b/osu.Game/Overlays/Settings/SettingsSlider.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; -using System.Globalization; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Graphics.UserInterface; @@ -24,15 +23,6 @@ namespace osu.Game.Overlays.Settings RelativeSizeAxes = Axes.X }; - /// - /// The format that will be used for the tooltip when the sliderbar is hovered. - /// - public NumberFormatInfo Format - { - get => ((U)Control).Format; - set => ((U)Control).Format = value; - } - public float KeyboardStep; [BackgroundDependencyLoader] diff --git a/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs b/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs index 65d83480a0..a63a3415e3 100644 --- a/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs +++ b/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs @@ -59,7 +59,6 @@ namespace osu.Game.Screens.Play.ReplaySettings } }; - sliderbar.Format.NumberDecimalDigits = 2; sliderbar.Bindable.ValueChanged += rateMultiplier => multiplierText.Text = $"{rateMultiplier}x"; } @@ -73,5 +72,6 @@ namespace osu.Game.Screens.Play.ReplaySettings var clockRate = AdjustableClock.Rate; sliderbar.Bindable.ValueChanged += rateMultiplier => AdjustableClock.Rate = clockRate * rateMultiplier; } + } } diff --git a/osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs b/osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs index 724f28dadf..e755e6bfd9 100644 --- a/osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs +++ b/osu.Game/Screens/Play/ReplaySettings/ReplaySliderBar.cs @@ -21,6 +21,8 @@ namespace osu.Game.Screens.Play.ReplaySettings private class Sliderbar : OsuSliderBar { + public override string TooltipText => $"{CurrentNumber.Value}"; + [BackgroundDependencyLoader] private void load(OsuColour colours) { From d1476833619261ed5ff136d6faf33069cf9ad2dc Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 10 Jan 2018 17:39:15 +0900 Subject: [PATCH 121/206] Cleanup --- osu.Game/Graphics/UserInterface/OsuSliderBar.cs | 9 --------- osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs | 1 - 2 files changed, 10 deletions(-) diff --git a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs index f574ac13f7..3c3939586e 100644 --- a/osu.Game/Graphics/UserInterface/OsuSliderBar.cs +++ b/osu.Game/Graphics/UserInterface/OsuSliderBar.cs @@ -113,15 +113,6 @@ namespace osu.Game.Graphics.UserInterface AccentColour = colours.Pink; } - private NumberFormatInfo createDefaultFormat() - { - var nfi = (NumberFormatInfo)NumberFormatInfo.CurrentInfo.Clone(); - nfi.PercentDecimalDigits = 0; - nfi.NumberDecimalDigits = 1; - - return nfi; - } - protected override bool OnHover(InputState state) { Nub.Glowing = true; diff --git a/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs b/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs index a63a3415e3..f8ac653f69 100644 --- a/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs +++ b/osu.Game/Screens/Play/ReplaySettings/PlaybackSettings.cs @@ -72,6 +72,5 @@ namespace osu.Game.Screens.Play.ReplaySettings var clockRate = AdjustableClock.Rate; sliderbar.Bindable.ValueChanged += rateMultiplier => AdjustableClock.Rate = clockRate * rateMultiplier; } - } } From 1c412e233ae48e65bf17f1a0fce1b8181dd93db9 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 10 Jan 2018 18:04:12 +0900 Subject: [PATCH 122/206] Update submodules --- osu-framework | 2 +- osu-resources | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu-framework b/osu-framework index 067fdb8f5b..80bcb82ef8 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 067fdb8f5b0594be1cd30e6bbd43f2ea749904ec +Subproject commit 80bcb82ef8d2e1af1ce077f4a037b6d279ad9e74 diff --git a/osu-resources b/osu-resources index e01f71160f..7724abdf1d 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit e01f71160fb9b3167efcd177c7d7dba9e5d36604 +Subproject commit 7724abdf1d7c9705ba2e3989a9c604e17ccdc871 From f71d086a41e25704ad801fc05c4e04bd6e90a114 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 10 Jan 2018 18:05:19 +0900 Subject: [PATCH 123/206] Fix post-merge issues --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 4 +--- osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj | 3 +-- 2 files changed, 2 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index dd99229cca..7fdabd46c2 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -2,8 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Graphics; -using osu.Game.Rulesets.UI; -using OpenTK; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; @@ -24,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly CatcherArea catcherArea; public CatchPlayfield(BeatmapDifficulty difficulty) - : base(Axes.Y, BASE_WIDTH) + : base(ScrollingDirection.Down, BASE_WIDTH) { Container explodingFruitContainer; diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj index eab39ff002..39f8333413 100644 --- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj +++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj @@ -64,7 +64,6 @@ - @@ -120,7 +119,7 @@ - + From 9036ea92ebc3146124348af74b3c490e6b6d51ac Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 10 Jan 2018 18:29:46 +0900 Subject: [PATCH 124/206] Run child updates for nested hitobjects when parent hitobjects are masked --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 34c34e1d33..e461cb96c5 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -36,6 +36,7 @@ namespace osu.Game.Rulesets.Objects.Drawables public override bool RemoveCompletedTransforms => false; public override bool RemoveWhenNotAlive => false; + protected override bool RequiresChildrenUpdate => true; protected DrawableHitObject(HitObject hitObject) { From 6255aaab687335b73e941fedb89ea72bbe6725f7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Wed, 10 Jan 2018 19:17:43 +0900 Subject: [PATCH 125/206] Per-hitobject lifetime management --- .../Objects/Drawables/DrawableHoldNote.cs | 4 ++++ .../Objects/Drawables/DrawableHoldNoteTick.cs | 4 ---- .../Objects/Drawables/DrawableManiaHitObject.cs | 4 ++++ osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs | 7 +++++++ .../Objects/Drawables/DrawableDrumRoll.cs | 7 +++++++ .../Objects/Drawables/DrawableDrumRollTick.cs | 2 +- .../UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs | 1 - .../UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs | 3 --- 8 files changed, 23 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 8e3159d531..1ed7cc594a 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -251,6 +251,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables }); } + protected override void UpdateState(ArmedState state) + { + } + public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down public override bool OnReleased(ManiaAction action) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index cfe82a2b59..0685c7bb2d 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -38,10 +38,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables RelativeSizeAxes = Axes.X; Size = new Vector2(1); - // Life time managed by the parent DrawableHoldNote - LifetimeStart = double.MinValue; - LifetimeEnd = double.MaxValue; - Children = new[] { glowContainer = new CircularContainer diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs index 5b98d84e68..0a1624b464 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Graphics; using OpenTK.Graphics; using osu.Game.Rulesets.Objects.Drawables; @@ -19,6 +20,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected DrawableManiaHitObject(TObject hitObject, ManiaAction? action = null) : base(hitObject) { + Anchor = Anchor.TopCentre; + Origin = Anchor.TopCentre; + HitObject = hitObject; if (action != null) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs index 1696de2880..101db0205c 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs @@ -78,6 +78,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected override void UpdateState(ArmedState state) { + switch (state) + { + case ArmedState.Hit: + case ArmedState.Miss: + this.FadeOut(100).Expire(); + break; + } } public virtual bool OnPressed(ManiaAction action) diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 564e496af5..0f16f85b63 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -100,6 +100,13 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables protected override void UpdateState(ArmedState state) { + switch (state) + { + case ArmedState.Hit: + case ArmedState.Miss: + this.FadeOut(100).Expire(); + break; + } } } } diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 96485fbc9e..3408a830ed 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables switch (state) { case ArmedState.Hit: - Content.ScaleTo(0, 100, Easing.OutQuint); + Content.ScaleTo(0, 100, Easing.OutQuint).Expire(); break; } } diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs index 0a69d00377..a8e41a951b 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs @@ -28,7 +28,6 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms var startPosition = hitObjectPositions[obj] = positionAt(obj.HitObject.StartTime, timeRange); obj.LifetimeStart = obj.HitObject.StartTime - timeRange - 1000; - obj.LifetimeEnd = ((obj.HitObject as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime) + timeRange + 1000; if (!(obj.HitObject is IHasEndTime endTime)) continue; diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs index be8612ca96..c956766474 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs @@ -4,7 +4,6 @@ using System.Collections.Generic; using osu.Framework.Lists; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; using OpenTK; @@ -26,9 +25,7 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms foreach (var obj in hitObjects) { var controlPoint = controlPointAt(obj.HitObject.StartTime); - obj.LifetimeStart = obj.HitObject.StartTime - timeRange / controlPoint.Multiplier; - obj.LifetimeEnd = ((obj.HitObject as IHasEndTime)?.EndTime ?? obj.HitObject.StartTime) + timeRange / controlPoint.Multiplier; } } From fbffc8bb89d7d4fd4e419e0d878987d44b64732b Mon Sep 17 00:00:00 2001 From: james58899 Date: Wed, 10 Jan 2018 18:55:04 +0800 Subject: [PATCH 126/206] fix load storyboard in osu file --- osu.Game/Beatmaps/BeatmapManager.cs | 11 +++-------- osu.Game/Beatmaps/Formats/Decoder.cs | 7 +++++-- 2 files changed, 8 insertions(+), 10 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index d7356cf100..c34ea13eda 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -696,14 +696,9 @@ namespace osu.Game.Beatmaps try { - Decoder decoder; - using (var stream = new StreamReader(store.GetStream(getPathForFile(BeatmapInfo?.Path)))) - decoder = Decoder.GetDecoder(stream); - - // try for .osb first and fall back to .osu - string storyboardFile = BeatmapSetInfo.StoryboardFile ?? BeatmapInfo.Path; - using (var stream = new StreamReader(store.GetStream(getPathForFile(storyboardFile)))) - return decoder.GetStoryboardDecoder().DecodeStoryboard(stream); + using (var beatmap = new StreamReader(store.GetStream(getPathForFile(BeatmapInfo?.Path)))) + using (var storyboard = new StreamReader(store.GetStream(getPathForFile(BeatmapSetInfo.StoryboardFile)))) + return Decoder.GetDecoder(beatmap).GetStoryboardDecoder().DecodeStoryboard(beatmap, storyboard); } catch { diff --git a/osu.Game/Beatmaps/Formats/Decoder.cs b/osu.Game/Beatmaps/Formats/Decoder.cs index 8eeada66e8..87e33429a4 100644 --- a/osu.Game/Beatmaps/Formats/Decoder.cs +++ b/osu.Game/Beatmaps/Formats/Decoder.cs @@ -70,10 +70,13 @@ namespace osu.Game.Beatmaps.Formats protected abstract void ParseBeatmap(StreamReader stream, Beatmap beatmap); - public virtual Storyboard DecodeStoryboard(StreamReader stream) + public virtual Storyboard DecodeStoryboard(params StreamReader[] streams) { var storyboard = new Storyboard(); - ParseStoryboard(stream, storyboard); + foreach (StreamReader stream in streams) + { + ParseStoryboard(stream, storyboard); + } return storyboard; } From 312f52072bd4762e5cbd998e1fd905f736c13126 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Wed, 10 Jan 2018 16:46:55 +0100 Subject: [PATCH 127/206] enable query change Avatar animation too add forgotten usings --- osu.Game/Overlays/Social/Header.cs | 4 +-- osu.Game/Overlays/SocialOverlay.cs | 42 ++++++++++++------------------ osu.Game/Users/UpdateableAvatar.cs | 2 +- 3 files changed, 19 insertions(+), 29 deletions(-) diff --git a/osu.Game/Overlays/Social/Header.cs b/osu.Game/Overlays/Social/Header.cs index 0767e0aec0..7bb4b4dde9 100644 --- a/osu.Game/Overlays/Social/Header.cs +++ b/osu.Game/Overlays/Social/Header.cs @@ -55,9 +55,9 @@ namespace osu.Game.Overlays.Social public enum SocialTab { [Description("All Players")] - AllPlayers = SocialSortCriteria.Rank, + AllPlayers, [Description("Friends")] - Friends = SocialSortCriteria.Name, + Friends, //[Description("Team Members")] //TeamMembers, //[Description("Chat Channels")] diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 8d91ae0c18..161ff70dc9 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -15,6 +15,8 @@ using osu.Game.Online.API.Requests; using osu.Game.Overlays.SearchableList; using osu.Game.Overlays.Social; using osu.Game.Users; +using osu.Framework.Configuration; +using osu.Framework.Threading; namespace osu.Game.Overlays { @@ -65,36 +67,24 @@ namespace osu.Game.Overlays } }; - Header.Tabs.Current.ValueChanged += tab => - { - //currentQuery.Value = string.Empty; - Filter.Tabs.Current.Value = (SocialSortCriteria)Header.Tabs.Current.Value; - Scheduler.AddOnce(updateSearch); - }; + Header.Tabs.Current.ValueChanged += tab => Scheduler.AddOnce(updateSearch); - Filter.Tabs.Current.ValueChanged += sortCriteria => - { - // force searching in players until searching for friends is supported - if (Header.Tabs.Current.Value != SocialTab.AllPlayers && sortCriteria != (SocialSortCriteria)Header.Tabs.Current.Value) - Header.Tabs.Current.Value = SocialTab.AllPlayers; - - Scheduler.AddOnce(updateSearch); - }; + Filter.Tabs.Current.ValueChanged += sortCriteria => Scheduler.AddOnce(updateSearch); Filter.DisplayStyleControl.DisplayStyle.ValueChanged += recreatePanels; Filter.DisplayStyleControl.Dropdown.Current.ValueChanged += sortOrder => Scheduler.AddOnce(updateSearch); - //currentQuery.ValueChanged += v => - //{ - // queryChangedDebounce?.Cancel(); + currentQuery.ValueChanged += query => + { + queryChangedDebounce?.Cancel(); - // if (string.IsNullOrEmpty(v)) - // Scheduler.AddOnce(updateSearch); - // else - // queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500); - //}; + if (string.IsNullOrEmpty(query)) + Scheduler.AddOnce(updateSearch); + else + queryChangedDebounce = Scheduler.AddDelayed(updateSearch, 500); + }; - //currentQuery.BindTo(Filter.Search.Current); + currentQuery.BindTo(Filter.Search.Current); } [BackgroundDependencyLoader] @@ -159,13 +149,13 @@ namespace osu.Game.Overlays private APIRequest getUsersRequest; - //private readonly Bindable currentQuery = new Bindable(); + private readonly Bindable currentQuery = new Bindable(); - //private ScheduledDelegate queryChangedDebounce; + private ScheduledDelegate queryChangedDebounce; private void updateSearch() { - //queryChangedDebounce?.Cancel(); + queryChangedDebounce?.Cancel(); if (!IsLoaded) return; diff --git a/osu.Game/Users/UpdateableAvatar.cs b/osu.Game/Users/UpdateableAvatar.cs index e58647c7f6..2edd7cbf55 100644 --- a/osu.Game/Users/UpdateableAvatar.cs +++ b/osu.Game/Users/UpdateableAvatar.cs @@ -44,7 +44,7 @@ namespace osu.Game.Users new Avatar(user) { RelativeSizeAxes = Axes.Both, - OnLoadComplete = d => d.FadeInFromZero(400, Easing.Out), + OnLoadComplete = d => d.FadeInFromZero(300, Easing.OutQuint), }) ); } From 6a5a3b01b265878c5fccca36cc80307769c5cfe5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 11 Jan 2018 12:39:06 +0900 Subject: [PATCH 128/206] Fix license headers --- osu.Game/Configuration/ScrollingAlgorithmType.cs | 2 +- .../Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs | 2 +- osu.Game/Rulesets/UI/HitObjectContainer.cs | 2 +- .../UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs | 2 +- .../Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs | 2 +- .../Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs | 2 +- osu.Game/Rulesets/UI/Scrolling/ScrollingDirection.cs | 2 +- osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs | 2 +- 8 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game/Configuration/ScrollingAlgorithmType.cs b/osu.Game/Configuration/ScrollingAlgorithmType.cs index b4a2b8a4a3..8b9d292634 100644 --- a/osu.Game/Configuration/ScrollingAlgorithmType.cs +++ b/osu.Game/Configuration/ScrollingAlgorithmType.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.ComponentModel; diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs index b2a2a25da7..3243f4c23a 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; using osu.Game.Configuration; diff --git a/osu.Game/Rulesets/UI/HitObjectContainer.cs b/osu.Game/Rulesets/UI/HitObjectContainer.cs index e7843c86ca..c26a6cdff0 100644 --- a/osu.Game/Rulesets/UI/HitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/HitObjectContainer.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; using System.Linq; diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs index a8e41a951b..55a0a7c2f3 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using System.Collections.Generic; diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs index 2621ae7d6f..f9863bd299 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; using osu.Game.Rulesets.Objects.Drawables; diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs index c956766474..b2d4289a9a 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; using osu.Framework.Lists; diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingDirection.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingDirection.cs index d89795f4d3..372bdb1030 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingDirection.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingDirection.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE namespace osu.Game.Rulesets.UI.Scrolling { diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 67f2e8aee0..dfa6a40db4 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -1,4 +1,4 @@ -// Copyright (c) 2007-2017 ppy Pty Ltd . +// Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using osu.Framework.Allocation; From 3a869edf36312657761727a26917a3bafb5e7029 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 11 Jan 2018 12:44:17 +0900 Subject: [PATCH 129/206] Add a flag to disable user scroll speed adjustments --- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 1 + osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs | 8 ++++++++ 2 files changed, 9 insertions(+) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index b8e4ede120..3c5093d82f 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -37,6 +37,7 @@ namespace osu.Game.Rulesets.Taiko.UI /// private const float left_area_size = 240; + protected override bool UserScrollSpeedAdjustment => false; private readonly Container hitExplosionContainer; private readonly Container kiaiExplosionContainer; diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index 5be1c8bed7..11185015b8 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -47,6 +47,11 @@ namespace osu.Game.Rulesets.UI.Scrolling MaxValue = time_span_max }; + /// + /// Whether the player can change . + /// + protected virtual bool UserScrollSpeedAdjustment => true; + /// /// The container that contains the s and s. /// @@ -92,6 +97,9 @@ namespace osu.Game.Rulesets.UI.Scrolling protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { + if (!UserScrollSpeedAdjustment) + return false; + if (state.Keyboard.ControlPressed) { switch (args.Key) From a6d8b28221910993005d6adbbcc5b0447b5a1511 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 11 Jan 2018 13:40:46 +0900 Subject: [PATCH 130/206] Add OSD + config value for scroll speed --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 5 ++++- osu.Game/Configuration/OsuConfigManager.cs | 4 +++- osu.Game/Overlays/OnScreenDisplay.cs | 6 +++++- osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs | 7 +++++-- 4 files changed, 17 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 919518dbe8..532be2759f 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -15,6 +15,7 @@ using osu.Framework.Configuration; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Framework.Graphics.Shapes; +using osu.Game.Configuration; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.UI.Scrolling; @@ -161,8 +162,10 @@ namespace osu.Game.Rulesets.Mania.UI } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, OsuConfigManager config) { + config.BindWith(OsuSetting.UserScrollSpeed, VisibleTimeRange); + normalColumnColours = new List { colours.RedDark, diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 13213a54a1..26879782fc 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -73,6 +73,7 @@ namespace osu.Game.Configuration Set(OsuSetting.FloatingComments, false); Set(OsuSetting.ScrollingAlgorithm, ScrollingAlgorithmType.Global); + Set(OsuSetting.UserScrollSpeed, 1500.0, 50.0, 10000.0); // Update Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); @@ -119,6 +120,7 @@ namespace osu.Game.Configuration ChatDisplayHeight, Version, ShowConvertedBeatmaps, - ScrollingAlgorithm + ScrollingAlgorithm, + UserScrollSpeed } } diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 6a1bd8e182..4f3f03c749 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -14,6 +14,7 @@ using osu.Game.Graphics; using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; +using osu.Game.Configuration; using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays @@ -115,7 +116,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(FrameworkConfigManager frameworkConfig) + private void load(FrameworkConfigManager frameworkConfig, OsuConfigManager osuConfig) { trackSetting(frameworkConfig.GetBindable(FrameworkSetting.FrameSync), v => display(v, "Frame Limiter", v.GetDescription(), "Ctrl+F7")); trackSetting(frameworkConfig.GetBindable(FrameworkSetting.AudioDevice), v => display(v, "Audio Device", string.IsNullOrEmpty(v) ? "Default" : v, v)); @@ -135,6 +136,9 @@ namespace osu.Game.Overlays }); trackSetting(frameworkConfig.GetBindable(FrameworkSetting.WindowMode), v => display(v, "Screen Mode", v.ToString(), "Alt+Enter")); + + // Todo: This should be part of the ruleset-specific OSD + trackSetting(osuConfig.GetBindable(OsuSetting.UserScrollSpeed), v => display(v, "Scroll Speed", $"{v:N0}ms", "Ctrl+(+/-) to change")); } private readonly List references = new List(); diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index 11185015b8..fa04b7f137 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -102,13 +103,15 @@ namespace osu.Game.Rulesets.UI.Scrolling if (state.Keyboard.ControlPressed) { + var lastValue = Transforms.OfType().LastOrDefault()?.EndValue ?? VisibleTimeRange.Value; + switch (args.Key) { case Key.Minus: - transformVisibleTimeRangeTo(VisibleTimeRange + time_span_step, 200, Easing.OutQuint); + transformVisibleTimeRangeTo(lastValue + time_span_step, 200, Easing.OutQuint); break; case Key.Plus: - transformVisibleTimeRangeTo(VisibleTimeRange - time_span_step, 200, Easing.OutQuint); + transformVisibleTimeRangeTo(lastValue - time_span_step, 200, Easing.OutQuint); break; } } From 4fa038aa27fcde705f2f53ae2bfb8b71026df15b Mon Sep 17 00:00:00 2001 From: james58899 Date: Thu, 11 Jan 2018 13:53:41 +0800 Subject: [PATCH 131/206] if not storyboard file --- osu.Game/Beatmaps/BeatmapManager.cs | 17 +++++++++++------ 1 file changed, 11 insertions(+), 6 deletions(-) diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index c34ea13eda..d342e495e2 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -691,14 +691,19 @@ namespace osu.Game.Beatmaps protected override Storyboard GetStoryboard() { - if (BeatmapInfo?.Path == null && BeatmapSetInfo?.StoryboardFile == null) - return new Storyboard(); - try { - using (var beatmap = new StreamReader(store.GetStream(getPathForFile(BeatmapInfo?.Path)))) - using (var storyboard = new StreamReader(store.GetStream(getPathForFile(BeatmapSetInfo.StoryboardFile)))) - return Decoder.GetDecoder(beatmap).GetStoryboardDecoder().DecodeStoryboard(beatmap, storyboard); + + using (var beatmap = new StreamReader(store.GetStream(getPathForFile(BeatmapInfo.Path)))) + { + Decoder decoder = Decoder.GetDecoder(beatmap); + + if (BeatmapSetInfo?.StoryboardFile == null) + return decoder.GetStoryboardDecoder().DecodeStoryboard(beatmap); + + using (var storyboard = new StreamReader(store.GetStream(getPathForFile(BeatmapSetInfo.StoryboardFile)))) + return decoder.GetStoryboardDecoder().DecodeStoryboard(beatmap, storyboard); + } } catch { From 9d00e5bb7dfc103003f11a73bda6d435b345686c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 11 Jan 2018 15:08:30 +0900 Subject: [PATCH 132/206] Make ScrollingHitObjectContainer handle nested hitobjects --- .../Objects/Drawable/DrawableJuiceStream.cs | 2 +- .../Objects/Drawables/DrawableHoldNote.cs | 24 +---------- .../Objects/Drawables/DrawableHoldNoteTick.cs | 3 -- .../Objects/Drawables/DrawableDrumRoll.cs | 7 +--- .../Objects/Drawables/DrawableDrumRollTick.cs | 12 ------ .../Objects/Drawables/DrawableHitObject.cs | 41 +++++++++++++------ .../Algorithms/GlobalScrollingAlgorithm.cs | 34 ++++++++------- .../Algorithms/LocalScrollingAlgorithm.cs | 6 +++ 8 files changed, 59 insertions(+), 70 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 031b70924d..dcb7fdb823 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable } } - protected override void AddNested(DrawableHitObject h) + protected override void AddNested(DrawableHitObject h) { ((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false; dropletContainer.Add(h); diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 1ed7cc594a..6748bc22e6 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -7,7 +7,6 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Framework.Graphics; using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces; using OpenTK.Graphics; -using OpenTK; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Mania.Judgements; using osu.Framework.Extensions.IEnumerableExtensions; @@ -59,12 +58,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Origin = Anchor.TopCentre, RelativeSizeAxes = Axes.X, }, - tickContainer = new Container - { - RelativeSizeAxes = Axes.Both, - RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime), - RelativeChildSize = new Vector2(1, (float)HitObject.Duration) - }, + tickContainer = new Container { RelativeSizeAxes = Axes.Both }, head = new DrawableHeadNote(this, action) { Anchor = Anchor.TopCentre, @@ -72,7 +66,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables }, tail = new DrawableTailNote(this, action) { - Anchor = Anchor.BottomCentre, + Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre } }); @@ -174,13 +168,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { this.holdNote = holdNote; - RelativePositionAxes = Axes.None; - Y = 0; - - // Life time managed by the parent DrawableHoldNote - LifetimeStart = double.MinValue; - LifetimeEnd = double.MaxValue; - GlowPiece.Alpha = 0; } @@ -213,13 +200,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables { this.holdNote = holdNote; - RelativePositionAxes = Axes.None; - Y = 0; - - // Life time managed by the parent DrawableHoldNote - LifetimeStart = double.MinValue; - LifetimeEnd = double.MaxValue; - GlowPiece.Alpha = 0; } diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs index 0685c7bb2d..f9c0b96d37 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs @@ -32,9 +32,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables Anchor = Anchor.TopCentre; Origin = Anchor.TopCentre; - RelativePositionAxes = Axes.Y; - Y = (float)HitObject.StartTime; - RelativeSizeAxes = Axes.X; Size = new Vector2(1); diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 0f16f85b63..2fa6c8ed95 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs @@ -37,12 +37,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables RelativeSizeAxes = Axes.Y; Container tickContainer; - MainPiece.Add(tickContainer = new Container - { - RelativeSizeAxes = Axes.Both, - RelativeChildOffset = new Vector2((float)HitObject.StartTime, 0), - RelativeChildSize = new Vector2((float)HitObject.Duration, 1) - }); + MainPiece.Add(tickContainer = new Container { RelativeSizeAxes = Axes.Both }); foreach (var tick in drumRoll.NestedHitObjects.OfType()) { diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs index 3408a830ed..bc5abce245 100644 --- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs +++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs @@ -15,23 +15,11 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables public DrawableDrumRollTick(DrumRollTick tick) : base(tick) { - // Because ticks aren't added by the ScrollingPlayfield, we need to set the following properties ourselves - RelativePositionAxes = Axes.X; - X = (float)tick.StartTime; - FillMode = FillMode.Fit; } public override bool DisplayJudgement => false; - protected override void LoadComplete() - { - base.LoadComplete(); - - // We need to set this here because RelativeSizeAxes won't/can't set our size by default with a different RelativeChildSize - Width *= Parent.RelativeChildSize.X; - } - protected override TaikoPiece CreateMainPiece() => new TickPiece { Filled = HitObject.FirstTick diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index e461cb96c5..13329a1470 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -38,11 +38,30 @@ namespace osu.Game.Rulesets.Objects.Drawables public override bool RemoveWhenNotAlive => false; protected override bool RequiresChildrenUpdate => true; + public virtual bool AllJudged => false; + protected DrawableHitObject(HitObject hitObject) { HitObject = hitObject; } + /// + /// Processes this , checking if any judgements have occurred. + /// + /// Whether the user triggered this process. + /// Whether a judgement has occurred from this or any nested s. + protected internal virtual bool UpdateJudgement(bool userTriggered) => false; + + private List nestedHitObjects; + public IReadOnlyList NestedHitObjects => nestedHitObjects; + + protected virtual void AddNested(DrawableHitObject h) + { + if (nestedHitObjects == null) + nestedHitObjects = new List(); + nestedHitObjects.Add(h); + } + /// /// The screen-space point that causes this to be selected in the Editor. /// @@ -145,7 +164,7 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// Whether this and all of its nested s have been judged. /// - public bool AllJudged => (!ProvidesJudgement || judgementFinalized) && (NestedHitObjects?.All(h => h.AllJudged) ?? true); + public sealed override bool AllJudged => (!ProvidesJudgement || judgementFinalized) && (NestedHitObjects?.All(h => h.AllJudged) ?? true); /// /// Notifies that a new judgement has occurred for this . @@ -181,7 +200,7 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// Whether the user triggered this process. /// Whether a judgement has occurred from this or any nested s. - protected bool UpdateJudgement(bool userTriggered) + protected internal sealed override bool UpdateJudgement(bool userTriggered) { judgementOccurred = false; @@ -238,18 +257,16 @@ namespace osu.Game.Rulesets.Objects.Drawables UpdateJudgement(false); } - private List> nestedHitObjects; - protected IEnumerable> NestedHitObjects => nestedHitObjects; - - protected virtual void AddNested(DrawableHitObject h) + protected override void AddNested(DrawableHitObject h) { - if (nestedHitObjects == null) - nestedHitObjects = new List>(); + base.AddNested(h); - h.OnJudgement += (d, j) => OnJudgement?.Invoke(d, j); - h.OnJudgementRemoved += (d, j) => OnJudgementRemoved?.Invoke(d, j); - h.ApplyCustomUpdateState += (d, s) => ApplyCustomUpdateState?.Invoke(d, s); - nestedHitObjects.Add(h); + if (!(h is DrawableHitObject hWithJudgement)) + return; + + hWithJudgement.OnJudgement += (d, j) => OnJudgement?.Invoke(d, j); + hWithJudgement.OnJudgementRemoved += (d, j) => OnJudgementRemoved?.Invoke(d, j); + hWithJudgement.ApplyCustomUpdateState += (d, s) => ApplyCustomUpdateState?.Invoke(d, s); } /// diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs index 55a0a7c2f3..c1347ad122 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs @@ -29,22 +29,25 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms obj.LifetimeStart = obj.HitObject.StartTime - timeRange - 1000; - if (!(obj.HitObject is IHasEndTime endTime)) - continue; - - var diff = positionAt(endTime.EndTime, timeRange) - startPosition; - - switch (direction) + if (obj.HitObject is IHasEndTime endTime) { - case ScrollingDirection.Up: - case ScrollingDirection.Down: - obj.Height = (float)(diff * length.Y); - break; - case ScrollingDirection.Left: - case ScrollingDirection.Right: - obj.Width = (float)(diff * length.X); - break; + var diff = positionAt(endTime.EndTime, timeRange) - startPosition; + + switch (direction) + { + case ScrollingDirection.Up: + case ScrollingDirection.Down: + obj.Height = (float)(diff * length.Y); + break; + case ScrollingDirection.Left: + case ScrollingDirection.Right: + obj.Width = (float)(diff * length.X); + break; + } } + + if (obj.NestedHitObjects != null) + ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); } } @@ -71,6 +74,9 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms obj.X = (float)(-finalPosition * length.X); break; } + + if (obj.NestedHitObjects != null) + ComputePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); } } diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs index b2d4289a9a..ecb7aaff95 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs @@ -26,6 +26,9 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms { var controlPoint = controlPointAt(obj.HitObject.StartTime); obj.LifetimeStart = obj.HitObject.StartTime - timeRange / controlPoint.Multiplier; + + if (obj.NestedHitObjects != null) + ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); } } @@ -52,6 +55,9 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms obj.X = (float)(-position * length.X); break; } + + if (obj.NestedHitObjects != null) + ComputePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); } } From 428f8b6670b2a7b55861de4dc63d53389514a320 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 11 Jan 2018 15:08:46 +0900 Subject: [PATCH 133/206] Fix up license header --- osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index 4f2e895e9d..b8e0934928 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -1,5 +1,5 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . -// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu-framework/master/LICENCE +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; using System.Collections.Generic; From 9ae67b519b6bb8f81dab49efa465c6004e5a5981 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 11 Jan 2018 15:25:15 +0900 Subject: [PATCH 134/206] Optimise nested hitobject position computations --- .../UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs | 6 +++--- .../UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs | 6 +++--- 2 files changed, 6 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs index c1347ad122..ed156ecfd5 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs @@ -47,7 +47,10 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms } if (obj.NestedHitObjects != null) + { ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); + ComputePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); + } } } @@ -74,9 +77,6 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms obj.X = (float)(-finalPosition * length.X); break; } - - if (obj.NestedHitObjects != null) - ComputePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); } } diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs index ecb7aaff95..96a85c5f9f 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs @@ -28,7 +28,10 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms obj.LifetimeStart = obj.HitObject.StartTime - timeRange / controlPoint.Multiplier; if (obj.NestedHitObjects != null) + { ComputeInitialStates(obj.NestedHitObjects, direction, timeRange, length); + ComputePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); + } } } @@ -55,9 +58,6 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms obj.X = (float)(-position * length.X); break; } - - if (obj.NestedHitObjects != null) - ComputePositions(obj.NestedHitObjects, direction, obj.HitObject.StartTime, timeRange, length); } } From d998936e9eaa57a276c3d371496c6dc3e95f0338 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 11 Jan 2018 15:50:44 +0900 Subject: [PATCH 135/206] Fix testcase errors --- osu.Game/Rulesets/UI/Playfield.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 25a7adb5a7..a1d07d9a03 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -49,14 +49,14 @@ namespace osu.Game.Rulesets.UI } } }); + + HitObjects = CreateHitObjectContainer(); + HitObjects.RelativeSizeAxes = Axes.Both; } [BackgroundDependencyLoader] private void load() { - HitObjects = CreateHitObjectContainer(); - HitObjects.RelativeSizeAxes = Axes.Both; - Add(HitObjects); } From ab762045d608655c6495298544ed62c5545f6b36 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 11 Jan 2018 16:51:46 +0900 Subject: [PATCH 136/206] Move back to using load(), fix testcase --- .../Visual/TestCaseEditorSelectionLayer.cs | 39 +++--- .../Visual/TestCaseScrollingHitObjects.cs | 114 ++++++++++-------- osu.Game/Rulesets/UI/Playfield.cs | 6 +- 3 files changed, 90 insertions(+), 69 deletions(-) diff --git a/osu.Game.Tests/Visual/TestCaseEditorSelectionLayer.cs b/osu.Game.Tests/Visual/TestCaseEditorSelectionLayer.cs index b318d4afd3..f236182939 100644 --- a/osu.Game.Tests/Visual/TestCaseEditorSelectionLayer.cs +++ b/osu.Game.Tests/Visual/TestCaseEditorSelectionLayer.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using osu.Framework.Allocation; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -18,26 +19,10 @@ namespace osu.Game.Tests.Visual { public override IReadOnlyList RequiredTypes => new[] { typeof(SelectionLayer) }; - public TestCaseEditorSelectionLayer() + [BackgroundDependencyLoader] + private void load() { - var playfield = new OsuEditPlayfield - { - new DrawableHitCircle(new HitCircle { Position = new Vector2(256, 192), Scale = 0.5f }), - new DrawableHitCircle(new HitCircle { Position = new Vector2(344, 148), Scale = 0.5f }), - new DrawableSlider(new Slider - { - ControlPoints = new List - { - new Vector2(128, 256), - new Vector2(344, 256), - }, - Distance = 400, - Position = new Vector2(128, 256), - Velocity = 1, - TickDistance = 100, - Scale = 0.5f - }) - }; + var playfield = new OsuEditPlayfield(); Children = new Drawable[] { @@ -49,6 +34,22 @@ namespace osu.Game.Tests.Visual }, new SelectionLayer(playfield) }; + + playfield.Add(new DrawableHitCircle(new HitCircle { Position = new Vector2(256, 192), Scale = 0.5f })); + playfield.Add(new DrawableHitCircle(new HitCircle { Position = new Vector2(344, 148), Scale = 0.5f })); + playfield.Add(new DrawableSlider(new Slider + { + ControlPoints = new List + { + new Vector2(128, 256), + new Vector2(344, 256), + }, + Distance = 400, + Position = new Vector2(128, 256), + Velocity = 1, + TickDistance = 100, + Scale = 0.5f + })); } } } diff --git a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs index b8e0934928..21d967c3e3 100644 --- a/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs +++ b/osu.Game.Tests/Visual/TestCaseScrollingHitObjects.cs @@ -3,7 +3,7 @@ using System; using System.Collections.Generic; -using osu.Framework.Configuration; +using osu.Framework.Extensions.IEnumerableExtensions; using OpenTK; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -13,7 +13,6 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; -using OpenTK.Graphics; namespace osu.Game.Tests.Visual { @@ -21,39 +20,29 @@ namespace osu.Game.Tests.Visual { public override IReadOnlyList RequiredTypes => new[] { typeof(Playfield) }; - private readonly List playfields = new List(); + private readonly TestPlayfield[] playfields = new TestPlayfield[4]; public TestCaseScrollingHitObjects() { - playfields.Add(new TestPlayfield(ScrollingDirection.Down)); - playfields.Add(new TestPlayfield(ScrollingDirection.Right)); - - playfields.ForEach(p => p.HitObjects.AddControlPoint(new MultiplierControlPoint(double.MinValue))); - - Add(new Container + Add(new GridContainer { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, RelativeSizeAxes = Axes.Both, - Size = new Vector2(0.85f), - Masking = true, - BorderColour = Color4.White, - BorderThickness = 2, - MaskingSmoothness = 1, - Children = new Drawable[] + Content = new[] { - new Box + new Drawable[] { - Name = "Background", - RelativeSizeAxes = Axes.Both, - Alpha = 0.35f, + playfields[0] = new TestPlayfield(ScrollingDirection.Up), + playfields[1] = new TestPlayfield(ScrollingDirection.Down) }, - playfields[0], - playfields[1] + new Drawable[] + { + playfields[2] = new TestPlayfield(ScrollingDirection.Left), + playfields[3] = new TestPlayfield(ScrollingDirection.Right) + } } }); - AddSliderStep("Time range", 100, 10000, 5000, v => playfields.ForEach(p => p.TimeRange.Value = v)); + AddSliderStep("Time range", 100, 10000, 5000, v => playfields.ForEach(p => p.VisibleTimeRange.Value = v)); AddStep("Add control point", () => addControlPoint(Time.Current + 5000)); } @@ -61,6 +50,8 @@ namespace osu.Game.Tests.Visual { base.LoadComplete(); + playfields.ForEach(p => p.HitObjects.AddControlPoint(new MultiplierControlPoint(0))); + for (int i = 0; i <= 5000; i += 1000) addHitObject(Time.Current + i); @@ -71,10 +62,10 @@ namespace osu.Game.Tests.Visual { playfields.ForEach(p => { - p.Add(new TestDrawableHitObject(time) - { - Anchor = p.Direction == ScrollingDirection.Right ? Anchor.CentreRight : Anchor.BottomCentre - }); + var hitObject = new TestDrawableHitObject(time); + setAnchor(hitObject, p); + + p.Add(hitObject); }); } @@ -86,10 +77,12 @@ namespace osu.Game.Tests.Visual p.HitObjects.AddControlPoint(new MultiplierControlPoint(time + 2000) { DifficultyPoint = { SpeedMultiplier = 2 } }); p.HitObjects.AddControlPoint(new MultiplierControlPoint(time + 3000) { DifficultyPoint = { SpeedMultiplier = 1 } }); - TestDrawableControlPoint createDrawablePoint(double t) => new TestDrawableControlPoint(t) + TestDrawableControlPoint createDrawablePoint(double t) { - Anchor = p.Direction == ScrollingDirection.Right ? Anchor.CentreRight : Anchor.BottomCentre - }; + var obj = new TestDrawableControlPoint(p.Direction, t); + setAnchor(obj, p); + return obj; + } p.Add(createDrawablePoint(time)); p.Add(createDrawablePoint(time + 2000)); @@ -97,12 +90,28 @@ namespace osu.Game.Tests.Visual }); } + private void setAnchor(DrawableHitObject obj, TestPlayfield playfield) + { + switch (playfield.Direction) + { + case ScrollingDirection.Up: + obj.Anchor = Anchor.TopCentre; + break; + case ScrollingDirection.Down: + obj.Anchor = Anchor.BottomCentre; + break; + case ScrollingDirection.Left: + obj.Anchor = Anchor.CentreLeft; + break; + case ScrollingDirection.Right: + obj.Anchor = Anchor.CentreRight; + break; + } + } private class TestPlayfield : ScrollingPlayfield { - public readonly BindableDouble TimeRange = new BindableDouble(5000); - public readonly ScrollingDirection Direction; public TestPlayfield(ScrollingDirection direction) @@ -110,34 +119,45 @@ namespace osu.Game.Tests.Visual { Direction = direction; - HitObjects.TimeRange.BindTo(TimeRange); + Padding = new MarginPadding(2); + ScaledContent.Masking = true; + + AddInternal(new Box + { + RelativeSizeAxes = Axes.Both, + Alpha = 0.5f, + Depth = float.MaxValue + }); } } private class TestDrawableControlPoint : DrawableHitObject { - private readonly Box box; - - public TestDrawableControlPoint(double time) + public TestDrawableControlPoint(ScrollingDirection direction, double time) : base(new HitObject { StartTime = time }) { Origin = Anchor.Centre; - Add(box = new Box + Add(new Box { Anchor = Anchor.Centre, Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both }); - } - protected override void Update() - { - base.Update(); - - RelativeSizeAxes = (Anchor & Anchor.x2) > 0 ? Axes.Y : Axes.X; - Size = new Vector2(1); - - box.Size = DrawSize; + switch (direction) + { + case ScrollingDirection.Up: + case ScrollingDirection.Down: + RelativeSizeAxes = Axes.X; + Height = 2; + break; + case ScrollingDirection.Left: + case ScrollingDirection.Right: + RelativeSizeAxes = Axes.Y; + Width = 2; + break; + } } protected override void UpdateState(ArmedState state) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index a1d07d9a03..25a7adb5a7 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -49,14 +49,14 @@ namespace osu.Game.Rulesets.UI } } }); - - HitObjects = CreateHitObjectContainer(); - HitObjects.RelativeSizeAxes = Axes.Both; } [BackgroundDependencyLoader] private void load() { + HitObjects = CreateHitObjectContainer(); + HitObjects.RelativeSizeAxes = Axes.Both; + Add(HitObjects); } From 86581b645163a83c0cc9886ca16f015bf812ba98 Mon Sep 17 00:00:00 2001 From: Dan Balasescu <1329837+smoogipoo@users.noreply.github.com> Date: Thu, 11 Jan 2018 17:02:09 +0900 Subject: [PATCH 137/206] Remove extra braces --- osu.Game/Beatmaps/Formats/Decoder.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Beatmaps/Formats/Decoder.cs b/osu.Game/Beatmaps/Formats/Decoder.cs index 87e33429a4..1aae52208a 100644 --- a/osu.Game/Beatmaps/Formats/Decoder.cs +++ b/osu.Game/Beatmaps/Formats/Decoder.cs @@ -74,9 +74,7 @@ namespace osu.Game.Beatmaps.Formats { var storyboard = new Storyboard(); foreach (StreamReader stream in streams) - { ParseStoryboard(stream, storyboard); - } return storyboard; } From c5c33e20bf86d3410ce939558dedff409693b669 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 11 Jan 2018 19:03:01 +0900 Subject: [PATCH 138/206] OverlayContainer changes in-line with framework --- .../Graphics/Containers/OsuFocusedOverlayContainer.cs | 9 --------- 1 file changed, 9 deletions(-) diff --git a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs index 648985e4b1..ec461b86fd 100644 --- a/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs +++ b/osu.Game/Graphics/Containers/OsuFocusedOverlayContainer.cs @@ -33,15 +33,6 @@ namespace osu.Game.Graphics.Containers // receive input outside our bounds so we can trigger a close event on ourselves. public override bool ReceiveMouseInputAt(Vector2 screenSpacePos) => BlockScreenWideMouse || base.ReceiveMouseInputAt(screenSpacePos); - protected override bool OnWheel(InputState state) - { - // always allow wheel to pass through to stuff outside our DrawRectangle. - if (!base.ReceiveMouseInputAt(state.Mouse.NativeState.Position)) - return false; - - return BlockPassThroughMouse; - } - protected override bool OnClick(InputState state) { if (!base.ReceiveMouseInputAt(state.Mouse.NativeState.Position)) From 5cfb2c2ffe3e3bb111b11d344955710a1b13cb66 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 11 Jan 2018 19:03:31 +0900 Subject: [PATCH 139/206] Make VolumeControlReceptor handle global input Fixes volume not being able to be changed in dead areas of OverlayContainers. --- .../Graphics/UserInterface/Volume/VolumeControlReceptor.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs b/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs index 0649e4033f..2328533665 100644 --- a/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs +++ b/osu.Game/Graphics/UserInterface/Volume/VolumeControlReceptor.cs @@ -3,12 +3,13 @@ using System; using osu.Framework.Graphics.Containers; +using osu.Framework.Input; using osu.Framework.Input.Bindings; using osu.Game.Input.Bindings; namespace osu.Game.Graphics.UserInterface.Volume { - public class VolumeControlReceptor : Container, IKeyBindingHandler + public class VolumeControlReceptor : Container, IKeyBindingHandler, IHandleGlobalInput { public Func ActionRequested; From 35c3ee261d9e3b90367947bbe3ad10e6fd1b3d51 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 11 Jan 2018 20:02:52 +0900 Subject: [PATCH 140/206] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 80bcb82ef8..6594729122 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 80bcb82ef8d2e1af1ce077f4a037b6d279ad9e74 +Subproject commit 65947291229541de3eb1aff0e703f6968b07f976 From 5b190d3cd2e311cf28d1fcdf93ebf08c521ab288 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 11 Jan 2018 12:47:04 +0900 Subject: [PATCH 141/206] Use correct container type when removing fruit (cherry picked from commit a2be7f7) --- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index e02849d0f5..c70cb15b40 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -15,6 +15,7 @@ using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.UI; using OpenTK; using OpenTK.Graphics; @@ -48,7 +49,7 @@ namespace osu.Game.Rulesets.Catch.UI var screenSpacePosition = fruit.ScreenSpaceDrawQuad.Centre; // todo: make this less ugly, somehow. - (fruit.Parent as Container)?.Remove(fruit); + (fruit.Parent as HitObjectContainer)?.Remove(fruit); (fruit.Parent as Container)?.Remove(fruit); fruit.RelativePositionAxes = Axes.None; From 66ebe2ee6679866d46b497a6b1318d8bc5cab5e3 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 11 Jan 2018 20:55:43 +0900 Subject: [PATCH 142/206] Change anchors in line with new ScrollingPlayfield implementation (cherry picked from commit 079827d) --- .../Objects/Drawable/DrawableCatchHitObject.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index 41313b9197..d9a16ad248 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -21,6 +21,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable HitObject = hitObject; Scale = new Vector2(HitObject.Scale); + + Anchor = Anchor.BottomLeft; } } From 0609fc40de1ba8ba08e5126bc22c1351b027d268 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 11 Jan 2018 20:56:09 +0900 Subject: [PATCH 143/206] Fix up DrawableJuiceStream/BananaShower (cherry picked from commit 0bfb3b6) --- .../Objects/Drawable/DrawableJuiceStream.cs | 9 ++------- 1 file changed, 2 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index dcb7fdb823..036c5bd879 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -16,15 +16,10 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableJuiceStream(JuiceStream s) : base(s) { RelativeSizeAxes = Axes.Both; - Height = (float)HitObject.Duration; + Origin = Anchor.BottomLeft; X = 0; - Child = dropletContainer = new Container - { - RelativeSizeAxes = Axes.Both, - RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime), - RelativeChildSize = new Vector2(1, (float)HitObject.Duration) - }; + Child = dropletContainer = new Container { RelativeSizeAxes = Axes.Both, }; foreach (CatchHitObject tick in s.NestedHitObjects.OfType()) { From 61062164cb3944efb45066132015a3a67b4d9bd0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 11 Jan 2018 21:12:27 +0900 Subject: [PATCH 144/206] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 80bcb82ef8..6594729122 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 80bcb82ef8d2e1af1ce077f4a037b6d279ad9e74 +Subproject commit 65947291229541de3eb1aff0e703f6968b07f976 From e5f17e3ddbd6ec793f5e618fb57f2067b376f1ad Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 11 Jan 2018 21:49:20 +0900 Subject: [PATCH 145/206] Remove scale from all but palpable fruit --- .../Objects/Drawable/DrawableCatchHitObject.cs | 14 +++++++++++--- .../Objects/Drawable/DrawableDroplet.cs | 2 +- .../Objects/Drawable/DrawableFruit.cs | 2 +- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index d9a16ad248..554fb1323e 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -10,6 +10,17 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Objects.Drawable { + public abstract class PalpableCatchHitObject : DrawableCatchHitObject + where TObject : CatchHitObject + { + protected PalpableCatchHitObject(TObject hitObject) + : base(hitObject) + { + Scale = new Vector2(HitObject.Scale); + } + } + + public abstract class DrawableCatchHitObject : DrawableCatchHitObject where TObject : CatchHitObject { @@ -19,9 +30,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable : base(hitObject) { HitObject = hitObject; - - Scale = new Vector2(HitObject.Scale); - Anchor = Anchor.BottomLeft; } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs index 289323c1b5..c2b0552ab3 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs @@ -8,7 +8,7 @@ using OpenTK; namespace osu.Game.Rulesets.Catch.Objects.Drawable { - public class DrawableDroplet : DrawableCatchHitObject + public class DrawableDroplet : PalpableCatchHitObject { public DrawableDroplet(Droplet h) : base(h) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index c2c59468e9..ae20abf0d9 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -14,7 +14,7 @@ using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.Objects.Drawable { - public class DrawableFruit : DrawableCatchHitObject + public class DrawableFruit : PalpableCatchHitObject { private Circle border; From 712d586d4159e1271d7b57129c4a6564637cb965 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 11 Jan 2018 13:40:46 +0900 Subject: [PATCH 146/206] Revert "Add OSD + config value for scroll speed" This reverts commit a6d8b28221910993005d6adbbcc5b0447b5a1511. --- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 5 +---- osu.Game/Configuration/OsuConfigManager.cs | 4 +--- osu.Game/Overlays/OnScreenDisplay.cs | 6 +----- osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs | 7 ++----- 4 files changed, 5 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 532be2759f..919518dbe8 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -15,7 +15,6 @@ using osu.Framework.Configuration; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Mania.Objects.Drawables; using osu.Framework.Graphics.Shapes; -using osu.Game.Configuration; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.UI.Scrolling; @@ -162,10 +161,8 @@ namespace osu.Game.Rulesets.Mania.UI } [BackgroundDependencyLoader] - private void load(OsuColour colours, OsuConfigManager config) + private void load(OsuColour colours) { - config.BindWith(OsuSetting.UserScrollSpeed, VisibleTimeRange); - normalColumnColours = new List { colours.RedDark, diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 26879782fc..13213a54a1 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -73,7 +73,6 @@ namespace osu.Game.Configuration Set(OsuSetting.FloatingComments, false); Set(OsuSetting.ScrollingAlgorithm, ScrollingAlgorithmType.Global); - Set(OsuSetting.UserScrollSpeed, 1500.0, 50.0, 10000.0); // Update Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); @@ -120,7 +119,6 @@ namespace osu.Game.Configuration ChatDisplayHeight, Version, ShowConvertedBeatmaps, - ScrollingAlgorithm, - UserScrollSpeed + ScrollingAlgorithm } } diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 4f3f03c749..6a1bd8e182 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -14,7 +14,6 @@ using osu.Game.Graphics; using OpenTK; using OpenTK.Graphics; using osu.Framework.Extensions.Color4Extensions; -using osu.Game.Configuration; using osu.Game.Graphics.Sprites; namespace osu.Game.Overlays @@ -116,7 +115,7 @@ namespace osu.Game.Overlays } [BackgroundDependencyLoader] - private void load(FrameworkConfigManager frameworkConfig, OsuConfigManager osuConfig) + private void load(FrameworkConfigManager frameworkConfig) { trackSetting(frameworkConfig.GetBindable(FrameworkSetting.FrameSync), v => display(v, "Frame Limiter", v.GetDescription(), "Ctrl+F7")); trackSetting(frameworkConfig.GetBindable(FrameworkSetting.AudioDevice), v => display(v, "Audio Device", string.IsNullOrEmpty(v) ? "Default" : v, v)); @@ -136,9 +135,6 @@ namespace osu.Game.Overlays }); trackSetting(frameworkConfig.GetBindable(FrameworkSetting.WindowMode), v => display(v, "Screen Mode", v.ToString(), "Alt+Enter")); - - // Todo: This should be part of the ruleset-specific OSD - trackSetting(osuConfig.GetBindable(OsuSetting.UserScrollSpeed), v => display(v, "Scroll Speed", $"{v:N0}ms", "Ctrl+(+/-) to change")); } private readonly List references = new List(); diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index fa04b7f137..11185015b8 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -2,7 +2,6 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -103,15 +102,13 @@ namespace osu.Game.Rulesets.UI.Scrolling if (state.Keyboard.ControlPressed) { - var lastValue = Transforms.OfType().LastOrDefault()?.EndValue ?? VisibleTimeRange.Value; - switch (args.Key) { case Key.Minus: - transformVisibleTimeRangeTo(lastValue + time_span_step, 200, Easing.OutQuint); + transformVisibleTimeRangeTo(VisibleTimeRange + time_span_step, 200, Easing.OutQuint); break; case Key.Plus: - transformVisibleTimeRangeTo(lastValue - time_span_step, 200, Easing.OutQuint); + transformVisibleTimeRangeTo(VisibleTimeRange - time_span_step, 200, Easing.OutQuint); break; } } From 4b2d971b005bf6e82d84d4969b248bbf55ef32b8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 13:03:47 +0900 Subject: [PATCH 147/206] Add some comments --- .../Algorithms/IScrollingAlgorithm.cs | 18 ++++++++++++++++++ .../Scrolling/ScrollingHitObjectContainer.cs | 10 +++++++--- 2 files changed, 25 insertions(+), 3 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs index f9863bd299..d9e4ab228f 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs @@ -9,7 +9,25 @@ namespace osu.Game.Rulesets.UI.Scrolling.Algorithms { public interface IScrollingAlgorithm { + /// + /// Computes the states of s that are constant, such as lifetime and spatial length. + /// This is invoked once whenever or changes. + /// + /// The s whose states should be computed. + /// The scrolling direction. + /// The duration required to scroll through one length of the screen before any control point adjustments. + /// The length of the screen that is scrolled through. void ComputeInitialStates(IEnumerable hitObjects, ScrollingDirection direction, double timeRange, Vector2 length); + + /// + /// Computes the states of s that change depending on , such as position. + /// This is invoked once per frame. + /// + /// The s whose states should be computed. + /// The scrolling direction. + /// The current time. + /// The duration required to scroll through one length of the screen before any control point adjustments. + /// The length of the screen that is scrolled through. void ComputePositions(IEnumerable hitObjects, ScrollingDirection direction, double currentTime, double timeRange, Vector2 length); } } diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index dfa6a40db4..960fd94762 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -15,12 +15,18 @@ namespace osu.Game.Rulesets.UI.Scrolling { public class ScrollingHitObjectContainer : HitObjectContainer { + /// + /// The duration required to scroll through one length of the before any control point adjustments. + /// public readonly BindableDouble TimeRange = new BindableDouble { MinValue = 0, MaxValue = double.MaxValue }; + /// + /// The control points that adjust the scrolling speed. + /// protected readonly SortedList ControlPoints = new SortedList(); private readonly ScrollingDirection direction; @@ -104,9 +110,7 @@ namespace osu.Game.Rulesets.UI.Scrolling { base.UpdateAfterChildrenLife(); - // We need to calculate this as soon as possible after lifetimes so that hitobjects - // get the final say in their positions - + // We need to calculate this as soon as possible after lifetimes so that hitobjects get the final say in their positions scrollingAlgorithm.ComputePositions(AliveObjects, direction, Time.Current, TimeRange, DrawSize); } } From 1985e5bdb23a887d7a1cc8d392f1380971843061 Mon Sep 17 00:00:00 2001 From: james58899 Date: Fri, 12 Jan 2018 12:21:37 +0800 Subject: [PATCH 148/206] fix background dim --- osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs | 2 +- osu.Game/Screens/Play/Player.cs | 5 ++--- 2 files changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index 1ce84289b2..032950db4a 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -54,7 +54,7 @@ namespace osu.Game.Screens.Backgrounds Beatmap = beatmap; } - public TransformSequence BlurTo(Vector2 sigma, double duration, Easing easing = Easing.None) + public void BlurTo(Vector2 sigma, double duration, Easing easing = Easing.None) => background?.BlurTo(blurTarget = sigma, duration, easing); public override bool Equals(BackgroundScreen other) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index c24b5e0d2a..fc8b0f2c88 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -394,9 +394,8 @@ namespace osu.Game.Screens.Play .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)? - .FadeTo(!storyboardVisible || beatmap.Background == null ? opacity : 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() From 2e235660ad6a5814d4dc0d4adb2baafc249c03b7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 13:25:49 +0900 Subject: [PATCH 149/206] Fix skip button appearing below osu!mania's stage --- osu.Game/Screens/Play/Player.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index c24b5e0d2a..577991c500 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -176,13 +176,13 @@ namespace osu.Game.Screens.Play }, Children = new Drawable[] { - new SkipButton(firstObjectTime) { AudioClock = decoupledClock }, new Container { RelativeSizeAxes = Axes.Both, Clock = offsetClock, Child = RulesetContainer, }, + new SkipButton(firstObjectTime) { AudioClock = decoupledClock }, hudOverlay = new HUDOverlay { Anchor = Anchor.Centre, From 61c8fd4ab94a24ea6fda301aeb92e9a18eaa7e90 Mon Sep 17 00:00:00 2001 From: james58899 Date: Fri, 12 Jan 2018 12:39:32 +0800 Subject: [PATCH 150/206] useless using --- osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index 032950db4a..f7042991ac 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -4,7 +4,6 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; -using osu.Framework.Graphics.Transforms; using OpenTK; using osu.Game.Beatmaps; using osu.Game.Graphics.Backgrounds; From 057efa24c729f570b7205cacda1f72f974b53f48 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 14:26:09 +0900 Subject: [PATCH 151/206] Move a few interfaces to base classes --- osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs | 2 +- osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs index e6711923ff..aafebb61ec 100644 --- a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs +++ b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs @@ -8,7 +8,7 @@ using osu.Game.Rulesets.Mods; namespace osu.Game.Rulesets.Mania.Mods { - public abstract class ManiaKeyMod : Mod, IApplicableMod, IApplicableToBeatmapConverter + public abstract class ManiaKeyMod : Mod, IApplicableToBeatmapConverter { public override string ShortenedName => Name; public abstract int KeyCount { get; } diff --git a/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs b/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs index 6b02a902e0..d89d6f20d8 100644 --- a/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs +++ b/osu.Game/Rulesets/Mods/IApplicableToBeatmapConverter.cs @@ -10,7 +10,7 @@ namespace osu.Game.Rulesets.Mods /// Interface for a that applies changes to a . /// /// The type of converted . - public interface IApplicableToBeatmapConverter + public interface IApplicableToBeatmapConverter : IApplicableMod where TObject : HitObject { /// From 9a77005d2e443aff2b5c3edf2b94841f6bc713b6 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 14:26:23 +0900 Subject: [PATCH 152/206] Make sure unimplemented auto mods aren't consumable --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 3 ++- osu.Game/Rulesets/Mods/ModAutoplay.cs | 17 +++++++++-------- 2 files changed, 11 insertions(+), 9 deletions(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 37525470c2..0d52046485 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -10,6 +10,7 @@ using osu.Game.Rulesets.UI; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; +using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch { @@ -80,7 +81,7 @@ namespace osu.Game.Rulesets.Catch { Mods = new Mod[] { - new ModAutoplay(), + new ModAutoplay(), new ModCinema(), }, }, diff --git a/osu.Game/Rulesets/Mods/ModAutoplay.cs b/osu.Game/Rulesets/Mods/ModAutoplay.cs index e8f5bb4740..a0752acb1a 100644 --- a/osu.Game/Rulesets/Mods/ModAutoplay.cs +++ b/osu.Game/Rulesets/Mods/ModAutoplay.cs @@ -5,23 +5,25 @@ using System; using osu.Game.Beatmaps; using osu.Game.Graphics; using osu.Game.Rulesets.Objects; +using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mods { - public abstract class ModAutoplay : ModAutoplay, IApplicableToRulesetContainer + public class ModAutoplay : ModAutoplay, IApplicableToRulesetContainer, IApplicableFailOverride where T : HitObject { - protected abstract Score CreateReplayScore(Beatmap beatmap); + protected virtual Score CreateReplayScore(Beatmap beatmap) => new Score { Replay = new Replay() }; - public virtual void ApplyToRulesetContainer(RulesetContainer rulesetContainer) - { - rulesetContainer.SetReplay(CreateReplayScore(rulesetContainer.Beatmap)?.Replay); - } + public override bool HasImplementation => GetType().GenericTypeArguments.Length == 0; + + public bool AllowFail => false; + + public virtual void ApplyToRulesetContainer(RulesetContainer rulesetContainer) => rulesetContainer.SetReplay(CreateReplayScore(rulesetContainer.Beatmap)?.Replay); } - public class ModAutoplay : Mod, IApplicableFailOverride + public abstract class ModAutoplay : Mod { public override string Name => "Autoplay"; public override string ShortenedName => "AT"; @@ -29,6 +31,5 @@ namespace osu.Game.Rulesets.Mods public override string Description => "Watch a perfect automated play through the song"; public override double ScoreMultiplier => 0; public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail) }; - public bool AllowFail => false; } } From f83c84a0a6139e8789b32d4c65767b94f4d9680f Mon Sep 17 00:00:00 2001 From: james58899 Date: Fri, 12 Jan 2018 14:24:42 +0800 Subject: [PATCH 153/206] keep BlurTo --- osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs index f7042991ac..1ce84289b2 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenBeatmap.cs @@ -4,6 +4,7 @@ using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Textures; +using osu.Framework.Graphics.Transforms; using OpenTK; using osu.Game.Beatmaps; using osu.Game.Graphics.Backgrounds; @@ -53,7 +54,7 @@ namespace osu.Game.Screens.Backgrounds Beatmap = beatmap; } - public void BlurTo(Vector2 sigma, double duration, Easing easing = Easing.None) + public TransformSequence BlurTo(Vector2 sigma, double duration, Easing easing = Easing.None) => background?.BlurTo(blurTarget = sigma, duration, easing); public override bool Equals(BackgroundScreen other) From 03824eccc8f658a50551e1f592520a45aa77447c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 17:09:21 +0900 Subject: [PATCH 154/206] Block fadeout on holdnote heads --- .../Objects/Drawables/DrawableHoldNote.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 6748bc22e6..76fc0dcf77 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -186,6 +186,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables return true; } + + protected override void UpdateState(ArmedState state) + { + // The holdnote keeps scrolling through for now, so having the head disappear looks weird + } } /// From cae93a1d1f7a6d31ebc181c97766e341d3023322 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 17:09:34 +0900 Subject: [PATCH 155/206] Add comment to fade override of holdnote tail --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 76fc0dcf77..58f024870d 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -238,6 +238,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables protected override void UpdateState(ArmedState state) { + // The holdnote keeps scrolling through, so having the tail disappear looks weird } public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down From 441e8aced51376ac99d153423a20de42b1a6e55e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 17:18:34 +0900 Subject: [PATCH 156/206] Better namings for the speed change "algorithms" --- osu.Game/Configuration/OsuConfigManager.cs | 4 ++-- ...pe.cs => SpeedChangeVisualisationMethod.cs} | 10 +++++----- .../Sections/Gameplay/ScrollingSettings.cs | 6 +++--- .../Scrolling/ScrollingHitObjectContainer.cs | 18 +++++++++--------- .../ISpeedChangeVisualiser.cs} | 4 ++-- .../OverlappingSpeedChangeVisualiser.cs} | 6 +++--- .../SequentialSpeedChangeVisualiser.cs} | 6 +++--- osu.Game/osu.Game.csproj | 8 ++++---- 8 files changed, 31 insertions(+), 31 deletions(-) rename osu.Game/Configuration/{ScrollingAlgorithmType.cs => SpeedChangeVisualisationMethod.cs} (57%) rename osu.Game/Rulesets/UI/Scrolling/{Algorithms/IScrollingAlgorithm.cs => Visualisers/ISpeedChangeVisualiser.cs} (93%) rename osu.Game/Rulesets/UI/Scrolling/{Algorithms/LocalScrollingAlgorithm.cs => Visualisers/OverlappingSpeedChangeVisualiser.cs} (90%) rename osu.Game/Rulesets/UI/Scrolling/{Algorithms/GlobalScrollingAlgorithm.cs => Visualisers/SequentialSpeedChangeVisualiser.cs} (92%) diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs index 13213a54a1..23f7fd6ac1 100644 --- a/osu.Game/Configuration/OsuConfigManager.cs +++ b/osu.Game/Configuration/OsuConfigManager.cs @@ -72,7 +72,7 @@ namespace osu.Game.Configuration Set(OsuSetting.FloatingComments, false); - Set(OsuSetting.ScrollingAlgorithm, ScrollingAlgorithmType.Global); + Set(OsuSetting.SpeedChangeVisualisation, SpeedChangeVisualisationMethod.Sequential); // Update Set(OsuSetting.ReleaseStream, ReleaseStream.Lazer); @@ -119,6 +119,6 @@ namespace osu.Game.Configuration ChatDisplayHeight, Version, ShowConvertedBeatmaps, - ScrollingAlgorithm + SpeedChangeVisualisation } } diff --git a/osu.Game/Configuration/ScrollingAlgorithmType.cs b/osu.Game/Configuration/SpeedChangeVisualisationMethod.cs similarity index 57% rename from osu.Game/Configuration/ScrollingAlgorithmType.cs rename to osu.Game/Configuration/SpeedChangeVisualisationMethod.cs index 8b9d292634..644ae0a727 100644 --- a/osu.Game/Configuration/ScrollingAlgorithmType.cs +++ b/osu.Game/Configuration/SpeedChangeVisualisationMethod.cs @@ -5,11 +5,11 @@ using System.ComponentModel; namespace osu.Game.Configuration { - public enum ScrollingAlgorithmType + public enum SpeedChangeVisualisationMethod { - [Description("Global")] - Global, - [Description("Local")] - Local + [Description("Sequential")] + Sequential, + [Description("Overlapping")] + Overlapping } } diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs index 3243f4c23a..4e8706137c 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/ScrollingSettings.cs @@ -15,10 +15,10 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay { Children = new[] { - new SettingsEnumDropdown + new SettingsEnumDropdown { - LabelText = "Scrolling algorithm", - Bindable = config.GetBindable(OsuSetting.ScrollingAlgorithm), + LabelText = "Visualise speed changes as", + Bindable = config.GetBindable(OsuSetting.SpeedChangeVisualisation), } }; } diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index 960fd94762..e69abec45e 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -9,7 +9,7 @@ using osu.Framework.Lists; using osu.Game.Configuration; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; -using osu.Game.Rulesets.UI.Scrolling.Algorithms; +using osu.Game.Rulesets.UI.Scrolling.Visualisers; namespace osu.Game.Rulesets.UI.Scrolling { @@ -42,18 +42,18 @@ namespace osu.Game.Rulesets.UI.Scrolling TimeRange.ValueChanged += v => initialStateCache.Invalidate(); } - private IScrollingAlgorithm scrollingAlgorithm; + private ISpeedChangeVisualiser speedChangeVisualiser; [BackgroundDependencyLoader] private void load(OsuConfigManager config) { - switch (config.Get(OsuSetting.ScrollingAlgorithm)) + switch (config.Get(OsuSetting.SpeedChangeVisualisation)) { - case ScrollingAlgorithmType.Global: - scrollingAlgorithm = new GlobalScrollingAlgorithm(ControlPoints); + case SpeedChangeVisualisationMethod.Sequential: + speedChangeVisualiser = new SequentialSpeedChangeVisualiser(ControlPoints); break; - case ScrollingAlgorithmType.Local: - scrollingAlgorithm = new LocalScrollingAlgorithm(ControlPoints); + case SpeedChangeVisualisationMethod.Overlapping: + speedChangeVisualiser = new OverlappingSpeedChangeVisualiser(ControlPoints); break; } } @@ -101,7 +101,7 @@ namespace osu.Game.Rulesets.UI.Scrolling if (initialStateCache.IsValid) return; - scrollingAlgorithm.ComputeInitialStates(Objects, direction, TimeRange, DrawSize); + speedChangeVisualiser.ComputeInitialStates(Objects, direction, TimeRange, DrawSize); initialStateCache.Validate(); } @@ -111,7 +111,7 @@ namespace osu.Game.Rulesets.UI.Scrolling base.UpdateAfterChildrenLife(); // We need to calculate this as soon as possible after lifetimes so that hitobjects get the final say in their positions - scrollingAlgorithm.ComputePositions(AliveObjects, direction, Time.Current, TimeRange, DrawSize); + speedChangeVisualiser.ComputePositions(AliveObjects, direction, Time.Current, TimeRange, DrawSize); } } } diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Visualisers/ISpeedChangeVisualiser.cs similarity index 93% rename from osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs rename to osu.Game/Rulesets/UI/Scrolling/Visualisers/ISpeedChangeVisualiser.cs index d9e4ab228f..46d71e1602 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/IScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Visualisers/ISpeedChangeVisualiser.cs @@ -5,9 +5,9 @@ using System.Collections.Generic; using osu.Game.Rulesets.Objects.Drawables; using OpenTK; -namespace osu.Game.Rulesets.UI.Scrolling.Algorithms +namespace osu.Game.Rulesets.UI.Scrolling.Visualisers { - public interface IScrollingAlgorithm + public interface ISpeedChangeVisualiser { /// /// Computes the states of s that are constant, such as lifetime and spatial length. diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs similarity index 90% rename from osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs rename to osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs index 96a85c5f9f..24f69c627d 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/LocalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs @@ -7,15 +7,15 @@ using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.Timing; using OpenTK; -namespace osu.Game.Rulesets.UI.Scrolling.Algorithms +namespace osu.Game.Rulesets.UI.Scrolling.Visualisers { - public class LocalScrollingAlgorithm : IScrollingAlgorithm + public class OverlappingSpeedChangeVisualiser : ISpeedChangeVisualiser { private readonly Dictionary hitObjectPositions = new Dictionary(); private readonly SortedList controlPoints; - public LocalScrollingAlgorithm(SortedList controlPoints) + public OverlappingSpeedChangeVisualiser(SortedList controlPoints) { this.controlPoints = controlPoints; } diff --git a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs b/osu.Game/Rulesets/UI/Scrolling/Visualisers/SequentialSpeedChangeVisualiser.cs similarity index 92% rename from osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs rename to osu.Game/Rulesets/UI/Scrolling/Visualisers/SequentialSpeedChangeVisualiser.cs index ed156ecfd5..94705426f8 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Algorithms/GlobalScrollingAlgorithm.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Visualisers/SequentialSpeedChangeVisualiser.cs @@ -8,15 +8,15 @@ using osu.Game.Rulesets.Objects.Types; using osu.Game.Rulesets.Timing; using OpenTK; -namespace osu.Game.Rulesets.UI.Scrolling.Algorithms +namespace osu.Game.Rulesets.UI.Scrolling.Visualisers { - public class GlobalScrollingAlgorithm : IScrollingAlgorithm + public class SequentialSpeedChangeVisualiser : ISpeedChangeVisualiser { private readonly Dictionary hitObjectPositions = new Dictionary(); private readonly IReadOnlyList controlPoints; - public GlobalScrollingAlgorithm(IReadOnlyList controlPoints) + public SequentialSpeedChangeVisualiser(IReadOnlyList controlPoints) { this.controlPoints = controlPoints; } diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 45183de092..01052a7898 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -265,7 +265,7 @@ - + @@ -318,9 +318,9 @@ - - - + + + From 8a04c954a90198a6c2e4b3369160a9fcd84c8dea Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 17:19:59 +0900 Subject: [PATCH 157/206] Cleanup --- .../UI/Scrolling/ScrollingHitObjectContainer.cs | 11 +++++------ .../Visualisers/OverlappingSpeedChangeVisualiser.cs | 2 -- osu.Game/osu.Game.csproj | 6 +++--- 3 files changed, 8 insertions(+), 11 deletions(-) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs index e69abec45e..530ed653aa 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingHitObjectContainer.cs @@ -98,12 +98,11 @@ namespace osu.Game.Rulesets.UI.Scrolling { base.Update(); - if (initialStateCache.IsValid) - return; - - speedChangeVisualiser.ComputeInitialStates(Objects, direction, TimeRange, DrawSize); - - initialStateCache.Validate(); + if (!initialStateCache.IsValid) + { + speedChangeVisualiser.ComputeInitialStates(Objects, direction, TimeRange, DrawSize); + initialStateCache.Validate(); + } } protected override void UpdateAfterChildrenLife() diff --git a/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs b/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs index 24f69c627d..4cce90ee94 100644 --- a/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs +++ b/osu.Game/Rulesets/UI/Scrolling/Visualisers/OverlappingSpeedChangeVisualiser.cs @@ -11,8 +11,6 @@ namespace osu.Game.Rulesets.UI.Scrolling.Visualisers { public class OverlappingSpeedChangeVisualiser : ISpeedChangeVisualiser { - private readonly Dictionary hitObjectPositions = new Dictionary(); - private readonly SortedList controlPoints; public OverlappingSpeedChangeVisualiser(SortedList controlPoints) diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 01052a7898..967f3fc1d7 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -318,9 +318,9 @@ - - - + + + From 0a06f8069f5d6515bd7209645bff54cf85374bf9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 17:22:51 +0900 Subject: [PATCH 158/206] Remove panel fade out for now Should be implemented at one level above using a dedicated container. --- osu.Game/Overlays/SocialOverlay.cs | 19 +++++++++---------- 1 file changed, 9 insertions(+), 10 deletions(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index 161ff70dc9..e61153d290 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -137,16 +137,6 @@ namespace osu.Game.Overlays }); } - private void clearPanels() - { - if (panels != null) - { - panels.FadeOut(200); - panels.Expire(); - panels = null; - } - } - private APIRequest getUsersRequest; private readonly Bindable currentQuery = new Bindable(); @@ -191,6 +181,15 @@ namespace osu.Game.Overlays recreatePanels(Filter.DisplayStyleControl.DisplayStyle.Value); } + private void clearPanels() + { + if (panels != null) + { + panels.Expire(); + panels = null; + } + } + public void APIStateChanged(APIAccess api, APIState state) { switch (state) From 7f189080b91a0d8d7a082b28b023eb939c86b023 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 17:43:56 +0900 Subject: [PATCH 159/206] Move fail override back to abstract implementation --- osu.Game/Rulesets/Mods/ModAutoplay.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModAutoplay.cs b/osu.Game/Rulesets/Mods/ModAutoplay.cs index a0752acb1a..3356a56c33 100644 --- a/osu.Game/Rulesets/Mods/ModAutoplay.cs +++ b/osu.Game/Rulesets/Mods/ModAutoplay.cs @@ -11,25 +11,24 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Mods { - public class ModAutoplay : ModAutoplay, IApplicableToRulesetContainer, IApplicableFailOverride + public class ModAutoplay : ModAutoplay, IApplicableToRulesetContainer where T : HitObject { protected virtual Score CreateReplayScore(Beatmap beatmap) => new Score { Replay = new Replay() }; public override bool HasImplementation => GetType().GenericTypeArguments.Length == 0; - public bool AllowFail => false; - public virtual void ApplyToRulesetContainer(RulesetContainer rulesetContainer) => rulesetContainer.SetReplay(CreateReplayScore(rulesetContainer.Beatmap)?.Replay); } - public abstract class ModAutoplay : Mod + public abstract class ModAutoplay : Mod, IApplicableFailOverride { public override string Name => "Autoplay"; public override string ShortenedName => "AT"; public override FontAwesome Icon => FontAwesome.fa_osu_mod_auto; public override string Description => "Watch a perfect automated play through the song"; public override double ScoreMultiplier => 0; + public bool AllowFail => false; public override Type[] IncompatibleMods => new[] { typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail) }; } } From b55adf655f9334ad292363465b33e49d2737e144 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 17:46:24 +0900 Subject: [PATCH 160/206] Yeah, cinema mod isn't going to work --- osu.Game/Rulesets/Mods/ModCinema.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Rulesets/Mods/ModCinema.cs b/osu.Game/Rulesets/Mods/ModCinema.cs index 576d29fdfb..c0480b0647 100644 --- a/osu.Game/Rulesets/Mods/ModCinema.cs +++ b/osu.Game/Rulesets/Mods/ModCinema.cs @@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Mods { public override string Name => "Cinema"; public override string ShortenedName => "CN"; + public override bool HasImplementation => false; public override FontAwesome Icon => FontAwesome.fa_osu_mod_cinema; } } From e5056e11f416fcaabdbc60d5e6bd3463c861794c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 18:07:40 +0900 Subject: [PATCH 161/206] Remove extra newline --- osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs index 0a1a6c7960..2d1331d30a 100644 --- a/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs +++ b/osu.Game.Rulesets.Osu/Objects/OsuHitObject.cs @@ -78,7 +78,6 @@ namespace osu.Game.Rulesets.Osu.Objects TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450); TimeFadein = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1200, 800, 300); - Scale = (1.0f - 0.7f * (difficulty.CircleSize - 5) / 5) / 2; } } From 2bf2cc15d41863014a81d46109425e0fcce23efd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 18:09:37 +0900 Subject: [PATCH 162/206] Fix unnecessary osu-resources rollback --- osu-resources | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-resources b/osu-resources index e01f71160f..7724abdf1d 160000 --- a/osu-resources +++ b/osu-resources @@ -1 +1 @@ -Subproject commit e01f71160fb9b3167efcd177c7d7dba9e5d36604 +Subproject commit 7724abdf1d7c9705ba2e3989a9c604e17ccdc871 From 512e4d2c9fbf411cdf573ec3df82cc248a1aef5f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 18:13:17 +0900 Subject: [PATCH 163/206] Rewrite the way that cursor overrides are done game-wide --- .../Edit/OsuEditPlayfield.cs | 3 -- .../Edit/OsuEditRulesetContainer.cs | 3 ++ osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 15 ------ .../UI/OsuRulesetContainer.cs | 4 ++ .../Graphics/Cursor/IProvideLocalCursor.cs | 22 ++++++++ .../Graphics/Cursor/OsuCursorContainer.cs | 53 +++++++++++++++++++ osu.Game/OsuGame.cs | 4 -- osu.Game/OsuGameBase.cs | 23 +++----- osu.Game/Rulesets/UI/Playfield.cs | 5 -- osu.Game/Rulesets/UI/RulesetContainer.cs | 24 ++++++--- osu.Game/Screens/Menu/Disclaimer.cs | 7 ++- osu.Game/Screens/Menu/Intro.cs | 9 ++-- osu.Game/Screens/OsuScreen.cs | 2 - osu.Game/Screens/Play/Player.cs | 16 ++++-- osu.Game/osu.Game.csproj | 2 + 15 files changed, 132 insertions(+), 60 deletions(-) create mode 100644 osu.Game/Graphics/Cursor/IProvideLocalCursor.cs create mode 100644 osu.Game/Graphics/Cursor/OsuCursorContainer.cs diff --git a/osu.Game.Rulesets.Osu/Edit/OsuEditPlayfield.cs b/osu.Game.Rulesets.Osu/Edit/OsuEditPlayfield.cs index a3f0b79475..5f232b1889 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuEditPlayfield.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuEditPlayfield.cs @@ -1,15 +1,12 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using osu.Framework.Graphics.Cursor; using osu.Game.Rulesets.Osu.UI; namespace osu.Game.Rulesets.Osu.Edit { public class OsuEditPlayfield : OsuPlayfield { - protected override CursorContainer CreateCursor() => null; - protected override bool ProxyApproachCircles => false; } } diff --git a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs index 96b9acbf78..56efc25fa5 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuEditRulesetContainer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Graphics.Cursor; using osu.Game.Beatmaps; using osu.Game.Rulesets.Osu.UI; using osu.Game.Rulesets.UI; @@ -15,5 +16,7 @@ namespace osu.Game.Rulesets.Osu.Edit } protected override Playfield CreatePlayfield() => new OsuEditPlayfield(); + + protected override CursorContainer CreateCursor() => null; } } diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index e7d47da391..892df089f5 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -12,8 +12,6 @@ using osu.Game.Rulesets.UI; using System.Linq; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Osu.Judgements; -using osu.Game.Rulesets.Osu.UI.Cursor; -using osu.Framework.Graphics.Cursor; namespace osu.Game.Rulesets.Osu.UI { @@ -23,8 +21,6 @@ namespace osu.Game.Rulesets.Osu.UI private readonly Container judgementLayer; private readonly ConnectionRenderer connectionLayer; - public override bool ProvidingUserCursor => true; - // Todo: This should not be a thing, but is currently required for the editor // https://github.com/ppy/osu-framework/issues/1283 protected virtual bool ProxyApproachCircles => true; @@ -70,15 +66,6 @@ namespace osu.Game.Rulesets.Osu.UI }); } - protected override void LoadComplete() - { - base.LoadComplete(); - - var cursor = CreateCursor(); - if (cursor != null) - AddInternal(cursor); - } - public override void Add(DrawableHitObject h) { h.Depth = (float)h.HitObject.StartTime; @@ -113,7 +100,5 @@ namespace osu.Game.Rulesets.Osu.UI judgementLayer.Add(explosion); } - - protected virtual CursorContainer CreateCursor() => new GameplayCursor(); } } diff --git a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs index 5c7413a71e..526348062f 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuRulesetContainer.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using osu.Framework.Graphics.Cursor; using osu.Framework.Input; using OpenTK; using osu.Game.Beatmaps; @@ -10,6 +11,7 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Objects.Drawables; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Osu.Scoring; +using osu.Game.Rulesets.Osu.UI.Cursor; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.Replays; @@ -49,5 +51,7 @@ namespace osu.Game.Rulesets.Osu.UI protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new OsuReplayInputHandler(replay); protected override Vector2 GetPlayfieldAspectAdjust() => new Vector2(0.75f); + + protected override CursorContainer CreateCursor() => new GameplayCursor(); } } diff --git a/osu.Game/Graphics/Cursor/IProvideLocalCursor.cs b/osu.Game/Graphics/Cursor/IProvideLocalCursor.cs new file mode 100644 index 0000000000..61631b1220 --- /dev/null +++ b/osu.Game/Graphics/Cursor/IProvideLocalCursor.cs @@ -0,0 +1,22 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.Graphics; +using osu.Framework.Graphics.Cursor; + +namespace osu.Game.Graphics.Cursor +{ + public interface IProvideLocalCursor : IDrawable + { + /// + /// The cursor provided by this . + /// + CursorContainer LocalCursor { get; } + + /// + /// Whether the cursor provided by this should be displayed. + /// If this is false, a cursor occurring earlier in the draw hierarchy will be displayed instead. + /// + bool ProvidesUserCursor { get; } + } +} diff --git a/osu.Game/Graphics/Cursor/OsuCursorContainer.cs b/osu.Game/Graphics/Cursor/OsuCursorContainer.cs new file mode 100644 index 0000000000..ca6b6085c2 --- /dev/null +++ b/osu.Game/Graphics/Cursor/OsuCursorContainer.cs @@ -0,0 +1,53 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Linq; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Cursor; +using osu.Framework.Input; + +namespace osu.Game.Graphics.Cursor +{ + public class OsuCursorContainer : Container, IProvideLocalCursor + { + protected override Container Content => content; + private readonly Container content; + + public CursorContainer LocalCursor { get; } + public bool ProvidesUserCursor => true; + + public OsuCursorContainer() + { + AddRangeInternal(new Drawable[] + { + LocalCursor = new MenuCursor { State = Visibility.Hidden }, + content = new Container { RelativeSizeAxes = Axes.Both } + }); + } + + private InputManager inputManager; + + protected override void LoadComplete() + { + base.LoadComplete(); + inputManager = GetContainingInputManager(); + } + + private IProvideLocalCursor currentTarget; + protected override void Update() + { + base.Update(); + + var newTarget = inputManager.HoveredDrawables.OfType().FirstOrDefault(t => t.ProvidesUserCursor) ?? this; + + if (currentTarget == newTarget) + return; + + currentTarget?.LocalCursor?.Hide(); + newTarget.LocalCursor?.Show(); + + currentTarget = newTarget; + } + } +} diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 5604ef8f3c..f0edcbbc6b 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -297,8 +297,6 @@ namespace osu.Game else Toolbar.State = Visibility.Visible; }; - - Cursor.State = Visibility.Hidden; } private void forwardLoggedErrorsToNotifications() @@ -446,8 +444,6 @@ namespace osu.Game Beatmap.Disabled = applyRestrictions; mainContent.Padding = new MarginPadding { Top = ToolbarOffset }; - - Cursor.State = currentScreen?.HasLocalCursorDisplayed == false ? Visibility.Visible : Visibility.Hidden; } private void screenAdded(Screen newScreen) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 1982fa0db5..ff9264c598 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -52,8 +52,6 @@ namespace osu.Game protected override Container Content => content; - protected MenuCursor Cursor; - public Bindable Beatmap { get; private set; } private Bindable fpsDisplayVisible; @@ -211,21 +209,14 @@ namespace osu.Game GlobalKeyBindingInputManager globalBinding; - base.Content.Add(new DrawSizePreservingFillContainer + var cursorContainer = new OsuCursorContainer { RelativeSizeAxes = Axes.Both }; + cursorContainer.Child = globalBinding = new GlobalKeyBindingInputManager(this) { - Children = new Drawable[] - { - Cursor = new MenuCursor(), - globalBinding = new GlobalKeyBindingInputManager(this) - { - RelativeSizeAxes = Axes.Both, - Child = content = new OsuTooltipContainer(Cursor) - { - RelativeSizeAxes = Axes.Both, - } - } - } - }); + RelativeSizeAxes = Axes.Both, + Child = content = new OsuTooltipContainer(cursorContainer.LocalCursor) { RelativeSizeAxes = Axes.Both } + }; + + base.Content.Add(new DrawSizePreservingFillContainer { Child = cursorContainer }); KeyBindingStore.Register(globalBinding); dependencies.Cache(globalBinding); diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 6274301a47..e60ac00588 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -22,11 +22,6 @@ namespace osu.Game.Rulesets.UI public Container ScaledContent; - /// - /// Whether we are currently providing the local user a gameplay cursor. - /// - public virtual bool ProvidingUserCursor => false; - protected override Container Content => content; private readonly Container content; diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 4d559549b7..40f88ce577 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -13,6 +13,7 @@ using System; using System.Collections.Generic; using System.Diagnostics; using System.Linq; +using osu.Framework.Graphics.Cursor; using osu.Framework.Input; using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; @@ -43,11 +44,6 @@ namespace osu.Game.Rulesets.UI /// public PassThroughInputManager KeyBindingInputManager; - /// - /// Whether we are currently providing the local user a gameplay cursor. - /// - public virtual bool ProvidingUserCursor => false; - /// /// Whether we have a replay loaded currently. /// @@ -61,6 +57,11 @@ namespace osu.Game.Rulesets.UI /// public Playfield Playfield => playfield.Value; + /// + /// The cursor provided by this . May be null if no cursor is provided. + /// + public readonly CursorContainer Cursor; + protected readonly Ruleset Ruleset; /// @@ -71,6 +72,8 @@ namespace osu.Game.Rulesets.UI { Ruleset = ruleset; playfield = new Lazy(CreatePlayfield); + + Cursor = CreateCursor(); } public abstract ScoreProcessor CreateScoreProcessor(); @@ -98,6 +101,12 @@ namespace osu.Game.Rulesets.UI ReplayInputManager.ReplayInputHandler = replay != null ? CreateReplayInputHandler(replay) : null; } + + /// + /// Creates the cursor. May be null if the doesn't provide a custom cursor. + /// + protected virtual CursorContainer CreateCursor() => null; + /// /// Creates a Playfield. /// @@ -144,8 +153,6 @@ namespace osu.Game.Rulesets.UI /// protected readonly bool IsForCurrentRuleset; - public sealed override bool ProvidingUserCursor => !HasReplayLoaded && Playfield.ProvidingUserCursor; - public override ScoreProcessor CreateScoreProcessor() => new ScoreProcessor(this); protected override Container Content => content; @@ -212,6 +219,9 @@ namespace osu.Game.Rulesets.UI AddInternal(KeyBindingInputManager); KeyBindingInputManager.Add(Playfield); + if (Cursor != null) + KeyBindingInputManager.Add(Cursor); + loadObjects(); } diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index 977c8828d2..a54abe8cf1 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -9,10 +9,12 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using OpenTK; using OpenTK.Graphics; +using osu.Game.Graphics.Cursor; +using osu.Framework.Graphics.Cursor; namespace osu.Game.Screens.Menu { - public class Disclaimer : OsuScreen + public class Disclaimer : OsuScreen, IProvideLocalCursor { private Intro intro; private readonly SpriteIcon icon; @@ -20,7 +22,8 @@ namespace osu.Game.Screens.Menu public override bool ShowOverlaysOnEnter => false; - public override bool HasLocalCursorDisplayed => true; + public CursorContainer LocalCursor => null; + public bool ProvidesUserCursor => true; public Disclaimer() { diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index fcee071f04..5fac56fafb 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -15,10 +15,12 @@ using osu.Game.Configuration; using osu.Game.Screens.Backgrounds; using OpenTK; using OpenTK.Graphics; +using osu.Game.Graphics.Cursor; +using osu.Framework.Graphics.Cursor; namespace osu.Game.Screens.Menu { - public class Intro : OsuScreen + public class Intro : OsuScreen, IProvideLocalCursor { private const string menu_music_beatmap_hash = "3c8b1fcc9434dbb29e2fb613d3b9eada9d7bb6c125ceb32396c3b53437280c83"; @@ -31,10 +33,11 @@ namespace osu.Game.Screens.Menu private SampleChannel welcome; private SampleChannel seeya; - public override bool HasLocalCursorDisplayed => true; - public override bool ShowOverlaysOnEnter => false; + public CursorContainer LocalCursor => null; + public bool ProvidesUserCursor => true; + protected override BackgroundScreen CreateBackground() => new BackgroundScreenEmpty(); private Bindable menuVoice; diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 0111dceb40..48ca4d5907 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -37,8 +37,6 @@ namespace osu.Game.Screens protected new OsuGameBase Game => base.Game as OsuGameBase; - public virtual bool HasLocalCursorDisplayed => false; - private OsuLogo logo; /// diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 577991c500..a2d1d161c4 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -23,22 +23,22 @@ using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Scoring; using osu.Game.Screens.Ranking; using osu.Framework.Audio.Sample; +using osu.Framework.Graphics.Cursor; using osu.Game.Beatmaps; using osu.Game.Graphics; +using osu.Game.Graphics.Cursor; using osu.Game.Online.API; using osu.Game.Screens.Play.BreaksOverlay; using osu.Game.Storyboards.Drawables; namespace osu.Game.Screens.Play { - public class Player : OsuScreen + public class Player : OsuScreen, IProvideLocalCursor { protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); public override bool ShowOverlaysOnEnter => false; - public override bool HasLocalCursorDisplayed => !pauseContainer.IsPaused && !HasFailed && RulesetContainer.ProvidingUserCursor; - public Action RestartRequested; public override bool AllowBeatmapRulesetChange => false; @@ -51,6 +51,9 @@ namespace osu.Game.Screens.Play public int RestartCount; + public CursorContainer LocalCursor => RulesetContainer.Cursor; + public bool ProvidesUserCursor => RulesetContainer?.Cursor != null && !RulesetContainer.HasReplayLoaded; + private IAdjustableClock adjustableSourceClock; private FramedOffsetClock offsetClock; private DecoupleableInterpolatingFramedClock decoupledClock; @@ -152,6 +155,12 @@ namespace osu.Game.Screens.Play userAudioOffset.ValueChanged += v => offsetClock.Offset = v; userAudioOffset.TriggerChange(); + // We want the cursor to be above everything (including the skip button), but still be able to be controlled + // by the ruleset's input manager and replay, so we need to proxy it out from the ruleset container + var cursorProxyContainer = new Container { RelativeSizeAxes = Axes.Both }; + if (RulesetContainer.Cursor != null) + cursorProxyContainer.Add(RulesetContainer.Cursor.CreateProxy()); + Children = new Drawable[] { storyboardContainer = new Container @@ -195,6 +204,7 @@ namespace osu.Game.Screens.Play Clock = decoupledClock, Breaks = beatmap.Breaks }, + cursorProxyContainer } }, failOverlay = new FailOverlay diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index f87f664199..b87c1a0c6e 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -374,8 +374,10 @@ + + From 8ed24e1bca2e750b16cdb0acfeffe9b7eddccbc9 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 18:15:53 +0900 Subject: [PATCH 164/206] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 6594729122..a6090d3f6f 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 65947291229541de3eb1aff0e703f6968b07f976 +Subproject commit a6090d3f6f03eaf9a3f643cf1ef3db96384c62ff From ff725f0e32f8acd3c5ac9100d8e21d8d6a5c9082 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 18:17:32 +0900 Subject: [PATCH 165/206] Fix incorrect online conditional check in social browser logic --- osu.Game/Overlays/SocialOverlay.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Overlays/SocialOverlay.cs b/osu.Game/Overlays/SocialOverlay.cs index e61153d290..ddcb933e5d 100644 --- a/osu.Game/Overlays/SocialOverlay.cs +++ b/osu.Game/Overlays/SocialOverlay.cs @@ -155,7 +155,7 @@ namespace osu.Game.Overlays loading.Hide(); getUsersRequest?.Cancel(); - if (api?.IsLoggedIn == false) + if (api?.IsLoggedIn != true) return; switch (Header.Tabs.Current.Value) From a6c6523a86e8549e98c298f99f20481562797ae5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 18:21:17 +0900 Subject: [PATCH 166/206] Make SkipButton an OverlayContainer to use the menu cursor --- osu.Game/Screens/Play/SkipButton.cs | 14 +++++++++++++- 1 file changed, 13 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/SkipButton.cs b/osu.Game/Screens/Play/SkipButton.cs index 55b2e21c53..827d77a73a 100644 --- a/osu.Game/Screens/Play/SkipButton.cs +++ b/osu.Game/Screens/Play/SkipButton.cs @@ -21,7 +21,7 @@ using osu.Game.Input.Bindings; namespace osu.Game.Screens.Play { - public class SkipButton : Container, IKeyBindingHandler + public class SkipButton : OverlayContainer, IKeyBindingHandler { private readonly double startTime; public IAdjustableClock AudioClock; @@ -36,6 +36,8 @@ namespace osu.Game.Screens.Play { this.startTime = startTime; + State = Visibility.Visible; + RelativePositionAxes = Axes.Both; RelativeSizeAxes = Axes.Both; @@ -112,6 +114,16 @@ namespace osu.Game.Screens.Play Expire(); } + protected override void PopIn() + { + this.FadeIn(); + } + + protected override void PopOut() + { + this.FadeOut(); + } + protected override void Update() { base.Update(); From 1c3c90bac6886e2757bba11b1c458d2b4aad92f4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 4 Jan 2018 18:32:16 +0900 Subject: [PATCH 167/206] Add banana design (cherry picked from commit 6961ca2) --- .../Objects/Drawable/DrawableFruit.cs | 21 +++++++++++++++++++ 1 file changed, 21 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs index ae20abf0d9..93a1483f6f 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs @@ -243,6 +243,27 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable }, } }; + case FruitVisualRepresentation.Banana: + return new Container + { + RelativeSizeAxes = Axes.Both, + Children = new Framework.Graphics.Drawable[] + { + new Pulp + { + Anchor = Anchor.TopCentre, + Origin = Anchor.TopCentre, + AccentColour = AccentColour, + Size = new Vector2(small_pulp), + Y = -0.15f + }, + new Pulp + { + AccentColour = AccentColour, + Size = new Vector2(large_pulp_4 * 1.2f, large_pulp_4 * 3), + }, + } + }; } } From a36cfd426532ed148cbcd0088f8babf89d6ea49e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 10 Jan 2018 14:52:22 +0900 Subject: [PATCH 168/206] Add BananaShower models and representations (cherry picked from commit e12e095) --- .../Objects/BananaShower.cs | 61 +++++++++++++++++++ .../Objects/Drawable/DrawableBananaShower.cs | 40 ++++++++++++ .../Tests/TestCaseBananaShower.cs | 38 ++++++++++++ .../UI/CatchRulesetContainer.cs | 16 ++--- .../osu.Game.Rulesets.Catch.csproj | 3 + 5 files changed, 151 insertions(+), 7 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Objects/BananaShower.cs create mode 100644 osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs create mode 100644 osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs new file mode 100644 index 0000000000..cb0f4eab96 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -0,0 +1,61 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Framework.MathUtils; +using osu.Game.Rulesets.Objects.Types; +using OpenTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Objects +{ + public class BananaShower : CatchHitObject, IHasEndTime + { + public override FruitVisualRepresentation VisualRepresentation => FruitVisualRepresentation.Banana; + + protected override void CreateNestedHitObjects() + { + base.CreateNestedHitObjects(); + createBananas(); + } + + private void createBananas() + { + double spacing = Duration; + while (spacing > 100) + spacing /= 2; + + if (spacing <= 0) + return; + + for (double i = StartTime; i <= EndTime; i += spacing) + AddNested(new Banana + { + Samples = Samples, + ComboColour = getNextComboColour(), + StartTime = i, + X = RNG.NextSingle() + }); + } + + private Color4 getNextComboColour() + { + switch (RNG.Next(0, 3)) + { + default: + return new Color4(255, 240, 0, 255); + case 1: + return new Color4(255, 192, 0, 255); + case 2: + return new Color4(214, 221, 28, 255); + } + } + + public double EndTime => StartTime + Duration; + + public double Duration { get; set; } + + public class Banana : Fruit + { + public override FruitVisualRepresentation VisualRepresentation => FruitVisualRepresentation.Banana; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs new file mode 100644 index 0000000000..ff787d80e9 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs @@ -0,0 +1,40 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Linq; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using OpenTK; +using osu.Game.Rulesets.Objects.Drawables; + +namespace osu.Game.Rulesets.Catch.Objects.Drawable +{ + public class DrawableBananaShower : DrawableCatchHitObject + { + private readonly Container dropletContainer; + + public DrawableBananaShower(BananaShower s) : base(s) + { + RelativeSizeAxes = Axes.Both; + Height = (float)HitObject.Duration; + X = 0; + + Child = dropletContainer = new Container + { + RelativeSizeAxes = Axes.Both, + RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime), + RelativeChildSize = new Vector2(1, (float)HitObject.Duration) + }; + + foreach (var b in s.NestedHitObjects.OfType()) + AddNested(new DrawableFruit(b)); + } + + protected override void AddNested(DrawableHitObject h) + { + ((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false; + dropletContainer.Add(h); + base.AddNested(h); + } + } +} diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs new file mode 100644 index 0000000000..4499905560 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.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 NUnit.Framework; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Catch.Objects; + +namespace osu.Game.Rulesets.Catch.Tests +{ + [TestFixture] + [Ignore("getting CI working")] + public class TestCaseBananaShower : Game.Tests.Visual.TestCasePlayer + { + public TestCaseBananaShower() + : base(typeof(CatchRuleset)) + { + } + + protected override Beatmap CreateBeatmap() + { + var beatmap = new Beatmap + { + BeatmapInfo = new BeatmapInfo + { + BaseDifficulty = new BeatmapDifficulty + { + CircleSize = 6, + } + } + }; + + for (int i = 0; i < 10; i++) + beatmap.HitObjects.Add(new BananaShower { StartTime = i * 1200, Duration = 1000, NewCombo = i % 2 == 0 }); + + return beatmap; + } + } +} diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index a146014ca4..076487a5e2 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -33,13 +33,15 @@ namespace osu.Game.Rulesets.Catch.UI protected override DrawableHitObject GetVisualRepresentation(CatchHitObject h) { - var fruit = h as Fruit; - if (fruit != null) - return new DrawableFruit(fruit); - - var stream = h as JuiceStream; - if (stream != null) - return new DrawableJuiceStream(stream); + switch (h) + { + case Fruit fruit: + return new DrawableFruit(fruit); + case JuiceStream stream: + return new DrawableJuiceStream(stream); + case BananaShower banana: + return new DrawableBananaShower(banana); + } return null; } diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 566ec385fc..50fbc8b6a2 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -60,6 +60,8 @@ + + @@ -73,6 +75,7 @@ + From 5c79bdc41c613ac3c9db32004abfe092f4e8e655 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 10 Jan 2018 15:37:55 +0900 Subject: [PATCH 169/206] Use switch pattern matching in more places Also switch access to many classes to public. (cherry picked from commit 86cc3b7) --- .../Beatmaps/CatchBeatmapProcessor.cs | 2 +- .../Objects/Drawable/DrawableJuiceStream.cs | 28 ++++++++--------- .../Scoring/CatchScoreProcessor.cs | 30 ++++++++++--------- 3 files changed, 30 insertions(+), 30 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs index f601ce624d..d3012b1981 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs @@ -12,7 +12,7 @@ using OpenTK; namespace osu.Game.Rulesets.Catch.Beatmaps { - internal class CatchBeatmapProcessor : BeatmapProcessor + public class CatchBeatmapProcessor : BeatmapProcessor { public override void PostProcess(Beatmap beatmap) { diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 036c5bd879..2955b51044 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using OpenTK; @@ -13,7 +12,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { private readonly Container dropletContainer; - public DrawableJuiceStream(JuiceStream s) : base(s) + public DrawableJuiceStream(JuiceStream s) + : base(s) { RelativeSizeAxes = Axes.Both; Origin = Anchor.BottomLeft; @@ -21,22 +21,20 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Child = dropletContainer = new Container { RelativeSizeAxes = Axes.Both, }; - foreach (CatchHitObject tick in s.NestedHitObjects.OfType()) + foreach (var tick in s.NestedHitObjects) { - TinyDroplet tiny = tick as TinyDroplet; - if (tiny != null) + switch (tick) { - AddNested(new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) }); - continue; + case TinyDroplet tiny: + AddNested(new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) }); + break; + case Droplet droplet: + AddNested(new DrawableDroplet(droplet)); + break; + case Fruit fruit: + AddNested(new DrawableFruit(fruit)); + break; } - - Droplet droplet = tick as Droplet; - if (droplet != null) - AddNested(new DrawableDroplet(droplet)); - - Fruit fruit = tick as Fruit; - if (fruit != null) - AddNested(new DrawableFruit(fruit)); } } diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs index a6dc1350be..6df9498881 100644 --- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs +++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.UI; namespace osu.Game.Rulesets.Catch.Scoring { - internal class CatchScoreProcessor : ScoreProcessor + public class CatchScoreProcessor : ScoreProcessor { public CatchScoreProcessor(RulesetContainer rulesetContainer) : base(rulesetContainer) @@ -21,23 +21,25 @@ namespace osu.Game.Rulesets.Catch.Scoring { foreach (var obj in beatmap.HitObjects) { - var stream = obj as JuiceStream; - - if (stream != null) + switch (obj) { - AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); - AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); - - foreach (var unused in stream.NestedHitObjects.OfType()) + case JuiceStream stream: + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); - continue; + foreach (var _ in stream.NestedHitObjects.Cast()) + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + break; + case BananaShower shower: + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + + foreach (var _ in shower.NestedHitObjects.Cast()) + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + break; + case Fruit _: + AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); + break; } - - var fruit = obj as Fruit; - - if (fruit != null) - AddJudgement(new CatchJudgement { Result = HitResult.Perfect }); } base.SimulateAutoplay(beatmap); From 5b150730107888fd4e39f881a3a05d7fe3c1fb24 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 10 Jan 2018 15:38:12 +0900 Subject: [PATCH 170/206] Add actual banana conversion/reading (cherry picked from commit d353158) --- .../Beatmaps/CatchBeatmapConverter.cs | 16 +++++++++++++++- .../Objects/Drawable/DrawableBananaShower.cs | 8 ++++---- 2 files changed, 19 insertions(+), 5 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs index dadb852654..01aa7abb9f 100644 --- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs +++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs @@ -11,7 +11,7 @@ using osu.Game.Rulesets.Objects; namespace osu.Game.Rulesets.Catch.Beatmaps { - internal class CatchBeatmapConverter : BeatmapConverter + public class CatchBeatmapConverter : BeatmapConverter { protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) }; @@ -20,6 +20,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps var curveData = obj as IHasCurve; var positionData = obj as IHasXPosition; var comboData = obj as IHasCombo; + var endTime = obj as IHasEndTime; if (positionData == null) yield break; @@ -42,6 +43,19 @@ namespace osu.Game.Rulesets.Catch.Beatmaps yield break; } + if (endTime != null) + { + yield return new BananaShower + { + StartTime = obj.StartTime, + Samples = obj.Samples, + Duration = endTime.Duration, + NewCombo = comboData?.NewCombo ?? false + }; + + yield break; + } + yield return new Fruit { StartTime = obj.StartTime, diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs index ff787d80e9..0bbf12bfcc 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs @@ -11,7 +11,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { public class DrawableBananaShower : DrawableCatchHitObject { - private readonly Container dropletContainer; + private readonly Container bananaContainer; public DrawableBananaShower(BananaShower s) : base(s) { @@ -19,21 +19,21 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Height = (float)HitObject.Duration; X = 0; - Child = dropletContainer = new Container + Child = bananaContainer = new Container { RelativeSizeAxes = Axes.Both, RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime), RelativeChildSize = new Vector2(1, (float)HitObject.Duration) }; - foreach (var b in s.NestedHitObjects.OfType()) + foreach (var b in s.NestedHitObjects.Cast()) AddNested(new DrawableFruit(b)); } protected override void AddNested(DrawableHitObject h) { ((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false; - dropletContainer.Add(h); + bananaContainer.Add(h); base.AddNested(h); } } From 26fedd7e61cac1145b92e3e32c6016c30b8f5d23 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 10 Jan 2018 16:58:20 +0900 Subject: [PATCH 171/206] Update in line with upstream changes (cherry picked from commit 2b6d991) --- .../Objects/Drawable/DrawableBananaShower.cs | 7 ++++--- .../Tests/TestCaseBananaShower.cs | 15 ++++++++++++++- 2 files changed, 18 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs index 0bbf12bfcc..b38880a8c3 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs @@ -13,13 +13,14 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { private readonly Container bananaContainer; - public DrawableBananaShower(BananaShower s) : base(s) + public DrawableBananaShower(BananaShower s) + : base(s) { RelativeSizeAxes = Axes.Both; Height = (float)HitObject.Duration; X = 0; - Child = bananaContainer = new Container + Child = bananaContainer = new Container { RelativeSizeAxes = Axes.Both, RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime), @@ -27,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable }; foreach (var b in s.NestedHitObjects.Cast()) - AddNested(new DrawableFruit(b)); + AddNested(new DrawableFruit(b)); } protected override void AddNested(DrawableHitObject h) diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs index 4499905560..aae36beb57 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs @@ -1,9 +1,13 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Collections.Generic; using NUnit.Framework; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Catch.UI; namespace osu.Game.Rulesets.Catch.Tests { @@ -11,8 +15,17 @@ namespace osu.Game.Rulesets.Catch.Tests [Ignore("getting CI working")] public class TestCaseBananaShower : Game.Tests.Visual.TestCasePlayer { + public override IReadOnlyList RequiredTypes => new[] + { + typeof(BananaShower), + typeof(DrawableBananaShower), + + typeof(CatchRuleset), + typeof(CatchRulesetContainer), + }; + public TestCaseBananaShower() - : base(typeof(CatchRuleset)) + : base(new CatchRuleset()) { } From 3b929ffd21035432d09ea8dc029150bc4194e54e Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Wed, 10 Jan 2018 19:18:03 +0900 Subject: [PATCH 172/206] Make test more useful (cherry picked from commit 5985115) --- osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs index aae36beb57..4f183c3ebc 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs @@ -42,8 +42,7 @@ namespace osu.Game.Rulesets.Catch.Tests } }; - for (int i = 0; i < 10; i++) - beatmap.HitObjects.Add(new BananaShower { StartTime = i * 1200, Duration = 1000, NewCombo = i % 2 == 0 }); + beatmap.HitObjects.Add(new BananaShower { StartTime = 200, Duration = 10000, NewCombo = true }); return beatmap; } From 9e3091bfe9c78c466b3044316c408340596f0537 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Thu, 11 Jan 2018 13:41:50 +0900 Subject: [PATCH 173/206] Change anchors in line with new ScrollingPlayfield implementation (cherry picked from commit 079827d) --- .../Objects/Drawable/DrawableBananaShower.cs | 14 ++++---------- .../Tests/TestCaseBananaShower.cs | 2 +- 2 files changed, 5 insertions(+), 11 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs index b38880a8c3..b5d9163a50 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs @@ -4,7 +4,6 @@ using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using OpenTK; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Objects.Drawable @@ -16,22 +15,17 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public DrawableBananaShower(BananaShower s) : base(s) { - RelativeSizeAxes = Axes.Both; - Height = (float)HitObject.Duration; + RelativeSizeAxes = Axes.X; + Origin = Anchor.BottomLeft; X = 0; - Child = bananaContainer = new Container - { - RelativeSizeAxes = Axes.Both, - RelativeChildOffset = new Vector2(0, (float)HitObject.StartTime), - RelativeChildSize = new Vector2(1, (float)HitObject.Duration) - }; + Child = bananaContainer = new Container { RelativeSizeAxes = Axes.Both }; foreach (var b in s.NestedHitObjects.Cast()) AddNested(new DrawableFruit(b)); } - protected override void AddNested(DrawableHitObject h) + protected override void AddNested(DrawableHitObject h) { ((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false; bananaContainer.Add(h); diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs index 4f183c3ebc..6bf5b6beca 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Catch.Tests } }; - beatmap.HitObjects.Add(new BananaShower { StartTime = 200, Duration = 10000, NewCombo = true }); + beatmap.HitObjects.Add(new BananaShower { StartTime = 200, Duration = 500, NewCombo = true }); return beatmap; } From 33fdc2c1d6210898150726457adfe62e48509937 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 18:35:28 +0900 Subject: [PATCH 174/206] Add very basic replay handling --- osu.Game.Rulesets.Catch/CatchInputManager.cs | 3 +- osu.Game.Rulesets.Catch/CatchRuleset.cs | 2 +- .../Mods/CatchModAutoplay.cs | 24 +++++++++ .../Replays/CatchAutoGenerator.cs | 54 +++++++++++++++++++ .../Replays/CatchFramedReplayInputHandler.cs | 32 +++++++++++ .../Replays/CatchReplayFrame.cs | 17 ++++++ .../UI/CatchRulesetContainer.cs | 4 ++ osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 17 +++++- .../osu.Game.Rulesets.Catch.csproj | 4 ++ 9 files changed, 154 insertions(+), 3 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs create mode 100644 osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs create mode 100644 osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs create mode 100644 osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs diff --git a/osu.Game.Rulesets.Catch/CatchInputManager.cs b/osu.Game.Rulesets.Catch/CatchInputManager.cs index d1851d31bf..f57952f95e 100644 --- a/osu.Game.Rulesets.Catch/CatchInputManager.cs +++ b/osu.Game.Rulesets.Catch/CatchInputManager.cs @@ -22,6 +22,7 @@ namespace osu.Game.Rulesets.Catch [Description("Move right")] MoveRight, [Description("Engage dash")] - Dash + Dash, + PositionUpdate } } diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 0d52046485..08bc94863b 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -81,7 +81,7 @@ namespace osu.Game.Rulesets.Catch { Mods = new Mod[] { - new ModAutoplay(), + new CatchModAutoplay(), new ModCinema(), }, }, diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs b/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs new file mode 100644 index 0000000000..8ff08ab825 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs @@ -0,0 +1,24 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.Replays; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Scoring; +using osu.Game.Users; + +namespace osu.Game.Rulesets.Catch.Mods +{ + public class CatchModAutoplay : ModAutoplay + { + protected override Score CreateReplayScore(Beatmap beatmap) + { + return new Score + { + User = new User { Username = "osu!salad!" }, + Replay = new CatchAutoGenerator(beatmap).Generate(), + }; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs new file mode 100644 index 0000000000..bc53e6e869 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs @@ -0,0 +1,54 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Linq; +using osu.Game.Beatmaps; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Replays; +using osu.Game.Users; + +namespace osu.Game.Rulesets.Catch.Replays +{ + internal class CatchAutoGenerator : AutoGenerator + { + public const double RELEASE_DELAY = 20; + + public CatchAutoGenerator(Beatmap beatmap) + : base(beatmap) + { + Replay = new Replay { User = new User { Username = @"Autoplay" } }; + } + + protected Replay Replay; + + public override Replay Generate() + { + // Todo: Realistically this shouldn't be needed, but the first frame is skipped with the way replays are currently handled + Replay.Frames.Add(new CatchReplayFrame(-100000, 0)); + + foreach (var obj in Beatmap.HitObjects) + { + switch (obj) + { + case Fruit _: + Replay.Frames.Add(new CatchReplayFrame(obj.StartTime, obj.X)); + break; + } + + foreach (var nestedObj in obj.NestedHitObjects.Cast()) + { + switch (nestedObj) + { + case BananaShower.Banana _: + case TinyDroplet _: + case Droplet _: + Replay.Frames.Add(new CatchReplayFrame(nestedObj.StartTime, nestedObj.X)); + break; + } + } + } + + return Replay; + } + } +} diff --git a/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs b/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs new file mode 100644 index 0000000000..146e31fa69 --- /dev/null +++ b/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs @@ -0,0 +1,32 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using System.Collections.Generic; +using osu.Framework.Input; +using osu.Game.Rulesets.Replays; + +namespace osu.Game.Rulesets.Catch.Replays +{ + public class CatchFramedReplayInputHandler : FramedReplayInputHandler + { + public CatchFramedReplayInputHandler(Replay replay) + : base(replay) + { + } + + public override List GetPendingStates() => new List + { + new CatchReplayState + { + PressedActions = new List { CatchAction.PositionUpdate }, + CatcherX = ((CatchReplayFrame)CurrentFrame).MouseX + }, + new CatchReplayState { PressedActions = new List() }, + }; + + public class CatchReplayState : ReplayState + { + public float? CatcherX { get; set; } + } + } +} diff --git a/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs b/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs new file mode 100644 index 0000000000..c47f60ec3c --- /dev/null +++ b/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs @@ -0,0 +1,17 @@ +// Copyright (c) 2007-2018 ppy Pty Ltd . +// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE + +using osu.Game.Rulesets.Replays; + +namespace osu.Game.Rulesets.Catch.Replays +{ + public class CatchReplayFrame : ReplayFrame + { + public override bool IsImportant => MouseX > 0; + + public CatchReplayFrame(double time, float? x = null) + : base(time, x ?? -1, null, ReplayButtonState.None) + { + } + } +} diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index a146014ca4..08808a445e 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -6,8 +6,10 @@ using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Catch.Scoring; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; @@ -23,6 +25,8 @@ namespace osu.Game.Rulesets.Catch.UI public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(this); + protected override FramedReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay); + protected override BeatmapProcessor CreateBeatmapProcessor() => new CatchBeatmapProcessor(); protected override BeatmapConverter CreateBeatmapConverter() => new CatchBeatmapConverter(); diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index c70cb15b40..1837086d9c 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -13,6 +13,7 @@ using osu.Framework.MathUtils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Catch.Objects.Drawable; +using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; using osu.Game.Rulesets.UI; @@ -21,7 +22,7 @@ using OpenTK.Graphics; namespace osu.Game.Rulesets.Catch.UI { - public class CatcherArea : Container + public class CatcherArea : Container, IKeyBindingHandler { public const float CATCHER_SIZE = 172; @@ -72,6 +73,20 @@ namespace osu.Game.Rulesets.Catch.UI } } + public bool OnPressed(CatchAction action) + { + if (action != CatchAction.PositionUpdate) return false; + + CatchFramedReplayInputHandler.CatchReplayState state = (CatchFramedReplayInputHandler.CatchReplayState)GetContainingInputManager().CurrentState; + + if (state.CatcherX.HasValue) + MovableCatcher.X = state.CatcherX.Value; + + return true; + } + + public bool OnReleased(CatchAction action) => false; + public bool AttemptCatch(CatchHitObject obj) => MovableCatcher.AttemptCatch(obj); public class Catcher : Container, IKeyBindingHandler diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj index 566ec385fc..4d17fa6570 100644 --- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj +++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj @@ -60,11 +60,15 @@ + + + + From 98894f010fada7224403248726d90825ccf64844 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 18:57:53 +0900 Subject: [PATCH 175/206] Update framework --- osu-framework | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu-framework b/osu-framework index 80bcb82ef8..49b563e2cf 160000 --- a/osu-framework +++ b/osu-framework @@ -1 +1 @@ -Subproject commit 80bcb82ef8d2e1af1ce077f4a037b6d279ad9e74 +Subproject commit 49b563e2cf170eb19006b98dd5b69c2398362d9e From 5952f1e7f19e3bf7b029aba917becf7f9536b5df Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 19:34:14 +0900 Subject: [PATCH 176/206] Adjust transforms for cursor transitions --- osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs | 12 ++++++++++++ osu.Game/Graphics/Cursor/MenuCursor.cs | 4 ++-- 2 files changed, 14 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs index 325f22f425..0aeb14514d 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/GameplayCursor.cs @@ -159,5 +159,17 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor return false; } + + protected override void PopIn() + { + ActiveCursor.FadeTo(1, 250, Easing.OutQuint); + ActiveCursor.ScaleTo(1, 400, Easing.OutQuint); + } + + protected override void PopOut() + { + ActiveCursor.FadeTo(0, 250, Easing.OutQuint); + ActiveCursor.ScaleTo(0.6f, 250, Easing.In); + } } } diff --git a/osu.Game/Graphics/Cursor/MenuCursor.cs b/osu.Game/Graphics/Cursor/MenuCursor.cs index 39af99f02e..0de6279b2e 100644 --- a/osu.Game/Graphics/Cursor/MenuCursor.cs +++ b/osu.Game/Graphics/Cursor/MenuCursor.cs @@ -99,8 +99,8 @@ namespace osu.Game.Graphics.Cursor protected override void PopOut() { - ActiveCursor.FadeTo(0, 900, Easing.OutQuint); - ActiveCursor.ScaleTo(0, 500, Easing.In); + ActiveCursor.FadeTo(0, 250, Easing.OutQuint); + ActiveCursor.ScaleTo(0.6f, 250, Easing.In); } [BackgroundDependencyLoader] From 620e125fad1a47e6a7f196d90bac84928647fa42 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 19:34:55 +0900 Subject: [PATCH 177/206] Fix cursor being displayed on intro/disclaimer --- osu.Game/Graphics/Cursor/OsuCursorContainer.cs | 11 +++++++++++ osu.Game/OsuGame.cs | 2 ++ osu.Game/OsuGameBase.cs | 10 ++++++---- osu.Game/Screens/Menu/Disclaimer.cs | 8 ++------ osu.Game/Screens/Menu/Intro.cs | 8 ++------ osu.Game/Screens/OsuScreen.cs | 5 +++++ 6 files changed, 28 insertions(+), 16 deletions(-) diff --git a/osu.Game/Graphics/Cursor/OsuCursorContainer.cs b/osu.Game/Graphics/Cursor/OsuCursorContainer.cs index ca6b6085c2..8a25c9c587 100644 --- a/osu.Game/Graphics/Cursor/OsuCursorContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuCursorContainer.cs @@ -14,6 +14,11 @@ namespace osu.Game.Graphics.Cursor protected override Container Content => content; private readonly Container content; + /// + /// Whether any cursors can be displayed. + /// + public bool CanShowCursor; + public CursorContainer LocalCursor { get; } public bool ProvidesUserCursor => true; @@ -39,6 +44,12 @@ namespace osu.Game.Graphics.Cursor { base.Update(); + if (!CanShowCursor) + { + currentTarget?.LocalCursor?.Hide(); + return; + } + var newTarget = inputManager.HoveredDrawables.OfType().FirstOrDefault(t => t.ProvidesUserCursor) ?? this; if (currentTarget == newTarget) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f0edcbbc6b..fb20fd57fa 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -444,6 +444,8 @@ namespace osu.Game Beatmap.Disabled = applyRestrictions; mainContent.Padding = new MarginPadding { Top = ToolbarOffset }; + + CursorContainer.CanShowCursor = currentScreen?.CursorVisible ?? false; } private void screenAdded(Screen newScreen) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index ff9264c598..c88ffd3739 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -44,6 +44,8 @@ namespace osu.Game protected KeyBindingStore KeyBindingStore; + protected OsuCursorContainer CursorContainer; + protected override string MainResourceFile => @"osu.Game.Resources.dll"; public APIAccess API; @@ -209,14 +211,14 @@ namespace osu.Game GlobalKeyBindingInputManager globalBinding; - var cursorContainer = new OsuCursorContainer { RelativeSizeAxes = Axes.Both }; - cursorContainer.Child = globalBinding = new GlobalKeyBindingInputManager(this) + CursorContainer = new OsuCursorContainer { RelativeSizeAxes = Axes.Both }; + CursorContainer.Child = globalBinding = new GlobalKeyBindingInputManager(this) { RelativeSizeAxes = Axes.Both, - Child = content = new OsuTooltipContainer(cursorContainer.LocalCursor) { RelativeSizeAxes = Axes.Both } + Child = content = new OsuTooltipContainer(CursorContainer.LocalCursor) { RelativeSizeAxes = Axes.Both } }; - base.Content.Add(new DrawSizePreservingFillContainer { Child = cursorContainer }); + base.Content.Add(new DrawSizePreservingFillContainer { Child = CursorContainer }); KeyBindingStore.Register(globalBinding); dependencies.Cache(globalBinding); diff --git a/osu.Game/Screens/Menu/Disclaimer.cs b/osu.Game/Screens/Menu/Disclaimer.cs index a54abe8cf1..8285416ecb 100644 --- a/osu.Game/Screens/Menu/Disclaimer.cs +++ b/osu.Game/Screens/Menu/Disclaimer.cs @@ -9,21 +9,17 @@ using osu.Game.Graphics; using osu.Game.Graphics.Sprites; using OpenTK; using OpenTK.Graphics; -using osu.Game.Graphics.Cursor; -using osu.Framework.Graphics.Cursor; namespace osu.Game.Screens.Menu { - public class Disclaimer : OsuScreen, IProvideLocalCursor + public class Disclaimer : OsuScreen { private Intro intro; private readonly SpriteIcon icon; private Color4 iconColour; public override bool ShowOverlaysOnEnter => false; - - public CursorContainer LocalCursor => null; - public bool ProvidesUserCursor => true; + public override bool CursorVisible => false; public Disclaimer() { diff --git a/osu.Game/Screens/Menu/Intro.cs b/osu.Game/Screens/Menu/Intro.cs index 5fac56fafb..10b08d704d 100644 --- a/osu.Game/Screens/Menu/Intro.cs +++ b/osu.Game/Screens/Menu/Intro.cs @@ -15,12 +15,10 @@ using osu.Game.Configuration; using osu.Game.Screens.Backgrounds; using OpenTK; using OpenTK.Graphics; -using osu.Game.Graphics.Cursor; -using osu.Framework.Graphics.Cursor; namespace osu.Game.Screens.Menu { - public class Intro : OsuScreen, IProvideLocalCursor + public class Intro : OsuScreen { private const string menu_music_beatmap_hash = "3c8b1fcc9434dbb29e2fb613d3b9eada9d7bb6c125ceb32396c3b53437280c83"; @@ -34,9 +32,7 @@ namespace osu.Game.Screens.Menu private SampleChannel seeya; public override bool ShowOverlaysOnEnter => false; - - public CursorContainer LocalCursor => null; - public bool ProvidesUserCursor => true; + public override bool CursorVisible => false; protected override BackgroundScreen CreateBackground() => new BackgroundScreenEmpty(); diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs index 48ca4d5907..a2d41dc206 100644 --- a/osu.Game/Screens/OsuScreen.cs +++ b/osu.Game/Screens/OsuScreen.cs @@ -35,6 +35,11 @@ namespace osu.Game.Screens /// public virtual bool ShowOverlaysOnEnter => true; + /// + /// Whether this allows the cursor to be displayed. + /// + public virtual bool CursorVisible => true; + protected new OsuGameBase Game => base.Game as OsuGameBase; private OsuLogo logo; From 16d739580b12de0c5aef1916e9c337aa9614f769 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 19:36:35 +0900 Subject: [PATCH 178/206] IProvideLocalCursor -> IProvideCursor --- ...{IProvideLocalCursor.cs => IProvideCursor.cs} | 4 ++-- osu.Game/Graphics/Cursor/OsuCursorContainer.cs | 16 ++++++++-------- osu.Game/OsuGameBase.cs | 2 +- osu.Game/Screens/Play/Player.cs | 4 ++-- osu.Game/osu.Game.csproj | 2 +- 5 files changed, 14 insertions(+), 14 deletions(-) rename osu.Game/Graphics/Cursor/{IProvideLocalCursor.cs => IProvideCursor.cs} (84%) diff --git a/osu.Game/Graphics/Cursor/IProvideLocalCursor.cs b/osu.Game/Graphics/Cursor/IProvideCursor.cs similarity index 84% rename from osu.Game/Graphics/Cursor/IProvideLocalCursor.cs rename to osu.Game/Graphics/Cursor/IProvideCursor.cs index 61631b1220..eb17f72846 100644 --- a/osu.Game/Graphics/Cursor/IProvideLocalCursor.cs +++ b/osu.Game/Graphics/Cursor/IProvideCursor.cs @@ -6,12 +6,12 @@ using osu.Framework.Graphics.Cursor; namespace osu.Game.Graphics.Cursor { - public interface IProvideLocalCursor : IDrawable + public interface IProvideCursor : IDrawable { /// /// The cursor provided by this . /// - CursorContainer LocalCursor { get; } + CursorContainer Cursor { get; } /// /// Whether the cursor provided by this should be displayed. diff --git a/osu.Game/Graphics/Cursor/OsuCursorContainer.cs b/osu.Game/Graphics/Cursor/OsuCursorContainer.cs index 8a25c9c587..bc4e084813 100644 --- a/osu.Game/Graphics/Cursor/OsuCursorContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuCursorContainer.cs @@ -9,7 +9,7 @@ using osu.Framework.Input; namespace osu.Game.Graphics.Cursor { - public class OsuCursorContainer : Container, IProvideLocalCursor + public class OsuCursorContainer : Container, IProvideCursor { protected override Container Content => content; private readonly Container content; @@ -19,14 +19,14 @@ namespace osu.Game.Graphics.Cursor /// public bool CanShowCursor; - public CursorContainer LocalCursor { get; } + public CursorContainer Cursor { get; } public bool ProvidesUserCursor => true; public OsuCursorContainer() { AddRangeInternal(new Drawable[] { - LocalCursor = new MenuCursor { State = Visibility.Hidden }, + Cursor = new MenuCursor { State = Visibility.Hidden }, content = new Container { RelativeSizeAxes = Axes.Both } }); } @@ -39,24 +39,24 @@ namespace osu.Game.Graphics.Cursor inputManager = GetContainingInputManager(); } - private IProvideLocalCursor currentTarget; + private IProvideCursor currentTarget; protected override void Update() { base.Update(); if (!CanShowCursor) { - currentTarget?.LocalCursor?.Hide(); + currentTarget?.Cursor?.Hide(); return; } - var newTarget = inputManager.HoveredDrawables.OfType().FirstOrDefault(t => t.ProvidesUserCursor) ?? this; + var newTarget = inputManager.HoveredDrawables.OfType().FirstOrDefault(t => t.ProvidesUserCursor) ?? this; if (currentTarget == newTarget) return; - currentTarget?.LocalCursor?.Hide(); - newTarget.LocalCursor?.Show(); + currentTarget?.Cursor?.Hide(); + newTarget.Cursor?.Show(); currentTarget = newTarget; } diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index c88ffd3739..c615b212c3 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -215,7 +215,7 @@ namespace osu.Game CursorContainer.Child = globalBinding = new GlobalKeyBindingInputManager(this) { RelativeSizeAxes = Axes.Both, - Child = content = new OsuTooltipContainer(CursorContainer.LocalCursor) { RelativeSizeAxes = Axes.Both } + Child = content = new OsuTooltipContainer(CursorContainer.Cursor) { RelativeSizeAxes = Axes.Both } }; base.Content.Add(new DrawSizePreservingFillContainer { Child = CursorContainer }); diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index a2d1d161c4..4c294b08ff 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -33,7 +33,7 @@ using osu.Game.Storyboards.Drawables; namespace osu.Game.Screens.Play { - public class Player : OsuScreen, IProvideLocalCursor + public class Player : OsuScreen, IProvideCursor { protected override BackgroundScreen CreateBackground() => new BackgroundScreenBeatmap(Beatmap); @@ -51,7 +51,7 @@ namespace osu.Game.Screens.Play public int RestartCount; - public CursorContainer LocalCursor => RulesetContainer.Cursor; + public CursorContainer Cursor => RulesetContainer.Cursor; public bool ProvidesUserCursor => RulesetContainer?.Cursor != null && !RulesetContainer.HasReplayLoaded; private IAdjustableClock adjustableSourceClock; diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index b87c1a0c6e..7175e813f4 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -374,7 +374,7 @@ - + From 34aee4fea0eae02556b6f9c07dc8ab05f68e61fd Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 19:37:57 +0900 Subject: [PATCH 179/206] Improve comments --- osu.Game/Graphics/Cursor/IProvideCursor.cs | 7 +++++-- 1 file changed, 5 insertions(+), 2 deletions(-) diff --git a/osu.Game/Graphics/Cursor/IProvideCursor.cs b/osu.Game/Graphics/Cursor/IProvideCursor.cs index eb17f72846..b36155a881 100644 --- a/osu.Game/Graphics/Cursor/IProvideCursor.cs +++ b/osu.Game/Graphics/Cursor/IProvideCursor.cs @@ -6,16 +6,19 @@ using osu.Framework.Graphics.Cursor; namespace osu.Game.Graphics.Cursor { + /// + /// Interface for s that display cursors which can replace the user's cursor. + /// public interface IProvideCursor : IDrawable { /// /// The cursor provided by this . + /// May be null if no cursor should be visible. /// CursorContainer Cursor { get; } /// - /// Whether the cursor provided by this should be displayed. - /// If this is false, a cursor occurring earlier in the draw hierarchy will be displayed instead. + /// Whether the cursor provided by this should be displayed as the user's cursor. /// bool ProvidesUserCursor { get; } } From 7bdedf802c8881071a42c9083ae6396ea9a532a0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 19:18:49 +0900 Subject: [PATCH 180/206] Fix juice streams not propagating accent colours to nested objects --- .../Objects/Drawable/DrawableJuiceStream.cs | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index 036c5bd879..1c59b65663 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -42,7 +42,11 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected override void AddNested(DrawableHitObject h) { - ((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false; + var catchObject = (DrawableCatchHitObject)h; + + catchObject.CheckPosition = o => CheckPosition?.Invoke(o) ?? false; + catchObject.AccentColour = HitObject.ComboColour; + dropletContainer.Add(h); base.AddNested(h); } From 78441c05cb5d561d0601ea82a13a1e67b28d972e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 19:45:09 +0900 Subject: [PATCH 181/206] OsuCursorContainer -> OsuCursorVisualiser --- .../{OsuCursorContainer.cs => OsuCursorVisualiser.cs} | 7 +++++-- osu.Game/OsuGame.cs | 2 +- osu.Game/OsuGameBase.cs | 10 +++++----- osu.Game/osu.Game.csproj | 2 +- 4 files changed, 12 insertions(+), 9 deletions(-) rename osu.Game/Graphics/Cursor/{OsuCursorContainer.cs => OsuCursorVisualiser.cs} (85%) diff --git a/osu.Game/Graphics/Cursor/OsuCursorContainer.cs b/osu.Game/Graphics/Cursor/OsuCursorVisualiser.cs similarity index 85% rename from osu.Game/Graphics/Cursor/OsuCursorContainer.cs rename to osu.Game/Graphics/Cursor/OsuCursorVisualiser.cs index bc4e084813..2b2ab593aa 100644 --- a/osu.Game/Graphics/Cursor/OsuCursorContainer.cs +++ b/osu.Game/Graphics/Cursor/OsuCursorVisualiser.cs @@ -9,7 +9,10 @@ using osu.Framework.Input; namespace osu.Game.Graphics.Cursor { - public class OsuCursorContainer : Container, IProvideCursor + /// + /// Visualises different cursors depending on the currently-hovered s. + /// + public class OsuCursorVisualiser : Container, IProvideCursor { protected override Container Content => content; private readonly Container content; @@ -22,7 +25,7 @@ namespace osu.Game.Graphics.Cursor public CursorContainer Cursor { get; } public bool ProvidesUserCursor => true; - public OsuCursorContainer() + public OsuCursorVisualiser() { AddRangeInternal(new Drawable[] { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index fb20fd57fa..3dda26fc02 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -445,7 +445,7 @@ namespace osu.Game mainContent.Padding = new MarginPadding { Top = ToolbarOffset }; - CursorContainer.CanShowCursor = currentScreen?.CursorVisible ?? false; + CursorVisualiser.CanShowCursor = currentScreen?.CursorVisible ?? false; } private void screenAdded(Screen newScreen) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index c615b212c3..61ad4024f0 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -44,7 +44,7 @@ namespace osu.Game protected KeyBindingStore KeyBindingStore; - protected OsuCursorContainer CursorContainer; + protected OsuCursorVisualiser CursorVisualiser; protected override string MainResourceFile => @"osu.Game.Resources.dll"; @@ -211,14 +211,14 @@ namespace osu.Game GlobalKeyBindingInputManager globalBinding; - CursorContainer = new OsuCursorContainer { RelativeSizeAxes = Axes.Both }; - CursorContainer.Child = globalBinding = new GlobalKeyBindingInputManager(this) + CursorVisualiser = new OsuCursorVisualiser { RelativeSizeAxes = Axes.Both }; + CursorVisualiser.Child = globalBinding = new GlobalKeyBindingInputManager(this) { RelativeSizeAxes = Axes.Both, - Child = content = new OsuTooltipContainer(CursorContainer.Cursor) { RelativeSizeAxes = Axes.Both } + Child = content = new OsuTooltipContainer(CursorVisualiser.Cursor) { RelativeSizeAxes = Axes.Both } }; - base.Content.Add(new DrawSizePreservingFillContainer { Child = CursorContainer }); + base.Content.Add(new DrawSizePreservingFillContainer { Child = CursorVisualiser }); KeyBindingStore.Register(globalBinding); dependencies.Cache(globalBinding); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index 7175e813f4..fd53a211e0 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -377,7 +377,7 @@ - + From d0b177e23390dfee9118453afc41ac1d0bde4c8f Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 19:50:09 +0900 Subject: [PATCH 182/206] Proxying isn't needed anymore --- osu.Game/Screens/Play/Player.cs | 9 +-------- 1 file changed, 1 insertion(+), 8 deletions(-) diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index 4c294b08ff..a93c616c6a 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -155,12 +155,6 @@ namespace osu.Game.Screens.Play userAudioOffset.ValueChanged += v => offsetClock.Offset = v; userAudioOffset.TriggerChange(); - // We want the cursor to be above everything (including the skip button), but still be able to be controlled - // by the ruleset's input manager and replay, so we need to proxy it out from the ruleset container - var cursorProxyContainer = new Container { RelativeSizeAxes = Axes.Both }; - if (RulesetContainer.Cursor != null) - cursorProxyContainer.Add(RulesetContainer.Cursor.CreateProxy()); - Children = new Drawable[] { storyboardContainer = new Container @@ -203,8 +197,7 @@ namespace osu.Game.Screens.Play Origin = Anchor.Centre, Clock = decoupledClock, Breaks = beatmap.Breaks - }, - cursorProxyContainer + } } }, failOverlay = new FailOverlay From 90bcec42d7ef99a48676b0d171f41203b5b30857 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 12 Jan 2018 20:48:58 +0900 Subject: [PATCH 183/206] Remove unused using --- osu.Game.Rulesets.Catch/CatchRuleset.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs index 08bc94863b..5e70239c7c 100644 --- a/osu.Game.Rulesets.Catch/CatchRuleset.cs +++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs @@ -10,7 +10,6 @@ using osu.Game.Rulesets.UI; using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Input.Bindings; -using osu.Game.Rulesets.Catch.Objects; namespace osu.Game.Rulesets.Catch { From 93c4d58b69d29c3a13b7bee1ab4737eb03b4ae3b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 21:46:50 +0900 Subject: [PATCH 184/206] Make catch plate fruit again --- .../Objects/Drawable/DrawableBananaShower.cs | 5 ++-- .../Drawable/DrawableCatchHitObject.cs | 26 ++++++++++++---- .../Objects/Drawable/DrawableJuiceStream.cs | 22 ++++---------- .../Objects/JuiceStream.cs | 2 -- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 4 ++- .../UI/CatchRulesetContainer.cs | 11 +++++-- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 30 ++++++++++--------- 7 files changed, 55 insertions(+), 45 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs index b5d9163a50..72aeddee56 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -12,7 +13,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { private readonly Container bananaContainer; - public DrawableBananaShower(BananaShower s) + public DrawableBananaShower(BananaShower s, Func> getVisualRepresentation = null) : base(s) { RelativeSizeAxes = Axes.X; @@ -22,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Child = bananaContainer = new Container { RelativeSizeAxes = Axes.Both }; foreach (var b in s.NestedHitObjects.Cast()) - AddNested(new DrawableFruit(b)); + AddNested(getVisualRepresentation?.Invoke(b)); } protected override void AddNested(DrawableHitObject h) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index 554fb1323e..8871e26101 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -5,6 +5,7 @@ using System; using osu.Framework.Graphics; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Objects.Types; using OpenTK; using osu.Game.Rulesets.Scoring; @@ -13,6 +14,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public abstract class PalpableCatchHitObject : DrawableCatchHitObject where TObject : CatchHitObject { + public override bool CanBePlated => true; + protected PalpableCatchHitObject(TObject hitObject) : base(hitObject) { @@ -36,6 +39,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable public abstract class DrawableCatchHitObject : DrawableHitObject { + public virtual bool CanBePlated => false; + protected DrawableCatchHitObject(CatchHitObject hitObject) : base(hitObject) { @@ -47,8 +52,10 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected override void CheckForJudgements(bool userTriggered, double timeOffset) { + if (CheckPosition == null) return; + if (timeOffset > 0) - AddJudgement(new Judgement { Result = CheckPosition?.Invoke(HitObject) ?? false ? HitResult.Perfect : HitResult.Miss }); + AddJudgement(new Judgement { Result = (bool)CheckPosition?.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); } private const float preempt = 1000; @@ -61,12 +68,19 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable this.FadeIn(200); } - switch (state) + var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; + + using (BeginAbsoluteSequence(endTime, true)) { - case ArmedState.Miss: - using (BeginAbsoluteSequence(HitObject.StartTime, true)) - this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out); - break; + switch (state) + { + case ArmedState.Miss: + this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out).Expire(); + break; + case ArmedState.Hit: + this.FadeOut().Expire(); + break; + } } } } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs index e66999229c..c8b15aec61 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs @@ -1,9 +1,10 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; +using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using OpenTK; using osu.Game.Rulesets.Objects.Drawables; namespace osu.Game.Rulesets.Catch.Objects.Drawable @@ -12,7 +13,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable { private readonly Container dropletContainer; - public DrawableJuiceStream(JuiceStream s) + public DrawableJuiceStream(JuiceStream s, Func> getVisualRepresentation = null) : base(s) { RelativeSizeAxes = Axes.Both; @@ -21,21 +22,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable Child = dropletContainer = new Container { RelativeSizeAxes = Axes.Both, }; - foreach (var tick in s.NestedHitObjects) - { - switch (tick) - { - case TinyDroplet tiny: - AddNested(new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) }); - break; - case Droplet droplet: - AddNested(new DrawableDroplet(droplet)); - break; - case Fruit fruit: - AddNested(new DrawableFruit(fruit)); - break; - } - } + foreach (var o in s.NestedHitObjects.Cast()) + AddNested(getVisualRepresentation?.Invoke(o)); } protected override void AddNested(DrawableHitObject h) diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs index b1c83f5964..188af58e6a 100644 --- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs +++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs @@ -125,10 +125,8 @@ namespace osu.Game.Rulesets.Catch.Objects X = Curve.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH }); } - } - public double EndTime => StartTime + RepeatCount * Curve.Distance / Velocity; public float EndX => Curve.PositionAt(ProgressAt(1)).X / CatchPlayfield.BASE_WIDTH; diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 7fdabd46c2..8ea30a2899 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -1,6 +1,7 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE +using System; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Beatmaps; @@ -21,7 +22,7 @@ namespace osu.Game.Rulesets.Catch.UI private readonly CatcherArea catcherArea; - public CatchPlayfield(BeatmapDifficulty difficulty) + public CatchPlayfield(BeatmapDifficulty difficulty, Func> getVisualRepresentation) : base(ScrollingDirection.Down, BASE_WIDTH) { Container explodingFruitContainer; @@ -44,6 +45,7 @@ namespace osu.Game.Rulesets.Catch.UI }, catcherArea = new CatcherArea(difficulty) { + GetVisualRepresentation = getVisualRepresentation, ExplodingFruitTarget = explodingFruitContainer, Anchor = Anchor.BottomLeft, Origin = Anchor.TopLeft, diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs index ae0fe8189e..956a524121 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs @@ -13,6 +13,7 @@ using osu.Game.Rulesets.Replays; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.UI; using osu.Game.Rulesets.UI.Scrolling; +using OpenTK; namespace osu.Game.Rulesets.Catch.UI { @@ -31,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.UI protected override BeatmapConverter CreateBeatmapConverter() => new CatchBeatmapConverter(); - protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty); + protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, GetVisualRepresentation); public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo); @@ -42,9 +43,13 @@ namespace osu.Game.Rulesets.Catch.UI case Fruit fruit: return new DrawableFruit(fruit); case JuiceStream stream: - return new DrawableJuiceStream(stream); + return new DrawableJuiceStream(stream, GetVisualRepresentation); case BananaShower banana: - return new DrawableBananaShower(banana); + return new DrawableBananaShower(banana, GetVisualRepresentation); + case TinyDroplet tiny: + return new DrawableDroplet(tiny) { Scale = new Vector2(0.5f) }; + case Droplet droplet: + return new DrawableDroplet(droplet); } return null; diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 1837086d9c..6d0c3589e8 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -16,7 +16,6 @@ using osu.Game.Rulesets.Catch.Objects.Drawable; using osu.Game.Rulesets.Catch.Replays; using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; -using osu.Game.Rulesets.UI; using OpenTK; using OpenTK.Graphics; @@ -28,6 +27,8 @@ namespace osu.Game.Rulesets.Catch.UI protected readonly Catcher MovableCatcher; + public Func> GetVisualRepresentation; + public Container ExplodingFruitTarget { set { MovableCatcher.ExplodingFruitTarget = value; } @@ -45,23 +46,24 @@ namespace osu.Game.Rulesets.Catch.UI public void OnJudgement(DrawableCatchHitObject fruit, Judgement judgement) { - if (judgement.IsHit) + if (judgement.IsHit && fruit.CanBePlated) { - var screenSpacePosition = fruit.ScreenSpaceDrawQuad.Centre; + var caughtFruit = (DrawableCatchHitObject)GetVisualRepresentation?.Invoke(fruit.HitObject); - // todo: make this less ugly, somehow. - (fruit.Parent as HitObjectContainer)?.Remove(fruit); - (fruit.Parent as Container)?.Remove(fruit); + if (caughtFruit != null) + { + caughtFruit.State.Value = ArmedState.Idle; + caughtFruit.AccentColour = fruit.AccentColour; + caughtFruit.RelativePositionAxes = Axes.None; + caughtFruit.Position = new Vector2(MovableCatcher.ToLocalSpace(fruit.ScreenSpaceDrawQuad.Centre).X - MovableCatcher.DrawSize.X / 2, 0); - fruit.RelativePositionAxes = Axes.None; - fruit.Position = new Vector2(MovableCatcher.ToLocalSpace(screenSpacePosition).X - MovableCatcher.DrawSize.X / 2, 0); + caughtFruit.Anchor = Anchor.TopCentre; + caughtFruit.Origin = Anchor.Centre; + caughtFruit.Scale *= 0.7f; + caughtFruit.LifetimeEnd = double.MaxValue; + } - fruit.Anchor = Anchor.TopCentre; - fruit.Origin = Anchor.Centre; - fruit.Scale *= 0.7f; - fruit.LifetimeEnd = double.MaxValue; - - MovableCatcher.Add(fruit); + MovableCatcher.Add(caughtFruit); } if (fruit.HitObject.LastInCombo) From 20c6f84efab1fa9f851b5b31466844e9492d5c0b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 21:46:57 +0900 Subject: [PATCH 185/206] Fix banana test regression --- osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs b/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs index 6bf5b6beca..e23e7633ca 100644 --- a/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Tests/TestCaseBananaShower.cs @@ -42,7 +42,7 @@ namespace osu.Game.Rulesets.Catch.Tests } }; - beatmap.HitObjects.Add(new BananaShower { StartTime = 200, Duration = 500, NewCombo = true }); + beatmap.HitObjects.Add(new BananaShower { StartTime = 200, Duration = 5000, NewCombo = true }); return beatmap; } From f03b8206da2c2a3e7eaa045b8631c882c352785f Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 21:47:52 +0900 Subject: [PATCH 186/206] Make banana showers always last in combo (explodey) --- osu.Game.Rulesets.Catch/Objects/BananaShower.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs index cb0f4eab96..89bd73f8fb 100644 --- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs @@ -11,6 +11,8 @@ namespace osu.Game.Rulesets.Catch.Objects { public override FruitVisualRepresentation VisualRepresentation => FruitVisualRepresentation.Banana; + public override bool LastInCombo => true; + protected override void CreateNestedHitObjects() { base.CreateNestedHitObjects(); From 7b19353ed8653356a7db2b0f2de42f6a3e488c17 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 22:07:21 +0900 Subject: [PATCH 187/206] Fix weird fruit not fading out --- .../Drawable/DrawableCatchHitObject.cs | 3 -- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 44 +++++++++++-------- 2 files changed, 26 insertions(+), 21 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index 8871e26101..d3b714fc9b 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -63,10 +63,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable protected override void UpdateState(ArmedState state) { using (BeginAbsoluteSequence(HitObject.StartTime - preempt)) - { - // animation this.FadeIn(200); - } var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 6d0c3589e8..23b0ceeac1 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -44,35 +44,43 @@ namespace osu.Game.Rulesets.Catch.UI }; } + private DrawableCatchHitObject lastPlateableFruit; + public void OnJudgement(DrawableCatchHitObject fruit, Judgement judgement) { if (judgement.IsHit && fruit.CanBePlated) { var caughtFruit = (DrawableCatchHitObject)GetVisualRepresentation?.Invoke(fruit.HitObject); - if (caughtFruit != null) - { - caughtFruit.State.Value = ArmedState.Idle; - caughtFruit.AccentColour = fruit.AccentColour; - caughtFruit.RelativePositionAxes = Axes.None; - caughtFruit.Position = new Vector2(MovableCatcher.ToLocalSpace(fruit.ScreenSpaceDrawQuad.Centre).X - MovableCatcher.DrawSize.X / 2, 0); + if (caughtFruit == null) return; - caughtFruit.Anchor = Anchor.TopCentre; - caughtFruit.Origin = Anchor.Centre; - caughtFruit.Scale *= 0.7f; - caughtFruit.LifetimeEnd = double.MaxValue; - } + caughtFruit.State.Value = ArmedState.Idle; + caughtFruit.AccentColour = fruit.AccentColour; + caughtFruit.RelativePositionAxes = Axes.None; + caughtFruit.Position = new Vector2(MovableCatcher.ToLocalSpace(fruit.ScreenSpaceDrawQuad.Centre).X - MovableCatcher.DrawSize.X / 2, 0); + + caughtFruit.Anchor = Anchor.TopCentre; + caughtFruit.Origin = Anchor.Centre; + caughtFruit.Scale *= 0.7f; + caughtFruit.LifetimeEnd = double.MaxValue; MovableCatcher.Add(caughtFruit); + + lastPlateableFruit = caughtFruit; } - if (fruit.HitObject.LastInCombo) + // this is required to make this run after the last caught fruit runs UpdateState at least once. + // TODO: find a better alternative + lastPlateableFruit.OnLoadComplete = _ => { - if (judgement.IsHit) - MovableCatcher.Explode(); - else - MovableCatcher.Drop(); - } + if (fruit.HitObject.LastInCombo) + { + if (judgement.IsHit) + MovableCatcher.Explode(); + else + MovableCatcher.Drop(); + } + }; } public bool OnPressed(CatchAction action) @@ -211,7 +219,7 @@ namespace osu.Game.Rulesets.Catch.UI while (caughtFruit.Any(f => f.LifetimeEnd == double.MaxValue && - Vector2Extensions.Distance(f.Position, fruit.Position) < (ourRadius + (theirRadius = f.DrawSize.X / 2 * f.Scale.X)) / (allowance / 2))) + Vector2Extensions.Distance(f.Position, fruit.Position) < (ourRadius + (theirRadius = f.DrawSize.X / 2 * f.Scale.X)) / (allowance / 2))) { float diff = (ourRadius + theirRadius) / allowance; fruit.X += (RNG.NextSingle() - 0.5f) * 2 * diff; From 9e108548400353781971f24e8c4445e4a9539729 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 12 Jan 2018 22:30:21 +0900 Subject: [PATCH 188/206] Fix banannanananana showers not exploding enough --- .../Objects/Drawable/DrawableBananaShower.cs | 8 ++++++++ osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 16 +++++++++------- 2 files changed, 17 insertions(+), 7 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs index 72aeddee56..7b0370ef88 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs @@ -5,7 +5,9 @@ using System; using System.Linq; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Judgements; using osu.Game.Rulesets.Objects.Drawables; +using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Catch.Objects.Drawable { @@ -26,6 +28,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable AddNested(getVisualRepresentation?.Invoke(b)); } + protected override void CheckForJudgements(bool userTriggered, double timeOffset) + { + if (timeOffset >= 0) + AddJudgement(new Judgement { Result = NestedHitObjects.Cast().Any(n => n.Judgements.Any(j => j.IsHit)) ? HitResult.Perfect : HitResult.Miss }); + } + protected override void AddNested(DrawableHitObject h) { ((DrawableCatchHitObject)h).CheckPosition = o => CheckPosition?.Invoke(o) ?? false; diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 23b0ceeac1..2df43bdcd4 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -69,18 +69,20 @@ namespace osu.Game.Rulesets.Catch.UI lastPlateableFruit = caughtFruit; } - // this is required to make this run after the last caught fruit runs UpdateState at least once. - // TODO: find a better alternative - lastPlateableFruit.OnLoadComplete = _ => + if (fruit.HitObject.LastInCombo) { - if (fruit.HitObject.LastInCombo) + if (judgement.IsHit) { - if (judgement.IsHit) + // this is required to make this run after the last caught fruit runs UpdateState at least once. + // TODO: find a better alternative + if (lastPlateableFruit.IsLoaded) MovableCatcher.Explode(); else - MovableCatcher.Drop(); + lastPlateableFruit.OnLoadComplete = _ => { MovableCatcher.Explode(); }; } - }; + else + MovableCatcher.Drop(); + } } public bool OnPressed(CatchAction action) From b4b15b7dd0893b9e4ecbcece91c26a1a0d2f1c59 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 13 Jan 2018 00:51:20 +0900 Subject: [PATCH 189/206] Apply review fixes --- .../Objects/Drawable/DrawableCatchHitObject.cs | 2 +- osu.Game.Rulesets.Catch/UI/CatcherArea.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index d3b714fc9b..fce43137d1 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -55,7 +55,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable if (CheckPosition == null) return; if (timeOffset > 0) - AddJudgement(new Judgement { Result = (bool)CheckPosition?.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); + AddJudgement(new Judgement { Result = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss }); } private const float preempt = 1000; diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs index 2df43bdcd4..17c78f3aa0 100644 --- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs +++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs @@ -54,7 +54,6 @@ namespace osu.Game.Rulesets.Catch.UI if (caughtFruit == null) return; - caughtFruit.State.Value = ArmedState.Idle; caughtFruit.AccentColour = fruit.AccentColour; caughtFruit.RelativePositionAxes = Axes.None; caughtFruit.Position = new Vector2(MovableCatcher.ToLocalSpace(fruit.ScreenSpaceDrawQuad.Centre).X - MovableCatcher.DrawSize.X / 2, 0); From 1c5b3d009cedc0e2de237b9531195a5accccf0da Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Fri, 12 Jan 2018 17:09:57 +0100 Subject: [PATCH 190/206] remove volume reduction on preview it doubles with global reduction --- osu.Game/Overlays/Direct/PlayButton.cs | 3 --- 1 file changed, 3 deletions(-) diff --git a/osu.Game/Overlays/Direct/PlayButton.cs b/osu.Game/Overlays/Direct/PlayButton.cs index e939047f1a..9ecddb01ba 100644 --- a/osu.Game/Overlays/Direct/PlayButton.cs +++ b/osu.Game/Overlays/Direct/PlayButton.cs @@ -174,10 +174,7 @@ namespace osu.Game.Overlays.Direct private void load(AudioManager audio) { if (!string.IsNullOrEmpty(preview)) - { Preview = audio.Track.Get(preview); - Preview.Volume.Value = 0.5; - } } } } From ae1adfd2f247509f9f36ce0ec0b43f1dfb1eed53 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Fri, 12 Jan 2018 19:30:34 +0100 Subject: [PATCH 191/206] remove unnecessary empty lines codefactor.io \(o.o)/ also one unnecessary semicolon --- osu.Desktop/Program.cs | 1 - .../Objects/Drawable/DrawableCatchHitObject.cs | 1 - osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs | 1 - osu.Game.Rulesets.Mania/Objects/HoldNote.cs | 1 - osu.Game/Beatmaps/BeatmapManager.cs | 3 --- osu.Game/Beatmaps/DifficultyCalculator.cs | 1 - osu.Game/Beatmaps/Formats/LegacyDecoder.cs | 2 +- osu.Game/Graphics/UserInterface/OsuTabControl.cs | 1 - osu.Game/Online/API/OAuthToken.cs | 1 - osu.Game/Overlays/Chat/ChatLine.cs | 1 - osu.Game/Overlays/Direct/DirectPanel.cs | 1 - osu.Game/Overlays/MedalSplash/DrawableMedal.cs | 2 -- osu.Game/Overlays/Music/PlaylistItem.cs | 1 - osu.Game/Overlays/Music/PlaylistList.cs | 1 - osu.Game/Overlays/Notifications/NotificationSection.cs | 1 - .../Overlays/Notifications/ProgressCompletionNotification.cs | 1 - osu.Game/Overlays/Notifications/ProgressNotification.cs | 1 - osu.Game/Rulesets/Objects/Types/IHasXPosition.cs | 1 - osu.Game/Rulesets/Objects/Types/IHasYPosition.cs | 1 - osu.Game/Rulesets/Replays/ReplayFrame.cs | 1 - osu.Game/Screens/Backgrounds/BackgroundScreenEmpty.cs | 1 - osu.Game/Screens/Menu/ButtonSystem.cs | 1 - osu.Game/Screens/Multiplayer/DrawableRoom.cs | 1 - 23 files changed, 1 insertion(+), 26 deletions(-) diff --git a/osu.Desktop/Program.cs b/osu.Desktop/Program.cs index 6927568cc4..9760538197 100644 --- a/osu.Desktop/Program.cs +++ b/osu.Desktop/Program.cs @@ -43,7 +43,6 @@ namespace osu.Desktop host.Run(new OsuGameDesktop(args)); break; } - } return 0; } diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs index fce43137d1..05ef947e4b 100644 --- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs +++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs @@ -23,7 +23,6 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable } } - public abstract class DrawableCatchHitObject : DrawableCatchHitObject where TObject : CatchHitObject { diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs index 8b0b59593c..557ce5eb1b 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs @@ -58,7 +58,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps protected override Beatmap ConvertBeatmap(Beatmap original) { - BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty; int seed = (int)Math.Round(difficulty.DrainRate + difficulty.CircleSize) * 20 + (int)(difficulty.OverallDifficulty * 41.2) + (int)Math.Round(difficulty.ApproachRate); diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs index 881ce9199d..728c79b9cf 100644 --- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs @@ -93,7 +93,6 @@ namespace osu.Game.Rulesets.Mania.Objects Column = Column }); } - } /// diff --git a/osu.Game/Beatmaps/BeatmapManager.cs b/osu.Game/Beatmaps/BeatmapManager.cs index d342e495e2..634b5bcd20 100644 --- a/osu.Game/Beatmaps/BeatmapManager.cs +++ b/osu.Game/Beatmaps/BeatmapManager.cs @@ -566,7 +566,6 @@ namespace osu.Game.Beatmaps using (var stream = new StreamReader(reader.GetStream(mapName))) metadata = Decoder.GetDecoder(stream).DecodeBeatmap(stream).Metadata; - // check if a set already exists with the same online id. if (metadata.OnlineBeatmapSetID != null) beatmapSet = beatmaps.BeatmapSets.FirstOrDefault(b => b.OnlineBeatmapSetID == metadata.OnlineBeatmapSetID); @@ -581,7 +580,6 @@ namespace osu.Game.Beatmaps Metadata = metadata }; - var mapNames = reader.Filenames.Where(f => f.EndsWith(".osu")); foreach (var name in mapNames) @@ -693,7 +691,6 @@ namespace osu.Game.Beatmaps { try { - using (var beatmap = new StreamReader(store.GetStream(getPathForFile(BeatmapInfo.Path)))) { Decoder decoder = Decoder.GetDecoder(beatmap); diff --git a/osu.Game/Beatmaps/DifficultyCalculator.cs b/osu.Game/Beatmaps/DifficultyCalculator.cs index 55aa876a1b..798268d05f 100644 --- a/osu.Game/Beatmaps/DifficultyCalculator.cs +++ b/osu.Game/Beatmaps/DifficultyCalculator.cs @@ -27,7 +27,6 @@ namespace osu.Game.Beatmaps Beatmap = CreateBeatmapConverter(beatmap).Convert(beatmap); Mods = mods ?? new Mod[0]; - ApplyMods(Mods); PreprocessHitObjects(); diff --git a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs index c4c91e3e09..e0fc439924 100644 --- a/osu.Game/Beatmaps/Formats/LegacyDecoder.cs +++ b/osu.Game/Beatmaps/Formats/LegacyDecoder.cs @@ -137,7 +137,7 @@ namespace osu.Game.Beatmaps.Formats CentreRight, BottomLeft, BottomRight - }; + } internal enum StoryLayer { diff --git a/osu.Game/Graphics/UserInterface/OsuTabControl.cs b/osu.Game/Graphics/UserInterface/OsuTabControl.cs index 032420b61e..7ad9bc73a8 100644 --- a/osu.Game/Graphics/UserInterface/OsuTabControl.cs +++ b/osu.Game/Graphics/UserInterface/OsuTabControl.cs @@ -180,7 +180,6 @@ namespace osu.Game.Graphics.UserInterface } } - protected class OsuTabDropdownHeader : OsuDropdownHeader { public override Color4 AccentColour diff --git a/osu.Game/Online/API/OAuthToken.cs b/osu.Game/Online/API/OAuthToken.cs index 7d644a2628..d2b9703a93 100644 --- a/osu.Game/Online/API/OAuthToken.cs +++ b/osu.Game/Online/API/OAuthToken.cs @@ -56,7 +56,6 @@ namespace osu.Game.Online.API } catch { - } return null; } diff --git a/osu.Game/Overlays/Chat/ChatLine.cs b/osu.Game/Overlays/Chat/ChatLine.cs index 19dede56a0..4895c3a37c 100644 --- a/osu.Game/Overlays/Chat/ChatLine.cs +++ b/osu.Game/Overlays/Chat/ChatLine.cs @@ -219,7 +219,6 @@ namespace osu.Game.Overlays.Chat } else contentFlow.Text = message.Content; - } private class MessageSender : OsuClickableContainer, IHasContextMenu diff --git a/osu.Game/Overlays/Direct/DirectPanel.cs b/osu.Game/Overlays/Direct/DirectPanel.cs index ede9f2c412..7dd6be8dc6 100644 --- a/osu.Game/Overlays/Direct/DirectPanel.cs +++ b/osu.Game/Overlays/Direct/DirectPanel.cs @@ -65,7 +65,6 @@ namespace osu.Game.Overlays.Direct Colour = Color4.Black.Opacity(0.3f), }; - [BackgroundDependencyLoader(permitNulls: true)] private void load(BeatmapManager beatmaps, OsuColour colours, BeatmapSetOverlay beatmapSetOverlay) { diff --git a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs index e1a780406b..8edfdf9d95 100644 --- a/osu.Game/Overlays/MedalSplash/DrawableMedal.cs +++ b/osu.Game/Overlays/MedalSplash/DrawableMedal.cs @@ -183,8 +183,6 @@ namespace osu.Game.Overlays.MedalSplash description.FadeInFromZero(duration * 2); break; } - - } } diff --git a/osu.Game/Overlays/Music/PlaylistItem.cs b/osu.Game/Overlays/Music/PlaylistItem.cs index 9eab8f797d..34dcc36699 100644 --- a/osu.Game/Overlays/Music/PlaylistItem.cs +++ b/osu.Game/Overlays/Music/PlaylistItem.cs @@ -148,7 +148,6 @@ namespace osu.Game.Overlays.Music private class PlaylistItemHandle : SpriteIcon { - public PlaylistItemHandle() { Anchor = Anchor.TopLeft; diff --git a/osu.Game/Overlays/Music/PlaylistList.cs b/osu.Game/Overlays/Music/PlaylistList.cs index 17687a9623..31b7d0f9aa 100644 --- a/osu.Game/Overlays/Music/PlaylistList.cs +++ b/osu.Game/Overlays/Music/PlaylistList.cs @@ -230,7 +230,6 @@ namespace osu.Game.Overlays.Music items.ChangeChildDepth(draggedItem, dstIndex); } - private class ItemSearchContainer : FillFlowContainer, IHasFilterableChildren { public IEnumerable FilterTerms => new string[] { }; diff --git a/osu.Game/Overlays/Notifications/NotificationSection.cs b/osu.Game/Overlays/Notifications/NotificationSection.cs index d51cdb8bcc..13a69fbe3a 100644 --- a/osu.Game/Overlays/Notifications/NotificationSection.cs +++ b/osu.Game/Overlays/Notifications/NotificationSection.cs @@ -168,5 +168,4 @@ namespace osu.Game.Overlays.Notifications // the layout portion of this is being tracked as a framework issue (https://github.com/ppy/osu-framework/issues/1297). protected override bool RequiresChildrenUpdate => true; } - } diff --git a/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs b/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs index 4cd48edcf3..df2be95b40 100644 --- a/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressCompletionNotification.cs @@ -5,7 +5,6 @@ using osu.Framework.Allocation; using osu.Game.Graphics; using osu.Framework.Graphics.Colour; - namespace osu.Game.Overlays.Notifications { public class ProgressCompletionNotification : SimpleNotification diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 4106a40867..b36ac6eebc 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -217,7 +217,6 @@ namespace osu.Game.Overlays.Notifications }; } - [BackgroundDependencyLoader] private void load(OsuColour colours) { diff --git a/osu.Game/Rulesets/Objects/Types/IHasXPosition.cs b/osu.Game/Rulesets/Objects/Types/IHasXPosition.cs index 2dec9e6ef1..f73f338778 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasXPosition.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasXPosition.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - namespace osu.Game.Rulesets.Objects.Types { /// diff --git a/osu.Game/Rulesets/Objects/Types/IHasYPosition.cs b/osu.Game/Rulesets/Objects/Types/IHasYPosition.cs index 8a38bde0f9..fc2d21481f 100644 --- a/osu.Game/Rulesets/Objects/Types/IHasYPosition.cs +++ b/osu.Game/Rulesets/Objects/Types/IHasYPosition.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE - namespace osu.Game.Rulesets.Objects.Types { /// diff --git a/osu.Game/Rulesets/Replays/ReplayFrame.cs b/osu.Game/Rulesets/Replays/ReplayFrame.cs index 92defad62e..4f8ed5163e 100644 --- a/osu.Game/Rulesets/Replays/ReplayFrame.cs +++ b/osu.Game/Rulesets/Replays/ReplayFrame.cs @@ -52,7 +52,6 @@ namespace osu.Game.Rulesets.Replays protected ReplayFrame() { - } public ReplayFrame(double time, float? mouseX, float? mouseY, ReplayButtonState buttonState) diff --git a/osu.Game/Screens/Backgrounds/BackgroundScreenEmpty.cs b/osu.Game/Screens/Backgrounds/BackgroundScreenEmpty.cs index c64ae23d46..758032a711 100644 --- a/osu.Game/Screens/Backgrounds/BackgroundScreenEmpty.cs +++ b/osu.Game/Screens/Backgrounds/BackgroundScreenEmpty.cs @@ -5,6 +5,5 @@ namespace osu.Game.Screens.Backgrounds { public class BackgroundScreenEmpty : BackgroundScreen { - } } diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs index 72fe4368f0..529565312e 100644 --- a/osu.Game/Screens/Menu/ButtonSystem.cs +++ b/osu.Game/Screens/Menu/ButtonSystem.cs @@ -157,7 +157,6 @@ namespace osu.Game.Screens.Menu return true; } - return false; } diff --git a/osu.Game/Screens/Multiplayer/DrawableRoom.cs b/osu.Game/Screens/Multiplayer/DrawableRoom.cs index 7fcd364fe0..cc2828fb91 100644 --- a/osu.Game/Screens/Multiplayer/DrawableRoom.cs +++ b/osu.Game/Screens/Multiplayer/DrawableRoom.cs @@ -229,7 +229,6 @@ namespace osu.Game.Screens.Multiplayer { coverContainer.FadeIn(transition_duration); - LoadComponentAsync(new BeatmapSetCover(value.BeatmapSet) { Anchor = Anchor.Centre, From 70fc09f81e697925955da38755691e4d6f1686f5 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 13 Jan 2018 12:42:42 +0100 Subject: [PATCH 192/206] move judgement + state logic up to DrawableHitObject --- .../Objects/Drawables/DrawableHitObject.cs | 298 +++++++++--------- 1 file changed, 142 insertions(+), 156 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 13329a1470..a29ea4cbbb 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -29,37 +29,167 @@ namespace osu.Game.Rulesets.Objects.Drawables /// public virtual Color4 AccentColour { get; set; } = Color4.Gray; + private List nestedHitObjects; + public IReadOnlyList NestedHitObjects => nestedHitObjects; + + public event Action OnJudgement; + public event Action OnJudgementRemoved; + + public IReadOnlyList Judgements => judgements; + private readonly List judgements = new List(); + /// /// Whether a visible judgement should be displayed when this representation is hit. /// public virtual bool DisplayJudgement => true; - public override bool RemoveCompletedTransforms => false; + /// + /// Whether this and all of its nested s have been judged. + /// + public bool AllJudged => (!ProvidesJudgement || judgementFinalized) && (NestedHitObjects?.All(h => h.AllJudged) ?? true); + + /// + /// Whether this can be judged. + /// + protected virtual bool ProvidesJudgement => true; + + private bool judgementOccurred; + private bool judgementFinalized => judgements.LastOrDefault()?.Final == true; + + public bool Interactive = true; + public override bool HandleInput => Interactive; + public override bool RemoveWhenNotAlive => false; + public override bool RemoveCompletedTransforms => false; protected override bool RequiresChildrenUpdate => true; - public virtual bool AllJudged => false; + public readonly Bindable State = new Bindable(); protected DrawableHitObject(HitObject hitObject) { HitObject = hitObject; } + protected override void LoadComplete() + { + base.LoadComplete(); + + State.ValueChanged += state => + { + UpdateState(state); + + // apply any custom state overrides + ApplyCustomUpdateState?.Invoke(this, state); + }; + + State.TriggerChange(); + } + + protected abstract void UpdateState(ArmedState state); + + /// + /// Bind to apply a custom state which can override the default implementation. + /// + public event Action ApplyCustomUpdateState; + + protected override void Update() + { + base.Update(); + + var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; + + while (judgements.Count > 0) + { + var lastJudgement = judgements[judgements.Count - 1]; + if (lastJudgement.TimeOffset + endTime <= Time.Current) + break; + + judgements.RemoveAt(judgements.Count - 1); + State.Value = ArmedState.Idle; + + OnJudgementRemoved?.Invoke(this, lastJudgement); + } + } + + protected override void UpdateAfterChildren() + { + base.UpdateAfterChildren(); + + UpdateJudgement(false); + } + + protected virtual void AddNested(DrawableHitObject h) + { + if (nestedHitObjects == null) + nestedHitObjects = new List(); + nestedHitObjects.Add(h); + } + + /// + /// Notifies that a new judgement has occurred for this . + /// + /// The . + protected void AddJudgement(Judgement judgement) + { + judgementOccurred = true; + + // Ensure that the judgement is given a valid time offset, because this may not get set by the caller + var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; + judgement.TimeOffset = Time.Current - endTime; + + judgements.Add(judgement); + + switch (judgement.Result) + { + case HitResult.None: + break; + case HitResult.Miss: + State.Value = ArmedState.Miss; + break; + default: + State.Value = ArmedState.Hit; + break; + } + + OnJudgement?.Invoke(this, judgement); + } + /// /// Processes this , checking if any judgements have occurred. /// /// Whether the user triggered this process. /// Whether a judgement has occurred from this or any nested s. - protected internal virtual bool UpdateJudgement(bool userTriggered) => false; - - private List nestedHitObjects; - public IReadOnlyList NestedHitObjects => nestedHitObjects; - - protected virtual void AddNested(DrawableHitObject h) + protected internal bool UpdateJudgement(bool userTriggered) + { + judgementOccurred = false; + + if (AllJudged) + return false; + + if (NestedHitObjects != null) + { + foreach (var d in NestedHitObjects) + judgementOccurred |= d.UpdateJudgement(userTriggered); + } + + if (!ProvidesJudgement || judgementFinalized || judgementOccurred) + return judgementOccurred; + + var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; + CheckForJudgements(userTriggered, Time.Current - endTime); + + return judgementOccurred; + } + + /// + /// Checks if any judgements have occurred for this . This method must construct + /// all s and notify of them through . + /// + /// Whether the user triggered this check. + /// The offset from the end time at which this check occurred. A > 0 + /// implies that this check occurred after the end time of . + protected virtual void CheckForJudgements(bool userTriggered, double timeOffset) { - if (nestedHitObjects == null) - nestedHitObjects = new List(); - nestedHitObjects.Add(h); } /// @@ -76,30 +206,14 @@ namespace osu.Game.Rulesets.Objects.Drawables public abstract class DrawableHitObject : DrawableHitObject where TObject : HitObject { - public event Action OnJudgement; - public event Action OnJudgementRemoved; - public new readonly TObject HitObject; - public override bool HandleInput => Interactive; - public bool Interactive = true; - - /// - /// Whether this can be judged. - /// - protected virtual bool ProvidesJudgement => true; - - private readonly List judgements = new List(); - public IReadOnlyList Judgements => judgements; - protected List Samples = new List(); protected virtual IEnumerable GetSamples() => HitObject.Samples; // Todo: Rulesets should be overriding the resources instead, but we need to figure out where/when to apply overrides first protected virtual string SampleNamespace => null; - public readonly Bindable State = new Bindable(); - protected DrawableHitObject(TObject hitObject) : base(hitObject) { @@ -141,139 +255,11 @@ namespace osu.Game.Rulesets.Objects.Drawables State.ValueChanged += state => { - UpdateState(state); - - // apply any custom state overrides - ApplyCustomUpdateState?.Invoke(this, state); - if (State == ArmedState.Hit) PlaySamples(); }; - - State.TriggerChange(); } - protected void PlaySamples() - { - Samples.ForEach(s => s?.Play()); - } - - private bool judgementOccurred; - private bool judgementFinalized => judgements.LastOrDefault()?.Final == true; - - /// - /// Whether this and all of its nested s have been judged. - /// - public sealed override bool AllJudged => (!ProvidesJudgement || judgementFinalized) && (NestedHitObjects?.All(h => h.AllJudged) ?? true); - - /// - /// Notifies that a new judgement has occurred for this . - /// - /// The . - protected void AddJudgement(Judgement judgement) - { - judgementOccurred = true; - - // Ensure that the judgement is given a valid time offset, because this may not get set by the caller - var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; - judgement.TimeOffset = Time.Current - endTime; - - judgements.Add(judgement); - - switch (judgement.Result) - { - case HitResult.None: - break; - case HitResult.Miss: - State.Value = ArmedState.Miss; - break; - default: - State.Value = ArmedState.Hit; - break; - } - - OnJudgement?.Invoke(this, judgement); - } - - /// - /// Processes this , checking if any judgements have occurred. - /// - /// Whether the user triggered this process. - /// Whether a judgement has occurred from this or any nested s. - protected internal sealed override bool UpdateJudgement(bool userTriggered) - { - judgementOccurred = false; - - if (AllJudged) - return false; - - if (NestedHitObjects != null) - { - foreach (var d in NestedHitObjects) - judgementOccurred |= d.UpdateJudgement(userTriggered); - } - - if (!ProvidesJudgement || judgementFinalized || judgementOccurred) - return judgementOccurred; - - var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; - CheckForJudgements(userTriggered, Time.Current - endTime); - - return judgementOccurred; - } - - /// - /// Checks if any judgements have occurred for this . This method must construct - /// all s and notify of them through . - /// - /// Whether the user triggered this check. - /// The offset from the end time at which this check occurred. A > 0 - /// implies that this check occurred after the end time of . - protected virtual void CheckForJudgements(bool userTriggered, double timeOffset) { } - - protected override void Update() - { - base.Update(); - - var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime; - - while (judgements.Count > 0) - { - var lastJudgement = judgements[judgements.Count - 1]; - if (lastJudgement.TimeOffset + endTime <= Time.Current) - break; - - judgements.RemoveAt(judgements.Count - 1); - State.Value = ArmedState.Idle; - - OnJudgementRemoved?.Invoke(this, lastJudgement); - } - } - - protected override void UpdateAfterChildren() - { - base.UpdateAfterChildren(); - - UpdateJudgement(false); - } - - protected override void AddNested(DrawableHitObject h) - { - base.AddNested(h); - - if (!(h is DrawableHitObject hWithJudgement)) - return; - - hWithJudgement.OnJudgement += (d, j) => OnJudgement?.Invoke(d, j); - hWithJudgement.OnJudgementRemoved += (d, j) => OnJudgementRemoved?.Invoke(d, j); - hWithJudgement.ApplyCustomUpdateState += (d, s) => ApplyCustomUpdateState?.Invoke(d, s); - } - - /// - /// Bind to apply a custom state which can override the default implementation. - /// - public event Action ApplyCustomUpdateState; - - protected abstract void UpdateState(ArmedState state); + protected void PlaySamples() => Samples.ForEach(s => s?.Play()); } } From 356bb5da1e5e63243174c84cfcdb7b2dbefc5839 Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 13 Jan 2018 12:55:52 +0100 Subject: [PATCH 193/206] move sample logic up too --- .../Objects/Drawables/DrawableHitObject.cs | 88 +++++++++---------- 1 file changed, 40 insertions(+), 48 deletions(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index a29ea4cbbb..68766789e0 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -29,6 +29,12 @@ namespace osu.Game.Rulesets.Objects.Drawables /// public virtual Color4 AccentColour { get; set; } = Color4.Gray; + // Todo: Rulesets should be overriding the resources instead, but we need to figure out where/when to apply overrides first + protected virtual string SampleNamespace => null; + + protected List Samples = new List(); + protected virtual IEnumerable GetSamples() => HitObject.Samples; + private List nestedHitObjects; public IReadOnlyList NestedHitObjects => nestedHitObjects; @@ -70,6 +76,35 @@ namespace osu.Game.Rulesets.Objects.Drawables HitObject = hitObject; } + [BackgroundDependencyLoader] + private void load(AudioManager audio) + { + var samples = GetSamples(); + if (samples.Any()) + { + if (HitObject.SampleControlPoint == null) + throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." + + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); + + foreach (SampleInfo s in samples) + { + SampleInfo localSampleInfo = new SampleInfo + { + Bank = s.Bank ?? HitObject.SampleControlPoint.SampleBank, + Name = s.Name, + Volume = s.Volume > 0 ? s.Volume : HitObject.SampleControlPoint.SampleVolume + }; + + SampleChannel channel = localSampleInfo.GetChannel(audio.Sample, SampleNamespace); + + if (channel == null) + continue; + + Samples.Add(channel); + } + } + } + protected override void LoadComplete() { base.LoadComplete(); @@ -80,6 +115,9 @@ namespace osu.Game.Rulesets.Objects.Drawables // apply any custom state overrides ApplyCustomUpdateState?.Invoke(this, state); + + if (State == ArmedState.Hit) + PlaySamples(); }; State.TriggerChange(); @@ -92,6 +130,8 @@ namespace osu.Game.Rulesets.Objects.Drawables /// public event Action ApplyCustomUpdateState; + protected void PlaySamples() => Samples.ForEach(s => s?.Play()); + protected override void Update() { base.Update(); @@ -208,58 +248,10 @@ namespace osu.Game.Rulesets.Objects.Drawables { public new readonly TObject HitObject; - protected List Samples = new List(); - protected virtual IEnumerable GetSamples() => HitObject.Samples; - - // Todo: Rulesets should be overriding the resources instead, but we need to figure out where/when to apply overrides first - protected virtual string SampleNamespace => null; - protected DrawableHitObject(TObject hitObject) : base(hitObject) { HitObject = hitObject; } - - [BackgroundDependencyLoader] - private void load(AudioManager audio) - { - var samples = GetSamples(); - if (samples.Any()) - { - if (HitObject.SampleControlPoint == null) - throw new ArgumentNullException(nameof(HitObject.SampleControlPoint), $"{nameof(HitObject)}s must always have an attached {nameof(HitObject.SampleControlPoint)}." - + $" This is an indication that {nameof(HitObject.ApplyDefaults)} has not been invoked on {this}."); - - foreach (SampleInfo s in samples) - { - SampleInfo localSampleInfo = new SampleInfo - { - Bank = s.Bank ?? HitObject.SampleControlPoint.SampleBank, - Name = s.Name, - Volume = s.Volume > 0 ? s.Volume : HitObject.SampleControlPoint.SampleVolume - }; - - SampleChannel channel = localSampleInfo.GetChannel(audio.Sample, SampleNamespace); - - if (channel == null) - continue; - - Samples.Add(channel); - } - } - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - State.ValueChanged += state => - { - if (State == ArmedState.Hit) - PlaySamples(); - }; - } - - protected void PlaySamples() => Samples.ForEach(s => s?.Play()); } } From 7875f0cb01d44738480b071fd0e7625b41bfe51a Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 13 Jan 2018 16:15:41 +0100 Subject: [PATCH 194/206] remove unnecessary internal --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index 68766789e0..e43ef1cc60 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -199,7 +199,7 @@ namespace osu.Game.Rulesets.Objects.Drawables /// /// Whether the user triggered this process. /// Whether a judgement has occurred from this or any nested s. - protected internal bool UpdateJudgement(bool userTriggered) + protected bool UpdateJudgement(bool userTriggered) { judgementOccurred = false; From 8ac6818639c93751a3b7212d05a987ead1bc4adc Mon Sep 17 00:00:00 2001 From: Aergwyn Date: Sat, 13 Jan 2018 13:05:23 +0100 Subject: [PATCH 195/206] expose IsHit --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index e43ef1cc60..af14c43a3f 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -49,6 +49,11 @@ namespace osu.Game.Rulesets.Objects.Drawables /// public virtual bool DisplayJudgement => true; + /// + /// 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); + /// /// Whether this and all of its nested s have been judged. /// From 43f8a8e8c57adc0266412687d65c6d8cb3037505 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 15 Jan 2018 14:00:13 +0900 Subject: [PATCH 196/206] Rename OsuCursorVisualiser -> CursorOverrideContainer --- ...uCursorVisualiser.cs => CursorOverrideContainer.cs} | 6 +++--- osu.Game/OsuGame.cs | 2 +- osu.Game/OsuGameBase.cs | 10 +++++----- osu.Game/osu.Game.csproj | 2 +- 4 files changed, 10 insertions(+), 10 deletions(-) rename osu.Game/Graphics/Cursor/{OsuCursorVisualiser.cs => CursorOverrideContainer.cs} (85%) diff --git a/osu.Game/Graphics/Cursor/OsuCursorVisualiser.cs b/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs similarity index 85% rename from osu.Game/Graphics/Cursor/OsuCursorVisualiser.cs rename to osu.Game/Graphics/Cursor/CursorOverrideContainer.cs index 2b2ab593aa..5035020492 100644 --- a/osu.Game/Graphics/Cursor/OsuCursorVisualiser.cs +++ b/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs @@ -10,9 +10,9 @@ using osu.Framework.Input; namespace osu.Game.Graphics.Cursor { /// - /// Visualises different cursors depending on the currently-hovered s. + /// A container which provides a which can be overridden by hovered s. /// - public class OsuCursorVisualiser : Container, IProvideCursor + public class CursorOverrideContainer : Container, IProvideCursor { protected override Container Content => content; private readonly Container content; @@ -25,7 +25,7 @@ namespace osu.Game.Graphics.Cursor public CursorContainer Cursor { get; } public bool ProvidesUserCursor => true; - public OsuCursorVisualiser() + public CursorOverrideContainer() { AddRangeInternal(new Drawable[] { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 3dda26fc02..124b9364b3 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -445,7 +445,7 @@ namespace osu.Game mainContent.Padding = new MarginPadding { Top = ToolbarOffset }; - CursorVisualiser.CanShowCursor = currentScreen?.CursorVisible ?? false; + CursorOverrideContainer.CanShowCursor = currentScreen?.CursorVisible ?? false; } private void screenAdded(Screen newScreen) diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs index 61ad4024f0..ef02f1a7ec 100644 --- a/osu.Game/OsuGameBase.cs +++ b/osu.Game/OsuGameBase.cs @@ -44,7 +44,7 @@ namespace osu.Game protected KeyBindingStore KeyBindingStore; - protected OsuCursorVisualiser CursorVisualiser; + protected CursorOverrideContainer CursorOverrideContainer; protected override string MainResourceFile => @"osu.Game.Resources.dll"; @@ -211,14 +211,14 @@ namespace osu.Game GlobalKeyBindingInputManager globalBinding; - CursorVisualiser = new OsuCursorVisualiser { RelativeSizeAxes = Axes.Both }; - CursorVisualiser.Child = globalBinding = new GlobalKeyBindingInputManager(this) + CursorOverrideContainer = new CursorOverrideContainer { RelativeSizeAxes = Axes.Both }; + CursorOverrideContainer.Child = globalBinding = new GlobalKeyBindingInputManager(this) { RelativeSizeAxes = Axes.Both, - Child = content = new OsuTooltipContainer(CursorVisualiser.Cursor) { RelativeSizeAxes = Axes.Both } + Child = content = new OsuTooltipContainer(CursorOverrideContainer.Cursor) { RelativeSizeAxes = Axes.Both } }; - base.Content.Add(new DrawSizePreservingFillContainer { Child = CursorVisualiser }); + base.Content.Add(new DrawSizePreservingFillContainer { Child = CursorOverrideContainer }); KeyBindingStore.Register(globalBinding); dependencies.Cache(globalBinding); diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fd53a211e0..7b97d46531 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -377,7 +377,7 @@ - + From 7c419251440240847ae22afbbcd5a91c0de532ff Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 15 Jan 2018 14:07:09 +0900 Subject: [PATCH 197/206] ProvidesUserCursor -> ProvidingUserCursor, and update xmldoc --- osu.Game/Graphics/Cursor/CursorOverrideContainer.cs | 4 ++-- osu.Game/Graphics/Cursor/IProvideCursor.cs | 7 ++++--- osu.Game/Screens/Play/Player.cs | 2 +- 3 files changed, 7 insertions(+), 6 deletions(-) diff --git a/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs b/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs index 5035020492..4b29414990 100644 --- a/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs +++ b/osu.Game/Graphics/Cursor/CursorOverrideContainer.cs @@ -23,7 +23,7 @@ namespace osu.Game.Graphics.Cursor public bool CanShowCursor; public CursorContainer Cursor { get; } - public bool ProvidesUserCursor => true; + public bool ProvidingUserCursor => true; public CursorOverrideContainer() { @@ -53,7 +53,7 @@ namespace osu.Game.Graphics.Cursor return; } - var newTarget = inputManager.HoveredDrawables.OfType().FirstOrDefault(t => t.ProvidesUserCursor) ?? this; + var newTarget = inputManager.HoveredDrawables.OfType().FirstOrDefault(t => t.ProvidingUserCursor) ?? this; if (currentTarget == newTarget) return; diff --git a/osu.Game/Graphics/Cursor/IProvideCursor.cs b/osu.Game/Graphics/Cursor/IProvideCursor.cs index b36155a881..91b44234fb 100644 --- a/osu.Game/Graphics/Cursor/IProvideCursor.cs +++ b/osu.Game/Graphics/Cursor/IProvideCursor.cs @@ -12,14 +12,15 @@ namespace osu.Game.Graphics.Cursor public interface IProvideCursor : IDrawable { /// - /// The cursor provided by this . + /// The cursor provided by this . /// May be null if no cursor should be visible. /// CursorContainer Cursor { get; } /// - /// Whether the cursor provided by this should be displayed as the user's cursor. + /// Whether should be displayed as the singular user cursor. This will temporarily hide any other user cursor. + /// This value is checked every frame and may be used to control whether multiple cursors are displayed (e.g. watching replays). /// - bool ProvidesUserCursor { get; } + bool ProvidingUserCursor { get; } } } diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index a93c616c6a..2ee58980f1 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -52,7 +52,7 @@ namespace osu.Game.Screens.Play public int RestartCount; public CursorContainer Cursor => RulesetContainer.Cursor; - public bool ProvidesUserCursor => RulesetContainer?.Cursor != null && !RulesetContainer.HasReplayLoaded; + public bool ProvidingUserCursor => RulesetContainer?.Cursor != null && !RulesetContainer.HasReplayLoaded; private IAdjustableClock adjustableSourceClock; private FramedOffsetClock offsetClock; From bfdfb52666015517059421009fdcdb7175d36316 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 15 Jan 2018 15:28:08 +0900 Subject: [PATCH 198/206] Fix a few usages of AllJudged possibly not being correct --- osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs | 2 +- osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index 58f024870d..57a4888b2b 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -150,7 +150,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables holdStartTime = null; // If the key has been released too early, the user should not receive full score for the release - if (!tail.AllJudged) + if (!tail.IsHit) hasBroken = true; return true; diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs index 2fa6c8ed95..29d464f614 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.AllJudged); + int countHit = NestedHitObjects.Count(o => o.IsHit); if (countHit > HitObject.RequiredGoodHits) { From 053a29f9a751abe93eb421c23f39fee9e47679a5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sun, 31 Dec 2017 21:05:01 +0900 Subject: [PATCH 199/206] Make judgements visually smaller This is a temporary change based on people's feedback. Makes judgements feel a lot better. nb: This is one of my changes that I've had deployed sinfce the end-of-year 2017 build. --- osu.Game/Rulesets/Judgements/DrawableJudgement.cs | 3 ++- 1 file changed, 2 insertions(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs index 0f6642ae0e..c1bf55b214 100644 --- a/osu.Game/Rulesets/Judgements/DrawableJudgement.cs +++ b/osu.Game/Rulesets/Judgements/DrawableJudgement.cs @@ -40,7 +40,8 @@ namespace osu.Game.Rulesets.Judgements Anchor = Anchor.Centre, Text = judgement.Result.GetDescription().ToUpper(), Font = @"Venera", - TextSize = 16 + Scale = new Vector2(0.85f, 1), + TextSize = 12 } }; } From 0ae0dac192f3905c1d33ac0c056b94e6ad01030e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 15 Jan 2018 20:35:38 +0900 Subject: [PATCH 200/206] Fix DrawableHitObject not binding nested hitobject events --- osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs index af14c43a3f..2db899c646 100644 --- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs +++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs @@ -167,6 +167,11 @@ namespace osu.Game.Rulesets.Objects.Drawables { 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); } From c32ff9c43b7ac6d477c456fa916f4be58e837ea4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 15 Jan 2018 20:22:41 +0900 Subject: [PATCH 201/206] Move nested playfields to the base Playfield --- osu.Game/Rulesets/UI/Playfield.cs | 23 ++++++++++++++++++- .../UI/Scrolling/ScrollingPlayfield.cs | 20 ---------------- .../UI/Scrolling/ScrollingRulesetContainer.cs | 2 +- 3 files changed, 23 insertions(+), 22 deletions(-) diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index 9b80bba891..e011908c04 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -2,6 +2,7 @@ // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE using System; +using System.Collections.Generic; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; @@ -23,6 +24,13 @@ namespace osu.Game.Rulesets.UI protected override Container Content => content; private readonly Container content; + private List nestedPlayfields; + + /// + /// All the s nested inside this playfield. + /// + public IReadOnlyList NestedPlayfields => nestedPlayfields; + /// /// A container for keeping track of DrawableHitObjects. /// @@ -64,7 +72,7 @@ namespace osu.Game.Rulesets.UI /// /// Performs post-processing tasks (if any) after all DrawableHitObjects are loaded into this Playfield. /// - public virtual void PostProcess() { } + public virtual void PostProcess() => nestedPlayfields?.ForEach(p => p.PostProcess()); /// /// Adds a DrawableHitObject to this Playfield. @@ -85,6 +93,19 @@ namespace osu.Game.Rulesets.UI /// The that occurred. public virtual void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { } + /// + /// Registers a as a nested . + /// This does not add the to the draw hierarchy. + /// + /// The to add. + protected void AddNested(Playfield otherPlayfield) + { + if (nestedPlayfields == null) + nestedPlayfields = new List(); + + nestedPlayfields.Add(otherPlayfield); + } + /// /// Creates the container that will be used to contain the s. /// diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs index 11185015b8..287e917c7b 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingPlayfield.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Configuration; using osu.Framework.Graphics; @@ -76,25 +75,6 @@ namespace osu.Game.Rulesets.UI.Scrolling HitObjects.TimeRange.BindTo(VisibleTimeRange); } - private List nestedPlayfields; - /// - /// All the s nested inside this playfield. - /// - public IEnumerable NestedPlayfields => nestedPlayfields; - - /// - /// Adds a to this playfield. The nested - /// will be given all of the same speed adjustments as this playfield. - /// - /// The to add. - protected void AddNested(ScrollingPlayfield otherPlayfield) - { - if (nestedPlayfields == null) - nestedPlayfields = new List(); - - nestedPlayfields.Add(otherPlayfield); - } - protected override bool OnKeyDown(InputState state, KeyDownEventArgs args) { if (!UserScrollSpeedAdjustment) diff --git a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs index 286545270f..5f6b6801ce 100644 --- a/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs +++ b/osu.Game/Rulesets/UI/Scrolling/ScrollingRulesetContainer.cs @@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.UI.Scrolling private void applySpeedAdjustment(MultiplierControlPoint controlPoint, ScrollingPlayfield playfield) { playfield.HitObjects.AddControlPoint(controlPoint); - playfield.NestedPlayfields.ForEach(p => applySpeedAdjustment(controlPoint, p)); + playfield.NestedPlayfields?.OfType().ForEach(p => applySpeedAdjustment(controlPoint, p)); } /// From 8c5ef0a33076ea2a1948a5a02154d2a1b93759a8 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Mon, 15 Jan 2018 20:45:30 +0900 Subject: [PATCH 202/206] Remove base OnJudgement from Playfield to properly accomodate nested playfields --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 3 ++- osu.Game.Rulesets.Mania/UI/Column.cs | 5 +++-- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 11 ++++++----- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 4 +++- .../Tests/TestCaseTaikoPlayfield.cs | 8 ++++---- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 4 +++- osu.Game/Rulesets/UI/Playfield.cs | 8 -------- osu.Game/Rulesets/UI/RulesetContainer.cs | 7 +------ 8 files changed, 22 insertions(+), 28 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index 8ea30a2899..a2324671b2 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -58,6 +58,7 @@ namespace osu.Game.Rulesets.Catch.UI public override void Add(DrawableHitObject h) { h.Depth = (float)h.HitObject.StartTime; + h.OnJudgement += OnJudgement; base.Add(h); @@ -65,6 +66,6 @@ namespace osu.Game.Rulesets.Catch.UI fruit.CheckPosition = CheckIfWeCanCatch; } - public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) => catcherArea.OnJudgement((DrawableCatchHitObject)judgedObject, judgement); + public void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) => catcherArea.OnJudgement((DrawableCatchHitObject)judgedObject, judgement); } } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index eef57897de..2f6759abf3 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -204,12 +204,13 @@ namespace osu.Game.Rulesets.Mania.UI public override void Add(DrawableHitObject hitObject) { hitObject.Depth = (float)hitObject.HitObject.StartTime; - hitObject.AccentColour = AccentColour; + hitObject.OnJudgement += OnJudgement; + HitObjects.Add(hitObject); } - public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) + public void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { if (!judgement.IsHit) return; diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 919518dbe8..0e53ac2d6d 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -192,11 +192,8 @@ namespace osu.Game.Rulesets.Mania.UI } } - public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) + public void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { - var maniaObject = (ManiaHitObject)judgedObject.HitObject; - columns[maniaObject.Column].OnJudgement(judgedObject, judgement); - judgements.Clear(); judgements.Add(new DrawableManiaJudgement(judgement) { @@ -224,7 +221,11 @@ namespace osu.Game.Rulesets.Mania.UI } } - public override void Add(DrawableHitObject h) => Columns.ElementAt(((ManiaHitObject)h.HitObject).Column).Add(h); + public override void Add(DrawableHitObject h) + { + h.OnJudgement += OnJudgement; + Columns.ElementAt(((ManiaHitObject)h.HitObject).Column).Add(h); + } public void Add(DrawableBarLine barline) => HitObjects.Add(barline); diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 892df089f5..5310524089 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -70,6 +70,8 @@ namespace osu.Game.Rulesets.Osu.UI { h.Depth = (float)h.HitObject.StartTime; + h.OnJudgement += OnJudgement; + var c = h as IDrawableHitObjectWithProxiedApproach; if (c != null && ProxyApproachCircles) approachCircles.Add(c.ProxiedLayer.CreateProxy()); @@ -84,7 +86,7 @@ namespace osu.Game.Rulesets.Osu.UI .OrderBy(h => h.StartTime).OfType(); } - public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) + public void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { var osuJudgement = (OsuJudgement)judgement; var osuObject = (OsuHitObject)judgedObject.HitObject; diff --git a/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs index 9500a1a747..fd396c201d 100644 --- a/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/Tests/TestCaseTaikoPlayfield.cs @@ -143,18 +143,18 @@ namespace osu.Game.Rulesets.Taiko.Tests var h = new DrawableTestHit(hit) { X = RNG.NextSingle(hitResult == HitResult.Good ? -0.1f : -0.05f, hitResult == HitResult.Good ? 0.1f : 0.05f) }; - rulesetContainer.Playfield.OnJudgement(h, new TaikoJudgement { Result = hitResult }); + ((TaikoPlayfield)rulesetContainer.Playfield).OnJudgement(h, new TaikoJudgement { Result = hitResult }); if (RNG.Next(10) == 0) { - rulesetContainer.Playfield.OnJudgement(h, new TaikoJudgement { Result = hitResult }); - rulesetContainer.Playfield.OnJudgement(h, new TaikoStrongHitJudgement()); + ((TaikoPlayfield)rulesetContainer.Playfield).OnJudgement(h, new TaikoJudgement { Result = hitResult }); + ((TaikoPlayfield)rulesetContainer.Playfield).OnJudgement(h, new TaikoStrongHitJudgement()); } } private void addMissJudgement() { - rulesetContainer.Playfield.OnJudgement(new DrawableTestHit(new Hit()), new TaikoJudgement { Result = HitResult.Miss }); + ((TaikoPlayfield)rulesetContainer.Playfield).OnJudgement(new DrawableTestHit(new Hit()), new TaikoJudgement { Result = HitResult.Miss }); } private void addBarLine(bool major, double delay = scroll_time) diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index 3c5093d82f..ba7807ec3d 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -209,6 +209,8 @@ namespace osu.Game.Rulesets.Taiko.UI { h.Depth = (float)h.HitObject.StartTime; + h.OnJudgement += OnJudgement; + base.Add(h); var barline = h as DrawableBarLine; @@ -221,7 +223,7 @@ namespace osu.Game.Rulesets.Taiko.UI swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy()); } - public override void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) + public void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { if (judgedObject.DisplayJudgement && judgementContainer.FirstOrDefault(j => j.JudgedObject == judgedObject) == null) { diff --git a/osu.Game/Rulesets/UI/Playfield.cs b/osu.Game/Rulesets/UI/Playfield.cs index e011908c04..b17ea07355 100644 --- a/osu.Game/Rulesets/UI/Playfield.cs +++ b/osu.Game/Rulesets/UI/Playfield.cs @@ -7,7 +7,6 @@ using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Rulesets.Objects.Drawables; using OpenTK; -using osu.Game.Rulesets.Judgements; using osu.Framework.Allocation; namespace osu.Game.Rulesets.UI @@ -86,13 +85,6 @@ namespace osu.Game.Rulesets.UI /// The DrawableHitObject to remove. public virtual void Remove(DrawableHitObject h) => HitObjects.Remove(h); - /// - /// Triggered when a new occurs on a . - /// - /// The object that occured for. - /// The that occurred. - public virtual void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { } - /// /// Registers a as a nested . /// This does not add the to the draw hierarchy. diff --git a/osu.Game/Rulesets/UI/RulesetContainer.cs b/osu.Game/Rulesets/UI/RulesetContainer.cs index 40f88ce577..626b56ad67 100644 --- a/osu.Game/Rulesets/UI/RulesetContainer.cs +++ b/osu.Game/Rulesets/UI/RulesetContainer.cs @@ -262,12 +262,7 @@ namespace osu.Game.Rulesets.UI if (drawableObject == null) continue; - drawableObject.OnJudgement += (d, j) => - { - Playfield.OnJudgement(d, j); - OnJudgement?.Invoke(j); - }; - + drawableObject.OnJudgement += (d, j) => OnJudgement?.Invoke(j); drawableObject.OnJudgementRemoved += (d, j) => OnJudgementRemoved?.Invoke(j); Playfield.Add(drawableObject); From 65ecc18141ef81eb1945141e4269f7ace3f08a7e Mon Sep 17 00:00:00 2001 From: aQaTL Date: Mon, 15 Jan 2018 16:04:57 +0100 Subject: [PATCH 203/206] Cap ApproachRate in HardRock mod at 10.0f --- osu.Game/Rulesets/Mods/ModHardRock.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/Mods/ModHardRock.cs b/osu.Game/Rulesets/Mods/ModHardRock.cs index 97b2fe7d1e..c4c0f38faf 100644 --- a/osu.Game/Rulesets/Mods/ModHardRock.cs +++ b/osu.Game/Rulesets/Mods/ModHardRock.cs @@ -20,7 +20,7 @@ namespace osu.Game.Rulesets.Mods { const float ratio = 1.4f; difficulty.CircleSize *= 1.3f; // CS uses a custom 1.3 ratio. - difficulty.ApproachRate *= ratio; + difficulty.ApproachRate = Math.Min(difficulty.ApproachRate * ratio, 10.0f); difficulty.DrainRate *= ratio; difficulty.OverallDifficulty *= ratio; } From 3c11978cfa76a32436c2e275cf887735e3c5351f Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Mon, 15 Jan 2018 21:42:17 +0300 Subject: [PATCH 204/206] Use local functions --- osu.Desktop/OsuGameDesktop.cs | 2 +- .../Patterns/Legacy/DistanceObjectPatternGenerator.cs | 2 +- osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs | 4 ++-- osu.Game.Tests/Visual/TestCasePlaySongSelect.cs | 2 +- osu.Game/Overlays/OnScreenDisplay.cs | 2 +- osu.Game/Overlays/Profile/ProfileHeader.cs | 4 ++-- osu.Game/Screens/Menu/IntroSequence.cs | 2 +- osu.Game/Screens/Menu/OsuLogo.cs | 4 ++-- osu.Game/Screens/Select/SongSelect.cs | 4 ++-- osu.Game/Screens/Tournament/Drawings.cs | 6 +++--- 10 files changed, 16 insertions(+), 16 deletions(-) diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs index 8e6391168b..f37282366a 100644 --- a/osu.Desktop/OsuGameDesktop.cs +++ b/osu.Desktop/OsuGameDesktop.cs @@ -45,7 +45,7 @@ namespace osu.Desktop { protected override string LocateBasePath() { - Func checkExists = p => Directory.Exists(Path.Combine(p, "Songs")); + bool checkExists(string p) => Directory.Exists(Path.Combine(p, "Songs")); string stableInstallPath; diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs index d15303af39..1d739c114e 100644 --- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs +++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs @@ -321,7 +321,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy break; } - Func isDoubleSample = sample => sample.Name == SampleInfo.HIT_CLAP && sample.Name == SampleInfo.HIT_FINISH; + bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP && sample.Name == SampleInfo.HIT_FINISH; bool canGenerateTwoNotes = (convertType & PatternType.LowProbability) == 0; canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample); diff --git a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs index 322f0ec608..ece1f626ec 100644 --- a/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs +++ b/osu.Game.Tests/Beatmaps/IO/ImportBeatmapTest.cs @@ -117,8 +117,8 @@ namespace osu.Game.Tests.Beatmaps.IO //ensure we were stored to beatmap database backing... Assert.IsTrue(resultSets.Count() == 1, $@"Incorrect result count found ({resultSets.Count()} but should be 1)."); - Func> queryBeatmaps = () => store.QueryBeatmaps(s => s.BeatmapSet.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0); - Func> queryBeatmapSets = () => store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526); + IEnumerable queryBeatmaps() => store.QueryBeatmaps(s => s.BeatmapSet.OnlineBeatmapSetID == 241526 && s.BaseDifficultyID > 0); + IEnumerable queryBeatmapSets() => store.QueryBeatmapSets(s => s.OnlineBeatmapSetID == 241526); //if we don't re-check here, the set will be inserted but the beatmaps won't be present yet. waitForOrAssert(() => queryBeatmaps().Count() == 12, diff --git a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs index f16cf73039..809de2b8db 100644 --- a/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs +++ b/osu.Game.Tests/Visual/TestCasePlaySongSelect.cs @@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual // this is by no means clean. should be replacing inside of OsuGameBase somehow. var context = new OsuDbContext(); - Func contextFactory = () => context; + OsuDbContext contextFactory() => context; dependencies.Cache(rulesets = new RulesetStore(contextFactory)); dependencies.Cache(manager = new BeatmapManager(storage, contextFactory, rulesets, null) diff --git a/osu.Game/Overlays/OnScreenDisplay.cs b/osu.Game/Overlays/OnScreenDisplay.cs index 6a1bd8e182..d29941d590 100644 --- a/osu.Game/Overlays/OnScreenDisplay.cs +++ b/osu.Game/Overlays/OnScreenDisplay.cs @@ -121,7 +121,7 @@ namespace osu.Game.Overlays trackSetting(frameworkConfig.GetBindable(FrameworkSetting.AudioDevice), v => display(v, "Audio Device", string.IsNullOrEmpty(v) ? "Default" : v, v)); trackSetting(frameworkConfig.GetBindable(FrameworkSetting.ShowLogOverlay), v => display(v, "Debug Logs", v ? "visible" : "hidden", "Ctrl+F10")); - Action displayResolution = delegate { display(null, "Screen Resolution", frameworkConfig.Get(FrameworkSetting.Width) + "x" + frameworkConfig.Get(FrameworkSetting.Height)); }; + void displayResolution() => display(null, "Screen Resolution", frameworkConfig.Get(FrameworkSetting.Width) + "x" + frameworkConfig.Get(FrameworkSetting.Height)); trackSetting(frameworkConfig.GetBindable(FrameworkSetting.Width), v => displayResolution()); trackSetting(frameworkConfig.GetBindable(FrameworkSetting.Height), v => displayResolution()); diff --git a/osu.Game/Overlays/Profile/ProfileHeader.cs b/osu.Game/Overlays/Profile/ProfileHeader.cs index 6a9f4b84b0..ed8eb258f4 100644 --- a/osu.Game/Overlays/Profile/ProfileHeader.cs +++ b/osu.Game/Overlays/Profile/ProfileHeader.cs @@ -319,11 +319,11 @@ namespace osu.Game.Overlays.Profile colourBar.Show(); } - Action boldItalic = t => + void boldItalic(SpriteText t) { t.Font = @"Exo2.0-BoldItalic"; t.Alpha = 1; - }; + } if (user.Age != null) { diff --git a/osu.Game/Screens/Menu/IntroSequence.cs b/osu.Game/Screens/Menu/IntroSequence.cs index 577eb33d18..6f346995e8 100644 --- a/osu.Game/Screens/Menu/IntroSequence.cs +++ b/osu.Game/Screens/Menu/IntroSequence.cs @@ -188,7 +188,7 @@ namespace osu.Game.Screens.Menu mediumRing.ResizeTo(130, 340, Easing.OutQuad); mediumRing.Foreground.ResizeTo(1, 880, Easing.Out); - Func remainingTime = () => length - TransformDelay; + double remainingTime() => length - TransformDelay; using (BeginDelayedSequence(250, true)) { diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index 4a13ae421e..f6af204237 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -231,7 +231,7 @@ namespace osu.Game.Screens.Menu /// If true, the new animation is delayed until all previous transforms finish. If false, existing transformed are cleared. public void AppendAnimatingAction(Action action, bool waitForPrevious) { - Action runnableAction = () => + void runnableAction() { if (waitForPrevious) this.DelayUntilTransformsFinished().Schedule(action); @@ -240,7 +240,7 @@ namespace osu.Game.Screens.Menu ClearTransforms(); action(); } - }; + } if (IsLoaded) runnableAction(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 7431a6e0e6..357931b878 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -266,7 +266,7 @@ namespace osu.Game.Screens.Select /// private void carouselSelectionChanged(BeatmapInfo beatmap) { - Action performLoad = delegate + void performLoad() { // We may be arriving here due to another component changing the bindable Beatmap. // In these cases, the other component has already loaded the beatmap, so we don't need to do so again. @@ -279,7 +279,7 @@ namespace osu.Game.Screens.Select } UpdateBeatmap(Beatmap.Value); - }; + } if (beatmap?.Equals(beatmapNoDebounce) == true) return; diff --git a/osu.Game/Screens/Tournament/Drawings.cs b/osu.Game/Screens/Tournament/Drawings.cs index 17a678c191..498dd7de6f 100644 --- a/osu.Game/Screens/Tournament/Drawings.cs +++ b/osu.Game/Screens/Tournament/Drawings.cs @@ -265,7 +265,7 @@ namespace osu.Game.Screens.Tournament private void writeResults(string text) { - Action writeAction = () => + void writeAction() { try { @@ -280,9 +280,9 @@ namespace osu.Game.Screens.Tournament { Logger.Error(ex, "Failed to write results."); } - }; + } - writeOp = writeOp?.ContinueWith(t => { writeAction(); }) ?? Task.Run(writeAction); + writeOp = writeOp?.ContinueWith(t => { writeAction(); }) ?? Task.Run((Action)writeAction); } private void reloadTeams() From c3ca40dcff48e7844c098ed4507f8bfc829b7e0f Mon Sep 17 00:00:00 2001 From: TocoToucan Date: Mon, 15 Jan 2018 23:27:00 +0300 Subject: [PATCH 205/206] Local functions related CI fixes --- osu.Game/Screens/Menu/IntroSequence.cs | 1 - osu.Game/Screens/Menu/OsuLogo.cs | 2 +- 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Menu/IntroSequence.cs b/osu.Game/Screens/Menu/IntroSequence.cs index 6f346995e8..ff3b4eba56 100644 --- a/osu.Game/Screens/Menu/IntroSequence.cs +++ b/osu.Game/Screens/Menu/IntroSequence.cs @@ -1,7 +1,6 @@ // Copyright (c) 2007-2018 ppy Pty Ltd . // Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE -using System; using System.Linq; using OpenTK; using OpenTK.Graphics; diff --git a/osu.Game/Screens/Menu/OsuLogo.cs b/osu.Game/Screens/Menu/OsuLogo.cs index f6af204237..b91ff0d74b 100644 --- a/osu.Game/Screens/Menu/OsuLogo.cs +++ b/osu.Game/Screens/Menu/OsuLogo.cs @@ -245,7 +245,7 @@ namespace osu.Game.Screens.Menu if (IsLoaded) runnableAction(); else - Schedule(() => runnableAction()); + Schedule(runnableAction); } [BackgroundDependencyLoader] From c309cc94540db54ebc48918f9ca45d2e016c8ab3 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Tue, 16 Jan 2018 15:37:32 +0900 Subject: [PATCH 206/206] Privatise OnJudgements as much as possible --- osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs | 4 ++-- osu.Game.Rulesets.Mania/UI/Column.cs | 4 ++-- osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs | 2 +- osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs | 4 ++-- osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs | 2 +- 5 files changed, 8 insertions(+), 8 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs index a2324671b2..7f56c3bbb1 100644 --- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs +++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs @@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Catch.UI public override void Add(DrawableHitObject h) { h.Depth = (float)h.HitObject.StartTime; - h.OnJudgement += OnJudgement; + h.OnJudgement += onJudgement; base.Add(h); @@ -66,6 +66,6 @@ namespace osu.Game.Rulesets.Catch.UI fruit.CheckPosition = CheckIfWeCanCatch; } - public void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) => catcherArea.OnJudgement((DrawableCatchHitObject)judgedObject, judgement); + private void onJudgement(DrawableHitObject judgedObject, Judgement judgement) => catcherArea.OnJudgement((DrawableCatchHitObject)judgedObject, judgement); } } diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs index 2f6759abf3..d79a4d62c4 100644 --- a/osu.Game.Rulesets.Mania/UI/Column.cs +++ b/osu.Game.Rulesets.Mania/UI/Column.cs @@ -205,12 +205,12 @@ namespace osu.Game.Rulesets.Mania.UI { hitObject.Depth = (float)hitObject.HitObject.StartTime; hitObject.AccentColour = AccentColour; - hitObject.OnJudgement += OnJudgement; + hitObject.OnJudgement += onJudgement; HitObjects.Add(hitObject); } - public void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) + private void onJudgement(DrawableHitObject judgedObject, Judgement judgement) { if (!judgement.IsHit) return; diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs index 0e53ac2d6d..7d3df6cda7 100644 --- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs +++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs @@ -192,7 +192,7 @@ namespace osu.Game.Rulesets.Mania.UI } } - public void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) + internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { judgements.Clear(); judgements.Add(new DrawableManiaJudgement(judgement) diff --git a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs index 5310524089..17521f8992 100644 --- a/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs +++ b/osu.Game.Rulesets.Osu/UI/OsuPlayfield.cs @@ -70,7 +70,7 @@ namespace osu.Game.Rulesets.Osu.UI { h.Depth = (float)h.HitObject.StartTime; - h.OnJudgement += OnJudgement; + h.OnJudgement += onJudgement; var c = h as IDrawableHitObjectWithProxiedApproach; if (c != null && ProxyApproachCircles) @@ -86,7 +86,7 @@ namespace osu.Game.Rulesets.Osu.UI .OrderBy(h => h.StartTime).OfType(); } - public void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) + private void onJudgement(DrawableHitObject judgedObject, Judgement judgement) { var osuJudgement = (OsuJudgement)judgement; var osuObject = (OsuHitObject)judgedObject.HitObject; diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs index ba7807ec3d..49c87f7480 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs @@ -223,7 +223,7 @@ namespace osu.Game.Rulesets.Taiko.UI swell.OnStart += () => topLevelHitContainer.Add(swell.CreateProxy()); } - public void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) + internal void OnJudgement(DrawableHitObject judgedObject, Judgement judgement) { if (judgedObject.DisplayJudgement && judgementContainer.FirstOrDefault(j => j.JudgedObject == judgedObject) == null) {