From 45ce6cc82d54e16529e4fd892237e4c892d2608e Mon Sep 17 00:00:00 2001 From: kamp Date: Fri, 13 Nov 2020 00:36:47 +0100 Subject: [PATCH 1/7] Allow spinners to be reversed --- osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs index a72dcff1e9..ec0a6a2bcc 100644 --- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs +++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs @@ -45,12 +45,12 @@ namespace osu.Game.Rulesets.Osu.Edit public override bool HandleReverse() { - var hitObjects = selectedMovableObjects; + var hitObjects = EditorBeatmap.SelectedHitObjects; double endTime = hitObjects.Max(h => h.GetEndTime()); double startTime = hitObjects.Min(h => h.StartTime); - bool moreThanOneObject = hitObjects.Length > 1; + bool moreThanOneObject = hitObjects.Count > 1; foreach (var h in hitObjects) { From 43626573df0308b599d32499feb65458dc883277 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Nov 2020 13:15:54 +0900 Subject: [PATCH 2/7] Fix combo break sounds playing when seeking --- osu.Game/Screens/Play/ComboEffects.cs | 11 ++++++++++- 1 file changed, 10 insertions(+), 1 deletion(-) diff --git a/osu.Game/Screens/Play/ComboEffects.cs b/osu.Game/Screens/Play/ComboEffects.cs index 831b2f593c..f22fd541d0 100644 --- a/osu.Game/Screens/Play/ComboEffects.cs +++ b/osu.Game/Screens/Play/ComboEffects.cs @@ -38,12 +38,21 @@ namespace osu.Game.Screens.Play processor.Combo.BindValueChanged(onComboChange); } + [Resolved(canBeNull: true)] + private ISamplePlaybackDisabler samplePlaybackDisabler { get; set; } + private void onComboChange(ValueChangedEvent combo) { if (combo.NewValue == 0 && (combo.OldValue > 20 || (alwaysPlay.Value && firstTime))) { - comboBreakSample?.Play(); firstTime = false; + + // combo break isn't a pausable sound itself as we want to let it play out. + // we still need to disable during seeks, though. + if (samplePlaybackDisabler?.SamplePlaybackDisabled.Value == true) + return; + + comboBreakSample?.Play(); } } } From 4b5743d993c5a8b9a2f279e6c6ef6df02540cb4b Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Nov 2020 13:35:01 +0900 Subject: [PATCH 3/7] Fix combo break sound not playing after rewind --- osu.Game/Screens/Play/ComboEffects.cs | 21 ++++++++++++++++----- osu.Game/Screens/Play/Player.cs | 2 +- 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/osu.Game/Screens/Play/ComboEffects.cs b/osu.Game/Screens/Play/ComboEffects.cs index f22fd541d0..5041d07e5d 100644 --- a/osu.Game/Screens/Play/ComboEffects.cs +++ b/osu.Game/Screens/Play/ComboEffects.cs @@ -17,8 +17,9 @@ namespace osu.Game.Screens.Play private SkinnableSound comboBreakSample; - private Bindable alwaysPlay; - private bool firstTime = true; + private Bindable alwaysPlayFirst; + + private double? firstBreakTime; public ComboEffects(ScoreProcessor processor) { @@ -29,7 +30,7 @@ namespace osu.Game.Screens.Play private void load(OsuConfigManager config) { InternalChild = comboBreakSample = new SkinnableSound(new SampleInfo("Gameplay/combobreak")); - alwaysPlay = config.GetBindable(OsuSetting.AlwaysPlayFirstComboBreak); + alwaysPlayFirst = config.GetBindable(OsuSetting.AlwaysPlayFirstComboBreak); } protected override void LoadComplete() @@ -41,11 +42,21 @@ namespace osu.Game.Screens.Play [Resolved(canBeNull: true)] private ISamplePlaybackDisabler samplePlaybackDisabler { get; set; } + [Resolved] + private GameplayClock gameplayClock { get; set; } + private void onComboChange(ValueChangedEvent combo) { - if (combo.NewValue == 0 && (combo.OldValue > 20 || (alwaysPlay.Value && firstTime))) + // handle the case of rewinding before the first combo break time. + if (gameplayClock.CurrentTime < firstBreakTime) + firstBreakTime = null; + + if (gameplayClock.ElapsedFrameTime < 0) + return; + + if (combo.NewValue == 0 && (combo.OldValue > 20 || (alwaysPlayFirst.Value && firstBreakTime == null))) { - firstTime = false; + firstBreakTime = gameplayClock.CurrentTime; // combo break isn't a pausable sound itself as we want to let it play out. // we still need to disable during seeks, though. diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs index f9af1818d0..49cc390775 100644 --- a/osu.Game/Screens/Play/Player.cs +++ b/osu.Game/Screens/Play/Player.cs @@ -302,12 +302,12 @@ namespace osu.Game.Screens.Play { ScoreProcessor, HealthProcessor, + new ComboEffects(ScoreProcessor), breakTracker = new BreakTracker(DrawableRuleset.GameplayStartTime, ScoreProcessor) { Breaks = working.Beatmap.Breaks } }), - new ComboEffects(ScoreProcessor) } }; From a2c81a3a52f8daf0d81aee1626b7e48dbd91c2e4 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Nov 2020 13:42:00 +0900 Subject: [PATCH 4/7] Add back setting to toggle "always play first combo break" --- .../Overlays/Settings/Sections/Gameplay/GeneralSettings.cs | 5 +++++ 1 file changed, 5 insertions(+) diff --git a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs index 9cb02ff3b9..be464fa2b7 100644 --- a/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs +++ b/osu.Game/Overlays/Settings/Sections/Gameplay/GeneralSettings.cs @@ -68,6 +68,11 @@ namespace osu.Game.Overlays.Settings.Sections.Gameplay LabelText = "Positional hitsounds", Current = config.GetBindable(OsuSetting.PositionalHitSounds) }, + new SettingsCheckbox + { + LabelText = "Always play first combo break sound", + Current = config.GetBindable(OsuSetting.AlwaysPlayFirstComboBreak) + }, new SettingsEnumDropdown { LabelText = "Score meter type", From 0985cb3327421220f0634d567a07f3a2688ed0a7 Mon Sep 17 00:00:00 2001 From: Dean Herbert Date: Fri, 13 Nov 2020 14:08:08 +0900 Subject: [PATCH 5/7] Fix perform from menu not hiding overlays if already on target screen --- .../Navigation/TestScenePerformFromScreen.cs | 19 +++++++++++++++++++ osu.Game/PerformFromMenuRunner.cs | 4 ++-- 2 files changed, 21 insertions(+), 2 deletions(-) diff --git a/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs b/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs index a4190e0b84..21d3bdaae3 100644 --- a/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs +++ b/osu.Game.Tests/Visual/Navigation/TestScenePerformFromScreen.cs @@ -1,9 +1,12 @@ // 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.Allocation; +using osu.Framework.Graphics.Containers; using osu.Framework.Screens; +using osu.Framework.Testing; using osu.Game.Overlays; using osu.Game.Screens; using osu.Game.Screens.Menu; @@ -73,6 +76,22 @@ namespace osu.Game.Tests.Visual.Navigation AddAssert("did perform", () => actionPerformed); } + [Test] + public void TestOverlaysAlwaysClosed() + { + ChatOverlay chat = null; + AddUntilStep("is at menu", () => Game.ScreenStack.CurrentScreen is MainMenu); + AddUntilStep("wait for chat load", () => (chat = Game.ChildrenOfType().SingleOrDefault()) != null); + + AddStep("show chat", () => InputManager.Key(Key.F8)); + + AddStep("try to perform", () => Game.PerformFromScreen(_ => actionPerformed = true)); + + AddUntilStep("still at menu", () => Game.ScreenStack.CurrentScreen is MainMenu); + AddAssert("did perform", () => actionPerformed); + AddAssert("chat closed", () => chat.State.Value == Visibility.Hidden); + } + [TestCase(true)] [TestCase(false)] public void TestPerformBlockedByDialog(bool confirmed) diff --git a/osu.Game/PerformFromMenuRunner.cs b/osu.Game/PerformFromMenuRunner.cs index 9afe87f74f..5898c116dd 100644 --- a/osu.Game/PerformFromMenuRunner.cs +++ b/osu.Game/PerformFromMenuRunner.cs @@ -76,6 +76,8 @@ namespace osu.Game // a dialog may be blocking the execution for now. if (checkForDialog(current)) return; + game.CloseAllOverlays(false); + // we may already be at the target screen type. if (validScreens.Contains(getCurrentScreen().GetType()) && !beatmap.Disabled) { @@ -83,8 +85,6 @@ namespace osu.Game return; } - game.CloseAllOverlays(false); - while (current != null) { if (validScreens.Contains(current.GetType())) From 21b015d63afffa9b0acdb0027f37d0b228614698 Mon Sep 17 00:00:00 2001 From: smoogipoo Date: Sat, 14 Nov 2020 01:06:38 +0900 Subject: [PATCH 6/7] Remove explicit public --- osu.Game/Rulesets/UI/IPooledHitObjectProvider.cs | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) diff --git a/osu.Game/Rulesets/UI/IPooledHitObjectProvider.cs b/osu.Game/Rulesets/UI/IPooledHitObjectProvider.cs index d8240d892f..315926dfc6 100644 --- a/osu.Game/Rulesets/UI/IPooledHitObjectProvider.cs +++ b/osu.Game/Rulesets/UI/IPooledHitObjectProvider.cs @@ -15,6 +15,6 @@ namespace osu.Game.Rulesets.UI /// The to retrieve the representation of. /// The representing , or null if no poolable representation exists. [CanBeNull] - public DrawableHitObject GetPooledDrawableRepresentation([NotNull] HitObject hitObject); + DrawableHitObject GetPooledDrawableRepresentation([NotNull] HitObject hitObject); } } From 7a89e58483a998a484a944acd5edf4c61bdcbdcf Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Bart=C5=82omiej=20Dach?= Date: Fri, 13 Nov 2020 20:49:06 +0100 Subject: [PATCH 7/7] Disable pressed/released action logic when rewinding --- .../Objects/Drawables/DrawableHoldNote.cs | 8 ++++++++ 1 file changed, 8 insertions(+) diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs index d9d740c145..59899637f9 100644 --- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs +++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs @@ -249,6 +249,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (action != Action.Value) return false; + // do not run any of this logic when rewinding, as it inverts order of presses/releases. + if (Time.Elapsed < 0) + return false; + if (CheckHittable?.Invoke(this, Time.Current) == false) return false; @@ -281,6 +285,10 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables if (action != Action.Value) return; + // do not run any of this logic when rewinding, as it inverts order of presses/releases. + if (Time.Elapsed < 0) + return; + // Make sure a hold was started if (HoldStartTime == null) return;