2022-03-27 05:43:17 +08:00
|
|
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
|
|
// See the LICENCE file in the repository root for full licence text.
|
|
|
|
|
2022-04-22 05:49:40 +08:00
|
|
|
using System;
|
2022-03-27 06:21:17 +08:00
|
|
|
using System.Linq;
|
2022-03-27 05:43:17 +08:00
|
|
|
using NUnit.Framework;
|
2022-04-04 02:24:32 +08:00
|
|
|
using osu.Framework.Allocation;
|
2022-03-27 05:43:17 +08:00
|
|
|
using osu.Framework.Graphics;
|
|
|
|
using osu.Framework.Graphics.Containers;
|
2022-03-27 06:21:17 +08:00
|
|
|
using osu.Framework.Testing;
|
2022-04-03 23:43:13 +08:00
|
|
|
using osu.Framework.Utils;
|
2022-03-27 06:21:17 +08:00
|
|
|
using osu.Game.Graphics.UserInterface;
|
2022-03-27 05:43:17 +08:00
|
|
|
using osu.Game.Overlays.Mods;
|
2022-04-04 02:24:32 +08:00
|
|
|
using osu.Game.Rulesets;
|
2022-04-03 23:43:13 +08:00
|
|
|
using osu.Game.Rulesets.Mods;
|
2022-03-27 06:21:17 +08:00
|
|
|
using osu.Game.Rulesets.Osu.Mods;
|
|
|
|
using osuTK.Input;
|
2022-03-27 05:43:17 +08:00
|
|
|
|
|
|
|
namespace osu.Game.Tests.Visual.UserInterface
|
|
|
|
{
|
|
|
|
[TestFixture]
|
2022-03-27 06:21:17 +08:00
|
|
|
public class TestSceneModSelectScreen : OsuManualInputManagerTestScene
|
2022-03-27 05:43:17 +08:00
|
|
|
{
|
2022-04-04 02:24:32 +08:00
|
|
|
[Resolved]
|
|
|
|
private RulesetStore rulesetStore { get; set; }
|
|
|
|
|
2022-04-04 01:42:52 +08:00
|
|
|
private UserModSelectScreen modSelectScreen;
|
2022-03-27 05:43:17 +08:00
|
|
|
|
2022-03-27 06:21:17 +08:00
|
|
|
[SetUpSteps]
|
|
|
|
public void SetUpSteps()
|
|
|
|
{
|
2022-04-04 02:24:32 +08:00
|
|
|
AddStep("clear contents", Clear);
|
|
|
|
AddStep("reset ruleset", () => Ruleset.Value = rulesetStore.GetRuleset(0));
|
2022-04-03 23:43:13 +08:00
|
|
|
AddStep("reset mods", () => SelectedMods.SetDefault());
|
2022-03-27 06:21:17 +08:00
|
|
|
}
|
2022-03-27 05:43:17 +08:00
|
|
|
|
2022-04-04 02:24:32 +08:00
|
|
|
private void createScreen()
|
2022-04-03 23:43:13 +08:00
|
|
|
{
|
2022-04-04 01:42:52 +08:00
|
|
|
AddStep("create screen", () => Child = modSelectScreen = new UserModSelectScreen
|
2022-04-04 02:24:32 +08:00
|
|
|
{
|
|
|
|
RelativeSizeAxes = Axes.Both,
|
|
|
|
State = { Value = Visibility.Visible },
|
|
|
|
SelectedMods = { BindTarget = SelectedMods }
|
|
|
|
});
|
|
|
|
waitForColumnLoad();
|
|
|
|
}
|
2022-04-03 23:43:13 +08:00
|
|
|
|
2022-03-27 06:21:17 +08:00
|
|
|
[Test]
|
|
|
|
public void TestStateChange()
|
|
|
|
{
|
2022-04-03 23:43:13 +08:00
|
|
|
createScreen();
|
2022-04-05 02:05:54 +08:00
|
|
|
AddStep("toggle state", () => modSelectScreen.ToggleVisibility());
|
2022-03-27 05:43:17 +08:00
|
|
|
}
|
2022-03-27 06:21:17 +08:00
|
|
|
|
2022-04-03 23:43:13 +08:00
|
|
|
[Test]
|
|
|
|
public void TestPreexistingSelection()
|
|
|
|
{
|
|
|
|
AddStep("set mods", () => SelectedMods.Value = new Mod[] { new OsuModAlternate(), new OsuModDaycore() });
|
|
|
|
createScreen();
|
|
|
|
AddUntilStep("two panels active", () => modSelectScreen.ChildrenOfType<ModPanel>().Count(panel => panel.Active.Value) == 2);
|
|
|
|
AddAssert("mod multiplier correct", () =>
|
|
|
|
{
|
2022-04-04 14:29:03 +08:00
|
|
|
double multiplier = SelectedMods.Value.Aggregate(1d, (m, mod) => m * mod.ScoreMultiplier);
|
2022-04-03 23:43:13 +08:00
|
|
|
return Precision.AlmostEquals(multiplier, modSelectScreen.ChildrenOfType<DifficultyMultiplierDisplay>().Single().Current.Value);
|
|
|
|
});
|
|
|
|
assertCustomisationToggleState(disabled: false, active: false);
|
|
|
|
}
|
|
|
|
|
|
|
|
[Test]
|
|
|
|
public void TestExternalSelection()
|
|
|
|
{
|
|
|
|
createScreen();
|
|
|
|
AddStep("set mods", () => SelectedMods.Value = new Mod[] { new OsuModAlternate(), new OsuModDaycore() });
|
|
|
|
AddUntilStep("two panels active", () => modSelectScreen.ChildrenOfType<ModPanel>().Count(panel => panel.Active.Value) == 2);
|
|
|
|
AddAssert("mod multiplier correct", () =>
|
|
|
|
{
|
2022-04-04 14:29:03 +08:00
|
|
|
double multiplier = SelectedMods.Value.Aggregate(1d, (m, mod) => m * mod.ScoreMultiplier);
|
2022-04-03 23:43:13 +08:00
|
|
|
return Precision.AlmostEquals(multiplier, modSelectScreen.ChildrenOfType<DifficultyMultiplierDisplay>().Single().Current.Value);
|
|
|
|
});
|
|
|
|
assertCustomisationToggleState(disabled: false, active: false);
|
|
|
|
}
|
|
|
|
|
2022-04-04 00:38:23 +08:00
|
|
|
[Test]
|
|
|
|
public void TestRulesetChange()
|
|
|
|
{
|
|
|
|
createScreen();
|
2022-04-04 02:24:32 +08:00
|
|
|
changeRuleset(0);
|
|
|
|
changeRuleset(1);
|
|
|
|
changeRuleset(2);
|
|
|
|
changeRuleset(3);
|
2022-04-04 00:38:23 +08:00
|
|
|
}
|
|
|
|
|
2022-04-22 05:49:40 +08:00
|
|
|
[Test]
|
|
|
|
public void TestIncompatibilityToggling()
|
|
|
|
{
|
|
|
|
createScreen();
|
|
|
|
changeRuleset(0);
|
|
|
|
|
|
|
|
AddStep("activate DT", () => getPanelForMod(typeof(OsuModDoubleTime)).TriggerClick());
|
|
|
|
AddAssert("DT active", () => SelectedMods.Value.Single().GetType() == typeof(OsuModDoubleTime));
|
|
|
|
|
|
|
|
AddStep("activate NC", () => getPanelForMod(typeof(OsuModNightcore)).TriggerClick());
|
|
|
|
AddAssert("only NC active", () => SelectedMods.Value.Single().GetType() == typeof(OsuModNightcore));
|
|
|
|
|
|
|
|
AddStep("activate HR", () => getPanelForMod(typeof(OsuModHardRock)).TriggerClick());
|
|
|
|
AddAssert("NC+HR active", () => SelectedMods.Value.Any(mod => mod.GetType() == typeof(OsuModNightcore))
|
|
|
|
&& SelectedMods.Value.Any(mod => mod.GetType() == typeof(OsuModHardRock)));
|
|
|
|
|
|
|
|
AddStep("activate MR", () => getPanelForMod(typeof(OsuModMirror)).TriggerClick());
|
|
|
|
AddAssert("NC+MR active", () => SelectedMods.Value.Any(mod => mod.GetType() == typeof(OsuModNightcore))
|
|
|
|
&& SelectedMods.Value.Any(mod => mod.GetType() == typeof(OsuModMirror)));
|
|
|
|
}
|
|
|
|
|
2022-04-26 05:41:40 +08:00
|
|
|
[Test]
|
|
|
|
public void TestDimmedState()
|
|
|
|
{
|
|
|
|
createScreen();
|
|
|
|
changeRuleset(0);
|
|
|
|
|
|
|
|
AddUntilStep("any column dimmed", () => this.ChildrenOfType<ModColumn>().Any(column => !column.Active.Value));
|
|
|
|
|
|
|
|
ModColumn firstDimmed = null;
|
|
|
|
ModPanel firstPanel = null;
|
|
|
|
|
|
|
|
AddStep("click first panel on dimmed column", () =>
|
|
|
|
{
|
|
|
|
firstDimmed = this.ChildrenOfType<ModColumn>().First(column => !column.Active.Value);
|
|
|
|
firstPanel = firstDimmed.ChildrenOfType<ModPanel>().First();
|
|
|
|
InputManager.MoveMouseTo(firstPanel);
|
|
|
|
InputManager.Click(MouseButton.Left);
|
|
|
|
});
|
|
|
|
AddUntilStep("column undimmed", () => firstDimmed.Active.Value);
|
|
|
|
AddAssert("panel not selected", () => !firstPanel.Active.Value);
|
|
|
|
|
|
|
|
AddStep("click panel again", () =>
|
|
|
|
{
|
|
|
|
InputManager.MoveMouseTo(firstPanel);
|
|
|
|
InputManager.Click(MouseButton.Left);
|
|
|
|
});
|
|
|
|
AddUntilStep("panel selected", () => firstPanel.Active.Value);
|
|
|
|
}
|
|
|
|
|
2022-03-27 06:21:17 +08:00
|
|
|
[Test]
|
|
|
|
public void TestCustomisationToggleState()
|
|
|
|
{
|
2022-04-03 23:43:13 +08:00
|
|
|
createScreen();
|
2022-03-27 06:21:17 +08:00
|
|
|
assertCustomisationToggleState(disabled: true, active: false);
|
|
|
|
|
|
|
|
AddStep("select customisable mod", () => SelectedMods.Value = new[] { new OsuModDoubleTime() });
|
|
|
|
assertCustomisationToggleState(disabled: false, active: false);
|
|
|
|
|
|
|
|
AddStep("select mod requiring configuration", () => SelectedMods.Value = new[] { new OsuModDifficultyAdjust() });
|
|
|
|
assertCustomisationToggleState(disabled: false, active: true);
|
|
|
|
|
|
|
|
AddStep("dismiss mod customisation", () =>
|
|
|
|
{
|
|
|
|
InputManager.MoveMouseTo(modSelectScreen.ChildrenOfType<ShearedToggleButton>().Single());
|
|
|
|
InputManager.Click(MouseButton.Left);
|
|
|
|
});
|
|
|
|
|
|
|
|
AddStep("append another mod not requiring config", () => SelectedMods.Value = SelectedMods.Value.Append(new OsuModFlashlight()).ToArray());
|
|
|
|
assertCustomisationToggleState(disabled: false, active: false);
|
|
|
|
|
|
|
|
AddStep("select mod without configuration", () => SelectedMods.Value = new[] { new OsuModAutoplay() });
|
|
|
|
assertCustomisationToggleState(disabled: true, active: false);
|
|
|
|
|
|
|
|
AddStep("select mod requiring configuration", () => SelectedMods.Value = new[] { new OsuModDifficultyAdjust() });
|
|
|
|
assertCustomisationToggleState(disabled: false, active: true);
|
|
|
|
|
|
|
|
AddStep("select mod without configuration", () => SelectedMods.Value = new[] { new OsuModAutoplay() });
|
|
|
|
assertCustomisationToggleState(disabled: true, active: false); // config was dismissed without explicit user action.
|
|
|
|
}
|
|
|
|
|
2022-04-04 02:24:32 +08:00
|
|
|
private void waitForColumnLoad() => AddUntilStep("all column content loaded",
|
|
|
|
() => modSelectScreen.ChildrenOfType<ModColumn>().Any() && modSelectScreen.ChildrenOfType<ModColumn>().All(column => column.IsLoaded && column.ItemsLoaded));
|
|
|
|
|
|
|
|
private void changeRuleset(int id)
|
|
|
|
{
|
|
|
|
AddStep($"set ruleset to {id}", () => Ruleset.Value = rulesetStore.GetRuleset(id));
|
|
|
|
waitForColumnLoad();
|
|
|
|
}
|
|
|
|
|
2022-03-27 06:21:17 +08:00
|
|
|
private void assertCustomisationToggleState(bool disabled, bool active)
|
|
|
|
{
|
|
|
|
ShearedToggleButton getToggle() => modSelectScreen.ChildrenOfType<ShearedToggleButton>().Single();
|
|
|
|
|
|
|
|
AddAssert($"customisation toggle is {(disabled ? "" : "not ")}disabled", () => getToggle().Active.Disabled == disabled);
|
|
|
|
AddAssert($"customisation toggle is {(active ? "" : "not ")}active", () => getToggle().Active.Value == active);
|
|
|
|
}
|
2022-04-22 05:49:40 +08:00
|
|
|
|
|
|
|
private ModPanel getPanelForMod(Type modType)
|
|
|
|
=> modSelectScreen.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.GetType() == modType);
|
2022-03-27 05:43:17 +08:00
|
|
|
}
|
|
|
|
}
|