diff --git a/.gitattributes b/.gitattributes
index e3ffd343db..c61ca25cd2 100644
--- a/.gitattributes
+++ b/.gitattributes
@@ -15,6 +15,7 @@ App.config text eol=crlf
*.cmd text eol=crlf
*.snippet text eol=crlf
*.manifest text eol=crlf
+*.licenseheader text eol=crlf
# Check out with lf (UNIX) line endings
*.sh text eol=lf
diff --git a/.github/FUNDING.yml b/.github/FUNDING.yml
new file mode 100644
index 0000000000..0c6b80e97e
--- /dev/null
+++ b/.github/FUNDING.yml
@@ -0,0 +1 @@
+custom: https://osu.ppy.sh/home/support
diff --git a/.github/ISSUE_TEMPLATE/bug-issues.md b/.github/ISSUE_TEMPLATE/bug-issues.md
index 8d85c92fec..c8c41e5a78 100644
--- a/.github/ISSUE_TEMPLATE/bug-issues.md
+++ b/.github/ISSUE_TEMPLATE/bug-issues.md
@@ -1,14 +1,11 @@
---
name: Bug Report
-about: For issues regarding encountered game bugs
+about: Issues regarding encountered bugs.
---
-
-
-
-**Describe your problem:**
+**Describe the bug:**
**Screenshots or videos showing encountered issue:**
-**osu!lazer version:**
+**osu!lazer version:**
-**Logs:**
\ No newline at end of file
+**Logs:**
diff --git a/.github/ISSUE_TEMPLATE/crash-issues.md b/.github/ISSUE_TEMPLATE/crash-issues.md
index 849f042c1f..8ad27e9e31 100644
--- a/.github/ISSUE_TEMPLATE/crash-issues.md
+++ b/.github/ISSUE_TEMPLATE/crash-issues.md
@@ -1,16 +1,13 @@
---
name: Crash Report
-about: For issues regarding game crashes or permanent freezes
+about: Issues regarding crashes or permanent freezes.
---
-
-
-
-**Describe your problem:**
+**Describe the crash:**
**Screenshots or videos showing encountered issue:**
-**osu!lazer version:**
+**osu!lazer version:**
-**Logs:**
+**Logs:**
-**Computer Specifications:**
\ No newline at end of file
+**Computer Specifications:**
diff --git a/.github/ISSUE_TEMPLATE/feature-request-issues.md b/.github/ISSUE_TEMPLATE/feature-request-issues.md
index 73c4f37a3e..54c4ff94e5 100644
--- a/.github/ISSUE_TEMPLATE/feature-request-issues.md
+++ b/.github/ISSUE_TEMPLATE/feature-request-issues.md
@@ -1,10 +1,7 @@
---
name: Feature Request
-about: Let us know what you would like to see in the game!
+about: Features you would like to see in the game!
---
+**Describe the new feature:**
-
-
-**Describe the feature:**
-
-**Proposal designs of the feature:**
+**Proposal designs of the feature:**
diff --git a/.github/ISSUE_TEMPLATE/missing-for-live-issues.md b/.github/ISSUE_TEMPLATE/missing-for-live-issues.md
index ae3cf20a8c..5822da9c65 100644
--- a/.github/ISSUE_TEMPLATE/missing-for-live-issues.md
+++ b/.github/ISSUE_TEMPLATE/missing-for-live-issues.md
@@ -1,10 +1,7 @@
---
name: Missing for Live
-about: Let us know the features you need which are available in osu-stable but not lazer
+about: Features which are available in osu!stable but not yet in osu!lazer.
---
+**Describe the missing feature:**
-
-
-**Describe the feature:**
-
-**Designs:**
+**Proposal designs of the feature:**
diff --git a/.github/pull_request_template.md b/.github/pull_request_template.md
deleted file mode 100644
index 221e4746cb..0000000000
--- a/.github/pull_request_template.md
+++ /dev/null
@@ -1,8 +0,0 @@
-Add any details pertaining to developers above the break.
-
-- [ ] Depends on #PR
-- Closes #ISSUE
-
----
-
-Add a sentence or two describing this change in plain english. This will be displayed on the [changelog](https://osu.ppy.sh/home/changelog). A single screenshot or short gif is also welcomed.
\ No newline at end of file
diff --git a/.gitignore b/.gitignore
index f95a04e517..e60058ab35 100644
--- a/.gitignore
+++ b/.gitignore
@@ -11,8 +11,10 @@
*.userprefs
### Cake ###
-tools/*
-!tools/cakebuild.csproj
+tools/**
+build/tools/**
+
+fastlane/report.xml
# Build results
bin/[Dd]ebug/
@@ -196,6 +198,7 @@ ClientBin/
*.publishsettings
node_modules/
orleans.codegen.cs
+Resource.designer.cs
# Since there are multiple workflows, uncomment next line to ignore bower_components
# (https://github.com/github/gitignore/pull/1529#issuecomment-104372622)
diff --git a/.gitmodules b/.gitmodules
index f1c4f5d172..e69de29bb2 100644
--- a/.gitmodules
+++ b/.gitmodules
@@ -1,3 +0,0 @@
-[submodule "osu-resources"]
- path = osu-resources
- url = https://github.com/ppy/osu-resources
\ No newline at end of file
diff --git a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__catch_.xml b/.idea/.idea.osu/.idea/runConfigurations/CatchRuleset__Tests_.xml
similarity index 67%
rename from .idea/.idea.osu/.idea/runConfigurations/RulesetTests__catch_.xml
rename to .idea/.idea.osu/.idea/runConfigurations/CatchRuleset__Tests_.xml
index 1c988fe6fd..6463dd6ea5 100644
--- a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__catch_.xml
+++ b/.idea/.idea.osu/.idea/runConfigurations/CatchRuleset__Tests_.xml
@@ -1,18 +1,21 @@
-
-
+
+
+
-
+
-
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__mania_.xml b/.idea/.idea.osu/.idea/runConfigurations/ManiaRuleset__Tests_.xml
similarity index 67%
rename from .idea/.idea.osu/.idea/runConfigurations/RulesetTests__mania_.xml
rename to .idea/.idea.osu/.idea/runConfigurations/ManiaRuleset__Tests_.xml
index d7bb0f90f1..0b63b2d966 100644
--- a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__mania_.xml
+++ b/.idea/.idea.osu/.idea/runConfigurations/ManiaRuleset__Tests_.xml
@@ -1,18 +1,21 @@
-
-
+
+
+
-
+
-
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__osu__.xml b/.idea/.idea.osu/.idea/runConfigurations/OsuRuleset__Tests_.xml
similarity index 67%
rename from .idea/.idea.osu/.idea/runConfigurations/RulesetTests__osu__.xml
rename to .idea/.idea.osu/.idea/runConfigurations/OsuRuleset__Tests_.xml
index 997ac6b078..750ece648b 100644
--- a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__osu__.xml
+++ b/.idea/.idea.osu/.idea/runConfigurations/OsuRuleset__Tests_.xml
@@ -1,18 +1,21 @@
-
-
+
+
+
-
+
-
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__taiko_.xml b/.idea/.idea.osu/.idea/runConfigurations/TaikoRuleset__Tests_.xml
similarity index 67%
rename from .idea/.idea.osu/.idea/runConfigurations/RulesetTests__taiko_.xml
rename to .idea/.idea.osu/.idea/runConfigurations/TaikoRuleset__Tests_.xml
index b7a070174c..7b359a1ca0 100644
--- a/.idea/.idea.osu/.idea/runConfigurations/RulesetTests__taiko_.xml
+++ b/.idea/.idea.osu/.idea/runConfigurations/TaikoRuleset__Tests_.xml
@@ -1,18 +1,21 @@
-
-
+
+
+
-
+
-
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu/.idea/runConfigurations/Tournament.xml b/.idea/.idea.osu/.idea/runConfigurations/Tournament.xml
new file mode 100644
index 0000000000..3722f3dc04
--- /dev/null
+++ b/.idea/.idea.osu/.idea/runConfigurations/Tournament.xml
@@ -0,0 +1,20 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu/.idea/runConfigurations/Tournament__Tests_.xml b/.idea/.idea.osu/.idea/runConfigurations/Tournament__Tests_.xml
new file mode 100644
index 0000000000..e2628a1bb4
--- /dev/null
+++ b/.idea/.idea.osu/.idea/runConfigurations/Tournament__Tests_.xml
@@ -0,0 +1,21 @@
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu/.idea/runConfigurations/osu_.xml b/.idea/.idea.osu/.idea/runConfigurations/osu_.xml
index 344301d4a7..7ac6bb745d 100644
--- a/.idea/.idea.osu/.idea/runConfigurations/osu_.xml
+++ b/.idea/.idea.osu/.idea/runConfigurations/osu_.xml
@@ -1,17 +1,20 @@
-
-
+
+
+
-
-
+
+
+
+
\ No newline at end of file
diff --git a/.idea/.idea.osu/.idea/runConfigurations/VisualTests.xml b/.idea/.idea.osu/.idea/runConfigurations/osu___Tests_.xml
similarity index 66%
rename from .idea/.idea.osu/.idea/runConfigurations/VisualTests.xml
rename to .idea/.idea.osu/.idea/runConfigurations/osu___Tests_.xml
index bf5a1f64e0..7fcb7c15ea 100644
--- a/.idea/.idea.osu/.idea/runConfigurations/VisualTests.xml
+++ b/.idea/.idea.osu/.idea/runConfigurations/osu___Tests_.xml
@@ -1,17 +1,20 @@
-
-
+
+
+
-
-
+
+
+
+
\ No newline at end of file
diff --git a/.vscode/launch.json b/.vscode/launch.json
index e9b8d6f397..57ff3e6b43 100644
--- a/.vscode/launch.json
+++ b/.vscode/launch.json
@@ -1,53 +1,18 @@
{
"version": "0.2.0",
- "configurations": [
- {
- "name": "VisualTests (Debug)",
- "type": "coreclr",
- "request": "launch",
- "program": "dotnet",
- "args": [
- "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tests.dll"
- ],
- "cwd": "${workspaceRoot}",
- "preLaunchTask": "Build tests (Debug)",
- "linux": {
- "env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
- }
- },
- "console": "internalConsole"
- },
- {
- "name": "VisualTests (Release)",
- "type": "coreclr",
- "request": "launch",
- "program": "dotnet",
- "args": [
- "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1/osu.Game.Tests.dll"
- ],
- "cwd": "${workspaceRoot}",
- "preLaunchTask": "Build tests (Release)",
- "linux": {
- "env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
- }
- },
- "console": "internalConsole"
- },
- {
+ "configurations": [{
"name": "osu! (Debug)",
"type": "coreclr",
"request": "launch",
"program": "dotnet",
"args": [
- "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1/osu!.dll"
+ "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Debug)",
"linux": {
"env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
+ "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
}
},
"console": "internalConsole"
@@ -58,16 +23,135 @@
"request": "launch",
"program": "dotnet",
"args": [
- "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1/osu!.dll"
+ "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2/osu!.dll"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build osu! (Release)",
"linux": {
"env": {
- "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.1:${env:LD_LIBRARY_PATH}"
+ "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
}
},
"console": "internalConsole"
+ },
+ {
+ "name": "osu! (Tests, Debug)",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "dotnet",
+ "args": [
+ "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tests.dll"
+ ],
+ "cwd": "${workspaceRoot}",
+ "preLaunchTask": "Build tests (Debug)",
+ "linux": {
+ "env": {
+ "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
+ }
+ },
+ "console": "internalConsole"
+ }, {
+ "name": "osu! (Tests, Release)",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "dotnet",
+ "args": [
+ "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2/osu.Game.Tests.dll"
+ ],
+ "cwd": "${workspaceRoot}",
+ "preLaunchTask": "Build tests (Release)",
+ "linux": {
+ "env": {
+ "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
+ }
+ },
+ "console": "internalConsole"
+ },
+ {
+ "name": "Tournament (Debug)",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "dotnet",
+ "args": [
+ "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll",
+ "--tournament"
+ ],
+ "cwd": "${workspaceRoot}",
+ "preLaunchTask": "Build osu! (Debug)",
+ "linux": {
+ "env": {
+ "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
+ }
+ },
+ "console": "internalConsole"
+ },
+ {
+ "name": "Tournament (Release)",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "dotnet",
+ "args": [
+ "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2/osu!.dll",
+ "--tournament"
+ ],
+ "cwd": "${workspaceRoot}",
+ "preLaunchTask": "Build osu! (Release)",
+ "linux": {
+ "env": {
+ "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Desktop/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
+ }
+ },
+ "console": "internalConsole"
+ },
+ {
+ "name": "Tournament (Tests, Debug)",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "dotnet",
+ "args": [
+ "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tournament.Tests.dll",
+ "--tournament"
+ ],
+ "cwd": "${workspaceRoot}",
+ "preLaunchTask": "Build tournament tests (Debug)",
+ "linux": {
+ "env": {
+ "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
+ }
+ },
+ "console": "internalConsole"
+ },
+ {
+ "name": "Tournament (Tests, Release)",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "dotnet",
+ "args": [
+ "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tournament.Tests.dll",
+ "--tournament"
+ ],
+ "cwd": "${workspaceRoot}",
+ "preLaunchTask": "Build tournament tests (Release)",
+ "linux": {
+ "env": {
+ "LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
+ }
+ },
+ "console": "internalConsole"
+ },
+ {
+ "name": "Cake: Debug Script",
+ "type": "coreclr",
+ "request": "launch",
+ "program": "${workspaceRoot}/build/tools/Cake.CoreCLR/0.30.0/Cake.dll",
+ "args": [
+ "${workspaceRoot}/build/build.cake",
+ "--debug",
+ "--verbosity=diagnostic"
+ ],
+ "cwd": "${workspaceRoot}/build",
+ "stopAtEntry": true,
+ "externalConsole": false
}
]
-}
+}
\ No newline at end of file
diff --git a/.vscode/tasks.json b/.vscode/tasks.json
index 188f20b69f..aba590f466 100644
--- a/.vscode/tasks.json
+++ b/.vscode/tasks.json
@@ -2,8 +2,7 @@
// See https://go.microsoft.com/fwlink/?LinkId=733558
// for the documentation about the tasks.json format
"version": "2.0.0",
- "tasks": [
- {
+ "tasks": [{
"label": "Build osu! (Debug)",
"type": "shell",
"command": "dotnet",
@@ -11,7 +10,6 @@
"build",
"--no-restore",
"osu.Desktop",
- "/p:TargetFramework=netcoreapp2.1",
"/p:GenerateFullPaths=true",
"/m",
"/verbosity:m"
@@ -27,7 +25,6 @@
"build",
"--no-restore",
"osu.Desktop",
- "/p:TargetFramework=netcoreapp2.1",
"/p:Configuration=Release",
"/p:GenerateFullPaths=true",
"/m",
@@ -44,7 +41,6 @@
"build",
"--no-restore",
"osu.Game.Tests",
- "/p:TargetFramework=netcoreapp2.1",
"/p:GenerateFullPaths=true",
"/m",
"/verbosity:m"
@@ -60,7 +56,6 @@
"build",
"--no-restore",
"osu.Game.Tests",
- "/p:TargetFramework=netcoreapp2.1",
"/p:Configuration=Release",
"/p:GenerateFullPaths=true",
"/m",
@@ -70,11 +65,42 @@
"problemMatcher": "$msCompile"
},
{
- "label": "Restore (netcoreapp2.1)",
+ "label": "Build tournament tests (Debug)",
"type": "shell",
"command": "dotnet",
"args": [
- "restore"
+ "build",
+ "--no-restore",
+ "osu.Game.Tournament.Tests",
+ "/p:GenerateFullPaths=true",
+ "/m",
+ "/verbosity:m"
+ ],
+ "group": "build",
+ "problemMatcher": "$msCompile"
+ }, {
+ "label": "Build tournament tests (Release)",
+ "type": "shell",
+ "command": "dotnet",
+ "args": [
+ "build",
+ "--no-restore",
+ "osu.Game.Tournament.Tests",
+ "/p:Configuration=Release",
+ "/p:GenerateFullPaths=true",
+ "/m",
+ "/verbosity:m"
+ ],
+ "group": "build",
+ "problemMatcher": "$msCompile"
+ },
+ {
+ "label": "Restore (netcoreapp2.2)",
+ "type": "shell",
+ "command": "dotnet",
+ "args": [
+ "restore",
+ "osu.sln"
],
"problemMatcher": []
}
diff --git a/Gemfile b/Gemfile
new file mode 100644
index 0000000000..cdd3a6b349
--- /dev/null
+++ b/Gemfile
@@ -0,0 +1,6 @@
+source "https://rubygems.org"
+
+gem "fastlane"
+
+plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
+eval_gemfile(plugins_path) if File.exist?(plugins_path)
diff --git a/Gemfile.lock b/Gemfile.lock
new file mode 100644
index 0000000000..17c0db12e7
--- /dev/null
+++ b/Gemfile.lock
@@ -0,0 +1,173 @@
+GEM
+ remote: https://rubygems.org/
+ specs:
+ CFPropertyList (3.0.0)
+ addressable (2.6.0)
+ public_suffix (>= 2.0.2, < 4.0)
+ atomos (0.1.3)
+ babosa (1.0.2)
+ claide (1.0.2)
+ colored (1.2)
+ colored2 (3.1.2)
+ commander-fastlane (4.4.6)
+ highline (~> 1.7.2)
+ declarative (0.0.10)
+ declarative-option (0.1.0)
+ digest-crc (0.4.1)
+ domain_name (0.5.20180417)
+ unf (>= 0.0.5, < 1.0.0)
+ dotenv (2.7.1)
+ emoji_regex (1.0.1)
+ excon (0.62.0)
+ faraday (0.15.4)
+ multipart-post (>= 1.2, < 3)
+ faraday-cookie_jar (0.0.6)
+ faraday (>= 0.7.4)
+ http-cookie (~> 1.0.0)
+ faraday_middleware (0.13.1)
+ faraday (>= 0.7.4, < 1.0)
+ fastimage (2.1.5)
+ fastlane (2.117.0)
+ CFPropertyList (>= 2.3, < 4.0.0)
+ addressable (>= 2.3, < 3.0.0)
+ babosa (>= 1.0.2, < 2.0.0)
+ bundler (>= 1.12.0, < 3.0.0)
+ colored
+ commander-fastlane (>= 4.4.6, < 5.0.0)
+ dotenv (>= 2.1.1, < 3.0.0)
+ emoji_regex (>= 0.1, < 2.0)
+ excon (>= 0.45.0, < 1.0.0)
+ faraday (~> 0.9)
+ faraday-cookie_jar (~> 0.0.6)
+ faraday_middleware (~> 0.9)
+ fastimage (>= 2.1.0, < 3.0.0)
+ gh_inspector (>= 1.1.2, < 2.0.0)
+ google-api-client (>= 0.21.2, < 0.24.0)
+ google-cloud-storage (>= 1.15.0, < 2.0.0)
+ highline (>= 1.7.2, < 2.0.0)
+ json (< 3.0.0)
+ mini_magick (~> 4.5.1)
+ multi_json
+ multi_xml (~> 0.5)
+ multipart-post (~> 2.0.0)
+ plist (>= 3.1.0, < 4.0.0)
+ public_suffix (~> 2.0.0)
+ rubyzip (>= 1.2.2, < 2.0.0)
+ security (= 0.1.3)
+ simctl (~> 1.6.3)
+ slack-notifier (>= 2.0.0, < 3.0.0)
+ terminal-notifier (>= 1.6.2, < 2.0.0)
+ terminal-table (>= 1.4.5, < 2.0.0)
+ tty-screen (>= 0.6.3, < 1.0.0)
+ tty-spinner (>= 0.8.0, < 1.0.0)
+ word_wrap (~> 1.0.0)
+ xcodeproj (>= 1.6.0, < 2.0.0)
+ xcpretty (~> 0.3.0)
+ xcpretty-travis-formatter (>= 0.0.3)
+ fastlane-plugin-clean_testflight_testers (0.2.0)
+ fastlane-plugin-souyuz (0.8.1)
+ souyuz (>= 0.8.1)
+ fastlane-plugin-xamarin (0.6.3)
+ gh_inspector (1.1.3)
+ google-api-client (0.23.9)
+ addressable (~> 2.5, >= 2.5.1)
+ googleauth (>= 0.5, < 0.7.0)
+ httpclient (>= 2.8.1, < 3.0)
+ mime-types (~> 3.0)
+ representable (~> 3.0)
+ retriable (>= 2.0, < 4.0)
+ signet (~> 0.9)
+ google-cloud-core (1.3.0)
+ google-cloud-env (~> 1.0)
+ google-cloud-env (1.0.5)
+ faraday (~> 0.11)
+ google-cloud-storage (1.16.0)
+ digest-crc (~> 0.4)
+ google-api-client (~> 0.23)
+ google-cloud-core (~> 1.2)
+ googleauth (>= 0.6.2, < 0.10.0)
+ googleauth (0.6.7)
+ faraday (~> 0.12)
+ jwt (>= 1.4, < 3.0)
+ memoist (~> 0.16)
+ multi_json (~> 1.11)
+ os (>= 0.9, < 2.0)
+ signet (~> 0.7)
+ highline (1.7.10)
+ http-cookie (1.0.3)
+ domain_name (~> 0.5)
+ httpclient (2.8.3)
+ json (2.2.0)
+ jwt (2.1.0)
+ memoist (0.16.0)
+ mime-types (3.2.2)
+ mime-types-data (~> 3.2015)
+ mime-types-data (3.2018.0812)
+ mini_magick (4.5.1)
+ mini_portile2 (2.4.0)
+ multi_json (1.13.1)
+ multi_xml (0.6.0)
+ multipart-post (2.0.0)
+ nanaimo (0.2.6)
+ naturally (2.2.0)
+ nokogiri (1.10.1)
+ mini_portile2 (~> 2.4.0)
+ os (1.0.0)
+ plist (3.5.0)
+ public_suffix (2.0.5)
+ representable (3.0.4)
+ declarative (< 0.1.0)
+ declarative-option (< 0.2.0)
+ uber (< 0.2.0)
+ retriable (3.1.2)
+ rouge (2.0.7)
+ rubyzip (1.2.2)
+ security (0.1.3)
+ signet (0.11.0)
+ addressable (~> 2.3)
+ faraday (~> 0.9)
+ jwt (>= 1.5, < 3.0)
+ multi_json (~> 1.10)
+ simctl (1.6.5)
+ CFPropertyList
+ naturally
+ slack-notifier (2.3.2)
+ souyuz (0.8.1)
+ fastlane (>= 2.29.0)
+ highline (~> 1.7)
+ nokogiri (~> 1.7)
+ terminal-notifier (1.8.0)
+ terminal-table (1.8.0)
+ unicode-display_width (~> 1.1, >= 1.1.1)
+ tty-cursor (0.6.1)
+ tty-screen (0.6.5)
+ tty-spinner (0.9.0)
+ tty-cursor (~> 0.6.0)
+ uber (0.1.0)
+ unf (0.1.4)
+ unf_ext
+ unf_ext (0.0.7.5)
+ unicode-display_width (1.4.1)
+ word_wrap (1.0.0)
+ xcodeproj (1.8.1)
+ CFPropertyList (>= 2.3.3, < 4.0)
+ atomos (~> 0.1.3)
+ claide (>= 1.0.2, < 2.0)
+ colored2 (~> 3.1)
+ nanaimo (~> 0.2.6)
+ xcpretty (0.3.0)
+ rouge (~> 2.0.7)
+ xcpretty-travis-formatter (1.0.0)
+ xcpretty (~> 0.2, >= 0.0.7)
+
+PLATFORMS
+ ruby
+
+DEPENDENCIES
+ fastlane
+ fastlane-plugin-clean_testflight_testers
+ fastlane-plugin-souyuz
+ fastlane-plugin-xamarin
+
+BUNDLED WITH
+ 2.0.1
diff --git a/ISSUE_TEMPLATE.md b/ISSUE_TEMPLATE.md
deleted file mode 100644
index 2bff304fba..0000000000
--- a/ISSUE_TEMPLATE.md
+++ /dev/null
@@ -1,11 +0,0 @@
-osu!lazer is currently still under heavy development!
-
-Please ensure that you are making an issue for one of the following:
-
-- A bug with currently implemented features (not features that don't exist)
-- A feature you are considering adding, so we can collaborate on feedback and design.
-- Discussions about technical design decisions
-
-If your issue qualifies, replace this text with a detailed description of your issue with as much relevant information as you can provide.
-
-Screenshots and log files are highly welcomed.
\ No newline at end of file
diff --git a/LICENCE b/LICENCE
index a11a7ce75b..21c6a7090f 100644
--- a/LICENCE
+++ b/LICENCE
@@ -1,4 +1,4 @@
-Copyright (c) 2007-2018 ppy Pty Ltd .
+Copyright (c) 2019 ppy Pty Ltd .
Permission is hereby granted, free of charge, to any person obtaining a copy
of this software and associated documentation files (the "Software"), to deal
diff --git a/README.md b/README.md
index baaba22726..52fc29cb98 100644
--- a/README.md
+++ b/README.md
@@ -1,47 +1,108 @@
-# osu! [](https://ci.appveyor.com/project/peppy/osu) [](https://www.codefactor.io/repository/github/ppy/osu) [](https://discord.gg/ppy)
+
+
+
+
+# osu!
+
+[](https://ci.appveyor.com/project/peppy/osu) [](https://www.codefactor.io/repository/github/ppy/osu) [](https://discord.gg/ppy)
Rhythm is just a *click* away. The future of [osu!](https://osu.ppy.sh) and the beginning of an open era! Commonly known by the codename "osu!lazer". Pew pew.
-# Status
+## Status
This project is still heavily under development, but is in a state where users are encouraged to try it out and keep it installed alongside the stable osu! client. It will continue to evolve over the coming months and hopefully bring some new unique features to the table.
We are accepting bug reports (please report with as much detail as possible). Feature requests are welcome as long as you read and understand the contribution guidelines listed below.
-# Requirements
+Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh/home/changelog).
-- A desktop platform with the [.NET Core SDK 2.1](https://www.microsoft.com/net/learn/get-started) or higher installed.
-- When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio Community Edition](https://www.visualstudio.com/) (Windows), [Visual Studio Code](https://code.visualstudio.com/) (with the C# plugin installed) or [Jetbrains Rider](https://www.jetbrains.com/rider/) (commercial).
+## Requirements
-# Building and running
+- A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed.
+- When working with the codebase, we recommend using an IDE with intellisense and syntax highlighting, such as [Visual Studio 2017+](https://visualstudio.microsoft.com/vs/), [Jetbrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/).
+- Note that there are **[additional requirements for Windows 7 and Windows 8.1](https://docs.microsoft.com/en-us/dotnet/core/windows-prerequisites?tabs=netcore2x)** which you may need to manually install if your operating system is not up-to-date.
-If you are not interested in developing the game, please head over to the [releases](https://github.com/ppy/osu/releases) to download a precompiled build with automatic updating enabled (download and run the install executable for your platform).
+## Running osu!
-Clone the repository including submodules
+### Releases
-`git clone --recurse-submodules https://github.com/ppy/osu`
+If you are not interested in developing the game, you can still consume our [binary releases](https://github.com/ppy/osu/releases).
-Build and run
+**Latest build:**
-- Using Visual Studio 2017, Rider or Visual Studio Code (configurations are included)
-- From command line using `dotnet run --project osu.Desktop`. When building for non-development purposes, add `-c Release` to gain higher performance.
-- To run with code analysis, instead use `powershell ./build.ps1` or `build.sh`. This is currently only supported under windows due to [resharper cli shortcomings](https://youtrack.jetbrains.com/issue/RSRP-410004). Alternative, you can install resharper or use rider to get inline support in your IDE of choice.
+| [Windows (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.12+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) |
+| ------------- | ------------- |
-Note: If you run from command line under linux, you will need to prefix the output folder to your `LD_LIBRARY_PATH`. See `.vscode/launch.json` for an example
+- **Linux** users are recommended to self-compile until we have official deployment in place.
+- **iOS** users can join the [TestFlight beta program](https://t.co/PasE1zrHhw) (note that due to high demand this is regularly full).
+- **Android** users can self-compile, and expect a public beta soon.
-If you run into issues building you may need to restore nuget packages (commonly via `dotnet restore`). Visual Studio Code users must run `Restore` task from debug tab before attempt to build.
+If your platform is not listed above, there is still a chance you can manually build it by following the instructions below.
-# Contributing
+### Downloading the source code
+
+Clone the repository:
+
+```shell
+git clone https://github.com/ppy/osu
+cd osu
+```
+
+To update the source code to the latest commit, run the following command inside the `osu` directory:
+
+```shell
+git pull
+```
+
+### Building
+
+Build configurations for the recommended IDEs (listed above) are included. You should use the provided Build/Run functionality of your IDE to get things going. When testing or building new components, it's highly encouraged you use the `VisualTests` project/configuration. More information on this provided [below](#contributing).
+
+> Visual Studio Code users must run the `Restore` task before any build attempt.
+
+You can also build and run osu! from the command-line with a single command:
+
+```shell
+dotnet run --project osu.Desktop
+```
+
+If you are not interested in debugging osu!, you can add `-c Release` to gain performance. In this case, you must replace `Debug` with `Release` in any commands mentioned in this document.
+
+If the build fails, try to restore nuget packages with `dotnet restore`.
+
+#### A note for Linux users
+
+On Linux, the environment variable `LD_LIBRARY_PATH` must point to the build directory, located at `osu.Desktop/bin/Debug/$NETCORE_VERSION`.
+
+`$NETCORE_VERSION` is the version of the targeted .NET Core SDK. You can check it by running `grep TargetFramework osu.Desktop/osu.Desktop.csproj | sed -r 's/.*>(.*)<\/.*/\1/'`.
+
+For example, you can run osu! with the following command:
+
+```shell
+LD_LIBRARY_PATH="$(pwd)/osu.Desktop/bin/Debug/netcoreapp2.2" dotnet run --project osu.Desktop
+```
+
+### Testing with resource/framework modifications
+
+Sometimes it may be necessary to cross-test changes in [osu-resources](https://github.com/ppy/osu-resources) or [osu-framework](https://github.com/ppy/osu-framework). This can be achieved by running some commands as documented on the [osu-resources](https://github.com/ppy/osu-resources/wiki/Testing-local-resources-checkout-with-other-projects) and [osu-framework](https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects) wiki pages.
+
+### Code analysis
+
+Code analysis can be run with `powershell ./build.ps1` or `build.sh`. This is currently only supported under windows due to [resharper cli shortcomings](https://youtrack.jetbrains.com/issue/RSRP-410004). Alternatively, you can install resharper or use rider to get inline support in your IDE of choice.
+
+## Contributing
We welcome all contributions, but keep in mind that we already have a lot of the UI designed. If you wish to work on something with the intention on having it included in the official distribution, please open an issue for discussion and we will give you what you need from a design perspective to proceed. If you want to make *changes* to the design, we recommend you open an issue with your intentions before spending too much time, to ensure no effort is wasted.
-Please make sure you are familiar with the [development and testing](https://github.com/ppy/osu-framework/wiki/Development-and-Testing) procedure we have set up. New component development, and where possible, bug fixing and debugging existing components **should always be done under VisualTests**.
+If you're unsure of what you can help with, check out the [list of open issues](https://github.com/ppy/osu/issues) (especially those with the ["good first issue"](https://github.com/ppy/osu/issues?q=is%3Aissue+is%3Aopen+sort%3Aupdated-desc+label%3A%22good+first+issue%22) label).
-Contributions can be made via pull requests to this repository. We hope to credit and reward larger contributions via a [bounty system](https://www.bountysource.com/teams/ppy). If you're unsure of what you can help with, check out the [list of open issues](https://github.com/ppy/osu/issues).
+Before starting, please make sure you are familiar with the [development and testing](https://github.com/ppy/osu-framework/wiki/Development-and-Testing) procedure we have set up. New component development, and where possible, bug fixing and debugging existing components **should always be done under VisualTests**.
-Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured; with any libraries we are using; with any processes involved with contributing, *please* bring it up. I welcome all feedback so we can make contributing to this project as pain-free as possible.
+Note that while we already have certain standards in place, nothing is set in stone. If you have an issue with the way code is structured; with any libraries we are using; with any processes involved with contributing, *please* bring it up. We welcome all feedback so we can make contributing to this project as pain-free as possible.
-# Licence
+For those interested, we love to reward quality contributions via [bounties](https://docs.google.com/spreadsheets/d/1jNXfj_S3Pb5PErA-czDdC9DUu4IgUbe1Lt8E7CYUJuE/view?&rm=minimal#gid=523803337), paid out via paypal or osu! supporter tags. Don't hesitate to [request a bounty](https://docs.google.com/forms/d/e/1FAIpQLSet_8iFAgPMG526pBZ2Kic6HSh7XPM3fE8xPcnWNkMzINDdYg/viewform) for your work on this project.
+
+## Licence
The osu! client code and framework are licensed under the [MIT licence](https://opensource.org/licenses/MIT). Please see [the licence file](LICENCE) for more information. [tl;dr](https://tldrlegal.com/license/mit-license) you can do whatever you want as long as you include the original copyright and license notice in any copy of the software/source.
diff --git a/appveyor.yml b/appveyor.yml
index 1f485485da..4dcaa7b45e 100644
--- a/appveyor.yml
+++ b/appveyor.yml
@@ -1,6 +1,6 @@
clone_depth: 1
version: '{branch}-{build}'
-image: Visual Studio 2017
+image: Previous Visual Studio 2017
test: off
install:
- cmd: git submodule update --init --recursive --depth=5
diff --git a/assets/lazer.png b/assets/lazer.png
new file mode 100644
index 0000000000..1e40e844cc
Binary files /dev/null and b/assets/lazer.png differ
diff --git a/build.ps1 b/build.ps1
index 9968673c90..c6a0bf6d4a 100644
--- a/build.ps1
+++ b/build.ps1
@@ -41,27 +41,28 @@ Param(
[switch]$ShowDescription,
[Alias("WhatIf", "Noop")]
[switch]$DryRun,
- [Parameter(Position=0,Mandatory=$false,ValueFromRemainingArguments=$true)]
+ [Parameter(Position = 0, Mandatory = $false, ValueFromRemainingArguments = $true)]
[string[]]$ScriptArgs
)
Write-Host "Preparing to run build script..."
# Determine the script root for resolving other paths.
-if(!$PSScriptRoot){
+if(!$PSScriptRoot) {
$PSScriptRoot = Split-Path $MyInvocation.MyCommand.Path -Parent
}
# Resolve the paths for resources used for debugging.
-$TOOLS_DIR = Join-Path $PSScriptRoot "tools"
-$CAKE_CSPROJ = Join-Path $TOOLS_DIR "cakebuild.csproj"
+$BUILD_DIR = Join-Path $PSScriptRoot "build"
+$TOOLS_DIR = Join-Path $BUILD_DIR "tools"
+$CAKE_CSPROJ = Join-Path $BUILD_DIR "cakebuild.csproj"
# Install the required tools locally.
Write-Host "Restoring cake tools..."
Invoke-Expression "dotnet restore `"$CAKE_CSPROJ`" --packages `"$TOOLS_DIR`"" | Out-Null
# Find the Cake executable
-$CAKE_EXECUTABLE = (Get-ChildItem -Path ./tools/cake.coreclr/ -Filter Cake.dll -Recurse).FullName
+$CAKE_EXECUTABLE = (Get-ChildItem -Path "$TOOLS_DIR/cake.coreclr/" -Filter Cake.dll -Recurse).FullName
# Build Cake arguments
$cakeArguments = @("$Script");
@@ -75,5 +76,7 @@ $cakeArguments += $ScriptArgs
# Start Cake
Write-Host "Running build script..."
+Push-Location -Path $BUILD_DIR
Invoke-Expression "dotnet `"$CAKE_EXECUTABLE`" $cakeArguments"
+Pop-Location
exit $LASTEXITCODE
diff --git a/build.sh b/build.sh
index caf1702f41..8f1ef5b455 100755
--- a/build.sh
+++ b/build.sh
@@ -6,12 +6,13 @@
echo "Preparing to run build script..."
+cd build
SCRIPT_DIR=$( cd "$( dirname "${BASH_SOURCE[0]}" )" && pwd )
TOOLS_DIR=$SCRIPT_DIR/tools
CAKE_BINARY_PATH=$TOOLS_DIR/"cake.coreclr"
SCRIPT="build.cake"
-CAKE_CSPROJ=$TOOLS_DIR/"cakebuild.csproj"
+CAKE_CSPROJ=$SCRIPT_DIR/"cakebuild.csproj"
# Parse arguments.
CAKE_ARGUMENTS=()
diff --git a/build.cake b/build/build.cake
similarity index 68%
rename from build.cake
rename to build/build.cake
index bc7dfafb8c..1d2588de49 100644
--- a/build.cake
+++ b/build/build.cake
@@ -1,6 +1,7 @@
#addin "nuget:?package=CodeFileSanity&version=0.0.21"
-#addin "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2018.2.2"
+#addin "nuget:?package=JetBrains.ReSharper.CommandLineTools&version=2019.1.1"
#tool "nuget:?package=NVika.MSBuild&version=1.0.1"
+var nVikaToolPath = GetFiles("./tools/NVika.MSBuild.*/tools/NVika.exe").First();
///////////////////////////////////////////////////////////////////////////////
// ARGUMENTS
@@ -9,30 +10,24 @@
var target = Argument("target", "Build");
var configuration = Argument("configuration", "Release");
-var osuSolution = new FilePath("./osu.sln");
+var rootDirectory = new DirectoryPath("..");
+var solution = rootDirectory.CombineWithFilePath("osu.sln");
///////////////////////////////////////////////////////////////////////////////
// TASKS
///////////////////////////////////////////////////////////////////////////////
-Task("Restore")
- .Does(() => {
- DotNetCoreRestore(osuSolution.FullPath);
- });
-
Task("Compile")
- .IsDependentOn("Restore")
.Does(() => {
- DotNetCoreBuild(osuSolution.FullPath, new DotNetCoreBuildSettings {
+ DotNetCoreBuild(solution.FullPath, new DotNetCoreBuildSettings {
Configuration = configuration,
- NoRestore = true,
});
});
Task("Test")
.IsDependentOn("Compile")
.Does(() => {
- var testAssemblies = GetFiles("**/*.Tests/bin/**/*.Tests.dll");
+ var testAssemblies = GetFiles(rootDirectory + "/**/*.Tests/bin/**/*.Tests.dll");
DotNetCoreVSTest(testAssemblies, new DotNetCoreVSTestSettings {
Logger = AppVeyor.IsRunningOnAppVeyor ? "Appveyor" : $"trx",
@@ -46,20 +41,20 @@ Task("InspectCode")
.WithCriteria(IsRunningOnWindows())
.IsDependentOn("Compile")
.Does(() => {
- var nVikaToolPath = GetFiles("./tools/NVika.MSBuild.*/tools/NVika.exe").First();
-
- InspectCode(osuSolution, new InspectCodeSettings {
+ InspectCode(solution, new InspectCodeSettings {
CachesHome = "inspectcode",
OutputFile = "inspectcodereport.xml",
});
- StartProcess(nVikaToolPath, @"parsereport ""inspectcodereport.xml"" --treatwarningsaserrors");
+ int returnCode = StartProcess(nVikaToolPath, $@"parsereport ""inspectcodereport.xml"" --treatwarningsaserrors");
+ if (returnCode != 0)
+ throw new Exception($"inspectcode failed with return code {returnCode}");
});
Task("CodeFileSanity")
.Does(() => {
ValidateCodeSanity(new ValidateCodeSanitySettings {
- RootDirectory = ".",
+ RootDirectory = rootDirectory.FullPath,
IsAppveyorBuild = AppVeyor.IsRunningOnAppVeyor
});
});
diff --git a/tools/cakebuild.csproj b/build/cakebuild.csproj
similarity index 100%
rename from tools/cakebuild.csproj
rename to build/cakebuild.csproj
diff --git a/fastlane/Appfile b/fastlane/Appfile
new file mode 100644
index 0000000000..083de66985
--- /dev/null
+++ b/fastlane/Appfile
@@ -0,0 +1,2 @@
+app_identifier("sh.ppy.osulazer") # The bundle identifier of your app
+apple_id("apple-dev@ppy.sh") # Your Apple email address
diff --git a/fastlane/Fastfile b/fastlane/Fastfile
new file mode 100644
index 0000000000..48c16caf0f
--- /dev/null
+++ b/fastlane/Fastfile
@@ -0,0 +1,65 @@
+update_fastlane
+
+default_platform(:ios)
+
+platform :ios do
+ lane :testflight_prune_dry do
+ clean_testflight_testers(days_of_inactivity:45, dry_run: true)
+ end
+
+ # Specify a custom number for what's "inactive"
+ lane :testflight_prune do
+ clean_testflight_testers(days_of_inactivity: 45) # 120 days, so about 4 months
+ end
+
+ lane :update_version do |options|
+ options[:plist_path] = '../osu.iOS/Info.plist'
+ app_version(options)
+ end
+
+ desc 'Deploy to testflight'
+ lane :beta do |options|
+ update_version(options)
+
+ provision(
+ type: 'appstore'
+ )
+
+ build(
+ build_configuration: 'Release',
+ build_platform: 'iPhone'
+ )
+
+ client = HTTPClient.new
+ changelog = client.get_content 'https://gist.githubusercontent.com/peppy/ab89c29dcc0dce95f39eb218e8fad197/raw'
+ changelog.gsub!('$BUILD_ID', options[:build])
+
+ pilot(
+ wait_processing_interval: 1800,
+ changelog: changelog,
+ ipa: './osu.iOS/bin/iPhone/Release/osu.iOS.ipa'
+ )
+ end
+
+ desc 'Compile the project'
+ lane :build do
+ nuget_restore(
+ project_path: 'osu.iOS.sln'
+ )
+
+ souyuz(
+ platform: "ios",
+ build_target: "osu_iOS",
+ plist_path: "../osu.iOS/Info.plist"
+ )
+ end
+
+ desc 'Install provisioning profiles using match'
+ lane :provision do |options|
+ if Helper.is_ci?
+ options[:readonly] = true
+ end
+
+ match(options)
+ end
+end
diff --git a/fastlane/Matchfile b/fastlane/Matchfile
new file mode 100644
index 0000000000..40c974b09e
--- /dev/null
+++ b/fastlane/Matchfile
@@ -0,0 +1 @@
+git_url('https://github.com/peppy/apple-certificates')
diff --git a/fastlane/Pluginfile b/fastlane/Pluginfile
new file mode 100644
index 0000000000..9f4f47f213
--- /dev/null
+++ b/fastlane/Pluginfile
@@ -0,0 +1,7 @@
+# Autogenerated by fastlane
+#
+# Ensure this file is checked in to source control!
+
+gem 'fastlane-plugin-clean_testflight_testers'
+gem 'fastlane-plugin-souyuz'
+gem 'fastlane-plugin-xamarin'
diff --git a/fastlane/README.md b/fastlane/README.md
new file mode 100644
index 0000000000..53bbc62cae
--- /dev/null
+++ b/fastlane/README.md
@@ -0,0 +1,54 @@
+fastlane documentation
+================
+# Installation
+
+Make sure you have the latest version of the Xcode command line tools installed:
+
+```
+xcode-select --install
+```
+
+Install _fastlane_ using
+```
+[sudo] gem install fastlane -NV
+```
+or alternatively using `brew cask install fastlane`
+
+# Available Actions
+## iOS
+### ios testflight_prune_dry
+```
+fastlane ios testflight_prune_dry
+```
+
+### ios testflight_prune
+```
+fastlane ios testflight_prune
+```
+
+### ios update_version
+```
+fastlane ios update_version
+```
+
+### ios beta
+```
+fastlane ios beta
+```
+Deploy to testflight
+### ios build
+```
+fastlane ios build
+```
+Compile the project
+### ios provision
+```
+fastlane ios provision
+```
+Install provisioning profiles using match
+
+----
+
+This README.md is auto-generated and will be re-generated every time [fastlane](https://fastlane.tools) is run.
+More information about fastlane can be found on [fastlane.tools](https://fastlane.tools).
+The documentation of fastlane can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
diff --git a/osu-resources b/osu-resources
deleted file mode 160000
index 694cb03f19..0000000000
--- a/osu-resources
+++ /dev/null
@@ -1 +0,0 @@
-Subproject commit 694cb03f19c93106ed0f2593f3e506e835fb652a
diff --git a/osu.Android.props b/osu.Android.props
new file mode 100644
index 0000000000..6744590f0d
--- /dev/null
+++ b/osu.Android.props
@@ -0,0 +1,68 @@
+
+
+ bin\$(Configuration)
+ 4
+ 2.0
+ false
+ false
+ default
+ Library
+ 512
+ Off
+ True
+ Xamarin.Android.Net.AndroidClientHandler
+ v9.0
+ false
+
+
+ True
+ portable
+ False
+ DEBUG;TRACE
+ prompt
+ false
+ false
+ SdkOnly
+ true
+ false
+ cjk,mideast,other,rare,west
+ true
+ armeabi-v7a;x86;arm64-v8a
+ true
+
+
+ false
+ None
+ True
+ prompt
+ true
+ false
+ SdkOnly
+ False
+ true
+ cjk,mideast,other,rare,west
+ true
+ armeabi-v7a;x86;arm64-v8a
+ true
+
+
+
+ osu.licenseheader
+
+
+ Always
+
+
+
+
+
+
+
+
+
+
+
+
+
+
+
diff --git a/osu.Android.sln b/osu.Android.sln
new file mode 100644
index 0000000000..ebf2c55cb4
--- /dev/null
+++ b/osu.Android.sln
@@ -0,0 +1,126 @@
+
+Microsoft Visual Studio Solution File, Format Version 12.00
+# Visual Studio Version 16
+VisualStudioVersion = 16.0.28516.95
+MinimumVisualStudioVersion = 10.0.40219.1
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game", "osu.Game\osu.Game.csproj", "{2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Osu", "osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj", "{C92A607B-1FDD-4954-9F92-03FF547D9080}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Catch", "osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj", "{58F6C80C-1253-4A0E-A465-B8C85EBEADF3}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Taiko", "osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj", "{F167E17A-7DE6-4AF5-B920-A5112296C695}"
+EndProject
+Project("{9A19103F-16F7-4668-BE54-9A1E7A4F7556}") = "osu.Game.Rulesets.Mania", "osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj", "{48F4582B-7687-4621-9CBE-5C24197CB536}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Android", "osu.Android\osu.Android.csproj", "{D1D5F9A8-B40B-40E6-B02F-482D03346D3D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Catch.Tests.Android", "osu.Game.Rulesets.Catch.Tests.Android\osu.Game.Rulesets.Catch.Tests.Android.csproj", "{C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Mania.Tests.Android", "osu.Game.Rulesets.Mania.Tests.Android\osu.Game.Rulesets.Mania.Tests.Android.csproj", "{531F1092-DB27-445D-AA33-2A77C7187C99}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Osu.Tests.Android", "osu.Game.Rulesets.Osu.Tests.Android\osu.Game.Rulesets.Osu.Tests.Android.csproj", "{90CAB706-39CB-4B93-9629-3218A6FF8E9B}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Rulesets.Taiko.Tests.Android", "osu.Game.Rulesets.Taiko.Tests.Android\osu.Game.Rulesets.Taiko.Tests.Android.csproj", "{3701A0A1-8476-42C6-B5C4-D24129B4A484}"
+EndProject
+Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "osu.Game.Tests.Android", "osu.Game.Tests.Android\osu.Game.Tests.Android.csproj", "{5CC222DC-5716-4499-B897-DCBDDA4A5CF9}"
+EndProject
+Global
+ GlobalSection(SolutionConfigurationPlatforms) = preSolution
+ Debug|Any CPU = Debug|Any CPU
+ Release|Any CPU = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(ProjectConfigurationPlatforms) = postSolution
+ {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C92A607B-1FDD-4954-9F92-03FF547D9080}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C92A607B-1FDD-4954-9F92-03FF547D9080}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C92A607B-1FDD-4954-9F92-03FF547D9080}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C92A607B-1FDD-4954-9F92-03FF547D9080}.Release|Any CPU.Build.0 = Release|Any CPU
+ {58F6C80C-1253-4A0E-A465-B8C85EBEADF3}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {58F6C80C-1253-4A0E-A465-B8C85EBEADF3}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {58F6C80C-1253-4A0E-A465-B8C85EBEADF3}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {58F6C80C-1253-4A0E-A465-B8C85EBEADF3}.Release|Any CPU.Build.0 = Release|Any CPU
+ {F167E17A-7DE6-4AF5-B920-A5112296C695}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {F167E17A-7DE6-4AF5-B920-A5112296C695}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {F167E17A-7DE6-4AF5-B920-A5112296C695}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {F167E17A-7DE6-4AF5-B920-A5112296C695}.Release|Any CPU.Build.0 = Release|Any CPU
+ {48F4582B-7687-4621-9CBE-5C24197CB536}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {48F4582B-7687-4621-9CBE-5C24197CB536}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {48F4582B-7687-4621-9CBE-5C24197CB536}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {48F4582B-7687-4621-9CBE-5C24197CB536}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {D1D5F9A8-B40B-40E6-B02F-482D03346D3D}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Release|Any CPU.Build.0 = Release|Any CPU
+ {C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {531F1092-DB27-445D-AA33-2A77C7187C99}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {531F1092-DB27-445D-AA33-2A77C7187C99}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {531F1092-DB27-445D-AA33-2A77C7187C99}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {531F1092-DB27-445D-AA33-2A77C7187C99}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {531F1092-DB27-445D-AA33-2A77C7187C99}.Release|Any CPU.Build.0 = Release|Any CPU
+ {531F1092-DB27-445D-AA33-2A77C7187C99}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Release|Any CPU.Build.0 = Release|Any CPU
+ {90CAB706-39CB-4B93-9629-3218A6FF8E9B}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {3701A0A1-8476-42C6-B5C4-D24129B4A484}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {3701A0A1-8476-42C6-B5C4-D24129B4A484}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {3701A0A1-8476-42C6-B5C4-D24129B4A484}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {3701A0A1-8476-42C6-B5C4-D24129B4A484}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {3701A0A1-8476-42C6-B5C4-D24129B4A484}.Release|Any CPU.Build.0 = Release|Any CPU
+ {3701A0A1-8476-42C6-B5C4-D24129B4A484}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ {5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
+ {5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Debug|Any CPU.Build.0 = Debug|Any CPU
+ {5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Debug|Any CPU.Deploy.0 = Debug|Any CPU
+ {5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Release|Any CPU.ActiveCfg = Release|Any CPU
+ {5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Release|Any CPU.Build.0 = Release|Any CPU
+ {5CC222DC-5716-4499-B897-DCBDDA4A5CF9}.Release|Any CPU.Deploy.0 = Release|Any CPU
+ EndGlobalSection
+ GlobalSection(SolutionProperties) = preSolution
+ HideSolutionNode = FALSE
+ EndGlobalSection
+ GlobalSection(ExtensibilityGlobals) = postSolution
+ SolutionGuid = {671B0BEC-2403-45B0-9357-2C97CC517668}
+ EndGlobalSection
+ GlobalSection(MonoDevelopProperties) = preSolution
+ Policies = $0
+ $0.TextStylePolicy = $1
+ $1.EolMarker = Windows
+ $1.inheritsSet = VisualStudio
+ $1.inheritsScope = text/plain
+ $1.scope = text/x-csharp
+ $0.CSharpFormattingPolicy = $2
+ $2.IndentSwitchSection = True
+ $2.NewLinesForBracesInProperties = True
+ $2.NewLinesForBracesInAccessors = True
+ $2.NewLinesForBracesInAnonymousMethods = True
+ $2.NewLinesForBracesInControlBlocks = True
+ $2.NewLinesForBracesInAnonymousTypes = True
+ $2.NewLinesForBracesInObjectCollectionArrayInitializers = True
+ $2.NewLinesForBracesInLambdaExpressionBody = True
+ $2.NewLineForElse = True
+ $2.NewLineForCatch = True
+ $2.NewLineForFinally = True
+ $2.NewLineForMembersInObjectInit = True
+ $2.NewLineForMembersInAnonymousTypes = True
+ $2.NewLineForClausesInQuery = True
+ $2.SpacingAfterMethodDeclarationName = False
+ $2.SpaceAfterMethodCallName = False
+ $2.SpaceBeforeOpenSquareBracket = False
+ $2.inheritsSet = Mono
+ $2.inheritsScope = text/x-csharp
+ $2.scope = text/x-csharp
+ EndGlobalSection
+EndGlobal
diff --git a/osu.Android.sln.DotSettings b/osu.Android.sln.DotSettings
new file mode 100644
index 0000000000..3f5bd9d34d
--- /dev/null
+++ b/osu.Android.sln.DotSettings
@@ -0,0 +1,815 @@
+
+ True
+ True
+ True
+ True
+ ExplicitlyExcluded
+ ExplicitlyExcluded
+ SOLUTION
+ HINT
+ WARNING
+
+ True
+ WARNING
+ WARNING
+ HINT
+ HINT
+ HINT
+ HINT
+ WARNING
+ WARNING
+ WARNING
+ HINT
+ WARNING
+ HINT
+ SUGGESTION
+ HINT
+ HINT
+ HINT
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ HINT
+ WARNING
+ WARNING
+ HINT
+ WARNING
+ WARNING
+ DO_NOT_SHOW
+ HINT
+ WARNING
+ DO_NOT_SHOW
+ WARNING
+ HINT
+ HINT
+ HINT
+ ERROR
+ HINT
+ HINT
+ HINT
+ WARNING
+ WARNING
+ HINT
+ DO_NOT_SHOW
+ HINT
+ HINT
+ HINT
+ HINT
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ HINT
+ HINT
+ HINT
+ HINT
+ HINT
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ HINT
+ DO_NOT_SHOW
+ DO_NOT_SHOW
+ DO_NOT_SHOW
+ WARNING
+
+ WARNING
+ WARNING
+ WARNING
+ ERROR
+ WARNING
+ WARNING
+ HINT
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ HINT
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ HINT
+ DO_NOT_SHOW
+ DO_NOT_SHOW
+ DO_NOT_SHOW
+ WARNING
+ WARNING
+ HINT
+ WARNING
+ HINT
+ HINT
+ HINT
+ HINT
+ HINT
+ HINT
+ HINT
+
+ HINT
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ WARNING
+ HINT
+ WARNING
+ WARNING
+ HINT
+ HINT
+ WARNING
+ <?xml version="1.0" encoding="utf-16"?><Profile name="Code Cleanup (peppy)"><CSArrangeThisQualifier>True</CSArrangeThisQualifier><CSUseVar><BehavourStyle>CAN_CHANGE_TO_EXPLICIT</BehavourStyle><LocalVariableStyle>ALWAYS_EXPLICIT</LocalVariableStyle><ForeachVariableStyle>ALWAYS_EXPLICIT</ForeachVariableStyle></CSUseVar><CSOptimizeUsings><OptimizeUsings>True</OptimizeUsings><EmbraceInRegion>False</EmbraceInRegion><RegionName></RegionName></CSOptimizeUsings><CSShortenReferences>True</CSShortenReferences><CSReformatCode>True</CSReformatCode><CSUpdateFileHeader>True</CSUpdateFileHeader><CSCodeStyleAttributes ArrangeTypeAccessModifier="False" ArrangeTypeMemberAccessModifier="False" SortModifiers="True" RemoveRedundantParentheses="True" AddMissingParentheses="False" ArrangeBraces="False" ArrangeAttributes="False" ArrangeArgumentsStyle="False" /><XAMLCollapseEmptyTags>False</XAMLCollapseEmptyTags><CSFixBuiltinTypeReferences>True</CSFixBuiltinTypeReferences><CSArrangeQualifiers>True</CSArrangeQualifiers></Profile>
+ Code Cleanup (peppy)
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ NEXT_LINE
+ NEXT_LINE
+ True
+ NEVER
+ NEVER
+ False
+ NEVER
+ False
+ True
+ False
+ False
+ True
+ True
+ False
+ CHOP_IF_LONG
+ True
+ 200
+ CHOP_IF_LONG
+ False
+ False
+ AABB
+ API
+ BPM
+ GC
+ GL
+ GLSL
+ HID
+ HUD
+ ID
+ IP
+ IPC
+ LTRB
+ MD5
+ NS
+ OS
+ RGB
+ RNG
+ SHA
+ SRGB
+ TK
+ SS
+ PP
+ GMT
+ QAT
+ BNG
+ UI
+ HINT
+ <?xml version="1.0" encoding="utf-16"?>
+<Patterns xmlns="urn:schemas-jetbrains-com:member-reordering-patterns">
+ <TypePattern DisplayName="COM interfaces or structs">
+ <TypePattern.Match>
+ <Or>
+ <And>
+ <Kind Is="Interface" />
+ <Or>
+ <HasAttribute Name="System.Runtime.InteropServices.InterfaceTypeAttribute" />
+ <HasAttribute Name="System.Runtime.InteropServices.ComImport" />
+ </Or>
+ </And>
+ <Kind Is="Struct" />
+ </Or>
+ </TypePattern.Match>
+ </TypePattern>
+ <TypePattern DisplayName="NUnit Test Fixtures" RemoveRegions="All">
+ <TypePattern.Match>
+ <And>
+ <Kind Is="Class" />
+ <HasAttribute Name="NUnit.Framework.TestFixtureAttribute" Inherited="True" />
+ </And>
+ </TypePattern.Match>
+ <Entry DisplayName="Setup/Teardown Methods">
+ <Entry.Match>
+ <And>
+ <Kind Is="Method" />
+ <Or>
+ <HasAttribute Name="NUnit.Framework.SetUpAttribute" Inherited="True" />
+ <HasAttribute Name="NUnit.Framework.TearDownAttribute" Inherited="True" />
+ <HasAttribute Name="NUnit.Framework.FixtureSetUpAttribute" Inherited="True" />
+ <HasAttribute Name="NUnit.Framework.FixtureTearDownAttribute" Inherited="True" />
+ </Or>
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="All other members" />
+ <Entry Priority="100" DisplayName="Test Methods">
+ <Entry.Match>
+ <And>
+ <Kind Is="Method" />
+ <HasAttribute Name="NUnit.Framework.TestAttribute" />
+ </And>
+ </Entry.Match>
+ <Entry.SortBy>
+ <Name />
+ </Entry.SortBy>
+ </Entry>
+ </TypePattern>
+ <TypePattern DisplayName="Default Pattern">
+ <Group DisplayName="Fields/Properties">
+ <Group DisplayName="Public Fields">
+ <Entry DisplayName="Constant Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Public" />
+ <Or>
+ <Kind Is="Constant" />
+ <Readonly />
+ <And>
+ <Static />
+ <Readonly />
+ </And>
+ </Or>
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Static Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Public" />
+ <Static />
+ <Not>
+ <Readonly />
+ </Not>
+ <Kind Is="Field" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Normal Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Public" />
+ <Not>
+ <Or>
+ <Static />
+ <Readonly />
+ </Or>
+ </Not>
+ <Kind Is="Field" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ </Group>
+ <Entry DisplayName="Public Properties">
+ <Entry.Match>
+ <And>
+ <Access Is="Public" />
+ <Kind Is="Property" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Group DisplayName="Internal Fields">
+ <Entry DisplayName="Constant Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Internal" />
+ <Or>
+ <Kind Is="Constant" />
+ <Readonly />
+ <And>
+ <Static />
+ <Readonly />
+ </And>
+ </Or>
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Static Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Internal" />
+ <Static />
+ <Not>
+ <Readonly />
+ </Not>
+ <Kind Is="Field" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Normal Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Internal" />
+ <Not>
+ <Or>
+ <Static />
+ <Readonly />
+ </Or>
+ </Not>
+ <Kind Is="Field" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ </Group>
+ <Entry DisplayName="Internal Properties">
+ <Entry.Match>
+ <And>
+ <Access Is="Internal" />
+ <Kind Is="Property" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Group DisplayName="Protected Fields">
+ <Entry DisplayName="Constant Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Protected" />
+ <Or>
+ <Kind Is="Constant" />
+ <Readonly />
+ <And>
+ <Static />
+ <Readonly />
+ </And>
+ </Or>
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Static Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Protected" />
+ <Static />
+ <Not>
+ <Readonly />
+ </Not>
+ <Kind Is="Field" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Normal Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Protected" />
+ <Not>
+ <Or>
+ <Static />
+ <Readonly />
+ </Or>
+ </Not>
+ <Kind Is="Field" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ </Group>
+ <Entry DisplayName="Protected Properties">
+ <Entry.Match>
+ <And>
+ <Access Is="Protected" />
+ <Kind Is="Property" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Group DisplayName="Private Fields">
+ <Entry DisplayName="Constant Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Private" />
+ <Or>
+ <Kind Is="Constant" />
+ <Readonly />
+ <And>
+ <Static />
+ <Readonly />
+ </And>
+ </Or>
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Static Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Private" />
+ <Static />
+ <Not>
+ <Readonly />
+ </Not>
+ <Kind Is="Field" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Normal Fields">
+ <Entry.Match>
+ <And>
+ <Access Is="Private" />
+ <Not>
+ <Or>
+ <Static />
+ <Readonly />
+ </Or>
+ </Not>
+ <Kind Is="Field" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ </Group>
+ <Entry DisplayName="Private Properties">
+ <Entry.Match>
+ <And>
+ <Access Is="Private" />
+ <Kind Is="Property" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ </Group>
+ <Group DisplayName="Constructor/Destructor">
+ <Entry DisplayName="Ctor">
+ <Entry.Match>
+ <Kind Is="Constructor" />
+ </Entry.Match>
+ </Entry>
+ <Region Name="Disposal">
+ <Entry DisplayName="Dtor">
+ <Entry.Match>
+ <Kind Is="Destructor" />
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Dispose()">
+ <Entry.Match>
+ <And>
+ <Access Is="Public" />
+ <Kind Is="Method" />
+ <Name Is="Dispose" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Dispose(true)">
+ <Entry.Match>
+ <And>
+ <Access Is="Protected" />
+ <Or>
+ <Virtual />
+ <Override />
+ </Or>
+ <Kind Is="Method" />
+ <Name Is="Dispose" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ </Region>
+ </Group>
+ <Group DisplayName="Methods">
+ <Group DisplayName="Public">
+ <Entry DisplayName="Static Methods">
+ <Entry.Match>
+ <And>
+ <Access Is="Public" />
+ <Static />
+ <Kind Is="Method" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Methods">
+ <Entry.Match>
+ <And>
+ <Access Is="Public" />
+ <Not>
+ <Static />
+ </Not>
+ <Kind Is="Method" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ </Group>
+ <Group DisplayName="Internal">
+ <Entry DisplayName="Static Methods">
+ <Entry.Match>
+ <And>
+ <Access Is="Internal" />
+ <Static />
+ <Kind Is="Method" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Methods">
+ <Entry.Match>
+ <And>
+ <Access Is="Internal" />
+ <Not>
+ <Static />
+ </Not>
+ <Kind Is="Method" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ </Group>
+ <Group DisplayName="Protected">
+ <Entry DisplayName="Static Methods">
+ <Entry.Match>
+ <And>
+ <Access Is="Protected" />
+ <Static />
+ <Kind Is="Method" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Methods">
+ <Entry.Match>
+ <And>
+ <Access Is="Protected" />
+ <Not>
+ <Static />
+ </Not>
+ <Kind Is="Method" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ </Group>
+ <Group DisplayName="Private">
+ <Entry DisplayName="Static Methods">
+ <Entry.Match>
+ <And>
+ <Access Is="Private" />
+ <Static />
+ <Kind Is="Method" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ <Entry DisplayName="Methods">
+ <Entry.Match>
+ <And>
+ <Access Is="Private" />
+ <Not>
+ <Static />
+ </Not>
+ <Kind Is="Method" />
+ </And>
+ </Entry.Match>
+ </Entry>
+ </Group>
+ </Group>
+ </TypePattern>
+</Patterns>
+ 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.
+
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" />
+ <Policy Inspect="False" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb"><ExtraRule Prefix="_" Suffix="" Style="aaBb" /></Policy>
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aa_bb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AA_BB" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Private" Description="private methods"><ElementKinds><Kind Name="ASYNC_METHOD" /><Kind Name="METHOD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy>
+ <Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public" Description="internal/protected/public methods"><ElementKinds><Kind Name="ASYNC_METHOD" /><Kind Name="METHOD" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy>
+ <Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Private" Description="private properties"><ElementKinds><Kind Name="PROPERTY" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" /></Policy>
+ <Policy><Descriptor Staticness="Static, Instance" AccessRightKinds="Protected, ProtectedInternal, Internal, Public" Description="internal/protected/public properties"><ElementKinds><Kind Name="PROPERTY" /></ElementKinds></Descriptor><Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" /></Policy>
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="I" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="T" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="aaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ <Policy Inspect="True" Prefix="" Suffix="" Style="AaBb" />
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ o!f – Object Initializer: Anchor&Origin
+ True
+ constant("Centre")
+ 0
+ True
+ True
+ 2.0
+ InCSharpFile
+ ofao
+ True
+ Anchor = Anchor.$anchor$,
+Origin = Anchor.$anchor$,
+ True
+ True
+ o!f – InternalChildren = []
+ True
+ True
+ 2.0
+ InCSharpFile
+ ofic
+ True
+ InternalChildren = new Drawable[]
+{
+ $END$
+};
+ True
+ True
+ o!f – new GridContainer { .. }
+ True
+ True
+ 2.0
+ InCSharpFile
+ ofgc
+ True
+ new GridContainer
+{
+ RelativeSizeAxes = Axes.Both,
+ Content = new[]
+ {
+ new Drawable[] { $END$ },
+ new Drawable[] { }
+ }
+};
+ True
+ True
+ o!f – new FillFlowContainer { .. }
+ True
+ True
+ 2.0
+ InCSharpFile
+ offf
+ True
+ new FillFlowContainer
+{
+ RelativeSizeAxes = Axes.Both,
+ Direction = FillDirection.Vertical,
+ Children = new Drawable[]
+ {
+ $END$
+ }
+},
+ True
+ True
+ o!f – new Container { .. }
+ True
+ True
+ 2.0
+ InCSharpFile
+ ofcont
+ True
+ new Container
+{
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
+ {
+ $END$
+ }
+},
+ True
+ True
+ o!f – BackgroundDependencyLoader load()
+ True
+ True
+ 2.0
+ InCSharpFile
+ ofbdl
+ True
+ [BackgroundDependencyLoader]
+private void load()
+{
+ $END$
+}
+ True
+ True
+ o!f – new Box { .. }
+ True
+ True
+ 2.0
+ InCSharpFile
+ ofbox
+ True
+ new Box
+{
+ Colour = Color4.Black,
+ RelativeSizeAxes = Axes.Both,
+},
+ True
+ True
+ o!f – Children = []
+ True
+ True
+ 2.0
+ InCSharpFile
+ ofc
+ True
+ Children = new Drawable[]
+{
+ $END$
+};
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
+ True
diff --git a/osu.Android/OsuGameActivity.cs b/osu.Android/OsuGameActivity.cs
new file mode 100644
index 0000000000..762a9c418d
--- /dev/null
+++ b/osu.Android/OsuGameActivity.cs
@@ -0,0 +1,25 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Android.App;
+using Android.Content.PM;
+using Android.OS;
+using Android.Views;
+using osu.Framework.Android;
+
+namespace osu.Android
+{
+ [Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.FullSensor, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize, HardwareAccelerated = true)]
+ public class OsuGameActivity : AndroidGameActivity
+ {
+ protected override Framework.Game CreateGame() => new OsuGameAndroid();
+
+ protected override void OnCreate(Bundle savedInstanceState)
+ {
+ base.OnCreate(savedInstanceState);
+
+ Window.AddFlags(WindowManagerFlags.Fullscreen);
+ Window.AddFlags(WindowManagerFlags.KeepScreenOn);
+ }
+ }
+}
diff --git a/osu.Android/OsuGameAndroid.cs b/osu.Android/OsuGameAndroid.cs
new file mode 100644
index 0000000000..d9bdd9c0c2
--- /dev/null
+++ b/osu.Android/OsuGameAndroid.cs
@@ -0,0 +1,14 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using Android.App;
+using osu.Game;
+
+namespace osu.Android
+{
+ public class OsuGameAndroid : OsuGame
+ {
+ public override Version AssemblyVersion => new Version(Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0).VersionName);
+ }
+}
diff --git a/osu.Android/Properties/AndroidManifest.xml b/osu.Android/Properties/AndroidManifest.xml
new file mode 100644
index 0000000000..acd21f9587
--- /dev/null
+++ b/osu.Android/Properties/AndroidManifest.xml
@@ -0,0 +1,10 @@
+
+
+
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/osu.Android/Resources/drawable/lazer.png b/osu.Android/Resources/drawable/lazer.png
new file mode 100644
index 0000000000..fc7aa8a092
Binary files /dev/null and b/osu.Android/Resources/drawable/lazer.png differ
diff --git a/osu.Android/lib/arm64-v8a/libbass.so b/osu.Android/lib/arm64-v8a/libbass.so
new file mode 100644
index 0000000000..d5c24b3e4b
Binary files /dev/null and b/osu.Android/lib/arm64-v8a/libbass.so differ
diff --git a/osu.Android/lib/arm64-v8a/libbass_fx.so b/osu.Android/lib/arm64-v8a/libbass_fx.so
new file mode 100644
index 0000000000..e498b10117
Binary files /dev/null and b/osu.Android/lib/arm64-v8a/libbass_fx.so differ
diff --git a/osu.Android/lib/armeabi-v7a/libbass.so b/osu.Android/lib/armeabi-v7a/libbass.so
new file mode 100644
index 0000000000..f7d23b9052
Binary files /dev/null and b/osu.Android/lib/armeabi-v7a/libbass.so differ
diff --git a/osu.Android/lib/armeabi-v7a/libbass_fx.so b/osu.Android/lib/armeabi-v7a/libbass_fx.so
new file mode 100644
index 0000000000..006e2feb30
Binary files /dev/null and b/osu.Android/lib/armeabi-v7a/libbass_fx.so differ
diff --git a/osu.Android/lib/x86/libbass.so b/osu.Android/lib/x86/libbass.so
new file mode 100644
index 0000000000..b0f758a42b
Binary files /dev/null and b/osu.Android/lib/x86/libbass.so differ
diff --git a/osu.Android/lib/x86/libbass_fx.so b/osu.Android/lib/x86/libbass_fx.so
new file mode 100644
index 0000000000..526dca39ca
Binary files /dev/null and b/osu.Android/lib/x86/libbass_fx.so differ
diff --git a/osu.Android/osu.Android.csproj b/osu.Android/osu.Android.csproj
new file mode 100644
index 0000000000..ac3905a372
--- /dev/null
+++ b/osu.Android/osu.Android.csproj
@@ -0,0 +1,55 @@
+
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {D1D5F9A8-B40B-40E6-B02F-482D03346D3D}
+ {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {122416d6-6b49-4ee2-a1e8-b825f31c79fe}
+ osu.Android
+ osu.Android
+ Properties\AndroidManifest.xml
+ armeabi-v7a;x86;arm64-v8a
+
+
+ cjk;mideast;other;rare;west
+ d8
+ r8
+
+
+
+
+
+
+
+
+
+
+ {58f6c80c-1253-4a0e-a465-b8c85ebeadf3}
+ osu.Game.Rulesets.Catch
+
+
+ {48f4582b-7687-4621-9cbe-5c24197cb536}
+ osu.Game.Rulesets.Mania
+
+
+ {c92a607b-1fdd-4954-9f92-03ff547d9080}
+ osu.Game.Rulesets.Osu
+
+
+ {f167e17a-7de6-4af5-b920-a5112296c695}
+ osu.Game.Rulesets.Taiko
+
+
+ {2a66dd92-adb1-4994-89e2-c94e04acda0d}
+ osu.Game
+
+
+
+
+
+
+
\ No newline at end of file
diff --git a/osu.Desktop/OsuGameDesktop.cs b/osu.Desktop/OsuGameDesktop.cs
index 93fd3935c6..975b7f9f5a 100644
--- a/osu.Desktop/OsuGameDesktop.cs
+++ b/osu.Desktop/OsuGameDesktop.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.IO;
@@ -7,20 +7,23 @@ using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using osu.Desktop.Overlays;
-using osu.Framework.Graphics.Containers;
using osu.Framework.Platform;
using osu.Game;
using osuTK.Input;
using Microsoft.Win32;
using osu.Desktop.Updater;
using osu.Framework;
+using osu.Framework.Logging;
using osu.Framework.Platform.Windows;
+using osu.Framework.Screens;
+using osu.Game.Screens.Menu;
namespace osu.Desktop
{
internal class OsuGameDesktop : OsuGame
{
private readonly bool noVersionOverlay;
+ private VersionManager versionManager;
public OsuGameDesktop(string[] args = null)
: base(args)
@@ -32,12 +35,15 @@ namespace osu.Desktop
{
try
{
- return new StableStorage();
+ if (Host is DesktopGameHost desktopHost)
+ return new StableStorage(desktopHost);
}
- catch
+ catch (Exception e)
{
- return null;
+ Logger.Error(e, "Error while searching for stable install");
}
+
+ return null;
}
protected override void LoadComplete()
@@ -46,10 +52,10 @@ namespace osu.Desktop
if (!noVersionOverlay)
{
- LoadComponentAsync(new VersionManager { Depth = int.MinValue }, v =>
+ LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, v =>
{
Add(v);
- v.State = Visibility.Visible;
+ v.Show();
});
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows)
@@ -59,11 +65,28 @@ namespace osu.Desktop
}
}
+ protected override void ScreenChanged(IScreen lastScreen, IScreen newScreen)
+ {
+ base.ScreenChanged(lastScreen, newScreen);
+
+ switch (newScreen)
+ {
+ case Intro _:
+ case MainMenu _:
+ versionManager?.Show();
+ break;
+
+ default:
+ versionManager?.Hide();
+ break;
+ }
+ }
+
public override void SetHost(GameHost host)
{
base.SetHost(host);
- var desktopWindow = host.Window as DesktopGameWindow;
- if (desktopWindow != null)
+
+ if (host.Window is DesktopGameWindow desktopWindow)
{
desktopWindow.CursorState |= CursorState.Hidden;
@@ -76,7 +99,7 @@ namespace osu.Desktop
private void fileDrop(object sender, FileDropEventArgs e)
{
- var filePaths = new[] { e.FileName };
+ var filePaths = e.FileNames;
var firstExtension = Path.GetExtension(filePaths.First());
@@ -119,8 +142,8 @@ namespace osu.Desktop
return null;
}
- public StableStorage()
- : base(string.Empty, null)
+ public StableStorage(DesktopGameHost host)
+ : base(string.Empty, host)
{
}
}
diff --git a/osu.Desktop/Overlays/VersionManager.cs b/osu.Desktop/Overlays/VersionManager.cs
index f31bba1e1e..1f1d2cea5f 100644
--- a/osu.Desktop/Overlays/VersionManager.cs
+++ b/osu.Desktop/Overlays/VersionManager.cs
@@ -1,20 +1,18 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
-using System;
using osu.Framework.Allocation;
+using osu.Framework.Development;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
-using osu.Framework.Platform;
using osu.Game;
using osu.Game.Configuration;
using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
-using osu.Game.Utils;
using osuTK;
using osuTK.Graphics;
@@ -25,15 +23,13 @@ namespace osu.Desktop.Overlays
private OsuConfigManager config;
private OsuGameBase game;
private NotificationOverlay notificationOverlay;
- private GameHost host;
[BackgroundDependencyLoader]
- private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config, GameHost host)
+ private void load(NotificationOverlay notification, OsuColour colours, TextureStore textures, OsuGameBase game, OsuConfigManager config)
{
notificationOverlay = notification;
this.config = config;
this.game = game;
- this.host = host;
AutoSizeAxes = Axes.Both;
Anchor = Anchor.BottomCentre;
@@ -60,12 +56,12 @@ namespace osu.Desktop.Overlays
{
new OsuSpriteText
{
- Font = @"Exo2.0-Bold",
+ Font = OsuFont.GetFont(weight: FontWeight.Bold),
Text = game.Name
},
new OsuSpriteText
{
- Colour = DebugUtils.IsDebug ? colours.Red : Color4.White,
+ Colour = DebugUtils.IsDebugBuild ? colours.Red : Color4.White,
Text = game.Version
},
}
@@ -74,9 +70,8 @@ namespace osu.Desktop.Overlays
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
- TextSize = 12,
+ Font = OsuFont.Numeric.With(size: 12),
Colour = colours.Yellow,
- Font = @"Venera",
Text = @"Development Build"
},
new Sprite
@@ -96,43 +91,49 @@ namespace osu.Desktop.Overlays
var version = game.Version;
var lastVersion = config.Get(OsuSetting.Version);
+
if (game.IsDeployedBuild && version != lastVersion)
{
config.Set(OsuSetting.Version, version);
// only show a notification if we've previously saved a version to the config file (ie. not the first run).
if (!string.IsNullOrEmpty(lastVersion))
- notificationOverlay.Post(new UpdateCompleteNotification(version, host.OpenUrlExternally));
+ notificationOverlay.Post(new UpdateCompleteNotification(version));
}
}
private class UpdateCompleteNotification : SimpleNotification
{
- public UpdateCompleteNotification(string version, Action openUrl = null)
+ private readonly string version;
+
+ public UpdateCompleteNotification(string version)
{
+ this.version = version;
Text = $"You are now running osu!lazer {version}.\nClick to see what's new!";
- Icon = FontAwesome.fa_check_square;
- Activated = delegate
- {
- openUrl?.Invoke($"https://osu.ppy.sh/home/changelog/lazer/{version}");
- return true;
- };
}
[BackgroundDependencyLoader]
- private void load(OsuColour colours)
+ private void load(OsuColour colours, ChangelogOverlay changelog)
{
+ Icon = FontAwesome.Solid.CheckSquare;
IconBackgound.Colour = colours.BlueDark;
+
+ Activated = delegate
+ {
+ changelog.ShowBuild(OsuGameBase.CLIENT_STREAM_NAME, version);
+ return true;
+ };
}
}
protected override void PopIn()
{
- this.FadeIn(1000);
+ this.FadeIn(1400, Easing.OutQuint);
}
protected override void PopOut()
{
+ this.FadeOut(500, Easing.OutQuint);
}
}
}
diff --git a/osu.Desktop/Program.cs b/osu.Desktop/Program.cs
index 257155478f..141b2cdbbc 100644
--- a/osu.Desktop/Program.cs
+++ b/osu.Desktop/Program.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.IO;
@@ -11,6 +11,7 @@ using osu.Framework.Development;
using osu.Framework.Logging;
using osu.Framework.Platform;
using osu.Game.IPC;
+using osu.Game.Tournament;
namespace osu.Desktop
{
@@ -28,24 +29,36 @@ namespace osu.Desktop
if (!host.IsPrimaryInstance)
{
- var importer = new ArchiveImportIPCChannel(host);
- // Restore the cwd so relative paths given at the command line work correctly
- Directory.SetCurrentDirectory(cwd);
- foreach (var file in args)
+ if (args.Length > 0 && args[0].Contains('.')) // easy way to check for a file import in args
{
- Console.WriteLine(@"Importing {0}", file);
- if (!importer.ImportAsync(Path.GetFullPath(file)).Wait(3000))
- throw new TimeoutException(@"IPC took too long to send");
+ var importer = new ArchiveImportIPCChannel(host);
+ // Restore the cwd so relative paths given at the command line work correctly
+ Directory.SetCurrentDirectory(cwd);
+
+ foreach (var file in args)
+ {
+ Console.WriteLine(@"Importing {0}", file);
+ if (!importer.ImportAsync(Path.GetFullPath(file)).Wait(3000))
+ throw new TimeoutException(@"IPC took too long to send");
+ }
+
+ return 0;
}
+
+ // we want to allow multiple instances to be started when in debug.
+ if (!DebugUtils.IsDebugBuild)
+ return 0;
}
- else
+
+ switch (args.FirstOrDefault() ?? string.Empty)
{
- switch (args.FirstOrDefault() ?? string.Empty)
- {
- default:
- host.Run(new OsuGameDesktop(args));
- break;
- }
+ default:
+ host.Run(new OsuGameDesktop(args));
+ break;
+
+ case "--tournament":
+ host.Run(new TournamentGame());
+ break;
}
return 0;
diff --git a/osu.Desktop/Updater/SimpleUpdateManager.cs b/osu.Desktop/Updater/SimpleUpdateManager.cs
index 6c363422f7..5184791de1 100644
--- a/osu.Desktop/Updater/SimpleUpdateManager.cs
+++ b/osu.Desktop/Updater/SimpleUpdateManager.cs
@@ -1,17 +1,16 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . 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 System.Threading.Tasks;
using Newtonsoft.Json;
using osu.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
using osu.Framework.IO.Network;
using osu.Framework.Platform;
using osu.Game;
-using osu.Game.Graphics;
using osu.Game.Overlays;
using osu.Game.Overlays.Notifications;
@@ -41,24 +40,32 @@ namespace osu.Desktop.Updater
private async void checkForUpdateAsync()
{
- var releases = new JsonWebRequest("https://api.github.com/repos/ppy/osu/releases/latest");
- await releases.PerformAsync();
-
- var latest = releases.ResponseObject;
-
- if (latest.TagName != version)
+ try
{
- notificationOverlay.Post(new SimpleNotification
+ var releases = new JsonWebRequest("https://api.github.com/repos/ppy/osu/releases/latest");
+
+ await releases.PerformAsync();
+
+ var latest = releases.ResponseObject;
+
+ if (latest.TagName != version)
{
- Text = $"A newer release of osu! has been found ({version} → {latest.TagName}).\n\n"
- + "Click here to download the new version, which can be installed over the top of your existing installation",
- Icon = FontAwesome.fa_upload,
- Activated = () =>
+ notificationOverlay.Post(new SimpleNotification
{
- host.OpenUrlExternally(getBestUrl(latest));
- return true;
- }
- });
+ Text = $"A newer release of osu! has been found ({version} → {latest.TagName}).\n\n"
+ + "Click here to download the new version, which can be installed over the top of your existing installation",
+ Icon = FontAwesome.Solid.Upload,
+ Activated = () =>
+ {
+ host.OpenUrlExternally(getBestUrl(latest));
+ return true;
+ }
+ });
+ }
+ }
+ catch
+ {
+ // we shouldn't crash on a web failure. or any failure for the matter.
}
}
@@ -69,10 +76,11 @@ namespace osu.Desktop.Updater
switch (RuntimeInfo.OS)
{
case RuntimeInfo.Platform.Windows:
- bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".exe"));
+ bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".exe"));
break;
+
case RuntimeInfo.Platform.MacOsx:
- bestAsset = release.Assets?.FirstOrDefault(f => f.Name.EndsWith(".app.zip"));
+ bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".app.zip"));
break;
}
diff --git a/osu.Desktop/Updater/SquirrelUpdateManager.cs b/osu.Desktop/Updater/SquirrelUpdateManager.cs
index 19383d617f..78a1e680ec 100644
--- a/osu.Desktop/Updater/SquirrelUpdateManager.cs
+++ b/osu.Desktop/Updater/SquirrelUpdateManager.cs
@@ -1,14 +1,13 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
-using System.IO;
-using System.Reflection;
using System.Threading.Tasks;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
using osu.Framework.Graphics.Shapes;
+using osu.Framework.Graphics.Sprites;
using osu.Framework.Logging;
using osu.Game;
using osu.Game.Graphics;
@@ -26,11 +25,7 @@ namespace osu.Desktop.Updater
private UpdateManager updateManager;
private NotificationOverlay notificationOverlay;
- public void PrepareUpdate()
- {
- // Squirrel returns execution to us after the update process is started, so it's safe to use Wait() here
- UpdateManager.RestartAppWhenExited().Wait();
- }
+ public Task PrepareUpdateAsync() => UpdateManager.RestartAppWhenExited();
[BackgroundDependencyLoader]
private void load(NotificationOverlay notification, OsuGameBase game)
@@ -47,7 +42,7 @@ namespace osu.Desktop.Updater
private async void checkForUpdateAsync(bool useDeltaPatching = true, UpdateProgressNotification notification = null)
{
//should we schedule a retry on completion of this check?
- bool scheduleRetry = true;
+ bool scheduleRecheck = true;
try
{
@@ -87,10 +82,11 @@ namespace osu.Desktop.Updater
//could fail if deltas are unavailable for full update path (https://github.com/Squirrel/Squirrel.Windows/issues/959)
//try again without deltas.
checkForUpdateAsync(false, notification);
- scheduleRetry = false;
+ scheduleRecheck = false;
}
else
{
+ notification.State = ProgressNotificationState.Cancelled;
Logger.Error(e, @"update failed!");
}
}
@@ -101,11 +97,8 @@ namespace osu.Desktop.Updater
}
finally
{
- if (scheduleRetry)
+ if (scheduleRecheck)
{
- if (notification != null)
- notification.State = ProgressNotificationState.Cancelled;
-
//check again in 30 minutes.
Scheduler.AddDelayed(() => checkForUpdateAsync(), 60000 * 30);
}
@@ -135,8 +128,8 @@ namespace osu.Desktop.Updater
Text = @"Update ready to install. Click to restart!",
Activated = () =>
{
- updateManager.PrepareUpdate();
- game.GracefullyExit();
+ updateManager.PrepareUpdateAsync()
+ .ContinueWith(_ => updateManager.Schedule(() => game.GracefullyExit()));
return true;
}
};
@@ -158,7 +151,7 @@ namespace osu.Desktop.Updater
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- Icon = FontAwesome.fa_upload,
+ Icon = FontAwesome.Solid.Upload,
Colour = Color4.White,
Size = new Vector2(20),
}
@@ -168,23 +161,19 @@ namespace osu.Desktop.Updater
private class SquirrelLogger : Splat.ILogger, IDisposable
{
- private readonly string path;
- private readonly object locker = new object();
public LogLevel Level { get; set; } = LogLevel.Info;
- public SquirrelLogger()
- {
- var file = Path.Combine(Path.GetDirectoryName(Assembly.GetEntryAssembly().Location), "SquirrelSetupUpdater.log");
- if (File.Exists(file)) File.Delete(file);
- path = file;
- }
+ private Logger logger;
public void Write(string message, LogLevel logLevel)
{
if (logLevel < Level)
return;
- lock (locker) File.AppendAllText(path, message + "\r\n");
+ if (logger == null)
+ logger = Logger.GetLogger("updater");
+
+ logger.Add(message);
}
public void Dispose()
diff --git a/osu.Desktop/lazer.ico b/osu.Desktop/lazer.ico
old mode 100644
new mode 100755
index 0c894dca41..a6aa8abb9f
Binary files a/osu.Desktop/lazer.ico and b/osu.Desktop/lazer.ico differ
diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj
index 09bfdc67d4..8c9e1f279f 100644
--- a/osu.Desktop/osu.Desktop.csproj
+++ b/osu.Desktop/osu.Desktop.csproj
@@ -1,7 +1,7 @@
- netcoreapp2.1
+ netcoreapp2.2
WinExe
AnyCPU
true
@@ -17,19 +17,19 @@
osu.Desktop.Program
+
-
-
-
-
+
+
+
diff --git a/osu.Desktop/osu.nuspec b/osu.Desktop/osu.nuspec
index cdd232a9b2..a26b35fcd5 100644
--- a/osu.Desktop/osu.nuspec
+++ b/osu.Desktop/osu.nuspec
@@ -12,7 +12,7 @@
click the circles. to the beat.
click the circles.
testing
- Copyright ppy Pty Ltd 2007-2018
+ Copyright (c) 2019 ppy Pty Ltd
en-AU
diff --git a/osu.Game.Rulesets.Catch.Tests.Android/MainActivity.cs b/osu.Game.Rulesets.Catch.Tests.Android/MainActivity.cs
new file mode 100644
index 0000000000..d918305f3d
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests.Android/MainActivity.cs
@@ -0,0 +1,16 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Android.App;
+using Android.Content.PM;
+using osu.Framework.Android;
+using osu.Game.Tests;
+
+namespace osu.Game.Rulesets.Catch.Tests.Android
+{
+ [Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.SensorLandscape, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
+ public class MainActivity : AndroidGameActivity
+ {
+ protected override Framework.Game CreateGame() => new OsuTestBrowser();
+ }
+}
diff --git a/osu.Game.Rulesets.Catch.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Rulesets.Catch.Tests.Android/Properties/AndroidManifest.xml
new file mode 100644
index 0000000000..db95e18f13
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests.Android/Properties/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj b/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj
new file mode 100644
index 0000000000..88b420ffad
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests.Android/osu.Game.Rulesets.Catch.Tests.Android.csproj
@@ -0,0 +1,39 @@
+
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {C5379ECB-3A94-4D2F-AC3B-2615AC23EB0D}
+ {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {122416d6-6b49-4ee2-a1e8-b825f31c79fe}
+ osu.Game.Rulesets.Catch.Tests
+ osu.Game.Rulesets.Catch.Tests.Android
+ Properties\AndroidManifest.xml
+ armeabi-v7a;x86;arm64-v8a
+
+
+
+
+
+
+
+
+
+ %(RecursiveDir)%(Filename)%(Extension)
+
+
+
+
+ {58f6c80c-1253-4a0e-a465-b8c85ebeadf3}
+ osu.Game.Rulesets.Catch
+
+
+ {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}
+ osu.Game
+
+
+
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/AppDelegate.cs b/osu.Game.Rulesets.Catch.Tests.iOS/AppDelegate.cs
new file mode 100644
index 0000000000..39fe3dac25
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests.iOS/AppDelegate.cs
@@ -0,0 +1,15 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Foundation;
+using osu.Framework.iOS;
+using osu.Game.Tests;
+
+namespace osu.Game.Rulesets.Catch.Tests.iOS
+{
+ [Register("AppDelegate")]
+ public class AppDelegate : GameAppDelegate
+ {
+ protected override Framework.Game CreateGame() => new OsuTestBrowser();
+ }
+}
diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs b/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs
new file mode 100644
index 0000000000..beca477943
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests.iOS/Application.cs
@@ -0,0 +1,15 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using UIKit;
+
+namespace osu.Game.Rulesets.Catch.Tests.iOS
+{
+ public class Application
+ {
+ public static void Main(string[] args)
+ {
+ UIApplication.Main(args, "GameUIApplication", "AppDelegate");
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/Entitlements.plist b/osu.Game.Rulesets.Catch.Tests.iOS/Entitlements.plist
new file mode 100644
index 0000000000..9ae599370b
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests.iOS/Entitlements.plist
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/Info.plist b/osu.Game.Rulesets.Catch.Tests.iOS/Info.plist
new file mode 100644
index 0000000000..5115746cbb
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests.iOS/Info.plist
@@ -0,0 +1,36 @@
+
+
+
+
+ CFBundleName
+ osu.Game.Rulesets.Catch.Tests.iOS
+ CFBundleIdentifier
+ ppy.osu-Game-Rulesets-Catch-Tests-iOS
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ MinimumOSVersion
+ 10.0
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ XSAppIconAssets
+ Assets.xcassets/AppIcon.appiconset
+
+
diff --git a/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj b/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj
new file mode 100644
index 0000000000..37e7c45a4e
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests.iOS/osu.Game.Rulesets.Catch.Tests.iOS.csproj
@@ -0,0 +1,45 @@
+
+
+
+
+ Debug
+ iPhoneSimulator
+ {4004C7B7-1A62-43F1-9DF2-52450FA67E70}
+ Exe
+ osu.Game.Rulesets.Catch.Tests
+ osu.Game.Rulesets.Catch.Tests.iOS
+
+
+
+
+
+
+ libbass.a
+ PreserveNewest
+
+
+ libbass_fx.a
+ PreserveNewest
+
+
+ Linker.xml
+
+
+
+
+ %(RecursiveDir)%(Filename)%(Extension)
+
+
+
+
+ {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}
+ osu.Game
+
+
+ {58F6C80C-1253-4A0E-A465-B8C85EBEADF3}
+ osu.Game.Rulesets.Catch
+
+
+
+
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json b/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json
index da9344b6a2..5dfaf5ec39 100644
--- a/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json
+++ b/osu.Game.Rulesets.Catch.Tests/.vscode/launch.json
@@ -7,7 +7,7 @@
"request": "launch",
"program": "dotnet",
"args": [
- "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
+ "${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Debug)",
@@ -20,7 +20,7 @@
"request": "launch",
"program": "dotnet",
"args": [
- "${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Catch.Tests.dll"
+ "${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)",
diff --git a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs
index 162624da57..e45ed8c6f4 100644
--- a/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs
+++ b/osu.Game.Rulesets.Catch.Tests/CatchBeatmapConversionTest.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -21,6 +21,7 @@ namespace osu.Game.Rulesets.Catch.Tests
[TestCase("basic")]
[TestCase("spinner")]
[TestCase("spinner-and-circles")]
+ [TestCase("slider")]
public new void Test(string name)
{
base.Test(name);
@@ -33,13 +34,18 @@ namespace osu.Game.Rulesets.Catch.Tests
case JuiceStream stream:
foreach (var nested in stream.NestedHitObjects)
yield return new ConvertValue((CatchHitObject)nested);
+
break;
+
case BananaShower shower:
foreach (var nested in shower.NestedHitObjects)
yield return new ConvertValue((CatchHitObject)nested);
+
break;
+
default:
yield return new ConvertValue((CatchHitObject)hitObject);
+
break;
}
}
diff --git a/osu.Game.Rulesets.Catch.Tests/CatchDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Catch.Tests/CatchDifficultyCalculatorTest.cs
new file mode 100644
index 0000000000..51fe0b035d
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests/CatchDifficultyCalculatorTest.cs
@@ -0,0 +1,24 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Catch.Difficulty;
+using osu.Game.Rulesets.Difficulty;
+using osu.Game.Tests.Beatmaps;
+
+namespace osu.Game.Rulesets.Catch.Tests
+{
+ public class CatchDifficultyCalculatorTest : DifficultyCalculatorTest
+ {
+ protected override string ResourceAssembly => "osu.Game.Rulesets.Catch";
+
+ [TestCase(4.2058561036909863d, "diffcalc-test")]
+ public void Test(double expected, string name)
+ => base.Test(expected, name);
+
+ protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(new CatchRuleset(), beatmap);
+
+ protected override Ruleset CreateRuleset() => new CatchRuleset();
+ }
+}
diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseCatchPlayer.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseCatchPlayer.cs
deleted file mode 100644
index a2c886f1f3..0000000000
--- a/osu.Game.Rulesets.Catch.Tests/TestCaseCatchPlayer.cs
+++ /dev/null
@@ -1,15 +0,0 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using NUnit.Framework;
-
-namespace osu.Game.Rulesets.Catch.Tests
-{
- [TestFixture]
- public class TestCaseCatchPlayer : Game.Tests.Visual.TestCasePlayer
- {
- public TestCaseCatchPlayer() : base(new CatchRuleset())
- {
- }
- }
-}
diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestCaseHyperDash.cs
deleted file mode 100644
index 14487b2c7f..0000000000
--- a/osu.Game.Rulesets.Catch.Tests/TestCaseHyperDash.cs
+++ /dev/null
@@ -1,30 +0,0 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using NUnit.Framework;
-using osu.Game.Beatmaps;
-using osu.Game.Rulesets.Catch.Objects;
-
-namespace osu.Game.Rulesets.Catch.Tests
-{
- [TestFixture]
- public class TestCaseHyperDash : Game.Tests.Visual.TestCasePlayer
- {
- public TestCaseHyperDash()
- : base(new CatchRuleset())
- {
- }
-
- protected override IBeatmap CreateBeatmap(Ruleset ruleset)
- {
- var beatmap = new Beatmap { BeatmapInfo = { Ruleset = ruleset.RulesetInfo } };
-
-
- for (int i = 0; i < 512; i++)
- if (i % 5 < 3)
- beatmap.HitObjects.Add(new Fruit { X = i % 10 < 5 ? 0.02f : 0.98f, StartTime = i * 100, NewCombo = i % 8 == 0 });
-
- return beatmap;
- }
- }
-}
diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs
similarity index 74%
rename from osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs
rename to osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs
index fc3809fae4..ab3c040b4e 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestCaseAutoJuiceStream.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneAutoJuiceStream.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osu.Game.Beatmaps;
@@ -13,21 +13,21 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests
{
- public class TestCaseAutoJuiceStream : TestCasePlayer
+ public class TestSceneAutoJuiceStream : PlayerTestScene
{
- public TestCaseAutoJuiceStream()
+ public TestSceneAutoJuiceStream()
: base(new CatchRuleset())
{
}
- protected override IBeatmap CreateBeatmap(Ruleset ruleset)
+ protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
{
var beatmap = new Beatmap
{
BeatmapInfo = new BeatmapInfo
{
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6, SliderMultiplier = 3 },
- Ruleset = ruleset.RulesetInfo
+ Ruleset = ruleset
}
};
@@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Catch.Tests
protected override Player CreatePlayer(Ruleset ruleset)
{
- Beatmap.Value.Mods.Value = Beatmap.Value.Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() });
+ Mods.Value = Mods.Value.Concat(new[] { ruleset.GetAutoplayMod() }).ToArray();
return base.CreatePlayer(ruleset);
}
}
diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseBananaShower.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs
similarity index 68%
rename from osu.Game.Rulesets.Catch.Tests/TestCaseBananaShower.cs
rename to osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs
index b5cf0e3d1d..0ad72412fc 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestCaseBananaShower.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneBananaShower.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -8,11 +8,12 @@ using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Catch.UI;
+using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
- public class TestCaseBananaShower : Game.Tests.Visual.TestCasePlayer
+ public class TestSceneBananaShower : PlayerTestScene
{
public override IReadOnlyList RequiredTypes => new[]
{
@@ -20,22 +21,22 @@ namespace osu.Game.Rulesets.Catch.Tests
typeof(DrawableBananaShower),
typeof(CatchRuleset),
- typeof(CatchRulesetContainer),
+ typeof(DrawableCatchRuleset),
};
- public TestCaseBananaShower()
+ public TestSceneBananaShower()
: base(new CatchRuleset())
{
}
- protected override IBeatmap CreateBeatmap(Ruleset ruleset)
+ protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
{
var beatmap = new Beatmap
{
BeatmapInfo = new BeatmapInfo
{
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
- Ruleset = ruleset.RulesetInfo
+ Ruleset = ruleset
}
};
diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayer.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayer.cs
new file mode 100644
index 0000000000..9836a7811a
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchPlayer.cs
@@ -0,0 +1,17 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Game.Tests.Visual;
+
+namespace osu.Game.Rulesets.Catch.Tests
+{
+ [TestFixture]
+ public class TestSceneCatchPlayer : PlayerTestScene
+ {
+ public TestSceneCatchPlayer()
+ : base(new CatchRuleset())
+ {
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseCatchStacker.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs
similarity index 63%
rename from osu.Game.Rulesets.Catch.Tests/TestCaseCatchStacker.cs
rename to osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs
index 8a90b48180..9ce46ad6ba 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestCaseCatchStacker.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchStacker.cs
@@ -1,32 +1,32 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
+using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
- public class TestCaseCatchStacker : Game.Tests.Visual.TestCasePlayer
+ public class TestSceneCatchStacker : PlayerTestScene
{
- public TestCaseCatchStacker()
+ public TestSceneCatchStacker()
: base(new CatchRuleset())
{
}
- protected override IBeatmap CreateBeatmap(Ruleset ruleset)
+ protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
{
var beatmap = new Beatmap
{
BeatmapInfo = new BeatmapInfo
{
BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
- Ruleset = ruleset.RulesetInfo
+ Ruleset = ruleset
}
};
-
for (int i = 0; i < 512; i++)
beatmap.HitObjects.Add(new Fruit { X = 0.5f + i / 2048f * (i % 10 - 5), StartTime = i * 100, NewCombo = i % 8 == 0 });
diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs
new file mode 100644
index 0000000000..33f93cdb4a
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcher.cs
@@ -0,0 +1,105 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics;
+using osu.Game.Rulesets.Catch.UI;
+using osu.Game.Tests.Visual;
+using System;
+using System.Collections.Generic;
+using osu.Game.Skinning;
+using osu.Framework.Graphics.Shapes;
+using osu.Framework.Graphics.Sprites;
+using osuTK.Graphics;
+using osu.Framework.Audio.Sample;
+using osu.Framework.Graphics.Textures;
+
+namespace osu.Game.Rulesets.Catch.Tests
+{
+ [TestFixture]
+ public class TestSceneCatcher : OsuTestScene
+ {
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(CatcherSprite),
+ };
+
+ private readonly Container container;
+
+ public TestSceneCatcher()
+ {
+ Child = container = new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ AddStep("show default catcher implementation", () => { container.Child = new CatcherSprite(); });
+
+ AddStep("show custom catcher implementation", () =>
+ {
+ container.Child = new CatchCustomSkinSourceContainer
+ {
+ Child = new CatcherSprite()
+ };
+ });
+ }
+
+ private class CatcherCustomSkin : Container
+ {
+ public CatcherCustomSkin()
+ {
+ RelativeSizeAxes = Axes.Both;
+
+ Children = new Drawable[]
+ {
+ new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.Blue
+ },
+ new SpriteText
+ {
+ Text = "custom"
+ }
+ };
+ }
+ }
+
+ [Cached(typeof(ISkinSource))]
+ private class CatchCustomSkinSourceContainer : Container, ISkinSource
+ {
+ public event Action SourceChanged
+ {
+ add { }
+ remove { }
+ }
+
+ public Drawable GetDrawableComponent(string componentName)
+ {
+ switch (componentName)
+ {
+ case "Play/Catch/fruit-catcher-idle":
+ return new CatcherCustomSkin();
+ }
+
+ return null;
+ }
+
+ public SampleChannel GetSample(string sampleName) =>
+ throw new NotImplementedException();
+
+ public Texture GetTexture(string componentName) =>
+ throw new NotImplementedException();
+
+ public TValue GetValue(Func query) where TConfiguration : SkinConfiguration =>
+ throw new NotImplementedException();
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs
similarity index 86%
rename from osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs
rename to osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs
index 25f7ca108d..3ae6886c31 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestCaseCatcherArea.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatcherArea.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -13,7 +13,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
- public class TestCaseCatcherArea : OsuTestCase
+ public class TestSceneCatcherArea : OsuTestScene
{
private RulesetInfo catchRuleset;
private TestCatcherArea catcherArea;
@@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Catch.Tests
typeof(CatcherArea),
};
- public TestCaseCatcherArea()
+ public TestSceneCatcherArea()
{
AddSliderStep("CircleSize", 0, 8, 5, createCatcher);
AddToggleStep("Hyperdash", t => catcherArea.ToggleHyperDash(t));
diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs
new file mode 100644
index 0000000000..7a9b61c60c
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjects.cs
@@ -0,0 +1,160 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Beatmaps;
+using osu.Game.Beatmaps.ControlPoints;
+using osu.Game.Rulesets.Catch.Objects;
+using osu.Game.Rulesets.Catch.Objects.Drawable;
+using osu.Game.Rulesets.Catch.UI;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Objects.Types;
+using osu.Game.Tests.Visual;
+using osuTK;
+
+namespace osu.Game.Rulesets.Catch.Tests
+{
+ public class TestSceneDrawableHitObjects : OsuTestScene
+ {
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(CatcherArea.Catcher),
+ typeof(DrawableCatchRuleset),
+ typeof(DrawableFruit),
+ typeof(DrawableJuiceStream),
+ typeof(DrawableBanana)
+ };
+
+ private DrawableCatchRuleset drawableRuleset;
+ private double playfieldTime => drawableRuleset.Playfield.Time.Current;
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ var controlPointInfo = new ControlPointInfo();
+ controlPointInfo.TimingPoints.Add(new TimingControlPoint());
+
+ WorkingBeatmap beatmap = CreateWorkingBeatmap(new Beatmap
+ {
+ HitObjects = new List { new Fruit() },
+ BeatmapInfo = new BeatmapInfo
+ {
+ BaseDifficulty = new BeatmapDifficulty(),
+ Metadata = new BeatmapMetadata
+ {
+ Artist = @"Unknown",
+ Title = @"You're breathtaking",
+ AuthorString = @"Everyone",
+ },
+ Ruleset = new CatchRuleset().RulesetInfo
+ },
+ ControlPointInfo = controlPointInfo
+ });
+
+ Add(new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Children = new[]
+ {
+ drawableRuleset = new DrawableCatchRuleset(new CatchRuleset(), beatmap, Array.Empty())
+ }
+ });
+
+ AddStep("miss fruits", () => spawnFruits());
+ AddStep("hit fruits", () => spawnFruits(true));
+ AddStep("miss juicestream", () => spawnJuiceStream());
+ AddStep("hit juicestream", () => spawnJuiceStream(true));
+ AddStep("miss bananas", () => spawnBananas());
+ AddStep("hit bananas", () => spawnBananas(true));
+ }
+
+ private void spawnFruits(bool hit = false)
+ {
+ for (int i = 1; i <= 4; i++)
+ {
+ var fruit = new Fruit
+ {
+ X = getXCoords(hit),
+ LastInCombo = i % 4 == 0,
+ StartTime = playfieldTime + 800 + (200 * i)
+ };
+
+ fruit.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
+
+ addToPlayfield(new DrawableFruit(fruit));
+ }
+ }
+
+ private void spawnJuiceStream(bool hit = false)
+ {
+ var xCoords = getXCoords(hit);
+
+ var juice = new JuiceStream
+ {
+ X = xCoords,
+ StartTime = playfieldTime + 1000,
+ Path = new SliderPath(PathType.Linear, new[]
+ {
+ Vector2.Zero,
+ new Vector2(0, 200)
+ })
+ };
+
+ juice.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
+
+ if (juice.NestedHitObjects.Last() is CatchHitObject tail)
+ tail.LastInCombo = true; // usually the (Catch)BeatmapProcessor would do this for us when necessary
+
+ addToPlayfield(new DrawableJuiceStream(juice, drawableRuleset.CreateDrawableRepresentation));
+ }
+
+ private void spawnBananas(bool hit = false)
+ {
+ for (int i = 1; i <= 4; i++)
+ {
+ var banana = new Banana
+ {
+ X = getXCoords(hit),
+ LastInCombo = i % 4 == 0,
+ StartTime = playfieldTime + 800 + (200 * i)
+ };
+
+ banana.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
+
+ addToPlayfield(new DrawableBanana(banana));
+ }
+ }
+
+ private float getXCoords(bool hit)
+ {
+ const float x_offset = 0.2f;
+ float xCoords = drawableRuleset.Playfield.Width / 2;
+
+ if (drawableRuleset.Playfield is CatchPlayfield catchPlayfield)
+ catchPlayfield.CatcherArea.MovableCatcher.X = xCoords - x_offset;
+
+ if (hit)
+ xCoords -= x_offset;
+ else
+ xCoords += x_offset;
+
+ return xCoords;
+ }
+
+ private void addToPlayfield(DrawableCatchHitObject drawable)
+ {
+ foreach (var mod in Mods.Value.OfType())
+ mod.ApplyToDrawableHitObjects(new[] { drawable });
+
+ drawableRuleset.Playfield.Add(drawable);
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs
new file mode 100644
index 0000000000..f6d26addaa
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneDrawableHitObjectsHidden.cs
@@ -0,0 +1,20 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using osu.Game.Rulesets.Catch.Mods;
+
+namespace osu.Game.Rulesets.Catch.Tests
+{
+ public class TestSceneDrawableHitObjectsHidden : TestSceneDrawableHitObjects
+ {
+ public override IReadOnlyList RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(CatchModHidden) }).ToList();
+
+ public TestSceneDrawableHitObjectsHidden()
+ {
+ Mods.Value = new[] { new CatchModHidden() };
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch.Tests/TestCaseFruitObjects.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs
similarity index 90%
rename from osu.Game.Rulesets.Catch.Tests/TestCaseFruitObjects.cs
rename to osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs
index 7b6773ad58..44517382f7 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestCaseFruitObjects.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneFruitObjects.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -15,7 +15,7 @@ using osuTK;
namespace osu.Game.Rulesets.Catch.Tests
{
[TestFixture]
- public class TestCaseFruitObjects : OsuTestCase
+ public class TestSceneFruitObjects : OsuTestScene
{
public override IReadOnlyList RequiredTypes => new[]
{
@@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Tests
typeof(Pulp),
};
- public TestCaseFruitObjects()
+ public TestSceneFruitObjects()
{
Add(new GridContainer
{
diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs
new file mode 100644
index 0000000000..a603d96201
--- /dev/null
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneHyperDash.cs
@@ -0,0 +1,47 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Catch.Objects;
+using osu.Game.Tests.Visual;
+
+namespace osu.Game.Rulesets.Catch.Tests
+{
+ [TestFixture]
+ public class TestSceneHyperDash : PlayerTestScene
+ {
+ public TestSceneHyperDash()
+ : base(new CatchRuleset())
+ {
+ }
+
+ [Test]
+ public void TestHyperDash()
+ {
+ AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash);
+ }
+
+ protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
+ {
+ var beatmap = new Beatmap
+ {
+ BeatmapInfo =
+ {
+ Ruleset = ruleset,
+ BaseDifficulty = new BeatmapDifficulty { CircleSize = 3.6f }
+ }
+ };
+
+ // Should produce a hyper-dash
+ beatmap.HitObjects.Add(new Fruit { StartTime = 816, X = 308 / 512f, NewCombo = true });
+ beatmap.HitObjects.Add(new Fruit { StartTime = 1008, X = 56 / 512f, });
+
+ for (int i = 0; i < 512; i++)
+ if (i % 5 < 3)
+ beatmap.HitObjects.Add(new Fruit { X = i % 10 < 5 ? 0.02f : 0.98f, StartTime = 2000 + i * 100, NewCombo = i % 8 == 0 });
+
+ return beatmap;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
index b76f591239..9acf47a67c 100644
--- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
+++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
@@ -2,14 +2,14 @@
-
-
-
+
+
+
WinExe
- netcoreapp2.1
+ netcoreapp2.2
diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs
index 5b4af6ea8a..18cc300ff9 100644
--- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs
+++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmap.cs
@@ -1,10 +1,10 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . 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 osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
-using osu.Game.Graphics;
using osu.Game.Rulesets.Catch.Objects;
namespace osu.Game.Rulesets.Catch.Beatmaps
@@ -23,19 +23,19 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
{
Name = @"Fruit Count",
Content = fruits.ToString(),
- Icon = FontAwesome.fa_circle_o
+ Icon = FontAwesome.Regular.Circle
},
new BeatmapStatistic
{
Name = @"Juice Stream Count",
Content = juiceStreams.ToString(),
- Icon = FontAwesome.fa_circle
+ Icon = FontAwesome.Regular.Circle
},
new BeatmapStatistic
{
Name = @"Banana Shower Count",
Content = bananaShowers.ToString(),
- Icon = FontAwesome.fa_circle
+ Icon = FontAwesome.Regular.Circle
}
};
}
diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs
index c3dc9499c2..0d9a663b9f 100644
--- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs
+++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapConverter.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
diff --git a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs
index 22c1180c09..645cb5701a 100644
--- a/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs
+++ b/osu.Game.Rulesets.Catch/Beatmaps/CatchBeatmapProcessor.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -31,6 +31,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
initialiseHyperDash((List)Beatmap.HitObjects);
int index = 0;
+
foreach (var obj in Beatmap.HitObjects.OfType())
{
obj.IndexInBeatmap = index++;
@@ -56,7 +57,9 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
rng.Next(); // osu!stable retrieved a random banana rotation
rng.Next(); // osu!stable retrieved a random banana colour
}
+
break;
+
case JuiceStream juiceStream:
foreach (var nested in juiceStream.NestedHitObjects)
{
@@ -67,6 +70,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
rng.Next(); // osu!stable retrieved a random droplet rotation
hitObject.X = MathHelper.Clamp(hitObject.X, 0, 1);
}
+
break;
}
}
@@ -98,9 +102,10 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
CatchHitObject nextObject = objectWithDroplets[i + 1];
int thisDirection = nextObject.X > currentObject.X ? 1 : -1;
- double timeToNext = nextObject.StartTime - currentObject.StartTime;
+ double timeToNext = nextObject.StartTime - currentObject.StartTime - 1000f / 60f / 4; // 1/4th of a frame of grace time, taken from osu-stable
double distanceToNext = Math.Abs(nextObject.X - currentObject.X) - (lastDirection == thisDirection ? lastExcess : halfCatcherWidth);
float distanceToHyper = (float)(timeToNext * CatcherArea.Catcher.BASE_SPEED - distanceToNext);
+
if (distanceToHyper < 0)
{
currentObject.HyperDashTarget = nextObject;
diff --git a/osu.Game.Rulesets.Catch/CatchInputManager.cs b/osu.Game.Rulesets.Catch/CatchInputManager.cs
index 4f976bb7b2..021d7a7efe 100644
--- a/osu.Game.Rulesets.Catch/CatchInputManager.cs
+++ b/osu.Game.Rulesets.Catch/CatchInputManager.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.ComponentModel;
using osu.Framework.Input.Bindings;
@@ -19,8 +19,10 @@ namespace osu.Game.Rulesets.Catch
{
[Description("Move left")]
MoveLeft,
+
[Description("Move right")]
MoveRight,
+
[Description("Engage dash")]
Dash,
}
diff --git a/osu.Game.Rulesets.Catch/CatchRuleset.cs b/osu.Game.Rulesets.Catch/CatchRuleset.cs
index 1f1d2475f6..ea9f225cc1 100644
--- a/osu.Game.Rulesets.Catch/CatchRuleset.cs
+++ b/osu.Game.Rulesets.Catch/CatchRuleset.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps;
using osu.Game.Graphics;
@@ -9,19 +9,22 @@ using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using System.Collections.Generic;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
+using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Replays;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Beatmaps.Legacy;
using osu.Game.Rulesets.Catch.Beatmaps;
using osu.Game.Rulesets.Catch.Difficulty;
using osu.Game.Rulesets.Difficulty;
+using osu.Game.Scoring;
namespace osu.Game.Rulesets.Catch
{
public class CatchRuleset : Ruleset
{
- public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new CatchRulesetContainer(this, beatmap);
+ public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableCatchRuleset(this, beatmap, mods);
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap);
@@ -84,6 +87,7 @@ namespace osu.Game.Rulesets.Catch
new CatchModNoFail(),
new MultiMod(new CatchModHalfTime(), new CatchModDaycore())
};
+
case ModType.DifficultyIncrease:
return new Mod[]
{
@@ -93,12 +97,20 @@ namespace osu.Game.Rulesets.Catch
new CatchModHidden(),
new CatchModFlashlight(),
};
+
case ModType.Automation:
return new Mod[]
{
new MultiMod(new CatchModAutoplay(), new ModCinema()),
new CatchModRelax(),
};
+
+ case ModType.Fun:
+ return new Mod[]
+ {
+ new MultiMod(new ModWindUp(), new ModWindDown())
+ };
+
default:
return new Mod[] { };
}
@@ -108,10 +120,12 @@ namespace osu.Game.Rulesets.Catch
public override string ShortName => "fruits";
- public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_fruits_o };
+ public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetCatch };
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new CatchDifficultyCalculator(this, beatmap);
+ public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new CatchPerformanceCalculator(this, beatmap, score);
+
public override int? LegacyID => 2;
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new CatchReplayFrame();
diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyAttributes.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyAttributes.cs
index f6535380c8..75f5b18607 100644
--- a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyAttributes.cs
+++ b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyAttributes.cs
@@ -1,8 +1,7 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Difficulty;
-using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Catch.Difficulty
{
@@ -10,10 +9,5 @@ namespace osu.Game.Rulesets.Catch.Difficulty
{
public double ApproachRate;
public int MaxCombo;
-
- public CatchDifficultyAttributes(Mod[] mods, double starRating)
- : base(mods, starRating)
- {
- }
}
}
diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs
index a763989750..44e1a8e5cc 100644
--- a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyCalculator.cs
@@ -1,149 +1,91 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
-using osu.Game.Rulesets.Difficulty;
-using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Catch.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Catch.Difficulty.Skills;
+using osu.Game.Rulesets.Catch.Mods;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
+using osu.Game.Rulesets.Difficulty;
+using osu.Game.Rulesets.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Difficulty.Skills;
+using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Catch.Difficulty
{
public class CatchDifficultyCalculator : DifficultyCalculator
{
-
- ///
- /// In milliseconds. For difficulty calculation we will only look at the highest strain value in each time interval of size STRAIN_STEP.
- /// This is to eliminate higher influence of stream over aim by simply having more HitObjects with high strain.
- /// The higher this value, the less strains there will be, indirectly giving long beatmaps an advantage.
- ///
- private const double strain_step = 750;
-
- ///
- /// The weighting of each strain value decays to this number * it's previous value
- ///
- private const double decay_weight = 0.94;
-
private const double star_scaling_factor = 0.145;
+ protected override int SectionLength => 750;
+
public CatchDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap)
: base(ruleset, beatmap)
{
}
- protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate)
+ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{
- if (!beatmap.HitObjects.Any())
- return new CatchDifficultyAttributes(mods, 0);
-
- var catcher = new CatcherArea.Catcher(beatmap.BeatmapInfo.BaseDifficulty);
- float halfCatchWidth = catcher.CatchWidth * 0.5f;
-
- var difficultyHitObjects = new List();
-
- foreach (var hitObject in beatmap.HitObjects)
- {
- switch (hitObject)
- {
- // We want to only consider fruits that contribute to the combo. Droplets are addressed as accuracy and spinners are not relevant for "skill" calculations.
- case Fruit fruit:
- difficultyHitObjects.Add(new CatchDifficultyHitObject(fruit, halfCatchWidth));
- break;
- case JuiceStream _:
- difficultyHitObjects.AddRange(hitObject.NestedHitObjects.OfType().Where(o => !(o is TinyDroplet)).Select(o => new CatchDifficultyHitObject(o, halfCatchWidth)));
- break;
- }
- }
-
- difficultyHitObjects.Sort((a, b) => a.BaseHitObject.StartTime.CompareTo(b.BaseHitObject.StartTime));
-
- if (!calculateStrainValues(difficultyHitObjects, timeRate))
- return new CatchDifficultyAttributes(mods, 0);
+ if (beatmap.HitObjects.Count == 0)
+ return new CatchDifficultyAttributes { Mods = mods, Skills = skills };
// this is the same as osu!, so there's potential to share the implementation... maybe
- double preempt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / timeRate;
- double starRating = Math.Sqrt(calculateDifficulty(difficultyHitObjects, timeRate)) * star_scaling_factor;
+ double preempt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / clockRate;
- return new CatchDifficultyAttributes(mods, starRating)
+ return new CatchDifficultyAttributes
{
+ StarRating = Math.Sqrt(skills[0].DifficultyValue()) * star_scaling_factor,
+ Mods = mods,
ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0,
- MaxCombo = difficultyHitObjects.Count
+ MaxCombo = beatmap.HitObjects.Count(h => h is Fruit) + beatmap.HitObjects.OfType().SelectMany(j => j.NestedHitObjects).Count(h => !(h is TinyDroplet)),
+ Skills = skills
};
}
- private bool calculateStrainValues(List objects, double timeRate)
+ protected override IEnumerable CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
{
- CatchDifficultyHitObject lastObject = null;
+ float halfCatchWidth;
- if (!objects.Any()) return false;
-
- // Traverse hitObjects in pairs to calculate the strain value of NextHitObject from the strain value of CurrentHitObject and environment.
- foreach (var currentObject in objects)
+ using (var catcher = new CatcherArea.Catcher(beatmap.BeatmapInfo.BaseDifficulty))
{
+ halfCatchWidth = catcher.CatchWidth * 0.5f;
+ halfCatchWidth *= 0.8f; // We're only using 80% of the catcher's width to simulate imperfect gameplay.
+ }
+
+ CatchHitObject lastObject = null;
+
+ // In 2B beatmaps, it is possible that a normal Fruit is placed in the middle of a JuiceStream.
+ foreach (var hitObject in beatmap.HitObjects
+ .SelectMany(obj => obj is JuiceStream stream ? stream.NestedHitObjects : new[] { obj })
+ .Cast()
+ .OrderBy(x => x.StartTime))
+ {
+ // We want to only consider fruits that contribute to the combo.
+ if (hitObject is BananaShower || hitObject is TinyDroplet)
+ continue;
+
if (lastObject != null)
- currentObject.CalculateStrains(lastObject, timeRate);
+ yield return new CatchDifficultyHitObject(hitObject, lastObject, clockRate, halfCatchWidth);
- lastObject = currentObject;
+ lastObject = hitObject;
}
-
- return true;
}
- private double calculateDifficulty(List objects, double timeRate)
+ protected override Skill[] CreateSkills(IBeatmap beatmap) => new Skill[]
{
- // The strain step needs to be adjusted for the algorithm to be considered equal with speed changing mods
- double actualStrainStep = strain_step * timeRate;
+ new Movement(),
+ };
- // Find the highest strain value within each strain step
- var highestStrains = new List();
- double intervalEndTime = actualStrainStep;
- double maximumStrain = 0; // We need to keep track of the maximum strain in the current interval
-
- CatchDifficultyHitObject previousHitObject = null;
- foreach (CatchDifficultyHitObject hitObject in objects)
- {
- // While we are beyond the current interval push the currently available maximum to our strain list
- while (hitObject.BaseHitObject.StartTime > intervalEndTime)
- {
- highestStrains.Add(maximumStrain);
-
- // The maximum strain of the next interval is not zero by default! We need to take the last hitObject we encountered, take its strain and apply the decay
- // until the beginning of the next interval.
- if (previousHitObject == null)
- {
- maximumStrain = 0;
- }
- else
- {
- double decay = Math.Pow(CatchDifficultyHitObject.DECAY_BASE, (intervalEndTime - previousHitObject.BaseHitObject.StartTime) / 1000);
- maximumStrain = previousHitObject.Strain * decay;
- }
-
- // Go to the next time interval
- intervalEndTime += actualStrainStep;
- }
-
- // Obtain maximum strain
- maximumStrain = Math.Max(hitObject.Strain, maximumStrain);
-
- previousHitObject = hitObject;
- }
-
- // Build the weighted sum over the highest strains for each interval
- double difficulty = 0;
- double weight = 1;
- highestStrains.Sort((a, b) => b.CompareTo(a)); // Sort from highest to lowest strain.
-
- foreach (double strain in highestStrains)
- {
- difficulty += weight * strain;
- weight *= decay_weight;
- }
-
- return difficulty;
- }
+ protected override Mod[] DifficultyAdjustmentMods => new Mod[]
+ {
+ new CatchModDoubleTime(),
+ new CatchModHalfTime(),
+ new CatchModHardRock(),
+ new CatchModEasy(),
+ };
}
}
diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyHitObject.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyHitObject.cs
deleted file mode 100644
index bd7796ed91..0000000000
--- a/osu.Game.Rulesets.Catch/Difficulty/CatchDifficultyHitObject.cs
+++ /dev/null
@@ -1,130 +0,0 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using System;
-using osu.Game.Rulesets.Catch.Objects;
-using osu.Game.Rulesets.Catch.UI;
-using osuTK;
-
-namespace osu.Game.Rulesets.Catch.Difficulty
-{
- public class CatchDifficultyHitObject
- {
- internal static readonly double DECAY_BASE = 0.20;
- private const float normalized_hitobject_radius = 41.0f;
- private const float absolute_player_positioning_error = 16f;
- private readonly float playerPositioningError;
-
- internal CatchHitObject BaseHitObject;
-
- ///
- /// Measures jump difficulty. CtB doesn't have something like button pressing speed or accuracy
- ///
- internal double Strain = 1;
-
- ///
- /// This is required to keep track of lazy player movement (always moving only as far as necessary)
- /// Without this quick repeat sliders / weirdly shaped streams might become ridiculously overrated
- ///
- internal float PlayerPositionOffset;
- internal float LastMovement;
-
- internal float NormalizedPosition;
- internal float ActualNormalizedPosition => NormalizedPosition + PlayerPositionOffset;
-
- internal CatchDifficultyHitObject(CatchHitObject baseHitObject, float catcherWidthHalf)
- {
- BaseHitObject = baseHitObject;
-
- // We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps.
- float scalingFactor = normalized_hitobject_radius / catcherWidthHalf;
-
- playerPositioningError = absolute_player_positioning_error; // * scalingFactor;
- NormalizedPosition = baseHitObject.X * CatchPlayfield.BASE_WIDTH * scalingFactor;
- }
-
- private const double direction_change_bonus = 12.5;
- internal void CalculateStrains(CatchDifficultyHitObject previousHitObject, double timeRate)
- {
- // Rather simple, but more specialized things are inherently inaccurate due to the big difference playstyles and opinions make.
- // See Taiko feedback thread.
- double timeElapsed = (BaseHitObject.StartTime - previousHitObject.BaseHitObject.StartTime) / timeRate;
- double decay = Math.Pow(DECAY_BASE, timeElapsed / 1000);
-
- // Update new position with lazy movement.
- PlayerPositionOffset =
- MathHelper.Clamp(
- previousHitObject.ActualNormalizedPosition,
- NormalizedPosition - (normalized_hitobject_radius - playerPositioningError),
- NormalizedPosition + (normalized_hitobject_radius - playerPositioningError)) // Obtain new lazy position, but be stricter by allowing for an error of a certain degree of the player.
- - NormalizedPosition; // Subtract HitObject position to obtain offset
-
- LastMovement = DistanceTo(previousHitObject);
- double addition = spacingWeight(LastMovement);
-
- if (NormalizedPosition < previousHitObject.NormalizedPosition)
- {
- LastMovement = -LastMovement;
- }
-
- CatchHitObject previousHitCircle = previousHitObject.BaseHitObject;
-
- double additionBonus = 0;
- double sqrtTime = Math.Sqrt(Math.Max(timeElapsed, 25));
-
- // Direction changes give an extra point!
- if (Math.Abs(LastMovement) > 0.1)
- {
- if (Math.Abs(previousHitObject.LastMovement) > 0.1 && Math.Sign(LastMovement) != Math.Sign(previousHitObject.LastMovement))
- {
- double bonus = direction_change_bonus / sqrtTime;
-
- // Weight bonus by how
- double bonusFactor = Math.Min(playerPositioningError, Math.Abs(LastMovement)) / playerPositioningError;
-
- // We want time to play a role twice here!
- addition += bonus * bonusFactor;
-
- // Bonus for tougher direction switches and "almost" hyperdashes at this point
- if (previousHitCircle != null && previousHitCircle.DistanceToHyperDash <= 10.0f / CatchPlayfield.BASE_WIDTH)
- {
- additionBonus += 0.3 * bonusFactor;
- }
- }
-
- // Base bonus for every movement, giving some weight to streams.
- addition += 7.5 * Math.Min(Math.Abs(LastMovement), normalized_hitobject_radius * 2) / (normalized_hitobject_radius * 6) / sqrtTime;
- }
-
- // Bonus for "almost" hyperdashes at corner points
- if (previousHitCircle != null && previousHitCircle.DistanceToHyperDash <= 10.0f / CatchPlayfield.BASE_WIDTH)
- {
- if (!previousHitCircle.HyperDash)
- {
- additionBonus += 1.0;
- }
- else
- {
- // After a hyperdash we ARE in the correct position. Always!
- PlayerPositionOffset = 0;
- }
-
- addition *= 1.0 + additionBonus * ((10 - previousHitCircle.DistanceToHyperDash * CatchPlayfield.BASE_WIDTH) / 10);
- }
-
- addition *= 850.0 / Math.Max(timeElapsed, 25);
-
- Strain = previousHitObject.Strain * decay + addition;
- }
-
- private static double spacingWeight(float distance)
- {
- return Math.Pow(distance, 1.3) / 500;
- }
-
- internal float DistanceTo(CatchDifficultyHitObject other)
- {
- return Math.Abs(ActualNormalizedPosition - other.ActualNormalizedPosition);
- }
- }
-}
diff --git a/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs
new file mode 100644
index 0000000000..5a640f6d1a
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/Difficulty/CatchPerformanceCalculator.cs
@@ -0,0 +1,104 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using System.Collections.Generic;
+using System.Linq;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Difficulty;
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Scoring;
+using osu.Game.Scoring;
+using osu.Game.Scoring.Legacy;
+using osuTK;
+
+namespace osu.Game.Rulesets.Catch.Difficulty
+{
+ public class CatchPerformanceCalculator : PerformanceCalculator
+ {
+ protected new CatchDifficultyAttributes Attributes => (CatchDifficultyAttributes)base.Attributes;
+
+ private Mod[] mods;
+
+ private int fruitsHit;
+ private int ticksHit;
+ private int tinyTicksHit;
+ private int tinyTicksMissed;
+ private int misses;
+
+ public CatchPerformanceCalculator(Ruleset ruleset, WorkingBeatmap beatmap, ScoreInfo score)
+ : base(ruleset, beatmap, score)
+ {
+ }
+
+ public override double Calculate(Dictionary categoryDifficulty = null)
+ {
+ mods = Score.Mods;
+
+ var legacyScore = Score as LegacyScoreInfo;
+
+ fruitsHit = legacyScore?.Count300 ?? Score.Statistics[HitResult.Perfect];
+ ticksHit = legacyScore?.Count100 ?? 0;
+ tinyTicksHit = legacyScore?.Count50 ?? 0;
+ tinyTicksMissed = legacyScore?.CountKatu ?? 0;
+ misses = Score.Statistics[HitResult.Miss];
+
+ // Don't count scores made with supposedly unranked mods
+ if (mods.Any(m => !m.Ranked))
+ return 0;
+
+ // We are heavily relying on aim in catch the beat
+ double value = Math.Pow(5.0f * Math.Max(1.0f, Attributes.StarRating / 0.0049f) - 4.0f, 2.0f) / 100000.0f;
+
+ // Longer maps are worth more. "Longer" means how many hits there are which can contribute to combo
+ int numTotalHits = totalComboHits();
+
+ // Longer maps are worth more
+ float lengthBonus =
+ 0.95f + 0.4f * Math.Min(1.0f, numTotalHits / 3000.0f) +
+ (numTotalHits > 3000 ? (float)Math.Log10(numTotalHits / 3000.0f) * 0.5f : 0.0f);
+
+ // Longer maps are worth more
+ value *= lengthBonus;
+
+ // Penalize misses exponentially. This mainly fixes tag4 maps and the likes until a per-hitobject solution is available
+ value *= Math.Pow(0.97f, misses);
+
+ // Combo scaling
+ float beatmapMaxCombo = Attributes.MaxCombo;
+ if (beatmapMaxCombo > 0)
+ value *= Math.Min(Math.Pow(Attributes.MaxCombo, 0.8f) / Math.Pow(beatmapMaxCombo, 0.8f), 1.0f);
+
+ float approachRate = (float)Attributes.ApproachRate;
+ float approachRateFactor = 1.0f;
+ if (approachRate > 9.0f)
+ approachRateFactor += 0.1f * (approachRate - 9.0f); // 10% for each AR above 9
+ else if (approachRate < 8.0f)
+ approachRateFactor += 0.025f * (8.0f - approachRate); // 2.5% for each AR below 8
+
+ value *= approachRateFactor;
+
+ if (mods.Any(m => m is ModHidden))
+ // Hiddens gives nothing on max approach rate, and more the lower it is
+ value *= 1.05f + 0.075f * (10.0f - Math.Min(10.0f, approachRate)); // 7.5% for each AR below 10
+
+ if (mods.Any(m => m is ModFlashlight))
+ // Apply length bonus again if flashlight is on simply because it becomes a lot harder on longer maps.
+ value *= 1.35f * lengthBonus;
+
+ // Scale the aim value with accuracy _slightly_
+ value *= Math.Pow(accuracy(), 5.5f);
+
+ // Custom multipliers for NoFail. SpunOut is not applicable.
+ if (mods.Any(m => m is ModNoFail))
+ value *= 0.90f;
+
+ return value;
+ }
+
+ private float accuracy() => totalHits() == 0 ? 0 : MathHelper.Clamp((float)totalSuccessfulHits() / totalHits(), 0f, 1f);
+ private int totalHits() => tinyTicksHit + ticksHit + fruitsHit + misses + tinyTicksMissed;
+ private int totalSuccessfulHits() => tinyTicksHit + ticksHit + fruitsHit;
+ private int totalComboHits() => misses + ticksHit + fruitsHit;
+ }
+}
diff --git a/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs b/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs
new file mode 100644
index 0000000000..24e526ed19
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/Difficulty/Preprocessing/CatchDifficultyHitObject.cs
@@ -0,0 +1,41 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using osu.Game.Rulesets.Catch.Objects;
+using osu.Game.Rulesets.Catch.UI;
+using osu.Game.Rulesets.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Objects;
+
+namespace osu.Game.Rulesets.Catch.Difficulty.Preprocessing
+{
+ public class CatchDifficultyHitObject : DifficultyHitObject
+ {
+ private const float normalized_hitobject_radius = 41.0f;
+
+ public new CatchHitObject BaseObject => (CatchHitObject)base.BaseObject;
+
+ public new CatchHitObject LastObject => (CatchHitObject)base.LastObject;
+
+ public readonly float NormalizedPosition;
+ public readonly float LastNormalizedPosition;
+
+ ///
+ /// Milliseconds elapsed since the start time of the previous , with a minimum of 25ms.
+ ///
+ public readonly double StrainTime;
+
+ public CatchDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate, float halfCatcherWidth)
+ : base(hitObject, lastObject, clockRate)
+ {
+ // We will scale everything by this factor, so we can assume a uniform CircleSize among beatmaps.
+ var scalingFactor = normalized_hitobject_radius / halfCatcherWidth;
+
+ NormalizedPosition = BaseObject.X * CatchPlayfield.BASE_WIDTH * scalingFactor;
+ LastNormalizedPosition = LastObject.X * CatchPlayfield.BASE_WIDTH * scalingFactor;
+
+ // Every strain interval is hard capped at the equivalent of 600 BPM streaming speed as a safety measure
+ StrainTime = Math.Max(25, DeltaTime);
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs b/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs
new file mode 100644
index 0000000000..d146153294
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/Difficulty/Skills/Movement.cs
@@ -0,0 +1,85 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using osu.Game.Rulesets.Catch.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Catch.UI;
+using osu.Game.Rulesets.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Difficulty.Skills;
+using osuTK;
+
+namespace osu.Game.Rulesets.Catch.Difficulty.Skills
+{
+ public class Movement : Skill
+ {
+ private const float absolute_player_positioning_error = 16f;
+ private const float normalized_hitobject_radius = 41.0f;
+ private const double direction_change_bonus = 12.5;
+
+ protected override double SkillMultiplier => 850;
+ protected override double StrainDecayBase => 0.2;
+
+ protected override double DecayWeight => 0.94;
+
+ private float? lastPlayerPosition;
+ private float lastDistanceMoved;
+
+ protected override double StrainValueOf(DifficultyHitObject current)
+ {
+ var catchCurrent = (CatchDifficultyHitObject)current;
+
+ if (lastPlayerPosition == null)
+ lastPlayerPosition = catchCurrent.LastNormalizedPosition;
+
+ float playerPosition = MathHelper.Clamp(
+ lastPlayerPosition.Value,
+ catchCurrent.NormalizedPosition - (normalized_hitobject_radius - absolute_player_positioning_error),
+ catchCurrent.NormalizedPosition + (normalized_hitobject_radius - absolute_player_positioning_error)
+ );
+
+ float distanceMoved = playerPosition - lastPlayerPosition.Value;
+
+ double distanceAddition = Math.Pow(Math.Abs(distanceMoved), 1.3) / 500;
+ double sqrtStrain = Math.Sqrt(catchCurrent.StrainTime);
+
+ double bonus = 0;
+
+ // Direction changes give an extra point!
+ if (Math.Abs(distanceMoved) > 0.1)
+ {
+ if (Math.Abs(lastDistanceMoved) > 0.1 && Math.Sign(distanceMoved) != Math.Sign(lastDistanceMoved))
+ {
+ double bonusFactor = Math.Min(absolute_player_positioning_error, Math.Abs(distanceMoved)) / absolute_player_positioning_error;
+
+ distanceAddition += direction_change_bonus / sqrtStrain * bonusFactor;
+
+ // Bonus for tougher direction switches and "almost" hyperdashes at this point
+ if (catchCurrent.LastObject.DistanceToHyperDash <= 10 / CatchPlayfield.BASE_WIDTH)
+ bonus = 0.3 * bonusFactor;
+ }
+
+ // Base bonus for every movement, giving some weight to streams.
+ distanceAddition += 7.5 * Math.Min(Math.Abs(distanceMoved), normalized_hitobject_radius * 2) / (normalized_hitobject_radius * 6) / sqrtStrain;
+ }
+
+ // Bonus for "almost" hyperdashes at corner points
+ if (catchCurrent.LastObject.DistanceToHyperDash <= 10.0f / CatchPlayfield.BASE_WIDTH)
+ {
+ if (!catchCurrent.LastObject.HyperDash)
+ bonus += 1.0;
+ else
+ {
+ // After a hyperdash we ARE in the correct position. Always!
+ playerPosition = catchCurrent.NormalizedPosition;
+ }
+
+ distanceAddition *= 1.0 + bonus * ((10 - catchCurrent.LastObject.DistanceToHyperDash * CatchPlayfield.BASE_WIDTH) / 10);
+ }
+
+ lastPlayerPosition = playerPosition;
+ lastDistanceMoved = distanceMoved;
+
+ return distanceAddition / catchCurrent.StrainTime;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs
index f38009263f..374dd50c11 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchBananaJudgement.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
@@ -16,19 +16,21 @@ namespace osu.Game.Rulesets.Catch.Judgements
{
default:
return 0;
+
case HitResult.Perfect:
return 1100;
}
}
- protected override float HealthIncreaseFor(HitResult result)
+ protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
default:
return 0;
+
case HitResult.Perfect:
- return 8;
+ return 0.008;
}
}
diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs
index 0df2305339..f1399bb5c0 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchDropletJudgement.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Scoring;
@@ -13,19 +13,21 @@ namespace osu.Game.Rulesets.Catch.Judgements
{
default:
return 0;
+
case HitResult.Perfect:
return 30;
}
}
- protected override float HealthIncreaseFor(HitResult result)
+ protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
default:
- return 0;
+ return base.HealthIncreaseFor(result);
+
case HitResult.Perfect:
- return 7;
+ return 0.007;
}
}
}
diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
index 8a51867899..8fd9ac92ba 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchJudgement.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Types;
@@ -17,34 +17,24 @@ namespace osu.Game.Rulesets.Catch.Judgements
{
default:
return 0;
+
case HitResult.Perfect:
return 300;
}
}
- ///
- /// Retrieves the numeric health increase of a .
- ///
- /// The to find the numeric health increase for.
- /// The numeric health increase of .
- protected virtual float HealthIncreaseFor(HitResult result)
+ protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
default:
- return 0;
+ return -0.02;
+
case HitResult.Perfect:
- return 10.2f;
+ return 0.01;
}
}
- ///
- /// Retrieves the numeric health increase of a .
- ///
- /// The to find the numeric health increase for.
- /// The numeric health increase of .
- public float HealthIncreaseFor(JudgementResult result) => HealthIncreaseFor(result.Type);
-
///
/// Whether fruit on the platter should explode or drop.
/// Note that this is only checked if the owning object is also
diff --git a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs
index 8b77351027..3829b5e94f 100644
--- a/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs
+++ b/osu.Game.Rulesets.Catch/Judgements/CatchTinyDropletJudgement.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Scoring;
@@ -15,19 +15,21 @@ namespace osu.Game.Rulesets.Catch.Judgements
{
default:
return 0;
+
case HitResult.Perfect:
return 10;
}
}
- protected override float HealthIncreaseFor(HitResult result)
+ protected override double HealthIncreaseFor(HitResult result)
{
switch (result)
{
default:
return 0;
+
case HitResult.Perfect:
- return 4;
+ return 0.004;
}
}
}
diff --git a/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs b/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs
index 5b3835755a..b3605b013b 100644
--- a/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs
+++ b/osu.Game.Rulesets.Catch/MathUtils/FastRandom.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
@@ -33,11 +33,11 @@ namespace osu.Game.Rulesets.Catch.MathUtils
/// The random value.
public uint NextUInt()
{
- uint t = _x ^ _x << 11;
+ uint t = _x ^ (_x << 11);
_x = _y;
_y = _z;
_z = _w;
- return _w = _w ^ _w >> 19 ^ t ^ t >> 8;
+ return _w = _w ^ (_w >> 19) ^ t ^ (t >> 8);
}
///
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs b/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs
index 8bba73ed64..692e63fa69 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModAutoplay.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
@@ -12,7 +12,7 @@ namespace osu.Game.Rulesets.Catch.Mods
{
public class CatchModAutoplay : ModAutoplay
{
- protected override Score CreateReplayScore(Beatmap beatmap) => new Score
+ public override Score CreateReplayScore(IBeatmap beatmap) => new Score
{
ScoreInfo = new ScoreInfo { User = new User { Username = "osu!salad!" } },
Replay = new CatchAutoGenerator(beatmap).Generate(),
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs
index 6d4caef8d2..cae19e9468 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModDaycore.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs b/osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs
index dcf417c405..178909387f 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModDoubleTime.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModEasy.cs b/osu.Game.Rulesets.Catch/Mods/CatchModEasy.cs
index d20a2ec727..a82d0af102 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModEasy.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModEasy.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs
index 9cfba0236a..71268d899d 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModFlashlight.cs
@@ -1,6 +1,7 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
@@ -20,10 +21,10 @@ namespace osu.Game.Rulesets.Catch.Mods
private CatchPlayfield playfield;
- public override void ApplyToRulesetContainer(RulesetContainer rulesetContainer)
+ public override void ApplyToDrawableRuleset(DrawableRuleset drawableRuleset)
{
- playfield = (CatchPlayfield)rulesetContainer.Playfield;
- base.ApplyToRulesetContainer(rulesetContainer);
+ playfield = (CatchPlayfield)drawableRuleset.Playfield;
+ base.ApplyToDrawableRuleset(drawableRuleset);
}
private class CatchFlashlight : Flashlight
@@ -55,9 +56,9 @@ namespace osu.Game.Rulesets.Catch.Mods
return default_flashlight_size;
}
- protected override void OnComboChange(int newCombo)
+ protected override void OnComboChange(ValueChangedEvent e)
{
- this.TransformTo(nameof(FlashlightSize), new Vector2(0, getSizeFor(newCombo)), FLASHLIGHT_FADE_DURATION);
+ this.TransformTo(nameof(FlashlightSize), new Vector2(0, getSizeFor(e.NewValue)), FLASHLIGHT_FADE_DURATION);
}
protected override string FragmentShader => "CircularFlashlight";
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs
index 4e48de454f..ce06b841aa 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModHalfTime.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs
index 8e19c0614a..060e51e31d 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModHardRock.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.MathUtils;
using osu.Game.Rulesets.Catch.Objects;
@@ -15,77 +15,107 @@ namespace osu.Game.Rulesets.Catch.Mods
public override double ScoreMultiplier => 1.12;
public override bool Ranked => true;
- private float lastStartX;
- private int lastStartTime;
+ private float? lastPosition;
+ private double lastStartTime;
public void ApplyToHitObject(HitObject hitObject)
{
+ if (hitObject is JuiceStream stream)
+ {
+ lastPosition = stream.EndX;
+ lastStartTime = stream.EndTime;
+ return;
+ }
+
+ if (!(hitObject is Fruit))
+ return;
+
var catchObject = (CatchHitObject)hitObject;
float position = catchObject.X;
- int startTime = (int)hitObject.StartTime;
+ double startTime = hitObject.StartTime;
- if (lastStartX == 0)
+ if (lastPosition == null)
{
- lastStartX = position;
+ lastPosition = position;
lastStartTime = startTime;
+
return;
}
- float diff = lastStartX - position;
- int timeDiff = startTime - lastStartTime;
+ float positionDiff = position - lastPosition.Value;
+ double timeDiff = startTime - lastStartTime;
if (timeDiff > 1000)
{
- lastStartX = position;
+ lastPosition = position;
lastStartTime = startTime;
return;
}
- if (diff == 0)
+ if (positionDiff == 0)
{
- bool right = RNG.NextBool();
-
- float rand = Math.Min(20, (float)RNG.NextDouble(0, timeDiff / 4d)) / CatchPlayfield.BASE_WIDTH;
-
- if (right)
- {
- if (position + rand <= 1)
- position += rand;
- else
- position -= rand;
- }
- else
- {
- if (position - rand >= 0)
- position -= rand;
- else
- position += rand;
- }
-
+ applyRandomOffset(ref position, timeDiff / 4d);
catchObject.X = position;
-
return;
}
- if (Math.Abs(diff) < timeDiff / 3d)
- {
- if (diff > 0)
- {
- if (position - diff > 0)
- position -= diff;
- }
- else
- {
- if (position - diff < 1)
- position -= diff;
- }
- }
+ if (Math.Abs(positionDiff * CatchPlayfield.BASE_WIDTH) < timeDiff / 3d)
+ applyOffset(ref position, positionDiff);
catchObject.X = position;
- lastStartX = position;
+ lastPosition = position;
lastStartTime = startTime;
}
+
+ ///
+ /// Applies a random offset in a random direction to a position, ensuring that the final position remains within the boundary of the playfield.
+ ///
+ /// The position which the offset should be applied to.
+ /// The maximum offset, cannot exceed 20px.
+ private void applyRandomOffset(ref float position, double maxOffset)
+ {
+ bool right = RNG.NextBool();
+ float rand = Math.Min(20, (float)RNG.NextDouble(0, Math.Max(0, maxOffset))) / CatchPlayfield.BASE_WIDTH;
+
+ if (right)
+ {
+ // Clamp to the right bound
+ if (position + rand <= 1)
+ position += rand;
+ else
+ position -= rand;
+ }
+ else
+ {
+ // Clamp to the left bound
+ if (position - rand >= 0)
+ position -= rand;
+ else
+ position += rand;
+ }
+ }
+
+ ///
+ /// Applies an offset to a position, ensuring that the final position remains within the boundary of the playfield.
+ ///
+ /// The position which the offset should be applied to.
+ /// The amount to offset by.
+ private void applyOffset(ref float position, float amount)
+ {
+ if (amount > 0)
+ {
+ // Clamp to the right bound
+ if (position + amount < 1)
+ position += amount;
+ }
+ else
+ {
+ // Clamp to the left bound
+ if (position + amount > 0)
+ position += amount;
+ }
+ }
}
}
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs b/osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs
index f2716f351e..606a935229 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModHidden.cs
@@ -1,7 +1,11 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+using System.Linq;
+using osu.Framework.Graphics;
+using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Catch.Mods
{
@@ -9,5 +13,36 @@ namespace osu.Game.Rulesets.Catch.Mods
{
public override string Description => @"Play with fading fruits.";
public override double ScoreMultiplier => 1.06;
+
+ private const double fade_out_offset_multiplier = 0.6;
+ private const double fade_out_duration_multiplier = 0.44;
+
+ protected override void ApplyHiddenState(DrawableHitObject drawable, ArmedState state)
+ {
+ if (!(drawable is DrawableCatchHitObject catchDrawable))
+ return;
+
+ if (catchDrawable.NestedHitObjects.Any())
+ {
+ foreach (var nestedDrawable in catchDrawable.NestedHitObjects)
+ {
+ if (nestedDrawable is DrawableCatchHitObject nestedCatchDrawable)
+ fadeOutHitObject(nestedCatchDrawable);
+ }
+ }
+ else
+ fadeOutHitObject(catchDrawable);
+ }
+
+ private void fadeOutHitObject(DrawableCatchHitObject drawable)
+ {
+ var hitObject = drawable.HitObject;
+
+ var offset = hitObject.TimePreempt * fade_out_offset_multiplier;
+ var duration = offset - hitObject.TimePreempt * fade_out_duration_multiplier;
+
+ using (drawable.BeginAbsoluteSequence(hitObject.StartTime - offset, true))
+ drawable.FadeOut(duration);
+ }
}
}
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs b/osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs
index 687db172cf..da2edcee44 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModNightcore.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModNoFail.cs b/osu.Game.Rulesets.Catch/Mods/CatchModNoFail.cs
index 914419438d..3c02646e99 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModNoFail.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModNoFail.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs b/osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs
index de00ff31ce..fb92399102 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModPerfect.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs b/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs
index 8bf9f32572..0454bc969d 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModRelax.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Catch/Mods/CatchModSuddenDeath.cs b/osu.Game.Rulesets.Catch/Mods/CatchModSuddenDeath.cs
index 71461cfc40..68e01391ce 100644
--- a/osu.Game.Rulesets.Catch/Mods/CatchModSuddenDeath.cs
+++ b/osu.Game.Rulesets.Catch/Mods/CatchModSuddenDeath.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Catch/Objects/Banana.cs b/osu.Game.Rulesets.Catch/Objects/Banana.cs
index e1af4c1075..0b3d1d23e0 100644
--- a/osu.Game.Rulesets.Catch/Objects/Banana.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Banana.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Judgements;
diff --git a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
index 25af7e4bdf..6d44e4660e 100644
--- a/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
+++ b/osu.Game.Rulesets.Catch/Objects/BananaShower.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Objects.Types;
diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs
index 0c50dae9fb..be76edc01b 100644
--- a/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs
+++ b/osu.Game.Rulesets.Catch/Objects/CatchHitObject.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
@@ -14,6 +14,8 @@ namespace osu.Game.Rulesets.Catch.Objects
public float X { get; set; }
+ public double TimePreempt = 1000;
+
public int IndexInBeatmap { get; set; }
public virtual FruitVisualRepresentation VisualRepresentation => (FruitVisualRepresentation)(ComboIndex % 4);
@@ -54,6 +56,8 @@ namespace osu.Game.Rulesets.Catch.Objects
{
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
+ TimePreempt = (float)BeatmapDifficulty.DifficultyRange(difficulty.ApproachRate, 1800, 1200, 450);
+
Scale = 1.0f - 0.7f * (difficulty.CircleSize - 5) / 5;
}
diff --git a/osu.Game.Rulesets.Catch/Objects/CatchHitWindows.cs b/osu.Game.Rulesets.Catch/Objects/CatchHitWindows.cs
new file mode 100644
index 0000000000..837662f5fe
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/Objects/CatchHitWindows.cs
@@ -0,0 +1,23 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Scoring;
+
+namespace osu.Game.Rulesets.Catch.Objects
+{
+ public class CatchHitWindows : HitWindows
+ {
+ public override bool IsHitResultAllowed(HitResult result)
+ {
+ switch (result)
+ {
+ case HitResult.Perfect:
+ case HitResult.Miss:
+ return true;
+ }
+
+ return false;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs
index 8756a5178f..5afdb14888 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBanana.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs
index 697fab85c9..42646851d7 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableBananaShower.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
@@ -13,17 +13,17 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
private readonly Container bananaContainer;
- public DrawableBananaShower(BananaShower s, Func> getVisualRepresentation = null)
+ public DrawableBananaShower(BananaShower s, Func> createDrawableRepresentation = null)
: base(s)
{
RelativeSizeAxes = Axes.X;
Origin = Anchor.BottomLeft;
X = 0;
- InternalChild = bananaContainer = new Container { RelativeSizeAxes = Axes.Both };
+ AddInternal(bananaContainer = new Container { RelativeSizeAxes = Axes.Both });
foreach (var b in s.NestedHitObjects.Cast())
- AddNested(getVisualRepresentation?.Invoke(b));
+ AddNested(createDrawableRepresentation?.Invoke(b));
}
protected override void AddNested(DrawableHitObject h)
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs
index 2db252ebc6..a1279e8443 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableCatchHitObject.cs
@@ -1,14 +1,12 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using osuTK;
-using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Scoring;
-using osu.Game.Skinning;
namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
@@ -60,19 +58,12 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
ApplyResult(r => r.Type = CheckPosition.Invoke(HitObject) ? HitResult.Perfect : HitResult.Miss);
}
- protected override void SkinChanged(ISkinSource skin, bool allowFallback)
- {
- base.SkinChanged(skin, allowFallback);
-
- if (HitObject is IHasComboInformation combo)
- AccentColour = skin.GetValue(s => s.ComboColours.Count > 0 ? s.ComboColours[combo.ComboIndex % s.ComboColours.Count] : (Color4?)null) ?? Color4.White;
- }
-
- private const float preempt = 1000;
+ protected override bool UseTransformStateManagement => false;
protected override void UpdateState(ArmedState state)
{
- using (BeginAbsoluteSequence(HitObject.StartTime - preempt))
+ // TODO: update to use new state management.
+ using (BeginAbsoluteSequence(HitObject.StartTime - HitObject.TimePreempt))
this.FadeIn(200);
var endTime = (HitObject as IHasEndTime)?.EndTime ?? HitObject.StartTime;
@@ -84,6 +75,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
case ArmedState.Miss:
this.FadeOut(250).RotateTo(Rotation * 2, 250, Easing.Out).Expire();
break;
+
case ArmedState.Hit:
this.FadeOut().Expire();
break;
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs
index a896d13132..059310d671 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableDroplet.cs
@@ -1,11 +1,10 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
using osuTK;
-using osuTK.Graphics;
namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
@@ -26,20 +25,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
[BackgroundDependencyLoader]
private void load()
{
- InternalChild = pulp = new Pulp
- {
- Size = Size
- };
- }
+ AddInternal(pulp = new Pulp { Size = Size });
- public override Color4 AccentColour
- {
- get { return base.AccentColour; }
- set
- {
- base.AccentColour = value;
- pulp.AccentColour = AccentColour;
- }
+ AccentColour.BindValueChanged(colour => { pulp.AccentColour = colour.NewValue; }, true);
}
}
}
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs
index 4bd50f29f6..ce2daebbf1 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableFruit.cs
@@ -1,11 +1,12 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.MathUtils;
using osu.Game.Rulesets.Catch.Objects.Drawable.Pieces;
@@ -40,9 +41,9 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
private void load()
{
// todo: this should come from the skin.
- AccentColour = colourForRepresentation(HitObject.VisualRepresentation);
+ AccentColour.Value = colourForRepresentation(HitObject.VisualRepresentation);
- InternalChildren = new[]
+ AddRangeInternal(new[]
{
createPulp(HitObject.VisualRepresentation),
border = new Circle
@@ -52,7 +53,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
Hollow = !HitObject.HyperDash,
Type = EdgeEffectType.Glow,
Radius = 4 * radius_adjust,
- Colour = HitObject.HyperDash ? Color4.Red : AccentColour.Darken(1).Opacity(0.6f)
+ Colour = HitObject.HyperDash ? Color4.Red : AccentColour.Value.Darken(1).Opacity(0.6f)
},
Size = new Vector2(Height),
Anchor = Anchor.Centre,
@@ -64,13 +65,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
new Box
{
AlwaysPresent = true,
- Colour = AccentColour,
+ Colour = AccentColour.Value,
Alpha = 0,
RelativeSizeAxes = Axes.Both
}
}
},
- };
+ });
if (HitObject.HyperDash)
{
@@ -105,6 +106,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
default:
return new Container();
+
case FruitVisualRepresentation.Raspberry:
return new Container
{
@@ -113,36 +115,37 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(small_pulp),
Y = -0.34f,
},
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(large_pulp_4),
Position = positionAt(0, distance_from_centre_4),
},
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(large_pulp_4),
Position = positionAt(90, distance_from_centre_4),
},
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(large_pulp_4),
Position = positionAt(180, distance_from_centre_4),
},
new Pulp
{
Size = new Vector2(large_pulp_4),
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Position = positionAt(270, distance_from_centre_4),
},
}
};
+
case FruitVisualRepresentation.Pineapple:
return new Container
{
@@ -151,36 +154,37 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(small_pulp),
Y = -0.3f,
},
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(large_pulp_4),
Position = positionAt(45, distance_from_centre_4),
},
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(large_pulp_4),
Position = positionAt(135, distance_from_centre_4),
},
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(large_pulp_4),
Position = positionAt(225, distance_from_centre_4),
},
new Pulp
{
Size = new Vector2(large_pulp_4),
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Position = positionAt(315, distance_from_centre_4),
},
}
};
+
case FruitVisualRepresentation.Pear:
return new Container
{
@@ -189,30 +193,31 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(small_pulp),
Y = -0.33f,
},
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(large_pulp_3),
Position = positionAt(60, distance_from_centre_3),
},
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(large_pulp_3),
Position = positionAt(180, distance_from_centre_3),
},
new Pulp
{
Size = new Vector2(large_pulp_3),
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Position = positionAt(300, distance_from_centre_3),
},
}
};
+
case FruitVisualRepresentation.Grape:
return new Container
{
@@ -221,30 +226,31 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(small_pulp),
Y = -0.25f,
},
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(large_pulp_3),
Position = positionAt(0, distance_from_centre_3),
},
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(large_pulp_3),
Position = positionAt(120, distance_from_centre_3),
},
new Pulp
{
Size = new Vector2(large_pulp_3),
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Position = positionAt(240, distance_from_centre_3),
},
}
};
+
case FruitVisualRepresentation.Banana:
return new Container
{
@@ -253,13 +259,13 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(small_pulp),
Y = -0.3f
},
new Pulp
{
- AccentColour = AccentColour,
+ AccentColour = AccentColour.Value,
Size = new Vector2(large_pulp_4 * 0.8f, large_pulp_4 * 2.5f),
Y = 0.05f,
},
@@ -282,19 +288,25 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
default:
case FruitVisualRepresentation.Pear:
return new Color4(17, 136, 170, 255);
+
case FruitVisualRepresentation.Grape:
return new Color4(204, 102, 0, 255);
+
case FruitVisualRepresentation.Raspberry:
return new Color4(121, 9, 13, 255);
+
case FruitVisualRepresentation.Pineapple:
return new Color4(102, 136, 0, 255);
+
case FruitVisualRepresentation.Banana:
switch (RNG.Next(0, 3))
{
default:
return new Color4(255, 240, 0, 255);
+
case 1:
return new Color4(255, 192, 0, 255);
+
case 2:
return new Color4(214, 221, 28, 255);
}
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs
index e66852c5c2..9e5e9f6a04 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableJuiceStream.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
@@ -13,17 +13,17 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
{
private readonly Container dropletContainer;
- public DrawableJuiceStream(JuiceStream s, Func> getVisualRepresentation = null)
+ public DrawableJuiceStream(JuiceStream s, Func> createDrawableRepresentation = null)
: base(s)
{
RelativeSizeAxes = Axes.Both;
Origin = Anchor.BottomLeft;
X = 0;
- InternalChild = dropletContainer = new Container { RelativeSizeAxes = Axes.Both, };
+ AddInternal(dropletContainer = new Container { RelativeSizeAxes = Axes.Both, });
foreach (var o in s.NestedHitObjects.Cast())
- AddNested(getVisualRepresentation?.Invoke(o));
+ AddNested(createDrawableRepresentation?.Invoke(o));
}
protected override void AddNested(DrawableHitObject h)
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs
index 2f167121aa..d41aea1e7b 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/DrawableTinyDroplet.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osuTK;
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs
index f21c14f076..b9b6d5b924 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawable/Pieces/Pulp.cs
@@ -1,9 +1,9 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osuTK.Graphics;
@@ -23,9 +23,10 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable.Pieces
}
private Color4 accentColour;
+
public Color4 AccentColour
{
- get { return accentColour; }
+ get => accentColour;
set
{
accentColour = value;
diff --git a/osu.Game.Rulesets.Catch/Objects/Droplet.cs b/osu.Game.Rulesets.Catch/Objects/Droplet.cs
index 8b54922959..7b0bb3f0ae 100644
--- a/osu.Game.Rulesets.Catch/Objects/Droplet.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Droplet.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Judgements;
diff --git a/osu.Game.Rulesets.Catch/Objects/Fruit.cs b/osu.Game.Rulesets.Catch/Objects/Fruit.cs
index 2c2cd013c3..6f0423b420 100644
--- a/osu.Game.Rulesets.Catch/Objects/Fruit.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Fruit.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Judgements;
diff --git a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
index d8bd3e0edc..0952e8981a 100644
--- a/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
+++ b/osu.Game.Rulesets.Catch/Objects/JuiceStream.cs
@@ -1,7 +1,6 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
-using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Audio;
@@ -25,6 +24,11 @@ namespace osu.Game.Rulesets.Catch.Objects
public double Velocity;
public double TickDistance;
+ ///
+ /// The length of one span of this .
+ ///
+ public double SpanDuration => Duration / this.SpanCount();
+
protected override void ApplyDefaultsToSelf(ControlPointInfo controlPointInfo, BeatmapDifficulty difficulty)
{
base.ApplyDefaultsToSelf(controlPointInfo, difficulty);
@@ -41,93 +45,68 @@ namespace osu.Game.Rulesets.Catch.Objects
protected override void CreateNestedHitObjects()
{
base.CreateNestedHitObjects();
- createTicks();
- }
- private void createTicks()
- {
- if (TickDistance == 0)
- return;
-
- var length = Path.Distance;
- var tickDistance = Math.Min(TickDistance, length);
- var spanDuration = length / Velocity;
-
- var minDistanceFromEnd = Velocity * 0.01;
-
- AddNested(new Fruit
+ var tickSamples = Samples.Select(s => new HitSampleInfo
{
- Samples = Samples,
- StartTime = StartTime,
- X = X
- });
+ Bank = s.Bank,
+ Name = @"slidertick",
+ Volume = s.Volume
+ }).ToList();
- double lastDropletTime = StartTime;
+ SliderEventDescriptor? lastEvent = null;
- for (int span = 0; span < this.SpanCount(); span++)
+ foreach (var e in SliderEventGenerator.Generate(StartTime, SpanDuration, Velocity, TickDistance, Path.Distance, this.SpanCount(), LegacyLastTickOffset))
{
- var spanStartTime = StartTime + span * spanDuration;
- var reversed = span % 2 == 1;
-
- for (double d = 0; d <= length; d += tickDistance)
+ // generate tiny droplets since the last point
+ if (lastEvent != null)
{
- var timeProgress = d / length;
- var distanceProgress = reversed ? 1 - timeProgress : timeProgress;
+ double sinceLastTick = e.Time - lastEvent.Value.Time;
- double time = spanStartTime + timeProgress * spanDuration;
-
- if (LegacyLastTickOffset != null)
+ if (sinceLastTick > 80)
{
- // If we're the last tick, apply the legacy offset
- if (span == this.SpanCount() - 1 && d + tickDistance > length)
- time = Math.Max(StartTime + Duration / 2, time - LegacyLastTickOffset.Value);
- }
+ double timeBetweenTiny = sinceLastTick;
+ while (timeBetweenTiny > 100)
+ timeBetweenTiny /= 2;
- double tinyTickInterval = time - lastDropletTime;
- while (tinyTickInterval > 100)
- tinyTickInterval /= 2;
-
- for (double t = lastDropletTime + tinyTickInterval; t < time; t += tinyTickInterval)
- {
- double progress = reversed ? 1 - (t - spanStartTime) / spanDuration : (t - spanStartTime) / spanDuration;
-
- AddNested(new TinyDroplet
+ for (double t = timeBetweenTiny; t < sinceLastTick; t += timeBetweenTiny)
{
- StartTime = t,
- X = X + Path.PositionAt(progress).X / CatchPlayfield.BASE_WIDTH,
- Samples = new List(Samples.Select(s => new SampleInfo
+ AddNested(new TinyDroplet
{
- Bank = s.Bank,
- Name = @"slidertick",
- Volume = s.Volume
- }))
- });
+ Samples = tickSamples,
+ StartTime = t + lastEvent.Value.Time,
+ X = X + Path.PositionAt(
+ lastEvent.Value.PathProgress + (t / sinceLastTick) * (e.PathProgress - lastEvent.Value.PathProgress)).X / CatchPlayfield.BASE_WIDTH,
+ });
+ }
}
-
- if (d > minDistanceFromEnd && Math.Abs(d - length) > minDistanceFromEnd)
- {
- AddNested(new Droplet
- {
- StartTime = time,
- X = X + Path.PositionAt(distanceProgress).X / CatchPlayfield.BASE_WIDTH,
- Samples = new List(Samples.Select(s => new SampleInfo
- {
- Bank = s.Bank,
- Name = @"slidertick",
- Volume = s.Volume
- }))
- });
- }
-
- lastDropletTime = time;
}
- AddNested(new Fruit
+ // this also includes LegacyLastTick and this is used for TinyDroplet generation above.
+ // this means that the final segment of TinyDroplets are increasingly mistimed where LegacyLastTickOffset is being applied.
+ lastEvent = e;
+
+ switch (e.Type)
{
- Samples = Samples,
- StartTime = spanStartTime + spanDuration,
- X = X + Path.PositionAt(reversed ? 0 : 1).X / CatchPlayfield.BASE_WIDTH
- });
+ case SliderEventType.Tick:
+ AddNested(new Droplet
+ {
+ Samples = tickSamples,
+ StartTime = e.Time,
+ X = X + Path.PositionAt(e.PathProgress).X / CatchPlayfield.BASE_WIDTH,
+ });
+ break;
+
+ case SliderEventType.Head:
+ case SliderEventType.Tail:
+ case SliderEventType.Repeat:
+ AddNested(new Fruit
+ {
+ Samples = Samples,
+ StartTime = e.Time,
+ X = X + Path.PositionAt(e.PathProgress).X / CatchPlayfield.BASE_WIDTH,
+ });
+ break;
+ }
}
}
@@ -147,7 +126,7 @@ namespace osu.Game.Rulesets.Catch.Objects
public double Distance => Path.Distance;
- public List> NodeSamples { get; set; } = new List>();
+ public List> NodeSamples { get; set; } = new List>();
public double? LegacyLastTickOffset { get; set; }
}
diff --git a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs
index 39f1cadad5..1bf160b5a6 100644
--- a/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs
+++ b/osu.Game.Rulesets.Catch/Objects/TinyDroplet.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Judgements;
diff --git a/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs b/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs
index 045d0824c6..26f20b223a 100644
--- a/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs
+++ b/osu.Game.Rulesets.Catch/Properties/AssemblyInfo.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Runtime.CompilerServices;
@@ -9,3 +9,5 @@ using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Catch.Tests")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Catch.Tests.Dynamic")]
+[assembly: InternalsVisibleTo("osu.Game.Rulesets.Catch.Tests.iOS")]
+[assembly: InternalsVisibleTo("osu.Game.Rulesets.Catch.Tests.Android")]
diff --git a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs
index 20bf2ee5c7..8dd00756f2 100644
--- a/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs
+++ b/osu.Game.Rulesets.Catch/Replays/CatchAutoGenerator.cs
@@ -1,22 +1,25 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
using osu.Game.Replays;
+using osu.Game.Rulesets.Catch.Beatmaps;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.UI;
using osu.Game.Rulesets.Replays;
namespace osu.Game.Rulesets.Catch.Replays
{
- internal class CatchAutoGenerator : AutoGenerator
+ internal class CatchAutoGenerator : AutoGenerator
{
public const double RELEASE_DELAY = 20;
- public CatchAutoGenerator(Beatmap beatmap)
+ public new CatchBeatmap Beatmap => (CatchBeatmap)base.Beatmap;
+
+ public CatchAutoGenerator(IBeatmap beatmap)
: base(beatmap)
{
Replay = new Replay();
@@ -40,10 +43,13 @@ namespace osu.Game.Rulesets.Catch.Replays
float positionChange = Math.Abs(lastPosition - h.X);
double timeAvailable = h.StartTime - lastTime;
- //So we can either make it there without a dash or not.
- double speedRequired = positionChange / timeAvailable;
+ // So we can either make it there without a dash or not.
+ // If positionChange is 0, we don't need to move, so speedRequired should also be 0 (could be NaN if timeAvailable is 0 too)
+ // The case where positionChange > 0 and timeAvailable == 0 results in PositiveInfinity which provides expected beheaviour.
+ double speedRequired = positionChange == 0 ? 0 : positionChange / timeAvailable;
- bool dashRequired = speedRequired > movement_speed && h.StartTime != 0;
+ bool dashRequired = speedRequired > movement_speed;
+ bool impossibleJump = speedRequired > movement_speed * 2;
// todo: get correct catcher size, based on difficulty CS.
const float catcher_width_half = CatcherArea.CATCHER_SIZE / CatchPlayfield.BASE_WIDTH * 0.3f * 0.5f;
@@ -56,9 +62,8 @@ namespace osu.Game.Rulesets.Catch.Replays
return;
}
- if (h is Banana)
+ if (impossibleJump)
{
- // auto bananas unrealistically warp to catch 100% combo.
Replay.Frames.Add(new CatchReplayFrame(h.StartTime, h.X));
}
else if (h.HyperDash)
diff --git a/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs b/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs
index c907fec653..103aa6c3f1 100644
--- a/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs
+++ b/osu.Game.Rulesets.Catch/Replays/CatchFramedReplayInputHandler.cs
@@ -1,7 +1,8 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
+using System.Diagnostics;
using osu.Framework.Input.StateChanges;
using osu.Framework.MathUtils;
using osu.Game.Replays;
@@ -22,10 +23,14 @@ namespace osu.Game.Rulesets.Catch.Replays
{
get
{
- if (!HasFrames)
+ var frame = CurrentFrame;
+
+ if (frame == null)
return null;
- return Interpolation.ValueAt(CurrentTime, CurrentFrame.Position, NextFrame.Position, CurrentFrame.Time, NextFrame.Time);
+ Debug.Assert(CurrentTime != null);
+
+ return NextFrame != null ? Interpolation.ValueAt(CurrentTime.Value, frame.Position, NextFrame.Position, frame.Time, NextFrame.Time) : frame.Position;
}
}
diff --git a/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs b/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs
index 8c32b75959..1e88b35c3b 100644
--- a/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs
+++ b/osu.Game.Rulesets.Catch/Replays/CatchReplayFrame.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps;
using osu.Game.Replays.Legacy;
diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/diffcalc-test.osu b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/diffcalc-test.osu
new file mode 100644
index 0000000000..ebad654404
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/diffcalc-test.osu
@@ -0,0 +1,138 @@
+osu file format v14
+
+[General]
+StackLeniency: 0.3
+Mode: 2
+
+[Difficulty]
+CircleSize:4
+OverallDifficulty:7
+ApproachRate:8.3
+SliderMultiplier:1.6
+SliderTickRate:1
+
+[TimingPoints]
+500,500,4,2,1,50,1,0
+34500,-50,4,2,1,50,0,0
+
+[HitObjects]
+// fruits spaced 1/1 beat apart
+32,128,0,5,0,0:0:0:0:
+96,128,500,1,0,0:0:0:0:
+160,128,1000,1,0,0:0:0:0:
+224,128,1500,1,0,0:0:0:0:
+288,128,2000,1,0,0:0:0:0:
+352,128,2500,1,0,0:0:0:0:
+416,128,3000,1,0,0:0:0:0:
+480,128,3500,1,0,0:0:0:0:
+
+// fruits spaced 1/2 beat apart
+32,160,4500,1,0,0:0:0:0:
+64,160,4750,1,0,0:0:0:0:
+96,160,5000,1,0,0:0:0:0:
+128,160,5250,1,0,0:0:0:0:
+160,160,5500,1,0,0:0:0:0:
+192,160,5750,1,0,0:0:0:0:
+224,160,6000,1,0,0:0:0:0:
+256,160,6250,1,0,0:0:0:0:
+288,160,6500,1,0,0:0:0:0:
+
+// fruits spaced 1/4 beat apart
+96,128,7500,1,0,0:0:0:0:
+128,128,7625,1,0,0:0:0:0:
+160,128,7750,1,0,0:0:0:0:
+192,128,7875,1,0,0:0:0:0:
+224,128,8000,1,0,0:0:0:0:
+256,128,8125,1,0,0:0:0:0:
+288,128,8250,1,0,0:0:0:0:
+320,128,8375,1,0,0:0:0:0:
+352,128,8500,1,0,0:0:0:0:
+
+// fruit hyperdashes, spaced 1/2 beat apart
+32,160,9500,1,0,0:0:0:0:
+480,160,9750,1,0,0:0:0:0:
+32,160,10000,1,0,0:0:0:0:
+480,160,10250,1,0,0:0:0:0:
+32,160,10500,1,0,0:0:0:0:
+480,160,10750,1,0,0:0:0:0:
+32,160,11000,1,0,0:0:0:0:
+
+// fruit hyperdashes, spaced 1/4 beat apart
+32,192,12000,1,0,0:0:0:0:
+480,192,12125,1,0,0:0:0:0:
+32,192,12250,1,0,0:0:0:0:
+480,192,12375,1,0,0:0:0:0:
+32,192,12500,1,0,0:0:0:0:
+480,192,12625,1,0,0:0:0:0:
+32,192,12750,1,0,0:0:0:0:
+480,192,12875,1,0,0:0:0:0:
+32,192,13000,1,0,0:0:0:0:
+
+// stream + hyperdash + stream, spaced 1/4 beat apart
+32,192,14000,1,0,0:0:0:0:
+64,192,14125,1,0,0:0:0:0:
+96,192,14250,1,0,0:0:0:0:
+128,192,14375,1,0,0:0:0:0:
+480,192,14500,1,0,0:0:0:0:
+448,192,14625,1,0,0:0:0:0:
+416,192,14750,1,0,0:0:0:0:
+384,192,14875,1,0,0:0:0:0:
+32,192,15000,1,0,0:0:0:0:
+
+// basic sliders
+32,192,16000,2,0,L|192:192,1,160
+224,192,17000,2,0,L|384:192,1,160
+416,192,17875,2,0,L|480:192,1,40
+
+// slider hyperdashes, spaced 1/4 beat apart
+32,192,19000,2,0,L|128:192,1,80
+480,192,19375,2,0,L|384:192,1,80
+352,192,19750,2,0,L|256:192,1,80
+0,192,20125,2,0,L|128:192,1,120
+
+// stream + slider hyperdashes, spaced 1/4 beat apart
+32,192,21500,1,0,0:0:0:0:
+64,192,21625,1,0,0:0:0:0:
+96,192,21750,1,0,0:0:0:0:
+512,192,21875,2,0,L|320:192,1,160
+320,192,22500,1,0,0:0:0:0:
+288,192,22625,1,0,0:0:0:0:
+256,192,22750,1,0,0:0:0:0:
+0,192,22875,2,0,L|64:192,1,40
+
+// streams, spaced 1/4 beat apart
+64,192,24000,1,0,0:0:0:0:
+160,192,24125,1,0,0:0:0:0:
+64,192,24250,1,0,0:0:0:0:
+160,192,24375,1,0,0:0:0:0:
+64,192,24500,1,0,0:0:0:0:
+160,192,24625,1,0,0:0:0:0:
+64,192,24750,1,0,0:0:0:0:
+160,192,24875,1,0,0:0:0:0:
+64,192,25000,1,0,0:0:0:0:
+160,192,25125,1,0,0:0:0:0:
+64,192,25250,1,0,0:0:0:0:
+160,192,25375,1,0,0:0:0:0:
+64,192,25500,1,0,0:0:0:0:
+
+// stream + spinner combo, spaced 1/4 beat apart
+256,192,26500,12,0,27000,0:0:0:0:
+128,192,27250,5,0,0:0:0:0:
+128,192,27375,1,0,0:0:0:0:
+160,192,27500,1,0,0:0:0:0:
+192,192,27625,1,0,0:0:0:0:
+256,192,27750,12,0,28500,0:0:0:0:
+192,192,28625,5,0,0:0:0:0:
+224,192,28750,1,0,0:0:0:0:
+256,192,28875,1,0,0:0:0:0:
+256,192,29000,1,0,0:0:0:0:
+256,192,29125,12,0,29500,0:0:0:0:
+
+// long slow slider
+0,192,30500,6,0,B|480:192|480:192|0:192,2,960
+
+// long fast slider
+0,192,37500,6,0,B|480:192|480:192|0:192,2,960
+
+// long hyperdash slider
+0,192,41500,2,0,P|544:192|544:192,5,480
diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider-expected-conversion.json b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider-expected-conversion.json
new file mode 100644
index 0000000000..58c52b6867
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider-expected-conversion.json
@@ -0,0 +1 @@
+{"Mappings":[{"StartTime":19184.0,"Objects":[{"StartTime":19184.0,"Position":320.0},{"StartTime":19263.0,"Position":311.730255},{"StartTime":19343.0,"Position":324.6205},{"StartTime":19423.0,"Position":343.0907},{"StartTime":19503.0,"Position":372.2917},{"StartTime":19582.0,"Position":385.194733},{"StartTime":19662.0,"Position":379.0426},{"StartTime":19742.0,"Position":385.1066},{"StartTime":19822.0,"Position":391.624664},{"StartTime":19919.0,"Position":386.27832},{"StartTime":20016.0,"Position":380.117035},{"StartTime":20113.0,"Position":381.664154},{"StartTime":20247.0,"Position":370.872864}]}]}
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider.osu b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider.osu
new file mode 100644
index 0000000000..d48b2d7769
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/Resources/Testing/Beatmaps/slider.osu
@@ -0,0 +1,18 @@
+osu file format v14
+
+[General]
+Mode: 2
+
+[Difficulty]
+HPDrainRate:3
+CircleSize:2
+OverallDifficulty:4
+ApproachRate:4
+SliderMultiplier:0.9
+SliderTickRate:1
+
+[TimingPoints]
+35.4473684210527,638.298947368422,4,2,1,60,1,0
+
+[HitObjects]
+320,176,19184,2,8,P|384:168|368:232,1,150
diff --git a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs
index 403cedde8c..99b22b2d56 100644
--- a/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs
+++ b/osu.Game.Rulesets.Catch/Scoring/CatchScoreProcessor.cs
@@ -1,11 +1,10 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
-using System;
using osu.Game.Beatmaps;
-using osu.Game.Rulesets.Catch.Judgements;
using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Judgements;
+using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
@@ -13,8 +12,8 @@ namespace osu.Game.Rulesets.Catch.Scoring
{
public class CatchScoreProcessor : ScoreProcessor
{
- public CatchScoreProcessor(RulesetContainer rulesetContainer)
- : base(rulesetContainer)
+ public CatchScoreProcessor(DrawableRuleset drawableRuleset)
+ : base(drawableRuleset)
{
}
@@ -27,21 +26,18 @@ namespace osu.Game.Rulesets.Catch.Scoring
hpDrainRate = beatmap.BeatmapInfo.BaseDifficulty.DrainRate;
}
- private const double harshness = 0.01;
-
- protected override void ApplyResult(JudgementResult result)
+ protected override double HealthAdjustmentFactorFor(JudgementResult result)
{
- base.ApplyResult(result);
-
- if (result.Type == HitResult.Miss)
+ switch (result.Type)
{
- if (!result.Judgement.IsBonus)
- Health.Value -= hpDrainRate * (harshness * 2);
- return;
- }
+ case HitResult.Miss:
+ return hpDrainRate;
- if (result.Judgement is CatchJudgement catchJudgement)
- Health.Value += Math.Max(catchJudgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness;
+ default:
+ return 10.2 - hpDrainRate; // Award less HP as drain rate is increased
+ }
}
+
+ public override HitWindows CreateHitWindows() => new CatchHitWindows();
}
}
diff --git a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
index 0697a72325..b6d8cf9cbe 100644
--- a/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfield.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Graphics;
@@ -10,7 +10,6 @@ using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
-using osuTK;
namespace osu.Game.Rulesets.Catch.UI
{
@@ -20,33 +19,24 @@ namespace osu.Game.Rulesets.Catch.UI
internal readonly CatcherArea CatcherArea;
- public CatchPlayfield(BeatmapDifficulty difficulty, Func> getVisualRepresentation)
+ public CatchPlayfield(BeatmapDifficulty difficulty, Func> createDrawableRepresentation)
{
Container explodingFruitContainer;
- Anchor = Anchor.TopCentre;
- Origin = Anchor.TopCentre;
-
- Size = new Vector2(0.86f); // matches stable's vertical offset for catcher plate
-
- InternalChild = new PlayfieldAdjustmentContainer
+ InternalChildren = new Drawable[]
{
- RelativeSizeAxes = Axes.Both,
- Children = new Drawable[]
+ explodingFruitContainer = new Container
{
- explodingFruitContainer = new Container
- {
- RelativeSizeAxes = Axes.Both,
- },
- CatcherArea = new CatcherArea(difficulty)
- {
- GetVisualRepresentation = getVisualRepresentation,
- ExplodingFruitTarget = explodingFruitContainer,
- Anchor = Anchor.BottomLeft,
- Origin = Anchor.TopLeft,
- },
- HitObjectContainer
- }
+ RelativeSizeAxes = Axes.Both,
+ },
+ CatcherArea = new CatcherArea(difficulty)
+ {
+ CreateDrawableRepresentation = createDrawableRepresentation,
+ ExplodingFruitTarget = explodingFruitContainer,
+ Anchor = Anchor.BottomLeft,
+ Origin = Anchor.TopLeft,
+ },
+ HitObjectContainer
};
}
diff --git a/osu.Game.Rulesets.Catch/UI/PlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs
similarity index 69%
rename from osu.Game.Rulesets.Catch/UI/PlayfieldAdjustmentContainer.cs
rename to osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs
index fa1a7ee868..b8d3dc9017 100644
--- a/osu.Game.Rulesets.Catch/UI/PlayfieldAdjustmentContainer.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatchPlayfieldAdjustmentContainer.cs
@@ -1,19 +1,25 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Game.Rulesets.UI;
using osuTK;
namespace osu.Game.Rulesets.Catch.UI
{
- public class PlayfieldAdjustmentContainer : Container
+ public class CatchPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer
{
protected override Container Content => content;
private readonly Container content;
- public PlayfieldAdjustmentContainer()
+ public CatchPlayfieldAdjustmentContainer()
{
+ Anchor = Anchor.TopCentre;
+ Origin = Anchor.TopCentre;
+
+ Size = new Vector2(0.86f); // matches stable's vertical offset for catcher plate
+
InternalChild = new Container
{
Anchor = Anchor.Centre,
diff --git a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
index 3637fe0c36..0b06e958e6 100644
--- a/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatcherArea.cs
@@ -1,13 +1,11 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Sprites;
-using osu.Framework.Graphics.Textures;
using osu.Framework.Input.Bindings;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
@@ -25,15 +23,15 @@ namespace osu.Game.Rulesets.Catch.UI
{
public class CatcherArea : Container
{
- public const float CATCHER_SIZE = 100;
+ public const float CATCHER_SIZE = 106.75f;
protected internal readonly Catcher MovableCatcher;
- public Func> GetVisualRepresentation;
+ public Func> CreateDrawableRepresentation;
public Container ExplodingFruitTarget
{
- set { MovableCatcher.ExplodingFruitTarget = value; }
+ set => MovableCatcher.ExplodingFruitTarget = value;
}
public CatcherArea(BeatmapDifficulty difficulty = null)
@@ -60,12 +58,12 @@ namespace osu.Game.Rulesets.Catch.UI
if (lastPlateableFruit.IsLoaded)
action();
else
- lastPlateableFruit.OnLoadComplete = _ => action();
+ lastPlateableFruit.OnLoadComplete += _ => action();
}
if (result.IsHit && fruit.CanBePlated)
{
- var caughtFruit = (DrawableCatchHitObject)GetVisualRepresentation?.Invoke(fruit.HitObject);
+ var caughtFruit = (DrawableCatchHitObject)CreateDrawableRepresentation?.Invoke(fruit.HitObject);
if (caughtFruit == null) return;
@@ -141,7 +139,7 @@ namespace osu.Game.Rulesets.Catch.UI
[BackgroundDependencyLoader]
private void load()
{
- Children = new Drawable[]
+ Children = new[]
{
caughtFruit = new Container
{
@@ -158,7 +156,7 @@ namespace osu.Game.Rulesets.Catch.UI
protected bool Dashing
{
- get { return dashing; }
+ get => dashing;
set
{
if (value == dashing) return;
@@ -176,7 +174,7 @@ namespace osu.Game.Rulesets.Catch.UI
///
protected bool Trail
{
- get { return trail; }
+ get => trail;
set
{
if (value == trail) return;
@@ -212,7 +210,7 @@ namespace osu.Game.Rulesets.Catch.UI
Scheduler.AddDelayed(beginTrail, HyperDashing ? 25 : 50);
}
- private Sprite createCatcherSprite() => new CatcherSprite();
+ private Drawable createCatcherSprite() => new CatcherSprite();
///
/// Add a caught fruit to the catcher's stack.
@@ -292,6 +290,7 @@ namespace osu.Game.Rulesets.Catch.UI
const float hyper_dash_transition_length = 180;
bool previouslyHyperDashing = HyperDashing;
+
if (modifier <= 1 || X == targetPosition)
{
hyperDashModifier = 1;
@@ -325,9 +324,11 @@ namespace osu.Game.Rulesets.Catch.UI
case CatchAction.MoveLeft:
currentDirection--;
return true;
+
case CatchAction.MoveRight:
currentDirection++;
return true;
+
case CatchAction.Dash:
Dashing = true;
return true;
@@ -343,9 +344,11 @@ namespace osu.Game.Rulesets.Catch.UI
case CatchAction.MoveLeft:
currentDirection++;
return true;
+
case CatchAction.MoveRight:
currentDirection--;
return true;
+
case CatchAction.Dash:
Dashing = false;
return true;
@@ -374,8 +377,8 @@ namespace osu.Game.Rulesets.Catch.UI
X = (float)MathHelper.Clamp(X + direction * Clock.ElapsedFrameTime * speed, 0, 1);
// Correct overshooting.
- if (hyperDashDirection > 0 && hyperDashTargetPosition < X ||
- hyperDashDirection < 0 && hyperDashTargetPosition > X)
+ if ((hyperDashDirection > 0 && hyperDashTargetPosition < X) ||
+ (hyperDashDirection < 0 && hyperDashTargetPosition > X))
{
X = hyperDashTargetPosition;
SetHyperDashState();
@@ -439,23 +442,6 @@ namespace osu.Game.Rulesets.Catch.UI
fruit.Expire();
}
-
- private class CatcherSprite : Sprite
- {
- public CatcherSprite()
- {
- Size = new Vector2(CATCHER_SIZE);
-
- // Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling.
- OriginPosition = new Vector2(-0.02f, 0.06f) * CATCHER_SIZE;
- }
-
- [BackgroundDependencyLoader]
- private void load(TextureStore textures)
- {
- Texture = textures.Get(@"Play/Catch/fruit-catcher-idle");
- }
- }
}
}
}
diff --git a/osu.Game.Rulesets.Catch/UI/CatcherSprite.cs b/osu.Game.Rulesets.Catch/UI/CatcherSprite.cs
new file mode 100644
index 0000000000..c0c1952064
--- /dev/null
+++ b/osu.Game.Rulesets.Catch/UI/CatcherSprite.cs
@@ -0,0 +1,33 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Game.Skinning;
+using osuTK;
+
+namespace osu.Game.Rulesets.Catch.UI
+{
+ public class CatcherSprite : CompositeDrawable
+ {
+ public CatcherSprite()
+ {
+ Size = new Vector2(CatcherArea.CATCHER_SIZE);
+
+ // Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling.
+ OriginPosition = new Vector2(-0.02f, 0.06f) * CatcherArea.CATCHER_SIZE;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ InternalChild = new SkinnableSprite(@"Play/Catch/fruit-catcher-idle")
+ {
+ RelativeSizeAxes = Axes.Both,
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ };
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs
similarity index 61%
rename from osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs
rename to osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs
index 3673657cd8..f48b84e344 100644
--- a/osu.Game.Rulesets.Catch/UI/CatchRulesetContainer.cs
+++ b/osu.Game.Rulesets.Catch/UI/DrawableCatchRuleset.cs
@@ -1,6 +1,7 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+using System.Collections.Generic;
using osu.Framework.Input;
using osu.Game.Beatmaps;
using osu.Game.Configuration;
@@ -10,6 +11,7 @@ using osu.Game.Rulesets.Catch.Objects;
using osu.Game.Rulesets.Catch.Objects.Drawable;
using osu.Game.Rulesets.Catch.Replays;
using osu.Game.Rulesets.Catch.Scoring;
+using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
@@ -17,14 +19,14 @@ using osu.Game.Rulesets.UI.Scrolling;
namespace osu.Game.Rulesets.Catch.UI
{
- public class CatchRulesetContainer : ScrollingRulesetContainer
+ public class DrawableCatchRuleset : DrawableScrollingRuleset
{
protected override ScrollVisualisationMethod VisualisationMethod => ScrollVisualisationMethod.Constant;
protected override bool UserScrollSpeedAdjustment => false;
- public CatchRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
- : base(ruleset, beatmap)
+ public DrawableCatchRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods)
+ : base(ruleset, beatmap, mods)
{
Direction.Value = ScrollingDirection.Down;
TimeRange.Value = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450);
@@ -34,24 +36,31 @@ namespace osu.Game.Rulesets.Catch.UI
protected override ReplayInputHandler CreateReplayInputHandler(Replay replay) => new CatchFramedReplayInputHandler(replay);
- protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, GetVisualRepresentation);
+ protected override Playfield CreatePlayfield() => new CatchPlayfield(Beatmap.BeatmapInfo.BaseDifficulty, CreateDrawableRepresentation);
- public override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
+ public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new CatchPlayfieldAdjustmentContainer();
- public override DrawableHitObject GetVisualRepresentation(CatchHitObject h)
+ protected override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
+
+ public override DrawableHitObject CreateDrawableRepresentation(CatchHitObject h)
{
switch (h)
{
case Banana banana:
return new DrawableBanana(banana);
+
case Fruit fruit:
return new DrawableFruit(fruit);
+
case JuiceStream stream:
- return new DrawableJuiceStream(stream, GetVisualRepresentation);
+ return new DrawableJuiceStream(stream, CreateDrawableRepresentation);
+
case BananaShower shower:
- return new DrawableBananaShower(shower, GetVisualRepresentation);
+ return new DrawableBananaShower(shower, CreateDrawableRepresentation);
+
case TinyDroplet tiny:
return new DrawableTinyDroplet(tiny);
+
case Droplet droplet:
return new DrawableDroplet(droplet);
}
diff --git a/osu.Game.Rulesets.Mania.Tests.Android/MainActivity.cs b/osu.Game.Rulesets.Mania.Tests.Android/MainActivity.cs
new file mode 100644
index 0000000000..0a3f05ae54
--- /dev/null
+++ b/osu.Game.Rulesets.Mania.Tests.Android/MainActivity.cs
@@ -0,0 +1,16 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Android.App;
+using Android.Content.PM;
+using osu.Framework.Android;
+using osu.Game.Tests;
+
+namespace osu.Game.Rulesets.Mania.Tests.Android
+{
+ [Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.SensorLandscape, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
+ public class MainActivity : AndroidGameActivity
+ {
+ protected override Framework.Game CreateGame() => new OsuTestBrowser();
+ }
+}
diff --git a/osu.Game.Rulesets.Mania.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Rulesets.Mania.Tests.Android/Properties/AndroidManifest.xml
new file mode 100644
index 0000000000..e6728c801d
--- /dev/null
+++ b/osu.Game.Rulesets.Mania.Tests.Android/Properties/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj b/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj
new file mode 100644
index 0000000000..0e557cb260
--- /dev/null
+++ b/osu.Game.Rulesets.Mania.Tests.Android/osu.Game.Rulesets.Mania.Tests.Android.csproj
@@ -0,0 +1,39 @@
+
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {531F1092-DB27-445D-AA33-2A77C7187C99}
+ {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {122416d6-6b49-4ee2-a1e8-b825f31c79fe}
+ osu.Game.Rulesets.Mania.Tests
+ osu.Game.Rulesets.Mania.Tests.Android
+ Properties\AndroidManifest.xml
+ armeabi-v7a;x86;arm64-v8a
+
+
+
+
+
+
+
+
+
+ %(RecursiveDir)%(Filename)%(Extension)
+
+
+
+
+ {48f4582b-7687-4621-9cbe-5c24197cb536}
+ osu.Game.Rulesets.Mania
+
+
+ {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}
+ osu.Game
+
+
+
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/AppDelegate.cs b/osu.Game.Rulesets.Mania.Tests.iOS/AppDelegate.cs
new file mode 100644
index 0000000000..9cd1e47023
--- /dev/null
+++ b/osu.Game.Rulesets.Mania.Tests.iOS/AppDelegate.cs
@@ -0,0 +1,15 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Foundation;
+using osu.Framework.iOS;
+using osu.Game.Tests;
+
+namespace osu.Game.Rulesets.Mania.Tests.iOS
+{
+ [Register("AppDelegate")]
+ public class AppDelegate : GameAppDelegate
+ {
+ protected override Framework.Game CreateGame() => new OsuTestBrowser();
+ }
+}
diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs b/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs
new file mode 100644
index 0000000000..0362402320
--- /dev/null
+++ b/osu.Game.Rulesets.Mania.Tests.iOS/Application.cs
@@ -0,0 +1,15 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using UIKit;
+
+namespace osu.Game.Rulesets.Mania.Tests.iOS
+{
+ public class Application
+ {
+ public static void Main(string[] args)
+ {
+ UIApplication.Main(args, "GameUIApplication", "AppDelegate");
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/Entitlements.plist b/osu.Game.Rulesets.Mania.Tests.iOS/Entitlements.plist
new file mode 100644
index 0000000000..9ae599370b
--- /dev/null
+++ b/osu.Game.Rulesets.Mania.Tests.iOS/Entitlements.plist
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/Info.plist b/osu.Game.Rulesets.Mania.Tests.iOS/Info.plist
new file mode 100644
index 0000000000..8780204d5b
--- /dev/null
+++ b/osu.Game.Rulesets.Mania.Tests.iOS/Info.plist
@@ -0,0 +1,36 @@
+
+
+
+
+ CFBundleName
+ osu.Game.Rulesets.Mania.Tests.iOS
+ CFBundleIdentifier
+ ppy.osu-Game-Rulesets-Mania-Tests-iOS
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ MinimumOSVersion
+ 10.0
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ XSAppIconAssets
+ Assets.xcassets/AppIcon.appiconset
+
+
diff --git a/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj b/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj
new file mode 100644
index 0000000000..24abccb19d
--- /dev/null
+++ b/osu.Game.Rulesets.Mania.Tests.iOS/osu.Game.Rulesets.Mania.Tests.iOS.csproj
@@ -0,0 +1,45 @@
+
+
+
+
+ Debug
+ iPhoneSimulator
+ {39FD990E-B6CE-4B2A-999F-BC008CF2C64C}
+ Exe
+ osu.Game.Rulesets.Mania.Tests
+ osu.Game.Rulesets.Mania.Tests.iOS
+
+
+
+
+
+
+ libbass.a
+ PreserveNewest
+
+
+ libbass_fx.a
+ PreserveNewest
+
+
+ Linker.xml
+
+
+
+
+ %(RecursiveDir)%(Filename)%(Extension)
+
+
+
+
+ {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}
+ osu.Game
+
+
+ {48F4582B-7687-4621-9CBE-5C24197CB536}
+ osu.Game.Rulesets.Mania
+
+
+
+
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json b/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json
index c781b0e64e..492f894484 100644
--- a/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json
+++ b/osu.Game.Rulesets.Mania.Tests/.vscode/launch.json
@@ -7,7 +7,7 @@
"request": "launch",
"program": "dotnet",
"args": [
- "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
+ "${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Debug)",
@@ -20,7 +20,7 @@
"request": "launch",
"program": "dotnet",
"args": [
- "${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Mania.Tests.dll"
+ "${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)",
diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs
index 58f2ab7747..6b95975059 100644
--- a/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs
+++ b/osu.Game.Rulesets.Mania.Tests/ManiaBeatmapConversionTest.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -40,29 +40,29 @@ namespace osu.Game.Rulesets.Mania.Tests
protected override Ruleset CreateRuleset() => new ManiaRuleset();
}
- public class ManiaConvertMapping : ConvertMapping, IEquatable
- {
- public uint RandomW;
- public uint RandomX;
- public uint RandomY;
- public uint RandomZ;
+ public class ManiaConvertMapping : ConvertMapping, IEquatable
+ {
+ public uint RandomW;
+ public uint RandomX;
+ public uint RandomY;
+ public uint RandomZ;
- public ManiaConvertMapping()
- {
- }
+ public ManiaConvertMapping()
+ {
+ }
- public ManiaConvertMapping(IBeatmapConverter converter)
- {
- var maniaConverter = (ManiaBeatmapConverter)converter;
- RandomW = maniaConverter.Random.W;
- RandomX = maniaConverter.Random.X;
- RandomY = maniaConverter.Random.Y;
- RandomZ = maniaConverter.Random.Z;
- }
+ public ManiaConvertMapping(IBeatmapConverter converter)
+ {
+ var maniaConverter = (ManiaBeatmapConverter)converter;
+ RandomW = maniaConverter.Random.W;
+ RandomX = maniaConverter.Random.X;
+ RandomY = maniaConverter.Random.Y;
+ RandomZ = maniaConverter.Random.Z;
+ }
- public bool Equals(ManiaConvertMapping other) => other != null && RandomW == other.RandomW && RandomX == other.RandomX && RandomY == other.RandomY && RandomZ == other.RandomZ;
- public override bool Equals(ConvertMapping other) => base.Equals(other) && Equals(other as ManiaConvertMapping);
- }
+ public bool Equals(ManiaConvertMapping other) => other != null && RandomW == other.RandomW && RandomX == other.RandomX && RandomY == other.RandomY && RandomZ == other.RandomZ;
+ public override bool Equals(ConvertMapping other) => base.Equals(other) && Equals(other as ManiaConvertMapping);
+ }
public struct ConvertValue : IEquatable
{
diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Mania.Tests/ManiaDifficultyCalculatorTest.cs
new file mode 100644
index 0000000000..2c36e81190
--- /dev/null
+++ b/osu.Game.Rulesets.Mania.Tests/ManiaDifficultyCalculatorTest.cs
@@ -0,0 +1,24 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Difficulty;
+using osu.Game.Rulesets.Mania.Difficulty;
+using osu.Game.Tests.Beatmaps;
+
+namespace osu.Game.Rulesets.Mania.Tests
+{
+ public class ManiaDifficultyCalculatorTest : DifficultyCalculatorTest
+ {
+ protected override string ResourceAssembly => "osu.Game.Rulesets.Mania";
+
+ [TestCase(2.3683365342338796d, "diffcalc-test")]
+ public void Test(double expected, string name)
+ => base.Test(expected, name);
+
+ protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(new ManiaRuleset(), beatmap);
+
+ protected override Ruleset CreateRuleset() => new ManiaRuleset();
+ }
+}
diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaInputTestCase.cs b/osu.Game.Rulesets.Mania.Tests/ManiaInputTestScene.cs
similarity index 83%
rename from osu.Game.Rulesets.Mania.Tests/ManiaInputTestCase.cs
rename to osu.Game.Rulesets.Mania.Tests/ManiaInputTestScene.cs
index 75c8fc7e79..909d0d45c6 100644
--- a/osu.Game.Rulesets.Mania.Tests/ManiaInputTestCase.cs
+++ b/osu.Game.Rulesets.Mania.Tests/ManiaInputTestScene.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -8,12 +8,12 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
- public abstract class ManiaInputTestCase : OsuTestCase
+ public abstract class ManiaInputTestScene : OsuTestScene
{
private readonly Container content;
protected override Container Content => content ?? base.Content;
- protected ManiaInputTestCase(int keys)
+ protected ManiaInputTestScene(int keys)
{
base.Content.Add(content = new LocalInputManager(keys));
}
diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaPlacementBlueprintTestCase.cs b/osu.Game.Rulesets.Mania.Tests/ManiaPlacementBlueprintTestScene.cs
similarity index 75%
rename from osu.Game.Rulesets.Mania.Tests/ManiaPlacementBlueprintTestCase.cs
rename to osu.Game.Rulesets.Mania.Tests/ManiaPlacementBlueprintTestScene.cs
index fb8c740d16..4b3786c30a 100644
--- a/osu.Game.Rulesets.Mania.Tests/ManiaPlacementBlueprintTestCase.cs
+++ b/osu.Game.Rulesets.Mania.Tests/ManiaPlacementBlueprintTestScene.cs
@@ -1,6 +1,8 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+using System;
+using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -8,6 +10,7 @@ using osu.Framework.Timing;
using osu.Game.Rulesets.Mania.Edit;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.UI;
+using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Tests.Visual;
@@ -17,11 +20,14 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[Cached(Type = typeof(IManiaHitObjectComposer))]
- public abstract class ManiaPlacementBlueprintTestCase : PlacementBlueprintTestCase, IManiaHitObjectComposer
+ public abstract class ManiaPlacementBlueprintTestScene : PlacementBlueprintTestScene, IManiaHitObjectComposer
{
private readonly Column column;
- protected ManiaPlacementBlueprintTestCase()
+ [Cached(typeof(IReadOnlyList))]
+ private IReadOnlyList mods { get; set; } = Array.Empty();
+
+ protected ManiaPlacementBlueprintTestScene()
{
Add(column = new Column(0)
{
diff --git a/osu.Game.Rulesets.Mania.Tests/ManiaSelectionBlueprintTestCase.cs b/osu.Game.Rulesets.Mania.Tests/ManiaSelectionBlueprintTestScene.cs
similarity index 74%
rename from osu.Game.Rulesets.Mania.Tests/ManiaSelectionBlueprintTestCase.cs
rename to osu.Game.Rulesets.Mania.Tests/ManiaSelectionBlueprintTestScene.cs
index 50de5ce7a3..b598893e8c 100644
--- a/osu.Game.Rulesets.Mania.Tests/ManiaSelectionBlueprintTestCase.cs
+++ b/osu.Game.Rulesets.Mania.Tests/ManiaSelectionBlueprintTestScene.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -13,14 +13,14 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[Cached(Type = typeof(IManiaHitObjectComposer))]
- public abstract class ManiaSelectionBlueprintTestCase : SelectionBlueprintTestCase, IManiaHitObjectComposer
+ public abstract class ManiaSelectionBlueprintTestScene : SelectionBlueprintTestScene, IManiaHitObjectComposer
{
[Cached(Type = typeof(IAdjustableClock))]
private readonly IAdjustableClock clock = new StopwatchClock();
private readonly Column column;
- protected ManiaSelectionBlueprintTestCase()
+ protected ManiaSelectionBlueprintTestScene()
{
Add(column = new Column(0)
{
diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseAutoGeneration.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneAutoGeneration.cs
similarity index 97%
rename from osu.Game.Rulesets.Mania.Tests/TestCaseAutoGeneration.cs
rename to osu.Game.Rulesets.Mania.Tests/TestSceneAutoGeneration.cs
index bab3a4db32..20ac5eaa39 100644
--- a/osu.Game.Rulesets.Mania.Tests/TestCaseAutoGeneration.cs
+++ b/osu.Game.Rulesets.Mania.Tests/TestSceneAutoGeneration.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using NUnit.Framework;
@@ -12,7 +12,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
- public class TestCaseAutoGeneration : OsuTestCase
+ public class TestSceneAutoGeneration : OsuTestScene
{
[Test]
public void TestSingleNote()
diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneColumn.cs
similarity index 88%
rename from osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs
rename to osu.Game.Rulesets.Mania.Tests/TestSceneColumn.cs
index eecc578861..d94a986dae 100644
--- a/osu.Game.Rulesets.Mania.Tests/TestCaseColumn.cs
+++ b/osu.Game.Rulesets.Mania.Tests/TestSceneColumn.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -13,6 +13,7 @@ using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mania.UI.Components;
+using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Tests.Visual;
using osuTK;
@@ -21,7 +22,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
- public class TestCaseColumn : ManiaInputTestCase
+ public class TestSceneColumn : ManiaInputTestScene
{
public override IReadOnlyList RequiredTypes => new[]
{
@@ -31,9 +32,12 @@ namespace osu.Game.Rulesets.Mania.Tests
typeof(ColumnHitObjectArea)
};
+ [Cached(typeof(IReadOnlyList))]
+ private IReadOnlyList mods { get; set; } = Array.Empty();
+
private readonly List columns = new List();
- public TestCaseColumn()
+ public TestSceneColumn()
: base(2)
{
}
diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseEditor.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneEditor.cs
similarity index 61%
rename from osu.Game.Rulesets.Mania.Tests/TestCaseEditor.cs
rename to osu.Game.Rulesets.Mania.Tests/TestSceneEditor.cs
index 6c0f931cda..7ed886be49 100644
--- a/osu.Game.Rulesets.Mania.Tests/TestCaseEditor.cs
+++ b/osu.Game.Rulesets.Mania.Tests/TestSceneEditor.cs
@@ -1,9 +1,9 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using NUnit.Framework;
using osu.Framework.Allocation;
-using osu.Framework.Configuration;
+using osu.Framework.Bindables;
using osu.Game.Rulesets.Mania.Configuration;
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Tests.Visual;
@@ -11,11 +11,11 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
- public class TestCaseEditor : EditorTestCase
+ public class TestSceneEditor : EditorTestScene
{
private readonly Bindable direction = new Bindable();
- public TestCaseEditor()
+ public TestSceneEditor()
: base(new ManiaRuleset())
{
AddStep("upwards scroll", () => direction.Value = ManiaScrollingDirection.Up);
@@ -25,8 +25,8 @@ namespace osu.Game.Rulesets.Mania.Tests
[BackgroundDependencyLoader]
private void load(RulesetConfigCache configCache)
{
- var config = (ManiaConfigManager)configCache.GetConfigFor(Ruleset.Value.CreateInstance());
- config.BindWith(ManiaSetting.ScrollDirection, direction);
+ var config = (ManiaRulesetConfigManager)configCache.GetConfigFor(Ruleset.Value.CreateInstance());
+ config.BindWith(ManiaRulesetSetting.ScrollDirection, direction);
}
}
}
diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseHoldNotePlacementBlueprint.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNotePlacementBlueprint.cs
similarity index 69%
rename from osu.Game.Rulesets.Mania.Tests/TestCaseHoldNotePlacementBlueprint.cs
rename to osu.Game.Rulesets.Mania.Tests/TestSceneHoldNotePlacementBlueprint.cs
index ea7433268d..b4332264b9 100644
--- a/osu.Game.Rulesets.Mania.Tests/TestCaseHoldNotePlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNotePlacementBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Edit.Blueprints;
@@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Tests
{
- public class TestCaseHoldNotePlacementBlueprint : ManiaPlacementBlueprintTestCase
+ public class TestSceneHoldNotePlacementBlueprint : ManiaPlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHoldNote((HoldNote)hitObject);
protected override PlacementBlueprint CreateBlueprint() => new HoldNotePlacementBlueprint();
diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseHoldNoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteSelectionBlueprint.cs
similarity index 82%
rename from osu.Game.Rulesets.Mania.Tests/TestCaseHoldNoteSelectionBlueprint.cs
rename to osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteSelectionBlueprint.cs
index 756031a463..622d840a0c 100644
--- a/osu.Game.Rulesets.Mania.Tests/TestCaseHoldNoteSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Mania.Tests/TestSceneHoldNoteSelectionBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -15,14 +15,14 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Mania.Tests
{
- public class TestCaseHoldNoteSelectionBlueprint : ManiaSelectionBlueprintTestCase
+ public class TestSceneHoldNoteSelectionBlueprint : ManiaSelectionBlueprintTestScene
{
private readonly DrawableHoldNote drawableObject;
protected override Container Content => content ?? base.Content;
private readonly Container content;
- public TestCaseHoldNoteSelectionBlueprint()
+ public TestSceneHoldNoteSelectionBlueprint()
{
var holdNote = new HoldNote { Column = 0, Duration = 1000 };
holdNote.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
@@ -36,7 +36,7 @@ namespace osu.Game.Rulesets.Mania.Tests
Child = drawableObject = new DrawableHoldNote(holdNote)
{
Height = 300,
- AccentColour = OsuColour.Gray(0.3f)
+ AccentColour = { Value = OsuColour.Gray(0.3f) }
}
};
}
diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseNotePlacementBlueprint.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneNotePlacementBlueprint.cs
similarity index 68%
rename from osu.Game.Rulesets.Mania.Tests/TestCaseNotePlacementBlueprint.cs
rename to osu.Game.Rulesets.Mania.Tests/TestSceneNotePlacementBlueprint.cs
index 9ae49d200e..d7b539a2a0 100644
--- a/osu.Game.Rulesets.Mania.Tests/TestCaseNotePlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Mania.Tests/TestSceneNotePlacementBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Mania.Edit.Blueprints;
@@ -10,7 +10,7 @@ using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Mania.Tests
{
- public class TestCaseNotePlacementBlueprint : ManiaPlacementBlueprintTestCase
+ public class TestSceneNotePlacementBlueprint : ManiaPlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableNote((Note)hitObject);
protected override PlacementBlueprint CreateBlueprint() => new NotePlacementBlueprint();
diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseNoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneNoteSelectionBlueprint.cs
similarity index 80%
rename from osu.Game.Rulesets.Mania.Tests/TestCaseNoteSelectionBlueprint.cs
rename to osu.Game.Rulesets.Mania.Tests/TestSceneNoteSelectionBlueprint.cs
index 4023f97eb3..6bb344f977 100644
--- a/osu.Game.Rulesets.Mania.Tests/TestCaseNoteSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Mania.Tests/TestSceneNoteSelectionBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -15,14 +15,14 @@ using osuTK;
namespace osu.Game.Rulesets.Mania.Tests
{
- public class TestCaseNoteSelectionBlueprint : ManiaSelectionBlueprintTestCase
+ public class TestSceneNoteSelectionBlueprint : ManiaSelectionBlueprintTestScene
{
private readonly DrawableNote drawableObject;
protected override Container Content => content ?? base.Content;
private readonly Container content;
- public TestCaseNoteSelectionBlueprint()
+ public TestSceneNoteSelectionBlueprint()
{
var note = new Note { Column = 0 };
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneNotes.cs
similarity index 93%
rename from osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs
rename to osu.Game.Rulesets.Mania.Tests/TestSceneNotes.cs
index 6344aee6bd..031abb08e2 100644
--- a/osu.Game.Rulesets.Mania.Tests/TestCaseNotes.cs
+++ b/osu.Game.Rulesets.Mania.Tests/TestSceneNotes.cs
@@ -1,19 +1,20 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
-using osu.Framework.Configuration;
+using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
-using osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
+using osu.Game.Graphics;
+using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Objects.Drawables;
@@ -26,7 +27,7 @@ using osuTK.Graphics;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
- public class TestCaseNotes : OsuTestCase
+ public class TestSceneNotes : OsuTestScene
{
public override IReadOnlyList RequiredTypes => new[]
{
@@ -69,7 +70,7 @@ namespace osu.Game.Rulesets.Mania.Tests
AutoSizeAxes = Axes.Both,
Child = new NoteContainer(direction, $"note {identifier}, scrolling {direction.ToString().ToLowerInvariant()}")
{
- Child = hitObject = new DrawableNote(note) { AccentColour = Color4.OrangeRed }
+ Child = hitObject = new DrawableNote(note) { AccentColour = { Value = Color4.OrangeRed } }
}
};
}
@@ -87,7 +88,7 @@ namespace osu.Game.Rulesets.Mania.Tests
Child = hitObject = new DrawableHoldNote(note)
{
RelativeSizeAxes = Axes.Both,
- AccentColour = Color4.OrangeRed,
+ AccentColour = { Value = Color4.OrangeRed },
}
}
};
@@ -137,11 +138,11 @@ namespace osu.Game.Rulesets.Mania.Tests
content = new Container { RelativeSizeAxes = Axes.Both }
}
},
- new SpriteText
+ new OsuSpriteText
{
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre,
- TextSize = 14,
+ Font = OsuFont.GetFont(size: 14),
Text = description
}
}
@@ -167,11 +168,13 @@ namespace osu.Game.Rulesets.Mania.Tests
foreach (var nested in obj.NestedHitObjects)
{
double finalPosition = (nested.HitObject.StartTime - obj.HitObject.StartTime) / endTime.Duration;
+
switch (direction)
{
case ScrollingDirection.Up:
nested.Y = (float)(finalPosition * content.DrawHeight);
break;
+
case ScrollingDirection.Down:
nested.Y = (float)(-finalPosition * content.DrawHeight);
break;
diff --git a/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs b/osu.Game.Rulesets.Mania.Tests/TestSceneStage.cs
similarity index 91%
rename from osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs
rename to osu.Game.Rulesets.Mania.Tests/TestSceneStage.cs
index 7acc37cb67..395e6daf0a 100644
--- a/osu.Game.Rulesets.Mania.Tests/TestCaseStage.cs
+++ b/osu.Game.Rulesets.Mania.Tests/TestSceneStage.cs
@@ -1,6 +1,7 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+using System;
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@@ -13,6 +14,7 @@ using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.UI;
+using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI.Scrolling;
using osu.Game.Tests.Visual;
using osuTK;
@@ -20,15 +22,18 @@ using osuTK;
namespace osu.Game.Rulesets.Mania.Tests
{
[TestFixture]
- public class TestCaseStage : ManiaInputTestCase
+ public class TestSceneStage : ManiaInputTestScene
{
private const int columns = 4;
+ [Cached(typeof(IReadOnlyList))]
+ private IReadOnlyList mods { get; set; } = Array.Empty();
+
private readonly List stages = new List();
private FillFlowContainer fill;
- public TestCaseStage()
+ public TestSceneStage()
: base(columns)
{
}
diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
index 98ad086c66..df5131dd8b 100644
--- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
+++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
@@ -2,14 +2,14 @@
-
-
-
+
+
+
WinExe
- netcoreapp2.1
+ netcoreapp2.2
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs
index ad5f8e447d..dc24a344e9 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmap.cs
@@ -1,10 +1,10 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . 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 osu.Framework.Graphics.Sprites;
using osu.Game.Beatmaps;
-using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.UI;
@@ -42,13 +42,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
{
Name = @"Note Count",
Content = notes.ToString(),
- Icon = FontAwesome.fa_circle_o
+ Icon = FontAwesome.Regular.Circle
},
new BeatmapStatistic
{
Name = @"Hold Note Count",
Content = holdnotes.ToString(),
- Icon = FontAwesome.fa_circle
+ Icon = FontAwesome.Regular.Circle
},
};
}
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
index 2770a6ff5b..e10602312e 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/ManiaBeatmapConverter.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mania.Objects;
using System;
@@ -27,6 +27,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
protected override IEnumerable ValidConversionTypes { get; } = new[] { typeof(IHasXPosition) };
public int TargetColumns;
+ public bool Dual;
public readonly bool IsForCurrentRuleset;
// Internal for testing purposes
@@ -45,7 +46,15 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
var roundedOverallDifficulty = Math.Round(beatmap.BeatmapInfo.BaseDifficulty.OverallDifficulty);
if (IsForCurrentRuleset)
+ {
TargetColumns = (int)Math.Max(1, roundedCircleSize);
+
+ if (TargetColumns >= 10)
+ {
+ TargetColumns = TargetColumns / 2;
+ Dual = true;
+ }
+ }
else
{
float percentSliderOrSpinner = (float)beatmap.HitObjects.Count(h => h is IHasEndTime) / beatmap.HitObjects.Count;
@@ -70,14 +79,22 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
return base.ConvertBeatmap(original);
}
- protected override Beatmap CreateBeatmap() => beatmap = new ManiaBeatmap(new StageDefinition { Columns = TargetColumns });
+ protected override Beatmap CreateBeatmap()
+ {
+ beatmap = new ManiaBeatmap(new StageDefinition { Columns = TargetColumns });
+
+ if (Dual)
+ beatmap.Stages.Add(new StageDefinition { Columns = TargetColumns });
+
+ return beatmap;
+ }
protected override IEnumerable ConvertHitObject(HitObject original, IBeatmap beatmap)
{
- var maniaOriginal = original as ManiaHitObject;
- if (maniaOriginal != null)
+ if (original is ManiaHitObject maniaOriginal)
{
yield return maniaOriginal;
+
yield break;
}
@@ -92,6 +109,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
private readonly List prevNoteTimes = new List(max_notes_for_density);
private double density = int.MaxValue;
+
private void computeDensity(double newNoteTime)
{
if (prevNoteTimes.Count == max_notes_for_density)
@@ -104,6 +122,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
private double lastTime;
private Vector2 lastPosition;
private PatternType lastStair = PatternType.Stair;
+
private void recordNote(double time, Vector2 position)
{
lastTime = time;
@@ -180,7 +199,6 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
foreach (var obj in newPattern.HitObjects)
yield return obj;
-
}
}
@@ -237,7 +255,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
///
/// The time to retrieve the sample info list from.
///
- private List sampleInfoListAt(double time)
+ private List sampleInfoListAt(double time)
{
var curveData = HitObject as IHasCurve;
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs
index 635004d2f6..ea418eedb4 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/DistanceObjectPatternGenerator.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -65,6 +65,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
if (originalPattern.HitObjects.Count() == 1)
{
yield return originalPattern;
+
yield break;
}
@@ -135,6 +136,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
if (convertType.HasFlag(PatternType.LowProbability))
return generateNRandomNotes(HitObject.StartTime, 0.78, 0.3, 0);
+
return generateNRandomNotes(HitObject.StartTime, 0.85, 0.36, 0.03);
}
@@ -142,6 +144,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
if (convertType.HasFlag(PatternType.LowProbability))
return generateNRandomNotes(HitObject.StartTime, 0.43, 0.08, 0);
+
return generateNRandomNotes(HitObject.StartTime, 0.56, 0.18, 0);
}
@@ -149,11 +152,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
if (convertType.HasFlag(PatternType.LowProbability))
return generateNRandomNotes(HitObject.StartTime, 0.3, 0, 0);
+
return generateNRandomNotes(HitObject.StartTime, 0.37, 0.08, 0);
}
if (convertType.HasFlag(PatternType.LowProbability))
return generateNRandomNotes(HitObject.StartTime, 0.17, 0, 0);
+
return generateNRandomNotes(HitObject.StartTime, 0.27, 0, 0);
}
@@ -174,6 +179,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
int usableColumns = TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects;
int nextColumn = GetRandomColumn();
+
for (int i = 0; i < Math.Min(usableColumns, noteCount); i++)
{
// Find available column
@@ -212,6 +218,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
nextColumn = FindAvailableColumn(nextColumn, PreviousPattern);
int lastColumn = nextColumn;
+
for (int i = 0; i < noteCount; i++)
{
addToPattern(pattern, nextColumn, startTime, startTime);
@@ -294,6 +301,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
int interval = Random.Next(1, TotalColumns - (legacy ? 1 : 0));
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
+
for (int i = 0; i <= spanCount; i++)
{
addToPattern(pattern, nextColumn, startTime, startTime);
@@ -336,16 +344,19 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
p3 = 0;
p4 = 0;
break;
+
case 3:
p2 = Math.Min(p2, 0.1);
p3 = 0;
p4 = 0;
break;
+
case 4:
p2 = Math.Min(p2, 0.3);
p3 = Math.Min(p3, 0.04);
p4 = 0;
break;
+
case 5:
p2 = Math.Min(p2, 0.34);
p3 = Math.Min(p3, 0.1);
@@ -353,7 +364,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
break;
}
- bool isDoubleSample(SampleInfo sample) => sample.Name == SampleInfo.HIT_CLAP || sample.Name == SampleInfo.HIT_FINISH;
+ bool isDoubleSample(HitSampleInfo sample) => sample.Name == HitSampleInfo.HIT_CLAP || sample.Name == HitSampleInfo.HIT_FINISH;
bool canGenerateTwoNotes = !convertType.HasFlag(PatternType.LowProbability);
canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(HitObject.StartTime).Any(isDoubleSample);
@@ -432,9 +443,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
noteCount = 0;
noteCount = Math.Min(TotalColumns - 1, noteCount);
- bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP);
+ bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == HitSampleInfo.HIT_WHISTLE || s.Name == HitSampleInfo.HIT_FINISH || s.Name == HitSampleInfo.HIT_CLAP);
var rowPattern = new Pattern();
+
for (int i = 0; i <= spanCount; i++)
{
if (!(ignoreHead && startTime == HitObject.StartTime))
@@ -460,7 +472,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
///
/// The time to retrieve the sample info list from.
///
- private List sampleInfoListAt(double time)
+ private List sampleInfoListAt(double time)
{
var curveData = HitObject as IHasCurve;
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs
index 775a4145e6..b3be08e1f7 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/EndTimeObjectPatternGenerator.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Game.Rulesets.Mania.MathUtils;
@@ -35,12 +35,14 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
switch (TotalColumns)
{
- case 8 when HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000:
+ case 8 when HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH) && endTime - HitObject.StartTime < 1000:
addToPattern(pattern, 0, generateHold);
break;
+
case 8:
addToPattern(pattern, FindAvailableColumn(GetRandomColumn(), PreviousPattern), generateHold);
break;
+
default:
if (TotalColumns > 0)
addToPattern(pattern, GetRandomColumn(), generateHold);
@@ -70,9 +72,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
};
if (hold.Head.Samples == null)
- hold.Head.Samples = new List();
+ hold.Head.Samples = new List();
- hold.Head.Samples.Add(new SampleInfo { Name = SampleInfo.HIT_NORMAL });
+ hold.Head.Samples.Add(new HitSampleInfo { Name = HitSampleInfo.HIT_NORMAL });
hold.Tail.Samples = HitObject.Samples;
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs
index 8463e209e4..decd159ee9 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/HitObjectPatternGenerator.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -79,9 +79,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
if (!convertType.HasFlag(PatternType.KeepSingle))
{
- if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH) && TotalColumns != 8)
+ if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH) && TotalColumns != 8)
convertType |= PatternType.Mirror;
- else if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP))
+ else if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP))
convertType |= PatternType.Gathered;
}
}
@@ -116,10 +116,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
}
if (convertType.HasFlag(PatternType.Cycle) && PreviousPattern.HitObjects.Count() == 1
- // If we convert to 7K + 1, let's not overload the special key
- && (TotalColumns != 8 || lastColumn != 0)
- // Make sure the last column was not the centre column
- && (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2))
+ // If we convert to 7K + 1, let's not overload the special key
+ && (TotalColumns != 8 || lastColumn != 0)
+ // Make sure the last column was not the centre column
+ && (TotalColumns % 2 == 0 || lastColumn != TotalColumns / 2))
{
// Generate a new pattern by cycling backwards (similar to Reverse but for only one hit object)
int column = RandomStart + TotalColumns - lastColumn - 1;
@@ -172,6 +172,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
return pattern = generateRandomPatternWithMirrored(0.12, 0.38, 0.12);
if (ConversionDifficulty > 4)
return pattern = generateRandomPatternWithMirrored(0.12, 0.17, 0);
+
return pattern = generateRandomPatternWithMirrored(0.12, 0, 0);
}
@@ -179,6 +180,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
if (convertType.HasFlag(PatternType.LowProbability))
return pattern = generateRandomPattern(0.78, 0.42, 0, 0);
+
return pattern = generateRandomPattern(1, 0.62, 0, 0);
}
@@ -186,6 +188,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
if (convertType.HasFlag(PatternType.LowProbability))
return pattern = generateRandomPattern(0.35, 0.08, 0, 0);
+
return pattern = generateRandomPattern(0.52, 0.15, 0, 0);
}
@@ -193,6 +196,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
{
if (convertType.HasFlag(PatternType.LowProbability))
return pattern = generateRandomPattern(0.18, 0, 0, 0);
+
return pattern = generateRandomPattern(0.45, 0, 0, 0);
}
@@ -229,6 +233,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
noteCount = Math.Min(noteCount, TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects);
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
+
for (int i = 0; i < noteCount; i++)
{
nextColumn = allowStacking
@@ -250,6 +255,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
}
else
last = GetRandomColumn();
+
return last;
}
}
@@ -257,7 +263,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
///
/// Whether this hit object can generate a note in the special column.
///
- private bool hasSpecialColumn => HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP) && HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_FINISH);
+ private bool hasSpecialColumn => HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP) && HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH);
///
/// Generates a random pattern.
@@ -298,6 +304,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
int columnLimit = (TotalColumns % 2 == 0 ? TotalColumns : TotalColumns - 1) / 2;
int nextColumn = GetRandomColumn(upperBound: columnLimit);
+
for (int i = 0; i < noteCount; i++)
{
nextColumn = FindAvailableColumn(nextColumn, upperBound: columnLimit, patterns: pattern);
@@ -335,18 +342,21 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
p4 = 0;
p5 = 0;
break;
+
case 3:
p2 = Math.Min(p2, 0.1);
p3 = 0;
p4 = 0;
p5 = 0;
break;
+
case 4:
p2 = Math.Min(p2, 0.23);
p3 = Math.Min(p3, 0.04);
p4 = 0;
p5 = 0;
break;
+
case 5:
p3 = Math.Min(p3, 0.15);
p4 = Math.Min(p4, 0.03);
@@ -354,7 +364,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
break;
}
- if (HitObject.Samples.Any(s => s.Name == SampleInfo.HIT_CLAP))
+ if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_CLAP))
p2 = 1;
return GetRandomNoteCount(p2, p3, p4, p5);
@@ -379,20 +389,24 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
p2 = 0;
p3 = 0;
break;
+
case 3:
centreProbability = Math.Min(centreProbability, 0.03);
p2 = 0;
p3 = 0;
break;
+
case 4:
centreProbability = 0;
p2 = Math.Min(p2 * 2, 0.2);
p3 = 0;
break;
+
case 5:
centreProbability = Math.Min(centreProbability, 0.03);
p3 = 0;
break;
+
case 6:
centreProbability = 0;
p2 = Math.Min(p2 * 2, 0.5);
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs
index f412e127c5..fba52dfc32 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternGenerator.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
@@ -87,6 +87,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
return 4;
if (val >= 1 - p3)
return 3;
+
return val >= 1 - p2 ? 2 : 1;
}
@@ -157,6 +158,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
// Ensure that we have at least one free column, so that an endless loop is avoided
bool hasValidColumns = false;
+
for (int i = lowerBound.Value; i < upperBound.Value; i++)
{
hasValidColumns = isValid(i);
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs
index 2eba2d5843..a3cd455886 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Legacy/PatternType.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
@@ -12,51 +12,63 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
internal enum PatternType
{
None = 0,
+
///
/// Keep the same as last row.
///
ForceStack = 1 << 0,
+
///
/// Keep different from last row.
///
ForceNotStack = 1 << 1,
+
///
/// Keep as single note at its original position.
///
KeepSingle = 1 << 2,
+
///
/// Use a lower random value.
///
LowProbability = 1 << 3,
+
///
/// Reserved.
///
Alternate = 1 << 4,
+
///
/// Ignore the repeat count.
///
ForceSigSlider = 1 << 5,
+
///
/// Convert slider to circle.
///
ForceNotSlider = 1 << 6,
+
///
/// Notes gathered together.
///
Gathered = 1 << 7,
Mirror = 1 << 8,
+
///
/// Change 0 -> 6.
///
Reverse = 1 << 9,
+
///
/// 1 -> 5 -> 1 -> 5 like reverse.
///
Cycle = 1 << 10,
+
///
/// Next note will be at column + 1.
///
Stair = 1 << 11,
+
///
/// Next note will be at column - 1.
///
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Pattern.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Pattern.cs
index 32d2d096b2..f095a0ffce 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Pattern.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/Pattern.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs
index a42d57cdd1..71b3f6ecf2 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/Patterns/PatternGenerator.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
diff --git a/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs b/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs
index afec607a7c..dff7cb72ce 100644
--- a/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs
+++ b/osu.Game.Rulesets.Mania/Beatmaps/StageDefinition.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mania.UI;
diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs
deleted file mode 100644
index 1c9e1e4c73..0000000000
--- a/osu.Game.Rulesets.Mania/Configuration/ManiaConfigManager.cs
+++ /dev/null
@@ -1,37 +0,0 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Framework.Configuration.Tracking;
-using osu.Game.Configuration;
-using osu.Game.Rulesets.Configuration;
-using osu.Game.Rulesets.Mania.UI;
-
-namespace osu.Game.Rulesets.Mania.Configuration
-{
- public class ManiaConfigManager : RulesetConfigManager
- {
- public ManiaConfigManager(SettingsStore settings, RulesetInfo ruleset, int? variant = null)
- : base(settings, ruleset, variant)
- {
- }
-
- protected override void InitialiseDefaults()
- {
- base.InitialiseDefaults();
-
- Set(ManiaSetting.ScrollTime, 2250.0, 50.0, 10000.0, 50.0);
- Set(ManiaSetting.ScrollDirection, ManiaScrollingDirection.Down);
- }
-
- public override TrackedSettings CreateTrackedSettings() => new TrackedSettings
- {
- new TrackedSetting(ManiaSetting.ScrollTime, v => new SettingDescription(v, "Scroll Time", $"{v}ms"))
- };
- }
-
- public enum ManiaSetting
- {
- ScrollTime,
- ScrollDirection
- }
-}
diff --git a/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs b/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs
new file mode 100644
index 0000000000..b591f9da22
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/Configuration/ManiaRulesetConfigManager.cs
@@ -0,0 +1,37 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Configuration.Tracking;
+using osu.Game.Configuration;
+using osu.Game.Rulesets.Configuration;
+using osu.Game.Rulesets.Mania.UI;
+
+namespace osu.Game.Rulesets.Mania.Configuration
+{
+ public class ManiaRulesetConfigManager : RulesetConfigManager
+ {
+ public ManiaRulesetConfigManager(SettingsStore settings, RulesetInfo ruleset, int? variant = null)
+ : base(settings, ruleset, variant)
+ {
+ }
+
+ protected override void InitialiseDefaults()
+ {
+ base.InitialiseDefaults();
+
+ Set(ManiaRulesetSetting.ScrollTime, 2250.0, 50.0, 10000.0, 50.0);
+ Set(ManiaRulesetSetting.ScrollDirection, ManiaScrollingDirection.Down);
+ }
+
+ public override TrackedSettings CreateTrackedSettings() => new TrackedSettings
+ {
+ new TrackedSetting(ManiaRulesetSetting.ScrollTime, v => new SettingDescription(v, "Scroll Time", $"{v}ms"))
+ };
+ }
+
+ public enum ManiaRulesetSetting
+ {
+ ScrollTime,
+ ScrollDirection
+ }
+}
diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyAttributes.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyAttributes.cs
index c7f6890b93..3ff665d2c8 100644
--- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyAttributes.cs
+++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyAttributes.cs
@@ -1,18 +1,12 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Difficulty;
-using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Difficulty
{
public class ManiaDifficultyAttributes : DifficultyAttributes
{
public double GreatHitWindow;
-
- public ManiaDifficultyAttributes(Mod[] mods, double starRating)
- : base(mods, starRating)
- {
- }
}
}
diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs
index 7b4d4b12ed..4a9c22d339 100644
--- a/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaDifficultyCalculator.cs
@@ -1,34 +1,24 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
-using System;
using System.Collections.Generic;
using System.Linq;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Difficulty;
+using osu.Game.Rulesets.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Difficulty.Skills;
using osu.Game.Rulesets.Mania.Beatmaps;
+using osu.Game.Rulesets.Mania.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Mania.Difficulty.Skills;
using osu.Game.Rulesets.Mania.Mods;
-using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Difficulty
{
- internal class ManiaDifficultyCalculator : DifficultyCalculator
+ public class ManiaDifficultyCalculator : DifficultyCalculator
{
private const double star_scaling_factor = 0.018;
- ///
- /// In milliseconds. For difficulty calculation we will only look at the highest strain value in each time interval of size strain_step.
- /// This is to eliminate higher influence of stream over aim by simply having more HitObjects with high strain.
- /// The higher this value, the less strains there will be, indirectly giving long beatmaps an advantage.
- ///
- private const double strain_step = 400;
-
- ///
- /// The weighting of each strain value decays to this number * it's previous value
- ///
- private const double decay_weight = 0.9;
-
private readonly bool isForCurrentRuleset;
public ManiaDifficultyCalculator(Ruleset ruleset, WorkingBeatmap beatmap)
@@ -37,109 +27,71 @@ namespace osu.Game.Rulesets.Mania.Difficulty
isForCurrentRuleset = beatmap.BeatmapInfo.Ruleset.Equals(ruleset.RulesetInfo);
}
- protected override DifficultyAttributes Calculate(IBeatmap beatmap, Mod[] mods, double timeRate)
+ protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
{
- if (!beatmap.HitObjects.Any())
- return new ManiaDifficultyAttributes(mods, 0);
+ if (beatmap.HitObjects.Count == 0)
+ return new ManiaDifficultyAttributes { Mods = mods, Skills = skills };
- var difficultyHitObjects = new List();
-
- int columnCount = ((ManiaBeatmap)beatmap).TotalColumns;
-
- // Sort DifficultyHitObjects by StartTime of the HitObjects - just to make sure.
- // Note: Stable sort is done so that the ordering of hitobjects with equal start times doesn't change
- difficultyHitObjects.AddRange(beatmap.HitObjects.Select(h => new ManiaHitObjectDifficulty((ManiaHitObject)h, columnCount)).OrderBy(h => h.BaseHitObject.StartTime));
-
- if (!calculateStrainValues(difficultyHitObjects, timeRate))
- return new DifficultyAttributes(mods, 0);
-
-
- double starRating = calculateDifficulty(difficultyHitObjects, timeRate) * star_scaling_factor;
-
- return new ManiaDifficultyAttributes(mods, starRating)
+ return new ManiaDifficultyAttributes
{
- // Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be remoevd in the future
- GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / timeRate
+ StarRating = difficultyValue(skills) * star_scaling_factor,
+ Mods = mods,
+ // Todo: This int cast is temporary to achieve 1:1 results with osu!stable, and should be removed in the future
+ GreatHitWindow = (int)(beatmap.HitObjects.First().HitWindows.Great / 2) / clockRate,
+ Skills = skills
};
}
- private bool calculateStrainValues(List objects, double timeRate)
+ private double difficultyValue(Skill[] skills)
{
- // Traverse hitObjects in pairs to calculate the strain value of NextHitObject from the strain value of CurrentHitObject and environment.
- using (var hitObjectsEnumerator = objects.GetEnumerator())
+ // Preprocess the strains to find the maximum overall + individual (aggregate) strain from each section
+ var overall = skills.OfType().Single();
+ var aggregatePeaks = new List(Enumerable.Repeat(0.0, overall.StrainPeaks.Count));
+
+ foreach (var individual in skills.OfType())
{
- if (!hitObjectsEnumerator.MoveNext())
- return false;
-
- ManiaHitObjectDifficulty current = hitObjectsEnumerator.Current;
-
- // First hitObject starts at strain 1. 1 is the default for strain values, so we don't need to set it here. See DifficultyHitObject.
- while (hitObjectsEnumerator.MoveNext())
+ for (int i = 0; i < individual.StrainPeaks.Count; i++)
{
- var next = hitObjectsEnumerator.Current;
- next?.CalculateStrains(current, timeRate);
- current = next;
+ double aggregate = individual.StrainPeaks[i] + overall.StrainPeaks[i];
+
+ if (aggregate > aggregatePeaks[i])
+ aggregatePeaks[i] = aggregate;
}
-
- return true;
- }
- }
-
- private double calculateDifficulty(List objects, double timeRate)
- {
- double actualStrainStep = strain_step * timeRate;
-
- // Find the highest strain value within each strain step
- List highestStrains = new List();
- double intervalEndTime = actualStrainStep;
- double maximumStrain = 0; // We need to keep track of the maximum strain in the current interval
-
- ManiaHitObjectDifficulty previousHitObject = null;
- foreach (var hitObject in objects)
- {
- // While we are beyond the current interval push the currently available maximum to our strain list
- while (hitObject.BaseHitObject.StartTime > intervalEndTime)
- {
- highestStrains.Add(maximumStrain);
-
- // The maximum strain of the next interval is not zero by default! We need to take the last hitObject we encountered, take its strain and apply the decay
- // until the beginning of the next interval.
- if (previousHitObject == null)
- {
- maximumStrain = 0;
- }
- else
- {
- double individualDecay = Math.Pow(ManiaHitObjectDifficulty.INDIVIDUAL_DECAY_BASE, (intervalEndTime - previousHitObject.BaseHitObject.StartTime) / 1000);
- double overallDecay = Math.Pow(ManiaHitObjectDifficulty.OVERALL_DECAY_BASE, (intervalEndTime - previousHitObject.BaseHitObject.StartTime) / 1000);
- maximumStrain = previousHitObject.IndividualStrain * individualDecay + previousHitObject.OverallStrain * overallDecay;
- }
-
- // Go to the next time interval
- intervalEndTime += actualStrainStep;
- }
-
- // Obtain maximum strain
- double strain = hitObject.IndividualStrain + hitObject.OverallStrain;
- maximumStrain = Math.Max(strain, maximumStrain);
-
- previousHitObject = hitObject;
}
- // Build the weighted sum over the highest strains for each interval
+ aggregatePeaks.Sort((a, b) => b.CompareTo(a)); // Sort from highest to lowest strain.
+
double difficulty = 0;
double weight = 1;
- highestStrains.Sort((a, b) => b.CompareTo(a)); // Sort from highest to lowest strain.
- foreach (double strain in highestStrains)
+ // Difficulty is the weighted sum of the highest strains from every section.
+ foreach (double strain in aggregatePeaks)
{
- difficulty += weight * strain;
- weight *= decay_weight;
+ difficulty += strain * weight;
+ weight *= 0.9;
}
return difficulty;
}
+ protected override IEnumerable CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
+ {
+ for (int i = 1; i < beatmap.HitObjects.Count; i++)
+ yield return new ManiaDifficultyHitObject(beatmap.HitObjects[i], beatmap.HitObjects[i - 1], clockRate);
+ }
+
+ protected override Skill[] CreateSkills(IBeatmap beatmap)
+ {
+ int columnCount = ((ManiaBeatmap)beatmap).TotalColumns;
+
+ var skills = new List { new Overall(columnCount) };
+
+ for (int i = 0; i < columnCount; i++)
+ skills.Add(new Individual(i, columnCount));
+
+ return skills.ToArray();
+ }
+
protected override Mod[] DifficultyAdjustmentMods
{
get
diff --git a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs
index 610c7a8fee..b99bddee96 100644
--- a/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Mania/Difficulty/ManiaPerformanceCalculator.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -114,8 +114,8 @@ namespace osu.Game.Rulesets.Mania.Difficulty
// Lots of arbitrary values from testing.
// Considering to use derivation from perfect accuracy in a probabilistic manner - assume normal distribution
double accuracyValue = Math.Max(0.0, 0.2 - (Attributes.GreatHitWindow - 34) * 0.006667)
- * strainValue
- * Math.Pow(Math.Max(0.0, scaledScore - 960000) / 40000, 1.1);
+ * strainValue
+ * Math.Pow(Math.Max(0.0, scaledScore - 960000) / 40000, 1.1);
// Bonus for many hitcircles - it's harder to keep good accuracy up for longer
// accuracyValue *= Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3));
diff --git a/osu.Game.Rulesets.Mania/Difficulty/Preprocessing/ManiaDifficultyHitObject.cs b/osu.Game.Rulesets.Mania/Difficulty/Preprocessing/ManiaDifficultyHitObject.cs
new file mode 100644
index 0000000000..29ba934e9f
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/Difficulty/Preprocessing/ManiaDifficultyHitObject.cs
@@ -0,0 +1,19 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Game.Rulesets.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Mania.Objects;
+using osu.Game.Rulesets.Objects;
+
+namespace osu.Game.Rulesets.Mania.Difficulty.Preprocessing
+{
+ public class ManiaDifficultyHitObject : DifficultyHitObject
+ {
+ public new ManiaHitObject BaseObject => (ManiaHitObject)base.BaseObject;
+
+ public ManiaDifficultyHitObject(HitObject hitObject, HitObject lastObject, double clockRate)
+ : base(hitObject, lastObject, clockRate)
+ {
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Mania/Difficulty/Skills/Individual.cs b/osu.Game.Rulesets.Mania/Difficulty/Skills/Individual.cs
new file mode 100644
index 0000000000..059cd39641
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/Difficulty/Skills/Individual.cs
@@ -0,0 +1,47 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System.Linq;
+using osu.Game.Rulesets.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Difficulty.Skills;
+using osu.Game.Rulesets.Mania.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Mania.Objects;
+
+namespace osu.Game.Rulesets.Mania.Difficulty.Skills
+{
+ public class Individual : Skill
+ {
+ protected override double SkillMultiplier => 1;
+ protected override double StrainDecayBase => 0.125;
+
+ private readonly double[] holdEndTimes;
+
+ private readonly int column;
+
+ public Individual(int column, int columnCount)
+ {
+ this.column = column;
+
+ holdEndTimes = new double[columnCount];
+ }
+
+ protected override double StrainValueOf(DifficultyHitObject current)
+ {
+ var maniaCurrent = (ManiaDifficultyHitObject)current;
+ var endTime = (maniaCurrent.BaseObject as HoldNote)?.EndTime ?? maniaCurrent.BaseObject.StartTime;
+
+ try
+ {
+ if (maniaCurrent.BaseObject.Column != column)
+ return 0;
+
+ // We give a slight bonus if something is held meanwhile
+ return holdEndTimes.Any(t => t > endTime) ? 2.5 : 2;
+ }
+ finally
+ {
+ holdEndTimes[maniaCurrent.BaseObject.Column] = endTime;
+ }
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Mania/Difficulty/Skills/Overall.cs b/osu.Game.Rulesets.Mania/Difficulty/Skills/Overall.cs
new file mode 100644
index 0000000000..ed25173d38
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/Difficulty/Skills/Overall.cs
@@ -0,0 +1,56 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Game.Rulesets.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Difficulty.Skills;
+using osu.Game.Rulesets.Mania.Difficulty.Preprocessing;
+using osu.Game.Rulesets.Mania.Objects;
+
+namespace osu.Game.Rulesets.Mania.Difficulty.Skills
+{
+ public class Overall : Skill
+ {
+ protected override double SkillMultiplier => 1;
+ protected override double StrainDecayBase => 0.3;
+
+ private readonly double[] holdEndTimes;
+
+ private readonly int columnCount;
+
+ public Overall(int columnCount)
+ {
+ this.columnCount = columnCount;
+
+ holdEndTimes = new double[columnCount];
+ }
+
+ protected override double StrainValueOf(DifficultyHitObject current)
+ {
+ var maniaCurrent = (ManiaDifficultyHitObject)current;
+ var endTime = (maniaCurrent.BaseObject as HoldNote)?.EndTime ?? maniaCurrent.BaseObject.StartTime;
+
+ double holdFactor = 1.0; // Factor in case something else is held
+ double holdAddition = 0; // Addition to the current note in case it's a hold and has to be released awkwardly
+
+ for (int i = 0; i < columnCount; i++)
+ {
+ // If there is at least one other overlapping end or note, then we get an addition, buuuuuut...
+ if (current.BaseObject.StartTime < holdEndTimes[i] && endTime > holdEndTimes[i])
+ holdAddition = 1.0;
+
+ // ... this addition only is valid if there is _no_ other note with the same ending.
+ // Releasing multiple notes at the same time is just as easy as releasing one
+ if (endTime == holdEndTimes[i])
+ holdAddition = 0;
+
+ // We give a slight bonus if something is held meanwhile
+ if (holdEndTimes[i] > endTime)
+ holdFactor = 1.25;
+ }
+
+ holdEndTimes[maniaCurrent.BaseObject.Column] = endTime;
+
+ return (1 + holdAddition) * holdFactor;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs
index 41b2e950f9..b99a1157f3 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditBodyPiece.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Game.Graphics;
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditNotePiece.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditNotePiece.cs
index 424ff1118c..6f85fd9167 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditNotePiece.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/Components/EditNotePiece.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics.Containers;
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs
index 081bdffc27..26115311f7 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNotePlacementBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs
index 4b78dd68cb..d64c5dbc6a 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/HoldNoteSelectionBlueprint.cs
@@ -1,8 +1,8 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Configuration;
+using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Primitives;
using osu.Game.Graphics;
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs
index d76d20f2b8..d3779e2e18 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaPlacementBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs
index f190843f5d..d3c12b1944 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/ManiaSelectionBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/NotePlacementBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/NotePlacementBlueprint.cs
index acb43e38ba..32c6a6fd07 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/NotePlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/NotePlacementBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
diff --git a/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs
index 440a539412..d345b14e84 100644
--- a/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Blueprints/NoteSelectionBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Edit.Blueprints.Components;
diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaEditRulesetContainer.cs b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs
similarity index 55%
rename from osu.Game.Rulesets.Mania/Edit/ManiaEditRulesetContainer.cs
rename to osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs
index f605ad0a22..e5f379f608 100644
--- a/osu.Game.Rulesets.Mania/Edit/ManiaEditRulesetContainer.cs
+++ b/osu.Game.Rulesets.Mania/Edit/DrawableManiaEditRuleset.cs
@@ -1,21 +1,23 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+using System.Collections.Generic;
using osu.Framework.Graphics;
using osuTK;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.UI;
+using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using osu.Game.Rulesets.UI.Scrolling;
namespace osu.Game.Rulesets.Mania.Edit
{
- public class ManiaEditRulesetContainer : ManiaRulesetContainer
+ public class DrawableManiaEditRuleset : DrawableManiaRuleset
{
public new IScrollingInfo ScrollingInfo => base.ScrollingInfo;
- public ManiaEditRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
- : base(ruleset, beatmap)
+ public DrawableManiaEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods)
+ : base(ruleset, beatmap, mods)
{
}
diff --git a/osu.Game.Rulesets.Mania/Edit/HoldNoteCompositionTool.cs b/osu.Game.Rulesets.Mania/Edit/HoldNoteCompositionTool.cs
index b1872c200f..295bf417c4 100644
--- a/osu.Game.Rulesets.Mania/Edit/HoldNoteCompositionTool.cs
+++ b/osu.Game.Rulesets.Mania/Edit/HoldNoteCompositionTool.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools;
diff --git a/osu.Game.Rulesets.Mania/Edit/IManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/IManiaHitObjectComposer.cs
index d9de400ac5..f64bab1fae 100644
--- a/osu.Game.Rulesets.Mania/Edit/IManiaHitObjectComposer.cs
+++ b/osu.Game.Rulesets.Mania/Edit/IManiaHitObjectComposer.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mania.UI;
using osuTK;
diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaEditPlayfield.cs b/osu.Game.Rulesets.Mania/Edit/ManiaEditPlayfield.cs
index e7bc526471..a42f793a77 100644
--- a/osu.Game.Rulesets.Mania/Edit/ManiaEditPlayfield.cs
+++ b/osu.Game.Rulesets.Mania/Edit/ManiaEditPlayfield.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.UI;
diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs
index d73ce3966f..2729621ab3 100644
--- a/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs
+++ b/osu.Game.Rulesets.Mania/Edit/ManiaHitObjectComposer.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
@@ -11,6 +11,7 @@ using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Game.Rulesets.Mania.Edit.Blueprints;
using osu.Game.Rulesets.Mania.UI;
+using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.UI;
using osu.Game.Screens.Edit.Compose.Components;
using osuTK;
@@ -20,7 +21,7 @@ namespace osu.Game.Rulesets.Mania.Edit
[Cached(Type = typeof(IManiaHitObjectComposer))]
public class ManiaHitObjectComposer : HitObjectComposer, IManiaHitObjectComposer
{
- protected new ManiaEditRulesetContainer RulesetContainer { get; private set; }
+ protected new DrawableManiaEditRuleset DrawableRuleset { get; private set; }
public ManiaHitObjectComposer(Ruleset ruleset)
: base(ruleset)
@@ -32,23 +33,23 @@ namespace osu.Game.Rulesets.Mania.Edit
///
/// The screen-space position.
/// The column which intersects with .
- public Column ColumnAt(Vector2 screenSpacePosition) => RulesetContainer.GetColumnByPosition(screenSpacePosition);
+ public Column ColumnAt(Vector2 screenSpacePosition) => DrawableRuleset.GetColumnByPosition(screenSpacePosition);
private DependencyContainer dependencies;
protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent)
=> dependencies = new DependencyContainer(base.CreateChildDependencies(parent));
- public int TotalColumns => ((ManiaPlayfield)RulesetContainer.Playfield).TotalColumns;
+ public int TotalColumns => ((ManiaPlayfield)DrawableRuleset.Playfield).TotalColumns;
- protected override RulesetContainer CreateRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
+ protected override DrawableRuleset CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods)
{
- RulesetContainer = new ManiaEditRulesetContainer(ruleset, beatmap);
+ DrawableRuleset = new DrawableManiaEditRuleset(ruleset, beatmap, mods);
// This is the earliest we can cache the scrolling info to ourselves, before masks are added to the hierarchy and inject it
- dependencies.CacheAs(RulesetContainer.ScrollingInfo);
+ dependencies.CacheAs(DrawableRuleset.ScrollingInfo);
- return RulesetContainer;
+ return DrawableRuleset;
}
protected override IReadOnlyList CompositionTools => new HitObjectCompositionTool[]
@@ -65,6 +66,7 @@ namespace osu.Game.Rulesets.Mania.Edit
{
case DrawableNote note:
return new NoteSelectionBlueprint(note);
+
case DrawableHoldNote holdNote:
return new HoldNoteSelectionBlueprint(holdNote);
}
diff --git a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs
index 828f6d87bc..6f49c7f0c4 100644
--- a/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs
+++ b/osu.Game.Rulesets.Mania/Edit/ManiaSelectionHandler.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osu.Framework.Allocation;
diff --git a/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs b/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs
index 81a2728ad4..30b0f09a94 100644
--- a/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Mania/Edit/Masks/ManiaSelectionBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Game.Rulesets.Edit;
diff --git a/osu.Game.Rulesets.Mania/Edit/NoteCompositionTool.cs b/osu.Game.Rulesets.Mania/Edit/NoteCompositionTool.cs
index 93f49d1cc0..50b5f9a8fe 100644
--- a/osu.Game.Rulesets.Mania/Edit/NoteCompositionTool.cs
+++ b/osu.Game.Rulesets.Mania/Edit/NoteCompositionTool.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Tools;
diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs
index 9055e48a4c..e8b48768a1 100644
--- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs
+++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteJudgement.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Scoring;
diff --git a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs
index 6eb5a79200..b9c6e3a7f7 100644
--- a/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs
+++ b/osu.Game.Rulesets.Mania/Judgements/HoldNoteTickJudgement.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Scoring;
@@ -10,5 +10,17 @@ namespace osu.Game.Rulesets.Mania.Judgements
public override bool AffectsCombo => false;
protected override int NumericResultFor(HitResult result) => 20;
+
+ protected override double HealthIncreaseFor(HitResult result)
+ {
+ switch (result)
+ {
+ case HitResult.Miss:
+ return 0;
+
+ default:
+ return 0.040;
+ }
+ }
}
}
diff --git a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs
index 4e0649c708..0e4c811945 100644
--- a/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs
+++ b/osu.Game.Rulesets.Mania/Judgements/ManiaJudgement.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
@@ -14,16 +14,47 @@ namespace osu.Game.Rulesets.Mania.Judgements
{
default:
return 0;
+
case HitResult.Meh:
return 50;
+
case HitResult.Ok:
return 100;
+
case HitResult.Good:
return 200;
+
case HitResult.Great:
case HitResult.Perfect:
return 300;
}
}
+
+ protected override double HealthIncreaseFor(HitResult result)
+ {
+ switch (result)
+ {
+ case HitResult.Miss:
+ return -0.125;
+
+ case HitResult.Meh:
+ return 0.005;
+
+ case HitResult.Ok:
+ return 0.010;
+
+ case HitResult.Good:
+ return 0.035;
+
+ case HitResult.Great:
+ return 0.055;
+
+ case HitResult.Perfect:
+ return 0.065;
+
+ default:
+ return 0;
+ }
+ }
}
}
diff --git a/osu.Game.Rulesets.Mania/ManiaInputManager.cs b/osu.Game.Rulesets.Mania/ManiaInputManager.cs
index 61356d96dc..292990fd7e 100644
--- a/osu.Game.Rulesets.Mania/ManiaInputManager.cs
+++ b/osu.Game.Rulesets.Mania/ManiaInputManager.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.ComponentModel;
using osu.Framework.Input.Bindings;
@@ -19,6 +19,7 @@ namespace osu.Game.Rulesets.Mania
{
[Description("Special 1")]
Special1 = 1,
+
[Description("Special 2")]
Special2,
@@ -26,38 +27,55 @@ namespace osu.Game.Rulesets.Mania
// above at a later time, without breaking replays/configs.
[Description("Key 1")]
Key1 = 10,
+
[Description("Key 2")]
Key2,
+
[Description("Key 3")]
Key3,
+
[Description("Key 4")]
Key4,
+
[Description("Key 5")]
Key5,
+
[Description("Key 6")]
Key6,
+
[Description("Key 7")]
Key7,
+
[Description("Key 8")]
Key8,
+
[Description("Key 9")]
Key9,
+
[Description("Key 10")]
Key10,
+
[Description("Key 11")]
Key11,
+
[Description("Key 12")]
Key12,
+
[Description("Key 13")]
Key13,
+
[Description("Key 14")]
Key14,
+
[Description("Key 15")]
Key15,
+
[Description("Key 16")]
Key16,
+
[Description("Key 17")]
Key17,
+
[Description("Key 18")]
Key18,
}
diff --git a/osu.Game.Rulesets.Mania/ManiaRuleset.cs b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
index 392d10b414..d83033f9c6 100644
--- a/osu.Game.Rulesets.Mania/ManiaRuleset.cs
+++ b/osu.Game.Rulesets.Mania/ManiaRuleset.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Game.Beatmaps;
@@ -10,8 +10,10 @@ using osu.Game.Rulesets.UI;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Bindings;
using osu.Game.Graphics;
+using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Replays;
using osu.Game.Rulesets.Replays.Types;
using osu.Game.Beatmaps.Legacy;
@@ -30,7 +32,7 @@ namespace osu.Game.Rulesets.Mania
{
public class ManiaRuleset : Ruleset
{
- public override RulesetContainer CreateRulesetContainerWith(WorkingBeatmap beatmap) => new ManiaRulesetContainer(this, beatmap);
+ public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList mods) => new DrawableManiaRuleset(this, beatmap, mods);
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new ManiaBeatmapConverter(beatmap);
public override PerformanceCalculator CreatePerformanceCalculator(WorkingBeatmap beatmap, ScoreInfo score) => new ManiaPerformanceCalculator(this, beatmap, score);
@@ -115,6 +117,7 @@ namespace osu.Game.Rulesets.Mania
new ManiaModNoFail(),
new MultiMod(new ManiaModHalfTime(), new ManiaModDaycore()),
};
+
case ModType.DifficultyIncrease:
return new Mod[]
{
@@ -124,6 +127,7 @@ namespace osu.Game.Rulesets.Mania
new MultiMod(new ManiaModFadeIn(), new ManiaModHidden()),
new ManiaModFlashlight(),
};
+
case ModType.Conversion:
return new Mod[]
{
@@ -140,11 +144,19 @@ namespace osu.Game.Rulesets.Mania
new ManiaModDualStages(),
new ManiaModMirror(),
};
+
case ModType.Automation:
return new Mod[]
{
new MultiMod(new ManiaModAutoplay(), new ModCinema()),
};
+
+ case ModType.Fun:
+ return new Mod[]
+ {
+ new MultiMod(new ModWindUp(), new ModWindDown())
+ };
+
default:
return new Mod[] { };
}
@@ -154,7 +166,7 @@ namespace osu.Game.Rulesets.Mania
public override string ShortName => "mania";
- public override Drawable CreateIcon() => new SpriteIcon { Icon = FontAwesome.fa_osu_mania_o };
+ public override Drawable CreateIcon() => new SpriteIcon { Icon = OsuIcon.RulesetMania };
public override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new ManiaDifficultyCalculator(this, beatmap);
@@ -162,7 +174,7 @@ namespace osu.Game.Rulesets.Mania
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new ManiaReplayFrame();
- public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new ManiaConfigManager(settings, RulesetInfo);
+ public override IRulesetConfigManager CreateConfig(SettingsStore settings) => new ManiaRulesetConfigManager(settings, RulesetInfo);
public override RulesetSettingsSubsection CreateSettings() => new ManiaSettingsSubsection(this);
@@ -207,6 +219,7 @@ namespace osu.Game.Rulesets.Mania
SpecialAction = ManiaAction.Special1,
NormalActionStart = ManiaAction.Key1,
}.GenerateKeyBindingsFor(variant, out _);
+
case PlayfieldType.Dual:
int keys = getDualStageKeyCount(variant);
@@ -264,6 +277,7 @@ namespace osu.Game.Rulesets.Mania
{
default:
return $"{variant}K";
+
case PlayfieldType.Dual:
{
var keys = getDualStageKeyCount(variant);
@@ -330,12 +344,12 @@ namespace osu.Game.Rulesets.Mania
for (int i = LeftKeys.Length - columns / 2; i < LeftKeys.Length; i++)
bindings.Add(new KeyBinding(LeftKeys[i], currentNormalAction++));
- for (int i = 0; i < columns / 2; i++)
- bindings.Add(new KeyBinding(RightKeys[i], currentNormalAction++));
-
if (columns % 2 == 1)
bindings.Add(new KeyBinding(SpecialKey, SpecialAction));
+ for (int i = 0; i < columns / 2; i++)
+ bindings.Add(new KeyBinding(RightKeys[i], currentNormalAction++));
+
nextNormalAction = currentNormalAction;
return bindings;
}
@@ -349,6 +363,7 @@ namespace osu.Game.Rulesets.Mania
/// Number of columns in this stage lies at (item - Single).
///
Single = 0,
+
///
/// Columns are grouped into two stages.
/// Overall number of columns lies at (item - Dual), further computation is required for
diff --git a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs
index 783142fadc..2ebfd0cfc1 100644
--- a/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs
+++ b/osu.Game.Rulesets.Mania/ManiaSettingsSubsection.cs
@@ -1,8 +1,9 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
+using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Settings;
using osu.Game.Rulesets.Mania.Configuration;
using osu.Game.Rulesets.Mania.UI;
@@ -21,14 +22,26 @@ namespace osu.Game.Rulesets.Mania
[BackgroundDependencyLoader]
private void load()
{
+ var config = (ManiaRulesetConfigManager)Config;
+
Children = new Drawable[]
{
new SettingsEnumDropdown
{
LabelText = "Scrolling direction",
- Bindable = ((ManiaConfigManager)Config).GetBindable(ManiaSetting.ScrollDirection)
- }
+ Bindable = config.GetBindable(ManiaRulesetSetting.ScrollDirection)
+ },
+ new SettingsSlider
+ {
+ LabelText = "Scroll speed",
+ Bindable = config.GetBindable(ManiaRulesetSetting.ScrollTime)
+ },
};
}
+
+ private class TimeSlider : OsuSliderBar
+ {
+ public override string TooltipText => Current.Value.ToString("N0") + "ms";
+ }
}
}
diff --git a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs b/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs
index 785cd5ab06..a9cd7f2476 100644
--- a/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs
+++ b/osu.Game.Rulesets.Mania/MathUtils/FastRandom.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
@@ -37,11 +37,11 @@ namespace osu.Game.Rulesets.Mania.MathUtils
/// The random value.
public uint NextUInt()
{
- uint t = X ^ X << 11;
+ uint t = X ^ (X << 11);
X = Y;
Y = Z;
Z = W;
- return W = W ^ W >> 19 ^ t ^ t >> 8;
+ return W = W ^ (W >> 19) ^ t ^ (t >> 8);
}
///
diff --git a/osu.Game.Rulesets.Mania/Mods/IPlayfieldTypeMod.cs b/osu.Game.Rulesets.Mania/Mods/IPlayfieldTypeMod.cs
index e08c9aa2a8..410386c9d5 100644
--- a/osu.Game.Rulesets.Mania/Mods/IPlayfieldTypeMod.cs
+++ b/osu.Game.Rulesets.Mania/Mods/IPlayfieldTypeMod.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs
index d4164ec1f6..13fdd74113 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaKeyMod.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Linq;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs
index f53943ec85..c05e979e9a 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModAutoplay.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Beatmaps;
@@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Mania.Mods
{
public class ManiaModAutoplay : ModAutoplay
{
- protected override Score CreateReplayScore(Beatmap beatmap) => new Score
+ public override Score CreateReplayScore(IBeatmap beatmap) => new Score
{
ScoreInfo = new ScoreInfo { User = new User { Username = "osu!topus!" } },
Replay = new ManiaAutoGenerator((ManiaBeatmap)beatmap).Generate(),
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs
index 506879bb96..bec0a6a1d3 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDaycore.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs
index bd93f0db38..a302f95966 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDoubleTime.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs
index 5a8ce05873..c78bf72979 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModDualStages.cs
@@ -1,15 +1,13 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
-using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Mania.Beatmaps;
-using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods;
namespace osu.Game.Rulesets.Mania.Mods
{
- public class ManiaModDualStages : Mod, IPlayfieldTypeMod, IApplicableToBeatmapConverter, IApplicableToBeatmap
+ public class ManiaModDualStages : Mod, IPlayfieldTypeMod, IApplicableToBeatmapConverter
{
public override string Name => "Dual Stages";
public override string Acronym => "DS";
@@ -29,24 +27,7 @@ namespace osu.Game.Rulesets.Mania.Mods
if (isForCurrentRuleset)
return;
- mbc.TargetColumns *= 2;
- }
-
- public void ApplyToBeatmap(Beatmap beatmap)
- {
- if (isForCurrentRuleset)
- return;
-
- var maniaBeatmap = (ManiaBeatmap)beatmap;
-
- var newDefinitions = new List();
- foreach (var existing in maniaBeatmap.Stages)
- {
- newDefinitions.Add(new StageDefinition { Columns = existing.Columns / 2 });
- newDefinitions.Add(new StageDefinition { Columns = existing.Columns / 2 });
- }
-
- maniaBeatmap.Stages = newDefinitions;
+ mbc.Dual = true;
}
public PlayfieldType PlayfieldType => PlayfieldType.Dual;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModEasy.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModEasy.cs
index 8c85846ed1..ff77df0ae0 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModEasy.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModEasy.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs
index 229170cea8..39185e6a57 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFadeIn.cs
@@ -1,7 +1,8 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
+using osu.Framework.Graphics.Sprites;
using osu.Game.Graphics;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mods;
@@ -12,7 +13,7 @@ namespace osu.Game.Rulesets.Mania.Mods
{
public override string Name => "Fade In";
public override string Acronym => "FI";
- public override FontAwesome Icon => FontAwesome.fa_osu_mod_hidden;
+ public override IconUsage Icon => OsuIcon.ModHidden;
public override ModType Type => ModType.DifficultyIncrease;
public override string Description => @"Keys appear out of nowhere!";
public override double ScoreMultiplier => 1;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs
index cd84483eb9..6893e1e73b 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModFlashlight.cs
@@ -1,7 +1,8 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
+using osu.Framework.Bindables;
using osu.Framework.Caching;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Objects;
@@ -51,7 +52,7 @@ namespace osu.Game.Rulesets.Mania.Mods
}
}
- protected override void OnComboChange(int newCombo)
+ protected override void OnComboChange(ValueChangedEvent e)
{
}
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs
index 978554362d..014954dd60 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHalfTime.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs
index 7b766cab85..d9de06a811 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHardRock.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs
index 9bc2502a8f..66b90984b4 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModHidden.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Game.Rulesets.Mania.Objects;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs
index 11143f715e..948979505c 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey1.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mania.Mods
{
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs
index 0169d4ecac..de91902ca8 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey2.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mania.Mods
{
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs
index 12e84eda0f..8575a96bde 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey3.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mania.Mods
{
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey4.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey4.cs
index ab5ed91d9d..54ea3afa07 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey4.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey4.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mania.Mods
{
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey5.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey5.cs
index be9f0f8066..e9a9bba5bd 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey5.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey5.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mania.Mods
{
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey6.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey6.cs
index 571e533078..b9606d1cb5 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey6.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey6.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mania.Mods
{
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey7.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey7.cs
index 89c6bd997d..b80d794085 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey7.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey7.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mania.Mods
{
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey8.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey8.cs
index 8d043651d3..3462d634a4 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey8.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey8.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mania.Mods
{
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModKey9.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModKey9.cs
index 20471ebffc..83c505c048 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModKey9.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModKey9.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mania.Mods
{
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs
index 68325b40bf..17f4098420 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModMirror.cs
@@ -1,16 +1,16 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Game.Rulesets.Mania.Objects;
-using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mods;
-using osu.Game.Rulesets.UI;
using System.Linq;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Mania.Beatmaps;
namespace osu.Game.Rulesets.Mania.Mods
{
- public class ManiaModMirror : Mod, IApplicableToRulesetContainer
+ public class ManiaModMirror : Mod, IApplicableToBeatmap
{
public override string Name => "Mirror";
public override string Acronym => "MR";
@@ -18,11 +18,11 @@ namespace osu.Game.Rulesets.Mania.Mods
public override double ScoreMultiplier => 1;
public override bool Ranked => true;
- public void ApplyToRulesetContainer(RulesetContainer rulesetContainer)
+ public void ApplyToBeatmap(Beatmap beatmap)
{
- var availableColumns = ((ManiaRulesetContainer)rulesetContainer).Beatmap.TotalColumns;
+ var availableColumns = ((ManiaBeatmap)beatmap).TotalColumns;
- rulesetContainer.Objects.OfType().ForEach(h => h.Column = availableColumns - 1 - h.Column);
+ beatmap.HitObjects.OfType().ForEach(h => h.Column = availableColumns - 1 - h.Column);
}
}
}
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs
index b3e73be4ee..2d94fb6af5 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModNightcore.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModNoFail.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModNoFail.cs
index c22549bfc7..e8988be548 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModNoFail.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModNoFail.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModPerfect.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModPerfect.cs
index abada804fb..2e22e23dbd 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModPerfect.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModPerfect.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs
index b3a3d4280b..ba16140644 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModRandom.cs
@@ -1,32 +1,33 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osu.Framework.Extensions.IEnumerableExtensions;
+using osu.Framework.Graphics.Sprites;
using osu.Framework.MathUtils;
+using osu.Game.Beatmaps;
using osu.Game.Graphics;
+using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Objects;
-using osu.Game.Rulesets.Mania.UI;
using osu.Game.Rulesets.Mods;
-using osu.Game.Rulesets.UI;
namespace osu.Game.Rulesets.Mania.Mods
{
- public class ManiaModRandom : Mod, IApplicableToRulesetContainer
+ public class ManiaModRandom : Mod, IApplicableToBeatmap
{
public override string Name => "Random";
public override string Acronym => "RD";
public override ModType Type => ModType.Conversion;
- public override FontAwesome Icon => FontAwesome.fa_osu_dice;
+ public override IconUsage Icon => OsuIcon.Dice;
public override string Description => @"Shuffle around the keys!";
public override double ScoreMultiplier => 1;
- public void ApplyToRulesetContainer(RulesetContainer rulesetContainer)
+ public void ApplyToBeatmap(Beatmap beatmap)
{
- var availableColumns = ((ManiaRulesetContainer)rulesetContainer).Beatmap.TotalColumns;
+ var availableColumns = ((ManiaBeatmap)beatmap).TotalColumns;
var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => RNG.Next()).ToList();
- rulesetContainer.Objects.OfType().ForEach(h => h.Column = shuffledColumns[h.Column]);
+ beatmap.HitObjects.OfType().ForEach(h => h.Column = shuffledColumns[h.Column]);
}
}
}
diff --git a/osu.Game.Rulesets.Mania/Mods/ManiaModSuddenDeath.cs b/osu.Game.Rulesets.Mania/Mods/ManiaModSuddenDeath.cs
index 05843b3af8..ecc343ecaa 100644
--- a/osu.Game.Rulesets.Mania/Mods/ManiaModSuddenDeath.cs
+++ b/osu.Game.Rulesets.Mania/Mods/ManiaModSuddenDeath.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Mods;
diff --git a/osu.Game.Rulesets.Mania/Objects/BarLine.cs b/osu.Game.Rulesets.Mania/Objects/BarLine.cs
index 0ceb10cc89..4c644a8f09 100644
--- a/osu.Game.Rulesets.Mania/Objects/BarLine.cs
+++ b/osu.Game.Rulesets.Mania/Objects/BarLine.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps.ControlPoints;
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs
index cf718ebdb0..9c3197504f 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableBarLine.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osuTK;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs
index 5fcc71a039..952c6e128e 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs
@@ -1,11 +1,11 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Linq;
+using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
-using osuTK.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Scoring;
@@ -35,14 +35,13 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
///
private bool hasBroken;
- private readonly Container tickContainer;
-
public DrawableHoldNote(HoldNote hitObject)
: base(hitObject)
{
+ Container tickContainer;
RelativeSizeAxes = Axes.X;
- InternalChildren = new Drawable[]
+ AddRangeInternal(new Drawable[]
{
bodyPiece = new BodyPiece
{
@@ -66,34 +65,28 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
Anchor = Anchor.TopCentre,
Origin = Anchor.TopCentre
}
- };
+ });
foreach (var tick in tickContainer)
AddNested(tick);
AddNested(Head);
AddNested(Tail);
- }
- protected override void OnDirectionChanged(ScrollingDirection direction)
- {
- base.OnDirectionChanged(direction);
-
- bodyPiece.Anchor = bodyPiece.Origin = direction == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
- }
-
- public override Color4 AccentColour
- {
- get { return base.AccentColour; }
- set
+ AccentColour.BindValueChanged(colour =>
{
- base.AccentColour = value;
+ bodyPiece.AccentColour = colour.NewValue;
+ Head.AccentColour.Value = colour.NewValue;
+ Tail.AccentColour.Value = colour.NewValue;
+ tickContainer.ForEach(t => t.AccentColour.Value = colour.NewValue);
+ }, true);
+ }
- bodyPiece.AccentColour = value;
- Head.AccentColour = value;
- Tail.AccentColour = value;
- tickContainer.ForEach(t => t.AccentColour = value);
- }
+ protected override void OnDirectionChanged(ValueChangedEvent e)
+ {
+ base.OnDirectionChanged(e);
+
+ bodyPiece.Anchor = bodyPiece.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
}
protected override void CheckForResult(bool userTriggered, double timeOffset)
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs
index 3e014ec35c..9b0322a6cd 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNoteTick.cs
@@ -1,12 +1,12 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using osuTK;
-using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Scoring;
@@ -22,18 +22,18 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
///
public Func HoldStartTime;
- private readonly Container glowContainer;
-
public DrawableHoldNoteTick(HoldNoteTick hitObject)
: base(hitObject)
{
+ Container glowContainer;
+
Anchor = Anchor.TopCentre;
Origin = Anchor.TopCentre;
RelativeSizeAxes = Axes.X;
Size = new Vector2(1);
- InternalChildren = new[]
+ AddRangeInternal(new[]
{
glowContainer = new CircularContainer
{
@@ -51,24 +51,18 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
}
}
}
- };
- }
+ });
- public override Color4 AccentColour
- {
- get { return base.AccentColour; }
- set
+ AccentColour.BindValueChanged(colour =>
{
- base.AccentColour = value;
-
glowContainer.EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
Radius = 2f,
Roundness = 15f,
- Colour = value.Opacity(0.3f)
+ Colour = colour.NewValue.Opacity(0.3f)
};
- }
+ }, true);
}
protected override void CheckForResult(bool userTriggered, double timeOffset)
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs
index 70ff7b4124..db6b53e76d 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableManiaHitObject.cs
@@ -1,9 +1,9 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using JetBrains.Annotations;
using osu.Framework.Allocation;
-using osu.Framework.Configuration;
+using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
@@ -41,9 +41,9 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
protected override bool ShouldBeAlive => AlwaysAlive || base.ShouldBeAlive;
- protected virtual void OnDirectionChanged(ScrollingDirection direction)
+ protected virtual void OnDirectionChanged(ValueChangedEvent e)
{
- Anchor = Origin = direction == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
+ Anchor = Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
}
}
@@ -58,13 +58,17 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
HitObject = hitObject;
}
+ protected override bool UseTransformStateManagement => false;
+
protected override void UpdateState(ArmedState state)
{
+ // TODO: update to use new state management.
switch (state)
{
case ArmedState.Miss:
this.FadeOut(150, Easing.In).Expire();
break;
+
case ArmedState.Hit:
this.FadeOut(150, Easing.OutQuint).Expire();
break;
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs
index 423712b026..dccff7f6ac 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs
@@ -1,10 +1,10 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
-using osuTK.Graphics;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Effects;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Mania.Objects.Drawables.Pieces;
using osu.Game.Rulesets.Scoring;
@@ -28,31 +28,26 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
CornerRadius = 5;
Masking = true;
- InternalChild = headPiece = new NotePiece();
- }
+ AddInternal(headPiece = new NotePiece());
- protected override void OnDirectionChanged(ScrollingDirection direction)
- {
- base.OnDirectionChanged(direction);
-
- headPiece.Anchor = headPiece.Origin = direction == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
- }
-
- public override Color4 AccentColour
- {
- get { return base.AccentColour; }
- set
+ AccentColour.BindValueChanged(colour =>
{
- base.AccentColour = value;
- headPiece.AccentColour = AccentColour;
+ headPiece.AccentColour = colour.NewValue;
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
- Colour = AccentColour.Lighten(1f).Opacity(0.6f),
+ Colour = colour.NewValue.Lighten(1f).Opacity(0.6f),
Radius = 10,
};
- }
+ }, true);
+ }
+
+ protected override void OnDirectionChanged(ValueChangedEvent e)
+ {
+ base.OnDirectionChanged(e);
+
+ headPiece.Anchor = headPiece.Origin = e.NewValue == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
}
protected override void CheckForResult(bool userTriggered, double timeOffset)
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs
index 8dbf33c183..8102718edf 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/BodyPiece.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using osu.Framework.Caching;
@@ -7,6 +7,7 @@ using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
@@ -77,11 +78,12 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
public Color4 AccentColour
{
- get { return accentColour; }
+ get => accentColour;
set
{
if (accentColour == value)
return;
+
accentColour = value;
updateAccentColour();
@@ -90,7 +92,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
public bool Hitting
{
- get { return hitting; }
+ get => hitting;
set
{
hitting = value;
@@ -143,6 +145,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
const float animation_length = 50;
Foreground.ClearTransforms(false, nameof(Foreground.Colour));
+
if (hitting)
{
// wait for the next sync point
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs
index 3a524bfc90..1d25a0c966 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/GlowPiece.cs
@@ -1,9 +1,10 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osuTK.Graphics;
@@ -35,13 +36,15 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
}
private Color4 accentColour;
+
public Color4 AccentColour
{
- get { return accentColour; }
+ get => accentColour;
set
{
if (accentColour == value)
return;
+
accentColour = value;
updateGlow();
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs
index 8325cb8ac0..9e0307c5c2 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/LaneGlowPiece.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
@@ -78,8 +78,8 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
public Color4 AccentColour
{
- get { return Colour; }
- set { Colour = value; }
+ get => Colour;
+ set => Colour = value;
}
}
}
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/NotePiece.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/NotePiece.cs
index 26d5a7f188..bb33693783 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/NotePiece.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/Pieces/NotePiece.cs
@@ -1,8 +1,8 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Configuration;
+using osu.Framework.Bindables;
using osuTK.Graphics;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
@@ -49,20 +49,22 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables.Pieces
private void load(IScrollingInfo scrollingInfo)
{
direction.BindTo(scrollingInfo.Direction);
- direction.BindValueChanged(direction =>
+ direction.BindValueChanged(dir =>
{
- colouredBox.Anchor = colouredBox.Origin = direction == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
+ colouredBox.Anchor = colouredBox.Origin = dir.NewValue == ScrollingDirection.Up ? Anchor.TopCentre : Anchor.BottomCentre;
}, true);
}
private Color4 accentColour;
+
public Color4 AccentColour
{
- get { return accentColour; }
+ get => accentColour;
set
{
if (accentColour == value)
return;
+
accentColour = value;
colouredBox.Colour = AccentColour.Lighten(0.9f);
diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
index 77562bb4c2..5e9f46d9c7 100644
--- a/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/HoldNote.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
@@ -17,9 +17,10 @@ namespace osu.Game.Rulesets.Mania.Objects
public double EndTime => StartTime + Duration;
private double duration;
+
public double Duration
{
- get { return duration; }
+ get => duration;
set
{
duration = value;
@@ -29,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Objects
public override double StartTime
{
- get { return base.StartTime; }
+ get => base.StartTime;
set
{
base.StartTime = value;
@@ -40,7 +41,7 @@ namespace osu.Game.Rulesets.Mania.Objects
public override int Column
{
- get { return base.Column; }
+ get => base.Column;
set
{
base.Column = value;
diff --git a/osu.Game.Rulesets.Mania/Objects/HoldNoteTick.cs b/osu.Game.Rulesets.Mania/Objects/HoldNoteTick.cs
index 05959a31c0..c133ee73b1 100644
--- a/osu.Game.Rulesets.Mania/Objects/HoldNoteTick.cs
+++ b/osu.Game.Rulesets.Mania/Objects/HoldNoteTick.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Judgements;
diff --git a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs
index bb3d060e61..70720a926b 100644
--- a/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs
+++ b/osu.Game.Rulesets.Mania/Objects/ManiaHitObject.cs
@@ -1,7 +1,7 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
-using osu.Framework.Configuration;
+using osu.Framework.Bindables;
using osu.Game.Rulesets.Mania.Objects.Types;
using osu.Game.Rulesets.Objects;
@@ -13,7 +13,7 @@ namespace osu.Game.Rulesets.Mania.Objects
public virtual int Column
{
- get => ColumnBindable;
+ get => ColumnBindable.Value;
set => ColumnBindable.Value = value;
}
diff --git a/osu.Game.Rulesets.Mania/Objects/ManiaHitObjectDifficulty.cs b/osu.Game.Rulesets.Mania/Objects/ManiaHitObjectDifficulty.cs
deleted file mode 100644
index 390d2b0218..0000000000
--- a/osu.Game.Rulesets.Mania/Objects/ManiaHitObjectDifficulty.cs
+++ /dev/null
@@ -1,113 +0,0 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using osu.Game.Rulesets.Objects.Types;
-using System;
-
-namespace osu.Game.Rulesets.Mania.Objects
-{
- internal class ManiaHitObjectDifficulty
- {
- ///
- /// Factor by how much individual / overall strain decays per second.
- ///
- ///
- /// These values are results of tweaking a lot and taking into account general feedback.
- ///
- internal const double INDIVIDUAL_DECAY_BASE = 0.125;
- internal const double OVERALL_DECAY_BASE = 0.30;
-
- internal ManiaHitObject BaseHitObject;
-
- private readonly int beatmapColumnCount;
-
-
- private readonly double endTime;
- private readonly double[] heldUntil;
-
- ///
- /// Measures jacks or more generally: repeated presses of the same button
- ///
- private readonly double[] individualStrains;
-
- internal double IndividualStrain
- {
- get
- {
- return individualStrains[BaseHitObject.Column];
- }
-
- set
- {
- individualStrains[BaseHitObject.Column] = value;
- }
- }
-
- ///
- /// Measures note density in a way
- ///
- internal double OverallStrain = 1;
-
- public ManiaHitObjectDifficulty(ManiaHitObject baseHitObject, int columnCount)
- {
- BaseHitObject = baseHitObject;
-
- endTime = (baseHitObject as IHasEndTime)?.EndTime ?? baseHitObject.StartTime;
-
- beatmapColumnCount = columnCount;
- heldUntil = new double[beatmapColumnCount];
- individualStrains = new double[beatmapColumnCount];
-
- for (int i = 0; i < beatmapColumnCount; ++i)
- {
- individualStrains[i] = 0;
- heldUntil[i] = 0;
- }
- }
-
- internal void CalculateStrains(ManiaHitObjectDifficulty previousHitObject, double timeRate)
- {
- // TODO: Factor in holds
- double timeElapsed = (BaseHitObject.StartTime - previousHitObject.BaseHitObject.StartTime) / timeRate;
- double individualDecay = Math.Pow(INDIVIDUAL_DECAY_BASE, timeElapsed / 1000);
- double overallDecay = Math.Pow(OVERALL_DECAY_BASE, timeElapsed / 1000);
-
- double holdFactor = 1.0; // Factor to all additional strains in case something else is held
- double holdAddition = 0; // Addition to the current note in case it's a hold and has to be released awkwardly
-
- // Fill up the heldUntil array
- for (int i = 0; i < beatmapColumnCount; ++i)
- {
- heldUntil[i] = previousHitObject.heldUntil[i];
-
- // If there is at least one other overlapping end or note, then we get an addition, buuuuuut...
- if (BaseHitObject.StartTime < heldUntil[i] && endTime > heldUntil[i])
- {
- holdAddition = 1.0;
- }
-
- // ... this addition only is valid if there is _no_ other note with the same ending. Releasing multiple notes at the same time is just as easy as releasing 1
- if (endTime == heldUntil[i])
- {
- holdAddition = 0;
- }
-
- // We give a slight bonus to everything if something is held meanwhile
- if (heldUntil[i] > endTime)
- {
- holdFactor = 1.25;
- }
-
- // Decay individual strains
- individualStrains[i] = previousHitObject.individualStrains[i] * individualDecay;
- }
-
- heldUntil[BaseHitObject.Column] = endTime;
-
- // Increase individual strain in own column
- IndividualStrain += 2.0 * holdFactor;
-
- OverallStrain = previousHitObject.OverallStrain * overallDecay + (1.0 + holdAddition) * holdFactor;
- }
- }
-}
diff --git a/osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs b/osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs
index 063b626af1..5f2ceab48b 100644
--- a/osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs
+++ b/osu.Game.Rulesets.Mania/Objects/ManiaHitWindows.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Game.Beatmaps;
@@ -13,18 +13,17 @@ namespace osu.Game.Rulesets.Mania.Objects
private static readonly IReadOnlyDictionary base_ranges = new Dictionary
{
{ HitResult.Perfect, (44.8, 38.8, 27.8) },
- { HitResult.Great, (128, 98, 68 ) },
+ { HitResult.Great, (128, 98, 68) },
{ HitResult.Good, (194, 164, 134) },
{ HitResult.Ok, (254, 224, 194) },
{ HitResult.Meh, (302, 272, 242) },
{ HitResult.Miss, (376, 346, 316) },
};
+ public override bool IsHitResultAllowed(HitResult result) => true;
+
public override void SetDifficulty(double difficulty)
{
- AllowsPerfect = true;
- AllowsOk = true;
-
Perfect = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Perfect]);
Great = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Great]);
Good = BeatmapDifficulty.DifficultyRange(difficulty, base_ranges[HitResult.Good]);
diff --git a/osu.Game.Rulesets.Mania/Objects/Note.cs b/osu.Game.Rulesets.Mania/Objects/Note.cs
index 42877649d2..0035960c63 100644
--- a/osu.Game.Rulesets.Mania/Objects/Note.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Note.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Judgements;
diff --git a/osu.Game.Rulesets.Mania/Objects/TailNote.cs b/osu.Game.Rulesets.Mania/Objects/TailNote.cs
index 9de542bcd3..5a30fd6a12 100644
--- a/osu.Game.Rulesets.Mania/Objects/TailNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/TailNote.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.Judgements;
diff --git a/osu.Game.Rulesets.Mania/Objects/Types/IHasColumn.cs b/osu.Game.Rulesets.Mania/Objects/Types/IHasColumn.cs
index 44a79de7db..1ea3138828 100644
--- a/osu.Game.Rulesets.Mania/Objects/Types/IHasColumn.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Types/IHasColumn.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
namespace osu.Game.Rulesets.Mania.Objects.Types
{
diff --git a/osu.Game.Rulesets.Mania/Properties/AssemblyInfo.cs b/osu.Game.Rulesets.Mania/Properties/AssemblyInfo.cs
index 76ccfe324b..ca1f7036c7 100644
--- a/osu.Game.Rulesets.Mania/Properties/AssemblyInfo.cs
+++ b/osu.Game.Rulesets.Mania/Properties/AssemblyInfo.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Runtime.CompilerServices;
@@ -9,3 +9,5 @@ using System.Runtime.CompilerServices;
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Mania.Tests")]
[assembly: InternalsVisibleTo("osu.Game.Rulesets.Mania.Tests.Dynamic")]
+[assembly: InternalsVisibleTo("osu.Game.Rulesets.Mania.Tests.iOS")]
+[assembly: InternalsVisibleTo("osu.Game.Rulesets.Mania.Tests.Android")]
diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs
index c58d66c66a..e5669816fa 100644
--- a/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs
+++ b/osu.Game.Rulesets.Mania/Replays/ManiaAutoGenerator.cs
@@ -1,17 +1,16 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . 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 osu.Game.Replays;
using osu.Game.Rulesets.Mania.Beatmaps;
-using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Replays;
namespace osu.Game.Rulesets.Mania.Replays
{
- internal class ManiaAutoGenerator : AutoGenerator
+ internal class ManiaAutoGenerator : AutoGenerator
{
public const double RELEASE_DELAY = 20;
@@ -29,6 +28,7 @@ namespace osu.Game.Rulesets.Mania.Replays
var normalAction = ManiaAction.Key1;
var specialAction = ManiaAction.Special1;
int totalCounter = 0;
+
foreach (var stage in Beatmap.Stages)
{
for (int i = 0; i < stage.Columns; i++)
@@ -52,6 +52,7 @@ namespace osu.Game.Rulesets.Mania.Replays
var pointGroups = generateActionPoints().GroupBy(a => a.Time).OrderBy(g => g.First().Time);
var actions = new List();
+
foreach (var group in pointGroups)
{
foreach (var point in group)
@@ -61,6 +62,7 @@ namespace osu.Game.Rulesets.Mania.Replays
case HitPoint _:
actions.Add(columnActions[point.Column]);
break;
+
case ReleasePoint _:
actions.Remove(columnActions[point.Column]);
break;
diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs b/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs
index 20b0775c57..899718b77e 100644
--- a/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs
+++ b/osu.Game.Rulesets.Mania/Replays/ManiaFramedReplayInputHandler.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using System.Linq;
@@ -18,6 +18,6 @@ namespace osu.Game.Rulesets.Mania.Replays
protected override bool IsImportant(ManiaReplayFrame frame) => frame.Actions.Any();
- public override List GetPendingInputs() => new List { new ReplayState { PressedActions = CurrentFrame.Actions } };
+ public override List GetPendingInputs() => new List { new ReplayState { PressedActions = CurrentFrame?.Actions ?? new List() } };
}
}
diff --git a/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs b/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs
index 04d3bdf5f5..f7277d3669 100644
--- a/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs
+++ b/osu.Game.Rulesets.Mania/Replays/ManiaReplayFrame.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Collections.Generic;
using osu.Game.Beatmaps;
@@ -39,6 +39,7 @@ namespace osu.Game.Rulesets.Mania.Replays
int activeColumns = (int)(legacyFrame.MouseX ?? 0);
int counter = 0;
+
while (activeColumns > 0)
{
var isSpecial = stage.IsSpecialColumn(counter);
diff --git a/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/diffcalc-test.osu b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/diffcalc-test.osu
new file mode 100644
index 0000000000..4c877c6193
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/Resources/Testing/Beatmaps/diffcalc-test.osu
@@ -0,0 +1,180 @@
+osu file format v14
+
+[General]
+Mode: 3
+
+[Difficulty]
+CircleSize:4
+OverallDifficulty:7
+ApproachRate:8.3
+SliderMultiplier:1.6
+SliderTickRate:1
+
+[TimingPoints]
+500,500,4,2,1,50,1,0
+37500,-50,4,2,1,50,0,0
+41500,-25,4,2,1,50,0,0
+
+[HitObjects]
+// jacks spaced 1/1 beat apart
+64,192,0,1,0,0:0:0:0:
+64,192,500,1,0,0:0:0:0:
+64,192,1000,1,0,0:0:0:0:
+64,192,1500,1,0,0:0:0:0:
+64,192,2000,1,0,0:0:0:0:
+64,192,2500,1,0,0:0:0:0:
+
+// jacks spaced 1/2 beat apart
+64,192,3500,1,0,0:0:0:0:
+64,192,3750,1,0,0:0:0:0:
+64,192,4000,1,0,0:0:0:0:
+64,192,4250,1,0,0:0:0:0:
+64,192,4500,1,0,0:0:0:0:
+64,192,4750,1,0,0:0:0:0:
+64,192,5000,1,0,0:0:0:0:
+64,192,6000,1,0,0:0:0:0:
+
+// doubles jacks spaced 1/2 beat apart
+192,192,6000,1,0,0:0:0:0:
+64,192,6250,1,0,0:0:0:0:
+192,192,6250,1,0,0:0:0:0:
+64,192,6500,1,0,0:0:0:0:
+192,192,6500,1,0,0:0:0:0:
+64,192,6750,1,0,0:0:0:0:
+192,192,6750,1,0,0:0:0:0:
+64,192,7000,1,0,0:0:0:0:
+192,192,7000,1,0,0:0:0:0:
+64,192,7250,1,0,0:0:0:0:
+192,192,7250,1,0,0:0:0:0:
+64,192,7500,1,0,0:0:0:0:
+192,192,7500,1,0,0:0:0:0:
+
+// trill spaced 1/2 beat apart
+64,192,8500,1,0,0:0:0:0:
+192,192,8750,1,0,0:0:0:0:
+64,192,9000,1,0,0:0:0:0:
+192,192,9250,1,0,0:0:0:0:
+64,192,9500,1,0,0:0:0:0:
+192,192,9750,1,0,0:0:0:0:
+64,192,10000,1,0,0:0:0:0:
+192,192,10250,1,0,0:0:0:0:
+64,192,10500,1,0,0:0:0:0:
+
+// stair spaced 1/4 apart
+64,192,11500,1,0,0:0:0:0:
+192,192,11625,1,0,0:0:0:0:
+320,192,11750,1,0,0:0:0:0:
+448,192,11875,1,0,0:0:0:0:
+320,192,12000,1,0,0:0:0:0:
+192,192,12125,1,0,0:0:0:0:
+64,192,12250,1,0,0:0:0:0:
+192,192,12375,1,0,0:0:0:0:
+320,192,12500,1,0,0:0:0:0:
+448,192,12625,1,0,0:0:0:0:
+
+// jumpstreams?
+64,192,13500,1,0,0:0:0:0:
+192,192,13625,1,0,0:0:0:0:
+320,192,13750,1,0,0:0:0:0:
+448,192,13875,1,0,0:0:0:0:
+320,192,14000,1,0,0:0:0:0:
+192,192,14000,1,0,0:0:0:0:
+64,192,14125,1,0,0:0:0:0:
+192,192,14250,1,0,0:0:0:0:
+320,192,14250,1,0,0:0:0:0:
+448,192,14250,1,0,0:0:0:0:
+64,192,14375,1,0,0:0:0:0:
+64,192,14500,1,0,0:0:0:0:
+320,192,14625,1,0,0:0:0:0:
+448,192,14625,1,0,0:0:0:0:
+192,192,14625,1,0,0:0:0:0:
+192,192,14750,1,0,0:0:0:0:
+64,192,14875,1,0,0:0:0:0:
+192,192,15000,1,0,0:0:0:0:
+320,192,15125,1,0,0:0:0:0:
+448,192,15125,1,0,0:0:0:0:
+
+// double... jumps?
+64,192,16000,1,0,0:0:0:0:
+64,192,16250,1,0,0:0:0:0:
+192,192,16250,1,0,0:0:0:0:
+192,192,16500,1,0,0:0:0:0:
+320,192,16500,1,0,0:0:0:0:
+320,192,16750,1,0,0:0:0:0:
+448,192,16750,1,0,0:0:0:0:
+448,192,17000,1,0,0:0:0:0:
+
+// notes alongside hold
+64,192,18000,128,0,18500:0:0:0:0:
+192,192,18000,1,0,0:0:0:0:
+192,192,18250,1,0,0:0:0:0:
+192,192,18500,1,0,0:0:0:0:
+
+// notes overlapping hold
+64,192,19500,1,0,0:0:0:0:
+192,192,19625,128,0,20875:0:0:0:0:
+64,192,19750,1,0,0:0:0:0:
+64,192,20000,1,0,0:0:0:0:
+64,192,20250,1,0,0:0:0:0:
+64,192,20500,1,0,0:0:0:0:
+64,192,20750,1,0,0:0:0:0:
+64,192,21000,1,0,0:0:0:0:
+
+// simultaneous holds
+64,192,22000,128,0,23000:0:0:0:0:
+192,192,22000,128,0,23000:0:0:0:0:
+320,192,22000,128,0,23000:0:0:0:0:
+448,192,22000,128,0,23000:0:0:0:0:
+
+// hold stairs
+64,192,24500,128,0,25500:0:0:0:0:
+192,192,24625,128,0,25375:0:0:0:0:
+320,192,24750,128,0,25250:0:0:0:0:
+448,192,24875,128,0,25125:0:0:0:0:
+448,192,25375,128,0,26375:0:0:0:0:
+320,192,25500,128,0,26250:0:0:0:0:
+192,192,25625,128,0,26125:0:0:0:0:
+64,192,25750,128,0,26000:0:0:0:0:
+
+// quads
+64,192,26500,1,0,0:0:0:0:
+64,192,27500,1,0,0:0:0:0:
+192,192,27500,1,0,0:0:0:0:
+320,192,27500,1,0,0:0:0:0:
+448,192,27500,1,0,0:0:0:0:
+64,192,27750,1,0,0:0:0:0:
+192,192,27750,1,0,0:0:0:0:
+320,192,27750,1,0,0:0:0:0:
+448,192,27750,1,0,0:0:0:0:
+64,192,28000,1,0,0:0:0:0:
+192,192,28000,1,0,0:0:0:0:
+320,192,28000,1,0,0:0:0:0:
+448,192,28000,1,0,0:0:0:0:
+64,192,28250,1,0,0:0:0:0:
+192,192,28250,1,0,0:0:0:0:
+320,192,28250,1,0,0:0:0:0:
+448,192,28250,1,0,0:0:0:0:
+64,192,28500,1,0,0:0:0:0:
+192,192,28500,1,0,0:0:0:0:
+320,192,28500,1,0,0:0:0:0:
+448,192,28500,1,0,0:0:0:0:
+
+// double-trills
+64,192,29500,1,0,0:0:0:0:
+192,192,29500,1,0,0:0:0:0:
+320,192,29625,1,0,0:0:0:0:
+448,192,29625,1,0,0:0:0:0:
+64,192,29750,1,0,0:0:0:0:
+192,192,29750,1,0,0:0:0:0:
+320,192,29875,1,0,0:0:0:0:
+448,192,29875,1,0,0:0:0:0:
+64,192,30000,1,0,0:0:0:0:
+192,192,30000,1,0,0:0:0:0:
+320,192,30125,1,0,0:0:0:0:
+448,192,30125,1,0,0:0:0:0:
+64,192,30250,1,0,0:0:0:0:
+192,192,30250,1,0,0:0:0:0:
+320,192,30375,1,0,0:0:0:0:
+448,192,30375,1,0,0:0:0:0:
+64,192,30500,1,0,0:0:0:0:
+192,192,30500,1,0,0:0:0:0:
diff --git a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs
index 12b32c46ee..5caf08fb1e 100644
--- a/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs
+++ b/osu.Game.Rulesets.Mania/Scoring/ManiaScoreProcessor.cs
@@ -1,10 +1,10 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Judgements;
-using osu.Game.Rulesets.Mania.Judgements;
using osu.Game.Rulesets.Mania.Objects;
+using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.UI;
@@ -27,36 +27,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
///
private const double hp_multiplier_max = 1;
- ///
- /// The default BAD hit HP increase.
- ///
- private const double hp_increase_bad = 0.005;
-
- ///
- /// The default OK hit HP increase.
- ///
- private const double hp_increase_ok = 0.010;
-
- ///
- /// The default GOOD hit HP increase.
- ///
- private const double hp_increase_good = 0.035;
-
- ///
- /// The default tick hit HP increase.
- ///
- private const double hp_increase_tick = 0.040;
-
- ///
- /// The default GREAT hit HP increase.
- ///
- private const double hp_increase_great = 0.055;
-
- ///
- /// The default PERFECT hit HP increase.
- ///
- private const double hp_increase_perfect = 0.065;
-
///
/// The MISS HP multiplier at OD = 0.
///
@@ -72,11 +42,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
///
private const double hp_multiplier_miss_max = 1;
- ///
- /// The default MISS HP increase.
- ///
- private const double hp_increase_miss = -0.125;
-
///
/// The MISS HP multiplier. This is multiplied to the miss hp increase.
///
@@ -87,12 +52,8 @@ namespace osu.Game.Rulesets.Mania.Scoring
///
private double hpMultiplier = 1;
- public ManiaScoreProcessor()
- {
- }
-
- public ManiaScoreProcessor(RulesetContainer rulesetContainer)
- : base(rulesetContainer)
+ public ManiaScoreProcessor(DrawableRuleset drawableRuleset)
+ : base(drawableRuleset)
{
}
@@ -121,41 +82,9 @@ namespace osu.Game.Rulesets.Mania.Scoring
}
}
- protected override void ApplyResult(JudgementResult result)
- {
- base.ApplyResult(result);
+ protected override double HealthAdjustmentFactorFor(JudgementResult result)
+ => result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier;
- bool isTick = result.Judgement is HoldNoteTickJudgement;
-
- if (isTick)
- {
- if (result.IsHit)
- Health.Value += hpMultiplier * hp_increase_tick;
- }
- else
- {
- switch (result.Type)
- {
- case HitResult.Miss:
- Health.Value += hpMissMultiplier * hp_increase_miss;
- break;
- case HitResult.Meh:
- Health.Value += hpMultiplier * hp_increase_bad;
- break;
- case HitResult.Ok:
- Health.Value += hpMultiplier * hp_increase_ok;
- break;
- case HitResult.Good:
- Health.Value += hpMultiplier * hp_increase_good;
- break;
- case HitResult.Great:
- Health.Value += hpMultiplier * hp_increase_great;
- break;
- case HitResult.Perfect:
- Health.Value += hpMultiplier * hp_increase_perfect;
- break;
- }
- }
- }
+ public override HitWindows CreateHitWindows() => new ManiaHitWindows();
}
}
diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs
index efa4a671a3..91dd236ab1 100644
--- a/osu.Game.Rulesets.Mania/UI/Column.cs
+++ b/osu.Game.Rulesets.Mania/UI/Column.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System.Linq;
using osuTK.Graphics;
@@ -8,7 +8,7 @@ using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Framework.Allocation;
-using osu.Framework.Configuration;
+using osu.Framework.Bindables;
using osu.Framework.Input.Bindings;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Mania.UI.Components;
@@ -82,28 +82,30 @@ namespace osu.Game.Rulesets.Mania.UI
TopLevelContainer.Add(explosionContainer.CreateProxy());
- Direction.BindValueChanged(d =>
+ Direction.BindValueChanged(dir =>
{
hitTargetContainer.Padding = new MarginPadding
{
- Top = d == ScrollingDirection.Up ? ManiaStage.HIT_TARGET_POSITION : 0,
- Bottom = d == ScrollingDirection.Down ? ManiaStage.HIT_TARGET_POSITION : 0,
+ Top = dir.NewValue == ScrollingDirection.Up ? ManiaStage.HIT_TARGET_POSITION : 0,
+ Bottom = dir.NewValue == ScrollingDirection.Down ? ManiaStage.HIT_TARGET_POSITION : 0,
};
- keyArea.Anchor = keyArea.Origin= d == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
+ keyArea.Anchor = keyArea.Origin = dir.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
}, true);
}
public override Axes RelativeSizeAxes => Axes.Y;
private bool isSpecial;
+
public bool IsSpecial
{
- get { return isSpecial; }
+ get => isSpecial;
set
{
if (isSpecial == value)
return;
+
isSpecial = value;
Width = isSpecial ? special_column_width : column_width;
@@ -111,13 +113,15 @@ namespace osu.Game.Rulesets.Mania.UI
}
private Color4 accentColour;
+
public Color4 AccentColour
{
- get { return accentColour; }
+ get => accentColour;
set
{
if (accentColour == value)
return;
+
accentColour = value;
background.AccentColour = value;
@@ -139,7 +143,7 @@ namespace osu.Game.Rulesets.Mania.UI
/// The DrawableHitObject to add.
public override void Add(DrawableHitObject hitObject)
{
- hitObject.AccentColour = AccentColour;
+ hitObject.AccentColour.Value = AccentColour;
hitObject.OnNewResult += OnNewResult;
HitObjectContainer.Add(hitObject);
@@ -156,7 +160,7 @@ namespace osu.Game.Rulesets.Mania.UI
internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result)
{
- if (!result.IsHit || !judgedObject.DisplayResult || !DisplayJudgements)
+ if (!result.IsHit || !judgedObject.DisplayResult || !DisplayJudgements.Value)
return;
explosionContainer.Add(new HitExplosion(judgedObject)
@@ -167,7 +171,7 @@ namespace osu.Game.Rulesets.Mania.UI
public bool OnPressed(ManiaAction action)
{
- if (action != Action)
+ if (action != Action.Value)
return false;
var nextObject =
diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs
index 6aef158205..b4e29ae9f9 100644
--- a/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs
+++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnBackground.cs
@@ -1,8 +1,8 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Configuration;
+using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Colour;
@@ -48,9 +48,9 @@ namespace osu.Game.Rulesets.Mania.UI.Components
};
direction.BindTo(scrollingInfo.Direction);
- direction.BindValueChanged(direction =>
+ direction.BindValueChanged(dir =>
{
- backgroundOverlay.Anchor = backgroundOverlay.Origin = direction == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
+ backgroundOverlay.Anchor = backgroundOverlay.Origin = dir.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
updateColours();
}, true);
}
@@ -70,6 +70,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
{
if (accentColour == value)
return;
+
accentColour = value;
updateColours();
diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
index f158d5be07..a0d713067d 100644
--- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
+++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
@@ -1,11 +1,12 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Configuration;
+using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Rulesets.UI;
@@ -49,9 +50,9 @@ namespace osu.Game.Rulesets.Mania.UI.Components
private void load(IScrollingInfo scrollingInfo)
{
direction.BindTo(scrollingInfo.Direction);
- direction.BindValueChanged(direction =>
+ direction.BindValueChanged(dir =>
{
- Anchor anchor = direction == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
+ Anchor anchor = dir.NewValue == ScrollingDirection.Up ? Anchor.TopLeft : Anchor.BottomLeft;
hitTargetBar.Anchor = hitTargetBar.Origin = anchor;
hitTargetLine.Anchor = hitTargetLine.Origin = anchor;
@@ -73,6 +74,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
{
if (accentColour == value)
return;
+
accentColour = value;
updateColours();
diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs
index 228e81fef3..85880222d7 100644
--- a/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs
+++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnKeyArea.cs
@@ -1,12 +1,13 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
-using osu.Framework.Configuration;
+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.Framework.Input.Bindings;
using osu.Game.Graphics;
@@ -64,11 +65,11 @@ namespace osu.Game.Rulesets.Mania.UI.Components
};
direction.BindTo(scrollingInfo.Direction);
- direction.BindValueChanged(direction =>
+ direction.BindValueChanged(dir =>
{
gradient.Colour = ColourInfo.GradientVertical(
- direction == ScrollingDirection.Up ? Color4.Black : Color4.Black.Opacity(0),
- direction == ScrollingDirection.Up ? Color4.Black.Opacity(0) : Color4.Black);
+ dir.NewValue == ScrollingDirection.Up ? Color4.Black : Color4.Black.Opacity(0),
+ dir.NewValue == ScrollingDirection.Up ? Color4.Black.Opacity(0) : Color4.Black);
}, true);
}
@@ -87,6 +88,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
{
if (accentColour == value)
return;
+
accentColour = value;
updateColours();
diff --git a/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs
index f78cfefab8..8797f014df 100644
--- a/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs
+++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaJudgement.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -19,25 +19,18 @@ namespace osu.Game.Rulesets.Mania.UI
private void load()
{
if (JudgementText != null)
- JudgementText.TextSize = 25;
+ JudgementText.Font = JudgementText.Font.With(size: 25);
}
- protected override void LoadComplete()
+ protected override double FadeInDuration => 50;
+
+ protected override void ApplyHitAnimations()
{
- base.LoadComplete();
+ JudgementBody.ScaleTo(0.8f);
+ JudgementBody.ScaleTo(1, 250, Easing.OutElastic);
- this.FadeInFromZero(50, Easing.OutQuint);
-
- if (Result.IsHit)
- {
- JudgementBody.ScaleTo(0.8f);
- JudgementBody.ScaleTo(1, 250, Easing.OutElastic);
-
- JudgementBody.Delay(50).ScaleTo(0.75f, 250);
- this.Delay(50).FadeOut(200);
- }
-
- Expire();
+ JudgementBody.Delay(FadeInDuration).ScaleTo(0.75f, 250);
+ this.Delay(FadeInDuration).FadeOut(200);
}
}
}
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs
similarity index 70%
rename from osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs
rename to osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs
index db65dfae41..c8aeda8fe4 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaRulesetContainer.cs
+++ b/osu.Game.Rulesets.Mania/UI/DrawableManiaRuleset.cs
@@ -1,12 +1,11 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . 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 osu.Framework.Allocation;
-using osu.Framework.Configuration;
+using osu.Framework.Bindables;
using osu.Framework.Extensions.IEnumerableExtensions;
-using osu.Framework.Graphics;
using osu.Framework.Input;
using osu.Framework.MathUtils;
using osu.Game.Beatmaps;
@@ -15,11 +14,11 @@ using osu.Game.Input.Handlers;
using osu.Game.Replays;
using osu.Game.Rulesets.Mania.Beatmaps;
using osu.Game.Rulesets.Mania.Configuration;
-using osu.Game.Rulesets.Mania.Mods;
using osu.Game.Rulesets.Mania.Objects;
using osu.Game.Rulesets.Mania.Objects.Drawables;
using osu.Game.Rulesets.Mania.Replays;
using osu.Game.Rulesets.Mania.Scoring;
+using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Scoring;
@@ -29,18 +28,20 @@ using osuTK;
namespace osu.Game.Rulesets.Mania.UI
{
- public class ManiaRulesetContainer : ScrollingRulesetContainer
+ public class DrawableManiaRuleset : DrawableScrollingRuleset
{
+ protected new ManiaPlayfield Playfield => (ManiaPlayfield)base.Playfield;
+
public new ManiaBeatmap Beatmap => (ManiaBeatmap)base.Beatmap;
public IEnumerable BarLines;
- protected new ManiaConfigManager Config => (ManiaConfigManager)base.Config;
+ protected new ManiaRulesetConfigManager Config => (ManiaRulesetConfigManager)base.Config;
private readonly Bindable configDirection = new Bindable();
- public ManiaRulesetContainer(Ruleset ruleset, WorkingBeatmap beatmap)
- : base(ruleset, beatmap)
+ public DrawableManiaRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList mods)
+ : base(ruleset, beatmap, mods)
{
// Generate the bar lines
double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue;
@@ -56,6 +57,7 @@ namespace osu.Game.Rulesets.Mania.UI
double endTime = i < timingPoints.Count - 1 ? timingPoints[i + 1].Time - point.BeatLength : lastObjectTime + point.BeatLength * (int)point.TimeSignature;
int index = 0;
+
for (double t = timingPoints[i].Time; Precision.DefinitelyBigger(endTime, t); t += point.BeatLength, index++)
{
barLines.Add(new BarLine
@@ -75,10 +77,10 @@ namespace osu.Game.Rulesets.Mania.UI
{
BarLines.ForEach(Playfield.Add);
- Config.BindWith(ManiaSetting.ScrollDirection, configDirection);
- configDirection.BindValueChanged(v => Direction.Value = (ScrollingDirection)v, true);
+ Config.BindWith(ManiaRulesetSetting.ScrollDirection, configDirection);
+ configDirection.BindValueChanged(direction => Direction.Value = (ScrollingDirection)direction.NewValue, true);
- Config.BindWith(ManiaSetting.ScrollTime, TimeRange);
+ Config.BindWith(ManiaRulesetSetting.ScrollTime, TimeRange);
}
///
@@ -88,26 +90,26 @@ namespace osu.Game.Rulesets.Mania.UI
/// The column which intersects with .
public Column GetColumnByPosition(Vector2 screenSpacePosition) => Playfield.GetColumnByPosition(screenSpacePosition);
- protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages)
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- };
+ public override PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new ManiaPlayfieldAdjustmentContainer();
+
+ protected override Playfield CreatePlayfield() => new ManiaPlayfield(Beatmap.Stages);
public override ScoreProcessor CreateScoreProcessor() => new ManiaScoreProcessor(this);
- public override int Variant => (int)(Mods.OfType().FirstOrDefault()?.PlayfieldType ?? PlayfieldType.Single) + Beatmap.TotalColumns;
+ public override int Variant => (int)(Beatmap.Stages.Count == 1 ? PlayfieldType.Single : PlayfieldType.Dual) + Beatmap.TotalColumns;
- public override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant);
+ protected override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant);
- public override DrawableHitObject GetVisualRepresentation(ManiaHitObject h)
+ public override DrawableHitObject CreateDrawableRepresentation(ManiaHitObject h)
{
switch (h)
{
case HoldNote holdNote:
return new DrawableHoldNote(holdNote);
+
case Note note:
return new DrawableNote(note);
+
default:
return null;
}
diff --git a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs
index 817b60d14a..48470add8b 100644
--- a/osu.Game.Rulesets.Mania/UI/HitExplosion.cs
+++ b/osu.Game.Rulesets.Mania/UI/HitExplosion.cs
@@ -1,9 +1,10 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osuTK.Graphics;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Framework.MathUtils;
using osu.Game.Rulesets.Mania.Objects.Drawables;
@@ -43,7 +44,7 @@ namespace osu.Game.Rulesets.Mania.UI
EdgeEffect = new EdgeEffectParameters
{
Type = EdgeEffectType.Glow,
- Colour = Interpolation.ValueAt(0.1f, judgedObject.AccentColour, Color4.White, 0, 1),
+ Colour = Interpolation.ValueAt(0.1f, judgedObject.AccentColour.Value, Color4.White, 0, 1),
Radius = 100,
},
Child = new Box
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
index 0caac39f21..5ab07416a6 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfield.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -28,8 +28,6 @@ namespace osu.Game.Rulesets.Mania.UI
if (stageDefinitions.Count <= 0)
throw new ArgumentException("Can't have zero or fewer stages.");
- Size = new Vector2(1, 0.8f);
-
GridContainer playfieldGrid;
AddInternal(playfieldGrid = new GridContainer
{
@@ -40,6 +38,7 @@ namespace osu.Game.Rulesets.Mania.UI
var normalColumnAction = ManiaAction.Key1;
var specialColumnAction = ManiaAction.Special1;
int firstColumnIndex = 0;
+
for (int i = 0; i < stageDefinitions.Count; i++)
{
var newStage = new ManiaStage(firstColumnIndex, stageDefinitions[i], ref normalColumnAction, ref specialColumnAction);
@@ -94,6 +93,7 @@ namespace osu.Game.Rulesets.Mania.UI
private ManiaStage getStageByColumn(int column)
{
int sum = 0;
+
foreach (var stage in stages)
{
sum = sum + stage.Columns.Count;
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Mania/UI/ManiaPlayfieldAdjustmentContainer.cs
new file mode 100644
index 0000000000..d893a3fdde
--- /dev/null
+++ b/osu.Game.Rulesets.Mania/UI/ManiaPlayfieldAdjustmentContainer.cs
@@ -0,0 +1,20 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics;
+using osu.Game.Rulesets.UI;
+using osuTK;
+
+namespace osu.Game.Rulesets.Mania.UI
+{
+ public class ManiaPlayfieldAdjustmentContainer : PlayfieldAdjustmentContainer
+ {
+ public ManiaPlayfieldAdjustmentContainer()
+ {
+ Anchor = Anchor.Centre;
+ Origin = Anchor.Centre;
+
+ Size = new Vector2(1, 0.8f);
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs b/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs
index 0fc9c1920a..98165fedeb 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaScrollingDirection.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.UI.Scrolling;
diff --git a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs
index f71b866912..a28de7ea58 100644
--- a/osu.Game.Rulesets.Mania/UI/ManiaStage.cs
+++ b/osu.Game.Rulesets.Mania/UI/ManiaStage.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -136,12 +136,12 @@ namespace osu.Game.Rulesets.Mania.UI
AddColumn(column);
}
- Direction.BindValueChanged(d =>
+ Direction.BindValueChanged(dir =>
{
barLineContainer.Padding = new MarginPadding
{
- Top = d == ScrollingDirection.Up ? HIT_TARGET_POSITION : 0,
- Bottom = d == ScrollingDirection.Down ? HIT_TARGET_POSITION : 0,
+ Top = dir.NewValue == ScrollingDirection.Up ? HIT_TARGET_POSITION : 0,
+ Bottom = dir.NewValue == ScrollingDirection.Down ? HIT_TARGET_POSITION : 0,
};
}, true);
}
@@ -185,7 +185,7 @@ namespace osu.Game.Rulesets.Mania.UI
internal void OnNewResult(DrawableHitObject judgedObject, JudgementResult result)
{
- if (!judgedObject.DisplayResult || !DisplayJudgements)
+ if (!judgedObject.DisplayResult || !DisplayJudgements.Value)
return;
judgements.Clear();
diff --git a/osu.Game.Rulesets.Osu.Tests.Android/MainActivity.cs b/osu.Game.Rulesets.Osu.Tests.Android/MainActivity.cs
new file mode 100644
index 0000000000..e6c508d99e
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests.Android/MainActivity.cs
@@ -0,0 +1,16 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Android.App;
+using Android.Content.PM;
+using osu.Framework.Android;
+using osu.Game.Tests;
+
+namespace osu.Game.Rulesets.Osu.Tests.Android
+{
+ [Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.SensorLandscape, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize)]
+ public class MainActivity : AndroidGameActivity
+ {
+ protected override Framework.Game CreateGame() => new OsuTestBrowser();
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests.Android/Properties/AndroidManifest.xml b/osu.Game.Rulesets.Osu.Tests.Android/Properties/AndroidManifest.xml
new file mode 100644
index 0000000000..aad907b241
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests.Android/Properties/AndroidManifest.xml
@@ -0,0 +1,5 @@
+
+
+
+
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj b/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj
new file mode 100644
index 0000000000..dcf1573522
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests.Android/osu.Game.Rulesets.Osu.Tests.Android.csproj
@@ -0,0 +1,39 @@
+
+
+
+
+ Debug
+ AnyCPU
+ 8.0.30703
+ 2.0
+ {90CAB706-39CB-4B93-9629-3218A6FF8E9B}
+ {EFBA0AD7-5A72-4C68-AF49-83D382785DCF};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}
+ {122416d6-6b49-4ee2-a1e8-b825f31c79fe}
+ osu.Game.Rulesets.Osu.Tests
+ osu.Game.Rulesets.Osu.Tests.Android
+ Properties\AndroidManifest.xml
+ armeabi-v7a;x86;arm64-v8a
+
+
+
+
+
+
+
+
+
+ %(RecursiveDir)%(Filename)%(Extension)
+
+
+
+
+ {c92a607b-1fdd-4954-9f92-03ff547d9080}
+ osu.Game.Rulesets.Osu
+
+
+ {2a66dd92-adb1-4994-89e2-c94e04acda0d}
+ osu.Game
+
+
+
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/AppDelegate.cs b/osu.Game.Rulesets.Osu.Tests.iOS/AppDelegate.cs
new file mode 100644
index 0000000000..01e635f09c
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests.iOS/AppDelegate.cs
@@ -0,0 +1,15 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using Foundation;
+using osu.Framework.iOS;
+using osu.Game.Tests;
+
+namespace osu.Game.Rulesets.Osu.Tests.iOS
+{
+ [Register("AppDelegate")]
+ public class AppDelegate : GameAppDelegate
+ {
+ protected override Framework.Game CreateGame() => new OsuTestBrowser();
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs b/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs
new file mode 100644
index 0000000000..3718264a42
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests.iOS/Application.cs
@@ -0,0 +1,15 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using UIKit;
+
+namespace osu.Game.Rulesets.Osu.Tests.iOS
+{
+ public class Application
+ {
+ public static void Main(string[] args)
+ {
+ UIApplication.Main(args, "GameUIApplication", "AppDelegate");
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/Entitlements.plist b/osu.Game.Rulesets.Osu.Tests.iOS/Entitlements.plist
new file mode 100644
index 0000000000..9ae599370b
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests.iOS/Entitlements.plist
@@ -0,0 +1,6 @@
+
+
+
+
+
+
diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/Info.plist b/osu.Game.Rulesets.Osu.Tests.iOS/Info.plist
new file mode 100644
index 0000000000..f79215cf54
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests.iOS/Info.plist
@@ -0,0 +1,36 @@
+
+
+
+
+ CFBundleName
+ osu.Game.Rulesets.Osu.Tests.iOS
+ CFBundleIdentifier
+ ppy.osu-Game-Rulesets-Osu-Tests-iOS
+ CFBundleShortVersionString
+ 1.0
+ CFBundleVersion
+ 1.0
+ LSRequiresIPhoneOS
+
+ MinimumOSVersion
+ 10.0
+ UIDeviceFamily
+
+ 1
+ 2
+
+ UIRequiredDeviceCapabilities
+
+ armv7
+
+ UISupportedInterfaceOrientations
+
+ UIInterfaceOrientationPortrait
+ UIInterfaceOrientationPortraitUpsideDown
+ UIInterfaceOrientationLandscapeLeft
+ UIInterfaceOrientationLandscapeRight
+
+ XSAppIconAssets
+ Assets.xcassets/AppIcon.appiconset
+
+
diff --git a/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj b/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj
new file mode 100644
index 0000000000..9930a166e3
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests.iOS/osu.Game.Rulesets.Osu.Tests.iOS.csproj
@@ -0,0 +1,45 @@
+
+
+
+
+ Debug
+ iPhoneSimulator
+ {6653CA6F-DB06-4604-A3FD-762E25C2AF96}
+ Exe
+ osu.Game.Rulesets.Osu.Tests
+ osu.Game.Rulesets.Osu.Tests.iOS
+
+
+
+
+
+
+ libbass.a
+ PreserveNewest
+
+
+ libbass_fx.a
+ PreserveNewest
+
+
+ Linker.xml
+
+
+
+
+ %(RecursiveDir)%(Filename)%(Extension)
+
+
+
+
+ {2A66DD92-ADB1-4994-89E2-C94E04ACDA0D}
+ osu.Game
+
+
+ {C92A607B-1FDD-4954-9F92-03FF547D9080}
+ osu.Game.Rulesets.Osu
+
+
+
+
+
\ No newline at end of file
diff --git a/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json b/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json
index fe3ecbec47..ed03e99b9b 100644
--- a/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json
+++ b/osu.Game.Rulesets.Osu.Tests/.vscode/launch.json
@@ -7,7 +7,7 @@
"request": "launch",
"program": "dotnet",
"args": [
- "${workspaceRoot}/bin/Debug/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
+ "${workspaceRoot}/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Debug)",
@@ -20,7 +20,7 @@
"request": "launch",
"program": "dotnet",
"args": [
- "${workspaceRoot}/bin/Release/netcoreapp2.1/osu.Game.Rulesets.Osu.Tests.dll"
+ "${workspaceRoot}/bin/Release/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll"
],
"cwd": "${workspaceRoot}",
"preLaunchTask": "Build (Release)",
diff --git a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs
index 3a551bbbcf..f98d63e6c7 100644
--- a/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs
+++ b/osu.Game.Rulesets.Osu.Tests/OsuBeatmapConversionTest.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -33,9 +33,12 @@ namespace osu.Game.Rulesets.Osu.Tests
case Slider slider:
foreach (var nested in slider.NestedHitObjects)
yield return createConvertValue(nested);
+
break;
+
default:
yield return createConvertValue(hitObject);
+
break;
}
diff --git a/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs
new file mode 100644
index 0000000000..693faee3b7
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/OsuDifficultyCalculatorTest.cs
@@ -0,0 +1,26 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Difficulty;
+using osu.Game.Rulesets.Osu.Difficulty;
+using osu.Game.Tests.Beatmaps;
+
+namespace osu.Game.Rulesets.Osu.Tests
+{
+ [TestFixture]
+ public class OsuDifficultyCalculatorTest : DifficultyCalculatorTest
+ {
+ protected override string ResourceAssembly => "osu.Game.Rulesets.Osu";
+
+ [TestCase(6.931145117263422, "diffcalc-test")]
+ [TestCase(1.0736587013228804d, "zero-length-sliders")]
+ public void Test(double expected, string name)
+ => base.Test(expected, name);
+
+ protected override DifficultyCalculator CreateDifficultyCalculator(WorkingBeatmap beatmap) => new OsuDifficultyCalculator(new OsuRuleset(), beatmap);
+
+ protected override Ruleset CreateRuleset() => new OsuRuleset();
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/StackingTest.cs b/osu.Game.Rulesets.Osu.Tests/StackingTest.cs
index 579cb77084..e8b99e86f9 100644
--- a/osu.Game.Rulesets.Osu.Tests/StackingTest.cs
+++ b/osu.Game.Rulesets.Osu.Tests/StackingTest.cs
@@ -1,11 +1,13 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+using System;
using System.IO;
using System.Linq;
using System.Text;
using NUnit.Framework;
using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Tests.Beatmaps;
using Decoder = osu.Game.Beatmaps.Formats.Decoder;
@@ -22,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Tests
using (var reader = new StreamReader(stream))
{
var beatmap = Decoder.GetDecoder(reader).Decode(reader);
- var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo);
+ var converted = new TestWorkingBeatmap(beatmap).GetPlayableBeatmap(new OsuRuleset().RulesetInfo, Array.Empty());
var objects = converted.HitObjects.ToList();
diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseEditor.cs b/osu.Game.Rulesets.Osu.Tests/TestCaseEditor.cs
deleted file mode 100644
index f2525ad555..0000000000
--- a/osu.Game.Rulesets.Osu.Tests/TestCaseEditor.cs
+++ /dev/null
@@ -1,17 +0,0 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
-
-using NUnit.Framework;
-using osu.Game.Tests.Visual;
-
-namespace osu.Game.Rulesets.Osu.Tests
-{
- [TestFixture]
- public class TestCaseEditor : EditorTestCase
- {
- public TestCaseEditor()
- : base(new OsuRuleset())
- {
- }
- }
-}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneEditor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneEditor.cs
new file mode 100644
index 0000000000..4aca34bf64
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneEditor.cs
@@ -0,0 +1,17 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Game.Tests.Visual;
+
+namespace osu.Game.Rulesets.Osu.Tests
+{
+ [TestFixture]
+ public class TestSceneEditor : EditorTestScene
+ {
+ public TestSceneEditor()
+ : base(new OsuRuleset())
+ {
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs
similarity index 52%
rename from osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs
rename to osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs
index 472da88e1f..1b1cfa89c0 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestCaseGameplayCursor.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -9,25 +9,26 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Cursor;
using osu.Game.Graphics.Cursor;
using osu.Game.Rulesets.Osu.UI.Cursor;
+using osu.Game.Rulesets.UI;
using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
- public class TestCaseGameplayCursor : OsuTestCase, IProvideCursor
+ public class TestSceneGameplayCursor : OsuTestScene, IProvideCursor
{
- private GameplayCursor cursor;
+ private GameplayCursorContainer cursorContainer;
- public override IReadOnlyList RequiredTypes => new [] { typeof(CursorTrail) };
+ public override IReadOnlyList RequiredTypes => new[] { typeof(CursorTrail) };
- public CursorContainer Cursor => cursor;
+ public CursorContainer Cursor => cursorContainer;
public bool ProvidingUserCursor => true;
[BackgroundDependencyLoader]
private void load()
{
- Add(cursor = new GameplayCursor { RelativeSizeAxes = Axes.Both });
+ Add(cursorContainer = new OsuCursorContainer { RelativeSizeAxes = Axes.Both });
}
}
}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircle.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs
similarity index 89%
rename from osu.Game.Rulesets.Osu.Tests/TestCaseHitCircle.cs
rename to osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs
index 1c1a027411..d44a0cd841 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircle.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircle.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -19,7 +19,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
- public class TestCaseHitCircle : OsuTestCase
+ public class TestSceneHitCircle : OsuTestScene
{
public override IReadOnlyList RequiredTypes => new[]
{
@@ -30,9 +30,8 @@ namespace osu.Game.Rulesets.Osu.Tests
protected override Container Content => content;
private int depthIndex;
- protected readonly List Mods = new List();
- public TestCaseHitCircle()
+ public TestSceneHitCircle()
{
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
@@ -68,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Tests
Depth = depthIndex++
};
- foreach (var mod in Mods.OfType())
+ foreach (var mod in Mods.Value.OfType())
mod.ApplyToDrawableHitObjects(new[] { drawable });
Add(drawable);
@@ -89,7 +88,8 @@ namespace osu.Game.Rulesets.Osu.Tests
{
private readonly bool auto;
- public TestDrawableHitCircle(HitCircle h, bool auto) : base(h)
+ public TestDrawableHitCircle(HitCircle h, bool auto)
+ : base(h)
{
this.auto = auto;
}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleHidden.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs
similarity index 52%
rename from osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleHidden.cs
rename to osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs
index 68c35faca4..55c6b22146 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleHidden.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleHidden.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -10,13 +10,13 @@ using osu.Game.Rulesets.Osu.Mods;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
- public class TestCaseHitCircleHidden : TestCaseHitCircle
+ public class TestSceneHitCircleHidden : TestSceneHitCircle
{
public override IReadOnlyList RequiredTypes => base.RequiredTypes.Concat(new[] { typeof(OsuModHidden) }).ToList();
- public TestCaseHitCircleHidden()
+ public TestSceneHitCircleHidden()
{
- Mods.Add(new OsuModHidden());
+ Mods.Value = new[] { new OsuModHidden() };
}
}
}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLongCombo.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLongCombo.cs
new file mode 100644
index 0000000000..399cf22599
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleLongCombo.cs
@@ -0,0 +1,37 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Game.Beatmaps;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Tests.Visual;
+using osuTK;
+
+namespace osu.Game.Rulesets.Osu.Tests
+{
+ [TestFixture]
+ public class TestSceneHitCircleLongCombo : PlayerTestScene
+ {
+ public TestSceneHitCircleLongCombo()
+ : base(new OsuRuleset())
+ {
+ }
+
+ protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
+ {
+ var beatmap = new Beatmap
+ {
+ BeatmapInfo = new BeatmapInfo
+ {
+ BaseDifficulty = new BeatmapDifficulty { CircleSize = 6 },
+ Ruleset = ruleset
+ }
+ };
+
+ for (int i = 0; i < 512; i++)
+ beatmap.HitObjects.Add(new HitCircle { Position = new Vector2(256, 192), StartTime = i * 100 });
+
+ return beatmap;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCirclePlacementBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCirclePlacementBlueprint.cs
similarity index 70%
rename from osu.Game.Rulesets.Osu.Tests/TestCaseHitCirclePlacementBlueprint.cs
rename to osu.Game.Rulesets.Osu.Tests/TestSceneHitCirclePlacementBlueprint.cs
index 313438a337..4c6abc45f7 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCirclePlacementBlueprint.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCirclePlacementBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Objects;
@@ -11,7 +11,7 @@ using osu.Game.Tests.Visual;
namespace osu.Game.Rulesets.Osu.Tests
{
- public class TestCaseHitCirclePlacementBlueprint : PlacementBlueprintTestCase
+ public class TestSceneHitCirclePlacementBlueprint : PlacementBlueprintTestScene
{
protected override DrawableHitObject CreateHitObject(HitObject hitObject) => new DrawableHitCircle((HitCircle)hitObject);
protected override PlacementBlueprint CreateBlueprint() => new HitCirclePlacementBlueprint();
diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleSelectionBlueprint.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleSelectionBlueprint.cs
similarity index 73%
rename from osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleSelectionBlueprint.cs
rename to osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleSelectionBlueprint.cs
index fed62188ab..32043bf5d7 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestCaseHitCircleSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleSelectionBlueprint.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Game.Beatmaps;
using osu.Game.Beatmaps.ControlPoints;
@@ -12,11 +12,11 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Tests
{
- public class TestCaseHitCircleSelectionBlueprint : SelectionBlueprintTestCase
+ public class TestSceneHitCircleSelectionBlueprint : SelectionBlueprintTestScene
{
private readonly DrawableHitCircle drawableObject;
- public TestCaseHitCircleSelectionBlueprint()
+ public TestSceneHitCircleSelectionBlueprint()
{
var hitCircle = new HitCircle { Position = new Vector2(256, 192) };
hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty { CircleSize = 2 });
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs
new file mode 100644
index 0000000000..64e7632b1b
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuFlashlight.cs
@@ -0,0 +1,19 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Game.Rulesets.Mods;
+using osu.Game.Rulesets.Osu.Mods;
+using osu.Game.Screens.Play;
+
+namespace osu.Game.Rulesets.Osu.Tests
+{
+ public class TestSceneOsuFlashlight : TestSceneOsuPlayer
+ {
+ protected override Player CreatePlayer(Ruleset ruleset)
+ {
+ Mods.Value = new Mod[] { new OsuModAutoplay(), new OsuModFlashlight(), };
+
+ return base.CreatePlayer(ruleset);
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs
new file mode 100644
index 0000000000..0a33b09ba8
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneOsuPlayer.cs
@@ -0,0 +1,17 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using NUnit.Framework;
+using osu.Game.Tests.Visual;
+
+namespace osu.Game.Rulesets.Osu.Tests
+{
+ [TestFixture]
+ public class TestSceneOsuPlayer : PlayerTestScene
+ {
+ public TestSceneOsuPlayer()
+ : base(new OsuRuleset())
+ {
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneResumeOverlay.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneResumeOverlay.cs
new file mode 100644
index 0000000000..8e73d6152f
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneResumeOverlay.cs
@@ -0,0 +1,70 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using System.Collections.Generic;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Cursor;
+using osu.Game.Rulesets.Osu.UI;
+using osu.Game.Screens.Play;
+using osu.Game.Tests.Visual;
+
+namespace osu.Game.Rulesets.Osu.Tests
+{
+ public class TestSceneResumeOverlay : ManualInputManagerTestScene
+ {
+ public override IReadOnlyList RequiredTypes => new[]
+ {
+ typeof(OsuResumeOverlay),
+ };
+
+ public TestSceneResumeOverlay()
+ {
+ ManualOsuInputManager osuInputManager;
+ CursorContainer cursor;
+ ResumeOverlay resume;
+
+ bool resumeFired = false;
+
+ Child = osuInputManager = new ManualOsuInputManager(new OsuRuleset().RulesetInfo)
+ {
+ Children = new Drawable[]
+ {
+ cursor = new CursorContainer(),
+ resume = new OsuResumeOverlay
+ {
+ GameplayCursor = cursor
+ },
+ }
+ };
+
+ resume.ResumeAction = () => resumeFired = true;
+
+ AddStep("move mouse to center", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre));
+ AddStep("show", () => resume.Show());
+
+ AddStep("move mouse away", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.TopLeft));
+ AddStep("click", () => osuInputManager.GameClick());
+ AddAssert("not dismissed", () => !resumeFired && resume.State.Value == Visibility.Visible);
+
+ AddStep("move mouse back", () => InputManager.MoveMouseTo(ScreenSpaceDrawQuad.Centre));
+ AddStep("click", () => osuInputManager.GameClick());
+ AddAssert("dismissed", () => resumeFired && resume.State.Value == Visibility.Hidden);
+ }
+
+ private class ManualOsuInputManager : OsuInputManager
+ {
+ public ManualOsuInputManager(RulesetInfo ruleset)
+ : base(ruleset)
+ {
+ }
+
+ public void GameClick()
+ {
+ KeyBindingContainer.TriggerPressed(OsuAction.LeftButton);
+ KeyBindingContainer.TriggerReleased(OsuAction.LeftButton);
+ }
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseShaking.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneShaking.cs
similarity index 73%
rename from osu.Game.Rulesets.Osu.Tests/TestCaseShaking.cs
rename to osu.Game.Rulesets.Osu.Tests/TestSceneShaking.cs
index 97978cff1e..3d8afd66f4 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestCaseShaking.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneShaking.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Graphics;
using osu.Framework.MathUtils;
@@ -7,7 +7,7 @@ using osu.Game.Rulesets.Scoring;
namespace osu.Game.Rulesets.Osu.Tests
{
- public class TestCaseShaking : TestCaseHitCircle
+ public class TestSceneShaking : TestSceneHitCircle
{
public override void Add(Drawable drawable)
{
diff --git a/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs
similarity index 94%
rename from osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs
rename to osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs
index 1895913917..c5a27205d6 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestCaseSlider.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSlider.cs
@@ -1,5 +1,5 @@
-// Copyright (c) 2007-2018 ppy Pty Ltd .
-// Licensed under the MIT Licence - https://raw.githubusercontent.com/ppy/osu/master/LICENCE
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
@@ -16,6 +16,7 @@ using osuTK.Graphics;
using osu.Game.Rulesets.Mods;
using System.Linq;
using NUnit.Framework;
+using osu.Game.Graphics;
using osu.Game.Graphics.Sprites;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects;
@@ -26,7 +27,7 @@ using osu.Game.Rulesets.Osu.Objects.Drawables.Pieces;
namespace osu.Game.Rulesets.Osu.Tests
{
[TestFixture]
- public class TestCaseSlider : OsuTestCase
+ public class TestSceneSlider : OsuTestScene
{
public override IReadOnlyList RequiredTypes => new[]
{
@@ -43,9 +44,8 @@ namespace osu.Game.Rulesets.Osu.Tests
protected override Container Content => content;
private int depthIndex;
- protected readonly List Mods = new List();
- public TestCaseSlider()
+ public TestSceneSlider()
{
base.Content.Add(content = new OsuInputManager(new RulesetInfo { ID = 0 }));
@@ -248,9 +248,9 @@ namespace osu.Game.Rulesets.Osu.Tests
private void createCatmull(int repeats = 0)
{
- var repeatSamples = new List>();
+ var repeatSamples = new List