diff --git a/.github/workflows/ci.yml b/.github/workflows/ci.yml
index 103e4dbc30..de902df93f 100644
--- a/.github/workflows/ci.yml
+++ b/.github/workflows/ci.yml
@@ -15,17 +15,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
- # FIXME: Tools won't run in .NET 6.0 unless you install 3.1.x LTS side by side.
- # https://itnext.io/how-to-support-multiple-net-sdks-in-github-actions-workflows-b988daa884e
- - name: Install .NET 3.1.x LTS
+ - name: Install .NET 8.0.x
uses: actions/setup-dotnet@v3
with:
- dotnet-version: "3.1.x"
-
- - name: Install .NET 6.0.x
- uses: actions/setup-dotnet@v3
- with:
- dotnet-version: "6.0.x"
+ dotnet-version: "8.0.x"
- name: Restore Tools
run: dotnet tool restore
@@ -79,10 +72,10 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
- - name: Install .NET 6.0.x
+ - name: Install .NET 8.0.x
uses: actions/setup-dotnet@v3
with:
- dotnet-version: "6.0.x"
+ dotnet-version: "8.0.x"
- name: Compile
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
@@ -114,10 +107,10 @@ jobs:
distribution: microsoft
java-version: 11
- - name: Install .NET 6.0.x
+ - name: Install .NET 8.0.x
uses: actions/setup-dotnet@v3
with:
- dotnet-version: "6.0.x"
+ dotnet-version: "8.0.x"
- name: Install .NET workloads
run: dotnet workload install maui-android
@@ -135,13 +128,16 @@ jobs:
- name: Checkout
uses: actions/checkout@v3
- - name: Install .NET 6.0.x
+ - name: Install .NET 8.0.x
uses: actions/setup-dotnet@v3
with:
- dotnet-version: "6.0.x"
+ dotnet-version: "8.0.x"
- name: Install .NET Workloads
run: dotnet workload install maui-ios
+ - name: Select Xcode 15.2
+ run: sudo xcode-select -s /Applications/Xcode_15.2.app/Contents/Developer
+
- name: Build
run: dotnet build -c Debug osu.iOS
diff --git a/.github/workflows/update-web-mod-definitions.yml b/.github/workflows/update-web-mod-definitions.yml
index 32d3d37ffe..5827a6cdbf 100644
--- a/.github/workflows/update-web-mod-definitions.yml
+++ b/.github/workflows/update-web-mod-definitions.yml
@@ -12,10 +12,10 @@ jobs:
name: Update osu-web mod definitions
runs-on: ubuntu-latest
steps:
- - name: Install .NET 6.0.x
+ - name: Install .NET 8.0.x
uses: actions/setup-dotnet@v3
with:
- dotnet-version: "6.0.x"
+ dotnet-version: "8.0.x"
- name: Checkout ppy/osu
uses: actions/checkout@v3
diff --git a/Directory.Build.props b/Directory.Build.props
index b08283f071..2d289d0f22 100644
--- a/Directory.Build.props
+++ b/Directory.Build.props
@@ -1,7 +1,7 @@
- 10.0
+ 12.0
true
enable
diff --git a/README.md b/README.md
index d7e710f392..dc5809d46b 100644
--- a/README.md
+++ b/README.md
@@ -30,8 +30,8 @@ If you are just looking to give the game a whirl, you can grab the latest releas
### Latest release:
-| [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 10.15+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
-| ------------- | ------------- | ------------- | ------------- | ------------- |
+| [Windows 10+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 12+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
+|--------------------------------------------------------------------------------------|--------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------| ------------- | ------------- | ------------- |
You can also generally download a version for your current device from the [osu! site](https://osu.ppy.sh/home/download).
diff --git a/Templates/Rulesets/ruleset-empty/Directory.Build.props b/Templates/Rulesets/ruleset-empty/Directory.Build.props
new file mode 100644
index 0000000000..74d05ff690
--- /dev/null
+++ b/Templates/Rulesets/ruleset-empty/Directory.Build.props
@@ -0,0 +1,10 @@
+
+
+
+ $(MSBuildThisFileDirectory)app.manifest
+
+
+ true
+ $(NoWarn);CS1591
+
+
diff --git a/Templates/Rulesets/ruleset-empty/app.manifest b/Templates/Rulesets/ruleset-empty/app.manifest
new file mode 100644
index 0000000000..1c1e5f540c
--- /dev/null
+++ b/Templates/Rulesets/ruleset-empty/app.manifest
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
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 5babdb47ff..7d43eb2b05 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
@@ -18,7 +18,7 @@
WinExe
- net6.0
+ net8.0
osu.Game.Rulesets.EmptyFreeform.Tests
diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/osu.Game.Rulesets.EmptyFreeform.csproj b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/osu.Game.Rulesets.EmptyFreeform.csproj
index d09e7647e0..89abd5665c 100644
--- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/osu.Game.Rulesets.EmptyFreeform.csproj
+++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform/osu.Game.Rulesets.EmptyFreeform.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
osu.Game.Rulesets.EmptyFreeform
Library
AnyCPU
diff --git a/Templates/Rulesets/ruleset-example/Directory.Build.props b/Templates/Rulesets/ruleset-example/Directory.Build.props
new file mode 100644
index 0000000000..74d05ff690
--- /dev/null
+++ b/Templates/Rulesets/ruleset-example/Directory.Build.props
@@ -0,0 +1,10 @@
+
+
+
+ $(MSBuildThisFileDirectory)app.manifest
+
+
+ true
+ $(NoWarn);CS1591
+
+
diff --git a/Templates/Rulesets/ruleset-example/app.manifest b/Templates/Rulesets/ruleset-example/app.manifest
new file mode 100644
index 0000000000..1c1e5f540c
--- /dev/null
+++ b/Templates/Rulesets/ruleset-example/app.manifest
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
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 5d64ca832a..7dc8a1336b 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
@@ -18,7 +18,7 @@
WinExe
- net6.0
+ net8.0
osu.Game.Rulesets.Pippidon.Tests
diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/osu.Game.Rulesets.Pippidon.csproj b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/osu.Game.Rulesets.Pippidon.csproj
index 9c8867f4ef..165b6b6c6b 100644
--- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/osu.Game.Rulesets.Pippidon.csproj
+++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon/osu.Game.Rulesets.Pippidon.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
osu.Game.Rulesets.Pippidon
Library
AnyCPU
diff --git a/Templates/Rulesets/ruleset-scrolling-empty/Directory.Build.props b/Templates/Rulesets/ruleset-scrolling-empty/Directory.Build.props
new file mode 100644
index 0000000000..74d05ff690
--- /dev/null
+++ b/Templates/Rulesets/ruleset-scrolling-empty/Directory.Build.props
@@ -0,0 +1,10 @@
+
+
+
+ $(MSBuildThisFileDirectory)app.manifest
+
+
+ true
+ $(NoWarn);CS1591
+
+
diff --git a/Templates/Rulesets/ruleset-scrolling-empty/app.manifest b/Templates/Rulesets/ruleset-scrolling-empty/app.manifest
new file mode 100644
index 0000000000..1c1e5f540c
--- /dev/null
+++ b/Templates/Rulesets/ruleset-scrolling-empty/app.manifest
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
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 6796a8962b..9c4c8217f0 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
@@ -18,7 +18,7 @@
WinExe
- net6.0
+ net8.0
osu.Game.Rulesets.EmptyScrolling.Tests
diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/osu.Game.Rulesets.EmptyScrolling.csproj b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/osu.Game.Rulesets.EmptyScrolling.csproj
index 5bf3884f53..6d9565a6f2 100644
--- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/osu.Game.Rulesets.EmptyScrolling.csproj
+++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling/osu.Game.Rulesets.EmptyScrolling.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
osu.Game.Rulesets.EmptyScrolling
Library
AnyCPU
diff --git a/Templates/Rulesets/ruleset-scrolling-example/Directory.Build.props b/Templates/Rulesets/ruleset-scrolling-example/Directory.Build.props
new file mode 100644
index 0000000000..74d05ff690
--- /dev/null
+++ b/Templates/Rulesets/ruleset-scrolling-example/Directory.Build.props
@@ -0,0 +1,10 @@
+
+
+
+ $(MSBuildThisFileDirectory)app.manifest
+
+
+ true
+ $(NoWarn);CS1591
+
+
diff --git a/Templates/Rulesets/ruleset-scrolling-example/app.manifest b/Templates/Rulesets/ruleset-scrolling-example/app.manifest
new file mode 100644
index 0000000000..1c1e5f540c
--- /dev/null
+++ b/Templates/Rulesets/ruleset-scrolling-example/app.manifest
@@ -0,0 +1,46 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+ true
+
+
+
+
+
+
+
+
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 5d64ca832a..7dc8a1336b 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
@@ -18,7 +18,7 @@
WinExe
- net6.0
+ net8.0
osu.Game.Rulesets.Pippidon.Tests
diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/osu.Game.Rulesets.Pippidon.csproj b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/osu.Game.Rulesets.Pippidon.csproj
index 9c8867f4ef..165b6b6c6b 100644
--- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/osu.Game.Rulesets.Pippidon.csproj
+++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon/osu.Game.Rulesets.Pippidon.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
osu.Game.Rulesets.Pippidon
Library
AnyCPU
diff --git a/global.json b/global.json
index 5dcd5f425a..789bff3bd0 100644
--- a/global.json
+++ b/global.json
@@ -1,7 +1,7 @@
{
"sdk": {
- "version": "6.0.100",
- "rollForward": "latestFeature"
+ "version": "8.0.100",
+ "rollForward": "latestFeature",
+ "allowPrerelease": false
}
-}
-
+}
\ No newline at end of file
diff --git a/osu.Android.props b/osu.Android.props
index d944e2ce8e..d7f29beeb3 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -10,7 +10,7 @@
true
-
+
- false
0.0.0
1
$(Version)
@@ -19,4 +16,7 @@
+
+
+
diff --git a/osu.Desktop/NVAPI.cs b/osu.Desktop/NVAPI.cs
index bb3a59cc7f..78a814c585 100644
--- a/osu.Desktop/NVAPI.cs
+++ b/osu.Desktop/NVAPI.cs
@@ -138,7 +138,7 @@ namespace osu.Desktop
return false;
// Make sure that this is a laptop.
- var gpus = new IntPtr[64];
+ IntPtr[] gpus = new IntPtr[64];
if (checkError(EnumPhysicalGPUs(gpus, out int gpuCount)))
return false;
@@ -456,7 +456,7 @@ namespace osu.Desktop
[MarshalAs(UnmanagedType.ByValTStr, SizeConst = NVAPI.UNICODE_STRING_MAX)]
public string ProfileName;
- [MarshalAs(UnmanagedType.ByValArray)]
+ [MarshalAs(UnmanagedType.ByValArray, SizeConst = 32)]
public uint[] GPUSupport;
public uint IsPredefined;
diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj
index d6a11fa924..cf2ec6e681 100644
--- a/osu.Desktop/osu.Desktop.csproj
+++ b/osu.Desktop/osu.Desktop.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
WinExe
true
A free-to-win rhythm game. Rhythm is just a *click* away!
diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
index 47c93fbd02..64da5412a8 100644
--- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
+++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
@@ -1,7 +1,7 @@
- net6.0
+ net8.0
Exe
false
diff --git a/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml b/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml
index 52b34959b9..b6ab91ed5c 100644
--- a/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml
+++ b/osu.Game.Rulesets.Catch.Tests.Android/AndroidManifest.xml
@@ -1,6 +1,6 @@
-
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj b/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj
index 4ee3219442..4b2e54be67 100644
--- a/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj
+++ b/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj
@@ -1,7 +1,7 @@
- net6.0-android
+ net8.0-android
Exe
osu.Game.Rulesets.Catch.Tests
osu.Game.Rulesets.Catch.Tests.Android
@@ -21,4 +21,4 @@
-
\ No newline at end of file
+
diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj b/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj
index acf12bb0ac..9c262a752a 100644
--- a/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj
+++ b/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj
@@ -1,7 +1,7 @@
Exe
- net6.0-ios
+ net8.0-ios
13.4
osu.Game.Rulesets.Catch.Tests
osu.Game.Rulesets.Catch.Tests.iOS
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 0a77845343..619081c754 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
@@ -7,7 +7,7 @@
WinExe
- net6.0
+ net8.0
diff --git a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
index ecce7c1b3f..a5138ffb39 100644
--- a/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
+++ b/osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
Library
true
catch the fruit. to the beat.
diff --git a/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml b/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml
index f5a49210ea..df4930419c 100644
--- a/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml
+++ b/osu.Game.Rulesets.Mania.Tests.Android/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj b/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj
index 25335754d2..2866508a02 100644
--- a/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj
+++ b/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj
@@ -1,7 +1,7 @@
- net6.0-android
+ net8.0-android
Exe
osu.Game.Rulesets.Mania.Tests
osu.Game.Rulesets.Mania.Tests.Android
@@ -21,4 +21,4 @@
-
\ No newline at end of file
+
diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj b/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj
index 51e07dd6c1..d51e541e95 100644
--- a/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj
+++ b/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj
@@ -1,7 +1,7 @@
Exe
- net6.0-ios
+ net8.0-ios
13.4
osu.Game.Rulesets.Mania.Tests
osu.Game.Rulesets.Mania.Tests.iOS
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 877b9c3ea4..eee06acdb8 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
@@ -7,7 +7,7 @@
WinExe
- net6.0
+ net8.0
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs
index 050b302bd8..88d6a19822 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs
@@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public abstract int KeyCount { get; }
public override ModType Type => ModType.Conversion;
public override double ScoreMultiplier => 1; // TODO: Implement the mania key mod score multiplier
+ public override bool Ranked => UsesDefaultConfiguration;
public void ApplyToBeatmapConverter(IBeatmapConverter beatmapConverter)
{
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs
index d9de06a811..189c4b3a5f 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs
@@ -8,5 +8,6 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModHardRock : ModHardRock
{
public override double ScoreMultiplier => 1;
+ public override bool Ranked => false;
}
}
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs
index 31f52610e9..7dd0c499da 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs
@@ -11,5 +11,6 @@ namespace osu.Game.Rulesets.Mania.Mods
public override string Name => "One Key";
public override string Acronym => "1K";
public override LocalisableString Description => @"Play with one key.";
+ public override bool Ranked => false;
}
}
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey10.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey10.cs
index 67e65b887a..a6c57d4597 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey10.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey10.cs
@@ -11,5 +11,6 @@ namespace osu.Game.Rulesets.Mania.Mods
public override string Name => "Ten Keys";
public override string Acronym => "10K";
public override LocalisableString Description => @"Play with ten keys.";
+ public override bool Ranked => false;
}
}
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs
index 0f8148d252..0d04395a52 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs
@@ -11,5 +11,6 @@ namespace osu.Game.Rulesets.Mania.Mods
public override string Name => "Two Keys";
public override string Acronym => "2K";
public override LocalisableString Description => @"Play with two keys.";
+ public override bool Ranked => false;
}
}
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs
index 0f8af7940c..c83b0979ee 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs
@@ -11,5 +11,6 @@ namespace osu.Game.Rulesets.Mania.Mods
public override string Name => "Three Keys";
public override string Acronym => "3K";
public override LocalisableString Description => @"Play with three keys.";
+ public override bool Ranked => false;
}
}
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs
index f9690b4298..cc7e270dda 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs
@@ -14,6 +14,7 @@ namespace osu.Game.Rulesets.Mania.Mods
public class ManiaModMirror : ModMirror, IApplicableToBeatmap
{
public override LocalisableString Description => "Notes are flipped horizontally.";
+ public override bool Ranked => UsesDefaultConfiguration;
public void ApplyToBeatmap(IBeatmap beatmap)
{
diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs
index bea536e4af..decf670c5d 100644
--- a/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs
+++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs
@@ -1,16 +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 disable
-
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
+using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Input;
+using osu.Framework.Threading;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
using osu.Game.Input.Handlers;
@@ -59,10 +59,9 @@ namespace osu.Game.Rulesets.Mania.UI
// Stores the current speed adjustment active in gameplay.
private readonly Track speedAdjustmentTrack = new TrackVirtual(0);
- [Resolved]
- private ISkinSource skin { get; set; }
+ private ISkinSource currentSkin = null!;
- public DrawableManiaRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList mods = null)
+ public DrawableManiaRuleset(Ruleset ruleset, IBeatmap beatmap, IReadOnlyList? mods = null)
: base(ruleset, beatmap, mods)
{
BarLines = new BarLineGenerator(Beatmap).BarLines;
@@ -72,8 +71,12 @@ namespace osu.Game.Rulesets.Mania.UI
}
[BackgroundDependencyLoader]
- private void load()
+ private void load(ISkinSource source)
{
+ currentSkin = source;
+ currentSkin.SourceChanged += onSkinChange;
+ skinChanged();
+
foreach (var mod in Mods.OfType())
mod.ApplyToTrack(speedAdjustmentTrack);
@@ -109,12 +112,28 @@ namespace osu.Game.Rulesets.Mania.UI
updateTimeRange();
}
+ private ScheduledDelegate? pendingSkinChange;
+ private float hitPosition;
+
+ private void onSkinChange()
+ {
+ // schedule required to avoid calls after disposed.
+ // note that this has the side-effect of components only performing a skin change when they are alive.
+ pendingSkinChange?.Cancel();
+ pendingSkinChange = Scheduler.Add(skinChanged);
+ }
+
+ private void skinChanged()
+ {
+ hitPosition = currentSkin.GetConfig(
+ new ManiaSkinConfigurationLookup(LegacyManiaSkinConfigurationLookups.HitPosition))?.Value
+ ?? Stage.HIT_TARGET_POSITION;
+
+ pendingSkinChange = null;
+ }
+
private void updateTimeRange()
{
- float hitPosition = skin.GetConfig(
- new ManiaSkinConfigurationLookup(LegacyManiaSkinConfigurationLookups.HitPosition))?.Value
- ?? Stage.HIT_TARGET_POSITION;
-
const float length_to_default_hit_position = 768 - LegacyManiaSkinConfiguration.DEFAULT_HIT_POSITION;
float lengthToHitPosition = 768 - hitPosition;
@@ -139,10 +158,18 @@ namespace osu.Game.Rulesets.Mania.UI
protected override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant);
- public override DrawableHitObject CreateDrawableRepresentation(ManiaHitObject h) => null;
+ public override DrawableHitObject? CreateDrawableRepresentation(ManiaHitObject h) => null;
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new ManiaFramedReplayInputHandler(replay);
protected override ReplayRecorder CreateReplayRecorder(Score score) => new ManiaReplayRecorder(score);
+
+ protected override void Dispose(bool isDisposing)
+ {
+ base.Dispose(isDisposing);
+
+ if (currentSkin.IsNotNull())
+ currentSkin.SourceChanged -= onSkinChange;
+ }
}
}
diff --git a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
index 72f172188e..3bca938450 100644
--- a/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
+++ b/osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
Library
true
smash the keys. to the beat.
diff --git a/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml b/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml
index ed4725dd94..d0c3484cfd 100644
--- a/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml
+++ b/osu.Game.Rulesets.Osu.Tests.Android/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj b/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj
index e8a46a9828..b79de6d40b 100644
--- a/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj
+++ b/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj
@@ -1,7 +1,7 @@
- net6.0-android
+ net8.0-android
Exe
osu.Game.Rulesets.Osu.Tests
osu.Game.Rulesets.Osu.Tests.Android
@@ -24,4 +24,4 @@
-
\ No newline at end of file
+
diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj b/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj
index 7d50deb8ba..cc0233d7fd 100644
--- a/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj
+++ b/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj
@@ -1,7 +1,7 @@
Exe
- net6.0-ios
+ net8.0-ios
13.4
Exe
osu.Game.Rulesets.Osu.Tests
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 9c248abd66..ea54c8d313 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
@@ -8,7 +8,7 @@
WinExe
- net6.0
+ net8.0
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs
index f691731afe..df9544b71e 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModSpunOut.cs
@@ -22,6 +22,7 @@ namespace osu.Game.Rulesets.Osu.Mods
public override LocalisableString Description => @"Spinners will be automatically completed.";
public override double ScoreMultiplier => 0.9;
public override Type[] IncompatibleMods => new[] { typeof(ModAutoplay), typeof(OsuModAutopilot), typeof(OsuModTargetPractice) };
+ public override bool Ranked => UsesDefaultConfiguration;
public void ApplyToDrawableHitObject(DrawableHitObject hitObject)
{
diff --git a/osu.Game.Rulesets.Osu/Mods/OsuModTouchDevice.cs b/osu.Game.Rulesets.Osu/Mods/OsuModTouchDevice.cs
index f1468d414e..917685cdad 100644
--- a/osu.Game.Rulesets.Osu/Mods/OsuModTouchDevice.cs
+++ b/osu.Game.Rulesets.Osu/Mods/OsuModTouchDevice.cs
@@ -10,5 +10,6 @@ namespace osu.Game.Rulesets.Osu.Mods
public class OsuModTouchDevice : ModTouchDevice
{
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(OsuModAutopilot) }).ToArray();
+ public override bool Ranked => UsesDefaultConfiguration;
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs
index ceee513412..ee2490439f 100644
--- a/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/SliderTailCircle.cs
@@ -30,7 +30,6 @@ namespace osu.Game.Rulesets.Osu.Objects
public class TailJudgement : SliderEndJudgement
{
public override HitResult MaxResult => HitResult.SliderTailHit;
- public override HitResult MinResult => HitResult.IgnoreMiss;
}
}
}
diff --git a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
index 75656e2976..518ab362ca 100644
--- a/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
+++ b/osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
Library
true
click the circles. to the beat.
diff --git a/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml b/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml
index cc88d3080a..0ae9ee43ad 100644
--- a/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml
+++ b/osu.Game.Rulesets.Taiko.Tests.Android/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj b/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj
index a639326ebd..ee973e8544 100644
--- a/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj
+++ b/osu.Game.Rulesets.Taiko.Tests.Android/osu.Game.Rulesets.Taiko.Tests.Android.csproj
@@ -1,7 +1,7 @@
- net6.0-android
+ net8.0-android
Exe
osu.Game.Rulesets.Taiko.Tests
osu.Game.Rulesets.Taiko.Tests.Android
@@ -21,4 +21,4 @@
-
\ No newline at end of file
+
diff --git a/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj b/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj
index e648a11299..ee2d4d703e 100644
--- a/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj
+++ b/osu.Game.Rulesets.Taiko.Tests.iOS/osu.Game.Rulesets.Taiko.Tests.iOS.csproj
@@ -1,7 +1,7 @@
Exe
- net6.0-ios
+ net8.0-ios
13.4
osu.Game.Rulesets.Taiko.Tests
osu.Game.Rulesets.Taiko.Tests.iOS
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 4eb6b0ab3d..26afd42445 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
@@ -7,7 +7,7 @@
WinExe
- net6.0
+ net8.0
diff --git a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj
index f0e1cb8e8f..cacba55c2a 100644
--- a/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj
+++ b/osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
Library
true
bash the drum. to the beat.
diff --git a/osu.Game.Tests.Android/AndroidManifest.xml b/osu.Game.Tests.Android/AndroidManifest.xml
index 6f91fb928c..71793af977 100644
--- a/osu.Game.Tests.Android/AndroidManifest.xml
+++ b/osu.Game.Tests.Android/AndroidManifest.xml
@@ -1,5 +1,5 @@
-
+
\ No newline at end of file
diff --git a/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj b/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj
index b745d91980..889f0a3583 100644
--- a/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj
+++ b/osu.Game.Tests.Android/osu.Game.Tests.Android.csproj
@@ -1,7 +1,7 @@
- net6.0-android
+ net8.0-android
Exe
osu.Game.Tests
osu.Game.Tests.Android
diff --git a/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj b/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj
index 79771fcd50..e4b9d2ba94 100644
--- a/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj
+++ b/osu.Game.Tests.iOS/osu.Game.Tests.iOS.csproj
@@ -1,7 +1,7 @@
Exe
- net6.0-ios
+ net8.0-ios
13.4
osu.Game.Tests
osu.Game.Tests.iOS
diff --git a/osu.Game.Tests/NonVisual/TaskChainTest.cs b/osu.Game.Tests/NonVisual/TaskChainTest.cs
index ad1a3fd63f..2ac89efb69 100644
--- a/osu.Game.Tests/NonVisual/TaskChainTest.cs
+++ b/osu.Game.Tests/NonVisual/TaskChainTest.cs
@@ -58,7 +58,7 @@ namespace osu.Game.Tests.NonVisual
var task3 = addTask();
// Cancel task2, allow task3 to complete.
- task2.cancellation.Cancel();
+ await task2.cancellation.CancelAsync();
task2.mutex.Set();
task3.mutex.Set();
diff --git a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs
index 73465fae08..a3f91fffba 100644
--- a/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs
+++ b/osu.Game.Tests/Rulesets/Scoring/ScoreProcessorTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Collections.Generic;
using System.Linq;
@@ -31,8 +29,8 @@ namespace osu.Game.Tests.Rulesets.Scoring
{
public partial class ScoreProcessorTest
{
- private ScoreProcessor scoreProcessor;
- private IBeatmap beatmap;
+ private ScoreProcessor scoreProcessor = null!;
+ private IBeatmap beatmap = null!;
[SetUp]
public void SetUp()
@@ -86,7 +84,7 @@ namespace osu.Game.Tests.Rulesets.Scoring
[TestCase(ScoringMode.Standardised, HitResult.SmallTickHit, HitResult.SmallTickHit, 493_652)]
[TestCase(ScoringMode.Standardised, HitResult.LargeTickMiss, HitResult.LargeTickHit, 0)]
[TestCase(ScoringMode.Standardised, HitResult.LargeTickHit, HitResult.LargeTickHit, 326_963)]
- [TestCase(ScoringMode.Standardised, HitResult.SliderTailHit, HitResult.SliderTailHit, 326_963)]
+ [TestCase(ScoringMode.Standardised, HitResult.SliderTailHit, HitResult.SliderTailHit, 371_627)]
[TestCase(ScoringMode.Standardised, HitResult.SmallBonus, HitResult.SmallBonus, 1_000_030)]
[TestCase(ScoringMode.Standardised, HitResult.LargeBonus, HitResult.LargeBonus, 1_000_150)]
[TestCase(ScoringMode.Classic, HitResult.Miss, HitResult.Great, 0)]
@@ -99,7 +97,7 @@ namespace osu.Game.Tests.Rulesets.Scoring
[TestCase(ScoringMode.Classic, HitResult.SmallTickHit, HitResult.SmallTickHit, 49_365)]
[TestCase(ScoringMode.Classic, HitResult.LargeTickMiss, HitResult.LargeTickHit, 0)]
[TestCase(ScoringMode.Classic, HitResult.LargeTickHit, HitResult.LargeTickHit, 32_696)]
- [TestCase(ScoringMode.Classic, HitResult.SliderTailHit, HitResult.SliderTailHit, 32_696)]
+ [TestCase(ScoringMode.Classic, HitResult.SliderTailHit, HitResult.SliderTailHit, 37_163)]
[TestCase(ScoringMode.Classic, HitResult.SmallBonus, HitResult.SmallBonus, 100_003)]
[TestCase(ScoringMode.Classic, HitResult.LargeBonus, HitResult.LargeBonus, 100_015)]
public void TestFourVariousResultsOneMiss(ScoringMode scoringMode, HitResult hitResult, HitResult maxResult, int expectedScore)
@@ -171,7 +169,7 @@ namespace osu.Game.Tests.Rulesets.Scoring
[TestCase(HitResult.Perfect, HitResult.Miss)]
[TestCase(HitResult.SmallTickHit, HitResult.SmallTickMiss)]
[TestCase(HitResult.LargeTickHit, HitResult.LargeTickMiss)]
- [TestCase(HitResult.SliderTailHit, HitResult.LargeTickMiss)]
+ [TestCase(HitResult.SliderTailHit, HitResult.IgnoreMiss)]
[TestCase(HitResult.SmallBonus, HitResult.IgnoreMiss)]
[TestCase(HitResult.LargeBonus, HitResult.IgnoreMiss)]
public void TestMinResults(HitResult hitResult, HitResult expectedMinResult)
@@ -476,7 +474,7 @@ namespace osu.Game.Tests.Rulesets.Scoring
public override IEnumerable GetModsFor(ModType type) => throw new NotImplementedException();
- public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList mods = null) => throw new NotImplementedException();
+ public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList? mods = null) => throw new NotImplementedException();
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => throw new NotImplementedException();
diff --git a/osu.Game.Tests/Visual/Online/TestSceneDashboardOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneDashboardOverlay.cs
index 9407941da6..b6a300322f 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneDashboardOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneDashboardOverlay.cs
@@ -2,14 +2,15 @@
// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
+using osu.Framework.Allocation;
+using osu.Game.Online.API;
+using osu.Game.Online.API.Requests.Responses;
using osu.Game.Overlays;
namespace osu.Game.Tests.Visual.Online
{
public partial class TestSceneDashboardOverlay : OsuTestScene
{
- protected override bool UseOnlineAPI => true;
-
private readonly DashboardOverlay overlay;
public TestSceneDashboardOverlay()
@@ -17,6 +18,30 @@ namespace osu.Game.Tests.Visual.Online
Add(overlay = new DashboardOverlay());
}
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ int supportLevel = 0;
+
+ for (int i = 0; i < 1000; i++)
+ {
+ supportLevel++;
+
+ if (supportLevel > 3)
+ supportLevel = 0;
+
+ ((DummyAPIAccess)API).Friends.Add(new APIUser
+ {
+ Username = @"peppy",
+ Id = 2,
+ Colour = "99EB47",
+ CoverUrl = @"https://osu.ppy.sh/images/headers/profile-covers/c3.jpg",
+ IsSupporter = supportLevel > 0,
+ SupportLevel = supportLevel
+ });
+ }
+ }
+
[Test]
public void TestShow()
{
diff --git a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs
index 685a685896..cf4bec54ff 100644
--- a/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs
+++ b/osu.Game.Tests/Visual/Ranking/TestSceneResultsScreen.cs
@@ -26,8 +26,10 @@ using osu.Game.Scoring;
using osu.Game.Screens;
using osu.Game.Screens.Play;
using osu.Game.Screens.Ranking;
+using osu.Game.Screens.Ranking.Expanded.Accuracy;
using osu.Game.Screens.Ranking.Expanded.Statistics;
using osu.Game.Screens.Ranking.Statistics;
+using osu.Game.Skinning;
using osu.Game.Tests.Resources;
using osuTK;
using osuTK.Input;
@@ -44,6 +46,9 @@ namespace osu.Game.Tests.Visual.Ranking
[Resolved]
private RealmAccess realm { get; set; }
+ [Resolved]
+ private SkinManager skins { get; set; }
+
protected override void LoadComplete()
{
base.LoadComplete();
@@ -57,8 +62,17 @@ namespace osu.Game.Tests.Visual.Ranking
if (beatmapInfo != null)
Beatmap.Value = beatmaps.GetWorkingBeatmap(beatmapInfo);
});
+
+ AddToggleStep("toggle legacy classic skin", v =>
+ {
+ if (skins != null)
+ skins.CurrentSkinInfo.Value = v ? skins.DefaultClassicSkin.SkinInfo : skins.CurrentSkinInfo.Default;
+ });
}
+ [SetUp]
+ public void SetUp() => Schedule(() => skins.CurrentSkinInfo.SetDefault());
+
[Test]
public void TestScaling()
{
@@ -132,6 +146,46 @@ namespace osu.Game.Tests.Visual.Ranking
AddAssert("retry overlay present", () => screen.RetryOverlay != null);
}
+ [Test]
+ public void TestResultsWithFailingRank()
+ {
+ TestResultsScreen screen = null;
+
+ loadResultsScreen(() =>
+ {
+ var score = TestResources.CreateTestScoreInfo();
+
+ score.OnlineID = onlineScoreID++;
+ score.HitEvents = TestSceneStatisticsPanel.CreatePositionDistributedHitEvents();
+ score.Rank = ScoreRank.F;
+ return screen = createResultsScreen(score);
+ });
+ AddUntilStep("wait for loaded", () => screen.IsLoaded);
+ AddAssert("retry overlay present", () => screen.RetryOverlay != null);
+ AddAssert("no badges displayed", () => this.ChildrenOfType().All(b => !b.IsPresent));
+ }
+
+ [Test]
+ public void TestResultsWithFailingRankOnLegacySkin()
+ {
+ TestResultsScreen screen = null;
+
+ AddStep("set legacy skin", () => skins.CurrentSkinInfo.Value = skins.DefaultClassicSkin.SkinInfo);
+
+ loadResultsScreen(() =>
+ {
+ var score = TestResources.CreateTestScoreInfo();
+
+ score.OnlineID = onlineScoreID++;
+ score.HitEvents = TestSceneStatisticsPanel.CreatePositionDistributedHitEvents();
+ score.Rank = ScoreRank.F;
+ return screen = createResultsScreen(score);
+ });
+ AddUntilStep("wait for loaded", () => screen.IsLoaded);
+ AddAssert("retry overlay present", () => screen.RetryOverlay != null);
+ AddAssert("no badges displayed", () => this.ChildrenOfType().All(b => !b.IsPresent));
+ }
+
[Test]
public void TestShowHideStatisticsViaOutsideClick()
{
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs
index a95bb2c9e3..b79ce6c75f 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneFooterButtonMods.cs
@@ -5,6 +5,7 @@ using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
+using osu.Framework.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Mods;
@@ -67,6 +68,15 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert(@"Check empty multiplier", () => assertModsMultiplier(Array.Empty()));
}
+ [Test]
+ public void TestUnrankedBadge()
+ {
+ AddStep(@"Add unranked mod", () => changeMods(new[] { new OsuModDeflate() }));
+ AddAssert("Unranked badge shown", () => footerButtonMods.UnrankedBadge.Alpha == 1);
+ AddStep(@"Clear selected mod", () => changeMods(Array.Empty()));
+ AddAssert("Unranked badge not shown", () => footerButtonMods.UnrankedBadge.Alpha == 0);
+ }
+
private void changeMods(IReadOnlyList mods)
{
footerButtonMods.Current.Value = mods;
@@ -83,6 +93,7 @@ namespace osu.Game.Tests.Visual.UserInterface
private partial class TestFooterButtonMods : FooterButtonMods
{
public new OsuSpriteText MultiplierText => base.MultiplierText;
+ public new Drawable UnrankedBadge => base.UnrankedBadge;
}
}
}
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
index 046954db47..99a5897dff 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
@@ -119,7 +119,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("mod multiplier correct", () =>
{
double multiplier = SelectedMods.Value.Aggregate(1d, (m, mod) => m * mod.ScoreMultiplier);
- return Precision.AlmostEquals(multiplier, modSelectOverlay.ChildrenOfType().Single().Current.Value);
+ return Precision.AlmostEquals(multiplier, modSelectOverlay.ChildrenOfType().Single().ModMultiplier.Value);
});
assertCustomisationToggleState(disabled: false, active: false);
AddAssert("setting items created", () => modSelectOverlay.ChildrenOfType().Any());
@@ -134,7 +134,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddAssert("mod multiplier correct", () =>
{
double multiplier = SelectedMods.Value.Aggregate(1d, (m, mod) => m * mod.ScoreMultiplier);
- return Precision.AlmostEquals(multiplier, modSelectOverlay.ChildrenOfType().Single().Current.Value);
+ return Precision.AlmostEquals(multiplier, modSelectOverlay.ChildrenOfType().Single().ModMultiplier.Value);
});
assertCustomisationToggleState(disabled: false, active: false);
AddAssert("setting items created", () => modSelectOverlay.ChildrenOfType().Any());
@@ -846,7 +846,7 @@ namespace osu.Game.Tests.Visual.UserInterface
InputManager.Click(MouseButton.Left);
});
AddAssert("difficulty multiplier display shows correct value",
- () => modSelectOverlay.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(0.1).Within(Precision.DOUBLE_EPSILON));
+ () => modSelectOverlay.ChildrenOfType().Single().ModMultiplier.Value, () => Is.EqualTo(0.1).Within(Precision.DOUBLE_EPSILON));
// this is highly unorthodox in a test, but because the `ModSettingChangeTracker` machinery heavily leans on events and object disposal and re-creation,
// it is instrumental in the reproduction of the failure scenario that this test is supposed to cover.
@@ -856,7 +856,7 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("reset half time speed to default", () => modSelectOverlay.ChildrenOfType().Single()
.ChildrenOfType>().Single().TriggerClick());
AddUntilStep("difficulty multiplier display shows correct value",
- () => modSelectOverlay.ChildrenOfType().Single().Current.Value, () => Is.EqualTo(0.3).Within(Precision.DOUBLE_EPSILON));
+ () => modSelectOverlay.ChildrenOfType().Single().ModMultiplier.Value, () => Is.EqualTo(0.3).Within(Precision.DOUBLE_EPSILON));
}
private void waitForColumnLoad() => AddUntilStep("all column content loaded", () =>
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneScoreMultiplierDisplay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneRankingInformationDisplay.cs
similarity index 50%
rename from osu.Game.Tests/Visual/UserInterface/TestSceneScoreMultiplierDisplay.cs
rename to osu.Game.Tests/Visual/UserInterface/TestSceneRankingInformationDisplay.cs
index c2ddd814b7..42f243cc21 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneScoreMultiplierDisplay.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneRankingInformationDisplay.cs
@@ -11,7 +11,7 @@ using osu.Game.Overlays.Mods;
namespace osu.Game.Tests.Visual.UserInterface
{
[TestFixture]
- public partial class TestSceneScoreMultiplierDisplay : OsuTestScene
+ public partial class TestSceneRankingInformationDisplay : OsuTestScene
{
[Cached]
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
@@ -19,22 +19,24 @@ namespace osu.Game.Tests.Visual.UserInterface
[Test]
public void TestBasic()
{
- ScoreMultiplierDisplay multiplierDisplay = null!;
+ RankingInformationDisplay onlinePropertiesDisplay = null!;
- AddStep("create content", () => Child = multiplierDisplay = new ScoreMultiplierDisplay
+ AddStep("create content", () => Child = onlinePropertiesDisplay = new RankingInformationDisplay
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre
});
- AddStep("set multiplier below 1", () => multiplierDisplay.Current.Value = 0.5);
- AddStep("set multiplier to 1", () => multiplierDisplay.Current.Value = 1);
- AddStep("set multiplier above 1", () => multiplierDisplay.Current.Value = 1.5);
+ AddToggleStep("toggle ranked", ranked => onlinePropertiesDisplay.Ranked.Value = ranked);
+
+ AddStep("set multiplier below 1", () => onlinePropertiesDisplay.ModMultiplier.Value = 0.5);
+ AddStep("set multiplier to 1", () => onlinePropertiesDisplay.ModMultiplier.Value = 1);
+ AddStep("set multiplier above 1", () => onlinePropertiesDisplay.ModMultiplier.Value = 1.5);
AddSliderStep("set multiplier", 0, 2, 1d, multiplier =>
{
- if (multiplierDisplay.IsNotNull())
- multiplierDisplay.Current.Value = multiplier;
+ if (onlinePropertiesDisplay.IsNotNull())
+ onlinePropertiesDisplay.ModMultiplier.Value = multiplier;
});
}
}
diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj
index 7b08524240..c0bbdfb4ed 100644
--- a/osu.Game.Tests/osu.Game.Tests.csproj
+++ b/osu.Game.Tests/osu.Game.Tests.csproj
@@ -10,7 +10,7 @@
WinExe
- net6.0
+ net8.0
tests.ruleset
diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
index 3b00f103c4..8f1d7114b1 100644
--- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
+++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
@@ -10,7 +10,7 @@
WinExe
- net6.0
+ net8.0
diff --git a/osu.Game.Tournament/osu.Game.Tournament.csproj b/osu.Game.Tournament/osu.Game.Tournament.csproj
index ab67e490cd..c8578ac464 100644
--- a/osu.Game.Tournament/osu.Game.Tournament.csproj
+++ b/osu.Game.Tournament/osu.Game.Tournament.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
Library
true
tools for tournaments.
diff --git a/osu.Game/IO/HardLinkHelper.cs b/osu.Game/IO/HardLinkHelper.cs
index 619bfdad6e..ad57f87d10 100644
--- a/osu.Game/IO/HardLinkHelper.cs
+++ b/osu.Game/IO/HardLinkHelper.cs
@@ -153,12 +153,12 @@ namespace osu.Game.IO
public static extern int link(string oldpath, string newpath);
[DllImport("libc", SetLastError = true)]
- private static extern int stat(string pathname, out struct_stat statbuf);
+ private static extern int stat(string pathname, out Stat statbuf);
// ReSharper disable once InconsistentNaming
// Struct layout is likely non-portable across unices. Tread with caution.
[StructLayout(LayoutKind.Sequential)]
- private struct struct_stat
+ private struct Stat
{
public readonly long st_dev;
public readonly long st_ino;
@@ -170,14 +170,14 @@ namespace osu.Game.IO
public readonly long st_size;
public readonly long st_blksize;
public readonly long st_blocks;
- public readonly timespec st_atim;
- public readonly timespec st_mtim;
- public readonly timespec st_ctim;
+ public readonly Timespec st_atim;
+ public readonly Timespec st_mtim;
+ public readonly Timespec st_ctim;
}
// ReSharper disable once InconsistentNaming
[StructLayout(LayoutKind.Sequential)]
- private struct timespec
+ private struct Timespec
{
public readonly long tv_sec;
public readonly long tv_nsec;
diff --git a/osu.Game/Localisation/ModSelectOverlayStrings.cs b/osu.Game/Localisation/ModSelectOverlayStrings.cs
index 86ebebd293..9513eacf02 100644
--- a/osu.Game/Localisation/ModSelectOverlayStrings.cs
+++ b/osu.Game/Localisation/ModSelectOverlayStrings.cs
@@ -49,6 +49,26 @@ namespace osu.Game.Localisation
///
public static LocalisableString ScoreMultiplier => new TranslatableString(getKey(@"score_multiplier"), @"Score Multiplier");
+ ///
+ /// "Ranked"
+ ///
+ public static LocalisableString Ranked => new TranslatableString(getKey(@"ranked"), @"Ranked");
+
+ ///
+ /// "Performance points can be granted for the active mods."
+ ///
+ public static LocalisableString RankedExplanation => new TranslatableString(getKey(@"ranked_explanation"), @"Performance points can be granted for the active mods.");
+
+ ///
+ /// "Unranked"
+ ///
+ public static LocalisableString Unranked => new TranslatableString(getKey(@"unranked"), @"Unranked");
+
+ ///
+ /// "Performance points will not be granted due to active mods."
+ ///
+ public static LocalisableString UnrankedExplanation => new TranslatableString(getKey(@"ranked_explanation"), @"Performance points will not be granted due to active mods.");
+
private static string getKey(string key) => $@"{prefix}:{key}";
}
}
diff --git a/osu.Game/Online/Chat/WebSocketChatClient.cs b/osu.Game/Online/Chat/WebSocketChatClient.cs
index b74f8bec4b..8e1b501b25 100644
--- a/osu.Game/Online/Chat/WebSocketChatClient.cs
+++ b/osu.Game/Online/Chat/WebSocketChatClient.cs
@@ -61,7 +61,7 @@ namespace osu.Game.Online.Chat
{
await client.SendAsync(new StartChatRequest()).ConfigureAwait(false);
Logger.Log(@"Now listening to websocket chat messages.", LoggingTarget.Network);
- chatStartCancellationSource.Cancel();
+ await chatStartCancellationSource.CancelAsync().ConfigureAwait(false);
}
catch (Exception ex)
{
diff --git a/osu.Game/Overlays/Mods/EditPresetPopover.cs b/osu.Game/Overlays/Mods/EditPresetPopover.cs
index 8bce57c96a..9554ba8ce2 100644
--- a/osu.Game/Overlays/Mods/EditPresetPopover.cs
+++ b/osu.Game/Overlays/Mods/EditPresetPopover.cs
@@ -92,7 +92,7 @@ namespace osu.Game.Overlays.Mods
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
- Direction = FillDirection.Horizontal,
+ RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Spacing = new Vector2(7),
Children = new Drawable[]
diff --git a/osu.Game/Overlays/Mods/ModSelectOverlay.cs b/osu.Game/Overlays/Mods/ModSelectOverlay.cs
index 7271c53e7a..ddf96c1cb3 100644
--- a/osu.Game/Overlays/Mods/ModSelectOverlay.cs
+++ b/osu.Game/Overlays/Mods/ModSelectOverlay.cs
@@ -125,7 +125,7 @@ namespace osu.Game.Overlays.Mods
private DeselectAllModsButton deselectAllModsButton = null!;
private Container aboveColumnsContent = null!;
- private ScoreMultiplierDisplay? multiplierDisplay;
+ private RankingInformationDisplay? rankingInformationDisplay;
private BeatmapAttributesDisplay? beatmapAttributesDisplay;
protected ShearedButton BackButton { get; private set; } = null!;
@@ -185,7 +185,7 @@ namespace osu.Game.Overlays.Mods
aboveColumnsContent = new Container
{
RelativeSizeAxes = Axes.X,
- Height = ScoreMultiplierDisplay.HEIGHT,
+ Height = RankingInformationDisplay.HEIGHT,
Padding = new MarginPadding { Horizontal = 100 },
Child = SearchTextBox = new ShearedSearchTextBox
{
@@ -200,7 +200,7 @@ namespace osu.Game.Overlays.Mods
{
Padding = new MarginPadding
{
- Top = ScoreMultiplierDisplay.HEIGHT + PADDING,
+ Top = RankingInformationDisplay.HEIGHT + PADDING,
Bottom = PADDING
},
RelativeSizeAxes = Axes.Both,
@@ -269,7 +269,7 @@ namespace osu.Game.Overlays.Mods
},
Children = new Drawable[]
{
- multiplierDisplay = new ScoreMultiplierDisplay
+ rankingInformationDisplay = new RankingInformationDisplay
{
Anchor = Anchor.BottomRight,
Origin = Anchor.BottomRight
@@ -315,7 +315,7 @@ namespace osu.Game.Overlays.Mods
SelectedMods.BindValueChanged(_ =>
{
- updateMultiplier();
+ updateRankingInformation();
updateFromExternalSelection();
updateCustomisation();
@@ -328,7 +328,7 @@ namespace osu.Game.Overlays.Mods
//
// See https://github.com/ppy/osu/pull/23284#issuecomment-1529056988
modSettingChangeTracker = new ModSettingChangeTracker(SelectedMods.Value);
- modSettingChangeTracker.SettingChanged += _ => updateMultiplier();
+ modSettingChangeTracker.SettingChanged += _ => updateRankingInformation();
}
}, true);
@@ -450,9 +450,9 @@ namespace osu.Game.Overlays.Mods
modState.ValidForSelection.Value = modState.Mod.Type != ModType.System && modState.Mod.HasImplementation && IsValidMod.Invoke(modState.Mod);
}
- private void updateMultiplier()
+ private void updateRankingInformation()
{
- if (multiplierDisplay == null)
+ if (rankingInformationDisplay == null)
return;
double multiplier = 1.0;
@@ -460,7 +460,8 @@ namespace osu.Game.Overlays.Mods
foreach (var mod in SelectedMods.Value)
multiplier *= mod.ScoreMultiplier;
- multiplierDisplay.Current.Value = multiplier;
+ rankingInformationDisplay.ModMultiplier.Value = multiplier;
+ rankingInformationDisplay.Ranked.Value = SelectedMods.Value.All(m => m.Ranked);
}
private void updateCustomisation()
diff --git a/osu.Game/Overlays/Mods/ScoreMultiplierDisplay.cs b/osu.Game/Overlays/Mods/RankingInformationDisplay.cs
similarity index 60%
rename from osu.Game/Overlays/Mods/ScoreMultiplierDisplay.cs
rename to osu.Game/Overlays/Mods/RankingInformationDisplay.cs
index a86eba81e4..494f8a377f 100644
--- a/osu.Game/Overlays/Mods/ScoreMultiplierDisplay.cs
+++ b/osu.Game/Overlays/Mods/RankingInformationDisplay.cs
@@ -6,8 +6,8 @@ using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Cursor;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Graphics.UserInterface;
using osu.Framework.Localisation;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
@@ -22,15 +22,13 @@ namespace osu.Game.Overlays.Mods
///
/// On the mod select overlay, this provides a local updating view of the aggregate score multiplier coming from mods.
///
- public partial class ScoreMultiplierDisplay : ModFooterInformationDisplay, IHasCurrentValue
+ public partial class RankingInformationDisplay : ModFooterInformationDisplay
{
public const float HEIGHT = 42;
- public Bindable Current
- {
- get => current.Current;
- set => current.Current = value;
- }
+ public Bindable ModMultiplier = new BindableDouble(1);
+
+ public Bindable Ranked { get; } = new BindableBool(true);
private readonly BindableWithCurrent current = new BindableWithCurrent();
@@ -39,16 +37,11 @@ namespace osu.Game.Overlays.Mods
private RollingCounter counter = null!;
private Box flashLayer = null!;
+ private TextWithTooltip rankedText = null!;
[Resolved]
private OsuColour colours { get; set; } = null!;
- public ScoreMultiplierDisplay()
- {
- Current.Default = 1d;
- Current.Value = 1d;
- }
-
[BackgroundDependencyLoader]
private void load()
{
@@ -75,13 +68,20 @@ namespace osu.Game.Overlays.Mods
LeftContent.AddRange(new Drawable[]
{
- new OsuSpriteText
+ new Container
{
+ Width = 50,
+ RelativeSizeAxes = Axes.Y,
+ Margin = new MarginPadding(10),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Shear = new Vector2(-ShearedOverlayContainer.SHEAR, 0),
- Text = ModSelectOverlayStrings.ScoreMultiplier,
- Font = OsuFont.Default.With(size: 17, weight: FontWeight.SemiBold)
+ Child = rankedText = new TextWithTooltip
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Shear = new Vector2(-ShearedOverlayContainer.SHEAR, 0),
+ Font = OsuFont.Default.With(size: 17, weight: FontWeight.SemiBold)
+ }
}
});
@@ -97,7 +97,7 @@ namespace osu.Game.Overlays.Mods
Shear = new Vector2(-ShearedOverlayContainer.SHEAR, 0),
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Current = { BindTarget = Current }
+ Current = { BindTarget = ModMultiplier }
}
});
}
@@ -106,30 +106,22 @@ namespace osu.Game.Overlays.Mods
{
base.LoadComplete();
- Current.BindValueChanged(e =>
+ ModMultiplier.BindValueChanged(e =>
{
- if (e.NewValue > Current.Default)
+ if (e.NewValue > ModMultiplier.Default)
{
- MainBackground
- .FadeColour(colours.ForModType(ModType.DifficultyIncrease), transition_duration, Easing.OutQuint);
- counter.FadeColour(ColourProvider.Background5, transition_duration, Easing.OutQuint);
+ counter.FadeColour(colours.ForModType(ModType.DifficultyIncrease), transition_duration, Easing.OutQuint);
}
- else if (e.NewValue < Current.Default)
+ else if (e.NewValue < ModMultiplier.Default)
{
- MainBackground
- .FadeColour(colours.ForModType(ModType.DifficultyReduction), transition_duration, Easing.OutQuint);
- counter.FadeColour(ColourProvider.Background5, transition_duration, Easing.OutQuint);
+ counter.FadeColour(colours.ForModType(ModType.DifficultyReduction), transition_duration, Easing.OutQuint);
}
else
{
- MainBackground.FadeColour(ColourProvider.Background4, transition_duration, Easing.OutQuint);
counter.FadeColour(Colour4.White, transition_duration, Easing.OutQuint);
}
- flashLayer
- .FadeOutFromOne()
- .FadeTo(0.15f, 60, Easing.OutQuint)
- .Then().FadeOut(500, Easing.OutQuint);
+ flash();
const float move_amount = 4;
if (e.NewValue > e.OldValue)
@@ -140,10 +132,43 @@ namespace osu.Game.Overlays.Mods
// required to prevent the counter initially rolling up from 0 to 1
// due to `Current.Value` having a nonstandard default value of 1.
- counter.SetCountWithoutRolling(Current.Value);
+ counter.SetCountWithoutRolling(ModMultiplier.Value);
+
+ Ranked.BindValueChanged(e =>
+ {
+ flash();
+
+ if (e.NewValue)
+ {
+ rankedText.Text = ModSelectOverlayStrings.Ranked;
+ rankedText.TooltipText = ModSelectOverlayStrings.RankedExplanation;
+ rankedText.FadeColour(Colour4.White, transition_duration, Easing.OutQuint);
+ FrontBackground.FadeColour(ColourProvider.Background3, transition_duration, Easing.OutQuint);
+ }
+ else
+ {
+ rankedText.Text = ModSelectOverlayStrings.Unranked;
+ rankedText.TooltipText = ModSelectOverlayStrings.UnrankedExplanation;
+ rankedText.FadeColour(ColourProvider.Background5, transition_duration, Easing.OutQuint);
+ FrontBackground.FadeColour(colours.Orange1, transition_duration, Easing.OutQuint);
+ }
+ }, true);
}
- private partial class EffectCounter : RollingCounter
+ private void flash()
+ {
+ flashLayer
+ .FadeOutFromOne()
+ .FadeTo(0.15f, 60, Easing.OutQuint)
+ .Then().FadeOut(500, Easing.OutQuint);
+ }
+
+ private partial class TextWithTooltip : OsuSpriteText, IHasTooltip
+ {
+ public LocalisableString TooltipText { get; set; }
+ }
+
+ private partial class EffectCounter : RollingCounter, IHasTooltip
{
protected override double RollingDuration => 250;
@@ -155,6 +180,8 @@ namespace osu.Game.Overlays.Mods
Origin = Anchor.Centre,
Font = OsuFont.Default.With(size: 17, weight: FontWeight.SemiBold)
};
+
+ public LocalisableString TooltipText => ModSelectOverlayStrings.ScoreMultiplier;
}
}
}
diff --git a/osu.Game/Rulesets/Judgements/Judgement.cs b/osu.Game/Rulesets/Judgements/Judgement.cs
index 93386de483..d4d06167f1 100644
--- a/osu.Game/Rulesets/Judgements/Judgement.cs
+++ b/osu.Game/Rulesets/Judgements/Judgement.cs
@@ -73,9 +73,11 @@ namespace osu.Game.Rulesets.Judgements
return HitResult.SmallTickMiss;
case HitResult.LargeTickHit:
- case HitResult.SliderTailHit:
return HitResult.LargeTickMiss;
+ case HitResult.SliderTailHit:
+ return HitResult.IgnoreMiss;
+
default:
return HitResult.Miss;
}
diff --git a/osu.Game/Rulesets/Mods/IMod.cs b/osu.Game/Rulesets/Mods/IMod.cs
index 744d02a4fa..3a33d14835 100644
--- a/osu.Game/Rulesets/Mods/IMod.cs
+++ b/osu.Game/Rulesets/Mods/IMod.cs
@@ -66,6 +66,11 @@ namespace osu.Game.Rulesets.Mods
///
bool AlwaysValidForSubmission { get; }
+ ///
+ /// Whether scores with this mod active can give performance points.
+ ///
+ bool Ranked { get; }
+
///
/// Create a fresh instance based on this mod.
///
diff --git a/osu.Game/Rulesets/Mods/Mod.cs b/osu.Game/Rulesets/Mods/Mod.cs
index 0500b49513..50c867f41b 100644
--- a/osu.Game/Rulesets/Mods/Mod.cs
+++ b/osu.Game/Rulesets/Mods/Mod.cs
@@ -167,6 +167,12 @@ namespace osu.Game.Rulesets.Mods
[JsonIgnore]
public virtual bool RequiresConfiguration => false;
+ ///
+ /// Whether scores with this mod active can give performance points.
+ ///
+ [JsonIgnore]
+ public virtual bool Ranked => false;
+
///
/// The mods this mod cannot be enabled with.
///
diff --git a/osu.Game/Rulesets/Mods/ModDaycore.cs b/osu.Game/Rulesets/Mods/ModDaycore.cs
index 09b35c249e..359f8a950c 100644
--- a/osu.Game/Rulesets/Mods/ModDaycore.cs
+++ b/osu.Game/Rulesets/Mods/ModDaycore.cs
@@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Mods
public override IconUsage? Icon => null;
public override ModType Type => ModType.DifficultyReduction;
public override LocalisableString Description => "Whoaaaaa...";
+ public override bool Ranked => UsesDefaultConfiguration;
[SettingSource("Speed decrease", "The actual decrease to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
public override BindableNumber SpeedChange { get; } = new BindableDouble(0.75)
diff --git a/osu.Game/Rulesets/Mods/ModDoubleTime.cs b/osu.Game/Rulesets/Mods/ModDoubleTime.cs
index 789291772d..8e430da368 100644
--- a/osu.Game/Rulesets/Mods/ModDoubleTime.cs
+++ b/osu.Game/Rulesets/Mods/ModDoubleTime.cs
@@ -18,6 +18,7 @@ namespace osu.Game.Rulesets.Mods
public override IconUsage? Icon => OsuIcon.ModDoubleTime;
public override ModType Type => ModType.DifficultyIncrease;
public override LocalisableString Description => "Zoooooooooom...";
+ public override bool Ranked => UsesDefaultConfiguration;
[SettingSource("Speed increase", "The actual increase to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
public override BindableNumber SpeedChange { get; } = new BindableDouble(1.5)
diff --git a/osu.Game/Rulesets/Mods/ModEasy.cs b/osu.Game/Rulesets/Mods/ModEasy.cs
index 0f51e2a6d5..da43a6b294 100644
--- a/osu.Game/Rulesets/Mods/ModEasy.cs
+++ b/osu.Game/Rulesets/Mods/ModEasy.cs
@@ -16,6 +16,7 @@ namespace osu.Game.Rulesets.Mods
public override ModType Type => ModType.DifficultyReduction;
public override double ScoreMultiplier => 0.5;
public override Type[] IncompatibleMods => new[] { typeof(ModHardRock), typeof(ModDifficultyAdjust) };
+ public override bool Ranked => UsesDefaultConfiguration;
public virtual void ReadFromDifficulty(BeatmapDifficulty difficulty)
{
diff --git a/osu.Game/Rulesets/Mods/ModFlashlight.cs b/osu.Game/Rulesets/Mods/ModFlashlight.cs
index dc2ad6f47e..9227af64b8 100644
--- a/osu.Game/Rulesets/Mods/ModFlashlight.cs
+++ b/osu.Game/Rulesets/Mods/ModFlashlight.cs
@@ -33,6 +33,7 @@ namespace osu.Game.Rulesets.Mods
public override IconUsage? Icon => OsuIcon.ModFlashlight;
public override ModType Type => ModType.DifficultyIncrease;
public override LocalisableString Description => "Restricted view area.";
+ public override bool Ranked => UsesDefaultConfiguration;
[SettingSource("Flashlight size", "Multiplier applied to the default flashlight size.")]
public abstract BindableFloat SizeMultiplier { get; }
diff --git a/osu.Game/Rulesets/Mods/ModHalfTime.cs b/osu.Game/Rulesets/Mods/ModHalfTime.cs
index 8b5dd39584..59e40ee9cc 100644
--- a/osu.Game/Rulesets/Mods/ModHalfTime.cs
+++ b/osu.Game/Rulesets/Mods/ModHalfTime.cs
@@ -18,6 +18,7 @@ namespace osu.Game.Rulesets.Mods
public override IconUsage? Icon => OsuIcon.ModHalftime;
public override ModType Type => ModType.DifficultyReduction;
public override LocalisableString Description => "Less zoom...";
+ public override bool Ranked => UsesDefaultConfiguration;
[SettingSource("Speed decrease", "The actual decrease to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
public override BindableNumber SpeedChange { get; } = new BindableDouble(0.75)
diff --git a/osu.Game/Rulesets/Mods/ModHardRock.cs b/osu.Game/Rulesets/Mods/ModHardRock.cs
index 4b2d1d050e..1e99891b99 100644
--- a/osu.Game/Rulesets/Mods/ModHardRock.cs
+++ b/osu.Game/Rulesets/Mods/ModHardRock.cs
@@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Mods
public override ModType Type => ModType.DifficultyIncrease;
public override LocalisableString Description => "Everything just got a bit harder...";
public override Type[] IncompatibleMods => new[] { typeof(ModEasy), typeof(ModDifficultyAdjust) };
+ public override bool Ranked => UsesDefaultConfiguration;
protected const float ADJUST_RATIO = 1.4f;
diff --git a/osu.Game/Rulesets/Mods/ModHidden.cs b/osu.Game/Rulesets/Mods/ModHidden.cs
index 8b25768575..5a1abf115f 100644
--- a/osu.Game/Rulesets/Mods/ModHidden.cs
+++ b/osu.Game/Rulesets/Mods/ModHidden.cs
@@ -14,6 +14,7 @@ namespace osu.Game.Rulesets.Mods
public override string Acronym => "HD";
public override IconUsage? Icon => OsuIcon.ModHidden;
public override ModType Type => ModType.DifficultyIncrease;
+ public override bool Ranked => UsesDefaultConfiguration;
public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor)
{
diff --git a/osu.Game/Rulesets/Mods/ModMuted.cs b/osu.Game/Rulesets/Mods/ModMuted.cs
index 131f501630..3ecd9aa6a1 100644
--- a/osu.Game/Rulesets/Mods/ModMuted.cs
+++ b/osu.Game/Rulesets/Mods/ModMuted.cs
@@ -25,6 +25,7 @@ namespace osu.Game.Rulesets.Mods
public override LocalisableString Description => "Can you still feel the rhythm without music?";
public override ModType Type => ModType.Fun;
public override double ScoreMultiplier => 1;
+ public override bool Ranked => UsesDefaultConfiguration;
}
public abstract class ModMuted : ModMuted, IApplicableToDrawableRuleset, IApplicableToTrack, IApplicableToScoreProcessor
diff --git a/osu.Game/Rulesets/Mods/ModNightcore.cs b/osu.Game/Rulesets/Mods/ModNightcore.cs
index b42927256c..bb18940f8c 100644
--- a/osu.Game/Rulesets/Mods/ModNightcore.cs
+++ b/osu.Game/Rulesets/Mods/ModNightcore.cs
@@ -28,6 +28,7 @@ namespace osu.Game.Rulesets.Mods
public override IconUsage? Icon => OsuIcon.ModNightcore;
public override ModType Type => ModType.DifficultyIncrease;
public override LocalisableString Description => "Uguuuuuuuu...";
+ public override bool Ranked => UsesDefaultConfiguration;
[SettingSource("Speed increase", "The actual increase to apply", SettingControlType = typeof(MultiplierSettingsSlider))]
public override BindableNumber SpeedChange { get; } = new BindableDouble(1.5)
diff --git a/osu.Game/Rulesets/Mods/ModNoFail.cs b/osu.Game/Rulesets/Mods/ModNoFail.cs
index cc451772b2..1aaef8eac4 100644
--- a/osu.Game/Rulesets/Mods/ModNoFail.cs
+++ b/osu.Game/Rulesets/Mods/ModNoFail.cs
@@ -20,6 +20,7 @@ namespace osu.Game.Rulesets.Mods
public override LocalisableString Description => "You can't fail, no matter what.";
public override double ScoreMultiplier => 0.5;
public override Type[] IncompatibleMods => new[] { typeof(ModFailCondition), typeof(ModCinema) };
+ public override bool Ranked => UsesDefaultConfiguration;
private readonly Bindable showHealthBar = new Bindable();
diff --git a/osu.Game/Rulesets/Mods/ModPerfect.cs b/osu.Game/Rulesets/Mods/ModPerfect.cs
index 0ba40ba070..f8f498ceb5 100644
--- a/osu.Game/Rulesets/Mods/ModPerfect.cs
+++ b/osu.Game/Rulesets/Mods/ModPerfect.cs
@@ -19,6 +19,7 @@ namespace osu.Game.Rulesets.Mods
public override ModType Type => ModType.DifficultyIncrease;
public override double ScoreMultiplier => 1;
public override LocalisableString Description => "SS or quit.";
+ public override bool Ranked => UsesDefaultConfiguration;
public override Type[] IncompatibleMods => base.IncompatibleMods.Concat(new[] { typeof(ModSuddenDeath), typeof(ModAccuracyChallenge) }).ToArray();
diff --git a/osu.Game/Rulesets/Mods/ModSuddenDeath.cs b/osu.Game/Rulesets/Mods/ModSuddenDeath.cs
index 4e4e8662e8..62579a168c 100644
--- a/osu.Game/Rulesets/Mods/ModSuddenDeath.cs
+++ b/osu.Game/Rulesets/Mods/ModSuddenDeath.cs
@@ -19,6 +19,7 @@ namespace osu.Game.Rulesets.Mods
public override ModType Type => ModType.DifficultyIncrease;
public override LocalisableString Description => "Miss and fail.";
public override double ScoreMultiplier => 1;
+ public override bool Ranked => UsesDefaultConfiguration;
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ModPerfect)).ToArray();
diff --git a/osu.Game/Rulesets/Scoring/HitResult.cs b/osu.Game/Rulesets/Scoring/HitResult.cs
index 20ec3c4946..b6cfca58db 100644
--- a/osu.Game/Rulesets/Scoring/HitResult.cs
+++ b/osu.Game/Rulesets/Scoring/HitResult.cs
@@ -138,7 +138,8 @@ namespace osu.Game.Rulesets.Scoring
ComboBreak,
///
- /// A special judgement similar to that's used to increase the valuation of the final tick of a slider.
+ /// A special tick judgement to increase the valuation of the final tick of a slider.
+ /// The default minimum result is , but may be overridden to .
///
[EnumMember(Value = "slider_tail_hit")]
[Order(8)]
diff --git a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs
index ac6403bb34..bff1a8c64c 100644
--- a/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs
+++ b/osu.Game/Screens/OnlinePlay/Lounge/Components/RoomsContainer.cs
@@ -126,7 +126,13 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
case NotifyCollectionChangedAction.Remove:
Debug.Assert(args.OldItems != null);
- removeRooms(args.OldItems.Cast());
+ // clear operations have a separate path that benefits from async disposal,
+ // since disposing is quite expensive when performed on a high number of drawables synchronously.
+ if (args.OldItems.Count == roomFlow.Count)
+ clearRooms();
+ else
+ removeRooms(args.OldItems.Cast());
+
break;
}
}
@@ -151,6 +157,15 @@ namespace osu.Game.Screens.OnlinePlay.Lounge.Components
}
}
+ private void clearRooms()
+ {
+ roomFlow.Clear();
+
+ // selection may have a lease due to being in a sub screen.
+ if (!SelectedRoom.Disabled)
+ SelectedRoom.Value = null;
+ }
+
private void updateSorting()
{
foreach (var room in roomFlow)
diff --git a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
index 0aff98df2b..d209c305fa 100644
--- a/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
+++ b/osu.Game/Screens/Ranking/Expanded/Accuracy/AccuracyCircle.cs
@@ -4,6 +4,7 @@
#nullable disable
using System;
+using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Audio;
@@ -259,10 +260,15 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
if (isFailedSDueToMisses)
AddInternal(failedSRankText = new RankText(ScoreRank.S));
+ var applauseSamples = new List { applauseSampleName };
+ if (score.Rank >= ScoreRank.B)
+ // when rank is B or higher, play legacy applause sample on legacy skins.
+ applauseSamples.Insert(0, @"applause");
+
AddRangeInternal(new Drawable[]
{
rankImpactSound = new PoolableSkinnableSample(new SampleInfo(impactSampleName)),
- rankApplauseSound = new PoolableSkinnableSample(new SampleInfo(@"applause", applauseSampleName)),
+ rankApplauseSound = new PoolableSkinnableSample(new SampleInfo(applauseSamples.ToArray())),
scoreTickSound = new PoolableSkinnableSample(new SampleInfo(@"Results/score-tick")),
badgeTickSound = new PoolableSkinnableSample(new SampleInfo(@"Results/badge-dink")),
badgeMaxSound = new PoolableSkinnableSample(new SampleInfo(@"Results/badge-dink-max")),
@@ -351,24 +357,28 @@ namespace osu.Game.Screens.Ranking.Expanded.Accuracy
int badgeNum = 0;
- foreach (var badge in badges)
+ if (score.Rank != ScoreRank.F)
{
- if (badge.Accuracy > score.Accuracy)
- continue;
-
- using (BeginDelayedSequence(inverseEasing(ACCURACY_TRANSFORM_EASING, Math.Min(accuracyX - virtual_ss_percentage, badge.Accuracy) / targetAccuracy) * ACCURACY_TRANSFORM_DURATION))
+ foreach (var badge in badges)
{
- badge.Appear();
+ if (badge.Accuracy > score.Accuracy)
+ continue;
- if (withFlair)
+ using (BeginDelayedSequence(
+ inverseEasing(ACCURACY_TRANSFORM_EASING, Math.Min(accuracyX - virtual_ss_percentage, badge.Accuracy) / targetAccuracy) * ACCURACY_TRANSFORM_DURATION))
{
- Schedule(() =>
- {
- var dink = badgeNum < badges.Count - 1 ? badgeTickSound : badgeMaxSound;
+ badge.Appear();
- dink.FrequencyTo(1 + badgeNum++ * 0.05);
- dink.Play();
- });
+ if (withFlair)
+ {
+ Schedule(() =>
+ {
+ var dink = badgeNum < badges.Count - 1 ? badgeTickSound : badgeMaxSound;
+
+ dink.FrequencyTo(1 + badgeNum++ * 0.05);
+ dink.Play();
+ });
+ }
}
}
}
diff --git a/osu.Game/Screens/Select/FooterButtonMods.cs b/osu.Game/Screens/Select/FooterButtonMods.cs
index 69782c25bb..5685910c0a 100644
--- a/osu.Game/Screens/Select/FooterButtonMods.cs
+++ b/osu.Game/Screens/Select/FooterButtonMods.cs
@@ -1,17 +1,17 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Screens.Play.HUD;
using osu.Game.Rulesets.Mods;
using System.Collections.Generic;
using System.Linq;
-using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
+using osu.Framework.Extensions.LocalisationExtensions;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.UserInterface;
using osu.Game.Configuration;
using osu.Game.Graphics;
@@ -19,6 +19,7 @@ using osu.Game.Graphics.Sprites;
using osuTK;
using osuTK.Graphics;
using osu.Game.Input.Bindings;
+using osu.Game.Localisation;
using osu.Game.Utils;
namespace osu.Game.Screens.Select
@@ -31,26 +32,26 @@ namespace osu.Game.Screens.Select
set => modDisplay.Current = value;
}
- protected readonly OsuSpriteText MultiplierText;
+ protected OsuSpriteText MultiplierText { get; private set; } = null!;
+ protected Container UnrankedBadge { get; private set; } = null!;
+
private readonly ModDisplay modDisplay;
+
+ private ModSettingChangeTracker? modSettingChangeTracker;
+
private Color4 lowMultiplierColour;
private Color4 highMultiplierColour;
public FooterButtonMods()
{
- ButtonContentContainer.Add(modDisplay = new ModDisplay
+ // must be created in ctor for correct operation of `Current`.
+ modDisplay = new ModDisplay
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
Scale = new Vector2(0.8f),
ExpansionMode = ExpansionMode.AlwaysContracted,
- });
- ButtonContentContainer.Add(MultiplierText = new OsuSpriteText
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- Font = OsuFont.GetFont(weight: FontWeight.Bold),
- });
+ };
}
[BackgroundDependencyLoader]
@@ -62,10 +63,43 @@ namespace osu.Game.Screens.Select
highMultiplierColour = colours.Green;
Text = @"mods";
Hotkey = GlobalAction.ToggleModSelection;
- }
- [CanBeNull]
- private ModSettingChangeTracker modSettingChangeTracker;
+ ButtonContentContainer.AddRange(new Drawable[]
+ {
+ modDisplay,
+ MultiplierText = new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Font = OsuFont.GetFont(weight: FontWeight.Bold),
+ },
+ UnrankedBadge = new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ AutoSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ new Circle
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Colour = colours.Yellow,
+ RelativeSizeAxes = Axes.Both,
+ },
+ new OsuSpriteText
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Colour = colours.Gray2,
+ Padding = new MarginPadding(5),
+ UseFullGlyphHeight = false,
+ Text = ModSelectOverlayStrings.Unranked.ToLower()
+ }
+ }
+ },
+ });
+ }
protected override void LoadComplete()
{
@@ -101,6 +135,9 @@ namespace osu.Game.Screens.Select
modDisplay.FadeIn();
else
modDisplay.FadeOut();
+
+ bool anyUnrankedMods = Current.Value?.Any(m => !m.Ranked) == true;
+ UnrankedBadge.FadeTo(anyUnrankedMods ? 1 : 0);
});
}
}
diff --git a/osu.Game/Users/UserGridPanel.cs b/osu.Game/Users/UserGridPanel.cs
index fe3435c248..fce543415d 100644
--- a/osu.Game/Users/UserGridPanel.cs
+++ b/osu.Game/Users/UserGridPanel.cs
@@ -35,98 +35,84 @@ namespace osu.Game.Users
{
FillFlowContainer details;
- var layout = new Container
+ var layout = new GridContainer
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding(margin),
- Child = new GridContainer
+ ColumnDimensions = new[]
{
- RelativeSizeAxes = Axes.Both,
- ColumnDimensions = new[]
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension()
+ },
+ RowDimensions = new[]
+ {
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension()
+ },
+ Content = new[]
+ {
+ new Drawable[]
{
- new Dimension(GridSizeMode.AutoSize),
- new Dimension()
- },
- RowDimensions = new[]
- {
- new Dimension(GridSizeMode.AutoSize),
- new Dimension(GridSizeMode.Absolute, margin),
- new Dimension()
- },
- Content = new[]
- {
- new Drawable[]
+ CreateAvatar().With(avatar =>
{
- CreateAvatar().With(avatar =>
+ avatar.Size = new Vector2(60);
+ avatar.Masking = true;
+ avatar.CornerRadius = 6;
+ avatar.Margin = new MarginPadding { Bottom = margin };
+ }),
+ new GridContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding { Left = margin, Bottom = margin },
+ ColumnDimensions = new[]
{
- avatar.Size = new Vector2(60);
- avatar.Masking = true;
- avatar.CornerRadius = 6;
- }),
- new Container
+ new Dimension()
+ },
+ RowDimensions = new[]
{
- RelativeSizeAxes = Axes.Both,
- Padding = new MarginPadding { Left = margin },
- Child = new GridContainer
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension()
+ },
+ Content = new[]
+ {
+ new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- ColumnDimensions = new[]
+ details = new FillFlowContainer
{
- new Dimension()
- },
- RowDimensions = new[]
- {
- new Dimension(GridSizeMode.AutoSize),
- new Dimension()
- },
- Content = new[]
- {
- new Drawable[]
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(6),
+ Children = new Drawable[]
{
- details = new FillFlowContainer
- {
- AutoSizeAxes = Axes.Both,
- Direction = FillDirection.Horizontal,
- Spacing = new Vector2(6),
- Children = new Drawable[]
- {
- CreateFlag(),
- // supporter icon is being added later
- }
- }
- },
- new Drawable[]
- {
- CreateUsername().With(username =>
- {
- username.Anchor = Anchor.CentreLeft;
- username.Origin = Anchor.CentreLeft;
- })
+ CreateFlag(),
+ // supporter icon is being added later
}
}
+ },
+ new Drawable[]
+ {
+ CreateUsername().With(username =>
+ {
+ username.Anchor = Anchor.CentreLeft;
+ username.Origin = Anchor.CentreLeft;
+ })
}
}
- },
- new[]
- {
- // padding
- Empty(),
- Empty()
- },
- new Drawable[]
- {
- CreateStatusIcon().With(icon =>
- {
- icon.Anchor = Anchor.Centre;
- icon.Origin = Anchor.Centre;
- }),
- CreateStatusMessage(false).With(message =>
- {
- message.Anchor = Anchor.CentreLeft;
- message.Origin = Anchor.CentreLeft;
- message.Margin = new MarginPadding { Left = margin };
- })
}
+ },
+ new Drawable[]
+ {
+ CreateStatusIcon().With(icon =>
+ {
+ icon.Anchor = Anchor.Centre;
+ icon.Origin = Anchor.Centre;
+ }),
+ CreateStatusMessage(false).With(message =>
+ {
+ message.Anchor = Anchor.CentreLeft;
+ message.Origin = Anchor.CentreLeft;
+ message.Margin = new MarginPadding { Left = margin };
+ })
}
}
};
diff --git a/osu.Game/Users/UserRankPanel.cs b/osu.Game/Users/UserRankPanel.cs
index a38962dfc7..84ff3114fc 100644
--- a/osu.Game/Users/UserRankPanel.cs
+++ b/osu.Game/Users/UserRankPanel.cs
@@ -81,117 +81,95 @@ namespace osu.Game.Users
},
new GridContainer
{
- AutoSizeAxes = Axes.Y,
- RelativeSizeAxes = Axes.X,
+ RelativeSizeAxes = Axes.Both,
+ Padding = new MarginPadding(padding),
ColumnDimensions = new[]
{
- new Dimension(GridSizeMode.Absolute, padding),
new Dimension(GridSizeMode.AutoSize),
new Dimension(),
- new Dimension(GridSizeMode.Absolute, padding),
},
RowDimensions = new[]
{
- new Dimension(GridSizeMode.Absolute, padding),
- new Dimension(GridSizeMode.AutoSize),
+ new Dimension()
},
Content = new[]
{
- new[]
+ new Drawable[]
{
- // padding
- Empty(),
- Empty(),
- Empty(),
- Empty()
- },
- new[]
- {
- Empty(), // padding
CreateAvatar().With(avatar =>
{
avatar.Size = new Vector2(60);
avatar.Masking = true;
avatar.CornerRadius = 6;
}),
- new Container
+ new GridContainer
{
RelativeSizeAxes = Axes.Both,
Padding = new MarginPadding { Left = padding },
- Child = new GridContainer
+ ColumnDimensions = new[]
{
- RelativeSizeAxes = Axes.Both,
- ColumnDimensions = new[]
+ new Dimension()
+ },
+ RowDimensions = new[]
+ {
+ new Dimension(GridSizeMode.AutoSize),
+ new Dimension()
+ },
+ Content = new[]
+ {
+ new Drawable[]
{
- new Dimension()
- },
- RowDimensions = new[]
- {
- new Dimension(GridSizeMode.AutoSize),
- new Dimension()
- },
- Content = new[]
- {
- new Drawable[]
+ details = new FillFlowContainer
{
- details = new FillFlowContainer
+ AutoSizeAxes = Axes.Both,
+ Direction = FillDirection.Horizontal,
+ Spacing = new Vector2(6),
+ Children = new Drawable[]
{
- AutoSizeAxes = Axes.Both,
- Direction = FillDirection.Horizontal,
- Spacing = new Vector2(6),
- Children = new Drawable[]
- {
- CreateFlag(),
- // supporter icon is being added later
- }
+ CreateFlag(),
+ // supporter icon is being added later
}
- },
- new Drawable[]
- {
- CreateUsername().With(username =>
- {
- username.Anchor = Anchor.CentreLeft;
- username.Origin = Anchor.CentreLeft;
- })
}
+ },
+ new Drawable[]
+ {
+ CreateUsername().With(username =>
+ {
+ username.Anchor = Anchor.CentreLeft;
+ username.Origin = Anchor.CentreLeft;
+ })
}
}
- },
- Empty() // padding
+ }
}
}
}
}
},
- new Container
+ new GridContainer
{
Name = "Bottom content",
Margin = new MarginPadding { Top = main_content_height },
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y,
Padding = new MarginPadding { Left = 80, Vertical = padding },
- Child = new GridContainer
+ ColumnDimensions = new[]
{
- RelativeSizeAxes = Axes.X,
- AutoSizeAxes = Axes.Y,
- ColumnDimensions = new[]
+ new Dimension(),
+ new Dimension()
+ },
+ RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) },
+ Content = new[]
+ {
+ new Drawable[]
{
- new Dimension(),
- new Dimension()
- },
- RowDimensions = new[] { new Dimension(GridSizeMode.AutoSize) },
- Content = new[]
- {
- new Drawable[]
+ globalRankDisplay = new ProfileValueDisplay(true)
{
- globalRankDisplay = new ProfileValueDisplay(true)
- {
- Title = UsersStrings.ShowRankGlobalSimple,
- },
- countryRankDisplay = new ProfileValueDisplay(true)
- {
- Title = UsersStrings.ShowRankCountrySimple,
- }
+ Title = UsersStrings.ShowRankGlobalSimple,
+ },
+ countryRankDisplay = new ProfileValueDisplay(true)
+ {
+ Title = UsersStrings.ShowRankCountrySimple,
}
}
}
diff --git a/osu.Game/osu.Game.csproj b/osu.Game/osu.Game.csproj
index a5d212bffe..935b759e4d 100644
--- a/osu.Game/osu.Game.csproj
+++ b/osu.Game/osu.Game.csproj
@@ -1,6 +1,6 @@
- net6.0
+ net8.0
Library
true
10
@@ -36,7 +36,7 @@
runtime; build; native; contentfiles; analyzers; buildtransitive
-
+
diff --git a/osu.iOS.props b/osu.iOS.props
index bd6891f448..a4cd26a372 100644
--- a/osu.iOS.props
+++ b/osu.iOS.props
@@ -23,6 +23,6 @@
iossimulator-x64
-
+
diff --git a/osu.iOS/osu.iOS.csproj b/osu.iOS/osu.iOS.csproj
index 2d61b73125..19c0c610b5 100644
--- a/osu.iOS/osu.iOS.csproj
+++ b/osu.iOS/osu.iOS.csproj
@@ -1,9 +1,8 @@
- net6.0-ios
+ net8.0-ios
13.4
Exe
- true
0.1.0
$(Version)
$(Version)
@@ -16,4 +15,7 @@
+
+
+