mirror of
https://github.com/ppy/osu.git
synced 2026-05-15 05:02:33 +08:00
Compare commits
2318 Commits
2019.321.0
...
2019.628.0
@@ -0,0 +1 @@
|
||||
custom: https://osu.ppy.sh/home/support
|
||||
@@ -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.
|
||||
@@ -1,14 +1,11 @@
|
||||
---
|
||||
name: Bug Report
|
||||
about: For issues regarding encountered game bugs
|
||||
about: Issues regarding encountered bugs.
|
||||
---
|
||||
|
||||
<!-- After you fill in all information, delete all comments in the issue -->
|
||||
|
||||
**Describe your problem:** <!-- Provide any information you believe could be useful -->
|
||||
**Describe the bug:**
|
||||
|
||||
**Screenshots or videos showing encountered issue:**
|
||||
|
||||
**osu!lazer version:** <!-- Provide the version of your osu!lazer, you can find it at the bottom of the screen -->
|
||||
**osu!lazer version:**
|
||||
|
||||
**Logs:** <!-- Attach your osu!lazer logs, you can find them under %appdata%\osu\logs in Windows, or under ~/.local/share/osu/ in Linux and macOS -->
|
||||
**Logs:**
|
||||
|
||||
@@ -1,16 +1,13 @@
|
||||
---
|
||||
name: Crash Report
|
||||
about: For issues regarding game crashes or permanent freezes
|
||||
about: Issues regarding crashes or permanent freezes.
|
||||
---
|
||||
|
||||
<!-- After you fill in all information, delete all comments in the issue -->
|
||||
|
||||
**Describe your problem:** <!-- Provide any information you believe could be useful -->
|
||||
**Describe the crash:**
|
||||
|
||||
**Screenshots or videos showing encountered issue:**
|
||||
|
||||
**osu!lazer version:** <!-- Provide the version of your osu!lazer, you can find it at the bottom of the screen -->
|
||||
**osu!lazer version:**
|
||||
|
||||
**Logs:** <!-- Attach your osu!lazer logs, you can find them under %appdata%\osu\logs in Windows, or under ~/.local/share/osu/ in Linux and macOS -->
|
||||
**Logs:**
|
||||
|
||||
**Computer Specifications:** <!-- Attach your computer specifications, you can find them by using System Information in Windows, System Monitor in Linux, or About This Mac in macOS -->
|
||||
**Computer Specifications:**
|
||||
|
||||
@@ -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:**
|
||||
|
||||
<!-- After you fill in all information, delete all comments in the issue -->
|
||||
|
||||
**Describe the feature:** <!-- Describe the feature you would like to see in the game -->
|
||||
|
||||
**Proposal designs of the feature:** <!-- Attach screenshots of how the feature should look like according to you -->
|
||||
**Proposal designs of the feature:**
|
||||
|
||||
@@ -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:**
|
||||
|
||||
<!-- After you fill in all information, delete all comments in the issue -->
|
||||
|
||||
**Describe the feature:** <!-- Describe the missing game feature -->
|
||||
|
||||
**Designs:** <!-- Attach screenshots of how the feature is supposed to look like. For illustrative purpose only; final designs are usually re-imagined from scratch. -->
|
||||
**Proposal designs of the feature:**
|
||||
|
||||
+6
-3
@@ -1,18 +1,21 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="RulesetTests (catch)" type="DotNetProject" factoryName=".NET Project">
|
||||
<configuration default="false" name="CatchRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Catch.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj" />
|
||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
+6
-3
@@ -1,18 +1,21 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="RulesetTests (mania)" type="DotNetProject" factoryName=".NET Project">
|
||||
<configuration default="false" name="ManiaRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Mania.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj" />
|
||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
+6
-3
@@ -1,18 +1,21 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="RulesetTests (osu!)" type="DotNetProject" factoryName=".NET Project">
|
||||
<configuration default="false" name="OsuRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Osu.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj" />
|
||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
+6
-3
@@ -1,18 +1,21 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="RulesetTests (taiko)" type="DotNetProject" factoryName=".NET Project">
|
||||
<configuration default="false" name="TaikoRuleset (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Ruleset">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/bin/Debug/netcoreapp2.2/osu.Game.Rulesets.Taiko.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj" />
|
||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,20 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Tournament" type="DotNetProject" factoryName=".NET Project" folderName="Tournament">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="--tournament" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Desktop/osu.Desktop.csproj" />
|
||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
@@ -0,0 +1,21 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="Tournament (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="Tournament">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/bin/Debug/netcoreapp2.1/osu.Game.Tournament.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tournament.Tests" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj" />
|
||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<browser url="http://localhost:5000" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
+1
-1
@@ -1,5 +1,5 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project">
|
||||
<configuration default="false" name="osu!" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Desktop/bin/Debug/netcoreapp2.2/osu!.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Desktop" />
|
||||
|
||||
+6
-3
@@ -1,17 +1,20 @@
|
||||
<component name="ProjectRunConfigurationManager">
|
||||
<configuration default="false" name="VisualTests" type="DotNetProject" factoryName=".NET Project">
|
||||
<configuration default="false" name="osu! (Tests)" type="DotNetProject" factoryName=".NET Project" folderName="osu!">
|
||||
<option name="EXE_PATH" value="$PROJECT_DIR$/osu.Game.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tests.dll" />
|
||||
<option name="PROGRAM_PARAMETERS" value="" />
|
||||
<option name="WORKING_DIRECTORY" value="$PROJECT_DIR$/osu.Game.Tests" />
|
||||
<option name="PASS_PARENT_ENVS" value="1" />
|
||||
<option name="USE_EXTERNAL_CONSOLE" value="0" />
|
||||
<option name="USE_MONO" value="0" />
|
||||
<option name="RUNTIME_ARGUMENTS" value="" />
|
||||
<option name="PROJECT_PATH" value="$PROJECT_DIR$/osu.Game.Tests/osu.Game.Tests.csproj" />
|
||||
<option name="PROJECT_EXE_PATH_TRACKING" value="1" />
|
||||
<option name="PROJECT_ARGUMENTS_TRACKING" value="1" />
|
||||
<option name="PROJECT_WORKING_DIRECTORY_TRACKING" value="1" />
|
||||
<option name="PROJECT_KIND" value="DotNetCore" />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.1" />
|
||||
<method />
|
||||
<option name="PROJECT_TFM" value=".NETCoreApp,Version=v2.2" />
|
||||
<method v="2">
|
||||
<option name="Build" enabled="true" />
|
||||
</method>
|
||||
</configuration>
|
||||
</component>
|
||||
Vendored
+107
-37
@@ -1,41 +1,6 @@
|
||||
{
|
||||
"version": "0.2.0",
|
||||
"configurations": [
|
||||
{
|
||||
"name": "VisualTests (Debug)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2/osu.Game.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build tests (Debug)",
|
||||
"linux": {
|
||||
"env": {
|
||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Debug/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||
}
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"name": "VisualTests (Release)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
"program": "dotnet",
|
||||
"args": [
|
||||
"${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2/osu.Game.Tests.dll"
|
||||
],
|
||||
"cwd": "${workspaceRoot}",
|
||||
"preLaunchTask": "Build tests (Release)",
|
||||
"linux": {
|
||||
"env": {
|
||||
"LD_LIBRARY_PATH": "${workspaceRoot}/osu.Game.Tests/bin/Release/netcoreapp2.2:${env:LD_LIBRARY_PATH}"
|
||||
}
|
||||
},
|
||||
"console": "internalConsole"
|
||||
},
|
||||
{
|
||||
"configurations": [{
|
||||
"name": "osu! (Debug)",
|
||||
"type": "coreclr",
|
||||
"request": "launch",
|
||||
@@ -69,6 +34,111 @@
|
||||
},
|
||||
"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",
|
||||
@@ -84,4 +154,4 @@
|
||||
"externalConsole": false
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
Vendored
+31
-2
@@ -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",
|
||||
@@ -65,6 +64,36 @@
|
||||
"group": "build",
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Build tournament tests (Debug)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Tournament.Tests",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
],
|
||||
"group": "build",
|
||||
"problemMatcher": "$msCompile"
|
||||
}, {
|
||||
"label": "Build tournament tests (Release)",
|
||||
"type": "shell",
|
||||
"command": "dotnet",
|
||||
"args": [
|
||||
"build",
|
||||
"--no-restore",
|
||||
"osu.Game.Tournament.Tests",
|
||||
"/p:Configuration=Release",
|
||||
"/p:GenerateFullPaths=true",
|
||||
"/m",
|
||||
"/verbosity:m"
|
||||
],
|
||||
"group": "build",
|
||||
"problemMatcher": "$msCompile"
|
||||
},
|
||||
{
|
||||
"label": "Restore (netcoreapp2.2)",
|
||||
"type": "shell",
|
||||
|
||||
@@ -10,6 +10,8 @@ This project is still heavily under development, but is in a state where users a
|
||||
|
||||
We are accepting bug reports (please report with as much detail as possible). Feature requests are welcome as long as you read and understand the contribution guidelines listed below.
|
||||
|
||||
Detailed changelogs are published on the [official osu! site](https://osu.ppy.sh/home/changelog).
|
||||
|
||||
## Requirements
|
||||
|
||||
- A desktop platform with the [.NET Core SDK 2.2](https://www.microsoft.com/net/learn/get-started) or higher installed.
|
||||
@@ -20,17 +22,24 @@ We are accepting bug reports (please report with as much detail as possible). Fe
|
||||
|
||||
### Releases
|
||||
|
||||
If you are not interested in developing the game, please head over to the [releases](https://github.com/ppy/osu/releases) to download a precompiled build with automatic updating enabled.
|
||||

|
||||
|
||||
- Windows (x64) users should download and run `install.exe`.
|
||||
- macOS users (10.12 "Sierra" and higher) should download and run `osu.app.zip`.
|
||||
- iOS users can join the [TestFlight beta program](https://t.co/xQJmHkfC18).
|
||||
If you are not interested in developing the game, you can still consume our [binary releases](https://github.com/ppy/osu/releases).
|
||||
|
||||
**Latest build:**
|
||||
|
||||
| [Windows (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | [macOS 10.12+](https://github.com/ppy/osu/releases/latest/download/osu.app.zip) |
|
||||
| ------------- | ------------- |
|
||||
|
||||
- **Linux** users are recommended to self-compile until we have official deployment in place.
|
||||
- **iOS** users can join the [TestFlight beta program](https://t.co/PasE1zrHhw) (note that due to high demand this is regularly full).
|
||||
- **Android** users can self-compile, and expect a public beta soon.
|
||||
|
||||
If your platform is not listed above, there is still a chance you can manually build it by following the instructions below.
|
||||
|
||||
### Downloading the source code
|
||||
|
||||
Clone the repository **including submodules**:
|
||||
Clone the repository:
|
||||
|
||||
```shell
|
||||
git clone https://github.com/ppy/osu
|
||||
@@ -45,7 +54,7 @@ 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.
|
||||
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.
|
||||
|
||||
@@ -63,7 +72,7 @@ If the build fails, try to restore nuget packages with `dotnet restore`.
|
||||
|
||||
On Linux, the environment variable `LD_LIBRARY_PATH` must point to the build directory, located at `osu.Desktop/bin/Debug/$NETCORE_VERSION`.
|
||||
|
||||
`$NETCORE_VERSION` is the version of .NET Core SDK. You can have it with `grep TargetFramework osu.Desktop/osu.Desktop.csproj | sed -r 's/.*>(.*)<\/.*/\1/'`.
|
||||
`$NETCORE_VERSION` is the version of the targeted .NET Core SDK. You can check it by running `grep TargetFramework osu.Desktop/osu.Desktop.csproj | sed -r 's/.*>(.*)<\/.*/\1/'`.
|
||||
|
||||
For example, you can run osu! with the following command:
|
||||
|
||||
|
||||
+1
-1
@@ -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
|
||||
|
||||
+4
-2
@@ -1,5 +1,5 @@
|
||||
#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();
|
||||
|
||||
@@ -46,7 +46,9 @@ Task("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")
|
||||
|
||||
+1
-1
@@ -35,7 +35,7 @@ platform :ios do
|
||||
changelog.gsub!('$BUILD_ID', options[:build])
|
||||
|
||||
pilot(
|
||||
wait_processing_interval: 900,
|
||||
wait_processing_interval: 1800,
|
||||
changelog: changelog,
|
||||
ipa: './osu.iOS/bin/iPhone/Release/osu.iOS.ipa'
|
||||
)
|
||||
|
||||
@@ -7,13 +7,13 @@ 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;
|
||||
@@ -35,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()
|
||||
@@ -52,7 +55,7 @@ namespace osu.Desktop
|
||||
LoadComponentAsync(versionManager = new VersionManager { Depth = int.MinValue }, v =>
|
||||
{
|
||||
Add(v);
|
||||
v.State = Visibility.Visible;
|
||||
v.Show();
|
||||
});
|
||||
|
||||
if (RuntimeInfo.OS == RuntimeInfo.Platform.Windows)
|
||||
@@ -70,12 +73,11 @@ namespace osu.Desktop
|
||||
{
|
||||
case Intro _:
|
||||
case MainMenu _:
|
||||
if (versionManager != null)
|
||||
versionManager.State = Visibility.Visible;
|
||||
versionManager?.Show();
|
||||
break;
|
||||
|
||||
default:
|
||||
if (versionManager != null)
|
||||
versionManager.State = Visibility.Hidden;
|
||||
versionManager?.Hide();
|
||||
break;
|
||||
}
|
||||
}
|
||||
@@ -83,6 +85,7 @@ namespace osu.Desktop
|
||||
public override void SetHost(GameHost host)
|
||||
{
|
||||
base.SetHost(host);
|
||||
|
||||
if (host.Window is DesktopGameWindow desktopWindow)
|
||||
{
|
||||
desktopWindow.CursorState |= CursorState.Hidden;
|
||||
@@ -139,8 +142,8 @@ namespace osu.Desktop
|
||||
return null;
|
||||
}
|
||||
|
||||
public StableStorage()
|
||||
: base(string.Empty, null)
|
||||
public StableStorage(DesktopGameHost host)
|
||||
: base(string.Empty, host)
|
||||
{
|
||||
}
|
||||
}
|
||||
|
||||
@@ -1,20 +1,18 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.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;
|
||||
@@ -65,7 +61,7 @@ namespace osu.Desktop.Overlays
|
||||
},
|
||||
new OsuSpriteText
|
||||
{
|
||||
Colour = DebugUtils.IsDebug ? colours.Red : Color4.White,
|
||||
Colour = DebugUtils.IsDebugBuild ? colours.Red : Color4.White,
|
||||
Text = game.Version
|
||||
},
|
||||
}
|
||||
@@ -95,33 +91,38 @@ namespace osu.Desktop.Overlays
|
||||
|
||||
var version = game.Version;
|
||||
var lastVersion = config.Get<string>(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<string> openUrl = null)
|
||||
private readonly string version;
|
||||
|
||||
public UpdateCompleteNotification(string version)
|
||||
{
|
||||
this.version = version;
|
||||
Text = $"You are now running osu!lazer {version}.\nClick to see what's new!";
|
||||
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;
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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
|
||||
{
|
||||
@@ -31,6 +32,7 @@ namespace osu.Desktop
|
||||
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);
|
||||
@@ -45,6 +47,10 @@ namespace osu.Desktop
|
||||
default:
|
||||
host.Run(new OsuGameDesktop(args));
|
||||
break;
|
||||
|
||||
case "--tournament":
|
||||
host.Run(new TournamentGame());
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -7,10 +7,10 @@ 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;
|
||||
|
||||
@@ -54,7 +54,7 @@ namespace osu.Desktop.Updater
|
||||
{
|
||||
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,
|
||||
Icon = FontAwesome.Solid.Upload,
|
||||
Activated = () =>
|
||||
{
|
||||
host.OpenUrlExternally(getBestUrl(latest));
|
||||
@@ -78,6 +78,7 @@ namespace osu.Desktop.Updater
|
||||
case RuntimeInfo.Platform.Windows:
|
||||
bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".exe"));
|
||||
break;
|
||||
|
||||
case RuntimeInfo.Platform.MacOsx:
|
||||
bestAsset = release.Assets?.Find(f => f.Name.EndsWith(".app.zip"));
|
||||
break;
|
||||
|
||||
@@ -2,13 +2,12 @@
|
||||
// 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;
|
||||
@@ -158,7 +157,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 +167,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()
|
||||
|
||||
@@ -17,6 +17,7 @@
|
||||
<StartupObject>osu.Desktop.Program</StartupObject>
|
||||
</PropertyGroup>
|
||||
<ItemGroup Label="Project References">
|
||||
<ProjectReference Include="..\osu.Game.Tournament\osu.Game.Tournament.csproj" />
|
||||
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
||||
@@ -26,9 +27,9 @@
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="System.IO.Packaging" Version="4.5.0" />
|
||||
<PackageReference Include="ppy.squirrel.windows" Version="1.9.0.3" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.1" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.1" />
|
||||
<PackageReference Include="ppy.squirrel.windows" Version="1.9.0.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.4" />
|
||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Design" Version="2.2.4" />
|
||||
</ItemGroup>
|
||||
<ItemGroup Label="Resources">
|
||||
<EmbeddedResource Include="lazer.ico" />
|
||||
|
||||
@@ -36,11 +36,13 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
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);
|
||||
|
||||
|
||||
+5
-5
@@ -13,21 +13,21 @@ using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
public class TestCaseAutoJuiceStream : PlayerTestCase
|
||||
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);
|
||||
}
|
||||
}
|
||||
+4
-4
@@ -13,7 +13,7 @@ using osu.Game.Tests.Visual;
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseBananaShower : PlayerTestCase
|
||||
public class TestSceneBananaShower : PlayerTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
@@ -24,19 +24,19 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
+2
-2
@@ -7,9 +7,9 @@ using osu.Game.Tests.Visual;
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseCatchPlayer : PlayerTestCase
|
||||
public class TestSceneCatchPlayer : PlayerTestScene
|
||||
{
|
||||
public TestCaseCatchPlayer()
|
||||
public TestSceneCatchPlayer()
|
||||
: base(new CatchRuleset())
|
||||
{
|
||||
}
|
||||
+4
-4
@@ -9,21 +9,21 @@ using osu.Game.Tests.Visual;
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseCatchStacker : PlayerTestCase
|
||||
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
|
||||
}
|
||||
};
|
||||
|
||||
@@ -0,0 +1,105 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Game.Rulesets.Catch.UI;
|
||||
using osu.Game.Tests.Visual;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Game.Skinning;
|
||||
using osu.Framework.Graphics.Shapes;
|
||||
using osu.Framework.Graphics.Sprites;
|
||||
using osuTK.Graphics;
|
||||
using osu.Framework.Audio.Sample;
|
||||
using osu.Framework.Graphics.Textures;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestSceneCatcher : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
typeof(CatcherSprite),
|
||||
};
|
||||
|
||||
private readonly Container container;
|
||||
|
||||
public TestSceneCatcher()
|
||||
{
|
||||
Child = container = new Container
|
||||
{
|
||||
Anchor = Anchor.Centre,
|
||||
Origin = Anchor.Centre,
|
||||
};
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
AddStep("show default catcher implementation", () => { container.Child = new CatcherSprite(); });
|
||||
|
||||
AddStep("show custom catcher implementation", () =>
|
||||
{
|
||||
container.Child = new CatchCustomSkinSourceContainer
|
||||
{
|
||||
Child = new CatcherSprite()
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
private class CatcherCustomSkin : Container
|
||||
{
|
||||
public CatcherCustomSkin()
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both;
|
||||
|
||||
Children = new Drawable[]
|
||||
{
|
||||
new Box
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Colour = Color4.Blue
|
||||
},
|
||||
new SpriteText
|
||||
{
|
||||
Text = "custom"
|
||||
}
|
||||
};
|
||||
}
|
||||
}
|
||||
|
||||
[Cached(typeof(ISkinSource))]
|
||||
private class CatchCustomSkinSourceContainer : Container, ISkinSource
|
||||
{
|
||||
public event Action SourceChanged
|
||||
{
|
||||
add { }
|
||||
remove { }
|
||||
}
|
||||
|
||||
public Drawable GetDrawableComponent(string componentName)
|
||||
{
|
||||
switch (componentName)
|
||||
{
|
||||
case "Play/Catch/fruit-catcher-idle":
|
||||
return new CatcherCustomSkin();
|
||||
}
|
||||
|
||||
return null;
|
||||
}
|
||||
|
||||
public SampleChannel GetSample(string sampleName) =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
public Texture GetTexture(string componentName) =>
|
||||
throw new NotImplementedException();
|
||||
|
||||
public TValue GetValue<TConfiguration, TValue>(Func<TConfiguration, TValue> query) where TConfiguration : SkinConfiguration =>
|
||||
throw new NotImplementedException();
|
||||
}
|
||||
}
|
||||
}
|
||||
+2
-2
@@ -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<float>("CircleSize", 0, 8, 5, createCatcher);
|
||||
AddToggleStep("Hyperdash", t => catcherArea.ToggleHyperDash(t));
|
||||
+2
-2
@@ -15,7 +15,7 @@ using osuTK;
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseFruitObjects : OsuTestCase
|
||||
public class TestSceneFruitObjects : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
@@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
||||
typeof(Pulp),
|
||||
};
|
||||
|
||||
public TestCaseFruitObjects()
|
||||
public TestSceneFruitObjects()
|
||||
{
|
||||
Add(new GridContainer
|
||||
{
|
||||
+6
-7
@@ -2,7 +2,6 @@
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using NUnit.Framework;
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Tests.Visual;
|
||||
@@ -10,26 +9,26 @@ using osu.Game.Tests.Visual;
|
||||
namespace osu.Game.Rulesets.Catch.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseHyperDash : PlayerTestCase
|
||||
public class TestSceneHyperDash : PlayerTestScene
|
||||
{
|
||||
public TestCaseHyperDash()
|
||||
public TestSceneHyperDash()
|
||||
: base(new CatchRuleset())
|
||||
{
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
[Test]
|
||||
public void TestHyperDash()
|
||||
{
|
||||
AddAssert("First note is hyperdash", () => Beatmap.Value.Beatmap.HitObjects[0] is Fruit f && f.HyperDash);
|
||||
}
|
||||
|
||||
protected override IBeatmap CreateBeatmap(Ruleset ruleset)
|
||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||
{
|
||||
var beatmap = new Beatmap
|
||||
{
|
||||
BeatmapInfo =
|
||||
{
|
||||
Ruleset = ruleset.RulesetInfo,
|
||||
Ruleset = ruleset,
|
||||
BaseDifficulty = new BeatmapDifficulty { CircleSize = 3.6f }
|
||||
}
|
||||
};
|
||||
@@ -2,9 +2,9 @@
|
||||
<Import Project="..\osu.TestProject.props" />
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
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
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
@@ -31,6 +31,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
initialiseHyperDash((List<CatchHitObject>)Beatmap.HitObjects);
|
||||
|
||||
int index = 0;
|
||||
|
||||
foreach (var obj in Beatmap.HitObjects.OfType<CatchHitObject>())
|
||||
{
|
||||
obj.IndexInBeatmap = index++;
|
||||
@@ -58,6 +59,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
}
|
||||
|
||||
break;
|
||||
|
||||
case JuiceStream juiceStream:
|
||||
foreach (var nested in juiceStream.NestedHitObjects)
|
||||
{
|
||||
@@ -103,6 +105,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
||||
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;
|
||||
|
||||
@@ -9,6 +9,7 @@ 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;
|
||||
@@ -17,12 +18,13 @@ 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 DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap) => new DrawableCatchRuleset(this, beatmap);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList<Mod> mods) => new DrawableCatchRuleset(this, beatmap, mods);
|
||||
public override IBeatmapConverter CreateBeatmapConverter(IBeatmap beatmap) => new CatchBeatmapConverter(beatmap);
|
||||
public override IBeatmapProcessor CreateBeatmapProcessor(IBeatmap beatmap) => new CatchBeatmapProcessor(beatmap);
|
||||
|
||||
@@ -85,6 +87,7 @@ namespace osu.Game.Rulesets.Catch
|
||||
new CatchModNoFail(),
|
||||
new MultiMod(new CatchModHalfTime(), new CatchModDaycore())
|
||||
};
|
||||
|
||||
case ModType.DifficultyIncrease:
|
||||
return new Mod[]
|
||||
{
|
||||
@@ -94,17 +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<CatchHitObject>(), new ModWindDown<CatchHitObject>())
|
||||
};
|
||||
|
||||
default:
|
||||
return new Mod[] { };
|
||||
}
|
||||
@@ -114,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();
|
||||
|
||||
@@ -31,7 +31,7 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new CatchDifficultyAttributes { Mods = mods };
|
||||
return new CatchDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
|
||||
// this is the same as osu!, so there's potential to share the implementation... maybe
|
||||
double preempt = BeatmapDifficulty.DifficultyRange(beatmap.BeatmapInfo.BaseDifficulty.ApproachRate, 1800, 1200, 450) / clockRate;
|
||||
@@ -41,7 +41,8 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
StarRating = Math.Sqrt(skills[0].DifficultyValue()) * star_scaling_factor,
|
||||
Mods = mods,
|
||||
ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0,
|
||||
MaxCombo = beatmap.HitObjects.Count(h => h is Fruit) + beatmap.HitObjects.OfType<JuiceStream>().SelectMany(j => j.NestedHitObjects).Count(h => !(h is TinyDroplet))
|
||||
MaxCombo = beatmap.HitObjects.Count(h => h is Fruit) + beatmap.HitObjects.OfType<JuiceStream>().SelectMany(j => j.NestedHitObjects).Count(h => !(h is TinyDroplet)),
|
||||
Skills = skills
|
||||
};
|
||||
}
|
||||
|
||||
@@ -57,32 +58,20 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
||||
|
||||
CatchHitObject lastObject = null;
|
||||
|
||||
foreach (var hitObject in beatmap.HitObjects.OfType<CatchHitObject>())
|
||||
// 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<CatchHitObject>()
|
||||
.OrderBy(x => x.StartTime))
|
||||
{
|
||||
if (lastObject == null)
|
||||
{
|
||||
lastObject = hitObject;
|
||||
// We want to only consider fruits that contribute to the combo.
|
||||
if (hitObject is BananaShower || hitObject is TinyDroplet)
|
||||
continue;
|
||||
}
|
||||
|
||||
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:
|
||||
yield return new CatchDifficultyHitObject(fruit, lastObject, clockRate, halfCatchWidth);
|
||||
if (lastObject != null)
|
||||
yield return new CatchDifficultyHitObject(hitObject, lastObject, clockRate, halfCatchWidth);
|
||||
|
||||
lastObject = hitObject;
|
||||
break;
|
||||
case JuiceStream _:
|
||||
foreach (var nested in hitObject.NestedHitObjects.OfType<CatchHitObject>().Where(o => !(o is TinyDroplet)))
|
||||
{
|
||||
yield return new CatchDifficultyHitObject(nested, lastObject, clockRate, halfCatchWidth);
|
||||
|
||||
lastObject = nested;
|
||||
}
|
||||
|
||||
break;
|
||||
}
|
||||
lastObject = hitObject;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,104 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using osu.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<string, double> 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;
|
||||
}
|
||||
}
|
||||
@@ -16,6 +16,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 1100;
|
||||
}
|
||||
@@ -27,8 +28,9 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 8;
|
||||
return 0.008;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -13,6 +13,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 30;
|
||||
}
|
||||
@@ -23,9 +24,10 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
switch (result)
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
return base.HealthIncreaseFor(result);
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 7;
|
||||
return 0.007;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -17,6 +17,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 300;
|
||||
}
|
||||
@@ -27,9 +28,10 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
switch (result)
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
return -0.02;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 10.2;
|
||||
return 0.01;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -15,6 +15,7 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 10;
|
||||
}
|
||||
@@ -26,8 +27,9 @@ namespace osu.Game.Rulesets.Catch.Judgements
|
||||
{
|
||||
default:
|
||||
return 0;
|
||||
|
||||
case HitResult.Perfect:
|
||||
return 4;
|
||||
return 0.004;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -13,17 +13,17 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
{
|
||||
private readonly Container bananaContainer;
|
||||
|
||||
public DrawableBananaShower(BananaShower s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation = null)
|
||||
public DrawableBananaShower(BananaShower s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> 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<Banana>())
|
||||
AddNested(getVisualRepresentation?.Invoke(b));
|
||||
AddNested(createDrawableRepresentation?.Invoke(b));
|
||||
}
|
||||
|
||||
protected override void AddNested(DrawableHitObject h)
|
||||
|
||||
@@ -84,6 +84,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;
|
||||
|
||||
@@ -26,10 +26,7 @@ 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
|
||||
|
||||
@@ -6,6 +6,7 @@ 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;
|
||||
@@ -42,7 +43,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
// todo: this should come from the skin.
|
||||
AccentColour = colourForRepresentation(HitObject.VisualRepresentation);
|
||||
|
||||
InternalChildren = new[]
|
||||
AddRangeInternal(new[]
|
||||
{
|
||||
createPulp(HitObject.VisualRepresentation),
|
||||
border = new Circle
|
||||
@@ -70,7 +71,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
}
|
||||
}
|
||||
},
|
||||
};
|
||||
});
|
||||
|
||||
if (HitObject.HyperDash)
|
||||
{
|
||||
@@ -105,6 +106,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
{
|
||||
default:
|
||||
return new Container();
|
||||
|
||||
case FruitVisualRepresentation.Raspberry:
|
||||
return new Container
|
||||
{
|
||||
@@ -143,6 +145,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
case FruitVisualRepresentation.Pineapple:
|
||||
return new Container
|
||||
{
|
||||
@@ -181,6 +184,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
case FruitVisualRepresentation.Pear:
|
||||
return new Container
|
||||
{
|
||||
@@ -213,6 +217,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
case FruitVisualRepresentation.Grape:
|
||||
return new Container
|
||||
{
|
||||
@@ -245,6 +250,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
},
|
||||
}
|
||||
};
|
||||
|
||||
case FruitVisualRepresentation.Banana:
|
||||
return new Container
|
||||
{
|
||||
@@ -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);
|
||||
}
|
||||
|
||||
@@ -13,17 +13,17 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawable
|
||||
{
|
||||
private readonly Container dropletContainer;
|
||||
|
||||
public DrawableJuiceStream(JuiceStream s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation = null)
|
||||
public DrawableJuiceStream(JuiceStream s, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> 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<CatchHitObject>())
|
||||
AddNested(getVisualRepresentation?.Invoke(o));
|
||||
AddNested(createDrawableRepresentation?.Invoke(o));
|
||||
}
|
||||
|
||||
protected override void AddNested(DrawableHitObject h)
|
||||
|
||||
@@ -3,7 +3,7 @@
|
||||
|
||||
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;
|
||||
|
||||
@@ -95,6 +95,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
||||
X = X + Path.PositionAt(e.PathProgress).X / CatchPlayfield.BASE_WIDTH,
|
||||
});
|
||||
break;
|
||||
|
||||
case SliderEventType.Head:
|
||||
case SliderEventType.Tail:
|
||||
case SliderEventType.Repeat:
|
||||
|
||||
@@ -43,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;
|
||||
@@ -59,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)
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -1,7 +1,6 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using osu.Game.Beatmaps;
|
||||
using osu.Game.Rulesets.Catch.Objects;
|
||||
using osu.Game.Rulesets.Judgements;
|
||||
@@ -27,20 +26,16 @@ 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;
|
||||
|
||||
Health.Value += Math.Max(result.Judgement.HealthIncreaseFor(result) - hpDrainRate, 0) * harshness;
|
||||
default:
|
||||
return 10.2 - hpDrainRate; // Award less HP as drain rate is increased
|
||||
}
|
||||
}
|
||||
|
||||
public override HitWindows CreateHitWindows() => new CatchHitWindows();
|
||||
|
||||
@@ -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<CatchHitObject, DrawableHitObject<CatchHitObject>> getVisualRepresentation)
|
||||
public CatchPlayfield(BeatmapDifficulty difficulty, Func<CatchHitObject, DrawableHitObject<CatchHitObject>> 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
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
+8
-2
@@ -3,17 +3,23 @@
|
||||
|
||||
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<Drawable> 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,
|
||||
@@ -6,8 +6,6 @@ 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;
|
||||
@@ -29,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
protected internal readonly Catcher MovableCatcher;
|
||||
|
||||
public Func<CatchHitObject, DrawableHitObject<CatchHitObject>> GetVisualRepresentation;
|
||||
public Func<CatchHitObject, DrawableHitObject<CatchHitObject>> CreateDrawableRepresentation;
|
||||
|
||||
public Container ExplodingFruitTarget
|
||||
{
|
||||
@@ -65,7 +63,7 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
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<DrawableHitObject>
|
||||
{
|
||||
@@ -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();
|
||||
|
||||
/// <summary>
|
||||
/// 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");
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -0,0 +1,33 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using osu.Framework.Allocation;
|
||||
using osu.Framework.Graphics;
|
||||
using osu.Framework.Graphics.Containers;
|
||||
using osu.Game.Skinning;
|
||||
using osuTK;
|
||||
|
||||
namespace osu.Game.Rulesets.Catch.UI
|
||||
{
|
||||
public class CatcherSprite : CompositeDrawable
|
||||
{
|
||||
public CatcherSprite()
|
||||
{
|
||||
Size = new Vector2(CatcherArea.CATCHER_SIZE);
|
||||
|
||||
// Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling.
|
||||
OriginPosition = new Vector2(-0.02f, 0.06f) * CatcherArea.CATCHER_SIZE;
|
||||
}
|
||||
|
||||
[BackgroundDependencyLoader]
|
||||
private void load()
|
||||
{
|
||||
InternalChild = new SkinnableSprite(@"Play/Catch/fruit-catcher-idle")
|
||||
{
|
||||
RelativeSizeAxes = Axes.Both,
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using 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;
|
||||
@@ -23,8 +25,8 @@ namespace osu.Game.Rulesets.Catch.UI
|
||||
|
||||
protected override bool UserScrollSpeedAdjustment => false;
|
||||
|
||||
public DrawableCatchRuleset(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
: base(ruleset, beatmap)
|
||||
public DrawableCatchRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> 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 PlayfieldAdjustmentContainer CreatePlayfieldAdjustmentContainer() => new CatchPlayfieldAdjustmentContainer();
|
||||
|
||||
protected override PassThroughInputManager CreateInputManager() => new CatchInputManager(Ruleset.RulesetInfo);
|
||||
|
||||
public override DrawableHitObject<CatchHitObject> GetVisualRepresentation(CatchHitObject h)
|
||||
public override DrawableHitObject<CatchHitObject> 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);
|
||||
}
|
||||
|
||||
+2
-2
@@ -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<Drawable> content;
|
||||
protected override Container<Drawable> Content => content ?? base.Content;
|
||||
|
||||
protected ManiaInputTestCase(int keys)
|
||||
protected ManiaInputTestScene(int keys)
|
||||
{
|
||||
base.Content.Add(content = new LocalInputManager(keys));
|
||||
}
|
||||
+8
-2
@@ -1,6 +1,8 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using osu.Framework.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<Mod>))]
|
||||
private IReadOnlyList<Mod> mods { get; set; } = Array.Empty<Mod>();
|
||||
|
||||
protected ManiaPlacementBlueprintTestScene()
|
||||
{
|
||||
Add(column = new Column(0)
|
||||
{
|
||||
+2
-2
@@ -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)
|
||||
{
|
||||
+1
-1
@@ -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()
|
||||
+6
-2
@@ -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<Type> RequiredTypes => new[]
|
||||
{
|
||||
@@ -31,9 +32,12 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
typeof(ColumnHitObjectArea)
|
||||
};
|
||||
|
||||
[Cached(typeof(IReadOnlyList<Mod>))]
|
||||
private IReadOnlyList<Mod> mods { get; set; } = Array.Empty<Mod>();
|
||||
|
||||
private readonly List<Column> columns = new List<Column>();
|
||||
|
||||
public TestCaseColumn()
|
||||
public TestSceneColumn()
|
||||
: base(2)
|
||||
{
|
||||
}
|
||||
+2
-2
@@ -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<ManiaScrollingDirection> direction = new Bindable<ManiaScrollingDirection>();
|
||||
|
||||
public TestCaseEditor()
|
||||
public TestSceneEditor()
|
||||
: base(new ManiaRuleset())
|
||||
{
|
||||
AddStep("upwards scroll", () => direction.Value = ManiaScrollingDirection.Up);
|
||||
+1
-1
@@ -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();
|
||||
+2
-2
@@ -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<Drawable> 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());
|
||||
+1
-1
@@ -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();
|
||||
+2
-2
@@ -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<Drawable> Content => content ?? base.Content;
|
||||
private readonly Container content;
|
||||
|
||||
public TestCaseNoteSelectionBlueprint()
|
||||
public TestSceneNoteSelectionBlueprint()
|
||||
{
|
||||
var note = new Note { Column = 0 };
|
||||
note.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||
+5
-3
@@ -11,10 +11,10 @@ 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;
|
||||
@@ -27,7 +27,7 @@ using osuTK.Graphics;
|
||||
namespace osu.Game.Rulesets.Mania.Tests
|
||||
{
|
||||
[TestFixture]
|
||||
public class TestCaseNotes : OsuTestCase
|
||||
public class TestSceneNotes : OsuTestScene
|
||||
{
|
||||
public override IReadOnlyList<Type> RequiredTypes => new[]
|
||||
{
|
||||
@@ -138,7 +138,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
||||
content = new Container { RelativeSizeAxes = Axes.Both }
|
||||
}
|
||||
},
|
||||
new SpriteText
|
||||
new OsuSpriteText
|
||||
{
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre,
|
||||
@@ -168,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;
|
||||
+7
-2
@@ -1,6 +1,7 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System;
|
||||
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<Mod>))]
|
||||
private IReadOnlyList<Mod> mods { get; set; } = Array.Empty<Mod>();
|
||||
|
||||
private readonly List<ManiaStage> stages = new List<ManiaStage>();
|
||||
|
||||
private FillFlowContainer<ScrollingTestContainer> fill;
|
||||
|
||||
public TestCaseStage()
|
||||
public TestSceneStage()
|
||||
: base(columns)
|
||||
{
|
||||
}
|
||||
@@ -2,9 +2,9 @@
|
||||
<Import Project="..\osu.TestProject.props" />
|
||||
<ItemGroup Label="Package References">
|
||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="15.9.0" />
|
||||
<PackageReference Include="NUnit" Version="3.11.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.12.0" />
|
||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.1.0" />
|
||||
<PackageReference Include="NUnit" Version="3.12.0" />
|
||||
<PackageReference Include="NUnit3TestAdapter" Version="3.13.0" />
|
||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||
</ItemGroup>
|
||||
<PropertyGroup Label="Project">
|
||||
|
||||
@@ -3,8 +3,8 @@
|
||||
|
||||
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
|
||||
},
|
||||
};
|
||||
}
|
||||
|
||||
@@ -48,6 +48,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
||||
if (IsForCurrentRuleset)
|
||||
{
|
||||
TargetColumns = (int)Math.Max(1, roundedCircleSize);
|
||||
|
||||
if (TargetColumns >= 10)
|
||||
{
|
||||
TargetColumns = TargetColumns / 2;
|
||||
|
||||
@@ -179,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
|
||||
@@ -217,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);
|
||||
@@ -299,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);
|
||||
@@ -341,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);
|
||||
@@ -440,6 +446,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
bool ignoreHead = !sampleInfoListAt(startTime).Any(s => s.Name == SampleInfo.HIT_WHISTLE || s.Name == SampleInfo.HIT_FINISH || s.Name == SampleInfo.HIT_CLAP);
|
||||
|
||||
var rowPattern = new Pattern();
|
||||
|
||||
for (int i = 0; i <= spanCount; i++)
|
||||
{
|
||||
if (!(ignoreHead && startTime == HitObject.StartTime))
|
||||
|
||||
@@ -38,9 +38,11 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
||||
case 8 when HitObject.Samples.Any(s => s.Name == SampleInfo.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);
|
||||
|
||||
@@ -233,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
|
||||
@@ -303,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);
|
||||
@@ -340,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);
|
||||
@@ -384,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);
|
||||
|
||||
@@ -158,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);
|
||||
|
||||
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||
{
|
||||
if (beatmap.HitObjects.Count == 0)
|
||||
return new ManiaDifficultyAttributes { Mods = mods };
|
||||
return new ManiaDifficultyAttributes { Mods = mods, Skills = skills };
|
||||
|
||||
return new ManiaDifficultyAttributes
|
||||
{
|
||||
@@ -38,6 +38,7 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
||||
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
|
||||
};
|
||||
}
|
||||
|
||||
|
||||
@@ -1,10 +1,12 @@
|
||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||
// See the LICENCE file in the repository root for full licence text.
|
||||
|
||||
using System.Collections.Generic;
|
||||
using 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;
|
||||
|
||||
@@ -14,8 +16,8 @@ namespace osu.Game.Rulesets.Mania.Edit
|
||||
{
|
||||
public new IScrollingInfo ScrollingInfo => base.ScrollingInfo;
|
||||
|
||||
public DrawableManiaEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
: base(ruleset, beatmap)
|
||||
public DrawableManiaEditRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
}
|
||||
|
||||
|
||||
@@ -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;
|
||||
@@ -41,9 +42,9 @@ namespace osu.Game.Rulesets.Mania.Edit
|
||||
|
||||
public int TotalColumns => ((ManiaPlayfield)DrawableRuleset.Playfield).TotalColumns;
|
||||
|
||||
protected override DrawableRuleset<ManiaHitObject> CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
protected override DrawableRuleset<ManiaHitObject> CreateDrawableRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
{
|
||||
DrawableRuleset = new DrawableManiaEditRuleset(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(DrawableRuleset.ScrollingInfo);
|
||||
@@ -65,6 +66,7 @@ namespace osu.Game.Rulesets.Mania.Edit
|
||||
{
|
||||
case DrawableNote note:
|
||||
return new NoteSelectionBlueprint(note);
|
||||
|
||||
case DrawableHoldNote holdNote:
|
||||
return new HoldNoteSelectionBlueprint(holdNote);
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -10,6 +10,7 @@ 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;
|
||||
@@ -31,7 +32,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
public class ManiaRuleset : Ruleset
|
||||
{
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap) => new DrawableManiaRuleset(this, beatmap);
|
||||
public override DrawableRuleset CreateDrawableRulesetWith(WorkingBeatmap beatmap, IReadOnlyList<Mod> 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);
|
||||
|
||||
@@ -116,6 +117,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
new ManiaModNoFail(),
|
||||
new MultiMod(new ManiaModHalfTime(), new ManiaModDaycore()),
|
||||
};
|
||||
|
||||
case ModType.DifficultyIncrease:
|
||||
return new Mod[]
|
||||
{
|
||||
@@ -125,6 +127,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
new MultiMod(new ManiaModFadeIn(), new ManiaModHidden()),
|
||||
new ManiaModFlashlight(),
|
||||
};
|
||||
|
||||
case ModType.Conversion:
|
||||
return new Mod[]
|
||||
{
|
||||
@@ -141,16 +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<ManiaHitObject>(), new ModWindDown<ManiaHitObject>())
|
||||
};
|
||||
|
||||
default:
|
||||
return new Mod[] { };
|
||||
}
|
||||
@@ -160,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);
|
||||
|
||||
@@ -213,6 +219,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
SpecialAction = ManiaAction.Special1,
|
||||
NormalActionStart = ManiaAction.Key1,
|
||||
}.GenerateKeyBindingsFor(variant, out _);
|
||||
|
||||
case PlayfieldType.Dual:
|
||||
int keys = getDualStageKeyCount(variant);
|
||||
|
||||
@@ -270,6 +277,7 @@ namespace osu.Game.Rulesets.Mania
|
||||
{
|
||||
default:
|
||||
return $"{variant}K";
|
||||
|
||||
case PlayfieldType.Dual:
|
||||
{
|
||||
var keys = getDualStageKeyCount(variant);
|
||||
|
||||
@@ -2,6 +2,7 @@
|
||||
// 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;
|
||||
|
||||
@@ -3,6 +3,7 @@
|
||||
|
||||
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;
|
||||
@@ -17,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
||||
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;
|
||||
|
||||
|
||||
@@ -43,7 +43,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
{
|
||||
RelativeSizeAxes = Axes.X;
|
||||
|
||||
InternalChildren = new Drawable[]
|
||||
AddRangeInternal(new Drawable[]
|
||||
{
|
||||
bodyPiece = new BodyPiece
|
||||
{
|
||||
@@ -67,7 +67,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
Anchor = Anchor.TopCentre,
|
||||
Origin = Anchor.TopCentre
|
||||
}
|
||||
};
|
||||
});
|
||||
|
||||
foreach (var tick in tickContainer)
|
||||
AddNested(tick);
|
||||
|
||||
@@ -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.Rulesets.Scoring;
|
||||
|
||||
@@ -33,7 +34,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
RelativeSizeAxes = Axes.X;
|
||||
Size = new Vector2(1);
|
||||
|
||||
InternalChildren = new[]
|
||||
AddRangeInternal(new[]
|
||||
{
|
||||
glowContainer = new CircularContainer
|
||||
{
|
||||
@@ -51,7 +52,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
}
|
||||
}
|
||||
}
|
||||
};
|
||||
});
|
||||
}
|
||||
|
||||
public override Color4 AccentColour
|
||||
|
||||
@@ -65,6 +65,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
case ArmedState.Miss:
|
||||
this.FadeOut(150, Easing.In).Expire();
|
||||
break;
|
||||
|
||||
case ArmedState.Hit:
|
||||
this.FadeOut(150, Easing.OutQuint).Expire();
|
||||
break;
|
||||
|
||||
@@ -5,7 +5,7 @@ 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;
|
||||
@@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
|
||||
CornerRadius = 5;
|
||||
Masking = true;
|
||||
|
||||
InternalChild = headPiece = new NotePiece();
|
||||
AddInternal(headPiece = new NotePiece());
|
||||
}
|
||||
|
||||
protected override void OnDirectionChanged(ValueChangedEvent<ScrollingDirection> e)
|
||||
|
||||
@@ -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;
|
||||
|
||||
@@ -144,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
|
||||
|
||||
@@ -4,6 +4,7 @@
|
||||
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;
|
||||
|
||||
@@ -28,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++)
|
||||
@@ -51,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<ManiaAction>();
|
||||
|
||||
foreach (var group in pointGroups)
|
||||
{
|
||||
foreach (var point in group)
|
||||
@@ -60,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;
|
||||
|
||||
@@ -18,6 +18,6 @@ namespace osu.Game.Rulesets.Mania.Replays
|
||||
|
||||
protected override bool IsImportant(ManiaReplayFrame frame) => frame.Actions.Any();
|
||||
|
||||
public override List<IInput> GetPendingInputs() => new List<IInput> { new ReplayState<ManiaAction> { PressedActions = CurrentFrame.Actions } };
|
||||
public override List<IInput> GetPendingInputs() => new List<IInput> { new ReplayState<ManiaAction> { PressedActions = CurrentFrame?.Actions ?? new List<ManiaAction>() } };
|
||||
}
|
||||
}
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -3,7 +3,6 @@
|
||||
|
||||
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;
|
||||
@@ -28,36 +27,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
/// </summary>
|
||||
private const double hp_multiplier_max = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The default BAD hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_bad = 0.005;
|
||||
|
||||
/// <summary>
|
||||
/// The default OK hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_ok = 0.010;
|
||||
|
||||
/// <summary>
|
||||
/// The default GOOD hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_good = 0.035;
|
||||
|
||||
/// <summary>
|
||||
/// The default tick hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_tick = 0.040;
|
||||
|
||||
/// <summary>
|
||||
/// The default GREAT hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_great = 0.055;
|
||||
|
||||
/// <summary>
|
||||
/// The default PERFECT hit HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_perfect = 0.065;
|
||||
|
||||
/// <summary>
|
||||
/// The MISS HP multiplier at OD = 0.
|
||||
/// </summary>
|
||||
@@ -73,11 +42,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
/// </summary>
|
||||
private const double hp_multiplier_miss_max = 1;
|
||||
|
||||
/// <summary>
|
||||
/// The default MISS HP increase.
|
||||
/// </summary>
|
||||
private const double hp_increase_miss = -0.125;
|
||||
|
||||
/// <summary>
|
||||
/// The MISS HP multiplier. This is multiplied to the miss hp increase.
|
||||
/// </summary>
|
||||
@@ -88,10 +52,6 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
/// </summary>
|
||||
private double hpMultiplier = 1;
|
||||
|
||||
public ManiaScoreProcessor()
|
||||
{
|
||||
}
|
||||
|
||||
public ManiaScoreProcessor(DrawableRuleset<ManiaHitObject> drawableRuleset)
|
||||
: base(drawableRuleset)
|
||||
{
|
||||
@@ -122,42 +82,8 @@ namespace osu.Game.Rulesets.Mania.Scoring
|
||||
}
|
||||
}
|
||||
|
||||
protected override void ApplyResult(JudgementResult result)
|
||||
{
|
||||
base.ApplyResult(result);
|
||||
|
||||
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;
|
||||
}
|
||||
}
|
||||
}
|
||||
protected override double HealthAdjustmentFactorFor(JudgementResult result)
|
||||
=> result.Type == HitResult.Miss ? hpMissMultiplier : hpMultiplier;
|
||||
|
||||
public override HitWindows CreateHitWindows() => new ManiaHitWindows();
|
||||
}
|
||||
|
||||
@@ -6,6 +6,7 @@ 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;
|
||||
|
||||
@@ -7,6 +7,7 @@ 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;
|
||||
|
||||
@@ -6,7 +6,6 @@ using System.Linq;
|
||||
using osu.Framework.Allocation;
|
||||
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;
|
||||
@@ -19,6 +18,7 @@ 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;
|
||||
@@ -40,8 +40,8 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
private readonly Bindable<ManiaScrollingDirection> configDirection = new Bindable<ManiaScrollingDirection>();
|
||||
|
||||
public DrawableManiaRuleset(Ruleset ruleset, WorkingBeatmap beatmap)
|
||||
: base(ruleset, beatmap)
|
||||
public DrawableManiaRuleset(Ruleset ruleset, WorkingBeatmap beatmap, IReadOnlyList<Mod> mods)
|
||||
: base(ruleset, beatmap, mods)
|
||||
{
|
||||
// Generate the bar lines
|
||||
double lastObjectTime = (Objects.LastOrDefault() as IHasEndTime)?.EndTime ?? Objects.LastOrDefault()?.StartTime ?? double.MaxValue;
|
||||
@@ -57,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
|
||||
@@ -89,11 +90,9 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
/// <returns>The column which intersects with <paramref name="screenSpacePosition"/>.</returns>
|
||||
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);
|
||||
|
||||
@@ -101,14 +100,16 @@ namespace osu.Game.Rulesets.Mania.UI
|
||||
|
||||
protected override PassThroughInputManager CreateInputManager() => new ManiaInputManager(Ruleset.RulesetInfo, Variant);
|
||||
|
||||
public override DrawableHitObject<ManiaHitObject> GetVisualRepresentation(ManiaHitObject h)
|
||||
public override DrawableHitObject<ManiaHitObject> CreateDrawableRepresentation(ManiaHitObject h)
|
||||
{
|
||||
switch (h)
|
||||
{
|
||||
case HoldNote holdNote:
|
||||
return new DrawableHoldNote(holdNote);
|
||||
|
||||
case Note note:
|
||||
return new DrawableNote(note);
|
||||
|
||||
default:
|
||||
return null;
|
||||
}
|
||||
|
||||
Some files were not shown because too many files have changed in this diff Show More
Reference in New Issue
Block a user