From 283d953c4fc5da054b875c4c958ce75c238740fd Mon Sep 17 00:00:00 2001 From: aitani9 <55509723+aitani9@users.noreply.github.com> Date: Wed, 21 Jul 2021 14:07:00 -0700 Subject: [PATCH 01/53] Fix blinds moving when barrel roll mod is active --- osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs | 35 +++++++++++++++++++--- 1 file changed, 31 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs index 636cd63c69..f37058564e 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -32,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { - drawableRuleset.Overlays.Add(blinds = new DrawableOsuBlinds(drawableRuleset.Playfield.HitObjectContainer, drawableRuleset.Beatmap)); + drawableRuleset.Overlays.Add(blinds = new DrawableOsuBlinds(drawableRuleset.Playfield, drawableRuleset.Beatmap, drawableRuleset.Mods)); } public void ApplyToHealthProcessor(HealthProcessor healthProcessor) @@ -67,6 +68,8 @@ namespace osu.Game.Rulesets.Osu.Mods private readonly CompositeDrawable restrictTo; + private readonly bool barrelRollActive; + /// /// /// Percentage of playfield to extend blinds over. Basically moves the origin points where the blinds start. @@ -80,13 +83,24 @@ namespace osu.Game.Rulesets.Osu.Mods /// private const float leniency = 0.1f; - public DrawableOsuBlinds(CompositeDrawable restrictTo, Beatmap beatmap) + public DrawableOsuBlinds(CompositeDrawable restrictTo, Beatmap beatmap, IEnumerable mods) { this.restrictTo = restrictTo; this.beatmap = beatmap; targetBreakMultiplier = 0; easing = 1; + + barrelRollActive = false; + + foreach (Mod mod in mods) + { + if (mod is OsuModBarrelRoll) + { + barrelRollActive = true; + break; + } + } } [BackgroundDependencyLoader] @@ -128,8 +142,21 @@ namespace osu.Game.Rulesets.Osu.Mods protected override void Update() { - float start = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopLeft).X; - float end = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopRight).X; + float start, end; + + if (barrelRollActive) + { + float origin = restrictTo.ToSpaceOfOtherDrawable(restrictTo.OriginPosition, Parent).X; + float halfDiagonal = MathF.Sqrt(MathF.Pow(restrictTo.DrawWidth / 2, 2) + MathF.Pow(restrictTo.DrawHeight / 2, 2)); + + start = origin - halfDiagonal; + end = origin + halfDiagonal; + } + else + { + start = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopLeft).X; + end = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopRight).X; + } float rawWidth = end - start; From e6b28e1386a481ee8e06aef41ae30ef1fae61370 Mon Sep 17 00:00:00 2001 From: aitani9 <55509723+aitani9@users.noreply.github.com> Date: Thu, 22 Jul 2021 14:01:31 -0700 Subject: [PATCH 02/53] Rename `origin` to `center` for clarity --- osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs index f37058564e..c4872aaf64 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs @@ -146,11 +146,11 @@ namespace osu.Game.Rulesets.Osu.Mods if (barrelRollActive) { - float origin = restrictTo.ToSpaceOfOtherDrawable(restrictTo.OriginPosition, Parent).X; + float center = restrictTo.ToSpaceOfOtherDrawable(restrictTo.OriginPosition, Parent).X; float halfDiagonal = MathF.Sqrt(MathF.Pow(restrictTo.DrawWidth / 2, 2) + MathF.Pow(restrictTo.DrawHeight / 2, 2)); - start = origin - halfDiagonal; - end = origin + halfDiagonal; + start = center - halfDiagonal; + end = center + halfDiagonal; } else { From 80cb7c77b911f380a7fd558d375509bc3e729bf4 Mon Sep 17 00:00:00 2001 From: aitani9 <55509723+aitani9@users.noreply.github.com> Date: Thu, 22 Jul 2021 14:04:01 -0700 Subject: [PATCH 03/53] Calculate the diagonal length using `Vector2.LengthFast` instead of manually --- osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs index c4872aaf64..09d73566a1 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs @@ -147,7 +147,7 @@ namespace osu.Game.Rulesets.Osu.Mods if (barrelRollActive) { float center = restrictTo.ToSpaceOfOtherDrawable(restrictTo.OriginPosition, Parent).X; - float halfDiagonal = MathF.Sqrt(MathF.Pow(restrictTo.DrawWidth / 2, 2) + MathF.Pow(restrictTo.DrawHeight / 2, 2)); + float halfDiagonal = (restrictTo.DrawSize / 2).LengthFast; start = center - halfDiagonal; end = center + halfDiagonal; From 715f3e3f7c1240baed2b64c2c096923f9fcec180 Mon Sep 17 00:00:00 2001 From: aitani9 <55509723+aitani9@users.noreply.github.com> Date: Thu, 22 Jul 2021 14:07:41 -0700 Subject: [PATCH 04/53] Make blinds move correctly whenever the playfield is rotated --- osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs | 31 +++++++--------------- 1 file changed, 9 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs index 09d73566a1..3102db270e 100644 --- a/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs +++ b/osu.Game.Rulesets.Osu/Mods/OsuModBlinds.cs @@ -2,13 +2,13 @@ // See the LICENCE file in the repository root for full licence text. using System; -using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Graphics.Sprites; using osu.Framework.Graphics.Textures; +using osu.Framework.Utils; using osu.Game.Beatmaps; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Objects; @@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Osu.Mods public void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset) { - drawableRuleset.Overlays.Add(blinds = new DrawableOsuBlinds(drawableRuleset.Playfield, drawableRuleset.Beatmap, drawableRuleset.Mods)); + drawableRuleset.Overlays.Add(blinds = new DrawableOsuBlinds(drawableRuleset.Playfield, drawableRuleset.Beatmap)); } public void ApplyToHealthProcessor(HealthProcessor healthProcessor) @@ -68,8 +68,6 @@ namespace osu.Game.Rulesets.Osu.Mods private readonly CompositeDrawable restrictTo; - private readonly bool barrelRollActive; - /// /// /// Percentage of playfield to extend blinds over. Basically moves the origin points where the blinds start. @@ -83,24 +81,13 @@ namespace osu.Game.Rulesets.Osu.Mods /// private const float leniency = 0.1f; - public DrawableOsuBlinds(CompositeDrawable restrictTo, Beatmap beatmap, IEnumerable mods) + public DrawableOsuBlinds(CompositeDrawable restrictTo, Beatmap beatmap) { this.restrictTo = restrictTo; this.beatmap = beatmap; targetBreakMultiplier = 0; easing = 1; - - barrelRollActive = false; - - foreach (Mod mod in mods) - { - if (mod is OsuModBarrelRoll) - { - barrelRollActive = true; - break; - } - } } [BackgroundDependencyLoader] @@ -144,7 +131,12 @@ namespace osu.Game.Rulesets.Osu.Mods { float start, end; - if (barrelRollActive) + if (Precision.AlmostEquals(restrictTo.Rotation, 0)) + { + start = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopLeft).X; + end = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopRight).X; + } + else { float center = restrictTo.ToSpaceOfOtherDrawable(restrictTo.OriginPosition, Parent).X; float halfDiagonal = (restrictTo.DrawSize / 2).LengthFast; @@ -152,11 +144,6 @@ namespace osu.Game.Rulesets.Osu.Mods start = center - halfDiagonal; end = center + halfDiagonal; } - else - { - start = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopLeft).X; - end = Parent.ToLocalSpace(restrictTo.ScreenSpaceDrawQuad.TopRight).X; - } float rawWidth = end - start; From 067ff0e0ad4051ceaa7a8726d8f38d3ce884a8d6 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Aug 2021 18:38:14 +0300 Subject: [PATCH 05/53] Store last opened settings subpanel rather than relying on LINQ --- osu.Game/Overlays/SettingsOverlay.cs | 13 ++++++++----- 1 file changed, 8 insertions(+), 5 deletions(-) diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 54b780615d..050502b3be 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -9,7 +9,6 @@ using osu.Game.Overlays.Settings.Sections; using osu.Game.Overlays.Settings.Sections.Input; using osuTK.Graphics; using System.Collections.Generic; -using System.Linq; using osu.Framework.Bindables; using osu.Framework.Localisation; using osu.Game.Localisation; @@ -38,6 +37,8 @@ namespace osu.Game.Overlays private readonly List subPanels = new List(); + private SettingsSubPanel lastOpenedSubPanel; + protected override Drawable CreateHeader() => new SettingsHeader(Title, Description); protected override Drawable CreateFooter() => new SettingsFooter(); @@ -46,21 +47,21 @@ namespace osu.Game.Overlays { } - public override bool AcceptsFocus => subPanels.All(s => s.State.Value != Visibility.Visible); + public override bool AcceptsFocus => lastOpenedSubPanel == null || lastOpenedSubPanel.State.Value == Visibility.Hidden; private T createSubPanel(T subPanel) where T : SettingsSubPanel { subPanel.Depth = 1; subPanel.Anchor = Anchor.TopRight; - subPanel.State.ValueChanged += subPanelStateChanged; + subPanel.State.ValueChanged += e => subPanelStateChanged(subPanel, e); subPanels.Add(subPanel); return subPanel; } - private void subPanelStateChanged(ValueChangedEvent state) + private void subPanelStateChanged(SettingsSubPanel panel, ValueChangedEvent state) { switch (state.NewValue) { @@ -69,6 +70,8 @@ namespace osu.Game.Overlays SectionsContainer.FadeOut(300, Easing.OutQuint); ContentContainer.MoveToX(-WIDTH, 500, Easing.OutQuint); + + lastOpenedSubPanel = panel; break; case Visibility.Hidden: @@ -80,7 +83,7 @@ namespace osu.Game.Overlays } } - protected override float ExpandedPosition => subPanels.Any(s => s.State.Value == Visibility.Visible) ? -WIDTH : base.ExpandedPosition; + protected override float ExpandedPosition => lastOpenedSubPanel?.State.Value == Visibility.Visible ? -WIDTH : base.ExpandedPosition; [BackgroundDependencyLoader] private void load() From 8e8e0fb8d8c9abce26fe64a0098507c8967d0739 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Aug 2021 18:36:43 +0300 Subject: [PATCH 06/53] Add placement-dependent horizontal screen offset properties --- osu.Game/Overlays/NotificationOverlay.cs | 5 +++++ osu.Game/Overlays/SettingsOverlay.cs | 2 ++ osu.Game/Overlays/SettingsPanel.cs | 6 ++++++ 3 files changed, 13 insertions(+) diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index b26e17b34c..af4f41901f 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -30,6 +30,11 @@ namespace osu.Game.Overlays private FlowContainer sections; + /// + /// A horizontal offset to apply to the game-wide screen. + /// + public float HorizontalScreenOffset => -width + X; + /// /// Provide a source for the toolbar height. /// diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 050502b3be..9ed1d950e3 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -21,6 +21,8 @@ namespace osu.Game.Overlays public LocalisableString Title => SettingsStrings.HeaderTitle; public LocalisableString Description => SettingsStrings.HeaderDescription; + public override float HorizontalScreenOffset => base.HorizontalScreenOffset + (lastOpenedSubPanel?.HorizontalScreenOffset ?? 0f); + protected override IEnumerable CreateSections() => new SettingsSection[] { new GeneralSection(), diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index eae828c142..2916ea013f 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -34,6 +34,11 @@ namespace osu.Game.Overlays protected override Container Content => ContentContainer; + /// + /// A horizontal offset to apply to the game-wide screen. + /// + public virtual float HorizontalScreenOffset => (WIDTH + Content?.X) ?? 0f; + protected Sidebar Sidebar; private SidebarButton selectedSidebarButton; @@ -64,6 +69,7 @@ namespace osu.Game.Overlays { InternalChild = ContentContainer = new NonMaskedContent { + X = -WIDTH + ExpandedPosition, Width = WIDTH, RelativeSizeAxes = Axes.Y, Children = new Drawable[] From f77037ef57d6df00845867ae436ceb77e3f525dd Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Aug 2021 18:38:48 +0300 Subject: [PATCH 07/53] Replace state-based screen offsetting logic with `HorizontalScreenOffset`s --- osu.Game/OsuGame.cs | 18 +++--------------- 1 file changed, 3 insertions(+), 15 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 3cfa2cc755..85428a12e3 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -828,21 +828,6 @@ namespace osu.Game { if (mode.NewValue != OverlayActivation.All) CloseAllOverlays(); }; - - void updateScreenOffset() - { - float offset = 0; - - if (Settings.State.Value == Visibility.Visible) - offset += Toolbar.HEIGHT / 2; - if (notifications.State.Value == Visibility.Visible) - offset -= Toolbar.HEIGHT / 2; - - screenOffsetContainer.MoveToX(offset, SettingsPanel.TRANSITION_LENGTH, Easing.OutQuint); - } - - Settings.State.ValueChanged += _ => updateScreenOffset(); - notifications.State.ValueChanged += _ => updateScreenOffset(); } private void showOverlayAboveOthers(OverlayContainer overlay, OverlayContainer[] otherOverlays) @@ -1026,6 +1011,9 @@ namespace osu.Game screenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset }; overlayContent.Padding = new MarginPadding { Top = ToolbarOffset }; + screenOffsetContainer.X = Settings.HorizontalScreenOffset * 0.125f + + notifications.HorizontalScreenOffset * 0.125f; + MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; } From ac157f6cef91f35252599059451fa315819180cf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Aug 2021 22:10:03 +0300 Subject: [PATCH 08/53] Fix settings panel children not processing transforms while masked away --- osu.Game/Overlays/SettingsPanel.cs | 6 ++++++ 1 file changed, 6 insertions(+) diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 2916ea013f..79d78e6805 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -34,6 +34,12 @@ namespace osu.Game.Overlays protected override Container Content => ContentContainer; + /// + /// The always needs to be present for to process transforms while overlay is masked away. + /// todo: there may be a better solution for this and the existing , likely requires a refactor. + /// + public override bool IsPresent => true; + /// /// A horizontal offset to apply to the game-wide screen. /// From 8dc0650ca71d9143d0268268a6f21f826d658679 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 6 Aug 2021 22:36:40 +0300 Subject: [PATCH 09/53] Add test coverage --- .../Visual/Menus/TestSceneSideOverlays.cs | 62 +++++++++++++++++++ .../Visual/Navigation/OsuGameTestScene.cs | 7 ++- osu.Game/OsuGame.cs | 33 +++++----- osu.Game/Overlays/NotificationOverlay.cs | 8 +-- 4 files changed, 90 insertions(+), 20 deletions(-) create mode 100644 osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs new file mode 100644 index 0000000000..34259574f3 --- /dev/null +++ b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs @@ -0,0 +1,62 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System.Linq; +using NUnit.Framework; +using osu.Framework.Graphics.Containers; +using osu.Framework.Testing; +using osu.Game.Overlays; +using osu.Game.Overlays.Settings.Sections.Input; +using osu.Game.Tests.Visual.Navigation; + +namespace osu.Game.Tests.Visual.Menus +{ + public class TestSceneSideOverlays : OsuGameTestScene + { + [SetUpSteps] + public override void SetUpSteps() + { + base.SetUpSteps(); + + AddAssert("no screen offset applied", () => Game.ScreenOffsetContainer.X == 0f); + } + + [Test] + public void TestScreenOffsettingOnSettingsOverlay() + { + AddStep("open settings", () => Game.Settings.Show()); + AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + + AddStep("hide settings", () => Game.Settings.Hide()); + AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); + } + + [Test] + public void TestScreenOffsettingAccountsForKeyBindingPanel() + { + AddStep("open settings", () => Game.Settings.Show()); + AddStep("open key binding panel", () => Game.Settings.ChildrenOfType().Single().Show()); + AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + + AddStep("hide key binding", () => Game.Settings.ChildrenOfType().Single().Show()); + AddUntilStep("right screen offset still applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + + AddStep("open key binding", () => Game.Settings.Show()); + AddUntilStep("right screen offset still applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + + AddStep("hide settings", () => Game.Settings.Hide()); + AddAssert("key binding panel still open", () => Game.Settings.ChildrenOfType().Single().State.Value == Visibility.Visible); + AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); + } + + [Test] + public void TestScreenOffsettingOnNotificationOverlay() + { + AddStep("open notifications", () => Game.Notifications.Show()); + AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == -NotificationOverlay.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + + AddStep("hide notifications", () => Game.Notifications.Hide()); + AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); + } + } +} diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs index f9a991f756..5cd55ed233 100644 --- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs @@ -6,6 +6,7 @@ using System.Collections.Generic; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Shapes; using osu.Framework.Platform; using osu.Framework.Screens; @@ -103,7 +104,11 @@ namespace osu.Game.Tests.Visual.Navigation public new ScoreManager ScoreManager => base.ScoreManager; - public new SettingsPanel Settings => base.Settings; + public new Container ScreenOffsetContainer => base.ScreenOffsetContainer; + + public new SettingsOverlay Settings => base.Settings; + + public new NotificationOverlay Notifications => base.Notifications; public new MusicController MusicController => base.MusicController; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 85428a12e3..d2f86f812e 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -64,6 +64,8 @@ namespace osu.Game /// public class OsuGame : OsuGameBase, IKeyBindingHandler { + public const float SCREEN_OFFSET_RATIO = 0.125f; + public Toolbar Toolbar; private ChatOverlay chatOverlay; @@ -71,7 +73,7 @@ namespace osu.Game private ChannelManager channelManager; [NotNull] - private readonly NotificationOverlay notifications = new NotificationOverlay(); + protected readonly NotificationOverlay Notifications = new NotificationOverlay(); private BeatmapListingOverlay beatmapListing; @@ -97,7 +99,7 @@ namespace osu.Game private ScalingContainer screenContainer; - private Container screenOffsetContainer; + protected Container ScreenOffsetContainer; [Resolved] private FrameworkConfigManager frameworkConfig { get; set; } @@ -312,7 +314,7 @@ namespace osu.Game case LinkAction.OpenEditorTimestamp: case LinkAction.JoinMultiplayerMatch: case LinkAction.Spectate: - waitForReady(() => notifications, _ => notifications.Post(new SimpleNotification + waitForReady(() => Notifications, _ => Notifications.Post(new SimpleNotification { Text = @"This link type is not yet supported!", Icon = FontAwesome.Solid.LifeRing, @@ -611,12 +613,12 @@ namespace osu.Game MenuCursorContainer.CanShowCursor = menuScreen?.CursorVisible ?? false; // todo: all archive managers should be able to be looped here. - SkinManager.PostNotification = n => notifications.Post(n); + SkinManager.PostNotification = n => Notifications.Post(n); - BeatmapManager.PostNotification = n => notifications.Post(n); + BeatmapManager.PostNotification = n => Notifications.Post(n); BeatmapManager.PresentImport = items => PresentBeatmap(items.First()); - ScoreManager.PostNotification = n => notifications.Post(n); + ScoreManager.PostNotification = n => Notifications.Post(n); ScoreManager.PresentImport = items => PresentScore(items.First()); // make config aware of how to lookup skins for on-screen display purposes. @@ -655,7 +657,7 @@ namespace osu.Game ActionRequested = action => volume.Adjust(action), ScrollActionRequested = (action, amount, isPrecise) => volume.Adjust(action, amount, isPrecise), }, - screenOffsetContainer = new Container + ScreenOffsetContainer = new Container { RelativeSizeAxes = Axes.Both, Children = new Drawable[] @@ -724,7 +726,7 @@ namespace osu.Game loadComponentSingleFile(onScreenDisplay, Add, true); - loadComponentSingleFile(notifications.With(d => + loadComponentSingleFile(Notifications.With(d => { d.GetToolbarHeight = () => ToolbarOffset; d.Anchor = Anchor.TopRight; @@ -733,7 +735,7 @@ namespace osu.Game loadComponentSingleFile(new CollectionManager(Storage) { - PostNotification = n => notifications.Post(n), + PostNotification = n => Notifications.Post(n), }, Add, true); loadComponentSingleFile(stableImportManager, Add); @@ -785,7 +787,7 @@ namespace osu.Game Add(new MusicKeyBindingHandler()); // side overlays which cancel each other. - var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications }; + var singleDisplaySideOverlays = new OverlayContainer[] { Settings, Notifications }; foreach (var overlay in singleDisplaySideOverlays) { @@ -859,7 +861,7 @@ namespace osu.Game if (recentLogCount < short_term_display_limit) { - Schedule(() => notifications.Post(new SimpleErrorNotification + Schedule(() => Notifications.Post(new SimpleErrorNotification { Icon = entry.Level == LogLevel.Important ? FontAwesome.Solid.ExclamationCircle : FontAwesome.Solid.Bomb, Text = entry.Message.Truncate(256) + (entry.Exception != null && IsDeployedBuild ? "\n\nThis error has been automatically reported to the devs." : string.Empty), @@ -867,7 +869,7 @@ namespace osu.Game } else if (recentLogCount == short_term_display_limit) { - Schedule(() => notifications.Post(new SimpleNotification + Schedule(() => Notifications.Post(new SimpleNotification { Icon = FontAwesome.Solid.EllipsisH, Text = "Subsequent messages have been logged. Click to view log files.", @@ -1008,11 +1010,12 @@ namespace osu.Game { base.UpdateAfterChildren(); - screenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset }; + ScreenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset }; overlayContent.Padding = new MarginPadding { Top = ToolbarOffset }; - screenOffsetContainer.X = Settings.HorizontalScreenOffset * 0.125f + - notifications.HorizontalScreenOffset * 0.125f; + var settingsOffset = Settings.HorizontalScreenOffset * SCREEN_OFFSET_RATIO; + var notificationsOffset = Notifications.HorizontalScreenOffset * SCREEN_OFFSET_RATIO; + ScreenOffsetContainer.X = settingsOffset + notificationsOffset; MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; } diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index af4f41901f..9be3212159 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -24,7 +24,7 @@ namespace osu.Game.Overlays public LocalisableString Title => NotificationsStrings.HeaderTitle; public LocalisableString Description => NotificationsStrings.HeaderDescription; - private const float width = 320; + public const float WIDTH = 320; public const float TRANSITION_LENGTH = 600; @@ -33,7 +33,7 @@ namespace osu.Game.Overlays /// /// A horizontal offset to apply to the game-wide screen. /// - public float HorizontalScreenOffset => -width + X; + public float HorizontalScreenOffset => -WIDTH + X; /// /// Provide a source for the toolbar height. @@ -43,7 +43,7 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load() { - Width = width; + Width = WIDTH; RelativeSizeAxes = Axes.Y; Children = new Drawable[] @@ -157,7 +157,7 @@ namespace osu.Game.Overlays markAllRead(); - this.MoveToX(width, TRANSITION_LENGTH, Easing.OutQuint); + this.MoveToX(WIDTH, TRANSITION_LENGTH, Easing.OutQuint); this.FadeTo(0, TRANSITION_LENGTH, Easing.OutQuint); } From ae733e202ff574b9a3065b9bc72fca71b8960580 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 00:36:52 +0300 Subject: [PATCH 10/53] Fix tests executing before overlays load --- osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs index 34259574f3..598998586d 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs @@ -19,6 +19,7 @@ namespace osu.Game.Tests.Visual.Menus base.SetUpSteps(); AddAssert("no screen offset applied", () => Game.ScreenOffsetContainer.X == 0f); + AddUntilStep("wait for overlays", () => Game.Settings.IsLoaded && Game.Notifications.IsLoaded); } [Test] From 9ac5c9aa2f8d426d1733140702ab3d3c518bce99 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 01:27:54 +0300 Subject: [PATCH 11/53] Fix notification overlay having incorrect initial X --- osu.Game/Overlays/NotificationOverlay.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 9be3212159..cb5d4d57c6 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -43,6 +43,7 @@ namespace osu.Game.Overlays [BackgroundDependencyLoader] private void load() { + X = WIDTH; Width = WIDTH; RelativeSizeAxes = Axes.Y; From e924ea8d934d043a446d92a0ffeea7885cee46ec Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 18:52:27 +0300 Subject: [PATCH 12/53] Make `ScreenOffsetContainer` privatly settable only --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index d2f86f812e..6fb884f80a 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -99,7 +99,7 @@ namespace osu.Game private ScalingContainer screenContainer; - protected Container ScreenOffsetContainer; + protected Container ScreenOffsetContainer { get; private set; } [Resolved] private FrameworkConfigManager frameworkConfig { get; set; } From 9f3013e2c89a1ea018008cb6221d9165e72f13a2 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 19:30:12 +0300 Subject: [PATCH 13/53] Remove all `HorizontalScreenOffset` calculations from overlays --- osu.Game/Overlays/NotificationOverlay.cs | 5 ----- osu.Game/Overlays/SettingsOverlay.cs | 2 -- osu.Game/Overlays/SettingsPanel.cs | 5 ----- 3 files changed, 12 deletions(-) diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index cb5d4d57c6..e3956089c2 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -30,11 +30,6 @@ namespace osu.Game.Overlays private FlowContainer sections; - /// - /// A horizontal offset to apply to the game-wide screen. - /// - public float HorizontalScreenOffset => -WIDTH + X; - /// /// Provide a source for the toolbar height. /// diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 9ed1d950e3..050502b3be 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -21,8 +21,6 @@ namespace osu.Game.Overlays public LocalisableString Title => SettingsStrings.HeaderTitle; public LocalisableString Description => SettingsStrings.HeaderDescription; - public override float HorizontalScreenOffset => base.HorizontalScreenOffset + (lastOpenedSubPanel?.HorizontalScreenOffset ?? 0f); - protected override IEnumerable CreateSections() => new SettingsSection[] { new GeneralSection(), diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 79d78e6805..64c3be4b9a 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -40,11 +40,6 @@ namespace osu.Game.Overlays /// public override bool IsPresent => true; - /// - /// A horizontal offset to apply to the game-wide screen. - /// - public virtual float HorizontalScreenOffset => (WIDTH + Content?.X) ?? 0f; - protected Sidebar Sidebar; private SidebarButton selectedSidebarButton; From 19a19f915cde29015df6e085406af348c487bba4 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 19:56:51 +0300 Subject: [PATCH 14/53] Adjust settings panel to autosize to zero when hiding it Previously, when hiding the settings overlay, it remains to have a width of `56` (sidebar width), this is due to the panel content being placed next to the sidebar, so therefore the content has to move 400 (PANEL_WIDTH) + 56 (sidebar_width) backwards, for the overlay to have a width of 0 on hide. --- .../Visual/Settings/TestSceneTabletSettings.cs | 2 +- osu.Game/Overlays/SettingsOverlay.cs | 4 ++-- osu.Game/Overlays/SettingsPanel.cs | 12 ++++++++++-- 3 files changed, 13 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs b/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs index a62980addf..da474a64ba 100644 --- a/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs +++ b/osu.Game.Tests/Visual/Settings/TestSceneTabletSettings.cs @@ -27,7 +27,7 @@ namespace osu.Game.Tests.Visual.Settings new TabletSettings(tabletHandler) { RelativeSizeAxes = Axes.None, - Width = SettingsPanel.WIDTH, + Width = SettingsPanel.PANEL_WIDTH, Anchor = Anchor.TopCentre, Origin = Anchor.TopCentre, } diff --git a/osu.Game/Overlays/SettingsOverlay.cs b/osu.Game/Overlays/SettingsOverlay.cs index 050502b3be..55e8aee266 100644 --- a/osu.Game/Overlays/SettingsOverlay.cs +++ b/osu.Game/Overlays/SettingsOverlay.cs @@ -69,7 +69,7 @@ namespace osu.Game.Overlays Sidebar?.FadeColour(Color4.DarkGray, 300, Easing.OutQuint); SectionsContainer.FadeOut(300, Easing.OutQuint); - ContentContainer.MoveToX(-WIDTH, 500, Easing.OutQuint); + ContentContainer.MoveToX(-PANEL_WIDTH, 500, Easing.OutQuint); lastOpenedSubPanel = panel; break; @@ -83,7 +83,7 @@ namespace osu.Game.Overlays } } - protected override float ExpandedPosition => lastOpenedSubPanel?.State.Value == Visibility.Visible ? -WIDTH : base.ExpandedPosition; + protected override float ExpandedPosition => lastOpenedSubPanel?.State.Value == Visibility.Visible ? -PANEL_WIDTH : base.ExpandedPosition; [BackgroundDependencyLoader] private void load() diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 64c3be4b9a..8b953e8655 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -28,7 +28,15 @@ namespace osu.Game.Overlays private const float sidebar_width = Sidebar.DEFAULT_WIDTH; - public const float WIDTH = 400; + /// + /// The width of the settings panel content, excluding the sidebar. + /// + public const float PANEL_WIDTH = 400; + + /// + /// The full width of the settings panel, including the sidebar. + /// + public const float WIDTH = sidebar_width + PANEL_WIDTH; protected Container ContentContainer; @@ -71,7 +79,7 @@ namespace osu.Game.Overlays InternalChild = ContentContainer = new NonMaskedContent { X = -WIDTH + ExpandedPosition, - Width = WIDTH, + Width = PANEL_WIDTH, RelativeSizeAxes = Axes.Y, Children = new Drawable[] { From d099bb8ab631424f6a841d4f9947dc1ca3ba45bf Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 7 Aug 2021 19:33:22 +0300 Subject: [PATCH 15/53] Calculate offsets from overlay `ScreenSpaceDrawQuad`s instead --- .../Visual/Menus/TestSceneSideOverlays.cs | 21 ------------------- osu.Game/OsuGame.cs | 7 ++++--- 2 files changed, 4 insertions(+), 24 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs index 598998586d..21db7e2802 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs @@ -1,12 +1,9 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using System.Linq; using NUnit.Framework; -using osu.Framework.Graphics.Containers; using osu.Framework.Testing; using osu.Game.Overlays; -using osu.Game.Overlays.Settings.Sections.Input; using osu.Game.Tests.Visual.Navigation; namespace osu.Game.Tests.Visual.Menus @@ -32,24 +29,6 @@ namespace osu.Game.Tests.Visual.Menus AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); } - [Test] - public void TestScreenOffsettingAccountsForKeyBindingPanel() - { - AddStep("open settings", () => Game.Settings.Show()); - AddStep("open key binding panel", () => Game.Settings.ChildrenOfType().Single().Show()); - AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); - - AddStep("hide key binding", () => Game.Settings.ChildrenOfType().Single().Show()); - AddUntilStep("right screen offset still applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); - - AddStep("open key binding", () => Game.Settings.Show()); - AddUntilStep("right screen offset still applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); - - AddStep("hide settings", () => Game.Settings.Hide()); - AddAssert("key binding panel still open", () => Game.Settings.ChildrenOfType().Single().State.Value == Visibility.Visible); - AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); - } - [Test] public void TestScreenOffsettingOnNotificationOverlay() { diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6fb884f80a..1539d984ae 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1013,9 +1013,10 @@ namespace osu.Game ScreenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset }; overlayContent.Padding = new MarginPadding { Top = ToolbarOffset }; - var settingsOffset = Settings.HorizontalScreenOffset * SCREEN_OFFSET_RATIO; - var notificationsOffset = Notifications.HorizontalScreenOffset * SCREEN_OFFSET_RATIO; - ScreenOffsetContainer.X = settingsOffset + notificationsOffset; + ScreenOffsetContainer.X = 0f; + + if (Settings.IsLoaded) ScreenOffsetContainer.X += (ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X) * SCREEN_OFFSET_RATIO; + if (Notifications.IsLoaded) ScreenOffsetContainer.X += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; } From a1f50e39aa12d86456af684804c0894ec1ccf871 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 25 Jul 2021 16:50:52 +0200 Subject: [PATCH 16/53] Add basic structure for skinning catch explosions --- .../TestSceneCatcherArea.cs | 1 + .../CatchSkinComponents.cs | 3 +- .../Skinning/Default/DefaultHitExplosion.cs | 145 ++++++++++++++++++ osu.Game.Rulesets.Catch/UI/HitExplosion.cs | 121 ++------------- .../UI/HitExplosionContainer.cs | 3 + 5 files changed, 168 insertions(+), 105 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs index a3307c9224..6abfbdbe21 100644 --- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs +++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs @@ -40,6 +40,7 @@ namespace osu.Game.Rulesets.Catch.Tests { AddSliderStep("circle size", 0, 8, 5, createCatcher); AddToggleStep("hyper dash", t => this.ChildrenOfType().ForEach(area => area.ToggleHyperDash(t))); + AddToggleStep("toggle hit lighting", lighting => config.SetValue(OsuSetting.HitLighting, lighting)); AddStep("catch centered fruit", () => attemptCatch(new Fruit())); AddStep("catch many random fruit", () => diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs index e736d68740..371e901c69 100644 --- a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs +++ b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs @@ -9,6 +9,7 @@ namespace osu.Game.Rulesets.Catch Banana, Droplet, Catcher, - CatchComboCounter + CatchComboCounter, + HitExplosion } } diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs new file mode 100644 index 0000000000..41ba81d34c --- /dev/null +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs @@ -0,0 +1,145 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Effects; +using osu.Framework.Utils; +using osu.Game.Rulesets.Catch.UI; +using osu.Game.Utils; +using osuTK; +using osuTK.Graphics; + +namespace osu.Game.Rulesets.Catch.Skinning.Default +{ + public class DefaultHitExplosion : CompositeDrawable + { + [Resolved] + private Bindable entryBindable { get; set; } + + private CircularContainer largeFaint; + private CircularContainer smallFaint; + private CircularContainer directionalGlow1; + private CircularContainer directionalGlow2; + + [BackgroundDependencyLoader] + private void load() + { + Size = new Vector2(20); + Anchor = Anchor.BottomCentre; + Origin = Anchor.BottomCentre; + + // scale roughly in-line with visual appearance of notes + const float initial_height = 10; + + InternalChildren = new Drawable[] + { + largeFaint = new CircularContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + Blending = BlendingParameters.Additive, + }, + smallFaint = new CircularContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + Blending = BlendingParameters.Additive, + }, + directionalGlow1 = new CircularContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + Size = new Vector2(0.01f, initial_height), + Blending = BlendingParameters.Additive, + }, + directionalGlow2 = new CircularContainer + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + RelativeSizeAxes = Axes.Both, + Masking = true, + Size = new Vector2(0.01f, initial_height), + Blending = BlendingParameters.Additive, + } + }; + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + entryBindable.BindValueChanged(entry => apply(entry.NewValue), true); + } + + private void apply(HitExplosionEntry entry) + { + if (entry == null) + return; + + X = entry.Position; + Scale = new Vector2(entry.Scale); + setColour(entry.ObjectColour); + + using (BeginAbsoluteSequence(entry.LifetimeStart)) + applyTransforms(entry.RNGSeed); + } + + private void applyTransforms(int randomSeed) + { + ClearTransforms(true); + + const double duration = 400; + + // we want our size to be very small so the glow dominates it. + largeFaint.Size = new Vector2(0.8f); + largeFaint + .ResizeTo(largeFaint.Size * new Vector2(5, 1), duration, Easing.OutQuint) + .FadeOut(duration * 2); + + const float angle_variangle = 15; // should be less than 45 + directionalGlow1.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 4); + directionalGlow2.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 5); + + this.FadeInFromZero(50).Then().FadeOut(duration, Easing.Out).Expire(); + } + + private void setColour(Color4 objectColour) + { + const float roundness = 100; + + largeFaint.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = Interpolation.ValueAt(0.1f, objectColour, Color4.White, 0, 1).Opacity(0.3f), + Roundness = 160, + Radius = 200, + }; + + smallFaint.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = Interpolation.ValueAt(0.6f, objectColour, Color4.White, 0, 1), + Roundness = 20, + Radius = 50, + }; + + directionalGlow1.EdgeEffect = directionalGlow2.EdgeEffect = new EdgeEffectParameters + { + Type = EdgeEffectType.Glow, + Colour = Interpolation.ValueAt(0.4f, objectColour, Color4.White, 0, 1), + Roundness = roundness, + Radius = 40, + }; + } + } +} diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs index d9ab428231..7f3b1619ce 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs @@ -1,129 +1,42 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Extensions.Color4Extensions; +using osu.Framework.Allocation; +using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Effects; -using osu.Framework.Utils; +using osu.Game.Rulesets.Catch.Skinning.Default; using osu.Game.Rulesets.Objects.Pooling; -using osu.Game.Utils; -using osuTK; -using osuTK.Graphics; +using osu.Game.Skinning; namespace osu.Game.Rulesets.Catch.UI { public class HitExplosion : PoolableDrawableWithLifetime { - private readonly CircularContainer largeFaint; - private readonly CircularContainer smallFaint; - private readonly CircularContainer directionalGlow1; - private readonly CircularContainer directionalGlow2; + [Cached] + private Bindable bindableEntry { get; set; } = new Bindable(); public HitExplosion() { - Size = new Vector2(20); - Anchor = Anchor.TopCentre; + RelativeSizeAxes = Axes.Both; + Anchor = Anchor.BottomCentre; Origin = Anchor.BottomCentre; + } - // scale roughly in-line with visual appearance of notes - const float initial_height = 10; - - InternalChildren = new Drawable[] + [BackgroundDependencyLoader] + private void load() + { + InternalChild = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { - largeFaint = new CircularContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Masking = true, - Blending = BlendingParameters.Additive, - }, - smallFaint = new CircularContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Masking = true, - Blending = BlendingParameters.Additive, - }, - directionalGlow1 = new CircularContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Masking = true, - Size = new Vector2(0.01f, initial_height), - Blending = BlendingParameters.Additive, - }, - directionalGlow2 = new CircularContainer - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.Both, - Masking = true, - Size = new Vector2(0.01f, initial_height), - Blending = BlendingParameters.Additive, - } + Anchor = Anchor.BottomCentre, + Origin = Anchor.BottomCentre }; } protected override void OnApply(HitExplosionEntry entry) { - X = entry.Position; - Scale = new Vector2(entry.Scale); - setColour(entry.ObjectColour); + base.OnApply(entry); - using (BeginAbsoluteSequence(entry.LifetimeStart)) - applyTransforms(entry.RNGSeed); - } - - private void applyTransforms(int randomSeed) - { - ClearTransforms(true); - - const double duration = 400; - - // we want our size to be very small so the glow dominates it. - largeFaint.Size = new Vector2(0.8f); - largeFaint - .ResizeTo(largeFaint.Size * new Vector2(5, 1), duration, Easing.OutQuint) - .FadeOut(duration * 2); - - const float angle_variangle = 15; // should be less than 45 - directionalGlow1.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 4); - directionalGlow2.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 5); - - this.FadeInFromZero(50).Then().FadeOut(duration, Easing.Out).Expire(); - } - - private void setColour(Color4 objectColour) - { - const float roundness = 100; - - largeFaint.EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = Interpolation.ValueAt(0.1f, objectColour, Color4.White, 0, 1).Opacity(0.3f), - Roundness = 160, - Radius = 200, - }; - - smallFaint.EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = Interpolation.ValueAt(0.6f, objectColour, Color4.White, 0, 1), - Roundness = 20, - Radius = 50, - }; - - directionalGlow1.EdgeEffect = directionalGlow2.EdgeEffect = new EdgeEffectParameters - { - Type = EdgeEffectType.Glow, - Colour = Interpolation.ValueAt(0.4f, objectColour, Color4.White, 0, 1), - Roundness = roundness, - Radius = 40, - }; + bindableEntry.Value = entry; } } } diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs b/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs index 094d88243a..6df13e52ef 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosionContainer.cs @@ -1,6 +1,7 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using osu.Framework.Graphics; using osu.Framework.Graphics.Pooling; using osu.Game.Rulesets.Objects.Pooling; @@ -14,6 +15,8 @@ namespace osu.Game.Rulesets.Catch.UI public HitExplosionContainer() { + RelativeSizeAxes = Axes.Both; + AddInternal(pool = new DrawablePool(10)); } From 95a58ca3666dfe785034741caa6d4f5ac39b9170 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 25 Jul 2021 17:19:51 +0200 Subject: [PATCH 17/53] Store judgement directly in hit explosion entry --- .../Skinning/Default/DefaultHitExplosion.cs | 4 +-- osu.Game.Rulesets.Catch/UI/Catcher.cs | 6 ++-- .../UI/HitExplosionEntry.cs | 30 ++++++++++++++----- 3 files changed, 28 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs index 41ba81d34c..f4b952c559 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs @@ -87,11 +87,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default return; X = entry.Position; - Scale = new Vector2(entry.Scale); + Scale = new Vector2(entry.HitObject.Scale); setColour(entry.ObjectColour); using (BeginAbsoluteSequence(entry.LifetimeStart)) - applyTransforms(entry.RNGSeed); + applyTransforms(entry.HitObject.RandomSeed); } private void applyTransforms(int randomSeed) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index 9fd4610e6e..a1aa58f163 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -216,7 +216,7 @@ namespace osu.Game.Rulesets.Catch.UI placeCaughtObject(palpableObject, positionInStack); if (hitLighting.Value) - addLighting(hitObject, positionInStack.X, drawableObject.AccentColour.Value); + addLighting(result, drawableObject.AccentColour.Value, positionInStack.X); } // droplet doesn't affect the catcher state @@ -365,8 +365,8 @@ namespace osu.Game.Rulesets.Catch.UI return position; } - private void addLighting(CatchHitObject hitObject, float x, Color4 colour) => - hitExplosionContainer.Add(new HitExplosionEntry(Time.Current, x, hitObject.Scale, colour, hitObject.RandomSeed)); + private void addLighting(JudgementResult judgementResult, Color4 colour, float x) => + hitExplosionContainer.Add(new HitExplosionEntry(judgementResult, colour, x, Time.Current)); private CaughtObject getCaughtObject(PalpableCatchHitObject source) { diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs b/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs index b142962a8a..749a448314 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs @@ -2,24 +2,40 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Graphics.Performance; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Judgements; using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.UI { public class HitExplosionEntry : LifetimeEntry { - public readonly float Position; - public readonly float Scale; - public readonly Color4 ObjectColour; - public readonly int RNGSeed; + /// + /// The judgement result that triggered this explosion. + /// + public JudgementResult JudgementResult { get; } - public HitExplosionEntry(double startTime, float position, float scale, Color4 objectColour, int rngSeed) + /// + /// The hitobject which triggered this explosion. + /// + public CatchHitObject HitObject => (CatchHitObject)JudgementResult.HitObject; + + /// + /// The accent colour of the object caught. + /// + public Color4 ObjectColour { get; } + + /// + /// The position at which the object was caught. + /// + public float Position { get; } + + public HitExplosionEntry(JudgementResult judgementResult, Color4 objectColour, float position, double startTime) { LifetimeStart = startTime; Position = position; - Scale = scale; + JudgementResult = judgementResult; ObjectColour = objectColour; - RNGSeed = rngSeed; } } } From 8c8a64fe6eafc5452c2f63c3b0c464bc025389bc Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sun, 25 Jul 2021 19:00:37 +0200 Subject: [PATCH 18/53] Add legacy hit lighting implementation --- .../Legacy/CatchLegacySkinTransformer.cs | 20 +++- .../Skinning/Legacy/LegacyHitExplosion.cs | 103 ++++++++++++++++++ osu.Game.Rulesets.Catch/UI/Catcher.cs | 7 +- osu.Game.Rulesets.Catch/UI/HitExplosion.cs | 1 + 4 files changed, 124 insertions(+), 7 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs index 5e744ec001..10fc4e78b2 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs @@ -70,13 +70,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy if (version < 2.3m) { - if (GetTexture(@"fruit-ryuuta") != null || - GetTexture(@"fruit-ryuuta-0") != null) + if (hasOldStyleCatcherSprite()) return new LegacyCatcherOld(); } - if (GetTexture(@"fruit-catcher-idle") != null || - GetTexture(@"fruit-catcher-idle-0") != null) + if (hasNewStyleCatcherSprite()) return new LegacyCatcherNew(); return null; @@ -86,12 +84,26 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy return new LegacyCatchComboCounter(Skin); return null; + + case CatchSkinComponents.HitExplosion: + if (hasOldStyleCatcherSprite() || hasNewStyleCatcherSprite()) + return new LegacyHitExplosion(); + + return null; } } return base.GetDrawableComponent(component); } + private bool hasOldStyleCatcherSprite() => + GetTexture(@"fruit-ryuuta") != null + || GetTexture(@"fruit-ryuuta-0") != null; + + private bool hasNewStyleCatcherSprite() => + GetTexture(@"fruit-catcher-idle") != null + || GetTexture(@"fruit-catcher-idle-0") != null; + public override IBindable GetConfig(TLookup lookup) { switch (lookup) diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs new file mode 100644 index 0000000000..339055c91d --- /dev/null +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs @@ -0,0 +1,103 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +using System; +using osu.Framework.Allocation; +using osu.Framework.Bindables; +using osu.Framework.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Sprites; +using osu.Game.Rulesets.Catch.Objects; +using osu.Game.Rulesets.Catch.UI; +using osu.Game.Skinning; +using osuTK; + +namespace osu.Game.Rulesets.Catch.Skinning.Legacy +{ + public class LegacyHitExplosion : CompositeDrawable + { + [Resolved] + private Catcher catcher { get; set; } + + [Resolved] + private Bindable entryBindable { get; set; } + + private const float catch_margin = (1 - Catcher.ALLOWED_CATCH_RANGE) / 2; + + private readonly Sprite explosion1; + private readonly Sprite explosion2; + + public LegacyHitExplosion() + { + Anchor = Anchor.BottomCentre; + Origin = Anchor.BottomCentre; + RelativeSizeAxes = Axes.Both; + Scale = new Vector2(0.4f); + + InternalChildren = new[] + { + explosion1 = new Sprite + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.CentreLeft, + Blending = BlendingParameters.Additive, + Rotation = -90 + }, + explosion2 = new Sprite + { + Anchor = Anchor.BottomCentre, + Origin = Anchor.CentreLeft, + Blending = BlendingParameters.Additive, + Rotation = -90 + } + }; + } + + [BackgroundDependencyLoader] + private void load(SkinManager skins) + { + var defaultLegacySkin = skins.DefaultLegacySkin; + + explosion1.Texture = defaultLegacySkin.GetTexture("scoreboard-explosion-2"); + explosion2.Texture = defaultLegacySkin.GetTexture("scoreboard-explosion-1"); + } + + protected override void LoadComplete() + { + base.LoadComplete(); + + entryBindable.BindValueChanged(entry => apply(entry.NewValue), true); + } + + private void apply(HitExplosionEntry entry) + { + if (entry == null) + return; + + Colour = entry.ObjectColour; + + using (BeginAbsoluteSequence(entry.LifetimeStart)) + { + float halfCatchWidth = catcher.CatchWidth / 2; + float explosionOffset = Math.Clamp(entry.Position, -halfCatchWidth + catch_margin * 3, halfCatchWidth - catch_margin * 3); + + if (!(entry.HitObject is Droplet)) + { + float scale = Math.Clamp(entry.JudgementResult.ComboAtJudgement / 200f, 0.35f, 1.125f); + + explosion1.Scale = new Vector2(1, 0.9f); + explosion1.Position = new Vector2(explosionOffset, 0); + + explosion1.FadeOut(300); + explosion1.ScaleTo(new Vector2(20 * scale, 1.1f), 160, Easing.Out); + } + + explosion2.Scale = new Vector2(0.9f, 1); + explosion2.Position = new Vector2(explosionOffset, 0); + + explosion2.FadeOut(700); + explosion2.ScaleTo(new Vector2(0.9f, 1.3f), 500, Easing.Out); + } + } + } +} diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index a1aa58f163..aec8e752a7 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -23,6 +23,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.UI { + [Cached] public class Catcher : SkinReloadableDrawable { /// @@ -106,7 +107,7 @@ namespace osu.Game.Rulesets.Catch.UI /// /// Width of the area that can be used to attempt catches during gameplay. /// - private readonly float catchWidth; + public readonly float CatchWidth; private readonly SkinnableCatcher body; @@ -133,7 +134,7 @@ namespace osu.Game.Rulesets.Catch.UI if (difficulty != null) Scale = calculateScale(difficulty); - catchWidth = CalculateCatchWidth(Scale); + CatchWidth = CalculateCatchWidth(Scale); InternalChildren = new Drawable[] { @@ -193,7 +194,7 @@ namespace osu.Game.Rulesets.Catch.UI if (!(hitObject is PalpableCatchHitObject fruit)) return false; - float halfCatchWidth = catchWidth * 0.5f; + float halfCatchWidth = CatchWidth * 0.5f; return fruit.EffectiveX >= X - halfCatchWidth && fruit.EffectiveX <= X + halfCatchWidth; } diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs index 7f3b1619ce..671b14640d 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs @@ -27,6 +27,7 @@ namespace osu.Game.Rulesets.Catch.UI { InternalChild = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { + CentreComponent = false, Anchor = Anchor.BottomCentre, Origin = Anchor.BottomCentre }; From 4bcbe6ac90def30bda7da29052b748bc5a2b1359 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Sat, 7 Aug 2021 18:19:29 +0200 Subject: [PATCH 19/53] Restructure explosion to ensure proper lifetime bounds --- .../Skinning/Default/DefaultHitExplosion.cs | 17 +++------------ .../Skinning/Legacy/LegacyHitExplosion.cs | 21 ++++++------------- osu.Game.Rulesets.Catch/UI/HitExplosion.cs | 12 ++++++----- osu.Game.Rulesets.Catch/UI/IHitExplosion.cs | 16 ++++++++++++++ 4 files changed, 32 insertions(+), 34 deletions(-) create mode 100644 osu.Game.Rulesets.Catch/UI/IHitExplosion.cs diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs index f4b952c559..2660e0730d 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; @@ -15,11 +14,8 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Default { - public class DefaultHitExplosion : CompositeDrawable + public class DefaultHitExplosion : CompositeDrawable, IHitExplosion { - [Resolved] - private Bindable entryBindable { get; set; } - private CircularContainer largeFaint; private CircularContainer smallFaint; private CircularContainer directionalGlow1; @@ -74,14 +70,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default }; } - protected override void LoadComplete() - { - base.LoadComplete(); - - entryBindable.BindValueChanged(entry => apply(entry.NewValue), true); - } - - private void apply(HitExplosionEntry entry) + public void Animate(HitExplosionEntry entry) { if (entry == null) return; @@ -110,7 +99,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default directionalGlow1.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 4); directionalGlow2.Rotation = StatelessRNG.NextSingle(-angle_variangle, angle_variangle, randomSeed, 5); - this.FadeInFromZero(50).Then().FadeOut(duration, Easing.Out).Expire(); + this.FadeInFromZero(50).Then().FadeOut(duration, Easing.Out); } private void setColour(Color4 objectColour) diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs index 339055c91d..6708989b89 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs @@ -3,7 +3,6 @@ using System; using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Framework.Graphics.Sprites; @@ -14,14 +13,11 @@ using osuTK; namespace osu.Game.Rulesets.Catch.Skinning.Legacy { - public class LegacyHitExplosion : CompositeDrawable + public class LegacyHitExplosion : CompositeDrawable, IHitExplosion { [Resolved] private Catcher catcher { get; set; } - [Resolved] - private Bindable entryBindable { get; set; } - private const float catch_margin = (1 - Catcher.ALLOWED_CATCH_RANGE) / 2; private readonly Sprite explosion1; @@ -62,14 +58,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy explosion2.Texture = defaultLegacySkin.GetTexture("scoreboard-explosion-1"); } - protected override void LoadComplete() - { - base.LoadComplete(); - - entryBindable.BindValueChanged(entry => apply(entry.NewValue), true); - } - - private void apply(HitExplosionEntry entry) + public void Animate(HitExplosionEntry entry) { if (entry == null) return; @@ -88,15 +77,17 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy explosion1.Scale = new Vector2(1, 0.9f); explosion1.Position = new Vector2(explosionOffset, 0); - explosion1.FadeOut(300); + explosion1.FadeOutFromOne(300); explosion1.ScaleTo(new Vector2(20 * scale, 1.1f), 160, Easing.Out); } explosion2.Scale = new Vector2(0.9f, 1); explosion2.Position = new Vector2(explosionOffset, 0); - explosion2.FadeOut(700); + explosion2.FadeOutFromOne(700); explosion2.ScaleTo(new Vector2(0.9f, 1.3f), 500, Easing.Out); + + this.Delay(700).FadeOutFromOne(); } } } diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs index 671b14640d..0a5341cb67 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs @@ -2,7 +2,6 @@ // See the LICENCE file in the repository root for full licence text. using osu.Framework.Allocation; -using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Skinning.Default; using osu.Game.Rulesets.Objects.Pooling; @@ -12,8 +11,7 @@ namespace osu.Game.Rulesets.Catch.UI { public class HitExplosion : PoolableDrawableWithLifetime { - [Cached] - private Bindable bindableEntry { get; set; } = new Bindable(); + private SkinnableDrawable skinnableExplosion; public HitExplosion() { @@ -25,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.UI [BackgroundDependencyLoader] private void load() { - InternalChild = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) + InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { CentreComponent = false, Anchor = Anchor.BottomCentre, @@ -37,7 +35,11 @@ namespace osu.Game.Rulesets.Catch.UI { base.OnApply(entry); - bindableEntry.Value = entry; + ApplyTransformsAt(double.MinValue, true); + ClearTransforms(true); + + (skinnableExplosion.Drawable as IHitExplosion)?.Animate(entry); + LifetimeEnd = skinnableExplosion.Drawable.LatestTransformEndTime; } } } diff --git a/osu.Game.Rulesets.Catch/UI/IHitExplosion.cs b/osu.Game.Rulesets.Catch/UI/IHitExplosion.cs new file mode 100644 index 0000000000..4a9d7e8ac0 --- /dev/null +++ b/osu.Game.Rulesets.Catch/UI/IHitExplosion.cs @@ -0,0 +1,16 @@ +// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. +// See the LICENCE file in the repository root for full licence text. + +namespace osu.Game.Rulesets.Catch.UI +{ + /// + /// Common interface for all hit explosion skinnables. + /// + public interface IHitExplosion + { + /// + /// Begins animating this . + /// + void Animate(HitExplosionEntry entry); + } +} From 2fb19210af31d7aba85348c4b8bc3f023f0e61da Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 11 Aug 2021 22:36:27 +0200 Subject: [PATCH 20/53] Fix legacy explosion sprites incorrectly showing after skin change --- osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs index 6708989b89..78b0e1e327 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs @@ -36,6 +36,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { Anchor = Anchor.BottomCentre, Origin = Anchor.CentreLeft, + Alpha = 0, Blending = BlendingParameters.Additive, Rotation = -90 }, @@ -43,6 +44,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { Anchor = Anchor.BottomCentre, Origin = Anchor.CentreLeft, + Alpha = 0, Blending = BlendingParameters.Additive, Rotation = -90 } From 427a88940c56988484a17c0e0020613243be9083 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 11 Aug 2021 23:18:42 +0200 Subject: [PATCH 21/53] Remove duplicated `ClearTransforms()` call --- osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs index 2660e0730d..680fbc7b15 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs @@ -85,8 +85,6 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default private void applyTransforms(int randomSeed) { - ClearTransforms(true); - const double duration = 400; // we want our size to be very small so the glow dominates it. From 98ce69d1d32b65abd9983dbd1124cad8f6bc938b Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Wed, 11 Aug 2021 23:32:58 +0200 Subject: [PATCH 22/53] Fix explosion reading out time values from wrong clock --- osu.Game.Rulesets.Catch/UI/HitExplosion.cs | 11 +++++++++++ 1 file changed, 11 insertions(+) diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs index 0a5341cb67..35af39348d 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs @@ -34,7 +34,18 @@ namespace osu.Game.Rulesets.Catch.UI protected override void OnApply(HitExplosionEntry entry) { base.OnApply(entry); + if (IsLoaded) + apply(entry); + } + protected override void LoadComplete() + { + base.LoadComplete(); + apply(Entry); + } + + private void apply(HitExplosionEntry entry) + { ApplyTransformsAt(double.MinValue, true); ClearTransforms(true); From 14fe2eea2a907f5cf2130aed4204e350500909e2 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 6 Aug 2021 19:40:29 +0900 Subject: [PATCH 23/53] Add empty step to multiplayer TestEmpty() test --- osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index 0ffa5209e3..7ff0368fc2 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -87,6 +87,7 @@ namespace osu.Game.Tests.Visual.Multiplayer public void TestEmpty() { // used to test the flow of multiplayer from visual tests. + AddStep("empty step", () => { }); } [Test] From d07bb10d0294fd4986442cb415b603248d022ed4 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Aug 2021 16:52:30 +0900 Subject: [PATCH 24/53] Remove breadcrumbs from header --- osu.Game/Screens/OnlinePlay/Header.cs | 88 +++++---------------------- 1 file changed, 16 insertions(+), 72 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Header.cs b/osu.Game/Screens/OnlinePlay/Header.cs index bf0a53cbb6..c025099ebe 100644 --- a/osu.Game/Screens/OnlinePlay/Header.cs +++ b/osu.Game/Screens/OnlinePlay/Header.cs @@ -2,19 +2,15 @@ // See the LICENCE file in the repository root for full licence text. using Humanizer; +using JetBrains.Annotations; 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.Graphics.UserInterface; using osu.Framework.Screens; using osu.Game.Graphics; using osu.Game.Graphics.Sprites; -using osu.Game.Graphics.UserInterface; using osu.Game.Overlays; using osuTK; -using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay { @@ -22,52 +18,29 @@ namespace osu.Game.Screens.OnlinePlay { public const float HEIGHT = 80; + private readonly ScreenStack stack; + private readonly MultiHeaderTitle title; + public Header(string mainTitle, ScreenStack stack) { + this.stack = stack; + RelativeSizeAxes = Axes.X; Height = HEIGHT; + Padding = new MarginPadding { Left = WaveOverlayContainer.WIDTH_PADDING }; - HeaderBreadcrumbControl breadcrumbs; - MultiHeaderTitle title; - - Children = new Drawable[] + Child = title = new MultiHeaderTitle(mainTitle) { - new Box - { - RelativeSizeAxes = Axes.Both, - Colour = Color4Extensions.FromHex(@"#1f1921"), - }, - new Container - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.CentreLeft, - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Left = WaveOverlayContainer.WIDTH_PADDING + OsuScreen.HORIZONTAL_OVERFLOW_PADDING }, - Children = new Drawable[] - { - title = new MultiHeaderTitle(mainTitle) - { - Anchor = Anchor.CentreLeft, - Origin = Anchor.BottomLeft, - }, - breadcrumbs = new HeaderBreadcrumbControl(stack) - { - Anchor = Anchor.BottomLeft, - Origin = Anchor.BottomLeft - } - }, - }, + Anchor = Anchor.CentreLeft, + Origin = Anchor.BottomLeft, }; - breadcrumbs.Current.ValueChanged += screen => - { - if (screen.NewValue is IOnlinePlaySubScreen onlineSubScreen) - title.Screen = onlineSubScreen; - }; - - breadcrumbs.Current.TriggerChange(); + stack.ScreenPushed += (_, __) => updateSubScreenTitle(); + stack.ScreenExited += (_, __) => updateSubScreenTitle(); } + private void updateSubScreenTitle() => title.Screen = stack.CurrentScreen as IOnlinePlaySubScreen; + private class MultiHeaderTitle : CompositeDrawable { private const float spacing = 6; @@ -75,9 +48,10 @@ namespace osu.Game.Screens.OnlinePlay private readonly OsuSpriteText dot; private readonly OsuSpriteText pageTitle; + [CanBeNull] public IOnlinePlaySubScreen Screen { - set => pageTitle.Text = value.ShortTitle.Titleize(); + set => pageTitle.Text = value?.ShortTitle.Titleize() ?? string.Empty; } public MultiHeaderTitle(string mainTitle) @@ -125,35 +99,5 @@ namespace osu.Game.Screens.OnlinePlay pageTitle.Colour = dot.Colour = colours.Yellow; } } - - private class HeaderBreadcrumbControl : ScreenBreadcrumbControl - { - public HeaderBreadcrumbControl(ScreenStack stack) - : base(stack) - { - RelativeSizeAxes = Axes.X; - StripColour = Color4.Transparent; - } - - protected override void LoadComplete() - { - base.LoadComplete(); - AccentColour = Color4Extensions.FromHex("#e35c99"); - } - - protected override TabItem CreateTabItem(IScreen value) => new HeaderBreadcrumbTabItem(value) - { - AccentColour = AccentColour - }; - - private class HeaderBreadcrumbTabItem : BreadcrumbTabItem - { - public HeaderBreadcrumbTabItem(IScreen value) - : base(value) - { - Bar.Colour = Color4.Transparent; - } - } - } } } From 3b7aa262d5b559f72511af9c8dfb6230f3c9ba1e Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Aug 2021 16:52:35 +0900 Subject: [PATCH 25/53] Make header overlap content --- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index fee612c0a5..6238000e85 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -101,7 +101,6 @@ namespace osu.Game.Screens.OnlinePlay new Container { RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Top = Header.HEIGHT }, Children = new[] { header = new Container From b75c20fee421138d8b10b538fe55baf6d59c5d78 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Aug 2021 18:02:00 +0900 Subject: [PATCH 26/53] Adjust positioning and paddings --- osu.Game/Screens/OnlinePlay/Header.cs | 2 +- osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 2 ++ osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs | 2 ++ osu.Game/Screens/Select/SongSelect.cs | 9 +++++---- 4 files changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Header.cs b/osu.Game/Screens/OnlinePlay/Header.cs index c025099ebe..58c67a51e8 100644 --- a/osu.Game/Screens/OnlinePlay/Header.cs +++ b/osu.Game/Screens/OnlinePlay/Header.cs @@ -32,7 +32,7 @@ namespace osu.Game.Screens.OnlinePlay Child = title = new MultiHeaderTitle(mainTitle) { Anchor = Anchor.CentreLeft, - Origin = Anchor.BottomLeft, + Origin = Anchor.CentreLeft, }; stack.ScreenPushed += (_, __) => updateSubScreenTitle(); diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index a53e253581..b29a1ab1b6 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -61,6 +61,8 @@ namespace osu.Game.Screens.OnlinePlay.Match protected RoomSubScreen() { + Padding = new MarginPadding { Top = Header.HEIGHT }; + AddRangeInternal(new Drawable[] { BeatmapAvailabilityTracker = new OnlinePlayBeatmapAvailabilityTracker diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs index be28de5c43..1502463022 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlaySongSelect.cs @@ -59,6 +59,8 @@ namespace osu.Game.Screens.OnlinePlay [BackgroundDependencyLoader] private void load() { + LeftArea.Padding = new MarginPadding { Top = Header.HEIGHT }; + initialBeatmap = Beatmap.Value; initialRuleset = Ruleset.Value; initialMods = Mods.Value.ToList(); diff --git a/osu.Game/Screens/Select/SongSelect.cs b/osu.Game/Screens/Select/SongSelect.cs index 270addc8e6..0e113a71bc 100644 --- a/osu.Game/Screens/Select/SongSelect.cs +++ b/osu.Game/Screens/Select/SongSelect.cs @@ -79,6 +79,8 @@ namespace osu.Game.Screens.Select protected BeatmapCarousel Carousel { get; private set; } + protected Container LeftArea { get; private set; } + private BeatmapInfoWedge beatmapInfoWedge; private DialogOverlay dialogOverlay; @@ -186,12 +188,12 @@ namespace osu.Game.Screens.Select { new Drawable[] { - new Container + LeftArea = new Container { Origin = Anchor.BottomLeft, Anchor = Anchor.BottomLeft, RelativeSizeAxes = Axes.Both, - + Padding = new MarginPadding { Top = left_area_padding }, Children = new Drawable[] { beatmapInfoWedge = new BeatmapInfoWedge @@ -200,7 +202,6 @@ namespace osu.Game.Screens.Select RelativeSizeAxes = Axes.X, Margin = new MarginPadding { - Top = left_area_padding, Right = left_area_padding, }, }, @@ -210,7 +211,7 @@ namespace osu.Game.Screens.Select Padding = new MarginPadding { Bottom = Footer.HEIGHT, - Top = WEDGE_HEIGHT + left_area_padding, + Top = WEDGE_HEIGHT, Left = left_area_padding, Right = left_area_padding * 2, }, From b58b5ec2b47af2376b9ff355c5591629af397d55 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Aug 2021 12:14:39 +0300 Subject: [PATCH 27/53] Apply horizontal offset changing once per frame The previous way was causing every-frame invalidation when an overlay is visible. --- osu.Game/OsuGame.cs | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 1539d984ae..b6809c0290 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1013,10 +1013,14 @@ namespace osu.Game ScreenOffsetContainer.Padding = new MarginPadding { Top = ToolbarOffset }; overlayContent.Padding = new MarginPadding { Top = ToolbarOffset }; - ScreenOffsetContainer.X = 0f; + var horizontalOffset = 0f; - if (Settings.IsLoaded) ScreenOffsetContainer.X += (ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X) * SCREEN_OFFSET_RATIO; - if (Notifications.IsLoaded) ScreenOffsetContainer.X += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; + if (Settings.IsLoaded) + horizontalOffset += (ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X) * SCREEN_OFFSET_RATIO; + if (Notifications.IsLoaded) + horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; + + ScreenOffsetContainer.X = horizontalOffset; MenuCursorContainer.CanShowCursor = (ScreenStack.CurrentScreen as IOsuScreen)?.CursorVisible ?? false; } From ab7bd1df9dade8869369175d53055efcbf40a42d Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Aug 2021 19:27:06 +0900 Subject: [PATCH 28/53] Use full-screen background --- .../Screens/OnlinePlay/OnlinePlayScreen.cs | 62 ++++--------------- 1 file changed, 13 insertions(+), 49 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index 6238000e85..21e4f047f0 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -21,8 +21,8 @@ using osu.Game.Screens.Menu; using osu.Game.Screens.OnlinePlay.Components; using osu.Game.Screens.OnlinePlay.Lounge; using osu.Game.Screens.OnlinePlay.Lounge.Components; -using osu.Game.Screens.OnlinePlay.Match; using osu.Game.Users; +using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay { @@ -68,9 +68,6 @@ namespace osu.Game.Screens.OnlinePlay [Resolved(CanBeNull = true)] private OsuLogo logo { get; set; } - private Drawable header; - private Drawable headerBackground; - protected OnlinePlayScreen() { Anchor = Anchor.Centre; @@ -101,41 +98,21 @@ namespace osu.Game.Screens.OnlinePlay new Container { RelativeSizeAxes = Axes.Both, - Children = new[] + Children = new Drawable[] { - header = new Container + new HeaderBackgroundSprite { - RelativeSizeAxes = Axes.X, - Height = 400, - Children = new[] - { - headerBackground = new Container - { - RelativeSizeAxes = Axes.Both, - Width = 1.25f, - Masking = true, - Children = new Drawable[] - { - new HeaderBackgroundSprite - { - RelativeSizeAxes = Axes.X, - Height = 400 // Keep a static height so the header doesn't change as it's resized between subscreens - }, - } - }, - new Container - { - RelativeSizeAxes = Axes.Both, - Padding = new MarginPadding { Bottom = -1 }, // 1px padding to avoid a 1px gap due to masking - Child = new Box - { - RelativeSizeAxes = Axes.Both, - Colour = ColourInfo.GradientVertical(backgroundColour.Opacity(0.5f), backgroundColour) - }, - } - } + RelativeSizeAxes = Axes.Both }, - screenStack = new OnlinePlaySubScreenStack { RelativeSizeAxes = Axes.Both } + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = ColourInfo.GradientVertical(Color4.Black.Opacity(0.9f), Color4.Black.Opacity(0.6f)) + }, + screenStack = new OnlinePlaySubScreenStack + { + RelativeSizeAxes = Axes.Both + } } }, new Header(ScreenTitle, screenStack), @@ -288,19 +265,6 @@ namespace osu.Game.Screens.OnlinePlay private void subScreenChanged(IScreen lastScreen, IScreen newScreen) { - switch (newScreen) - { - case LoungeSubScreen _: - header.Delay(OnlinePlaySubScreen.RESUME_TRANSITION_DELAY).ResizeHeightTo(400, OnlinePlaySubScreen.APPEAR_DURATION, Easing.OutQuint); - headerBackground.MoveToX(0, OnlinePlaySubScreen.X_MOVE_DURATION, Easing.OutQuint); - break; - - case RoomSubScreen _: - header.ResizeHeightTo(135, OnlinePlaySubScreen.APPEAR_DURATION, Easing.OutQuint); - headerBackground.MoveToX(-OnlinePlaySubScreen.X_SHIFT, OnlinePlaySubScreen.X_MOVE_DURATION, Easing.OutQuint); - break; - } - if (lastScreen is IOsuScreen lastOsuScreen) Activity.UnbindFrom(lastOsuScreen.Activity); From 047b37788bb8087c248986de83a4b4732d362020 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Aug 2021 19:48:15 +0900 Subject: [PATCH 29/53] Merge online play filter control with the lounge subscreen --- .../TestScenePlaylistsFilterControl.cs | 23 ---- .../Lounge/Components/FilterControl.cs | 125 ----------------- .../Components/PlaylistsFilterControl.cs | 57 -------- .../OnlinePlay/Lounge/LoungeSubScreen.cs | 129 ++++++++++++++---- .../Multiplayer/MultiplayerFilterControl.cs | 17 --- .../Multiplayer/MultiplayerLoungeSubScreen.cs | 7 +- .../Playlists/PlaylistsLoungeSubScreen.cs | 44 +++++- 7 files changed, 154 insertions(+), 248 deletions(-) delete mode 100644 osu.Game.Tests/Visual/Playlists/TestScenePlaylistsFilterControl.cs delete mode 100644 osu.Game/Screens/OnlinePlay/Lounge/Components/FilterControl.cs delete mode 100644 osu.Game/Screens/OnlinePlay/Lounge/Components/PlaylistsFilterControl.cs delete mode 100644 osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerFilterControl.cs diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsFilterControl.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsFilterControl.cs deleted file mode 100644 index 40e191dd7e..0000000000 --- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsFilterControl.cs +++ /dev/null @@ -1,23 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; -using osu.Game.Screens.OnlinePlay.Lounge.Components; - -namespace osu.Game.Tests.Visual.Playlists -{ - public class TestScenePlaylistsFilterControl : OsuTestScene - { - public TestScenePlaylistsFilterControl() - { - Child = new PlaylistsFilterControl - { - Anchor = Anchor.Centre, - Origin = Anchor.Centre, - RelativeSizeAxes = Axes.X, - Width = 0.7f, - Height = 80, - }; - } - } -} diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/FilterControl.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/FilterControl.cs deleted file mode 100644 index e2f02fca68..0000000000 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/FilterControl.cs +++ /dev/null @@ -1,125 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Allocation; -using osu.Framework.Bindables; -using osu.Framework.Graphics; -using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.UserInterface; -using osu.Framework.Threading; -using osu.Game.Graphics; -using osu.Game.Graphics.UserInterface; -using osu.Game.Rulesets; -using osuTK; - -namespace osu.Game.Screens.OnlinePlay.Lounge.Components -{ - public abstract class FilterControl : CompositeDrawable - { - protected readonly FillFlowContainer Filters; - - [Resolved(CanBeNull = true)] - private Bindable filter { get; set; } - - [Resolved] - private IBindable ruleset { get; set; } - - private readonly SearchTextBox search; - private readonly Dropdown statusDropdown; - - protected FilterControl() - { - RelativeSizeAxes = Axes.X; - Height = 70; - - InternalChild = new FillFlowContainer - { - RelativeSizeAxes = Axes.Both, - Direction = FillDirection.Vertical, - Spacing = new Vector2(10), - Children = new Drawable[] - { - search = new FilterSearchTextBox - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.X, - Width = 0.6f, - }, - Filters = new FillFlowContainer - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - AutoSizeAxes = Axes.Both, - Direction = FillDirection.Horizontal, - Spacing = new Vector2(10), - Child = statusDropdown = new SlimEnumDropdown - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.None, - Width = 160, - } - }, - } - }; - } - - [BackgroundDependencyLoader] - private void load(OsuColour colours) - { - filter ??= new Bindable(); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - search.Current.BindValueChanged(_ => updateFilterDebounced()); - ruleset.BindValueChanged(_ => UpdateFilter()); - statusDropdown.Current.BindValueChanged(_ => UpdateFilter(), true); - } - - private ScheduledDelegate scheduledFilterUpdate; - - private void updateFilterDebounced() - { - scheduledFilterUpdate?.Cancel(); - scheduledFilterUpdate = Scheduler.AddDelayed(UpdateFilter, 200); - } - - protected void UpdateFilter() => Scheduler.AddOnce(updateFilter); - - private void updateFilter() - { - scheduledFilterUpdate?.Cancel(); - - var criteria = CreateCriteria(); - criteria.SearchString = search.Current.Value; - criteria.Status = statusDropdown.Current.Value; - criteria.Ruleset = ruleset.Value; - - filter.Value = criteria; - } - - protected virtual FilterCriteria CreateCriteria() => new FilterCriteria(); - - public bool HoldFocus - { - get => search.HoldFocus; - set => search.HoldFocus = value; - } - - public void TakeFocus() => search.TakeFocus(); - - private class FilterSearchTextBox : SearchTextBox - { - [BackgroundDependencyLoader] - private void load() - { - BackgroundUnfocused = OsuColour.Gray(0.06f); - BackgroundFocused = OsuColour.Gray(0.12f); - } - } - } -} diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/PlaylistsFilterControl.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/PlaylistsFilterControl.cs deleted file mode 100644 index bbf34d3893..0000000000 --- a/osu.Game/Screens/OnlinePlay/Lounge/Components/PlaylistsFilterControl.cs +++ /dev/null @@ -1,57 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Framework.Graphics; -using osu.Framework.Graphics.UserInterface; -using osu.Game.Graphics.UserInterface; - -namespace osu.Game.Screens.OnlinePlay.Lounge.Components -{ - public class PlaylistsFilterControl : FilterControl - { - private readonly Dropdown categoryDropdown; - - public PlaylistsFilterControl() - { - Filters.Add(categoryDropdown = new SlimEnumDropdown - { - Anchor = Anchor.TopRight, - Origin = Anchor.TopRight, - RelativeSizeAxes = Axes.None, - Width = 160, - }); - } - - protected override void LoadComplete() - { - base.LoadComplete(); - - categoryDropdown.Current.BindValueChanged(_ => UpdateFilter()); - } - - protected override FilterCriteria CreateCriteria() - { - var criteria = base.CreateCriteria(); - - switch (categoryDropdown.Current.Value) - { - case PlaylistsCategory.Normal: - criteria.Category = "normal"; - break; - - case PlaylistsCategory.Spotlight: - criteria.Category = "spotlight"; - break; - } - - return criteria; - } - - private enum PlaylistsCategory - { - Any, - Normal, - Spotlight - } - } -} diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 122b30b1d2..1c28405e40 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -2,6 +2,7 @@ // See the LICENCE file in the repository root for full licence text. using System; +using System.Collections.Generic; using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; @@ -9,24 +10,28 @@ using osu.Framework.Bindables; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.Shapes; +using osu.Framework.Graphics.UserInterface; using osu.Framework.Input.Events; using osu.Framework.Screens; +using osu.Framework.Threading; +using osu.Game.Graphics; using osu.Game.Graphics.Containers; using osu.Game.Graphics.UserInterface; using osu.Game.Online.Rooms; using osu.Game.Overlays; +using osu.Game.Rulesets; using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Screens.OnlinePlay.Match; using osu.Game.Users; using osuTK; -using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay.Lounge { [Cached] public abstract class LoungeSubScreen : OnlinePlaySubScreen { + private const float button_height = 25; + public override string Title => "Lounge"; protected override UserActivity InitialActivity => new UserActivity.SearchingForLobby(); @@ -41,7 +46,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge private readonly IBindable initialRoomsReceived = new Bindable(); private readonly IBindable operationInProgress = new Bindable(); - private FilterControl filter; private LoadingLayer loadingLayer; [Resolved] @@ -53,31 +57,33 @@ namespace osu.Game.Screens.OnlinePlay.Lounge [Resolved(CanBeNull = true)] private OngoingOperationTracker ongoingOperationTracker { get; set; } + [Resolved(CanBeNull = true)] + private Bindable filter { get; set; } + + [Resolved] + private IBindable ruleset { get; set; } + [CanBeNull] private IDisposable joiningRoomOperation { get; set; } private RoomsContainer roomsContainer; + private SearchTextBox searchTextBox; + private Dropdown statusDropdown; [BackgroundDependencyLoader] private void load() { + filter ??= new Bindable(new FilterCriteria()); + OsuScrollContainer scrollContainer; InternalChildren = new Drawable[] { - new Box - { - RelativeSizeAxes = Axes.X, - Height = 100, - Colour = Color4.Black, - Alpha = 0.5f, - }, new Container { RelativeSizeAxes = Axes.Both, Padding = new MarginPadding { - Top = 20, Left = WaveOverlayContainer.WIDTH_PADDING, Right = WaveOverlayContainer.WIDTH_PADDING, }, @@ -86,26 +92,48 @@ namespace osu.Game.Screens.OnlinePlay.Lounge RelativeSizeAxes = Axes.Both, RowDimensions = new[] { - new Dimension(GridSizeMode.AutoSize), + new Dimension(GridSizeMode.Absolute, Header.HEIGHT), + new Dimension(GridSizeMode.Absolute, button_height), new Dimension(GridSizeMode.Absolute, 20) }, Content = new[] { + new Drawable[] + { + searchTextBox = new LoungeSearchTextBox + { + Anchor = Anchor.CentreRight, + Origin = Anchor.CentreRight, + RelativeSizeAxes = Axes.X, + Width = 0.6f, + }, + }, new Drawable[] { new Container { - RelativeSizeAxes = Axes.X, - Height = 70, - Depth = -1, + RelativeSizeAxes = Axes.Both, + Depth = float.MinValue, // Contained filters should appear over the top of rooms. Children = new Drawable[] { - filter = CreateFilterControl(), Buttons.WithChild(CreateNewRoomButton().With(d => { - d.Size = new Vector2(150, 25); + d.Size = new Vector2(150, button_height); d.Action = () => Open(); - })) + })), + new FillFlowContainer + { + Anchor = Anchor.TopRight, + Origin = Anchor.TopRight, + AutoSizeAxes = Axes.Both, + Direction = FillDirection.Horizontal, + Spacing = new Vector2(10), + ChildrenEnumerable = CreateFilterControls().Select(f => f.With(d => + { + d.Anchor = Anchor.TopRight; + d.Origin = Anchor.TopRight; + })) + } } } }, @@ -145,6 +173,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { base.LoadComplete(); + searchTextBox.Current.BindValueChanged(_ => updateFilterDebounced()); + ruleset.BindValueChanged(_ => UpdateFilter()); + initialRoomsReceived.BindTo(RoomManager.InitialRoomsReceived); initialRoomsReceived.BindValueChanged(_ => updateLoadingLayer()); @@ -153,13 +184,50 @@ namespace osu.Game.Screens.OnlinePlay.Lounge operationInProgress.BindTo(ongoingOperationTracker.InProgress); operationInProgress.BindValueChanged(_ => updateLoadingLayer(), true); } + + updateFilter(); } - protected override void OnFocus(FocusEvent e) + #region Filtering + + protected void UpdateFilter() => Scheduler.AddOnce(updateFilter); + + private ScheduledDelegate scheduledFilterUpdate; + + private void updateFilterDebounced() { - filter.TakeFocus(); + scheduledFilterUpdate?.Cancel(); + scheduledFilterUpdate = Scheduler.AddDelayed(UpdateFilter, 200); } + private void updateFilter() + { + scheduledFilterUpdate?.Cancel(); + filter.Value = CreateFilterCriteria(); + } + + protected virtual FilterCriteria CreateFilterCriteria() => new FilterCriteria + { + SearchString = searchTextBox.Current.Value, + Ruleset = ruleset.Value, + Status = statusDropdown.Current.Value + }; + + protected virtual IEnumerable CreateFilterControls() + { + statusDropdown = new SlimEnumDropdown + { + RelativeSizeAxes = Axes.None, + Width = 160, + }; + + statusDropdown.Current.BindValueChanged(_ => UpdateFilter()); + + yield return statusDropdown; + } + + #endregion + public override void OnEntering(IScreen last) { base.OnEntering(last); @@ -191,14 +259,19 @@ namespace osu.Game.Screens.OnlinePlay.Lounge base.OnSuspending(next); } + protected override void OnFocus(FocusEvent e) + { + searchTextBox.TakeFocus(); + } + private void onReturning() { - filter.HoldFocus = true; + searchTextBox.HoldFocus = true; } private void onLeaving() { - filter.HoldFocus = false; + searchTextBox.HoldFocus = false; // ensure any password prompt is dismissed. this.HidePopover(); @@ -243,8 +316,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge this.Push(CreateRoomSubScreen(room)); } - protected abstract FilterControl CreateFilterControl(); - protected abstract OsuButton CreateNewRoomButton(); /// @@ -262,5 +333,15 @@ namespace osu.Game.Screens.OnlinePlay.Lounge else loadingLayer.Hide(); } + + private class LoungeSearchTextBox : SearchTextBox + { + [BackgroundDependencyLoader] + private void load() + { + BackgroundUnfocused = OsuColour.Gray(0.06f); + BackgroundFocused = OsuColour.Gray(0.12f); + } + } } } diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerFilterControl.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerFilterControl.cs deleted file mode 100644 index 37e0fd109a..0000000000 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerFilterControl.cs +++ /dev/null @@ -1,17 +0,0 @@ -// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. -// See the LICENCE file in the repository root for full licence text. - -using osu.Game.Screens.OnlinePlay.Lounge.Components; - -namespace osu.Game.Screens.OnlinePlay.Multiplayer -{ - public class MultiplayerFilterControl : FilterControl - { - protected override FilterCriteria CreateCriteria() - { - var criteria = base.CreateCriteria(); - criteria.Category = "realtime"; - return criteria; - } - } -} diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs index 621ff8881f..a7eaa37faa 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs @@ -21,7 +21,12 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer [Resolved] private MultiplayerClient client { get; set; } - protected override FilterControl CreateFilterControl() => new MultiplayerFilterControl(); + protected override FilterCriteria CreateFilterCriteria() + { + var criteria = base.CreateFilterCriteria(); + criteria.Category = "realtime"; + return criteria; + } protected override OsuButton CreateNewRoomButton() => new CreateMultiplayerMatchButton(); diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs index 4db1d6380d..254769d06b 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs @@ -1,7 +1,11 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; +using osu.Framework.Graphics; +using osu.Framework.Graphics.UserInterface; using osu.Game.Graphics.UserInterface; using osu.Game.Online.API; using osu.Game.Online.Rooms; @@ -16,7 +20,38 @@ namespace osu.Game.Screens.OnlinePlay.Playlists [Resolved] private IAPIProvider api { get; set; } - protected override FilterControl CreateFilterControl() => new PlaylistsFilterControl(); + private Dropdown categoryDropdown; + + protected override IEnumerable CreateFilterControls() + { + categoryDropdown = new SlimEnumDropdown + { + RelativeSizeAxes = Axes.None, + Width = 160, + }; + + categoryDropdown.Current.BindValueChanged(_ => UpdateFilter()); + + return base.CreateFilterControls().Append(categoryDropdown); + } + + protected override FilterCriteria CreateFilterCriteria() + { + var criteria = base.CreateFilterCriteria(); + + switch (categoryDropdown.Current.Value) + { + case PlaylistsCategory.Normal: + criteria.Category = "normal"; + break; + + case PlaylistsCategory.Spotlight: + criteria.Category = "spotlight"; + break; + } + + return criteria; + } protected override OsuButton CreateNewRoomButton() => new CreatePlaylistsRoomButton(); @@ -30,5 +65,12 @@ namespace osu.Game.Screens.OnlinePlay.Playlists } protected override RoomSubScreen CreateRoomSubScreen(Room room) => new PlaylistsRoomSubScreen(room); + + private enum PlaylistsCategory + { + Any, + Normal, + Spotlight + } } } From 050f2d6b0d379a675c2d5dbee3d7ba80e85873f5 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Aug 2021 19:51:03 +0900 Subject: [PATCH 30/53] Add background to room subscreen --- osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs | 7 +++++++ 1 file changed, 7 insertions(+) diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs index b29a1ab1b6..0074479a4d 100644 --- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs @@ -8,8 +8,10 @@ using osu.Framework.Allocation; using osu.Framework.Audio; using osu.Framework.Audio.Sample; using osu.Framework.Bindables; +using osu.Framework.Extensions.Color4Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; using osu.Framework.Screens; using osu.Game.Audio; using osu.Game.Beatmaps; @@ -65,6 +67,11 @@ namespace osu.Game.Screens.OnlinePlay.Match AddRangeInternal(new Drawable[] { + new Box + { + RelativeSizeAxes = Axes.Both, + Colour = Color4Extensions.FromHex(@"3e3a44") // This is super temporary. + }, BeatmapAvailabilityTracker = new OnlinePlayBeatmapAvailabilityTracker { SelectedItem = { BindTarget = SelectedItem } From 03351cf434d100356e1d16fdc86e07d05541a374 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Thu, 12 Aug 2021 20:01:53 +0900 Subject: [PATCH 31/53] Add blur to background --- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 10 ++++++++-- 1 file changed, 8 insertions(+), 2 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index 21e4f047f0..d1c701974e 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -22,6 +22,7 @@ using osu.Game.Screens.OnlinePlay.Components; using osu.Game.Screens.OnlinePlay.Lounge; using osu.Game.Screens.OnlinePlay.Lounge.Components; using osu.Game.Users; +using osuTK; using osuTK.Graphics; namespace osu.Game.Screens.OnlinePlay @@ -100,9 +101,14 @@ namespace osu.Game.Screens.OnlinePlay RelativeSizeAxes = Axes.Both, Children = new Drawable[] { - new HeaderBackgroundSprite + new BufferedContainer { - RelativeSizeAxes = Axes.Both + RelativeSizeAxes = Axes.Both, + BlurSigma = new Vector2(10), + Child = new HeaderBackgroundSprite + { + RelativeSizeAxes = Axes.Both + } }, new Box { From 3d7866e82da57bc422af3bb0cc22557653d10964 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Aug 2021 14:14:54 +0300 Subject: [PATCH 32/53] Calculate horizontal offset on present overlays only --- osu.Game/OsuGame.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b6809c0290..b8a4388282 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1015,9 +1015,9 @@ namespace osu.Game var horizontalOffset = 0f; - if (Settings.IsLoaded) + if (Settings.IsLoaded && Settings.IsPresent) horizontalOffset += (ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X) * SCREEN_OFFSET_RATIO; - if (Notifications.IsLoaded) + if (Notifications.IsLoaded && Notifications.IsPresent) horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; ScreenOffsetContainer.X = horizontalOffset; From bb1d74255e70081a806f9f3a9db773b6a3b06262 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Thu, 12 Aug 2021 14:15:51 +0300 Subject: [PATCH 33/53] Remove unrequired parenthesis --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index b8a4388282..f92f7e9e8c 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -1016,7 +1016,7 @@ namespace osu.Game var horizontalOffset = 0f; if (Settings.IsLoaded && Settings.IsPresent) - horizontalOffset += (ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X) * SCREEN_OFFSET_RATIO; + horizontalOffset += ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X * SCREEN_OFFSET_RATIO; if (Notifications.IsLoaded && Notifications.IsPresent) horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; From 1069f9d50119bfc08e97cb28bc33a7608e568587 Mon Sep 17 00:00:00 2001 From: TheOmyNomy Date: Fri, 13 Aug 2021 00:13:03 +1000 Subject: [PATCH 34/53] Always add cursor trail for legacy cursor with disjoint trail --- .../Skinning/Legacy/LegacyCursorTrail.cs | 24 ++++++++--- .../UI/Cursor/CursorTrail.cs | 43 ++++++++++++------- 2 files changed, 45 insertions(+), 22 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs index f6fd3e36ab..f98d936b48 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs @@ -5,10 +5,12 @@ using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; +using osu.Framework.Graphics.Shaders; using osu.Framework.Input.Events; using osu.Game.Configuration; using osu.Game.Rulesets.Osu.UI.Cursor; using osu.Game.Skinning; +using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Legacy { @@ -21,14 +23,18 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy private double lastTrailTime; private IBindable cursorSize; + private Vector2? currentPosition; + public LegacyCursorTrail(ISkin skin) { this.skin = skin; } [BackgroundDependencyLoader] - private void load(OsuConfigManager config) + private void load(ShaderManager shaders, OsuConfigManager config) { + Shader = shaders.Load(@"LegacyCursorTrail", FragmentShaderDescriptor.TEXTURE); + Texture = skin.GetTexture("cursortrail"); disjointTrail = skin.GetTexture("cursormiddle") == null; @@ -59,18 +65,24 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy protected override float IntervalMultiplier => 1 / Math.Max(cursorSize.Value, 1); - protected override bool OnMouseMove(MouseMoveEvent e) + protected override void Update() { - if (!disjointTrail) - return base.OnMouseMove(e); + base.Update(); + + if (!disjointTrail || !currentPosition.HasValue) + return; if (Time.Current - lastTrailTime >= disjoint_trail_time_separation) { lastTrailTime = Time.Current; - return base.OnMouseMove(e); + AddTrail(currentPosition.Value); } + } - return false; + protected override bool OnMouseMove(MouseMoveEvent e) + { + currentPosition = e.ScreenSpaceMousePosition; + return base.OnMouseMove(e); } } } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs index 7f86e9daf7..66a9302f5f 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs @@ -28,7 +28,9 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private readonly TrailPart[] parts = new TrailPart[max_sprites]; private int currentIndex; - private IShader shader; + + protected IShader Shader; + private double timeOffset; private float time; @@ -63,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor [BackgroundDependencyLoader] private void load(ShaderManager shaders) { - shader = shaders.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE); + Shader = shaders.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE); } protected override void LoadComplete() @@ -141,21 +143,32 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor protected override bool OnMouseMove(MouseMoveEvent e) { - Vector2 pos = e.ScreenSpaceMousePosition; + Vector2 position = e.ScreenSpaceMousePosition; if (lastPosition == null) { - lastPosition = pos; + lastPosition = position; resampler.AddPosition(lastPosition.Value); return base.OnMouseMove(e); } - foreach (Vector2 pos2 in resampler.AddPosition(pos)) - { - Trace.Assert(lastPosition.HasValue); + if (InterpolateMovements) + AddTrail(position); - if (InterpolateMovements) + return base.OnMouseMove(e); + } + + protected void AddTrail(Vector2 position) + { + if (!lastPosition.HasValue) + return; + + if (InterpolateMovements) + { + foreach (Vector2 pos2 in resampler.AddPosition(position)) { + Trace.Assert(lastPosition.HasValue); + // ReSharper disable once PossibleInvalidOperationException Vector2 pos1 = lastPosition.Value; Vector2 diff = pos2 - pos1; @@ -170,14 +183,12 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor addPart(lastPosition.Value); } } - else - { - lastPosition = pos2; - addPart(lastPosition.Value); - } } - - return base.OnMouseMove(e); + else + { + lastPosition = position; + addPart(lastPosition.Value); + } } private void addPart(Vector2 screenSpacePosition) @@ -223,7 +234,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor { base.ApplyState(); - shader = Source.shader; + shader = Source.Shader; texture = Source.texture; size = Source.partSize; time = Source.time; From 68f454b51a8ecc9753e21e323be29a9067b6b406 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 12 Aug 2021 21:09:08 +0200 Subject: [PATCH 35/53] Enable NRT in explosion-related classes and streamline null handling --- .../Skinning/Default/DefaultHitExplosion.cs | 3 --- .../Skinning/Legacy/LegacyHitExplosion.cs | 3 --- osu.Game.Rulesets.Catch/UI/HitExplosion.cs | 14 +++++++------- osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs | 2 ++ osu.Game.Rulesets.Catch/UI/IHitExplosion.cs | 2 ++ 5 files changed, 11 insertions(+), 13 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs index 680fbc7b15..e1fad564a3 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs @@ -72,9 +72,6 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default public void Animate(HitExplosionEntry entry) { - if (entry == null) - return; - X = entry.Position; Scale = new Vector2(entry.HitObject.Scale); setColour(entry.ObjectColour); diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs index 78b0e1e327..08f86df2f3 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs @@ -62,9 +62,6 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy public void Animate(HitExplosionEntry entry) { - if (entry == null) - return; - Colour = entry.ObjectColour; using (BeginAbsoluteSequence(entry.LifetimeStart)) diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs index 35af39348d..955b1e6edb 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs @@ -1,28 +1,25 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. -using osu.Framework.Allocation; using osu.Framework.Graphics; using osu.Game.Rulesets.Catch.Skinning.Default; using osu.Game.Rulesets.Objects.Pooling; using osu.Game.Skinning; +#nullable enable + namespace osu.Game.Rulesets.Catch.UI { public class HitExplosion : PoolableDrawableWithLifetime { - private SkinnableDrawable skinnableExplosion; + private readonly SkinnableDrawable skinnableExplosion; public HitExplosion() { RelativeSizeAxes = Axes.Both; Anchor = Anchor.BottomCentre; Origin = Anchor.BottomCentre; - } - [BackgroundDependencyLoader] - private void load() - { InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion()) { CentreComponent = false, @@ -44,8 +41,11 @@ namespace osu.Game.Rulesets.Catch.UI apply(Entry); } - private void apply(HitExplosionEntry entry) + private void apply(HitExplosionEntry? entry) { + if (entry == null) + return; + ApplyTransformsAt(double.MinValue, true); ClearTransforms(true); diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs b/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs index 749a448314..815a0d8c98 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs @@ -6,6 +6,8 @@ using osu.Game.Rulesets.Catch.Objects; using osu.Game.Rulesets.Judgements; using osuTK.Graphics; +#nullable enable + namespace osu.Game.Rulesets.Catch.UI { public class HitExplosionEntry : LifetimeEntry diff --git a/osu.Game.Rulesets.Catch/UI/IHitExplosion.cs b/osu.Game.Rulesets.Catch/UI/IHitExplosion.cs index 4a9d7e8ac0..c744c00d9a 100644 --- a/osu.Game.Rulesets.Catch/UI/IHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/UI/IHitExplosion.cs @@ -1,6 +1,8 @@ // Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. +#nullable enable + namespace osu.Game.Rulesets.Catch.UI { /// From f3045b315285c1d82ce144c635055e47236df4a7 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 12 Aug 2021 21:13:45 +0200 Subject: [PATCH 36/53] Add comment about swapped sprite names --- osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs index 08f86df2f3..c2570c4d1f 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs @@ -56,6 +56,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy { var defaultLegacySkin = skins.DefaultLegacySkin; + // sprite names intentionally swapped to match stable member naming / ease of cross-referencing explosion1.Texture = defaultLegacySkin.GetTexture("scoreboard-explosion-2"); explosion2.Texture = defaultLegacySkin.GetTexture("scoreboard-explosion-1"); } From e79150d4da09d35870380e2d92156ec9b011728e Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 12 Aug 2021 21:14:46 +0200 Subject: [PATCH 37/53] Reorder constructor arguments for `HitExplosionEntry` --- osu.Game.Rulesets.Catch/UI/Catcher.cs | 2 +- osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/UI/Catcher.cs b/osu.Game.Rulesets.Catch/UI/Catcher.cs index aec8e752a7..5cd85aac56 100644 --- a/osu.Game.Rulesets.Catch/UI/Catcher.cs +++ b/osu.Game.Rulesets.Catch/UI/Catcher.cs @@ -367,7 +367,7 @@ namespace osu.Game.Rulesets.Catch.UI } private void addLighting(JudgementResult judgementResult, Color4 colour, float x) => - hitExplosionContainer.Add(new HitExplosionEntry(judgementResult, colour, x, Time.Current)); + hitExplosionContainer.Add(new HitExplosionEntry(Time.Current, judgementResult, colour, x)); private CaughtObject getCaughtObject(PalpableCatchHitObject source) { diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs b/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs index 815a0d8c98..88871c77f6 100644 --- a/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs +++ b/osu.Game.Rulesets.Catch/UI/HitExplosionEntry.cs @@ -32,7 +32,7 @@ namespace osu.Game.Rulesets.Catch.UI /// public float Position { get; } - public HitExplosionEntry(JudgementResult judgementResult, Color4 objectColour, float position, double startTime) + public HitExplosionEntry(double startTime, JudgementResult judgementResult, Color4 objectColour, float position) { LifetimeStart = startTime; Position = position; From b84f2381065a00021c88361714387bf715441d1f Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Thu, 12 Aug 2021 22:33:09 +0200 Subject: [PATCH 38/53] Adjust scaling numbers to be closer to stable --- osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs index c2570c4d1f..c262b0a4ac 100644 --- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs +++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs @@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy Anchor = Anchor.BottomCentre; Origin = Anchor.BottomCentre; RelativeSizeAxes = Axes.Both; - Scale = new Vector2(0.4f); + Scale = new Vector2(0.5f); InternalChildren = new[] { @@ -78,7 +78,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy explosion1.Position = new Vector2(explosionOffset, 0); explosion1.FadeOutFromOne(300); - explosion1.ScaleTo(new Vector2(20 * scale, 1.1f), 160, Easing.Out); + explosion1.ScaleTo(new Vector2(16 * scale, 1.1f), 160, Easing.Out); } explosion2.Scale = new Vector2(0.9f, 1); From 7aa361d77280c14ea53d7a563a59d988a7b7f29c Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 09:02:13 +0900 Subject: [PATCH 39/53] Remove now-incorrect test --- osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs index 7ff0368fc2..7f961d4c8b 100644 --- a/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs +++ b/osu.Game.Tests/Visual/Multiplayer/TestSceneMultiplayer.cs @@ -405,8 +405,6 @@ namespace osu.Game.Tests.Visual.Multiplayer AddAssert("dialog overlay is hidden", () => DialogOverlay.State.Value == Visibility.Hidden); - testLeave("lounge tab item", () => this.ChildrenOfType.BreadcrumbTabItem>().First().TriggerClick()); - testLeave("back button", () => multiplayerScreen.OnBackButton()); // mimics home button and OS window close From 524102951348592f84312bb946e1eb85b40298c7 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 10:27:26 +0900 Subject: [PATCH 40/53] Use new FadeExponent shader uniform --- .../Skinning/Legacy/LegacyCursorTrail.cs | 6 ++---- osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs | 17 +++++++++++------ 2 files changed, 13 insertions(+), 10 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs index f98d936b48..9493dc2ef1 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs @@ -5,7 +5,6 @@ using System; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; -using osu.Framework.Graphics.Shaders; using osu.Framework.Input.Events; using osu.Game.Configuration; using osu.Game.Rulesets.Osu.UI.Cursor; @@ -31,10 +30,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy } [BackgroundDependencyLoader] - private void load(ShaderManager shaders, OsuConfigManager config) + private void load(OsuConfigManager config) { - Shader = shaders.Load(@"LegacyCursorTrail", FragmentShaderDescriptor.TEXTURE); - Texture = skin.GetTexture("cursortrail"); disjointTrail = skin.GetTexture("cursormiddle") == null; @@ -60,6 +57,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy } protected override double FadeDuration => disjointTrail ? 150 : 500; + protected override float FadeExponent => 1; protected override bool InterpolateMovements => !disjointTrail; diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs index 66a9302f5f..b05bf5c93e 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs @@ -26,11 +26,14 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor { private const int max_sprites = 2048; + /// + /// An exponentiating factor to ease the trail fade. + /// + protected virtual float FadeExponent => 1.7f; + private readonly TrailPart[] parts = new TrailPart[max_sprites]; private int currentIndex; - - protected IShader Shader; - + private IShader shader; private double timeOffset; private float time; @@ -65,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor [BackgroundDependencyLoader] private void load(ShaderManager shaders) { - Shader = shaders.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE); + shader = shaders.Load(@"CursorTrail", FragmentShaderDescriptor.TEXTURE); } protected override void LoadComplete() @@ -217,10 +220,10 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor private Texture texture; private float time; + private float fadeExponent; private readonly TrailPart[] parts = new TrailPart[max_sprites]; private Vector2 size; - private Vector2 originPosition; private readonly QuadBatch vertexBatch = new QuadBatch(max_sprites, 1); @@ -234,10 +237,11 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor { base.ApplyState(); - shader = Source.Shader; + shader = Source.shader; texture = Source.texture; size = Source.partSize; time = Source.time; + fadeExponent = Source.FadeExponent; originPosition = Vector2.Zero; @@ -260,6 +264,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor shader.Bind(); shader.GetUniform("g_FadeClock").UpdateValue(ref time); + shader.GetUniform("g_FadeExponent").UpdateValue(ref fadeExponent); texture.TextureGL.Bind(); From 7cc0a2a76fdb8acecf4502bac1a75279c9b29e49 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 12:10:33 +0900 Subject: [PATCH 41/53] Refactor to fix InterpolateMovements=false --- .../Skinning/Legacy/LegacyCursorTrail.cs | 7 +++++- .../UI/Cursor/CursorTrail.cs | 24 +++++++------------ 2 files changed, 14 insertions(+), 17 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs index 9493dc2ef1..587ff4b573 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs @@ -79,8 +79,13 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy protected override bool OnMouseMove(MouseMoveEvent e) { + if (!disjointTrail) + return base.OnMouseMove(e); + currentPosition = e.ScreenSpaceMousePosition; - return base.OnMouseMove(e); + + // Intentionally block the base call as we're adding the trails ourselves. + return false; } } } diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs index b05bf5c93e..7a95111c91 100644 --- a/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs +++ b/osu.Game.Rulesets.Osu/UI/Cursor/CursorTrail.cs @@ -146,33 +146,25 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor protected override bool OnMouseMove(MouseMoveEvent e) { - Vector2 position = e.ScreenSpaceMousePosition; - - if (lastPosition == null) - { - lastPosition = position; - resampler.AddPosition(lastPosition.Value); - return base.OnMouseMove(e); - } - - if (InterpolateMovements) - AddTrail(position); - + AddTrail(e.ScreenSpaceMousePosition); return base.OnMouseMove(e); } protected void AddTrail(Vector2 position) { - if (!lastPosition.HasValue) - return; - if (InterpolateMovements) { + if (!lastPosition.HasValue) + { + lastPosition = position; + resampler.AddPosition(lastPosition.Value); + return; + } + foreach (Vector2 pos2 in resampler.AddPosition(position)) { Trace.Assert(lastPosition.HasValue); - // ReSharper disable once PossibleInvalidOperationException Vector2 pos1 = lastPosition.Value; Vector2 diff = pos2 - pos1; float distance = diff.Length; From e913c8f92fdff9cd6f76c5b63cd079e15b8bbc8a Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Fri, 13 Aug 2021 13:07:02 +0900 Subject: [PATCH 42/53] Change strings to verbatim --- .../OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs | 2 +- .../Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs | 4 ++-- 2 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs index a7eaa37faa..ad7882abc2 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerLoungeSubScreen.cs @@ -24,7 +24,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer protected override FilterCriteria CreateFilterCriteria() { var criteria = base.CreateFilterCriteria(); - criteria.Category = "realtime"; + criteria.Category = @"realtime"; return criteria; } diff --git a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs index 254769d06b..eee4d4f407 100644 --- a/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Playlists/PlaylistsLoungeSubScreen.cs @@ -42,11 +42,11 @@ namespace osu.Game.Screens.OnlinePlay.Playlists switch (categoryDropdown.Current.Value) { case PlaylistsCategory.Normal: - criteria.Category = "normal"; + criteria.Category = @"normal"; break; case PlaylistsCategory.Spotlight: - criteria.Category = "spotlight"; + criteria.Category = @"spotlight"; break; } From e93660c0f4f0936828548479711d2c3031514128 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 13:19:34 +0900 Subject: [PATCH 43/53] Update resources --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 2 +- 3 files changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 454bb46059..33d3a623ed 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -51,7 +51,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index e6219fcb85..6ccd34dd48 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -37,7 +37,7 @@ - + diff --git a/osu.iOS.props b/osu.iOS.props index 9904946363..b6623da540 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -71,7 +71,7 @@ - + From 89eded457c094701a1c4532a546cfe96df50db80 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 14:27:28 +0900 Subject: [PATCH 44/53] Fix weird margins on loading display in lounge --- osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 9 ++++++--- 1 file changed, 6 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 122b30b1d2..910afb5540 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -63,6 +63,8 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { OsuScrollContainer scrollContainer; + Container filterContainer; + InternalChildren = new Drawable[] { new Box @@ -93,7 +95,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { new Drawable[] { - new Container + filterContainer = new Container { RelativeSizeAxes = Axes.X, Height = 70, @@ -123,13 +125,14 @@ namespace osu.Game.Screens.OnlinePlay.Lounge ScrollbarOverlapsContent = false, Child = roomsContainer = new RoomsContainer() }, - loadingLayer = new LoadingLayer(true), } }, } } }, - } + }, + loadingLayer = new LoadingLayer(true), + filterContainer.CreateProxy() }; // scroll selected room into view on selection. From a1b72e7f97731b072a3a1fb204fd12310e239bdb Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 14:41:07 +0900 Subject: [PATCH 45/53] Remove redundant array type specification --- osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 910afb5540..fb0b963167 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -65,7 +65,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge Container filterContainer; - InternalChildren = new Drawable[] + InternalChildren = new[] { new Box { From 5cec50bdd14ad16b4b07e14605cb9d5d3dd2eddf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 15:24:43 +0900 Subject: [PATCH 46/53] Add comment mentioning why event bindings are not unbound --- osu.Game/Screens/OnlinePlay/Header.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/OnlinePlay/Header.cs b/osu.Game/Screens/OnlinePlay/Header.cs index 58c67a51e8..b0db9256f5 100644 --- a/osu.Game/Screens/OnlinePlay/Header.cs +++ b/osu.Game/Screens/OnlinePlay/Header.cs @@ -35,6 +35,7 @@ namespace osu.Game.Screens.OnlinePlay Origin = Anchor.CentreLeft, }; + // unnecessary to unbind these as this header has the same lifetime as the screen stack we are attaching to. stack.ScreenPushed += (_, __) => updateSubScreenTitle(); stack.ScreenExited += (_, __) => updateSubScreenTitle(); } From 3b6a8a2bae61e342da76a735cc49c97cf9c5d99d Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 15:24:53 +0900 Subject: [PATCH 47/53] Rename background sprite and reduce load delay --- osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs | 6 +++--- 1 file changed, 3 insertions(+), 3 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs index 978b35e4b1..c2ad0285b1 100644 --- a/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs +++ b/osu.Game/Screens/OnlinePlay/OnlinePlayScreen.cs @@ -108,7 +108,7 @@ namespace osu.Game.Screens.OnlinePlay { RelativeSizeAxes = Axes.Both, BlurSigma = new Vector2(10), - Child = new HeaderBackgroundSprite + Child = new BeatmapBackgroundSprite { RelativeSizeAxes = Axes.Both } @@ -304,13 +304,13 @@ namespace osu.Game.Screens.OnlinePlay } } - private class HeaderBackgroundSprite : OnlinePlayBackgroundSprite + private class BeatmapBackgroundSprite : OnlinePlayBackgroundSprite { protected override UpdateableBeatmapBackgroundSprite CreateBackgroundSprite() => new BackgroundSprite { RelativeSizeAxes = Axes.Both }; private class BackgroundSprite : UpdateableBeatmapBackgroundSprite { - protected override double TransformDuration => 200; + protected override double LoadDelay => 200; } } From dd7ca4b77b45ae0f69078afd1fdbedf7e82cad80 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 15:35:45 +0900 Subject: [PATCH 48/53] Increase "create room" button height --- osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 1c28405e40..7249ccdd93 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -30,8 +30,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge [Cached] public abstract class LoungeSubScreen : OnlinePlaySubScreen { - private const float button_height = 25; - public override string Title => "Lounge"; protected override UserActivity InitialActivity => new UserActivity.SearchingForLobby(); @@ -93,7 +91,7 @@ namespace osu.Game.Screens.OnlinePlay.Lounge RowDimensions = new[] { new Dimension(GridSizeMode.Absolute, Header.HEIGHT), - new Dimension(GridSizeMode.Absolute, button_height), + new Dimension(GridSizeMode.Absolute, 25), new Dimension(GridSizeMode.Absolute, 20) }, Content = new[] @@ -118,7 +116,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge { Buttons.WithChild(CreateNewRoomButton().With(d => { - d.Size = new Vector2(150, button_height); + d.Anchor = Anchor.BottomLeft; + d.Origin = Anchor.BottomLeft; + d.Size = new Vector2(150, 37.5f); d.Action = () => Open(); })), new FillFlowContainer From db52549152f56e28cf22bb018ff22f32d19bb8de Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 16:20:53 +0900 Subject: [PATCH 49/53] Move below everything rather than proxying (works better with new design) --- osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) diff --git a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs index 43da62d466..ceec609f6d 100644 --- a/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs +++ b/osu.Game/Screens/OnlinePlay/Lounge/LoungeSubScreen.cs @@ -75,10 +75,9 @@ namespace osu.Game.Screens.OnlinePlay.Lounge OsuScrollContainer scrollContainer; - Container filterContainer; - InternalChildren = new[] { + loadingLayer = new LoadingLayer(true), new Container { RelativeSizeAxes = Axes.Both, @@ -159,8 +158,6 @@ namespace osu.Game.Screens.OnlinePlay.Lounge } }, }, - loadingLayer = new LoadingLayer(true), - filterContainer.CreateProxy() }; // scroll selected room into view on selection. From c1d67976e6accf5ca2980a6aa116e791e8e9432a Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 16:29:36 +0900 Subject: [PATCH 50/53] Rename const, add xmldoc and make protected --- osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs | 4 ++-- osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs | 2 ++ osu.Game/OsuGame.cs | 9 ++++++--- 3 files changed, 10 insertions(+), 5 deletions(-) diff --git a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs index 21db7e2802..e58f85b0b3 100644 --- a/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs +++ b/osu.Game.Tests/Visual/Menus/TestSceneSideOverlays.cs @@ -23,7 +23,7 @@ namespace osu.Game.Tests.Visual.Menus public void TestScreenOffsettingOnSettingsOverlay() { AddStep("open settings", () => Game.Settings.Show()); - AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == SettingsPanel.WIDTH * TestOsuGame.SIDE_OVERLAY_OFFSET_RATIO); AddStep("hide settings", () => Game.Settings.Hide()); AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); @@ -33,7 +33,7 @@ namespace osu.Game.Tests.Visual.Menus public void TestScreenOffsettingOnNotificationOverlay() { AddStep("open notifications", () => Game.Notifications.Show()); - AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == -NotificationOverlay.WIDTH * OsuGame.SCREEN_OFFSET_RATIO); + AddUntilStep("right screen offset applied", () => Game.ScreenOffsetContainer.X == -NotificationOverlay.WIDTH * TestOsuGame.SIDE_OVERLAY_OFFSET_RATIO); AddStep("hide notifications", () => Game.Notifications.Hide()); AddUntilStep("screen offset removed", () => Game.ScreenOffsetContainer.X == 0f); diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs index 5cd55ed233..c9a1471e41 100644 --- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs +++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs @@ -96,6 +96,8 @@ namespace osu.Game.Tests.Visual.Navigation public class TestOsuGame : OsuGame { + public new const float SIDE_OVERLAY_OFFSET_RATIO = OsuGame.SIDE_OVERLAY_OFFSET_RATIO; + public new ScreenStack ScreenStack => base.ScreenStack; public new BackButton BackButton => base.BackButton; diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index f92f7e9e8c..6d76fec7c1 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -64,7 +64,10 @@ namespace osu.Game /// public class OsuGame : OsuGameBase, IKeyBindingHandler { - public const float SCREEN_OFFSET_RATIO = 0.125f; + /// + /// The amount of global offset to apply when a left/right anchored overlay is displayed (ie. settings or notifications). + /// + protected const float SIDE_OVERLAY_OFFSET_RATIO = 0.125f; public Toolbar Toolbar; @@ -1016,9 +1019,9 @@ namespace osu.Game var horizontalOffset = 0f; if (Settings.IsLoaded && Settings.IsPresent) - horizontalOffset += ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X * SCREEN_OFFSET_RATIO; + horizontalOffset += ToLocalSpace(Settings.ScreenSpaceDrawQuad.TopRight).X * SIDE_OVERLAY_OFFSET_RATIO; if (Notifications.IsLoaded && Notifications.IsPresent) - horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SCREEN_OFFSET_RATIO; + horizontalOffset += (ToLocalSpace(Notifications.ScreenSpaceDrawQuad.TopLeft).X - DrawWidth) * SIDE_OVERLAY_OFFSET_RATIO; ScreenOffsetContainer.X = horizontalOffset; From da18c399e2d7cd531e019c8b140155a02135a4dd Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 16:33:00 +0900 Subject: [PATCH 51/53] Remove unnecessary `IsPresent` override --- osu.Game/Overlays/SettingsPanel.cs | 6 ------ 1 file changed, 6 deletions(-) diff --git a/osu.Game/Overlays/SettingsPanel.cs b/osu.Game/Overlays/SettingsPanel.cs index 8b953e8655..f1c41c4b50 100644 --- a/osu.Game/Overlays/SettingsPanel.cs +++ b/osu.Game/Overlays/SettingsPanel.cs @@ -42,12 +42,6 @@ namespace osu.Game.Overlays protected override Container Content => ContentContainer; - /// - /// The always needs to be present for to process transforms while overlay is masked away. - /// todo: there may be a better solution for this and the existing , likely requires a refactor. - /// - public override bool IsPresent => true; - protected Sidebar Sidebar; private SidebarButton selectedSidebarButton; From 93b97e5110774787b27ba91cb595158a65491cbf Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 16:35:22 +0900 Subject: [PATCH 52/53] Adjust ratio to match previous behaviour --- osu.Game/OsuGame.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 6d76fec7c1..fb682e0909 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -67,7 +67,7 @@ namespace osu.Game /// /// The amount of global offset to apply when a left/right anchored overlay is displayed (ie. settings or notifications). /// - protected const float SIDE_OVERLAY_OFFSET_RATIO = 0.125f; + protected const float SIDE_OVERLAY_OFFSET_RATIO = 0.05f; public Toolbar Toolbar; From 5a60b39643b172dd679cd5e81712c99422fff024 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Aug 2021 16:42:58 +0900 Subject: [PATCH 53/53] Remove unnecessary delimiters from song select filter splitting --- osu.Game/Screens/Select/FilterCriteria.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Select/FilterCriteria.cs b/osu.Game/Screens/Select/FilterCriteria.cs index b9e912df8e..f47bc5f466 100644 --- a/osu.Game/Screens/Select/FilterCriteria.cs +++ b/osu.Game/Screens/Select/FilterCriteria.cs @@ -56,7 +56,7 @@ namespace osu.Game.Screens.Select set { searchText = value; - SearchTerms = searchText.Split(new[] { ',', ' ', '!' }, StringSplitOptions.RemoveEmptyEntries).ToArray(); + SearchTerms = searchText.Split(' ', StringSplitOptions.RemoveEmptyEntries).ToArray(); SearchNumber = null;