From f31deaef7ca8dd0f7defd794c77f8a8b6f0f718c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Mon, 12 Sep 2022 19:51:49 +0900 Subject: [PATCH 01/27] Simplify skin bindable flow Now, nothing touches the configuration apart from `OsuGame`, making everything else flow better and avoid weird cyclic set bugs. Closes https://github.com/ppy/osu/issues/20234. --- osu.Game/OsuGame.cs | 24 ++----- .../Overlays/Settings/Sections/SkinSection.cs | 62 ++++--------------- osu.Game/Skinning/SkinManager.cs | 20 +++++- 3 files changed, 36 insertions(+), 70 deletions(-) diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs index 9e2384322a..0d115f62fe 100644 --- a/osu.Game/OsuGame.cs +++ b/osu.Game/OsuGame.cs @@ -56,14 +56,12 @@ using osu.Game.Screens.Menu; using osu.Game.Screens.Play; using osu.Game.Screens.Ranking; using osu.Game.Screens.Select; -using osu.Game.Skinning; using osu.Game.Skinning.Editor; using osu.Game.Updater; using osu.Game.Users; using osu.Game.Utils; using osuTK.Graphics; using Sentry; -using Logger = osu.Framework.Logging.Logger; namespace osu.Game { @@ -294,25 +292,13 @@ namespace osu.Game Ruleset.ValueChanged += r => configRuleset.Value = r.NewValue.ShortName; - // bind config int to database SkinInfo configSkin = LocalConfig.GetBindable(OsuSetting.Skin); + + // Transfer skin from config to realm instance once on startup. + SkinManager.SetSkinFromConfiguration(configSkin.Value); + + // Transfer any runtime changes back to configuration file. SkinManager.CurrentSkinInfo.ValueChanged += skin => configSkin.Value = skin.NewValue.ID.ToString(); - configSkin.ValueChanged += skinId => - { - Live skinInfo = null; - - if (Guid.TryParse(skinId.NewValue, out var guid)) - skinInfo = SkinManager.Query(s => s.ID == guid); - - if (skinInfo == null) - { - if (guid == SkinInfo.CLASSIC_SKIN) - skinInfo = DefaultLegacySkin.CreateInfo().ToLiveUnmanaged(); - } - - SkinManager.CurrentSkinInfo.Value = skinInfo ?? DefaultSkin.CreateInfo().ToLiveUnmanaged(); - }; - configSkin.TriggerChange(); IsActive.BindValueChanged(active => updateActiveState(active.NewValue), true); diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index d23ef7e3e7..13249e37ca 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -14,7 +14,6 @@ using osu.Framework.Graphics.Sprites; using osu.Framework.Localisation; using osu.Framework.Logging; using osu.Framework.Platform; -using osu.Game.Configuration; using osu.Game.Database; using osu.Game.Graphics.UserInterface; using osu.Game.Localisation; @@ -36,9 +35,6 @@ namespace osu.Game.Overlays.Settings.Sections Icon = FontAwesome.Solid.PaintBrush }; - private readonly Bindable> dropdownBindable = new Bindable> { Default = DefaultSkin.CreateInfo().ToLiveUnmanaged() }; - private readonly Bindable configBindable = new Bindable(); - private static readonly Live random_skin_info = new SkinInfo { ID = SkinInfo.RANDOM_SKIN, @@ -56,13 +52,14 @@ namespace osu.Game.Overlays.Settings.Sections private IDisposable realmSubscription; [BackgroundDependencyLoader(permitNulls: true)] - private void load(OsuConfigManager config, [CanBeNull] SkinEditorOverlay skinEditor) + private void load([CanBeNull] SkinEditorOverlay skinEditor) { Children = new Drawable[] { skinDropdown = new SkinSettingsDropdown { LabelText = SkinSettingsStrings.CurrentSkin, + Current = skins.CurrentSkinInfo, Keywords = new[] { @"skins" } }, new SettingsButton @@ -73,47 +70,30 @@ namespace osu.Game.Overlays.Settings.Sections new ExportSkinButton(), new DeleteSkinButton(), }; - - config.BindWith(OsuSetting.Skin, configBindable); } protected override void LoadComplete() { base.LoadComplete(); - skinDropdown.Current = dropdownBindable; + skinDropdown.Current = skins.CurrentSkinInfo; realmSubscription = realm.RegisterForNotifications(_ => realm.Realm.All() .Where(s => !s.DeletePending) .OrderByDescending(s => s.Protected) // protected skins should be at the top. .ThenBy(s => s.Name, StringComparer.OrdinalIgnoreCase), skinsChanged); - configBindable.BindValueChanged(_ => Scheduler.AddOnce(updateSelectedSkinFromConfig)); - - dropdownBindable.BindValueChanged(dropdownSelectionChanged); - } - - private void dropdownSelectionChanged(ValueChangedEvent> skin) - { - // Only handle cases where it's clear the user has intent to change skins. - if (skin.OldValue == null) return; - - if (skin.NewValue.Equals(random_skin_info)) + skinDropdown.Current.BindValueChanged(skin => { - var skinBefore = skins.CurrentSkinInfo.Value; - - skins.SelectRandomSkin(); - - if (skinBefore == skins.CurrentSkinInfo.Value) + if (skin.NewValue == random_skin_info) { - // the random selection didn't change the skin, so we should manually update the dropdown to match. - dropdownBindable.Value = skins.CurrentSkinInfo.Value; + // before selecting random, set the skin back to the previous selection. + // this is done because at this point it will be random_skin_info, and would + // cause SelectRandomSkin to be unable to skip the previous selection. + skins.CurrentSkinInfo.Value = skin.OldValue; + skins.SelectRandomSkin(); } - - return; - } - - configBindable.Value = skin.NewValue.ID.ToString(); + }); } private void skinsChanged(IRealmCollection sender, ChangeSet changes, Exception error) @@ -132,25 +112,7 @@ namespace osu.Game.Overlays.Settings.Sections dropdownItems.Add(skin.ToLive(realm)); dropdownItems.Insert(protectedCount, random_skin_info); - Schedule(() => - { - skinDropdown.Items = dropdownItems; - - updateSelectedSkinFromConfig(); - }); - } - - private void updateSelectedSkinFromConfig() - { - if (!skinDropdown.Items.Any()) - return; - - Live skin = null; - - if (Guid.TryParse(configBindable.Value, out var configId)) - skin = skinDropdown.Items.FirstOrDefault(s => s.ID == configId); - - dropdownBindable.Value = skin ?? skinDropdown.Items.First(); + Schedule(() => skinDropdown.Items = dropdownItems); } protected override void Dispose(bool isDisposing) diff --git a/osu.Game/Skinning/SkinManager.cs b/osu.Game/Skinning/SkinManager.cs index f677cebe51..7ffea3b54f 100644 --- a/osu.Game/Skinning/SkinManager.cs +++ b/osu.Game/Skinning/SkinManager.cs @@ -119,7 +119,9 @@ namespace osu.Game.Skinning Realm.Run(r => { // choose from only user skins, removing the current selection to ensure a new one is chosen. - var randomChoices = r.All().Where(s => !s.DeletePending && s.ID != CurrentSkinInfo.Value.ID).ToArray(); + var randomChoices = r.All() + .Where(s => !s.DeletePending && s.ID != CurrentSkinInfo.Value.ID) + .ToArray(); if (randomChoices.Length == 0) { @@ -297,5 +299,21 @@ namespace osu.Game.Skinning Delete(items.ToList(), silent); }); } + + public void SetSkinFromConfiguration(string guidString) + { + Live skinInfo = null; + + if (Guid.TryParse(guidString, out var guid)) + skinInfo = Query(s => s.ID == guid); + + if (skinInfo == null) + { + if (guid == SkinInfo.CLASSIC_SKIN) + skinInfo = DefaultLegacySkin.SkinInfo; + } + + CurrentSkinInfo.Value = skinInfo ?? DefaultSkin.SkinInfo; + } } } From d368f37c3ab8c360cd1a31138543118f90fd1625 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Sep 2022 13:50:59 +0900 Subject: [PATCH 02/27] Remove redundant second `Current` set operation --- osu.Game/Overlays/Settings/Sections/SkinSection.cs | 2 -- 1 file changed, 2 deletions(-) diff --git a/osu.Game/Overlays/Settings/Sections/SkinSection.cs b/osu.Game/Overlays/Settings/Sections/SkinSection.cs index 13249e37ca..4787b07af8 100644 --- a/osu.Game/Overlays/Settings/Sections/SkinSection.cs +++ b/osu.Game/Overlays/Settings/Sections/SkinSection.cs @@ -76,8 +76,6 @@ namespace osu.Game.Overlays.Settings.Sections { base.LoadComplete(); - skinDropdown.Current = skins.CurrentSkinInfo; - realmSubscription = realm.RegisterForNotifications(_ => realm.Realm.All() .Where(s => !s.DeletePending) .OrderByDescending(s => s.Protected) // protected skins should be at the top. From 0fcd9e02f632230d3d1b884e88a5d4c0891f2c9c Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Sep 2022 14:01:40 +0900 Subject: [PATCH 03/27] Fix skin dropdown not updating correctly when skin is changed externally --- osu.Game/Database/Live.cs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/osu.Game/Database/Live.cs b/osu.Game/Database/Live.cs index 52e1d420f7..a21b7f606b 100644 --- a/osu.Game/Database/Live.cs +++ b/osu.Game/Database/Live.cs @@ -53,6 +53,8 @@ namespace osu.Game.Database public bool Equals(Live? other) => ID == other?.ID; + public override int GetHashCode() => HashCode.Combine(ID); + public override string ToString() => PerformRead(i => i.ToString()); } } From 9226f0abbca34bd14e6c3571ea7a4426cf9abf57 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Tue, 13 Sep 2022 19:16:25 +0900 Subject: [PATCH 04/27] Implement equality correctly in `Live` --- osu.Game/Database/Live.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Database/Live.cs b/osu.Game/Database/Live.cs index a21b7f606b..3bb11c3a50 100644 --- a/osu.Game/Database/Live.cs +++ b/osu.Game/Database/Live.cs @@ -51,7 +51,13 @@ namespace osu.Game.Database ID = id; } - public bool Equals(Live? other) => ID == other?.ID; + public bool Equals(Live? other) + { + if (ReferenceEquals(this, other)) return true; + if (other == null) return false; + + return ID == other.ID; + } public override int GetHashCode() => HashCode.Combine(ID); From 0ff4e343f87c82b04692584c0e61c1ef26ba56d0 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Sep 2022 16:29:53 +0900 Subject: [PATCH 05/27] Add failing test showing incorrect unread notification count --- .../Visual/UserInterface/TestSceneNotificationOverlay.cs | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs index e978b57ba4..a97096e143 100644 --- a/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs +++ b/osu.Game.Tests/Visual/UserInterface/TestSceneNotificationOverlay.cs @@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.UserInterface displayedCount = new OsuSpriteText() }; - notificationOverlay.UnreadCount.ValueChanged += count => { displayedCount.Text = $"displayed count: {count.NewValue}"; }; + notificationOverlay.UnreadCount.ValueChanged += count => { displayedCount.Text = $"unread count: {count.NewValue}"; }; }); [Test] @@ -270,6 +270,8 @@ namespace osu.Game.Tests.Visual.UserInterface AddUntilStep("wait completion", () => notification.State == ProgressNotificationState.Completed); AddAssert("Completion toast shown", () => notificationOverlay.ToastCount == 1); + AddUntilStep("wait forwarded", () => notificationOverlay.ToastCount == 0); + AddAssert("only one unread", () => notificationOverlay.UnreadCount.Value == 1); } [Test] From 0d24fda4b9cbaaa107717feab3fc9adc4635cdd5 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Sep 2022 16:36:56 +0900 Subject: [PATCH 06/27] Fire `Notification.Closed` immediately to ensure off-screen notifications are closed --- osu.Game/Overlays/NotificationOverlay.cs | 4 ++-- .../Overlays/Notifications/Notification.cs | 23 +++++++++++-------- .../Notifications/ProgressNotification.cs | 5 ++-- 3 files changed, 19 insertions(+), 13 deletions(-) diff --git a/osu.Game/Overlays/NotificationOverlay.cs b/osu.Game/Overlays/NotificationOverlay.cs index 15573f99af..fad8afd371 100644 --- a/osu.Game/Overlays/NotificationOverlay.cs +++ b/osu.Game/Overlays/NotificationOverlay.cs @@ -210,14 +210,14 @@ namespace osu.Game.Overlays mainContent.FadeTo(0, TRANSITION_LENGTH, Easing.OutQuint); } - private void notificationClosed() + private void notificationClosed() => Schedule(() => { updateCounts(); // this debounce is currently shared between popin/popout sounds, which means one could potentially not play when the user is expecting it. // popout is constant across all notification types, and should therefore be handled using playback concurrency instead, but seems broken at the moment. playDebouncedSample("UI/overlay-pop-out"); - } + }); private void playDebouncedSample(string sampleName) { diff --git a/osu.Game/Overlays/Notifications/Notification.cs b/osu.Game/Overlays/Notifications/Notification.cs index 885bb2fc6c..4e7cebf0ae 100644 --- a/osu.Game/Overlays/Notifications/Notification.cs +++ b/osu.Game/Overlays/Notifications/Notification.cs @@ -26,7 +26,8 @@ namespace osu.Game.Overlays.Notifications public abstract class Notification : Container { /// - /// User requested close. + /// Notification was closed, either by user or otherwise. + /// Importantly, this event may be fired from a non-update thread. /// public event Action? Closed; @@ -55,6 +56,8 @@ namespace osu.Game.Overlays.Notifications protected Container IconContent; + public bool WasClosed { get; private set; } + private readonly Container content; protected override Container Content => content; @@ -245,21 +248,23 @@ namespace osu.Game.Overlays.Notifications initialFlash.FadeOutFromOne(2000, Easing.OutQuart); } - public bool WasClosed; - public virtual void Close(bool runFlingAnimation) { if (WasClosed) return; WasClosed = true; - if (runFlingAnimation && dragContainer.FlingLeft()) - this.FadeOut(600, Easing.In); - else - this.FadeOut(100); - Closed?.Invoke(); - Expire(); + + Schedule(() => + { + if (runFlingAnimation && dragContainer.FlingLeft()) + this.FadeOut(600, Easing.In); + else + this.FadeOut(100); + + Expire(); + }); } private class DragContainer : Container diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index c4d402e5b9..58c9814781 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -141,8 +141,6 @@ namespace osu.Game.Overlays.Notifications case ProgressNotificationState.Completed: loadingSpinner.Hide(); - attemptPostCompletion(); - base.Close(false); break; } } @@ -166,6 +164,8 @@ namespace osu.Game.Overlays.Notifications CompletionTarget.Invoke(CreateCompletionNotification()); completionSent = true; + + Close(false); } private ProgressNotificationState state; @@ -239,6 +239,7 @@ namespace osu.Game.Overlays.Notifications { switch (State) { + case ProgressNotificationState.Completed: case ProgressNotificationState.Cancelled: base.Close(runFlingAnimation); break; From 38d8d457d97a43d64deb14cec6f6e8b11b493d53 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Sep 2022 17:54:44 +0900 Subject: [PATCH 07/27] Add back second completion post attempt for case when notification overlay isn't loaded yet --- osu.Game/Overlays/Notifications/ProgressNotification.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Overlays/Notifications/ProgressNotification.cs b/osu.Game/Overlays/Notifications/ProgressNotification.cs index 58c9814781..61bb22041e 100644 --- a/osu.Game/Overlays/Notifications/ProgressNotification.cs +++ b/osu.Game/Overlays/Notifications/ProgressNotification.cs @@ -141,6 +141,7 @@ namespace osu.Game.Overlays.Notifications case ProgressNotificationState.Completed: loadingSpinner.Hide(); + attemptPostCompletion(); break; } } From 85bb6f0beb859cf9f57d6ef6e68f28f557cb9c64 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 16 Sep 2022 00:54:16 +0900 Subject: [PATCH 08/27] Update framework Update framework (again) Update framework --- osu.Android.props | 2 +- osu.Game/osu.Game.csproj | 2 +- osu.iOS.props | 4 ++-- 3 files changed, 4 insertions(+), 4 deletions(-) diff --git a/osu.Android.props b/osu.Android.props index 2c186a52dd..77c29a5d6e 100644 --- a/osu.Android.props +++ b/osu.Android.props @@ -52,7 +52,7 @@ - + diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj index fed7c27f07..29e690a024 100644 --- a/osu.Game/osu.Game.csproj +++ b/osu.Game/osu.Game.csproj @@ -35,7 +35,7 @@ runtime; build; native; contentfiles; analyzers; buildtransitive - + diff --git a/osu.iOS.props b/osu.iOS.props index 496bfbb85c..83410b08f6 100644 --- a/osu.iOS.props +++ b/osu.iOS.props @@ -61,7 +61,7 @@ - + @@ -82,7 +82,7 @@ - + From f512106bee0ae1adc2faa16eb3abc09d3552b7a4 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 16 Sep 2022 20:00:38 +0300 Subject: [PATCH 09/27] Adjust test scene to match expectations - Adds a scenario where no button is pressed before second hitobject. - Adjusts press time to not conflict with break start time. --- .../Mods/TestSceneOsuModAlternate.cs | 31 ++++++++++++------- 1 file changed, 19 insertions(+), 12 deletions(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs index 5e46498aca..8994abcea5 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs @@ -2,6 +2,8 @@ // See the LICENCE file in the repository root for full licence text. using System.Collections.Generic; +using System.Linq; +using AutoMapper.Internal; using NUnit.Framework; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Timing; @@ -125,7 +127,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods /// Ensures alternation is reset before the first hitobject after a break. /// [Test] - public void TestInputSingularWithBreak() => CreateModTest(new ModTestData + public void TestInputSingularWithBreak([Values] bool pressBeforeSecondObject) => CreateModTest(new ModTestData { Mod = new OsuModAlternate(), PassCondition = () => Player.ScoreProcessor.Combo.Value == 0 && Player.ScoreProcessor.HighestCombo.Value == 2, @@ -155,21 +157,26 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods }, } }, - ReplayFrames = new List + ReplayFrames = new ReplayFrame[] { // first press to start alternate lock. - new OsuReplayFrame(500, new Vector2(100), OsuAction.LeftButton), - new OsuReplayFrame(501, new Vector2(100)), - // press same key after break but before hit object. - new OsuReplayFrame(2250, new Vector2(300, 100), OsuAction.LeftButton), - new OsuReplayFrame(2251, new Vector2(300, 100)), + new OsuReplayFrame(450, new Vector2(100), OsuAction.LeftButton), + new OsuReplayFrame(451, new Vector2(100)), // press same key at second hitobject and ensure it has been hit. - new OsuReplayFrame(2500, new Vector2(500, 100), OsuAction.LeftButton), - new OsuReplayFrame(2501, new Vector2(500, 100)), + new OsuReplayFrame(2450, new Vector2(500, 100), OsuAction.LeftButton), + new OsuReplayFrame(2451, new Vector2(500, 100)), // press same key at third hitobject and ensure it has been missed. - new OsuReplayFrame(3000, new Vector2(500, 100), OsuAction.LeftButton), - new OsuReplayFrame(3001, new Vector2(500, 100)), - } + new OsuReplayFrame(2950, new Vector2(500, 100), OsuAction.LeftButton), + new OsuReplayFrame(2951, new Vector2(500, 100)), + }.Concat(!pressBeforeSecondObject + ? Enumerable.Empty() + : new ReplayFrame[] + { + // press same key after break but before hit object. + new OsuReplayFrame(2250, new Vector2(300, 100), OsuAction.LeftButton), + new OsuReplayFrame(2251, new Vector2(300, 100)), + } + ).ToList() }); } } From 557b39b69b051cc4bc3e74ac9d7fc775f0dc1d21 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 16 Sep 2022 19:48:24 +0300 Subject: [PATCH 10/27] Fix `InputBlockingMod` not always clearing last action on break periods --- osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs | 11 +++++++---- 1 file changed, 7 insertions(+), 4 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs b/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs index a7aca8257b..e4e8905722 100644 --- a/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs +++ b/osu.Game.Rulesets.Osu/Mods/InputBlockingMod.cs @@ -18,7 +18,7 @@ using osu.Game.Utils; namespace osu.Game.Rulesets.Osu.Mods { - public abstract class InputBlockingMod : Mod, IApplicableToDrawableRuleset + public abstract class InputBlockingMod : Mod, IApplicableToDrawableRuleset, IUpdatableByPlayfield { public override double ScoreMultiplier => 1.0; public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(ModRelax), typeof(OsuModCinema) }; @@ -62,15 +62,18 @@ namespace osu.Game.Rulesets.Osu.Mods gameplayClock = drawableRuleset.FrameStableClock; } + public void Update(Playfield playfield) + { + if (LastAcceptedAction != null && nonGameplayPeriods.IsInAny(gameplayClock.CurrentTime)) + LastAcceptedAction = null; + } + protected abstract bool CheckValidNewAction(OsuAction action); private bool checkCorrectAction(OsuAction action) { if (nonGameplayPeriods.IsInAny(gameplayClock.CurrentTime)) - { - LastAcceptedAction = null; return true; - } switch (action) { From fe7223711890b614cdc2eabf9933d6400da73b9e Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Fri, 16 Sep 2022 20:08:50 +0300 Subject: [PATCH 11/27] Remove unused using --- osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs | 1 - 1 file changed, 1 deletion(-) diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs index 8994abcea5..521c10c10c 100644 --- a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs +++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModAlternate.cs @@ -3,7 +3,6 @@ using System.Collections.Generic; using System.Linq; -using AutoMapper.Internal; using NUnit.Framework; using osu.Game.Beatmaps; using osu.Game.Beatmaps.Timing; From 288cc7b201b8a404dc677017fe002220c4b2ab97 Mon Sep 17 00:00:00 2001 From: vegguid <75315940+vegguid@users.noreply.github.com> Date: Fri, 16 Sep 2022 21:36:17 +0200 Subject: [PATCH 12/27] Fixed Leaderboard tooltip not following time format setting --- .../Leaderboards/LeaderboardScoreTooltip.cs | 16 +++++++++++++--- 1 file changed, 13 insertions(+), 3 deletions(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs b/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs index 2f3ece0e3b..7123a274d4 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs @@ -15,6 +15,8 @@ using osu.Framework.Localisation; using osu.Game.Rulesets.Scoring; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.UI; +using osu.Framework.Bindables; +using osu.Game.Configuration; namespace osu.Game.Online.Leaderboards { @@ -24,7 +26,7 @@ namespace osu.Game.Online.Leaderboards private FillFlowContainer topScoreStatistics = null!; private FillFlowContainer bottomScoreStatistics = null!; private FillFlowContainer modStatistics = null!; - + private readonly Bindable prefer24HourTime = new Bindable(); public LeaderboardScoreTooltip() { AutoSizeAxes = Axes.Both; @@ -36,8 +38,9 @@ namespace osu.Game.Online.Leaderboards } [BackgroundDependencyLoader] - private void load(OsuColour colours) + private void load(OsuColour colours, OsuConfigManager configManager) { + configManager.BindWith(OsuSetting.Prefer24HourTime, prefer24HourTime); InternalChildren = new Drawable[] { new Box @@ -92,6 +95,13 @@ namespace osu.Game.Online.Leaderboards }; } + private void updateDisplay() + { + if (displayedScore != null) + { + timestampLabel.Text = prefer24HourTime.Value ? $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy HH:mm}" : $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy h:mm tt}"; + } + } private ScoreInfo? displayedScore; public void SetContent(ScoreInfo score) @@ -101,7 +111,7 @@ namespace osu.Game.Online.Leaderboards displayedScore = score; - timestampLabel.Text = $"Played on {score.Date.ToLocalTime():d MMMM yyyy HH:mm}"; + prefer24HourTime.BindValueChanged(_ => updateDisplay(), true); modStatistics.Clear(); topScoreStatistics.Clear(); From 0bfe967452a0ae9a910d4ca31318aed155c58608 Mon Sep 17 00:00:00 2001 From: vegguid <75315940+vegguid@users.noreply.github.com> Date: Sat, 17 Sep 2022 12:58:23 +0200 Subject: [PATCH 13/27] moved BindValueChanged to LoadComplete --- .../Leaderboards/LeaderboardScoreTooltip.cs | 19 ++++++++++++------- 1 file changed, 12 insertions(+), 7 deletions(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs b/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs index 7123a274d4..0651fe0072 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs @@ -94,13 +94,11 @@ namespace osu.Game.Online.Leaderboards } }; } - - private void updateDisplay() + protected override void LoadComplete() { - if (displayedScore != null) - { - timestampLabel.Text = prefer24HourTime.Value ? $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy HH:mm}" : $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy h:mm tt}"; - } + base.LoadComplete(); + + prefer24HourTime.BindValueChanged(_ => updateTimestampLabel(), true); } private ScoreInfo? displayedScore; @@ -111,7 +109,7 @@ namespace osu.Game.Online.Leaderboards displayedScore = score; - prefer24HourTime.BindValueChanged(_ => updateDisplay(), true); + updateTimestampLabel(); modStatistics.Clear(); topScoreStatistics.Clear(); @@ -130,6 +128,13 @@ namespace osu.Game.Online.Leaderboards topScoreStatistics.Add(new HitResultCell(result)); } } + private void updateTimestampLabel() + { + if (displayedScore != null) + { + timestampLabel.Text = prefer24HourTime.Value ? $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy HH:mm}" : $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy h:mm tt}"; + } + } protected override void PopIn() => this.FadeIn(20, Easing.OutQuint); protected override void PopOut() => this.FadeOut(80, Easing.OutQuint); From a1d830e47f3728329353a39be1fce94de727c483 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Sat, 17 Sep 2022 22:22:56 +0900 Subject: [PATCH 14/27] Fix formatting --- osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs | 8 +++++++- 1 file changed, 7 insertions(+), 1 deletion(-) diff --git a/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs b/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs index 0651fe0072..f51f57c031 100644 --- a/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs +++ b/osu.Game/Online/Leaderboards/LeaderboardScoreTooltip.cs @@ -27,6 +27,7 @@ namespace osu.Game.Online.Leaderboards private FillFlowContainer bottomScoreStatistics = null!; private FillFlowContainer modStatistics = null!; private readonly Bindable prefer24HourTime = new Bindable(); + public LeaderboardScoreTooltip() { AutoSizeAxes = Axes.Both; @@ -94,12 +95,14 @@ namespace osu.Game.Online.Leaderboards } }; } + protected override void LoadComplete() { base.LoadComplete(); prefer24HourTime.BindValueChanged(_ => updateTimestampLabel(), true); } + private ScoreInfo? displayedScore; public void SetContent(ScoreInfo score) @@ -128,11 +131,14 @@ namespace osu.Game.Online.Leaderboards topScoreStatistics.Add(new HitResultCell(result)); } } + private void updateTimestampLabel() { if (displayedScore != null) { - timestampLabel.Text = prefer24HourTime.Value ? $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy HH:mm}" : $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy h:mm tt}"; + timestampLabel.Text = prefer24HourTime.Value + ? $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy HH:mm}" + : $"Played on {displayedScore.Date.ToLocalTime():d MMMM yyyy h:mm tt}"; } } From 0b6a77bc8bd90c76aa9fbf491d6542e5e7dff887 Mon Sep 17 00:00:00 2001 From: Drison64 Date: Sat, 17 Sep 2022 15:59:42 +0200 Subject: [PATCH 15/27] EditorBeatmap's TimelineZoom should never be zero --- osu.Game/Screens/Edit/EditorBeatmap.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 16c0064e80..356276039c 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -96,6 +96,7 @@ namespace osu.Game.Screens.Edit PlayableBeatmap.ControlPointInfo = ConvertControlPoints(PlayableBeatmap.ControlPointInfo); this.beatmapInfo = beatmapInfo ?? playableBeatmap.BeatmapInfo; + if (this.beatmapInfo.TimelineZoom <= 0) this.beatmapInfo.TimelineZoom = 1; if (beatmapSkin is Skin skin) { From 9a10ecb3789630bd3715ce5e38ffd2cfe5bc1b24 Mon Sep 17 00:00:00 2001 From: Salman Ahmed Date: Sat, 17 Sep 2022 19:37:30 +0300 Subject: [PATCH 16/27] Clarify purpose of `APIUserScoreAggregate` --- .../Online/API/Requests/Responses/APIUserScoreAggregate.cs | 3 +++ 1 file changed, 3 insertions(+) diff --git a/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs b/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs index 30433ab8cd..c870157fec 100644 --- a/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs +++ b/osu.Game/Online/API/Requests/Responses/APIUserScoreAggregate.cs @@ -10,6 +10,9 @@ using osu.Game.Scoring; namespace osu.Game.Online.API.Requests.Responses { + /// + /// Represents an aggregate score for a user based off all beatmaps that have been played in the playlist. + /// public class APIUserScoreAggregate { [JsonProperty("attempts")] From 3c7ea5c8fadbc0348f5f84304c2872ff1d831a64 Mon Sep 17 00:00:00 2001 From: Drison64 Date: Sat, 17 Sep 2022 18:57:09 +0200 Subject: [PATCH 17/27] Update --- osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs | 2 +- osu.Game/Screens/Edit/EditorBeatmap.cs | 1 - 2 files changed, 1 insertion(+), 2 deletions(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 9e96a7386d..721f0c4e3b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -196,7 +196,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { defaultTimelineZoom = getZoomLevelForVisibleMilliseconds(6000); - float initialZoom = (float)(defaultTimelineZoom * editorBeatmap.BeatmapInfo.TimelineZoom); + float initialZoom = (float)(defaultTimelineZoom * (editorBeatmap.BeatmapInfo.TimelineZoom == 0 ? 1 : editorBeatmap.BeatmapInfo.TimelineZoom)); float minimumZoom = getZoomLevelForVisibleMilliseconds(10000); float maximumZoom = getZoomLevelForVisibleMilliseconds(500); diff --git a/osu.Game/Screens/Edit/EditorBeatmap.cs b/osu.Game/Screens/Edit/EditorBeatmap.cs index 356276039c..16c0064e80 100644 --- a/osu.Game/Screens/Edit/EditorBeatmap.cs +++ b/osu.Game/Screens/Edit/EditorBeatmap.cs @@ -96,7 +96,6 @@ namespace osu.Game.Screens.Edit PlayableBeatmap.ControlPointInfo = ConvertControlPoints(PlayableBeatmap.ControlPointInfo); this.beatmapInfo = beatmapInfo ?? playableBeatmap.BeatmapInfo; - if (this.beatmapInfo.TimelineZoom <= 0) this.beatmapInfo.TimelineZoom = 1; if (beatmapSkin is Skin skin) { From c8768eb39919c649556a4bb508f1bbde4863a765 Mon Sep 17 00:00:00 2001 From: Drison64 Date: Sat, 17 Sep 2022 19:00:50 +0200 Subject: [PATCH 18/27] Changed == to <= on TimelineZoom check --- osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 721f0c4e3b..09fa2c8cee 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -196,7 +196,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { defaultTimelineZoom = getZoomLevelForVisibleMilliseconds(6000); - float initialZoom = (float)(defaultTimelineZoom * (editorBeatmap.BeatmapInfo.TimelineZoom == 0 ? 1 : editorBeatmap.BeatmapInfo.TimelineZoom)); + float initialZoom = (float)(defaultTimelineZoom * (editorBeatmap.BeatmapInfo.TimelineZoom <= 0 ? 1 : editorBeatmap.BeatmapInfo.TimelineZoom)); float minimumZoom = getZoomLevelForVisibleMilliseconds(10000); float maximumZoom = getZoomLevelForVisibleMilliseconds(500); From 9d94343317a00d8cf122b88baf7757cd4c584fae Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Ond=C5=99ej=20Vaj=C4=8F=C3=A1k?= Date: Sat, 17 Sep 2022 19:51:44 +0200 Subject: [PATCH 19/27] Update osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs Co-authored-by: Salman Ahmed --- osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs index 09fa2c8cee..721f0c4e3b 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/Timeline.cs @@ -196,7 +196,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline { defaultTimelineZoom = getZoomLevelForVisibleMilliseconds(6000); - float initialZoom = (float)(defaultTimelineZoom * (editorBeatmap.BeatmapInfo.TimelineZoom <= 0 ? 1 : editorBeatmap.BeatmapInfo.TimelineZoom)); + float initialZoom = (float)(defaultTimelineZoom * (editorBeatmap.BeatmapInfo.TimelineZoom == 0 ? 1 : editorBeatmap.BeatmapInfo.TimelineZoom)); float minimumZoom = getZoomLevelForVisibleMilliseconds(10000); float maximumZoom = getZoomLevelForVisibleMilliseconds(500); From c075d3de08accdd9f49d1e347a3aad4b6607a078 Mon Sep 17 00:00:00 2001 From: Drison64 Date: Sat, 17 Sep 2022 22:43:40 +0200 Subject: [PATCH 20/27] Create a test and a check if initial zoom value of ZoomableScrollContainer is in range --- .../Editing/TestSceneZoomableScrollContainer.cs | 13 +++++++++++++ .../Components/Timeline/ZoomableScrollContainer.cs | 3 +++ 2 files changed, 16 insertions(+) diff --git a/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs b/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs index ce418f33f0..1858aee76b 100644 --- a/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs +++ b/osu.Game.Tests/Visual/Editing/TestSceneZoomableScrollContainer.cs @@ -3,6 +3,7 @@ #nullable disable +using System; using NUnit.Framework; using osu.Framework.Graphics; using osu.Framework.Graphics.Colour; @@ -66,6 +67,18 @@ namespace osu.Game.Tests.Visual.Editing AddUntilStep("Scroll container is loaded", () => scrollContainer.LoadState >= LoadState.Loaded); } + [Test] + public void TestInitialZoomOutOfRange() + { + AddStep("Invalid ZoomableScrollContainer throws ArgumentException", () => + { + Assert.Throws(() => + { + _ = new ZoomableScrollContainer(1, 60, 0); + }); + }); + } + [Test] public void TestWidthInitialization() { diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs index 7d51284f46..0fb59a8a1f 100644 --- a/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs +++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/ZoomableScrollContainer.cs @@ -87,6 +87,9 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline if (minimum > maximum) throw new ArgumentException($"{nameof(minimum)} ({minimum}) must be less than {nameof(maximum)} ({maximum})"); + if (initial < minimum || initial > maximum) + throw new ArgumentException($"{nameof(initial)} ({initial}) must be between {nameof(minimum)} ({minimum}) and {nameof(maximum)} ({maximum})"); + minZoom = minimum; maxZoom = maximum; CurrentZoom = zoomTarget = initial; From beef3b418ad1e1ba4023a55348992f69e40fbcde Mon Sep 17 00:00:00 2001 From: O Thiago Date: Sat, 17 Sep 2022 23:41:23 -0400 Subject: [PATCH 21/27] Simplifies size calculation --- osu.Game/Rulesets/Mods/ModFlashlight.cs | 17 +++++++++-------- 1 file changed, 9 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 558605efc3..a34e55faae 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -50,6 +50,11 @@ namespace osu.Game.Rulesets.Mods where T : HitObject { public const double FLASHLIGHT_FADE_DURATION = 800; + + private const int flashlight_size_decrease_combo = 100; + private const int last_flashlight_size_decrease_combo = 200; + private const float decrease_flashlight_with_combo_multiplier = 0.1f; + protected readonly BindableInt Combo = new BindableInt(); public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) @@ -147,16 +152,12 @@ namespace osu.Game.Rulesets.Mods protected float GetSizeFor(int combo) { float size = defaultFlashlightSize * sizeMultiplier; + int comboForSize = Math.Min(combo, last_flashlight_size_decrease_combo); - if (comboBasedSize) - { - if (combo > 200) - size *= 0.8f; - else if (combo > 100) - size *= 0.9f; - } + if (!comboBasedSize) + comboForSize = 0; - return size; + return size * (1 - decrease_flashlight_with_combo_multiplier * MathF.Floor(MathF.Min(comboForSize, last_flashlight_size_decrease_combo) / flashlight_size_decrease_combo)); } private Vector2 flashlightPosition; From 8464a1941bef4c47a949a1c935bdc58aa2b8791f Mon Sep 17 00:00:00 2001 From: O Thiago Date: Sat, 17 Sep 2022 23:49:23 -0400 Subject: [PATCH 22/27] Use linq expression for handling breaks --- osu.Game/Rulesets/Mods/ModFlashlight.cs | 8 ++------ 1 file changed, 2 insertions(+), 6 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index a34e55faae..f43f54541d 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -3,6 +3,7 @@ using System; using System.Collections.Generic; +using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -132,13 +133,8 @@ namespace osu.Game.Rulesets.Mods using (BeginAbsoluteSequence(0)) { - foreach (var breakPeriod in Breaks) + foreach (BreakPeriod breakPeriod in Breaks.Where(breakPeriod => breakPeriod.HasEffect && breakPeriod.Duration >= FLASHLIGHT_FADE_DURATION * 2)) { - if (!breakPeriod.HasEffect) - continue; - - if (breakPeriod.Duration < FLASHLIGHT_FADE_DURATION * 2) continue; - this.Delay(breakPeriod.StartTime + FLASHLIGHT_FADE_DURATION).FadeOutFromOne(FLASHLIGHT_FADE_DURATION); this.Delay(breakPeriod.EndTime - FLASHLIGHT_FADE_DURATION).FadeInFromZero(FLASHLIGHT_FADE_DURATION); } From 3b87ecf56c0f473b7081bad10e715825becbc6b8 Mon Sep 17 00:00:00 2001 From: O Thiago Date: Sun, 18 Sep 2022 00:18:17 -0400 Subject: [PATCH 23/27] renames variables to make more logical sense --- osu.Game/Rulesets/Mods/ModFlashlight.cs | 10 +++++----- 1 file changed, 5 insertions(+), 5 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index f43f54541d..4d24bdfa02 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -53,8 +53,8 @@ namespace osu.Game.Rulesets.Mods public const double FLASHLIGHT_FADE_DURATION = 800; private const int flashlight_size_decrease_combo = 100; - private const int last_flashlight_size_decrease_combo = 200; - private const float decrease_flashlight_with_combo_multiplier = 0.1f; + private const int flashlight_size_decrease_combo_max = 200; + private const float flashlight_size_decrease_with_combo_multiplier = 0.1f; protected readonly BindableInt Combo = new BindableInt(); @@ -133,7 +133,7 @@ namespace osu.Game.Rulesets.Mods using (BeginAbsoluteSequence(0)) { - foreach (BreakPeriod breakPeriod in Breaks.Where(breakPeriod => breakPeriod.HasEffect && breakPeriod.Duration >= FLASHLIGHT_FADE_DURATION * 2)) + foreach (var breakPeriod in Breaks.Where(breakPeriod => breakPeriod.HasEffect && breakPeriod.Duration >= FLASHLIGHT_FADE_DURATION * 2)) { this.Delay(breakPeriod.StartTime + FLASHLIGHT_FADE_DURATION).FadeOutFromOne(FLASHLIGHT_FADE_DURATION); this.Delay(breakPeriod.EndTime - FLASHLIGHT_FADE_DURATION).FadeInFromZero(FLASHLIGHT_FADE_DURATION); @@ -148,12 +148,12 @@ namespace osu.Game.Rulesets.Mods protected float GetSizeFor(int combo) { float size = defaultFlashlightSize * sizeMultiplier; - int comboForSize = Math.Min(combo, last_flashlight_size_decrease_combo); + int comboForSize = Math.Min(combo, flashlight_size_decrease_combo_max); if (!comboBasedSize) comboForSize = 0; - return size * (1 - decrease_flashlight_with_combo_multiplier * MathF.Floor(MathF.Min(comboForSize, last_flashlight_size_decrease_combo) / flashlight_size_decrease_combo)); + return size * (1 - flashlight_size_decrease_with_combo_multiplier * MathF.Floor(MathF.Min(comboForSize, flashlight_size_decrease_combo_max) / flashlight_size_decrease_combo)); } private Vector2 flashlightPosition; From ac4229e3d4654b07758617e6c274d7cde550caad Mon Sep 17 00:00:00 2001 From: O Thiago Date: Sun, 18 Sep 2022 00:38:01 -0400 Subject: [PATCH 24/27] Removes overhead when not combo based size --- osu.Game/Rulesets/Mods/ModFlashlight.cs | 7 +++---- 1 file changed, 3 insertions(+), 4 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 4d24bdfa02..490f9120b1 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -148,12 +148,11 @@ namespace osu.Game.Rulesets.Mods protected float GetSizeFor(int combo) { float size = defaultFlashlightSize * sizeMultiplier; - int comboForSize = Math.Min(combo, flashlight_size_decrease_combo_max); - if (!comboBasedSize) - comboForSize = 0; + if (comboBasedSize) + size *= 1 - flashlight_size_decrease_with_combo_multiplier * MathF.Floor(MathF.Min(combo, flashlight_size_decrease_combo_max) / flashlight_size_decrease_combo); - return size * (1 - flashlight_size_decrease_with_combo_multiplier * MathF.Floor(MathF.Min(comboForSize, flashlight_size_decrease_combo_max) / flashlight_size_decrease_combo)); + return size; } private Vector2 flashlightPosition; From 2dcaf7cfd8ee9294cc6c7162d01520f24e9e0691 Mon Sep 17 00:00:00 2001 From: Dan Balasescu Date: Sun, 18 Sep 2022 14:25:31 +0900 Subject: [PATCH 25/27] Fix memory leak due to missing event unbind --- .../Screens/OnlinePlay/Multiplayer/MultiplayerRoomComposite.cs | 1 + 1 file changed, 1 insertion(+) diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomComposite.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomComposite.cs index 1f80c47d13..5a297f18db 100644 --- a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomComposite.cs +++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomComposite.cs @@ -110,6 +110,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer if (Client != null) { Client.RoomUpdated -= invokeOnRoomUpdated; + Client.LoadRequested -= invokeOnRoomLoadRequested; Client.UserLeft -= invokeUserLeft; Client.UserKicked -= invokeUserKicked; Client.UserJoined -= invokeUserJoined; From 407b104116c45f99d21d9cd9bde842d5984b8178 Mon Sep 17 00:00:00 2001 From: O Thiago Date: Sun, 18 Sep 2022 18:55:47 -0400 Subject: [PATCH 26/27] Revert changes This reverts commit beef3b418ad1e1ba4023a55348992f69e40fbcde. Revert "Use linq expression for handling breaks" This reverts commit 8464a1941bef4c47a949a1c935bdc58aa2b8791f. Revert "renames variables to make more logical sense" This reverts commit 3b87ecf56c0f473b7081bad10e715825becbc6b8. Revert "Removes overhead when not combo based size" This reverts commit ac4229e3d4654b07758617e6c274d7cde550caad. --- osu.Game/Rulesets/Mods/ModFlashlight.cs | 20 ++++++++++++-------- 1 file changed, 12 insertions(+), 8 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 490f9120b1..558605efc3 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -3,7 +3,6 @@ using System; using System.Collections.Generic; -using System.Linq; using osu.Framework.Allocation; using osu.Framework.Bindables; using osu.Framework.Graphics; @@ -51,11 +50,6 @@ namespace osu.Game.Rulesets.Mods where T : HitObject { public const double FLASHLIGHT_FADE_DURATION = 800; - - private const int flashlight_size_decrease_combo = 100; - private const int flashlight_size_decrease_combo_max = 200; - private const float flashlight_size_decrease_with_combo_multiplier = 0.1f; - protected readonly BindableInt Combo = new BindableInt(); public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor) @@ -133,8 +127,13 @@ namespace osu.Game.Rulesets.Mods using (BeginAbsoluteSequence(0)) { - foreach (var breakPeriod in Breaks.Where(breakPeriod => breakPeriod.HasEffect && breakPeriod.Duration >= FLASHLIGHT_FADE_DURATION * 2)) + foreach (var breakPeriod in Breaks) { + if (!breakPeriod.HasEffect) + continue; + + if (breakPeriod.Duration < FLASHLIGHT_FADE_DURATION * 2) continue; + this.Delay(breakPeriod.StartTime + FLASHLIGHT_FADE_DURATION).FadeOutFromOne(FLASHLIGHT_FADE_DURATION); this.Delay(breakPeriod.EndTime - FLASHLIGHT_FADE_DURATION).FadeInFromZero(FLASHLIGHT_FADE_DURATION); } @@ -150,7 +149,12 @@ namespace osu.Game.Rulesets.Mods float size = defaultFlashlightSize * sizeMultiplier; if (comboBasedSize) - size *= 1 - flashlight_size_decrease_with_combo_multiplier * MathF.Floor(MathF.Min(combo, flashlight_size_decrease_combo_max) / flashlight_size_decrease_combo); + { + if (combo > 200) + size *= 0.8f; + else if (combo > 100) + size *= 0.9f; + } return size; } From a4e9c7711c4b042101d6499a8b30d5fe27bf567c Mon Sep 17 00:00:00 2001 From: O Thiago Date: Sun, 18 Sep 2022 18:59:17 -0400 Subject: [PATCH 27/27] Fix when flashlight shrinking takes place --- osu.Game/Rulesets/Mods/ModFlashlight.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs index 558605efc3..6d7706cde2 100644 --- a/osu.Game/Rulesets/Mods/ModFlashlight.cs +++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs @@ -150,9 +150,9 @@ namespace osu.Game.Rulesets.Mods if (comboBasedSize) { - if (combo > 200) + if (combo >= 200) size *= 0.8f; - else if (combo > 100) + else if (combo >= 100) size *= 0.9f; }