mirror of
https://github.com/ppy/osu.git
synced 2025-01-29 02:12:57 +08:00
Merge branch 'master' into better-filter-bypass
This commit is contained in:
commit
e085aa8c1d
42
.vscode/launch.json
vendored
42
.vscode/launch.json
vendored
@ -11,11 +11,6 @@
|
|||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Debug)",
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
"linux": {
|
|
||||||
"env": {
|
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -28,11 +23,6 @@
|
|||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Release)",
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
"linux": {
|
|
||||||
"env": {
|
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -45,11 +35,6 @@
|
|||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tests (Debug)",
|
"preLaunchTask": "Build tests (Debug)",
|
||||||
"linux": {
|
|
||||||
"env": {
|
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -62,11 +47,6 @@
|
|||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tests (Release)",
|
"preLaunchTask": "Build tests (Release)",
|
||||||
"linux": {
|
|
||||||
"env": {
|
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -80,11 +60,6 @@
|
|||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Debug)",
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
"linux": {
|
|
||||||
"env": {
|
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -98,11 +73,6 @@
|
|||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Release)",
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
"linux": {
|
|
||||||
"env": {
|
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -116,11 +86,6 @@
|
|||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tournament tests (Debug)",
|
"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"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -134,11 +99,6 @@
|
|||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tournament tests (Release)",
|
"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"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
@ -169,4 +129,4 @@
|
|||||||
"externalConsole": false
|
"externalConsole": false
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -30,11 +30,6 @@ namespace osu.Android
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override UpdateManager CreateUpdateManager() => new SimpleUpdateManager();
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
Add(new SimpleUpdateManager());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
@ -47,20 +47,25 @@ namespace osu.Desktop
|
|||||||
return null;
|
return null;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override UpdateManager CreateUpdateManager()
|
||||||
|
{
|
||||||
|
switch (RuntimeInfo.OS)
|
||||||
|
{
|
||||||
|
case RuntimeInfo.Platform.Windows:
|
||||||
|
return new SquirrelUpdateManager();
|
||||||
|
|
||||||
|
default:
|
||||||
|
return new SimpleUpdateManager();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
if (!noVersionOverlay)
|
if (!noVersionOverlay)
|
||||||
{
|
|
||||||
LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, Add);
|
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);
|
LoadComponentAsync(new DiscordRichPresence(), Add);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -7,7 +7,6 @@ using osu.Game.Rulesets.Catch.Objects;
|
|||||||
using osu.Game.Rulesets.Catch.UI;
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -51,7 +50,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
return beatmap;
|
return beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override TestPlayer CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
||||||
return base.CreatePlayer(ruleset);
|
return base.CreatePlayer(ruleset);
|
||||||
|
@ -0,0 +1,86 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
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<DrawableHitCircle>();
|
||||||
|
if (!objects.Any())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return objects.All(o => o.HitObject.TimePreempt == target);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool checkObjectsScale(float target)
|
||||||
|
{
|
||||||
|
var objects = Player.ChildrenOfType<DrawableHitCircle>();
|
||||||
|
if (!objects.Any())
|
||||||
|
return false;
|
||||||
|
|
||||||
|
return objects.All(o => Precision.AlmostEquals(o.ChildrenOfType<ShakeContainer>().First().Children.OfType<Container>().Single().Scale.X, target));
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool checkSomeHit()
|
||||||
|
{
|
||||||
|
return Player.ScoreProcessor.JudgedHits >= 2;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,9 +2,12 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
@ -114,6 +117,22 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
assertGroups();
|
assertGroups();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestStackedObjects()
|
||||||
|
{
|
||||||
|
addObjectsStep(() => new OsuHitObject[]
|
||||||
|
{
|
||||||
|
new HitCircle { Position = new Vector2(300, 100) },
|
||||||
|
new HitCircle
|
||||||
|
{
|
||||||
|
Position = new Vector2(300, 300),
|
||||||
|
StackHeight = 20
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
assertDirections();
|
||||||
|
}
|
||||||
|
|
||||||
private void addMultipleObjectsStep() => addObjectsStep(() => new OsuHitObject[]
|
private void addMultipleObjectsStep() => addObjectsStep(() => new OsuHitObject[]
|
||||||
{
|
{
|
||||||
new HitCircle { Position = new Vector2(100, 100) },
|
new HitCircle { Position = new Vector2(100, 100) },
|
||||||
@ -207,6 +226,33 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void assertDirections()
|
||||||
|
{
|
||||||
|
AddAssert("group directions are correct", () =>
|
||||||
|
{
|
||||||
|
for (int i = 0; i < hitObjectContainer.Count; i++)
|
||||||
|
{
|
||||||
|
DrawableOsuHitObject expectedStart = getObject(i);
|
||||||
|
DrawableOsuHitObject expectedEnd = i < hitObjectContainer.Count - 1 ? getObject(i + 1) : null;
|
||||||
|
|
||||||
|
if (expectedEnd == null)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
var points = getGroup(i).ChildrenOfType<FollowPoint>().ToArray();
|
||||||
|
if (points.Length == 0)
|
||||||
|
continue;
|
||||||
|
|
||||||
|
float expectedDirection = MathF.Atan2(expectedStart.Position.Y - expectedEnd.Position.Y, expectedStart.Position.X - expectedEnd.Position.X);
|
||||||
|
float realDirection = MathF.Atan2(expectedStart.Position.Y - points[^1].Position.Y, expectedStart.Position.X - points[^1].Position.X);
|
||||||
|
|
||||||
|
if (!Precision.AlmostEquals(expectedDirection, realDirection))
|
||||||
|
throw new AssertionException($"Expected group {i} in direction {expectedDirection}, but was {realDirection}.");
|
||||||
|
}
|
||||||
|
|
||||||
|
return true;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
private DrawableOsuHitObject getObject(int index) => hitObjectContainer[index];
|
private DrawableOsuHitObject getObject(int index) => hitObjectContainer[index];
|
||||||
|
|
||||||
private FollowPointConnection getGroup(int index) => followPointRenderer.Connections[index];
|
private FollowPointConnection getGroup(int index) => followPointRenderer.Connections[index];
|
||||||
|
@ -3,13 +3,13 @@
|
|||||||
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
{
|
{
|
||||||
public class TestSceneOsuFlashlight : TestSceneOsuPlayer
|
public class TestSceneOsuFlashlight : TestSceneOsuPlayer
|
||||||
{
|
{
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override TestPlayer CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
SelectedMods.Value = new Mod[] { new OsuModAutoplay(), new OsuModFlashlight(), };
|
SelectedMods.Value = new Mod[] { new OsuModAutoplay(), new OsuModFlashlight(), };
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Storyboards;
|
using osu.Game.Storyboards;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
@ -56,7 +55,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
private void checkNextHitObject(string skin) =>
|
private void checkNextHitObject(string skin) =>
|
||||||
AddUntilStep($"check skin from {skin}", () =>
|
AddUntilStep($"check skin from {skin}", () =>
|
||||||
{
|
{
|
||||||
var firstObject = ((TestPlayer)Player).DrawableRuleset.Playfield.HitObjectContainer.AliveObjects.OfType<DrawableHitCircle>().FirstOrDefault();
|
var firstObject = Player.DrawableRuleset.Playfield.HitObjectContainer.AliveObjects.OfType<DrawableHitCircle>().FirstOrDefault();
|
||||||
|
|
||||||
if (firstObject == null)
|
if (firstObject == null)
|
||||||
return false;
|
return false;
|
||||||
@ -75,7 +74,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private AudioManager audio { get; set; }
|
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);
|
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null) => new CustomSkinWorkingBeatmap(beatmap, storyboard, Clock, audio, testBeatmapSkin);
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Tests.Visual;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
@ -44,7 +43,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
base.SetUpSteps();
|
base.SetUpSteps();
|
||||||
|
|
||||||
AddUntilStep("wait for track to start running", () => track.IsRunning);
|
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]
|
[Test]
|
||||||
@ -89,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
AddStep($"seek to {time}", () => track.Seek(time));
|
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
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new Beatmap
|
||||||
|
@ -104,8 +104,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
Vector2 startPosition = osuStart.EndPosition;
|
Vector2 startPosition = osuStart.StackedEndPosition;
|
||||||
Vector2 endPosition = osuEnd.Position;
|
Vector2 endPosition = osuEnd.StackedPosition;
|
||||||
double endTime = osuEnd.StartTime;
|
double endTime = osuEnd.StartTime;
|
||||||
|
|
||||||
Vector2 distanceVector = endPosition - startPosition;
|
Vector2 distanceVector = endPosition - startPosition;
|
||||||
|
@ -1,23 +1,16 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Judgements;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Tests
|
namespace osu.Game.Rulesets.Taiko.Tests
|
||||||
{
|
{
|
||||||
public class TestSceneSwellJudgements : PlayerTestScene
|
public class TestSceneSwellJudgements : PlayerTestScene
|
||||||
{
|
{
|
||||||
protected new TestPlayer Player => (TestPlayer)base.Player;
|
|
||||||
|
|
||||||
public TestSceneSwellJudgements()
|
public TestSceneSwellJudgements()
|
||||||
: base(new TaikoRuleset())
|
: base(new TaikoRuleset())
|
||||||
{
|
{
|
||||||
@ -49,25 +42,5 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
|
|
||||||
return beatmap;
|
return beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Player CreatePlayer(Ruleset ruleset) => new TestPlayer();
|
|
||||||
|
|
||||||
protected class TestPlayer : Player
|
|
||||||
{
|
|
||||||
public readonly List<JudgementResult> Results = new List<JudgementResult>();
|
|
||||||
|
|
||||||
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
|
||||||
|
|
||||||
public TestPlayer()
|
|
||||||
: base(false, false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
ScoreProcessor.NewJudgement += r => Results.Add(r);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -4,11 +4,9 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osu.Game.Rulesets.Taiko.Beatmaps;
|
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||||
using osu.Game.Rulesets.Taiko.Mods;
|
using osu.Game.Rulesets.Taiko.Mods;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Tests
|
namespace osu.Game.Rulesets.Taiko.Tests
|
||||||
@ -22,10 +20,10 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
|
|
||||||
protected override bool AllowFail => true;
|
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();
|
SelectedMods.Value = SelectedMods.Value.Concat(new[] { new TaikoModSuddenDeath() }).ToArray();
|
||||||
return new ScoreAccessiblePlayer();
|
return base.CreatePlayer(ruleset);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) =>
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) =>
|
||||||
@ -49,20 +47,10 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
AddStep("Setup judgements", () =>
|
AddStep("Setup judgements", () =>
|
||||||
{
|
{
|
||||||
judged = false;
|
judged = false;
|
||||||
((ScoreAccessiblePlayer)Player).ScoreProcessor.NewJudgement += b => judged = true;
|
Player.ScoreProcessor.NewJudgement += b => judged = true;
|
||||||
});
|
});
|
||||||
AddUntilStep("swell judged", () => judged);
|
AddUntilStep("swell judged", () => judged);
|
||||||
AddAssert("not failed", () => !Player.HasFailed);
|
AddAssert("not failed", () => !Player.HasFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ScoreAccessiblePlayer : TestPlayer
|
|
||||||
{
|
|
||||||
public ScoreAccessiblePlayer()
|
|
||||||
: base(false, false)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
|
|
||||||
private DummySongSelect songSelect;
|
private DummySongSelect songSelect;
|
||||||
private TestPlayerLoader playerLoader;
|
private TestPlayerLoader playerLoader;
|
||||||
private TestPlayer player;
|
private LoadBlockingTestPlayer player;
|
||||||
private BeatmapManager manager;
|
private BeatmapManager manager;
|
||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
|
|
||||||
@ -81,7 +81,7 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
public void PlayerLoaderSettingsHoverTest()
|
public void PlayerLoaderSettingsHoverTest()
|
||||||
{
|
{
|
||||||
setupUserSettings();
|
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);
|
AddUntilStep("Wait for Player Loader to load", () => playerLoader?.IsLoaded ?? false);
|
||||||
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
|
AddAssert("Background retained from song select", () => songSelect.IsBackgroundCurrent());
|
||||||
AddStep("Trigger background preview", () =>
|
AddStep("Trigger background preview", () =>
|
||||||
@ -268,7 +268,7 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
{
|
{
|
||||||
setupUserSettings();
|
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);
|
AddUntilStep("Wait for Player Loader to load", () => playerLoader.IsLoaded);
|
||||||
AddStep("Move mouse to center of screen", () => InputManager.MoveMouseTo(playerLoader.ScreenPos));
|
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);
|
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);
|
protected override BackgroundScreen CreateBackground() => new FadeAccessibleBackground(Beatmap.Value);
|
||||||
|
|
||||||
@ -360,7 +360,7 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
public readonly Bindable<bool> ReplacesBackground = new Bindable<bool>();
|
public readonly Bindable<bool> ReplacesBackground = new Bindable<bool>();
|
||||||
public readonly Bindable<bool> IsPaused = new Bindable<bool>();
|
public readonly Bindable<bool> IsPaused = new Bindable<bool>();
|
||||||
|
|
||||||
public TestPlayer(bool allowPause = true)
|
public LoadBlockingTestPlayer(bool allowPause = true)
|
||||||
: base(allowPause)
|
: base(allowPause)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,6 @@ using System.ComponentModel;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Storyboards;
|
using osu.Game.Storyboards;
|
||||||
|
|
||||||
@ -14,20 +13,22 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Description("Player instantiated with an autoplay mod.")]
|
[Description("Player instantiated with an autoplay mod.")]
|
||||||
public class TestSceneAutoplay : TestSceneAllRulesetPlayers
|
public class TestSceneAutoplay : TestSceneAllRulesetPlayers
|
||||||
{
|
{
|
||||||
|
protected new TestPlayer Player => (TestPlayer)base.Player;
|
||||||
|
|
||||||
private ClockBackedTestWorkingBeatmap.TrackVirtualManual track;
|
private ClockBackedTestWorkingBeatmap.TrackVirtualManual track;
|
||||||
|
|
||||||
protected override Player CreatePlayer(Ruleset ruleset)
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
||||||
return new ScoreAccessiblePlayer();
|
return new TestPlayer(false, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void AddCheckSteps()
|
protected override void AddCheckSteps()
|
||||||
{
|
{
|
||||||
AddUntilStep("score above zero", () => ((ScoreAccessiblePlayer)Player).ScoreProcessor.TotalScore.Value > 0);
|
AddUntilStep("score above zero", () => Player.ScoreProcessor.TotalScore.Value > 0);
|
||||||
AddUntilStep("key counter counted keys", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2));
|
AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.Any(kc => kc.CountPresses > 2));
|
||||||
AddStep("rewind", () => track.Seek(-10000));
|
AddStep("rewind", () => track.Seek(-10000));
|
||||||
AddUntilStep("key counter reset", () => ((ScoreAccessiblePlayer)Player).HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
|
AddUntilStep("key counter reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
||||||
@ -38,18 +39,5 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
return working;
|
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)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -11,12 +10,8 @@ using osu.Framework.Utils;
|
|||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Judgements;
|
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
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 osu.Game.Storyboards;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -24,8 +19,6 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
public class TestSceneGameplayRewinding : PlayerTestScene
|
public class TestSceneGameplayRewinding : PlayerTestScene
|
||||||
{
|
{
|
||||||
private RulesetExposingPlayer player => (RulesetExposingPlayer)Player;
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private AudioManager audioManager { get; set; }
|
private AudioManager audioManager { get; set; }
|
||||||
|
|
||||||
@ -48,13 +41,13 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
AddUntilStep("wait for track to start running", () => track.IsRunning);
|
AddUntilStep("wait for track to start running", () => track.IsRunning);
|
||||||
addSeekStep(3000);
|
addSeekStep(3000);
|
||||||
AddAssert("all judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged));
|
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));
|
AddUntilStep("key counter counted keys", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses >= 7));
|
||||||
AddStep("clear results", () => player.AppliedResults.Clear());
|
AddStep("clear results", () => Player.Results.Clear());
|
||||||
addSeekStep(0);
|
addSeekStep(0);
|
||||||
AddAssert("none judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged));
|
AddAssert("none judged", () => Player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged));
|
||||||
AddUntilStep("key counters reset", () => player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
|
AddUntilStep("key counters reset", () => Player.HUDOverlay.KeyCounter.Children.All(kc => kc.CountPresses == 0));
|
||||||
AddAssert("no results triggered", () => player.AppliedResults.Count == 0);
|
AddAssert("no results triggered", () => Player.Results.Count == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSeekStep(double time)
|
private void addSeekStep(double time)
|
||||||
@ -62,13 +55,13 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddStep($"seek to {time}", () => track.Seek(time));
|
AddStep($"seek to {time}", () => track.Seek(time));
|
||||||
|
|
||||||
// Allow a few frames of lenience
|
// 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();
|
SelectedMods.Value = SelectedMods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
||||||
return new RulesetExposingPlayer();
|
return base.CreatePlayer(ruleset);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||||
@ -89,29 +82,5 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
return beatmap;
|
return beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class RulesetExposingPlayer : Player
|
|
||||||
{
|
|
||||||
public readonly List<JudgementResult> AppliedResults = new List<JudgementResult>();
|
|
||||||
|
|
||||||
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);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,7 +11,6 @@ using osu.Game.Graphics.Containers;
|
|||||||
using osu.Game.Graphics.Cursor;
|
using osu.Game.Graphics.Cursor;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
@ -282,14 +281,10 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
protected override bool AllowFail => true;
|
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
|
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 FailOverlayVisible => FailOverlay.State.Value == Visibility.Visible;
|
||||||
|
|
||||||
public bool PauseOverlayVisible => PauseOverlay.State.Value == Visibility.Visible;
|
public bool PauseOverlayVisible => PauseOverlay.State.Value == Visibility.Visible;
|
||||||
|
@ -9,15 +9,12 @@ using osu.Framework.Testing;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
[HeadlessTest] // we alter unsafe properties on the game host to test inactive window state.
|
[HeadlessTest] // we alter unsafe properties on the game host to test inactive window state.
|
||||||
public class TestScenePauseWhenInactive : PlayerTestScene
|
public class TestScenePauseWhenInactive : PlayerTestScene
|
||||||
{
|
{
|
||||||
protected new TestPlayer Player => (TestPlayer)base.Player;
|
|
||||||
|
|
||||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||||
{
|
{
|
||||||
var beatmap = (Beatmap)base.CreateBeatmap(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);
|
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);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,7 +9,6 @@ using System.Threading.Tasks;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Bindables;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
@ -307,17 +306,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank;
|
public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestPlayer : Visual.TestPlayer
|
protected class SlowLoadPlayer : TestPlayer
|
||||||
{
|
|
||||||
public new Bindable<IReadOnlyList<Mod>> Mods => base.Mods;
|
|
||||||
|
|
||||||
public TestPlayer(bool allowPause = true, bool showResults = true)
|
|
||||||
: base(allowPause, showResults)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected class SlowLoadPlayer : Visual.TestPlayer
|
|
||||||
{
|
{
|
||||||
public readonly ManualResetEventSlim AllowLoad = new ManualResetEventSlim(false);
|
public readonly ManualResetEventSlim AllowLoad = new ManualResetEventSlim(false);
|
||||||
|
|
||||||
|
@ -62,14 +62,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
var frameworkConfig = host.Dependencies.Get<FrameworkConfigManager>();
|
var frameworkConfig = host.Dependencies.Get<FrameworkConfigManager>();
|
||||||
frameworkConfig.GetBindable<double>(FrameworkSetting.CursorSensitivity).Disabled = false;
|
frameworkConfig.GetBindable<double>(FrameworkSetting.CursorSensitivity).Disabled = false;
|
||||||
|
|
||||||
Game = new TestOsuGame(LocalStorage, API);
|
CreateGame();
|
||||||
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);
|
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("Wait for load", () => Game.IsLoaded);
|
AddUntilStep("Wait for load", () => Game.IsLoaded);
|
||||||
@ -78,6 +71,18 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
ConfirmAtMainMenu();
|
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<Screen> newScreen)
|
protected void PushAndConfirm(Func<Screen> newScreen)
|
||||||
{
|
{
|
||||||
Screen screen = null;
|
Screen screen = null;
|
||||||
@ -97,12 +102,17 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
|
|
||||||
public new SettingsPanel Settings => base.Settings;
|
public new SettingsPanel Settings => base.Settings;
|
||||||
|
|
||||||
|
public new MusicController MusicController => base.MusicController;
|
||||||
|
|
||||||
public new OsuConfigManager LocalConfig => base.LocalConfig;
|
public new OsuConfigManager LocalConfig => base.LocalConfig;
|
||||||
|
|
||||||
public new Bindable<WorkingBeatmap> Beatmap => base.Beatmap;
|
public new Bindable<WorkingBeatmap> Beatmap => base.Beatmap;
|
||||||
|
|
||||||
public new Bindable<RulesetInfo> Ruleset => base.Ruleset;
|
public new Bindable<RulesetInfo> 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();
|
protected override Loader CreateLoader() => new TestLoader();
|
||||||
|
|
||||||
public new void PerformFromScreen(Action<IScreen> action, IEnumerable<Type> validScreens = null) => base.PerformFromScreen(action, validScreens);
|
public new void PerformFromScreen(Action<IScreen> action, IEnumerable<Type> validScreens = null) => base.PerformFromScreen(action, validScreens);
|
||||||
|
@ -114,6 +114,22 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
AddAssert("Options overlay was closed", () => Game.Settings.State.Value == Visibility.Hidden);
|
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() =>
|
private void pushEscape() =>
|
||||||
AddStep("Press escape", () => pressAndRelease(Key.Escape));
|
AddStep("Press escape", () => pressAndRelease(Key.Escape));
|
||||||
|
|
||||||
|
41
osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs
Normal file
41
osu.Game.Tests/Visual/Navigation/TestSettingsMigration.cs
Normal file
@ -0,0 +1,41 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
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<double>(OsuSetting.DisplayStarsMaximum), 10.1));
|
||||||
|
|
||||||
|
AddStep("set value again", () => Game.LocalConfig.Set<double>(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<double>(OsuSetting.DisplayStarsMaximum), 10));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,9 +2,11 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -13,13 +15,19 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneUserPanel : OsuTestScene
|
public class TestSceneUserPanel : OsuTestScene
|
||||||
{
|
{
|
||||||
private readonly UserPanel peppy;
|
private readonly Bindable<UserActivity> activity = new Bindable<UserActivity>();
|
||||||
|
|
||||||
public TestSceneUserPanel()
|
private UserPanel peppy;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private RulesetStore rulesetStore { get; set; }
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
UserPanel flyte;
|
UserPanel flyte;
|
||||||
|
|
||||||
Add(new FillFlowContainer
|
Child = new FillFlowContainer
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -44,34 +52,38 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
SupportLevel = 3,
|
SupportLevel = 3,
|
||||||
}) { Width = 300 },
|
}) { Width = 300 },
|
||||||
},
|
},
|
||||||
});
|
};
|
||||||
|
|
||||||
flyte.Status.Value = new UserStatusOnline();
|
flyte.Status.Value = new UserStatusOnline();
|
||||||
peppy.Status.Value = null;
|
peppy.Status.Value = null;
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void UserStatusesTests()
|
|
||||||
{
|
|
||||||
AddStep("online", () => { peppy.Status.Value = new UserStatusOnline(); });
|
|
||||||
AddStep(@"do not disturb", () => { peppy.Status.Value = new UserStatusDoNotDisturb(); });
|
|
||||||
AddStep(@"offline", () => { peppy.Status.Value = new UserStatusOffline(); });
|
|
||||||
AddStep(@"null status", () => { peppy.Status.Value = null; });
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void UserActivitiesTests()
|
|
||||||
{
|
|
||||||
Bindable<UserActivity> activity = new Bindable<UserActivity>();
|
|
||||||
|
|
||||||
peppy.Activity.BindTo(activity);
|
peppy.Activity.BindTo(activity);
|
||||||
|
});
|
||||||
|
|
||||||
AddStep("idle", () => { activity.Value = null; });
|
[Test]
|
||||||
AddStep("spectating", () => { activity.Value = new UserActivity.Spectating(); });
|
public void TestUserStatus()
|
||||||
AddStep("solo", () => { activity.Value = new UserActivity.SoloGame(null, null); });
|
{
|
||||||
AddStep("choosing", () => { activity.Value = new UserActivity.ChoosingBeatmap(); });
|
AddStep("online", () => peppy.Status.Value = new UserStatusOnline());
|
||||||
AddStep("editing", () => { activity.Value = new UserActivity.Editing(null); });
|
AddStep("do not disturb", () => peppy.Status.Value = new UserStatusDoNotDisturb());
|
||||||
AddStep("modding", () => { activity.Value = new UserActivity.Modding(); });
|
AddStep("offline", () => peppy.Status.Value = new UserStatusOffline());
|
||||||
|
AddStep("null status", () => peppy.Status.Value = null);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestUserActivity()
|
||||||
|
{
|
||||||
|
AddStep("set online status", () => peppy.Status.Value = new UserStatusOnline());
|
||||||
|
|
||||||
|
AddStep("idle", () => activity.Value = null);
|
||||||
|
AddStep("spectating", () => activity.Value = new UserActivity.Spectating());
|
||||||
|
AddStep("solo (osu!)", () => activity.Value = soloGameStatusForRuleset(0));
|
||||||
|
AddStep("solo (osu!taiko)", () => activity.Value = soloGameStatusForRuleset(1));
|
||||||
|
AddStep("solo (osu!catch)", () => activity.Value = soloGameStatusForRuleset(2));
|
||||||
|
AddStep("solo (osu!mania)", () => activity.Value = soloGameStatusForRuleset(3));
|
||||||
|
AddStep("choosing", () => activity.Value = new UserActivity.ChoosingBeatmap());
|
||||||
|
AddStep("editing", () => activity.Value = new UserActivity.Editing(null));
|
||||||
|
AddStep("modding", () => activity.Value = new UserActivity.Modding());
|
||||||
|
}
|
||||||
|
|
||||||
|
private UserActivity soloGameStatusForRuleset(int rulesetId) => new UserActivity.SoloGame(null, rulesetStore.GetRuleset(rulesetId));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Configuration.Tracking;
|
using osu.Framework.Configuration.Tracking;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
@ -126,6 +127,35 @@ namespace osu.Game.Configuration
|
|||||||
public OsuConfigManager(Storage storage)
|
public OsuConfigManager(Storage storage)
|
||||||
: base(storage)
|
: base(storage)
|
||||||
{
|
{
|
||||||
|
Migrate();
|
||||||
|
}
|
||||||
|
|
||||||
|
public void Migrate()
|
||||||
|
{
|
||||||
|
// arrives as 2020.123.0
|
||||||
|
var rawVersion = Get<string>(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<double>(OsuSetting.DisplayStarsMaximum);
|
||||||
|
|
||||||
|
if (maxStars.Value == 10)
|
||||||
|
maxStars.Value = maxStars.MaxValue;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public override TrackedSettings CreateTrackedSettings() => new TrackedSettings
|
public override TrackedSettings CreateTrackedSettings() => new TrackedSettings
|
||||||
|
@ -43,6 +43,7 @@ using osu.Game.Overlays.Volume;
|
|||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
|
using osu.Game.Updater;
|
||||||
using osu.Game.Utils;
|
using osu.Game.Utils;
|
||||||
using LogLevel = osu.Framework.Logging.LogLevel;
|
using LogLevel = osu.Framework.Logging.LogLevel;
|
||||||
|
|
||||||
@ -390,24 +391,35 @@ namespace osu.Game
|
|||||||
|
|
||||||
protected virtual Loader CreateLoader() => new Loader();
|
protected virtual Loader CreateLoader() => new Loader();
|
||||||
|
|
||||||
|
protected virtual UpdateManager CreateUpdateManager() => new UpdateManager();
|
||||||
|
|
||||||
protected override Container CreateScalingContainer() => new ScalingContainer(ScalingMode.Everything);
|
protected override Container CreateScalingContainer() => new ScalingContainer(ScalingMode.Everything);
|
||||||
|
|
||||||
#region Beatmap progression
|
#region Beatmap progression
|
||||||
|
|
||||||
private void beatmapChanged(ValueChangedEvent<WorkingBeatmap> beatmap)
|
private void beatmapChanged(ValueChangedEvent<WorkingBeatmap> beatmap)
|
||||||
{
|
{
|
||||||
var nextBeatmap = beatmap.NewValue;
|
beatmap.OldValue?.CancelAsyncLoad();
|
||||||
if (nextBeatmap?.Track != null)
|
|
||||||
nextBeatmap.Track.Completed += currentTrackCompleted;
|
|
||||||
|
|
||||||
var oldBeatmap = beatmap.OldValue;
|
|
||||||
if (oldBeatmap?.Track != null)
|
|
||||||
oldBeatmap.Track.Completed -= currentTrackCompleted;
|
|
||||||
|
|
||||||
updateModDefaults();
|
updateModDefaults();
|
||||||
|
|
||||||
oldBeatmap?.CancelAsyncLoad();
|
var newBeatmap = beatmap.NewValue;
|
||||||
nextBeatmap?.BeginAsyncLoad();
|
|
||||||
|
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<IReadOnlyList<Mod>> mods)
|
private void modsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
|
||||||
@ -428,12 +440,6 @@ namespace osu.Game
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void currentTrackCompleted() => Schedule(() =>
|
|
||||||
{
|
|
||||||
if (!Beatmap.Value.Track.Looping && !Beatmap.Disabled)
|
|
||||||
musicController.NextTrack();
|
|
||||||
});
|
|
||||||
|
|
||||||
#endregion
|
#endregion
|
||||||
|
|
||||||
private ScheduledDelegate performFromMainMenuTask;
|
private ScheduledDelegate performFromMainMenuTask;
|
||||||
@ -585,7 +591,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
loadComponentSingleFile(new OnScreenDisplay(), Add, true);
|
loadComponentSingleFile(new OnScreenDisplay(), Add, true);
|
||||||
|
|
||||||
loadComponentSingleFile(musicController = new MusicController(), Add, true);
|
loadComponentSingleFile(MusicController = new MusicController(), Add, true);
|
||||||
|
|
||||||
loadComponentSingleFile(notifications = new NotificationOverlay
|
loadComponentSingleFile(notifications = new NotificationOverlay
|
||||||
{
|
{
|
||||||
@ -628,6 +634,7 @@ namespace osu.Game
|
|||||||
chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;
|
chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;
|
||||||
|
|
||||||
Add(externalLinkOpener = new ExternalLinkOpener());
|
Add(externalLinkOpener = new ExternalLinkOpener());
|
||||||
|
Add(CreateUpdateManager()); // dependency on notification overlay
|
||||||
|
|
||||||
// side overlays which cancel each other.
|
// side overlays which cancel each other.
|
||||||
var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications };
|
var singleDisplaySideOverlays = new OverlayContainer[] { Settings, notifications };
|
||||||
@ -893,7 +900,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
private ScalingContainer screenContainer;
|
private ScalingContainer screenContainer;
|
||||||
|
|
||||||
private MusicController musicController;
|
protected MusicController MusicController { get; private set; }
|
||||||
|
|
||||||
protected override bool OnExiting()
|
protected override bool OnExiting()
|
||||||
{
|
{
|
||||||
@ -951,7 +958,7 @@ namespace osu.Game
|
|||||||
{
|
{
|
||||||
OverlayActivationMode.Value = newOsuScreen.InitialOverlayActivationMode;
|
OverlayActivationMode.Value = newOsuScreen.InitialOverlayActivationMode;
|
||||||
|
|
||||||
musicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments;
|
MusicController.AllowRateAdjustments = newOsuScreen.AllowRateAdjustments;
|
||||||
|
|
||||||
if (newOsuScreen.HideOverlaysOnEnter)
|
if (newOsuScreen.HideOverlaysOnEnter)
|
||||||
CloseAllOverlays();
|
CloseAllOverlays();
|
||||||
|
@ -97,7 +97,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
public bool IsDeployedBuild => AssemblyVersion.Major > 0;
|
public bool IsDeployedBuild => AssemblyVersion.Major > 0;
|
||||||
|
|
||||||
public string Version
|
public virtual string Version
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
@ -211,6 +211,10 @@ namespace osu.Game
|
|||||||
Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));
|
Audio.Tracks.AddAdjustment(AdjustableProperty.Volume, new BindableDouble(0.8));
|
||||||
|
|
||||||
Beatmap = new NonNullableBindable<WorkingBeatmap>(defaultBeatmap);
|
Beatmap = new NonNullableBindable<WorkingBeatmap>(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(() =>
|
Beatmap.BindValueChanged(b => ScheduleAfterChildren(() =>
|
||||||
{
|
{
|
||||||
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
|
// compare to last beatmap as sometimes the two may share a track representation (optimisation, see WorkingBeatmap.TransferTo)
|
||||||
|
@ -15,7 +15,7 @@ namespace osu.Game.Overlays.SearchableList
|
|||||||
{
|
{
|
||||||
public abstract class SearchableListOverlay : FullscreenOverlay
|
public abstract class SearchableListOverlay : FullscreenOverlay
|
||||||
{
|
{
|
||||||
public const float WIDTH_PADDING = 10;
|
public const float WIDTH_PADDING = 80;
|
||||||
|
|
||||||
protected SearchableListOverlay(OverlayColourScheme colourScheme)
|
protected SearchableListOverlay(OverlayColourScheme colourScheme)
|
||||||
: base(colourScheme)
|
: base(colourScheme)
|
||||||
@ -80,7 +80,7 @@ namespace osu.Game.Overlays.SearchableList
|
|||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Padding = new MarginPadding { Horizontal = WIDTH_PADDING, Bottom = 50 },
|
Padding = new MarginPadding { Horizontal = 10, Bottom = 50 },
|
||||||
Direction = FillDirection.Vertical,
|
Direction = FillDirection.Vertical,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
99
osu.Game/Tests/Visual/ModTestScene.cs
Normal file
99
osu.Game/Tests/Visual/ModTestScene.cs
Normal file
@ -0,0 +1,99 @@
|
|||||||
|
// 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.
|
||||||
|
|
||||||
|
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<Type> 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<Mod>(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
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Whether to use a replay to simulate an auto-play. True by default.
|
||||||
|
/// </summary>
|
||||||
|
public bool Autoplay = true;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The beatmap for this test case.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public IBeatmap Beatmap;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The conditions that cause this test case to pass.
|
||||||
|
/// </summary>
|
||||||
|
[CanBeNull]
|
||||||
|
public Func<bool> PassCondition;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The <see cref="Mod"/> this test case tests.
|
||||||
|
/// </summary>
|
||||||
|
public Mod Mod;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
base.Content.Add(content = new DrawSizePreservingFillContainer());
|
base.Content.Add(content = new DrawSizePreservingFillContainer());
|
||||||
}
|
}
|
||||||
|
|
||||||
public void RecycleLocalStorage()
|
public virtual void RecycleLocalStorage()
|
||||||
{
|
{
|
||||||
if (localStorage?.IsValueCreated == true)
|
if (localStorage?.IsValueCreated == true)
|
||||||
{
|
{
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
@ -8,15 +9,19 @@ using osu.Framework.Testing;
|
|||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Screens.Play;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
public abstract class PlayerTestScene : RateAdjustedBeatmapTestScene
|
public abstract class PlayerTestScene : RateAdjustedBeatmapTestScene
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Whether custom test steps are provided. Custom tests should invoke <see cref="CreateTest"/> to create the test steps.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual bool HasCustomSteps { get; } = false;
|
||||||
|
|
||||||
private readonly Ruleset ruleset;
|
private readonly Ruleset ruleset;
|
||||||
|
|
||||||
protected Player Player;
|
protected TestPlayer Player;
|
||||||
|
|
||||||
protected PlayerTestScene(Ruleset ruleset)
|
protected PlayerTestScene(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
@ -37,7 +42,18 @@ namespace osu.Game.Tests.Visual
|
|||||||
{
|
{
|
||||||
base.SetUpSteps();
|
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);
|
AddUntilStep("player loaded", () => Player.IsLoaded && Player.Alpha == 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -45,12 +61,14 @@ namespace osu.Game.Tests.Visual
|
|||||||
|
|
||||||
protected virtual bool Autoplay => false;
|
protected virtual bool Autoplay => false;
|
||||||
|
|
||||||
private void loadPlayer()
|
protected void LoadPlayer()
|
||||||
{
|
{
|
||||||
var beatmap = CreateBeatmap(ruleset.RulesetInfo);
|
var beatmap = CreateBeatmap(ruleset.RulesetInfo);
|
||||||
|
|
||||||
Beatmap.Value = CreateWorkingBeatmap(beatmap);
|
Beatmap.Value = CreateWorkingBeatmap(beatmap);
|
||||||
|
|
||||||
|
SelectedMods.Value = Array.Empty<Mod>();
|
||||||
|
|
||||||
if (!AllowFail)
|
if (!AllowFail)
|
||||||
{
|
{
|
||||||
var noFailMod = ruleset.GetAllMods().FirstOrDefault(m => m is ModNoFail);
|
var noFailMod = ruleset.GetAllMods().FirstOrDefault(m => m is ModNoFail);
|
||||||
@ -69,6 +87,6 @@ namespace osu.Game.Tests.Visual
|
|||||||
LoadScreen(Player);
|
LoadScreen(Player);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Player CreatePlayer(Ruleset ruleset) => new TestPlayer(false, false);
|
protected virtual TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(false, false);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,7 +34,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
public virtual void SetUpSteps() => addExitAllScreensStep();
|
public virtual void SetUpSteps() => addExitAllScreensStep();
|
||||||
|
|
||||||
[TearDownSteps]
|
[TearDownSteps]
|
||||||
public void TearDownSteps() => addExitAllScreensStep();
|
public virtual void TearDownSteps() => addExitAllScreensStep();
|
||||||
|
|
||||||
private void addExitAllScreensStep()
|
private void addExitAllScreensStep()
|
||||||
{
|
{
|
||||||
|
@ -1,23 +1,51 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// 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.
|
// 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.Rulesets.UI;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual
|
namespace osu.Game.Tests.Visual
|
||||||
{
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A player that exposes many components that would otherwise not be available, for testing purposes.
|
||||||
|
/// </summary>
|
||||||
public class TestPlayer : Player
|
public class TestPlayer : Player
|
||||||
{
|
{
|
||||||
protected override bool PauseOnFocusLost { get; }
|
protected override bool PauseOnFocusLost { get; }
|
||||||
|
|
||||||
public new DrawableRuleset DrawableRuleset => base.DrawableRuleset;
|
public new DrawableRuleset DrawableRuleset => base.DrawableRuleset;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Mods from *player* (not OsuScreen).
|
||||||
|
/// </summary>
|
||||||
|
public new Bindable<IReadOnlyList<Mod>> Mods => base.Mods;
|
||||||
|
|
||||||
|
public new HUDOverlay HUDOverlay => base.HUDOverlay;
|
||||||
|
|
||||||
public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer;
|
public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer;
|
||||||
|
|
||||||
|
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||||
|
|
||||||
|
public new HealthProcessor HealthProcessor => base.HealthProcessor;
|
||||||
|
|
||||||
|
public readonly List<JudgementResult> Results = new List<JudgementResult>();
|
||||||
|
|
||||||
public TestPlayer(bool allowPause = true, bool showResults = true, bool pauseOnFocusLost = false)
|
public TestPlayer(bool allowPause = true, bool showResults = true, bool pauseOnFocusLost = false)
|
||||||
: base(allowPause, showResults)
|
: base(allowPause, showResults)
|
||||||
{
|
{
|
||||||
PauseOnFocusLost = pauseOnFocusLost;
|
PauseOnFocusLost = pauseOnFocusLost;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
ScoreProcessor.NewJudgement += r => Results.Add(r);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,12 +34,14 @@ namespace osu.Game.Updater
|
|||||||
|
|
||||||
if (game.IsDeployedBuild && version != lastVersion)
|
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).
|
// only show a notification if we've previously saved a version to the config file (ie. not the first run).
|
||||||
if (!string.IsNullOrEmpty(lastVersion))
|
if (!string.IsNullOrEmpty(lastVersion))
|
||||||
Notifications.Post(new UpdateCompleteNotification(version));
|
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
|
private class UpdateCompleteNotification : SimpleNotification
|
||||||
|
@ -11,12 +11,5 @@ namespace osu.iOS
|
|||||||
public class OsuGameIOS : OsuGame
|
public class OsuGameIOS : OsuGame
|
||||||
{
|
{
|
||||||
public override Version AssemblyVersion => new Version(NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString());
|
public override Version AssemblyVersion => new Version(NSBundle.MainBundle.InfoDictionary["CFBundleVersion"].ToString());
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
|
|
||||||
Add(new UpdateManager());
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Loading…
Reference in New Issue
Block a user