mirror of
https://github.com/ppy/osu.git
synced 2025-01-14 00:42:55 +08:00
Merge branch 'master' into fix-editor-scroll-interruption
This commit is contained in:
commit
04095cd5b9
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Benchmarks" type="DotNetProject" factoryName=".NET Project">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Benchmarks/bin/Release/netcoreapp3.1/osu.Game.Benchmarks.dll" />
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Benchmarks/bin/Release/net5.0/osu.Game.Benchmarks.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="--filter *" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Benchmarks/bin/Release/netcoreapp3.1" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Benchmarks/bin/Release/net5.0" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<option name="PROJECT_TFM" value="net5.0" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="CatchRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Catch.Tests.dll" />
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/net5.0/osu.Game.Rulesets.Catch.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/net5.0" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<option name="PROJECT_TFM" value="net5.0" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="ManiaRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Mania.Tests.dll" />
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/net5.0/osu.Game.Rulesets.Mania.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/net5.0" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<option name="PROJECT_TFM" value="net5.0" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="OsuRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Osu.Tests.dll" />
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/net5.0/osu.Game.Rulesets.Osu.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/net5.0" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<option name="PROJECT_TFM" value="net5.0" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="TaikoRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Taiko.Tests.dll" />
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/net5.0/osu.Game.Rulesets.Taiko.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/net5.0" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<option name="PROJECT_TFM" value="net5.0" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Tournament" type="DotNetProject" factoryName=".NET Project" folderName="Tournament" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll" />
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0/osu!.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="--tournament" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<option name="PROJECT_TFM" value="net5.0" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
</method>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Tournament (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Tournament" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tournament.Tests.dll" />
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/net5.0/osu.Game.Tournament.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/net5.0" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<option name="PROJECT_TFM" value="net5.0" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project" folderName="osu!" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll" />
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0/osu!.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<option name="PROJECT_TFM" value="net5.0" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
</method>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="osu! (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="osu!" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tests.dll" />
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/net5.0/osu.Game.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp3.1" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/net5.0" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<option name="PROJECT_TFM" value="net5.0" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
</method>
|
||||
|
@ -1,8 +1,8 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="osu! (legacy osuTK)" type="DotNetProject" factoryName=".NET Project" folderName="osu!" activateToolWindowBeforeRun="false">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll" />
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0/osu!.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="--tk" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp3.1" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/net5.0" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
@ -12,7 +12,7 @@
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v3.1" />
|
||||
<option name="PROJECT_TFM" value="net5.0" />
|
||||
<method v="2">
|
||||
<option name="Build" />
|
||||
</method>
|
||||
|
18
.vscode/launch.json
vendored
18
.vscode/launch.json
vendored
@ -7,7 +7,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll"
|
||||
"${workspaceRoot}/osu.Desktop/bin/Debug/net5.0/osu!.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build osu! (Debug)",
|
||||
@ -19,7 +19,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1/osu!.dll"
|
||||
"${workspaceRoot}/osu.Desktop/bin/Release/net5.0/osu!.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build osu! (Release)",
|
||||
@ -31,7 +31,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tests.dll"
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/net5.0/osu.Game.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build tests (Debug)",
|
||||
@ -43,7 +43,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp3.1/osu.Game.Tests.dll"
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/net5.0/osu.Game.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build tests (Release)",
|
||||
@ -55,7 +55,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp3.1/osu!.dll",
|
||||
"${workspaceRoot}/osu.Desktop/bin/Debug/net5.0/osu!.dll",
|
||||
"--tournament"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
@ -68,7 +68,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp3.1/osu!.dll",
|
||||
"${workspaceRoot}/osu.Desktop/bin/Release/net5.0/osu!.dll",
|
||||
"--tournament"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
@ -81,7 +81,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tournament.Tests.dll",
|
||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net5.0/osu.Game.Tournament.Tests.dll",
|
||||
"--tournament"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
@ -94,7 +94,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp3.1/osu.Game.Tournament.Tests.dll",
|
||||
"${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/net5.0/osu.Game.Tournament.Tests.dll",
|
||||
"--tournament"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
@ -105,7 +105,7 @@
|
||||
"name": "Benchmark",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "${workspaceRoot}/osu.Game.Benchmarks/bin/Release/netcoreapp3.1/osu.Game.Benchmarks.dll",
|
||||
"program": "${workspaceRoot}/osu.Game.Benchmarks/bin/Release/net5.0/osu.Game.Benchmarks.dll",
|
||||
"args": [
|
||||
"--filter",
|
||||
"*"
|
||||
|
@ -36,8 +36,7 @@ If you are looking to install or test osu! without setting up a development envi
|
||||
|
||||
- The iOS testflight link may fill up (Apple has a hard limit of 10,000 users). We reset it occasionally when this happens. Please do not ask about this. Check back regularly for link resets or follow [peppy](https://twitter.com/ppy) on twitter for announcements of link resets.
|
||||
|
||||
- When running on Windows 7 or 8.1, **[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/install/dependencies?tabs=netcore31&pivots=os-windows)** may be required to correctly run .NET Core applications if your operating system is not up-to-date with the latest service packs.
|
||||
|
||||
- When running on Windows 7 or 8.1, *[additional prerequisites](https://docs.microsoft.com/en-us/dotnet/core/install/windows?tabs=net50&pivots=os-windows#dependencies)** may be required to correctly run .NET 5 applications if your operating system is not up-to-date with the latest service packs.
|
||||
If your platform is not listed above, there is still a chance you can manually build it by following the instructions below.
|
||||
|
||||
## Developing a custom ruleset
|
||||
@ -50,7 +49,7 @@ You can see some examples of custom rulesets by visiting the [custom ruleset dir
|
||||
|
||||
Please make sure you have the following prerequisites:
|
||||
|
||||
- A desktop platform with the [.NET Core 3.1 SDK](https://dotnet.microsoft.com/download) or higher installed.
|
||||
- A desktop platform with the [.NET 5.0 SDK](https://dotnet.microsoft.com/download) or higher installed.
|
||||
- When developing with mobile, [Xamarin](https://docs.microsoft.com/en-us/xamarin/) is required, which is shipped together with Visual Studio or [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/).
|
||||
- When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as [Visual Studio 2019+](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/).
|
||||
- When running on Linux, please have a system-wide FFmpeg installation available to support video decoding.
|
||||
|
@ -1,21 +1,68 @@
|
||||
clone_depth: 1
|
||||
version: '{build}'
|
||||
image: Visual Studio 2019
|
||||
dotnet_csproj:
|
||||
patch: true
|
||||
file: 'osu.Game\osu.Game.csproj' # Use wildcard when it's able to exclude Xamarin projects
|
||||
version: $(APPVEYOR_REPO_TAG_NAME)
|
||||
before_build:
|
||||
- ps: dotnet --info # Useful when version mismatch between CI and local
|
||||
- ps: nuget restore -verbosity quiet # Only nuget.exe knows both new (.NET Core) and old (Xamarin) projects
|
||||
test: off
|
||||
skip_non_tags: true
|
||||
configuration: Release
|
||||
build:
|
||||
project: build\Desktop.proj # Skipping Xamarin Release that's slow and covered by fastlane
|
||||
parallel: true
|
||||
verbosity: minimal
|
||||
publish_nuget: true
|
||||
|
||||
environment:
|
||||
matrix:
|
||||
- job_name: osu-game
|
||||
- job_name: osu-ruleset
|
||||
job_depends_on: osu-game
|
||||
- job_name: taiko-ruleset
|
||||
job_depends_on: osu-game
|
||||
- job_name: catch-ruleset
|
||||
job_depends_on: osu-game
|
||||
- job_name: mania-ruleset
|
||||
job_depends_on: osu-game
|
||||
|
||||
nuget:
|
||||
project_feed: true
|
||||
|
||||
for:
|
||||
-
|
||||
matrix:
|
||||
only:
|
||||
- job_name: osu-game
|
||||
build_script:
|
||||
- cmd: dotnet pack osu.Game\osu.Game.csproj /p:Version=%APPVEYOR_REPO_TAG_NAME%
|
||||
-
|
||||
matrix:
|
||||
only:
|
||||
- job_name: osu-ruleset
|
||||
build_script:
|
||||
- cmd: dotnet remove osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj reference osu.Game\osu.Game.csproj
|
||||
- cmd: dotnet add osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj package ppy.osu.Game -v %APPVEYOR_REPO_TAG_NAME%
|
||||
- cmd: dotnet pack osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj /p:Version=%APPVEYOR_REPO_TAG_NAME%
|
||||
-
|
||||
matrix:
|
||||
only:
|
||||
- job_name: taiko-ruleset
|
||||
build_script:
|
||||
- cmd: dotnet remove osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj reference osu.Game\osu.Game.csproj
|
||||
- cmd: dotnet add osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj package ppy.osu.Game -v %APPVEYOR_REPO_TAG_NAME%
|
||||
- cmd: dotnet pack osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj /p:Version=%APPVEYOR_REPO_TAG_NAME%
|
||||
-
|
||||
matrix:
|
||||
only:
|
||||
- job_name: catch-ruleset
|
||||
build_script:
|
||||
- cmd: dotnet remove osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj reference osu.Game\osu.Game.csproj
|
||||
- cmd: dotnet add osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj package ppy.osu.Game -v %APPVEYOR_REPO_TAG_NAME%
|
||||
- cmd: dotnet pack osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj /p:Version=%APPVEYOR_REPO_TAG_NAME%
|
||||
-
|
||||
matrix:
|
||||
only:
|
||||
- job_name: mania-ruleset
|
||||
build_script:
|
||||
- cmd: dotnet remove osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj reference osu.Game\osu.Game.csproj
|
||||
- cmd: dotnet add osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj package ppy.osu.Game -v %APPVEYOR_REPO_TAG_NAME%
|
||||
- cmd: dotnet pack osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj /p:Version=%APPVEYOR_REPO_TAG_NAME%
|
||||
|
||||
artifacts:
|
||||
- path: '**\*.nupkg'
|
||||
|
||||
deploy:
|
||||
- provider: Environment
|
||||
name: nuget
|
||||
name: nuget
|
@ -48,9 +48,12 @@ desc 'Deploy to play store'
|
||||
|
||||
desc 'Compile the project'
|
||||
lane :build do |options|
|
||||
nuget_restore(
|
||||
project_path: 'osu.sln'
|
||||
)
|
||||
nuget_restore(project_path: 'osu.Android/osu.Android.csproj')
|
||||
nuget_restore(project_path: 'osu.Game/osu.Game.csproj')
|
||||
nuget_restore(project_path: 'osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj')
|
||||
nuget_restore(project_path: 'osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj')
|
||||
nuget_restore(project_path: 'osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj')
|
||||
nuget_restore(project_path: 'osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj')
|
||||
|
||||
souyuz(
|
||||
build_configuration: 'Release',
|
||||
@ -107,9 +110,12 @@ platform :ios do
|
||||
|
||||
desc 'Compile the project'
|
||||
lane :build do
|
||||
nuget_restore(
|
||||
project_path: 'osu.sln'
|
||||
)
|
||||
nuget_restore(project_path: 'osu.iOS/osu.iOS.csproj')
|
||||
nuget_restore(project_path: 'osu.Game/osu.Game.csproj')
|
||||
nuget_restore(project_path: 'osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj')
|
||||
nuget_restore(project_path: 'osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj')
|
||||
nuget_restore(project_path: 'osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj')
|
||||
nuget_restore(project_path: 'osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj')
|
||||
|
||||
souyuz(
|
||||
platform: "ios",
|
||||
|
10
global.json
10
global.json
@ -1,10 +0,0 @@
|
||||
{
|
||||
"sdk": {
|
||||
"allowPrerelease": false,
|
||||
"rollForward": "minor",
|
||||
"version": "3.1.100"
|
||||
},
|
||||
"msbuild-sdks": {
|
||||
"Microsoft.Build.Traversal": "3.0.2"
|
||||
}
|
||||
}
|
@ -52,6 +52,6 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup>
|
||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2020.1202.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.106.0" />
|
||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.118.0" />
|
||||
</ItemGroup>
|
||||
</Project>
|
||||
|
@ -1,6 +1,7 @@
|
||||
// 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.IO;
|
||||
using System.Linq;
|
||||
using System.Threading.Tasks;
|
||||
@ -12,13 +13,14 @@ using Android.OS;
|
||||
using Android.Provider;
|
||||
using Android.Views;
|
||||
using osu.Framework.Android;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Android
|
||||
{
|
||||
[Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.FullUser, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize, HardwareAccelerated = false, LaunchMode = LaunchMode.SingleInstance)]
|
||||
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osz", DataHost = "*", DataMimeType = "*/*")]
|
||||
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osk", DataHost = "*", DataMimeType = "*/*")]
|
||||
[IntentFilter(new[] { Intent.ActionSend }, Categories = new[] { Intent.CategoryDefault }, DataMimeTypes = new[] { "application/zip", "application/octet-stream" })]
|
||||
[IntentFilter(new[] { Intent.ActionSend, Intent.ActionSendMultiple }, Categories = new[] { Intent.CategoryDefault }, DataMimeTypes = new[] { "application/zip", "application/octet-stream" })]
|
||||
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryBrowsable, Intent.CategoryDefault }, DataSchemes = new[] { "osu", "osump" })]
|
||||
public class OsuGameActivity : AndroidGameActivity
|
||||
{
|
||||
@ -54,43 +56,59 @@ namespace osu.Android
|
||||
{
|
||||
case Intent.ActionDefault:
|
||||
if (intent.Scheme == ContentResolver.SchemeContent)
|
||||
handleImportFromUri(intent.Data);
|
||||
handleImportFromUris(intent.Data);
|
||||
else if (osu_url_schemes.Contains(intent.Scheme))
|
||||
game.HandleLink(intent.DataString);
|
||||
break;
|
||||
|
||||
case Intent.ActionSend:
|
||||
case Intent.ActionSendMultiple:
|
||||
{
|
||||
var content = intent.ClipData?.GetItemAt(0);
|
||||
if (content != null)
|
||||
handleImportFromUri(content.Uri);
|
||||
var uris = new List<Uri>();
|
||||
for (int i = 0; i < intent.ClipData?.ItemCount; i++)
|
||||
{
|
||||
var content = intent.ClipData?.GetItemAt(i);
|
||||
if (content != null)
|
||||
uris.Add(content.Uri);
|
||||
}
|
||||
handleImportFromUris(uris.ToArray());
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
private void handleImportFromUri(Uri uri) => Task.Factory.StartNew(async () =>
|
||||
private void handleImportFromUris(params Uri[] uris) => Task.Factory.StartNew(async () =>
|
||||
{
|
||||
// there are more performant overloads of this method, but this one is the most backwards-compatible
|
||||
// (dates back to API 1).
|
||||
var cursor = ContentResolver?.Query(uri, null, null, null, null);
|
||||
var tasks = new List<ImportTask>();
|
||||
|
||||
if (cursor == null)
|
||||
return;
|
||||
await Task.WhenAll(uris.Select(async uri =>
|
||||
{
|
||||
// there are more performant overloads of this method, but this one is the most backwards-compatible
|
||||
// (dates back to API 1).
|
||||
var cursor = ContentResolver?.Query(uri, null, null, null, null);
|
||||
|
||||
cursor.MoveToFirst();
|
||||
if (cursor == null)
|
||||
return;
|
||||
|
||||
var filenameColumn = cursor.GetColumnIndex(OpenableColumns.DisplayName);
|
||||
string filename = cursor.GetString(filenameColumn);
|
||||
cursor.MoveToFirst();
|
||||
|
||||
// SharpCompress requires archive streams to be seekable, which the stream opened by
|
||||
// OpenInputStream() seems to not necessarily be.
|
||||
// copy to an arbitrary-access memory stream to be able to proceed with the import.
|
||||
var copy = new MemoryStream();
|
||||
using (var stream = ContentResolver.OpenInputStream(uri))
|
||||
await stream.CopyToAsync(copy);
|
||||
var filenameColumn = cursor.GetColumnIndex(OpenableColumns.DisplayName);
|
||||
string filename = cursor.GetString(filenameColumn);
|
||||
|
||||
await game.Import(copy, filename);
|
||||
// SharpCompress requires archive streams to be seekable, which the stream opened by
|
||||
// OpenInputStream() seems to not necessarily be.
|
||||
// copy to an arbitrary-access memory stream to be able to proceed with the import.
|
||||
var copy = new MemoryStream();
|
||||
using (var stream = ContentResolver.OpenInputStream(uri))
|
||||
await stream.CopyToAsync(copy);
|
||||
|
||||
lock (tasks)
|
||||
{
|
||||
tasks.Add(new ImportTask(copy, filename));
|
||||
}
|
||||
}));
|
||||
|
||||
await game.Import(tasks.ToArray());
|
||||
}, TaskCreationOptions.LongRunning);
|
||||
}
|
||||
}
|
||||
|
@ -5,6 +5,7 @@ using System;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Reflection;
|
||||
using System.Runtime.Versioning;
|
||||
using System.Threading.Tasks;
|
||||
using Microsoft.Win32;
|
||||
using osu.Desktop.Overlays;
|
||||
@ -56,16 +57,16 @@ namespace osu.Desktop
|
||||
|
||||
string stableInstallPath;
|
||||
|
||||
try
|
||||
if (OperatingSystem.IsWindows())
|
||||
{
|
||||
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu"))
|
||||
stableInstallPath = key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty)?.ToString()?.Split('"')[1].Replace("osu!.exe", "");
|
||||
try
|
||||
{
|
||||
stableInstallPath = getStableInstallPathFromRegistry();
|
||||
|
||||
if (checkExists(stableInstallPath))
|
||||
return stableInstallPath;
|
||||
}
|
||||
catch
|
||||
{
|
||||
if (!string.IsNullOrEmpty(stableInstallPath) && checkExists(stableInstallPath))
|
||||
return stableInstallPath;
|
||||
}
|
||||
catch { }
|
||||
}
|
||||
|
||||
stableInstallPath = Path.Combine(Environment.GetFolderPath(Environment.SpecialFolder.LocalApplicationData), @"osu!");
|
||||
@ -79,6 +80,13 @@ namespace osu.Desktop
|
||||
return null;
|
||||
}
|
||||
|
||||
[SupportedOSPlatform("windows")]
|
||||
private string getStableInstallPathFromRegistry()
|
||||
{
|
||||
using (RegistryKey key = Registry.ClassesRoot.OpenSubKey("osu"))
|
||||
return key?.OpenSubKey(@"shell\open\command")?.GetValue(string.Empty)?.ToString()?.Split('"')[1].Replace("osu!.exe", "");
|
||||
}
|
||||
|
||||
protected override UpdateManager CreateUpdateManager()
|
||||
{
|
||||
switch (RuntimeInfo.OS)
|
||||
|
@ -1,6 +1,6 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
<PropertyGroup Label="Project">
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<OutputType>WinExe</OutputType>
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Description>A free-to-win rhythm game. Rhythm is just a *click* away!</Description>
|
||||
|
@ -1,7 +1,7 @@
|
||||
<Project Sdk="Microsoft.NET.Sdk">
|
||||
|
||||
<PropertyGroup>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
<OutputType>Exe</OutputType>
|
||||
<IsPackable>false</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
@ -7,7 +7,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Catch.Tests.dll"
|
||||
"${workspaceRoot}/bin/Debug/net5.0/osu.Game.Rulesets.Catch.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Debug)",
|
||||
@ -20,7 +20,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Release/netcoreapp3.1/osu.Game.Rulesets.Catch.Tests.dll"
|
||||
"${workspaceRoot}/bin/Release/net5.0/osu.Game.Rulesets.Catch.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release)",
|
||||
|
151
osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs
Normal file
151
osu.Game.Rulesets.Catch.Tests/TestSceneLegacyBeatmapSkin.cs
Normal file
@ -0,0 +1,151 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Catch.Skinning;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
public class TestSceneLegacyBeatmapSkin : LegacyBeatmapSkinColourTest
|
||||
{
|
||||
[Resolved]
|
||||
private AudioManager audio { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager config)
|
||||
{
|
||||
config.BindWith(OsuSetting.BeatmapSkins, BeatmapSkins);
|
||||
config.BindWith(OsuSetting.BeatmapColours, BeatmapColours);
|
||||
}
|
||||
|
||||
[TestCase(true, true)]
|
||||
[TestCase(true, false)]
|
||||
[TestCase(false, true)]
|
||||
[TestCase(false, false)]
|
||||
public override void TestBeatmapComboColours(bool userHasCustomColours, bool useBeatmapSkin)
|
||||
{
|
||||
TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true);
|
||||
base.TestBeatmapComboColours(userHasCustomColours, useBeatmapSkin);
|
||||
AddAssert("is beatmap skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestBeatmapSkin.Colours));
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public override void TestBeatmapComboColoursOverride(bool useBeatmapSkin)
|
||||
{
|
||||
TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true);
|
||||
base.TestBeatmapComboColoursOverride(useBeatmapSkin);
|
||||
AddAssert("is user custom skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestSkin.Colours));
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public override void TestBeatmapComboColoursOverrideWithDefaultColours(bool useBeatmapSkin)
|
||||
{
|
||||
TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true);
|
||||
base.TestBeatmapComboColoursOverrideWithDefaultColours(useBeatmapSkin);
|
||||
AddAssert("is default user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours));
|
||||
}
|
||||
|
||||
[TestCase(true, true)]
|
||||
[TestCase(false, true)]
|
||||
[TestCase(true, false)]
|
||||
[TestCase(false, false)]
|
||||
public override void TestBeatmapNoComboColours(bool useBeatmapSkin, bool useBeatmapColour)
|
||||
{
|
||||
TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, false);
|
||||
base.TestBeatmapNoComboColours(useBeatmapSkin, useBeatmapColour);
|
||||
AddAssert("is default user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours));
|
||||
}
|
||||
|
||||
[TestCase(true, true)]
|
||||
[TestCase(false, true)]
|
||||
[TestCase(true, false)]
|
||||
[TestCase(false, false)]
|
||||
public override void TestBeatmapNoComboColoursSkinOverride(bool useBeatmapSkin, bool useBeatmapColour)
|
||||
{
|
||||
TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, false);
|
||||
base.TestBeatmapNoComboColoursSkinOverride(useBeatmapSkin, useBeatmapColour);
|
||||
AddAssert("is custom user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestSkin.Colours));
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void TestBeatmapHyperDashColours(bool useBeatmapSkin)
|
||||
{
|
||||
TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true);
|
||||
ConfigureTest(useBeatmapSkin, true, true);
|
||||
AddAssert("is custom hyper dash colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashColour == TestBeatmapSkin.HYPER_DASH_COLOUR);
|
||||
AddAssert("is custom hyper dash after image colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashAfterImageColour == TestBeatmapSkin.HYPER_DASH_AFTER_IMAGE_COLOUR);
|
||||
AddAssert("is custom hyper dash fruit colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashFruitColour == TestBeatmapSkin.HYPER_DASH_FRUIT_COLOUR);
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void TestBeatmapHyperDashColoursOverride(bool useBeatmapSkin)
|
||||
{
|
||||
TestBeatmap = new CatchCustomSkinWorkingBeatmap(audio, true);
|
||||
ConfigureTest(useBeatmapSkin, false, true);
|
||||
AddAssert("is custom hyper dash colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashColour == TestSkin.HYPER_DASH_COLOUR);
|
||||
AddAssert("is custom hyper dash after image colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashAfterImageColour == TestSkin.HYPER_DASH_AFTER_IMAGE_COLOUR);
|
||||
AddAssert("is custom hyper dash fruit colours", () => ((CatchExposedPlayer)TestPlayer).UsableHyperDashFruitColour == TestSkin.HYPER_DASH_FRUIT_COLOUR);
|
||||
}
|
||||
|
||||
protected override ExposedPlayer CreateTestPlayer(bool userHasCustomColours) => new CatchExposedPlayer(userHasCustomColours);
|
||||
|
||||
private class CatchExposedPlayer : ExposedPlayer
|
||||
{
|
||||
public CatchExposedPlayer(bool userHasCustomColours)
|
||||
: base(userHasCustomColours)
|
||||
{
|
||||
}
|
||||
|
||||
public Color4 UsableHyperDashColour =>
|
||||
GameplayClockContainer.ChildrenOfType<BeatmapSkinProvidingContainer>()
|
||||
.First()
|
||||
.GetConfig<SkinCustomColourLookup, Color4>(new SkinCustomColourLookup(CatchSkinColour.HyperDash))?
|
||||
.Value ?? Color4.Red;
|
||||
|
||||
public Color4 UsableHyperDashAfterImageColour =>
|
||||
GameplayClockContainer.ChildrenOfType<BeatmapSkinProvidingContainer>()
|
||||
.First()
|
||||
.GetConfig<SkinCustomColourLookup, Color4>(new SkinCustomColourLookup(CatchSkinColour.HyperDashAfterImage))?
|
||||
.Value ?? Color4.Red;
|
||||
|
||||
public Color4 UsableHyperDashFruitColour =>
|
||||
GameplayClockContainer.ChildrenOfType<BeatmapSkinProvidingContainer>()
|
||||
.First()
|
||||
.GetConfig<SkinCustomColourLookup, Color4>(new SkinCustomColourLookup(CatchSkinColour.HyperDashFruit))?
|
||||
.Value ?? Color4.Red;
|
||||
}
|
||||
|
||||
private class CatchCustomSkinWorkingBeatmap : CustomSkinWorkingBeatmap
|
||||
{
|
||||
public CatchCustomSkinWorkingBeatmap(AudioManager audio, bool hasColours)
|
||||
: base(createBeatmap(), audio, hasColours)
|
||||
{
|
||||
}
|
||||
|
||||
private static IBeatmap createBeatmap() =>
|
||||
new Beatmap
|
||||
{
|
||||
BeatmapInfo =
|
||||
{
|
||||
BeatmapSet = new BeatmapSetInfo(),
|
||||
Ruleset = new CatchRuleset().RulesetInfo
|
||||
},
|
||||
HitObjects = { new Fruit { StartTime = 1816, X = 56, NewCombo = true } }
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -9,7 +9,7 @@
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||
|
@ -5,6 +5,13 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Description>catch the fruit. to the beat.</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Nuget">
|
||||
<Title>osu!catch (ruleset)</Title>
|
||||
<PackageId>ppy.osu.Game.Rulesets.Catch</PackageId>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
||||
</ItemGroup>
|
||||
|
@ -7,7 +7,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Mania.Tests.dll"
|
||||
"${workspaceRoot}/bin/Debug/net5.0/osu.Game.Rulesets.Mania.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Debug)",
|
||||
@ -20,7 +20,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Release/netcoreapp3.1/osu.Game.Rulesets.Mania.Tests.dll"
|
||||
"${workspaceRoot}/bin/Release/net5.0/osu.Game.Rulesets.Mania.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release)",
|
||||
|
@ -9,7 +9,7 @@
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
||||
|
@ -5,6 +5,13 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Description>smash the keys. to the beat.</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Nuget">
|
||||
<Title>osu!mania (ruleset)</Title>
|
||||
<PackageId>ppy.osu.Game.Rulesets.Mania</PackageId>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
||||
</ItemGroup>
|
||||
|
@ -7,7 +7,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Osu.Tests.dll"
|
||||
"${workspaceRoot}/bin/Debug/net5.0/osu.Game.Rulesets.Osu.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Debug)",
|
||||
@ -20,7 +20,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Release/netcoreapp3.1/osu.Game.Rulesets.Osu.Tests.dll"
|
||||
"${workspaceRoot}/bin/Release/net5.0/osu.Game.Rulesets.Osu.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release)",
|
||||
|
@ -1,107 +1,91 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.IO.Stores;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Rulesets.Osu.Objects;
|
||||
using osu.Game.Screens.Play;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Game.Tests.Visual;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Rulesets.Osu.Tests
|
||||
{
|
||||
public class TestSceneLegacyBeatmapSkin : ScreenTestScene
|
||||
public class TestSceneLegacyBeatmapSkin : LegacyBeatmapSkinColourTest
|
||||
{
|
||||
[Resolved]
|
||||
private AudioManager audio { get; set; }
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OsuConfigManager config)
|
||||
{
|
||||
config.BindWith(OsuSetting.BeatmapSkins, BeatmapSkins);
|
||||
config.BindWith(OsuSetting.BeatmapColours, BeatmapColours);
|
||||
}
|
||||
|
||||
[TestCase(true, true)]
|
||||
[TestCase(true, false)]
|
||||
[TestCase(false, true)]
|
||||
[TestCase(false, false)]
|
||||
public override void TestBeatmapComboColours(bool userHasCustomColours, bool useBeatmapSkin)
|
||||
{
|
||||
TestBeatmap = new OsuCustomSkinWorkingBeatmap(audio, true);
|
||||
base.TestBeatmapComboColours(userHasCustomColours, useBeatmapSkin);
|
||||
AddAssert("is beatmap skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestBeatmapSkin.Colours));
|
||||
}
|
||||
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public void TestBeatmapComboColours(bool customSkinColoursPresent)
|
||||
public override void TestBeatmapComboColoursOverride(bool useBeatmapSkin)
|
||||
{
|
||||
ExposedPlayer player = null;
|
||||
|
||||
AddStep("load coloured beatmap", () => player = loadBeatmap(customSkinColoursPresent, true));
|
||||
AddUntilStep("wait for player", () => player.IsLoaded);
|
||||
|
||||
AddAssert("is beatmap skin colours", () => player.UsableComboColours.SequenceEqual(TestBeatmapSkin.Colours));
|
||||
TestBeatmap = new OsuCustomSkinWorkingBeatmap(audio, true);
|
||||
base.TestBeatmapComboColoursOverride(useBeatmapSkin);
|
||||
AddAssert("is user custom skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestSkin.Colours));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBeatmapNoComboColours()
|
||||
[TestCase(true)]
|
||||
[TestCase(false)]
|
||||
public override void TestBeatmapComboColoursOverrideWithDefaultColours(bool useBeatmapSkin)
|
||||
{
|
||||
ExposedPlayer player = null;
|
||||
|
||||
AddStep("load no-colour beatmap", () => player = loadBeatmap(false, false));
|
||||
AddUntilStep("wait for player", () => player.IsLoaded);
|
||||
|
||||
AddAssert("is default user skin colours", () => player.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours));
|
||||
TestBeatmap = new OsuCustomSkinWorkingBeatmap(audio, true);
|
||||
base.TestBeatmapComboColoursOverrideWithDefaultColours(useBeatmapSkin);
|
||||
AddAssert("is default user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBeatmapNoComboColoursSkinOverride()
|
||||
[TestCase(true, true)]
|
||||
[TestCase(false, true)]
|
||||
[TestCase(true, false)]
|
||||
[TestCase(false, false)]
|
||||
public override void TestBeatmapNoComboColours(bool useBeatmapSkin, bool useBeatmapColour)
|
||||
{
|
||||
ExposedPlayer player = null;
|
||||
|
||||
AddStep("load custom-skin colour", () => player = loadBeatmap(true, false));
|
||||
AddUntilStep("wait for player", () => player.IsLoaded);
|
||||
|
||||
AddAssert("is custom user skin colours", () => player.UsableComboColours.SequenceEqual(TestSkin.Colours));
|
||||
TestBeatmap = new OsuCustomSkinWorkingBeatmap(audio, false);
|
||||
base.TestBeatmapNoComboColours(useBeatmapSkin, useBeatmapColour);
|
||||
AddAssert("is default user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(SkinConfiguration.DefaultComboColours));
|
||||
}
|
||||
|
||||
private ExposedPlayer loadBeatmap(bool userHasCustomColours, bool beatmapHasColours)
|
||||
[TestCase(true, true)]
|
||||
[TestCase(false, true)]
|
||||
[TestCase(true, false)]
|
||||
[TestCase(false, false)]
|
||||
public override void TestBeatmapNoComboColoursSkinOverride(bool useBeatmapSkin, bool useBeatmapColour)
|
||||
{
|
||||
ExposedPlayer player;
|
||||
|
||||
Beatmap.Value = new CustomSkinWorkingBeatmap(audio, beatmapHasColours);
|
||||
|
||||
LoadScreen(player = new ExposedPlayer(userHasCustomColours));
|
||||
|
||||
return player;
|
||||
TestBeatmap = new OsuCustomSkinWorkingBeatmap(audio, false);
|
||||
base.TestBeatmapNoComboColoursSkinOverride(useBeatmapSkin, useBeatmapColour);
|
||||
AddAssert("is custom user skin colours", () => TestPlayer.UsableComboColours.SequenceEqual(TestSkin.Colours));
|
||||
}
|
||||
|
||||
private class ExposedPlayer : Player
|
||||
private class OsuCustomSkinWorkingBeatmap : CustomSkinWorkingBeatmap
|
||||
{
|
||||
private readonly bool userHasCustomColours;
|
||||
|
||||
public ExposedPlayer(bool userHasCustomColours)
|
||||
: base(new PlayerConfiguration
|
||||
{
|
||||
AllowPause = false,
|
||||
ShowResults = false,
|
||||
})
|
||||
public OsuCustomSkinWorkingBeatmap(AudioManager audio, bool hasColours)
|
||||
: base(createBeatmap(), audio, hasColours)
|
||||
{
|
||||
this.userHasCustomColours = userHasCustomColours;
|
||||
}
|
||||
|
||||
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
|
||||
{
|
||||
var dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
|
||||
dependencies.CacheAs<ISkinSource>(new TestSkin(userHasCustomColours));
|
||||
return dependencies;
|
||||
}
|
||||
|
||||
public IReadOnlyList<Color4> UsableComboColours =>
|
||||
GameplayClockContainer.ChildrenOfType<BeatmapSkinProvidingContainer>()
|
||||
.First()
|
||||
.GetConfig<GlobalSkinColours, IReadOnlyList<Color4>>(GlobalSkinColours.ComboColours)?.Value;
|
||||
}
|
||||
|
||||
private class CustomSkinWorkingBeatmap : ClockBackedTestWorkingBeatmap
|
||||
{
|
||||
private readonly bool hasColours;
|
||||
|
||||
public CustomSkinWorkingBeatmap(AudioManager audio, bool hasColours)
|
||||
: base(new Beatmap
|
||||
private static IBeatmap createBeatmap() =>
|
||||
new Beatmap
|
||||
{
|
||||
BeatmapInfo =
|
||||
{
|
||||
@ -109,50 +93,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
Ruleset = new OsuRuleset().RulesetInfo,
|
||||
},
|
||||
HitObjects = { new HitCircle { Position = new Vector2(256, 192) } }
|
||||
}, null, null, audio)
|
||||
{
|
||||
this.hasColours = hasColours;
|
||||
}
|
||||
|
||||
protected override ISkin GetSkin() => new TestBeatmapSkin(BeatmapInfo, hasColours);
|
||||
}
|
||||
|
||||
private class TestBeatmapSkin : LegacyBeatmapSkin
|
||||
{
|
||||
public static Color4[] Colours { get; } =
|
||||
{
|
||||
new Color4(50, 100, 150, 255),
|
||||
new Color4(40, 80, 120, 255),
|
||||
};
|
||||
|
||||
public TestBeatmapSkin(BeatmapInfo beatmap, bool hasColours)
|
||||
: base(beatmap, new ResourceStore<byte[]>(), null)
|
||||
{
|
||||
if (hasColours)
|
||||
Configuration.AddComboColours(Colours);
|
||||
}
|
||||
}
|
||||
|
||||
private class TestSkin : LegacySkin, ISkinSource
|
||||
{
|
||||
public static Color4[] Colours { get; } =
|
||||
{
|
||||
new Color4(150, 100, 50, 255),
|
||||
new Color4(20, 20, 20, 255),
|
||||
};
|
||||
|
||||
public TestSkin(bool hasCustomColours)
|
||||
: base(new SkinInfo(), null, null, string.Empty)
|
||||
{
|
||||
if (hasCustomColours)
|
||||
Configuration.AddComboColours(Colours);
|
||||
}
|
||||
|
||||
public event Action SourceChanged
|
||||
{
|
||||
add { }
|
||||
remove { }
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -52,6 +52,31 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
checkNextHitObject(null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestBeatmapColourDefault()
|
||||
{
|
||||
AddStep("enable user provider", () => testUserSkin.Enabled = true);
|
||||
|
||||
AddStep("enable beatmap skin", () => LocalConfig.Set<bool>(OsuSetting.BeatmapSkins, true));
|
||||
AddStep("enable beatmap colours", () => LocalConfig.Set<bool>(OsuSetting.BeatmapColours, true));
|
||||
checkNextHitObject("beatmap");
|
||||
|
||||
AddStep("enable beatmap skin", () => LocalConfig.Set<bool>(OsuSetting.BeatmapSkins, true));
|
||||
AddStep("disable beatmap colours", () => LocalConfig.Set<bool>(OsuSetting.BeatmapColours, false));
|
||||
checkNextHitObject("beatmap");
|
||||
|
||||
AddStep("disable beatmap skin", () => LocalConfig.Set<bool>(OsuSetting.BeatmapSkins, false));
|
||||
AddStep("enable beatmap colours", () => LocalConfig.Set<bool>(OsuSetting.BeatmapColours, true));
|
||||
checkNextHitObject("user");
|
||||
|
||||
AddStep("disable beatmap skin", () => LocalConfig.Set<bool>(OsuSetting.BeatmapSkins, false));
|
||||
AddStep("disable beatmap colours", () => LocalConfig.Set<bool>(OsuSetting.BeatmapColours, false));
|
||||
checkNextHitObject("user");
|
||||
|
||||
AddStep("disable user provider", () => testUserSkin.Enabled = false);
|
||||
checkNextHitObject(null);
|
||||
}
|
||||
|
||||
private void checkNextHitObject(string skin) =>
|
||||
AddUntilStep($"check skin from {skin}", () =>
|
||||
{
|
||||
|
@ -1,9 +1,11 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Audio;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Beatmaps.ControlPoints;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
@ -34,7 +36,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
[TestCase(true)]
|
||||
public void TestLongSpinner(bool autoplay)
|
||||
{
|
||||
AddStep("Very short spinner", () => SetContents(() => testSingle(5, autoplay, 2000)));
|
||||
AddStep("Very long spinner", () => SetContents(() => testSingle(5, autoplay, 4000)));
|
||||
AddUntilStep("Wait for completion", () => drawableSpinner.Result.HasResult);
|
||||
AddUntilStep("Check correct progress", () => drawableSpinner.Progress == (autoplay ? 1 : 0));
|
||||
}
|
||||
@ -55,7 +57,11 @@ namespace osu.Game.Rulesets.Osu.Tests
|
||||
var spinner = new Spinner
|
||||
{
|
||||
StartTime = Time.Current + delay,
|
||||
EndTime = Time.Current + delay + length
|
||||
EndTime = Time.Current + delay + length,
|
||||
Samples = new List<HitSampleInfo>
|
||||
{
|
||||
new HitSampleInfo("hitnormal")
|
||||
}
|
||||
};
|
||||
|
||||
spinner.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = circleSize });
|
||||
|
@ -9,7 +9,7 @@
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||
|
@ -30,6 +30,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles
|
||||
|
||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => DrawableObject.HitArea.ReceivePositionalInputAt(screenSpacePos);
|
||||
|
||||
public override Quad SelectionQuad => DrawableObject.HitArea.ScreenSpaceDrawQuad;
|
||||
public override Quad SelectionQuad => CirclePiece.ScreenSpaceDrawQuad;
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
|
||||
[Resolved(CanBeNull = true)]
|
||||
private IEditorChangeHandler changeHandler { get; set; }
|
||||
|
||||
public override Quad SelectionQuad => BodyPiece.ScreenSpaceDrawQuad;
|
||||
|
||||
private readonly BindableList<PathControlPoint> controlPoints = new BindableList<PathControlPoint>();
|
||||
private readonly IBindable<int> pathVersion = new Bindable<int>();
|
||||
|
||||
|
@ -236,7 +236,20 @@ namespace osu.Game.Rulesets.Osu.Edit
|
||||
/// </summary>
|
||||
/// <param name="hitObjects">The hit objects to calculate a quad for.</param>
|
||||
private Quad getSurroundingQuad(OsuHitObject[] hitObjects) =>
|
||||
getSurroundingQuad(hitObjects.SelectMany(h => new[] { h.Position, h.EndPosition }));
|
||||
getSurroundingQuad(hitObjects.SelectMany(h =>
|
||||
{
|
||||
if (h is IHasPath path)
|
||||
{
|
||||
return new[]
|
||||
{
|
||||
h.Position,
|
||||
// can't use EndPosition for reverse slider cases.
|
||||
h.Position + path.Path.PositionAt(1)
|
||||
};
|
||||
}
|
||||
|
||||
return new[] { h.Position };
|
||||
}));
|
||||
|
||||
/// <summary>
|
||||
/// Returns a gamefield-space quad surrounding the provided points.
|
||||
|
@ -130,12 +130,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
|
||||
{
|
||||
if (tracking.NewValue)
|
||||
{
|
||||
spinningSample?.Play();
|
||||
spinningSample?.VolumeTo(1, 200);
|
||||
spinningSample?.Play(!spinningSample.IsPlaying);
|
||||
spinningSample?.VolumeTo(1, 300);
|
||||
}
|
||||
else
|
||||
{
|
||||
spinningSample?.VolumeTo(0, 200).Finally(_ => spinningSample.Stop());
|
||||
spinningSample?.VolumeTo(0, 300).OnComplete(_ => spinningSample.Stop());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -5,6 +5,13 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Description>click the circles. to the beat.</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Nuget">
|
||||
<Title>osu! (ruleset)</Title>
|
||||
<PackageId>ppy.osu.Game.Rulesets.Osu</PackageId>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
||||
</ItemGroup>
|
||||
|
@ -7,7 +7,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp3.1/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||
"${workspaceRoot}/bin/Debug/net5.0/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Debug)",
|
||||
@ -20,7 +20,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Release/netcoreapp3.1/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||
"${workspaceRoot}/bin/Release/net5.0/osu.Game.Rulesets.Taiko.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release)",
|
||||
|
@ -9,7 +9,7 @@
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
|
||||
|
@ -5,6 +5,13 @@
|
||||
<AllowUnsafeBlocks>true</AllowUnsafeBlocks>
|
||||
<Description>bash the drum. to the beat.</Description>
|
||||
</PropertyGroup>
|
||||
|
||||
<PropertyGroup Label="Nuget">
|
||||
<Title>osu!taiko (ruleset)</Title>
|
||||
<PackageId>ppy.osu.Game.Rulesets.Taiko</PackageId>
|
||||
<IsPackable>true</IsPackable>
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
||||
</ItemGroup>
|
||||
|
@ -9,7 +9,6 @@ using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
|
@ -5,7 +5,7 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Configuration.Tracking;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
using osu.Framework.IO.Stores;
|
||||
|
@ -17,10 +17,12 @@ using osu.Framework.Utils;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Difficulty;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Game.Rulesets.Objects.Legacy;
|
||||
using osu.Game.Rulesets.Objects.Types;
|
||||
using osu.Game.Rulesets.UI;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
@ -129,6 +131,31 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
AddUntilStep("no DHOs shown", () => !this.ChildrenOfType<DrawableTestHitObject>().Any());
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestApplyHitResultOnKilled()
|
||||
{
|
||||
ManualClock clock = null;
|
||||
bool anyJudged = false;
|
||||
|
||||
void onNewResult(JudgementResult _) => anyJudged = true;
|
||||
|
||||
var beatmap = new Beatmap();
|
||||
beatmap.HitObjects.Add(new TestKilledHitObject { Duration = 20 });
|
||||
|
||||
createTest(beatmap, 10, () => new FramedClock(clock = new ManualClock()));
|
||||
|
||||
AddStep("subscribe to new result", () =>
|
||||
{
|
||||
anyJudged = false;
|
||||
drawableRuleset.NewResult += onNewResult;
|
||||
});
|
||||
AddStep("skip past object", () => clock.CurrentTime = beatmap.HitObjects[0].GetEndTime() + 1000);
|
||||
|
||||
AddAssert("object judged", () => anyJudged);
|
||||
|
||||
AddStep("clean up", () => drawableRuleset.NewResult -= onNewResult);
|
||||
}
|
||||
|
||||
private void createTest(IBeatmap beatmap, int poolSize, Func<IFrameBasedClock> createClock = null) => AddStep("create test", () =>
|
||||
{
|
||||
var ruleset = new TestPoolingRuleset();
|
||||
@ -192,6 +219,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
private void load()
|
||||
{
|
||||
RegisterPool<TestHitObject, DrawableTestHitObject>(poolSize);
|
||||
RegisterPool<TestKilledHitObject, DrawableTestKilledHitObject>(poolSize);
|
||||
}
|
||||
|
||||
protected override HitObjectLifetimeEntry CreateLifetimeEntry(HitObject hitObject) => new TestHitObjectLifetimeEntry(hitObject);
|
||||
@ -220,19 +248,30 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
protected override IEnumerable<TestHitObject> ConvertHitObject(HitObject original, IBeatmap beatmap, CancellationToken cancellationToken)
|
||||
{
|
||||
yield return new TestHitObject
|
||||
switch (original)
|
||||
{
|
||||
StartTime = original.StartTime,
|
||||
Duration = 250
|
||||
};
|
||||
case TestKilledHitObject h:
|
||||
yield return h;
|
||||
|
||||
break;
|
||||
|
||||
default:
|
||||
yield return new TestHitObject
|
||||
{
|
||||
StartTime = original.StartTime,
|
||||
Duration = 250
|
||||
};
|
||||
|
||||
break;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
|
||||
#region HitObject
|
||||
#region HitObjects
|
||||
|
||||
private class TestHitObject : ConvertHitObject
|
||||
private class TestHitObject : ConvertHitObject, IHasDuration
|
||||
{
|
||||
public double EndTime => StartTime + Duration;
|
||||
|
||||
@ -287,6 +326,30 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
}
|
||||
}
|
||||
|
||||
private class TestKilledHitObject : TestHitObject
|
||||
{
|
||||
}
|
||||
|
||||
private class DrawableTestKilledHitObject : DrawableHitObject<TestKilledHitObject>
|
||||
{
|
||||
public DrawableTestKilledHitObject()
|
||||
: base(null)
|
||||
{
|
||||
}
|
||||
|
||||
protected override void UpdateHitStateTransforms(ArmedState state)
|
||||
{
|
||||
base.UpdateHitStateTransforms(state);
|
||||
Expire();
|
||||
}
|
||||
|
||||
public override void OnKilled()
|
||||
{
|
||||
base.OnKilled();
|
||||
ApplyResult(r => r.Type = r.Judgement.MinResult);
|
||||
}
|
||||
}
|
||||
|
||||
#endregion
|
||||
}
|
||||
}
|
||||
|
@ -244,7 +244,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
internal class TestKeyBindingContainer : KeyBindingContainer<TestAction>
|
||||
{
|
||||
public override IEnumerable<KeyBinding> DefaultKeyBindings => new[]
|
||||
public override IEnumerable<IKeyBinding> DefaultKeyBindings => new[]
|
||||
{
|
||||
new KeyBinding(InputKey.MouseLeft, TestAction.Down),
|
||||
};
|
||||
|
@ -179,7 +179,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
internal class TestKeyBindingContainer : KeyBindingContainer<TestAction>
|
||||
{
|
||||
public override IEnumerable<KeyBinding> DefaultKeyBindings => new[]
|
||||
public override IEnumerable<IKeyBinding> DefaultKeyBindings => new[]
|
||||
{
|
||||
new KeyBinding(InputKey.MouseLeft, TestAction.Down),
|
||||
};
|
||||
|
@ -4,6 +4,7 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.Specialized;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
@ -74,6 +75,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
switch (args.Action)
|
||||
{
|
||||
case NotifyCollectionChangedAction.Add:
|
||||
Debug.Assert(args.NewItems != null);
|
||||
|
||||
foreach (int user in args.NewItems)
|
||||
{
|
||||
if (user == api.LocalUser.Value.Id)
|
||||
@ -83,6 +86,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
break;
|
||||
|
||||
case NotifyCollectionChangedAction.Remove:
|
||||
Debug.Assert(args.OldItems != null);
|
||||
|
||||
foreach (int user in args.OldItems)
|
||||
{
|
||||
if (user == api.LocalUser.Value.Id)
|
||||
@ -298,7 +303,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
||||
|
||||
internal class TestKeyBindingContainer : KeyBindingContainer<TestAction>
|
||||
{
|
||||
public override IEnumerable<KeyBinding> DefaultKeyBindings => new[]
|
||||
public override IEnumerable<IKeyBinding> DefaultKeyBindings => new[]
|
||||
{
|
||||
new KeyBinding(InputKey.MouseLeft, TestAction.Down),
|
||||
};
|
||||
|
@ -201,11 +201,20 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestDownloadButtonHiddenInitiallyWhenBeatmapExists()
|
||||
public void TestDownloadButtonHiddenWhenBeatmapExists()
|
||||
{
|
||||
createPlaylist(new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo);
|
||||
|
||||
AddAssert("download button hidden", () => !playlist.ChildrenOfType<BeatmapDownloadTrackingComposite>().Single().IsPresent);
|
||||
assertDownloadButtonVisible(false);
|
||||
|
||||
AddStep("delete beatmap set", () => manager.Delete(manager.QueryBeatmapSets(_ => true).Single()));
|
||||
assertDownloadButtonVisible(true);
|
||||
|
||||
AddStep("undelete beatmap set", () => manager.Undelete(manager.QueryBeatmapSets(_ => true).Single()));
|
||||
assertDownloadButtonVisible(false);
|
||||
|
||||
void assertDownloadButtonVisible(bool visible) => AddUntilStep($"download button {(visible ? "shown" : "hidden")}",
|
||||
() => playlist.ChildrenOfType<BeatmapDownloadTrackingComposite>().Single().Alpha == (visible ? 1 : 0));
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -222,6 +231,15 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
||||
AddAssert("download buttons shown", () => playlist.ChildrenOfType<BeatmapDownloadTrackingComposite>().All(d => d.IsPresent));
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestExplicitBeatmapItem()
|
||||
{
|
||||
var beatmap = new TestBeatmap(new OsuRuleset().RulesetInfo).BeatmapInfo;
|
||||
beatmap.BeatmapSet.OnlineInfo.HasExplicitContent = true;
|
||||
|
||||
createPlaylist(beatmap);
|
||||
}
|
||||
|
||||
private void moveToItem(int index, Vector2? offset = null)
|
||||
=> AddStep($"move mouse to item {index}", () => InputManager.MoveMouseTo(playlist.ChildrenOfType<OsuRearrangeableListItem<PlaylistItem>>().ElementAt(index), offset));
|
||||
|
||||
|
@ -231,8 +231,19 @@ namespace osu.Game.Tests.Visual.Online
|
||||
});
|
||||
});
|
||||
|
||||
AddAssert("shown beatmaps of current ruleset", () => overlay.Header.Picker.Difficulties.All(b => b.Beatmap.Ruleset.Equals(overlay.Header.RulesetSelector.Current.Value)));
|
||||
AddAssert("left-most beatmap selected", () => overlay.Header.Picker.Difficulties.First().State == BeatmapPicker.DifficultySelectorState.Selected);
|
||||
AddAssert("shown beatmaps of current ruleset", () => overlay.Header.HeaderContent.Picker.Difficulties.All(b => b.Beatmap.Ruleset.Equals(overlay.Header.RulesetSelector.Current.Value)));
|
||||
AddAssert("left-most beatmap selected", () => overlay.Header.HeaderContent.Picker.Difficulties.First().State == BeatmapPicker.DifficultySelectorState.Selected);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestExplicitBeatmap()
|
||||
{
|
||||
AddStep("show explicit map", () =>
|
||||
{
|
||||
var beatmapSet = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet;
|
||||
beatmapSet.OnlineInfo.HasExplicitContent = true;
|
||||
overlay.ShowBeatmapSet(beatmapSet);
|
||||
});
|
||||
}
|
||||
|
||||
[Test]
|
||||
@ -299,12 +310,12 @@ namespace osu.Game.Tests.Visual.Online
|
||||
|
||||
private void downloadAssert(bool shown)
|
||||
{
|
||||
AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.Header.DownloadButtonsVisible == shown);
|
||||
AddAssert($"is download button {(shown ? "shown" : "hidden")}", () => overlay.Header.HeaderContent.DownloadButtonsVisible == shown);
|
||||
}
|
||||
|
||||
private class TestBeatmapSetOverlay : BeatmapSetOverlay
|
||||
{
|
||||
public new Header Header => base.Header;
|
||||
public new BeatmapSetHeader Header => base.Header;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -99,13 +99,16 @@ namespace osu.Game.Tests.Visual.Online
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(RulesetStore rulesets)
|
||||
{
|
||||
var normal = CreateWorkingBeatmap(Ruleset.Value).BeatmapSetInfo;
|
||||
var normal = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet;
|
||||
normal.OnlineInfo.HasVideo = true;
|
||||
normal.OnlineInfo.HasStoryboard = true;
|
||||
|
||||
var undownloadable = getUndownloadableBeatmapSet();
|
||||
var manyDifficulties = getManyDifficultiesBeatmapSet(rulesets);
|
||||
|
||||
var explicitMap = CreateBeatmap(Ruleset.Value).BeatmapInfo.BeatmapSet;
|
||||
explicitMap.OnlineInfo.HasExplicitContent = true;
|
||||
|
||||
Child = new BasicScrollContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
@ -121,9 +124,11 @@ namespace osu.Game.Tests.Visual.Online
|
||||
new GridBeatmapPanel(normal),
|
||||
new GridBeatmapPanel(undownloadable),
|
||||
new GridBeatmapPanel(manyDifficulties),
|
||||
new GridBeatmapPanel(explicitMap),
|
||||
new ListBeatmapPanel(normal),
|
||||
new ListBeatmapPanel(undownloadable),
|
||||
new ListBeatmapPanel(manyDifficulties),
|
||||
new ListBeatmapPanel(explicitMap)
|
||||
},
|
||||
},
|
||||
};
|
||||
|
@ -11,12 +11,10 @@ using osu.Framework.Platform;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Framework.Testing;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Osu;
|
||||
using osu.Game.Screens.OnlinePlay;
|
||||
using osu.Game.Screens.OnlinePlay.Match.Components;
|
||||
using osu.Game.Screens.OnlinePlay.Playlists;
|
||||
using osu.Game.Tests.Beatmaps;
|
||||
using osu.Game.Users;
|
||||
@ -85,8 +83,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
||||
|
||||
AddStep("move mouse to create button", () =>
|
||||
{
|
||||
var footer = match.ChildrenOfType<Footer>().Single();
|
||||
InputManager.MoveMouseTo(footer.ChildrenOfType<OsuButton>().Single());
|
||||
InputManager.MoveMouseTo(this.ChildrenOfType<PlaylistsMatchSettingsOverlay.CreateRoomButton>().Single());
|
||||
});
|
||||
|
||||
AddStep("click", () => InputManager.Click(MouseButton.Left));
|
||||
|
@ -7,6 +7,7 @@ using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays;
|
||||
using osu.Game.Overlays.BeatmapListing;
|
||||
@ -19,9 +20,18 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
[Cached]
|
||||
private readonly OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Blue);
|
||||
|
||||
private readonly BeatmapListingSearchControl control;
|
||||
private BeatmapListingSearchControl control;
|
||||
|
||||
public TestSceneBeatmapListingSearchControl()
|
||||
private OsuConfigManager localConfig;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
Dependencies.Cache(localConfig = new OsuConfigManager(LocalStorage));
|
||||
}
|
||||
|
||||
[SetUp]
|
||||
public void SetUp() => Schedule(() =>
|
||||
{
|
||||
OsuSpriteText query;
|
||||
OsuSpriteText ruleset;
|
||||
@ -31,30 +41,34 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
OsuSpriteText extra;
|
||||
OsuSpriteText ranks;
|
||||
OsuSpriteText played;
|
||||
OsuSpriteText explicitMap;
|
||||
|
||||
Add(control = new BeatmapListingSearchControl
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
});
|
||||
|
||||
Add(new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5),
|
||||
Children = new Drawable[]
|
||||
control = new BeatmapListingSearchControl
|
||||
{
|
||||
query = new OsuSpriteText(),
|
||||
ruleset = new OsuSpriteText(),
|
||||
category = new OsuSpriteText(),
|
||||
genre = new OsuSpriteText(),
|
||||
language = new OsuSpriteText(),
|
||||
extra = new OsuSpriteText(),
|
||||
ranks = new OsuSpriteText(),
|
||||
played = new OsuSpriteText()
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(0, 5),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
query = new OsuSpriteText(),
|
||||
ruleset = new OsuSpriteText(),
|
||||
category = new OsuSpriteText(),
|
||||
genre = new OsuSpriteText(),
|
||||
language = new OsuSpriteText(),
|
||||
extra = new OsuSpriteText(),
|
||||
ranks = new OsuSpriteText(),
|
||||
played = new OsuSpriteText(),
|
||||
explicitMap = new OsuSpriteText(),
|
||||
}
|
||||
}
|
||||
});
|
||||
};
|
||||
|
||||
control.Query.BindValueChanged(q => query.Text = $"Query: {q.NewValue}", true);
|
||||
control.Ruleset.BindValueChanged(r => ruleset.Text = $"Ruleset: {r.NewValue}", true);
|
||||
@ -64,7 +78,8 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
control.Extra.BindCollectionChanged((u, v) => extra.Text = $"Extra: {(control.Extra.Any() ? string.Join('.', control.Extra.Select(i => i.ToString().ToLowerInvariant())) : "")}", true);
|
||||
control.Ranks.BindCollectionChanged((u, v) => ranks.Text = $"Ranks: {(control.Ranks.Any() ? string.Join('.', control.Ranks.Select(i => i.ToString())) : "")}", true);
|
||||
control.Played.BindValueChanged(p => played.Text = $"Played: {p.NewValue}", true);
|
||||
}
|
||||
control.ExplicitContent.BindValueChanged(e => explicitMap.Text = $"Explicit Maps: {e.NewValue}", true);
|
||||
});
|
||||
|
||||
[Test]
|
||||
public void TestCovers()
|
||||
@ -74,6 +89,22 @@ namespace osu.Game.Tests.Visual.UserInterface
|
||||
AddStep("Set null beatmap", () => control.BeatmapSet = null);
|
||||
}
|
||||
|
||||
[Test]
|
||||
public void TestExplicitConfig()
|
||||
{
|
||||
AddStep("configure explicit content to allowed", () => localConfig.Set(OsuSetting.ShowOnlineExplicitContent, true));
|
||||
AddAssert("explicit control set to show", () => control.ExplicitContent.Value == SearchExplicit.Show);
|
||||
|
||||
AddStep("configure explicit content to disallowed", () => localConfig.Set(OsuSetting.ShowOnlineExplicitContent, false));
|
||||
AddAssert("explicit control set to hide", () => control.ExplicitContent.Value == SearchExplicit.Hide);
|
||||
}
|
||||
|
||||
protected override void Dispose(bool isDisposing)
|
||||
{
|
||||
localConfig?.Dispose();
|
||||
base.Dispose(isDisposing);
|
||||
}
|
||||
|
||||
private static readonly BeatmapSetInfo beatmap_set = new BeatmapSetInfo
|
||||
{
|
||||
OnlineInfo = new BeatmapSetOnlineInfo
|
||||
|
@ -10,7 +10,7 @@
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||
|
@ -7,7 +7,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Tournament.Tests.dll"
|
||||
"${workspaceRoot}/bin/Debug/net5.0/osu.Game.Tournament.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Debug)",
|
||||
@ -20,7 +20,7 @@
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Tournament.Tests.dll"
|
||||
"${workspaceRoot}/bin/Release/net5.0/osu.Game.Tournament.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build (Release)",
|
||||
|
@ -11,7 +11,7 @@
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
<OutputType>WinExe</OutputType>
|
||||
<TargetFramework>netcoreapp3.1</TargetFramework>
|
||||
<TargetFramework>net5.0</TargetFramework>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||
|
@ -31,6 +31,11 @@ namespace osu.Game.Beatmaps
|
||||
/// </summary>
|
||||
public BeatmapSetOnlineStatus Status { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not this beatmap set has explicit content.
|
||||
/// </summary>
|
||||
public bool HasExplicitContent { get; set; }
|
||||
|
||||
/// <summary>
|
||||
/// Whether or not this beatmap set has a background video.
|
||||
/// </summary>
|
||||
|
@ -60,6 +60,8 @@ namespace osu.Game.Configuration
|
||||
Set(OsuSetting.ExternalLinkWarning, true);
|
||||
Set(OsuSetting.PreferNoVideo, false);
|
||||
|
||||
Set(OsuSetting.ShowOnlineExplicitContent, false);
|
||||
|
||||
// Audio
|
||||
Set(OsuSetting.VolumeInactive, 0.25, 0, 1, 0.01);
|
||||
|
||||
@ -82,6 +84,7 @@ namespace osu.Game.Configuration
|
||||
|
||||
Set(OsuSetting.ShowStoryboard, true);
|
||||
Set(OsuSetting.BeatmapSkins, true);
|
||||
Set(OsuSetting.BeatmapColours, true);
|
||||
Set(OsuSetting.BeatmapHitsounds, true);
|
||||
|
||||
Set(OsuSetting.CursorRotation, true);
|
||||
@ -250,6 +253,7 @@ namespace osu.Game.Configuration
|
||||
ScreenshotCaptureMenuCursor,
|
||||
SongSelectRightMouseScroll,
|
||||
BeatmapSkins,
|
||||
BeatmapColours,
|
||||
BeatmapHitsounds,
|
||||
IncreaseFirstObjectVisibility,
|
||||
ScoreDisplayMode,
|
||||
@ -270,5 +274,6 @@ namespace osu.Game.Configuration
|
||||
EditorWaveformOpacity,
|
||||
DiscordRichPresence,
|
||||
AutomaticallyDownloadWhenSpectating,
|
||||
ShowOnlineExplicitContent,
|
||||
}
|
||||
}
|
||||
|
@ -115,13 +115,13 @@ namespace osu.Game.Database
|
||||
return Import(notification, paths.Select(p => new ImportTask(p)).ToArray());
|
||||
}
|
||||
|
||||
public Task Import(Stream stream, string filename)
|
||||
public Task Import(params ImportTask[] tasks)
|
||||
{
|
||||
var notification = new ProgressNotification { State = ProgressNotificationState.Active };
|
||||
|
||||
PostNotification?.Invoke(notification);
|
||||
|
||||
return Import(notification, new ImportTask(stream, filename));
|
||||
return Import(notification, tasks);
|
||||
}
|
||||
|
||||
protected async Task<IEnumerable<TModel>> Import(ProgressNotification notification, params ImportTask[] tasks)
|
||||
|
@ -2,7 +2,6 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
|
||||
namespace osu.Game.Database
|
||||
@ -19,11 +18,10 @@ namespace osu.Game.Database
|
||||
Task Import(params string[] paths);
|
||||
|
||||
/// <summary>
|
||||
/// Import the provided stream as a simple item.
|
||||
/// Import the specified files from the given import tasks.
|
||||
/// </summary>
|
||||
/// <param name="stream">The stream to import files from. Should be in a supported archive format.</param>
|
||||
/// <param name="filename">The filename of the archive being imported.</param>
|
||||
Task Import(Stream stream, string filename);
|
||||
/// <param name="tasks">The import tasks from which the files should be imported.</param>
|
||||
Task Import(params ImportTask[] tasks);
|
||||
|
||||
/// <summary>
|
||||
/// An array of accepted file extensions (in the standard format of ".abc").
|
||||
|
@ -135,6 +135,8 @@ namespace osu.Game.Database
|
||||
|
||||
modelBuilder.Entity<DatabasedKeyBinding>().HasIndex(b => new { b.RulesetID, b.Variant });
|
||||
modelBuilder.Entity<DatabasedKeyBinding>().HasIndex(b => b.IntAction);
|
||||
modelBuilder.Entity<DatabasedKeyBinding>().Ignore(b => b.KeyCombination);
|
||||
modelBuilder.Entity<DatabasedKeyBinding>().Ignore(b => b.Action);
|
||||
|
||||
modelBuilder.Entity<DatabasedSetting>().HasIndex(b => new { b.RulesetID, b.Variant });
|
||||
|
||||
|
@ -23,7 +23,7 @@ namespace osu.Game.Input.Bindings
|
||||
|
||||
private KeyBindingStore store;
|
||||
|
||||
public override IEnumerable<KeyBinding> DefaultKeyBindings => ruleset.CreateInstance().GetDefaultKeyBindings(variant ?? 0);
|
||||
public override IEnumerable<IKeyBinding> DefaultKeyBindings => ruleset.CreateInstance().GetDefaultKeyBindings(variant ?? 0);
|
||||
|
||||
/// <summary>
|
||||
/// Create a new instance.
|
||||
|
@ -21,7 +21,7 @@ namespace osu.Game.Input.Bindings
|
||||
handler = game;
|
||||
}
|
||||
|
||||
public override IEnumerable<KeyBinding> DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings).Concat(AudioControlKeyBindings).Concat(EditorKeyBindings);
|
||||
public override IEnumerable<IKeyBinding> DefaultKeyBindings => GlobalKeyBindings.Concat(InGameKeyBindings).Concat(AudioControlKeyBindings).Concat(EditorKeyBindings);
|
||||
|
||||
public IEnumerable<KeyBinding> GlobalKeyBindings => new[]
|
||||
{
|
||||
|
@ -49,7 +49,7 @@ namespace osu.Game.Input
|
||||
}
|
||||
}
|
||||
|
||||
private void insertDefaults(IEnumerable<KeyBinding> defaults, int? rulesetId = null, int? variant = null)
|
||||
private void insertDefaults(IEnumerable<IKeyBinding> defaults, int? rulesetId = null, int? variant = null)
|
||||
{
|
||||
using (var usage = ContextFactory.GetForWrite())
|
||||
{
|
||||
|
@ -42,6 +42,9 @@ namespace osu.Game.Online.API.Requests.Responses
|
||||
[JsonProperty(@"bpm")]
|
||||
private double bpm { get; set; }
|
||||
|
||||
[JsonProperty(@"nsfw")]
|
||||
private bool hasExplicitContent { get; set; }
|
||||
|
||||
[JsonProperty(@"video")]
|
||||
private bool hasVideo { get; set; }
|
||||
|
||||
@ -94,6 +97,7 @@ namespace osu.Game.Online.API.Requests.Responses
|
||||
FavouriteCount = favouriteCount,
|
||||
BPM = bpm,
|
||||
Status = Status,
|
||||
HasExplicitContent = hasExplicitContent,
|
||||
HasVideo = hasVideo,
|
||||
HasStoryboard = hasStoryboard,
|
||||
Submitted = submitted,
|
||||
|
@ -30,6 +30,8 @@ namespace osu.Game.Online.API.Requests
|
||||
|
||||
public SearchPlayed Played { get; }
|
||||
|
||||
public SearchExplicit ExplicitContent { get; }
|
||||
|
||||
[CanBeNull]
|
||||
public IReadOnlyCollection<ScoreRank> Ranks { get; }
|
||||
|
||||
@ -50,7 +52,8 @@ namespace osu.Game.Online.API.Requests
|
||||
SearchLanguage language = SearchLanguage.Any,
|
||||
IReadOnlyCollection<SearchExtra> extra = null,
|
||||
IReadOnlyCollection<ScoreRank> ranks = null,
|
||||
SearchPlayed played = SearchPlayed.Any)
|
||||
SearchPlayed played = SearchPlayed.Any,
|
||||
SearchExplicit explicitContent = SearchExplicit.Hide)
|
||||
{
|
||||
this.query = string.IsNullOrEmpty(query) ? string.Empty : System.Uri.EscapeDataString(query);
|
||||
this.ruleset = ruleset;
|
||||
@ -64,6 +67,7 @@ namespace osu.Game.Online.API.Requests
|
||||
Extra = extra;
|
||||
Ranks = ranks;
|
||||
Played = played;
|
||||
ExplicitContent = explicitContent;
|
||||
}
|
||||
|
||||
protected override WebRequest CreateWebRequest()
|
||||
@ -93,6 +97,8 @@ namespace osu.Game.Online.API.Requests
|
||||
if (Played != SearchPlayed.Any)
|
||||
req.AddParameter("played", Played.ToString().ToLowerInvariant());
|
||||
|
||||
req.AddParameter("nsfw", ExplicitContent == SearchExplicit.Show ? "true" : "false");
|
||||
|
||||
req.AddCursor(cursor);
|
||||
|
||||
return req;
|
||||
|
@ -7,7 +7,6 @@ using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Diagnostics;
|
||||
using System.Linq;
|
||||
using System.Threading;
|
||||
using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
@ -128,7 +127,8 @@ namespace osu.Game.Online.Multiplayer
|
||||
|
||||
Debug.Assert(Room != null);
|
||||
|
||||
var users = getRoomUsers();
|
||||
var users = await getRoomUsers();
|
||||
Debug.Assert(users != null);
|
||||
|
||||
await Task.WhenAll(users.Select(PopulateUser));
|
||||
|
||||
@ -437,24 +437,20 @@ namespace osu.Game.Online.Multiplayer
|
||||
/// This should be used whenever accessing users from outside of an Update thread context (ie. when not calling <see cref="Drawable.Schedule"/>).
|
||||
/// </summary>
|
||||
/// <returns>A copy of users in the current room, or null if unavailable.</returns>
|
||||
private List<MultiplayerRoomUser>? getRoomUsers()
|
||||
private Task<List<MultiplayerRoomUser>?> getRoomUsers()
|
||||
{
|
||||
List<MultiplayerRoomUser>? users = null;
|
||||
|
||||
ManualResetEventSlim resetEvent = new ManualResetEventSlim();
|
||||
var tcs = new TaskCompletionSource<List<MultiplayerRoomUser>?>();
|
||||
|
||||
// at some point we probably want to replace all these schedule calls with Room.LockForUpdate.
|
||||
// for now, as this would require quite some consideration due to the number of accesses to the room instance,
|
||||
// let's just add a manual schedule for the non-scheduled usages instead.
|
||||
Scheduler.Add(() =>
|
||||
{
|
||||
users = Room?.Users.ToList();
|
||||
resetEvent.Set();
|
||||
var users = Room?.Users.ToList();
|
||||
tcs.SetResult(users);
|
||||
}, false);
|
||||
|
||||
resetEvent.Wait(100);
|
||||
|
||||
return users;
|
||||
return tcs.Task;
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
|
@ -51,7 +51,7 @@ using osu.Game.Screens.Select;
|
||||
using osu.Game.Updater;
|
||||
using osu.Game.Utils;
|
||||
using LogLevel = osu.Framework.Logging.LogLevel;
|
||||
using System.IO;
|
||||
using osu.Game.Database;
|
||||
|
||||
namespace osu.Game
|
||||
{
|
||||
@ -438,10 +438,10 @@ namespace osu.Game
|
||||
}, validScreens: new[] { typeof(PlaySongSelect) });
|
||||
}
|
||||
|
||||
public override Task Import(Stream stream, string filename)
|
||||
public override Task Import(params ImportTask[] imports)
|
||||
{
|
||||
// encapsulate task as we don't want to begin the import process until in a ready state.
|
||||
var importTask = new Task(async () => await base.Import(stream, filename));
|
||||
var importTask = new Task(async () => await base.Import(imports));
|
||||
|
||||
waitForReady(() => this, _ => importTask.Start());
|
||||
|
||||
|
@ -327,6 +327,7 @@ namespace osu.Game
|
||||
|
||||
if (!SelectedMods.Disabled)
|
||||
SelectedMods.Value = Array.Empty<Mod>();
|
||||
|
||||
AvailableMods.Value = dict;
|
||||
}
|
||||
|
||||
@ -419,15 +420,14 @@ namespace osu.Game
|
||||
}
|
||||
}
|
||||
|
||||
public virtual async Task Import(Stream stream, string filename)
|
||||
public virtual async Task Import(params ImportTask[] tasks)
|
||||
{
|
||||
var extension = Path.GetExtension(filename)?.ToLowerInvariant();
|
||||
|
||||
foreach (var importer in fileImporters)
|
||||
var tasksPerExtension = tasks.GroupBy(t => Path.GetExtension(t.Path).ToLowerInvariant());
|
||||
await Task.WhenAll(tasksPerExtension.Select(taskGroup =>
|
||||
{
|
||||
if (importer.HandledExtensions.Contains(extension))
|
||||
await importer.Import(stream, Path.GetFileNameWithoutExtension(filename));
|
||||
}
|
||||
var importer = fileImporters.FirstOrDefault(i => i.HandledExtensions.Contains(taskGroup.Key));
|
||||
return importer?.Import(taskGroup.ToArray()) ?? Task.CompletedTask;
|
||||
}));
|
||||
}
|
||||
|
||||
public IEnumerable<string> HandledExtensions => fileImporters.SelectMany(i => i.HandledExtensions);
|
||||
|
@ -141,6 +141,7 @@ namespace osu.Game.Overlays.BeatmapListing
|
||||
searchControl.Extra.CollectionChanged += (_, __) => queueUpdateSearch();
|
||||
searchControl.Ranks.CollectionChanged += (_, __) => queueUpdateSearch();
|
||||
searchControl.Played.BindValueChanged(_ => queueUpdateSearch());
|
||||
searchControl.ExplicitContent.BindValueChanged(_ => queueUpdateSearch());
|
||||
|
||||
sortCriteria.BindValueChanged(_ => queueUpdateSearch());
|
||||
sortDirection.BindValueChanged(_ => queueUpdateSearch());
|
||||
@ -193,7 +194,8 @@ namespace osu.Game.Overlays.BeatmapListing
|
||||
searchControl.Language.Value,
|
||||
searchControl.Extra,
|
||||
searchControl.Ranks,
|
||||
searchControl.Played.Value);
|
||||
searchControl.Played.Value,
|
||||
searchControl.ExplicitContent.Value);
|
||||
|
||||
getSetsRequest.Success += response =>
|
||||
{
|
||||
|
@ -11,6 +11,7 @@ using osu.Framework.Bindables;
|
||||
using osu.Framework.Input.Events;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Configuration;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osuTK.Graphics;
|
||||
@ -42,6 +43,8 @@ namespace osu.Game.Overlays.BeatmapListing
|
||||
|
||||
public Bindable<SearchPlayed> Played => playedFilter.Current;
|
||||
|
||||
public Bindable<SearchExplicit> ExplicitContent => explicitContentFilter.Current;
|
||||
|
||||
public BeatmapSetInfo BeatmapSet
|
||||
{
|
||||
set
|
||||
@ -65,6 +68,7 @@ namespace osu.Game.Overlays.BeatmapListing
|
||||
private readonly BeatmapSearchMultipleSelectionFilterRow<SearchExtra> extraFilter;
|
||||
private readonly BeatmapSearchScoreFilterRow ranksFilter;
|
||||
private readonly BeatmapSearchFilterRow<SearchPlayed> playedFilter;
|
||||
private readonly BeatmapSearchFilterRow<SearchExplicit> explicitContentFilter;
|
||||
|
||||
private readonly Box background;
|
||||
private readonly UpdateableBeatmapSetCover beatmapCover;
|
||||
@ -125,7 +129,8 @@ namespace osu.Game.Overlays.BeatmapListing
|
||||
languageFilter = new BeatmapSearchFilterRow<SearchLanguage>(@"Language"),
|
||||
extraFilter = new BeatmapSearchMultipleSelectionFilterRow<SearchExtra>(@"Extra"),
|
||||
ranksFilter = new BeatmapSearchScoreFilterRow(),
|
||||
playedFilter = new BeatmapSearchFilterRow<SearchPlayed>(@"Played")
|
||||
playedFilter = new BeatmapSearchFilterRow<SearchPlayed>(@"Played"),
|
||||
explicitContentFilter = new BeatmapSearchFilterRow<SearchExplicit>(@"Explicit Content"),
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -136,10 +141,18 @@ namespace osu.Game.Overlays.BeatmapListing
|
||||
categoryFilter.Current.Value = SearchCategory.Leaderboard;
|
||||
}
|
||||
|
||||
private IBindable<bool> allowExplicitContent;
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load(OverlayColourProvider colourProvider)
|
||||
private void load(OverlayColourProvider colourProvider, OsuConfigManager config)
|
||||
{
|
||||
background.Colour = colourProvider.Dark6;
|
||||
|
||||
allowExplicitContent = config.GetBindable<bool>(OsuSetting.ShowOnlineExplicitContent);
|
||||
allowExplicitContent.BindValueChanged(allow =>
|
||||
{
|
||||
ExplicitContent.Value = allow.NewValue ? SearchExplicit.Show : SearchExplicit.Hide;
|
||||
}, true);
|
||||
}
|
||||
|
||||
public void TakeFocus() => textBox.TakeFocus();
|
||||
|
@ -14,6 +14,7 @@ using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays.BeatmapSet;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -24,7 +25,7 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
|
||||
private const float horizontal_padding = 10;
|
||||
private const float vertical_padding = 5;
|
||||
|
||||
private FillFlowContainer bottomPanel, statusContainer;
|
||||
private FillFlowContainer bottomPanel, statusContainer, titleContainer;
|
||||
private PlayButton playButton;
|
||||
private Box progressBar;
|
||||
|
||||
@ -73,12 +74,20 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Left = horizontal_padding, Right = horizontal_padding },
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new[]
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
titleContainer = new FillFlowContainer
|
||||
{
|
||||
Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)),
|
||||
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true)
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)),
|
||||
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true)
|
||||
},
|
||||
}
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
@ -194,6 +203,16 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
|
||||
},
|
||||
});
|
||||
|
||||
if (SetInfo.OnlineInfo?.HasExplicitContent ?? false)
|
||||
{
|
||||
titleContainer.Add(new ExplicitContentBeatmapPill
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Left = 10f, Top = 2f },
|
||||
});
|
||||
}
|
||||
|
||||
if (SetInfo.OnlineInfo?.HasVideo ?? false)
|
||||
{
|
||||
statusContainer.Add(new IconPill(FontAwesome.Solid.Film));
|
||||
|
@ -14,6 +14,7 @@ using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Containers;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
using osu.Game.Overlays.BeatmapSet;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
@ -26,7 +27,7 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
|
||||
private const float vertical_padding = 5;
|
||||
private const float height = 70;
|
||||
|
||||
private FillFlowContainer statusContainer;
|
||||
private FillFlowContainer statusContainer, titleContainer;
|
||||
protected BeatmapPanelDownloadButton DownloadButton;
|
||||
private PlayButton playButton;
|
||||
private Box progressBar;
|
||||
@ -98,10 +99,18 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
titleContainer = new FillFlowContainer
|
||||
{
|
||||
Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)),
|
||||
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true)
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Children = new[]
|
||||
{
|
||||
new OsuSpriteText
|
||||
{
|
||||
Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)),
|
||||
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true)
|
||||
},
|
||||
}
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
@ -208,6 +217,16 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
|
||||
},
|
||||
});
|
||||
|
||||
if (SetInfo.OnlineInfo?.HasExplicitContent ?? false)
|
||||
{
|
||||
titleContainer.Add(new ExplicitContentBeatmapPill
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Left = 10f, Top = 2f },
|
||||
});
|
||||
}
|
||||
|
||||
if (SetInfo.OnlineInfo?.HasVideo ?? false)
|
||||
{
|
||||
statusContainer.Add(new IconPill(FontAwesome.Solid.Film) { IconSize = new Vector2(20) });
|
||||
|
11
osu.Game/Overlays/BeatmapListing/SearchExplicit.cs
Normal file
11
osu.Game/Overlays/BeatmapListing/SearchExplicit.cs
Normal file
@ -0,0 +1,11 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapListing
|
||||
{
|
||||
public enum SearchExplicit
|
||||
{
|
||||
Hide,
|
||||
Show
|
||||
}
|
||||
}
|
@ -1,25 +1,55 @@
|
||||
// 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.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
public class BeatmapSetHeader : OverlayHeader
|
||||
{
|
||||
public readonly Bindable<RulesetInfo> Ruleset = new Bindable<RulesetInfo>();
|
||||
public readonly Bindable<BeatmapSetInfo> BeatmapSet = new Bindable<BeatmapSetInfo>();
|
||||
|
||||
public BeatmapSetHeaderContent HeaderContent { get; private set; }
|
||||
|
||||
[Cached]
|
||||
public BeatmapRulesetSelector RulesetSelector { get; private set; }
|
||||
|
||||
protected override OverlayTitle CreateTitle() => new BeatmapHeaderTitle();
|
||||
[Cached(typeof(IBindable<RulesetInfo>))]
|
||||
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||
|
||||
public BeatmapSetHeader()
|
||||
{
|
||||
Masking = true;
|
||||
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Colour = Color4.Black.Opacity(0.25f),
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 3,
|
||||
Offset = new Vector2(0f, 1f),
|
||||
};
|
||||
}
|
||||
|
||||
protected override Drawable CreateContent() => HeaderContent = new BeatmapSetHeaderContent
|
||||
{
|
||||
BeatmapSet = { BindTarget = BeatmapSet }
|
||||
};
|
||||
|
||||
protected override Drawable CreateTitleContent() => RulesetSelector = new BeatmapRulesetSelector
|
||||
{
|
||||
Current = Ruleset
|
||||
Current = ruleset
|
||||
};
|
||||
|
||||
protected override OverlayTitle CreateTitle() => new BeatmapHeaderTitle();
|
||||
|
||||
private class BeatmapHeaderTitle : OverlayTitle
|
||||
{
|
||||
public BeatmapHeaderTitle()
|
||||
|
@ -3,12 +3,10 @@
|
||||
|
||||
using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.Color4Extensions;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Colour;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics.Effects;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Game.Beatmaps.Drawables;
|
||||
using osu.Game.Graphics;
|
||||
@ -18,197 +16,177 @@ using osu.Game.Online;
|
||||
using osu.Game.Online.API;
|
||||
using osu.Game.Overlays.BeatmapListing.Panels;
|
||||
using osu.Game.Overlays.BeatmapSet.Buttons;
|
||||
using osu.Game.Rulesets;
|
||||
using osuTK;
|
||||
using osuTK.Graphics;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
public class Header : BeatmapDownloadTrackingComposite
|
||||
public class BeatmapSetHeaderContent : BeatmapDownloadTrackingComposite
|
||||
{
|
||||
private const float transition_duration = 200;
|
||||
private const float buttons_height = 45;
|
||||
private const float buttons_spacing = 5;
|
||||
|
||||
public bool DownloadButtonsVisible => downloadButtonsContainer.Any();
|
||||
|
||||
public readonly Details Details;
|
||||
public readonly BeatmapPicker Picker;
|
||||
|
||||
private readonly UpdateableBeatmapSetCover cover;
|
||||
private readonly Box coverGradient;
|
||||
private readonly OsuSpriteText title, artist;
|
||||
private readonly AuthorInfo author;
|
||||
private readonly ExplicitContentBeatmapPill explicitContentPill;
|
||||
private readonly FillFlowContainer downloadButtonsContainer;
|
||||
private readonly BeatmapAvailability beatmapAvailability;
|
||||
private readonly BeatmapSetOnlineStatusPill onlineStatusPill;
|
||||
public Details Details;
|
||||
|
||||
public bool DownloadButtonsVisible => downloadButtonsContainer.Any();
|
||||
private readonly FavouriteButton favouriteButton;
|
||||
private readonly FillFlowContainer fadeContent;
|
||||
private readonly LoadingSpinner loading;
|
||||
|
||||
[Resolved]
|
||||
private IAPIProvider api { get; set; }
|
||||
|
||||
public BeatmapRulesetSelector RulesetSelector => beatmapSetHeader.RulesetSelector;
|
||||
public readonly BeatmapPicker Picker;
|
||||
[Resolved]
|
||||
private BeatmapRulesetSelector rulesetSelector { get; set; }
|
||||
|
||||
private readonly FavouriteButton favouriteButton;
|
||||
private readonly FillFlowContainer fadeContent;
|
||||
private readonly LoadingSpinner loading;
|
||||
private readonly BeatmapSetHeader beatmapSetHeader;
|
||||
|
||||
[Cached(typeof(IBindable<RulesetInfo>))]
|
||||
private readonly Bindable<RulesetInfo> ruleset = new Bindable<RulesetInfo>();
|
||||
|
||||
public Header()
|
||||
public BeatmapSetHeaderContent()
|
||||
{
|
||||
ExternalLinkButton externalLink;
|
||||
|
||||
RelativeSizeAxes = Axes.X;
|
||||
AutoSizeAxes = Axes.Y;
|
||||
Masking = true;
|
||||
|
||||
EdgeEffect = new EdgeEffectParameters
|
||||
{
|
||||
Colour = Color4.Black.Opacity(0.25f),
|
||||
Type = EdgeEffectType.Shadow,
|
||||
Radius = 3,
|
||||
Offset = new Vector2(0f, 1f),
|
||||
};
|
||||
|
||||
InternalChild = new FillFlowContainer
|
||||
InternalChild = new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
beatmapSetHeader = new BeatmapSetHeader
|
||||
new Container
|
||||
{
|
||||
Ruleset = { BindTarget = ruleset },
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
cover = new UpdateableBeatmapSetCover
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
},
|
||||
coverGradient = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
},
|
||||
},
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Vertical = BeatmapSetOverlay.Y_PADDING,
|
||||
Left = BeatmapSetOverlay.X_PADDING,
|
||||
Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH,
|
||||
},
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
cover = new UpdateableBeatmapSetCover
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Masking = true,
|
||||
},
|
||||
coverGradient = new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both
|
||||
},
|
||||
},
|
||||
},
|
||||
new Container
|
||||
fadeContent = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Padding = new MarginPadding
|
||||
{
|
||||
Vertical = BeatmapSetOverlay.Y_PADDING,
|
||||
Left = BeatmapSetOverlay.X_PADDING,
|
||||
Right = BeatmapSetOverlay.X_PADDING + BeatmapSetOverlay.RIGHT_WIDTH,
|
||||
},
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
fadeContent = new FillFlowContainer
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Direction = FillDirection.Vertical,
|
||||
Child = Picker = new BeatmapPicker(),
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Direction = FillDirection.Horizontal,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Margin = new MarginPadding { Top = 15 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Container
|
||||
title = new OsuSpriteText
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Child = Picker = new BeatmapPicker(),
|
||||
Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true)
|
||||
},
|
||||
new FillFlowContainer
|
||||
externalLink = new ExternalLinkButton
|
||||
{
|
||||
Direction = FillDirection.Horizontal,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Margin = new MarginPadding { Top = 15 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
title = new OsuSpriteText
|
||||
{
|
||||
Font = OsuFont.GetFont(size: 30, weight: FontWeight.SemiBold, italics: true)
|
||||
},
|
||||
externalLink = new ExternalLinkButton
|
||||
{
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Margin = new MarginPadding { Left = 3, Bottom = 4 }, // To better lineup with the font
|
||||
},
|
||||
}
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Margin = new MarginPadding { Left = 5, Bottom = 4 }, // To better lineup with the font
|
||||
},
|
||||
artist = new OsuSpriteText
|
||||
explicitContentPill = new ExplicitContentBeatmapPill
|
||||
{
|
||||
Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true),
|
||||
Margin = new MarginPadding { Bottom = 20 }
|
||||
Alpha = 0f,
|
||||
Anchor = Anchor.BottomLeft,
|
||||
Origin = Anchor.BottomLeft,
|
||||
Margin = new MarginPadding { Left = 10, Bottom = 4 },
|
||||
}
|
||||
}
|
||||
},
|
||||
artist = new OsuSpriteText
|
||||
{
|
||||
Font = OsuFont.GetFont(size: 20, weight: FontWeight.Medium, italics: true),
|
||||
Margin = new MarginPadding { Bottom = 20 }
|
||||
},
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Child = author = new AuthorInfo(),
|
||||
},
|
||||
beatmapAvailability = new BeatmapAvailability(),
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = buttons_height,
|
||||
Margin = new MarginPadding { Top = 10 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
favouriteButton = new FavouriteButton
|
||||
{
|
||||
BeatmapSet = { BindTarget = BeatmapSet }
|
||||
},
|
||||
new Container
|
||||
downloadButtonsContainer = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
AutoSizeAxes = Axes.Y,
|
||||
Child = author = new AuthorInfo(),
|
||||
},
|
||||
beatmapAvailability = new BeatmapAvailability(),
|
||||
new Container
|
||||
{
|
||||
RelativeSizeAxes = Axes.X,
|
||||
Height = buttons_height,
|
||||
Margin = new MarginPadding { Top = 10 },
|
||||
Children = new Drawable[]
|
||||
{
|
||||
favouriteButton = new FavouriteButton
|
||||
{
|
||||
BeatmapSet = { BindTarget = BeatmapSet }
|
||||
},
|
||||
downloadButtonsContainer = new FillFlowContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Left = buttons_height + buttons_spacing },
|
||||
Spacing = new Vector2(buttons_spacing),
|
||||
},
|
||||
},
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Padding = new MarginPadding { Left = buttons_height + buttons_spacing },
|
||||
Spacing = new Vector2(buttons_spacing),
|
||||
},
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
loading = new LoadingSpinner
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(1.5f),
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Margin = new MarginPadding { Top = BeatmapSetOverlay.Y_PADDING, Right = BeatmapSetOverlay.X_PADDING },
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(10),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
onlineStatusPill = new BeatmapSetOnlineStatusPill
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
TextSize = 14,
|
||||
TextPadding = new MarginPadding { Horizontal = 35, Vertical = 10 }
|
||||
},
|
||||
Details = new Details(),
|
||||
},
|
||||
},
|
||||
}
|
||||
},
|
||||
loading = new LoadingSpinner
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
Scale = new Vector2(1.5f),
|
||||
},
|
||||
new FillFlowContainer
|
||||
{
|
||||
Anchor = Anchor.BottomRight,
|
||||
Origin = Anchor.BottomRight,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Margin = new MarginPadding { Top = BeatmapSetOverlay.Y_PADDING, Right = BeatmapSetOverlay.X_PADDING },
|
||||
Direction = FillDirection.Vertical,
|
||||
Spacing = new Vector2(10),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
onlineStatusPill = new BeatmapSetOnlineStatusPill
|
||||
{
|
||||
Anchor = Anchor.TopRight,
|
||||
Origin = Anchor.TopRight,
|
||||
TextSize = 14,
|
||||
TextPadding = new MarginPadding { Horizontal = 35, Vertical = 10 }
|
||||
},
|
||||
Details = new Details(),
|
||||
},
|
||||
},
|
||||
}
|
||||
@ -231,7 +209,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
|
||||
BeatmapSet.BindValueChanged(setInfo =>
|
||||
{
|
||||
Picker.BeatmapSet = RulesetSelector.BeatmapSet = author.BeatmapSet = beatmapAvailability.BeatmapSet = Details.BeatmapSet = setInfo.NewValue;
|
||||
Picker.BeatmapSet = rulesetSelector.BeatmapSet = author.BeatmapSet = beatmapAvailability.BeatmapSet = Details.BeatmapSet = setInfo.NewValue;
|
||||
cover.BeatmapSet = setInfo.NewValue;
|
||||
|
||||
if (setInfo.NewValue == null)
|
||||
@ -253,6 +231,8 @@ namespace osu.Game.Overlays.BeatmapSet
|
||||
title.Text = setInfo.NewValue.Metadata.Title ?? string.Empty;
|
||||
artist.Text = setInfo.NewValue.Metadata.Artist ?? string.Empty;
|
||||
|
||||
explicitContentPill.Alpha = setInfo.NewValue.OnlineInfo.HasExplicitContent ? 1 : 0;
|
||||
|
||||
onlineStatusPill.FadeIn(500, Easing.OutQuint);
|
||||
onlineStatusPill.Status = setInfo.NewValue.OnlineInfo.Status;
|
||||
|
45
osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapPill.cs
Normal file
45
osu.Game/Overlays/BeatmapSet/ExplicitContentBeatmapPill.cs
Normal file
@ -0,0 +1,45 @@
|
||||
// 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.Framework.Graphics.Shapes;
|
||||
using osu.Game.Graphics;
|
||||
using osu.Game.Graphics.Sprites;
|
||||
|
||||
namespace osu.Game.Overlays.BeatmapSet
|
||||
{
|
||||
public class ExplicitContentBeatmapPill : CompositeDrawable
|
||||
{
|
||||
public ExplicitContentBeatmapPill()
|
||||
{
|
||||
AutoSizeAxes = Axes.Both;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader(true)]
|
||||
private void load(OsuColour colours, OverlayColourProvider colourProvider)
|
||||
{
|
||||
InternalChild = new CircularContainer
|
||||
{
|
||||
Masking = true,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = colourProvider?.Background5 ?? colours.Gray2,
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Margin = new MarginPadding { Horizontal = 10f, Vertical = 2f },
|
||||
Text = "EXPLICIT",
|
||||
Font = OsuFont.GetFont(size: 10, weight: FontWeight.SemiBold),
|
||||
Colour = OverlayColourProvider.Orange.Colour2,
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
@ -19,15 +19,12 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Overlays
|
||||
{
|
||||
public class BeatmapSetOverlay : FullscreenOverlay<OverlayHeader> // we don't provide a standard header for now.
|
||||
public class BeatmapSetOverlay : FullscreenOverlay<BeatmapSetHeader>
|
||||
{
|
||||
public const float X_PADDING = 40;
|
||||
public const float Y_PADDING = 25;
|
||||
public const float RIGHT_WIDTH = 275;
|
||||
|
||||
//todo: should be an OverlayHeader? or maybe not?
|
||||
protected new readonly Header Header;
|
||||
|
||||
[Resolved]
|
||||
private RulesetStore rulesets { get; set; }
|
||||
|
||||
@ -39,7 +36,7 @@ namespace osu.Game.Overlays
|
||||
private readonly Box background;
|
||||
|
||||
public BeatmapSetOverlay()
|
||||
: base(OverlayColourScheme.Blue, null)
|
||||
: base(OverlayColourScheme.Blue, new BeatmapSetHeader())
|
||||
{
|
||||
OverlayScrollContainer scroll;
|
||||
Info info;
|
||||
@ -72,14 +69,14 @@ namespace osu.Game.Overlays
|
||||
Direction = FillDirection.Vertical,
|
||||
Children = new Drawable[]
|
||||
{
|
||||
Header = new Header(),
|
||||
Header,
|
||||
info = new Info()
|
||||
}
|
||||
},
|
||||
},
|
||||
new ScoresContainer
|
||||
{
|
||||
Beatmap = { BindTarget = Header.Picker.Beatmap }
|
||||
Beatmap = { BindTarget = Header.HeaderContent.Picker.Beatmap }
|
||||
},
|
||||
comments = new CommentsSection()
|
||||
},
|
||||
@ -91,7 +88,7 @@ namespace osu.Game.Overlays
|
||||
info.BeatmapSet.BindTo(beatmapSet);
|
||||
comments.BeatmapSet.BindTo(beatmapSet);
|
||||
|
||||
Header.Picker.Beatmap.ValueChanged += b =>
|
||||
Header.HeaderContent.Picker.Beatmap.ValueChanged += b =>
|
||||
{
|
||||
info.Beatmap = b.NewValue;
|
||||
|
||||
@ -125,7 +122,7 @@ namespace osu.Game.Overlays
|
||||
req.Success += res =>
|
||||
{
|
||||
beatmapSet.Value = res.ToBeatmapSet(rulesets);
|
||||
Header.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId);
|
||||
Header.HeaderContent.Picker.Beatmap.Value = Header.BeatmapSet.Value.Beatmaps.First(b => b.OnlineBeatmapID == beatmapId);
|
||||
};
|
||||
API.Queue(req);
|
||||
|
||||
|
@ -24,6 +24,13 @@ namespace osu.Game.Overlays
|
||||
[Resolved]
|
||||
private AudioManager audio { get; set; }
|
||||
|
||||
private readonly float finalFillAlpha;
|
||||
|
||||
protected HoldToConfirmOverlay(float finalFillAlpha = 1)
|
||||
{
|
||||
this.finalFillAlpha = finalFillAlpha;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
@ -42,8 +49,10 @@ namespace osu.Game.Overlays
|
||||
|
||||
Progress.ValueChanged += p =>
|
||||
{
|
||||
audioVolume.Value = 1 - p.NewValue;
|
||||
overlay.Alpha = (float)p.NewValue;
|
||||
var target = p.NewValue * finalFillAlpha;
|
||||
|
||||
audioVolume.Value = 1 - target;
|
||||
overlay.Alpha = (float)target;
|
||||
};
|
||||
|
||||
audio.Tracks.AddAdjustment(AdjustableProperty.Volume, audioVolume);
|
||||
|
@ -30,6 +30,7 @@ namespace osu.Game.Overlays.Mods
|
||||
{
|
||||
public class ModSelectOverlay : WaveOverlayContainer
|
||||
{
|
||||
private readonly Func<Mod, bool> isValidMod;
|
||||
public const float HEIGHT = 510;
|
||||
|
||||
protected readonly TriangleButton DeselectAllButton;
|
||||
@ -60,8 +61,10 @@ namespace osu.Game.Overlays.Mods
|
||||
|
||||
private SampleChannel sampleOn, sampleOff;
|
||||
|
||||
public ModSelectOverlay()
|
||||
public ModSelectOverlay(Func<Mod, bool> isValidMod = null)
|
||||
{
|
||||
this.isValidMod = isValidMod ?? (m => true);
|
||||
|
||||
Waves.FirstWaveColour = Color4Extensions.FromHex(@"19b0e2");
|
||||
Waves.SecondWaveColour = Color4Extensions.FromHex(@"2280a2");
|
||||
Waves.ThirdWaveColour = Color4Extensions.FromHex(@"005774");
|
||||
@ -403,7 +406,7 @@ namespace osu.Game.Overlays.Mods
|
||||
if (mods.NewValue == null) return;
|
||||
|
||||
foreach (var section in ModSectionsContainer.Children)
|
||||
section.Mods = mods.NewValue[section.ModType];
|
||||
section.Mods = mods.NewValue[section.ModType].Where(isValidMod);
|
||||
}
|
||||
|
||||
private void selectedModsChanged(ValueChangedEvent<IReadOnlyList<Mod>> mods)
|
||||
|
@ -11,11 +11,23 @@ namespace osu.Game.Overlays
|
||||
{
|
||||
private readonly OverlayColourScheme colourScheme;
|
||||
|
||||
public static OverlayColourProvider Red { get; } = new OverlayColourProvider(OverlayColourScheme.Red);
|
||||
public static OverlayColourProvider Pink { get; } = new OverlayColourProvider(OverlayColourScheme.Pink);
|
||||
public static OverlayColourProvider Orange { get; } = new OverlayColourProvider(OverlayColourScheme.Orange);
|
||||
public static OverlayColourProvider Green { get; } = new OverlayColourProvider(OverlayColourScheme.Green);
|
||||
public static OverlayColourProvider Purple { get; } = new OverlayColourProvider(OverlayColourScheme.Purple);
|
||||
public static OverlayColourProvider Blue { get; } = new OverlayColourProvider(OverlayColourScheme.Blue);
|
||||
|
||||
public OverlayColourProvider(OverlayColourScheme colourScheme)
|
||||
{
|
||||
this.colourScheme = colourScheme;
|
||||
}
|
||||
|
||||
public Color4 Colour1 => getColour(1, 0.7f);
|
||||
public Color4 Colour2 => getColour(0.8f, 0.6f);
|
||||
public Color4 Colour3 => getColour(0.6f, 0.5f);
|
||||
public Color4 Colour4 => getColour(0.4f, 0.3f);
|
||||
|
||||
public Color4 Highlight1 => getColour(1, 0.7f);
|
||||
public Color4 Content1 => getColour(0.4f, 1);
|
||||
public Color4 Content2 => getColour(0.4f, 0.9f);
|
||||
|
@ -33,6 +33,12 @@ namespace osu.Game.Overlays.Settings.Sections.Online
|
||||
Keywords = new[] { "spectator" },
|
||||
Current = config.GetBindable<bool>(OsuSetting.AutomaticallyDownloadWhenSpectating),
|
||||
},
|
||||
new SettingsCheckbox
|
||||
{
|
||||
LabelText = "Show explicit content in search results",
|
||||
Keywords = new[] { "nsfw", "18+", "offensive" },
|
||||
Current = config.GetBindable<bool>(OsuSetting.ShowOnlineExplicitContent),
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
@ -38,6 +38,18 @@ namespace osu.Game.Overlays.Settings.Sections
|
||||
|
||||
private List<SkinInfo> skinItems;
|
||||
|
||||
private int firstNonDefaultSkinIndex
|
||||
{
|
||||
get
|
||||
{
|
||||
var index = skinItems.FindIndex(s => s.ID > 0);
|
||||
if (index < 0)
|
||||
index = skinItems.Count;
|
||||
|
||||
return index;
|
||||
}
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
private SkinManager skins { get; set; }
|
||||
|
||||
@ -70,6 +82,11 @@ namespace osu.Game.Overlays.Settings.Sections
|
||||
Current = config.GetBindable<bool>(OsuSetting.BeatmapSkins)
|
||||
},
|
||||
new SettingsCheckbox
|
||||
{
|
||||
LabelText = "Beatmap colours",
|
||||
Current = config.GetBindable<bool>(OsuSetting.BeatmapColours)
|
||||
},
|
||||
new SettingsCheckbox
|
||||
{
|
||||
LabelText = "Beatmap hitsounds",
|
||||
Current = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds)
|
||||
@ -107,21 +124,22 @@ namespace osu.Game.Overlays.Settings.Sections
|
||||
private void updateItems()
|
||||
{
|
||||
skinItems = skins.GetAllUsableSkins();
|
||||
|
||||
// insert after lazer built-in skins
|
||||
int firstNonDefault = skinItems.FindIndex(s => s.ID > 0);
|
||||
if (firstNonDefault < 0)
|
||||
firstNonDefault = skinItems.Count;
|
||||
|
||||
skinItems.Insert(firstNonDefault, random_skin_info);
|
||||
|
||||
skinItems.Insert(firstNonDefaultSkinIndex, random_skin_info);
|
||||
sortUserSkins(skinItems);
|
||||
skinDropdown.Items = skinItems;
|
||||
}
|
||||
|
||||
private void itemUpdated(ValueChangedEvent<WeakReference<SkinInfo>> weakItem)
|
||||
{
|
||||
if (weakItem.NewValue.TryGetTarget(out var item))
|
||||
Schedule(() => skinDropdown.Items = skinDropdown.Items.Where(i => !i.Equals(item)).Append(item).ToArray());
|
||||
{
|
||||
Schedule(() =>
|
||||
{
|
||||
List<SkinInfo> newDropdownItems = skinDropdown.Items.Where(i => !i.Equals(item)).Append(item).ToList();
|
||||
sortUserSkins(newDropdownItems);
|
||||
skinDropdown.Items = newDropdownItems;
|
||||
});
|
||||
}
|
||||
}
|
||||
|
||||
private void itemRemoved(ValueChangedEvent<WeakReference<SkinInfo>> weakItem)
|
||||
@ -130,6 +148,13 @@ namespace osu.Game.Overlays.Settings.Sections
|
||||
Schedule(() => skinDropdown.Items = skinDropdown.Items.Where(i => i.ID != item.ID).ToArray());
|
||||
}
|
||||
|
||||
private void sortUserSkins(List<SkinInfo> skinsList)
|
||||
{
|
||||
// Sort user skins separately from built-in skins
|
||||
skinsList.Sort(firstNonDefaultSkinIndex, skinsList.Count - firstNonDefaultSkinIndex,
|
||||
Comparer<SkinInfo>.Create((a, b) => string.Compare(a.Name, b.Name, StringComparison.OrdinalIgnoreCase)));
|
||||
}
|
||||
|
||||
private class SkinSettingsDropdown : SettingsDropdown<SkinInfo>
|
||||
{
|
||||
protected override OsuDropdown<SkinInfo> CreateDropdown() => new SkinDropdownControl();
|
||||
|
@ -8,7 +8,6 @@ using System.Threading.Tasks;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics.OpenGL.Textures;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
|
@ -124,9 +124,11 @@ namespace osu.Game.Rulesets.UI
|
||||
Debug.Assert(drawableMap.ContainsKey(entry));
|
||||
|
||||
var drawable = drawableMap[entry];
|
||||
|
||||
// OnKilled can potentially change the hitobject's result, so it needs to run first before unbinding.
|
||||
drawable.OnKilled();
|
||||
drawable.OnNewResult -= onNewResult;
|
||||
drawable.OnRevertResult -= onRevertResult;
|
||||
drawable.OnKilled();
|
||||
|
||||
drawableMap.Remove(entry);
|
||||
|
||||
|
@ -8,7 +8,6 @@ using JetBrains.Annotations;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Objects.Drawables;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
@ -20,6 +19,7 @@ using osu.Game.Rulesets.Objects;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
using System.Diagnostics;
|
||||
using osu.Framework.Audio.Sample;
|
||||
|
||||
namespace osu.Game.Rulesets.UI
|
||||
{
|
||||
|
@ -138,6 +138,15 @@ namespace osu.Game.Screens.Edit.Compose.Components.Timeline
|
||||
scrollToTrackTime();
|
||||
}
|
||||
|
||||
protected override bool OnScroll(ScrollEvent e)
|
||||
{
|
||||
// if this is not a precision scroll event, let the editor handle the seek itself (for snapping support)
|
||||
if (!e.AltPressed && !e.IsPrecise)
|
||||
return false;
|
||||
|
||||
return base.OnScroll(e);
|
||||
}
|
||||
|
||||
protected override void UpdateAfterChildren()
|
||||
{
|
||||
base.UpdateAfterChildren();
|
||||
|
@ -103,7 +103,7 @@ namespace osu.Game.Screens.Edit.Setup
|
||||
return Task.CompletedTask;
|
||||
}
|
||||
|
||||
Task ICanAcceptFiles.Import(Stream stream, string filename) => throw new NotImplementedException();
|
||||
Task ICanAcceptFiles.Import(params ImportTask[] tasks) => throw new NotImplementedException();
|
||||
|
||||
protected override void LoadComplete()
|
||||
{
|
||||
|
@ -13,6 +13,11 @@ namespace osu.Game.Screens.Menu
|
||||
|
||||
public void Abort() => AbortConfirm();
|
||||
|
||||
public ExitConfirmOverlay()
|
||||
: base(0.7f)
|
||||
{
|
||||
}
|
||||
|
||||
public bool OnPressed(GlobalAction action)
|
||||
{
|
||||
if (action == GlobalAction.Back)
|
||||
|
@ -23,6 +23,7 @@ using osu.Game.Online;
|
||||
using osu.Game.Online.Chat;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Overlays.BeatmapListing.Panels;
|
||||
using osu.Game.Overlays.BeatmapSet;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Play.HUD;
|
||||
@ -41,6 +42,7 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
private Container difficultyIconContainer;
|
||||
private LinkFlowContainer beatmapText;
|
||||
private LinkFlowContainer authorText;
|
||||
private ExplicitContentBeatmapPill explicitContentPill;
|
||||
private ModDisplay modDisplay;
|
||||
|
||||
private readonly Bindable<BeatmapInfo> beatmap = new Bindable<BeatmapInfo>();
|
||||
@ -116,6 +118,9 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
authorText.AddUserLink(Item.Beatmap.Value?.Metadata.Author);
|
||||
}
|
||||
|
||||
bool hasExplicitContent = Item.Beatmap.Value.BeatmapSet.OnlineInfo?.HasExplicitContent == true;
|
||||
explicitContentPill.Alpha = hasExplicitContent ? 1 : 0;
|
||||
|
||||
modDisplay.Current.Value = requiredMods.ToArray();
|
||||
}
|
||||
|
||||
@ -165,18 +170,37 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(15, 0),
|
||||
Spacing = new Vector2(10f, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
authorText = new LinkFlowContainer { AutoSizeAxes = Axes.Both },
|
||||
modDisplay = new ModDisplay
|
||||
new FillFlowContainer
|
||||
{
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Direction = FillDirection.Horizontal,
|
||||
Spacing = new Vector2(10f, 0),
|
||||
Children = new Drawable[]
|
||||
{
|
||||
authorText = new LinkFlowContainer { AutoSizeAxes = Axes.Both },
|
||||
explicitContentPill = new ExplicitContentBeatmapPill
|
||||
{
|
||||
Alpha = 0f,
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
Margin = new MarginPadding { Top = 3f },
|
||||
}
|
||||
},
|
||||
},
|
||||
new Container
|
||||
{
|
||||
Anchor = Anchor.CentreLeft,
|
||||
Origin = Anchor.CentreLeft,
|
||||
AutoSizeAxes = Axes.Both,
|
||||
Scale = new Vector2(0.4f),
|
||||
DisplayUnrankedText = false,
|
||||
ExpansionMode = ExpansionMode.AlwaysExpanded
|
||||
Child = modDisplay = new ModDisplay
|
||||
{
|
||||
Scale = new Vector2(0.4f),
|
||||
DisplayUnrankedText = false,
|
||||
ExpansionMode = ExpansionMode.AlwaysExpanded
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -225,6 +249,8 @@ namespace osu.Game.Screens.OnlinePlay
|
||||
[Resolved]
|
||||
private BeatmapManager beatmapManager { get; set; }
|
||||
|
||||
public override bool IsPresent => base.IsPresent || Scheduler.HasPendingTasks;
|
||||
|
||||
public PlaylistDownloadButton(PlaylistItem playlistItem)
|
||||
: base(playlistItem.Beatmap.Value.BeatmapSet)
|
||||
{
|
||||
|
@ -13,6 +13,7 @@ using osu.Game.Beatmaps;
|
||||
using osu.Game.Graphics.UserInterface;
|
||||
using osu.Game.Online.Multiplayer;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Overlays.Mods;
|
||||
using osu.Game.Rulesets;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.Select;
|
||||
@ -109,5 +110,9 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
}
|
||||
|
||||
protected override BeatmapDetailArea CreateBeatmapDetailArea() => new PlayBeatmapDetailArea();
|
||||
|
||||
protected override ModSelectOverlay CreateModSelectOverlay() => new ModSelectOverlay(isValidMod);
|
||||
|
||||
private bool isValidMod(Mod mod) => !(mod is ModAutoplay) && (mod as MultiMod)?.Mods.Any(mm => mm is ModAutoplay) != true;
|
||||
}
|
||||
}
|
||||
|
@ -44,6 +44,8 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
[CanBeNull]
|
||||
private IDisposable readyClickOperation;
|
||||
|
||||
private GridContainer mainContent;
|
||||
|
||||
public MultiplayerMatchSubScreen(Room room)
|
||||
{
|
||||
Title = room.RoomID.Value == null ? "New room" : room.Name.Value;
|
||||
@ -55,7 +57,7 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new GridContainer
|
||||
mainContent = new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Content = new[]
|
||||
@ -178,6 +180,19 @@ namespace osu.Game.Screens.OnlinePlay.Multiplayer
|
||||
State = { Value = client.Room == null ? Visibility.Visible : Visibility.Hidden }
|
||||
}
|
||||
};
|
||||
|
||||
if (client.Room == null)
|
||||
{
|
||||
// A new room is being created.
|
||||
// The main content should be hidden until the settings overlay is hidden, signaling the room is ready to be displayed.
|
||||
mainContent.Hide();
|
||||
|
||||
settingsOverlay.State.BindValueChanged(visibility =>
|
||||
{
|
||||
if (visibility.NewValue == Visibility.Hidden)
|
||||
mainContent.Show();
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
|
||||
protected override void LoadComplete()
|
||||
|
@ -33,6 +33,8 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
||||
|
||||
private OverlinedHeader participantsHeader;
|
||||
|
||||
private GridContainer mainContent;
|
||||
|
||||
public PlaylistsRoomSubScreen(Room room)
|
||||
{
|
||||
Title = room.RoomID.Value == null ? "New playlist" : room.Name.Value;
|
||||
@ -44,7 +46,7 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
||||
{
|
||||
InternalChildren = new Drawable[]
|
||||
{
|
||||
new GridContainer
|
||||
mainContent = new GridContainer
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Content = new[]
|
||||
@ -190,6 +192,19 @@ namespace osu.Game.Screens.OnlinePlay.Playlists
|
||||
State = { Value = roomId.Value == null ? Visibility.Visible : Visibility.Hidden }
|
||||
}
|
||||
};
|
||||
|
||||
if (roomId.Value == null)
|
||||
{
|
||||
// A new room is being created.
|
||||
// The main content should be hidden until the settings overlay is hidden, signaling the room is ready to be displayed.
|
||||
mainContent.Hide();
|
||||
|
||||
settingsOverlay.State.BindValueChanged(visibility =>
|
||||
{
|
||||
if (visibility.NewValue == Visibility.Hidden)
|
||||
mainContent.Show();
|
||||
}, true);
|
||||
}
|
||||
}
|
||||
|
||||
[Resolved]
|
||||
|
@ -14,6 +14,7 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
private readonly PlayerSliderBar<double> blurSliderBar;
|
||||
private readonly PlayerCheckbox showStoryboardToggle;
|
||||
private readonly PlayerCheckbox beatmapSkinsToggle;
|
||||
private readonly PlayerCheckbox beatmapColorsToggle;
|
||||
private readonly PlayerCheckbox beatmapHitsoundsToggle;
|
||||
|
||||
public VisualSettings()
|
||||
@ -43,6 +44,7 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
},
|
||||
showStoryboardToggle = new PlayerCheckbox { LabelText = "Storyboard / Video" },
|
||||
beatmapSkinsToggle = new PlayerCheckbox { LabelText = "Beatmap skins" },
|
||||
beatmapColorsToggle = new PlayerCheckbox { LabelText = "Beatmap colours" },
|
||||
beatmapHitsoundsToggle = new PlayerCheckbox { LabelText = "Beatmap hitsounds" }
|
||||
};
|
||||
}
|
||||
@ -54,6 +56,7 @@ namespace osu.Game.Screens.Play.PlayerSettings
|
||||
blurSliderBar.Current = config.GetBindable<double>(OsuSetting.BlurLevel);
|
||||
showStoryboardToggle.Current = config.GetBindable<bool>(OsuSetting.ShowStoryboard);
|
||||
beatmapSkinsToggle.Current = config.GetBindable<bool>(OsuSetting.BeatmapSkins);
|
||||
beatmapColorsToggle.Current = config.GetBindable<bool>(OsuSetting.BeatmapColours);
|
||||
beatmapHitsoundsToggle.Current = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds);
|
||||
}
|
||||
}
|
||||
|
@ -10,6 +10,8 @@ using osu.Framework.Graphics;
|
||||
using osu.Framework.Screens;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Online.Rooms;
|
||||
using osu.Game.Overlays.Mods;
|
||||
using osu.Game.Rulesets.Mods;
|
||||
using osu.Game.Screens.OnlinePlay;
|
||||
using osu.Game.Screens.OnlinePlay.Components;
|
||||
|
||||
@ -78,5 +80,9 @@ namespace osu.Game.Screens.Select
|
||||
item.RequiredMods.Clear();
|
||||
item.RequiredMods.AddRange(Mods.Value.Select(m => m.CreateCopy()));
|
||||
}
|
||||
|
||||
protected override ModSelectOverlay CreateModSelectOverlay() => new ModSelectOverlay(isValidMod);
|
||||
|
||||
private bool isValidMod(Mod mod) => !(mod is ModAutoplay) && (mod as MultiMod)?.Mods.Any(mm => mm is ModAutoplay) != true;
|
||||
}
|
||||
}
|
||||
|
@ -251,11 +251,7 @@ namespace osu.Game.Screens.Select
|
||||
Children = new Drawable[]
|
||||
{
|
||||
BeatmapOptions = new BeatmapOptionsOverlay(),
|
||||
ModSelect = new ModSelectOverlay
|
||||
{
|
||||
Origin = Anchor.BottomCentre,
|
||||
Anchor = Anchor.BottomCentre,
|
||||
}
|
||||
ModSelect = CreateModSelectOverlay()
|
||||
}
|
||||
}
|
||||
}
|
||||
@ -305,6 +301,8 @@ namespace osu.Game.Screens.Select
|
||||
}
|
||||
}
|
||||
|
||||
protected virtual ModSelectOverlay CreateModSelectOverlay() => new ModSelectOverlay();
|
||||
|
||||
protected virtual void ApplyFilterToCarousel(FilterCriteria criteria)
|
||||
{
|
||||
// if not the current screen, we want to get carousel in a good presentation state before displaying (resume or enter).
|
||||
|
@ -15,6 +15,7 @@ namespace osu.Game.Skinning
|
||||
public class BeatmapSkinProvidingContainer : SkinProvidingContainer
|
||||
{
|
||||
private Bindable<bool> beatmapSkins;
|
||||
private Bindable<bool> beatmapColours;
|
||||
private Bindable<bool> beatmapHitsounds;
|
||||
|
||||
protected override bool AllowConfigurationLookup
|
||||
@ -28,6 +29,17 @@ namespace osu.Game.Skinning
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool AllowColourLookup
|
||||
{
|
||||
get
|
||||
{
|
||||
if (beatmapColours == null)
|
||||
throw new InvalidOperationException($"{nameof(BeatmapSkinProvidingContainer)} needs to be loaded before being consumed.");
|
||||
|
||||
return beatmapColours.Value;
|
||||
}
|
||||
}
|
||||
|
||||
protected override bool AllowDrawableLookup(ISkinComponent component)
|
||||
{
|
||||
if (beatmapSkins == null)
|
||||
@ -62,6 +74,7 @@ namespace osu.Game.Skinning
|
||||
var config = parent.Get<OsuConfigManager>();
|
||||
|
||||
beatmapSkins = config.GetBindable<bool>(OsuSetting.BeatmapSkins);
|
||||
beatmapColours = config.GetBindable<bool>(OsuSetting.BeatmapColours);
|
||||
beatmapHitsounds = config.GetBindable<bool>(OsuSetting.BeatmapHitsounds);
|
||||
|
||||
return base.CreateChildDependencies(parent);
|
||||
@ -71,6 +84,7 @@ namespace osu.Game.Skinning
|
||||
private void load()
|
||||
{
|
||||
beatmapSkins.BindValueChanged(_ => TriggerSourceChanged());
|
||||
beatmapColours.BindValueChanged(_ => TriggerSourceChanged());
|
||||
beatmapHitsounds.BindValueChanged(_ => TriggerSourceChanged());
|
||||
}
|
||||
}
|
||||
|
@ -378,8 +378,10 @@ namespace osu.Game.Skinning
|
||||
// kind of wasteful that we throw this away, but should do for now.
|
||||
if (createDrawable() != null)
|
||||
{
|
||||
if (Configuration.LegacyVersion > 1)
|
||||
return new LegacyJudgementPieceNew(resultComponent.Component, createDrawable, getParticleTexture(resultComponent.Component));
|
||||
var particle = getParticleTexture(resultComponent.Component);
|
||||
|
||||
if (particle != null)
|
||||
return new LegacyJudgementPieceNew(resultComponent.Component, createDrawable, particle);
|
||||
else
|
||||
return new LegacyJudgementPieceOld(resultComponent.Component, createDrawable);
|
||||
}
|
||||
|
@ -67,7 +67,7 @@ namespace osu.Game.Skinning
|
||||
}
|
||||
}
|
||||
|
||||
public override void Play()
|
||||
public override void Play(bool restart = true)
|
||||
{
|
||||
cancelPendingStart();
|
||||
RequestedPlaying = true;
|
||||
@ -75,7 +75,7 @@ namespace osu.Game.Skinning
|
||||
if (samplePlaybackDisabled.Value)
|
||||
return;
|
||||
|
||||
base.Play();
|
||||
base.Play(restart);
|
||||
}
|
||||
|
||||
public override void Stop()
|
||||
|
@ -5,7 +5,7 @@ using System;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Audio;
|
||||
|
@ -32,6 +32,8 @@ namespace osu.Game.Skinning
|
||||
|
||||
protected virtual bool AllowConfigurationLookup => true;
|
||||
|
||||
protected virtual bool AllowColourLookup => true;
|
||||
|
||||
public SkinProvidingContainer(ISkin skin)
|
||||
{
|
||||
this.skin = skin;
|
||||
@ -68,7 +70,20 @@ namespace osu.Game.Skinning
|
||||
|
||||
public IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup)
|
||||
{
|
||||
if (AllowConfigurationLookup && skin != null)
|
||||
if (skin != null)
|
||||
{
|
||||
if (lookup is GlobalSkinColours || lookup is SkinCustomColourLookup)
|
||||
return lookupWithFallback<TLookup, TValue>(lookup, AllowColourLookup);
|
||||
|
||||
return lookupWithFallback<TLookup, TValue>(lookup, AllowConfigurationLookup);
|
||||
}
|
||||
|
||||
return fallbackSource?.GetConfig<TLookup, TValue>(lookup);
|
||||
}
|
||||
|
||||
private IBindable<TValue> lookupWithFallback<TLookup, TValue>(TLookup lookup, bool canUseSkinLookup)
|
||||
{
|
||||
if (canUseSkinLookup)
|
||||
{
|
||||
var bindable = skin.GetConfig<TLookup, TValue>(lookup);
|
||||
if (bindable != null)
|
||||
|
@ -7,7 +7,7 @@ using System.Linq;
|
||||
using JetBrains.Annotations;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Audio;
|
||||
using osu.Framework.Audio.Track;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Bindables;
|
||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||
using osu.Framework.Graphics;
|
||||
@ -119,12 +119,13 @@ namespace osu.Game.Skinning
|
||||
/// <summary>
|
||||
/// Plays the samples.
|
||||
/// </summary>
|
||||
public virtual void Play()
|
||||
/// <param name="restart">Whether to play the sample from the beginning.</param>
|
||||
public virtual void Play(bool restart = true)
|
||||
{
|
||||
samplesContainer.ForEach(c =>
|
||||
{
|
||||
if (PlayWhenZeroVolume || c.AggregateVolume.Value > 0)
|
||||
c.Play();
|
||||
c.Play(restart);
|
||||
});
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user