diff --git a/.vscode/launch.json b/.vscode/launch.json
index 6480612b2e..4e8af405a2 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -11,11 +11,6 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Debug)",
- "linux": {
- "env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
- }
- },
"console": "internalConsole"
},
{
@@ -28,11 +23,6 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Release)",
- "linux": {
- "env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
- }
- },
"console": "internalConsole"
},
{
@@ -45,11 +35,6 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build tests (Debug)",
- "linux": {
- "env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
- }
- },
"console": "internalConsole"
},
{
@@ -62,11 +47,6 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build tests (Release)",
- "linux": {
- "env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
- }
- },
"console": "internalConsole"
},
{
@@ -80,11 +60,6 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Debug)",
- "linux": {
- "env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
- }
- },
"console": "internalConsole"
},
{
@@ -98,11 +73,6 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Release)",
- "linux": {
- "env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
- }
- },
"console": "internalConsole"
},
{
@@ -116,11 +86,6 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build tournament tests (Debug)",
- "linux": {
- "env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
- }
- },
"console": "internalConsole"
},
{
@@ -134,11 +99,6 @@
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build tournament tests (Release)",
- "linux": {
- "env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
- }
- },
"console": "internalConsole"
},
{
@@ -169,4 +129,4 @@
"externalConsole": false
}
]
-}
\ No newline at end of file
+}
diff --git a/osu.Android.props b/osu.Android.props
index 1c4a6ffe75..97f7a7edb1 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -52,6 +52,6 @@
-
+
diff --git a/osu.Android/OsuGameAndroid.cs b/osu.Android/OsuGameAndroid.cs
index a91c010809..84f215f930 100644
--- a/osu.Android/OsuGameAndroid.cs
+++ b/osu.Android/OsuGameAndroid.cs
@@ -30,11 +30,6 @@ namespace osu.Android
}
}
- protected override void LoadComplete()
- {
- base.LoadComplete();
-
- Add(new SimpleUpdateManager());
- }
+ protected override UpdateManager CreateUpdateManager() => new SimpleUpdateManager();
}
}
\ No newline at end of file
diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs
index f70cc24159..f05ee48914 100644
--- a/osu.Desktop/OsuGameDesktop.cs
+++ b/osu.Desktop/OsuGameDesktop.cs
@@ -47,20 +47,25 @@ namespace osu.Desktop
return null;
}
+ protected override UpdateManager CreateUpdateManager()
+ {
+ switch (RuntimeInfo.OS)
+ {
+ case RuntimeInfo.Platform.Windows:
+ return new SquirrelUpdateManager();
+
+ default:
+ return new SimpleUpdateManager();
+ }
+ }
+
protected override void LoadComplete()
{
base.LoadComplete();
if (!noVersionOverlay)
- {
LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, Add);
- if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows)
- Add(new SquirrelUpdateManager());
- else
- Add(new SimpleUpdateManager());
- }
-
LoadComponentAsync(new DiscordRichPresence(), Add);
}
diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs
index 74a9c05bf9..ed7bfb9a44 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs
@@ -7,7 +7,6 @@ using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
-using osu.Game.Screens.Play;
using osu.Game.Tests.Visual;
using osuTK;
@@ -51,7 +50,7 @@ namespace osu.Game.Rulesets.Catch.Tests
return beatmap;
}
- protected override Player CreatePlayer(Ruleset ruleset)
+ protected override TestPlayer CreatePlayer(Ruleset ruleset)
{
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
return base.CreatePlayer(ruleset);
diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs
new file mode 100644
index 0000000000..69415b70e3
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDifficultyAdjust.cs
@@ -0,0 +1,86 @@
+// 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.Framework.Utils;
+using osu.Game.Graphics.Containers;
+using osu.Game.Rulesets.Osu.Mods;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
+using osu.Game.Tests.Visual;
+
+namespace osu.Game.Rulesets.Osu.Tests.Mods
+{
+ public class TestSceneOsuModDifficultyAdjust : ModTestScene
+ {
+ public TestSceneOsuModDifficultyAdjust()
+ : base(new OsuRuleset())
+ {
+ }
+
+ [Test]
+ public void TestNoAdjustment() => CreateModTest(new ModTestData
+ {
+ Mod = new OsuModDifficultyAdjust(),
+ Autoplay = true,
+ PassCondition = checkSomeHit
+ });
+
+ [Test]
+ public void TestCircleSize1() => CreateModTest(new ModTestData
+ {
+ Mod = new OsuModDifficultyAdjust { CircleSize = { Value = 1 } },
+ Autoplay = true,
+ PassCondition = () => checkSomeHit() && checkObjectsScale(0.78f)
+ });
+
+ [Test]
+ public void TestCircleSize10() => CreateModTest(new ModTestData
+ {
+ Mod = new OsuModDifficultyAdjust { CircleSize = { Value = 10 } },
+ Autoplay = true,
+ PassCondition = () => checkSomeHit() && checkObjectsScale(0.15f)
+ });
+
+ [Test]
+ public void TestApproachRate1() => CreateModTest(new ModTestData
+ {
+ Mod = new OsuModDifficultyAdjust { ApproachRate = { Value = 1 } },
+ Autoplay = true,
+ PassCondition = () => checkSomeHit() && checkObjectsPreempt(1680)
+ });
+
+ [Test]
+ public void TestApproachRate10() => CreateModTest(new ModTestData
+ {
+ Mod = new OsuModDifficultyAdjust { ApproachRate = { Value = 10 } },
+ Autoplay = true,
+ PassCondition = () => checkSomeHit() && checkObjectsPreempt(450)
+ });
+
+ private bool checkObjectsPreempt(double target)
+ {
+ var objects = Player.ChildrenOfType();
+ if (!objects.Any())
+ return false;
+
+ return objects.All(o => o.HitObject.TimePreempt == target);
+ }
+
+ private bool checkObjectsScale(float target)
+ {
+ var objects = Player.ChildrenOfType();
+ if (!objects.Any())
+ return false;
+
+ return objects.All(o => Precision.AlmostEquals(o.ChildrenOfType().First().Children.OfType().Single().Scale.X, target));
+ }
+
+ private bool checkSomeHit()
+ {
+ return Player.ScoreProcessor.JudgedHits >= 2;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs
new file mode 100644
index 0000000000..dcf19ad993
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/Mods/TestSceneOsuModDoubleTime.cs
@@ -0,0 +1,35 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Framework.Utils;
+using osu.Game.Rulesets.Osu.Mods;
+using osu.Game.Tests.Visual;
+
+namespace osu.Game.Rulesets.Osu.Tests.Mods
+{
+ public class TestSceneOsuModDoubleTime : ModTestScene
+ {
+ public TestSceneOsuModDoubleTime()
+ : base(new OsuRuleset())
+ {
+ }
+
+ [TestCase(0.5)]
+ [TestCase(1.01)]
+ [TestCase(1.5)]
+ [TestCase(2)]
+ [TestCase(5)]
+ public void TestSpeedChangeCustomisation(double rate)
+ {
+ var mod = new OsuModDoubleTime { SpeedChange = { Value = rate } };
+
+ CreateModTest(new ModTestData
+ {
+ Mod = mod,
+ PassCondition = () => Player.ScoreProcessor.JudgedHits >= 2 &&
+ Precision.AlmostEquals(Player.GameplayClockContainer.GameplayClock.Rate, mod.SpeedChange.Value)
+ });
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs
index 412effe176..19736a7709 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs
@@ -3,13 +3,13 @@
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
-using osu.Game.Screens.Play;
+using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
public class TestSceneOsuFlashlight : TestSceneOsuPlayer
{
- protected override Player CreatePlayer(Ruleset ruleset)
+ protected override TestPlayer CreatePlayer(Ruleset ruleset)
{
SelectedMods.Value = new Mod[] { new OsuModAutoplay(), new OsuModFlashlight(), };
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs
index 4da1b1dae0..d39e24fc1f 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs
@@ -18,7 +18,6 @@ using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Osu.Objects.Drawables;
-using osu.Game.Screens.Play;
using osu.Game.Skinning;
using osu.Game.Storyboards;
using osu.Game.Tests.Visual;
@@ -56,7 +55,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private void checkNextHitObject(string skin) =>
AddUntilStep($"check skin from {skin}", () =>
{
- var firstObject = ((TestPlayer)Player).DrawableRuleset.Playfield.HitObjectContainer.AliveObjects.OfType().FirstOrDefault();
+ var firstObject = Player.DrawableRuleset.Playfield.HitObjectContainer.AliveObjects.OfType().FirstOrDefault();
if (firstObject == null)
return false;
@@ -75,7 +74,7 @@ namespace osu.Game.Rulesets.Osu.Tests
[Resolved]
private AudioManager audio { get; set; }
- protected override Player CreatePlayer(Ruleset ruleset) => new SkinProvidingPlayer(testUserSkin);
+ protected override TestPlayer CreatePlayer(Ruleset ruleset) => new SkinProvidingPlayer(testUserSkin);
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) => new CustomSkinWorkingBeatmap(beatmap, storyboard, Clock, audio, testBeatmapSkin);
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs
index 5cf571d961..ea006ec607 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSpinnerRotation.cs
@@ -11,7 +11,6 @@ using osu.Game.Beatmaps;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
-using osu.Game.Tests.Visual;
using osuTK;
using System.Collections.Generic;
using System.Linq;
@@ -44,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Tests
base.SetUpSteps();
AddUntilStep("wait for track to start running", () => track.IsRunning);
- AddStep("retrieve spinner", () => drawableSpinner = (DrawableSpinner)((TestPlayer)Player).DrawableRuleset.Playfield.AllHitObjects.First());
+ AddStep("retrieve spinner", () => drawableSpinner = (DrawableSpinner)Player.DrawableRuleset.Playfield.AllHitObjects.First());
}
[Test]
@@ -89,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Tests
{
AddStep($"seek to {time}", () => track.Seek(time));
- AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, ((TestPlayer)Player).DrawableRuleset.FrameStableClock.CurrentTime, 100));
+ AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
}
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new Beatmap
diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs
index ccacc50de1..303f0163b1 100644
--- a/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs
+++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneSwellJudgements.cs
@@ -1,23 +1,16 @@
// 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 NUnit.Framework;
-using osu.Framework.Allocation;
using osu.Game.Beatmaps;
-using osu.Game.Rulesets.Judgements;
-using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects;
-using osu.Game.Screens.Play;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Taiko.Tests
{
public class TestSceneSwellJudgements : PlayerTestScene
{
- protected new TestPlayer Player => (TestPlayer)base.Player;
-
public TestSceneSwellJudgements()
: base(new TaikoRuleset())
{
@@ -49,25 +42,5 @@ namespace osu.Game.Rulesets.Taiko.Tests
return beatmap;
}
-
- protected override Player CreatePlayer(Ruleset ruleset) => new TestPlayer();
-
- protected class TestPlayer : Player
- {
- public readonly List Results = new List();
-
- public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
-
- public TestPlayer()
- : base(false, false)
- {
- }
-
- [BackgroundDependencyLoader]
- private void load()
- {
- ScoreProcessor.NewJudgement += r => Results.Add(r);
- }
- }
}
}
diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs
index 140433a523..2ab041e191 100644
--- a/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs
+++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs
@@ -4,11 +4,9 @@
using System.Linq;
using NUnit.Framework;
using osu.Game.Beatmaps;
-using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Beatmaps;
using osu.Game.Rulesets.Taiko.Mods;
using osu.Game.Rulesets.Taiko.Objects;
-using osu.Game.Screens.Play;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Taiko.Tests
@@ -22,10 +20,10 @@ namespace osu.Game.Rulesets.Taiko.Tests
protected override bool AllowFail => true;
- protected override Player CreatePlayer(Ruleset ruleset)
+ protected override TestPlayer CreatePlayer(Ruleset ruleset)
{
SelectedMods.Value = SelectedMods.Value.Concat(new[] { new TaikoModSuddenDeath() }).ToArray();
- return new ScoreAccessiblePlayer();
+ return base.CreatePlayer(ruleset);
}
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) =>
@@ -49,20 +47,10 @@ namespace osu.Game.Rulesets.Taiko.Tests
AddStep("Setup judgements", () =>
{
judged = false;
- ((ScoreAccessiblePlayer)Player).ScoreProcessor.NewJudgement += b => judged = true;
+ Player.ScoreProcessor.NewJudgement += b => judged = true;
});
AddUntilStep("swell judged", () => judged);
AddAssert("not failed", () => !Player.HasFailed);
}
-
- private class ScoreAccessiblePlayer : TestPlayer
- {
- public ScoreAccessiblePlayer()
- : base(false, false)
- {
- }
-
- public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
- }
}
}
diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
index 6d014ca1ca..06a155e78b 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
@@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual.Background
private DummySongSelect songSelect;
private TestPlayerLoader playerLoader;
- private TestPlayer player;
+ private LoadBlockingTestPlayer player;
private BeatmapManager manager;
private RulesetStore rulesets;
@@ -81,7 +81,7 @@ namespace osu.Game.Tests.Visual.Background
public void PlayerLoaderSettingsHoverTest()
{
setupUserSettings();
- AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new TestPlayer { BlockLoad = true })));
+ AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new LoadBlockingTestPlayer { BlockLoad = true })));
AddUntilStep("Wait for Player Loader to load", () => playerLoader?.IsLoaded ?? false);
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
AddStep("Trigger background preview", () =>
@@ -268,7 +268,7 @@ namespace osu.Game.Tests.Visual.Background
{
setupUserSettings();
- AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new TestPlayer(allowPause))));
+ AddStep("Start player loader", () => songSelect.Push(playerLoader = new TestPlayerLoader(player = new LoadBlockingTestPlayer(allowPause))));
AddUntilStep("Wait for Player Loader to load", () => playerLoader.IsLoaded);
AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
@@ -347,7 +347,7 @@ namespace osu.Game.Tests.Visual.Background
public bool IsBlurCorrect() => ((FadeAccessibleBackground)Background).CurrentBlur == new Vector2(BACKGROUND_BLUR);
}
- private class TestPlayer : Visual.TestPlayer
+ private class LoadBlockingTestPlayer : TestPlayer
{
protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value);
@@ -360,7 +360,7 @@ namespace osu.Game.Tests.Visual.Background
public readonly Bindable ReplacesBackground = new Bindable();
public readonly Bindable IsPaused = new Bindable();
- public TestPlayer(bool allowPause = true)
+ public LoadBlockingTestPlayer(bool allowPause = true)
: base(allowPause)
{
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
index 4daab8d137..afeda5fb7c 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAutoplay.cs
@@ -3,53 +3,32 @@
using System.ComponentModel;
using System.Linq;
-using osu.Game.Beatmaps;
using osu.Game.Rulesets;
-using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play;
-using osu.Game.Storyboards;
namespace osu.Game.Tests.Visual.Gameplay
{
[Description("Player instantiated with an autoplay mod.")]
public class TestSceneAutoplay : TestSceneAllRulesetPlayers
{
- private ClockBackedTestWorkingBeatmap.TrackVirtualManual track;
+ protected new TestPlayer Player => (TestPlayer)base.Player;
protected override Player CreatePlayer(Ruleset ruleset)
{
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
- return new ScoreAccessiblePlayer();
+ return new TestPlayer(false, false);
}
protected override void AddCheckSteps()
{
- AddUntilStep("score above zero", () => ((ScoreAccessiblePlayer)Player).ScoreProcessor.TotalScore.Value > 0);
- AddUntilStep("key counter counted keys", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2));
- AddStep("rewind", () => track.Seek(-10000));
- AddUntilStep("key counter reset", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
- }
-
- protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
- {
- var working = base.CreateWorkingBeatmap(beatmap, storyboard);
-
- track = (ClockBackedTestWorkingBeatmap.TrackVirtualManual)working.Track;
-
- return working;
- }
-
- private class ScoreAccessiblePlayer : TestPlayer
- {
- public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
- public new HUDOverlay HUDOverlay => base.HUDOverlay;
-
- public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer;
-
- public ScoreAccessiblePlayer()
- : base(false, false)
- {
- }
+ AddUntilStep("score above zero", () => Player.ScoreProcessor.TotalScore.Value > 0);
+ AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2));
+ AddStep("seek to break time", () => Player.GameplayClockContainer.Seek(Player.BreakOverlay.Breaks.First().StartTime));
+ AddUntilStep("wait for seek to complete", () =>
+ Player.HUDOverlay.Progress.ReferenceClock.CurrentTime >= Player.BreakOverlay.Breaks.First().StartTime);
+ AddAssert("test keys not counting", () => !Player.HUDOverlay.KeyCounter.IsCounting);
+ AddStep("rewind", () => Player.GameplayClockContainer.Seek(-80000));
+ AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
}
}
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs
index 78c3b22fb9..310746d179 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs
@@ -1,7 +1,6 @@
// 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 NUnit.Framework;
using osu.Framework.Allocation;
@@ -11,12 +10,8 @@ using osu.Framework.Utils;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
-using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Objects;
-using osu.Game.Rulesets.Scoring;
-using osu.Game.Rulesets.UI;
-using osu.Game.Screens.Play;
using osu.Game.Storyboards;
using osuTK;
@@ -24,8 +19,6 @@ namespace osu.Game.Tests.Visual.Gameplay
{
public class TestSceneGameplayRewinding : PlayerTestScene
{
- private RulesetExposingPlayer player => (RulesetExposingPlayer)Player;
-
[Resolved]
private AudioManager audioManager { get; set; }
@@ -48,13 +41,13 @@ namespace osu.Game.Tests.Visual.Gameplay
{
AddUntilStep("wait for track to start running", () => track.IsRunning);
addSeekStep(3000);
- AddAssert("all judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged));
- AddUntilStep("key counter counted keys", () => player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses >= 7));
- AddStep("clear results", () => player.AppliedResults.Clear());
+ AddAssert("all judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged));
+ AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses >= 7));
+ AddStep("clear results", () => Player.Results.Clear());
addSeekStep(0);
- AddAssert("none judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged));
- AddUntilStep("key counters reset", () => player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
- AddAssert("no results triggered", () => player.AppliedResults.Count == 0);
+ AddAssert("none judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged));
+ AddUntilStep("key counters reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
+ AddAssert("no results triggered", () => Player.Results.Count == 0);
}
private void addSeekStep(double time)
@@ -62,13 +55,13 @@ namespace osu.Game.Tests.Visual.Gameplay
AddStep($"seek to {time}", () => track.Seek(time));
// Allow a few frames of lenience
- AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
+ AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
}
- protected override Player CreatePlayer(Ruleset ruleset)
+ protected override TestPlayer CreatePlayer(Ruleset ruleset)
{
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
- return new RulesetExposingPlayer();
+ return base.CreatePlayer(ruleset);
}
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
@@ -89,29 +82,5 @@ namespace osu.Game.Tests.Visual.Gameplay
return beatmap;
}
-
- private class RulesetExposingPlayer : Player
- {
- public readonly List AppliedResults = new List();
-
- public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
-
- public new HUDOverlay HUDOverlay => base.HUDOverlay;
-
- public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer;
-
- public new DrawableRuleset DrawableRuleset => base.DrawableRuleset;
-
- public RulesetExposingPlayer()
- : base(false, false)
- {
- }
-
- [BackgroundDependencyLoader]
- private void load()
- {
- ScoreProcessor.NewJudgement += r => AppliedResults.Add(r);
- }
- }
}
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
index e7b3e007fc..227ada70fe 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneKeyCounter.cs
@@ -47,21 +47,22 @@ namespace osu.Game.Tests.Visual.Gameplay
Key testKey = ((KeyCounterKeyboard)kc.Children.First()).Key;
- AddStep($"Press {testKey} key", () =>
+ void addPressKeyStep()
{
- InputManager.PressKey(testKey);
- InputManager.ReleaseKey(testKey);
- });
+ AddStep($"Press {testKey} key", () =>
+ {
+ InputManager.PressKey(testKey);
+ InputManager.ReleaseKey(testKey);
+ });
+ }
+ addPressKeyStep();
AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses == 1);
-
- AddStep($"Press {testKey} key", () =>
- {
- InputManager.PressKey(testKey);
- InputManager.ReleaseKey(testKey);
- });
-
+ addPressKeyStep();
AddAssert($"Check {testKey} counter after keypress", () => testCounter.CountPresses == 2);
+ AddStep("Disable counting", () => testCounter.IsCounting = false);
+ addPressKeyStep();
+ AddAssert($"Check {testKey} count has not changed", () => testCounter.CountPresses == 2);
Add(kc);
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs
index ad5bab4681..944e6ca6be 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestScenePause.cs
@@ -11,7 +11,6 @@ using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Cursor;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu;
-using osu.Game.Rulesets.Scoring;
using osu.Game.Screens.Play;
using osuTK;
using osuTK.Input;
@@ -282,14 +281,10 @@ namespace osu.Game.Tests.Visual.Gameplay
protected override bool AllowFail => true;
- protected override Player CreatePlayer(Ruleset ruleset) => new PausePlayer();
+ protected override TestPlayer CreatePlayer(Ruleset ruleset) => new PausePlayer();
protected class PausePlayer : TestPlayer
{
- public new HealthProcessor HealthProcessor => base.HealthProcessor;
-
- public new HUDOverlay HUDOverlay => base.HUDOverlay;
-
public bool FailOverlayVisible => FailOverlay.State.Value == Visibility.Visible;
public bool PauseOverlayVisible => PauseOverlay.State.Value == Visibility.Visible;
diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs
index 3513b6c25a..a83320048b 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestScenePauseWhenInactive.cs
@@ -9,15 +9,12 @@ using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu;
-using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual.Gameplay
{
[HeadlessTest] // we alter unsafe properties on the game host to test inactive window state.
public class TestScenePauseWhenInactive : PlayerTestScene
{
- protected new TestPlayer Player => (TestPlayer)base.Player;
-
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
{
var beatmap = (Beatmap)base.CreateBeatmap(ruleset);
@@ -46,6 +43,6 @@ namespace osu.Game.Tests.Visual.Gameplay
AddAssert("time of pause is after gameplay start time", () => Player.GameplayClockContainer.GameplayClock.CurrentTime >= Player.DrawableRuleset.GameplayStartTime);
}
- protected override Player CreatePlayer(Ruleset ruleset) => new TestPlayer(true, true, true);
+ protected override TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(true, true, true);
}
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs
index 100f99d130..175f909a5a 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestScenePlayerLoader.cs
@@ -9,7 +9,6 @@ using System.Threading.Tasks;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
-using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Utils;
@@ -307,17 +306,7 @@ namespace osu.Game.Tests.Visual.Gameplay
public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank;
}
- private class TestPlayer : Visual.TestPlayer
- {
- public new Bindable> Mods => base.Mods;
-
- public TestPlayer(bool allowPause = true, bool showResults = true)
- : base(allowPause, showResults)
- {
- }
- }
-
- protected class SlowLoadPlayer : Visual.TestPlayer
+ protected class SlowLoadPlayer : TestPlayer
{
public readonly ManualResetEventSlim AllowLoad = new ManualResetEventSlim(false);
diff --git a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs
index 70d71d0952..0d64eb651f 100644
--- a/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs
+++ b/osu.Game.Tests/Visual/Navigation/OsuGameTestScene.cs
@@ -62,14 +62,7 @@ namespace osu.Game.Tests.Visual.Navigation
var frameworkConfig = host.Dependencies.Get();
frameworkConfig.GetBindable(FrameworkSetting.CursorSensitivity).Disabled = false;
- Game = new TestOsuGame(LocalStorage, API);
- Game.SetHost(host);
-
- // todo: this can be removed once we can run audio tracks without a device present
- // see https://github.com/ppy/osu/issues/1302
- Game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles);
-
- Add(Game);
+ CreateGame();
});
AddUntilStep("Wait for load", () => Game.IsLoaded);
@@ -78,6 +71,18 @@ namespace osu.Game.Tests.Visual.Navigation
ConfirmAtMainMenu();
}
+ protected void CreateGame()
+ {
+ Game = new TestOsuGame(LocalStorage, API);
+ Game.SetHost(host);
+
+ // todo: this can be removed once we can run audio tracks without a device present
+ // see https://github.com/ppy/osu/issues/1302
+ Game.LocalConfig.Set(OsuSetting.IntroSequence, IntroSequence.Circles);
+
+ Add(Game);
+ }
+
protected void PushAndConfirm(Func newScreen)
{
Screen screen = null;
@@ -97,12 +102,17 @@ namespace osu.Game.Tests.Visual.Navigation
public new SettingsPanel Settings => base.Settings;
+ public new MusicController MusicController => base.MusicController;
+
public new OsuConfigManager LocalConfig => base.LocalConfig;
public new Bindable Beatmap => base.Beatmap;
public new Bindable Ruleset => base.Ruleset;
+ // if we don't do this, when running under nUnit the version that gets populated is that of nUnit.
+ public override string Version => "test game";
+
protected override Loader CreateLoader() => new TestLoader();
public new void PerformFromScreen(Action action, IEnumerable validScreens = null) => base.PerformFromScreen(action, validScreens);
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
index 8258cc9465..9d603ac471 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
@@ -114,6 +114,22 @@ namespace osu.Game.Tests.Visual.Navigation
AddAssert("Options overlay was closed", () => Game.Settings.State.Value == Visibility.Hidden);
}
+ [Test]
+ public void TestWaitForNextTrackInMenu()
+ {
+ bool trackCompleted = false;
+
+ AddUntilStep("Wait for music controller", () => Game.MusicController.IsLoaded);
+ AddStep("Seek close to end", () =>
+ {
+ Game.MusicController.SeekTo(Game.Beatmap.Value.Track.Length - 1000);
+ Game.Beatmap.Value.Track.Completed += () => trackCompleted = true;
+ });
+
+ AddUntilStep("Track was completed", () => trackCompleted);
+ AddUntilStep("Track was restarted", () => Game.Beatmap.Value.Track.IsRunning);
+ }
+
private void pushEscape() =>
AddStep("Press escape", () => pressAndRelease(Key.Escape));
diff --git a/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs b/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs
new file mode 100644
index 0000000000..c0b77b580e
--- /dev/null
+++ b/osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs
@@ -0,0 +1,41 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Framework.Utils;
+using osu.Game.Configuration;
+
+namespace osu.Game.Tests.Visual.Navigation
+{
+ public class TestSettingsMigration : OsuGameTestScene
+ {
+ public override void RecycleLocalStorage()
+ {
+ base.RecycleLocalStorage();
+
+ using (var config = new OsuConfigManager(LocalStorage))
+ {
+ config.Set(OsuSetting.Version, "2020.101.0");
+ config.Set(OsuSetting.DisplayStarsMaximum, 10.0);
+ }
+ }
+
+ [Test]
+ public void TestDisplayStarsMigration()
+ {
+ AddAssert("config has migrated value", () => Precision.AlmostEquals(Game.LocalConfig.Get(OsuSetting.DisplayStarsMaximum), 10.1));
+
+ AddStep("set value again", () => Game.LocalConfig.Set(OsuSetting.DisplayStarsMaximum, 10));
+
+ AddStep("force save config", () => Game.LocalConfig.Save());
+
+ AddStep("remove game", () => Remove(Game));
+
+ AddStep("create game again", CreateGame);
+
+ AddUntilStep("Wait for load", () => Game.IsLoaded);
+
+ AddAssert("config did not migrate value", () => Precision.AlmostEquals(Game.LocalConfig.Get(OsuSetting.DisplayStarsMaximum), 10));
+ }
+ }
+}
diff --git a/osu.Game.Tournament/Components/TourneyVideo.cs b/osu.Game.Tournament/Components/TourneyVideo.cs
index 206689ca1a..7d2eaff515 100644
--- a/osu.Game.Tournament/Components/TourneyVideo.cs
+++ b/osu.Game.Tournament/Components/TourneyVideo.cs
@@ -1,12 +1,13 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-using System.IO;
+using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Video;
+using osu.Framework.Platform;
using osu.Framework.Timing;
using osu.Game.Graphics;
@@ -14,21 +15,24 @@ namespace osu.Game.Tournament.Components
{
public class TourneyVideo : CompositeDrawable
{
- private readonly VideoSprite video;
+ private readonly string filename;
+ private readonly bool drawFallbackGradient;
+ private VideoSprite video;
- private readonly ManualClock manualClock;
+ private ManualClock manualClock;
- public TourneyVideo(Stream stream)
+ public TourneyVideo(string filename, bool drawFallbackGradient = false)
{
- if (stream == null)
- {
- InternalChild = new Box
- {
- Colour = ColourInfo.GradientVertical(OsuColour.Gray(0.3f), OsuColour.Gray(0.6f)),
- RelativeSizeAxes = Axes.Both,
- };
- }
- else
+ this.filename = filename;
+ this.drawFallbackGradient = drawFallbackGradient;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(Storage storage)
+ {
+ var stream = storage.GetStream($@"videos/{filename}.m4v");
+
+ if (stream != null)
{
InternalChild = video = new VideoSprite(stream)
{
@@ -37,6 +41,14 @@ namespace osu.Game.Tournament.Components
Clock = new FramedClock(manualClock = new ManualClock())
};
}
+ else if (drawFallbackGradient)
+ {
+ InternalChild = new Box
+ {
+ Colour = ColourInfo.GradientVertical(OsuColour.Gray(0.3f), OsuColour.Gray(0.6f)),
+ RelativeSizeAxes = Axes.Both,
+ };
+ }
}
public bool Loop
diff --git a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
index 7119533743..8b8078e119 100644
--- a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
@@ -129,8 +129,6 @@ namespace osu.Game.Tournament.Screens.Editors
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
- LayoutDuration = 200,
- LayoutEasing = Easing.OutQuint,
ChildrenEnumerable = round.Beatmaps.Select(p => new RoundBeatmapRow(round, p))
};
}
diff --git a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs
index e68946aaf2..46bb7b83e3 100644
--- a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs
@@ -124,8 +124,6 @@ namespace osu.Game.Tournament.Screens.Editors
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
- LayoutDuration = 200,
- LayoutEasing = Easing.OutQuint,
ChildrenEnumerable = round.Beatmaps.Select(p => new SeedingBeatmapRow(round, p))
};
}
diff --git a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs
index bbbc948811..32d0ef7c17 100644
--- a/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/TeamEditorScreen.cs
@@ -202,8 +202,6 @@ namespace osu.Game.Tournament.Screens.Editors
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Direction = FillDirection.Vertical,
- LayoutDuration = 200,
- LayoutEasing = Easing.OutQuint,
ChildrenEnumerable = team.Players.Select(p => new PlayerRow(team, p))
};
}
diff --git a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs
index 5598910824..e4256e727d 100644
--- a/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/TournamentEditorScreen.cs
@@ -48,8 +48,6 @@ namespace osu.Game.Tournament.Screens.Editors
Direction = FillDirection.Vertical,
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
- LayoutDuration = 200,
- LayoutEasing = Easing.OutQuint,
Spacing = new Vector2(20)
},
},
diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs
index 6a3095d42d..d632e7c5f3 100644
--- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs
+++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs
@@ -6,6 +6,7 @@ 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.Threading;
using osu.Game.Graphics.UserInterface;
using osu.Game.Tournament.Components;
@@ -19,7 +20,7 @@ using osuTK.Graphics;
namespace osu.Game.Tournament.Screens.Gameplay
{
- public class GameplayScreen : BeatmapInfoScreen
+ public class GameplayScreen : BeatmapInfoScreen, IProvideVideo
{
private readonly BindableBool warmup = new BindableBool();
@@ -39,12 +40,17 @@ namespace osu.Game.Tournament.Screens.Gameplay
private TournamentMatchChatDisplay chat { get; set; }
[BackgroundDependencyLoader]
- private void load(LadderInfo ladder, MatchIPCInfo ipc)
+ private void load(LadderInfo ladder, MatchIPCInfo ipc, Storage storage)
{
this.ipc = ipc;
AddRangeInternal(new Drawable[]
{
+ new TourneyVideo("gameplay")
+ {
+ Loop = true,
+ RelativeSizeAxes = Axes.Both,
+ },
new MatchHeader(),
new Container
{
diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs
index 293f6e0068..7b265ded32 100644
--- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs
+++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs
@@ -42,7 +42,7 @@ namespace osu.Game.Tournament.Screens.Ladder
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
- new TourneyVideo(storage.GetStream(@"videos/ladder.m4v"))
+ new TourneyVideo("ladder")
{
RelativeSizeAxes = Axes.Both,
Loop = true,
diff --git a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs
index 080570eac4..4c93c04fcf 100644
--- a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs
+++ b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs
@@ -18,7 +18,7 @@ using osuTK.Graphics;
namespace osu.Game.Tournament.Screens.Schedule
{
- public class ScheduleScreen : TournamentScreen, IProvideVideo
+ public class ScheduleScreen : TournamentScreen
{
private readonly Bindable currentMatch = new Bindable();
private Container mainContainer;
@@ -33,7 +33,7 @@ namespace osu.Game.Tournament.Screens.Schedule
InternalChildren = new Drawable[]
{
- new TourneyVideo(storage.GetStream(@"videos/schedule.m4v"))
+ new TourneyVideo("schedule")
{
RelativeSizeAxes = Axes.Both,
Loop = true,
diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
index db5363c155..513d84b594 100644
--- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
+++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
@@ -34,7 +34,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
InternalChildren = new Drawable[]
{
- new TourneyVideo(storage.GetStream(@"videos/seeding.m4v"))
+ new TourneyVideo("seeding")
{
RelativeSizeAxes = Axes.Both,
Loop = true,
diff --git a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs
index 6559113f55..d584c21058 100644
--- a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs
+++ b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs
@@ -26,7 +26,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
InternalChildren = new Drawable[]
{
- new TourneyVideo(storage.GetStream(@"videos/teamintro.m4v"))
+ new TourneyVideo("teamintro")
{
RelativeSizeAxes = Axes.Both,
Loop = true,
diff --git a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs
index 30b86f8421..1765ab7ba2 100644
--- a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs
+++ b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs
@@ -31,13 +31,13 @@ namespace osu.Game.Tournament.Screens.TeamWin
InternalChildren = new Drawable[]
{
- blueWinVideo = new TourneyVideo(storage.GetStream(@"videos/teamwin-blue.m4v"))
+ blueWinVideo = new TourneyVideo("teamwin-blue")
{
Alpha = 1,
RelativeSizeAxes = Axes.Both,
Loop = true,
},
- redWinVideo = new TourneyVideo(storage.GetStream(@"videos/teamwin-red.m4v"))
+ redWinVideo = new TourneyVideo("teamwin-red")
{
Alpha = 0,
RelativeSizeAxes = Axes.Both,
diff --git a/osu.Game.Tournament/Screens/TournamentScreen.cs b/osu.Game.Tournament/Screens/TournamentScreen.cs
index 0b5b3e728b..5da7c7a5d2 100644
--- a/osu.Game.Tournament/Screens/TournamentScreen.cs
+++ b/osu.Game.Tournament/Screens/TournamentScreen.cs
@@ -18,6 +18,9 @@ namespace osu.Game.Tournament.Screens
protected TournamentScreen()
{
RelativeSizeAxes = Axes.Both;
+
+ FillMode = FillMode.Fit;
+ FillAspectRatio = 16 / 9f;
}
public override void Hide() => this.FadeOut(FADE_DELAY);
diff --git a/osu.Game.Tournament/TournamentSceneManager.cs b/osu.Game.Tournament/TournamentSceneManager.cs
index 9f5f2b6827..287e25b1fb 100644
--- a/osu.Game.Tournament/TournamentSceneManager.cs
+++ b/osu.Game.Tournament/TournamentSceneManager.cs
@@ -61,7 +61,7 @@ namespace osu.Game.Tournament
//Masking = true,
Children = new Drawable[]
{
- video = new TourneyVideo(storage.GetStream("videos/main.m4v"))
+ video = new TourneyVideo("main", true)
{
Loop = true,
RelativeSizeAxes = Axes.Both,
diff --git a/osu.Game/Configuration/OsuConfigManager.cs b/osu.Game/Configuration/OsuConfigManager.cs
index ce959e9057..21de654670 100644
--- a/osu.Game/Configuration/OsuConfigManager.cs
+++ b/osu.Game/Configuration/OsuConfigManager.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.Bindables;
using osu.Framework.Configuration;
using osu.Framework.Configuration.Tracking;
using osu.Framework.Extensions;
@@ -126,6 +127,35 @@ namespace osu.Game.Configuration
public OsuConfigManager(Storage storage)
: base(storage)
{
+ Migrate();
+ }
+
+ public void Migrate()
+ {
+ // arrives as 2020.123.0
+ var rawVersion = Get(OsuSetting.Version);
+
+ if (rawVersion.Length < 6)
+ return;
+
+ var pieces = rawVersion.Split('.');
+
+ // on a fresh install or when coming from a non-release build, execution will end here.
+ // we don't want to run migrations in such cases.
+ if (!int.TryParse(pieces[0], out int year)) return;
+ if (!int.TryParse(pieces[1], out int monthDay)) return;
+
+ int combined = (year * 10000) + monthDay;
+
+ if (combined < 20200305)
+ {
+ // the maximum value of this setting was changed.
+ // if we don't manually increase this, it causes song select to filter out beatmaps the user expects to see.
+ var maxStars = (BindableDouble)GetOriginalBindable(OsuSetting.DisplayStarsMaximum);
+
+ if (maxStars.Value == 10)
+ maxStars.Value = maxStars.MaxValue;
+ }
}
public override TrackedSettings CreateTrackedSettings() => new TrackedSettings
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index 5781a7fbc4..1b2fd658f4 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -43,6 +43,7 @@ using osu.Game.Overlays.Volume;
using osu.Game.Rulesets.Mods;
using osu.Game.Scoring;
using osu.Game.Screens.Select;
+using osu.Game.Updater;
using osu.Game.Utils;
using LogLevel = osu.Framework.Logging.LogLevel;
@@ -390,24 +391,35 @@ namespace osu.Game
protected virtual Loader CreateLoader() => new Loader();
+ protected virtual UpdateManager CreateUpdateManager() => new UpdateManager();
+
protected override Container CreateScalingContainer() => new ScalingContainer(ScalingMode.Everything);
#region Beatmap progression
private void beatmapChanged(ValueChangedEvent beatmap)
{
- var nextBeatmap = beatmap.NewValue;
- if (nextBeatmap?.Track != null)
- nextBeatmap.Track.Completed += currentTrackCompleted;
-
- var oldBeatmap = beatmap.OldValue;
- if (oldBeatmap?.Track != null)
- oldBeatmap.Track.Completed -= currentTrackCompleted;
+ beatmap.OldValue?.CancelAsyncLoad();
updateModDefaults();
- oldBeatmap?.CancelAsyncLoad();
- nextBeatmap?.BeginAsyncLoad();
+ var newBeatmap = beatmap.NewValue;
+
+ if (newBeatmap != null)
+ {
+ newBeatmap.Track.Completed += () => Scheduler.AddOnce(() => trackCompleted(newBeatmap));
+ newBeatmap.BeginAsyncLoad();
+ }
+
+ void trackCompleted(WorkingBeatmap b)
+ {
+ // the source of track completion is the audio thread, so the beatmap may have changed before firing.
+ if (Beatmap.Value != b)
+ return;
+
+ if (!Beatmap.Value.Track.Looping && !Beatmap.Disabled)
+ MusicController.NextTrack();
+ }
}
private void modsChanged(ValueChangedEvent> mods)
@@ -428,12 +440,6 @@ namespace osu.Game
}
}
- private void currentTrackCompleted() => Schedule(() =>
- {
- if (!Beatmap.Value.Track.Looping && !Beatmap.Disabled)
- musicController.NextTrack();
- });
-
#endregion
private ScheduledDelegate performFromMainMenuTask;
@@ -585,7 +591,7 @@ namespace osu.Game
loadComponentSingleFile(new OnScreenDisplay(), Add, true);
- loadComponentSingleFile(musicController = new MusicController(), Add, true);
+ loadComponentSingleFile(MusicController = new MusicController(), Add, true);
loadComponentSingleFile(notifications = new NotificationOverlay
{
@@ -628,6 +634,7 @@ namespace osu.Game
chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;
Add(externalLinkOpener = new ExternalLinkOpener());
+ Add(CreateUpdateManager()); // dependency on notification overlay
// side overlays which cancel each other.
var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications };
@@ -893,7 +900,7 @@ namespace osu.Game
private ScalingContainer screenContainer;
- private MusicController musicController;
+ protected MusicController MusicController { get; private set; }
protected override bool OnExiting()
{
@@ -951,7 +958,7 @@ namespace osu.Game
{
OverlayActivationMode.Value = newOsuScreen.InitialOverlayActivationMode;
- musicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments;
+ MusicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments;
if (newOsuScreen.HideOverlaysOnEnter)
CloseAllOverlays();
diff --git a/osu.Game/OsuGameBase.cs b/osu.Game/OsuGameBase.cs
index a890331f05..b2277e2abf 100644
--- a/osu.Game/OsuGameBase.cs
+++ b/osu.Game/OsuGameBase.cs
@@ -97,7 +97,7 @@ namespace osu.Game
public bool IsDeployedBuild => AssemblyVersion.Major > 0;
- public string Version
+ public virtual string Version
{
get
{
@@ -211,6 +211,10 @@ namespace osu.Game
Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));
Beatmap = new NonNullableBindable(defaultBeatmap);
+
+ // ScheduleAfterChildren is safety against something in the current frame accessing the previous beatmap's track
+ // and potentially causing a reload of it after just unloading.
+ // Note that the reason for this being added *has* been resolved, so it may be feasible to removed this if required.
Beatmap.BindValueChanged(b => ScheduleAfterChildren(() =>
{
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
diff --git a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs
index 72796df6d5..d6174e0733 100644
--- a/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs
+++ b/osu.Game/Overlays/SearchableList/SearchableListOverlay.cs
@@ -15,7 +15,7 @@ namespace osu.Game.Overlays.SearchableList
{
public abstract class SearchableListOverlay : FullscreenOverlay
{
- public const float WIDTH_PADDING = 10;
+ public const float WIDTH_PADDING = 80;
protected SearchableListOverlay(OverlayColourScheme colourScheme)
: base(colourScheme)
@@ -80,7 +80,7 @@ namespace osu.Game.Overlays.SearchableList
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
- Padding = new MarginPadding { Horizontal = WIDTH_PADDING, Bottom = 50 },
+ Padding = new MarginPadding { Horizontal = 10, Bottom = 50 },
Direction = FillDirection.Vertical,
},
},
diff --git a/osu.Game/Screens/Play/Player.cs b/osu.Game/Screens/Play/Player.cs
index 11ca36e25f..bcadba14af 100644
--- a/osu.Game/Screens/Play/Player.cs
+++ b/osu.Game/Screens/Play/Player.cs
@@ -184,7 +184,7 @@ namespace osu.Game.Screens.Play
foreach (var mod in Mods.Value.OfType())
mod.ApplyToHealthProcessor(HealthProcessor);
- BreakOverlay.IsBreakTime.ValueChanged += _ => updatePauseOnFocusLostState();
+ BreakOverlay.IsBreakTime.BindValueChanged(onBreakTimeChanged, true);
}
private void addUnderlayComponents(Container target)
@@ -229,7 +229,11 @@ namespace osu.Game.Screens.Play
IsPaused = { BindTarget = GameplayClockContainer.IsPaused }
},
PlayerSettingsOverlay = { PlaybackSettings = { UserPlaybackRate = { BindTarget = GameplayClockContainer.UserPlaybackRate } } },
- KeyCounter = { AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded } },
+ KeyCounter =
+ {
+ AlwaysVisible = { BindTarget = DrawableRuleset.HasReplayLoaded },
+ IsCounting = false
+ },
RequestSeek = GameplayClockContainer.Seek,
Anchor = Anchor.Centre,
Origin = Anchor.Centre
@@ -286,6 +290,12 @@ namespace osu.Game.Screens.Play
HealthProcessor.IsBreakTime.BindTo(BreakOverlay.IsBreakTime);
}
+ private void onBreakTimeChanged(ValueChangedEvent isBreakTime)
+ {
+ updatePauseOnFocusLostState();
+ HUDOverlay.KeyCounter.IsCounting = !isBreakTime.NewValue;
+ }
+
private void updatePauseOnFocusLostState() =>
HUDOverlay.HoldToQuit.PauseOnFocusLost = PauseOnFocusLost
&& !DrawableRuleset.HasReplayLoaded.Value
diff --git a/osu.Game/Screens/Play/SkipOverlay.cs b/osu.Game/Screens/Play/SkipOverlay.cs
index 3daf5b1ff1..ac7e509c2c 100644
--- a/osu.Game/Screens/Play/SkipOverlay.cs
+++ b/osu.Game/Screens/Play/SkipOverlay.cs
@@ -116,7 +116,7 @@ namespace osu.Game.Screens.Play
{
base.Update();
- var progress = Math.Max(0, 1 - (gameplayClock.CurrentTime - displayTime) / (fadeOutBeginTime - displayTime));
+ var progress = fadeOutBeginTime <= displayTime ? 1 : Math.Max(0, 1 - (gameplayClock.CurrentTime - displayTime) / (fadeOutBeginTime - displayTime));
remainingTimeBox.Width = (float)Interpolation.Lerp(remainingTimeBox.Width, progress, Math.Clamp(Time.Elapsed / 40, 0, 1));
diff --git a/osu.Game/Tests/Visual/ModTestScene.cs b/osu.Game/Tests/Visual/ModTestScene.cs
new file mode 100644
index 0000000000..9abe543bf6
--- /dev/null
+++ b/osu.Game/Tests/Visual/ModTestScene.cs
@@ -0,0 +1,99 @@
+// 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 System.Collections.Generic;
+using JetBrains.Annotations;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets;
+using osu.Game.Rulesets.Mods;
+
+namespace osu.Game.Tests.Visual
+{
+ public abstract class ModTestScene : PlayerTestScene
+ {
+ protected sealed override bool HasCustomSteps => true;
+
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(ModTestScene)
+ };
+
+ protected ModTestScene(Ruleset ruleset)
+ : base(ruleset)
+ {
+ }
+
+ private ModTestData currentTestData;
+
+ protected void CreateModTest(ModTestData testData) => CreateTest(() =>
+ {
+ AddStep("set test data", () => currentTestData = testData);
+ });
+
+ public override void TearDownSteps()
+ {
+ AddUntilStep("test passed", () =>
+ {
+ if (currentTestData == null)
+ return true;
+
+ return currentTestData.PassCondition?.Invoke() ?? false;
+ });
+
+ base.TearDownSteps();
+ }
+
+ protected sealed override IBeatmap CreateBeatmap(RulesetInfo ruleset) => currentTestData?.Beatmap ?? base.CreateBeatmap(ruleset);
+
+ protected sealed override TestPlayer CreatePlayer(Ruleset ruleset)
+ {
+ var mods = new List(SelectedMods.Value);
+
+ if (currentTestData.Mod != null)
+ mods.Add(currentTestData.Mod);
+ if (currentTestData.Autoplay)
+ mods.Add(ruleset.GetAutoplayMod());
+
+ SelectedMods.Value = mods;
+
+ return new ModTestPlayer(AllowFail);
+ }
+
+ protected class ModTestPlayer : TestPlayer
+ {
+ protected override bool AllowFail { get; }
+
+ public ModTestPlayer(bool allowFail)
+ : base(false, false)
+ {
+ AllowFail = allowFail;
+ }
+ }
+
+ protected class ModTestData
+ {
+ ///
+ /// Whether to use a replay to simulate an auto-play. True by default.
+ ///
+ public bool Autoplay = true;
+
+ ///
+ /// The beatmap for this test case.
+ ///
+ [CanBeNull]
+ public IBeatmap Beatmap;
+
+ ///
+ /// The conditions that cause this test case to pass.
+ ///
+ [CanBeNull]
+ public Func PassCondition;
+
+ ///
+ /// The this test case tests.
+ ///
+ public Mod Mod;
+ }
+ }
+}
diff --git a/osu.Game/Tests/Visual/OsuTestScene.cs b/osu.Game/Tests/Visual/OsuTestScene.cs
index b203557fab..d1d8059cb1 100644
--- a/osu.Game/Tests/Visual/OsuTestScene.cs
+++ b/osu.Game/Tests/Visual/OsuTestScene.cs
@@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual
base.Content.Add(content = new DrawSizePreservingFillContainer());
}
- public void RecycleLocalStorage()
+ public virtual void RecycleLocalStorage()
{
if (localStorage?.IsValueCreated == true)
{
@@ -231,15 +231,8 @@ namespace osu.Game.Tests.Visual
{
private readonly IFrameBasedClock referenceClock;
- private readonly ManualClock clock = new ManualClock();
-
private bool running;
- ///
- /// Local offset added to the reference clock to resolve correct time.
- ///
- private double offset;
-
public TrackVirtualManual(IFrameBasedClock referenceClock)
{
this.referenceClock = referenceClock;
@@ -248,10 +241,10 @@ namespace osu.Game.Tests.Visual
public override bool Seek(double seek)
{
- offset = Math.Clamp(seek, 0, Length);
+ accumulated = Math.Clamp(seek, 0, Length);
lastReferenceTime = null;
- return offset == seek;
+ return accumulated == seek;
}
public override void Start()
@@ -270,9 +263,6 @@ namespace osu.Game.Tests.Visual
if (running)
{
running = false;
- // on stopping, the current value should be transferred out of the clock, as we can no longer rely on
- // the referenceClock (which will still be counting time).
- offset = clock.CurrentTime;
lastReferenceTime = null;
}
}
@@ -281,7 +271,9 @@ namespace osu.Game.Tests.Visual
private double? lastReferenceTime;
- public override double CurrentTime => clock.CurrentTime;
+ private double accumulated;
+
+ public override double CurrentTime => Math.Min(accumulated, Length);
protected override void UpdateState()
{
@@ -291,18 +283,12 @@ namespace osu.Game.Tests.Visual
{
double refTime = referenceClock.CurrentTime;
- if (!lastReferenceTime.HasValue)
- {
- // if the clock just started running, the current value should be transferred to the offset
- // (to zero the progression of time).
- offset -= refTime;
- }
+ if (lastReferenceTime.HasValue)
+ accumulated += (refTime - lastReferenceTime.Value) * Rate;
lastReferenceTime = refTime;
}
- clock.CurrentTime = Math.Min((lastReferenceTime ?? 0) + offset, Length);
-
if (CurrentTime >= Length)
{
Stop();
diff --git a/osu.Game/Tests/Visual/PlayerTestScene.cs b/osu.Game/Tests/Visual/PlayerTestScene.cs
index 7c5ba7d30f..0b09b5c08f 100644
--- a/osu.Game/Tests/Visual/PlayerTestScene.cs
+++ b/osu.Game/Tests/Visual/PlayerTestScene.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 System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Extensions.IEnumerableExtensions;
@@ -8,15 +9,19 @@ using osu.Framework.Testing;
using osu.Game.Configuration;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
-using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual
{
public abstract class PlayerTestScene : RateAdjustedBeatmapTestScene
{
+ ///
+ /// Whether custom test steps are provided. Custom tests should invoke to create the test steps.
+ ///
+ protected virtual bool HasCustomSteps { get; } = false;
+
private readonly Ruleset ruleset;
- protected Player Player;
+ protected TestPlayer Player;
protected PlayerTestScene(Ruleset ruleset)
{
@@ -37,7 +42,18 @@ namespace osu.Game.Tests.Visual
{
base.SetUpSteps();
- AddStep(ruleset.RulesetInfo.Name, loadPlayer);
+ if (!HasCustomSteps)
+ CreateTest(null);
+ }
+
+ protected void CreateTest(Action action)
+ {
+ if (action != null && !HasCustomSteps)
+ throw new InvalidOperationException($"Cannot add custom test steps without {nameof(HasCustomSteps)} being set.");
+
+ action?.Invoke();
+
+ AddStep(ruleset.RulesetInfo.Name, LoadPlayer);
AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1);
}
@@ -45,12 +61,14 @@ namespace osu.Game.Tests.Visual
protected virtual bool Autoplay => false;
- private void loadPlayer()
+ protected void LoadPlayer()
{
var beatmap = CreateBeatmap(ruleset.RulesetInfo);
Beatmap.Value = CreateWorkingBeatmap(beatmap);
+ SelectedMods.Value = Array.Empty();
+
if (!AllowFail)
{
var noFailMod = ruleset.GetAllMods().FirstOrDefault(m => m is ModNoFail);
@@ -69,6 +87,6 @@ namespace osu.Game.Tests.Visual
LoadScreen(Player);
}
- protected virtual Player CreatePlayer(Ruleset ruleset) => new TestPlayer(false, false);
+ protected virtual TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(false, false);
}
}
diff --git a/osu.Game/Tests/Visual/ScreenTestScene.cs b/osu.Game/Tests/Visual/ScreenTestScene.cs
index feca592049..d26aacf2bc 100644
--- a/osu.Game/Tests/Visual/ScreenTestScene.cs
+++ b/osu.Game/Tests/Visual/ScreenTestScene.cs
@@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual
public virtual void SetUpSteps() => addExitAllScreensStep();
[TearDownSteps]
- public void TearDownSteps() => addExitAllScreensStep();
+ public virtual void TearDownSteps() => addExitAllScreensStep();
private void addExitAllScreensStep()
{
diff --git a/osu.Game/Tests/Visual/TestPlayer.cs b/osu.Game/Tests/Visual/TestPlayer.cs
index 8e3821f1a0..f016d29f38 100644
--- a/osu.Game/Tests/Visual/TestPlayer.cs
+++ b/osu.Game/Tests/Visual/TestPlayer.cs
@@ -1,23 +1,51 @@
// 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 osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Game.Rulesets.Judgements;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Play;
namespace osu.Game.Tests.Visual
{
+ ///
+ /// A player that exposes many components that would otherwise not be available, for testing purposes.
+ ///
public class TestPlayer : Player
{
protected override bool PauseOnFocusLost { get; }
public new DrawableRuleset DrawableRuleset => base.DrawableRuleset;
+ ///
+ /// Mods from *player* (not OsuScreen).
+ ///
+ public new Bindable> Mods => base.Mods;
+
+ public new HUDOverlay HUDOverlay => base.HUDOverlay;
+
public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer;
+ public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
+
+ public new HealthProcessor HealthProcessor => base.HealthProcessor;
+
+ public readonly List Results = new List();
+
public TestPlayer(bool allowPause = true, bool showResults = true, bool pauseOnFocusLost = false)
: base(allowPause, showResults)
{
PauseOnFocusLost = pauseOnFocusLost;
}
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ ScoreProcessor.NewJudgement += r => Results.Add(r);
+ }
}
}
diff --git a/osu.Game/Updater/UpdateManager.cs b/osu.Game/Updater/UpdateManager.cs
index 48505a9891..28a295215f 100644
--- a/osu.Game/Updater/UpdateManager.cs
+++ b/osu.Game/Updater/UpdateManager.cs
@@ -34,12 +34,14 @@ namespace osu.Game.Updater
if (game.IsDeployedBuild && version != lastVersion)
{
- config.Set(OsuSetting.Version, version);
-
// only show a notification if we've previously saved a version to the config file (ie. not the first run).
if (!string.IsNullOrEmpty(lastVersion))
Notifications.Post(new UpdateCompleteNotification(version));
}
+
+ // debug / local compilations will reset to a non-release string.
+ // can be useful to check when an install has transitioned between release and otherwise (see OsuConfigManager's migrations).
+ config.Set(OsuSetting.Version, version);
}
private class UpdateCompleteNotification : SimpleNotification
diff --git a/osu.Game/Users/Drawables/UpdateableAvatar.cs b/osu.Game/Users/Drawables/UpdateableAvatar.cs
index 59fbb5f910..171462f3fc 100644
--- a/osu.Game/Users/Drawables/UpdateableAvatar.cs
+++ b/osu.Game/Users/Drawables/UpdateableAvatar.cs
@@ -43,6 +43,8 @@ namespace osu.Game.Users.Drawables
set => base.EdgeEffect = value;
}
+ protected override double LoadDelay => 200;
+
///
/// Whether to show a default guest representation on null user (as opposed to nothing).
///
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 4d59b709aa..855bda3679 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -23,7 +23,7 @@
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 6897d3e625..e2c4c09047 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -71,7 +71,7 @@
-
+
@@ -79,7 +79,7 @@
-
+
diff --git a/osu.iOS/OsuGameIOS.cs b/osu.iOS/OsuGameIOS.cs
index e5ff4aec95..3a16f81530 100644
--- a/osu.iOS/OsuGameIOS.cs
+++ b/osu.iOS/OsuGameIOS.cs
@@ -11,12 +11,5 @@ namespace osu.iOS
public class OsuGameIOS : OsuGame
{
public override Version AssemblyVersion => new Version(NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString());
-
- protected override void LoadComplete()
- {
- base.LoadComplete();
-
- Add(new UpdateManager());
- }
}
}