mirror of
https://github.com/osukey/osukey.git
synced 2025-07-01 16:29:58 +09:00
Merge branch 'buttonsystem-entermode' of https://github.com/nyquillerium/osu into buttonsystem-entermode
This commit is contained in:
1
.github/FUNDING.yml
vendored
Normal file
1
.github/FUNDING.yml
vendored
Normal file
@ -0,0 +1 @@
|
|||||||
|
custom: https://osu.ppy.sh/home/support
|
@ -1,18 +1,21 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (catch)" type="DotNetProject" factoryName=".NET Project">
|
<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/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp2.2/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" />
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
<option name="USE_MONO" value="0" />
|
<option name="USE_MONO" value="0" />
|
||||||
|
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj" />
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj" />
|
||||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||||
<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=v2.2" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method />
|
<method v="2">
|
||||||
|
<option name="Build" enabled="true" />
|
||||||
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
@ -1,18 +1,21 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (mania)" type="DotNetProject" factoryName=".NET Project">
|
<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/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp2.2/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" />
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
<option name="USE_MONO" value="0" />
|
<option name="USE_MONO" value="0" />
|
||||||
|
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj" />
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj" />
|
||||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||||
<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=v2.2" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method />
|
<method v="2">
|
||||||
|
<option name="Build" enabled="true" />
|
||||||
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
@ -1,18 +1,21 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (osu!)" type="DotNetProject" factoryName=".NET Project">
|
<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/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp2.2/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" />
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
<option name="USE_MONO" value="0" />
|
<option name="USE_MONO" value="0" />
|
||||||
|
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj" />
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj" />
|
||||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||||
<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=v2.2" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method />
|
<method v="2">
|
||||||
|
<option name="Build" enabled="true" />
|
||||||
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
@ -1,18 +1,21 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="RulesetTests (taiko)" type="DotNetProject" factoryName=".NET Project">
|
<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/netcoreapp2.2/osu.Game.Rulesets.Taiko.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp2.2/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" />
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
<option name="USE_MONO" value="0" />
|
<option name="USE_MONO" value="0" />
|
||||||
|
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj" />
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj" />
|
||||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||||
<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=v2.2" />
|
||||||
<browser url="http://localhost:5000" />
|
<browser url="http://localhost:5000" />
|
||||||
<method />
|
<method v="2">
|
||||||
|
<option name="Build" enabled="true" />
|
||||||
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
20
.idea/.idea.osu/.idea/runConfigurations/Tournament.xml
generated
Normal file
20
.idea/.idea.osu/.idea/runConfigurations/Tournament.xml
generated
Normal file
@ -0,0 +1,20 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<configuration default="false" name="Tournament" type="DotNetProject" factoryName=".NET Project" folderName="Tournament">
|
||||||
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll" />
|
||||||
|
<option name="PROGRAM_PARAMETERS" value="--tournament" />
|
||||||
|
<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=v2.2" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Build" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
21
.idea/.idea.osu/.idea/runConfigurations/Tournament__Tests_.xml
generated
Normal file
21
.idea/.idea.osu/.idea/runConfigurations/Tournament__Tests_.xml
generated
Normal file
@ -0,0 +1,21 @@
|
|||||||
|
<component name="ProjectRunConfigurationManager">
|
||||||
|
<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="PROGRAM_PARAMETERS" value="" />
|
||||||
|
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tournament.Tests" />
|
||||||
|
<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.Tournament.Tests/osu.Game.Tournament.Tests.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=v2.1" />
|
||||||
|
<browser url="http://localhost:5000" />
|
||||||
|
<method v="2">
|
||||||
|
<option name="Build" enabled="true" />
|
||||||
|
</method>
|
||||||
|
</configuration>
|
||||||
|
</component>
|
2
.idea/.idea.osu/.idea/runConfigurations/osu_.xml
generated
2
.idea/.idea.osu/.idea/runConfigurations/osu_.xml
generated
@ -1,5 +1,5 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project">
|
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
|
||||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.2/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" />
|
||||||
|
@ -1,17 +1,20 @@
|
|||||||
<component name="ProjectRunConfigurationManager">
|
<component name="ProjectRunConfigurationManager">
|
||||||
<configuration default="false" name="VisualTests" type="DotNetProject" factoryName=".NET Project">
|
<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/netcoreapp2.2/osu.Game.Tests.dll" />
|
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.2/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" />
|
||||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||||
<option name="USE_MONO" value="0" />
|
<option name="USE_MONO" value="0" />
|
||||||
|
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Tests/osu.Game.Tests.csproj" />
|
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Tests/osu.Game.Tests.csproj" />
|
||||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||||
<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=v2.2" />
|
||||||
<method />
|
<method v="2">
|
||||||
|
<option name="Build" enabled="true" />
|
||||||
|
</method>
|
||||||
</configuration>
|
</configuration>
|
||||||
</component>
|
</component>
|
142
.vscode/launch.json
vendored
142
.vscode/launch.json
vendored
@ -1,41 +1,6 @@
|
|||||||
{
|
{
|
||||||
"version": "0.2.0",
|
"version": "0.2.0",
|
||||||
"configurations": [
|
"configurations": [{
|
||||||
{
|
|
||||||
"name": "VisualTests (Debug)",
|
|
||||||
"type": "coreclr",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "dotnet",
|
|
||||||
"args": [
|
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tests.dll"
|
|
||||||
],
|
|
||||||
"cwd": "${workspaceRoot}",
|
|
||||||
"preLaunchTask": "Build tests (Debug)",
|
|
||||||
"linux": {
|
|
||||||
"env": {
|
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"console": "internalConsole"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "VisualTests (Release)",
|
|
||||||
"type": "coreclr",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "dotnet",
|
|
||||||
"args": [
|
|
||||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2/osu.Game.Tests.dll"
|
|
||||||
],
|
|
||||||
"cwd": "${workspaceRoot}",
|
|
||||||
"preLaunchTask": "Build tests (Release)",
|
|
||||||
"linux": {
|
|
||||||
"env": {
|
|
||||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
|
||||||
}
|
|
||||||
},
|
|
||||||
"console": "internalConsole"
|
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "osu! (Debug)",
|
"name": "osu! (Debug)",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
"request": "launch",
|
"request": "launch",
|
||||||
@ -69,6 +34,111 @@
|
|||||||
},
|
},
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"name": "osu! (Tests, Debug)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tests.dll"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"preLaunchTask": "Build tests (Debug)",
|
||||||
|
"linux": {
|
||||||
|
"env": {
|
||||||
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"console": "internalConsole"
|
||||||
|
}, {
|
||||||
|
"name": "osu! (Tests, Release)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2/osu.Game.Tests.dll"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"preLaunchTask": "Build tests (Release)",
|
||||||
|
"linux": {
|
||||||
|
"env": {
|
||||||
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"console": "internalConsole"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tournament (Debug)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll",
|
||||||
|
"--tournament"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"preLaunchTask": "Build osu! (Debug)",
|
||||||
|
"linux": {
|
||||||
|
"env": {
|
||||||
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"console": "internalConsole"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tournament (Release)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2/osu!.dll",
|
||||||
|
"--tournament"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"preLaunchTask": "Build osu! (Release)",
|
||||||
|
"linux": {
|
||||||
|
"env": {
|
||||||
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"console": "internalConsole"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tournament (Tests, Debug)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tournament.Tests.dll",
|
||||||
|
"--tournament"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"preLaunchTask": "Build tournament tests (Debug)",
|
||||||
|
"linux": {
|
||||||
|
"env": {
|
||||||
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"console": "internalConsole"
|
||||||
|
},
|
||||||
|
{
|
||||||
|
"name": "Tournament (Tests, Release)",
|
||||||
|
"type": "coreclr",
|
||||||
|
"request": "launch",
|
||||||
|
"program": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tournament.Tests.dll",
|
||||||
|
"--tournament"
|
||||||
|
],
|
||||||
|
"cwd": "${workspaceRoot}",
|
||||||
|
"preLaunchTask": "Build tournament tests (Release)",
|
||||||
|
"linux": {
|
||||||
|
"env": {
|
||||||
|
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||||
|
}
|
||||||
|
},
|
||||||
|
"console": "internalConsole"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"name": "Cake: Debug Script",
|
"name": "Cake: Debug Script",
|
||||||
"type": "coreclr",
|
"type": "coreclr",
|
||||||
|
33
.vscode/tasks.json
vendored
33
.vscode/tasks.json
vendored
@ -2,8 +2,7 @@
|
|||||||
// 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",
|
||||||
@ -65,6 +64,36 @@
|
|||||||
"group": "build",
|
"group": "build",
|
||||||
"problemMatcher": "$msCompile"
|
"problemMatcher": "$msCompile"
|
||||||
},
|
},
|
||||||
|
{
|
||||||
|
"label": "Build tournament tests (Debug)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--no-restore",
|
||||||
|
"osu.Game.Tournament.Tests",
|
||||||
|
"/p:GenerateFullPaths=true",
|
||||||
|
"/m",
|
||||||
|
"/verbosity:m"
|
||||||
|
],
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
}, {
|
||||||
|
"label": "Build tournament tests (Release)",
|
||||||
|
"type": "shell",
|
||||||
|
"command": "dotnet",
|
||||||
|
"args": [
|
||||||
|
"build",
|
||||||
|
"--no-restore",
|
||||||
|
"osu.Game.Tournament.Tests",
|
||||||
|
"/p:Configuration=Release",
|
||||||
|
"/p:GenerateFullPaths=true",
|
||||||
|
"/m",
|
||||||
|
"/verbosity:m"
|
||||||
|
],
|
||||||
|
"group": "build",
|
||||||
|
"problemMatcher": "$msCompile"
|
||||||
|
},
|
||||||
{
|
{
|
||||||
"label": "Restore (netcoreapp2.2)",
|
"label": "Restore (netcoreapp2.2)",
|
||||||
"type": "shell",
|
"type": "shell",
|
||||||
|
23
README.md
23
README.md
@ -10,6 +10,8 @@ This project is still heavily under development, but is in a state where users a
|
|||||||
|
|
||||||
We are accepting bug reports (please report with as much detail as possible). Feature requests are welcome as long as you read and understand the contribution guidelines listed below.
|
We are accepting bug reports (please report with as much detail as possible). Feature requests are welcome as long as you read and understand the contribution guidelines listed below.
|
||||||
|
|
||||||
|
Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh/home/changelog).
|
||||||
|
|
||||||
## Requirements
|
## Requirements
|
||||||
|
|
||||||
- A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed.
|
- A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed.
|
||||||
@ -20,17 +22,24 @@ We are accepting bug reports (please report with as much detail as possible). Fe
|
|||||||
|
|
||||||
### Releases
|
### Releases
|
||||||
|
|
||||||
If you are not interested in developing the game, please head over to the [releases](https://github.com/ppy/osu/releases) to download a precompiled build with automatic updating enabled.
|

|
||||||
|
|
||||||
- Windows (x64) users should download and run `install.exe`.
|
If you are not interested in developing the game, you can still consume our [binary releases](https://github.com/ppy/osu/releases).
|
||||||
- macOS users (10.12 "Sierra" and higher) should download and run `osu.app.zip`.
|
|
||||||
- iOS users can join the [TestFlight beta program](https://t.co/xQJmHkfC18).
|
**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) |
|
||||||
|
| ------------- | ------------- |
|
||||||
|
|
||||||
|
- **Linux** users are recommended to self-compile until we have official deployment in place.
|
||||||
|
- **iOS** users can join the [TestFlight beta program](https://t.co/PasE1zrHhw) (note that due to high demand this is regularly full).
|
||||||
|
- **Android** users can self-compile, and expect a public beta soon.
|
||||||
|
|
||||||
If your platform is not listed above, there is still a chance you can manually build it by following the instructions below.
|
If your platform is not listed above, there is still a chance you can manually build it by following the instructions below.
|
||||||
|
|
||||||
### Downloading the source code
|
### Downloading the source code
|
||||||
|
|
||||||
Clone the repository **including submodules**:
|
Clone the repository:
|
||||||
|
|
||||||
```shell
|
```shell
|
||||||
git clone https://github.com/ppy/osu
|
git clone https://github.com/ppy/osu
|
||||||
@ -45,7 +54,7 @@ git pull
|
|||||||
|
|
||||||
### Building
|
### Building
|
||||||
|
|
||||||
Build configurations for the recommended IDEs (listed above) are included. You should use the provided Build/Run functionality of your IDE to get things going. When testing or building new components, it's highly encouraged you use the `VisualTests` project/configuration. More information on this provided below.
|
Build configurations for the recommended IDEs (listed above) are included. You should use the provided Build/Run functionality of your IDE to get things going. When testing or building new components, it's highly encouraged you use the `VisualTests` project/configuration. More information on this provided [below](#contributing).
|
||||||
|
|
||||||
> Visual Studio Code users must run the `Restore` task before any build attempt.
|
> Visual Studio Code users must run the `Restore` task before any build attempt.
|
||||||
|
|
||||||
@ -63,7 +72,7 @@ If the build fails, try to restore nuget packages with `dotnet restore`.
|
|||||||
|
|
||||||
On Linux, the environment variable `LD_LIBRARY_PATH` must point to the build directory, located at `osu.Desktop/bin/Debug/$NETCORE_VERSION`.
|
On Linux, the environment variable `LD_LIBRARY_PATH` must point to the build directory, located at `osu.Desktop/bin/Debug/$NETCORE_VERSION`.
|
||||||
|
|
||||||
`$NETCORE_VERSION` is the version of .NET Core SDK. You can have it with `grep TargetFramework osu.Desktop/osu.Desktop.csproj | sed -r 's/.*>(.*)<\/.*/\1/'`.
|
`$NETCORE_VERSION` is the version of the targeted .NET Core SDK. You can check it by running `grep TargetFramework osu.Desktop/osu.Desktop.csproj | sed -r 's/.*>(.*)<\/.*/\1/'`.
|
||||||
|
|
||||||
For example, you can run osu! with the following command:
|
For example, you can run osu! with the following command:
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ platform :ios do
|
|||||||
changelog.gsub!('$BUILD_ID', options[:build])
|
changelog.gsub!('$BUILD_ID', options[:build])
|
||||||
|
|
||||||
pilot(
|
pilot(
|
||||||
wait_processing_interval: 900,
|
wait_processing_interval: 1800,
|
||||||
changelog: changelog,
|
changelog: changelog,
|
||||||
ipa: './osu.iOS/bin/iPhone/Release/osu.iOS.ipa'
|
ipa: './osu.iOS/bin/iPhone/Release/osu.iOS.ipa'
|
||||||
)
|
)
|
||||||
|
@ -7,7 +7,6 @@ using System.Linq;
|
|||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using osu.Desktop.Overlays;
|
using osu.Desktop.Overlays;
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game;
|
using osu.Game;
|
||||||
using osuTK.Input;
|
using osuTK.Input;
|
||||||
@ -56,7 +55,7 @@ namespace osu.Desktop
|
|||||||
LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, v =>
|
LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, v =>
|
||||||
{
|
{
|
||||||
Add(v);
|
Add(v);
|
||||||
v.State = Visibility.Visible;
|
v.Show();
|
||||||
});
|
});
|
||||||
|
|
||||||
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows)
|
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows)
|
||||||
@ -74,13 +73,11 @@ namespace osu.Desktop
|
|||||||
{
|
{
|
||||||
case Intro _:
|
case Intro _:
|
||||||
case MainMenu _:
|
case MainMenu _:
|
||||||
if (versionManager != null)
|
versionManager?.Show();
|
||||||
versionManager.State = Visibility.Visible;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
if (versionManager != null)
|
versionManager?.Hide();
|
||||||
versionManager.State = Visibility.Hidden;
|
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,20 +1,18 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Development;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Platform;
|
|
||||||
using osu.Game;
|
using osu.Game;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
using osu.Game.Utils;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -25,15 +23,13 @@ namespace osu.Desktop.Overlays
|
|||||||
private OsuConfigManager config;
|
private OsuConfigManager config;
|
||||||
private OsuGameBase game;
|
private OsuGameBase game;
|
||||||
private NotificationOverlay notificationOverlay;
|
private NotificationOverlay notificationOverlay;
|
||||||
private GameHost host;
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config, GameHost host)
|
private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config)
|
||||||
{
|
{
|
||||||
notificationOverlay = notification;
|
notificationOverlay = notification;
|
||||||
this.config = config;
|
this.config = config;
|
||||||
this.game = game;
|
this.game = game;
|
||||||
this.host = host;
|
|
||||||
|
|
||||||
AutoSizeAxes = Axes.Both;
|
AutoSizeAxes = Axes.Both;
|
||||||
Anchor = Anchor.BottomCentre;
|
Anchor = Anchor.BottomCentre;
|
||||||
@ -65,7 +61,7 @@ namespace osu.Desktop.Overlays
|
|||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Colour = DebugUtils.IsDebug ? colours.Red : Color4.White,
|
Colour = DebugUtils.IsDebugBuild ? colours.Red : Color4.White,
|
||||||
Text = game.Version
|
Text = game.Version
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
@ -102,27 +98,31 @@ namespace osu.Desktop.Overlays
|
|||||||
|
|
||||||
// only show a notification if we've previously saved a version to the config file (ie. not the first run).
|
// only show a notification if we've previously saved a version to the config file (ie. not the first run).
|
||||||
if (!string.IsNullOrEmpty(lastVersion))
|
if (!string.IsNullOrEmpty(lastVersion))
|
||||||
notificationOverlay.Post(new UpdateCompleteNotification(version, host.OpenUrlExternally));
|
notificationOverlay.Post(new UpdateCompleteNotification(version));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class UpdateCompleteNotification : SimpleNotification
|
private class UpdateCompleteNotification : SimpleNotification
|
||||||
{
|
{
|
||||||
public UpdateCompleteNotification(string version, Action<string> openUrl = null)
|
private readonly string version;
|
||||||
|
|
||||||
|
public UpdateCompleteNotification(string version)
|
||||||
{
|
{
|
||||||
|
this.version = version;
|
||||||
Text = $"You are now running osu!lazer {version}.\nClick to see what's new!";
|
Text = $"You are now running osu!lazer {version}.\nClick to see what's new!";
|
||||||
Icon = FontAwesome.Solid.CheckSquare;
|
|
||||||
Activated = delegate
|
|
||||||
{
|
|
||||||
openUrl?.Invoke($"https://osu.ppy.sh/home/changelog/lazer/{version}");
|
|
||||||
return true;
|
|
||||||
};
|
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuColour colours)
|
private void load(OsuColour colours, ChangelogOverlay changelog)
|
||||||
{
|
{
|
||||||
|
Icon = FontAwesome.Solid.CheckSquare;
|
||||||
IconBackgound.Colour = colours.BlueDark;
|
IconBackgound.Colour = colours.BlueDark;
|
||||||
|
|
||||||
|
Activated = delegate
|
||||||
|
{
|
||||||
|
changelog.ShowBuild(OsuGameBase.CLIENT_STREAM_NAME, version);
|
||||||
|
return true;
|
||||||
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Development;
|
|||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.IPC;
|
using osu.Game.IPC;
|
||||||
|
using osu.Game.Tournament;
|
||||||
|
|
||||||
namespace osu.Desktop
|
namespace osu.Desktop
|
||||||
{
|
{
|
||||||
@ -46,6 +47,10 @@ namespace osu.Desktop
|
|||||||
default:
|
default:
|
||||||
host.Run(new OsuGameDesktop(args));
|
host.Run(new OsuGameDesktop(args));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case "--tournament":
|
||||||
|
host.Run(new TournamentGame());
|
||||||
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@ -25,11 +25,7 @@ namespace osu.Desktop.Updater
|
|||||||
private UpdateManager updateManager;
|
private UpdateManager updateManager;
|
||||||
private NotificationOverlay notificationOverlay;
|
private NotificationOverlay notificationOverlay;
|
||||||
|
|
||||||
public void PrepareUpdate()
|
public Task PrepareUpdateAsync() => UpdateManager.RestartAppWhenExited();
|
||||||
{
|
|
||||||
// Squirrel returns execution to us after the update process is started, so it's safe to use Wait() here
|
|
||||||
UpdateManager.RestartAppWhenExited().Wait();
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(NotificationOverlay notification, OsuGameBase game)
|
private void load(NotificationOverlay notification, OsuGameBase game)
|
||||||
@ -46,7 +42,7 @@ namespace osu.Desktop.Updater
|
|||||||
private async void checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null)
|
private async void checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null)
|
||||||
{
|
{
|
||||||
//should we schedule a retry on completion of this check?
|
//should we schedule a retry on completion of this check?
|
||||||
bool scheduleRetry = true;
|
bool scheduleRecheck = true;
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -86,10 +82,11 @@ namespace osu.Desktop.Updater
|
|||||||
//could fail if deltas are unavailable for full update path (https://github.com/Squirrel/Squirrel.Windows/issues/959)
|
//could fail if deltas are unavailable for full update path (https://github.com/Squirrel/Squirrel.Windows/issues/959)
|
||||||
//try again without deltas.
|
//try again without deltas.
|
||||||
checkForUpdateAsync(false, notification);
|
checkForUpdateAsync(false, notification);
|
||||||
scheduleRetry = false;
|
scheduleRecheck = false;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
|
notification.State = ProgressNotificationState.Cancelled;
|
||||||
Logger.Error(e, @"update failed!");
|
Logger.Error(e, @"update failed!");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -100,11 +97,8 @@ namespace osu.Desktop.Updater
|
|||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
if (scheduleRetry)
|
if (scheduleRecheck)
|
||||||
{
|
{
|
||||||
if (notification != null)
|
|
||||||
notification.State = ProgressNotificationState.Cancelled;
|
|
||||||
|
|
||||||
//check again in 30 minutes.
|
//check again in 30 minutes.
|
||||||
Scheduler.AddDelayed(() => checkForUpdateAsync(), 60000 * 30);
|
Scheduler.AddDelayed(() => checkForUpdateAsync(), 60000 * 30);
|
||||||
}
|
}
|
||||||
@ -134,8 +128,8 @@ namespace osu.Desktop.Updater
|
|||||||
Text = @"Update ready to install. Click to restart!",
|
Text = @"Update ready to install. Click to restart!",
|
||||||
Activated = () =>
|
Activated = () =>
|
||||||
{
|
{
|
||||||
updateManager.PrepareUpdate();
|
updateManager.PrepareUpdateAsync()
|
||||||
game.GracefullyExit();
|
.ContinueWith(_ => Schedule(() => game.GracefullyExit()));
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -17,6 +17,7 @@
|
|||||||
<StartupObject>osu.Desktop.Program</StartupObject>
|
<StartupObject>osu.Desktop.Program</StartupObject>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Project References">
|
<ItemGroup Label="Project References">
|
||||||
|
<ProjectReference Include="..\osu.Game.Tournament\osu.Game.Tournament.csproj" />
|
||||||
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||||
|
@ -20,14 +20,14 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmap CreateBeatmap(Ruleset ruleset)
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||||
{
|
{
|
||||||
var beatmap = new Beatmap
|
var beatmap = new Beatmap
|
||||||
{
|
{
|
||||||
BeatmapInfo = new BeatmapInfo
|
BeatmapInfo = new BeatmapInfo
|
||||||
{
|
{
|
||||||
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6, SliderMultiplier = 3 },
|
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6, SliderMultiplier = 3 },
|
||||||
Ruleset = ruleset.RulesetInfo
|
Ruleset = ruleset
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -29,14 +29,14 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmap CreateBeatmap(Ruleset ruleset)
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||||
{
|
{
|
||||||
var beatmap = new Beatmap
|
var beatmap = new Beatmap
|
||||||
{
|
{
|
||||||
BeatmapInfo = new BeatmapInfo
|
BeatmapInfo = new BeatmapInfo
|
||||||
{
|
{
|
||||||
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
|
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
|
||||||
Ruleset = ruleset.RulesetInfo
|
Ruleset = ruleset
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -16,14 +16,14 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmap CreateBeatmap(Ruleset ruleset)
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||||
{
|
{
|
||||||
var beatmap = new Beatmap
|
var beatmap = new Beatmap
|
||||||
{
|
{
|
||||||
BeatmapInfo = new BeatmapInfo
|
BeatmapInfo = new BeatmapInfo
|
||||||
{
|
{
|
||||||
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
|
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
|
||||||
Ruleset = ruleset.RulesetInfo
|
Ruleset = ruleset
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
105
osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs
Normal file
105
osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs
Normal file
@ -0,0 +1,105 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
using osu.Framework.Audio.Sample;
|
||||||
|
using osu.Framework.Graphics.Textures;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneCatcher : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(CatcherSprite),
|
||||||
|
};
|
||||||
|
|
||||||
|
private readonly Container container;
|
||||||
|
|
||||||
|
public TestSceneCatcher()
|
||||||
|
{
|
||||||
|
Child = container = new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
AddStep("show default catcher implementation", () => { container.Child = new CatcherSprite(); });
|
||||||
|
|
||||||
|
AddStep("show custom catcher implementation", () =>
|
||||||
|
{
|
||||||
|
container.Child = new CatchCustomSkinSourceContainer
|
||||||
|
{
|
||||||
|
Child = new CatcherSprite()
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private class CatcherCustomSkin : Container
|
||||||
|
{
|
||||||
|
public CatcherCustomSkin()
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both;
|
||||||
|
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Blue
|
||||||
|
},
|
||||||
|
new SpriteText
|
||||||
|
{
|
||||||
|
Text = "custom"
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Cached(typeof(ISkinSource))]
|
||||||
|
private class CatchCustomSkinSourceContainer : Container, ISkinSource
|
||||||
|
{
|
||||||
|
public event Action SourceChanged
|
||||||
|
{
|
||||||
|
add { }
|
||||||
|
remove { }
|
||||||
|
}
|
||||||
|
|
||||||
|
public Drawable GetDrawableComponent(string componentName)
|
||||||
|
{
|
||||||
|
switch (componentName)
|
||||||
|
{
|
||||||
|
case "Play/Catch/fruit-catcher-idle":
|
||||||
|
return new CatcherCustomSkin();
|
||||||
|
}
|
||||||
|
|
||||||
|
return null;
|
||||||
|
}
|
||||||
|
|
||||||
|
public SampleChannel GetSample(string sampleName) =>
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
|
public Texture GetTexture(string componentName) =>
|
||||||
|
throw new NotImplementedException();
|
||||||
|
|
||||||
|
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration =>
|
||||||
|
throw new NotImplementedException();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,6 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
@ -17,19 +16,19 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[Test]
|
||||||
private void load()
|
public void TestHyperDash()
|
||||||
{
|
{
|
||||||
AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash);
|
AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmap CreateBeatmap(Ruleset ruleset)
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||||
{
|
{
|
||||||
var beatmap = new Beatmap
|
var beatmap = new Beatmap
|
||||||
{
|
{
|
||||||
BeatmapInfo =
|
BeatmapInfo =
|
||||||
{
|
{
|
||||||
Ruleset = ruleset.RulesetInfo,
|
Ruleset = ruleset,
|
||||||
BaseDifficulty = new BeatmapDifficulty { CircleSize = 3.6f }
|
BaseDifficulty = new BeatmapDifficulty { CircleSize = 3.6f }
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||||
{
|
{
|
||||||
if (beatmap.HitObjects.Count == 0)
|
if (beatmap.HitObjects.Count == 0)
|
||||||
return new CatchDifficultyAttributes { Mods = mods };
|
return new CatchDifficultyAttributes { Mods = mods, Skills = skills };
|
||||||
|
|
||||||
// this is the same as osu!, so there's potential to share the implementation... maybe
|
// this is the same as osu!, so there's potential to share the implementation... maybe
|
||||||
double preempt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / clockRate;
|
double preempt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / clockRate;
|
||||||
@ -41,7 +41,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
StarRating = Math.Sqrt(skills[0].DifficultyValue()) * star_scaling_factor,
|
StarRating = Math.Sqrt(skills[0].DifficultyValue()) * star_scaling_factor,
|
||||||
Mods = mods,
|
Mods = mods,
|
||||||
ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0,
|
ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0,
|
||||||
MaxCombo = beatmap.HitObjects.Count(h => h is Fruit) + beatmap.HitObjects.OfType<JuiceStream>().SelectMany(j => j.NestedHitObjects).Count(h => !(h is TinyDroplet))
|
MaxCombo = beatmap.HitObjects.Count(h => h is Fruit) + beatmap.HitObjects.OfType<JuiceStream>().SelectMany(j => j.NestedHitObjects).Count(h => !(h is TinyDroplet)),
|
||||||
|
Skills = skills
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
{
|
{
|
||||||
base.CreateNestedHitObjects();
|
base.CreateNestedHitObjects();
|
||||||
|
|
||||||
var tickSamples = Samples.Select(s => new SampleInfo
|
var tickSamples = Samples.Select(s => new HitSampleInfo
|
||||||
{
|
{
|
||||||
Bank = s.Bank,
|
Bank = s.Bank,
|
||||||
Name = @"slidertick",
|
Name = @"slidertick",
|
||||||
@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
|
|
||||||
public double Distance => Path.Distance;
|
public double Distance => Path.Distance;
|
||||||
|
|
||||||
public List<List<SampleInfo>> NodeSamples { get; set; } = new List<List<SampleInfo>>();
|
public List<List<HitSampleInfo>> NodeSamples { get; set; } = new List<List<HitSampleInfo>>();
|
||||||
|
|
||||||
public double? LegacyLastTickOffset { get; set; }
|
public double? LegacyLastTickOffset { get; set; }
|
||||||
}
|
}
|
||||||
|
@ -43,10 +43,13 @@ namespace osu.Game.Rulesets.Catch.Replays
|
|||||||
float positionChange = Math.Abs(lastPosition - h.X);
|
float positionChange = Math.Abs(lastPosition - h.X);
|
||||||
double timeAvailable = h.StartTime - lastTime;
|
double timeAvailable = h.StartTime - lastTime;
|
||||||
|
|
||||||
//So we can either make it there without a dash or not.
|
// So we can either make it there without a dash or not.
|
||||||
double speedRequired = positionChange / timeAvailable;
|
// If positionChange is 0, we don't need to move, so speedRequired should also be 0 (could be NaN if timeAvailable is 0 too)
|
||||||
|
// The case where positionChange > 0 and timeAvailable == 0 results in PositiveInfinity which provides expected beheaviour.
|
||||||
|
double speedRequired = positionChange == 0 ? 0 : positionChange / timeAvailable;
|
||||||
|
|
||||||
bool dashRequired = speedRequired > movement_speed && h.StartTime != 0;
|
bool dashRequired = speedRequired > movement_speed;
|
||||||
|
bool impossibleJump = speedRequired > movement_speed * 2;
|
||||||
|
|
||||||
// todo: get correct catcher size, based on difficulty CS.
|
// todo: get correct catcher size, based on difficulty CS.
|
||||||
const float catcher_width_half = CatcherArea.CATCHER_SIZE / CatchPlayfield.BASE_WIDTH * 0.3f * 0.5f;
|
const float catcher_width_half = CatcherArea.CATCHER_SIZE / CatchPlayfield.BASE_WIDTH * 0.3f * 0.5f;
|
||||||
@ -59,9 +62,8 @@ namespace osu.Game.Rulesets.Catch.Replays
|
|||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (h is Banana)
|
if (impossibleJump)
|
||||||
{
|
{
|
||||||
// auto bananas unrealistically warp to catch 100% combo.
|
|
||||||
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
|
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
|
||||||
}
|
}
|
||||||
else if (h.HyperDash)
|
else if (h.HyperDash)
|
||||||
|
@ -6,8 +6,6 @@ using System.Linq;
|
|||||||
using osu.Framework.Allocation;
|
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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Graphics.Textures;
|
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -141,7 +139,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
Children = new[]
|
||||||
{
|
{
|
||||||
caughtFruit = new Container<DrawableHitObject>
|
caughtFruit = new Container<DrawableHitObject>
|
||||||
{
|
{
|
||||||
@ -212,7 +210,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50);
|
Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50);
|
||||||
}
|
}
|
||||||
|
|
||||||
private Sprite createCatcherSprite() => new CatcherSprite();
|
private Drawable createCatcherSprite() => new CatcherSprite();
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Add a caught fruit to the catcher's stack.
|
/// Add a caught fruit to the catcher's stack.
|
||||||
@ -379,8 +377,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * speed, 0, 1);
|
X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * speed, 0, 1);
|
||||||
|
|
||||||
// Correct overshooting.
|
// Correct overshooting.
|
||||||
if (hyperDashDirection > 0 && hyperDashTargetPosition < X ||
|
if ((hyperDashDirection > 0 && hyperDashTargetPosition < X) ||
|
||||||
hyperDashDirection < 0 && hyperDashTargetPosition > X)
|
(hyperDashDirection < 0 && hyperDashTargetPosition > X))
|
||||||
{
|
{
|
||||||
X = hyperDashTargetPosition;
|
X = hyperDashTargetPosition;
|
||||||
SetHyperDashState();
|
SetHyperDashState();
|
||||||
@ -444,23 +442,6 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
|
|
||||||
fruit.Expire();
|
fruit.Expire();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class CatcherSprite : Sprite
|
|
||||||
{
|
|
||||||
public CatcherSprite()
|
|
||||||
{
|
|
||||||
Size = new Vector2(CATCHER_SIZE);
|
|
||||||
|
|
||||||
// Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling.
|
|
||||||
OriginPosition = new Vector2(-0.02f, 0.06f) * CATCHER_SIZE;
|
|
||||||
}
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load(TextureStore textures)
|
|
||||||
{
|
|
||||||
Texture = textures.Get(@"Play/Catch/fruit-catcher-idle");
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
33
osu.Game.Rulesets.Catch/UI/CatcherSprite.cs
Normal file
33
osu.Game.Rulesets.Catch/UI/CatcherSprite.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// 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.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Skinning;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.UI
|
||||||
|
{
|
||||||
|
public class CatcherSprite : CompositeDrawable
|
||||||
|
{
|
||||||
|
public CatcherSprite()
|
||||||
|
{
|
||||||
|
Size = new Vector2(CatcherArea.CATCHER_SIZE);
|
||||||
|
|
||||||
|
// Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling.
|
||||||
|
OriginPosition = new Vector2(-0.02f, 0.06f) * CatcherArea.CATCHER_SIZE;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
InternalChild = new SkinnableSprite(@"Play/Catch/fruit-catcher-idle")
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Anchor = Anchor.TopCentre,
|
||||||
|
Origin = Anchor.TopCentre,
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -11,10 +11,10 @@ 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.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
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.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
@ -138,7 +138,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
content = new Container { RelativeSizeAxes = Axes.Both }
|
content = new Container { RelativeSizeAxes = Axes.Both }
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.TopCentre,
|
Origin = Anchor.TopCentre,
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -255,7 +255,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="time">The time to retrieve the sample info list from.</param>
|
/// <param name="time">The time to retrieve the sample info list from.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private List<SampleInfo> sampleInfoListAt(double time)
|
private List<HitSampleInfo> sampleInfoListAt(double time)
|
||||||
{
|
{
|
||||||
var curveData = HitObject as IHasCurve;
|
var curveData = HitObject as IHasCurve;
|
||||||
|
|
||||||
|
@ -364,7 +364,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP || sample.Name == SampleInfo.HIT_FINISH;
|
bool isDoubleSample(HitSampleInfo sample) => sample.Name == HitSampleInfo.HIT_CLAP || sample.Name == HitSampleInfo.HIT_FINISH;
|
||||||
|
|
||||||
bool canGenerateTwoNotes = !convertType.HasFlag(PatternType.LowProbability);
|
bool canGenerateTwoNotes = !convertType.HasFlag(PatternType.LowProbability);
|
||||||
canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample);
|
canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample);
|
||||||
@ -443,7 +443,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
noteCount = 0;
|
noteCount = 0;
|
||||||
noteCount = Math.Min(TotalColumns - 1, noteCount);
|
noteCount = Math.Min(TotalColumns - 1, noteCount);
|
||||||
|
|
||||||
bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP);
|
bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == HitSampleInfo.HIT_WHISTLE || s.Name == HitSampleInfo.HIT_FINISH || s.Name == HitSampleInfo.HIT_CLAP);
|
||||||
|
|
||||||
var rowPattern = new Pattern();
|
var rowPattern = new Pattern();
|
||||||
|
|
||||||
@ -472,7 +472,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="time">The time to retrieve the sample info list from.</param>
|
/// <param name="time">The time to retrieve the sample info list from.</param>
|
||||||
/// <returns></returns>
|
/// <returns></returns>
|
||||||
private List<SampleInfo> sampleInfoListAt(double time)
|
private List<HitSampleInfo> sampleInfoListAt(double time)
|
||||||
{
|
{
|
||||||
var curveData = HitObject as IHasCurve;
|
var curveData = HitObject as IHasCurve;
|
||||||
|
|
||||||
|
@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
switch (TotalColumns)
|
switch (TotalColumns)
|
||||||
{
|
{
|
||||||
case 8 when HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000:
|
case 8 when HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000:
|
||||||
addToPattern(pattern, 0, generateHold);
|
addToPattern(pattern, 0, generateHold);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -72,9 +72,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
};
|
};
|
||||||
|
|
||||||
if (hold.Head.Samples == null)
|
if (hold.Head.Samples == null)
|
||||||
hold.Head.Samples = new List<SampleInfo>();
|
hold.Head.Samples = new List<HitSampleInfo>();
|
||||||
|
|
||||||
hold.Head.Samples.Add(new SampleInfo { Name = SampleInfo.HIT_NORMAL });
|
hold.Head.Samples.Add(new HitSampleInfo { Name = HitSampleInfo.HIT_NORMAL });
|
||||||
|
|
||||||
hold.Tail.Samples = HitObject.Samples;
|
hold.Tail.Samples = HitObject.Samples;
|
||||||
|
|
||||||
|
@ -79,9 +79,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
if (!convertType.HasFlag(PatternType.KeepSingle))
|
if (!convertType.HasFlag(PatternType.KeepSingle))
|
||||||
{
|
{
|
||||||
if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && TotalColumns != 8)
|
if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH) && TotalColumns != 8)
|
||||||
convertType |= PatternType.Mirror;
|
convertType |= PatternType.Mirror;
|
||||||
else if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP))
|
else if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP))
|
||||||
convertType |= PatternType.Gathered;
|
convertType |= PatternType.Gathered;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -263,7 +263,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Whether this hit object can generate a note in the special column.
|
/// Whether this hit object can generate a note in the special column.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
private bool hasSpecialColumn => HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP) && HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH);
|
private bool hasSpecialColumn => HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP) && HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Generates a random pattern.
|
/// Generates a random pattern.
|
||||||
@ -364,7 +364,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP))
|
if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP))
|
||||||
p2 = 1;
|
p2 = 1;
|
||||||
|
|
||||||
return GetRandomNoteCount(p2, p3, p4, p5);
|
return GetRandomNoteCount(p2, p3, p4, p5);
|
||||||
|
@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
|||||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||||
{
|
{
|
||||||
if (beatmap.HitObjects.Count == 0)
|
if (beatmap.HitObjects.Count == 0)
|
||||||
return new ManiaDifficultyAttributes { Mods = mods };
|
return new ManiaDifficultyAttributes { Mods = mods, Skills = skills };
|
||||||
|
|
||||||
return new ManiaDifficultyAttributes
|
return new ManiaDifficultyAttributes
|
||||||
{
|
{
|
||||||
@ -38,6 +38,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
|||||||
Mods = mods,
|
Mods = mods,
|
||||||
// Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future
|
// Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future
|
||||||
GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate,
|
GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate,
|
||||||
|
Skills = skills
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,14 +17,14 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmap CreateBeatmap(Ruleset ruleset)
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||||
{
|
{
|
||||||
var beatmap = new Beatmap
|
var beatmap = new Beatmap
|
||||||
{
|
{
|
||||||
BeatmapInfo = new BeatmapInfo
|
BeatmapInfo = new BeatmapInfo
|
||||||
{
|
{
|
||||||
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
|
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
|
||||||
Ruleset = ruleset.RulesetInfo
|
Ruleset = ruleset
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -46,11 +46,11 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
AddStep("move mouse away", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.TopLeft));
|
AddStep("move mouse away", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.TopLeft));
|
||||||
AddStep("click", () => osuInputManager.GameClick());
|
AddStep("click", () => osuInputManager.GameClick());
|
||||||
AddAssert("not dismissed", () => !resumeFired && resume.State == Visibility.Visible);
|
AddAssert("not dismissed", () => !resumeFired && resume.State.Value == Visibility.Visible);
|
||||||
|
|
||||||
AddStep("move mouse back", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre));
|
AddStep("move mouse back", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre));
|
||||||
AddStep("click", () => osuInputManager.GameClick());
|
AddStep("click", () => osuInputManager.GameClick());
|
||||||
AddAssert("dismissed", () => resumeFired && resume.State == Visibility.Hidden);
|
AddAssert("dismissed", () => resumeFired && resume.State.Value == Visibility.Hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ManualOsuInputManager : OsuInputManager
|
private class ManualOsuInputManager : OsuInputManager
|
||||||
|
@ -248,9 +248,9 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
|
|
||||||
private void createCatmull(int repeats = 0)
|
private void createCatmull(int repeats = 0)
|
||||||
{
|
{
|
||||||
var repeatSamples = new List<List<SampleInfo>>();
|
var repeatSamples = new List<List<HitSampleInfo>>();
|
||||||
for (int i = 0; i < repeats; i++)
|
for (int i = 0; i < repeats; i++)
|
||||||
repeatSamples.Add(new List<SampleInfo>());
|
repeatSamples.Add(new List<HitSampleInfo>());
|
||||||
|
|
||||||
var slider = new Slider
|
var slider = new Slider
|
||||||
{
|
{
|
||||||
@ -270,11 +270,11 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
addSlider(slider, 3, 1);
|
addSlider(slider, 3, 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<List<SampleInfo>> createEmptySamples(int repeats)
|
private List<List<HitSampleInfo>> createEmptySamples(int repeats)
|
||||||
{
|
{
|
||||||
var repeatSamples = new List<List<SampleInfo>>();
|
var repeatSamples = new List<List<HitSampleInfo>>();
|
||||||
for (int i = 0; i < repeats; i++)
|
for (int i = 0; i < repeats; i++)
|
||||||
repeatSamples.Add(new List<SampleInfo>());
|
repeatSamples.Add(new List<HitSampleInfo>());
|
||||||
return repeatSamples;
|
return repeatSamples;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -20,7 +20,6 @@ using osu.Game.Rulesets.Replays;
|
|||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Tests.Beatmaps;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
@ -299,7 +298,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
AddStep("load player", () =>
|
AddStep("load player", () =>
|
||||||
{
|
{
|
||||||
Beatmap.Value = new TestWorkingBeatmap(new Beatmap<OsuHitObject>
|
Beatmap.Value = CreateWorkingBeatmap(new Beatmap<OsuHitObject>
|
||||||
{
|
{
|
||||||
HitObjects =
|
HitObjects =
|
||||||
{
|
{
|
||||||
@ -323,7 +322,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
BaseDifficulty = new BeatmapDifficulty { SliderTickRate = 3 },
|
BaseDifficulty = new BeatmapDifficulty { SliderTickRate = 3 },
|
||||||
Ruleset = new OsuRuleset().RulesetInfo
|
Ruleset = new OsuRuleset().RulesetInfo
|
||||||
},
|
},
|
||||||
}, Clock);
|
});
|
||||||
|
|
||||||
var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } });
|
var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } });
|
||||||
|
|
||||||
|
@ -2,8 +2,8 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -69,7 +69,7 @@ namespace osu.Game.Rulesets.Osu.Beatmaps
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
if (Vector2Extensions.Distance(stackBaseObject.Position, objectN.Position) < stack_distance
|
if (Vector2Extensions.Distance(stackBaseObject.Position, objectN.Position) < stack_distance
|
||||||
|| stackBaseObject is Slider && Vector2Extensions.Distance(stackBaseObject.EndPosition, objectN.Position) < stack_distance)
|
|| (stackBaseObject is Slider && Vector2Extensions.Distance(stackBaseObject.EndPosition, objectN.Position) < stack_distance))
|
||||||
{
|
{
|
||||||
stackBaseIndex = n;
|
stackBaseIndex = n;
|
||||||
|
|
||||||
|
@ -28,7 +28,7 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||||
{
|
{
|
||||||
if (beatmap.HitObjects.Count == 0)
|
if (beatmap.HitObjects.Count == 0)
|
||||||
return new OsuDifficultyAttributes { Mods = mods };
|
return new OsuDifficultyAttributes { Mods = mods, Skills = skills };
|
||||||
|
|
||||||
double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
|
double aimRating = Math.Sqrt(skills[0].DifficultyValue()) * difficulty_multiplier;
|
||||||
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
double speedRating = Math.Sqrt(skills[1].DifficultyValue()) * difficulty_multiplier;
|
||||||
@ -50,7 +50,8 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
SpeedStrain = speedRating,
|
SpeedStrain = speedRating,
|
||||||
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
|
ApproachRate = preempt > 1200 ? (1800 - preempt) / 120 : (1200 - preempt) / 150 + 5,
|
||||||
OverallDifficulty = (80 - hitWindowGreat) / 6,
|
OverallDifficulty = (80 - hitWindowGreat) / 6,
|
||||||
MaxCombo = maxCombo
|
MaxCombo = maxCombo,
|
||||||
|
Skills = skills
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,8 +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 System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
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;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
@ -11,7 +14,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
internal class OsuModGrow : Mod, IApplicableToDrawableHitObjects
|
internal class OsuModGrow : Mod, IReadFromConfig, IApplicableToDrawableHitObjects
|
||||||
{
|
{
|
||||||
public override string Name => "Grow";
|
public override string Name => "Grow";
|
||||||
|
|
||||||
@ -25,9 +28,16 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
|
private Bindable<bool> increaseFirstObjectVisibility = new Bindable<bool>();
|
||||||
|
|
||||||
|
public void ReadFromConfig(OsuConfigManager config)
|
||||||
|
{
|
||||||
|
increaseFirstObjectVisibility = config.GetBindable<bool>(OsuSetting.IncreaseFirstObjectVisibility);
|
||||||
|
}
|
||||||
|
|
||||||
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||||
{
|
{
|
||||||
foreach (var drawable in drawables)
|
foreach (var drawable in drawables.Skip(increaseFirstObjectVisibility.Value ? 1 : 0))
|
||||||
{
|
{
|
||||||
switch (drawable)
|
switch (drawable)
|
||||||
{
|
{
|
||||||
|
@ -37,11 +37,11 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
if (time < osuHit.HitObject.StartTime - relax_leniency) continue;
|
if (time < osuHit.HitObject.StartTime - relax_leniency) continue;
|
||||||
|
|
||||||
if (osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime || osuHit.IsHit)
|
if ((osuHit.HitObject is IHasEndTime hasEnd && time > hasEnd.EndTime) || osuHit.IsHit)
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
requiresHit |= osuHit is DrawableHitCircle && osuHit.IsHovered && osuHit.HitObject.HitWindows.CanBeHit(relativetime);
|
requiresHit |= osuHit is DrawableHitCircle && osuHit.IsHovered && osuHit.HitObject.HitWindows.CanBeHit(relativetime);
|
||||||
requiresHold |= osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered) || osuHit is DrawableSpinner;
|
requiresHold |= (osuHit is DrawableSlider slider && (slider.Ball.IsHovered || osuHit.IsHovered)) || osuHit is DrawableSpinner;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (requiresHit)
|
if (requiresHit)
|
||||||
|
@ -18,6 +18,9 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
|||||||
{
|
{
|
||||||
private readonly ShakeContainer shakeContainer;
|
private readonly ShakeContainer shakeContainer;
|
||||||
|
|
||||||
|
// Must be set to update IsHovered as it's used in relax mdo to detect osu hit objects.
|
||||||
|
public override bool HandlePositionalInput => true;
|
||||||
|
|
||||||
protected DrawableOsuHitObject(OsuHitObject hitObject)
|
protected DrawableOsuHitObject(OsuHitObject hitObject)
|
||||||
: base(hitObject)
|
: base(hitObject)
|
||||||
{
|
{
|
||||||
|
@ -4,7 +4,6 @@
|
|||||||
using osu.Framework.Allocation;
|
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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
@ -25,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(TextureStore textures)
|
private void load(TextureStore textures)
|
||||||
{
|
{
|
||||||
Child = new SkinnableDrawable("Play/osu/approachcircle", name => new Sprite { Texture = textures.Get(name) });
|
Child = new SkinnableSprite("Play/osu/approachcircle");
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,13 +2,10 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Lines;
|
using osu.Framework.Graphics.Lines;
|
||||||
using osu.Framework.Graphics.Primitives;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osuTK.Graphics.ES30;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
||||||
{
|
{
|
||||||
@ -19,8 +16,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
private readonly SliderPath path;
|
private readonly SliderPath path;
|
||||||
protected Path Path => path;
|
protected Path Path => path;
|
||||||
|
|
||||||
private readonly BufferedContainer container;
|
|
||||||
|
|
||||||
public float PathRadius
|
public float PathRadius
|
||||||
{
|
{
|
||||||
get => path.PathRadius;
|
get => path.PathRadius;
|
||||||
@ -44,8 +39,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
path.AccentColour = value;
|
path.AccentColour = value;
|
||||||
|
|
||||||
container.ForceRedraw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -61,8 +54,6 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
path.BorderColour = value;
|
path.BorderColour = value;
|
||||||
|
|
||||||
container.ForceRedraw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -78,23 +69,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
return;
|
return;
|
||||||
|
|
||||||
path.BorderSize = value;
|
path.BorderSize = value;
|
||||||
|
|
||||||
container.ForceRedraw();
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public Quad PathDrawQuad => container.ScreenSpaceDrawQuad;
|
|
||||||
|
|
||||||
protected SliderBody()
|
protected SliderBody()
|
||||||
{
|
{
|
||||||
InternalChild = container = new BufferedContainer
|
InternalChild = path = new SliderPath();
|
||||||
{
|
|
||||||
RelativeSizeAxes = Axes.Both,
|
|
||||||
CacheDrawnFrameBuffer = true,
|
|
||||||
Child = path = new SliderPath { Blending = BlendingMode.None }
|
|
||||||
};
|
|
||||||
|
|
||||||
container.Attach(RenderbufferInternalFormat.DepthComponent16);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => path.ReceivePositionalInputAt(screenSpacePos);
|
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => path.ReceivePositionalInputAt(screenSpacePos);
|
||||||
@ -103,11 +83,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Pieces
|
|||||||
/// Sets the vertices of the path which should be drawn by this <see cref="SliderBody"/>.
|
/// Sets the vertices of the path which should be drawn by this <see cref="SliderBody"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="vertices">The vertices</param>
|
/// <param name="vertices">The vertices</param>
|
||||||
protected void SetVertices(IReadOnlyList<Vector2> vertices)
|
protected void SetVertices(IReadOnlyList<Vector2> vertices) => path.Vertices = vertices;
|
||||||
{
|
|
||||||
path.Vertices = vertices;
|
|
||||||
container.ForceRedraw();
|
|
||||||
}
|
|
||||||
|
|
||||||
private class SliderPath : SmoothPath
|
private class SliderPath : SmoothPath
|
||||||
{
|
{
|
||||||
|
@ -99,7 +99,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
internal float LazyTravelDistance;
|
internal float LazyTravelDistance;
|
||||||
|
|
||||||
public List<List<SampleInfo>> NodeSamples { get; set; } = new List<List<SampleInfo>>();
|
public List<List<HitSampleInfo>> NodeSamples { get; set; } = new List<List<HitSampleInfo>>();
|
||||||
|
|
||||||
private int repeatCount;
|
private int repeatCount;
|
||||||
|
|
||||||
@ -157,12 +157,12 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
foreach (var e in
|
foreach (var e in
|
||||||
SliderEventGenerator.Generate(StartTime, SpanDuration, Velocity, TickDistance, Path.Distance, this.SpanCount(), LegacyLastTickOffset))
|
SliderEventGenerator.Generate(StartTime, SpanDuration, Velocity, TickDistance, Path.Distance, this.SpanCount(), LegacyLastTickOffset))
|
||||||
{
|
{
|
||||||
var firstSample = Samples.Find(s => s.Name == SampleInfo.HIT_NORMAL)
|
var firstSample = Samples.Find(s => s.Name == HitSampleInfo.HIT_NORMAL)
|
||||||
?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
|
?? Samples.FirstOrDefault(); // TODO: remove this when guaranteed sort is present for samples (https://github.com/ppy/osu/issues/1933)
|
||||||
var sampleList = new List<SampleInfo>();
|
var sampleList = new List<HitSampleInfo>();
|
||||||
|
|
||||||
if (firstSample != null)
|
if (firstSample != null)
|
||||||
sampleList.Add(new SampleInfo
|
sampleList.Add(new HitSampleInfo
|
||||||
{
|
{
|
||||||
Bank = firstSample.Bank,
|
Bank = firstSample.Bank,
|
||||||
Volume = firstSample.Volume,
|
Volume = firstSample.Volume,
|
||||||
@ -225,7 +225,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private List<SampleInfo> getNodeSamples(int nodeIndex) =>
|
private List<HitSampleInfo> getNodeSamples(int nodeIndex) =>
|
||||||
nodeIndex < NodeSamples.Count ? NodeSamples[nodeIndex] : Samples;
|
nodeIndex < NodeSamples.Count ? NodeSamples[nodeIndex] : Samples;
|
||||||
|
|
||||||
public override Judgement CreateJudgement() => new OsuJudgement();
|
public override Judgement CreateJudgement() => new OsuJudgement();
|
||||||
|
@ -6,7 +6,7 @@ using System.Diagnostics;
|
|||||||
using System.Runtime.InteropServices;
|
using System.Runtime.InteropServices;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.OpenGL.Buffers;
|
using osu.Framework.Graphics.Batches;
|
||||||
using osu.Framework.Graphics.OpenGL.Vertices;
|
using osu.Framework.Graphics.OpenGL.Vertices;
|
||||||
using osu.Framework.Graphics.Primitives;
|
using osu.Framework.Graphics.Primitives;
|
||||||
using osu.Framework.Graphics.Shaders;
|
using osu.Framework.Graphics.Shaders;
|
||||||
@ -54,8 +54,9 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
|
|
||||||
for (int i = 0; i < max_sprites; i++)
|
for (int i = 0; i < max_sprites; i++)
|
||||||
{
|
{
|
||||||
parts[i].InvalidationID = 0;
|
// InvalidationID 1 forces an update of each part of the cursor trail the first time ApplyState is run on the draw node
|
||||||
parts[i].WasUpdated = true;
|
// This is to prevent garbage data from being sent to the vertex shader, resulting in visual issues on some platforms
|
||||||
|
parts[i].InvalidationID = 1;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -147,7 +148,6 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
public Vector2 Position;
|
public Vector2 Position;
|
||||||
public float Time;
|
public float Time;
|
||||||
public long InvalidationID;
|
public long InvalidationID;
|
||||||
public bool WasUpdated;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TrailDrawNode : DrawNode
|
private class TrailDrawNode : DrawNode
|
||||||
@ -162,16 +162,13 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
private readonly TrailPart[] parts = new TrailPart[max_sprites];
|
private readonly TrailPart[] parts = new TrailPart[max_sprites];
|
||||||
private Vector2 size;
|
private Vector2 size;
|
||||||
|
|
||||||
private readonly VertexBuffer<TexturedTrailVertex> vertexBuffer = new QuadVertexBuffer<TexturedTrailVertex>(max_sprites, BufferUsageHint.DynamicDraw);
|
private readonly VertexBatch<TexturedTrailVertex> vertexBatch = new QuadBatch<TexturedTrailVertex>(max_sprites, 1);
|
||||||
|
|
||||||
public TrailDrawNode(CursorTrail source)
|
public TrailDrawNode(CursorTrail source)
|
||||||
: base(source)
|
: base(source)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < max_sprites; i++)
|
for (int i = 0; i < max_sprites; i++)
|
||||||
{
|
|
||||||
parts[i].InvalidationID = 0;
|
parts[i].InvalidationID = 0;
|
||||||
parts[i].WasUpdated = false;
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void ApplyState()
|
public override void ApplyState()
|
||||||
@ -192,55 +189,29 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
|
|
||||||
public override void Draw(Action<TexturedVertex2D> vertexAction)
|
public override void Draw(Action<TexturedVertex2D> vertexAction)
|
||||||
{
|
{
|
||||||
shader.GetUniform<float>("g_FadeClock").UpdateValue(ref time);
|
base.Draw(vertexAction);
|
||||||
|
|
||||||
int updateStart = -1, updateEnd = 0;
|
shader.Bind();
|
||||||
|
shader.GetUniform<float>("g_FadeClock").UpdateValue(ref time);
|
||||||
|
|
||||||
for (int i = 0; i < parts.Length; ++i)
|
for (int i = 0; i < parts.Length; ++i)
|
||||||
{
|
{
|
||||||
if (parts[i].WasUpdated)
|
|
||||||
{
|
|
||||||
if (updateStart == -1)
|
|
||||||
updateStart = i;
|
|
||||||
updateEnd = i + 1;
|
|
||||||
|
|
||||||
int start = i * 4;
|
|
||||||
int end = start;
|
|
||||||
|
|
||||||
Vector2 pos = parts[i].Position;
|
Vector2 pos = parts[i].Position;
|
||||||
float localTime = parts[i].Time;
|
float localTime = parts[i].Time;
|
||||||
|
|
||||||
texture.DrawQuad(
|
DrawQuad(
|
||||||
|
texture,
|
||||||
new Quad(pos.X - size.X / 2, pos.Y - size.Y / 2, size.X, size.Y),
|
new Quad(pos.X - size.X / 2, pos.Y - size.Y / 2, size.X, size.Y),
|
||||||
DrawColourInfo.Colour,
|
DrawColourInfo.Colour,
|
||||||
null,
|
null,
|
||||||
v => vertexBuffer.Vertices[end++] = new TexturedTrailVertex
|
v => vertexBatch.Add(new TexturedTrailVertex
|
||||||
{
|
{
|
||||||
Position = v.Position,
|
Position = v.Position,
|
||||||
TexturePosition = v.TexturePosition,
|
TexturePosition = v.TexturePosition,
|
||||||
Time = localTime + 1,
|
Time = localTime + 1,
|
||||||
Colour = v.Colour,
|
Colour = v.Colour,
|
||||||
});
|
}));
|
||||||
|
|
||||||
parts[i].WasUpdated = false;
|
|
||||||
}
|
}
|
||||||
else if (updateStart != -1)
|
|
||||||
{
|
|
||||||
vertexBuffer.UpdateRange(updateStart * 4, updateEnd * 4);
|
|
||||||
updateStart = -1;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
// Update all remaining vertices that have been changed.
|
|
||||||
if (updateStart != -1)
|
|
||||||
vertexBuffer.UpdateRange(updateStart * 4, updateEnd * 4);
|
|
||||||
|
|
||||||
base.Draw(vertexAction);
|
|
||||||
|
|
||||||
shader.Bind();
|
|
||||||
|
|
||||||
texture.TextureGL.Bind();
|
|
||||||
vertexBuffer.Draw();
|
|
||||||
|
|
||||||
shader.Unbind();
|
shader.Unbind();
|
||||||
}
|
}
|
||||||
@ -249,7 +220,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
|
|
||||||
vertexBuffer.Dispose();
|
vertexBatch.Dispose();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
@ -73,7 +74,10 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
|
|||||||
{
|
{
|
||||||
case OsuAction.LeftButton:
|
case OsuAction.LeftButton:
|
||||||
case OsuAction.RightButton:
|
case OsuAction.RightButton:
|
||||||
if (--downCount == 0)
|
// Todo: Math.Max() is required as a temporary measure to address https://github.com/ppy/osu-framework/issues/2576
|
||||||
|
downCount = Math.Max(0, downCount - 1);
|
||||||
|
|
||||||
|
if (downCount == 0)
|
||||||
updateExpandedState();
|
updateExpandedState();
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
|
|
||||||
private GameplayCursorContainer localCursorContainer;
|
private GameplayCursorContainer localCursorContainer;
|
||||||
|
|
||||||
public override CursorContainer LocalCursor => State == Visibility.Visible ? localCursorContainer : null;
|
public override CursorContainer LocalCursor => State.Value == Visibility.Visible ? localCursorContainer : null;
|
||||||
|
|
||||||
protected override string Message => "Click the orange cursor to resume";
|
protected override string Message => "Click the orange cursor to resume";
|
||||||
|
|
||||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
{
|
{
|
||||||
typeof(InputDrum),
|
typeof(InputDrum),
|
||||||
typeof(DrumSampleMapping),
|
typeof(DrumSampleMapping),
|
||||||
typeof(SampleInfo),
|
typeof(HitSampleInfo),
|
||||||
typeof(SampleControlPoint)
|
typeof(SampleControlPoint)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
@ -18,7 +18,6 @@ using osu.Game.Rulesets.Taiko.Judgements;
|
|||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Taiko.UI;
|
using osu.Game.Rulesets.Taiko.UI;
|
||||||
using osu.Game.Tests.Beatmaps;
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -64,7 +63,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
var controlPointInfo = new ControlPointInfo();
|
var controlPointInfo = new ControlPointInfo();
|
||||||
controlPointInfo.TimingPoints.Add(new TimingControlPoint());
|
controlPointInfo.TimingPoints.Add(new TimingControlPoint());
|
||||||
|
|
||||||
WorkingBeatmap beatmap = new TestWorkingBeatmap(new Beatmap
|
WorkingBeatmap beatmap = CreateWorkingBeatmap(new Beatmap
|
||||||
{
|
{
|
||||||
HitObjects = new List<HitObject> { new CentreHit() },
|
HitObjects = new List<HitObject> { new CentreHit() },
|
||||||
BeatmapInfo = new BeatmapInfo
|
BeatmapInfo = new BeatmapInfo
|
||||||
@ -79,7 +78,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
Ruleset = new TaikoRuleset().RulesetInfo
|
Ruleset = new TaikoRuleset().RulesetInfo
|
||||||
},
|
},
|
||||||
ControlPointInfo = controlPointInfo
|
ControlPointInfo = controlPointInfo
|
||||||
}, Clock);
|
});
|
||||||
|
|
||||||
Add(playfieldContainer = new Container
|
Add(playfieldContainer = new Container
|
||||||
{
|
{
|
||||||
|
68
osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs
Normal file
68
osu.Game.Rulesets.Taiko.Tests/TestSceneTaikoSuddenDeath.cs
Normal file
@ -0,0 +1,68 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Rulesets.Taiko.Beatmaps;
|
||||||
|
using osu.Game.Rulesets.Taiko.Mods;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Tests
|
||||||
|
{
|
||||||
|
public class TestSceneTaikoSuddenDeath : PlayerTestScene
|
||||||
|
{
|
||||||
|
public TestSceneTaikoSuddenDeath()
|
||||||
|
: base(new TaikoRuleset())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override bool AllowFail => true;
|
||||||
|
|
||||||
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
|
{
|
||||||
|
Mods.Value = Mods.Value.Concat(new[] { new TaikoModSuddenDeath() }).ToArray();
|
||||||
|
return new ScoreAccessiblePlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) =>
|
||||||
|
new TaikoBeatmap
|
||||||
|
{
|
||||||
|
HitObjects =
|
||||||
|
{
|
||||||
|
new Swell { StartTime = 1500 },
|
||||||
|
new Hit { StartTime = 100000 },
|
||||||
|
},
|
||||||
|
BeatmapInfo =
|
||||||
|
{
|
||||||
|
Ruleset = new TaikoRuleset().RulesetInfo
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSpinnerDoesNotFail()
|
||||||
|
{
|
||||||
|
bool judged = false;
|
||||||
|
AddStep("Setup judgements", () =>
|
||||||
|
{
|
||||||
|
judged = false;
|
||||||
|
((ScoreAccessiblePlayer)Player).ScoreProcessor.NewJudgement += b => judged = true;
|
||||||
|
});
|
||||||
|
AddUntilStep("swell judged", () => judged);
|
||||||
|
AddAssert("not failed", () => !Player.HasFailed);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ScoreAccessiblePlayer : TestPlayer
|
||||||
|
{
|
||||||
|
public ScoreAccessiblePlayer()
|
||||||
|
: base(false, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,8 +2,8 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.0.1" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
||||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Taiko.Audio
|
|||||||
foreach (var s in samplePoints)
|
foreach (var s in samplePoints)
|
||||||
{
|
{
|
||||||
var centre = s.GetSampleInfo();
|
var centre = s.GetSampleInfo();
|
||||||
var rim = s.GetSampleInfo(SampleInfo.HIT_CLAP);
|
var rim = s.GetSampleInfo(HitSampleInfo.HIT_CLAP);
|
||||||
|
|
||||||
// todo: this is ugly
|
// todo: this is ugly
|
||||||
centre.Namespace = "taiko";
|
centre.Namespace = "taiko";
|
||||||
@ -43,9 +43,9 @@ namespace osu.Game.Rulesets.Taiko.Audio
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private SkinnableSound addSound(SampleInfo sampleInfo)
|
private SkinnableSound addSound(HitSampleInfo hitSampleInfo)
|
||||||
{
|
{
|
||||||
var drawable = new SkinnableSound(sampleInfo);
|
var drawable = new SkinnableSound(hitSampleInfo);
|
||||||
Sounds.Add(drawable);
|
Sounds.Add(drawable);
|
||||||
return drawable;
|
return drawable;
|
||||||
}
|
}
|
||||||
|
@ -79,9 +79,9 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
|
|||||||
var curveData = obj as IHasCurve;
|
var curveData = obj as IHasCurve;
|
||||||
|
|
||||||
// Old osu! used hit sounding to determine various hit type information
|
// Old osu! used hit sounding to determine various hit type information
|
||||||
List<SampleInfo> samples = obj.Samples;
|
List<HitSampleInfo> samples = obj.Samples;
|
||||||
|
|
||||||
bool strong = samples.Any(s => s.Name == SampleInfo.HIT_FINISH);
|
bool strong = samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH);
|
||||||
|
|
||||||
if (distanceData != null)
|
if (distanceData != null)
|
||||||
{
|
{
|
||||||
@ -117,15 +117,15 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
|
|||||||
|
|
||||||
if (!isForCurrentRuleset && tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength)
|
if (!isForCurrentRuleset && tickSpacing > 0 && osuDuration < 2 * speedAdjustedBeatLength)
|
||||||
{
|
{
|
||||||
List<List<SampleInfo>> allSamples = curveData != null ? curveData.NodeSamples : new List<List<SampleInfo>>(new[] { samples });
|
List<List<HitSampleInfo>> allSamples = curveData != null ? curveData.NodeSamples : new List<List<HitSampleInfo>>(new[] { samples });
|
||||||
|
|
||||||
int i = 0;
|
int i = 0;
|
||||||
|
|
||||||
for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing)
|
for (double j = obj.StartTime; j <= obj.StartTime + taikoDuration + tickSpacing / 8; j += tickSpacing)
|
||||||
{
|
{
|
||||||
List<SampleInfo> currentSamples = allSamples[i];
|
List<HitSampleInfo> currentSamples = allSamples[i];
|
||||||
bool isRim = currentSamples.Any(s => s.Name == SampleInfo.HIT_CLAP || s.Name == SampleInfo.HIT_WHISTLE);
|
bool isRim = currentSamples.Any(s => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE);
|
||||||
strong = currentSamples.Any(s => s.Name == SampleInfo.HIT_FINISH);
|
strong = currentSamples.Any(s => s.Name == HitSampleInfo.HIT_FINISH);
|
||||||
|
|
||||||
if (isRim)
|
if (isRim)
|
||||||
{
|
{
|
||||||
@ -175,7 +175,7 @@ namespace osu.Game.Rulesets.Taiko.Beatmaps
|
|||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
bool isRim = samples.Any(s => s.Name == SampleInfo.HIT_CLAP || s.Name == SampleInfo.HIT_WHISTLE);
|
bool isRim = samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP || s.Name == HitSampleInfo.HIT_WHISTLE);
|
||||||
|
|
||||||
if (isRim)
|
if (isRim)
|
||||||
{
|
{
|
||||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
|||||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||||
{
|
{
|
||||||
if (beatmap.HitObjects.Count == 0)
|
if (beatmap.HitObjects.Count == 0)
|
||||||
return new TaikoDifficultyAttributes { Mods = mods };
|
return new TaikoDifficultyAttributes { Mods = mods, Skills = skills };
|
||||||
|
|
||||||
return new TaikoDifficultyAttributes
|
return new TaikoDifficultyAttributes
|
||||||
{
|
{
|
||||||
@ -36,6 +36,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
|||||||
// Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future
|
// Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future
|
||||||
GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate,
|
GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate,
|
||||||
MaxCombo = beatmap.HitObjects.Count(h => h is Hit),
|
MaxCombo = beatmap.HitObjects.Count(h => h is Hit),
|
||||||
|
Skills = skills
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -9,5 +9,6 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
|||||||
{
|
{
|
||||||
public override string Description => @"Beats fade out before you hit them!";
|
public override string Description => @"Beats fade out before you hit them!";
|
||||||
public override double ScoreMultiplier => 1.06;
|
public override double ScoreMultiplier => 1.06;
|
||||||
|
public override bool HasImplementation => false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -122,7 +122,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Normal and clap samples are handled by the drum
|
// Normal and clap samples are handled by the drum
|
||||||
protected override IEnumerable<SampleInfo> GetSamples() => HitObject.Samples.Where(s => s.Name != SampleInfo.HIT_NORMAL && s.Name != SampleInfo.HIT_CLAP);
|
protected override IEnumerable<HitSampleInfo> GetSamples() => HitObject.Samples.Where(s => s.Name != HitSampleInfo.HIT_NORMAL && s.Name != HitSampleInfo.HIT_CLAP);
|
||||||
|
|
||||||
protected override string SampleNamespace => "Taiko";
|
protected override string SampleNamespace => "Taiko";
|
||||||
|
|
||||||
|
@ -170,27 +170,98 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
var controlPoints = beatmap.ControlPointInfo;
|
var controlPoints = beatmap.ControlPointInfo;
|
||||||
|
|
||||||
Assert.AreEqual(4, controlPoints.TimingPoints.Count);
|
Assert.AreEqual(4, controlPoints.TimingPoints.Count);
|
||||||
var timingPoint = controlPoints.TimingPoints[0];
|
Assert.AreEqual(42, controlPoints.DifficultyPoints.Count);
|
||||||
|
Assert.AreEqual(42, controlPoints.SamplePoints.Count);
|
||||||
|
Assert.AreEqual(42, controlPoints.EffectPoints.Count);
|
||||||
|
|
||||||
|
var timingPoint = controlPoints.TimingPointAt(0);
|
||||||
|
Assert.AreEqual(956, timingPoint.Time);
|
||||||
|
Assert.AreEqual(329.67032967033, timingPoint.BeatLength);
|
||||||
|
Assert.AreEqual(TimeSignatures.SimpleQuadruple, timingPoint.TimeSignature);
|
||||||
|
|
||||||
|
timingPoint = controlPoints.TimingPointAt(48428);
|
||||||
Assert.AreEqual(956, timingPoint.Time);
|
Assert.AreEqual(956, timingPoint.Time);
|
||||||
Assert.AreEqual(329.67032967033d, timingPoint.BeatLength);
|
Assert.AreEqual(329.67032967033d, timingPoint.BeatLength);
|
||||||
Assert.AreEqual(TimeSignatures.SimpleQuadruple, timingPoint.TimeSignature);
|
Assert.AreEqual(TimeSignatures.SimpleQuadruple, timingPoint.TimeSignature);
|
||||||
|
|
||||||
Assert.AreEqual(5, controlPoints.DifficultyPoints.Count);
|
timingPoint = controlPoints.TimingPointAt(119637);
|
||||||
var difficultyPoint = controlPoints.DifficultyPoints[0];
|
Assert.AreEqual(119637, timingPoint.Time);
|
||||||
Assert.AreEqual(116999, difficultyPoint.Time);
|
Assert.AreEqual(659.340659340659, timingPoint.BeatLength);
|
||||||
Assert.AreEqual(0.75000000000000189d, difficultyPoint.SpeedMultiplier);
|
Assert.AreEqual(TimeSignatures.SimpleQuadruple, timingPoint.TimeSignature);
|
||||||
|
|
||||||
Assert.AreEqual(34, controlPoints.SamplePoints.Count);
|
var difficultyPoint = controlPoints.DifficultyPointAt(0);
|
||||||
var soundPoint = controlPoints.SamplePoints[0];
|
Assert.AreEqual(0, difficultyPoint.Time);
|
||||||
|
Assert.AreEqual(1.0, difficultyPoint.SpeedMultiplier);
|
||||||
|
|
||||||
|
difficultyPoint = controlPoints.DifficultyPointAt(48428);
|
||||||
|
Assert.AreEqual(48428, difficultyPoint.Time);
|
||||||
|
Assert.AreEqual(1.0, difficultyPoint.SpeedMultiplier);
|
||||||
|
|
||||||
|
difficultyPoint = controlPoints.DifficultyPointAt(116999);
|
||||||
|
Assert.AreEqual(116999, difficultyPoint.Time);
|
||||||
|
Assert.AreEqual(0.75, difficultyPoint.SpeedMultiplier, 0.1);
|
||||||
|
|
||||||
|
var soundPoint = controlPoints.SamplePointAt(0);
|
||||||
Assert.AreEqual(956, soundPoint.Time);
|
Assert.AreEqual(956, soundPoint.Time);
|
||||||
Assert.AreEqual("soft", soundPoint.SampleBank);
|
Assert.AreEqual("soft", soundPoint.SampleBank);
|
||||||
Assert.AreEqual(60, soundPoint.SampleVolume);
|
Assert.AreEqual(60, soundPoint.SampleVolume);
|
||||||
|
|
||||||
Assert.AreEqual(8, controlPoints.EffectPoints.Count);
|
soundPoint = controlPoints.SamplePointAt(53373);
|
||||||
var effectPoint = controlPoints.EffectPoints[0];
|
Assert.AreEqual(53373, soundPoint.Time);
|
||||||
|
Assert.AreEqual("soft", soundPoint.SampleBank);
|
||||||
|
Assert.AreEqual(60, soundPoint.SampleVolume);
|
||||||
|
|
||||||
|
soundPoint = controlPoints.SamplePointAt(119637);
|
||||||
|
Assert.AreEqual(119637, soundPoint.Time);
|
||||||
|
Assert.AreEqual("soft", soundPoint.SampleBank);
|
||||||
|
Assert.AreEqual(80, soundPoint.SampleVolume);
|
||||||
|
|
||||||
|
var effectPoint = controlPoints.EffectPointAt(0);
|
||||||
|
Assert.AreEqual(0, effectPoint.Time);
|
||||||
|
Assert.IsFalse(effectPoint.KiaiMode);
|
||||||
|
Assert.IsFalse(effectPoint.OmitFirstBarLine);
|
||||||
|
|
||||||
|
effectPoint = controlPoints.EffectPointAt(53703);
|
||||||
Assert.AreEqual(53703, effectPoint.Time);
|
Assert.AreEqual(53703, effectPoint.Time);
|
||||||
Assert.IsTrue(effectPoint.KiaiMode);
|
Assert.IsTrue(effectPoint.KiaiMode);
|
||||||
Assert.IsFalse(effectPoint.OmitFirstBarLine);
|
Assert.IsFalse(effectPoint.OmitFirstBarLine);
|
||||||
|
|
||||||
|
effectPoint = controlPoints.EffectPointAt(119637);
|
||||||
|
Assert.AreEqual(119637, effectPoint.Time);
|
||||||
|
Assert.IsFalse(effectPoint.KiaiMode);
|
||||||
|
Assert.IsFalse(effectPoint.OmitFirstBarLine);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDecodeOverlappingTimingPoints()
|
||||||
|
{
|
||||||
|
var decoder = new LegacyBeatmapDecoder { ApplyOffsets = false };
|
||||||
|
|
||||||
|
using (var resStream = TestResources.OpenResource("overlapping-control-points.osu"))
|
||||||
|
using (var stream = new StreamReader(resStream))
|
||||||
|
{
|
||||||
|
var controlPoints = decoder.Decode(stream).ControlPointInfo;
|
||||||
|
|
||||||
|
Assert.That(controlPoints.DifficultyPointAt(500).SpeedMultiplier, Is.EqualTo(1.5).Within(0.1));
|
||||||
|
Assert.That(controlPoints.DifficultyPointAt(1500).SpeedMultiplier, Is.EqualTo(1.5).Within(0.1));
|
||||||
|
Assert.That(controlPoints.DifficultyPointAt(2500).SpeedMultiplier, Is.EqualTo(0.75).Within(0.1));
|
||||||
|
Assert.That(controlPoints.DifficultyPointAt(3500).SpeedMultiplier, Is.EqualTo(1.5).Within(0.1));
|
||||||
|
|
||||||
|
Assert.That(controlPoints.EffectPointAt(500).KiaiMode, Is.True);
|
||||||
|
Assert.That(controlPoints.EffectPointAt(1500).KiaiMode, Is.True);
|
||||||
|
Assert.That(controlPoints.EffectPointAt(2500).KiaiMode, Is.False);
|
||||||
|
Assert.That(controlPoints.EffectPointAt(3500).KiaiMode, Is.True);
|
||||||
|
|
||||||
|
Assert.That(controlPoints.SamplePointAt(500).SampleBank, Is.EqualTo("drum"));
|
||||||
|
Assert.That(controlPoints.SamplePointAt(1500).SampleBank, Is.EqualTo("drum"));
|
||||||
|
Assert.That(controlPoints.SamplePointAt(2500).SampleBank, Is.EqualTo("normal"));
|
||||||
|
Assert.That(controlPoints.SamplePointAt(3500).SampleBank, Is.EqualTo("drum"));
|
||||||
|
|
||||||
|
Assert.That(controlPoints.TimingPointAt(500).BeatLength, Is.EqualTo(500).Within(0.1));
|
||||||
|
Assert.That(controlPoints.TimingPointAt(1500).BeatLength, Is.EqualTo(500).Within(0.1));
|
||||||
|
Assert.That(controlPoints.TimingPointAt(2500).BeatLength, Is.EqualTo(250).Within(0.1));
|
||||||
|
Assert.That(controlPoints.TimingPointAt(3500).BeatLength, Is.EqualTo(500).Within(0.1));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -283,14 +354,14 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
Assert.IsNotNull(curveData);
|
Assert.IsNotNull(curveData);
|
||||||
Assert.AreEqual(new Vector2(192, 168), positionData.Position);
|
Assert.AreEqual(new Vector2(192, 168), positionData.Position);
|
||||||
Assert.AreEqual(956, hitObjects[0].StartTime);
|
Assert.AreEqual(956, hitObjects[0].StartTime);
|
||||||
Assert.IsTrue(hitObjects[0].Samples.Any(s => s.Name == SampleInfo.HIT_NORMAL));
|
Assert.IsTrue(hitObjects[0].Samples.Any(s => s.Name == HitSampleInfo.HIT_NORMAL));
|
||||||
|
|
||||||
positionData = hitObjects[1] as IHasPosition;
|
positionData = hitObjects[1] as IHasPosition;
|
||||||
|
|
||||||
Assert.IsNotNull(positionData);
|
Assert.IsNotNull(positionData);
|
||||||
Assert.AreEqual(new Vector2(304, 56), positionData.Position);
|
Assert.AreEqual(new Vector2(304, 56), positionData.Position);
|
||||||
Assert.AreEqual(1285, hitObjects[1].StartTime);
|
Assert.AreEqual(1285, hitObjects[1].StartTime);
|
||||||
Assert.IsTrue(hitObjects[1].Samples.Any(s => s.Name == SampleInfo.HIT_CLAP));
|
Assert.IsTrue(hitObjects[1].Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -313,7 +384,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
Assert.AreEqual("soft-hitnormal8", getTestableSampleInfo(hitObjects[4]).LookupNames.First());
|
Assert.AreEqual("soft-hitnormal8", getTestableSampleInfo(hitObjects[4]).LookupNames.First());
|
||||||
}
|
}
|
||||||
|
|
||||||
SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]);
|
HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -331,7 +402,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
Assert.AreEqual("normal-hitnormal3", getTestableSampleInfo(hitObjects[2]).LookupNames.First());
|
Assert.AreEqual("normal-hitnormal3", getTestableSampleInfo(hitObjects[2]).LookupNames.First());
|
||||||
}
|
}
|
||||||
|
|
||||||
SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]);
|
HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -351,7 +422,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
Assert.AreEqual(70, getTestableSampleInfo(hitObjects[3]).Volume);
|
Assert.AreEqual(70, getTestableSampleInfo(hitObjects[3]).Volume);
|
||||||
}
|
}
|
||||||
|
|
||||||
SampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]);
|
HitSampleInfo getTestableSampleInfo(HitObject hitObject) => hitObject.SampleControlPoint.ApplyTo(hitObject.Samples[0]);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -367,34 +438,34 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
var slider1 = (ConvertSlider)hitObjects[0];
|
var slider1 = (ConvertSlider)hitObjects[0];
|
||||||
|
|
||||||
Assert.AreEqual(1, slider1.NodeSamples[0].Count);
|
Assert.AreEqual(1, slider1.NodeSamples[0].Count);
|
||||||
Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[0][0].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[0][0].Name);
|
||||||
Assert.AreEqual(1, slider1.NodeSamples[1].Count);
|
Assert.AreEqual(1, slider1.NodeSamples[1].Count);
|
||||||
Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[1][0].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[1][0].Name);
|
||||||
Assert.AreEqual(1, slider1.NodeSamples[2].Count);
|
Assert.AreEqual(1, slider1.NodeSamples[2].Count);
|
||||||
Assert.AreEqual(SampleInfo.HIT_NORMAL, slider1.NodeSamples[2][0].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider1.NodeSamples[2][0].Name);
|
||||||
|
|
||||||
var slider2 = (ConvertSlider)hitObjects[1];
|
var slider2 = (ConvertSlider)hitObjects[1];
|
||||||
|
|
||||||
Assert.AreEqual(2, slider2.NodeSamples[0].Count);
|
Assert.AreEqual(2, slider2.NodeSamples[0].Count);
|
||||||
Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[0][0].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[0][0].Name);
|
||||||
Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[0][1].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[0][1].Name);
|
||||||
Assert.AreEqual(2, slider2.NodeSamples[1].Count);
|
Assert.AreEqual(2, slider2.NodeSamples[1].Count);
|
||||||
Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[1][0].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[1][0].Name);
|
||||||
Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[1][1].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[1][1].Name);
|
||||||
Assert.AreEqual(2, slider2.NodeSamples[2].Count);
|
Assert.AreEqual(2, slider2.NodeSamples[2].Count);
|
||||||
Assert.AreEqual(SampleInfo.HIT_NORMAL, slider2.NodeSamples[2][0].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider2.NodeSamples[2][0].Name);
|
||||||
Assert.AreEqual(SampleInfo.HIT_CLAP, slider2.NodeSamples[2][1].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider2.NodeSamples[2][1].Name);
|
||||||
|
|
||||||
var slider3 = (ConvertSlider)hitObjects[2];
|
var slider3 = (ConvertSlider)hitObjects[2];
|
||||||
|
|
||||||
Assert.AreEqual(2, slider3.NodeSamples[0].Count);
|
Assert.AreEqual(2, slider3.NodeSamples[0].Count);
|
||||||
Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[0][0].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[0][0].Name);
|
||||||
Assert.AreEqual(SampleInfo.HIT_WHISTLE, slider3.NodeSamples[0][1].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_WHISTLE, slider3.NodeSamples[0][1].Name);
|
||||||
Assert.AreEqual(1, slider3.NodeSamples[1].Count);
|
Assert.AreEqual(1, slider3.NodeSamples[1].Count);
|
||||||
Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[1][0].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[1][0].Name);
|
||||||
Assert.AreEqual(2, slider3.NodeSamples[2].Count);
|
Assert.AreEqual(2, slider3.NodeSamples[2].Count);
|
||||||
Assert.AreEqual(SampleInfo.HIT_NORMAL, slider3.NodeSamples[2][0].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_NORMAL, slider3.NodeSamples[2][0].Name);
|
||||||
Assert.AreEqual(SampleInfo.HIT_CLAP, slider3.NodeSamples[2][1].Name);
|
Assert.AreEqual(HitSampleInfo.HIT_CLAP, slider3.NodeSamples[2][1].Name);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -101,14 +101,14 @@ namespace osu.Game.Tests.Beatmaps.Formats
|
|||||||
Assert.IsNotNull(curveData);
|
Assert.IsNotNull(curveData);
|
||||||
Assert.AreEqual(new Vector2(192, 168), positionData.Position);
|
Assert.AreEqual(new Vector2(192, 168), positionData.Position);
|
||||||
Assert.AreEqual(956, beatmap.HitObjects[0].StartTime);
|
Assert.AreEqual(956, beatmap.HitObjects[0].StartTime);
|
||||||
Assert.IsTrue(beatmap.HitObjects[0].Samples.Any(s => s.Name == SampleInfo.HIT_NORMAL));
|
Assert.IsTrue(beatmap.HitObjects[0].Samples.Any(s => s.Name == HitSampleInfo.HIT_NORMAL));
|
||||||
|
|
||||||
positionData = beatmap.HitObjects[1] as IHasPosition;
|
positionData = beatmap.HitObjects[1] as IHasPosition;
|
||||||
|
|
||||||
Assert.IsNotNull(positionData);
|
Assert.IsNotNull(positionData);
|
||||||
Assert.AreEqual(new Vector2(304, 56), positionData.Position);
|
Assert.AreEqual(new Vector2(304, 56), positionData.Position);
|
||||||
Assert.AreEqual(1285, beatmap.HitObjects[1].StartTime);
|
Assert.AreEqual(1285, beatmap.HitObjects[1].StartTime);
|
||||||
Assert.IsTrue(beatmap.HitObjects[1].Samples.Any(s => s.Name == SampleInfo.HIT_CLAP));
|
Assert.IsTrue(beatmap.HitObjects[1].Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP));
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(normal)]
|
[TestCase(normal)]
|
||||||
|
@ -11,7 +11,9 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.IPC;
|
using osu.Game.IPC;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.IO;
|
||||||
using osu.Game.Tests.Resources;
|
using osu.Game.Tests.Resources;
|
||||||
using SharpCompress.Archives.Zip;
|
using SharpCompress.Archives.Zip;
|
||||||
|
|
||||||
@ -21,14 +23,14 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
public class ImportBeatmapTest
|
public class ImportBeatmapTest
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void TestImportWhenClosed()
|
public async Task TestImportWhenClosed()
|
||||||
{
|
{
|
||||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWhenClosed"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWhenClosed"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
LoadOszIntoOsu(loadOsu(host));
|
await LoadOszIntoOsu(loadOsu(host));
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -38,7 +40,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestImportThenDelete()
|
public async Task TestImportThenDelete()
|
||||||
{
|
{
|
||||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenDelete"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenDelete"))
|
||||||
@ -47,7 +49,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
{
|
{
|
||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
var imported = LoadOszIntoOsu(osu);
|
var imported = await LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
deleteBeatmapSet(imported, osu);
|
deleteBeatmapSet(imported, osu);
|
||||||
}
|
}
|
||||||
@ -59,7 +61,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestImportThenImport()
|
public async Task TestImportThenImport()
|
||||||
{
|
{
|
||||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenImport"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenImport"))
|
||||||
@ -68,17 +70,15 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
{
|
{
|
||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
var imported = LoadOszIntoOsu(osu);
|
var imported = await LoadOszIntoOsu(osu);
|
||||||
var importedSecondTime = LoadOszIntoOsu(osu);
|
var importedSecondTime = await LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||||
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
||||||
Assert.IsTrue(imported.Beatmaps.First().ID == importedSecondTime.Beatmaps.First().ID);
|
Assert.IsTrue(imported.Beatmaps.First().ID == importedSecondTime.Beatmaps.First().ID);
|
||||||
|
|
||||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
checkBeatmapSetCount(osu, 1);
|
||||||
|
checkSingleReferencedFileCount(osu, 18);
|
||||||
Assert.AreEqual(1, manager.GetAllUsableBeatmapSets().Count);
|
|
||||||
Assert.AreEqual(1, manager.QueryBeatmapSets(_ => true).ToList().Count);
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -88,30 +88,41 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestRollbackOnFailure()
|
public async Task TestRollbackOnFailure()
|
||||||
{
|
{
|
||||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestRollbackOnFailure"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestRollbackOnFailure"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
int itemAddRemoveFireCount = 0;
|
||||||
|
int loggedExceptionCount = 0;
|
||||||
|
|
||||||
|
Logger.NewEntry += l =>
|
||||||
|
{
|
||||||
|
if (l.Target == LoggingTarget.Database && l.Exception != null)
|
||||||
|
Interlocked.Increment(ref loggedExceptionCount);
|
||||||
|
};
|
||||||
|
|
||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
int fireCount = 0;
|
|
||||||
|
|
||||||
// ReSharper disable once AccessToModifiedClosure
|
// ReSharper disable once AccessToModifiedClosure
|
||||||
manager.ItemAdded += (_, __) => fireCount++;
|
manager.ItemAdded += _ => Interlocked.Increment(ref itemAddRemoveFireCount);
|
||||||
manager.ItemRemoved += _ => fireCount++;
|
manager.ItemRemoved += _ => Interlocked.Increment(ref itemAddRemoveFireCount);
|
||||||
|
|
||||||
var imported = LoadOszIntoOsu(osu);
|
var imported = await LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
Assert.AreEqual(0, fireCount -= 1);
|
Assert.AreEqual(0, itemAddRemoveFireCount -= 1);
|
||||||
|
|
||||||
imported.Hash += "-changed";
|
imported.Hash += "-changed";
|
||||||
manager.Update(imported);
|
manager.Update(imported);
|
||||||
|
|
||||||
Assert.AreEqual(0, fireCount -= 2);
|
Assert.AreEqual(0, itemAddRemoveFireCount -= 2);
|
||||||
|
|
||||||
|
checkBeatmapSetCount(osu, 1);
|
||||||
|
checkBeatmapCount(osu, 12);
|
||||||
|
checkSingleReferencedFileCount(osu, 18);
|
||||||
|
|
||||||
var breakTemp = TestResources.GetTestBeatmapForImport();
|
var breakTemp = TestResources.GetTestBeatmapForImport();
|
||||||
|
|
||||||
@ -127,19 +138,24 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
zip.SaveTo(outStream, SharpCompress.Common.CompressionType.Deflate);
|
zip.SaveTo(outStream, SharpCompress.Common.CompressionType.Deflate);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.AreEqual(1, manager.GetAllUsableBeatmapSets().Count);
|
|
||||||
Assert.AreEqual(1, manager.QueryBeatmapSets(_ => true).ToList().Count);
|
|
||||||
Assert.AreEqual(12, manager.QueryBeatmaps(_ => true).ToList().Count);
|
|
||||||
|
|
||||||
// this will trigger purging of the existing beatmap (online set id match) but should rollback due to broken osu.
|
// this will trigger purging of the existing beatmap (online set id match) but should rollback due to broken osu.
|
||||||
manager.Import(breakTemp);
|
try
|
||||||
|
{
|
||||||
|
await manager.Import(breakTemp);
|
||||||
|
}
|
||||||
|
catch
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
// no events should be fired in the case of a rollback.
|
// no events should be fired in the case of a rollback.
|
||||||
Assert.AreEqual(0, fireCount);
|
Assert.AreEqual(0, itemAddRemoveFireCount);
|
||||||
|
|
||||||
Assert.AreEqual(1, manager.GetAllUsableBeatmapSets().Count);
|
checkBeatmapSetCount(osu, 1);
|
||||||
Assert.AreEqual(1, manager.QueryBeatmapSets(_ => true).ToList().Count);
|
checkBeatmapCount(osu, 12);
|
||||||
Assert.AreEqual(12, manager.QueryBeatmaps(_ => true).ToList().Count);
|
|
||||||
|
checkSingleReferencedFileCount(osu, 18);
|
||||||
|
|
||||||
|
Assert.AreEqual(1, loggedExceptionCount);
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -149,7 +165,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestImportThenImportDifferentHash()
|
public async Task TestImportThenImportDifferentHash()
|
||||||
{
|
{
|
||||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenImportDifferentHash"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenImportDifferentHash"))
|
||||||
@ -159,19 +175,18 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
var imported = LoadOszIntoOsu(osu);
|
var imported = await LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
imported.Hash += "-changed";
|
imported.Hash += "-changed";
|
||||||
manager.Update(imported);
|
manager.Update(imported);
|
||||||
|
|
||||||
var importedSecondTime = LoadOszIntoOsu(osu);
|
var importedSecondTime = await LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
Assert.IsTrue(imported.ID != importedSecondTime.ID);
|
Assert.IsTrue(imported.ID != importedSecondTime.ID);
|
||||||
Assert.IsTrue(imported.Beatmaps.First().ID < importedSecondTime.Beatmaps.First().ID);
|
Assert.IsTrue(imported.Beatmaps.First().ID < importedSecondTime.Beatmaps.First().ID);
|
||||||
|
|
||||||
// only one beatmap will exist as the online set ID matched, causing purging of the first import.
|
// only one beatmap will exist as the online set ID matched, causing purging of the first import.
|
||||||
Assert.AreEqual(1, manager.GetAllUsableBeatmapSets().Count);
|
checkBeatmapSetCount(osu, 1);
|
||||||
Assert.AreEqual(1, manager.QueryBeatmapSets(_ => true).ToList().Count);
|
|
||||||
}
|
}
|
||||||
finally
|
finally
|
||||||
{
|
{
|
||||||
@ -181,7 +196,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestImportThenDeleteThenImport()
|
public async Task TestImportThenDeleteThenImport()
|
||||||
{
|
{
|
||||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenDeleteThenImport"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportThenDeleteThenImport"))
|
||||||
@ -190,11 +205,11 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
{
|
{
|
||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
var imported = LoadOszIntoOsu(osu);
|
var imported = await LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
deleteBeatmapSet(imported, osu);
|
deleteBeatmapSet(imported, osu);
|
||||||
|
|
||||||
var importedSecondTime = LoadOszIntoOsu(osu);
|
var importedSecondTime = await LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
// check the newly "imported" beatmap is actually just the restored previous import. since it matches hash.
|
||||||
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
Assert.IsTrue(imported.ID == importedSecondTime.ID);
|
||||||
@ -209,7 +224,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
|
|
||||||
[TestCase(true)]
|
[TestCase(true)]
|
||||||
[TestCase(false)]
|
[TestCase(false)]
|
||||||
public void TestImportThenDeleteThenImportWithOnlineIDMismatch(bool set)
|
public async Task TestImportThenDeleteThenImportWithOnlineIDMismatch(bool set)
|
||||||
{
|
{
|
||||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost($"TestImportThenDeleteThenImport-{set}"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost($"TestImportThenDeleteThenImport-{set}"))
|
||||||
@ -218,7 +233,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
{
|
{
|
||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
|
|
||||||
var imported = LoadOszIntoOsu(osu);
|
var imported = await LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
if (set)
|
if (set)
|
||||||
imported.OnlineBeatmapSetID = 1234;
|
imported.OnlineBeatmapSetID = 1234;
|
||||||
@ -229,7 +244,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
|
|
||||||
deleteBeatmapSet(imported, osu);
|
deleteBeatmapSet(imported, osu);
|
||||||
|
|
||||||
var importedSecondTime = LoadOszIntoOsu(osu);
|
var importedSecondTime = await LoadOszIntoOsu(osu);
|
||||||
|
|
||||||
// check the newly "imported" beatmap has been reimported due to mismatch (even though hashes matched)
|
// check the newly "imported" beatmap has been reimported due to mismatch (even though hashes matched)
|
||||||
Assert.IsTrue(imported.ID != importedSecondTime.ID);
|
Assert.IsTrue(imported.ID != importedSecondTime.ID);
|
||||||
@ -243,7 +258,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestImportWithDuplicateBeatmapIDs()
|
public async Task TestImportWithDuplicateBeatmapIDs()
|
||||||
{
|
{
|
||||||
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
//unfortunately for the time being we need to reference osu.Framework.Desktop for a game host here.
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWithDuplicateBeatmapID"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWithDuplicateBeatmapID"))
|
||||||
@ -284,7 +299,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
|
|
||||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
var imported = manager.Import(toImport);
|
var imported = await manager.Import(toImport);
|
||||||
|
|
||||||
Assert.NotNull(imported);
|
Assert.NotNull(imported);
|
||||||
Assert.AreEqual(null, imported.Beatmaps[0].OnlineBeatmapID);
|
Assert.AreEqual(null, imported.Beatmaps[0].OnlineBeatmapID);
|
||||||
@ -330,7 +345,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestImportWhenFileOpen()
|
public async Task TestImportWhenFileOpen()
|
||||||
{
|
{
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWhenFileOpen"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportWhenFileOpen"))
|
||||||
{
|
{
|
||||||
@ -339,7 +354,7 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
var osu = loadOsu(host);
|
var osu = loadOsu(host);
|
||||||
var temp = TestResources.GetTestBeatmapForImport();
|
var temp = TestResources.GetTestBeatmapForImport();
|
||||||
using (File.OpenRead(temp))
|
using (File.OpenRead(temp))
|
||||||
osu.Dependencies.Get<BeatmapManager>().Import(temp);
|
await osu.Dependencies.Get<BeatmapManager>().Import(temp);
|
||||||
ensureLoaded(osu);
|
ensureLoaded(osu);
|
||||||
File.Delete(temp);
|
File.Delete(temp);
|
||||||
Assert.IsFalse(File.Exists(temp), "We likely held a read lock on the file when we shouldn't");
|
Assert.IsFalse(File.Exists(temp), "We likely held a read lock on the file when we shouldn't");
|
||||||
@ -351,13 +366,13 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static BeatmapSetInfo LoadOszIntoOsu(OsuGameBase osu, string path = null)
|
public static async Task<BeatmapSetInfo> LoadOszIntoOsu(OsuGameBase osu, string path = null)
|
||||||
{
|
{
|
||||||
var temp = path ?? TestResources.GetTestBeatmapForImport();
|
var temp = path ?? TestResources.GetTestBeatmapForImport();
|
||||||
|
|
||||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
manager.Import(temp);
|
await manager.Import(temp);
|
||||||
|
|
||||||
var imported = manager.GetAllUsableBeatmapSets();
|
var imported = manager.GetAllUsableBeatmapSets();
|
||||||
|
|
||||||
@ -373,11 +388,32 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
var manager = osu.Dependencies.Get<BeatmapManager>();
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
manager.Delete(imported);
|
manager.Delete(imported);
|
||||||
|
|
||||||
Assert.IsTrue(manager.GetAllUsableBeatmapSets().Count == 0);
|
checkBeatmapSetCount(osu, 0);
|
||||||
Assert.AreEqual(1, manager.QueryBeatmapSets(_ => true).ToList().Count);
|
checkBeatmapSetCount(osu, 1, true);
|
||||||
|
checkSingleReferencedFileCount(osu, 0);
|
||||||
|
|
||||||
Assert.IsTrue(manager.QueryBeatmapSets(_ => true).First().DeletePending);
|
Assert.IsTrue(manager.QueryBeatmapSets(_ => true).First().DeletePending);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void checkBeatmapSetCount(OsuGameBase osu, int expected, bool includeDeletePending = false)
|
||||||
|
{
|
||||||
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
|
Assert.AreEqual(expected, includeDeletePending
|
||||||
|
? manager.QueryBeatmapSets(_ => true).ToList().Count
|
||||||
|
: manager.GetAllUsableBeatmapSets().Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkBeatmapCount(OsuGameBase osu, int expected)
|
||||||
|
{
|
||||||
|
Assert.AreEqual(expected, osu.Dependencies.Get<BeatmapManager>().QueryBeatmaps(_ => true).ToList().Count);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkSingleReferencedFileCount(OsuGameBase osu, int expected)
|
||||||
|
{
|
||||||
|
Assert.AreEqual(expected, osu.Dependencies.Get<FileStore>().QueryFiles(f => f.ReferenceCount == 1).Count());
|
||||||
|
}
|
||||||
|
|
||||||
private OsuGameBase loadOsu(GameHost host)
|
private OsuGameBase loadOsu(GameHost host)
|
||||||
{
|
{
|
||||||
var osu = new OsuGameBase();
|
var osu = new OsuGameBase();
|
||||||
|
19
osu.Game.Tests/Resources/overlapping-control-points.osu
Normal file
19
osu.Game.Tests/Resources/overlapping-control-points.osu
Normal file
@ -0,0 +1,19 @@
|
|||||||
|
osu file format v14
|
||||||
|
|
||||||
|
[TimingPoints]
|
||||||
|
|
||||||
|
// Timing then inherited
|
||||||
|
0,500,4,2,0,100,1,0
|
||||||
|
0,-66.6666666666667,4,3,0,100,0,1
|
||||||
|
|
||||||
|
// Inherited then timing (equivalent to previous)
|
||||||
|
1000,-66.6666666666667,4,3,0,100,0,1
|
||||||
|
1000,500,4,2,0,100,1,0
|
||||||
|
|
||||||
|
// Inherited then timing (different to previous)
|
||||||
|
2000,-133.333333333333,4,1,0,100,0,0
|
||||||
|
2000,250,4,2,0,100,1,0
|
||||||
|
|
||||||
|
// Timing then inherited (different to previous)
|
||||||
|
3000,500,4,2,0,100,1,0
|
||||||
|
3000,-66.6666666666667,4,3,0,100,0,1
|
@ -23,13 +23,13 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
public class ImportScoreTest
|
public class ImportScoreTest
|
||||||
{
|
{
|
||||||
[Test]
|
[Test]
|
||||||
public void TestBasicImport()
|
public async Task TestBasicImport()
|
||||||
{
|
{
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestBasicImport"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestBasicImport"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var osu = loadOsu(host);
|
var osu = await loadOsu(host);
|
||||||
|
|
||||||
var toImport = new ScoreInfo
|
var toImport = new ScoreInfo
|
||||||
{
|
{
|
||||||
@ -43,7 +43,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
OnlineScoreID = 12345,
|
OnlineScoreID = 12345,
|
||||||
};
|
};
|
||||||
|
|
||||||
var imported = loadIntoOsu(osu, toImport);
|
var imported = await loadIntoOsu(osu, toImport);
|
||||||
|
|
||||||
Assert.AreEqual(toImport.Rank, imported.Rank);
|
Assert.AreEqual(toImport.Rank, imported.Rank);
|
||||||
Assert.AreEqual(toImport.TotalScore, imported.TotalScore);
|
Assert.AreEqual(toImport.TotalScore, imported.TotalScore);
|
||||||
@ -62,20 +62,20 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestImportMods()
|
public async Task TestImportMods()
|
||||||
{
|
{
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportMods"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportMods"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var osu = loadOsu(host);
|
var osu = await loadOsu(host);
|
||||||
|
|
||||||
var toImport = new ScoreInfo
|
var toImport = new ScoreInfo
|
||||||
{
|
{
|
||||||
Mods = new Mod[] { new OsuModHardRock(), new OsuModDoubleTime() },
|
Mods = new Mod[] { new OsuModHardRock(), new OsuModDoubleTime() },
|
||||||
};
|
};
|
||||||
|
|
||||||
var imported = loadIntoOsu(osu, toImport);
|
var imported = await loadIntoOsu(osu, toImport);
|
||||||
|
|
||||||
Assert.IsTrue(imported.Mods.Any(m => m is OsuModHardRock));
|
Assert.IsTrue(imported.Mods.Any(m => m is OsuModHardRock));
|
||||||
Assert.IsTrue(imported.Mods.Any(m => m is OsuModDoubleTime));
|
Assert.IsTrue(imported.Mods.Any(m => m is OsuModDoubleTime));
|
||||||
@ -88,13 +88,13 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestImportStatistics()
|
public async Task TestImportStatistics()
|
||||||
{
|
{
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportStatistics"))
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost("TestImportStatistics"))
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
var osu = loadOsu(host);
|
var osu = await loadOsu(host);
|
||||||
|
|
||||||
var toImport = new ScoreInfo
|
var toImport = new ScoreInfo
|
||||||
{
|
{
|
||||||
@ -105,7 +105,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
var imported = loadIntoOsu(osu, toImport);
|
var imported = await loadIntoOsu(osu, toImport);
|
||||||
|
|
||||||
Assert.AreEqual(toImport.Statistics[HitResult.Perfect], imported.Statistics[HitResult.Perfect]);
|
Assert.AreEqual(toImport.Statistics[HitResult.Perfect], imported.Statistics[HitResult.Perfect]);
|
||||||
Assert.AreEqual(toImport.Statistics[HitResult.Miss], imported.Statistics[HitResult.Miss]);
|
Assert.AreEqual(toImport.Statistics[HitResult.Miss], imported.Statistics[HitResult.Miss]);
|
||||||
@ -117,7 +117,7 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private ScoreInfo loadIntoOsu(OsuGameBase osu, ScoreInfo score)
|
private async Task<ScoreInfo> loadIntoOsu(OsuGameBase osu, ScoreInfo score)
|
||||||
{
|
{
|
||||||
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
|
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
@ -125,20 +125,24 @@ namespace osu.Game.Tests.Scores.IO
|
|||||||
score.Ruleset = new OsuRuleset().RulesetInfo;
|
score.Ruleset = new OsuRuleset().RulesetInfo;
|
||||||
|
|
||||||
var scoreManager = osu.Dependencies.Get<ScoreManager>();
|
var scoreManager = osu.Dependencies.Get<ScoreManager>();
|
||||||
scoreManager.Import(score);
|
await scoreManager.Import(score);
|
||||||
|
|
||||||
return scoreManager.GetAllUsableScores().First();
|
return scoreManager.GetAllUsableScores().First();
|
||||||
}
|
}
|
||||||
|
|
||||||
private OsuGameBase loadOsu(GameHost host)
|
private async Task<OsuGameBase> loadOsu(GameHost host)
|
||||||
{
|
{
|
||||||
var osu = new OsuGameBase();
|
var osu = new OsuGameBase();
|
||||||
|
|
||||||
|
#pragma warning disable 4014
|
||||||
Task.Run(() => host.Run(osu));
|
Task.Run(() => host.Run(osu));
|
||||||
|
#pragma warning restore 4014
|
||||||
|
|
||||||
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
|
waitForOrAssert(() => osu.IsLoaded, @"osu! failed to start in a reasonable amount of time");
|
||||||
|
|
||||||
var beatmapFile = TestResources.GetTestBeatmapForImport();
|
var beatmapFile = TestResources.GetTestBeatmapForImport();
|
||||||
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
|
var beatmapManager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
beatmapManager.Import(beatmapFile);
|
await beatmapManager.Import(beatmapFile);
|
||||||
|
|
||||||
return osu;
|
return osu;
|
||||||
}
|
}
|
||||||
|
@ -7,9 +7,9 @@ using System.Linq;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
using osu.Framework.Input.States;
|
using osu.Framework.Input.States;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
@ -19,6 +19,7 @@ using osu.Game.Configuration;
|
|||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
@ -54,7 +55,7 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
private RulesetStore rulesets;
|
private RulesetStore rulesets;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(GameHost host)
|
private void load(GameHost host, AudioManager audio)
|
||||||
{
|
{
|
||||||
factory = new DatabaseContextFactory(LocalStorage);
|
factory = new DatabaseContextFactory(LocalStorage);
|
||||||
factory.ResetDatabase();
|
factory.ResetDatabase();
|
||||||
@ -68,10 +69,10 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
usage.Migrate();
|
usage.Migrate();
|
||||||
|
|
||||||
Dependencies.Cache(rulesets = new RulesetStore(factory));
|
Dependencies.Cache(rulesets = new RulesetStore(factory));
|
||||||
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, null, host, Beatmap.Default));
|
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, factory, rulesets, null, audio, host, Beatmap.Default));
|
||||||
Dependencies.Cache(new OsuConfigManager(LocalStorage));
|
Dependencies.Cache(new OsuConfigManager(LocalStorage));
|
||||||
|
|
||||||
manager.Import(TestResources.GetTestBeatmapForImport());
|
manager.Import(TestResources.GetTestBeatmapForImport()).Wait();
|
||||||
|
|
||||||
Beatmap.SetDefault();
|
Beatmap.SetDefault();
|
||||||
}
|
}
|
||||||
@ -240,7 +241,7 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
{
|
{
|
||||||
player.StoryboardEnabled.Value = false;
|
player.StoryboardEnabled.Value = false;
|
||||||
player.ReplacesBackground.Value = false;
|
player.ReplacesBackground.Value = false;
|
||||||
player.CurrentStoryboardContainer.Add(new SpriteText
|
player.CurrentStoryboardContainer.Add(new OsuSpriteText
|
||||||
{
|
{
|
||||||
Size = new Vector2(250, 50),
|
Size = new Vector2(250, 50),
|
||||||
Alpha = 1,
|
Alpha = 1,
|
||||||
|
@ -14,94 +14,132 @@ namespace osu.Game.Tests.Visual.Components
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneIdleTracker : ManualInputManagerTestScene
|
public class TestSceneIdleTracker : ManualInputManagerTestScene
|
||||||
{
|
{
|
||||||
private readonly IdleTrackingBox box1;
|
private IdleTrackingBox box1;
|
||||||
private readonly IdleTrackingBox box2;
|
private IdleTrackingBox box2;
|
||||||
private readonly IdleTrackingBox box3;
|
private IdleTrackingBox box3;
|
||||||
private readonly IdleTrackingBox box4;
|
private IdleTrackingBox box4;
|
||||||
|
|
||||||
public TestSceneIdleTracker()
|
private IdleTrackingBox[] boxes;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
Children = new Drawable[]
|
InputManager.MoveMouseTo(Vector2.Zero);
|
||||||
|
|
||||||
|
Children = boxes = new[]
|
||||||
{
|
{
|
||||||
box1 = new IdleTrackingBox(1000)
|
box1 = new IdleTrackingBox(2000)
|
||||||
{
|
{
|
||||||
|
Name = "TopLeft",
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = Color4.Red,
|
Colour = Color4.Red,
|
||||||
Anchor = Anchor.TopLeft,
|
Anchor = Anchor.TopLeft,
|
||||||
Origin = Anchor.TopLeft,
|
Origin = Anchor.TopLeft,
|
||||||
},
|
},
|
||||||
box2 = new IdleTrackingBox(2000)
|
box2 = new IdleTrackingBox(4000)
|
||||||
{
|
{
|
||||||
|
Name = "TopRight",
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = Color4.Green,
|
Colour = Color4.Green,
|
||||||
Anchor = Anchor.TopRight,
|
Anchor = Anchor.TopRight,
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
},
|
},
|
||||||
box3 = new IdleTrackingBox(3000)
|
box3 = new IdleTrackingBox(6000)
|
||||||
{
|
{
|
||||||
|
Name = "BottomLeft",
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = Color4.Blue,
|
Colour = Color4.Blue,
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
},
|
},
|
||||||
box4 = new IdleTrackingBox(4000)
|
box4 = new IdleTrackingBox(8000)
|
||||||
{
|
{
|
||||||
|
Name = "BottomRight",
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Colour = Color4.Orange,
|
Colour = Color4.Orange,
|
||||||
Anchor = Anchor.BottomRight,
|
Anchor = Anchor.BottomRight,
|
||||||
Origin = Anchor.BottomRight,
|
Origin = Anchor.BottomRight,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
}
|
});
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestNudge()
|
public void TestNudge()
|
||||||
{
|
{
|
||||||
AddStep("move mouse to top left", () => InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.Centre));
|
AddStep("move to top left", () => InputManager.MoveMouseTo(box1));
|
||||||
|
|
||||||
AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
|
waitForAllIdle();
|
||||||
|
|
||||||
AddStep("nudge mouse", () => InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.Centre + new Vector2(1)));
|
AddStep("nudge mouse", () => InputManager.MoveMouseTo(box1.ScreenSpaceDrawQuad.Centre + new Vector2(1)));
|
||||||
|
|
||||||
AddAssert("check not idle", () => !box1.IsIdle);
|
checkIdleStatus(1, false);
|
||||||
AddAssert("check idle", () => box2.IsIdle);
|
checkIdleStatus(2, true);
|
||||||
AddAssert("check idle", () => box3.IsIdle);
|
checkIdleStatus(3, true);
|
||||||
AddAssert("check idle", () => box4.IsIdle);
|
checkIdleStatus(4, true);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestMovement()
|
public void TestMovement()
|
||||||
{
|
{
|
||||||
AddStep("move mouse", () => InputManager.MoveMouseTo(box2.ScreenSpaceDrawQuad.Centre));
|
AddStep("move to top right", () => InputManager.MoveMouseTo(box2));
|
||||||
|
|
||||||
AddAssert("check not idle", () => box1.IsIdle);
|
checkIdleStatus(1, true);
|
||||||
AddAssert("check not idle", () => !box2.IsIdle);
|
checkIdleStatus(2, false);
|
||||||
AddAssert("check idle", () => box3.IsIdle);
|
checkIdleStatus(3, true);
|
||||||
AddAssert("check idle", () => box4.IsIdle);
|
checkIdleStatus(4, true);
|
||||||
|
|
||||||
AddStep("move mouse", () => InputManager.MoveMouseTo(box3.ScreenSpaceDrawQuad.Centre));
|
AddStep("move to bottom left", () => InputManager.MoveMouseTo(box3));
|
||||||
AddStep("move mouse", () => InputManager.MoveMouseTo(box4.ScreenSpaceDrawQuad.Centre));
|
AddStep("move to bottom right", () => InputManager.MoveMouseTo(box4));
|
||||||
|
|
||||||
AddAssert("check not idle", () => box1.IsIdle);
|
checkIdleStatus(1, true);
|
||||||
AddAssert("check not idle", () => !box2.IsIdle);
|
checkIdleStatus(2, false);
|
||||||
AddAssert("check idle", () => !box3.IsIdle);
|
checkIdleStatus(3, false);
|
||||||
AddAssert("check idle", () => !box4.IsIdle);
|
checkIdleStatus(4, false);
|
||||||
|
|
||||||
AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
|
waitForAllIdle();
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestTimings()
|
public void TestTimings()
|
||||||
{
|
{
|
||||||
AddStep("move mouse", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre));
|
AddStep("move to centre", () => InputManager.MoveMouseTo(Content));
|
||||||
|
|
||||||
|
checkIdleStatus(1, false);
|
||||||
|
checkIdleStatus(2, false);
|
||||||
|
checkIdleStatus(3, false);
|
||||||
|
checkIdleStatus(4, false);
|
||||||
|
|
||||||
AddAssert("check not idle", () => !box1.IsIdle && !box2.IsIdle && !box3.IsIdle && !box4.IsIdle);
|
|
||||||
AddUntilStep("Wait for idle", () => box1.IsIdle);
|
AddUntilStep("Wait for idle", () => box1.IsIdle);
|
||||||
AddAssert("check not idle", () => !box2.IsIdle && !box3.IsIdle && !box4.IsIdle);
|
|
||||||
|
checkIdleStatus(1, true);
|
||||||
|
checkIdleStatus(2, false);
|
||||||
|
checkIdleStatus(3, false);
|
||||||
|
checkIdleStatus(4, false);
|
||||||
|
|
||||||
AddUntilStep("Wait for idle", () => box2.IsIdle);
|
AddUntilStep("Wait for idle", () => box2.IsIdle);
|
||||||
AddAssert("check not idle", () => !box3.IsIdle && !box4.IsIdle);
|
|
||||||
|
checkIdleStatus(1, true);
|
||||||
|
checkIdleStatus(2, true);
|
||||||
|
checkIdleStatus(3, false);
|
||||||
|
checkIdleStatus(4, false);
|
||||||
|
|
||||||
AddUntilStep("Wait for idle", () => box3.IsIdle);
|
AddUntilStep("Wait for idle", () => box3.IsIdle);
|
||||||
|
|
||||||
|
checkIdleStatus(1, true);
|
||||||
|
checkIdleStatus(2, true);
|
||||||
|
checkIdleStatus(3, true);
|
||||||
|
checkIdleStatus(4, false);
|
||||||
|
|
||||||
|
waitForAllIdle();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void checkIdleStatus(int box, bool expectedIdle)
|
||||||
|
{
|
||||||
|
AddAssert($"box {box} is {(expectedIdle ? "idle" : "active")}", () => boxes[box - 1].IsIdle == expectedIdle);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void waitForAllIdle()
|
||||||
|
{
|
||||||
AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
|
AddUntilStep("Wait for all idle", () => box1.IsIdle && box2.IsIdle && box3.IsIdle && box4.IsIdle);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -111,16 +111,19 @@ namespace osu.Game.Tests.Visual.Components
|
|||||||
|
|
||||||
private class TestPreviewTrackManager : PreviewTrackManager
|
private class TestPreviewTrackManager : PreviewTrackManager
|
||||||
{
|
{
|
||||||
protected override TrackManagerPreviewTrack CreatePreviewTrack(BeatmapSetInfo beatmapSetInfo, TrackManager trackManager) => new TestPreviewTrack(beatmapSetInfo, trackManager);
|
protected override TrackManagerPreviewTrack CreatePreviewTrack(BeatmapSetInfo beatmapSetInfo, ITrackStore trackStore) => new TestPreviewTrack(beatmapSetInfo, trackStore);
|
||||||
|
|
||||||
protected class TestPreviewTrack : TrackManagerPreviewTrack
|
protected class TestPreviewTrack : TrackManagerPreviewTrack
|
||||||
{
|
{
|
||||||
public TestPreviewTrack(BeatmapSetInfo beatmapSetInfo, TrackManager trackManager)
|
private readonly ITrackStore trackManager;
|
||||||
|
|
||||||
|
public TestPreviewTrack(BeatmapSetInfo beatmapSetInfo, ITrackStore trackManager)
|
||||||
: base(beatmapSetInfo, trackManager)
|
: base(beatmapSetInfo, trackManager)
|
||||||
{
|
{
|
||||||
|
this.trackManager = trackManager;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override Track GetTrack() => new TrackVirtual { Length = 100000 };
|
protected override Track GetTrack() => trackManager.GetVirtual(100000);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,7 +7,6 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Screens.Edit.Compose;
|
using osu.Game.Screens.Edit.Compose;
|
||||||
using osu.Game.Tests.Beatmaps;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Editor
|
namespace osu.Game.Tests.Visual.Editor
|
||||||
{
|
{
|
||||||
@ -19,7 +18,7 @@ namespace osu.Game.Tests.Visual.Editor
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, Clock);
|
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||||
Child = new ComposeScreen();
|
Child = new ComposeScreen();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
@ -30,9 +31,9 @@ namespace osu.Game.Tests.Visual.Editor
|
|||||||
};
|
};
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load(AudioManager audio)
|
||||||
{
|
{
|
||||||
Beatmap.Value = new WaveformTestBeatmap();
|
Beatmap.Value = new WaveformTestBeatmap(audio);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// 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 NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -10,7 +10,6 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Tests.Beatmaps;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -48,7 +47,7 @@ namespace osu.Game.Tests.Visual.Editor
|
|||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
Beatmap.Value = new TestWorkingBeatmap(testBeatmap, Clock);
|
Beatmap.Value = CreateWorkingBeatmap(testBeatmap);
|
||||||
|
|
||||||
Child = new TimingPointVisualiser(testBeatmap, 5000) { Clock = Clock };
|
Child = new TimingPointVisualiser(testBeatmap, 5000) { Clock = Clock };
|
||||||
}
|
}
|
||||||
|
@ -8,7 +8,6 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Screens.Edit.Components.Timelines.Summary;
|
using osu.Game.Screens.Edit.Components.Timelines.Summary;
|
||||||
using osu.Game.Tests.Beatmaps;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Editor
|
namespace osu.Game.Tests.Visual.Editor
|
||||||
@ -21,7 +20,7 @@ namespace osu.Game.Tests.Visual.Editor
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
Beatmap.Value = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, null);
|
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||||
|
|
||||||
Add(new SummaryTimeline
|
Add(new SummaryTimeline
|
||||||
{
|
{
|
||||||
|
@ -18,7 +18,6 @@ using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components;
|
|||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Screens.Edit.Compose;
|
using osu.Game.Screens.Edit.Compose;
|
||||||
using osu.Game.Screens.Edit.Compose.Components;
|
using osu.Game.Screens.Edit.Compose.Components;
|
||||||
using osu.Game.Tests.Beatmaps;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Editor
|
namespace osu.Game.Tests.Visual.Editor
|
||||||
@ -45,7 +44,7 @@ namespace osu.Game.Tests.Visual.Editor
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
Beatmap.Value = new TestWorkingBeatmap(new Beatmap
|
Beatmap.Value = CreateWorkingBeatmap(new Beatmap
|
||||||
{
|
{
|
||||||
HitObjects = new List<HitObject>
|
HitObjects = new List<HitObject>
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// 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 NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -7,7 +7,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Timing;
|
using osu.Framework.Timing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Screens.Edit.Components;
|
using osu.Game.Screens.Edit.Components;
|
||||||
using osu.Game.Tests.Beatmaps;
|
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Editor
|
namespace osu.Game.Tests.Visual.Editor
|
||||||
@ -29,7 +28,7 @@ namespace osu.Game.Tests.Visual.Editor
|
|||||||
Size = new Vector2(200, 100)
|
Size = new Vector2(200, 100)
|
||||||
};
|
};
|
||||||
|
|
||||||
Beatmap.Value = new TestWorkingBeatmap(new Beatmap(), Clock);
|
Beatmap.Value = CreateWorkingBeatmap(new Beatmap());
|
||||||
|
|
||||||
Child = playback;
|
Child = playback;
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Audio;
|
using osu.Framework.Graphics.Audio;
|
||||||
@ -10,6 +11,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Editor
|
namespace osu.Game.Tests.Visual.Editor
|
||||||
@ -20,9 +22,9 @@ namespace osu.Game.Tests.Visual.Editor
|
|||||||
private WorkingBeatmap waveformBeatmap;
|
private WorkingBeatmap waveformBeatmap;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load(AudioManager audio)
|
||||||
{
|
{
|
||||||
waveformBeatmap = new WaveformTestBeatmap();
|
waveformBeatmap = new WaveformTestBeatmap(audio);
|
||||||
}
|
}
|
||||||
|
|
||||||
[TestCase(1f)]
|
[TestCase(1f)]
|
||||||
@ -91,7 +93,7 @@ namespace osu.Game.Tests.Visual.Editor
|
|||||||
Child = graph = new TestWaveformGraph
|
Child = graph = new TestWaveformGraph
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Waveform = new DummyWorkingBeatmap().Waveform,
|
Waveform = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo).Waveform,
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
50
osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs
Normal file
50
osu.Game.Tests/Visual/Gameplay/TestSceneFailAnimation.cs
Normal file
@ -0,0 +1,50 @@
|
|||||||
|
// 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 osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
|
{
|
||||||
|
public class TestSceneFailAnimation : AllPlayersTestScene
|
||||||
|
{
|
||||||
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
|
{
|
||||||
|
Mods.Value = Array.Empty<Mod>();
|
||||||
|
return new FailPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(AllPlayersTestScene),
|
||||||
|
typeof(TestPlayer),
|
||||||
|
typeof(Player),
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override void AddCheckSteps()
|
||||||
|
{
|
||||||
|
AddUntilStep("wait for fail", () => Player.HasFailed);
|
||||||
|
AddUntilStep("wait for fail overlay", () => ((FailPlayer)Player).FailOverlay.State.Value == Visibility.Visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class FailPlayer : TestPlayer
|
||||||
|
{
|
||||||
|
public new FailOverlay FailOverlay => base.FailOverlay;
|
||||||
|
|
||||||
|
public FailPlayer()
|
||||||
|
: base(false, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
ScoreProcessor.FailConditions += (_, __) => true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -97,7 +97,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddStep("Show overlay", () => pauseOverlay.Show());
|
AddStep("Show overlay", () => pauseOverlay.Show());
|
||||||
|
|
||||||
AddStep("Press select", () => press(GlobalAction.Select));
|
AddStep("Press select", () => press(GlobalAction.Select));
|
||||||
AddAssert("Overlay still open", () => pauseOverlay.State == Visibility.Visible);
|
AddAssert("Overlay still open", () => pauseOverlay.State.Value == Visibility.Visible);
|
||||||
|
|
||||||
AddStep("Hide overlay", () => pauseOverlay.Hide());
|
AddStep("Hide overlay", () => pauseOverlay.Hide());
|
||||||
}
|
}
|
||||||
@ -237,7 +237,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("Action was triggered", () => triggered);
|
AddAssert("Action was triggered", () => triggered);
|
||||||
AddAssert("Overlay is closed", () => pauseOverlay.State == Visibility.Hidden);
|
AddAssert("Overlay is closed", () => pauseOverlay.State.Value == Visibility.Hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -272,7 +272,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
return triggered;
|
return triggered;
|
||||||
});
|
});
|
||||||
AddAssert("Overlay is closed", () => pauseOverlay.State == Visibility.Hidden);
|
AddAssert("Overlay is closed", () => pauseOverlay.State.Value == Visibility.Hidden);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void press(Key key)
|
private void press(Key key)
|
||||||
|
109
osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs
Normal file
109
osu.Game.Tests/Visual/Gameplay/TestSceneGameplayRewinding.cs
Normal file
@ -0,0 +1,109 @@
|
|||||||
|
// 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 System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Audio.Track;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Framework.Timing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
|
{
|
||||||
|
public class TestSceneGameplayRewinding : PlayerTestScene
|
||||||
|
{
|
||||||
|
private RulesetExposingPlayer player => (RulesetExposingPlayer)Player;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private AudioManager audioManager { get; set; }
|
||||||
|
|
||||||
|
public TestSceneGameplayRewinding()
|
||||||
|
: base(new OsuRuleset())
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
private Track track;
|
||||||
|
|
||||||
|
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap)
|
||||||
|
{
|
||||||
|
var working = new ClockBackedTestWorkingBeatmap(beatmap, new FramedClock(new ManualClock { Rate = 1 }), audioManager);
|
||||||
|
track = working.Track;
|
||||||
|
return working;
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNoJudgementsOnRewind()
|
||||||
|
{
|
||||||
|
AddUntilStep("wait for track to start running", () => track.IsRunning);
|
||||||
|
addSeekStep(3000);
|
||||||
|
AddAssert("all judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => h.Judged));
|
||||||
|
AddStep("clear results", () => player.AppliedResults.Clear());
|
||||||
|
addSeekStep(0);
|
||||||
|
AddAssert("none judged", () => player.DrawableRuleset.Playfield.AllHitObjects.All(h => !h.Judged));
|
||||||
|
AddAssert("no results triggered", () => player.AppliedResults.Count == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void addSeekStep(double time)
|
||||||
|
{
|
||||||
|
AddStep($"seek to {time}", () => track.Seek(time));
|
||||||
|
|
||||||
|
// Allow a few frames of lenience
|
||||||
|
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time, player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override Player CreatePlayer(Ruleset ruleset)
|
||||||
|
{
|
||||||
|
Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
|
||||||
|
return new RulesetExposingPlayer();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||||
|
{
|
||||||
|
var beatmap = new Beatmap
|
||||||
|
{
|
||||||
|
BeatmapInfo = { BaseDifficulty = { ApproachRate = 9 } },
|
||||||
|
};
|
||||||
|
|
||||||
|
for (int i = 0; i < 15; i++)
|
||||||
|
{
|
||||||
|
beatmap.HitObjects.Add(new HitCircle
|
||||||
|
{
|
||||||
|
Position = new Vector2(256, 192),
|
||||||
|
StartTime = 1000 + 30 * i
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
return beatmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RulesetExposingPlayer : Player
|
||||||
|
{
|
||||||
|
public readonly List<JudgementResult> AppliedResults = new List<JudgementResult>();
|
||||||
|
|
||||||
|
public new GameplayClockContainer GameplayClockContainer => base.GameplayClockContainer;
|
||||||
|
|
||||||
|
public new DrawableRuleset DrawableRuleset => base.DrawableRuleset;
|
||||||
|
|
||||||
|
public RulesetExposingPlayer()
|
||||||
|
: base(false, false)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
ScoreProcessor.NewJudgement += r => AppliedResults.Add(r);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -113,7 +113,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
public void TestPauseAfterFail()
|
public void TestPauseAfterFail()
|
||||||
{
|
{
|
||||||
AddUntilStep("wait for fail", () => Player.HasFailed);
|
AddUntilStep("wait for fail", () => Player.HasFailed);
|
||||||
AddAssert("fail overlay shown", () => Player.FailOverlayVisible);
|
AddUntilStep("fail overlay shown", () => Player.FailOverlayVisible);
|
||||||
|
|
||||||
confirmClockRunning(false);
|
confirmClockRunning(false);
|
||||||
|
|
||||||
@ -137,6 +137,22 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
exitAndConfirm();
|
exitAndConfirm();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestExitViaHoldToExit()
|
||||||
|
{
|
||||||
|
AddStep("exit", () =>
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(Player.HUDOverlay.HoldToQuit.First(c => c is HoldToConfirmContainer));
|
||||||
|
InputManager.PressButton(MouseButton.Left);
|
||||||
|
});
|
||||||
|
|
||||||
|
confirmPaused();
|
||||||
|
|
||||||
|
AddStep("release", () => InputManager.ReleaseButton(MouseButton.Left));
|
||||||
|
|
||||||
|
exitAndConfirm();
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestExitFromPause()
|
public void TestExitFromPause()
|
||||||
{
|
{
|
||||||
@ -189,7 +205,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddAssert("pause overlay " + (isShown ? "shown" : "hidden"), () => Player.PauseOverlayVisible == isShown);
|
AddAssert("pause overlay " + (isShown ? "shown" : "hidden"), () => Player.PauseOverlayVisible == isShown);
|
||||||
|
|
||||||
private void confirmClockRunning(bool isRunning) =>
|
private void confirmClockRunning(bool isRunning) =>
|
||||||
AddAssert("clock " + (isRunning ? "running" : "stopped"), () => Player.GameplayClockContainer.GameplayClock.IsRunning == isRunning);
|
AddUntilStep("clock " + (isRunning ? "running" : "stopped"), () => Player.GameplayClockContainer.GameplayClock.IsRunning == isRunning);
|
||||||
|
|
||||||
protected override bool AllowFail => true;
|
protected override bool AllowFail => true;
|
||||||
|
|
||||||
@ -203,9 +219,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
public new HUDOverlay HUDOverlay => base.HUDOverlay;
|
public new HUDOverlay HUDOverlay => base.HUDOverlay;
|
||||||
|
|
||||||
public bool FailOverlayVisible => FailOverlay.State == Visibility.Visible;
|
public bool FailOverlayVisible => FailOverlay.State.Value == Visibility.Visible;
|
||||||
|
|
||||||
public bool PauseOverlayVisible => PauseOverlay.State == Visibility.Visible;
|
public bool PauseOverlayVisible => PauseOverlay.State.Value == Visibility.Visible;
|
||||||
|
|
||||||
public override void OnEntering(IScreen last)
|
public override void OnEntering(IScreen last)
|
||||||
{
|
{
|
||||||
|
@ -1,4 +1,4 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
@ -16,7 +16,6 @@ using osu.Game.Rulesets.Scoring;
|
|||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using osu.Game.Screens;
|
using osu.Game.Screens;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
using osu.Game.Tests.Beatmaps;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
@ -29,7 +28,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
public void Setup() => Schedule(() =>
|
public void Setup() => Schedule(() =>
|
||||||
{
|
{
|
||||||
InputManager.Child = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both };
|
InputManager.Child = stack = new OsuScreenStack { RelativeSizeAxes = Axes.Both };
|
||||||
Beatmap.Value = new TestWorkingBeatmap(new TestBeatmap(new OsuRuleset().RulesetInfo), Clock);
|
Beatmap.Value = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo);
|
||||||
});
|
});
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Lists;
|
using osu.Framework.Lists;
|
||||||
using osu.Framework.Timing;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Screens.Play;
|
using osu.Game.Screens.Play;
|
||||||
@ -24,7 +23,9 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
GC.WaitForPendingFinalizers();
|
GC.WaitForPendingFinalizers();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
workingWeakReferences.ForEachAlive(_ => count++);
|
foreach (var unused in workingWeakReferences)
|
||||||
|
count++;
|
||||||
|
|
||||||
return count == 1;
|
return count == 1;
|
||||||
});
|
});
|
||||||
|
|
||||||
@ -34,14 +35,16 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
GC.WaitForPendingFinalizers();
|
GC.WaitForPendingFinalizers();
|
||||||
int count = 0;
|
int count = 0;
|
||||||
|
|
||||||
playerWeakReferences.ForEachAlive(_ => count++);
|
foreach (var unused in playerWeakReferences)
|
||||||
|
count++;
|
||||||
|
|
||||||
return count == 1;
|
return count == 1;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, IFrameBasedClock clock)
|
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap)
|
||||||
{
|
{
|
||||||
var working = base.CreateWorkingBeatmap(beatmap, clock);
|
var working = base.CreateWorkingBeatmap(beatmap);
|
||||||
workingWeakReferences.Add(working);
|
workingWeakReferences.Add(working);
|
||||||
return working;
|
return working;
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,76 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Online;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osuTK;
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneReplayDownloadButton : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(ReplayDownloadButton)
|
||||||
|
};
|
||||||
|
|
||||||
|
private TestReplayDownloadButton downloadButton;
|
||||||
|
|
||||||
|
public TestSceneReplayDownloadButton()
|
||||||
|
{
|
||||||
|
createButton(true);
|
||||||
|
AddStep(@"downloading state", () => downloadButton.SetDownloadState(DownloadState.Downloading));
|
||||||
|
AddStep(@"locally available state", () => downloadButton.SetDownloadState(DownloadState.LocallyAvailable));
|
||||||
|
AddStep(@"not downloaded state", () => downloadButton.SetDownloadState(DownloadState.NotDownloaded));
|
||||||
|
createButton(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createButton(bool withReplay)
|
||||||
|
{
|
||||||
|
AddStep(withReplay ? @"create button with replay" : "create button without replay", () =>
|
||||||
|
{
|
||||||
|
Child = downloadButton = new TestReplayDownloadButton(getScoreInfo(withReplay))
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(80, 40),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private ScoreInfo getScoreInfo(bool replayAvailable)
|
||||||
|
{
|
||||||
|
return new APILegacyScoreInfo
|
||||||
|
{
|
||||||
|
ID = 1,
|
||||||
|
OnlineScoreID = 2553163309,
|
||||||
|
Ruleset = new OsuRuleset().RulesetInfo,
|
||||||
|
Replay = replayAvailable,
|
||||||
|
User = new User
|
||||||
|
{
|
||||||
|
Id = 39828,
|
||||||
|
Username = @"WubWoofWolf",
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestReplayDownloadButton : ReplayDownloadButton
|
||||||
|
{
|
||||||
|
public void SetDownloadState(DownloadState state) => State.Value = state;
|
||||||
|
|
||||||
|
public TestReplayDownloadButton(ScoreInfo score)
|
||||||
|
: base(score)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,6 +5,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Screens.Play.HUD;
|
using osu.Game.Screens.Play.HUD;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -53,7 +54,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
};
|
};
|
||||||
Add(stars);
|
Add(stars);
|
||||||
|
|
||||||
SpriteText starsLabel = new SpriteText
|
SpriteText starsLabel = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
|
@ -7,9 +7,9 @@ using osu.Framework.Audio.Sample;
|
|||||||
using osu.Framework.Graphics;
|
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.Graphics.Sprites;
|
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
Colour = Color4.Black,
|
Colour = Color4.Black,
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
},
|
},
|
||||||
new SpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Font = OsuFont.Default.With(size: 40),
|
Font = OsuFont.Default.With(size: 40),
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
|
@ -46,7 +46,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
Origin = Anchor.TopRight,
|
Origin = Anchor.TopRight,
|
||||||
Anchor = Anchor.TopRight,
|
Anchor = Anchor.TopRight,
|
||||||
State = Visibility.Visible,
|
State = { Value = Visibility.Visible },
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("Restart", restart);
|
AddStep("Restart", restart);
|
||||||
|
@ -53,38 +53,12 @@ namespace osu.Game.Tests.Visual.Menus
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestShortLoad()
|
public void TestDelayedLoad()
|
||||||
{
|
{
|
||||||
bool logoVisible = false;
|
|
||||||
|
|
||||||
AddStep("begin loading", () => LoadScreen(loader = new TestLoader()));
|
AddStep("begin loading", () => LoadScreen(loader = new TestLoader()));
|
||||||
AddWaitStep("wait", 3);
|
AddUntilStep("wait for logo visible", () => loader.Logo?.Alpha > 0);
|
||||||
AddStep("finish loading", () =>
|
AddStep("finish loading", () => loader.AllowLoad.Set());
|
||||||
{
|
|
||||||
logoVisible = loader.Logo?.Alpha > 0;
|
|
||||||
loader.AllowLoad.Set();
|
|
||||||
});
|
|
||||||
|
|
||||||
AddAssert("loaded", () => loader.Logo != null && loader.ScreenLoaded);
|
AddAssert("loaded", () => loader.Logo != null && loader.ScreenLoaded);
|
||||||
AddAssert("logo was visible", () => logoVisible);
|
|
||||||
AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
|
|
||||||
}
|
|
||||||
|
|
||||||
[Test]
|
|
||||||
public void TestLongLoad()
|
|
||||||
{
|
|
||||||
bool logoVisible = false;
|
|
||||||
|
|
||||||
AddStep("begin loading", () => LoadScreen(loader = new TestLoader()));
|
|
||||||
AddWaitStep("wait", 10);
|
|
||||||
AddStep("finish loading", () =>
|
|
||||||
{
|
|
||||||
logoVisible = loader.Logo?.Alpha > 0;
|
|
||||||
loader.AllowLoad.Set();
|
|
||||||
});
|
|
||||||
|
|
||||||
AddAssert("loaded", () => loader.Logo != null && loader.ScreenLoaded);
|
|
||||||
AddAssert("logo was visible", () => logoVisible);
|
|
||||||
AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
|
AddUntilStep("logo gone", () => loader.Logo?.Alpha == 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -17,13 +17,13 @@ namespace osu.Game.Tests.Visual.Menus
|
|||||||
{
|
{
|
||||||
typeof(ToolbarButton),
|
typeof(ToolbarButton),
|
||||||
typeof(ToolbarRulesetSelector),
|
typeof(ToolbarRulesetSelector),
|
||||||
typeof(ToolbarRulesetButton),
|
typeof(ToolbarRulesetTabButton),
|
||||||
typeof(ToolbarNotificationButton),
|
typeof(ToolbarNotificationButton),
|
||||||
};
|
};
|
||||||
|
|
||||||
public TestSceneToolbar()
|
public TestSceneToolbar()
|
||||||
{
|
{
|
||||||
var toolbar = new Toolbar { State = Visibility.Visible };
|
var toolbar = new Toolbar { State = { Value = Visibility.Visible } };
|
||||||
ToolbarNotificationButton notificationButton = null;
|
ToolbarNotificationButton notificationButton = null;
|
||||||
|
|
||||||
AddStep("create toolbar", () =>
|
AddStep("create toolbar", () =>
|
||||||
|
@ -8,7 +8,6 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Beatmaps;
|
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Online.Multiplayer;
|
using osu.Game.Online.Multiplayer;
|
||||||
@ -37,7 +36,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
settings = new TestRoomSettings
|
settings = new TestRoomSettings
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
State = Visibility.Visible
|
State = { Value = Visibility.Visible }
|
||||||
};
|
};
|
||||||
|
|
||||||
Child = settings;
|
Child = settings;
|
||||||
@ -57,7 +56,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddStep("set name", () => Room.Name.Value = "Room name");
|
AddStep("set name", () => Room.Name.Value = "Room name");
|
||||||
AddAssert("button disabled", () => !settings.ApplyButton.Enabled.Value);
|
AddAssert("button disabled", () => !settings.ApplyButton.Enabled.Value);
|
||||||
|
|
||||||
AddStep("set beatmap", () => Room.Playlist.Add(new PlaylistItem { Beatmap = new DummyWorkingBeatmap().BeatmapInfo }));
|
AddStep("set beatmap", () => Room.Playlist.Add(new PlaylistItem { Beatmap = CreateBeatmap(Ruleset.Value).BeatmapInfo }));
|
||||||
AddAssert("button enabled", () => settings.ApplyButton.Enabled.Value);
|
AddAssert("button enabled", () => settings.ApplyButton.Enabled.Value);
|
||||||
|
|
||||||
AddStep("clear name", () => Room.Name.Value = "");
|
AddStep("clear name", () => Room.Name.Value = "");
|
||||||
|
@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
api.Logout();
|
api.Logout();
|
||||||
api.LocalUser.BindValueChanged(user => { userPanelArea.Child = new UserPanel(user.NewValue) { Width = 200 }; }, true);
|
api.LocalUser.BindValueChanged(user => { userPanelArea.Child = new UserPanel(user.NewValue) { Width = 200 }; }, true);
|
||||||
|
|
||||||
AddStep("show", () => accountCreation.State = Visibility.Visible);
|
AddStep("show", () => accountCreation.Show());
|
||||||
AddStep("logout", () => api.Logout());
|
AddStep("logout", () => api.Logout());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
95
osu.Game.Tests/Visual/Online/TestSceneBeatmapAvailability.cs
Normal file
95
osu.Game.Tests/Visual/Online/TestSceneBeatmapAvailability.cs
Normal file
@ -0,0 +1,95 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Overlays.BeatmapSet;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneBeatmapAvailability : OsuTestScene
|
||||||
|
{
|
||||||
|
private readonly BeatmapAvailability container;
|
||||||
|
|
||||||
|
public TestSceneBeatmapAvailability()
|
||||||
|
{
|
||||||
|
Add(container = new BeatmapAvailability());
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestUndownloadableWithLink()
|
||||||
|
{
|
||||||
|
AddStep("set undownloadable beatmapset with link", () => container.BeatmapSet = new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
|
{
|
||||||
|
Availability = new BeatmapSetOnlineAvailability
|
||||||
|
{
|
||||||
|
DownloadDisabled = true,
|
||||||
|
ExternalLink = @"https://osu.ppy.sh",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
visiblityAssert(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestUndownloadableNoLink()
|
||||||
|
{
|
||||||
|
AddStep("set undownloadable beatmapset without link", () => container.BeatmapSet = new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
|
{
|
||||||
|
Availability = new BeatmapSetOnlineAvailability
|
||||||
|
{
|
||||||
|
DownloadDisabled = true,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
visiblityAssert(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestPartsRemovedWithLink()
|
||||||
|
{
|
||||||
|
AddStep("set parts-removed beatmapset with link", () => container.BeatmapSet = new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
|
{
|
||||||
|
Availability = new BeatmapSetOnlineAvailability
|
||||||
|
{
|
||||||
|
DownloadDisabled = false,
|
||||||
|
ExternalLink = @"https://osu.ppy.sh",
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
visiblityAssert(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestNormal()
|
||||||
|
{
|
||||||
|
AddStep("set normal beatmapset", () => container.BeatmapSet = new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
|
{
|
||||||
|
Availability = new BeatmapSetOnlineAvailability
|
||||||
|
{
|
||||||
|
DownloadDisabled = false,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
});
|
||||||
|
|
||||||
|
visiblityAssert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void visiblityAssert(bool shown)
|
||||||
|
{
|
||||||
|
AddAssert($"is container {(shown ? "visible" : "hidden")}", () => container.Alpha == (shown ? 1 : 0));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -19,7 +19,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
[TestFixture]
|
[TestFixture]
|
||||||
public class TestSceneBeatmapSetOverlay : OsuTestScene
|
public class TestSceneBeatmapSetOverlay : OsuTestScene
|
||||||
{
|
{
|
||||||
private readonly BeatmapSetOverlay overlay;
|
private readonly TestBeatmapSetOverlay overlay;
|
||||||
|
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
{
|
{
|
||||||
@ -32,375 +32,204 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
typeof(BasicStats),
|
typeof(BasicStats),
|
||||||
typeof(BeatmapPicker),
|
typeof(BeatmapPicker),
|
||||||
typeof(Details),
|
typeof(Details),
|
||||||
typeof(DownloadButton),
|
typeof(HeaderDownloadButton),
|
||||||
typeof(FavouriteButton),
|
typeof(FavouriteButton),
|
||||||
typeof(Header),
|
typeof(Header),
|
||||||
typeof(HeaderButton),
|
typeof(HeaderButton),
|
||||||
typeof(Info),
|
typeof(Info),
|
||||||
typeof(PreviewButton),
|
typeof(PreviewButton),
|
||||||
typeof(SuccessRate),
|
typeof(SuccessRate),
|
||||||
|
typeof(BeatmapAvailability),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private RulesetInfo taikoRuleset;
|
||||||
|
private RulesetInfo maniaRuleset;
|
||||||
|
|
||||||
public TestSceneBeatmapSetOverlay()
|
public TestSceneBeatmapSetOverlay()
|
||||||
{
|
{
|
||||||
Add(overlay = new BeatmapSetOverlay());
|
Add(overlay = new TestBeatmapSetOverlay());
|
||||||
}
|
}
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(RulesetStore rulesets)
|
private void load(RulesetStore rulesets)
|
||||||
{
|
{
|
||||||
var mania = rulesets.GetRuleset(3);
|
taikoRuleset = rulesets.GetRuleset(1);
|
||||||
var taiko = rulesets.GetRuleset(1);
|
maniaRuleset = rulesets.GetRuleset(3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLoading()
|
||||||
|
{
|
||||||
AddStep(@"show loading", () => overlay.ShowBeatmapSet(null));
|
AddStep(@"show loading", () => overlay.ShowBeatmapSet(null));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestOnline()
|
||||||
|
{
|
||||||
AddStep(@"show online", () => overlay.FetchAndShowBeatmapSet(55));
|
AddStep(@"show online", () => overlay.FetchAndShowBeatmapSet(55));
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestLocalBeatmaps()
|
||||||
|
{
|
||||||
AddStep(@"show first", () =>
|
AddStep(@"show first", () =>
|
||||||
{
|
{
|
||||||
overlay.ShowBeatmapSet(new BeatmapSetInfo
|
overlay.ShowBeatmapSet(new BeatmapSetInfo
|
||||||
{
|
{
|
||||||
|
OnlineBeatmapSetID = 1235,
|
||||||
Metadata = new BeatmapMetadata
|
Metadata = new BeatmapMetadata
|
||||||
{
|
{
|
||||||
Title = @"Lachryma <Re:Queen’M>",
|
Title = @"an awesome beatmap",
|
||||||
Artist = @"Kaneko Chiharu",
|
Artist = @"naru narusegawa",
|
||||||
Source = @"SOUND VOLTEX III GRAVITY WARS",
|
Source = @"hinata sou",
|
||||||
Tags = @"sdvx grace the 5th kac original song contest konami bemani",
|
Tags = @"test tag tag more tag",
|
||||||
Author = new User
|
Author = new User
|
||||||
{
|
{
|
||||||
Username = @"Fresh Chicken",
|
Username = @"BanchoBot",
|
||||||
Id = 3984370,
|
Id = 3,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
{
|
{
|
||||||
Preview = @"https://b.ppy.sh/preview/415886.mp3",
|
Preview = @"https://b.ppy.sh/preview/12345.mp3",
|
||||||
PlayCount = 681380,
|
PlayCount = 123,
|
||||||
FavouriteCount = 356,
|
FavouriteCount = 456,
|
||||||
Submitted = new DateTime(2016, 2, 10),
|
Submitted = DateTime.Now,
|
||||||
Ranked = new DateTime(2016, 6, 19),
|
Ranked = DateTime.Now,
|
||||||
Status = BeatmapSetOnlineStatus.Ranked,
|
BPM = 111,
|
||||||
BPM = 236,
|
|
||||||
HasVideo = true,
|
HasVideo = true,
|
||||||
Covers = new BeatmapSetOnlineCovers
|
HasStoryboard = true,
|
||||||
{
|
Covers = new BeatmapSetOnlineCovers(),
|
||||||
Cover = @"https://assets.ppy.sh/beatmaps/415886/covers/cover.jpg?1465651778",
|
|
||||||
},
|
|
||||||
},
|
},
|
||||||
|
Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() },
|
||||||
Beatmaps = new List<BeatmapInfo>
|
Beatmaps = new List<BeatmapInfo>
|
||||||
{
|
{
|
||||||
new BeatmapInfo
|
new BeatmapInfo
|
||||||
{
|
{
|
||||||
StarDifficulty = 1.36,
|
StarDifficulty = 9.99,
|
||||||
Version = @"BASIC",
|
Version = @"TEST",
|
||||||
Ruleset = mania,
|
Ruleset = maniaRuleset,
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
{
|
{
|
||||||
CircleSize = 4,
|
CircleSize = 1,
|
||||||
DrainRate = 6.5f,
|
DrainRate = 2.3f,
|
||||||
OverallDifficulty = 6.5f,
|
OverallDifficulty = 4.5f,
|
||||||
ApproachRate = 5,
|
ApproachRate = 6,
|
||||||
},
|
},
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
OnlineInfo = new BeatmapOnlineInfo
|
||||||
{
|
{
|
||||||
Length = 115000,
|
Length = 456000,
|
||||||
CircleCount = 265,
|
CircleCount = 111,
|
||||||
SliderCount = 71,
|
SliderCount = 12,
|
||||||
PlayCount = 47906,
|
PlayCount = 222,
|
||||||
PassCount = 19899,
|
PassCount = 21,
|
||||||
},
|
},
|
||||||
Metrics = new BeatmapMetrics
|
Metrics = new BeatmapMetrics
|
||||||
{
|
{
|
||||||
Ratings = Enumerable.Range(0, 11),
|
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(),
|
||||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(),
|
||||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 2.22,
|
|
||||||
Version = @"NOVICE",
|
|
||||||
Ruleset = mania,
|
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
|
||||||
{
|
|
||||||
CircleSize = 4,
|
|
||||||
DrainRate = 7,
|
|
||||||
OverallDifficulty = 7,
|
|
||||||
ApproachRate = 5,
|
|
||||||
},
|
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
|
||||||
{
|
|
||||||
Length = 118000,
|
|
||||||
CircleCount = 592,
|
|
||||||
SliderCount = 62,
|
|
||||||
PlayCount = 162021,
|
|
||||||
PassCount = 72116,
|
|
||||||
},
|
|
||||||
Metrics = new BeatmapMetrics
|
|
||||||
{
|
|
||||||
Ratings = Enumerable.Range(0, 11),
|
|
||||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
|
||||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 3.49,
|
|
||||||
Version = @"ADVANCED",
|
|
||||||
Ruleset = mania,
|
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
|
||||||
{
|
|
||||||
CircleSize = 4,
|
|
||||||
DrainRate = 7.5f,
|
|
||||||
OverallDifficulty = 7.5f,
|
|
||||||
ApproachRate = 5,
|
|
||||||
},
|
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
|
||||||
{
|
|
||||||
Length = 118000,
|
|
||||||
CircleCount = 1042,
|
|
||||||
SliderCount = 79,
|
|
||||||
PlayCount = 225178,
|
|
||||||
PassCount = 73001,
|
|
||||||
},
|
|
||||||
Metrics = new BeatmapMetrics
|
|
||||||
{
|
|
||||||
Ratings = Enumerable.Range(0, 11),
|
|
||||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
|
||||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 4.24,
|
|
||||||
Version = @"EXHAUST",
|
|
||||||
Ruleset = mania,
|
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
|
||||||
{
|
|
||||||
CircleSize = 4,
|
|
||||||
DrainRate = 8,
|
|
||||||
OverallDifficulty = 8,
|
|
||||||
ApproachRate = 5,
|
|
||||||
},
|
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
|
||||||
{
|
|
||||||
Length = 118000,
|
|
||||||
CircleCount = 1352,
|
|
||||||
SliderCount = 69,
|
|
||||||
PlayCount = 131545,
|
|
||||||
PassCount = 42703,
|
|
||||||
},
|
|
||||||
Metrics = new BeatmapMetrics
|
|
||||||
{
|
|
||||||
Ratings = Enumerable.Range(0, 11),
|
|
||||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
|
||||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 5.26,
|
|
||||||
Version = @"GRAVITY",
|
|
||||||
Ruleset = mania,
|
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
|
||||||
{
|
|
||||||
CircleSize = 4,
|
|
||||||
DrainRate = 8.5f,
|
|
||||||
OverallDifficulty = 8.5f,
|
|
||||||
ApproachRate = 5,
|
|
||||||
},
|
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
|
||||||
{
|
|
||||||
Length = 118000,
|
|
||||||
CircleCount = 1730,
|
|
||||||
SliderCount = 115,
|
|
||||||
PlayCount = 117673,
|
|
||||||
PassCount = 24241,
|
|
||||||
},
|
|
||||||
Metrics = new BeatmapMetrics
|
|
||||||
{
|
|
||||||
Ratings = Enumerable.Range(0, 11),
|
|
||||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
|
||||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep(@"show second", () =>
|
downloadAssert(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestAvailability()
|
||||||
|
{
|
||||||
|
AddStep(@"show undownloadable", () =>
|
||||||
{
|
{
|
||||||
overlay.ShowBeatmapSet(new BeatmapSetInfo
|
overlay.ShowBeatmapSet(new BeatmapSetInfo
|
||||||
{
|
{
|
||||||
|
OnlineBeatmapSetID = 1234,
|
||||||
Metadata = new BeatmapMetadata
|
Metadata = new BeatmapMetadata
|
||||||
{
|
{
|
||||||
Title = @"Soumatou Labyrinth",
|
Title = @"undownloadable beatmap",
|
||||||
Artist = @"Yunomi with Momobako&miko",
|
Artist = @"no one",
|
||||||
Tags = @"mmbk.com yuzu__rinrin charlotte",
|
Source = @"some source",
|
||||||
|
Tags = @"another test tag tag more test tags",
|
||||||
Author = new User
|
Author = new User
|
||||||
{
|
{
|
||||||
Username = @"komasy",
|
Username = @"BanchoBot",
|
||||||
Id = 1980256,
|
Id = 3,
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
OnlineInfo = new BeatmapSetOnlineInfo
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
{
|
{
|
||||||
Preview = @"https://b.ppy.sh/preview/625493.mp3",
|
Availability = new BeatmapSetOnlineAvailability
|
||||||
PlayCount = 22996,
|
|
||||||
FavouriteCount = 58,
|
|
||||||
Submitted = new DateTime(2016, 6, 11),
|
|
||||||
Ranked = new DateTime(2016, 7, 12),
|
|
||||||
Status = BeatmapSetOnlineStatus.Pending,
|
|
||||||
BPM = 160,
|
|
||||||
HasVideo = false,
|
|
||||||
Covers = new BeatmapSetOnlineCovers
|
|
||||||
{
|
{
|
||||||
Cover = @"https://assets.ppy.sh/beatmaps/625493/covers/cover.jpg?1499167472",
|
DownloadDisabled = true,
|
||||||
|
ExternalLink = "https://osu.ppy.sh",
|
||||||
},
|
},
|
||||||
|
Preview = @"https://b.ppy.sh/preview/1234.mp3",
|
||||||
|
PlayCount = 123,
|
||||||
|
FavouriteCount = 456,
|
||||||
|
Submitted = DateTime.Now,
|
||||||
|
Ranked = DateTime.Now,
|
||||||
|
BPM = 111,
|
||||||
|
HasVideo = true,
|
||||||
|
HasStoryboard = true,
|
||||||
|
Covers = new BeatmapSetOnlineCovers(),
|
||||||
},
|
},
|
||||||
|
Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).ToArray() },
|
||||||
Beatmaps = new List<BeatmapInfo>
|
Beatmaps = new List<BeatmapInfo>
|
||||||
{
|
{
|
||||||
new BeatmapInfo
|
new BeatmapInfo
|
||||||
{
|
{
|
||||||
StarDifficulty = 1.40,
|
StarDifficulty = 5.67,
|
||||||
Version = @"yzrin's Kantan",
|
Version = @"ANOTHER TEST",
|
||||||
Ruleset = taiko,
|
Ruleset = taikoRuleset,
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
BaseDifficulty = new BeatmapDifficulty
|
||||||
{
|
{
|
||||||
CircleSize = 2,
|
CircleSize = 9,
|
||||||
DrainRate = 7,
|
DrainRate = 8,
|
||||||
OverallDifficulty = 3,
|
OverallDifficulty = 7,
|
||||||
ApproachRate = 10,
|
ApproachRate = 6,
|
||||||
},
|
},
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
OnlineInfo = new BeatmapOnlineInfo
|
||||||
{
|
{
|
||||||
Length = 193000,
|
Length = 123000,
|
||||||
CircleCount = 262,
|
CircleCount = 123,
|
||||||
SliderCount = 0,
|
SliderCount = 45,
|
||||||
PlayCount = 3952,
|
PlayCount = 567,
|
||||||
PassCount = 1373,
|
PassCount = 89,
|
||||||
},
|
},
|
||||||
Metrics = new BeatmapMetrics
|
Metrics = new BeatmapMetrics
|
||||||
{
|
{
|
||||||
Ratings = Enumerable.Range(0, 11),
|
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6).ToArray(),
|
||||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6).ToArray(),
|
||||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 2.23,
|
|
||||||
Version = @"Futsuu",
|
|
||||||
Ruleset = taiko,
|
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
|
||||||
{
|
|
||||||
CircleSize = 2,
|
|
||||||
DrainRate = 6,
|
|
||||||
OverallDifficulty = 4,
|
|
||||||
ApproachRate = 10,
|
|
||||||
},
|
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
|
||||||
{
|
|
||||||
Length = 193000,
|
|
||||||
CircleCount = 464,
|
|
||||||
SliderCount = 0,
|
|
||||||
PlayCount = 4833,
|
|
||||||
PassCount = 920,
|
|
||||||
},
|
|
||||||
Metrics = new BeatmapMetrics
|
|
||||||
{
|
|
||||||
Ratings = Enumerable.Range(0, 11),
|
|
||||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
|
||||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 3.19,
|
|
||||||
Version = @"Muzukashii",
|
|
||||||
Ruleset = taiko,
|
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
|
||||||
{
|
|
||||||
CircleSize = 2,
|
|
||||||
DrainRate = 6,
|
|
||||||
OverallDifficulty = 5,
|
|
||||||
ApproachRate = 10,
|
|
||||||
},
|
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
|
||||||
{
|
|
||||||
Length = 193000,
|
|
||||||
CircleCount = 712,
|
|
||||||
SliderCount = 0,
|
|
||||||
PlayCount = 4405,
|
|
||||||
PassCount = 854,
|
|
||||||
},
|
|
||||||
Metrics = new BeatmapMetrics
|
|
||||||
{
|
|
||||||
Ratings = Enumerable.Range(0, 11),
|
|
||||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
|
||||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 3.97,
|
|
||||||
Version = @"Charlotte's Oni",
|
|
||||||
Ruleset = taiko,
|
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
|
||||||
{
|
|
||||||
CircleSize = 5,
|
|
||||||
DrainRate = 6,
|
|
||||||
OverallDifficulty = 5.5f,
|
|
||||||
ApproachRate = 10,
|
|
||||||
},
|
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
|
||||||
{
|
|
||||||
Length = 193000,
|
|
||||||
CircleCount = 943,
|
|
||||||
SliderCount = 0,
|
|
||||||
PlayCount = 3950,
|
|
||||||
PassCount = 693,
|
|
||||||
},
|
|
||||||
Metrics = new BeatmapMetrics
|
|
||||||
{
|
|
||||||
Ratings = Enumerable.Range(0, 11),
|
|
||||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
|
||||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
|
||||||
},
|
|
||||||
},
|
|
||||||
new BeatmapInfo
|
|
||||||
{
|
|
||||||
StarDifficulty = 5.08,
|
|
||||||
Version = @"Labyrinth Oni",
|
|
||||||
Ruleset = taiko,
|
|
||||||
BaseDifficulty = new BeatmapDifficulty
|
|
||||||
{
|
|
||||||
CircleSize = 5,
|
|
||||||
DrainRate = 5,
|
|
||||||
OverallDifficulty = 6,
|
|
||||||
ApproachRate = 10,
|
|
||||||
},
|
|
||||||
OnlineInfo = new BeatmapOnlineInfo
|
|
||||||
{
|
|
||||||
Length = 193000,
|
|
||||||
CircleCount = 1068,
|
|
||||||
SliderCount = 0,
|
|
||||||
PlayCount = 5856,
|
|
||||||
PassCount = 1207,
|
|
||||||
},
|
|
||||||
Metrics = new BeatmapMetrics
|
|
||||||
{
|
|
||||||
Ratings = Enumerable.Range(0, 11),
|
|
||||||
Fails = Enumerable.Range(1, 100).Select(i => i % 12 - 6),
|
|
||||||
Retries = Enumerable.Range(-2, 100).Select(i => i % 12 - 6),
|
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
});
|
});
|
||||||
});
|
});
|
||||||
|
|
||||||
|
downloadAssert(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestHide()
|
||||||
|
{
|
||||||
AddStep(@"hide", overlay.Hide);
|
AddStep(@"hide", overlay.Hide);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestShowWithNoReload()
|
||||||
|
{
|
||||||
AddStep(@"show without reload", overlay.Show);
|
AddStep(@"show without reload", overlay.Show);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void downloadAssert(bool shown)
|
||||||
|
{
|
||||||
|
AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.DownloadButtonsVisible == shown);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestBeatmapSetOverlay : BeatmapSetOverlay
|
||||||
|
{
|
||||||
|
public bool DownloadButtonsVisible => Header.DownloadButtonsVisible;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -0,0 +1,69 @@
|
|||||||
|
// 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.Graphics;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Overlays.BeatmapSet;
|
||||||
|
using osu.Game.Screens.Select.Details;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
public class TestSceneBeatmapSetOverlayDetails : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(Details)
|
||||||
|
};
|
||||||
|
|
||||||
|
private RatingsExposingDetails details;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup() => Schedule(() =>
|
||||||
|
{
|
||||||
|
Child = details = new RatingsExposingDetails
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMetrics()
|
||||||
|
{
|
||||||
|
var firstSet = createSet();
|
||||||
|
var secondSet = createSet();
|
||||||
|
|
||||||
|
AddStep("set first set", () => details.BeatmapSet = firstSet);
|
||||||
|
AddAssert("ratings set", () => details.Ratings.Metrics == firstSet.Metrics);
|
||||||
|
|
||||||
|
AddStep("set second set", () => details.BeatmapSet = secondSet);
|
||||||
|
AddAssert("ratings set", () => details.Ratings.Metrics == secondSet.Metrics);
|
||||||
|
|
||||||
|
BeatmapSetInfo createSet() => new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
Metrics = new BeatmapSetMetrics { Ratings = Enumerable.Range(0, 11).Select(_ => RNG.Next(10)).ToArray() },
|
||||||
|
Beatmaps = new List<BeatmapInfo>
|
||||||
|
{
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Metrics = new BeatmapMetrics
|
||||||
|
{
|
||||||
|
Fails = Enumerable.Range(1, 100).Select(_ => RNG.Next(10)).ToArray(),
|
||||||
|
Retries = Enumerable.Range(-2, 100).Select(_ => RNG.Next(10)).ToArray(),
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private class RatingsExposingDetails : Details
|
||||||
|
{
|
||||||
|
public new UserRatings Ratings => base.Ratings;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,82 @@
|
|||||||
|
// 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.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Overlays.BeatmapSet;
|
||||||
|
using osu.Game.Screens.Select.Details;
|
||||||
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
public class TestSceneBeatmapSetOverlaySuccessRate : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(Details)
|
||||||
|
};
|
||||||
|
|
||||||
|
private GraphExposingSuccessRate successRate;
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup() => Schedule(() =>
|
||||||
|
{
|
||||||
|
Child = new Container
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(275, 220),
|
||||||
|
Children = new Drawable[]
|
||||||
|
{
|
||||||
|
new Box
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Colour = Color4.Gray,
|
||||||
|
},
|
||||||
|
successRate = new GraphExposingSuccessRate
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(275, 220),
|
||||||
|
Padding = new MarginPadding(20)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
});
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMetrics()
|
||||||
|
{
|
||||||
|
var firstBeatmap = createBeatmap();
|
||||||
|
var secondBeatmap = createBeatmap();
|
||||||
|
|
||||||
|
AddStep("set first set", () => successRate.Beatmap = firstBeatmap);
|
||||||
|
AddAssert("ratings set", () => successRate.Graph.Metrics == firstBeatmap.Metrics);
|
||||||
|
|
||||||
|
AddStep("set second set", () => successRate.Beatmap = secondBeatmap);
|
||||||
|
AddAssert("ratings set", () => successRate.Graph.Metrics == secondBeatmap.Metrics);
|
||||||
|
|
||||||
|
BeatmapInfo createBeatmap() => new BeatmapInfo
|
||||||
|
{
|
||||||
|
Metrics = new BeatmapMetrics
|
||||||
|
{
|
||||||
|
Fails = Enumerable.Range(1, 100).Select(_ => RNG.Next(10)).ToArray(),
|
||||||
|
Retries = Enumerable.Range(-2, 100).Select(_ => RNG.Next(10)).ToArray(),
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private class GraphExposingSuccessRate : SuccessRate
|
||||||
|
{
|
||||||
|
public new FailRetryGraph Graph => base.Graph;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
70
osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs
Normal file
70
osu.Game.Tests/Visual/Online/TestSceneChangelogOverlay.cs
Normal file
@ -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 System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Online.API.Requests.Responses;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.Changelog;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneChangelogOverlay : OsuTestScene
|
||||||
|
{
|
||||||
|
private ChangelogOverlay changelog;
|
||||||
|
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(UpdateStreamBadgeArea),
|
||||||
|
typeof(UpdateStreamBadge),
|
||||||
|
typeof(ChangelogHeader),
|
||||||
|
typeof(ChangelogContent),
|
||||||
|
typeof(ChangelogListing),
|
||||||
|
typeof(ChangelogSingleBuild),
|
||||||
|
typeof(ChangelogBuild),
|
||||||
|
};
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
Add(changelog = new ChangelogOverlay());
|
||||||
|
AddStep(@"Show", changelog.Show);
|
||||||
|
AddStep(@"Hide", changelog.Hide);
|
||||||
|
|
||||||
|
AddWaitStep("wait for hide", 3);
|
||||||
|
|
||||||
|
AddStep(@"Show with Lazer 2018.712.0", () =>
|
||||||
|
{
|
||||||
|
changelog.ShowBuild(new APIChangelogBuild
|
||||||
|
{
|
||||||
|
Version = "2018.712.0",
|
||||||
|
DisplayVersion = "2018.712.0",
|
||||||
|
UpdateStream = new APIUpdateStream { Name = OsuGameBase.CLIENT_STREAM_NAME },
|
||||||
|
ChangelogEntries = new List<APIChangelogEntry>
|
||||||
|
{
|
||||||
|
new APIChangelogEntry
|
||||||
|
{
|
||||||
|
Category = "Test",
|
||||||
|
Title = "Title",
|
||||||
|
MessageHtml = "Message",
|
||||||
|
}
|
||||||
|
}
|
||||||
|
});
|
||||||
|
changelog.Show();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddWaitStep("wait for show", 3);
|
||||||
|
AddStep(@"Hide", changelog.Hide);
|
||||||
|
AddWaitStep("wait for hide", 3);
|
||||||
|
|
||||||
|
AddStep(@"Show with listing", () =>
|
||||||
|
{
|
||||||
|
changelog.ShowListing();
|
||||||
|
changelog.Show();
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.MathUtils;
|
using osu.Framework.MathUtils;
|
||||||
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Online.Chat;
|
using osu.Game.Online.Chat;
|
||||||
using osu.Game.Overlays.Chat.Tabs;
|
using osu.Game.Overlays.Chat.Tabs;
|
||||||
using osu.Game.Users;
|
using osu.Game.Users;
|
||||||
@ -61,7 +62,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Anchor = Anchor.TopLeft,
|
Anchor = Anchor.TopLeft,
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
currentText = new SpriteText
|
currentText = new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = "Currently selected channel:"
|
Text = "Currently selected channel:"
|
||||||
}
|
}
|
||||||
|
@ -1,45 +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 System;
|
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.ComponentModel;
|
|
||||||
using osu.Framework.Allocation;
|
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Online.Chat;
|
|
||||||
using osu.Game.Overlays;
|
|
||||||
using osu.Game.Overlays.Chat;
|
|
||||||
using osu.Game.Overlays.Chat.Tabs;
|
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Online
|
|
||||||
{
|
|
||||||
[Description("Testing chat api and overlay")]
|
|
||||||
public class TestSceneChatDisplay : OsuTestScene
|
|
||||||
{
|
|
||||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
|
||||||
{
|
|
||||||
typeof(ChatOverlay),
|
|
||||||
typeof(ChatLine),
|
|
||||||
typeof(DrawableChannel),
|
|
||||||
typeof(ChannelSelectorTabItem),
|
|
||||||
typeof(ChannelTabControl),
|
|
||||||
typeof(ChannelTabItem),
|
|
||||||
typeof(PrivateChannelTabItem),
|
|
||||||
typeof(TabCloseButton)
|
|
||||||
};
|
|
||||||
|
|
||||||
[Cached]
|
|
||||||
private readonly ChannelManager channelManager = new ChannelManager();
|
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
|
||||||
private void load()
|
|
||||||
{
|
|
||||||
Children = new Drawable[]
|
|
||||||
{
|
|
||||||
channelManager,
|
|
||||||
new ChatOverlay { State = Visibility.Visible }
|
|
||||||
};
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
157
osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs
Normal file
157
osu.Game.Tests/Visual/Online/TestSceneChatOverlay.cs
Normal file
@ -0,0 +1,157 @@
|
|||||||
|
// 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 NUnit.Framework;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Game.Online.Chat;
|
||||||
|
using osu.Game.Overlays;
|
||||||
|
using osu.Game.Overlays.Chat;
|
||||||
|
using osu.Game.Overlays.Chat.Selection;
|
||||||
|
using osu.Game.Overlays.Chat.Tabs;
|
||||||
|
using osu.Game.Users;
|
||||||
|
using osuTK.Input;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
public class TestSceneChatOverlay : ManualInputManagerTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(ChatLine),
|
||||||
|
typeof(DrawableChannel),
|
||||||
|
typeof(ChannelSelectorTabItem),
|
||||||
|
typeof(ChannelTabControl),
|
||||||
|
typeof(ChannelTabItem),
|
||||||
|
typeof(PrivateChannelTabItem),
|
||||||
|
typeof(TabCloseButton)
|
||||||
|
};
|
||||||
|
|
||||||
|
private TestChatOverlay chatOverlay;
|
||||||
|
private ChannelManager channelManager;
|
||||||
|
|
||||||
|
private readonly Channel channel1 = new Channel(new User()) { Name = "test1" };
|
||||||
|
private readonly Channel channel2 = new Channel(new User()) { Name = "test2" };
|
||||||
|
|
||||||
|
[SetUp]
|
||||||
|
public void Setup()
|
||||||
|
{
|
||||||
|
Schedule(() =>
|
||||||
|
{
|
||||||
|
ChannelManagerContainer container;
|
||||||
|
|
||||||
|
Child = container = new ChannelManagerContainer(new List<Channel> { channel1, channel2 })
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
};
|
||||||
|
|
||||||
|
chatOverlay = container.ChatOverlay;
|
||||||
|
channelManager = container.ChannelManager;
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestHideOverlay()
|
||||||
|
{
|
||||||
|
AddAssert("Chat overlay is visible", () => chatOverlay.State.Value == Visibility.Visible);
|
||||||
|
AddAssert("Selector is visible", () => chatOverlay.SelectionOverlayState == Visibility.Visible);
|
||||||
|
|
||||||
|
AddStep("Close chat overlay", () => chatOverlay.Hide());
|
||||||
|
|
||||||
|
AddAssert("Chat overlay was hidden", () => chatOverlay.State.Value == Visibility.Hidden);
|
||||||
|
AddAssert("Channel selection overlay was hidden", () => chatOverlay.SelectionOverlayState == Visibility.Hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSelectingChannelClosesSelector()
|
||||||
|
{
|
||||||
|
AddAssert("Selector is visible", () => chatOverlay.SelectionOverlayState == Visibility.Visible);
|
||||||
|
|
||||||
|
AddStep("Join channel 1", () => channelManager.JoinChannel(channel1));
|
||||||
|
AddStep("Switch to channel 1", () => clickDrawable(chatOverlay.TabMap[channel1]));
|
||||||
|
|
||||||
|
AddAssert("Current channel is channel 1", () => channelManager.CurrentChannel.Value == channel1);
|
||||||
|
AddAssert("Channel selector was closed", () => chatOverlay.SelectionOverlayState == Visibility.Hidden);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCloseChannelWhileSelectorClosed()
|
||||||
|
{
|
||||||
|
AddStep("Join channel 1", () => channelManager.JoinChannel(channel1));
|
||||||
|
AddStep("Join channel 2", () => channelManager.JoinChannel(channel2));
|
||||||
|
|
||||||
|
AddStep("Switch to channel 2", () => clickDrawable(chatOverlay.TabMap[channel2]));
|
||||||
|
AddStep("Close channel 2", () => clickDrawable(((TestChannelTabItem)chatOverlay.TabMap[channel2]).CloseButton.Child));
|
||||||
|
|
||||||
|
AddAssert("Selector remained closed", () => chatOverlay.SelectionOverlayState == Visibility.Hidden);
|
||||||
|
AddAssert("Current channel is channel 1", () => channelManager.CurrentChannel.Value == channel1);
|
||||||
|
|
||||||
|
AddStep("Close channel 1", () => clickDrawable(((TestChannelTabItem)chatOverlay.TabMap[channel1]).CloseButton.Child));
|
||||||
|
|
||||||
|
AddAssert("Selector is visible", () => chatOverlay.SelectionOverlayState == Visibility.Visible);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void clickDrawable(Drawable d)
|
||||||
|
{
|
||||||
|
InputManager.MoveMouseTo(d);
|
||||||
|
InputManager.Click(MouseButton.Left);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ChannelManagerContainer : Container
|
||||||
|
{
|
||||||
|
public TestChatOverlay ChatOverlay { get; private set; }
|
||||||
|
|
||||||
|
[Cached]
|
||||||
|
public ChannelManager ChannelManager { get; } = new ChannelManager();
|
||||||
|
|
||||||
|
private readonly List<Channel> channels;
|
||||||
|
|
||||||
|
public ChannelManagerContainer(List<Channel> channels)
|
||||||
|
{
|
||||||
|
this.channels = channels;
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
((BindableList<Channel>)ChannelManager.AvailableChannels).AddRange(channels);
|
||||||
|
|
||||||
|
Child = ChatOverlay = new TestChatOverlay { RelativeSizeAxes = Axes.Both, };
|
||||||
|
ChatOverlay.Show();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestChatOverlay : ChatOverlay
|
||||||
|
{
|
||||||
|
public Visibility SelectionOverlayState => ChannelSelectionOverlay.State.Value;
|
||||||
|
|
||||||
|
public new ChannelSelectionOverlay ChannelSelectionOverlay => base.ChannelSelectionOverlay;
|
||||||
|
|
||||||
|
protected override ChannelTabControl CreateChannelTabControl() => new TestTabControl();
|
||||||
|
|
||||||
|
public IReadOnlyDictionary<Channel, TabItem<Channel>> TabMap => ((TestTabControl)ChannelTabControl).TabMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestTabControl : ChannelTabControl
|
||||||
|
{
|
||||||
|
protected override TabItem<Channel> CreateTabItem(Channel value) => new TestChannelTabItem(value);
|
||||||
|
|
||||||
|
public new IReadOnlyDictionary<Channel, TabItem<Channel>> TabMap => base.TabMap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestChannelTabItem : PrivateChannelTabItem
|
||||||
|
{
|
||||||
|
public TestChannelTabItem(Channel channel)
|
||||||
|
: base(channel)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public new ClickableContainer CloseButton => base.CloseButton;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
158
osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs
Normal file
158
osu.Game.Tests/Visual/Online/TestSceneDirectDownloadButton.cs
Normal file
@ -0,0 +1,158 @@
|
|||||||
|
// 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.Graphics;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Online;
|
||||||
|
using osu.Game.Overlays.Direct;
|
||||||
|
using osu.Game.Rulesets.Osu;
|
||||||
|
using osu.Game.Tests.Resources;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Online
|
||||||
|
{
|
||||||
|
public class TestSceneDirectDownloadButton : OsuTestScene
|
||||||
|
{
|
||||||
|
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||||
|
{
|
||||||
|
typeof(PanelDownloadButton)
|
||||||
|
};
|
||||||
|
|
||||||
|
private TestDownloadButton downloadButton;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BeatmapManager beatmaps { get; set; }
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDownloadableBeatmap()
|
||||||
|
{
|
||||||
|
createButton(true);
|
||||||
|
assertEnabled(true);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestUndownloadableBeatmap()
|
||||||
|
{
|
||||||
|
createButton(false);
|
||||||
|
assertEnabled(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestDownloadState()
|
||||||
|
{
|
||||||
|
AddUntilStep("ensure manager loaded", () => beatmaps != null);
|
||||||
|
ensureSoleilyRemoved();
|
||||||
|
createButtonWithBeatmap(createSoleily());
|
||||||
|
AddAssert("button state not downloaded", () => downloadButton.DownloadState == DownloadState.NotDownloaded);
|
||||||
|
AddStep("import soleily", () => beatmaps.Import(new[] { TestResources.GetTestBeatmapForImport() }));
|
||||||
|
AddUntilStep("wait for beatmap import", () => beatmaps.GetAllUsableBeatmapSets().Any(b => b.OnlineBeatmapSetID == 241526));
|
||||||
|
createButtonWithBeatmap(createSoleily());
|
||||||
|
AddAssert("button state downloaded", () => downloadButton.DownloadState == DownloadState.LocallyAvailable);
|
||||||
|
ensureSoleilyRemoved();
|
||||||
|
AddAssert("button state not downloaded", () => downloadButton.DownloadState == DownloadState.NotDownloaded);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void ensureSoleilyRemoved()
|
||||||
|
{
|
||||||
|
AddStep("remove soleily", () =>
|
||||||
|
{
|
||||||
|
var beatmap = beatmaps.QueryBeatmapSet(b => b.OnlineBeatmapSetID == 241526);
|
||||||
|
|
||||||
|
if (beatmap != null) beatmaps.Delete(beatmap);
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertEnabled(bool enabled)
|
||||||
|
{
|
||||||
|
AddAssert($"button {(enabled ? "enabled" : "disabled")}", () => downloadButton.DownloadEnabled == enabled);
|
||||||
|
}
|
||||||
|
|
||||||
|
private BeatmapSetInfo createSoleily()
|
||||||
|
{
|
||||||
|
return new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
ID = 1,
|
||||||
|
OnlineBeatmapSetID = 241526,
|
||||||
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
|
{
|
||||||
|
Availability = new BeatmapSetOnlineAvailability
|
||||||
|
{
|
||||||
|
DownloadDisabled = false,
|
||||||
|
ExternalLink = string.Empty,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createButtonWithBeatmap(BeatmapSetInfo beatmap)
|
||||||
|
{
|
||||||
|
AddStep("create button", () =>
|
||||||
|
{
|
||||||
|
Child = downloadButton = new TestDownloadButton(beatmap)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(75, 50),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private void createButton(bool downloadable)
|
||||||
|
{
|
||||||
|
AddStep("create button", () =>
|
||||||
|
{
|
||||||
|
Child = downloadButton = new TestDownloadButton(downloadable ? getDownloadableBeatmapSet() : getUndownloadableBeatmapSet())
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Size = new Vector2(75, 50),
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private BeatmapSetInfo getDownloadableBeatmapSet()
|
||||||
|
{
|
||||||
|
var normal = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo).BeatmapSetInfo;
|
||||||
|
normal.OnlineInfo.HasVideo = true;
|
||||||
|
normal.OnlineInfo.HasStoryboard = true;
|
||||||
|
|
||||||
|
return normal;
|
||||||
|
}
|
||||||
|
|
||||||
|
private BeatmapSetInfo getUndownloadableBeatmapSet()
|
||||||
|
{
|
||||||
|
var beatmap = CreateWorkingBeatmap(new OsuRuleset().RulesetInfo).BeatmapSetInfo;
|
||||||
|
beatmap.Metadata.Artist = "test";
|
||||||
|
beatmap.Metadata.Title = "undownloadable";
|
||||||
|
beatmap.Metadata.AuthorString = "test";
|
||||||
|
|
||||||
|
beatmap.OnlineInfo.HasVideo = true;
|
||||||
|
beatmap.OnlineInfo.HasStoryboard = true;
|
||||||
|
|
||||||
|
beatmap.OnlineInfo.Availability = new BeatmapSetOnlineAvailability
|
||||||
|
{
|
||||||
|
DownloadDisabled = true,
|
||||||
|
ExternalLink = "http://osu.ppy.sh",
|
||||||
|
};
|
||||||
|
|
||||||
|
return beatmap;
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestDownloadButton : PanelDownloadButton
|
||||||
|
{
|
||||||
|
public new bool DownloadEnabled => base.DownloadEnabled;
|
||||||
|
|
||||||
|
public DownloadState DownloadState => State.Value;
|
||||||
|
|
||||||
|
public TestDownloadButton(BeatmapSetInfo beatmapSet, bool noVideo = false)
|
||||||
|
: base(beatmapSet, noVideo)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -6,9 +6,11 @@ using System.Collections.Generic;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Overlays.Direct;
|
using osu.Game.Overlays.Direct;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Users;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Online
|
namespace osu.Game.Tests.Visual.Online
|
||||||
@ -22,13 +24,59 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
typeof(IconPill)
|
typeof(IconPill)
|
||||||
};
|
};
|
||||||
|
|
||||||
|
private BeatmapSetInfo getUndownloadableBeatmapSet(RulesetInfo ruleset) => new BeatmapSetInfo
|
||||||
|
{
|
||||||
|
OnlineBeatmapSetID = 123,
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Title = "undownloadable beatmap",
|
||||||
|
Artist = "test",
|
||||||
|
Source = "more tests",
|
||||||
|
Author = new User
|
||||||
|
{
|
||||||
|
Username = "BanchoBot",
|
||||||
|
Id = 3,
|
||||||
|
},
|
||||||
|
},
|
||||||
|
OnlineInfo = new BeatmapSetOnlineInfo
|
||||||
|
{
|
||||||
|
Availability = new BeatmapSetOnlineAvailability
|
||||||
|
{
|
||||||
|
DownloadDisabled = true,
|
||||||
|
},
|
||||||
|
Preview = @"https://b.ppy.sh/preview/12345.mp3",
|
||||||
|
PlayCount = 123,
|
||||||
|
FavouriteCount = 456,
|
||||||
|
BPM = 111,
|
||||||
|
HasVideo = true,
|
||||||
|
HasStoryboard = true,
|
||||||
|
Covers = new BeatmapSetOnlineCovers(),
|
||||||
|
},
|
||||||
|
Beatmaps = new List<BeatmapInfo>
|
||||||
|
{
|
||||||
|
new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = ruleset,
|
||||||
|
Version = "Test",
|
||||||
|
StarDifficulty = 6.42,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
var beatmap = new TestWorkingBeatmap(new OsuRuleset().RulesetInfo, null);
|
var ruleset = new OsuRuleset().RulesetInfo;
|
||||||
beatmap.BeatmapSetInfo.OnlineInfo.HasVideo = true;
|
|
||||||
beatmap.BeatmapSetInfo.OnlineInfo.HasStoryboard = true;
|
|
||||||
|
|
||||||
|
var normal = CreateWorkingBeatmap(ruleset).BeatmapSetInfo;
|
||||||
|
normal.OnlineInfo.HasVideo = true;
|
||||||
|
normal.OnlineInfo.HasStoryboard = true;
|
||||||
|
|
||||||
|
var undownloadable = getUndownloadableBeatmapSet(ruleset);
|
||||||
|
|
||||||
|
Child = new BasicScrollContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
Child = new FillFlowContainer
|
Child = new FillFlowContainer
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
@ -38,9 +86,12 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Spacing = new Vector2(0, 20),
|
Spacing = new Vector2(0, 20),
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
new DirectGridPanel(beatmap.BeatmapSetInfo),
|
new DirectGridPanel(normal),
|
||||||
new DirectListPanel(beatmap.BeatmapSetInfo)
|
new DirectListPanel(normal),
|
||||||
}
|
new DirectGridPanel(undownloadable),
|
||||||
|
new DirectListPanel(undownloadable),
|
||||||
|
},
|
||||||
|
},
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user