diff --git a/.idea/.idea.osu.Android/.idea/.name b/.idea/.idea.osu.Android/.idea/.name
new file mode 100644
index 0000000000..86363b495c
--- /dev/null
+++ b/.idea/.idea.osu.Android/.idea/.name
@@ -0,0 +1 @@
+osu.Android
\ No newline at end of file
diff --git a/.idea/.idea.osu.Android/.idea/indexLayout.xml b/.idea/.idea.osu.Android/.idea/indexLayout.xml
new file mode 100644
index 0000000000..7b08163ceb
--- /dev/null
+++ b/.idea/.idea.osu.Android/.idea/indexLayout.xml
@@ -0,0 +1,8 @@
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu.Android/.idea/misc.xml b/.idea/.idea.osu.Android/.idea/misc.xml
new file mode 100644
index 0000000000..1d8c84d0af
--- /dev/null
+++ b/.idea/.idea.osu.Android/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu.Android/.idea/projectSettingsUpdater.xml b/.idea/.idea.osu.Android/.idea/projectSettingsUpdater.xml
new file mode 100644
index 0000000000..4bb9f4d2a0
--- /dev/null
+++ b/.idea/.idea.osu.Android/.idea/projectSettingsUpdater.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu.Android/.idea/vcs.xml b/.idea/.idea.osu.Android/.idea/vcs.xml
new file mode 100644
index 0000000000..94a25f7f4c
--- /dev/null
+++ b/.idea/.idea.osu.Android/.idea/vcs.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu/.idea/misc.xml b/.idea/.idea.osu/.idea/misc.xml
new file mode 100644
index 0000000000..1d8c84d0af
--- /dev/null
+++ b/.idea/.idea.osu/.idea/misc.xml
@@ -0,0 +1,6 @@
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu/.idea/modules.xml b/.idea/.idea.osu/.idea/modules.xml
deleted file mode 100644
index 0360fdbc5e..0000000000
--- a/.idea/.idea.osu/.idea/modules.xml
+++ /dev/null
@@ -1,8 +0,0 @@
-
-
-
-
-
-
-
-
\ No newline at end of file
diff --git a/.idea/.idea.osu/.idea/projectSettingsUpdater.xml b/.idea/.idea.osu/.idea/projectSettingsUpdater.xml
index 7515e76054..4bb9f4d2a0 100644
--- a/.idea/.idea.osu/.idea/projectSettingsUpdater.xml
+++ b/.idea/.idea.osu/.idea/projectSettingsUpdater.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/README.md b/README.md
index f18c5e76f9..b1dfcab416 100644
--- a/README.md
+++ b/README.md
@@ -31,7 +31,7 @@ If you are looking to install or test osu! without setting up a development envi
**Latest build:**
-| [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.12+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 10+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk)
+| [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.15+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 10+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk)
| ------------- | ------------- | ------------- | ------------- | ------------- |
- The iOS testflight link may fill up (Apple has a hard limit of 10,000 users). We reset it occasionally when this happens. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements of link resets.
diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuGame.cs b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuGame.cs
index 536fdfc6df..5973db908c 100644
--- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuGame.cs
+++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/TestSceneOsuGame.cs
@@ -4,7 +4,6 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Platform;
using osu.Game.Tests.Visual;
using osuTK.Graphics;
@@ -13,7 +12,7 @@ namespace osu.Game.Rulesets.EmptyFreeform.Tests
public class TestSceneOsuGame : OsuTestScene
{
[BackgroundDependencyLoader]
- private void load(GameHost host, OsuGameBase gameBase)
+ private void load()
{
Children = new Drawable[]
{
diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj
index 3c6aaa39ca..a7078f1c09 100644
--- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj
+++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs
index 3cdf44e6f1..b75a5ec187 100644
--- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs
+++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs
@@ -4,7 +4,6 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Platform;
using osu.Game.Tests.Visual;
using osuTK.Graphics;
@@ -13,7 +12,7 @@ namespace osu.Game.Rulesets.Pippidon.Tests
public class TestSceneOsuGame : OsuTestScene
{
[BackgroundDependencyLoader]
- private void load(GameHost host, OsuGameBase gameBase)
+ private void load()
{
Children = new Drawable[]
{
diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
index 0719dd30df..c133b0e3f8 100644
--- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
+++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuGame.cs b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuGame.cs
index 4d3f5086d9..ffe921b54c 100644
--- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuGame.cs
+++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/TestSceneOsuGame.cs
@@ -4,7 +4,6 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Platform;
using osu.Game.Tests.Visual;
using osuTK.Graphics;
@@ -13,7 +12,7 @@ namespace osu.Game.Rulesets.EmptyScrolling.Tests
public class TestSceneOsuGame : OsuTestScene
{
[BackgroundDependencyLoader]
- private void load(GameHost host, OsuGameBase gameBase)
+ private void load()
{
Children = new Drawable[]
{
diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj
index d0db43cc81..92b48470e8 100644
--- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj
+++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs
index 3cdf44e6f1..b75a5ec187 100644
--- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs
+++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/TestSceneOsuGame.cs
@@ -4,7 +4,6 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Platform;
using osu.Game.Tests.Visual;
using osuTK.Graphics;
@@ -13,7 +12,7 @@ namespace osu.Game.Rulesets.Pippidon.Tests
public class TestSceneOsuGame : OsuTestScene
{
[BackgroundDependencyLoader]
- private void load(GameHost host, OsuGameBase gameBase)
+ private void load()
{
Children = new Drawable[]
{
diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
index 0719dd30df..c133b0e3f8 100644
--- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
+++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
@@ -12,7 +12,7 @@
-
+
diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs
index 0e50030162..ab8c6bb2e9 100644
--- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs
+++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/UI/PippidonPlayfield.cs
@@ -7,7 +7,6 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
@@ -28,7 +27,7 @@ namespace osu.Game.Rulesets.Pippidon.UI
private PippidonCharacter pippidon;
[BackgroundDependencyLoader]
- private void load(TextureStore textures)
+ private void load()
{
AddRangeInternal(new Drawable[]
{
diff --git a/osu.Android.props b/osu.Android.props
index 92adbebf5a..b296c114e9 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -51,11 +51,11 @@
-
-
+
+
-
+
diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs
index b234207848..cd3fb7eb61 100644
--- a/osu.Desktop/OsuGameDesktop.cs
+++ b/osu.Desktop/OsuGameDesktop.cs
@@ -10,14 +10,11 @@ using System.Runtime.Versioning;
using System.Threading.Tasks;
using Microsoft.Win32;
using osu.Desktop.Security;
-using osu.Desktop.Overlays;
using osu.Framework.Platform;
using osu.Game;
using osu.Desktop.Updater;
using osu.Framework;
using osu.Framework.Logging;
-using osu.Framework.Screens;
-using osu.Game.Screens.Menu;
using osu.Game.Updater;
using osu.Desktop.Windows;
using osu.Framework.Threading;
@@ -27,13 +24,9 @@ namespace osu.Desktop
{
internal class OsuGameDesktop : OsuGame
{
- private readonly bool noVersionOverlay;
- private VersionManager versionManager;
-
public OsuGameDesktop(string[] args = null)
: base(args)
{
- noVersionOverlay = args?.Any(a => a == "--no-version-overlay") ?? false;
}
public override StableStorage GetStorageForStableInstall()
@@ -114,9 +107,6 @@ namespace osu.Desktop
{
base.LoadComplete();
- if (!noVersionOverlay)
- LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, ScreenContainer.Add);
-
LoadComponentAsync(new DiscordRichPresence(), Add);
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows)
@@ -125,23 +115,6 @@ namespace osu.Desktop
LoadComponentAsync(new ElevatedPrivilegesChecker(), Add);
}
- protected override void ScreenChanged(IScreen lastScreen, IScreen newScreen)
- {
- base.ScreenChanged(lastScreen, newScreen);
-
- switch (newScreen)
- {
- case IntroScreen _:
- case MainMenu _:
- versionManager?.Show();
- break;
-
- default:
- versionManager?.Hide();
- break;
- }
- }
-
public override void SetHost(GameHost host)
{
base.SetHost(host);
diff --git a/osu.Desktop/Security/ElevatedPrivilegesChecker.cs b/osu.Desktop/Security/ElevatedPrivilegesChecker.cs
index 62ea3e0399..8f3ad853dc 100644
--- a/osu.Desktop/Security/ElevatedPrivilegesChecker.cs
+++ b/osu.Desktop/Security/ElevatedPrivilegesChecker.cs
@@ -73,7 +73,7 @@ namespace osu.Desktop.Security
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours, NotificationOverlay notificationOverlay)
+ private void load(OsuColour colours)
{
Icon = FontAwesome.Solid.ShieldAlt;
IconBackground.Colour = colours.YellowDark;
diff --git a/osu.Desktop/Windows/WindowsKey.cs b/osu.Desktop/Windows/WindowsKey.cs
index f19d741107..fdca2028d3 100644
--- a/osu.Desktop/Windows/WindowsKey.cs
+++ b/osu.Desktop/Windows/WindowsKey.cs
@@ -4,6 +4,8 @@
using System;
using System.Runtime.InteropServices;
+// ReSharper disable IdentifierTypo
+
namespace osu.Desktop.Windows
{
internal class WindowsKey
diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
index 57b914bee6..a8599f2cb6 100644
--- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
+++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
index 13f2e25f05..d5496b7479 100644
--- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
+++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
@@ -4,7 +4,7 @@
-
+
diff --git a/osu.Game.Rulesets.Mania.Tests/Resources/special-skin/skin.ini b/osu.Game.Rulesets.Mania.Tests/Resources/special-skin/skin.ini
index 36765d61bf..9c987efc60 100644
--- a/osu.Game.Rulesets.Mania.Tests/Resources/special-skin/skin.ini
+++ b/osu.Game.Rulesets.Mania.Tests/Resources/special-skin/skin.ini
@@ -4,11 +4,14 @@ Version: 2.5
[Mania]
Keys: 4
ColumnLineWidth: 3,1,3,1,1
-Hit0: mania/hit0
-Hit50: mania/hit50
-Hit100: mania/hit100
-Hit200: mania/hit200
-Hit300: mania/hit300
-Hit300g: mania/hit300g
+// some skins found in the wild had configuration keys where the @2x suffix was included in the values.
+// the expected compatibility behaviour is that the presence of the @2x suffix shouldn't change anything
+// if @2x assets are present.
+Hit0: mania/hit0@2x
+Hit50: mania/hit50@2x
+Hit100: mania/hit100@2x
+Hit200: mania/hit200@2x
+Hit300: mania/hit300@2x
+Hit300g: mania/hit300g@2x
StageLeft: mania/stage-left
StageRight: mania/stage-right
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs
index 75a5495078..d033676ec7 100644
--- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs
+++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneDrawableJudgement.cs
@@ -5,8 +5,10 @@ using System;
using System.Linq;
using osu.Framework.Extensions;
using osu.Framework.Graphics;
+using osu.Framework.Testing;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Scoring;
+using osu.Game.Rulesets.Mania.Skinning.Legacy;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
@@ -23,15 +25,24 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{
if (hitWindows.IsHitResultAllowed(result))
{
- AddStep("Show " + result.GetDescription(), () => SetContents(_ =>
- new DrawableManiaJudgement(new JudgementResult(new HitObject { StartTime = Time.Current }, new Judgement())
- {
- Type = result
- }, null)
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- }));
+ AddStep("Show " + result.GetDescription(), () =>
+ {
+ SetContents(_ =>
+ new DrawableManiaJudgement(new JudgementResult(new HitObject { StartTime = Time.Current }, new Judgement())
+ {
+ Type = result
+ }, null)
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ });
+
+ // for test purposes, undo the Y adjustment related to the `ScorePosition` legacy positioning config value
+ // (see `LegacyManiaJudgementPiece.load()`).
+ // this prevents the judgements showing somewhere below or above the bounding box of the judgement.
+ foreach (var legacyPiece in this.ChildrenOfType())
+ legacyPiece.Y = 0;
+ });
}
}
}
diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
index d51a6da4f9..2f12b1535e 100644
--- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
+++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
@@ -4,7 +4,7 @@
-
+
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs
index 5259fcbd5f..35889aea0c 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs
@@ -9,7 +9,6 @@ using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
using osu.Game.Rulesets.Mania.Objects;
-using osu.Game.Rulesets.UI.Scrolling;
using osuTK;
namespace osu.Game.Rulesets.Mania.Edit.Blueprints
@@ -28,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
}
[BackgroundDependencyLoader]
- private void load(IScrollingInfo scrollingInfo)
+ private void load()
{
InternalChildren = new Drawable[]
{
diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
index b0e7545d3e..6fc7dc018b 100644
--- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs
+++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
@@ -49,7 +49,7 @@ namespace osu.Game.Rulesets.Mania
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor();
- public override HealthProcessor CreateHealthProcessor(double drainStartTime) => new DrainingHealthProcessor(drainStartTime, 0.5);
+ public override HealthProcessor CreateHealthProcessor(double drainStartTime) => new ManiaHealthProcessor(drainStartTime, 0.5);
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap, this);
diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs
new file mode 100644
index 0000000000..57c2ba9c6d
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/Scoring/ManiaHealthProcessor.cs
@@ -0,0 +1,23 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Game.Rulesets.Judgements;
+using osu.Game.Rulesets.Scoring;
+
+namespace osu.Game.Rulesets.Mania.Scoring
+{
+ public class ManiaHealthProcessor : DrainingHealthProcessor
+ {
+ ///
+ public ManiaHealthProcessor(double drainStartTime, double drainLenience = 0)
+ : base(drainStartTime, drainLenience)
+ {
+ }
+
+ protected override HitResult GetSimulatedHitResult(Judgement judgement)
+ {
+ // Users are not expected to attain perfect judgements for all notes due to the tighter hit window.
+ return judgement.MaxResult == HitResult.Perfect ? HitResult.Great : judgement.MaxResult;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs
new file mode 100644
index 0000000000..b43b2b1461
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneSliderSnapping.cs
@@ -0,0 +1,225 @@
+// 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.Input.Events;
+using osu.Framework.Testing;
+using osu.Framework.Utils;
+using osu.Game.Beatmaps;
+using osu.Game.Beatmaps.ControlPoints;
+using osu.Game.Input.Bindings;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Osu.Edit;
+using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Rulesets.Osu.UI;
+using osu.Game.Screens.Edit;
+using osu.Game.Screens.Edit.Compose.Components;
+using osu.Game.Tests.Beatmaps;
+using osu.Game.Tests.Visual;
+using osuTK;
+using osuTK.Input;
+
+namespace osu.Game.Rulesets.Osu.Tests.Editor
+{
+ public class TestSceneSliderSnapping : EditorTestScene
+ {
+ private const double beat_length = 1000;
+
+ protected override Ruleset CreateEditorRuleset() => new OsuRuleset();
+
+ protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
+ {
+ var controlPointInfo = new ControlPointInfo();
+ controlPointInfo.Add(0, new TimingControlPoint { BeatLength = beat_length });
+ return new TestBeatmap(ruleset, false)
+ {
+ ControlPointInfo = controlPointInfo
+ };
+ }
+
+ private Slider slider;
+
+ public override void SetUpSteps()
+ {
+ base.SetUpSteps();
+
+ AddStep("add unsnapped slider", () => EditorBeatmap.Add(slider = new Slider
+ {
+ StartTime = 0,
+ Position = OsuPlayfield.BASE_SIZE / 5,
+ Path = new SliderPath
+ {
+ ControlPoints =
+ {
+ new PathControlPoint(Vector2.Zero),
+ new PathControlPoint(OsuPlayfield.BASE_SIZE * 2 / 5),
+ new PathControlPoint(OsuPlayfield.BASE_SIZE * 3 / 5)
+ }
+ }
+ }));
+ AddStep("set beat divisor to 1/1", () =>
+ {
+ var beatDivisor = (BindableBeatDivisor)Editor.Dependencies.Get(typeof(BindableBeatDivisor));
+ beatDivisor.Value = 1;
+ });
+ }
+
+ [Test]
+ public void TestMovingUnsnappedSliderNodesSnaps()
+ {
+ PathControlPointPiece sliderEnd = null;
+
+ assertSliderSnapped(false);
+
+ AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider));
+ AddStep("select slider end", () =>
+ {
+ sliderEnd = this.ChildrenOfType().Single(piece => piece.ControlPoint == slider.Path.ControlPoints.Last());
+ InputManager.MoveMouseTo(sliderEnd.ScreenSpaceDrawQuad.Centre);
+ });
+ AddStep("move slider end", () =>
+ {
+ InputManager.PressButton(MouseButton.Left);
+ InputManager.MoveMouseTo(sliderEnd.ScreenSpaceDrawQuad.Centre - new Vector2(0, 20));
+ InputManager.ReleaseButton(MouseButton.Left);
+ });
+ assertSliderSnapped(true);
+ }
+
+ [Test]
+ public void TestAddingControlPointToUnsnappedSliderNodesSnaps()
+ {
+ assertSliderSnapped(false);
+
+ AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider));
+ AddStep("move mouse to new point location", () =>
+ {
+ var firstPiece = this.ChildrenOfType().Single(piece => piece.ControlPoint == slider.Path.ControlPoints[0]);
+ var secondPiece = this.ChildrenOfType().Single(piece => piece.ControlPoint == slider.Path.ControlPoints[1]);
+ InputManager.MoveMouseTo((firstPiece.ScreenSpaceDrawQuad.Centre + secondPiece.ScreenSpaceDrawQuad.Centre) / 2);
+ });
+ AddStep("move slider end", () =>
+ {
+ InputManager.PressKey(Key.ControlLeft);
+ InputManager.Click(MouseButton.Left);
+ InputManager.ReleaseKey(Key.ControlLeft);
+ });
+ assertSliderSnapped(true);
+ }
+
+ [Test]
+ public void TestRemovingControlPointFromUnsnappedSliderNodesSnaps()
+ {
+ assertSliderSnapped(false);
+
+ AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider));
+ AddStep("move mouse to second control point", () =>
+ {
+ var secondPiece = this.ChildrenOfType().Single(piece => piece.ControlPoint == slider.Path.ControlPoints[1]);
+ InputManager.MoveMouseTo(secondPiece);
+ });
+ AddStep("quick delete", () =>
+ {
+ InputManager.PressKey(Key.ShiftLeft);
+ InputManager.PressButton(MouseButton.Right);
+ InputManager.ReleaseKey(Key.ShiftLeft);
+ });
+ assertSliderSnapped(true);
+ }
+
+ [Test]
+ public void TestResizingUnsnappedSliderSnaps()
+ {
+ SelectionBoxScaleHandle handle = null;
+
+ assertSliderSnapped(false);
+
+ AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider));
+ AddStep("move mouse to scale handle", () =>
+ {
+ handle = this.ChildrenOfType().First();
+ InputManager.MoveMouseTo(handle.ScreenSpaceDrawQuad.Centre);
+ });
+ AddStep("scale slider", () =>
+ {
+ InputManager.PressButton(MouseButton.Left);
+ InputManager.MoveMouseTo(handle.ScreenSpaceDrawQuad.Centre + new Vector2(20, 20));
+ InputManager.ReleaseButton(MouseButton.Left);
+ });
+ assertSliderSnapped(true);
+ }
+
+ [Test]
+ public void TestRotatingUnsnappedSliderDoesNotSnap()
+ {
+ SelectionBoxRotationHandle handle = null;
+
+ assertSliderSnapped(false);
+
+ AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider));
+ AddStep("move mouse to rotate handle", () =>
+ {
+ handle = this.ChildrenOfType().First();
+ InputManager.MoveMouseTo(handle.ScreenSpaceDrawQuad.Centre);
+ });
+ AddStep("scale slider", () =>
+ {
+ InputManager.PressButton(MouseButton.Left);
+ InputManager.MoveMouseTo(handle.ScreenSpaceDrawQuad.Centre + new Vector2(0, 20));
+ InputManager.ReleaseButton(MouseButton.Left);
+ });
+ assertSliderSnapped(false);
+ }
+
+ [Test]
+ public void TestFlippingSliderDoesNotSnap()
+ {
+ OsuSelectionHandler selectionHandler = null;
+
+ assertSliderSnapped(false);
+
+ AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider));
+ AddStep("flip slider horizontally", () =>
+ {
+ selectionHandler = this.ChildrenOfType().Single();
+ selectionHandler.OnPressed(new KeyBindingPressEvent(InputManager.CurrentState, GlobalAction.EditorFlipHorizontally));
+ });
+
+ assertSliderSnapped(false);
+
+ AddStep("flip slider vertically", () =>
+ {
+ selectionHandler = this.ChildrenOfType().Single();
+ selectionHandler.OnPressed(new KeyBindingPressEvent(InputManager.CurrentState, GlobalAction.EditorFlipVertically));
+ });
+
+ assertSliderSnapped(false);
+ }
+
+ [Test]
+ public void TestReversingSliderDoesNotSnap()
+ {
+ assertSliderSnapped(false);
+
+ AddStep("select slider", () => EditorBeatmap.SelectedHitObjects.Add(slider));
+ AddStep("reverse slider", () =>
+ {
+ InputManager.PressKey(Key.ControlLeft);
+ InputManager.Key(Key.G);
+ InputManager.ReleaseKey(Key.ControlLeft);
+ });
+
+ assertSliderSnapped(false);
+ }
+
+ private void assertSliderSnapped(bool snapped)
+ => AddAssert($"slider is {(snapped ? "" : "not ")}snapped", () =>
+ {
+ double durationInBeatLengths = slider.Duration / beat_length;
+ double fractionalPart = durationInBeatLengths - (int)durationInBeatLengths;
+ return Precision.AlmostEquals(fractionalPart, 0) == snapped;
+ });
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
index fea2e408f6..e5b2e070d8 100644
--- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
+++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
@@ -5,7 +5,7 @@
-
+
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs
index 065d4737a5..ae4141073e 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/Components/PathControlPointVisualiser.cs
@@ -283,6 +283,9 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
}
}
+ // Snap the path to the current beat divisor before checking length validity.
+ slider.SnapTo(snapProvider);
+
if (!slider.Path.HasValidLength)
{
for (int i = 0; i < slider.Path.ControlPoints.Count; i++)
@@ -290,6 +293,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components
slider.Position = oldPosition;
slider.StartTime = oldStartTime;
+ // Snap the path length again to undo the invalid length.
+ slider.SnapTo(snapProvider);
return;
}
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs
index 07b6a1bdc2..b868c9a7ee 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderPlacementBlueprint.cs
@@ -9,7 +9,6 @@ using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.Input.Events;
using osu.Game.Beatmaps.ControlPoints;
-using osu.Game.Graphics;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
@@ -50,7 +49,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load()
{
InternalChildren = new Drawable[]
{
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
index 2aebe05c2f..6cf2a493a9 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
@@ -80,7 +80,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
controlPoints.BindTo(HitObject.Path.ControlPoints);
pathVersion.BindTo(HitObject.Path.Version);
- pathVersion.BindValueChanged(_ => updatePath());
+ pathVersion.BindValueChanged(_ => editorBeatmap?.Update(HitObject));
BodyPiece.UpdateFrom(HitObject);
}
@@ -208,6 +208,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
// Move the control points from the insertion index onwards to make room for the insertion
controlPoints.Insert(insertionIndex, pathControlPoint);
+ HitObject.SnapTo(composer);
+
return pathControlPoint;
}
@@ -227,7 +229,10 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
controlPoints.Remove(c);
}
- // If there are 0 or 1 remaining control points, the slider is in a degenerate (single point) form and should be deleted
+ // Snap the slider to the current beat divisor before checking length validity.
+ HitObject.SnapTo(composer);
+
+ // If there are 0 or 1 remaining control points, or the slider has an invalid length, it is in a degenerate form and should be deleted
if (controlPoints.Count <= 1 || !HitObject.Path.HasValidLength)
{
placementHandler?.Delete(HitObject);
@@ -242,12 +247,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
HitObject.Position += first;
}
- private void updatePath()
- {
- HitObject.Path.ExpectedDistance.Value = composer?.GetSnappedDistanceFromDistance(HitObject, (float)HitObject.Path.CalculatedDistance) ?? (float)HitObject.Path.CalculatedDistance;
- editorBeatmap?.Update(HitObject);
- }
-
private void convertToStream()
{
if (editorBeatmap == null || changeHandler == null || beatDivisor == null)
diff --git a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs
index 071ecf6329..efbac5439c 100644
--- a/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs
+++ b/osu.Game.Rulesets.Osu/Edit/OsuSelectionHandler.cs
@@ -1,12 +1,16 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+#nullable enable
+
using System.Collections.Generic;
using System.Linq;
+using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Framework.Utils;
using osu.Game.Extensions;
+using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Objects;
@@ -18,6 +22,9 @@ namespace osu.Game.Rulesets.Osu.Edit
{
public class OsuSelectionHandler : EditorSelectionHandler
{
+ [Resolved(CanBeNull = true)]
+ private IPositionSnapProvider? positionSnapProvider { get; set; }
+
///
/// During a transform, the initial origin is stored so it can be used throughout the operation.
///
@@ -27,7 +34,7 @@ namespace osu.Game.Rulesets.Osu.Edit
/// During a transform, the initial path types of a single selected slider are stored so they
/// can be maintained throughout the operation.
///
- private List referencePathTypes;
+ private List? referencePathTypes;
protected override void OnSelectionChanged()
{
@@ -197,6 +204,10 @@ namespace osu.Game.Rulesets.Osu.Edit
for (int i = 0; i < slider.Path.ControlPoints.Count; ++i)
slider.Path.ControlPoints[i].Type = referencePathTypes[i];
+ // Snap the slider's length to the current beat divisor
+ // to calculate the final resulting duration / bounding box before the final checks.
+ slider.SnapTo(positionSnapProvider);
+
//if sliderhead or sliderend end up outside playfield, revert scaling.
Quad scaledQuad = getSurroundingQuad(new OsuHitObject[] { slider });
(bool xInBounds, bool yInBounds) = isQuadInBounds(scaledQuad);
@@ -206,6 +217,9 @@ namespace osu.Game.Rulesets.Osu.Edit
foreach (var point in slider.Path.ControlPoints)
point.Position = oldControlPoints.Dequeue();
+
+ // Snap the slider's length again to undo the potentially-invalid length applied by the previous snap.
+ slider.SnapTo(positionSnapProvider);
}
private void scaleHitObjects(OsuHitObject[] hitObjects, Anchor reference, Vector2 scale)
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
index ec87d3bfdf..c6db02ee02 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
@@ -10,7 +10,6 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Audio;
-using osu.Game.Graphics;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
@@ -69,7 +68,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load()
{
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.Both;
diff --git a/osu.Game.Rulesets.Osu/Objects/Spinner.cs b/osu.Game.Rulesets.Osu/Objects/Spinner.cs
index 0ad8e4ea68..1eddfb7fef 100644
--- a/osu.Game.Rulesets.Osu/Objects/Spinner.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Spinner.cs
@@ -65,8 +65,8 @@ namespace osu.Game.Rulesets.Osu.Objects
double startTime = StartTime + (float)(i + 1) / totalSpins * Duration;
AddNested(i < SpinsRequired
- ? new SpinnerTick { StartTime = startTime }
- : new SpinnerBonusTick { StartTime = startTime });
+ ? new SpinnerTick { StartTime = startTime, Position = Position }
+ : new SpinnerBonusTick { StartTime = startTime, Position = Position });
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs
index f8a6e1d3c9..a1184a15cd 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs
@@ -3,15 +3,13 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
-using osu.Game.Graphics;
-using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Osu.Skinning.Default
{
public class SpinnerBackgroundLayer : SpinnerFill
{
[BackgroundDependencyLoader]
- private void load(OsuColour colours, DrawableHitObject drawableHitObject)
+ private void load()
{
Disc.Alpha = 0;
Anchor = Anchor.Centre;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs
index 611ddd08eb..b511444c44 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs
@@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
private GameplayState gameplayState { get; set; }
[BackgroundDependencyLoader]
- private void load(ISkinSource skin, OsuColour colours)
+ private void load(ISkinSource skin)
{
var texture = skin.GetTexture("star2");
var starBreakAdditive = skin.GetConfig(OsuSkinColour.StarBreakAdditive)?.Value ?? new Color4(255, 182, 193, 255);
diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs
index 6953e66b5c..7b9cf8e1d1 100644
--- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs
@@ -12,6 +12,8 @@ namespace osu.Game.Rulesets.Osu.Skinning
CursorExpand,
CursorRotate,
HitCircleOverlayAboveNumber,
+
+ // ReSharper disable once IdentifierTypo
HitCircleOverlayAboveNumer, // Some old skins will have this typo
SpinnerFrequencyModulate,
SpinnerNoBlink
diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs
index d1d9ee9f4d..b60ea5da21 100644
--- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs
+++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs
@@ -58,7 +58,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
private OsuConfigManager config { get; set; }
[BackgroundDependencyLoader(true)]
- private void load(OsuConfigManager config, OsuRulesetConfigManager rulesetConfig)
+ private void load(OsuRulesetConfigManager rulesetConfig)
{
rulesetConfig?.BindWith(OsuRulesetSetting.ShowCursorTrail, showTrail);
}
diff --git a/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumRollJudgements.cs b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumRollJudgements.cs
new file mode 100644
index 0000000000..060c3c9443
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko.Tests/TestSceneDrumRollJudgements.cs
@@ -0,0 +1,36 @@
+// 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.Game.Beatmaps;
+using osu.Game.Rulesets.Taiko.Objects;
+
+namespace osu.Game.Rulesets.Taiko.Tests
+{
+ public class TestSceneDrumRollJudgements : TestSceneTaikoPlayer
+ {
+ [Test]
+ public void TestStrongDrumRollFullyJudgedOnKilled()
+ {
+ AddUntilStep("gameplay finished", () => Player.ScoreProcessor.HasCompleted.Value);
+ AddAssert("all judgements are misses", () => Player.Results.All(r => r.Type == r.Judgement.MinResult));
+ }
+
+ protected override bool Autoplay => false;
+
+ protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new Beatmap
+ {
+ BeatmapInfo = { Ruleset = new TaikoRuleset().RulesetInfo },
+ HitObjects =
+ {
+ new DrumRoll
+ {
+ StartTime = 1000,
+ Duration = 1000,
+ IsStrong = true
+ }
+ }
+ };
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
index ad3713e047..e48d80323a 100644
--- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
+++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
@@ -4,7 +4,7 @@
-
+
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
index 521189d36c..b84db513f7 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
@@ -197,6 +197,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
ApplyResult(r => r.Type = ParentHitObject.IsHit ? r.Judgement.MaxResult : r.Judgement.MinResult);
}
+ public override void OnKilled()
+ {
+ base.OnKilled();
+
+ if (Time.Current > ParentHitObject.HitObject.GetEndTime() && !Judged)
+ ApplyResult(r => r.Type = r.Judgement.MinResult);
+ }
+
public override bool OnPressed(KeyBindingPressEvent e) => false;
}
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
index dc2ed200a1..e24923e482 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
@@ -5,6 +5,7 @@ using System;
using JetBrains.Annotations;
using osu.Framework.Graphics;
using osu.Framework.Input.Events;
+using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Skinning.Default;
using osu.Game.Skinning;
@@ -52,6 +53,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
ApplyResult(r => r.Type = r.Judgement.MaxResult);
}
+ public override void OnKilled()
+ {
+ base.OnKilled();
+
+ if (Time.Current > HitObject.GetEndTime() && !Judged)
+ ApplyResult(r => r.Type = r.Judgement.MinResult);
+ }
+
protected override void UpdateHitStateTransforms(ArmedState state)
{
switch (state)
@@ -92,6 +101,14 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
ApplyResult(r => r.Type = ParentHitObject.IsHit ? r.Judgement.MaxResult : r.Judgement.MinResult);
}
+ public override void OnKilled()
+ {
+ base.OnKilled();
+
+ if (Time.Current > ParentHitObject.HitObject.GetEndTime() && !Judged)
+ ApplyResult(r => r.Type = r.Judgement.MinResult);
+ }
+
public override bool OnPressed(KeyBindingPressEvent e) => false;
}
}
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs
index 455b2fc596..25f895708f 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs
@@ -5,7 +5,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Game.Graphics;
using osu.Game.Rulesets.Taiko.Objects;
using osuTK;
@@ -19,7 +18,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load()
{
AccentColour = Hit.COLOUR_CENTRE;
}
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs
index bd21d511b1..c6165495d8 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs
@@ -5,7 +5,6 @@ using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Game.Graphics;
using osu.Game.Rulesets.Taiko.Objects;
using osuTK;
using osuTK.Graphics;
@@ -20,7 +19,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load()
{
AccentColour = Hit.COLOUR_RIM;
}
diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs
index e1063e1071..7ba2618a63 100644
--- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs
+++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs
@@ -7,7 +7,6 @@ using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Graphics.Containers;
using osu.Game.Rulesets.Judgements;
@@ -39,7 +38,7 @@ namespace osu.Game.Rulesets.Taiko.UI
}
[BackgroundDependencyLoader(true)]
- private void load(TextureStore textures, GameplayState gameplayState)
+ private void load(GameplayState gameplayState)
{
InternalChildren = new[]
{
diff --git a/osu.Game.Tests/Online/Chat/MessageNotifierTest.cs b/osu.Game.Tests/Online/Chat/MessageNotifierTest.cs
index 2ec5b778d1..855de9b656 100644
--- a/osu.Game.Tests/Online/Chat/MessageNotifierTest.cs
+++ b/osu.Game.Tests/Online/Chat/MessageNotifierTest.cs
@@ -46,7 +46,7 @@ namespace osu.Game.Tests.Online.Chat
}
[Test]
- public void TestContainsUsernameBetweenInterpunction()
+ public void TestContainsUsernameBetweenPunctuation()
{
Assert.IsTrue(MessageNotifier.CheckContainsUsername("Hello 'test'-message", "Test"));
}
diff --git a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs
index 844fe7705a..884e74346b 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneBackgroundScreenDefault.cs
@@ -6,18 +6,24 @@ using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Audio;
+using osu.Framework.Audio.Track;
+using osu.Framework.Graphics;
using osu.Framework.Graphics.Textures;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
using osu.Game.Database;
+using osu.Game.Graphics;
using osu.Game.Graphics.Backgrounds;
+using osu.Game.Graphics.Sprites;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Screens;
using osu.Game.Screens.Backgrounds;
using osu.Game.Skinning;
+using osu.Game.Storyboards;
+using osu.Game.Storyboards.Drawables;
using osu.Game.Tests.Beatmaps;
namespace osu.Game.Tests.Visual.Background
@@ -129,6 +135,46 @@ namespace osu.Game.Tests.Visual.Background
AddAssert("top level background reused existing", () => screen.CheckLastLoadChange() == false);
}
+ [Test]
+ public void TestBeatmapBackgroundWithStoryboardClockAlwaysUsesCurrentTrack()
+ {
+ BackgroundScreenBeatmap nestedScreen = null;
+ WorkingBeatmap originalWorking = null;
+
+ setSupporter(true);
+ setSourceMode(BackgroundSource.BeatmapWithStoryboard);
+
+ AddStep("change beatmap", () => originalWorking = Beatmap.Value = createTestWorkingBeatmapWithStoryboard());
+ AddAssert("background changed", () => screen.CheckLastLoadChange() == true);
+ AddUntilStep("wait for beatmap background to be loaded", () => getCurrentBackground()?.GetType() == typeof(BeatmapBackgroundWithStoryboard));
+
+ AddStep("start music", () => MusicController.Play());
+ AddUntilStep("storyboard clock running", () => screen.ChildrenOfType().SingleOrDefault()?.Clock.IsRunning == true);
+
+ // of note, this needs to be a type that doesn't match BackgroundScreenDefault else it is silently not pushed by the background stack.
+ AddStep("push new background to stack", () => stack.Push(nestedScreen = new BackgroundScreenBeatmap(Beatmap.Value)));
+ AddUntilStep("wait for screen to load", () => nestedScreen.IsLoaded && nestedScreen.IsCurrentScreen());
+
+ // we're testing a case where scheduling may be used to avoid issues, so ensure the scheduler is no longer running.
+ AddUntilStep("wait for top level not alive", () => !screen.IsAlive);
+
+ AddStep("stop music", () => MusicController.Stop());
+ AddStep("change beatmap", () => Beatmap.Value = createTestWorkingBeatmapWithStoryboard());
+ AddStep("change beatmap back", () => Beatmap.Value = originalWorking);
+ AddStep("restart music", () => MusicController.Play());
+
+ AddAssert("top level background hasn't changed yet", () => screen.CheckLastLoadChange() == null);
+
+ AddStep("pop screen back to top level", () => screen.MakeCurrent());
+
+ AddStep("top level screen is current", () => screen.IsCurrentScreen());
+ AddAssert("top level background reused existing", () => screen.CheckLastLoadChange() == false);
+ AddUntilStep("storyboard clock running", () => screen.ChildrenOfType().Single().Clock.IsRunning);
+
+ AddStep("stop music", () => MusicController.Stop());
+ AddStep("restore default beatmap", () => Beatmap.SetDefault());
+ }
+
[Test]
public void TestBackgroundTypeSwitch()
{
@@ -198,6 +244,7 @@ namespace osu.Game.Tests.Visual.Background
});
private WorkingBeatmap createTestWorkingBeatmapWithUniqueBackground() => new UniqueBackgroundTestWorkingBeatmap(Audio);
+ private WorkingBeatmap createTestWorkingBeatmapWithStoryboard() => new TestWorkingBeatmapWithStoryboard(Audio);
private class TestBackgroundScreenDefault : BackgroundScreenDefault
{
@@ -233,6 +280,51 @@ namespace osu.Game.Tests.Visual.Background
protected override Texture GetBackground() => new Texture(1, 1);
}
+ private class TestWorkingBeatmapWithStoryboard : TestWorkingBeatmap
+ {
+ public TestWorkingBeatmapWithStoryboard(AudioManager audioManager)
+ : base(new Beatmap(), createStoryboard(), audioManager)
+ {
+ }
+
+ protected override Track GetBeatmapTrack() => new TrackVirtual(100000);
+
+ private static Storyboard createStoryboard()
+ {
+ var storyboard = new Storyboard();
+ storyboard.Layers.Last().Add(new TestStoryboardElement());
+ return storyboard;
+ }
+
+ private class TestStoryboardElement : IStoryboardElementWithDuration
+ {
+ public string Path => string.Empty;
+ public bool IsDrawable => true;
+ public double StartTime => double.MinValue;
+ public double EndTime => double.MaxValue;
+
+ public Drawable CreateDrawable() => new DrawableTestStoryboardElement();
+ }
+
+ private class DrawableTestStoryboardElement : OsuSpriteText
+ {
+ public override bool RemoveWhenNotAlive => false;
+
+ public DrawableTestStoryboardElement()
+ {
+ Anchor = Origin = Anchor.Centre;
+ Font = OsuFont.Default.With(size: 32);
+ Text = "(not started)";
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+ Text = Time.Current.ToString("N2");
+ }
+ }
+ }
+
private void setCustomSkin()
{
// feign a skin switch. this doesn't do anything except force CurrentSkin to become a LegacySkin.
diff --git a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
index b1f642b909..5b2cf877ba 100644
--- a/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
+++ b/osu.Game.Tests/Visual/Background/TestSceneUserDimBackgrounds.cs
@@ -36,7 +36,7 @@ using osuTK.Graphics;
namespace osu.Game.Tests.Visual.Background
{
[TestFixture]
- public class TestSceneUserDimBackgrounds : OsuManualInputManagerTestScene
+ public class TestSceneUserDimBackgrounds : ScreenTestScene
{
private DummySongSelect songSelect;
private TestPlayerLoader playerLoader;
@@ -56,14 +56,12 @@ namespace osu.Game.Tests.Visual.Background
Beatmap.SetDefault();
}
- [SetUp]
- public virtual void SetUp() => Schedule(() =>
+ public override void SetUpSteps()
{
- var stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both };
- Child = stack;
+ base.SetUpSteps();
- stack.Push(songSelect = new DummySongSelect());
- });
+ AddStep("push song select", () => Stack.Push(songSelect = new DummySongSelect()));
+ }
///
/// User settings should always be ignored on song select screen.
diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDifficultyList.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDifficultyList.cs
index aec75884d6..e6fb4372ff 100644
--- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDifficultyList.cs
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDifficultyList.cs
@@ -6,7 +6,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Game.Beatmaps.Drawables.Cards;
-using osu.Game.Graphics;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
@@ -18,7 +17,7 @@ namespace osu.Game.Tests.Visual.Beatmaps
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load()
{
var beatmapSet = new APIBeatmapSet
{
diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs
index 3aff74a0a8..e41f8372b4 100644
--- a/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs
+++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorClipboard.cs
@@ -4,6 +4,7 @@
using System.Linq;
using NUnit.Framework;
using osu.Framework.Testing;
+using osu.Framework.Utils;
using osu.Game.Beatmaps;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Edit;
@@ -85,11 +86,17 @@ namespace osu.Game.Tests.Visual.Editing
AddAssert("is one object", () => EditorBeatmap.HitObjects.Count == 1);
+ Slider slider = null;
+ AddStep("retrieve slider", () => slider = (Slider)EditorBeatmap.HitObjects.Single());
AddAssert("path matches", () =>
{
- var path = ((Slider)EditorBeatmap.HitObjects.Single()).Path;
+ var path = slider.Path;
return path.ControlPoints.Count == 2 && path.ControlPoints.SequenceEqual(addedObject.Path.ControlPoints);
});
+
+ // see `HitObject.control_point_leniency`.
+ AddAssert("sample control point has correct time", () => Precision.AlmostEquals(slider.SampleControlPoint.Time, slider.GetEndTime(), 1));
+ AddAssert("difficulty control point has correct time", () => slider.DifficultyControlPoint.Time == slider.StartTime);
}
[Test]
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs
index c5ab3974a4..e10ef57a25 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneAllRulesetPlayers.cs
@@ -25,7 +25,7 @@ namespace osu.Game.Tests.Visual.Gameplay
protected OsuConfigManager Config { get; private set; }
[BackgroundDependencyLoader]
- private void load(RulesetStore rulesets)
+ private void load()
{
Dependencies.Cache(Config = new OsuConfigManager(LocalStorage));
Config.GetBindable(OsuSetting.DimLevel).Value = 1.0;
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs
new file mode 100644
index 0000000000..7a44a7643d
--- /dev/null
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneChangeAndUseGameplayBindings.cs
@@ -0,0 +1,88 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Linq;
+using NUnit.Framework;
+using osu.Framework.Allocation;
+using osu.Framework.Extensions;
+using osu.Framework.Input.Bindings;
+using osu.Framework.Testing;
+using osu.Game.Database;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Input.Bindings;
+using osu.Game.Overlays.Settings.Sections.Input;
+using osu.Game.Screens.Play;
+using osu.Game.Screens.Select;
+using osu.Game.Tests.Beatmaps.IO;
+using osuTK.Input;
+
+namespace osu.Game.Tests.Visual.Navigation
+{
+ public class TestSceneChangeAndUseGameplayBindings : OsuGameTestScene
+ {
+ [Test]
+ public void TestGameplayKeyBindings()
+ {
+ AddAssert("databased key is default", () => firstOsuRulesetKeyBindings.KeyCombination.Keys.SequenceEqual(new[] { InputKey.Z }));
+
+ AddStep("open settings", () => { Game.Settings.Show(); });
+
+ // Until step requires as settings has a delayed load.
+ AddUntilStep("wait for button", () => configureBindingsButton?.Enabled.Value == true);
+ AddStep("scroll to section", () => Game.Settings.SectionsContainer.ScrollTo(configureBindingsButton));
+ AddStep("press button", () => configureBindingsButton.TriggerClick());
+ AddUntilStep("wait for panel", () => keyBindingPanel?.IsLoaded == true);
+ AddUntilStep("wait for osu subsection", () => osuBindingSubsection?.IsLoaded == true);
+ AddStep("scroll to section", () => keyBindingPanel.SectionsContainer.ScrollTo(osuBindingSubsection));
+ AddWaitStep("wait for scroll to end", 3);
+ AddStep("start rebinding first osu! key", () =>
+ {
+ var button = osuBindingSubsection.ChildrenOfType().First();
+
+ InputManager.MoveMouseTo(button);
+ InputManager.Click(MouseButton.Left);
+ });
+
+ AddStep("Press 's'", () => InputManager.Key(Key.S));
+
+ AddUntilStep("wait for database updated", () => firstOsuRulesetKeyBindings.KeyCombination.Keys.SequenceEqual(new[] { InputKey.S }));
+
+ AddStep("close settings", () => Game.Settings.Hide());
+
+ AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).WaitSafely());
+ PushAndConfirm(() => new PlaySongSelect());
+
+ AddStep("enter gameplay", () => InputManager.Key(Key.Enter));
+
+ AddUntilStep("wait for gameplay", () => player?.IsBreakTime.Value == false);
+
+ AddStep("press 'z'", () => InputManager.Key(Key.Z));
+ AddAssert("key counter didn't increase", () => keyCounter.CountPresses == 0);
+
+ AddStep("press 's'", () => InputManager.Key(Key.S));
+ AddAssert("key counter did increase", () => keyCounter.CountPresses == 1);
+ }
+
+ private KeyBindingsSubsection osuBindingSubsection => keyBindingPanel
+ .ChildrenOfType()
+ .FirstOrDefault(s => s.Ruleset.ShortName == "osu");
+
+ private OsuButton configureBindingsButton => Game.Settings
+ .ChildrenOfType().SingleOrDefault()?
+ .ChildrenOfType()?
+ .First(b => b.Text.ToString() == "Configure");
+
+ private KeyBindingPanel keyBindingPanel => Game.Settings
+ .ChildrenOfType().SingleOrDefault();
+
+ private RealmKeyBinding firstOsuRulesetKeyBindings => Game.Dependencies
+ .Get().Context
+ .All()
+ .AsEnumerable()
+ .First(k => k.RulesetName == "osu" && k.ActionInt == 0);
+
+ private Player player => Game.ScreenStack.CurrentScreen as Player;
+
+ private KeyCounter keyCounter => player.ChildrenOfType().First();
+ }
+}
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
index d094d8b688..60aabf5639 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
@@ -251,8 +251,9 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestModSelectInput()
{
- TestPlaySongSelect songSelect = null;
+ AddUntilStep("Wait for toolbar to load", () => Game.Toolbar.IsLoaded);
+ TestPlaySongSelect songSelect = null;
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddStep("Show mods overlay", () => songSelect.ModSelectOverlay.Show());
@@ -272,8 +273,9 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestBeatmapOptionsInput()
{
- TestPlaySongSelect songSelect = null;
+ AddUntilStep("Wait for toolbar to load", () => Game.Toolbar.IsLoaded);
+ TestPlaySongSelect songSelect = null;
PushAndConfirm(() => songSelect = new TestPlaySongSelect());
AddStep("Show options overlay", () => songSelect.BeatmapOptionsOverlay.Show());
@@ -293,6 +295,8 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestSettingsViaHotkeyFromMainMenu()
{
+ AddUntilStep("Wait for toolbar to load", () => Game.Toolbar.IsLoaded);
+
AddAssert("toolbar not displayed", () => Game.Toolbar.State.Value == Visibility.Hidden);
AddStep("press settings hotkey", () =>
@@ -308,10 +312,11 @@ namespace osu.Game.Tests.Visual.Navigation
[Test]
public void TestToolbarHiddenByUser()
{
- AddStep("Enter menu", () => InputManager.Key(Key.Enter));
-
AddUntilStep("Wait for toolbar to load", () => Game.Toolbar.IsLoaded);
+ AddStep("Enter menu", () => InputManager.Key(Key.Enter));
+ AddUntilStep("Toolbar is visible", () => Game.Toolbar.State.Value == Visibility.Visible);
+
AddStep("Hide toolbar", () =>
{
InputManager.PressKey(Key.ControlLeft);
diff --git a/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs b/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs
index be2db9a8a0..8a304110dd 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneScoresContainer.cs
@@ -1,11 +1,15 @@
// 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 System.Linq;
+using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
+using osu.Framework.Testing;
using osu.Framework.Utils;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests.Responses;
@@ -24,10 +28,11 @@ namespace osu.Game.Tests.Visual.Online
[Cached]
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
- public TestSceneScoresContainer()
- {
- TestScoresContainer scoresContainer;
+ private TestScoresContainer scoresContainer;
+ [SetUpSteps]
+ public void SetUp() => Schedule(() =>
+ {
Child = new Container
{
Anchor = Anchor.TopCentre,
@@ -41,16 +46,110 @@ namespace osu.Game.Tests.Visual.Online
RelativeSizeAxes = Axes.Both,
Colour = Color4.Black,
},
- scoresContainer = new TestScoresContainer(),
+ scoresContainer = new TestScoresContainer
+ {
+ Beatmap = { Value = CreateAPIBeatmap() }
+ }
}
};
+ });
- var allScores = new APIScoresCollection
+ [Test]
+ public void TestNoUserBest()
+ {
+ AddStep("Scores with no user best", () =>
+ {
+ var allScores = createScores();
+
+ allScores.UserScore = null;
+
+ scoresContainer.Scores = allScores;
+ });
+
+ AddUntilStep("wait for scores displayed", () => scoresContainer.ChildrenOfType().Any());
+ AddAssert("no user best displayed", () => scoresContainer.ChildrenOfType().Count() == 1);
+
+ AddStep("Load null scores", () => scoresContainer.Scores = null);
+
+ AddUntilStep("wait for scores not displayed", () => !scoresContainer.ChildrenOfType().Any());
+ AddAssert("no best score displayed", () => !scoresContainer.ChildrenOfType().Any());
+
+ AddStep("Load only one score", () =>
+ {
+ var allScores = createScores();
+
+ allScores.Scores.RemoveRange(1, allScores.Scores.Count - 1);
+
+ scoresContainer.Scores = allScores;
+ });
+
+ AddUntilStep("wait for scores not displayed", () => scoresContainer.ChildrenOfType().Count() == 1);
+ AddAssert("no best score displayed", () => scoresContainer.ChildrenOfType().Count() == 1);
+ }
+
+ [Test]
+ public void TestUserBest()
+ {
+ AddStep("Load scores with personal best", () =>
+ {
+ var allScores = createScores();
+ allScores.UserScore = createUserBest();
+ scoresContainer.Scores = allScores;
+ });
+
+ AddUntilStep("wait for scores displayed", () => scoresContainer.ChildrenOfType().Any());
+ AddAssert("best score displayed", () => scoresContainer.ChildrenOfType().Count() == 2);
+
+ AddStep("Load scores with personal best (null position)", () =>
+ {
+ var allScores = createScores();
+ var userBest = createUserBest();
+ userBest.Position = null;
+ allScores.UserScore = userBest;
+ scoresContainer.Scores = allScores;
+ });
+
+ AddUntilStep("wait for scores displayed", () => scoresContainer.ChildrenOfType().Any());
+ AddAssert("best score displayed", () => scoresContainer.ChildrenOfType().Count() == 2);
+
+ AddStep("Load scores with personal best (first place)", () =>
+ {
+ var allScores = createScores();
+ allScores.UserScore = new APIScoreWithPosition
+ {
+ Score = allScores.Scores.First(),
+ Position = 1,
+ };
+ scoresContainer.Scores = allScores;
+ });
+
+ AddUntilStep("wait for scores displayed", () => scoresContainer.ChildrenOfType().Any());
+ AddAssert("best score displayed", () => scoresContainer.ChildrenOfType().Count() == 1);
+
+ AddStep("Scores with no user best", () =>
+ {
+ var allScores = createScores();
+
+ allScores.UserScore = null;
+
+ scoresContainer.Scores = allScores;
+ });
+
+ AddUntilStep("best score not displayed", () => scoresContainer.ChildrenOfType().Count() == 1);
+ }
+
+ private int onlineID = 1;
+
+ private APIScoresCollection createScores()
+ {
+ var scores = new APIScoresCollection
{
Scores = new List
{
new APIScore
{
+ Date = DateTimeOffset.Now,
+ OnlineID = onlineID++,
User = new APIUser
{
Id = 6602580,
@@ -76,6 +175,8 @@ namespace osu.Game.Tests.Visual.Online
},
new APIScore
{
+ Date = DateTimeOffset.Now,
+ OnlineID = onlineID++,
User = new APIUser
{
Id = 4608074,
@@ -100,6 +201,8 @@ namespace osu.Game.Tests.Visual.Online
},
new APIScore
{
+ Date = DateTimeOffset.Now,
+ OnlineID = onlineID++,
User = new APIUser
{
Id = 1014222,
@@ -123,6 +226,8 @@ namespace osu.Game.Tests.Visual.Online
},
new APIScore
{
+ Date = DateTimeOffset.Now,
+ OnlineID = onlineID++,
User = new APIUser
{
Id = 1541390,
@@ -145,6 +250,8 @@ namespace osu.Game.Tests.Visual.Online
},
new APIScore
{
+ Date = DateTimeOffset.Now,
+ OnlineID = onlineID++,
User = new APIUser
{
Id = 7151382,
@@ -164,85 +271,7 @@ namespace osu.Game.Tests.Visual.Online
}
};
- var myBestScore = new APIScoreWithPosition
- {
- Score = new APIScore
- {
- User = new APIUser
- {
- Id = 7151382,
- Username = @"Mayuri Hana",
- Country = new Country
- {
- FullName = @"Thailand",
- FlagName = @"TH",
- },
- },
- Rank = ScoreRank.D,
- PP = 160,
- MaxCombo = 1234,
- TotalScore = 123456,
- Accuracy = 0.6543,
- },
- Position = 1337,
- };
-
- var myBestScoreWithNullPosition = new APIScoreWithPosition
- {
- Score = new APIScore
- {
- User = new APIUser
- {
- Id = 7151382,
- Username = @"Mayuri Hana",
- Country = new Country
- {
- FullName = @"Thailand",
- FlagName = @"TH",
- },
- },
- Rank = ScoreRank.D,
- PP = 160,
- MaxCombo = 1234,
- TotalScore = 123456,
- Accuracy = 0.6543,
- },
- Position = null,
- };
-
- var oneScore = new APIScoresCollection
- {
- Scores = new List
- {
- new APIScore
- {
- User = new APIUser
- {
- Id = 6602580,
- Username = @"waaiiru",
- Country = new Country
- {
- FullName = @"Spain",
- FlagName = @"ES",
- },
- },
- Mods = new[]
- {
- new APIMod { Acronym = new OsuModDoubleTime().Acronym },
- new APIMod { Acronym = new OsuModHidden().Acronym },
- new APIMod { Acronym = new OsuModFlashlight().Acronym },
- new APIMod { Acronym = new OsuModHardRock().Acronym },
- },
- Rank = ScoreRank.XH,
- PP = 200,
- MaxCombo = 1234,
- TotalScore = 1234567890,
- Accuracy = 1,
- }
- }
- };
-
- foreach (var s in allScores.Scores)
+ foreach (var s in scores.Scores)
{
s.Statistics = new Dictionary
{
@@ -253,26 +282,34 @@ namespace osu.Game.Tests.Visual.Online
};
}
- AddStep("Load all scores", () =>
- {
- allScores.UserScore = null;
- scoresContainer.Scores = allScores;
- });
- AddStep("Load null scores", () => scoresContainer.Scores = null);
- AddStep("Load only one score", () => scoresContainer.Scores = oneScore);
- AddStep("Load scores with my best", () =>
- {
- allScores.UserScore = myBestScore;
- scoresContainer.Scores = allScores;
- });
-
- AddStep("Load scores with null my best position", () =>
- {
- allScores.UserScore = myBestScoreWithNullPosition;
- scoresContainer.Scores = allScores;
- });
+ return scores;
}
+ private APIScoreWithPosition createUserBest() => new APIScoreWithPosition
+ {
+ Score = new APIScore
+ {
+ Date = DateTimeOffset.Now,
+ OnlineID = onlineID++,
+ User = new APIUser
+ {
+ Id = 7151382,
+ Username = @"Mayuri Hana",
+ Country = new Country
+ {
+ FullName = @"Thailand",
+ FlagName = @"TH",
+ },
+ },
+ Rank = ScoreRank.D,
+ PP = 160,
+ MaxCombo = 1234,
+ TotalScore = 123456,
+ Accuracy = 0.6543,
+ },
+ Position = 1337,
+ };
+
private class TestScoresContainer : ScoresContainer
{
public new APIScoresCollection Scores
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs b/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs
index 52d5eb2c65..6c3678b0d2 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserPanel.cs
@@ -20,8 +20,8 @@ namespace osu.Game.Tests.Visual.Online
private readonly Bindable activity = new Bindable();
private readonly Bindable status = new Bindable();
- private UserGridPanel peppy;
- private TestUserListPanel evast;
+ private UserGridPanel boundPanel1;
+ private TestUserListPanel boundPanel2;
[Resolved]
private IRulesetStore rulesetStore { get; set; }
@@ -29,8 +29,6 @@ namespace osu.Game.Tests.Visual.Online
[SetUp]
public void SetUp() => Schedule(() =>
{
- UserGridPanel flyte;
-
activity.Value = null;
status.Value = null;
@@ -56,14 +54,15 @@ namespace osu.Game.Tests.Visual.Online
Colour = "99EB47",
CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
}),
- flyte = new UserGridPanel(new APIUser
+ new UserGridPanel(new APIUser
{
Username = @"flyte",
Id = 3103765,
Country = new Country { FlagName = @"JP" },
- CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg"
+ CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c6.jpg",
+ Status = { Value = new UserStatusOnline() }
}) { Width = 300 },
- peppy = new UserGridPanel(new APIUser
+ boundPanel1 = new UserGridPanel(new APIUser
{
Username = @"peppy",
Id = 2,
@@ -72,7 +71,7 @@ namespace osu.Game.Tests.Visual.Online
IsSupporter = true,
SupportLevel = 3,
}) { Width = 300 },
- evast = new TestUserListPanel(new APIUser
+ boundPanel2 = new TestUserListPanel(new APIUser
{
Username = @"Evast",
Id = 8195163,
@@ -84,13 +83,11 @@ namespace osu.Game.Tests.Visual.Online
},
};
- flyte.Status.Value = new UserStatusOnline();
+ boundPanel1.Status.BindTo(status);
+ boundPanel1.Activity.BindTo(activity);
- peppy.Status.BindTo(status);
- peppy.Activity.BindTo(activity);
-
- evast.Status.BindTo(status);
- evast.Activity.BindTo(activity);
+ boundPanel2.Status.BindTo(status);
+ boundPanel2.Activity.BindTo(activity);
});
[Test]
@@ -121,14 +118,14 @@ namespace osu.Game.Tests.Visual.Online
[Test]
public void TestUserActivityChange()
{
- AddAssert("visit message is visible", () => evast.LastVisitMessage.IsPresent);
+ AddAssert("visit message is visible", () => boundPanel2.LastVisitMessage.IsPresent);
AddStep("set online status", () => status.Value = new UserStatusOnline());
- AddAssert("visit message is not visible", () => !evast.LastVisitMessage.IsPresent);
+ AddAssert("visit message is not visible", () => !boundPanel2.LastVisitMessage.IsPresent);
AddStep("set choosing activity", () => activity.Value = new UserActivity.ChoosingBeatmap());
AddStep("set offline status", () => status.Value = new UserStatusOffline());
- AddAssert("visit message is visible", () => evast.LastVisitMessage.IsPresent);
+ AddAssert("visit message is visible", () => boundPanel2.LastVisitMessage.IsPresent);
AddStep("set online status", () => status.Value = new UserStatusOnline());
- AddAssert("visit message is not visible", () => !evast.LastVisitMessage.IsPresent);
+ AddAssert("visit message is not visible", () => !boundPanel2.LastVisitMessage.IsPresent);
}
private UserActivity soloGameStatusForRuleset(int rulesetId) => new UserActivity.InSoloGame(null, rulesetStore.GetRuleset(rulesetId));
diff --git a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs
index e59884f4f4..6efdd1b8b6 100644
--- a/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs
+++ b/osu.Game.Tests/Visual/Playlists/TestScenePlaylistsRoomCreation.cs
@@ -18,6 +18,7 @@ using osu.Game.Rulesets;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Screens.OnlinePlay.Components;
+using osu.Game.Screens.OnlinePlay.Match.Components;
using osu.Game.Screens.OnlinePlay.Playlists;
using osu.Game.Screens.Play;
using osu.Game.Tests.Beatmaps;
@@ -71,6 +72,8 @@ namespace osu.Game.Tests.Visual.Playlists
AddUntilStep("Progress details are hidden", () => match.ChildrenOfType().FirstOrDefault()?.Parent.Alpha == 0);
+ AddUntilStep("Leaderboard shows two aggregate scores", () => match.ChildrenOfType().Count(s => s.ScoreText.Text != "0") == 2);
+
AddStep("start match", () => match.ChildrenOfType().First().TriggerClick());
AddUntilStep("player loader loaded", () => Stack.CurrentScreen is PlayerLoader);
}
diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs
index 666cbf02b5..8a0ed2e108 100644
--- a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs
+++ b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs
@@ -203,7 +203,7 @@ namespace osu.Game.Tests.Visual.Ranking
{
DelayedFetchResultsScreen screen = null;
- var tcs = new TaskCompletionSource();
+ var tcs = new TaskCompletionSource();
AddStep("load results", () => Child = new TestResultsContainer(screen = new DelayedFetchResultsScreen(TestResources.CreateTestScoreInfo(), tcs.Task)));
@@ -218,7 +218,7 @@ namespace osu.Game.Tests.Visual.Ranking
AddAssert("no fetch yet", () => !screen.FetchCompleted);
- AddStep("allow fetch", () => tcs.SetResult());
+ AddStep("allow fetch", () => tcs.SetResult(true));
AddUntilStep("wait for fetch", () => screen.FetchCompleted);
AddAssert("expanded panel still on screen", () => this.ChildrenOfType().Single(p => p.State == PanelState.Expanded).ScreenSpaceDrawQuad.TopLeft.X > 0);
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapBackgroundSprite.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapBackgroundSprite.cs
index 6fe1ccc037..736df7dec1 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapBackgroundSprite.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneUpdateableBeatmapBackgroundSprite.cs
@@ -14,7 +14,6 @@ using osu.Game.Graphics.Containers;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
-using osu.Game.Rulesets;
using osu.Game.Tests.Beatmaps.IO;
using osuTK;
@@ -28,7 +27,7 @@ namespace osu.Game.Tests.Visual.UserInterface
private IAPIProvider api;
[BackgroundDependencyLoader]
- private void load(OsuGameBase osu, IAPIProvider api, RulesetStore rulesets)
+ private void load(OsuGameBase osu, IAPIProvider api)
{
this.api = api;
diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj
index 3b115d43e5..c64ef918e3 100644
--- a/osu.Game.Tests/osu.Game.Tests.csproj
+++ b/osu.Game.Tests/osu.Game.Tests.csproj
@@ -6,7 +6,7 @@
-
+
diff --git a/osu.Game.Tournament.Tests/TestSceneTournamentSceneManager.cs b/osu.Game.Tournament.Tests/TestSceneTournamentSceneManager.cs
index 4d134ce4af..53591da07b 100644
--- a/osu.Game.Tournament.Tests/TestSceneTournamentSceneManager.cs
+++ b/osu.Game.Tournament.Tests/TestSceneTournamentSceneManager.cs
@@ -2,14 +2,13 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Platform;
namespace osu.Game.Tournament.Tests
{
public class TestSceneTournamentSceneManager : TournamentTestScene
{
[BackgroundDependencyLoader]
- private void load(Storage storage)
+ private void load()
{
Add(new TournamentSceneManager());
}
diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
index 130fcfaca1..fb09a7be1e 100644
--- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
+++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
@@ -7,7 +7,7 @@
-
+
WinExe
diff --git a/osu.Game.Tournament/Components/DrawableTeamTitle.cs b/osu.Game.Tournament/Components/DrawableTeamTitle.cs
index 5aac37259f..6732eb152f 100644
--- a/osu.Game.Tournament/Components/DrawableTeamTitle.cs
+++ b/osu.Game.Tournament/Components/DrawableTeamTitle.cs
@@ -4,7 +4,6 @@
using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
-using osu.Framework.Graphics.Textures;
using osu.Game.Tournament.Models;
namespace osu.Game.Tournament.Components
@@ -22,7 +21,7 @@ namespace osu.Game.Tournament.Components
}
[BackgroundDependencyLoader]
- private void load(TextureStore textures)
+ private void load()
{
if (team == null) return;
diff --git a/osu.Game.Tournament/Components/DrawableTournamentTeam.cs b/osu.Game.Tournament/Components/DrawableTournamentTeam.cs
index b9442a67f5..367e447947 100644
--- a/osu.Game.Tournament/Components/DrawableTournamentTeam.cs
+++ b/osu.Game.Tournament/Components/DrawableTournamentTeam.cs
@@ -5,7 +5,6 @@ using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Textures;
using osu.Game.Graphics;
using osu.Game.Tournament.Models;
@@ -33,7 +32,7 @@ namespace osu.Game.Tournament.Components
}
[BackgroundDependencyLoader]
- private void load(TextureStore textures)
+ private void load()
{
if (Team == null) return;
diff --git a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
index 364cccd076..4189f3ccb5 100644
--- a/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
+++ b/osu.Game.Tournament/Components/TournamentBeatmapPanel.cs
@@ -9,7 +9,6 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Graphics.Textures;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.Drawables;
using osu.Game.Graphics;
@@ -45,7 +44,7 @@ namespace osu.Game.Tournament.Components
}
[BackgroundDependencyLoader]
- private void load(LadderInfo ladder, TextureStore textures)
+ private void load(LadderInfo ladder)
{
currentMatch.BindValueChanged(matchChanged);
currentMatch.BindTo(ladder.CurrentMatch);
diff --git a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
index f6bc607447..5c12d83d1c 100644
--- a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
@@ -12,7 +12,6 @@ using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Settings;
-using osu.Game.Rulesets;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models;
using osuTK;
@@ -218,7 +217,7 @@ namespace osu.Game.Tournament.Screens.Editors
}
[BackgroundDependencyLoader]
- private void load(RulesetStore rulesets)
+ private void load()
{
beatmapId.Value = Model.ID;
beatmapId.BindValueChanged(id =>
diff --git a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs
index 5d2fddffd9..5cdfe7dc08 100644
--- a/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/SeedingEditorScreen.cs
@@ -12,7 +12,6 @@ using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Settings;
-using osu.Game.Rulesets;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models;
using osuTK;
@@ -220,7 +219,7 @@ namespace osu.Game.Tournament.Screens.Editors
}
[BackgroundDependencyLoader]
- private void load(RulesetStore rulesets)
+ private void load()
{
beatmapId.Value = Model.ID;
beatmapId.BindValueChanged(id =>
diff --git a/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs b/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs
index 813bed86ae..db15a46fc8 100644
--- a/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs
+++ b/osu.Game.Tournament/Screens/Gameplay/Components/TournamentMatchScoreDisplay.cs
@@ -11,7 +11,6 @@ using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
using osu.Game.Tournament.IPC;
-using osu.Game.Tournament.Models;
using osuTK;
namespace osu.Game.Tournament.Screens.Gameplay.Components
@@ -91,7 +90,7 @@ namespace osu.Game.Tournament.Screens.Gameplay.Components
}
[BackgroundDependencyLoader]
- private void load(LadderInfo ladder, MatchIPCInfo ipc)
+ private void load(MatchIPCInfo ipc)
{
score1.BindValueChanged(_ => updateScores());
score1.BindTo(ipc.Score1);
diff --git a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs
index 7e7c719152..f900dd7eac 100644
--- a/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs
+++ b/osu.Game.Tournament/Screens/Gameplay/GameplayScreen.cs
@@ -6,7 +6,6 @@ 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.Overlays.Settings;
@@ -37,7 +36,7 @@ namespace osu.Game.Tournament.Screens.Gameplay
private Drawable chroma;
[BackgroundDependencyLoader]
- private void load(LadderInfo ladder, MatchIPCInfo ipc, Storage storage)
+ private void load(LadderInfo ladder, MatchIPCInfo ipc)
{
this.ipc = ipc;
diff --git a/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs b/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs
index bb1e4d2eff..ea453a53ca 100644
--- a/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs
+++ b/osu.Game.Tournament/Screens/Ladder/Components/DrawableMatchTeam.cs
@@ -81,7 +81,7 @@ namespace osu.Game.Tournament.Screens.Ladder.Components
}
[BackgroundDependencyLoader(true)]
- private void load(OsuColour colours, LadderEditorScreen ladderEditor)
+ private void load(LadderEditorScreen ladderEditor)
{
this.ladderEditor = ladderEditor;
diff --git a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs
index 534c402f6c..ad6e304c80 100644
--- a/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs
+++ b/osu.Game.Tournament/Screens/Ladder/LadderScreen.cs
@@ -9,8 +9,6 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Lines;
-using osu.Framework.Platform;
-using osu.Game.Graphics;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models;
using osu.Game.Tournament.Screens.Editors;
@@ -30,7 +28,7 @@ namespace osu.Game.Tournament.Screens.Ladder
protected Container Content;
[BackgroundDependencyLoader]
- private void load(OsuColour colours, Storage storage)
+ private void load()
{
normalPathColour = Color4Extensions.FromHex("#66D1FF");
losersPathColour = Color4Extensions.FromHex("#FFC700");
diff --git a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs
index e08be65465..84f38170ea 100644
--- a/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs
+++ b/osu.Game.Tournament/Screens/Schedule/ScheduleScreen.cs
@@ -8,7 +8,6 @@ using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Platform;
using osu.Game.Graphics;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models;
@@ -25,7 +24,7 @@ namespace osu.Game.Tournament.Screens.Schedule
private LadderInfo ladder;
[BackgroundDependencyLoader]
- private void load(LadderInfo ladder, Storage storage)
+ private void load(LadderInfo ladder)
{
this.ladder = ladder;
diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
index cd74a75b10..0003e213e7 100644
--- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
+++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
@@ -8,7 +8,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
-using osu.Framework.Platform;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Tournament.Components;
@@ -25,7 +24,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
private readonly Bindable currentTeam = new Bindable();
[BackgroundDependencyLoader]
- private void load(Storage storage)
+ private void load()
{
RelativeSizeAxes = Axes.Both;
diff --git a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs
index 74957cbca5..ef6f0b32ff 100644
--- a/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs
+++ b/osu.Game.Tournament/Screens/TeamIntro/TeamIntroScreen.cs
@@ -5,7 +5,6 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Platform;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models;
using osuTK;
@@ -17,7 +16,7 @@ namespace osu.Game.Tournament.Screens.TeamIntro
private Container mainContainer;
[BackgroundDependencyLoader]
- private void load(Storage storage)
+ private void load()
{
RelativeSizeAxes = Axes.Both;
diff --git a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs
index ebe2908b74..11db7bfad9 100644
--- a/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs
+++ b/osu.Game.Tournament/Screens/TeamWin/TeamWinScreen.cs
@@ -5,7 +5,6 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Platform;
using osu.Game.Graphics;
using osu.Game.Tournament.Components;
using osu.Game.Tournament.Models;
@@ -23,7 +22,7 @@ namespace osu.Game.Tournament.Screens.TeamWin
private TourneyVideo redWinVideo;
[BackgroundDependencyLoader]
- private void load(LadderInfo ladder, Storage storage)
+ private void load()
{
RelativeSizeAxes = Axes.Both;
diff --git a/osu.Game.Tournament/TournamentSceneManager.cs b/osu.Game.Tournament/TournamentSceneManager.cs
index 914d1163ad..80a9c07cde 100644
--- a/osu.Game.Tournament/TournamentSceneManager.cs
+++ b/osu.Game.Tournament/TournamentSceneManager.cs
@@ -7,11 +7,9 @@ using osu.Framework.Allocation;
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;
using osu.Game.Tournament.Components;
-using osu.Game.Tournament.Models;
using osu.Game.Tournament.Screens;
using osu.Game.Tournament.Screens.Drawings;
using osu.Game.Tournament.Screens.Editors;
@@ -52,7 +50,7 @@ namespace osu.Game.Tournament
}
[BackgroundDependencyLoader]
- private void load(LadderInfo ladder, Storage storage)
+ private void load()
{
InternalChildren = new Drawable[]
{
diff --git a/osu.Game/Collections/DrawableCollectionListItem.cs b/osu.Game/Collections/DrawableCollectionListItem.cs
index 909595bd1c..c4cb040b52 100644
--- a/osu.Game/Collections/DrawableCollectionListItem.cs
+++ b/osu.Game/Collections/DrawableCollectionListItem.cs
@@ -80,7 +80,7 @@ namespace osu.Game.Collections
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load()
{
Children = new Drawable[]
{
diff --git a/osu.Game/Database/RealmContextFactory.cs b/osu.Game/Database/RealmContextFactory.cs
index 96c24837a1..04253ade82 100644
--- a/osu.Game/Database/RealmContextFactory.cs
+++ b/osu.Game/Database/RealmContextFactory.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System;
+using System.IO;
using System.Linq;
using System.Reflection;
using System.Threading;
@@ -188,10 +189,17 @@ namespace osu.Game.Database
private RealmConfiguration getConfiguration()
{
+ // This is currently the only usage of temporary files at the osu! side.
+ // If we use the temporary folder in more situations in the future, this should be moved to a higher level (helper method or OsuGameBase).
+ string tempPathLocation = Path.Combine(Path.GetTempPath(), @"lazer");
+ if (!Directory.Exists(tempPathLocation))
+ Directory.CreateDirectory(tempPathLocation);
+
return new RealmConfiguration(storage.GetFullPath(Filename, true))
{
SchemaVersion = schema_version,
MigrationCallback = onMigration,
+ FallbackPipePath = tempPathLocation,
};
}
diff --git a/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs b/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs
index 6a42e83305..56ef87c1f4 100644
--- a/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs
+++ b/osu.Game/Graphics/Backgrounds/BeatmapBackgroundWithStoryboard.cs
@@ -1,20 +1,29 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
+#nullable enable
+
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Timing;
using osu.Game.Beatmaps;
+using osu.Game.Overlays;
using osu.Game.Storyboards.Drawables;
namespace osu.Game.Graphics.Backgrounds
{
public class BeatmapBackgroundWithStoryboard : BeatmapBackground
{
+ private readonly InterpolatingFramedClock storyboardClock;
+
+ [Resolved(CanBeNull = true)]
+ private MusicController? musicController { get; set; }
+
public BeatmapBackgroundWithStoryboard(WorkingBeatmap beatmap, string fallbackTextureName = "Backgrounds/bg1")
: base(beatmap, fallbackTextureName)
{
+ storyboardClock = new InterpolatingFramedClock();
}
[BackgroundDependencyLoader]
@@ -30,8 +39,40 @@ namespace osu.Game.Graphics.Backgrounds
{
RelativeSizeAxes = Axes.Both,
Volume = { Value = 0 },
- Child = new DrawableStoryboard(Beatmap.Storyboard) { Clock = new InterpolatingFramedClock(Beatmap.Track) }
+ Child = new DrawableStoryboard(Beatmap.Storyboard) { Clock = storyboardClock }
}, AddInternal);
}
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+ if (musicController != null)
+ musicController.TrackChanged += onTrackChanged;
+
+ updateStoryboardClockSource(Beatmap);
+ }
+
+ private void onTrackChanged(WorkingBeatmap newBeatmap, TrackChangeDirection _) => updateStoryboardClockSource(newBeatmap);
+
+ private void updateStoryboardClockSource(WorkingBeatmap newBeatmap)
+ {
+ if (newBeatmap != Beatmap)
+ return;
+
+ // `MusicController` will sometimes reload the track, even when the working beatmap technically hasn't changed.
+ // ensure that the storyboard's clock is always using the latest track instance.
+ storyboardClock.ChangeSource(newBeatmap.Track);
+ // more often than not, the previous source track's time will be in the future relative to the new source track.
+ // explicitly process a single frame so that `InterpolatingFramedClock`'s interpolation logic is bypassed
+ // and the storyboard clock is correctly rewound to the source track's time exactly.
+ storyboardClock.ProcessFrame();
+ }
+
+ protected override void Dispose(bool isDisposing)
+ {
+ base.Dispose(isDisposing);
+ if (musicController != null)
+ musicController.TrackChanged -= onTrackChanged;
+ }
}
}
diff --git a/osu.Game/Graphics/Sprites/LogoAnimation.cs b/osu.Game/Graphics/Sprites/LogoAnimation.cs
index b1383065fe..36fcd39b54 100644
--- a/osu.Game/Graphics/Sprites/LogoAnimation.cs
+++ b/osu.Game/Graphics/Sprites/LogoAnimation.cs
@@ -7,14 +7,13 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.OpenGL.Vertices;
using osu.Framework.Graphics.Shaders;
using osu.Framework.Graphics.Sprites;
-using osu.Framework.Graphics.Textures;
namespace osu.Game.Graphics.Sprites
{
public class LogoAnimation : Sprite
{
[BackgroundDependencyLoader]
- private void load(ShaderManager shaders, TextureStore textures)
+ private void load(ShaderManager shaders)
{
TextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, @"LogoAnimation");
RoundedTextureShader = shaders.Load(VertexShaderDescriptor.TEXTURE_2, @"LogoAnimation"); // Masking isn't supported for now
diff --git a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs
index fea84998cf..4267b82bb7 100644
--- a/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs
+++ b/osu.Game/Graphics/UserInterface/DrawableOsuMenuItem.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Audio;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -30,7 +29,7 @@ namespace osu.Game.Graphics.UserInterface
}
[BackgroundDependencyLoader]
- private void load(AudioManager audio)
+ private void load()
{
BackgroundColour = Color4.Transparent;
BackgroundColourHover = Color4Extensions.FromHex(@"172023");
diff --git a/osu.Game/Graphics/UserInterface/HoverSampleDebounceComponent.cs b/osu.Game/Graphics/UserInterface/HoverSampleDebounceComponent.cs
index 1fd03a34e7..34ab7626c9 100644
--- a/osu.Game/Graphics/UserInterface/HoverSampleDebounceComponent.cs
+++ b/osu.Game/Graphics/UserInterface/HoverSampleDebounceComponent.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
@@ -18,7 +17,7 @@ namespace osu.Game.Graphics.UserInterface
private Bindable lastPlaybackTime;
[BackgroundDependencyLoader]
- private void load(AudioManager audio, SessionStatics statics)
+ private void load(SessionStatics statics)
{
lastPlaybackTime = statics.GetBindable(Static.LastHoverSoundPlaybackTime);
}
diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs
index cf201b18b4..e0946fd9e1 100644
--- a/osu.Game/Graphics/UserInterface/OsuContextMenu.cs
+++ b/osu.Game/Graphics/UserInterface/OsuContextMenu.cs
@@ -3,7 +3,6 @@
using osuTK.Graphics;
using osu.Framework.Allocation;
-using osu.Framework.Audio;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Effects;
@@ -41,7 +40,7 @@ namespace osu.Game.Graphics.UserInterface
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours, AudioManager audio)
+ private void load(OsuColour colours)
{
BackgroundColour = colours.ContextMenuGray;
}
diff --git a/osu.Game/Graphics/UserInterface/OsuContextMenuSamples.cs b/osu.Game/Graphics/UserInterface/OsuContextMenuSamples.cs
index d67ea499e5..921fef7951 100644
--- a/osu.Game/Graphics/UserInterface/OsuContextMenuSamples.cs
+++ b/osu.Game/Graphics/UserInterface/OsuContextMenuSamples.cs
@@ -16,7 +16,7 @@ namespace osu.Game.Graphics.UserInterface
private Sample sampleClose;
[BackgroundDependencyLoader]
- private void load(OsuColour colours, AudioManager audio)
+ private void load(AudioManager audio)
{
sampleClick = audio.Samples.Get($@"UI/{HoverSampleSet.Default.GetDescription()}-select");
sampleOpen = audio.Samples.Get(@"UI/dropdown-open");
diff --git a/osu.Game/Localisation/DebugSettingsStrings.cs b/osu.Game/Localisation/DebugSettingsStrings.cs
index dd21739096..74b2c8d892 100644
--- a/osu.Game/Localisation/DebugSettingsStrings.cs
+++ b/osu.Game/Localisation/DebugSettingsStrings.cs
@@ -44,6 +44,11 @@ namespace osu.Game.Localisation
///
public static LocalisableString ClearAllCaches => new TranslatableString(getKey(@"clear_all_caches"), @"Clear all caches");
+ ///
+ /// "Compact realm"
+ ///
+ public static LocalisableString CompactRealm => new TranslatableString(getKey(@"compact_realm"), @"Compact realm");
+
private static string getKey(string key) => $"{prefix}:{key}";
}
}
diff --git a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs
index 123624d333..f2fa51bde7 100644
--- a/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs
+++ b/osu.Game/Online/API/Requests/GetUserRecentActivitiesRequest.cs
@@ -22,6 +22,8 @@ namespace osu.Game.Online.API.Requests
public enum RecentActivityType
{
Achievement,
+
+ // ReSharper disable once IdentifierTypo
BeatmapPlaycount,
BeatmapsetApprove,
BeatmapsetDelete,
diff --git a/osu.Game/Online/Chat/ChannelManager.cs b/osu.Game/Online/Chat/ChannelManager.cs
index 82e042ae4e..77b52c34d9 100644
--- a/osu.Game/Online/Chat/ChannelManager.cs
+++ b/osu.Game/Online/Chat/ChannelManager.cs
@@ -90,13 +90,16 @@ namespace osu.Game.Online.Chat
{
// Polling will eventually be replaced with websocket, but let's avoid doing these background operations as much as possible for now.
// The only loss will be delayed PM/message highlight notifications.
+ int millisecondsBetweenPolls = HighPollRate.Value ? 1000 : 60000;
- if (HighPollRate.Value)
- TimeBetweenPolls.Value = 1000;
- else if (!isIdle.Value)
- TimeBetweenPolls.Value = 60000;
- else
- TimeBetweenPolls.Value = 600000;
+ if (isIdle.Value)
+ millisecondsBetweenPolls *= 10;
+
+ if (TimeBetweenPolls.Value != millisecondsBetweenPolls)
+ {
+ TimeBetweenPolls.Value = millisecondsBetweenPolls;
+ Logger.Log($"Chat is now polling every {TimeBetweenPolls.Value} ms");
+ }
}
///
diff --git a/osu.Game/Online/Chat/StandAloneChatDisplay.cs b/osu.Game/Online/Chat/StandAloneChatDisplay.cs
index 81fd5ad98c..f83bf4877e 100644
--- a/osu.Game/Online/Chat/StandAloneChatDisplay.cs
+++ b/osu.Game/Online/Chat/StandAloneChatDisplay.cs
@@ -25,7 +25,7 @@ namespace osu.Game.Online.Chat
protected readonly ChatTextBox TextBox;
- protected ChannelManager ChannelManager;
+ private ChannelManager channelManager;
private StandAloneDrawableChannel drawableChannel;
@@ -80,7 +80,7 @@ namespace osu.Game.Online.Chat
[BackgroundDependencyLoader(true)]
private void load(ChannelManager manager)
{
- ChannelManager ??= manager;
+ channelManager ??= manager;
}
protected virtual StandAloneDrawableChannel CreateDrawableChannel(Channel channel) =>
@@ -94,9 +94,9 @@ namespace osu.Game.Online.Chat
return;
if (text[0] == '/')
- ChannelManager?.PostCommand(text.Substring(1), Channel.Value);
+ channelManager?.PostCommand(text.Substring(1), Channel.Value);
else
- ChannelManager?.PostMessage(text, target: Channel.Value);
+ channelManager?.PostMessage(text, target: Channel.Value);
TextBox.Text = string.Empty;
}
diff --git a/osu.Game/Online/Leaderboards/LeaderboardScore.cs b/osu.Game/Online/Leaderboards/LeaderboardScore.cs
index 14eec8b388..8f4a103513 100644
--- a/osu.Game/Online/Leaderboards/LeaderboardScore.cs
+++ b/osu.Game/Online/Leaderboards/LeaderboardScore.cs
@@ -53,7 +53,9 @@ namespace osu.Game.Online.Leaderboards
private Drawable avatar;
private Drawable scoreRank;
private OsuSpriteText nameLabel;
- private GlowingSpriteText scoreLabel;
+
+ public GlowingSpriteText ScoreText { get; private set; }
+
private Container flagBadgeContainer;
private FillFlowContainer modsContainer;
@@ -198,7 +200,7 @@ namespace osu.Game.Online.Leaderboards
Spacing = new Vector2(5f, 0f),
Children = new Drawable[]
{
- scoreLabel = new GlowingSpriteText
+ ScoreText = new GlowingSpriteText
{
TextColour = Color4.White,
GlowColour = Color4Extensions.FromHex(@"83ccfa"),
@@ -240,7 +242,7 @@ namespace osu.Game.Online.Leaderboards
public override void Show()
{
- foreach (var d in new[] { avatar, nameLabel, scoreLabel, scoreRank, flagBadgeContainer, modsContainer }.Concat(statisticsLabels))
+ foreach (var d in new[] { avatar, nameLabel, ScoreText, scoreRank, flagBadgeContainer, modsContainer }.Concat(statisticsLabels))
d.FadeOut();
Alpha = 0;
@@ -262,7 +264,7 @@ namespace osu.Game.Online.Leaderboards
using (BeginDelayedSequence(250))
{
- scoreLabel.FadeIn(200);
+ ScoreText.FadeIn(200);
scoreRank.FadeIn(200);
using (BeginDelayedSequence(50))
diff --git a/osu.Game/OsuGame.cs b/osu.Game/OsuGame.cs
index c5a465ae96..6730f2cf65 100644
--- a/osu.Game/OsuGame.cs
+++ b/osu.Game/OsuGame.cs
@@ -154,6 +154,8 @@ namespace osu.Game
private MainMenu menuScreen;
+ private VersionManager versionManager;
+
[CanBeNull]
private IntroScreen introScreen;
@@ -743,6 +745,9 @@ namespace osu.Game
ScreenStack.ScreenPushed += screenPushed;
ScreenStack.ScreenExited += screenExited;
+ if (!args?.Any(a => a == @"--no-version-overlay") ?? true)
+ loadComponentSingleFile(versionManager = new VersionManager { Depth = int.MinValue }, ScreenContainer.Add);
+
loadComponentSingleFile(osuLogo, logo =>
{
logoContainer.Add(logo);
@@ -820,7 +825,17 @@ namespace osu.Game
loadComponentSingleFile(CreateHighPerformanceSession(), Add);
- chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;
+ chatOverlay.State.BindValueChanged(_ => updateChatPollRate());
+ // Multiplayer modes need to increase poll rate temporarily.
+ API.Activity.BindValueChanged(_ => updateChatPollRate(), true);
+
+ void updateChatPollRate()
+ {
+ channelManager.HighPollRate.Value =
+ chatOverlay.State.Value == Visibility.Visible
+ || API.Activity.Value is UserActivity.InLobby
+ || API.Activity.Value is UserActivity.InMultiplayerGame;
+ }
Add(difficultyRecommender);
Add(externalLinkOpener = new ExternalLinkOpener());
@@ -1116,10 +1131,16 @@ namespace osu.Game
{
case IntroScreen intro:
introScreen = intro;
+ versionManager?.Show();
break;
case MainMenu menu:
menuScreen = menu;
+ versionManager?.Show();
+ break;
+
+ default:
+ versionManager?.Hide();
break;
}
diff --git a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs
index a11b234cb1..a2c04c6989 100644
--- a/osu.Game/Overlays/AccountCreation/ScreenEntry.cs
+++ b/osu.Game/Overlays/AccountCreation/ScreenEntry.cs
@@ -44,7 +44,7 @@ namespace osu.Game.Overlays.AccountCreation
private GameHost host { get; set; }
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load()
{
InternalChildren = new Drawable[]
{
diff --git a/osu.Game/Overlays/AccountCreationOverlay.cs b/osu.Game/Overlays/AccountCreationOverlay.cs
index 3084c7475a..a96aff2a5d 100644
--- a/osu.Game/Overlays/AccountCreationOverlay.cs
+++ b/osu.Game/Overlays/AccountCreationOverlay.cs
@@ -10,7 +10,6 @@ using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Screens;
using osu.Framework.Threading;
-using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Online.API;
using osu.Game.Overlays.AccountCreation;
@@ -35,7 +34,7 @@ namespace osu.Game.Overlays
private readonly IBindable apiState = new Bindable();
[BackgroundDependencyLoader]
- private void load(OsuColour colours, IAPIProvider api)
+ private void load(IAPIProvider api)
{
apiState.BindTo(api.State);
apiState.BindValueChanged(apiStateChanged, true);
diff --git a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs
index a40f29abf2..00dedc892b 100644
--- a/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs
+++ b/osu.Game/Overlays/BeatmapSet/Scores/ScoresContainer.cs
@@ -65,6 +65,9 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
scoreTable.ClearScores();
scoreTable.Hide();
+ loading.Hide();
+ loading.FinishTransforms();
+
if (value?.Scores.Any() != true)
return;
@@ -258,9 +261,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
{
Scores = null;
notSupporterPlaceholder.Show();
-
- loading.Hide();
- loading.FinishTransforms();
return;
}
@@ -272,9 +272,6 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
getScoresRequest = new GetScoresRequest(Beatmap.Value, Beatmap.Value.Ruleset, scope.Value, modSelector.SelectedMods);
getScoresRequest.Success += scores =>
{
- loading.Hide();
- loading.FinishTransforms();
-
Scores = scores;
if (!scores.Scores.Any())
diff --git a/osu.Game/Overlays/Changelog/ChangelogBuild.cs b/osu.Game/Overlays/Changelog/ChangelogBuild.cs
index 2d071b7345..c65eefdee4 100644
--- a/osu.Game/Overlays/Changelog/ChangelogBuild.cs
+++ b/osu.Game/Overlays/Changelog/ChangelogBuild.cs
@@ -46,7 +46,7 @@ namespace osu.Game.Overlays.Changelog
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours, OverlayColourProvider colourProvider)
+ private void load()
{
foreach (var categoryEntries in Build.ChangelogEntries.GroupBy(b => b.Category).OrderBy(c => c.Key))
{
diff --git a/osu.Game/Overlays/ChangelogOverlay.cs b/osu.Game/Overlays/ChangelogOverlay.cs
index fe611d0134..ab97ae950d 100644
--- a/osu.Game/Overlays/ChangelogOverlay.cs
+++ b/osu.Game/Overlays/ChangelogOverlay.cs
@@ -7,7 +7,6 @@ using System.Threading;
using System.Threading.Tasks;
using JetBrains.Annotations;
using osu.Framework.Allocation;
-using osu.Framework.Audio;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input.Events;
@@ -35,7 +34,7 @@ namespace osu.Game.Overlays
}
[BackgroundDependencyLoader]
- private void load(AudioManager audio)
+ private void load()
{
Header.Build.BindTarget = Current;
diff --git a/osu.Game/Overlays/Comments/CommentsContainer.cs b/osu.Game/Overlays/Comments/CommentsContainer.cs
index 970fc5ccef..6a5734b553 100644
--- a/osu.Game/Overlays/Comments/CommentsContainer.cs
+++ b/osu.Game/Overlays/Comments/CommentsContainer.cs
@@ -317,7 +317,7 @@ namespace osu.Game.Overlays.Comments
private class NoCommentsPlaceholder : CompositeDrawable
{
[BackgroundDependencyLoader]
- private void load(OverlayColourProvider colourProvider)
+ private void load()
{
Height = 80;
RelativeSizeAxes = Axes.X;
diff --git a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs
index a13f5ed6ce..00a866f1f4 100644
--- a/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs
+++ b/osu.Game/Overlays/Profile/Header/CentreHeaderContainer.cs
@@ -7,7 +7,6 @@ using osu.Framework.Extensions.LocalisationExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Graphics.Textures;
using osu.Framework.Localisation;
using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays.Profile.Header.Components;
@@ -30,7 +29,7 @@ namespace osu.Game.Overlays.Profile.Header
}
[BackgroundDependencyLoader]
- private void load(OverlayColourProvider colourProvider, TextureStore textures)
+ private void load(OverlayColourProvider colourProvider)
{
Container hiddenDetailContainer;
Container expandedDetailContainer;
diff --git a/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs b/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs
index 6f48768dcd..8d4fc5fc9f 100644
--- a/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs
+++ b/osu.Game/Overlays/Settings/Sections/DebugSettings/MemorySettings.cs
@@ -2,10 +2,10 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Configuration;
using osu.Framework.Graphics;
using osu.Framework.Localisation;
using osu.Framework.Platform;
+using osu.Game.Database;
using osu.Game.Localisation;
namespace osu.Game.Overlays.Settings.Sections.DebugSettings
@@ -15,7 +15,7 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
protected override LocalisableString Header => DebugSettingsStrings.MemoryHeader;
[BackgroundDependencyLoader]
- private void load(FrameworkDebugConfigManager config, GameHost host)
+ private void load(GameHost host, RealmContextFactory realmFactory)
{
Children = new Drawable[]
{
@@ -24,6 +24,17 @@ namespace osu.Game.Overlays.Settings.Sections.DebugSettings
Text = DebugSettingsStrings.ClearAllCaches,
Action = host.Collect
},
+ new SettingsButton
+ {
+ Text = DebugSettingsStrings.CompactRealm,
+ Action = () =>
+ {
+ // Blocking operations implicitly causes a Compact().
+ using (realmFactory.BlockAllOperations())
+ {
+ }
+ }
+ },
};
}
}
diff --git a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs
index 115a7bdc79..94c7c66538 100644
--- a/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs
+++ b/osu.Game/Overlays/Settings/Sections/Input/KeyBindingsSubsection.cs
@@ -18,7 +18,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
{
protected IEnumerable Defaults;
- protected RulesetInfo Ruleset;
+ public RulesetInfo Ruleset { get; protected set; }
private readonly int? variant;
diff --git a/osu.Game/Overlays/Settings/SettingsFooter.cs b/osu.Game/Overlays/Settings/SettingsFooter.cs
index ed49ce2b63..263f2f4829 100644
--- a/osu.Game/Overlays/Settings/SettingsFooter.cs
+++ b/osu.Game/Overlays/Settings/SettingsFooter.cs
@@ -19,7 +19,7 @@ namespace osu.Game.Overlays.Settings
public class SettingsFooter : FillFlowContainer
{
[BackgroundDependencyLoader]
- private void load(OsuGameBase game, OsuColour colours, RulesetStore rulesets)
+ private void load(OsuGameBase game, RulesetStore rulesets)
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
diff --git a/osu.Game/Overlays/Settings/SettingsSection.cs b/osu.Game/Overlays/Settings/SettingsSection.cs
index 0ae353602e..2539c32806 100644
--- a/osu.Game/Overlays/Settings/SettingsSection.cs
+++ b/osu.Game/Overlays/Settings/SettingsSection.cs
@@ -65,7 +65,7 @@ namespace osu.Game.Overlays.Settings
}
[BackgroundDependencyLoader]
- private void load(OverlayColourProvider colourProvider, OsuColour colours)
+ private void load(OverlayColourProvider colourProvider)
{
AddRangeInternal(new Drawable[]
{
diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Game/Overlays/VersionManager.cs
similarity index 98%
rename from osu.Desktop/Overlays/VersionManager.cs
rename to osu.Game/Overlays/VersionManager.cs
index e4a3451651..fe6613fba2 100644
--- a/osu.Desktop/Overlays/VersionManager.cs
+++ b/osu.Game/Overlays/VersionManager.cs
@@ -7,13 +7,12 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
-using osu.Game;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osuTK;
using osuTK.Graphics;
-namespace osu.Desktop.Overlays
+namespace osu.Game.Overlays
{
public class VersionManager : VisibilityContainer
{
diff --git a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
index 4ab513bf19..5531bf8b5a 100644
--- a/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
+++ b/osu.Game/Rulesets/Objects/Drawables/DrawableHitObject.cs
@@ -533,9 +533,9 @@ namespace osu.Game.Rulesets.Objects.Drawables
protected double CalculateSamplePlaybackBalance(double position)
{
float balanceAdjustAmount = positionalHitsoundsLevel.Value * 2;
- double returnedvalue = balanceAdjustAmount * (position - 0.5f);
+ double returnedValue = balanceAdjustAmount * (position - 0.5f);
- return returnedvalue;
+ return returnedValue;
}
///
diff --git a/osu.Game/Rulesets/Objects/HitObject.cs b/osu.Game/Rulesets/Objects/HitObject.cs
index a80b3d0fa5..c590cc302f 100644
--- a/osu.Game/Rulesets/Objects/HitObject.cs
+++ b/osu.Game/Rulesets/Objects/HitObject.cs
@@ -87,23 +87,6 @@ namespace osu.Game.Rulesets.Objects
[JsonIgnore]
public SlimReadOnlyListWrapper NestedHitObjects => nestedHitObjects.AsSlimReadOnly();
- public HitObject()
- {
- StartTimeBindable.ValueChanged += time =>
- {
- double offset = time.NewValue - time.OldValue;
-
- foreach (var nested in nestedHitObjects)
- nested.StartTime += offset;
-
- if (DifficultyControlPoint != DifficultyControlPoint.DEFAULT)
- DifficultyControlPoint.Time = time.NewValue;
-
- if (SampleControlPoint != SampleControlPoint.DEFAULT)
- SampleControlPoint.Time = this.GetEndTime() + control_point_leniency;
- };
- }
-
///
/// Applies default values to this HitObject.
///
@@ -115,24 +98,22 @@ namespace osu.Game.Rulesets.Objects
var legacyInfo = controlPointInfo as LegacyControlPointInfo;
if (legacyInfo != null)
- {
DifficultyControlPoint = (DifficultyControlPoint)legacyInfo.DifficultyPointAt(StartTime).DeepClone();
- DifficultyControlPoint.Time = StartTime;
- }
else if (DifficultyControlPoint == DifficultyControlPoint.DEFAULT)
DifficultyControlPoint = new DifficultyControlPoint();
+ DifficultyControlPoint.Time = StartTime;
+
ApplyDefaultsToSelf(controlPointInfo, difficulty);
// This is done here after ApplyDefaultsToSelf as we may require custom defaults to be applied to have an accurate end time.
if (legacyInfo != null)
- {
SampleControlPoint = (SampleControlPoint)legacyInfo.SamplePointAt(this.GetEndTime() + control_point_leniency).DeepClone();
- SampleControlPoint.Time = this.GetEndTime() + control_point_leniency;
- }
else if (SampleControlPoint == SampleControlPoint.DEFAULT)
SampleControlPoint = new SampleControlPoint();
+ SampleControlPoint.Time = this.GetEndTime() + control_point_leniency;
+
nestedHitObjects.Clear();
CreateNestedHitObjects(cancellationToken);
@@ -155,7 +136,28 @@ namespace osu.Game.Rulesets.Objects
foreach (var h in nestedHitObjects)
h.ApplyDefaults(controlPointInfo, difficulty, cancellationToken);
+ // `ApplyDefaults()` may be called multiple times on a single hitobject.
+ // to prevent subscribing to `StartTimeBindable.ValueChanged` multiple times with the same callback,
+ // remove the previous subscription (if present) before (re-)registering.
+ StartTimeBindable.ValueChanged -= onStartTimeChanged;
+
+ // this callback must be (re-)registered after default application
+ // to ensure that the read of `this.GetEndTime()` within `onStartTimeChanged` doesn't return an invalid value
+ // if `StartTimeBindable` is changed prior to default application.
+ StartTimeBindable.ValueChanged += onStartTimeChanged;
+
DefaultsApplied?.Invoke(this);
+
+ void onStartTimeChanged(ValueChangedEvent time)
+ {
+ double offset = time.NewValue - time.OldValue;
+
+ foreach (var nested in nestedHitObjects)
+ nested.StartTime += offset;
+
+ DifficultyControlPoint.Time = time.NewValue;
+ SampleControlPoint.Time = this.GetEndTime() + control_point_leniency;
+ }
}
protected virtual void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, IBeatmapDifficultyInfo difficulty)
diff --git a/osu.Game/Rulesets/Objects/SliderPathExtensions.cs b/osu.Game/Rulesets/Objects/SliderPathExtensions.cs
index 1308fff7ae..ba614900c0 100644
--- a/osu.Game/Rulesets/Objects/SliderPathExtensions.cs
+++ b/osu.Game/Rulesets/Objects/SliderPathExtensions.cs
@@ -2,6 +2,7 @@
// See the LICENCE file in the repository root for full licence text.
using System.Linq;
+using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects.Types;
using osuTK;
@@ -11,6 +12,15 @@ namespace osu.Game.Rulesets.Objects
{
public static class SliderPathExtensions
{
+ ///
+ /// Snaps the provided 's duration using the .
+ ///
+ public static void SnapTo(this THitObject hitObject, IPositionSnapProvider? snapProvider)
+ where THitObject : HitObject, IHasPath
+ {
+ hitObject.Path.ExpectedDistance.Value = snapProvider?.GetSnappedDistanceFromDistance(hitObject, (float)hitObject.Path.CalculatedDistance) ?? hitObject.Path.CalculatedDistance;
+ }
+
///
/// Reverse the direction of this path.
///
diff --git a/osu.Game/Rulesets/Scoring/JudgementProcessor.cs b/osu.Game/Rulesets/Scoring/JudgementProcessor.cs
index ed4a16f0e8..c3c4a2c949 100644
--- a/osu.Game/Rulesets/Scoring/JudgementProcessor.cs
+++ b/osu.Game/Rulesets/Scoring/JudgementProcessor.cs
@@ -135,7 +135,7 @@ namespace osu.Game.Rulesets.Scoring
if (result == null)
throw new InvalidOperationException($"{GetType().ReadableName()} must provide a {nameof(JudgementResult)} through {nameof(CreateResult)}.");
- result.Type = judgement.MaxResult;
+ result.Type = GetSimulatedHitResult(judgement);
ApplyResult(result);
}
}
@@ -145,5 +145,12 @@ namespace osu.Game.Rulesets.Scoring
base.Update();
hasCompleted.Value = JudgedHits == MaxHits && (JudgedHits == 0 || lastAppliedResult.TimeAbsolute < Clock.CurrentTime);
}
+
+ ///
+ /// Gets a simulated for a judgement. Used during to simulate a "perfect" play.
+ ///
+ /// The judgement to simulate a for.
+ /// The simulated for the judgement.
+ protected virtual HitResult GetSimulatedHitResult(Judgement judgement) => judgement.MaxResult;
}
}
diff --git a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
index c0b339a231..f2dbb1a23f 100644
--- a/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
+++ b/osu.Game/Rulesets/UI/FrameStabilityContainer.cs
@@ -61,7 +61,7 @@ namespace osu.Game.Rulesets.UI
private int direction = 1;
[BackgroundDependencyLoader(true)]
- private void load(GameplayClock clock, ISamplePlaybackDisabler sampleDisabler)
+ private void load(GameplayClock clock)
{
if (clock != null)
{
diff --git a/osu.Game/Rulesets/UI/RulesetInputManager.cs b/osu.Game/Rulesets/UI/RulesetInputManager.cs
index 6564ff9e23..370c99ffaf 100644
--- a/osu.Game/Rulesets/UI/RulesetInputManager.cs
+++ b/osu.Game/Rulesets/UI/RulesetInputManager.cs
@@ -127,6 +127,17 @@ namespace osu.Game.Rulesets.UI
return base.Handle(e);
}
+ protected override bool HandleMouseTouchStateChange(TouchStateChangeEvent e)
+ {
+ if (mouseDisabled.Value)
+ {
+ // Only propagate positional data when mouse buttons are disabled.
+ e = new TouchStateChangeEvent(e.State, e.Input, e.Touch, false, e.LastPosition);
+ }
+
+ return base.HandleMouseTouchStateChange(e);
+ }
+
#endregion
#region Key Counter Attachment
diff --git a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs
index 1f3a937311..926f2fd539 100644
--- a/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs
+++ b/osu.Game/Rulesets/UI/Scrolling/DrawableScrollingRuleset.cs
@@ -116,25 +116,11 @@ namespace osu.Game.Rulesets.UI.Scrolling
if (RelativeScaleBeatLengths)
{
- IReadOnlyList timingPoints = Beatmap.ControlPointInfo.TimingPoints;
- double maxDuration = 0;
+ baseBeatLength = Beatmap.GetMostCommonBeatLength();
- for (int i = 0; i < timingPoints.Count; i++)
- {
- if (timingPoints[i].Time > lastObjectTime)
- break;
-
- double endTime = i < timingPoints.Count - 1 ? timingPoints[i + 1].Time : lastObjectTime;
- double duration = endTime - timingPoints[i].Time;
-
- if (duration > maxDuration)
- {
- maxDuration = duration;
- // The slider multiplier is post-multiplied to determine the final velocity, but for relative scale beat lengths
- // the multiplier should not affect the effective timing point (the longest in the beatmap), so it is factored out here
- baseBeatLength = timingPoints[i].BeatLength / Beatmap.Difficulty.SliderMultiplier;
- }
- }
+ // The slider multiplier is post-multiplied to determine the final velocity, but for relative scale beat lengths
+ // the multiplier should not affect the effective timing point (the longest in the beatmap), so it is factored out here
+ baseBeatLength /= Beatmap.Difficulty.SliderMultiplier;
}
// Merge sequences of timing and difficulty control points to create the aggregate "multiplier" control point
diff --git a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs
index 39de13899d..9d5d8013b7 100644
--- a/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/SelectionHandler.cs
@@ -15,7 +15,6 @@ using osu.Framework.Input;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
using osu.Framework.Utils;
-using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Game.Input.Bindings;
using osu.Game.Rulesets.Edit;
@@ -57,7 +56,7 @@ namespace osu.Game.Screens.Edit.Compose.Components
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load()
{
InternalChild = SelectionBox = CreateSelectionBox();
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs
index 2cbfe88519..7d52645aa1 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/SamplePointPiece.cs
@@ -15,7 +15,6 @@ using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.UserInterface;
using osu.Framework.Input.Events;
using osu.Game.Beatmaps.ControlPoints;
-using osu.Game.Graphics;
using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Rulesets.Objects;
using osu.Game.Screens.Edit.Timing;
@@ -39,7 +38,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load()
{
volume.BindValueChanged(volume => updateText());
bank.BindValueChanged(bank => updateText(), true);
diff --git a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimingPointPiece.cs b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimingPointPiece.cs
index fa51281c55..2df4ef001c 100644
--- a/osu.Game/Screens/Edit/Compose/Components/Timeline/TimingPointPiece.cs
+++ b/osu.Game/Screens/Edit/Compose/Components/Timeline/TimingPointPiece.cs
@@ -4,7 +4,6 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Beatmaps.ControlPoints;
-using osu.Game.Graphics;
namespace osu.Game.Screens.Edit.Compose.Components.Timeline
{
@@ -19,7 +18,7 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load()
{
beatLength.BindValueChanged(beatLength =>
{
diff --git a/osu.Game/Screens/Edit/EditorRoundedScreenSettingsSection.cs b/osu.Game/Screens/Edit/EditorRoundedScreenSettingsSection.cs
index e17114ebcb..25d7dfbb4a 100644
--- a/osu.Game/Screens/Edit/EditorRoundedScreenSettingsSection.cs
+++ b/osu.Game/Screens/Edit/EditorRoundedScreenSettingsSection.cs
@@ -6,7 +6,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics.Sprites;
-using osu.Game.Overlays;
using osuTK;
namespace osu.Game.Screens.Edit
@@ -20,7 +19,7 @@ namespace osu.Game.Screens.Edit
protected FillFlowContainer Flow { get; private set; }
[BackgroundDependencyLoader]
- private void load(OverlayColourProvider colours)
+ private void load()
{
RelativeSizeAxes = Axes.X;
AutoSizeAxes = Axes.Y;
diff --git a/osu.Game/Screens/Edit/Verify/VisibilitySection.cs b/osu.Game/Screens/Edit/Verify/VisibilitySection.cs
index d049436376..0bdc8c0efd 100644
--- a/osu.Game/Screens/Edit/Verify/VisibilitySection.cs
+++ b/osu.Game/Screens/Edit/Verify/VisibilitySection.cs
@@ -4,7 +4,6 @@
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
-using osu.Game.Overlays;
using osu.Game.Overlays.Settings;
using osu.Game.Rulesets.Edit.Checks.Components;
@@ -24,7 +23,7 @@ namespace osu.Game.Screens.Edit.Verify
protected override string HeaderText => "Visibility";
[BackgroundDependencyLoader]
- private void load(OverlayColourProvider colours, VerifyScreen verify)
+ private void load(VerifyScreen verify)
{
hiddenIssueTypes = verify.HiddenIssueTypes.GetBoundCopy();
diff --git a/osu.Game/Screens/Import/FileImportScreen.cs b/osu.Game/Screens/Import/FileImportScreen.cs
index c32e230e11..09870e0bab 100644
--- a/osu.Game/Screens/Import/FileImportScreen.cs
+++ b/osu.Game/Screens/Import/FileImportScreen.cs
@@ -9,7 +9,6 @@ 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.Screens;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
@@ -40,7 +39,7 @@ namespace osu.Game.Screens.Import
private OsuColour colours { get; set; }
[BackgroundDependencyLoader(true)]
- private void load(Storage storage)
+ private void load()
{
InternalChild = contentContainer = new Container
{
diff --git a/osu.Game/Screens/Menu/ButtonSystem.cs b/osu.Game/Screens/Menu/ButtonSystem.cs
index feb6f6c92a..32731407fd 100644
--- a/osu.Game/Screens/Menu/ButtonSystem.cs
+++ b/osu.Game/Screens/Menu/ButtonSystem.cs
@@ -15,7 +15,6 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Framework.Input.Events;
-using osu.Framework.Localisation;
using osu.Framework.Logging;
using osu.Framework.Platform;
using osu.Framework.Threading;
@@ -123,7 +122,7 @@ namespace osu.Game.Screens.Menu
private LoginOverlay loginOverlay { get; set; }
[BackgroundDependencyLoader(true)]
- private void load(AudioManager audio, IdleTracker idleTracker, GameHost host, LocalisationManager strings)
+ private void load(AudioManager audio, IdleTracker idleTracker, GameHost host)
{
buttonsPlay.Add(new Button(ButtonSystemStrings.Solo, @"button-solo-select", FontAwesome.Solid.User, new Color4(102, 68, 204, 255), () => OnSolo?.Invoke(), WEDGE_WIDTH, Key.P));
buttonsPlay.Add(new Button(ButtonSystemStrings.Multi, @"button-generic-select", FontAwesome.Solid.Users, new Color4(94, 63, 186, 255), onMultiplayer, 0, Key.M));
diff --git a/osu.Game/Screens/Menu/IntroScreen.cs b/osu.Game/Screens/Menu/IntroScreen.cs
index 948e3a7d88..59bf1785d5 100644
--- a/osu.Game/Screens/Menu/IntroScreen.cs
+++ b/osu.Game/Screens/Menu/IntroScreen.cs
@@ -18,7 +18,6 @@ using osu.Game.Configuration;
using osu.Game.IO.Archives;
using osu.Game.Overlays;
using osu.Game.Screens.Backgrounds;
-using osu.Game.Skinning;
using osuTK;
using osuTK.Graphics;
@@ -81,7 +80,7 @@ namespace osu.Game.Screens.Menu
}
[BackgroundDependencyLoader]
- private void load(OsuConfigManager config, SkinManager skinManager, BeatmapManager beatmaps, Framework.Game game)
+ private void load(OsuConfigManager config, BeatmapManager beatmaps, Framework.Game game)
{
// prevent user from changing beatmap while the intro is still runnning.
beatmap = Beatmap.BeginLease(false);
diff --git a/osu.Game/Screens/Menu/IntroTriangles.cs b/osu.Game/Screens/Menu/IntroTriangles.cs
index d171e481b1..10f940e9de 100644
--- a/osu.Game/Screens/Menu/IntroTriangles.cs
+++ b/osu.Game/Screens/Menu/IntroTriangles.cs
@@ -133,7 +133,7 @@ namespace osu.Game.Screens.Menu
private OsuGameBase game { get; set; }
[BackgroundDependencyLoader]
- private void load(TextureStore textures)
+ private void load()
{
InternalChildren = new Drawable[]
{
diff --git a/osu.Game/Screens/Menu/MainMenu.cs b/osu.Game/Screens/Menu/MainMenu.cs
index 3da740b85d..8b1bab52b3 100644
--- a/osu.Game/Screens/Menu/MainMenu.cs
+++ b/osu.Game/Screens/Menu/MainMenu.cs
@@ -71,7 +71,7 @@ namespace osu.Game.Screens.Menu
private SongTicker songTicker;
[BackgroundDependencyLoader(true)]
- private void load(BeatmapListingOverlay beatmapListing, SettingsOverlay settings, RankingsOverlay rankings, OsuConfigManager config, SessionStatics statics)
+ private void load(BeatmapListingOverlay beatmapListing, SettingsOverlay settings, OsuConfigManager config, SessionStatics statics)
{
holdDelay = config.GetBindable(OsuSetting.UIHoldActivationDelay);
loginDisplayed = statics.GetBindable(Static.LoginOverlayDisplayed);
diff --git a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
index c31239616c..2d5225639f 100644
--- a/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
+++ b/osu.Game/Screens/OnlinePlay/Match/RoomSubScreen.cs
@@ -21,6 +21,7 @@ using osu.Game.Overlays.Mods;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Screens.OnlinePlay.Match.Components;
+using osu.Game.Screens.OnlinePlay.Multiplayer;
namespace osu.Game.Screens.OnlinePlay.Match
{
@@ -101,6 +102,7 @@ namespace osu.Game.Screens.OnlinePlay.Match
InternalChildren = new Drawable[]
{
beatmapAvailabilityTracker,
+ new MultiplayerRoomSounds(),
new GridContainer
{
RelativeSizeAxes = Axes.Both,
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomSounds.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomSounds.cs
new file mode 100644
index 0000000000..d467a32acb
--- /dev/null
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/MultiplayerRoomSounds.cs
@@ -0,0 +1,65 @@
+// 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.Allocation;
+using osu.Framework.Audio;
+using osu.Framework.Audio.Sample;
+using osu.Framework.Bindables;
+using osu.Game.Online.API.Requests.Responses;
+using osu.Game.Online.Multiplayer;
+
+namespace osu.Game.Screens.OnlinePlay.Multiplayer
+{
+ public class MultiplayerRoomSounds : MultiplayerRoomComposite
+ {
+ private Sample hostChangedSample;
+ private Sample userJoinedSample;
+ private Sample userLeftSample;
+ private Sample userKickedSample;
+
+ [BackgroundDependencyLoader]
+ private void load(AudioManager audio)
+ {
+ hostChangedSample = audio.Samples.Get(@"Multiplayer/host-changed");
+ userJoinedSample = audio.Samples.Get(@"Multiplayer/player-joined");
+ userLeftSample = audio.Samples.Get(@"Multiplayer/player-left");
+ userKickedSample = audio.Samples.Get(@"Multiplayer/player-kicked");
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ Host.BindValueChanged(hostChanged);
+ }
+
+ protected override void UserJoined(MultiplayerRoomUser user)
+ {
+ base.UserJoined(user);
+
+ userJoinedSample?.Play();
+ }
+
+ protected override void UserLeft(MultiplayerRoomUser user)
+ {
+ base.UserLeft(user);
+
+ userLeftSample?.Play();
+ }
+
+ protected override void UserKicked(MultiplayerRoomUser user)
+ {
+ base.UserKicked(user);
+
+ userKickedSample?.Play();
+ }
+
+ private void hostChanged(ValueChangedEvent value)
+ {
+ // only play sound when the host changes from an already-existing host.
+ if (value.OldValue == null) return;
+
+ hostChangedSample?.Play();
+ }
+ }
+}
diff --git a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs
index d36c556fac..fe40a4bfe6 100644
--- a/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs
+++ b/osu.Game/Screens/OnlinePlay/Multiplayer/Participants/ParticipantsList.cs
@@ -4,12 +4,10 @@
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio;
-using osu.Framework.Audio.Sample;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Cursor;
-using osu.Game.Online.Multiplayer;
using osuTK;
namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
@@ -18,10 +16,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
{
private FillFlowContainer panels;
- private Sample userJoinSample;
- private Sample userLeftSample;
- private Sample userKickedSample;
-
[BackgroundDependencyLoader]
private void load(AudioManager audio)
{
@@ -41,31 +35,6 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer.Participants
}
}
};
-
- userJoinSample = audio.Samples.Get(@"Multiplayer/player-joined");
- userLeftSample = audio.Samples.Get(@"Multiplayer/player-left");
- userKickedSample = audio.Samples.Get(@"Multiplayer/player-kicked");
- }
-
- protected override void UserJoined(MultiplayerRoomUser user)
- {
- base.UserJoined(user);
-
- userJoinSample?.Play();
- }
-
- protected override void UserLeft(MultiplayerRoomUser user)
- {
- base.UserLeft(user);
-
- userLeftSample?.Play();
- }
-
- protected override void UserKicked(MultiplayerRoomUser user)
- {
- base.UserKicked(user);
-
- userKickedSample?.Play();
}
protected override void OnRoomUpdated()
diff --git a/osu.Game/Screens/OsuScreen.cs b/osu.Game/Screens/OsuScreen.cs
index ccc891d3bf..ed4901e1fa 100644
--- a/osu.Game/Screens/OsuScreen.cs
+++ b/osu.Game/Screens/OsuScreen.cs
@@ -145,7 +145,7 @@ namespace osu.Game.Screens
}
[BackgroundDependencyLoader(true)]
- private void load(OsuGame osu, AudioManager audio)
+ private void load(AudioManager audio)
{
sampleExit = audio.Samples.Get(@"UI/screen-back");
}
diff --git a/osu.Game/Screens/Play/EpilepsyWarning.cs b/osu.Game/Screens/Play/EpilepsyWarning.cs
index 89e25d849f..ccb2870d78 100644
--- a/osu.Game/Screens/Play/EpilepsyWarning.cs
+++ b/osu.Game/Screens/Play/EpilepsyWarning.cs
@@ -2,11 +2,9 @@
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
-using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Containers;
using osu.Game.Screens.Backgrounds;
@@ -39,7 +37,7 @@ namespace osu.Game.Screens.Play
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours, IBindable beatmap)
+ private void load(OsuColour colours)
{
Children = new Drawable[]
{
diff --git a/osu.Game/Screens/Play/FailAnimation.cs b/osu.Game/Screens/Play/FailAnimation.cs
index cfbfdc9966..17a3e5eb71 100644
--- a/osu.Game/Screens/Play/FailAnimation.cs
+++ b/osu.Game/Screens/Play/FailAnimation.cs
@@ -36,6 +36,7 @@ namespace osu.Game.Screens.Play
private readonly DrawableRuleset drawableRuleset;
private readonly BindableDouble trackFreq = new BindableDouble(1);
+ private readonly BindableDouble volumeAdjustment = new BindableDouble(0.5);
private Container filters;
@@ -125,6 +126,7 @@ namespace osu.Game.Screens.Play
failSample.Play();
track.AddAdjustment(AdjustableProperty.Frequency, trackFreq);
+ track.AddAdjustment(AdjustableProperty.Volume, volumeAdjustment);
applyToPlayfield(drawableRuleset.Playfield);
drawableRuleset.Playfield.HitObjectContainer.FadeOut(duration / 2);
@@ -154,6 +156,8 @@ namespace osu.Game.Screens.Play
if (resetTrackFrequency)
track?.RemoveAdjustment(AdjustableProperty.Frequency, trackFreq);
+ track?.RemoveAdjustment(AdjustableProperty.Volume, volumeAdjustment);
+
if (filters.Parent == null)
return;
diff --git a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs
index 8e0a38aa1f..5a7ef786d3 100644
--- a/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs
+++ b/osu.Game/Screens/Play/HUD/HoldForMenuButton.cs
@@ -116,7 +116,7 @@ namespace osu.Game.Screens.Play.HUD
public Action HoverLost;
[BackgroundDependencyLoader]
- private void load(OsuColour colours, Framework.Game game)
+ private void load(OsuColour colours)
{
Size = new Vector2(60);
diff --git a/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs b/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs
index 235f0f01fd..a71b661965 100644
--- a/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs
+++ b/osu.Game/Screens/Play/HUD/UnstableRateCounter.cs
@@ -8,7 +8,6 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Localisation;
-using osu.Game.Beatmaps;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
@@ -37,7 +36,7 @@ namespace osu.Game.Screens.Play.HUD
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours, BeatmapDifficultyCache difficultyCache)
+ private void load(OsuColour colours)
{
Colour = colours.BlueLighter;
valid.BindValueChanged(e =>
diff --git a/osu.Game/Screens/Play/PlayerSettings/InputSettings.cs b/osu.Game/Screens/Play/PlayerSettings/InputSettings.cs
index 725a6e86bf..b1063966da 100644
--- a/osu.Game/Screens/Play/PlayerSettings/InputSettings.cs
+++ b/osu.Game/Screens/Play/PlayerSettings/InputSettings.cs
@@ -4,6 +4,7 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Configuration;
+using osu.Game.Localisation;
namespace osu.Game.Screens.Play.PlayerSettings
{
@@ -18,7 +19,7 @@ namespace osu.Game.Screens.Play.PlayerSettings
{
mouseButtonsCheckbox = new PlayerCheckbox
{
- LabelText = "Disable mouse buttons"
+ LabelText = MouseSettingsStrings.DisableMouseButtons
}
};
}
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
index 635be60549..e50520e0ca 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
@@ -10,7 +10,6 @@ using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Platform;
using osu.Framework.Utils;
using osu.Game.Audio;
using osu.Game.Graphics;
@@ -104,7 +103,7 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
}
[BackgroundDependencyLoader]
- private void load(GameHost host)
+ private void load()
{
InternalChildren = new Drawable[]
{
diff --git a/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs b/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs
index df8c68a0dd..0fd39db97c 100644
--- a/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs
+++ b/osu.Game/Screens/Select/BeatmapDetailAreaTabControl.cs
@@ -9,7 +9,6 @@ using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.UserInterface;
using osu.Framework.Graphics.Shapes;
@@ -83,7 +82,7 @@ namespace osu.Game.Screens.Select
}
[BackgroundDependencyLoader]
- private void load(OsuColour colour, OsuConfigManager config)
+ private void load(OsuColour colour)
{
modsCheckbox.AccentColour = tabs.AccentColour = colour.YellowLight;
}
diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs
index e677e2c01b..e64011941f 100644
--- a/osu.Game/Skinning/LegacySkin.cs
+++ b/osu.Game/Skinning/LegacySkin.cs
@@ -474,13 +474,18 @@ namespace osu.Game.Skinning
{
foreach (string name in getFallbackNames(componentName))
{
+ // some component names (especially user-controlled ones, like `HitX` in mania)
+ // may contain `@2x` scale specifications.
+ // stable happens to check for that and strip them, so do the same to match stable behaviour.
+ string lookupName = name.Replace(@"@2x", string.Empty);
+
float ratio = 2;
- var texture = Textures?.Get($"{name}@2x", wrapModeS, wrapModeT);
+ var texture = Textures?.Get(@$"{lookupName}@2x", wrapModeS, wrapModeT);
if (texture == null)
{
ratio = 1;
- texture = Textures?.Get(name, wrapModeS, wrapModeT);
+ texture = Textures?.Get(lookupName, wrapModeS, wrapModeT);
}
if (texture == null)
diff --git a/osu.Game/Skinning/SkinModelManager.cs b/osu.Game/Skinning/SkinModelManager.cs
index 822cb8efa0..964d99a2e5 100644
--- a/osu.Game/Skinning/SkinModelManager.cs
+++ b/osu.Game/Skinning/SkinModelManager.cs
@@ -210,13 +210,13 @@ namespace osu.Game.Skinning
{
using (var realm = ContextFactory.CreateContext())
{
- var skinsWithoutHashes = realm.All().Where(i => string.IsNullOrEmpty(i.Hash)).ToArray();
+ var skinsWithoutHashes = realm.All().Where(i => !i.Protected && string.IsNullOrEmpty(i.Hash)).ToArray();
foreach (SkinInfo skin in skinsWithoutHashes)
{
try
{
- Update(skin);
+ realm.Write(r => skin.Hash = ComputeHash(skin));
}
catch (Exception e)
{
diff --git a/osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs b/osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs
index 520f2c4585..5a0a7e71d4 100644
--- a/osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs
+++ b/osu.Game/Tests/Visual/OnlinePlay/TestRoomRequestsHandler.cs
@@ -70,6 +70,29 @@ namespace osu.Game.Tests.Visual.OnlinePlay
return true;
}
+ case GetRoomLeaderboardRequest roomLeaderboardRequest:
+ roomLeaderboardRequest.TriggerSuccess(new APILeaderboard
+ {
+ Leaderboard = new List
+ {
+ new APIUserScoreAggregate
+ {
+ TotalScore = 1000000,
+ TotalAttempts = 5,
+ CompletedBeatmaps = 2,
+ User = new APIUser { Username = "best user" }
+ },
+ new APIUserScoreAggregate
+ {
+ TotalScore = 50,
+ TotalAttempts = 1,
+ CompletedBeatmaps = 1,
+ User = new APIUser { Username = "worst user" }
+ }
+ }
+ });
+ return true;
+
case PartRoomRequest partRoomRequest:
partRoomRequest.TriggerSuccess();
return true;
diff --git a/osu.Game/Tests/Visual/SkinnableTestScene.cs b/osu.Game/Tests/Visual/SkinnableTestScene.cs
index 22aac79056..a080f47d66 100644
--- a/osu.Game/Tests/Visual/SkinnableTestScene.cs
+++ b/osu.Game/Tests/Visual/SkinnableTestScene.cs
@@ -41,7 +41,7 @@ namespace osu.Game.Tests.Visual
}
[BackgroundDependencyLoader]
- private void load(AudioManager audio, SkinManager skinManager)
+ private void load()
{
var dllStore = new DllResourceStore(DynamicCompilationOriginal.GetType().Assembly);
diff --git a/osu.Game/Users/Drawables/ClickableAvatar.cs b/osu.Game/Users/Drawables/ClickableAvatar.cs
index 2825c41ef6..e3cfaf1d14 100644
--- a/osu.Game/Users/Drawables/ClickableAvatar.cs
+++ b/osu.Game/Users/Drawables/ClickableAvatar.cs
@@ -4,7 +4,6 @@
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Events;
using osu.Framework.Localisation;
using osu.Game.Graphics.Containers;
@@ -58,7 +57,7 @@ namespace osu.Game.Users.Drawables
}
[BackgroundDependencyLoader]
- private void load(LargeTextureStore textures)
+ private void load()
{
LoadComponentAsync(new DrawableAvatar(user), clickableArea.Add);
}
diff --git a/osu.Game/Utils/SentryLogger.cs b/osu.Game/Utils/SentryLogger.cs
index 8f12760a6b..dbf04283b6 100644
--- a/osu.Game/Utils/SentryLogger.cs
+++ b/osu.Game/Utils/SentryLogger.cs
@@ -16,6 +16,7 @@ namespace osu.Game.Utils
{
private SentryClient sentry;
private Scope sentryScope;
+ private Exception lastException;
public SentryLogger(OsuGame game)
{
@@ -30,30 +31,27 @@ namespace osu.Game.Utils
sentry = new SentryClient(options);
sentryScope = new Scope(options);
- Exception lastException = null;
+ Logger.NewEntry += processLogEntry;
+ }
- Logger.NewEntry += entry =>
+ private void processLogEntry(LogEntry entry)
+ {
+ if (entry.Level < LogLevel.Verbose) return;
+
+ var exception = entry.Exception;
+
+ if (exception != null)
{
- if (entry.Level < LogLevel.Verbose) return;
+ if (!shouldSubmitException(exception)) return;
- var exception = entry.Exception;
+ // since we let unhandled exceptions go ignored at times, we want to ensure they don't get submitted on subsequent reports.
+ if (lastException != null && lastException.Message == exception.Message && exception.StackTrace.StartsWith(lastException.StackTrace, StringComparison.Ordinal)) return;
- if (exception != null)
- {
- if (!shouldSubmitException(exception))
- return;
-
- // since we let unhandled exceptions go ignored at times, we want to ensure they don't get submitted on subsequent reports.
- if (lastException != null &&
- lastException.Message == exception.Message && exception.StackTrace.StartsWith(lastException.StackTrace, StringComparison.Ordinal))
- return;
-
- lastException = exception;
- sentry.CaptureEvent(new SentryEvent(exception) { Message = entry.Message }, sentryScope);
- }
- else
- sentryScope.AddBreadcrumb(DateTimeOffset.Now, entry.Message, entry.Target.ToString(), "navigation");
- };
+ lastException = exception;
+ sentry.CaptureEvent(new SentryEvent(exception) { Message = entry.Message }, sentryScope);
+ }
+ else
+ sentryScope.AddBreadcrumb(DateTimeOffset.Now, entry.Message, entry.Target.ToString(), "navigation");
}
private bool shouldSubmitException(Exception exception)
@@ -92,15 +90,9 @@ namespace osu.Game.Utils
GC.SuppressFinalize(this);
}
- private bool isDisposed;
-
protected virtual void Dispose(bool isDisposing)
{
- if (isDisposed)
- return;
-
- isDisposed = true;
- sentry?.Dispose();
+ Logger.NewEntry -= processLogEntry;
sentry = null;
sentryScope = null;
}
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index 1430320c87..758575e74a 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -18,9 +18,9 @@
-
+
-
+
@@ -35,10 +35,10 @@
all
runtime; build; native; contentfiles; analyzers; buildtransitive
-
-
-
-
+
+
+
+
diff --git a/osu.iOS.props b/osu.iOS.props
index 3cef888447..5925581e28 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -60,8 +60,8 @@
-
-
+
+
@@ -83,11 +83,11 @@
-
+
-
+
diff --git a/osu.sln.DotSettings b/osu.sln.DotSettings
index 44d75f265c..2ff0f4d30b 100644
--- a/osu.sln.DotSettings
+++ b/osu.sln.DotSettings
@@ -930,14 +930,21 @@ private void load()
True
True
True
+ True
+ True
+ True
True
+ True
+ True
True
True
True
True
+ True
True
True
True
+ True
True
True
True
@@ -949,10 +956,14 @@ private void load()
True
True
True
+ True
True
True
+ True
+ True
True
True
+ True
True
True
True
@@ -967,11 +978,15 @@ private void load()
True
True
True
+ True
+ True
+ True
True
True
True
True
True
+ True
True
True
True
@@ -979,8 +994,10 @@ private void load()
True
True
True
+ True
True
True
True
True
- True
+ True
+ True