mirror of
https://github.com/osukey/osukey.git
synced 2025-05-07 14:47:22 +09:00
Merge remote-tracking branch 'upstream/master' into chat-mention
This commit is contained in:
commit
2b5d541857
3
.gitignore
vendored
3
.gitignore
vendored
@ -331,3 +331,6 @@ fastlane/report.xml
|
|||||||
# inspectcode
|
# inspectcode
|
||||||
inspectcodereport.xml
|
inspectcodereport.xml
|
||||||
inspectcode
|
inspectcode
|
||||||
|
|
||||||
|
# BenchmarkDotNet
|
||||||
|
/BenchmarkDotNet.Artifacts
|
||||||
|
20
.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml
generated
Normal file
20
.idea/.idea.osu.Desktop/.idea/runConfigurations/Benchmarks.xml
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Benchmarks" type="DotNetProject" factoryName=".NET Project">
|
||||||
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Benchmarks/bin/Release/netcoreapp3.1/osu.Game.Benchmarks.dll" />
|
||||||
|
<option name="PROGRAM_PARAMETERS" value="--filter *" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Benchmarks/bin/Release/netcoreapp3.1" />
|
||||||
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
|
<option name="USE_MONO" value="0" />
|
||||||
|
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||||
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj" />
|
||||||
|
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||||
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Build" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="CatchRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
<configuration default="false" name="CatchRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Catch.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Catch.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Build" enabled="true" />
|
<option name="Build" enabled="true" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="ManiaRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
<configuration default="false" name="ManiaRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Mania.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Mania.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Build" enabled="true" />
|
<option name="Build" enabled="true" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="OsuRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
<configuration default="false" name="OsuRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Osu.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Osu.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Build" enabled="true" />
|
<option name="Build" enabled="true" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="TaikoRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
<configuration default="false" name="TaikoRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Taiko.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Taiko.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Build" enabled="true" />
|
<option name="Build" enabled="true" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Tournament" type="DotNetProject" factoryName=".NET Project" folderName="Tournament">
|
<configuration default="false" name="Tournament" type="DotNetProject" factoryName=".NET Project" folderName="Tournament">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.0/osu!.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="--tournament" />
|
<option name="PROGRAM_PARAMETERS" value="--tournament" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Build" enabled="true" />
|
<option name="Build" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="Tournament (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Tournament">
|
<configuration default="false" name="Tournament (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Tournament">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tournament.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tournament.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tournament.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tournament.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Build" enabled="true" />
|
<option name="Build" enabled="true" />
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
|
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.0/osu!.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Build" enabled="true" />
|
<option name="Build" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
20
.idea/.idea.osu.Desktop/.idea/runConfigurations/osu_SDL.xml
generated
Normal file
20
.idea/.idea.osu.Desktop/.idea/runConfigurations/osu_SDL.xml
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="osu! SDL" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
|
||||||
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll" />
|
||||||
|
<option name="PROGRAM_PARAMETERS" value="--sdl" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||||
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
|
<option name="USE_MONO" value="0" />
|
||||||
|
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||||
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Desktop/osu.Desktop.csproj" />
|
||||||
|
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||||
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Build" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
@ -1,6 +1,6 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="osu! (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
|
<configuration default="false" name="osu! (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp3.0/osu.Game.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tests.dll" />
|
||||||
<option name="PROGRAM_PARAMETERS" value="" />
|
<option name="PROGRAM_PARAMETERS" value="" />
|
||||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
|
||||||
<option name="PASS_PARENT_ENVS" value="1" />
|
<option name="PASS_PARENT_ENVS" value="1" />
|
||||||
@ -12,7 +12,7 @@
|
|||||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.0" />
|
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||||
<method v="2">
|
<method v="2">
|
||||||
<option name="Build" enabled="true" />
|
<option name="Build" enabled="true" />
|
||||||
</method>
|
</method>
|
||||||
|
51
.vscode/launch.json
vendored
51
.vscode/launch.json
vendored
@ -1,18 +1,19 @@
|
|||||||
{
|
{
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [{
|
"configurations": [
|
||||||
|
{
|
||||||
"name": "osu! (Debug)",
|
"name": "osu! (Debug)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.0/osu!.dll"
|
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Debug)",
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -23,13 +24,13 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.0/osu!.dll"
|
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1/osu!.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Release)",
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -40,29 +41,30 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp3.0/osu.Game.Tests.dll"
|
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tests (Debug)",
|
"preLaunchTask": "Build tests (Debug)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"name": "osu! (Tests, Release)",
|
"name": "osu! (Tests, Release)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp3.0/osu.Game.Tests.dll"
|
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp3.1/osu.Game.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tests (Release)",
|
"preLaunchTask": "Build tests (Release)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -73,14 +75,14 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.0/osu!.dll",
|
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Debug)",
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -91,14 +93,14 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.0/osu!.dll",
|
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1/osu!.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build osu! (Release)",
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -109,14 +111,14 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.0/osu.Game.Tournament.Tests.dll",
|
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tournament.Tests.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tournament tests (Debug)",
|
"preLaunchTask": "Build tournament tests (Debug)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
@ -127,18 +129,31 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.0/osu.Game.Tournament.Tests.dll",
|
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tournament.Tests.dll",
|
||||||
"--tournament"
|
"--tournament"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build tournament tests (Release)",
|
"preLaunchTask": "Build tournament tests (Release)",
|
||||||
"linux": {
|
"linux": {
|
||||||
"env": {
|
"env": {
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.0:${env:LD_LIBRARY_PATH}"
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1:${env:LD_LIBRARY_PATH}"
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "Benchmark",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "${workspaceRoot}/osu.Game.Benchmarks/bin/Release/netcoreapp3.1/osu.Game.Benchmarks.dll",
|
||||||
|
"args": [
|
||||||
|
"--filter",
|
||||||
|
"*"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"preLaunchTask": "Build benchmarks",
|
||||||
|
"console": "internalConsole"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Cake: Debug Script",
|
"name": "Cake: Debug Script",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
|
24
.vscode/tasks.json
vendored
24
.vscode/tasks.json
vendored
@ -2,7 +2,8 @@
|
|||||||
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
// See https://go.microsoft.com/fwlink/?LinkId=733558
|
||||||
// for the documentation about the tasks.json format
|
// for the documentation about the tasks.json format
|
||||||
"version": "2.0.0",
|
"version": "2.0.0",
|
||||||
"tasks": [{
|
"tasks": [
|
||||||
|
{
|
||||||
"label": "Build osu! (Debug)",
|
"label": "Build osu! (Debug)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
@ -78,7 +79,8 @@
|
|||||||
],
|
],
|
||||||
"group": "build",
|
"group": "build",
|
||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
}, {
|
},
|
||||||
|
{
|
||||||
"label": "Build tournament tests (Release)",
|
"label": "Build tournament tests (Release)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
@ -95,7 +97,23 @@
|
|||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
{
|
{
|
||||||
"label": "Restore (netcoreapp3.0)",
|
"label": "Build benchmarks",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--no-restore",
|
||||||
|
"osu.Game.Benchmarks",
|
||||||
|
"/p:Configuration=Release",
|
||||||
|
"/p:GenerateFullPaths=true",
|
||||||
|
"/m",
|
||||||
|
"/verbosity:m"
|
||||||
|
],
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"label": "Restore (netcoreapp3.1)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
"command": "dotnet",
|
"command": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
|
58
CodeAnalysis/osu.ruleset
Normal file
58
CodeAnalysis/osu.ruleset
Normal file
@ -0,0 +1,58 @@
|
|||||||
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
<RuleSet Name="osu! Rule Set" Description=" " ToolsVersion="16.0">
|
||||||
|
<Rules AnalyzerId="Microsoft.CodeQuality.Analyzers" RuleNamespace="Microsoft.CodeQuality.Analyzers">
|
||||||
|
<Rule Id="CA1016" Action="None" />
|
||||||
|
<Rule Id="CA1028" Action="None" />
|
||||||
|
<Rule Id="CA1031" Action="None" />
|
||||||
|
<Rule Id="CA1034" Action="None" />
|
||||||
|
<Rule Id="CA1036" Action="None" />
|
||||||
|
<Rule Id="CA1040" Action="None" />
|
||||||
|
<Rule Id="CA1044" Action="None" />
|
||||||
|
<Rule Id="CA1051" Action="None" />
|
||||||
|
<Rule Id="CA1054" Action="None" />
|
||||||
|
<Rule Id="CA1056" Action="None" />
|
||||||
|
<Rule Id="CA1062" Action="None" />
|
||||||
|
<Rule Id="CA1063" Action="None" />
|
||||||
|
<Rule Id="CA1067" Action="None" />
|
||||||
|
<Rule Id="CA1707" Action="None" />
|
||||||
|
<Rule Id="CA1710" Action="None" />
|
||||||
|
<Rule Id="CA1714" Action="None" />
|
||||||
|
<Rule Id="CA1716" Action="None" />
|
||||||
|
<Rule Id="CA1717" Action="None" />
|
||||||
|
<Rule Id="CA1720" Action="None" />
|
||||||
|
<Rule Id="CA1721" Action="None" />
|
||||||
|
<Rule Id="CA1724" Action="None" />
|
||||||
|
<Rule Id="CA1801" Action="None" />
|
||||||
|
<Rule Id="CA1806" Action="None" />
|
||||||
|
<Rule Id="CA1812" Action="None" />
|
||||||
|
<Rule Id="CA1814" Action="None" />
|
||||||
|
<Rule Id="CA1815" Action="None" />
|
||||||
|
<Rule Id="CA1819" Action="None" />
|
||||||
|
<Rule Id="CA1822" Action="None" />
|
||||||
|
<Rule Id="CA1823" Action="None" />
|
||||||
|
<Rule Id="CA2007" Action="None" />
|
||||||
|
<Rule Id="CA2214" Action="None" />
|
||||||
|
<Rule Id="CA2227" Action="None" />
|
||||||
|
</Rules>
|
||||||
|
<Rules AnalyzerId="Microsoft.CodeQuality.CSharp.Analyzers" RuleNamespace="Microsoft.CodeQuality.CSharp.Analyzers">
|
||||||
|
<Rule Id="CA1001" Action="None" />
|
||||||
|
<Rule Id="CA1032" Action="None" />
|
||||||
|
</Rules>
|
||||||
|
<Rules AnalyzerId="Microsoft.NetCore.Analyzers" RuleNamespace="Microsoft.NetCore.Analyzers">
|
||||||
|
<Rule Id="CA1303" Action="None" />
|
||||||
|
<Rule Id="CA1304" Action="None" />
|
||||||
|
<Rule Id="CA1305" Action="None" />
|
||||||
|
<Rule Id="CA1307" Action="None" />
|
||||||
|
<Rule Id="CA1308" Action="None" />
|
||||||
|
<Rule Id="CA1816" Action="None" />
|
||||||
|
<Rule Id="CA1826" Action="None" />
|
||||||
|
<Rule Id="CA2000" Action="None" />
|
||||||
|
<Rule Id="CA2008" Action="None" />
|
||||||
|
<Rule Id="CA2213" Action="None" />
|
||||||
|
<Rule Id="CA2235" Action="None" />
|
||||||
|
</Rules>
|
||||||
|
<Rules AnalyzerId="Microsoft.NetCore.CSharp.Analyzers" RuleNamespace="Microsoft.NetCore.CSharp.Analyzers">
|
||||||
|
<Rule Id="CA1309" Action="Warning" />
|
||||||
|
<Rule Id="CA2201" Action="Warning" />
|
||||||
|
</Rules>
|
||||||
|
</RuleSet>
|
@ -18,7 +18,11 @@
|
|||||||
<ItemGroup Label="Code Analysis">
|
<ItemGroup Label="Code Analysis">
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="2.9.8" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="2.9.8" PrivateAssets="All" />
|
||||||
<AdditionalFiles Include="$(MSBuildThisFileDirectory)CodeAnalysis\BannedSymbols.txt" />
|
<AdditionalFiles Include="$(MSBuildThisFileDirectory)CodeAnalysis\BannedSymbols.txt" />
|
||||||
|
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="2.9.8" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
<PropertyGroup Label="Code Analysis">
|
||||||
|
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodeAnalysis\osu.ruleset</CodeAnalysisRuleSet>
|
||||||
|
</PropertyGroup>
|
||||||
<PropertyGroup Label="Documentation">
|
<PropertyGroup Label="Documentation">
|
||||||
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
<GenerateDocumentationFile>true</GenerateDocumentationFile>
|
||||||
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
<NoWarn>$(NoWarn);CS1591</NoWarn>
|
||||||
|
@ -21,9 +21,9 @@ Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh
|
|||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- A desktop platform with the [.NET Core SDK 3.0](https://www.microsoft.com/net/learn/get-started) or higher installed.
|
- A desktop platform with the [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download) or higher installed.
|
||||||
- When running on Linux, please have a system-wide FFmpeg installation available to support video decoding.
|
- When running on Linux, please have a system-wide FFmpeg installation available to support video decoding.
|
||||||
- When running on Windows 7 or 8.1, **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/install/dependencies?tabs=netcore30&pivots=os-windows)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs.
|
- When running on Windows 7 or 8.1, **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/install/dependencies?tabs=netcore31&pivots=os-windows)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs.
|
||||||
- When developing with mobile, [Xamarin](https://docs.microsoft.com/en-us/xamarin/) is required, which is shipped together with Visual Studio or [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/).
|
- When developing with mobile, [Xamarin](https://docs.microsoft.com/en-us/xamarin/) is required, which is shipped together with Visual Studio or [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/).
|
||||||
- When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as [Visual Studio 2019+](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/).
|
- When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as [Visual Studio 2019+](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/).
|
||||||
|
|
||||||
@ -35,7 +35,7 @@ If you are not interested in developing the game, you can still consume our [bin
|
|||||||
|
|
||||||
**Latest build:**
|
**Latest build:**
|
||||||
|
|
||||||
| [Windows (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) | [iOS(iOS 10+)](https://testflight.apple.com/join/2tLcjWlF) | [Android (5+)](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk)
|
| [Windows (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) | [iOS(iOS 10+)](https://osu.ppy.sh/home/testflight) | [Android (5+)](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk)
|
||||||
| ------------- | ------------- | ------------- | ------------- |
|
| ------------- | ------------- | ------------- | ------------- |
|
||||||
|
|
||||||
- **Linux** users are recommended to self-compile until we have official deployment in place.
|
- **Linux** users are recommended to self-compile until we have official deployment in place.
|
||||||
|
@ -53,7 +53,7 @@
|
|||||||
<Reference Include="Java.Interop" />
|
<Reference Include="Java.Interop" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1215.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2019.1230.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2019.1215.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2020.111.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
"path": "osu.sln",
|
"path": "osu.sln",
|
||||||
"projects": [
|
"projects": [
|
||||||
"osu.Desktop\\osu.Desktop.csproj",
|
"osu.Desktop\\osu.Desktop.csproj",
|
||||||
|
"osu.Game.Benchmarks\\osu.Game.Benchmarks.csproj",
|
||||||
"osu.Game.Rulesets.Catch.Tests\\osu.Game.Rulesets.Catch.Tests.csproj",
|
"osu.Game.Rulesets.Catch.Tests\\osu.Game.Rulesets.Catch.Tests.csproj",
|
||||||
"osu.Game.Rulesets.Catch\\osu.Game.Rulesets.Catch.csproj",
|
"osu.Game.Rulesets.Catch\\osu.Game.Rulesets.Catch.csproj",
|
||||||
"osu.Game.Rulesets.Mania.Tests\\osu.Game.Rulesets.Mania.Tests.csproj",
|
"osu.Game.Rulesets.Mania.Tests\\osu.Game.Rulesets.Mania.Tests.csproj",
|
||||||
|
149
osu.Desktop/DiscordRichPresence.cs
Normal file
149
osu.Desktop/DiscordRichPresence.cs
Normal file
@ -0,0 +1,149 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Text;
|
||||||
|
using DiscordRPC;
|
||||||
|
using DiscordRPC.Message;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Logging;
|
||||||
|
using osu.Game.Online.API;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using LogLevel = osu.Framework.Logging.LogLevel;
|
||||||
|
using User = osu.Game.Users.User;
|
||||||
|
|
||||||
|
namespace osu.Desktop
|
||||||
|
{
|
||||||
|
internal class DiscordRichPresence : Component
|
||||||
|
{
|
||||||
|
private const string client_id = "367827983903490050";
|
||||||
|
|
||||||
|
private DiscordRpcClient client;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private IBindable<RulesetInfo> ruleset { get; set; }
|
||||||
|
|
||||||
|
private Bindable<User> user;
|
||||||
|
|
||||||
|
private readonly IBindable<UserStatus> status = new Bindable<UserStatus>();
|
||||||
|
private readonly IBindable<UserActivity> activity = new Bindable<UserActivity>();
|
||||||
|
|
||||||
|
private readonly RichPresence presence = new RichPresence
|
||||||
|
{
|
||||||
|
Assets = new Assets { LargeImageKey = "osu_logo_lazer", }
|
||||||
|
};
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(IAPIProvider provider)
|
||||||
|
{
|
||||||
|
client = new DiscordRpcClient(client_id)
|
||||||
|
{
|
||||||
|
SkipIdenticalPresence = false // handles better on discord IPC loss, see updateStatus call in onReady.
|
||||||
|
};
|
||||||
|
|
||||||
|
client.OnReady += onReady;
|
||||||
|
|
||||||
|
// safety measure for now, until we performance test / improve backoff for failed connections.
|
||||||
|
client.OnConnectionFailed += (_, __) => client.Deinitialize();
|
||||||
|
|
||||||
|
client.OnError += (_, e) => Logger.Log($"An error occurred with Discord RPC Client: {e.Code} {e.Message}", LoggingTarget.Network);
|
||||||
|
|
||||||
|
(user = provider.LocalUser.GetBoundCopy()).BindValueChanged(u =>
|
||||||
|
{
|
||||||
|
status.UnbindBindings();
|
||||||
|
status.BindTo(u.NewValue.Status);
|
||||||
|
|
||||||
|
activity.UnbindBindings();
|
||||||
|
activity.BindTo(u.NewValue.Activity);
|
||||||
|
}, true);
|
||||||
|
|
||||||
|
ruleset.BindValueChanged(_ => updateStatus());
|
||||||
|
status.BindValueChanged(_ => updateStatus());
|
||||||
|
activity.BindValueChanged(_ => updateStatus());
|
||||||
|
|
||||||
|
client.Initialize();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void onReady(object _, ReadyMessage __)
|
||||||
|
{
|
||||||
|
Logger.Log("Discord RPC Client ready.", LoggingTarget.Network, LogLevel.Debug);
|
||||||
|
updateStatus();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateStatus()
|
||||||
|
{
|
||||||
|
if (!client.IsInitialized)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (status.Value is UserStatusOffline)
|
||||||
|
{
|
||||||
|
client.ClearPresence();
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (status.Value is UserStatusOnline && activity.Value != null)
|
||||||
|
{
|
||||||
|
presence.State = truncate(activity.Value.Status);
|
||||||
|
presence.Details = truncate(getDetails(activity.Value));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
presence.State = "Idle";
|
||||||
|
presence.Details = string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
// update user information
|
||||||
|
presence.Assets.LargeImageText = $"{user.Value.Username}" + (user.Value.Statistics?.Ranks.Global > 0 ? $" (rank #{user.Value.Statistics.Ranks.Global:N0})" : string.Empty);
|
||||||
|
|
||||||
|
// update ruleset
|
||||||
|
presence.Assets.SmallImageKey = ruleset.Value.ID <= 3 ? $"mode_{ruleset.Value.ID}" : "mode_custom";
|
||||||
|
presence.Assets.SmallImageText = ruleset.Value.Name;
|
||||||
|
|
||||||
|
client.SetPresence(presence);
|
||||||
|
}
|
||||||
|
|
||||||
|
private static readonly int ellipsis_length = Encoding.UTF8.GetByteCount(new[] { '…' });
|
||||||
|
|
||||||
|
private string truncate(string str)
|
||||||
|
{
|
||||||
|
if (Encoding.UTF8.GetByteCount(str) <= 128)
|
||||||
|
return str;
|
||||||
|
|
||||||
|
ReadOnlyMemory<char> strMem = str.AsMemory();
|
||||||
|
|
||||||
|
do
|
||||||
|
{
|
||||||
|
strMem = strMem[..^1];
|
||||||
|
} while (Encoding.UTF8.GetByteCount(strMem.Span) + ellipsis_length > 128);
|
||||||
|
|
||||||
|
return string.Create(strMem.Length + 1, strMem, (span, mem) =>
|
||||||
|
{
|
||||||
|
mem.Span.CopyTo(span);
|
||||||
|
span[^1] = '…';
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private string getDetails(UserActivity activity)
|
||||||
|
{
|
||||||
|
switch (activity)
|
||||||
|
{
|
||||||
|
case UserActivity.SoloGame solo:
|
||||||
|
return solo.Beatmap.ToString();
|
||||||
|
|
||||||
|
case UserActivity.Editing edit:
|
||||||
|
return edit.Beatmap.ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
return string.Empty;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Dispose(bool isDisposing)
|
||||||
|
{
|
||||||
|
client.Dispose();
|
||||||
|
base.Dispose(isDisposing);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -60,6 +60,8 @@ namespace osu.Desktop
|
|||||||
else
|
else
|
||||||
Add(new SimpleUpdateManager());
|
Add(new SimpleUpdateManager());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
LoadComponentAsync(new DiscordRichPresence(), Add);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ScreenChanged(IScreen lastScreen, IScreen newScreen)
|
protected override void ScreenChanged(IScreen lastScreen, IScreen newScreen)
|
||||||
|
@ -22,8 +22,9 @@ namespace osu.Desktop
|
|||||||
{
|
{
|
||||||
// Back up the cwd before DesktopGameHost changes it
|
// Back up the cwd before DesktopGameHost changes it
|
||||||
var cwd = Environment.CurrentDirectory;
|
var cwd = Environment.CurrentDirectory;
|
||||||
|
bool useSdl = args.Contains("--sdl");
|
||||||
|
|
||||||
using (DesktopGameHost host = Host.GetSuitableHost(@"osu", true))
|
using (DesktopGameHost host = Host.GetSuitableHost(@"osu", true, useSdl: useSdl))
|
||||||
{
|
{
|
||||||
host.ExceptionThrown += handleException;
|
host.ExceptionThrown += handleException;
|
||||||
|
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||||
<Description>click the circles. to the beat.</Description>
|
<Description>click the circles. to the beat.</Description>
|
||||||
@ -29,6 +29,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.Win32.Registry" Version="4.7.0" />
|
<PackageReference Include="Microsoft.Win32.Registry" Version="4.7.0" />
|
||||||
|
<PackageReference Include="DiscordRichPresence" Version="1.0.121" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Resources">
|
<ItemGroup Label="Resources">
|
||||||
<EmbeddedResource Include="lazer.ico" />
|
<EmbeddedResource Include="lazer.ico" />
|
||||||
|
37
osu.Game.Benchmarks/BenchmarkBeatmapParsing.cs
Normal file
37
osu.Game.Benchmarks/BenchmarkBeatmapParsing.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using osu.Framework.IO.Stores;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.Formats;
|
||||||
|
using osu.Game.IO;
|
||||||
|
using osu.Game.IO.Archives;
|
||||||
|
using osu.Game.Resources;
|
||||||
|
|
||||||
|
namespace osu.Game.Benchmarks
|
||||||
|
{
|
||||||
|
public class BenchmarkBeatmapParsing : BenchmarkTest
|
||||||
|
{
|
||||||
|
private readonly MemoryStream beatmapStream = new MemoryStream();
|
||||||
|
|
||||||
|
public override void SetUp()
|
||||||
|
{
|
||||||
|
using (var resources = new DllResourceStore(OsuResources.ResourceAssembly))
|
||||||
|
using (var archive = resources.GetStream("Beatmaps/241526 Soleily - Renatus.osz"))
|
||||||
|
using (var reader = new ZipArchiveReader(archive))
|
||||||
|
reader.GetStream("Soleily - Renatus (Gamu) [Insane].osu").CopyTo(beatmapStream);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public Beatmap BenchmarkBundledBeatmap()
|
||||||
|
{
|
||||||
|
beatmapStream.Seek(0, SeekOrigin.Begin);
|
||||||
|
var reader = new LineBufferedReader(beatmapStream); // no disposal
|
||||||
|
|
||||||
|
var decoder = Decoder.GetDecoder<Beatmap>(reader);
|
||||||
|
return decoder.Decode(reader);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
23
osu.Game.Benchmarks/BenchmarkTest.cs
Normal file
23
osu.Game.Benchmarks/BenchmarkTest.cs
Normal file
@ -0,0 +1,23 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using BenchmarkDotNet.Running;
|
||||||
|
using NUnit.Framework;
|
||||||
|
|
||||||
|
namespace osu.Game.Benchmarks
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
[MemoryDiagnoser]
|
||||||
|
public abstract class BenchmarkTest
|
||||||
|
{
|
||||||
|
[GlobalSetup]
|
||||||
|
[OneTimeSetUp]
|
||||||
|
public virtual void SetUp()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void RunBenchmark() => BenchmarkRunner.Run(GetType());
|
||||||
|
}
|
||||||
|
}
|
17
osu.Game.Benchmarks/Program.cs
Normal file
17
osu.Game.Benchmarks/Program.cs
Normal file
@ -0,0 +1,17 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using BenchmarkDotNet.Running;
|
||||||
|
|
||||||
|
namespace osu.Game.Benchmarks
|
||||||
|
{
|
||||||
|
public static class Program
|
||||||
|
{
|
||||||
|
public static void Main(string[] args)
|
||||||
|
{
|
||||||
|
BenchmarkSwitcher
|
||||||
|
.FromAssembly(typeof(Program).Assembly)
|
||||||
|
.Run(args);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
8
osu.Game.Benchmarks/Properties/launchSettings.json
Normal file
8
osu.Game.Benchmarks/Properties/launchSettings.json
Normal file
@ -0,0 +1,8 @@
|
|||||||
|
{
|
||||||
|
"profiles": {
|
||||||
|
"All Benchmarks": {
|
||||||
|
"commandName": "Project",
|
||||||
|
"commandLineArgs": "--filter *"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
19
osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
Normal file
19
osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
|
|
||||||
|
<PropertyGroup>
|
||||||
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
|
<OutputType>Exe</OutputType>
|
||||||
|
<IsPackable>false</IsPackable>
|
||||||
|
</PropertyGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<PackageReference Include="BenchmarkDotNet" Version="0.12.0" />
|
||||||
|
<PackageReference Include="nunit" Version="3.12.0" />
|
||||||
|
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
<ItemGroup>
|
||||||
|
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
||||||
|
</ItemGroup>
|
||||||
|
|
||||||
|
</Project>
|
@ -5,7 +5,7 @@ using UIKit;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests.iOS
|
namespace osu.Game.Rulesets.Catch.Tests.iOS
|
||||||
{
|
{
|
||||||
public class Application
|
public static class Application
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Catch.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Catch.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug)",
|
"preLaunchTask": "Build (Debug)",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Release/netcoreapp3.0/osu.Game.Rulesets.Catch.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp3.1/osu.Game.Rulesets.Catch.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release)",
|
"preLaunchTask": "Build (Release)",
|
||||||
|
@ -5,7 +5,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets.Catch.Mods;
|
using osu.Game.Rulesets.Catch.Mods;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.UI;
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
|
@ -9,7 +9,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System;
|
using System.Linq;
|
||||||
using osu.Game.Rulesets.Catch.UI;
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
@ -14,12 +14,12 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
{
|
{
|
||||||
public class CatchBeatmapConverter : BeatmapConverter<CatchHitObject>
|
public class CatchBeatmapConverter : BeatmapConverter<CatchHitObject>
|
||||||
{
|
{
|
||||||
public CatchBeatmapConverter(IBeatmap beatmap)
|
public CatchBeatmapConverter(IBeatmap beatmap, Ruleset ruleset)
|
||||||
: base(beatmap)
|
: base(beatmap, ruleset)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasXPosition);
|
||||||
|
|
||||||
protected override IEnumerable<CatchHitObject> ConvertHitObject(HitObject obj, IBeatmap beatmap)
|
protected override IEnumerable<CatchHitObject> ConvertHitObject(HitObject obj, IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
|
@ -16,15 +16,22 @@ using osu.Game.Rulesets.Replays.Types;
|
|||||||
using osu.Game.Beatmaps.Legacy;
|
using osu.Game.Beatmaps.Legacy;
|
||||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Difficulty;
|
using osu.Game.Rulesets.Catch.Difficulty;
|
||||||
|
using osu.Game.Rulesets.Catch.Scoring;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
using System;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch
|
namespace osu.Game.Rulesets.Catch
|
||||||
{
|
{
|
||||||
public class CatchRuleset : Ruleset
|
public class CatchRuleset : Ruleset, ILegacyRuleset
|
||||||
{
|
{
|
||||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableCatchRuleset(this, beatmap, mods);
|
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableCatchRuleset(this, beatmap, mods);
|
||||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
|
|
||||||
|
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor();
|
||||||
|
|
||||||
|
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap, this);
|
||||||
|
|
||||||
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap);
|
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap);
|
||||||
|
|
||||||
public const string SHORT_NAME = "fruits";
|
public const string SHORT_NAME = "fruits";
|
||||||
@ -100,6 +107,12 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
new CatchModFlashlight(),
|
new CatchModFlashlight(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case ModType.Conversion:
|
||||||
|
return new Mod[]
|
||||||
|
{
|
||||||
|
new CatchModDifficultyAdjust(),
|
||||||
|
};
|
||||||
|
|
||||||
case ModType.Automation:
|
case ModType.Automation:
|
||||||
return new Mod[]
|
return new Mod[]
|
||||||
{
|
{
|
||||||
@ -114,7 +127,7 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
};
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return new Mod[] { };
|
return Array.Empty<Mod>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -122,19 +135,16 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
|
|
||||||
public override string ShortName => SHORT_NAME;
|
public override string ShortName => SHORT_NAME;
|
||||||
|
|
||||||
|
public override string PlayingVerb => "Catching fruit";
|
||||||
|
|
||||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch };
|
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch };
|
||||||
|
|
||||||
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(this, beatmap);
|
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(this, beatmap);
|
||||||
|
|
||||||
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new CatchPerformanceCalculator(this, beatmap, score);
|
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new CatchPerformanceCalculator(this, beatmap, score);
|
||||||
|
|
||||||
public override int? LegacyID => 2;
|
public int LegacyID => 2;
|
||||||
|
|
||||||
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new CatchReplayFrame();
|
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new CatchReplayFrame();
|
||||||
|
|
||||||
public CatchRuleset(RulesetInfo rulesetInfo = null)
|
|
||||||
: base(rulesetInfo)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case HitResult.Perfect:
|
case HitResult.Perfect:
|
||||||
return 0.008;
|
return 0.01;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,17 +18,5 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
|||||||
return 30;
|
return 30;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override double HealthIncreaseFor(HitResult result)
|
|
||||||
{
|
|
||||||
switch (result)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
return base.HealthIncreaseFor(result);
|
|
||||||
|
|
||||||
case HitResult.Perfect:
|
|
||||||
return 0.007;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -23,18 +23,6 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override double HealthIncreaseFor(HitResult result)
|
|
||||||
{
|
|
||||||
switch (result)
|
|
||||||
{
|
|
||||||
default:
|
|
||||||
return -0.02;
|
|
||||||
|
|
||||||
case HitResult.Perfect:
|
|
||||||
return 0.01;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether fruit on the platter should explode or drop.
|
/// Whether fruit on the platter should explode or drop.
|
||||||
/// Note that this is only checked if the owning object is also <see cref="IHasComboInformation.LastInCombo" />
|
/// Note that this is only checked if the owning object is also <see cref="IHasComboInformation.LastInCombo" />
|
||||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
|||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
case HitResult.Perfect:
|
case HitResult.Perfect:
|
||||||
return 0.004;
|
return 0.02;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
49
osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs
Normal file
49
osu.Game.Rulesets.Catch/Mods/CatchModDifficultyAdjust.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
|
{
|
||||||
|
public class CatchModDifficultyAdjust : ModDifficultyAdjust
|
||||||
|
{
|
||||||
|
[SettingSource("Fruit Size", "Override a beatmap's set CS.")]
|
||||||
|
public BindableNumber<float> CircleSize { get; } = new BindableFloat
|
||||||
|
{
|
||||||
|
Precision = 0.1f,
|
||||||
|
MinValue = 1,
|
||||||
|
MaxValue = 10,
|
||||||
|
Default = 5,
|
||||||
|
Value = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
[SettingSource("Approach Rate", "Override a beatmap's set AR.")]
|
||||||
|
public BindableNumber<float> ApproachRate { get; } = new BindableFloat
|
||||||
|
{
|
||||||
|
Precision = 0.1f,
|
||||||
|
MinValue = 1,
|
||||||
|
MaxValue = 10,
|
||||||
|
Default = 5,
|
||||||
|
Value = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override void TransferSettings(BeatmapDifficulty difficulty)
|
||||||
|
{
|
||||||
|
base.TransferSettings(difficulty);
|
||||||
|
|
||||||
|
TransferSetting(CircleSize, difficulty.CircleSize);
|
||||||
|
TransferSetting(ApproachRate, difficulty.ApproachRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplySettings(BeatmapDifficulty difficulty)
|
||||||
|
{
|
||||||
|
base.ApplySettings(difficulty);
|
||||||
|
|
||||||
|
difficulty.CircleSize = CircleSize.Value;
|
||||||
|
difficulty.ApproachRate = ApproachRate.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,12 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Mods
|
namespace osu.Game.Rulesets.Catch.Mods
|
||||||
{
|
{
|
||||||
public class CatchModNightcore : ModNightcore
|
public class CatchModNightcore : ModNightcore<CatchHitObject>
|
||||||
{
|
{
|
||||||
public override double ScoreMultiplier => 1.06;
|
public override double ScoreMultiplier => 1.06;
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
|
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
@ -3,7 +3,7 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Replays;
|
using osu.Game.Replays;
|
||||||
using osu.Game.Rulesets.Catch.Beatmaps;
|
using osu.Game.Rulesets.Catch.Beatmaps;
|
||||||
|
@ -5,7 +5,7 @@ using System.Collections.Generic;
|
|||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Input.StateChanges;
|
using osu.Framework.Input.StateChanges;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Replays;
|
using osu.Game.Replays;
|
||||||
using osu.Game.Rulesets.Replays;
|
using osu.Game.Rulesets.Replays;
|
||||||
|
|
||||||
|
@ -1,40 +1,12 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Scoring
|
namespace osu.Game.Rulesets.Catch.Scoring
|
||||||
{
|
{
|
||||||
public class CatchScoreProcessor : ScoreProcessor
|
public class CatchScoreProcessor : ScoreProcessor
|
||||||
{
|
{
|
||||||
public CatchScoreProcessor(IBeatmap beatmap)
|
|
||||||
: base(beatmap)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
private float hpDrainRate;
|
|
||||||
|
|
||||||
protected override void ApplyBeatmap(IBeatmap beatmap)
|
|
||||||
{
|
|
||||||
base.ApplyBeatmap(beatmap);
|
|
||||||
|
|
||||||
hpDrainRate = beatmap.BeatmapInfo.BaseDifficulty.DrainRate;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override double HealthAdjustmentFactorFor(JudgementResult result)
|
|
||||||
{
|
|
||||||
switch (result.Type)
|
|
||||||
{
|
|
||||||
case HitResult.Miss:
|
|
||||||
return hpDrainRate;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 10.2 - hpDrainRate; // Award less HP as drain rate is increased
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
public override HitWindows CreateHitWindows() => new CatchHitWindows();
|
public override HitWindows CreateHitWindows() => new CatchHitWindows();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Judgements;
|
using osu.Game.Rulesets.Catch.Judgements;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
@ -10,10 +10,8 @@ using osu.Game.Replays;
|
|||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
using osu.Game.Rulesets.Catch.Objects.Drawable;
|
||||||
using osu.Game.Rulesets.Catch.Replays;
|
using osu.Game.Rulesets.Catch.Replays;
|
||||||
using osu.Game.Rulesets.Catch.Scoring;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
|
||||||
@ -32,8 +30,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
|
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override ScoreProcessor CreateScoreProcessor() => new CatchScoreProcessor(Beatmap);
|
|
||||||
|
|
||||||
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay);
|
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay);
|
||||||
|
|
||||||
protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, CreateDrawableRepresentation);
|
protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, CreateDrawableRepresentation);
|
||||||
|
@ -5,7 +5,7 @@ using UIKit;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Tests.iOS
|
namespace osu.Game.Rulesets.Mania.Tests.iOS
|
||||||
{
|
{
|
||||||
public class Application
|
public static class Application
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Mania.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Mania.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug)",
|
"preLaunchTask": "Build (Debug)",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Release/netcoreapp3.0/osu.Game.Rulesets.Mania.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp3.1/osu.Game.Rulesets.Mania.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release)",
|
"preLaunchTask": "Build (Release)",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
46
osu.Game.Rulesets.Mania.Tests/SkinnableTestScene.cs
Normal file
46
osu.Game.Rulesets.Mania.Tests/SkinnableTestScene.cs
Normal file
@ -0,0 +1,46 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
|
{
|
||||||
|
public abstract class SkinnableTestScene : OsuGridTestScene
|
||||||
|
{
|
||||||
|
private Skin defaultSkin;
|
||||||
|
|
||||||
|
protected SkinnableTestScene()
|
||||||
|
: base(1, 2)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(AudioManager audio, SkinManager skinManager)
|
||||||
|
{
|
||||||
|
defaultSkin = skinManager.GetSkin(DefaultLegacySkin.Info);
|
||||||
|
}
|
||||||
|
|
||||||
|
public void SetContents(Func<Drawable> creationFunction)
|
||||||
|
{
|
||||||
|
Cell(0).Child = createProvider(null, creationFunction);
|
||||||
|
Cell(1).Child = createProvider(defaultSkin, creationFunction);
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable createProvider(Skin skin, Func<Drawable> creationFunction)
|
||||||
|
{
|
||||||
|
var mainProvider = new SkinProvidingContainer(skin);
|
||||||
|
|
||||||
|
return mainProvider
|
||||||
|
.WithChild(new SkinProvidingContainer(Ruleset.Value.CreateInstance().CreateLegacySkinProvider(mainProvider))
|
||||||
|
{
|
||||||
|
Child = creationFunction()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
37
osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs
Normal file
37
osu.Game.Rulesets.Mania.Tests/TestSceneDrawableJudgement.cs
Normal file
@ -0,0 +1,37 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
|
{
|
||||||
|
public class TestSceneDrawableJudgement : SkinnableTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(DrawableJudgement),
|
||||||
|
typeof(DrawableManiaJudgement)
|
||||||
|
};
|
||||||
|
|
||||||
|
public TestSceneDrawableJudgement()
|
||||||
|
{
|
||||||
|
foreach (HitResult result in Enum.GetValues(typeof(HitResult)).OfType<HitResult>().Skip(1))
|
||||||
|
{
|
||||||
|
AddStep("Show " + result.GetDescription(), () => SetContents(() =>
|
||||||
|
new DrawableManiaJudgement(new JudgementResult(new HitObject(), new Judgement()) { Type = result }, null)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
314
osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs
Normal file
314
osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteInput.cs
Normal file
@ -0,0 +1,314 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Screens;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Replays;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.Replays;
|
||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
|
{
|
||||||
|
public class TestSceneHoldNoteInput : RateAdjustedBeatmapTestScene
|
||||||
|
{
|
||||||
|
private const double time_before_head = 250;
|
||||||
|
private const double time_head = 1500;
|
||||||
|
private const double time_during_hold_1 = 2500;
|
||||||
|
private const double time_tail = 4000;
|
||||||
|
private const double time_after_tail = 5250;
|
||||||
|
|
||||||
|
private List<JudgementResult> judgementResults;
|
||||||
|
private bool allJudgedFired;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// -----[ ]-----
|
||||||
|
/// o o
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestNoInput()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(time_before_head),
|
||||||
|
new ManiaReplayFrame(time_after_tail),
|
||||||
|
});
|
||||||
|
|
||||||
|
assertHeadJudgement(HitResult.Miss);
|
||||||
|
assertTickJudgement(HitResult.Miss);
|
||||||
|
assertTailJudgement(HitResult.Miss);
|
||||||
|
assertNoteJudgement(HitResult.Perfect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// -----[ ]-----
|
||||||
|
/// x o
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestPressTooEarlyAndReleaseAfterTail()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(time_before_head, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_after_tail, ManiaAction.Key1),
|
||||||
|
});
|
||||||
|
|
||||||
|
assertHeadJudgement(HitResult.Miss);
|
||||||
|
assertTickJudgement(HitResult.Miss);
|
||||||
|
assertTailJudgement(HitResult.Miss);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// -----[ ]-----
|
||||||
|
/// x o
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestPressTooEarlyAndReleaseAtTail()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(time_before_head, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_tail),
|
||||||
|
});
|
||||||
|
|
||||||
|
assertHeadJudgement(HitResult.Miss);
|
||||||
|
assertTickJudgement(HitResult.Miss);
|
||||||
|
assertTailJudgement(HitResult.Miss);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// -----[ ]-----
|
||||||
|
/// xo x o
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestPressTooEarlyThenPressAtStartAndReleaseAfterTail()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(time_before_head, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_before_head + 10),
|
||||||
|
new ManiaReplayFrame(time_head, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_after_tail),
|
||||||
|
});
|
||||||
|
|
||||||
|
assertHeadJudgement(HitResult.Perfect);
|
||||||
|
assertTickJudgement(HitResult.Perfect);
|
||||||
|
assertTailJudgement(HitResult.Miss);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// -----[ ]-----
|
||||||
|
/// xo x o
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestPressTooEarlyThenPressAtStartAndReleaseAtTail()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(time_before_head, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_before_head + 10),
|
||||||
|
new ManiaReplayFrame(time_head, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_tail),
|
||||||
|
});
|
||||||
|
|
||||||
|
assertHeadJudgement(HitResult.Perfect);
|
||||||
|
assertTickJudgement(HitResult.Perfect);
|
||||||
|
assertTailJudgement(HitResult.Perfect);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// -----[ ]-----
|
||||||
|
/// xo o
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestPressAtStartAndBreak()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(time_head, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_head + 10),
|
||||||
|
new ManiaReplayFrame(time_after_tail),
|
||||||
|
});
|
||||||
|
|
||||||
|
assertHeadJudgement(HitResult.Perfect);
|
||||||
|
assertTickJudgement(HitResult.Miss);
|
||||||
|
assertTailJudgement(HitResult.Miss);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// -----[ ]-----
|
||||||
|
/// xo x o
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestPressAtStartThenBreakThenRepressAndReleaseAfterTail()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(time_head, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_head + 10),
|
||||||
|
new ManiaReplayFrame(time_during_hold_1, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_after_tail),
|
||||||
|
});
|
||||||
|
|
||||||
|
assertHeadJudgement(HitResult.Perfect);
|
||||||
|
assertTickJudgement(HitResult.Perfect);
|
||||||
|
assertTailJudgement(HitResult.Miss);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// -----[ ]-----
|
||||||
|
/// xo x o o
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestPressAtStartThenBreakThenRepressAndReleaseAtTail()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(time_head, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_head + 10),
|
||||||
|
new ManiaReplayFrame(time_during_hold_1, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_tail),
|
||||||
|
});
|
||||||
|
|
||||||
|
assertHeadJudgement(HitResult.Perfect);
|
||||||
|
assertTickJudgement(HitResult.Perfect);
|
||||||
|
assertTailJudgement(HitResult.Meh);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// -----[ ]-----
|
||||||
|
/// x o
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestPressDuringNoteAndReleaseAfterTail()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(time_during_hold_1, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_after_tail),
|
||||||
|
});
|
||||||
|
|
||||||
|
assertHeadJudgement(HitResult.Miss);
|
||||||
|
assertTickJudgement(HitResult.Perfect);
|
||||||
|
assertTailJudgement(HitResult.Miss);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// -----[ ]-----
|
||||||
|
/// x o o
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestPressDuringNoteAndReleaseAtTail()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(time_during_hold_1, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_tail),
|
||||||
|
});
|
||||||
|
|
||||||
|
assertHeadJudgement(HitResult.Miss);
|
||||||
|
assertTickJudgement(HitResult.Perfect);
|
||||||
|
assertTailJudgement(HitResult.Meh);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// -----[ ]-----
|
||||||
|
/// xo o
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestPressAndReleaseAtTail()
|
||||||
|
{
|
||||||
|
performTest(new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new ManiaReplayFrame(time_tail, ManiaAction.Key1),
|
||||||
|
new ManiaReplayFrame(time_tail + 10),
|
||||||
|
});
|
||||||
|
|
||||||
|
assertHeadJudgement(HitResult.Miss);
|
||||||
|
assertTickJudgement(HitResult.Miss);
|
||||||
|
assertTailJudgement(HitResult.Meh);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertHeadJudgement(HitResult result)
|
||||||
|
=> AddAssert($"head judged as {result}", () => judgementResults[0].Type == result);
|
||||||
|
|
||||||
|
private void assertTailJudgement(HitResult result)
|
||||||
|
=> AddAssert($"tail judged as {result}", () => judgementResults[^2].Type == result);
|
||||||
|
|
||||||
|
private void assertNoteJudgement(HitResult result)
|
||||||
|
=> AddAssert($"hold note judged as {result}", () => judgementResults[^1].Type == result);
|
||||||
|
|
||||||
|
private void assertTickJudgement(HitResult result)
|
||||||
|
=> AddAssert($"tick judged as {result}", () => judgementResults[6].Type == result); // arbitrary tick
|
||||||
|
|
||||||
|
private ScoreAccessibleReplayPlayer currentPlayer;
|
||||||
|
|
||||||
|
private void performTest(List<ReplayFrame> frames)
|
||||||
|
{
|
||||||
|
AddStep("load player", () =>
|
||||||
|
{
|
||||||
|
Beatmap.Value = CreateWorkingBeatmap(new Beatmap<ManiaHitObject>
|
||||||
|
{
|
||||||
|
HitObjects =
|
||||||
|
{
|
||||||
|
new HoldNote
|
||||||
|
{
|
||||||
|
StartTime = time_head,
|
||||||
|
Duration = time_tail - time_head,
|
||||||
|
Column = 0,
|
||||||
|
}
|
||||||
|
},
|
||||||
|
BeatmapInfo =
|
||||||
|
{
|
||||||
|
BaseDifficulty = new BeatmapDifficulty { SliderTickRate = 4 },
|
||||||
|
Ruleset = new ManiaRuleset().RulesetInfo
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
Beatmap.Value.Beatmap.ControlPointInfo.Add(0, new DifficultyControlPoint { SpeedMultiplier = 0.1f });
|
||||||
|
|
||||||
|
var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } });
|
||||||
|
|
||||||
|
p.OnLoadComplete += _ =>
|
||||||
|
{
|
||||||
|
p.ScoreProcessor.NewJudgement += result =>
|
||||||
|
{
|
||||||
|
if (currentPlayer == p) judgementResults.Add(result);
|
||||||
|
};
|
||||||
|
p.ScoreProcessor.AllJudged += () =>
|
||||||
|
{
|
||||||
|
if (currentPlayer == p) allJudgedFired = true;
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
LoadScreen(currentPlayer = p);
|
||||||
|
allJudgedFired = false;
|
||||||
|
judgementResults = new List<JudgementResult>();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0);
|
||||||
|
AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen());
|
||||||
|
AddUntilStep("Wait for all judged", () => allJudgedFired);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ScoreAccessibleReplayPlayer : ReplayPlayer
|
||||||
|
{
|
||||||
|
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||||
|
|
||||||
|
protected override bool PauseOnFocusLost => false;
|
||||||
|
|
||||||
|
public ScoreAccessibleReplayPlayer(Score score)
|
||||||
|
: base(score, false, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
15
osu.Game.Rulesets.Mania.Tests/TestScenePlayer.cs
Normal file
15
osu.Game.Rulesets.Mania.Tests/TestScenePlayer.cs
Normal file
@ -0,0 +1,15 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Tests
|
||||||
|
{
|
||||||
|
public class TestScenePlayer : PlayerTestScene
|
||||||
|
{
|
||||||
|
public TestScenePlayer()
|
||||||
|
: base(new ManiaRuleset())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
||||||
|
@ -5,7 +5,7 @@ using osu.Game.Rulesets.Mania.Objects;
|
|||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
@ -24,8 +24,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
private const int max_notes_for_density = 7;
|
private const int max_notes_for_density = 7;
|
||||||
|
|
||||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
|
|
||||||
|
|
||||||
public int TargetColumns;
|
public int TargetColumns;
|
||||||
public bool Dual;
|
public bool Dual;
|
||||||
public readonly bool IsForCurrentRuleset;
|
public readonly bool IsForCurrentRuleset;
|
||||||
@ -37,10 +35,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
|
|
||||||
private ManiaBeatmap beatmap;
|
private ManiaBeatmap beatmap;
|
||||||
|
|
||||||
public ManiaBeatmapConverter(IBeatmap beatmap)
|
public ManiaBeatmapConverter(IBeatmap beatmap, Ruleset ruleset)
|
||||||
: base(beatmap)
|
: base(beatmap, ruleset)
|
||||||
{
|
{
|
||||||
IsForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(new ManiaRuleset().RulesetInfo);
|
IsForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(ruleset.RulesetInfo);
|
||||||
|
|
||||||
var roundedCircleSize = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.CircleSize);
|
var roundedCircleSize = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.CircleSize);
|
||||||
var roundedOverallDifficulty = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
|
var roundedOverallDifficulty = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
|
||||||
@ -69,6 +67,8 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasXPosition || h is ManiaHitObject);
|
||||||
|
|
||||||
protected override Beatmap<ManiaHitObject> ConvertBeatmap(IBeatmap original)
|
protected override Beatmap<ManiaHitObject> ConvertBeatmap(IBeatmap original)
|
||||||
{
|
{
|
||||||
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
|
BeatmapDifficulty difficulty = original.BeatmapInfo.BaseDifficulty;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
using osu.Game.Rulesets.Mania.MathUtils;
|
||||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.Edit.Blueprints
|
|||||||
// Todo: This shouldn't exist, mania should not reference the drawable hitobject directly.
|
// Todo: This shouldn't exist, mania should not reference the drawable hitobject directly.
|
||||||
if (DrawableObject.IsLoaded)
|
if (DrawableObject.IsLoaded)
|
||||||
{
|
{
|
||||||
DrawableNote note = position == HoldNotePosition.Start ? DrawableObject.Head : DrawableObject.Tail;
|
DrawableNote note = position == HoldNotePosition.Start ? (DrawableNote)DrawableObject.Head : DrawableObject.Tail;
|
||||||
|
|
||||||
Anchor = note.Anchor;
|
Anchor = note.Anchor;
|
||||||
Origin = note.Origin;
|
Origin = note.Origin;
|
||||||
|
@ -15,11 +15,11 @@ namespace osu.Game.Rulesets.Mania.Judgements
|
|||||||
{
|
{
|
||||||
switch (result)
|
switch (result)
|
||||||
{
|
{
|
||||||
case HitResult.Miss:
|
default:
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
default:
|
case HitResult.Perfect:
|
||||||
return 0.040;
|
return 0.01;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -29,32 +29,5 @@ namespace osu.Game.Rulesets.Mania.Judgements
|
|||||||
return 300;
|
return 300;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override double HealthIncreaseFor(HitResult result)
|
|
||||||
{
|
|
||||||
switch (result)
|
|
||||||
{
|
|
||||||
case HitResult.Miss:
|
|
||||||
return -0.125;
|
|
||||||
|
|
||||||
case HitResult.Meh:
|
|
||||||
return 0.005;
|
|
||||||
|
|
||||||
case HitResult.Ok:
|
|
||||||
return 0.010;
|
|
||||||
|
|
||||||
case HitResult.Good:
|
|
||||||
return 0.035;
|
|
||||||
|
|
||||||
case HitResult.Great:
|
|
||||||
return 0.055;
|
|
||||||
|
|
||||||
case HitResult.Perfect:
|
|
||||||
return 0.065;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,20 +25,30 @@ using osu.Game.Rulesets.Mania.Beatmaps;
|
|||||||
using osu.Game.Rulesets.Mania.Configuration;
|
using osu.Game.Rulesets.Mania.Configuration;
|
||||||
using osu.Game.Rulesets.Mania.Difficulty;
|
using osu.Game.Rulesets.Mania.Difficulty;
|
||||||
using osu.Game.Rulesets.Mania.Edit;
|
using osu.Game.Rulesets.Mania.Edit;
|
||||||
|
using osu.Game.Rulesets.Mania.Scoring;
|
||||||
|
using osu.Game.Rulesets.Mania.Skinning;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Skinning;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania
|
namespace osu.Game.Rulesets.Mania
|
||||||
{
|
{
|
||||||
public class ManiaRuleset : Ruleset
|
public class ManiaRuleset : Ruleset, ILegacyRuleset
|
||||||
{
|
{
|
||||||
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableManiaRuleset(this, beatmap, mods);
|
public override DrawableRuleset CreateDrawableRulesetWith(IBeatmap beatmap, IReadOnlyList<Mod> mods = null) => new DrawableManiaRuleset(this, beatmap, mods);
|
||||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
|
|
||||||
|
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor();
|
||||||
|
|
||||||
|
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap, this);
|
||||||
|
|
||||||
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score);
|
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score);
|
||||||
|
|
||||||
public const string SHORT_NAME = "mania";
|
public const string SHORT_NAME = "mania";
|
||||||
|
|
||||||
public override HitObjectComposer CreateHitObjectComposer() => new ManiaHitObjectComposer(this);
|
public override HitObjectComposer CreateHitObjectComposer() => new ManiaHitObjectComposer(this);
|
||||||
|
|
||||||
|
public override ISkin CreateLegacySkinProvider(ISkinSource source) => new ManiaLegacySkinTransformer(source);
|
||||||
|
|
||||||
public override IEnumerable<Mod> ConvertLegacyMods(LegacyMods mods)
|
public override IEnumerable<Mod> ConvertLegacyMods(LegacyMods mods)
|
||||||
{
|
{
|
||||||
if (mods.HasFlag(LegacyMods.Nightcore))
|
if (mods.HasFlag(LegacyMods.Nightcore))
|
||||||
@ -145,6 +155,7 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
new ManiaModRandom(),
|
new ManiaModRandom(),
|
||||||
new ManiaModDualStages(),
|
new ManiaModDualStages(),
|
||||||
new ManiaModMirror(),
|
new ManiaModMirror(),
|
||||||
|
new ManiaModDifficultyAdjust(),
|
||||||
};
|
};
|
||||||
|
|
||||||
case ModType.Automation:
|
case ModType.Automation:
|
||||||
@ -160,7 +171,7 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
};
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return new Mod[] { };
|
return Array.Empty<Mod>();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -168,11 +179,13 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
|
|
||||||
public override string ShortName => SHORT_NAME;
|
public override string ShortName => SHORT_NAME;
|
||||||
|
|
||||||
|
public override string PlayingVerb => "Smashing keys";
|
||||||
|
|
||||||
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetMania };
|
public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetMania };
|
||||||
|
|
||||||
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(this, beatmap);
|
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(this, beatmap);
|
||||||
|
|
||||||
public override int? LegacyID => 3;
|
public int LegacyID => 3;
|
||||||
|
|
||||||
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new ManiaReplayFrame();
|
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new ManiaReplayFrame();
|
||||||
|
|
||||||
@ -180,11 +193,6 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
|
|
||||||
public override RulesetSettingsSubsection CreateSettings() => new ManiaSettingsSubsection(this);
|
public override RulesetSettingsSubsection CreateSettings() => new ManiaSettingsSubsection(this);
|
||||||
|
|
||||||
public ManiaRuleset(RulesetInfo rulesetInfo = null)
|
|
||||||
: base(rulesetInfo)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
public override IEnumerable<int> AvailableVariants
|
public override IEnumerable<int> AvailableVariants
|
||||||
{
|
{
|
||||||
get
|
get
|
||||||
@ -270,7 +278,7 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
return stage1Bindings.Concat(stage2Bindings);
|
return stage1Bindings.Concat(stage2Bindings);
|
||||||
}
|
}
|
||||||
|
|
||||||
return new KeyBinding[0];
|
return Array.Empty<KeyBinding>();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override string GetVariantName(int variant)
|
public override string GetVariantName(int variant)
|
||||||
|
11
osu.Game.Rulesets.Mania/Mods/ManiaModDifficultyAdjust.cs
Normal file
11
osu.Game.Rulesets.Mania/Mods/ManiaModDifficultyAdjust.cs
Normal file
@ -0,0 +1,11 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public class ManiaModDifficultyAdjust : ModDifficultyAdjust
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
@ -1,11 +1,12 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
public class ManiaModNightcore : ModNightcore
|
public class ManiaModNightcore : ModNightcore<ManiaHitObject>
|
||||||
{
|
{
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
}
|
}
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Beatmaps;
|
using osu.Game.Rulesets.Mania.Beatmaps;
|
||||||
|
@ -1,7 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Diagnostics;
|
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
@ -21,11 +20,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
{
|
{
|
||||||
public override bool DisplayResult => false;
|
public override bool DisplayResult => false;
|
||||||
|
|
||||||
public DrawableNote Head => headContainer.Child;
|
public DrawableHoldNoteHead Head => headContainer.Child;
|
||||||
public DrawableNote Tail => tailContainer.Child;
|
public DrawableHoldNoteTail Tail => tailContainer.Child;
|
||||||
|
|
||||||
private readonly Container<DrawableHeadNote> headContainer;
|
private readonly Container<DrawableHoldNoteHead> headContainer;
|
||||||
private readonly Container<DrawableTailNote> tailContainer;
|
private readonly Container<DrawableHoldNoteTail> tailContainer;
|
||||||
private readonly Container<DrawableHoldNoteTick> tickContainer;
|
private readonly Container<DrawableHoldNoteTick> tickContainer;
|
||||||
|
|
||||||
private readonly BodyPiece bodyPiece;
|
private readonly BodyPiece bodyPiece;
|
||||||
@ -33,12 +32,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Time at which the user started holding this hold note. Null if the user is not holding this hold note.
|
/// Time at which the user started holding this hold note. Null if the user is not holding this hold note.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private double? holdStartTime;
|
public double? HoldStartTime { get; private set; }
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether the hold note has been released too early and shouldn't give full score for the release.
|
/// Whether the hold note has been released too early and shouldn't give full score for the release.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool hasBroken;
|
public bool HasBroken { get; private set; }
|
||||||
|
|
||||||
public DrawableHoldNote(HoldNote hitObject)
|
public DrawableHoldNote(HoldNote hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
@ -49,8 +48,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
{
|
{
|
||||||
bodyPiece = new BodyPiece { RelativeSizeAxes = Axes.X },
|
bodyPiece = new BodyPiece { RelativeSizeAxes = Axes.X },
|
||||||
tickContainer = new Container<DrawableHoldNoteTick> { RelativeSizeAxes = Axes.Both },
|
tickContainer = new Container<DrawableHoldNoteTick> { RelativeSizeAxes = Axes.Both },
|
||||||
headContainer = new Container<DrawableHeadNote> { RelativeSizeAxes = Axes.Both },
|
headContainer = new Container<DrawableHoldNoteHead> { RelativeSizeAxes = Axes.Both },
|
||||||
tailContainer = new Container<DrawableTailNote> { RelativeSizeAxes = Axes.Both },
|
tailContainer = new Container<DrawableHoldNoteTail> { RelativeSizeAxes = Axes.Both },
|
||||||
});
|
});
|
||||||
|
|
||||||
AccentColour.BindValueChanged(colour =>
|
AccentColour.BindValueChanged(colour =>
|
||||||
@ -65,11 +64,11 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
|
|
||||||
switch (hitObject)
|
switch (hitObject)
|
||||||
{
|
{
|
||||||
case DrawableHeadNote head:
|
case DrawableHoldNoteHead head:
|
||||||
headContainer.Child = head;
|
headContainer.Child = head;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DrawableTailNote tail:
|
case DrawableHoldNoteTail tail:
|
||||||
tailContainer.Child = tail;
|
tailContainer.Child = tail;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -92,7 +91,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
switch (hitObject)
|
switch (hitObject)
|
||||||
{
|
{
|
||||||
case TailNote _:
|
case TailNote _:
|
||||||
return new DrawableTailNote(this)
|
return new DrawableHoldNoteTail(this)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
@ -100,7 +99,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
};
|
};
|
||||||
|
|
||||||
case Note _:
|
case Note _:
|
||||||
return new DrawableHeadNote(this)
|
return new DrawableHoldNoteHead(this)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
@ -110,7 +109,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
case HoldNoteTick tick:
|
case HoldNoteTick tick:
|
||||||
return new DrawableHoldNoteTick(tick)
|
return new DrawableHoldNoteTick(tick)
|
||||||
{
|
{
|
||||||
HoldStartTime = () => holdStartTime,
|
HoldStartTime = () => HoldStartTime,
|
||||||
AccentColour = { BindTarget = AccentColour }
|
AccentColour = { BindTarget = AccentColour }
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
@ -125,12 +124,6 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
bodyPiece.Anchor = bodyPiece.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
|
bodyPiece.Anchor = bodyPiece.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
|
||||||
{
|
|
||||||
if (Tail.AllJudged)
|
|
||||||
ApplyResult(r => r.Type = HitResult.Perfect);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
@ -146,146 +139,64 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
|||||||
base.UpdateStateTransforms(state);
|
base.UpdateStateTransforms(state);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected void BeginHold()
|
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||||
{
|
{
|
||||||
holdStartTime = Time.Current;
|
if (Tail.AllJudged)
|
||||||
bodyPiece.Hitting = true;
|
ApplyResult(r => r.Type = HitResult.Perfect);
|
||||||
}
|
|
||||||
|
|
||||||
protected void EndHold()
|
if (Tail.Result.Type == HitResult.Miss)
|
||||||
{
|
HasBroken = true;
|
||||||
holdStartTime = null;
|
|
||||||
bodyPiece.Hitting = false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public bool OnPressed(ManiaAction action)
|
public bool OnPressed(ManiaAction action)
|
||||||
{
|
{
|
||||||
// Make sure the action happened within the body of the hold note
|
if (AllJudged)
|
||||||
if (Time.Current < HitObject.StartTime || Time.Current > HitObject.EndTime)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (action != Action.Value)
|
if (action != Action.Value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
// The user has pressed during the body of the hold note, after the head note and its hit windows have passed
|
beginHoldAt(Time.Current - Head.HitObject.StartTime);
|
||||||
// and within the limited range of the above if-statement. This state will be managed by the head note if the
|
Head.UpdateResult();
|
||||||
// user has pressed during the hit windows of the head note.
|
|
||||||
BeginHold();
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void beginHoldAt(double timeOffset)
|
||||||
|
{
|
||||||
|
if (timeOffset < -Head.HitObject.HitWindows.WindowFor(HitResult.Miss))
|
||||||
|
return;
|
||||||
|
|
||||||
|
HoldStartTime = Time.Current;
|
||||||
|
bodyPiece.Hitting = true;
|
||||||
|
}
|
||||||
|
|
||||||
public bool OnReleased(ManiaAction action)
|
public bool OnReleased(ManiaAction action)
|
||||||
{
|
{
|
||||||
// Make sure that the user started holding the key during the hold note
|
if (AllJudged)
|
||||||
if (!holdStartTime.HasValue)
|
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
if (action != Action.Value)
|
if (action != Action.Value)
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
EndHold();
|
// Make sure a hold was started
|
||||||
|
if (HoldStartTime == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
Tail.UpdateResult();
|
||||||
|
endHold();
|
||||||
|
|
||||||
// If the key has been released too early, the user should not receive full score for the release
|
// If the key has been released too early, the user should not receive full score for the release
|
||||||
if (!Tail.IsHit)
|
if (!Tail.IsHit)
|
||||||
hasBroken = true;
|
HasBroken = true;
|
||||||
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
private void endHold()
|
||||||
/// The head note of a hold.
|
|
||||||
/// </summary>
|
|
||||||
private class DrawableHeadNote : DrawableNote
|
|
||||||
{
|
{
|
||||||
private readonly DrawableHoldNote holdNote;
|
HoldStartTime = null;
|
||||||
|
bodyPiece.Hitting = false;
|
||||||
public DrawableHeadNote(DrawableHoldNote holdNote)
|
|
||||||
: base(holdNote.HitObject.Head)
|
|
||||||
{
|
|
||||||
this.holdNote = holdNote;
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnPressed(ManiaAction action)
|
|
||||||
{
|
|
||||||
if (!base.OnPressed(action))
|
|
||||||
return false;
|
|
||||||
|
|
||||||
// If the key has been released too early, the user should not receive full score for the release
|
|
||||||
if (Result.Type == HitResult.Miss)
|
|
||||||
holdNote.hasBroken = true;
|
|
||||||
|
|
||||||
// The head note also handles early hits before the body, but we want accurate early hits to count as the body being held
|
|
||||||
// The body doesn't handle these early early hits, so we have to explicitly set the holding state here
|
|
||||||
holdNote.BeginHold();
|
|
||||||
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The tail note of a hold.
|
|
||||||
/// </summary>
|
|
||||||
private class DrawableTailNote : DrawableNote
|
|
||||||
{
|
|
||||||
/// <summary>
|
|
||||||
/// Lenience of release hit windows. This is to make cases where the hold note release
|
|
||||||
/// is timed alongside presses of other hit objects less awkward.
|
|
||||||
/// Todo: This shouldn't exist for non-LegacyBeatmapDecoder beatmaps
|
|
||||||
/// </summary>
|
|
||||||
private const double release_window_lenience = 1.5;
|
|
||||||
|
|
||||||
private readonly DrawableHoldNote holdNote;
|
|
||||||
|
|
||||||
public DrawableTailNote(DrawableHoldNote holdNote)
|
|
||||||
: base(holdNote.HitObject.Tail)
|
|
||||||
{
|
|
||||||
this.holdNote = holdNote;
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
|
||||||
{
|
|
||||||
Debug.Assert(HitObject.HitWindows != null);
|
|
||||||
|
|
||||||
// Factor in the release lenience
|
|
||||||
timeOffset /= release_window_lenience;
|
|
||||||
|
|
||||||
if (!userTriggered)
|
|
||||||
{
|
|
||||||
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
|
||||||
ApplyResult(r => r.Type = HitResult.Miss);
|
|
||||||
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
|
|
||||||
var result = HitObject.HitWindows.ResultFor(timeOffset);
|
|
||||||
if (result == HitResult.None)
|
|
||||||
return;
|
|
||||||
|
|
||||||
ApplyResult(r =>
|
|
||||||
{
|
|
||||||
if (holdNote.hasBroken && (result == HitResult.Perfect || result == HitResult.Perfect))
|
|
||||||
result = HitResult.Good;
|
|
||||||
|
|
||||||
r.Type = result;
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
public override bool OnPressed(ManiaAction action) => false; // Tail doesn't handle key down
|
|
||||||
|
|
||||||
public override bool OnReleased(ManiaAction action)
|
|
||||||
{
|
|
||||||
// Make sure that the user started holding the key during the hold note
|
|
||||||
if (!holdNote.holdStartTime.HasValue)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
if (action != Action.Value)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
UpdateResult(true);
|
|
||||||
|
|
||||||
// Handled by the hold note, which will set holding = false
|
|
||||||
return false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,22 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The head of a <see cref="DrawableHoldNote"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class DrawableHoldNoteHead : DrawableNote
|
||||||
|
{
|
||||||
|
public DrawableHoldNoteHead(DrawableHoldNote holdNote)
|
||||||
|
: base(holdNote.HitObject.Head)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateResult() => base.UpdateResult(true);
|
||||||
|
|
||||||
|
public override bool OnPressed(ManiaAction action) => false; // Handled by the hold note
|
||||||
|
|
||||||
|
public override bool OnReleased(ManiaAction action) => false; // Handled by the hold note
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,64 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Diagnostics;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// The tail of a <see cref="DrawableHoldNote"/>.
|
||||||
|
/// </summary>
|
||||||
|
public class DrawableHoldNoteTail : DrawableNote
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Lenience of release hit windows. This is to make cases where the hold note release
|
||||||
|
/// is timed alongside presses of other hit objects less awkward.
|
||||||
|
/// Todo: This shouldn't exist for non-LegacyBeatmapDecoder beatmaps
|
||||||
|
/// </summary>
|
||||||
|
private const double release_window_lenience = 1.5;
|
||||||
|
|
||||||
|
private readonly DrawableHoldNote holdNote;
|
||||||
|
|
||||||
|
public DrawableHoldNoteTail(DrawableHoldNote holdNote)
|
||||||
|
: base(holdNote.HitObject.Tail)
|
||||||
|
{
|
||||||
|
this.holdNote = holdNote;
|
||||||
|
}
|
||||||
|
|
||||||
|
public void UpdateResult() => base.UpdateResult(true);
|
||||||
|
|
||||||
|
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||||
|
{
|
||||||
|
Debug.Assert(HitObject.HitWindows != null);
|
||||||
|
|
||||||
|
// Factor in the release lenience
|
||||||
|
timeOffset /= release_window_lenience;
|
||||||
|
|
||||||
|
if (!userTriggered)
|
||||||
|
{
|
||||||
|
if (!HitObject.HitWindows.CanBeHit(timeOffset))
|
||||||
|
ApplyResult(r => r.Type = HitResult.Miss);
|
||||||
|
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
var result = HitObject.HitWindows.ResultFor(timeOffset);
|
||||||
|
if (result == HitResult.None)
|
||||||
|
return;
|
||||||
|
|
||||||
|
ApplyResult(r =>
|
||||||
|
{
|
||||||
|
// If the head wasn't hit or the hold note was broken, cap the max score to Meh.
|
||||||
|
if (result > HitResult.Meh && (!holdNote.Head.IsHit || holdNote.HasBroken))
|
||||||
|
result = HitResult.Meh;
|
||||||
|
|
||||||
|
r.Type = result;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
public override bool OnPressed(ManiaAction action) => false; // Handled by the hold note
|
||||||
|
|
||||||
|
public override bool OnReleased(ManiaAction action) => false; // Handled by the hold note
|
||||||
|
}
|
||||||
|
}
|
@ -1,68 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Effects;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
using osuTK.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
|
||||||
{
|
|
||||||
public class GlowPiece : CompositeDrawable, IHasAccentColour
|
|
||||||
{
|
|
||||||
private const float glow_alpha = 0.7f;
|
|
||||||
private const float glow_radius = 5;
|
|
||||||
|
|
||||||
public GlowPiece()
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both;
|
|
||||||
Masking = true;
|
|
||||||
|
|
||||||
InternalChild = new Box
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Alpha = 0,
|
|
||||||
AlwaysPresent = true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
updateGlow();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Color4 accentColour;
|
|
||||||
|
|
||||||
public Color4 AccentColour
|
|
||||||
{
|
|
||||||
get => accentColour;
|
|
||||||
set
|
|
||||||
{
|
|
||||||
if (accentColour == value)
|
|
||||||
return;
|
|
||||||
|
|
||||||
accentColour = value;
|
|
||||||
|
|
||||||
updateGlow();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void updateGlow()
|
|
||||||
{
|
|
||||||
if (!IsLoaded)
|
|
||||||
return;
|
|
||||||
|
|
||||||
EdgeEffect = new EdgeEffectParameters
|
|
||||||
{
|
|
||||||
Type = EdgeEffectType.Glow,
|
|
||||||
Colour = AccentColour.Opacity(glow_alpha),
|
|
||||||
Radius = glow_radius,
|
|
||||||
Hollow = true
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,85 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
using osuTK.Graphics;
|
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Colour;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Graphics.Shapes;
|
|
||||||
using osu.Game.Graphics;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
|
|
||||||
{
|
|
||||||
public class LaneGlowPiece : CompositeDrawable, IHasAccentColour
|
|
||||||
{
|
|
||||||
private const float total_height = 100;
|
|
||||||
private const float glow_height = 50;
|
|
||||||
private const float glow_alpha = 0.4f;
|
|
||||||
private const float edge_alpha = 0.3f;
|
|
||||||
|
|
||||||
public LaneGlowPiece()
|
|
||||||
{
|
|
||||||
BypassAutoSizeAxes = Axes.Both;
|
|
||||||
RelativeSizeAxes = Axes.X;
|
|
||||||
Height = total_height;
|
|
||||||
|
|
||||||
InternalChildren = new[]
|
|
||||||
{
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
Name = "Left edge",
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Width = 1,
|
|
||||||
Children = createGradient(edge_alpha)
|
|
||||||
},
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
Name = "Right edge",
|
|
||||||
Anchor = Anchor.TopRight,
|
|
||||||
Origin = Anchor.TopRight,
|
|
||||||
RelativeSizeAxes = Axes.Y,
|
|
||||||
Width = 1,
|
|
||||||
Children = createGradient(edge_alpha)
|
|
||||||
},
|
|
||||||
new Container
|
|
||||||
{
|
|
||||||
Name = "Glow",
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Height = glow_height,
|
|
||||||
Children = createGradient(glow_alpha)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
}
|
|
||||||
|
|
||||||
private Drawable[] createGradient(float alpha) => new Drawable[]
|
|
||||||
{
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
Name = "Top",
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Height = 0.5f,
|
|
||||||
Blending = BlendingParameters.Additive,
|
|
||||||
Colour = ColourInfo.GradientVertical(Color4.Transparent, Color4.White.Opacity(alpha))
|
|
||||||
},
|
|
||||||
new Box
|
|
||||||
{
|
|
||||||
Name = "Bottom",
|
|
||||||
Anchor = Anchor.BottomLeft,
|
|
||||||
Origin = Anchor.BottomLeft,
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Height = 0.5f,
|
|
||||||
Blending = BlendingParameters.Additive,
|
|
||||||
Colour = ColourInfo.GradientVertical(Color4.White.Opacity(alpha), Color4.Transparent)
|
|
||||||
}
|
|
||||||
};
|
|
||||||
|
|
||||||
public Color4 AccentColour
|
|
||||||
{
|
|
||||||
get => Colour;
|
|
||||||
set => Colour = value;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.Replays
|
|||||||
public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap, ReplayFrame lastFrame = null)
|
public void ConvertFrom(LegacyReplayFrame legacyFrame, IBeatmap beatmap, ReplayFrame lastFrame = null)
|
||||||
{
|
{
|
||||||
// We don't need to fully convert, just create the converter
|
// We don't need to fully convert, just create the converter
|
||||||
var converter = new ManiaBeatmapConverter(beatmap);
|
var converter = new ManiaBeatmapConverter(beatmap, new ManiaRuleset());
|
||||||
|
|
||||||
// NB: Via co-op mod, osu-stable can have two stages with floor(col/2) and ceil(col/2) columns. This will need special handling
|
// NB: Via co-op mod, osu-stable can have two stages with floor(col/2) and ceil(col/2) columns. This will need special handling
|
||||||
// elsewhere in the game if we do choose to support the old co-op mod anyway. For now, assume that there is only one stage.
|
// elsewhere in the game if we do choose to support the old co-op mod anyway. For now, assume that there is only one stage.
|
||||||
|
@ -1,87 +1,12 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Rulesets.Judgements;
|
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Scoring
|
namespace osu.Game.Rulesets.Mania.Scoring
|
||||||
{
|
{
|
||||||
internal class ManiaScoreProcessor : ScoreProcessor
|
internal class ManiaScoreProcessor : ScoreProcessor
|
||||||
{
|
{
|
||||||
/// <summary>
|
|
||||||
/// The hit HP multiplier at OD = 0.
|
|
||||||
/// </summary>
|
|
||||||
private const double hp_multiplier_min = 0.75;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The hit HP multiplier at OD = 0.
|
|
||||||
/// </summary>
|
|
||||||
private const double hp_multiplier_mid = 0.85;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The hit HP multiplier at OD = 0.
|
|
||||||
/// </summary>
|
|
||||||
private const double hp_multiplier_max = 1;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The MISS HP multiplier at OD = 0.
|
|
||||||
/// </summary>
|
|
||||||
private const double hp_multiplier_miss_min = 0.5;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The MISS HP multiplier at OD = 5.
|
|
||||||
/// </summary>
|
|
||||||
private const double hp_multiplier_miss_mid = 0.75;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The MISS HP multiplier at OD = 10.
|
|
||||||
/// </summary>
|
|
||||||
private const double hp_multiplier_miss_max = 1;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The MISS HP multiplier. This is multiplied to the miss hp increase.
|
|
||||||
/// </summary>
|
|
||||||
private double hpMissMultiplier = 1;
|
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// The HIT HP multiplier. This is multiplied to hit hp increases.
|
|
||||||
/// </summary>
|
|
||||||
private double hpMultiplier = 1;
|
|
||||||
|
|
||||||
public ManiaScoreProcessor(IBeatmap beatmap)
|
|
||||||
: base(beatmap)
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void ApplyBeatmap(IBeatmap beatmap)
|
|
||||||
{
|
|
||||||
base.ApplyBeatmap(beatmap);
|
|
||||||
|
|
||||||
BeatmapDifficulty difficulty = beatmap.BeatmapInfo.BaseDifficulty;
|
|
||||||
hpMultiplier = BeatmapDifficulty.DifficultyRange(difficulty.DrainRate, hp_multiplier_min, hp_multiplier_mid, hp_multiplier_max);
|
|
||||||
hpMissMultiplier = BeatmapDifficulty.DifficultyRange(difficulty.DrainRate, hp_multiplier_miss_min, hp_multiplier_miss_mid, hp_multiplier_miss_max);
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void SimulateAutoplay(IBeatmap beatmap)
|
|
||||||
{
|
|
||||||
while (true)
|
|
||||||
{
|
|
||||||
base.SimulateAutoplay(beatmap);
|
|
||||||
|
|
||||||
if (!HasFailed)
|
|
||||||
break;
|
|
||||||
|
|
||||||
hpMultiplier *= 1.01;
|
|
||||||
hpMissMultiplier *= 0.98;
|
|
||||||
|
|
||||||
Reset(false);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override double HealthAdjustmentFactorFor(JudgementResult result)
|
|
||||||
=> result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier;
|
|
||||||
|
|
||||||
public override HitWindows CreateHitWindows() => new ManiaHitWindows();
|
public override HitWindows CreateHitWindows() => new ManiaHitWindows();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,67 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Audio;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Skinning
|
||||||
|
{
|
||||||
|
public class ManiaLegacySkinTransformer : ISkin
|
||||||
|
{
|
||||||
|
private readonly ISkin source;
|
||||||
|
|
||||||
|
public ManiaLegacySkinTransformer(ISkin source)
|
||||||
|
{
|
||||||
|
this.source = source;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Drawable GetDrawableComponent(ISkinComponent component)
|
||||||
|
{
|
||||||
|
switch (component)
|
||||||
|
{
|
||||||
|
case GameplaySkinComponent<HitResult> resultComponent:
|
||||||
|
return getResult(resultComponent);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
private Drawable getResult(GameplaySkinComponent<HitResult> resultComponent)
|
||||||
|
{
|
||||||
|
switch (resultComponent.Component)
|
||||||
|
{
|
||||||
|
case HitResult.Miss:
|
||||||
|
return this.GetAnimation("mania-hit0", true, true);
|
||||||
|
|
||||||
|
case HitResult.Meh:
|
||||||
|
return this.GetAnimation("mania-hit50", true, true);
|
||||||
|
|
||||||
|
case HitResult.Ok:
|
||||||
|
return this.GetAnimation("mania-hit100", true, true);
|
||||||
|
|
||||||
|
case HitResult.Good:
|
||||||
|
return this.GetAnimation("mania-hit200", true, true);
|
||||||
|
|
||||||
|
case HitResult.Great:
|
||||||
|
return this.GetAnimation("mania-hit300", true, true);
|
||||||
|
|
||||||
|
case HitResult.Perfect:
|
||||||
|
return this.GetAnimation("mania-hit300g", true, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public Texture GetTexture(string componentName) => source.GetTexture(componentName);
|
||||||
|
|
||||||
|
public SampleChannel GetSample(ISampleInfo sample) => source.GetSample(sample);
|
||||||
|
|
||||||
|
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup) =>
|
||||||
|
source.GetConfig<TLookup, TValue>(lookup);
|
||||||
|
}
|
||||||
|
}
|
@ -18,30 +18,17 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
|||||||
{
|
{
|
||||||
public class ColumnHitObjectArea : CompositeDrawable, IHasAccentColour
|
public class ColumnHitObjectArea : CompositeDrawable, IHasAccentColour
|
||||||
{
|
{
|
||||||
private const float hit_target_bar_height = 2;
|
|
||||||
|
|
||||||
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
|
|
||||||
private readonly Container hitTargetLine;
|
private readonly Drawable hitTarget;
|
||||||
private readonly Drawable hitTargetBar;
|
|
||||||
|
|
||||||
public ColumnHitObjectArea(HitObjectContainer hitObjectContainer)
|
public ColumnHitObjectArea(HitObjectContainer hitObjectContainer)
|
||||||
{
|
{
|
||||||
InternalChildren = new[]
|
InternalChildren = new[]
|
||||||
{
|
{
|
||||||
hitTargetBar = new Box
|
hitTarget = new DefaultHitTarget
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
Height = NotePiece.NOTE_HEIGHT,
|
|
||||||
Alpha = 0.6f,
|
|
||||||
Colour = Color4.Black
|
|
||||||
},
|
|
||||||
hitTargetLine = new Container
|
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.X,
|
|
||||||
Height = hit_target_bar_height,
|
|
||||||
Masking = true,
|
|
||||||
Child = new Box { RelativeSizeAxes = Axes.Both }
|
|
||||||
},
|
},
|
||||||
hitObjectContainer
|
hitObjectContainer
|
||||||
};
|
};
|
||||||
@ -55,17 +42,10 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
|||||||
{
|
{
|
||||||
Anchor anchor = dir.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
|
Anchor anchor = dir.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
|
||||||
|
|
||||||
hitTargetBar.Anchor = hitTargetBar.Origin = anchor;
|
hitTarget.Anchor = hitTarget.Origin = anchor;
|
||||||
hitTargetLine.Anchor = hitTargetLine.Origin = anchor;
|
|
||||||
}, true);
|
}, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
|
||||||
{
|
|
||||||
base.LoadComplete();
|
|
||||||
updateColours();
|
|
||||||
}
|
|
||||||
|
|
||||||
private Color4 accentColour;
|
private Color4 accentColour;
|
||||||
|
|
||||||
public Color4 AccentColour
|
public Color4 AccentColour
|
||||||
@ -78,21 +58,88 @@ namespace osu.Game.Rulesets.Mania.UI.Components
|
|||||||
|
|
||||||
accentColour = value;
|
accentColour = value;
|
||||||
|
|
||||||
updateColours();
|
if (hitTarget is IHasAccentColour colouredHitTarget)
|
||||||
|
colouredHitTarget.AccentColour = accentColour;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateColours()
|
private class DefaultHitTarget : CompositeDrawable, IHasAccentColour
|
||||||
{
|
{
|
||||||
if (!IsLoaded)
|
private const float hit_target_bar_height = 2;
|
||||||
return;
|
|
||||||
|
|
||||||
hitTargetLine.EdgeEffect = new EdgeEffectParameters
|
private readonly IBindable<ScrollingDirection> direction = new Bindable<ScrollingDirection>();
|
||||||
|
|
||||||
|
private readonly Container hitTargetLine;
|
||||||
|
private readonly Drawable hitTargetBar;
|
||||||
|
|
||||||
|
public DefaultHitTarget()
|
||||||
{
|
{
|
||||||
Type = EdgeEffectType.Glow,
|
InternalChildren = new[]
|
||||||
Radius = 5,
|
{
|
||||||
Colour = accentColour.Opacity(0.5f),
|
hitTargetBar = new Box
|
||||||
};
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = NotePiece.NOTE_HEIGHT,
|
||||||
|
Alpha = 0.6f,
|
||||||
|
Colour = Color4.Black
|
||||||
|
},
|
||||||
|
hitTargetLine = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Height = hit_target_bar_height,
|
||||||
|
Masking = true,
|
||||||
|
Child = new Box { RelativeSizeAxes = Axes.Both }
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(IScrollingInfo scrollingInfo)
|
||||||
|
{
|
||||||
|
direction.BindTo(scrollingInfo.Direction);
|
||||||
|
direction.BindValueChanged(dir =>
|
||||||
|
{
|
||||||
|
Anchor anchor = dir.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
|
||||||
|
|
||||||
|
hitTargetBar.Anchor = hitTargetBar.Origin = anchor;
|
||||||
|
hitTargetLine.Anchor = hitTargetLine.Origin = anchor;
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
updateColours();
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color4 accentColour;
|
||||||
|
|
||||||
|
public Color4 AccentColour
|
||||||
|
{
|
||||||
|
get => accentColour;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (accentColour == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
accentColour = value;
|
||||||
|
|
||||||
|
updateColours();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateColours()
|
||||||
|
{
|
||||||
|
if (!IsLoaded)
|
||||||
|
return;
|
||||||
|
|
||||||
|
hitTargetLine.EdgeEffect = new EdgeEffectParameters
|
||||||
|
{
|
||||||
|
Type = EdgeEffectType.Glow,
|
||||||
|
Radius = 5,
|
||||||
|
Colour = accentColour.Opacity(0.5f),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -14,11 +14,9 @@ using osu.Game.Rulesets.Mania.Configuration;
|
|||||||
using osu.Game.Rulesets.Mania.Objects;
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
using osu.Game.Rulesets.Mania.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Mania.Replays;
|
using osu.Game.Rulesets.Mania.Replays;
|
||||||
using osu.Game.Rulesets.Mania.Scoring;
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Scoring;
|
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -67,8 +65,6 @@ namespace osu.Game.Rulesets.Mania.UI
|
|||||||
|
|
||||||
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages);
|
protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages);
|
||||||
|
|
||||||
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(Beatmap);
|
|
||||||
|
|
||||||
public override int Variant => (int)(Beatmap.Stages.Count == 1 ? PlayfieldType.Single : PlayfieldType.Dual) + Beatmap.TotalColumns;
|
public override int Variant => (int)(Beatmap.Stages.Count == 1 ? PlayfieldType.Single : PlayfieldType.Dual) + Beatmap.TotalColumns;
|
||||||
|
|
||||||
protected override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant);
|
protected override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant);
|
||||||
|
@ -5,7 +5,7 @@ using osu.Framework.Extensions.Color4Extensions;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
@ -5,7 +5,7 @@ using UIKit;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Tests.iOS
|
namespace osu.Game.Rulesets.Osu.Tests.iOS
|
||||||
{
|
{
|
||||||
public class Application
|
public static class Application
|
||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
|
@ -7,7 +7,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Debug/netcoreapp3.0/osu.Game.Rulesets.Osu.Tests.dll"
|
"${workspaceRoot}/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Osu.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Debug)",
|
"preLaunchTask": "Build (Debug)",
|
||||||
@ -20,7 +20,7 @@
|
|||||||
"request": "launch",
|
"request": "launch",
|
||||||
"program": "dotnet",
|
"program": "dotnet",
|
||||||
"args": [
|
"args": [
|
||||||
"${workspaceRoot}/bin/Release/netcoreapp3.0/osu.Game.Rulesets.Osu.Tests.dll"
|
"${workspaceRoot}/bin/Release/netcoreapp3.1/osu.Game.Rulesets.Osu.Tests.dll"
|
||||||
],
|
],
|
||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build (Release)",
|
"preLaunchTask": "Build (Release)",
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(AudioManager audio, SkinManager skinManager)
|
private void load(AudioManager audio, SkinManager skinManager)
|
||||||
{
|
{
|
||||||
var dllStore = new DllResourceStore("osu.Game.Rulesets.Osu.Tests.dll");
|
var dllStore = new DllResourceStore(typeof(SkinnableTestScene).Assembly);
|
||||||
|
|
||||||
metricsSkin = new TestLegacySkin(new SkinInfo(), new NamespacedResourceStore<byte[]>(dllStore, "Resources/metrics_skin"), audio, true);
|
metricsSkin = new TestLegacySkin(new SkinInfo(), new NamespacedResourceStore<byte[]>(dllStore, "Resources/metrics_skin"), audio, true);
|
||||||
defaultSkin = skinManager.GetSkin(DefaultLegacySkin.Info);
|
defaultSkin = skinManager.GetSkin(DefaultLegacySkin.Info);
|
||||||
|
155
osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs
Normal file
155
osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs
Normal file
@ -0,0 +1,155 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.IO.Stores;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Screens;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
|
{
|
||||||
|
public class TestSceneLegacyBeatmapSkin : OsuTestScene
|
||||||
|
{
|
||||||
|
[Resolved]
|
||||||
|
private AudioManager audio { get; set; }
|
||||||
|
|
||||||
|
[TestCase(true)]
|
||||||
|
[TestCase(false)]
|
||||||
|
public void TestBeatmapComboColours(bool customSkinColoursPresent)
|
||||||
|
{
|
||||||
|
ExposedPlayer player = null;
|
||||||
|
|
||||||
|
AddStep("load coloured beatmap", () => player = loadBeatmap(customSkinColoursPresent, true));
|
||||||
|
AddUntilStep("wait for player", () => player.IsLoaded);
|
||||||
|
|
||||||
|
AddAssert("is beatmap skin colours", () => player.UsableComboColours.SequenceEqual(TestBeatmapSkin.Colours));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestBeatmapNoComboColours()
|
||||||
|
{
|
||||||
|
ExposedPlayer player = null;
|
||||||
|
|
||||||
|
AddStep("load no-colour beatmap", () => player = loadBeatmap(false, false));
|
||||||
|
AddUntilStep("wait for player", () => player.IsLoaded);
|
||||||
|
|
||||||
|
AddAssert("is default user skin colours", () => player.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestBeatmapNoComboColoursSkinOverride()
|
||||||
|
{
|
||||||
|
ExposedPlayer player = null;
|
||||||
|
|
||||||
|
AddStep("load custom-skin colour", () => player = loadBeatmap(true, false));
|
||||||
|
AddUntilStep("wait for player", () => player.IsLoaded);
|
||||||
|
|
||||||
|
AddAssert("is custom user skin colours", () => player.UsableComboColours.SequenceEqual(TestSkin.Colours));
|
||||||
|
}
|
||||||
|
|
||||||
|
private ExposedPlayer loadBeatmap(bool userHasCustomColours, bool beatmapHasColours)
|
||||||
|
{
|
||||||
|
ExposedPlayer player;
|
||||||
|
|
||||||
|
Beatmap.Value = new CustomSkinWorkingBeatmap(audio, beatmapHasColours);
|
||||||
|
Child = new OsuScreenStack(player = new ExposedPlayer(userHasCustomColours)) { RelativeSizeAxes = Axes.Both };
|
||||||
|
|
||||||
|
return player;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ExposedPlayer : Player
|
||||||
|
{
|
||||||
|
private readonly bool userHasCustomColours;
|
||||||
|
|
||||||
|
public ExposedPlayer(bool userHasCustomColours)
|
||||||
|
: base(false, false)
|
||||||
|
{
|
||||||
|
this.userHasCustomColours = userHasCustomColours;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||||
|
{
|
||||||
|
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||||
|
dependencies.CacheAs<ISkinSource>(new TestSkin(userHasCustomColours));
|
||||||
|
return dependencies;
|
||||||
|
}
|
||||||
|
|
||||||
|
public IReadOnlyList<Color4> UsableComboColours =>
|
||||||
|
GameplayClockContainer.ChildrenOfType<BeatmapSkinProvidingContainer>()
|
||||||
|
.First()
|
||||||
|
.GetConfig<GlobalSkinConfiguration, IReadOnlyList<Color4>>(GlobalSkinConfiguration.ComboColours)?.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap
|
||||||
|
{
|
||||||
|
private readonly bool hasColours;
|
||||||
|
|
||||||
|
public CustomSkinWorkingBeatmap(AudioManager audio, bool hasColours)
|
||||||
|
: base(new Beatmap
|
||||||
|
{
|
||||||
|
BeatmapInfo =
|
||||||
|
{
|
||||||
|
BeatmapSet = new BeatmapSetInfo(),
|
||||||
|
Ruleset = new OsuRuleset().RulesetInfo,
|
||||||
|
},
|
||||||
|
HitObjects = { new HitCircle { Position = new Vector2(256, 192) } }
|
||||||
|
}, null, null, audio)
|
||||||
|
{
|
||||||
|
this.hasColours = hasColours;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override ISkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestBeatmapSkin : LegacyBeatmapSkin
|
||||||
|
{
|
||||||
|
public static Color4[] Colours { get; } =
|
||||||
|
{
|
||||||
|
new Color4(50, 100, 150, 255),
|
||||||
|
new Color4(40, 80, 120, 255),
|
||||||
|
};
|
||||||
|
|
||||||
|
public TestBeatmapSkin(BeatmapInfo beatmap, bool hasColours)
|
||||||
|
: base(beatmap, new ResourceStore<byte[]>(), null)
|
||||||
|
{
|
||||||
|
if (hasColours)
|
||||||
|
Configuration.AddComboColours(Colours);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestSkin : LegacySkin, ISkinSource
|
||||||
|
{
|
||||||
|
public static Color4[] Colours { get; } =
|
||||||
|
{
|
||||||
|
new Color4(150, 100, 50, 255),
|
||||||
|
new Color4(20, 20, 20, 255),
|
||||||
|
};
|
||||||
|
|
||||||
|
public TestSkin(bool hasCustomColours)
|
||||||
|
: base(new SkinInfo(), null, null, string.Empty)
|
||||||
|
{
|
||||||
|
if (hasCustomColours)
|
||||||
|
Configuration.AddComboColours(Colours);
|
||||||
|
}
|
||||||
|
|
||||||
|
public event Action SourceChanged
|
||||||
|
{
|
||||||
|
add { }
|
||||||
|
remove { }
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -9,7 +9,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Osu.Beatmaps;
|
using osu.Game.Rulesets.Osu.Beatmaps;
|
||||||
@ -33,8 +33,8 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
typeof(CircularDistanceSnapGrid)
|
typeof(CircularDistanceSnapGrid)
|
||||||
};
|
};
|
||||||
|
|
||||||
[Cached(typeof(IEditorBeatmap))]
|
[Cached(typeof(EditorBeatmap))]
|
||||||
private readonly EditorBeatmap<OsuHitObject> editorBeatmap;
|
private readonly EditorBeatmap editorBeatmap;
|
||||||
|
|
||||||
[Cached]
|
[Cached]
|
||||||
private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor();
|
private readonly BindableBeatDivisor beatDivisor = new BindableBeatDivisor();
|
||||||
@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
public TestSceneOsuDistanceSnapGrid()
|
public TestSceneOsuDistanceSnapGrid()
|
||||||
{
|
{
|
||||||
editorBeatmap = new EditorBeatmap<OsuHitObject>(new OsuBeatmap());
|
editorBeatmap = new EditorBeatmap(new OsuBeatmap());
|
||||||
}
|
}
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
|
@ -4,7 +4,7 @@
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -70,6 +70,21 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
AddAssert("is rotation absolute almost same", () => Precision.AlmostEquals(drawableSpinner.Disc.RotationAbsolute, estimatedRotation, 100));
|
AddAssert("is rotation absolute almost same", () => Precision.AlmostEquals(drawableSpinner.Disc.RotationAbsolute, estimatedRotation, 100));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSpinPerMinuteOnRewind()
|
||||||
|
{
|
||||||
|
double estimatedSpm = 0;
|
||||||
|
|
||||||
|
addSeekStep(2500);
|
||||||
|
AddStep("retrieve spm", () => estimatedSpm = drawableSpinner.SpmCounter.SpinsPerMinute);
|
||||||
|
|
||||||
|
addSeekStep(5000);
|
||||||
|
AddAssert("spm still valid", () => Precision.AlmostEquals(drawableSpinner.SpmCounter.SpinsPerMinute, estimatedSpm, 1.0));
|
||||||
|
|
||||||
|
addSeekStep(2500);
|
||||||
|
AddAssert("spm still valid", () => Precision.AlmostEquals(drawableSpinner.SpmCounter.SpinsPerMinute, estimatedSpm, 1.0));
|
||||||
|
}
|
||||||
|
|
||||||
private void addSeekStep(double time)
|
private void addSeekStep(double time)
|
||||||
{
|
{
|
||||||
AddStep($"seek to {time}", () => track.Seek(time));
|
AddStep($"seek to {time}", () => track.Seek(time));
|
||||||
@ -84,10 +99,10 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
new Spinner
|
new Spinner
|
||||||
{
|
{
|
||||||
Position = new Vector2(256, 192),
|
Position = new Vector2(256, 192),
|
||||||
EndTime = 5000,
|
EndTime = 6000,
|
||||||
},
|
},
|
||||||
// placeholder object to avoid hitting the results screen
|
// placeholder object to avoid hitting the results screen
|
||||||
new HitObject
|
new HitCircle
|
||||||
{
|
{
|
||||||
StartTime = 99999,
|
StartTime = 99999,
|
||||||
}
|
}
|
||||||
|
@ -4,12 +4,12 @@
|
|||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.4.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.15.1" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.16.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
<TargetFramework>netcoreapp3.0</TargetFramework>
|
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||||
|
@ -7,7 +7,7 @@ using osu.Game.Rulesets.Objects;
|
|||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
using System;
|
using System.Linq;
|
||||||
using osu.Game.Rulesets.Osu.UI;
|
using osu.Game.Rulesets.Osu.UI;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
|
|
||||||
@ -15,12 +15,12 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
{
|
{
|
||||||
public class OsuBeatmapConverter : BeatmapConverter<OsuHitObject>
|
public class OsuBeatmapConverter : BeatmapConverter<OsuHitObject>
|
||||||
{
|
{
|
||||||
public OsuBeatmapConverter(IBeatmap beatmap)
|
public OsuBeatmapConverter(IBeatmap beatmap, Ruleset ruleset)
|
||||||
: base(beatmap)
|
: base(beatmap, ruleset)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IEnumerable<Type> ValidConversionTypes { get; } = new[] { typeof(IHasPosition) };
|
public override bool CanConvert() => Beatmap.HitObjects.All(h => h is IHasPosition);
|
||||||
|
|
||||||
protected override IEnumerable<OsuHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap)
|
protected override IEnumerable<OsuHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
|
@ -2,6 +2,7 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Screens.Edit.Compose.Components;
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
|
|
||||||
@ -10,7 +11,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
public class OsuDistanceSnapGrid : CircularDistanceSnapGrid
|
public class OsuDistanceSnapGrid : CircularDistanceSnapGrid
|
||||||
{
|
{
|
||||||
public OsuDistanceSnapGrid(OsuHitObject hitObject, [CanBeNull] OsuHitObject nextHitObject = null)
|
public OsuDistanceSnapGrid(OsuHitObject hitObject, [CanBeNull] OsuHitObject nextHitObject = null)
|
||||||
: base(hitObject.StackedPosition, hitObject.StartTime, nextHitObject?.StartTime)
|
: base(hitObject.StackedEndPosition, hitObject.GetEndTime(), nextHitObject?.StartTime)
|
||||||
{
|
{
|
||||||
Masking = true;
|
Masking = true;
|
||||||
}
|
}
|
||||||
|
@ -91,10 +91,27 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
if (sourceIndex == -1)
|
if (sourceIndex == -1)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
OsuHitObject sourceObject = EditorBeatmap.HitObjects[sourceIndex];
|
HitObject sourceObject = EditorBeatmap.HitObjects[sourceIndex];
|
||||||
OsuHitObject targetObject = sourceIndex + targetOffset < EditorBeatmap.HitObjects.Count ? EditorBeatmap.HitObjects[sourceIndex + targetOffset] : null;
|
|
||||||
|
|
||||||
return new OsuDistanceSnapGrid(sourceObject, targetObject);
|
int targetIndex = sourceIndex + targetOffset;
|
||||||
|
HitObject targetObject = null;
|
||||||
|
|
||||||
|
// Keep advancing the target object while its start time falls before the end time of the source object
|
||||||
|
while (true)
|
||||||
|
{
|
||||||
|
if (targetIndex >= EditorBeatmap.HitObjects.Count)
|
||||||
|
break;
|
||||||
|
|
||||||
|
if (EditorBeatmap.HitObjects[targetIndex].StartTime >= sourceObject.GetEndTime())
|
||||||
|
{
|
||||||
|
targetObject = EditorBeatmap.HitObjects[targetIndex];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
targetIndex++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return new OsuDistanceSnapGrid((OsuHitObject)sourceObject, (OsuHitObject)targetObject);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,22 +27,5 @@ namespace osu.Game.Rulesets.Osu.Judgements
|
|||||||
return 300;
|
return 300;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override double HealthIncreaseFor(HitResult result)
|
|
||||||
{
|
|
||||||
switch (result)
|
|
||||||
{
|
|
||||||
case HitResult.Miss:
|
|
||||||
return -0.02;
|
|
||||||
|
|
||||||
case HitResult.Meh:
|
|
||||||
case HitResult.Good:
|
|
||||||
case HitResult.Great:
|
|
||||||
return 0.01;
|
|
||||||
|
|
||||||
default:
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,7 +18,7 @@ using osuTK.Graphics;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
public class OsuModBlinds : Mod, IApplicableToDrawableRuleset<OsuHitObject>, IApplicableToScoreProcessor
|
public class OsuModBlinds : Mod, IApplicableToDrawableRuleset<OsuHitObject>, IApplicableToHealthProcessor
|
||||||
{
|
{
|
||||||
public override string Name => "Blinds";
|
public override string Name => "Blinds";
|
||||||
public override string Description => "Play with blinds on your screen.";
|
public override string Description => "Play with blinds on your screen.";
|
||||||
@ -37,9 +37,9 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
drawableRuleset.Overlays.Add(blinds = new DrawableOsuBlinds(drawableRuleset.Playfield.HitObjectContainer, drawableRuleset.Beatmap));
|
drawableRuleset.Overlays.Add(blinds = new DrawableOsuBlinds(drawableRuleset.Playfield.HitObjectContainer, drawableRuleset.Beatmap));
|
||||||
}
|
}
|
||||||
|
|
||||||
public void ApplyToScoreProcessor(ScoreProcessor scoreProcessor)
|
public void ApplyToHealthProcessor(HealthProcessor healthProcessor)
|
||||||
{
|
{
|
||||||
scoreProcessor.Health.ValueChanged += health => { blinds.AnimateClosedness((float)health.NewValue); };
|
healthProcessor.Health.ValueChanged += health => { blinds.AnimateClosedness((float)health.NewValue); };
|
||||||
}
|
}
|
||||||
|
|
||||||
public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank;
|
public ScoreRank AdjustRank(ScoreRank rank, double accuracy) => rank;
|
||||||
|
@ -5,7 +5,7 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
public class OsuModDeflate : OsuModeObjectScaleTween
|
public class OsuModDeflate : OsuModObjectScaleTween
|
||||||
{
|
{
|
||||||
public override string Name => "Deflate";
|
public override string Name => "Deflate";
|
||||||
|
|
||||||
|
49
osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs
Normal file
49
osu.Game.Rulesets.Osu/Mods/OsuModDifficultyAdjust.cs
Normal file
@ -0,0 +1,49 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModDifficultyAdjust : ModDifficultyAdjust
|
||||||
|
{
|
||||||
|
[SettingSource("Circle Size", "Override a beatmap's set CS.")]
|
||||||
|
public BindableNumber<float> CircleSize { get; } = new BindableFloat
|
||||||
|
{
|
||||||
|
Precision = 0.1f,
|
||||||
|
MinValue = 1,
|
||||||
|
MaxValue = 10,
|
||||||
|
Default = 5,
|
||||||
|
Value = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
[SettingSource("Approach Rate", "Override a beatmap's set AR.")]
|
||||||
|
public BindableNumber<float> ApproachRate { get; } = new BindableFloat
|
||||||
|
{
|
||||||
|
Precision = 0.1f,
|
||||||
|
MinValue = 1,
|
||||||
|
MaxValue = 10,
|
||||||
|
Default = 5,
|
||||||
|
Value = 5,
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override void TransferSettings(BeatmapDifficulty difficulty)
|
||||||
|
{
|
||||||
|
base.TransferSettings(difficulty);
|
||||||
|
|
||||||
|
TransferSetting(CircleSize, difficulty.CircleSize);
|
||||||
|
TransferSetting(ApproachRate, difficulty.ApproachRate);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void ApplySettings(BeatmapDifficulty difficulty)
|
||||||
|
{
|
||||||
|
base.ApplySettings(difficulty);
|
||||||
|
|
||||||
|
difficulty.CircleSize = CircleSize.Value;
|
||||||
|
difficulty.ApproachRate = ApproachRate.Value;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,7 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Input;
|
using osu.Framework.Input;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
@ -5,7 +5,7 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
internal class OsuModGrow : OsuModeObjectScaleTween
|
internal class OsuModGrow : OsuModObjectScaleTween
|
||||||
{
|
{
|
||||||
public override string Name => "Grow";
|
public override string Name => "Grow";
|
||||||
|
|
||||||
|
@ -2,10 +2,11 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
public class OsuModNightcore : ModNightcore
|
public class OsuModNightcore : ModNightcore<OsuHitObject>
|
||||||
{
|
{
|
||||||
public override double ScoreMultiplier => 1.12;
|
public override double ScoreMultiplier => 1.12;
|
||||||
}
|
}
|
||||||
|
@ -17,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Adjusts the size of hit objects during their fade in animation.
|
/// Adjusts the size of hit objects during their fade in animation.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
public abstract class OsuModeObjectScaleTween : Mod, IReadFromConfig, IApplicableToDrawableHitObjects
|
public abstract class OsuModObjectScaleTween : Mod, IReadFromConfig, IApplicableToDrawableHitObjects
|
||||||
{
|
{
|
||||||
public override ModType Type => ModType.Fun;
|
public override ModType Type => ModType.Fun;
|
||||||
|
|
@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
// todo: this mod should be able to be compatible with hidden with a bit of further implementation.
|
// todo: this mod should be able to be compatible with hidden with a bit of further implementation.
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(OsuModeObjectScaleTween), typeof(OsuModHidden), typeof(OsuModTraceable) };
|
public override Type[] IncompatibleMods => new[] { typeof(OsuModObjectScaleTween), typeof(OsuModHidden), typeof(OsuModTraceable) };
|
||||||
|
|
||||||
private const int rotate_offset = 360;
|
private const int rotate_offset = 360;
|
||||||
private const float rotate_starting_width = 2;
|
private const float rotate_starting_width = 2;
|
||||||
|
@ -11,6 +11,7 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
@ -23,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override string Description => "Put your faith in the approach circles...";
|
public override string Description => "Put your faith in the approach circles...";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(OsuModHidden), typeof(OsuModSpinIn), typeof(OsuModeObjectScaleTween) };
|
public override Type[] IncompatibleMods => new[] { typeof(OsuModHidden), typeof(OsuModSpinIn), typeof(OsuModObjectScaleTween) };
|
||||||
private Bindable<bool> increaseFirstObjectVisibility = new Bindable<bool>();
|
private Bindable<bool> increaseFirstObjectVisibility = new Bindable<bool>();
|
||||||
|
|
||||||
public void ReadFromConfig(OsuConfigManager config)
|
public void ReadFromConfig(OsuConfigManager config)
|
||||||
@ -54,13 +55,8 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case DrawableSlider slider:
|
case DrawableSlider slider:
|
||||||
slider.AccentColour.BindValueChanged(_ =>
|
slider.Body.OnSkinChanged += () => applySliderState(slider);
|
||||||
{
|
applySliderState(slider);
|
||||||
//will trigger on skin change.
|
|
||||||
slider.Body.AccentColour = slider.AccentColour.Value.Opacity(0);
|
|
||||||
slider.Body.BorderColour = slider.AccentColour.Value;
|
|
||||||
}, true);
|
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DrawableSpinner spinner:
|
case DrawableSpinner spinner:
|
||||||
@ -69,5 +65,11 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void applySliderState(DrawableSlider slider)
|
||||||
|
{
|
||||||
|
((PlaySliderBody)slider.Body.Drawable).AccentColour = slider.AccentColour.Value.Opacity(0);
|
||||||
|
((PlaySliderBody)slider.Body.Drawable).BorderColour = slider.AccentColour.Value;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,12 +6,11 @@ using System.Collections.Generic;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Utils;
|
||||||
using osu.Framework.MathUtils;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Game.Skinning;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||||
{
|
{
|
||||||
@ -22,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
private double animDuration;
|
private double animDuration;
|
||||||
|
|
||||||
private readonly SkinnableDrawable scaleContainer;
|
private readonly Drawable scaleContainer;
|
||||||
|
|
||||||
public DrawableRepeatPoint(RepeatPoint repeatPoint, DrawableSlider drawableSlider)
|
public DrawableRepeatPoint(RepeatPoint repeatPoint, DrawableSlider drawableSlider)
|
||||||
: base(repeatPoint)
|
: base(repeatPoint)
|
||||||
@ -35,16 +34,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
Blending = BlendingParameters.Additive;
|
Blending = BlendingParameters.Additive;
|
||||||
Origin = Anchor.Centre;
|
Origin = Anchor.Centre;
|
||||||
|
|
||||||
InternalChild = scaleContainer = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon
|
InternalChild = scaleContainer = new ReverseArrowPiece();
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
Icon = FontAwesome.Solid.ChevronRight,
|
|
||||||
Size = new Vector2(0.35f)
|
|
||||||
}, confineMode: ConfineMode.NoScaling)
|
|
||||||
{
|
|
||||||
Anchor = Anchor.Centre,
|
|
||||||
Origin = Anchor.Centre,
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly IBindable<float> scaleBindable = new Bindable<float>();
|
private readonly IBindable<float> scaleBindable = new Bindable<float>();
|
||||||
@ -64,11 +54,11 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
protected override void UpdateInitialTransforms()
|
protected override void UpdateInitialTransforms()
|
||||||
{
|
{
|
||||||
animDuration = Math.Min(150, repeatPoint.SpanDuration / 2);
|
animDuration = Math.Min(300, repeatPoint.SpanDuration);
|
||||||
|
|
||||||
this.Animate(
|
this.Animate(
|
||||||
d => d.FadeIn(animDuration),
|
d => d.FadeIn(animDuration),
|
||||||
d => d.ScaleTo(0.5f).ScaleTo(1f, animDuration * 4, Easing.OutElasticHalf)
|
d => d.ScaleTo(0.5f).ScaleTo(1f, animDuration * 2, Easing.OutElasticHalf)
|
||||||
);
|
);
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -87,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ArmedState.Hit:
|
case ArmedState.Hit:
|
||||||
this.FadeOut(animDuration, Easing.OutQuint)
|
this.FadeOut(animDuration, Easing.Out)
|
||||||
.ScaleTo(Scale * 1.5f, animDuration, Easing.Out);
|
.ScaleTo(Scale * 1.5f, animDuration, Easing.Out);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
@ -98,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
public void UpdateSnakingPosition(Vector2 start, Vector2 end)
|
public void UpdateSnakingPosition(Vector2 start, Vector2 end)
|
||||||
{
|
{
|
||||||
bool isRepeatAtEnd = repeatPoint.RepeatIndex % 2 == 0;
|
bool isRepeatAtEnd = repeatPoint.RepeatIndex % 2 == 0;
|
||||||
List<Vector2> curve = drawableSlider.Body.CurrentCurve;
|
List<Vector2> curve = ((PlaySliderBody)drawableSlider.Body.Drawable).CurrentCurve;
|
||||||
|
|
||||||
Position = isRepeatAtEnd ? end : start;
|
Position = isRepeatAtEnd ? end : start;
|
||||||
|
|
||||||
@ -120,7 +110,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
float aimRotation = MathHelper.RadiansToDegrees(MathF.Atan2(aimRotationVector.Y - Position.Y, aimRotationVector.X - Position.X));
|
float aimRotation = MathUtils.RadiansToDegrees(MathF.Atan2(aimRotationVector.Y - Position.Y, aimRotationVector.X - Position.X));
|
||||||
while (Math.Abs(aimRotation - Rotation) > 180)
|
while (Math.Abs(aimRotation - Rotation) > 180)
|
||||||
aimRotation += aimRotation < Rotation ? 360 : -360;
|
aimRotation += aimRotation < Rotation ? 360 : -360;
|
||||||
|
|
||||||
|
@ -11,7 +11,6 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Rulesets.Objects;
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Configuration;
|
|
||||||
using osu.Game.Rulesets.Osu.Skinning;
|
using osu.Game.Rulesets.Osu.Skinning;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
@ -24,8 +23,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
public DrawableSliderHead HeadCircle => headContainer.Child;
|
public DrawableSliderHead HeadCircle => headContainer.Child;
|
||||||
public DrawableSliderTail TailCircle => tailContainer.Child;
|
public DrawableSliderTail TailCircle => tailContainer.Child;
|
||||||
|
|
||||||
public readonly SnakingSliderBody Body;
|
|
||||||
public readonly SliderBall Ball;
|
public readonly SliderBall Ball;
|
||||||
|
public readonly SkinnableDrawable Body;
|
||||||
|
|
||||||
|
private PlaySliderBody sliderBody => Body.Drawable as PlaySliderBody;
|
||||||
|
|
||||||
private readonly Container<DrawableSliderHead> headContainer;
|
private readonly Container<DrawableSliderHead> headContainer;
|
||||||
private readonly Container<DrawableSliderTail> tailContainer;
|
private readonly Container<DrawableSliderTail> tailContainer;
|
||||||
@ -37,10 +38,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
private readonly IBindable<Vector2> positionBindable = new Bindable<Vector2>();
|
private readonly IBindable<Vector2> positionBindable = new Bindable<Vector2>();
|
||||||
private readonly IBindable<int> stackHeightBindable = new Bindable<int>();
|
private readonly IBindable<int> stackHeightBindable = new Bindable<int>();
|
||||||
private readonly IBindable<float> scaleBindable = new Bindable<float>();
|
private readonly IBindable<float> scaleBindable = new Bindable<float>();
|
||||||
private readonly IBindable<int> pathVersion = new Bindable<int>();
|
|
||||||
|
|
||||||
[Resolved(CanBeNull = true)]
|
|
||||||
private OsuRulesetConfigManager config { get; set; }
|
|
||||||
|
|
||||||
public DrawableSlider(Slider s)
|
public DrawableSlider(Slider s)
|
||||||
: base(s)
|
: base(s)
|
||||||
@ -51,7 +48,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
Body = new SnakingSliderBody(s),
|
Body = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling),
|
||||||
tickContainer = new Container<DrawableSliderTick> { RelativeSizeAxes = Axes.Both },
|
tickContainer = new Container<DrawableSliderTick> { RelativeSizeAxes = Axes.Both },
|
||||||
repeatContainer = new Container<DrawableRepeatPoint> { RelativeSizeAxes = Axes.Both },
|
repeatContainer = new Container<DrawableRepeatPoint> { RelativeSizeAxes = Axes.Both },
|
||||||
Ball = new SliderBall(s, this)
|
Ball = new SliderBall(s, this)
|
||||||
@ -70,28 +67,16 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
config?.BindWith(OsuRulesetSetting.SnakingInSliders, Body.SnakingIn);
|
|
||||||
config?.BindWith(OsuRulesetSetting.SnakingOutSliders, Body.SnakingOut);
|
|
||||||
|
|
||||||
positionBindable.BindValueChanged(_ => Position = HitObject.StackedPosition);
|
positionBindable.BindValueChanged(_ => Position = HitObject.StackedPosition);
|
||||||
stackHeightBindable.BindValueChanged(_ => Position = HitObject.StackedPosition);
|
stackHeightBindable.BindValueChanged(_ => Position = HitObject.StackedPosition);
|
||||||
scaleBindable.BindValueChanged(scale =>
|
scaleBindable.BindValueChanged(scale => Ball.Scale = new Vector2(scale.NewValue));
|
||||||
{
|
|
||||||
updatePathRadius();
|
|
||||||
Ball.Scale = new Vector2(scale.NewValue);
|
|
||||||
});
|
|
||||||
|
|
||||||
positionBindable.BindTo(HitObject.PositionBindable);
|
positionBindable.BindTo(HitObject.PositionBindable);
|
||||||
stackHeightBindable.BindTo(HitObject.StackHeightBindable);
|
stackHeightBindable.BindTo(HitObject.StackHeightBindable);
|
||||||
scaleBindable.BindTo(HitObject.ScaleBindable);
|
scaleBindable.BindTo(HitObject.ScaleBindable);
|
||||||
pathVersion.BindTo(slider.Path.Version);
|
|
||||||
|
|
||||||
pathVersion.BindValueChanged(_ => Body.Refresh());
|
|
||||||
|
|
||||||
AccentColour.BindValueChanged(colour =>
|
AccentColour.BindValueChanged(colour =>
|
||||||
{
|
{
|
||||||
Body.AccentColour = colour.NewValue;
|
|
||||||
|
|
||||||
foreach (var drawableHitObject in NestedHitObjects)
|
foreach (var drawableHitObject in NestedHitObjects)
|
||||||
drawableHitObject.AccentColour.Value = colour.NewValue;
|
drawableHitObject.AccentColour.Value = colour.NewValue;
|
||||||
}, true);
|
}, true);
|
||||||
@ -169,16 +154,16 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
double completionProgress = Math.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1);
|
double completionProgress = Math.Clamp((Time.Current - slider.StartTime) / slider.Duration, 0, 1);
|
||||||
|
|
||||||
Ball.UpdateProgress(completionProgress);
|
Ball.UpdateProgress(completionProgress);
|
||||||
Body.UpdateProgress(completionProgress);
|
sliderBody?.UpdateProgress(completionProgress);
|
||||||
|
|
||||||
foreach (DrawableHitObject hitObject in NestedHitObjects)
|
foreach (DrawableHitObject hitObject in NestedHitObjects)
|
||||||
{
|
{
|
||||||
if (hitObject is ITrackSnaking s) s.UpdateSnakingPosition(slider.Path.PositionAt(Body.SnakedStart ?? 0), slider.Path.PositionAt(Body.SnakedEnd ?? 0));
|
if (hitObject is ITrackSnaking s) s.UpdateSnakingPosition(slider.Path.PositionAt(sliderBody?.SnakedStart ?? 0), slider.Path.PositionAt(sliderBody?.SnakedEnd ?? 0));
|
||||||
if (hitObject is IRequireTracking t) t.Tracking = Ball.Tracking;
|
if (hitObject is IRequireTracking t) t.Tracking = Ball.Tracking;
|
||||||
}
|
}
|
||||||
|
|
||||||
Size = Body.Size;
|
Size = sliderBody?.Size ?? Vector2.Zero;
|
||||||
OriginPosition = Body.PathOffset;
|
OriginPosition = sliderBody?.PathOffset ?? Vector2.Zero;
|
||||||
|
|
||||||
if (DrawSize != Vector2.Zero)
|
if (DrawSize != Vector2.Zero)
|
||||||
{
|
{
|
||||||
@ -192,28 +177,17 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
public override void OnKilled()
|
public override void OnKilled()
|
||||||
{
|
{
|
||||||
base.OnKilled();
|
base.OnKilled();
|
||||||
Body.RecyclePath();
|
sliderBody?.RecyclePath();
|
||||||
}
|
}
|
||||||
|
|
||||||
private float sliderPathRadius;
|
|
||||||
|
|
||||||
protected override void ApplySkin(ISkinSource skin, bool allowFallback)
|
protected override void ApplySkin(ISkinSource skin, bool allowFallback)
|
||||||
{
|
{
|
||||||
base.ApplySkin(skin, allowFallback);
|
base.ApplySkin(skin, allowFallback);
|
||||||
|
|
||||||
Body.BorderSize = skin.GetConfig<OsuSkinConfiguration, float>(OsuSkinConfiguration.SliderBorderSize)?.Value ?? SliderBody.DEFAULT_BORDER_SIZE;
|
|
||||||
sliderPathRadius = skin.GetConfig<OsuSkinConfiguration, float>(OsuSkinConfiguration.SliderPathRadius)?.Value ?? OsuHitObject.OBJECT_RADIUS;
|
|
||||||
updatePathRadius();
|
|
||||||
|
|
||||||
Body.AccentColour = skin.GetConfig<OsuSkinColour, Color4>(OsuSkinColour.SliderTrackOverride)?.Value ?? AccentColour.Value;
|
|
||||||
Body.BorderColour = skin.GetConfig<OsuSkinColour, Color4>(OsuSkinColour.SliderBorder)?.Value ?? Color4.White;
|
|
||||||
|
|
||||||
bool allowBallTint = skin.GetConfig<OsuSkinConfiguration, bool>(OsuSkinConfiguration.AllowSliderBallTint)?.Value ?? false;
|
bool allowBallTint = skin.GetConfig<OsuSkinConfiguration, bool>(OsuSkinConfiguration.AllowSliderBallTint)?.Value ?? false;
|
||||||
Ball.Colour = allowBallTint ? AccentColour.Value : Color4.White;
|
Ball.Colour = allowBallTint ? AccentColour.Value : Color4.White;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updatePathRadius() => Body.PathRadius = slider.Scale * sliderPathRadius;
|
|
||||||
|
|
||||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||||
{
|
{
|
||||||
if (userTriggered || Time.Current < slider.EndTime)
|
if (userTriggered || Time.Current < slider.EndTime)
|
||||||
@ -264,6 +238,10 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
public Drawable ProxiedLayer => HeadCircle.ProxiedLayer;
|
public Drawable ProxiedLayer => HeadCircle.ProxiedLayer;
|
||||||
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => Body.ReceivePositionalInputAt(screenSpacePos);
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => sliderBody?.ReceivePositionalInputAt(screenSpacePos) ?? base.ReceivePositionalInputAt(screenSpacePos);
|
||||||
|
|
||||||
|
private class DefaultSliderBody : PlaySliderBody
|
||||||
|
{
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
public readonly SpinnerDisc Disc;
|
public readonly SpinnerDisc Disc;
|
||||||
public readonly SpinnerTicks Ticks;
|
public readonly SpinnerTicks Ticks;
|
||||||
private readonly SpinnerSpmCounter spmCounter;
|
public readonly SpinnerSpmCounter SpmCounter;
|
||||||
|
|
||||||
private readonly Container mainContainer;
|
private readonly Container mainContainer;
|
||||||
|
|
||||||
@ -110,7 +110,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
spmCounter = new SpinnerSpmCounter
|
SpmCounter = new SpinnerSpmCounter
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -177,8 +177,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
protected override void Update()
|
protected override void Update()
|
||||||
{
|
{
|
||||||
Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false;
|
Disc.Tracking = OsuActionInputManager?.PressedActions.Any(x => x == OsuAction.LeftButton || x == OsuAction.RightButton) ?? false;
|
||||||
if (!spmCounter.IsPresent && Disc.Tracking)
|
if (!SpmCounter.IsPresent && Disc.Tracking)
|
||||||
spmCounter.FadeIn(HitObject.TimeFadeIn);
|
SpmCounter.FadeIn(HitObject.TimeFadeIn);
|
||||||
|
|
||||||
base.Update();
|
base.Update();
|
||||||
}
|
}
|
||||||
@ -189,7 +189,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
|
|
||||||
circle.Rotation = Disc.Rotation;
|
circle.Rotation = Disc.Rotation;
|
||||||
Ticks.Rotation = Disc.Rotation;
|
Ticks.Rotation = Disc.Rotation;
|
||||||
spmCounter.SetRotation(Disc.RotationAbsolute);
|
SpmCounter.SetRotation(Disc.RotationAbsolute);
|
||||||
|
|
||||||
float relativeCircleScale = Spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight;
|
float relativeCircleScale = Spinner.Scale * circle.DrawHeight / mainContainer.DrawHeight;
|
||||||
Disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint);
|
Disc.ScaleTo(relativeCircleScale + (1 - relativeCircleScale) * Progress, 200, Easing.OutQuint);
|
||||||
|
@ -0,0 +1,70 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Framework.Graphics.Lines;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||||
|
{
|
||||||
|
public abstract class DrawableSliderPath : SmoothPath
|
||||||
|
{
|
||||||
|
protected const float BORDER_PORTION = 0.128f;
|
||||||
|
protected const float GRADIENT_PORTION = 1 - BORDER_PORTION;
|
||||||
|
|
||||||
|
private const float border_max_size = 8f;
|
||||||
|
private const float border_min_size = 0f;
|
||||||
|
|
||||||
|
private Color4 borderColour = Color4.White;
|
||||||
|
|
||||||
|
public Color4 BorderColour
|
||||||
|
{
|
||||||
|
get => borderColour;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (borderColour == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
borderColour = value;
|
||||||
|
|
||||||
|
InvalidateTexture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private Color4 accentColour = Color4.White;
|
||||||
|
|
||||||
|
public Color4 AccentColour
|
||||||
|
{
|
||||||
|
get => accentColour;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (accentColour == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
accentColour = value;
|
||||||
|
|
||||||
|
InvalidateTexture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private float borderSize = 1;
|
||||||
|
|
||||||
|
public float BorderSize
|
||||||
|
{
|
||||||
|
get => borderSize;
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (borderSize == value)
|
||||||
|
return;
|
||||||
|
|
||||||
|
if (value < border_min_size || value > border_max_size)
|
||||||
|
return;
|
||||||
|
|
||||||
|
borderSize = value;
|
||||||
|
|
||||||
|
InvalidateTexture();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
protected float CalculatedBorderPortion => BorderSize * BORDER_PORTION;
|
||||||
|
}
|
||||||
|
}
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
x
Reference in New Issue
Block a user