diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs index 347b4b6c54..b7a74dcd27 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs @@ -59,8 +59,7 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for player", () => { - // dismiss any notifications that may appear (ie. muted notification). - clickMouseInCentre(); + DismissAnyNotifications(); return player != null; }); @@ -73,12 +72,6 @@ namespace osu.Game.Tests.Visual.Navigation AddAssert("key counter did increase", () => keyCounter.CountPresses == 1); } - private void clickMouseInCentre() - { - InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.Centre); - InputManager.Click(MouseButton.Left); - } - private KeyBindingsSubsection osuBindingSubsection => keyBindingPanel .ChildrenOfType() .FirstOrDefault(s => s.Ruleset.ShortName == "osu"); diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneMouseWheelVolumeAdjust.cs b/osu.Game.Tests/Visual/Navigation/TestSceneMouseWheelVolumeAdjust.cs index 22a00a3e5a..2662b3930c 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneMouseWheelVolumeAdjust.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneMouseWheelVolumeAdjust.cs @@ -89,18 +89,11 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for player", () => { - // dismiss any notifications that may appear (ie. muted notification). - clickMouseInCentre(); + DismissAnyNotifications(); return (player = Game.ScreenStack.CurrentScreen as Player) != null; }); AddUntilStep("wait for play time active", () => !player.IsBreakTime.Value); } - - private void clickMouseInCentre() - { - InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.Centre); - InputManager.Click(MouseButton.Left); - } } } diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs index 0b7242eee0..a1f41d4caf 100644 --- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs +++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs @@ -8,7 +8,6 @@ using osu.Framework.Allocation; using osu.Framework.Extensions; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; -using osu.Framework.Graphics.UserInterface; using osu.Framework.Screens; using osu.Framework.Testing; using osu.Game.Beatmaps; @@ -16,7 +15,6 @@ using osu.Game.Graphics.UserInterface; using osu.Game.Online.Leaderboards; using osu.Game.Overlays; using osu.Game.Overlays.Mods; -using osu.Game.Overlays.Settings; using osu.Game.Overlays.Toolbar; using osu.Game.Rulesets.Mods; using osu.Game.Rulesets.Osu.Mods; @@ -24,12 +22,10 @@ using osu.Game.Scoring; using osu.Game.Screens.Menu; using osu.Game.Screens.OnlinePlay.Lounge; using osu.Game.Screens.Play; -using osu.Game.Screens.Play.HUD.HitErrorMeters; using osu.Game.Screens.Ranking; using osu.Game.Screens.Select; using osu.Game.Screens.Select.Leaderboards; using osu.Game.Screens.Select.Options; -using osu.Game.Skinning.Editor; using osu.Game.Tests.Beatmaps.IO; using osuTK; using osuTK.Input; @@ -71,73 +67,6 @@ namespace osu.Game.Tests.Visual.Navigation AddAssert("Overlay was shown", () => songSelect.ModSelectOverlay.State.Value == Visibility.Visible); } - [Test] - public void TestEditComponentDuringGameplay() - { - Screens.Select.SongSelect songSelect = null; - PushAndConfirm(() => songSelect = new TestPlaySongSelect()); - AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded); - - AddStep("import beatmap", () => BeatmapImportHelper.LoadQuickOszIntoOsu(Game).WaitSafely()); - - AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault); - - SkinEditor skinEditor = null; - - AddStep("open skin editor", () => - { - InputManager.PressKey(Key.ControlLeft); - InputManager.PressKey(Key.ShiftLeft); - InputManager.Key(Key.S); - InputManager.ReleaseKey(Key.ControlLeft); - InputManager.ReleaseKey(Key.ShiftLeft); - }); - - AddUntilStep("get skin editor", () => (skinEditor = Game.ChildrenOfType().FirstOrDefault()) != null); - - AddStep("Click gameplay scene button", () => - { - skinEditor.ChildrenOfType().First(b => b.Text == "Gameplay").TriggerClick(); - }); - - AddUntilStep("wait for player", () => - { - // dismiss any notifications that may appear (ie. muted notification). - clickMouseInCentre(); - return Game.ScreenStack.CurrentScreen is Player; - }); - - BarHitErrorMeter hitErrorMeter = null; - - AddUntilStep("select bar hit error blueprint", () => - { - var blueprint = skinEditor.ChildrenOfType().FirstOrDefault(b => b.Item is BarHitErrorMeter); - - if (blueprint == null) - return false; - - hitErrorMeter = (BarHitErrorMeter)blueprint.Item; - skinEditor.SelectedComponents.Clear(); - skinEditor.SelectedComponents.Add(blueprint.Item); - return true; - }); - - AddAssert("value is default", () => hitErrorMeter.JudgementLineThickness.IsDefault); - - AddStep("hover first slider", () => - { - InputManager.MoveMouseTo( - skinEditor.ChildrenOfType().First() - .ChildrenOfType>().First() - .ChildrenOfType>().First() - ); - }); - - AddStep("adjust slider via keyboard", () => InputManager.Key(Key.Left)); - - AddAssert("value is less than default", () => hitErrorMeter.JudgementLineThickness.Value < hitErrorMeter.JudgementLineThickness.Default); - } - [Test] public void TestRetryCountIncrements() { @@ -155,8 +84,7 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for player", () => { - // dismiss any notifications that may appear (ie. muted notification). - clickMouseInCentre(); + DismissAnyNotifications(); return (player = Game.ScreenStack.CurrentScreen as Player) != null; }); @@ -280,8 +208,7 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for player", () => { - // dismiss any notifications that may appear (ie. muted notification). - clickMouseInCentre(); + DismissAnyNotifications(); return (player = Game.ScreenStack.CurrentScreen as Player) != null; }); @@ -596,8 +523,7 @@ namespace osu.Game.Tests.Visual.Navigation AddUntilStep("wait for player", () => { - // dismiss any notifications that may appear (ie. muted notification). - clickMouseInCentre(); + DismissAnyNotifications(); return (player = Game.ScreenStack.CurrentScreen as Player) != null; }); @@ -607,12 +533,6 @@ namespace osu.Game.Tests.Visual.Navigation return () => player; } - private void clickMouseInCentre() - { - InputManager.MoveMouseTo(Game.ScreenSpaceDrawQuad.Centre); - InputManager.Click(MouseButton.Left); - } - private void pushEscape() => AddStep("Press escape", () => InputManager.Key(Key.Escape)); diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorSceneLibrary.cs b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorSceneLibrary.cs new file mode 100644 index 0000000000..d3aeba2c0f --- /dev/null +++ b/osu.Game.Tests/Visual/Navigation/TestSceneSkinEditorSceneLibrary.cs @@ -0,0 +1,136 @@ +// 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.Extensions; +using osu.Framework.Graphics.UserInterface; +using osu.Framework.Testing; +using osu.Game.Overlays.Settings; +using osu.Game.Rulesets.Mods; +using osu.Game.Rulesets.Osu.Mods; +using osu.Game.Screens.Play; +using osu.Game.Screens.Play.HUD.HitErrorMeters; +using osu.Game.Skinning.Editor; +using osu.Game.Tests.Beatmaps.IO; +using osuTK.Input; +using static osu.Game.Tests.Visual.Navigation.TestSceneScreenNavigation; + +namespace osu.Game.Tests.Visual.Navigation +{ + public class TestSceneSkinEditorSceneLibrary : OsuGameTestScene + { + private SkinEditor skinEditor; + + public override void SetUpSteps() + { + base.SetUpSteps(); + + Screens.Select.SongSelect songSelect = null; + PushAndConfirm(() => songSelect = new TestPlaySongSelect()); + AddUntilStep("wait for song select", () => songSelect.BeatmapSetsLoaded); + + AddStep("import beatmap", () => BeatmapImportHelper.LoadQuickOszIntoOsu(Game).WaitSafely()); + + AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault); + + AddStep("open skin editor", () => + { + InputManager.PressKey(Key.ControlLeft); + InputManager.PressKey(Key.ShiftLeft); + InputManager.Key(Key.S); + InputManager.ReleaseKey(Key.ControlLeft); + InputManager.ReleaseKey(Key.ShiftLeft); + }); + + AddUntilStep("get skin editor", () => (skinEditor = Game.ChildrenOfType().FirstOrDefault()) != null); + } + + [Test] + public void TestEditComponentDuringGameplay() + { + switchToGameplayScene(); + + BarHitErrorMeter hitErrorMeter = null; + + AddUntilStep("select bar hit error blueprint", () => + { + var blueprint = skinEditor.ChildrenOfType().FirstOrDefault(b => b.Item is BarHitErrorMeter); + + if (blueprint == null) + return false; + + hitErrorMeter = (BarHitErrorMeter)blueprint.Item; + skinEditor.SelectedComponents.Clear(); + skinEditor.SelectedComponents.Add(blueprint.Item); + return true; + }); + + AddAssert("value is default", () => hitErrorMeter.JudgementLineThickness.IsDefault); + + AddStep("hover first slider", () => + { + InputManager.MoveMouseTo( + skinEditor.ChildrenOfType().First() + .ChildrenOfType>().First() + .ChildrenOfType>().First() + ); + }); + + AddStep("adjust slider via keyboard", () => InputManager.Key(Key.Left)); + + AddAssert("value is less than default", () => hitErrorMeter.JudgementLineThickness.Value < hitErrorMeter.JudgementLineThickness.Default); + } + + [Test] + public void TestAutoplayCompatibleModsRetainedOnEnteringGameplay() + { + AddStep("select DT", () => Game.SelectedMods.Value = new Mod[] { new OsuModDoubleTime() }); + + switchToGameplayScene(); + + AddAssert("DT still selected", () => ((Player)Game.ScreenStack.CurrentScreen).Mods.Value.Single() is OsuModDoubleTime); + } + + [Test] + public void TestAutoplayIncompatibleModsRemovedOnEnteringGameplay() + { + AddStep("select no fail and spun out", () => Game.SelectedMods.Value = new Mod[] { new OsuModNoFail(), new OsuModSpunOut() }); + + switchToGameplayScene(); + + AddAssert("no mod selected", () => !((Player)Game.ScreenStack.CurrentScreen).Mods.Value.Any()); + } + + [Test] + public void TestDuplicateAutoplayModRemovedOnEnteringGameplay() + { + AddStep("select autoplay", () => Game.SelectedMods.Value = new Mod[] { new OsuModAutoplay() }); + + switchToGameplayScene(); + + AddAssert("no mod selected", () => !((Player)Game.ScreenStack.CurrentScreen).Mods.Value.Any()); + } + + [Test] + public void TestCinemaModRemovedOnEnteringGameplay() + { + AddStep("select cinema", () => Game.SelectedMods.Value = new Mod[] { new OsuModCinema() }); + + switchToGameplayScene(); + + AddAssert("no mod selected", () => !((Player)Game.ScreenStack.CurrentScreen).Mods.Value.Any()); + } + + private void switchToGameplayScene() + { + AddStep("Click gameplay scene button", () => skinEditor.ChildrenOfType().First(b => b.Text == "Gameplay").TriggerClick()); + + AddUntilStep("wait for player", () => + { + DismissAnyNotifications(); + return Game.ScreenStack.CurrentScreen is Player; + }); + } + } +} diff --git a/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs b/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs index 4507526806..2124ba9b6d 100644 --- a/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.cs +++ b/osu.Game/Skinning/Editor/SkinEditorSceneLibrary.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. +using System.Collections.Generic; +using System.Linq; using JetBrains.Annotations; using osu.Framework.Allocation; using osu.Framework.Bindables; @@ -18,6 +20,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Screens; using osu.Game.Screens.Play; using osu.Game.Screens.Select; +using osu.Game.Utils; using osuTK; namespace osu.Game.Skinning.Editor @@ -34,6 +37,9 @@ namespace osu.Game.Skinning.Editor [Resolved] private IBindable ruleset { get; set; } + [Resolved] + private Bindable> mods { get; set; } + public SkinEditorSceneLibrary() { Height = BUTTON_HEIGHT + padding * 2; @@ -95,6 +101,10 @@ namespace osu.Game.Skinning.Editor return; var replayGeneratingMod = ruleset.Value.CreateInstance().GetAutoplayMod(); + + if (!ModUtils.CheckCompatibleSet(mods.Value.Append(replayGeneratingMod), out var invalid)) + mods.Value = mods.Value.Except(invalid).ToArray(); + if (replayGeneratingMod != null) screen.Push(new PlayerLoader(() => new ReplayPlayer((beatmap, mods) => replayGeneratingMod.CreateScoreFromReplayData(beatmap, mods)))); }, new[] { typeof(Player), typeof(SongSelect) }) diff --git a/osu.Game/Tests/Visual/OsuGameTestScene.cs b/osu.Game/Tests/Visual/OsuGameTestScene.cs index 7a6f8c8cfb..6e4adb4d4c 100644 --- a/osu.Game/Tests/Visual/OsuGameTestScene.cs +++ b/osu.Game/Tests/Visual/OsuGameTestScene.cs @@ -23,6 +23,7 @@ using osu.Game.Rulesets.Mods; using osu.Game.Scoring; using osu.Game.Screens; using osu.Game.Screens.Menu; +using osu.Game.Screens.Play; using osuTK.Graphics; using IntroSequence = osu.Game.Configuration.IntroSequence; @@ -106,6 +107,11 @@ namespace osu.Game.Tests.Visual protected void ConfirmAtMainMenu() => AddUntilStep("Wait for main menu", () => Game.ScreenStack.CurrentScreen is MainMenu menu && menu.IsLoaded); + /// + /// Dismisses any notifications pushed which block from interacting with the game (or block screens from loading, e.g. ). + /// + protected void DismissAnyNotifications() => Game.Notifications.State.Value = Visibility.Hidden; + public class TestOsuGame : OsuGame { public new const float SIDE_OVERLAY_OFFSET_RATIO = OsuGame.SIDE_OVERLAY_OFFSET_RATIO;