mirror of
https://github.com/ppy/osu.git
synced 2025-02-13 15:43:21 +08:00
Merge branch 'master' into catch-hyperdash-stable-sort
This commit is contained in:
commit
4e1800860e
@ -15,13 +15,13 @@
|
|||||||
]
|
]
|
||||||
},
|
},
|
||||||
"codefilesanity": {
|
"codefilesanity": {
|
||||||
"version": "0.0.36",
|
"version": "0.0.37",
|
||||||
"commands": [
|
"commands": [
|
||||||
"CodeFileSanity"
|
"CodeFileSanity"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"ppy.localisationanalyser.tools": {
|
"ppy.localisationanalyser.tools": {
|
||||||
"version": "2022.809.0",
|
"version": "2023.712.0",
|
||||||
"commands": [
|
"commands": [
|
||||||
"localisation"
|
"localisation"
|
||||||
]
|
]
|
||||||
|
@ -9,6 +9,9 @@ indent_style = space
|
|||||||
indent_size = 2
|
indent_size = 2
|
||||||
trim_trailing_whitespace = true
|
trim_trailing_whitespace = true
|
||||||
|
|
||||||
|
[g_*.cs]
|
||||||
|
generated_code = true
|
||||||
|
|
||||||
[*.cs]
|
[*.cs]
|
||||||
end_of_line = crlf
|
end_of_line = crlf
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
@ -191,6 +194,8 @@ csharp_style_prefer_index_operator = false:silent
|
|||||||
csharp_style_prefer_range_operator = false:silent
|
csharp_style_prefer_range_operator = false:silent
|
||||||
csharp_style_prefer_switch_expression = false:none
|
csharp_style_prefer_switch_expression = false:none
|
||||||
|
|
||||||
|
csharp_style_namespace_declarations = block_scoped:warning
|
||||||
|
|
||||||
[*.{yaml,yml}]
|
[*.{yaml,yml}]
|
||||||
insert_final_newline = true
|
insert_final_newline = true
|
||||||
indent_style = space
|
indent_style = space
|
||||||
|
@ -6,3 +6,5 @@
|
|||||||
212d78865a6b5f091173a347bad5686834d1d5fe
|
212d78865a6b5f091173a347bad5686834d1d5fe
|
||||||
# Add partial specs in mobile projects too
|
# Add partial specs in mobile projects too
|
||||||
00c11b2b4e389e48f3995d63484a6bc66a7afbdb
|
00c11b2b4e389e48f3995d63484a6bc66a7afbdb
|
||||||
|
# Mass NRT enabling
|
||||||
|
0ab0c52ad577b3e7b406d09fa6056a56ff997c3e
|
||||||
|
2
.github/ISSUE_TEMPLATE/config.yml
vendored
2
.github/ISSUE_TEMPLATE/config.yml
vendored
@ -2,7 +2,7 @@ blank_issues_enabled: false
|
|||||||
contact_links:
|
contact_links:
|
||||||
- name: Help
|
- name: Help
|
||||||
url: https://github.com/ppy/osu/discussions/categories/q-a
|
url: https://github.com/ppy/osu/discussions/categories/q-a
|
||||||
about: osu! not working as you'd expect? Not sure it's a bug? Check the Q&A section!
|
about: osu! not working or performing as you'd expect? Not sure it's a bug? Check the Q&A section!
|
||||||
- name: Suggestions or feature request
|
- name: Suggestions or feature request
|
||||||
url: https://github.com/ppy/osu/discussions/categories/ideas
|
url: https://github.com/ppy/osu/discussions/categories/ideas
|
||||||
about: Got something you think should change or be added? Search for or start a new discussion!
|
about: Got something you think should change or be added? Search for or start a new discussion!
|
||||||
|
34
.github/workflows/ci.yml
vendored
34
.github/workflows/ci.yml
vendored
@ -13,17 +13,17 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
# FIXME: Tools won't run in .NET 6.0 unless you install 3.1.x LTS side by side.
|
# FIXME: Tools won't run in .NET 6.0 unless you install 3.1.x LTS side by side.
|
||||||
# https://itnext.io/how-to-support-multiple-net-sdks-in-github-actions-workflows-b988daa884e
|
# https://itnext.io/how-to-support-multiple-net-sdks-in-github-actions-workflows-b988daa884e
|
||||||
- name: Install .NET 3.1.x LTS
|
- name: Install .NET 3.1.x LTS
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: "3.1.x"
|
dotnet-version: "3.1.x"
|
||||||
|
|
||||||
- name: Install .NET 6.0.x
|
- name: Install .NET 6.0.x
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: "6.0.x"
|
dotnet-version: "6.0.x"
|
||||||
|
|
||||||
@ -77,10 +77,10 @@ jobs:
|
|||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install .NET 6.0.x
|
- name: Install .NET 6.0.x
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: "6.0.x"
|
dotnet-version: "6.0.x"
|
||||||
|
|
||||||
@ -94,7 +94,7 @@ jobs:
|
|||||||
# Attempt to upload results even if test fails.
|
# Attempt to upload results even if test fails.
|
||||||
# https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#always
|
# https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#always
|
||||||
- name: Upload Test Results
|
- name: Upload Test Results
|
||||||
uses: actions/upload-artifact@v2
|
uses: actions/upload-artifact@v3
|
||||||
if: ${{ always() }}
|
if: ${{ always() }}
|
||||||
with:
|
with:
|
||||||
name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
|
name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
|
||||||
@ -106,10 +106,10 @@ jobs:
|
|||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
- name: Install .NET 6.0.x
|
- name: Install .NET 6.0.x
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: "6.0.x"
|
dotnet-version: "6.0.x"
|
||||||
|
|
||||||
@ -121,14 +121,26 @@ jobs:
|
|||||||
|
|
||||||
build-only-ios:
|
build-only-ios:
|
||||||
name: Build only (iOS)
|
name: Build only (iOS)
|
||||||
runs-on: macos-latest
|
# `macos-13` is required, because Xcode 14.3 is required (see below).
|
||||||
|
# TODO: can be changed to `macos-latest` once `macos-13` becomes latest (currently in beta)
|
||||||
|
runs-on: macos-13
|
||||||
timeout-minutes: 60
|
timeout-minutes: 60
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
|
|
||||||
|
# newest Microsoft.iOS.Sdk versions require Xcode 14.3.
|
||||||
|
# 14.3 is currently not the default Xcode version (https://github.com/actions/runner-images/blob/main/images/macos/macos-13-Readme.md#xcode),
|
||||||
|
# so set it manually.
|
||||||
|
# TODO: remove when 14.3 becomes the default Xcode version.
|
||||||
|
- name: Set Xcode version
|
||||||
|
shell: bash
|
||||||
|
run: |
|
||||||
|
sudo xcode-select -s "/Applications/Xcode_14.3.app"
|
||||||
|
echo "MD_APPLE_SDK_ROOT=/Applications/Xcode_14.3.app" >> $GITHUB_ENV
|
||||||
|
|
||||||
- name: Install .NET 6.0.x
|
- name: Install .NET 6.0.x
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: "6.0.x"
|
dotnet-version: "6.0.x"
|
||||||
|
|
||||||
|
18
.github/workflows/diffcalc.yml
vendored
18
.github/workflows/diffcalc.yml
vendored
@ -48,8 +48,8 @@ jobs:
|
|||||||
CONTINUE="no"
|
CONTINUE="no"
|
||||||
fi
|
fi
|
||||||
|
|
||||||
echo "::set-output name=continue::${CONTINUE}"
|
echo "continue=${CONTINUE}" >> $GITHUB_OUTPUT
|
||||||
echo "::set-output name=matrix::${MATRIX_JSON}"
|
echo "matrix=${MATRIX_JSON}" >> $GITHUB_OUTPUT
|
||||||
diffcalc:
|
diffcalc:
|
||||||
name: Run
|
name: Run
|
||||||
runs-on: self-hosted
|
runs-on: self-hosted
|
||||||
@ -80,34 +80,34 @@ jobs:
|
|||||||
env:
|
env:
|
||||||
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
GITHUB_TOKEN: ${{ secrets.GITHUB_TOKEN }}
|
||||||
run: |
|
run: |
|
||||||
echo "::set-output name=branchname::$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.ref' | sed 's/\"//g')"
|
echo "branchname=$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.ref' | sed 's/\"//g')" >> $GITHUB_OUTPUT
|
||||||
echo "::set-output name=repo::$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.repo.full_name' | sed 's/\"//g')"
|
echo "repo=$(curl -H "Authorization: token ${GITHUB_TOKEN}" ${{ github.event.issue.pull_request.url }} | jq '.head.repo.full_name' | sed 's/\"//g')" >> $GITHUB_OUTPUT
|
||||||
|
|
||||||
# Checkout osu
|
# Checkout osu
|
||||||
- name: Checkout osu (master)
|
- name: Checkout osu (master)
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: 'master/osu'
|
path: 'master/osu'
|
||||||
- name: Checkout osu (pr)
|
- name: Checkout osu (pr)
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
path: 'pr/osu'
|
path: 'pr/osu'
|
||||||
repository: ${{ steps.upstreambranch.outputs.repo }}
|
repository: ${{ steps.upstreambranch.outputs.repo }}
|
||||||
ref: ${{ steps.upstreambranch.outputs.branchname }}
|
ref: ${{ steps.upstreambranch.outputs.branchname }}
|
||||||
|
|
||||||
- name: Checkout osu-difficulty-calculator (master)
|
- name: Checkout osu-difficulty-calculator (master)
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: ppy/osu-difficulty-calculator
|
repository: ppy/osu-difficulty-calculator
|
||||||
path: 'master/osu-difficulty-calculator'
|
path: 'master/osu-difficulty-calculator'
|
||||||
- name: Checkout osu-difficulty-calculator (pr)
|
- name: Checkout osu-difficulty-calculator (pr)
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
repository: ppy/osu-difficulty-calculator
|
repository: ppy/osu-difficulty-calculator
|
||||||
path: 'pr/osu-difficulty-calculator'
|
path: 'pr/osu-difficulty-calculator'
|
||||||
|
|
||||||
- name: Install .NET 5.0.x
|
- name: Install .NET 5.0.x
|
||||||
uses: actions/setup-dotnet@v1
|
uses: actions/setup-dotnet@v3
|
||||||
with:
|
with:
|
||||||
dotnet-version: "5.0.x"
|
dotnet-version: "5.0.x"
|
||||||
|
|
||||||
|
2
.github/workflows/sentry-release.yml
vendored
2
.github/workflows/sentry-release.yml
vendored
@ -13,7 +13,7 @@ jobs:
|
|||||||
runs-on: ubuntu-latest
|
runs-on: ubuntu-latest
|
||||||
steps:
|
steps:
|
||||||
- name: Checkout
|
- name: Checkout
|
||||||
uses: actions/checkout@v2
|
uses: actions/checkout@v3
|
||||||
with:
|
with:
|
||||||
fetch-depth: 0
|
fetch-depth: 0
|
||||||
|
|
||||||
|
53
.github/workflows/update-web-mod-definitions.yml
vendored
Normal file
53
.github/workflows/update-web-mod-definitions.yml
vendored
Normal file
@ -0,0 +1,53 @@
|
|||||||
|
name: Update osu-web mod definitions
|
||||||
|
on:
|
||||||
|
push:
|
||||||
|
tags:
|
||||||
|
- '*'
|
||||||
|
|
||||||
|
permissions:
|
||||||
|
contents: read # to fetch code (actions/checkout)
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
update-mod-definitions:
|
||||||
|
name: Update osu-web mod definitions
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Install .NET 6.0.x
|
||||||
|
uses: actions/setup-dotnet@v3
|
||||||
|
with:
|
||||||
|
dotnet-version: "6.0.x"
|
||||||
|
|
||||||
|
- name: Checkout ppy/osu
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
path: osu
|
||||||
|
|
||||||
|
- name: Checkout ppy/osu-tools
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: ppy/osu-tools
|
||||||
|
path: osu-tools
|
||||||
|
|
||||||
|
- name: Checkout ppy/osu-web
|
||||||
|
uses: actions/checkout@v3
|
||||||
|
with:
|
||||||
|
repository: ppy/osu-web
|
||||||
|
path: osu-web
|
||||||
|
|
||||||
|
- name: Setup local game checkout for tools
|
||||||
|
run: ./UseLocalOsu.sh
|
||||||
|
working-directory: ./osu-tools
|
||||||
|
|
||||||
|
- name: Regenerate mod definitions
|
||||||
|
run: dotnet run --project PerformanceCalculator -- mods > ../osu-web/database/mods.json
|
||||||
|
working-directory: ./osu-tools
|
||||||
|
|
||||||
|
- name: Create pull request with changes
|
||||||
|
uses: peter-evans/create-pull-request@v5
|
||||||
|
with:
|
||||||
|
title: Update mod definitions
|
||||||
|
body: "This PR has been auto-generated to update the mod definitions to match ppy/osu@${{ github.ref_name }}."
|
||||||
|
branch: update-mod-definitions
|
||||||
|
commit-message: Update mod definitions
|
||||||
|
path: osu-web
|
||||||
|
token: ${{ secrets.OSU_WEB_PULL_REQUEST_PAT }}
|
1
.gitignore
vendored
1
.gitignore
vendored
@ -339,6 +339,5 @@ inspectcode
|
|||||||
|
|
||||||
# Fody (pulled in by Realm) - schema file
|
# Fody (pulled in by Realm) - schema file
|
||||||
FodyWeavers.xsd
|
FodyWeavers.xsd
|
||||||
**/FodyWeavers.xml
|
|
||||||
|
|
||||||
.idea/.idea.osu.Desktop/.idea/misc.xml
|
.idea/.idea.osu.Desktop/.idea/misc.xml
|
@ -1,7 +1,7 @@
|
|||||||
<!-- Contains required properties for osu!framework projects. -->
|
<!-- Contains required properties for osu!framework projects. -->
|
||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup Label="C#">
|
<PropertyGroup Label="C#">
|
||||||
<LangVersion>9.0</LangVersion>
|
<LangVersion>10.0</LangVersion>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@ -17,7 +17,7 @@
|
|||||||
<EmbeddedResource Include="Resources\**\*.*" />
|
<EmbeddedResource Include="Resources\**\*.*" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Code Analysis">
|
<ItemGroup Label="Code Analysis">
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.3" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.4" PrivateAssets="All" />
|
||||||
<AdditionalFiles Include="$(MSBuildThisFileDirectory)CodeAnalysis\BannedSymbols.txt" />
|
<AdditionalFiles Include="$(MSBuildThisFileDirectory)CodeAnalysis\BannedSymbols.txt" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Code Analysis">
|
<PropertyGroup Label="Code Analysis">
|
||||||
|
6
Gemfile
6
Gemfile
@ -1,6 +0,0 @@
|
|||||||
source "https://rubygems.org"
|
|
||||||
|
|
||||||
gem "fastlane"
|
|
||||||
|
|
||||||
plugins_path = File.join(File.dirname(__FILE__), 'fastlane', 'Pluginfile')
|
|
||||||
eval_gemfile(plugins_path) if File.exist?(plugins_path)
|
|
234
Gemfile.lock
234
Gemfile.lock
@ -1,234 +0,0 @@
|
|||||||
GEM
|
|
||||||
remote: https://rubygems.org/
|
|
||||||
specs:
|
|
||||||
CFPropertyList (3.0.5)
|
|
||||||
rexml
|
|
||||||
addressable (2.8.1)
|
|
||||||
public_suffix (>= 2.0.2, < 6.0)
|
|
||||||
artifactory (3.0.15)
|
|
||||||
atomos (0.1.3)
|
|
||||||
aws-eventstream (1.2.0)
|
|
||||||
aws-partitions (1.653.0)
|
|
||||||
aws-sdk-core (3.166.0)
|
|
||||||
aws-eventstream (~> 1, >= 1.0.2)
|
|
||||||
aws-partitions (~> 1, >= 1.651.0)
|
|
||||||
aws-sigv4 (~> 1.5)
|
|
||||||
jmespath (~> 1, >= 1.6.1)
|
|
||||||
aws-sdk-kms (1.59.0)
|
|
||||||
aws-sdk-core (~> 3, >= 3.165.0)
|
|
||||||
aws-sigv4 (~> 1.1)
|
|
||||||
aws-sdk-s3 (1.117.1)
|
|
||||||
aws-sdk-core (~> 3, >= 3.165.0)
|
|
||||||
aws-sdk-kms (~> 1)
|
|
||||||
aws-sigv4 (~> 1.4)
|
|
||||||
aws-sigv4 (1.5.2)
|
|
||||||
aws-eventstream (~> 1, >= 1.0.2)
|
|
||||||
babosa (1.0.4)
|
|
||||||
claide (1.1.0)
|
|
||||||
colored (1.2)
|
|
||||||
colored2 (3.1.2)
|
|
||||||
commander (4.6.0)
|
|
||||||
highline (~> 2.0.0)
|
|
||||||
declarative (0.0.20)
|
|
||||||
digest-crc (0.6.4)
|
|
||||||
rake (>= 12.0.0, < 14.0.0)
|
|
||||||
domain_name (0.5.20190701)
|
|
||||||
unf (>= 0.0.5, < 1.0.0)
|
|
||||||
dotenv (2.8.1)
|
|
||||||
emoji_regex (3.2.3)
|
|
||||||
excon (0.93.1)
|
|
||||||
faraday (1.10.2)
|
|
||||||
faraday-em_http (~> 1.0)
|
|
||||||
faraday-em_synchrony (~> 1.0)
|
|
||||||
faraday-excon (~> 1.1)
|
|
||||||
faraday-httpclient (~> 1.0)
|
|
||||||
faraday-multipart (~> 1.0)
|
|
||||||
faraday-net_http (~> 1.0)
|
|
||||||
faraday-net_http_persistent (~> 1.0)
|
|
||||||
faraday-patron (~> 1.0)
|
|
||||||
faraday-rack (~> 1.0)
|
|
||||||
faraday-retry (~> 1.0)
|
|
||||||
ruby2_keywords (>= 0.0.4)
|
|
||||||
faraday-cookie_jar (0.0.7)
|
|
||||||
faraday (>= 0.8.0)
|
|
||||||
http-cookie (~> 1.0.0)
|
|
||||||
faraday-em_http (1.0.0)
|
|
||||||
faraday-em_synchrony (1.0.0)
|
|
||||||
faraday-excon (1.1.0)
|
|
||||||
faraday-httpclient (1.0.1)
|
|
||||||
faraday-multipart (1.0.4)
|
|
||||||
multipart-post (~> 2)
|
|
||||||
faraday-net_http (1.0.1)
|
|
||||||
faraday-net_http_persistent (1.2.0)
|
|
||||||
faraday-patron (1.0.0)
|
|
||||||
faraday-rack (1.0.0)
|
|
||||||
faraday-retry (1.0.3)
|
|
||||||
faraday_middleware (1.2.0)
|
|
||||||
faraday (~> 1.0)
|
|
||||||
fastimage (2.2.6)
|
|
||||||
fastlane (2.210.1)
|
|
||||||
CFPropertyList (>= 2.3, < 4.0.0)
|
|
||||||
addressable (>= 2.8, < 3.0.0)
|
|
||||||
artifactory (~> 3.0)
|
|
||||||
aws-sdk-s3 (~> 1.0)
|
|
||||||
babosa (>= 1.0.3, < 2.0.0)
|
|
||||||
bundler (>= 1.12.0, < 3.0.0)
|
|
||||||
colored
|
|
||||||
commander (~> 4.6)
|
|
||||||
dotenv (>= 2.1.1, < 3.0.0)
|
|
||||||
emoji_regex (>= 0.1, < 4.0)
|
|
||||||
excon (>= 0.71.0, < 1.0.0)
|
|
||||||
faraday (~> 1.0)
|
|
||||||
faraday-cookie_jar (~> 0.0.6)
|
|
||||||
faraday_middleware (~> 1.0)
|
|
||||||
fastimage (>= 2.1.0, < 3.0.0)
|
|
||||||
gh_inspector (>= 1.1.2, < 2.0.0)
|
|
||||||
google-apis-androidpublisher_v3 (~> 0.3)
|
|
||||||
google-apis-playcustomapp_v1 (~> 0.1)
|
|
||||||
google-cloud-storage (~> 1.31)
|
|
||||||
highline (~> 2.0)
|
|
||||||
json (< 3.0.0)
|
|
||||||
jwt (>= 2.1.0, < 3)
|
|
||||||
mini_magick (>= 4.9.4, < 5.0.0)
|
|
||||||
multipart-post (~> 2.0.0)
|
|
||||||
naturally (~> 2.2)
|
|
||||||
optparse (~> 0.1.1)
|
|
||||||
plist (>= 3.1.0, < 4.0.0)
|
|
||||||
rubyzip (>= 2.0.0, < 3.0.0)
|
|
||||||
security (= 0.1.3)
|
|
||||||
simctl (~> 1.6.3)
|
|
||||||
terminal-notifier (>= 2.0.0, < 3.0.0)
|
|
||||||
terminal-table (>= 1.4.5, < 2.0.0)
|
|
||||||
tty-screen (>= 0.6.3, < 1.0.0)
|
|
||||||
tty-spinner (>= 0.8.0, < 1.0.0)
|
|
||||||
word_wrap (~> 1.0.0)
|
|
||||||
xcodeproj (>= 1.13.0, < 2.0.0)
|
|
||||||
xcpretty (~> 0.3.0)
|
|
||||||
xcpretty-travis-formatter (>= 0.0.3)
|
|
||||||
fastlane-plugin-clean_testflight_testers (0.3.0)
|
|
||||||
fastlane-plugin-souyuz (0.11.1)
|
|
||||||
souyuz (= 0.11.1)
|
|
||||||
fastlane-plugin-xamarin (0.6.3)
|
|
||||||
gh_inspector (1.1.3)
|
|
||||||
google-apis-androidpublisher_v3 (0.29.0)
|
|
||||||
google-apis-core (>= 0.9.0, < 2.a)
|
|
||||||
google-apis-core (0.9.1)
|
|
||||||
addressable (~> 2.5, >= 2.5.1)
|
|
||||||
googleauth (>= 0.16.2, < 2.a)
|
|
||||||
httpclient (>= 2.8.1, < 3.a)
|
|
||||||
mini_mime (~> 1.0)
|
|
||||||
representable (~> 3.0)
|
|
||||||
retriable (>= 2.0, < 4.a)
|
|
||||||
rexml
|
|
||||||
webrick
|
|
||||||
google-apis-iamcredentials_v1 (0.15.0)
|
|
||||||
google-apis-core (>= 0.9.0, < 2.a)
|
|
||||||
google-apis-playcustomapp_v1 (0.12.0)
|
|
||||||
google-apis-core (>= 0.9.1, < 2.a)
|
|
||||||
google-apis-storage_v1 (0.19.0)
|
|
||||||
google-apis-core (>= 0.9.0, < 2.a)
|
|
||||||
google-cloud-core (1.6.0)
|
|
||||||
google-cloud-env (~> 1.0)
|
|
||||||
google-cloud-errors (~> 1.0)
|
|
||||||
google-cloud-env (1.6.0)
|
|
||||||
faraday (>= 0.17.3, < 3.0)
|
|
||||||
google-cloud-errors (1.3.0)
|
|
||||||
google-cloud-storage (1.43.0)
|
|
||||||
addressable (~> 2.8)
|
|
||||||
digest-crc (~> 0.4)
|
|
||||||
google-apis-iamcredentials_v1 (~> 0.1)
|
|
||||||
google-apis-storage_v1 (~> 0.19.0)
|
|
||||||
google-cloud-core (~> 1.6)
|
|
||||||
googleauth (>= 0.16.2, < 2.a)
|
|
||||||
mini_mime (~> 1.0)
|
|
||||||
googleauth (1.3.0)
|
|
||||||
faraday (>= 0.17.3, < 3.a)
|
|
||||||
jwt (>= 1.4, < 3.0)
|
|
||||||
memoist (~> 0.16)
|
|
||||||
multi_json (~> 1.11)
|
|
||||||
os (>= 0.9, < 2.0)
|
|
||||||
signet (>= 0.16, < 2.a)
|
|
||||||
highline (2.0.3)
|
|
||||||
http-cookie (1.0.5)
|
|
||||||
domain_name (~> 0.5)
|
|
||||||
httpclient (2.8.3)
|
|
||||||
jmespath (1.6.1)
|
|
||||||
json (2.6.2)
|
|
||||||
jwt (2.5.0)
|
|
||||||
memoist (0.16.2)
|
|
||||||
mini_magick (4.11.0)
|
|
||||||
mini_mime (1.1.2)
|
|
||||||
mini_portile2 (2.8.0)
|
|
||||||
multi_json (1.15.0)
|
|
||||||
multipart-post (2.0.0)
|
|
||||||
nanaimo (0.3.0)
|
|
||||||
naturally (2.2.1)
|
|
||||||
nokogiri (1.13.9)
|
|
||||||
mini_portile2 (~> 2.8.0)
|
|
||||||
racc (~> 1.4)
|
|
||||||
optparse (0.1.1)
|
|
||||||
os (1.1.4)
|
|
||||||
plist (3.6.0)
|
|
||||||
public_suffix (5.0.0)
|
|
||||||
racc (1.6.0)
|
|
||||||
rake (13.0.6)
|
|
||||||
representable (3.2.0)
|
|
||||||
declarative (< 0.1.0)
|
|
||||||
trailblazer-option (>= 0.1.1, < 0.2.0)
|
|
||||||
uber (< 0.2.0)
|
|
||||||
retriable (3.1.2)
|
|
||||||
rexml (3.2.5)
|
|
||||||
rouge (2.0.7)
|
|
||||||
ruby2_keywords (0.0.5)
|
|
||||||
rubyzip (2.3.2)
|
|
||||||
security (0.1.3)
|
|
||||||
signet (0.17.0)
|
|
||||||
addressable (~> 2.8)
|
|
||||||
faraday (>= 0.17.5, < 3.a)
|
|
||||||
jwt (>= 1.5, < 3.0)
|
|
||||||
multi_json (~> 1.10)
|
|
||||||
simctl (1.6.8)
|
|
||||||
CFPropertyList
|
|
||||||
naturally
|
|
||||||
souyuz (0.11.1)
|
|
||||||
fastlane (>= 2.182.0)
|
|
||||||
highline (~> 2.0)
|
|
||||||
nokogiri (~> 1.7)
|
|
||||||
terminal-notifier (2.0.0)
|
|
||||||
terminal-table (1.8.0)
|
|
||||||
unicode-display_width (~> 1.1, >= 1.1.1)
|
|
||||||
trailblazer-option (0.1.2)
|
|
||||||
tty-cursor (0.7.1)
|
|
||||||
tty-screen (0.8.1)
|
|
||||||
tty-spinner (0.9.3)
|
|
||||||
tty-cursor (~> 0.7)
|
|
||||||
uber (0.1.0)
|
|
||||||
unf (0.1.4)
|
|
||||||
unf_ext
|
|
||||||
unf_ext (0.0.8.2)
|
|
||||||
unicode-display_width (1.8.0)
|
|
||||||
webrick (1.7.0)
|
|
||||||
word_wrap (1.0.0)
|
|
||||||
xcodeproj (1.22.0)
|
|
||||||
CFPropertyList (>= 2.3.3, < 4.0)
|
|
||||||
atomos (~> 0.1.3)
|
|
||||||
claide (>= 1.0.2, < 2.0)
|
|
||||||
colored2 (~> 3.1)
|
|
||||||
nanaimo (~> 0.3.0)
|
|
||||||
rexml (~> 3.2.4)
|
|
||||||
xcpretty (0.3.0)
|
|
||||||
rouge (~> 2.0.7)
|
|
||||||
xcpretty-travis-formatter (1.0.1)
|
|
||||||
xcpretty (~> 0.2, >= 0.0.7)
|
|
||||||
|
|
||||||
PLATFORMS
|
|
||||||
ruby
|
|
||||||
|
|
||||||
DEPENDENCIES
|
|
||||||
fastlane
|
|
||||||
fastlane-plugin-clean_testflight_testers
|
|
||||||
fastlane-plugin-souyuz
|
|
||||||
fastlane-plugin-xamarin
|
|
||||||
|
|
||||||
BUNDLED WITH
|
|
||||||
2.0.1
|
|
40
README.md
40
README.md
@ -16,21 +16,20 @@ The future of [osu!](https://osu.ppy.sh) and the beginning of an open era! Curre
|
|||||||
|
|
||||||
## Status
|
## Status
|
||||||
|
|
||||||
This project is under heavy development, but is in a stable state. Users are encouraged to try it out and keep it installed alongside the stable *osu!* client. It will continue to evolve to the point of eventually replacing the existing stable client as an update.
|
This project is under constant development, but we aim to keep things in a stable state. Users are encouraged to try it out and keep it installed alongside the stable *osu!* client. It will continue to evolve to the point of eventually replacing the existing stable client as an update.
|
||||||
|
|
||||||
**IMPORTANT:** Gameplay mechanics (and other features which you may have come to know and love) are in a constant state of flux. Game balance and final quality-of-life passes come at the end of development, preceded by experimentation and changes which may potentially **reduce playability or usability**. This is done in order to allow us to move forward as developers and designers more efficiently. If this offends you, please consider sticking to the stable releases of osu! (found on the website). We are not yet open to heated discussion over game mechanics and will not be using github as a forum for such discussions just yet.
|
**IMPORTANT:** Gameplay mechanics (and other features which you may have come to know and love) are in a constant state of flux. Game balance and final quality-of-life passes come at the end of development, preceded by experimentation and changes which may potentially **reduce playability or usability**. This is done in order to allow us to move forward as developers and designers more efficiently. If this offends you, please consider sticking to a [stable release](https://osu.ppy.sh/home/download) of osu!. We are not yet open to heated discussion over game mechanics and will not be using github as a forum for such discussions just yet.
|
||||||
|
|
||||||
We are accepting bug reports (please report with as much detail as possible and follow the existing issue templates). Feature requests are also welcome, but understand that our focus is on completing the game to feature parity before adding new features. A few resources are available as starting points to getting involved and understanding the project:
|
We are accepting bug reports (please report with as much detail as possible and follow the existing issue templates). Feature requests are also welcome, but understand that our focus is on completing the game to feature parity before adding new features. A few resources are available as starting points to getting involved and understanding the project:
|
||||||
|
|
||||||
- Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer).
|
- Detailed release changelogs are available on the [official osu! site](https://osu.ppy.sh/home/changelog/lazer).
|
||||||
- You can learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management).
|
- You can learn more about our approach to [project management](https://github.com/ppy/osu/wiki/Project-management).
|
||||||
- Read peppy's [blog post](https://blog.ppy.sh/a-definitive-lazer-faq/) exploring where the project is currently and the roadmap going forward.
|
|
||||||
|
|
||||||
## Running osu!
|
## Running osu!
|
||||||
|
|
||||||
If you are looking to install or test osu! without setting up a development environment, you can consume our [binary releases](https://github.com/ppy/osu/releases). Handy links below will download the latest version for your operating system of choice:
|
If you are looking to install or test osu! without setting up a development environment, you can consume our [releases](https://github.com/ppy/osu/releases). You can also generally download a version for your current device from the [osu! site](https://osu.ppy.sh/home/download). Failing that, you may use the links below to download the latest version for your operating system of choice:
|
||||||
|
|
||||||
**Latest build:**
|
**Latest release:**
|
||||||
|
|
||||||
| [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 10.15+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
|
| [Windows 8.1+ (x64)](https://github.com/ppy/osu/releases/latest/download/install.exe) | macOS 10.15+ ([Intel](https://github.com/ppy/osu/releases/latest/download/osu.app.Intel.zip), [Apple Silicon](https://github.com/ppy/osu/releases/latest/download/osu.app.Apple.Silicon.zip)) | [Linux (x64)](https://github.com/ppy/osu/releases/latest/download/osu.AppImage) | [iOS 13.4+](https://osu.ppy.sh/home/testflight) | [Android 5+](https://github.com/ppy/osu/releases/latest/download/sh.ppy.osulazer.apk) |
|
||||||
| ------------- | ------------- | ------------- | ------------- | ------------- |
|
| ------------- | ------------- | ------------- | ------------- | ------------- |
|
||||||
@ -50,9 +49,8 @@ You can see some examples of custom rulesets by visiting the [custom ruleset dir
|
|||||||
Please make sure you have the following prerequisites:
|
Please make sure you have the following prerequisites:
|
||||||
|
|
||||||
- A desktop platform with the [.NET 6.0 SDK](https://dotnet.microsoft.com/download) installed.
|
- A desktop platform with the [.NET 6.0 SDK](https://dotnet.microsoft.com/download) installed.
|
||||||
- When developing with mobile, [Xamarin](https://docs.microsoft.com/en-us/xamarin/) is required, which is shipped together with Visual Studio or [Visual Studio for Mac](https://visualstudio.microsoft.com/vs/mac/).
|
|
||||||
- When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as the latest version of [Visual Studio](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/) or [Visual Studio Code](https://code.visualstudio.com/).
|
When working with the codebase, we recommend using an IDE with intelligent code completion and syntax highlighting, such as the latest version of [Visual Studio](https://visualstudio.microsoft.com/vs/), [JetBrains Rider](https://www.jetbrains.com/rider/), or [Visual Studio Code](https://code.visualstudio.com/) with the [EditorConfig](https://marketplace.visualstudio.com/items?itemName=EditorConfig.EditorConfig) and [C#](https://marketplace.visualstudio.com/items?itemName=ms-dotnettools.csharp) plugin installed.
|
||||||
- When running on Linux, please have a system-wide FFmpeg installation available to support video decoding.
|
|
||||||
|
|
||||||
### Downloading the source code
|
### Downloading the source code
|
||||||
|
|
||||||
@ -89,7 +87,29 @@ _Due to a historical feature gap between .NET Core and Xamarin, running `dotnet`
|
|||||||
|
|
||||||
### Testing with resource/framework modifications
|
### Testing with resource/framework modifications
|
||||||
|
|
||||||
Sometimes it may be necessary to cross-test changes in [osu-resources](https://github.com/ppy/osu-resources) or [osu-framework](https://github.com/ppy/osu-framework). This can be achieved by running some commands as documented on the [osu-resources](https://github.com/ppy/osu-resources/wiki/Testing-local-resources-checkout-with-other-projects) and [osu-framework](https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects) wiki pages.
|
Sometimes it may be necessary to cross-test changes in [osu-resources](https://github.com/ppy/osu-resources) or [osu-framework](https://github.com/ppy/osu-framework). This can be quickly achieved using included commands:
|
||||||
|
|
||||||
|
Windows:
|
||||||
|
|
||||||
|
```ps
|
||||||
|
UseLocalFramework.ps1
|
||||||
|
UseLocalResources.ps1
|
||||||
|
```
|
||||||
|
|
||||||
|
macOS / Linux:
|
||||||
|
|
||||||
|
```ps
|
||||||
|
UseLocalFramework.sh
|
||||||
|
UseLocalResources.sh
|
||||||
|
```
|
||||||
|
|
||||||
|
Note that these commands assume you have the relevant project(s) checked out in adjacent directories:
|
||||||
|
|
||||||
|
```
|
||||||
|
|- osu // this repository
|
||||||
|
|- osu-framework
|
||||||
|
|- osu-resources
|
||||||
|
```
|
||||||
|
|
||||||
### Code analysis
|
### Code analysis
|
||||||
|
|
||||||
@ -105,7 +125,7 @@ When it comes to contributing to the project, the two main things you can do to
|
|||||||
|
|
||||||
If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web).
|
If you wish to help with localisation efforts, head over to [crowdin](https://crowdin.com/project/osu-web).
|
||||||
|
|
||||||
For those interested, we love to reward quality contributions via [bounties](https://docs.google.com/spreadsheets/d/1jNXfj_S3Pb5PErA-czDdC9DUu4IgUbe1Lt8E7CYUJuE/view?&rm=minimal#gid=523803337), paid out via PayPal or osu!supporter tags. Don't hesitate to [request a bounty](https://docs.google.com/forms/d/e/1FAIpQLSet_8iFAgPMG526pBZ2Kic6HSh7XPM3fE8xPcnWNkMzINDdYg/viewform) for your work on this project.
|
We love to reward quality contributions. If you have made a large contribution, or are a regular contributor, you are welcome to [submit an expense via opencollective](https://opencollective.com/ppy/expenses/new). If you have any questions, feel free to [reach out to peppy](mailto:pe@ppy.sh) before doing so.
|
||||||
|
|
||||||
## Licence
|
## Licence
|
||||||
|
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
<GenerateProgramFile>false</GenerateProgramFile>
|
<GenerateProgramFile>false</GenerateProgramFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.EmptyFreeform\osu.Game.Rulesets.EmptyFreeform.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.EmptyFreeform\osu.Game.Rulesets.EmptyFreeform.csproj" />
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
<GenerateProgramFile>false</GenerateProgramFile>
|
<GenerateProgramFile>false</GenerateProgramFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Pippidon\osu.Game.Rulesets.Pippidon.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Pippidon\osu.Game.Rulesets.Pippidon.csproj" />
|
||||||
|
@ -8,7 +8,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -44,7 +43,7 @@ namespace osu.Game.Rulesets.Pippidon.Objects.Drawables
|
|||||||
|
|
||||||
public override IEnumerable<HitSampleInfo> GetSamples() => new[]
|
public override IEnumerable<HitSampleInfo> GetSamples() => new[]
|
||||||
{
|
{
|
||||||
new HitSampleInfo(HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK)
|
new HitSampleInfo(HitSampleInfo.HIT_NORMAL)
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
<GenerateProgramFile>false</GenerateProgramFile>
|
<GenerateProgramFile>false</GenerateProgramFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.EmptyScrolling\osu.Game.Rulesets.EmptyScrolling.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.EmptyScrolling\osu.Game.Rulesets.EmptyScrolling.csproj" />
|
||||||
|
@ -9,9 +9,9 @@
|
|||||||
<GenerateProgramFile>false</GenerateProgramFile>
|
<GenerateProgramFile>false</GenerateProgramFile>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Pippidon\osu.Game.Rulesets.Pippidon.csproj" />
|
<ProjectReference Include="..\osu.Game.Rulesets.Pippidon\osu.Game.Rulesets.Pippidon.csproj" />
|
||||||
|
@ -8,7 +8,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
using osu.Game.Rulesets.Pippidon.UI;
|
using osu.Game.Rulesets.Pippidon.UI;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
@ -44,7 +43,7 @@ namespace osu.Game.Rulesets.Pippidon.Objects.Drawables
|
|||||||
|
|
||||||
public override IEnumerable<HitSampleInfo> GetSamples() => new[]
|
public override IEnumerable<HitSampleInfo> GetSamples() => new[]
|
||||||
{
|
{
|
||||||
new HitSampleInfo(HitSampleInfo.HIT_NORMAL, SampleControlPoint.DEFAULT_BANK)
|
new HitSampleInfo(HitSampleInfo.HIT_NORMAL)
|
||||||
};
|
};
|
||||||
|
|
||||||
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
protected override void CheckForResult(bool userTriggered, double timeOffset)
|
||||||
|
@ -3,15 +3,53 @@
|
|||||||
#
|
#
|
||||||
# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects
|
# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects
|
||||||
|
|
||||||
$CSPROJ="osu.Game/osu.Game.csproj"
|
$GAME_CSPROJ="osu.Game/osu.Game.csproj"
|
||||||
|
$ANDROID_PROPS="osu.Android.props"
|
||||||
|
$IOS_PROPS="osu.iOS.props"
|
||||||
$SLN="osu.sln"
|
$SLN="osu.sln"
|
||||||
|
|
||||||
dotnet remove $CSPROJ package ppy.osu.Framework;
|
dotnet remove $GAME_CSPROJ reference ppy.osu.Framework;
|
||||||
dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj;
|
dotnet remove $ANDROID_PROPS reference ppy.osu.Framework.Android;
|
||||||
dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj
|
dotnet remove $IOS_PROPS reference ppy.osu.Framework.iOS;
|
||||||
|
|
||||||
|
dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj `
|
||||||
|
../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj `
|
||||||
|
../osu-framework/osu.Framework.Android/osu.Framework.Android.csproj `
|
||||||
|
../osu-framework/osu.Framework.iOS/osu.Framework.iOS.csproj;
|
||||||
|
|
||||||
|
dotnet add $GAME_CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj;
|
||||||
|
dotnet add $ANDROID_PROPS reference ../osu-framework/osu.Framework.Android/osu.Framework.Android.csproj;
|
||||||
|
dotnet add $IOS_PROPS reference ../osu-framework/osu.Framework.iOS/osu.Framework.iOS.csproj;
|
||||||
|
|
||||||
|
# workaround for dotnet add not inserting $(MSBuildThisFileDirectory) on props files
|
||||||
|
(Get-Content "osu.Android.props") -replace "`"..\\osu-framework", "`"`$(MSBuildThisFileDirectory)..\osu-framework" | Set-Content "osu.Android.props"
|
||||||
|
(Get-Content "osu.iOS.props") -replace "`"..\\osu-framework", "`"`$(MSBuildThisFileDirectory)..\osu-framework" | Set-Content "osu.iOS.props"
|
||||||
|
|
||||||
|
# needed because iOS framework nupkg includes a set of properties to work around certain issues during building,
|
||||||
|
# and those get ignored when referencing framework via project, threfore we have to manually include it via props reference.
|
||||||
|
(Get-Content "osu.iOS.props") |
|
||||||
|
Foreach-Object {
|
||||||
|
if ($_ -match "</Project>")
|
||||||
|
{
|
||||||
|
" <Import Project=`"`$(MSBuildThisFileDirectory)../osu-framework/osu.Framework.iOS.props`"/>"
|
||||||
|
}
|
||||||
|
|
||||||
|
$_
|
||||||
|
} | Set-Content "osu.iOS.props"
|
||||||
|
|
||||||
|
$TMP=New-TemporaryFile
|
||||||
|
|
||||||
$SLNF=Get-Content "osu.Desktop.slnf" | ConvertFrom-Json
|
$SLNF=Get-Content "osu.Desktop.slnf" | ConvertFrom-Json
|
||||||
$TMP=New-TemporaryFile
|
|
||||||
$SLNF.solution.projects += ("../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj")
|
$SLNF.solution.projects += ("../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj")
|
||||||
ConvertTo-Json $SLNF | Out-File $TMP -Encoding UTF8
|
ConvertTo-Json $SLNF | Out-File $TMP -Encoding UTF8
|
||||||
Move-Item -Path $TMP -Destination "osu.Desktop.slnf" -Force
|
Move-Item -Path $TMP -Destination "osu.Desktop.slnf" -Force
|
||||||
|
|
||||||
|
$SLNF=Get-Content "osu.Android.slnf" | ConvertFrom-Json
|
||||||
|
$SLNF.solution.projects += ("../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj", "../osu-framework/osu.Framework.Android/osu.Framework.Android.csproj")
|
||||||
|
ConvertTo-Json $SLNF | Out-File $TMP -Encoding UTF8
|
||||||
|
Move-Item -Path $TMP -Destination "osu.Android.slnf" -Force
|
||||||
|
|
||||||
|
$SLNF=Get-Content "osu.iOS.slnf" | ConvertFrom-Json
|
||||||
|
$SLNF.solution.projects += ("../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj", "../osu-framework/osu.Framework.iOS/osu.Framework.iOS.csproj")
|
||||||
|
ConvertTo-Json $SLNF | Out-File $TMP -Encoding UTF8
|
||||||
|
Move-Item -Path $TMP -Destination "osu.iOS.slnf" -Force
|
||||||
|
@ -5,14 +5,41 @@
|
|||||||
#
|
#
|
||||||
# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects
|
# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects
|
||||||
|
|
||||||
CSPROJ="osu.Game/osu.Game.csproj"
|
GAME_CSPROJ="osu.Game/osu.Game.csproj"
|
||||||
|
ANDROID_PROPS="osu.Android.props"
|
||||||
|
IOS_PROPS="osu.iOS.props"
|
||||||
SLN="osu.sln"
|
SLN="osu.sln"
|
||||||
|
|
||||||
dotnet remove $CSPROJ package ppy.osu.Framework
|
dotnet remove $GAME_CSPROJ reference ppy.osu.Framework
|
||||||
dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj
|
dotnet remove $ANDROID_PROPS reference ppy.osu.Framework.Android
|
||||||
dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj
|
dotnet remove $IOS_PROPS reference ppy.osu.Framework.iOS
|
||||||
|
|
||||||
|
dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj \
|
||||||
|
../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj \
|
||||||
|
../osu-framework/osu.Framework.Android/osu.Framework.Android.csproj \
|
||||||
|
../osu-framework/osu.Framework.iOS/osu.Framework.iOS.csproj
|
||||||
|
|
||||||
|
dotnet add $GAME_CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj
|
||||||
|
dotnet add $ANDROID_PROPS reference ../osu-framework/osu.Framework.Android/osu.Framework.Android.csproj
|
||||||
|
dotnet add $IOS_PROPS reference ../osu-framework/osu.Framework.iOS/osu.Framework.iOS.csproj
|
||||||
|
|
||||||
|
# workaround for dotnet add not inserting $(MSBuildThisFileDirectory) on props files
|
||||||
|
sed -i.bak 's:"..\\osu-framework:"$(MSBuildThisFileDirectory)..\\osu-framework:g' ./osu.Android.props && rm osu.Android.props.bak
|
||||||
|
sed -i.bak 's:"..\\osu-framework:"$(MSBuildThisFileDirectory)..\\osu-framework:g' ./osu.iOS.props && rm osu.iOS.props.bak
|
||||||
|
|
||||||
|
# needed because iOS framework nupkg includes a set of properties to work around certain issues during building,
|
||||||
|
# and those get ignored when referencing framework via project, threfore we have to manually include it via props reference.
|
||||||
|
sed -i.bak '/<\/Project>/i\
|
||||||
|
<Import Project=\"$(MSBuildThisFileDirectory)../osu-framework/osu.Framework.iOS.props\"/>\
|
||||||
|
' ./osu.iOS.props && rm osu.iOS.props.bak
|
||||||
|
|
||||||
SLNF="osu.Desktop.slnf"
|
|
||||||
tmp=$(mktemp)
|
tmp=$(mktemp)
|
||||||
|
|
||||||
jq '.solution.projects += ["../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj"]' osu.Desktop.slnf > $tmp
|
jq '.solution.projects += ["../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj"]' osu.Desktop.slnf > $tmp
|
||||||
mv -f $tmp $SLNF
|
mv -f $tmp osu.Desktop.slnf
|
||||||
|
|
||||||
|
jq '.solution.projects += ["../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj", "../osu-framework/osu.Framework.Android/osu.Framework.Android.csproj"]' osu.Android.slnf > $tmp
|
||||||
|
mv -f $tmp osu.Android.slnf
|
||||||
|
|
||||||
|
jq '.solution.projects += ["../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj", "../osu-framework/osu.Framework.iOS/osu.Framework.iOS.csproj"]' osu.iOS.slnf > $tmp
|
||||||
|
mv -f $tmp osu.iOS.slnf
|
||||||
|
26
app.manifest
26
app.manifest
@ -1,6 +1,7 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
||||||
<assemblyIdentity version="1.0.0.0" name="osu!" />
|
<assemblyIdentity version="1.0.0.0" name="osu!" />
|
||||||
|
<SquirrelAwareVersion xmlns="urn:schema-squirrel-com:asm.v1">1</SquirrelAwareVersion>
|
||||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
||||||
<security>
|
<security>
|
||||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
||||||
@ -14,33 +15,10 @@
|
|||||||
</trustInfo>
|
</trustInfo>
|
||||||
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
<compatibility xmlns="urn:schemas-microsoft-com:compatibility.v1">
|
||||||
<application>
|
<application>
|
||||||
<!-- Windows Vista -->
|
|
||||||
<supportedOS Id="{e2011457-1546-43c5-a5fe-008deee3d3f0}" />
|
|
||||||
<!-- Windows 7 -->
|
|
||||||
<supportedOS Id="{35138b9a-5d96-4fbd-8e2d-a2440225f93a}" />
|
|
||||||
<!-- Windows 8 -->
|
|
||||||
<supportedOS Id="{4a2f28e3-53b9-4441-ba9c-d69d4a4a6e38}" />
|
|
||||||
<!-- Windows 8.1 -->
|
<!-- Windows 8.1 -->
|
||||||
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
<supportedOS Id="{1f676c76-80e1-4239-95bb-83d0f6d0da78}" />
|
||||||
<!-- Windows 10 -->
|
<!-- Windows 10 and Windows 11 -->
|
||||||
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
<supportedOS Id="{8e0f7a12-bfb3-4fe8-b9a5-48fd50a15a9a}" />
|
||||||
</application>
|
</application>
|
||||||
</compatibility>
|
</compatibility>
|
||||||
<asmv3:application>
|
|
||||||
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
|
||||||
<dpiAware>true</dpiAware>
|
|
||||||
</asmv3:windowsSettings>
|
|
||||||
</asmv3:application>
|
|
||||||
<dependency>
|
|
||||||
<dependentAssembly>
|
|
||||||
<assemblyIdentity
|
|
||||||
type="win32"
|
|
||||||
name="Microsoft.Windows.Common-Controls"
|
|
||||||
version="6.0.0.0"
|
|
||||||
processorArchitecture="*"
|
|
||||||
publicKeyToken="6595b64144ccf1df"
|
|
||||||
language="*"
|
|
||||||
/>
|
|
||||||
</dependentAssembly>
|
|
||||||
</dependency>
|
|
||||||
</asmv1:assembly>
|
</asmv1:assembly>
|
||||||
|
@ -1,2 +0,0 @@
|
|||||||
app_identifier("sh.ppy.osulazer") # The bundle identifier of your app
|
|
||||||
apple_id("apple-dev@ppy.sh") # Your Apple email address
|
|
@ -1,147 +0,0 @@
|
|||||||
update_fastlane
|
|
||||||
|
|
||||||
platform :android do
|
|
||||||
desc 'Deploy to play store'
|
|
||||||
lane :beta do |options|
|
|
||||||
|
|
||||||
update_version(
|
|
||||||
version: options[:version],
|
|
||||||
build: options[:build],
|
|
||||||
)
|
|
||||||
|
|
||||||
build(options)
|
|
||||||
|
|
||||||
supply(
|
|
||||||
apk: './osu.Android/bin/Release/sh.ppy.osulazer-Signed.apk',
|
|
||||||
package_name: 'sh.ppy.osulazer',
|
|
||||||
track: 'alpha', # upload to alpha, we can promote it later
|
|
||||||
json_key: options[:json_key],
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'Deploy to github release'
|
|
||||||
lane :build_github do |options|
|
|
||||||
|
|
||||||
update_version(
|
|
||||||
version: options[:version],
|
|
||||||
build: options[:build],
|
|
||||||
)
|
|
||||||
|
|
||||||
build(options)
|
|
||||||
|
|
||||||
client = HTTPClient.new
|
|
||||||
changelog = client.get_content 'https://gist.githubusercontent.com/peppy/aaa2ec1a323554b619671cac6dbbb776/raw'
|
|
||||||
changelog.gsub!('$BUILD_ID', options[:build])
|
|
||||||
|
|
||||||
set_github_release(
|
|
||||||
repository_name: "ppy/osu",
|
|
||||||
api_token: ENV["GITHUB_TOKEN"],
|
|
||||||
name: options[:build],
|
|
||||||
tag_name: options[:build],
|
|
||||||
is_draft: true,
|
|
||||||
description: changelog,
|
|
||||||
commitish: "master",
|
|
||||||
upload_assets: ["osu.Android/bin/Release/sh.ppy.osulazer.apk"]
|
|
||||||
)
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'Compile the project'
|
|
||||||
lane :build do |options|
|
|
||||||
nuget_restore(project_path: 'osu.Android/osu.Android.csproj')
|
|
||||||
nuget_restore(project_path: 'osu.Game/osu.Game.csproj')
|
|
||||||
nuget_restore(project_path: 'osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj')
|
|
||||||
nuget_restore(project_path: 'osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj')
|
|
||||||
nuget_restore(project_path: 'osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj')
|
|
||||||
nuget_restore(project_path: 'osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj')
|
|
||||||
|
|
||||||
souyuz(
|
|
||||||
build_configuration: 'Release',
|
|
||||||
solution_path: 'osu.sln',
|
|
||||||
platform: "android",
|
|
||||||
output_path: "osu.Android/bin/Release/",
|
|
||||||
keystore_path: options[:keystore_path],
|
|
||||||
keystore_alias: options[:keystore_alias],
|
|
||||||
keystore_password: ENV["KEYSTORE_PASSWORD"]
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
lane :update_version do |options|
|
|
||||||
|
|
||||||
split = options[:build].split('.')
|
|
||||||
split[1] = split[1].to_s.rjust(4, '0')
|
|
||||||
android_build = split.join('')
|
|
||||||
|
|
||||||
app_version(
|
|
||||||
solution_path: 'osu.sln',
|
|
||||||
version: options[:version],
|
|
||||||
build: android_build,
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
end
|
|
||||||
|
|
||||||
platform :ios do
|
|
||||||
desc 'Deploy to testflight'
|
|
||||||
lane :beta do |options|
|
|
||||||
update_version(options)
|
|
||||||
|
|
||||||
provision(
|
|
||||||
type: 'appstore'
|
|
||||||
)
|
|
||||||
|
|
||||||
build(
|
|
||||||
build_configuration: 'Release',
|
|
||||||
build_platform: 'iPhone'
|
|
||||||
)
|
|
||||||
|
|
||||||
client = HTTPClient.new
|
|
||||||
changelog = client.get_content 'https://gist.githubusercontent.com/peppy/ab89c29dcc0dce95f39eb218e8fad197/raw'
|
|
||||||
changelog.gsub!('$BUILD_ID', options[:build])
|
|
||||||
|
|
||||||
pilot(
|
|
||||||
wait_processing_interval: 900,
|
|
||||||
changelog: changelog,
|
|
||||||
groups: ['osu! supporters', 'public'],
|
|
||||||
distribute_external: true,
|
|
||||||
ipa: './osu.iOS/bin/iPhone/Release/osu.iOS.ipa'
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'Compile the project'
|
|
||||||
lane :build do
|
|
||||||
nuget_restore(project_path: 'osu.iOS/osu.iOS.csproj')
|
|
||||||
nuget_restore(project_path: 'osu.Game/osu.Game.csproj')
|
|
||||||
nuget_restore(project_path: 'osu.Game.Rulesets.Osu/osu.Game.Rulesets.Osu.csproj')
|
|
||||||
nuget_restore(project_path: 'osu.Game.Rulesets.Taiko/osu.Game.Rulesets.Taiko.csproj')
|
|
||||||
nuget_restore(project_path: 'osu.Game.Rulesets.Catch/osu.Game.Rulesets.Catch.csproj')
|
|
||||||
nuget_restore(project_path: 'osu.Game.Rulesets.Mania/osu.Game.Rulesets.Mania.csproj')
|
|
||||||
|
|
||||||
souyuz(
|
|
||||||
platform: "ios",
|
|
||||||
plist_path: "osu.iOS/Info.plist"
|
|
||||||
)
|
|
||||||
end
|
|
||||||
|
|
||||||
desc 'Install provisioning profiles using match'
|
|
||||||
lane :provision do |options|
|
|
||||||
if Helper.is_ci?
|
|
||||||
options[:readonly] = true
|
|
||||||
end
|
|
||||||
|
|
||||||
match(options)
|
|
||||||
end
|
|
||||||
|
|
||||||
lane :update_version do |options|
|
|
||||||
options[:plist_path] = 'osu.iOS/Info.plist'
|
|
||||||
app_version(options)
|
|
||||||
end
|
|
||||||
|
|
||||||
lane :testflight_prune_dry do
|
|
||||||
clean_testflight_testers(days_of_inactivity:30, dry_run: true)
|
|
||||||
end
|
|
||||||
|
|
||||||
lane :testflight_prune do
|
|
||||||
clean_testflight_testers(days_of_inactivity: 30)
|
|
||||||
end
|
|
||||||
end
|
|
@ -1 +0,0 @@
|
|||||||
git_url('https://github.com/peppy/apple-certificates')
|
|
@ -1,7 +0,0 @@
|
|||||||
# Autogenerated by fastlane
|
|
||||||
#
|
|
||||||
# Ensure this file is checked in to source control!
|
|
||||||
|
|
||||||
gem 'fastlane-plugin-clean_testflight_testers'
|
|
||||||
gem 'fastlane-plugin-souyuz'
|
|
||||||
gem 'fastlane-plugin-xamarin'
|
|
@ -1,109 +0,0 @@
|
|||||||
fastlane documentation
|
|
||||||
----
|
|
||||||
|
|
||||||
# Installation
|
|
||||||
|
|
||||||
Make sure you have the latest version of the Xcode command line tools installed:
|
|
||||||
|
|
||||||
```sh
|
|
||||||
xcode-select --install
|
|
||||||
```
|
|
||||||
|
|
||||||
For _fastlane_ installation instructions, see [Installing _fastlane_](https://docs.fastlane.tools/#installing-fastlane)
|
|
||||||
|
|
||||||
# Available Actions
|
|
||||||
|
|
||||||
## Android
|
|
||||||
|
|
||||||
### android beta
|
|
||||||
|
|
||||||
```sh
|
|
||||||
[bundle exec] fastlane android beta
|
|
||||||
```
|
|
||||||
|
|
||||||
Deploy to play store
|
|
||||||
|
|
||||||
### android build_github
|
|
||||||
|
|
||||||
```sh
|
|
||||||
[bundle exec] fastlane android build_github
|
|
||||||
```
|
|
||||||
|
|
||||||
Deploy to github release
|
|
||||||
|
|
||||||
### android build
|
|
||||||
|
|
||||||
```sh
|
|
||||||
[bundle exec] fastlane android build
|
|
||||||
```
|
|
||||||
|
|
||||||
Compile the project
|
|
||||||
|
|
||||||
### android update_version
|
|
||||||
|
|
||||||
```sh
|
|
||||||
[bundle exec] fastlane android update_version
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
|
|
||||||
## iOS
|
|
||||||
|
|
||||||
### ios beta
|
|
||||||
|
|
||||||
```sh
|
|
||||||
[bundle exec] fastlane ios beta
|
|
||||||
```
|
|
||||||
|
|
||||||
Deploy to testflight
|
|
||||||
|
|
||||||
### ios build
|
|
||||||
|
|
||||||
```sh
|
|
||||||
[bundle exec] fastlane ios build
|
|
||||||
```
|
|
||||||
|
|
||||||
Compile the project
|
|
||||||
|
|
||||||
### ios provision
|
|
||||||
|
|
||||||
```sh
|
|
||||||
[bundle exec] fastlane ios provision
|
|
||||||
```
|
|
||||||
|
|
||||||
Install provisioning profiles using match
|
|
||||||
|
|
||||||
### ios update_version
|
|
||||||
|
|
||||||
```sh
|
|
||||||
[bundle exec] fastlane ios update_version
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### ios testflight_prune_dry
|
|
||||||
|
|
||||||
```sh
|
|
||||||
[bundle exec] fastlane ios testflight_prune_dry
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
### ios testflight_prune
|
|
||||||
|
|
||||||
```sh
|
|
||||||
[bundle exec] fastlane ios testflight_prune
|
|
||||||
```
|
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
----
|
|
||||||
|
|
||||||
This README.md is auto-generated and will be re-generated every time [_fastlane_](https://fastlane.tools) is run.
|
|
||||||
|
|
||||||
More information about _fastlane_ can be found on [fastlane.tools](https://fastlane.tools).
|
|
||||||
|
|
||||||
The documentation of _fastlane_ can be found on [docs.fastlane.tools](https://docs.fastlane.tools).
|
|
7
global.json
Normal file
7
global.json
Normal file
@ -0,0 +1,7 @@
|
|||||||
|
{
|
||||||
|
"sdk": {
|
||||||
|
"version": "6.0.100",
|
||||||
|
"rollForward": "latestFeature"
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -10,7 +10,7 @@
|
|||||||
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
<EmbedAssembliesIntoApk>true</EmbedAssembliesIntoApk>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.131.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2023.914.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
<!-- Fody does not handle Android build well, and warns when unchanged.
|
<!-- Fody does not handle Android build well, and warns when unchanged.
|
||||||
|
63
osu.Android/AndroidImportTask.cs
Normal file
63
osu.Android/AndroidImportTask.cs
Normal file
@ -0,0 +1,63 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.IO;
|
||||||
|
using System.Threading.Tasks;
|
||||||
|
using Android.Content;
|
||||||
|
using Android.Net;
|
||||||
|
using Android.Provider;
|
||||||
|
using osu.Game.Database;
|
||||||
|
|
||||||
|
namespace osu.Android
|
||||||
|
{
|
||||||
|
public class AndroidImportTask : ImportTask
|
||||||
|
{
|
||||||
|
private readonly ContentResolver contentResolver;
|
||||||
|
|
||||||
|
private readonly Uri uri;
|
||||||
|
|
||||||
|
private AndroidImportTask(Stream stream, string filename, ContentResolver contentResolver, Uri uri)
|
||||||
|
: base(stream, filename)
|
||||||
|
{
|
||||||
|
this.contentResolver = contentResolver;
|
||||||
|
this.uri = uri;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void DeleteFile()
|
||||||
|
{
|
||||||
|
contentResolver.Delete(uri, null, null);
|
||||||
|
}
|
||||||
|
|
||||||
|
public static async Task<AndroidImportTask?> Create(ContentResolver contentResolver, Uri uri)
|
||||||
|
{
|
||||||
|
// there are more performant overloads of this method, but this one is the most backwards-compatible
|
||||||
|
// (dates back to API 1).
|
||||||
|
|
||||||
|
var cursor = contentResolver.Query(uri, null, null, null, null);
|
||||||
|
|
||||||
|
if (cursor == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
if (!cursor.MoveToFirst())
|
||||||
|
return null;
|
||||||
|
|
||||||
|
int filenameColumn = cursor.GetColumnIndex(IOpenableColumns.DisplayName);
|
||||||
|
string filename = cursor.GetString(filenameColumn) ?? uri.Path ?? string.Empty;
|
||||||
|
|
||||||
|
// SharpCompress requires archive streams to be seekable, which the stream opened by
|
||||||
|
// OpenInputStream() seems to not necessarily be.
|
||||||
|
// copy to an arbitrary-access memory stream to be able to proceed with the import.
|
||||||
|
var copy = new MemoryStream();
|
||||||
|
|
||||||
|
using (var stream = contentResolver.OpenInputStream(uri))
|
||||||
|
{
|
||||||
|
if (stream == null)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
await stream.CopyToAsync(copy).ConfigureAwait(false);
|
||||||
|
}
|
||||||
|
|
||||||
|
return new AndroidImportTask(copy, filename, contentResolver, uri);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -1,5 +1,8 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="sh.ppy.osulazer" android:installLocation="auto">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" package="sh.ppy.osulazer" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
|
||||||
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!" android:icon="@drawable/lazer" />
|
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!" android:icon="@drawable/lazer" />
|
||||||
|
<!-- for editor usage -->
|
||||||
|
<uses-permission android:name="android.permission.READ_MEDIA_IMAGES" />
|
||||||
|
<uses-permission android:name="android.permission.READ_MEDIA_AUDIO" />
|
||||||
</manifest>
|
</manifest>
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -13,10 +11,10 @@ namespace osu.Android
|
|||||||
{
|
{
|
||||||
public partial class GameplayScreenRotationLocker : Component
|
public partial class GameplayScreenRotationLocker : Component
|
||||||
{
|
{
|
||||||
private Bindable<bool> localUserPlaying;
|
private Bindable<bool> localUserPlaying = null!;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuGameActivity gameActivity { get; set; }
|
private OsuGameActivity gameActivity { get; set; } = null!;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuGame game)
|
private void load(OsuGame game)
|
||||||
|
@ -1,11 +1,8 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.IO;
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
@ -14,9 +11,9 @@ using Android.Content;
|
|||||||
using Android.Content.PM;
|
using Android.Content.PM;
|
||||||
using Android.Graphics;
|
using Android.Graphics;
|
||||||
using Android.OS;
|
using Android.OS;
|
||||||
using Android.Provider;
|
|
||||||
using Android.Views;
|
using Android.Views;
|
||||||
using osu.Framework.Android;
|
using osu.Framework.Android;
|
||||||
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
using Debug = System.Diagnostics.Debug;
|
using Debug = System.Diagnostics.Debug;
|
||||||
using Uri = Android.Net.Uri;
|
using Uri = Android.Net.Uri;
|
||||||
@ -53,11 +50,11 @@ namespace osu.Android
|
|||||||
/// <remarks>Adjusted on startup to match expected UX for the current device type (phone/tablet).</remarks>
|
/// <remarks>Adjusted on startup to match expected UX for the current device type (phone/tablet).</remarks>
|
||||||
public ScreenOrientation DefaultOrientation = ScreenOrientation.Unspecified;
|
public ScreenOrientation DefaultOrientation = ScreenOrientation.Unspecified;
|
||||||
|
|
||||||
private OsuGameAndroid game;
|
private OsuGameAndroid game = null!;
|
||||||
|
|
||||||
protected override Framework.Game CreateGame() => game = new OsuGameAndroid(this);
|
protected override Framework.Game CreateGame() => game = new OsuGameAndroid(this);
|
||||||
|
|
||||||
protected override void OnCreate(Bundle savedInstanceState)
|
protected override void OnCreate(Bundle? savedInstanceState)
|
||||||
{
|
{
|
||||||
base.OnCreate(savedInstanceState);
|
base.OnCreate(savedInstanceState);
|
||||||
|
|
||||||
@ -94,15 +91,15 @@ namespace osu.Android
|
|||||||
Assembly.Load("osu.Game.Rulesets.Mania");
|
Assembly.Load("osu.Game.Rulesets.Mania");
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void OnNewIntent(Intent intent) => handleIntent(intent);
|
protected override void OnNewIntent(Intent? intent) => handleIntent(intent);
|
||||||
|
|
||||||
private void handleIntent(Intent intent)
|
private void handleIntent(Intent? intent)
|
||||||
{
|
{
|
||||||
switch (intent.Action)
|
switch (intent?.Action)
|
||||||
{
|
{
|
||||||
case Intent.ActionDefault:
|
case Intent.ActionDefault:
|
||||||
if (intent.Scheme == ContentResolver.SchemeContent)
|
if (intent.Scheme == ContentResolver.SchemeContent)
|
||||||
handleImportFromUris(intent.Data);
|
handleImportFromUris(intent.Data.AsNonNull());
|
||||||
else if (osu_url_schemes.Contains(intent.Scheme))
|
else if (osu_url_schemes.Contains(intent.Scheme))
|
||||||
game.HandleLink(intent.DataString);
|
game.HandleLink(intent.DataString);
|
||||||
break;
|
break;
|
||||||
@ -116,7 +113,7 @@ namespace osu.Android
|
|||||||
{
|
{
|
||||||
var content = intent.ClipData?.GetItemAt(i);
|
var content = intent.ClipData?.GetItemAt(i);
|
||||||
if (content != null)
|
if (content != null)
|
||||||
uris.Add(content.Uri);
|
uris.Add(content.Uri.AsNonNull());
|
||||||
}
|
}
|
||||||
|
|
||||||
handleImportFromUris(uris.ToArray());
|
handleImportFromUris(uris.ToArray());
|
||||||
@ -131,28 +128,14 @@ namespace osu.Android
|
|||||||
|
|
||||||
await Task.WhenAll(uris.Select(async uri =>
|
await Task.WhenAll(uris.Select(async uri =>
|
||||||
{
|
{
|
||||||
// there are more performant overloads of this method, but this one is the most backwards-compatible
|
var task = await AndroidImportTask.Create(ContentResolver!, uri).ConfigureAwait(false);
|
||||||
// (dates back to API 1).
|
|
||||||
var cursor = ContentResolver?.Query(uri, null, null, null, null);
|
|
||||||
|
|
||||||
if (cursor == null)
|
if (task != null)
|
||||||
return;
|
|
||||||
|
|
||||||
cursor.MoveToFirst();
|
|
||||||
|
|
||||||
int filenameColumn = cursor.GetColumnIndex(IOpenableColumns.DisplayName);
|
|
||||||
string filename = cursor.GetString(filenameColumn);
|
|
||||||
|
|
||||||
// SharpCompress requires archive streams to be seekable, which the stream opened by
|
|
||||||
// OpenInputStream() seems to not necessarily be.
|
|
||||||
// copy to an arbitrary-access memory stream to be able to proceed with the import.
|
|
||||||
var copy = new MemoryStream();
|
|
||||||
using (var stream = ContentResolver.OpenInputStream(uri))
|
|
||||||
await stream.CopyToAsync(copy).ConfigureAwait(false);
|
|
||||||
|
|
||||||
lock (tasks)
|
|
||||||
{
|
{
|
||||||
tasks.Add(new ImportTask(copy, filename));
|
lock (tasks)
|
||||||
|
{
|
||||||
|
tasks.Add(task);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
})).ConfigureAwait(false);
|
})).ConfigureAwait(false);
|
||||||
|
|
||||||
|
@ -1,13 +1,12 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using Microsoft.Maui.Devices;
|
using Microsoft.Maui.Devices;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Android.Input;
|
using osu.Framework.Android.Input;
|
||||||
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
using osu.Framework.Input.Handlers;
|
using osu.Framework.Input.Handlers;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game;
|
using osu.Game;
|
||||||
@ -32,7 +31,7 @@ namespace osu.Android
|
|||||||
{
|
{
|
||||||
get
|
get
|
||||||
{
|
{
|
||||||
var packageInfo = Application.Context.ApplicationContext.PackageManager.GetPackageInfo(Application.Context.ApplicationContext.PackageName, 0);
|
var packageInfo = Application.Context.ApplicationContext!.PackageManager!.GetPackageInfo(Application.Context.ApplicationContext.PackageName!, 0).AsNonNull();
|
||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
@ -45,7 +44,7 @@ namespace osu.Android
|
|||||||
// Basic conversion format (as done in Fastfile): 2020.606.0 -> 202006060
|
// Basic conversion format (as done in Fastfile): 2020.606.0 -> 202006060
|
||||||
|
|
||||||
// https://stackoverflow.com/questions/52977079/android-sdk-28-versioncode-in-packageinfo-has-been-deprecated
|
// https://stackoverflow.com/questions/52977079/android-sdk-28-versioncode-in-packageinfo-has-been-deprecated
|
||||||
string versionName = string.Empty;
|
string versionName;
|
||||||
|
|
||||||
if (OperatingSystem.IsAndroidVersionAtLeast(28))
|
if (OperatingSystem.IsAndroidVersionAtLeast(28))
|
||||||
{
|
{
|
||||||
@ -68,7 +67,7 @@ namespace osu.Android
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
return new Version(packageInfo.VersionName);
|
return new Version(packageInfo.VersionName.AsNonNull());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using Android;
|
using Android;
|
||||||
using Android.App;
|
using Android.App;
|
||||||
|
|
||||||
|
@ -54,9 +54,6 @@ namespace osu.Desktop
|
|||||||
|
|
||||||
client.OnReady += onReady;
|
client.OnReady += onReady;
|
||||||
|
|
||||||
// safety measure for now, until we performance test / improve backoff for failed connections.
|
|
||||||
client.OnConnectionFailed += (_, _) => client.Deinitialize();
|
|
||||||
|
|
||||||
client.OnError += (_, e) => Logger.Log($"An error occurred with Discord RPC Client: {e.Code} {e.Message}", LoggingTarget.Network);
|
client.OnError += (_, e) => Logger.Log($"An error occurred with Discord RPC Client: {e.Code} {e.Message}", LoggingTarget.Network);
|
||||||
|
|
||||||
config.BindWith(OsuSetting.DiscordRichPresence, privacyMode);
|
config.BindWith(OsuSetting.DiscordRichPresence, privacyMode);
|
||||||
@ -98,7 +95,7 @@ namespace osu.Desktop
|
|||||||
|
|
||||||
if (status.Value is UserStatusOnline && activity.Value != null)
|
if (status.Value is UserStatusOnline && activity.Value != null)
|
||||||
{
|
{
|
||||||
presence.State = truncate(activity.Value.Status);
|
presence.State = truncate(activity.Value.GetStatus(privacyMode.Value == DiscordRichPresenceMode.Limited));
|
||||||
presence.Details = truncate(getDetails(activity.Value));
|
presence.Details = truncate(getDetails(activity.Value));
|
||||||
|
|
||||||
if (getBeatmap(activity.Value) is IBeatmapInfo beatmap && beatmap.OnlineID > 0)
|
if (getBeatmap(activity.Value) is IBeatmapInfo beatmap && beatmap.OnlineID > 0)
|
||||||
@ -169,7 +166,7 @@ namespace osu.Desktop
|
|||||||
case UserActivity.InGame game:
|
case UserActivity.InGame game:
|
||||||
return game.BeatmapInfo;
|
return game.BeatmapInfo;
|
||||||
|
|
||||||
case UserActivity.Editing edit:
|
case UserActivity.EditingBeatmap edit:
|
||||||
return edit.BeatmapInfo;
|
return edit.BeatmapInfo;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,9 +180,12 @@ namespace osu.Desktop
|
|||||||
case UserActivity.InGame game:
|
case UserActivity.InGame game:
|
||||||
return game.BeatmapInfo.ToString() ?? string.Empty;
|
return game.BeatmapInfo.ToString() ?? string.Empty;
|
||||||
|
|
||||||
case UserActivity.Editing edit:
|
case UserActivity.EditingBeatmap edit:
|
||||||
return edit.BeatmapInfo.ToString() ?? string.Empty;
|
return edit.BeatmapInfo.ToString() ?? string.Empty;
|
||||||
|
|
||||||
|
case UserActivity.WatchingReplay watching:
|
||||||
|
return watching.BeatmapInfo?.ToString() ?? string.Empty;
|
||||||
|
|
||||||
case UserActivity.InLobby lobby:
|
case UserActivity.InLobby lobby:
|
||||||
return privacyMode.Value == DiscordRichPresenceMode.Limited ? string.Empty : lobby.Room.Name.Value;
|
return privacyMode.Value == DiscordRichPresenceMode.Limited ? string.Empty : lobby.Room.Name.Value;
|
||||||
}
|
}
|
||||||
|
@ -75,7 +75,7 @@ namespace osu.Desktop.LegacyIpc
|
|||||||
case LegacyIpcDifficultyCalculationRequest req:
|
case LegacyIpcDifficultyCalculationRequest req:
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WorkingBeatmap beatmap = new FlatFileWorkingBeatmap(req.BeatmapFile);
|
WorkingBeatmap beatmap = new FlatWorkingBeatmap(req.BeatmapFile);
|
||||||
var ruleset = beatmap.BeatmapInfo.Ruleset.CreateInstance();
|
var ruleset = beatmap.BeatmapInfo.Ruleset.CreateInstance();
|
||||||
Mod[] mods = ruleset.ConvertFromLegacyMods((LegacyMods)req.Mods).ToArray();
|
Mod[] mods = ruleset.ConvertFromLegacyMods((LegacyMods)req.Mods).ToArray();
|
||||||
|
|
||||||
|
@ -2,13 +2,10 @@
|
|||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
|
||||||
using System.Reflection;
|
using System.Reflection;
|
||||||
using System.Runtime.Versioning;
|
using System.Runtime.Versioning;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using Microsoft.Win32;
|
using Microsoft.Win32;
|
||||||
using osu.Desktop.Security;
|
using osu.Desktop.Security;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
@ -18,9 +15,9 @@ using osu.Framework;
|
|||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Updater;
|
using osu.Game.Updater;
|
||||||
using osu.Desktop.Windows;
|
using osu.Desktop.Windows;
|
||||||
using osu.Framework.Threading;
|
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
using osu.Game.IPC;
|
using osu.Game.IPC;
|
||||||
|
using osu.Game.Online.Multiplayer;
|
||||||
using osu.Game.Utils;
|
using osu.Game.Utils;
|
||||||
using SDL2;
|
using SDL2;
|
||||||
|
|
||||||
@ -29,6 +26,7 @@ namespace osu.Desktop
|
|||||||
internal partial class OsuGameDesktop : OsuGame
|
internal partial class OsuGameDesktop : OsuGame
|
||||||
{
|
{
|
||||||
private OsuSchemeLinkIPCChannel? osuSchemeLinkIPCChannel;
|
private OsuSchemeLinkIPCChannel? osuSchemeLinkIPCChannel;
|
||||||
|
private ArchiveImportIPCChannel? archiveImportIPCChannel;
|
||||||
|
|
||||||
public OsuGameDesktop(string[]? args = null)
|
public OsuGameDesktop(string[]? args = null)
|
||||||
: base(args)
|
: base(args)
|
||||||
@ -111,6 +109,25 @@ namespace osu.Desktop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool RestartAppWhenExited()
|
||||||
|
{
|
||||||
|
switch (RuntimeInfo.OS)
|
||||||
|
{
|
||||||
|
case RuntimeInfo.Platform.Windows:
|
||||||
|
Debug.Assert(OperatingSystem.IsWindows());
|
||||||
|
|
||||||
|
// Of note, this is an async method in squirrel that adds an arbitrary delay before returning
|
||||||
|
// likely to ensure the external process is in a good state.
|
||||||
|
//
|
||||||
|
// We're not waiting on that here, but the outro playing before the actual exit should be enough
|
||||||
|
// to cover this.
|
||||||
|
Squirrel.UpdateManager.RestartAppWhenExited().FireAndForget();
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
return base.RestartAppWhenExited();
|
||||||
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
@ -123,64 +140,28 @@ namespace osu.Desktop
|
|||||||
LoadComponentAsync(new ElevatedPrivilegesChecker(), Add);
|
LoadComponentAsync(new ElevatedPrivilegesChecker(), Add);
|
||||||
|
|
||||||
osuSchemeLinkIPCChannel = new OsuSchemeLinkIPCChannel(Host, this);
|
osuSchemeLinkIPCChannel = new OsuSchemeLinkIPCChannel(Host, this);
|
||||||
|
archiveImportIPCChannel = new ArchiveImportIPCChannel(Host, this);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void SetHost(GameHost host)
|
public override void SetHost(GameHost host)
|
||||||
{
|
{
|
||||||
base.SetHost(host);
|
base.SetHost(host);
|
||||||
|
|
||||||
var desktopWindow = (SDL2DesktopWindow)host.Window;
|
|
||||||
|
|
||||||
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
|
var iconStream = Assembly.GetExecutingAssembly().GetManifestResourceStream(GetType(), "lazer.ico");
|
||||||
if (iconStream != null)
|
if (iconStream != null)
|
||||||
desktopWindow.SetIconFromStream(iconStream);
|
host.Window.SetIconFromStream(iconStream);
|
||||||
|
|
||||||
desktopWindow.CursorState |= CursorState.Hidden;
|
host.Window.CursorState |= CursorState.Hidden;
|
||||||
desktopWindow.Title = Name;
|
host.Window.Title = Name;
|
||||||
desktopWindow.DragDrop += f => fileDrop(new[] { f });
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override BatteryInfo CreateBatteryInfo() => new SDL2BatteryInfo();
|
protected override BatteryInfo CreateBatteryInfo() => new SDL2BatteryInfo();
|
||||||
|
|
||||||
private readonly List<string> importableFiles = new List<string>();
|
|
||||||
private ScheduledDelegate? importSchedule;
|
|
||||||
|
|
||||||
private void fileDrop(string[] filePaths)
|
|
||||||
{
|
|
||||||
lock (importableFiles)
|
|
||||||
{
|
|
||||||
string firstExtension = Path.GetExtension(filePaths.First());
|
|
||||||
|
|
||||||
if (filePaths.Any(f => Path.GetExtension(f) != firstExtension)) return;
|
|
||||||
|
|
||||||
importableFiles.AddRange(filePaths);
|
|
||||||
|
|
||||||
Logger.Log($"Adding {filePaths.Length} files for import");
|
|
||||||
|
|
||||||
// File drag drop operations can potentially trigger hundreds or thousands of these calls on some platforms.
|
|
||||||
// In order to avoid spawning multiple import tasks for a single drop operation, debounce a touch.
|
|
||||||
importSchedule?.Cancel();
|
|
||||||
importSchedule = Scheduler.AddDelayed(handlePendingImports, 100);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private void handlePendingImports()
|
|
||||||
{
|
|
||||||
lock (importableFiles)
|
|
||||||
{
|
|
||||||
Logger.Log($"Handling batch import of {importableFiles.Count} files");
|
|
||||||
|
|
||||||
string[] paths = importableFiles.ToArray();
|
|
||||||
importableFiles.Clear();
|
|
||||||
|
|
||||||
Task.Factory.StartNew(() => Import(paths), TaskCreationOptions.LongRunning);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
{
|
{
|
||||||
base.Dispose(isDisposing);
|
base.Dispose(isDisposing);
|
||||||
osuSchemeLinkIPCChannel?.Dispose();
|
osuSchemeLinkIPCChannel?.Dispose();
|
||||||
|
archiveImportIPCChannel?.Dispose();
|
||||||
}
|
}
|
||||||
|
|
||||||
private class SDL2BatteryInfo : BatteryInfo
|
private class SDL2BatteryInfo : BatteryInfo
|
||||||
|
@ -85,7 +85,7 @@ namespace osu.Desktop
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
using (DesktopGameHost host = Host.GetSuitableDesktopHost(gameName, new HostOptions { BindIPC = true }))
|
using (DesktopGameHost host = Host.GetSuitableDesktopHost(gameName, new HostOptions { BindIPC = !tournamentClient }))
|
||||||
{
|
{
|
||||||
if (!host.IsPrimaryInstance)
|
if (!host.IsPrimaryInstance)
|
||||||
{
|
{
|
||||||
|
@ -9,6 +9,7 @@ using osu.Framework.Logging;
|
|||||||
using osu.Game;
|
using osu.Game;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Notifications;
|
using osu.Game.Overlays.Notifications;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
using Squirrel;
|
using Squirrel;
|
||||||
using Squirrel.SimpleSplat;
|
using Squirrel.SimpleSplat;
|
||||||
using LogLevel = Squirrel.SimpleSplat.LogLevel;
|
using LogLevel = Squirrel.SimpleSplat.LogLevel;
|
||||||
@ -36,6 +37,9 @@ namespace osu.Desktop.Updater
|
|||||||
[Resolved]
|
[Resolved]
|
||||||
private OsuGameBase game { get; set; } = null!;
|
private OsuGameBase game { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private ILocalUserPlayInfo? localUserInfo { get; set; }
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(INotificationOverlay notifications)
|
private void load(INotificationOverlay notifications)
|
||||||
{
|
{
|
||||||
@ -55,6 +59,10 @@ namespace osu.Desktop.Updater
|
|||||||
|
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
// Avoid any kind of update checking while gameplay is running.
|
||||||
|
if (localUserInfo?.IsPlaying.Value == true)
|
||||||
|
return false;
|
||||||
|
|
||||||
updateManager ??= new GithubUpdateManager(@"https://github.com/ppy/osu", false, github_token, @"osulazer");
|
updateManager ??= new GithubUpdateManager(@"https://github.com/ppy/osu", false, github_token, @"osulazer");
|
||||||
|
|
||||||
var info = await updateManager.CheckForUpdate(!useDeltaPatching).ConfigureAwait(false);
|
var info = await updateManager.CheckForUpdate(!useDeltaPatching).ConfigureAwait(false);
|
||||||
|
@ -1,21 +0,0 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
|
||||||
<asmv1:assembly manifestVersion="1.0" xmlns="urn:schemas-microsoft-com:asm.v1" xmlns:asmv1="urn:schemas-microsoft-com:asm.v1" xmlns:asmv2="urn:schemas-microsoft-com:asm.v2" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance" xmlns:asmv3="urn:schemas-microsoft-com:asm.v3">
|
|
||||||
<assemblyIdentity version="1.0.0.0" name="osu!" />
|
|
||||||
<SquirrelAwareVersion xmlns="urn:schema-squirrel-com:asm.v1">1</SquirrelAwareVersion>
|
|
||||||
<trustInfo xmlns="urn:schemas-microsoft-com:asm.v2">
|
|
||||||
<security>
|
|
||||||
<requestedPrivileges xmlns="urn:schemas-microsoft-com:asm.v3">
|
|
||||||
<requestedExecutionLevel level="asInvoker" uiAccess="false" />
|
|
||||||
</requestedPrivileges>
|
|
||||||
<applicationRequestMinimum>
|
|
||||||
<defaultAssemblyRequest permissionSetReference="Custom" />
|
|
||||||
<PermissionSet class="System.Security.PermissionSet" version="1" Unrestricted="true" ID="Custom" SameSite="site" />
|
|
||||||
</applicationRequestMinimum>
|
|
||||||
</security>
|
|
||||||
</trustInfo>
|
|
||||||
<asmv3:application>
|
|
||||||
<asmv3:windowsSettings xmlns="http://schemas.microsoft.com/SMI/2005/WindowsSettings">
|
|
||||||
<dpiAware>true</dpiAware>
|
|
||||||
</asmv3:windowsSettings>
|
|
||||||
</asmv3:application>
|
|
||||||
</asmv1:assembly>
|
|
@ -8,7 +8,6 @@
|
|||||||
<Title>osu!</Title>
|
<Title>osu!</Title>
|
||||||
<Product>osu!(lazer)</Product>
|
<Product>osu!(lazer)</Product>
|
||||||
<ApplicationIcon>lazer.ico</ApplicationIcon>
|
<ApplicationIcon>lazer.ico</ApplicationIcon>
|
||||||
<ApplicationManifest>app.manifest</ApplicationManifest>
|
|
||||||
<Version>0.0.0</Version>
|
<Version>0.0.0</Version>
|
||||||
<FileVersion>0.0.0</FileVersion>
|
<FileVersion>0.0.0</FileVersion>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
@ -26,8 +25,8 @@
|
|||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Clowd.Squirrel" Version="2.9.42" />
|
<PackageReference Include="Clowd.Squirrel" Version="2.9.42" />
|
||||||
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
<PackageReference Include="Mono.Posix.NETStandard" Version="1.0.0" />
|
||||||
<PackageReference Include="System.IO.Packaging" Version="6.0.0" />
|
<PackageReference Include="System.IO.Packaging" Version="7.0.0" />
|
||||||
<PackageReference Include="DiscordRichPresence" Version="1.1.1.14" />
|
<PackageReference Include="DiscordRichPresence" Version="1.1.4.20" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Resources">
|
<ItemGroup Label="Resources">
|
||||||
<EmbeddedResource Include="lazer.ico" />
|
<EmbeddedResource Include="lazer.ico" />
|
||||||
|
123
osu.Game.Benchmarks/BenchmarkCarouselFilter.cs
Normal file
123
osu.Game.Benchmarks/BenchmarkCarouselFilter.cs
Normal file
@ -0,0 +1,123 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using BenchmarkDotNet.Attributes;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Screens.Select;
|
||||||
|
using osu.Game.Screens.Select.Carousel;
|
||||||
|
|
||||||
|
namespace osu.Game.Benchmarks
|
||||||
|
{
|
||||||
|
public class BenchmarkCarouselFilter : BenchmarkTest
|
||||||
|
{
|
||||||
|
private BeatmapInfo getExampleBeatmap() => new BeatmapInfo
|
||||||
|
{
|
||||||
|
Ruleset = new RulesetInfo
|
||||||
|
{
|
||||||
|
ShortName = "osu",
|
||||||
|
OnlineID = 0
|
||||||
|
},
|
||||||
|
StarRating = 4.0d,
|
||||||
|
Difficulty = new BeatmapDifficulty
|
||||||
|
{
|
||||||
|
ApproachRate = 5.0f,
|
||||||
|
DrainRate = 3.0f,
|
||||||
|
CircleSize = 2.0f,
|
||||||
|
},
|
||||||
|
Metadata = new BeatmapMetadata
|
||||||
|
{
|
||||||
|
Artist = "The Artist",
|
||||||
|
ArtistUnicode = "check unicode too",
|
||||||
|
Title = "Title goes here",
|
||||||
|
TitleUnicode = "Title goes here",
|
||||||
|
Author = { Username = "The Author" },
|
||||||
|
Source = "unit tests",
|
||||||
|
Tags = "look for tags too",
|
||||||
|
},
|
||||||
|
DifficultyName = "version as well",
|
||||||
|
Length = 2500,
|
||||||
|
BPM = 160,
|
||||||
|
BeatDivisor = 12,
|
||||||
|
Status = BeatmapOnlineStatus.Loved
|
||||||
|
};
|
||||||
|
|
||||||
|
private CarouselBeatmap carouselBeatmap = null!;
|
||||||
|
private FilterCriteria criteria1 = null!;
|
||||||
|
private FilterCriteria criteria2 = null!;
|
||||||
|
private FilterCriteria criteria3 = null!;
|
||||||
|
private FilterCriteria criteria4 = null!;
|
||||||
|
private FilterCriteria criteria5 = null!;
|
||||||
|
private FilterCriteria criteria6 = null!;
|
||||||
|
|
||||||
|
public override void SetUp()
|
||||||
|
{
|
||||||
|
var beatmap = getExampleBeatmap();
|
||||||
|
beatmap.OnlineID = 20201010;
|
||||||
|
beatmap.BeatmapSet = new BeatmapSetInfo { OnlineID = 1535 };
|
||||||
|
carouselBeatmap = new CarouselBeatmap(beatmap);
|
||||||
|
criteria1 = new FilterCriteria();
|
||||||
|
criteria2 = new FilterCriteria
|
||||||
|
{
|
||||||
|
Ruleset = new RulesetInfo { ShortName = "catch" }
|
||||||
|
};
|
||||||
|
criteria3 = new FilterCriteria
|
||||||
|
{
|
||||||
|
Ruleset = new RulesetInfo { OnlineID = 6 },
|
||||||
|
AllowConvertedBeatmaps = true,
|
||||||
|
BPM = new FilterCriteria.OptionalRange<double>
|
||||||
|
{
|
||||||
|
IsUpperInclusive = false,
|
||||||
|
Max = 160d
|
||||||
|
}
|
||||||
|
};
|
||||||
|
criteria4 = new FilterCriteria
|
||||||
|
{
|
||||||
|
Ruleset = new RulesetInfo { OnlineID = 6 },
|
||||||
|
AllowConvertedBeatmaps = true,
|
||||||
|
SearchText = "an artist"
|
||||||
|
};
|
||||||
|
criteria5 = new FilterCriteria
|
||||||
|
{
|
||||||
|
Creator = new FilterCriteria.OptionalTextFilter { SearchTerm = "the author AND then something else" }
|
||||||
|
};
|
||||||
|
criteria6 = new FilterCriteria { SearchText = "20201010" };
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void CarouselBeatmapFilter()
|
||||||
|
{
|
||||||
|
carouselBeatmap.Filter(criteria1);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void CriteriaMatchingSpecificRuleset()
|
||||||
|
{
|
||||||
|
carouselBeatmap.Filter(criteria2);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void CriteriaMatchingRangeMax()
|
||||||
|
{
|
||||||
|
carouselBeatmap.Filter(criteria3);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void CriteriaMatchingTerms()
|
||||||
|
{
|
||||||
|
carouselBeatmap.Filter(criteria4);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void CriteriaMatchingCreator()
|
||||||
|
{
|
||||||
|
carouselBeatmap.Filter(criteria5);
|
||||||
|
}
|
||||||
|
|
||||||
|
[Benchmark]
|
||||||
|
public void CriteriaMatchingBeatmapIDs()
|
||||||
|
{
|
||||||
|
carouselBeatmap.Filter(criteria6);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,9 +7,9 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="BenchmarkDotNet" Version="0.13.2" />
|
<PackageReference Include="BenchmarkDotNet" Version="0.13.4" />
|
||||||
<PackageReference Include="nunit" Version="3.13.3" />
|
<PackageReference Include="nunit" Version="3.13.3" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
|
@ -1,6 +1,6 @@
|
|||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<!-- using a different name because package name cannot contain 'catch' -->
|
<!-- using a different name because package name cannot contain 'catch' -->
|
||||||
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Catch_Tests.Android" android:installLocation="auto">
|
<manifest xmlns:android="http://schemas.android.com/apk/res/android" android:versionCode="1" android:versionName="1.0" package="osu.Game.Rulesets.Catch_Tests.Android" android:installLocation="auto">
|
||||||
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="31" />
|
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="33" />
|
||||||
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!catch Test" />
|
<application android:allowBackup="true" android:supportsRtl="true" android:label="osu!catch Test" />
|
||||||
</manifest>
|
</manifest>
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using Android.App;
|
using Android.App;
|
||||||
using osu.Framework.Android;
|
using osu.Framework.Android;
|
||||||
using osu.Game.Tests;
|
using osu.Game.Tests;
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using Foundation;
|
|
||||||
using osu.Framework.iOS;
|
|
||||||
using osu.Game.Tests;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests.iOS
|
|
||||||
{
|
|
||||||
[Register("AppDelegate")]
|
|
||||||
public class AppDelegate : GameAppDelegate
|
|
||||||
{
|
|
||||||
protected override Framework.Game CreateGame() => new OsuTestBrowser();
|
|
||||||
}
|
|
||||||
}
|
|
@ -1,9 +1,8 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
using osu.Framework.iOS;
|
||||||
|
using osu.Game.Tests;
|
||||||
using UIKit;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests.iOS
|
namespace osu.Game.Rulesets.Catch.Tests.iOS
|
||||||
{
|
{
|
||||||
@ -11,7 +10,7 @@ namespace osu.Game.Rulesets.Catch.Tests.iOS
|
|||||||
{
|
{
|
||||||
public static void Main(string[] args)
|
public static void Main(string[] args)
|
||||||
{
|
{
|
||||||
UIApplication.Main(args, null, typeof(AppDelegate));
|
GameApplication.Main(new OsuTestBrowser());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -5,7 +5,7 @@
|
|||||||
<key>CFBundleName</key>
|
<key>CFBundleName</key>
|
||||||
<string>osu.Game.Rulesets.Catch.Tests.iOS</string>
|
<string>osu.Game.Rulesets.Catch.Tests.iOS</string>
|
||||||
<key>CFBundleIdentifier</key>
|
<key>CFBundleIdentifier</key>
|
||||||
<string>ppy.osu-Game-Rulesets-Catch-Tests-iOS</string>
|
<string>sh.ppy.catch-ruleset-tests</string>
|
||||||
<key>CFBundleShortVersionString</key>
|
<key>CFBundleShortVersionString</key>
|
||||||
<string>1.0</string>
|
<string>1.0</string>
|
||||||
<key>CFBundleVersion</key>
|
<key>CFBundleVersion</key>
|
||||||
@ -42,4 +42,4 @@
|
|||||||
<key>CADisableMinimumFrameDurationOnPhone</key>
|
<key>CADisableMinimumFrameDurationOnPhone</key>
|
||||||
<true/>
|
<true/>
|
||||||
</dict>
|
</dict>
|
||||||
</plist>
|
</plist>
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Difficulty;
|
using osu.Game.Rulesets.Catch.Difficulty;
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps.Legacy;
|
using osu.Game.Beatmaps.Legacy;
|
||||||
using osu.Game.Rulesets.Catch.Mods;
|
using osu.Game.Rulesets.Catch.Mods;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Tests.Beatmaps;
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
@ -26,7 +25,8 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
new object[] { LegacyMods.HalfTime, new[] { typeof(CatchModHalfTime) } },
|
new object[] { LegacyMods.HalfTime, new[] { typeof(CatchModHalfTime) } },
|
||||||
new object[] { LegacyMods.Flashlight, new[] { typeof(CatchModFlashlight) } },
|
new object[] { LegacyMods.Flashlight, new[] { typeof(CatchModFlashlight) } },
|
||||||
new object[] { LegacyMods.Autoplay, new[] { typeof(CatchModAutoplay) } },
|
new object[] { LegacyMods.Autoplay, new[] { typeof(CatchModAutoplay) } },
|
||||||
new object[] { LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(CatchModHardRock), typeof(CatchModDoubleTime) } }
|
new object[] { LegacyMods.HardRock | LegacyMods.DoubleTime, new[] { typeof(CatchModHardRock), typeof(CatchModDoubleTime) } },
|
||||||
|
new object[] { LegacyMods.ScoreV2, new[] { typeof(ModScoreV2) } },
|
||||||
};
|
};
|
||||||
|
|
||||||
[TestCaseSource(nameof(catch_mod_mapping))]
|
[TestCaseSource(nameof(catch_mod_mapping))]
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
using osu.Game.Rulesets.Catch.Skinning;
|
using osu.Game.Rulesets.Catch.Skinning;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Tests
|
namespace osu.Game.Rulesets.Catch.Tests
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
|
@ -45,7 +45,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
|
|||||||
AddAssert("end time is correct", () => Precision.AlmostEquals(lastObject.EndTime, times[1]));
|
AddAssert("end time is correct", () => Precision.AlmostEquals(lastObject.EndTime, times[1]));
|
||||||
AddAssert("start position is correct", () => Precision.AlmostEquals(lastObject.OriginalX, positions[0]));
|
AddAssert("start position is correct", () => Precision.AlmostEquals(lastObject.OriginalX, positions[0]));
|
||||||
AddAssert("end position is correct", () => Precision.AlmostEquals(lastObject.EndX, positions[1]));
|
AddAssert("end position is correct", () => Precision.AlmostEquals(lastObject.EndX, positions[1]));
|
||||||
AddAssert("default slider velocity", () => lastObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
|
AddAssert("default slider velocity", () => lastObject.SliderVelocityMultiplierBindable.IsDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
|
|||||||
addPlacementSteps(times, positions);
|
addPlacementSteps(times, positions);
|
||||||
addPathCheckStep(times, positions);
|
addPathCheckStep(times, positions);
|
||||||
|
|
||||||
AddAssert("slider velocity changed", () => !lastObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
|
AddAssert("slider velocity changed", () => !lastObject.SliderVelocityMultiplierBindable.IsDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -108,11 +108,11 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor
|
|||||||
double[] times = { 100, 300 };
|
double[] times = { 100, 300 };
|
||||||
float[] positions = { 200, 300 };
|
float[] positions = { 200, 300 };
|
||||||
addBlueprintStep(times, positions);
|
addBlueprintStep(times, positions);
|
||||||
AddAssert("default slider velocity", () => hitObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
|
AddAssert("default slider velocity", () => hitObject.SliderVelocityMultiplierBindable.IsDefault);
|
||||||
|
|
||||||
addDragStartStep(times[1], positions[1]);
|
addDragStartStep(times[1], positions[1]);
|
||||||
AddMouseMoveStep(times[1], 400);
|
AddMouseMoveStep(times[1], 400);
|
||||||
AddAssert("slider velocity changed", () => !hitObject.DifficultyControlPoint.SliderVelocityBindable.IsDefault);
|
AddAssert("slider velocity changed", () => !hitObject.SliderVelocityMultiplierBindable.IsDefault);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
@ -45,7 +43,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
NewCombo = i % 8 == 0,
|
NewCombo = i % 8 == 0,
|
||||||
Samples = new List<HitSampleInfo>(new[]
|
Samples = new List<HitSampleInfo>(new[]
|
||||||
{
|
{
|
||||||
new HitSampleInfo(HitSampleInfo.HIT_NORMAL, "normal", volume: 100)
|
new HitSampleInfo(HitSampleInfo.HIT_NORMAL)
|
||||||
})
|
})
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Tests.Visual;
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
@ -26,7 +24,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
if (withModifiedSkin)
|
if (withModifiedSkin)
|
||||||
{
|
{
|
||||||
AddStep("change component scale", () => Player.ChildrenOfType<LegacyScoreCounter>().First().Scale = new Vector2(2f));
|
AddStep("change component scale", () => Player.ChildrenOfType<LegacyScoreCounter>().First().Scale = new Vector2(2f));
|
||||||
AddStep("update target", () => Player.ChildrenOfType<SkinnableTargetContainer>().ForEach(LegacySkin.UpdateDrawableTarget));
|
AddStep("update target", () => Player.ChildrenOfType<SkinComponentsContainer>().ForEach(LegacySkin.UpdateDrawableTarget));
|
||||||
AddStep("exit player", () => Player.Exit());
|
AddStep("exit player", () => Player.Exit());
|
||||||
CreateTest();
|
CreateTest();
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
|
@ -60,26 +60,24 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestCatcherHyperStateReverted()
|
public void TestCatcherHyperStateReverted()
|
||||||
{
|
{
|
||||||
DrawableCatchHitObject drawableObject1 = null;
|
|
||||||
DrawableCatchHitObject drawableObject2 = null;
|
|
||||||
JudgementResult result1 = null;
|
JudgementResult result1 = null;
|
||||||
JudgementResult result2 = null;
|
JudgementResult result2 = null;
|
||||||
AddStep("catch hyper fruit", () =>
|
AddStep("catch hyper fruit", () =>
|
||||||
{
|
{
|
||||||
attemptCatch(new Fruit { HyperDashTarget = new Fruit { X = 100 } }, out drawableObject1, out result1);
|
result1 = attemptCatch(new Fruit { HyperDashTarget = new Fruit { X = 100 } });
|
||||||
});
|
});
|
||||||
AddStep("catch normal fruit", () =>
|
AddStep("catch normal fruit", () =>
|
||||||
{
|
{
|
||||||
attemptCatch(new Fruit(), out drawableObject2, out result2);
|
result2 = attemptCatch(new Fruit());
|
||||||
});
|
});
|
||||||
AddStep("revert second result", () =>
|
AddStep("revert second result", () =>
|
||||||
{
|
{
|
||||||
catcher.OnRevertResult(drawableObject2, result2);
|
catcher.OnRevertResult(result2);
|
||||||
});
|
});
|
||||||
checkHyperDash(true);
|
checkHyperDash(true);
|
||||||
AddStep("revert first result", () =>
|
AddStep("revert first result", () =>
|
||||||
{
|
{
|
||||||
catcher.OnRevertResult(drawableObject1, result1);
|
catcher.OnRevertResult(result1);
|
||||||
});
|
});
|
||||||
checkHyperDash(false);
|
checkHyperDash(false);
|
||||||
}
|
}
|
||||||
@ -87,16 +85,15 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestCatcherAnimationStateReverted()
|
public void TestCatcherAnimationStateReverted()
|
||||||
{
|
{
|
||||||
DrawableCatchHitObject drawableObject = null;
|
|
||||||
JudgementResult result = null;
|
JudgementResult result = null;
|
||||||
AddStep("catch kiai fruit", () =>
|
AddStep("catch kiai fruit", () =>
|
||||||
{
|
{
|
||||||
attemptCatch(new TestKiaiFruit(), out drawableObject, out result);
|
result = attemptCatch(new TestKiaiFruit());
|
||||||
});
|
});
|
||||||
checkState(CatcherAnimationState.Kiai);
|
checkState(CatcherAnimationState.Kiai);
|
||||||
AddStep("revert result", () =>
|
AddStep("revert result", () =>
|
||||||
{
|
{
|
||||||
catcher.OnRevertResult(drawableObject, result);
|
catcher.OnRevertResult(result);
|
||||||
});
|
});
|
||||||
checkState(CatcherAnimationState.Idle);
|
checkState(CatcherAnimationState.Idle);
|
||||||
}
|
}
|
||||||
@ -268,23 +265,19 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
|
|
||||||
private void checkHyperDash(bool state) => AddAssert($"catcher is {(state ? "" : "not ")}hyper dashing", () => catcher.HyperDashing == state);
|
private void checkHyperDash(bool state) => AddAssert($"catcher is {(state ? "" : "not ")}hyper dashing", () => catcher.HyperDashing == state);
|
||||||
|
|
||||||
private void attemptCatch(CatchHitObject hitObject)
|
|
||||||
{
|
|
||||||
attemptCatch(() => hitObject, 1);
|
|
||||||
}
|
|
||||||
|
|
||||||
private void attemptCatch(Func<CatchHitObject> hitObject, int count)
|
private void attemptCatch(Func<CatchHitObject> hitObject, int count)
|
||||||
{
|
{
|
||||||
for (int i = 0; i < count; i++)
|
for (int i = 0; i < count; i++)
|
||||||
attemptCatch(hitObject(), out _, out _);
|
attemptCatch(hitObject());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void attemptCatch(CatchHitObject hitObject, out DrawableCatchHitObject drawableObject, out JudgementResult result)
|
private JudgementResult attemptCatch(CatchHitObject hitObject)
|
||||||
{
|
{
|
||||||
hitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
hitObject.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
|
||||||
drawableObject = createDrawableObject(hitObject);
|
var drawableObject = createDrawableObject(hitObject);
|
||||||
result = createResult(hitObject);
|
var result = createResult(hitObject);
|
||||||
applyResult(drawableObject, result);
|
applyResult(drawableObject, result);
|
||||||
|
return result;
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyResult(DrawableCatchHitObject drawableObject, JudgementResult result)
|
private void applyResult(DrawableCatchHitObject drawableObject, JudgementResult result)
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Rulesets.Catch.Mods;
|
using osu.Game.Rulesets.Catch.Mods;
|
||||||
|
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawables;
|
using osu.Game.Rulesets.Catch.Objects.Drawables;
|
||||||
@ -28,6 +26,8 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
AddSliderStep("start time", 500, 600, 0, x =>
|
AddSliderStep("start time", 500, 600, 0, x =>
|
||||||
{
|
{
|
||||||
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = x;
|
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = x;
|
||||||
|
drawableFruit.RefreshStateTransforms();
|
||||||
|
drawableBanana.RefreshStateTransforms();
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -46,6 +46,8 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
AddStep("Initialize start time", () =>
|
AddStep("Initialize start time", () =>
|
||||||
{
|
{
|
||||||
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = initial_start_time;
|
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = initial_start_time;
|
||||||
|
drawableFruit.RefreshStateTransforms();
|
||||||
|
drawableBanana.RefreshStateTransforms();
|
||||||
|
|
||||||
fruitRotation = drawableFruit.DisplayRotation;
|
fruitRotation = drawableFruit.DisplayRotation;
|
||||||
bananaRotation = drawableBanana.DisplayRotation;
|
bananaRotation = drawableBanana.DisplayRotation;
|
||||||
@ -56,6 +58,8 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
AddStep("change start time", () =>
|
AddStep("change start time", () =>
|
||||||
{
|
{
|
||||||
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = another_start_time;
|
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = another_start_time;
|
||||||
|
drawableFruit.RefreshStateTransforms();
|
||||||
|
drawableBanana.RefreshStateTransforms();
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("fruit rotation is changed", () => drawableFruit.DisplayRotation != fruitRotation);
|
AddAssert("fruit rotation is changed", () => drawableFruit.DisplayRotation != fruitRotation);
|
||||||
@ -66,6 +70,8 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
AddStep("reset start time", () =>
|
AddStep("reset start time", () =>
|
||||||
{
|
{
|
||||||
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = initial_start_time;
|
drawableFruit.HitObject.StartTime = drawableBanana.HitObject.StartTime = initial_start_time;
|
||||||
|
drawableFruit.RefreshStateTransforms();
|
||||||
|
drawableBanana.RefreshStateTransforms();
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("rotation and size restored", () =>
|
AddAssert("rotation and size restored", () =>
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Game.Rulesets.Catch.Objects;
|
using osu.Game.Rulesets.Catch.Objects;
|
||||||
using osu.Game.Rulesets.Catch.Objects.Drawables;
|
using osu.Game.Rulesets.Catch.Objects.Drawables;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
@ -1,8 +1,6 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
@ -21,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
public partial class TestSceneLegacyBeatmapSkin : LegacyBeatmapSkinColourTest
|
public partial class TestSceneLegacyBeatmapSkin : LegacyBeatmapSkinColourTest
|
||||||
{
|
{
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private AudioManager audio { get; set; }
|
private AudioManager audio { get; set; } = null!;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager config)
|
private void load(OsuConfigManager config)
|
||||||
|
@ -1,9 +1,9 @@
|
|||||||
<Project Sdk="Microsoft.NET.Sdk">
|
<Project Sdk="Microsoft.NET.Sdk">
|
||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.3.2" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="17.4.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.3" />
|
<PackageReference Include="NUnit" Version="3.13.3" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="4.3.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="4.3.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
|
@ -26,6 +26,7 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
var xPositionData = obj as IHasXPosition;
|
var xPositionData = obj as IHasXPosition;
|
||||||
var yPositionData = obj as IHasYPosition;
|
var yPositionData = obj as IHasYPosition;
|
||||||
var comboData = obj as IHasCombo;
|
var comboData = obj as IHasCombo;
|
||||||
|
var sliderVelocityData = obj as IHasSliderVelocity;
|
||||||
|
|
||||||
switch (obj)
|
switch (obj)
|
||||||
{
|
{
|
||||||
@ -41,7 +42,8 @@ namespace osu.Game.Rulesets.Catch.Beatmaps
|
|||||||
NewCombo = comboData?.NewCombo ?? false,
|
NewCombo = comboData?.NewCombo ?? false,
|
||||||
ComboOffset = comboData?.ComboOffset ?? 0,
|
ComboOffset = comboData?.ComboOffset ?? 0,
|
||||||
LegacyLastTickOffset = (obj as IHasLegacyLastTickOffset)?.LegacyLastTickOffset ?? 0,
|
LegacyLastTickOffset = (obj as IHasLegacyLastTickOffset)?.LegacyLastTickOffset ?? 0,
|
||||||
LegacyConvertedY = yPositionData?.Y ?? CatchHitObject.DEFAULT_LEGACY_CONVERT_Y
|
LegacyConvertedY = yPositionData?.Y ?? CatchHitObject.DEFAULT_LEGACY_CONVERT_Y,
|
||||||
|
SliderVelocityMultiplier = sliderVelocityData?.SliderVelocityMultiplier ?? 1
|
||||||
}.Yield();
|
}.Yield();
|
||||||
|
|
||||||
case IHasDuration endTime:
|
case IHasDuration endTime:
|
||||||
|
@ -26,6 +26,8 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.Replays.Types;
|
using osu.Game.Rulesets.Replays.Types;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Ranking.Statistics;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch
|
namespace osu.Game.Rulesets.Catch
|
||||||
@ -91,6 +93,9 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
|
|
||||||
if (mods.HasFlagFast(LegacyMods.Relax))
|
if (mods.HasFlagFast(LegacyMods.Relax))
|
||||||
yield return new CatchModRelax();
|
yield return new CatchModRelax();
|
||||||
|
|
||||||
|
if (mods.HasFlagFast(LegacyMods.ScoreV2))
|
||||||
|
yield return new ModScoreV2();
|
||||||
}
|
}
|
||||||
|
|
||||||
public override IEnumerable<Mod> GetModsFor(ModType type)
|
public override IEnumerable<Mod> GetModsFor(ModType type)
|
||||||
@ -140,6 +145,12 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
new CatchModNoScope(),
|
new CatchModNoScope(),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
case ModType.System:
|
||||||
|
return new Mod[]
|
||||||
|
{
|
||||||
|
new ModScoreV2(),
|
||||||
|
};
|
||||||
|
|
||||||
default:
|
default:
|
||||||
return Array.Empty<Mod>();
|
return Array.Empty<Mod>();
|
||||||
}
|
}
|
||||||
@ -202,10 +213,24 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
|
|
||||||
public int LegacyID => 2;
|
public int LegacyID => 2;
|
||||||
|
|
||||||
|
public ILegacyScoreSimulator CreateLegacyScoreSimulator() => new CatchLegacyScoreSimulator();
|
||||||
|
|
||||||
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new CatchReplayFrame();
|
public override IConvertibleReplayFrame CreateConvertibleReplayFrame() => new CatchReplayFrame();
|
||||||
|
|
||||||
public override HitObjectComposer CreateHitObjectComposer() => new CatchHitObjectComposer(this);
|
public override HitObjectComposer CreateHitObjectComposer() => new CatchHitObjectComposer(this);
|
||||||
|
|
||||||
public override IBeatmapVerifier CreateBeatmapVerifier() => new CatchBeatmapVerifier();
|
public override IBeatmapVerifier CreateBeatmapVerifier() => new CatchBeatmapVerifier();
|
||||||
|
|
||||||
|
public override StatisticItem[] CreateStatisticsForScore(ScoreInfo score, IBeatmap playableBeatmap)
|
||||||
|
{
|
||||||
|
return new[]
|
||||||
|
{
|
||||||
|
new StatisticItem("Performance Breakdown", () => new PerformanceBreakdownChart(score, playableBeatmap)
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
AutoSizeAxes = Axes.Y
|
||||||
|
}),
|
||||||
|
};
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,6 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
// Todo: osu!catch should not output star rating in the 'aim' attribute.
|
// Todo: osu!catch should not output star rating in the 'aim' attribute.
|
||||||
yield return (ATTRIB_ID_AIM, StarRating);
|
yield return (ATTRIB_ID_AIM, StarRating);
|
||||||
yield return (ATTRIB_ID_APPROACH_RATE, ApproachRate);
|
yield return (ATTRIB_ID_APPROACH_RATE, ApproachRate);
|
||||||
yield return (ATTRIB_ID_MAX_COMBO, MaxCombo);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo)
|
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo)
|
||||||
@ -36,7 +35,6 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
|
|
||||||
StarRating = values[ATTRIB_ID_AIM];
|
StarRating = values[ATTRIB_ID_AIM];
|
||||||
ApproachRate = values[ATTRIB_ID_APPROACH_RATE];
|
ApproachRate = values[ATTRIB_ID_APPROACH_RATE];
|
||||||
MaxCombo = (int)values[ATTRIB_ID_MAX_COMBO];
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -26,9 +26,12 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
|
|
||||||
public override int Version => 20220701;
|
public override int Version => 20220701;
|
||||||
|
|
||||||
|
private readonly IWorkingBeatmap workingBeatmap;
|
||||||
|
|
||||||
public CatchDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
|
public CatchDifficultyCalculator(IRulesetInfo ruleset, IWorkingBeatmap beatmap)
|
||||||
: base(ruleset, beatmap)
|
: base(ruleset, beatmap)
|
||||||
{
|
{
|
||||||
|
workingBeatmap = beatmap;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
protected override DifficultyAttributes CreateDifficultyAttributes(IBeatmap beatmap, Mod[] mods, Skill[] skills, double clockRate)
|
||||||
@ -39,13 +42,24 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
// this is the same as osu!, so there's potential to share the implementation... maybe
|
// this is the same as osu!, so there's potential to share the implementation... maybe
|
||||||
double preempt = IBeatmapDifficultyInfo.DifficultyRange(beatmap.Difficulty.ApproachRate, 1800, 1200, 450) / clockRate;
|
double preempt = IBeatmapDifficultyInfo.DifficultyRange(beatmap.Difficulty.ApproachRate, 1800, 1200, 450) / clockRate;
|
||||||
|
|
||||||
return new CatchDifficultyAttributes
|
CatchDifficultyAttributes attributes = new CatchDifficultyAttributes
|
||||||
{
|
{
|
||||||
StarRating = Math.Sqrt(skills[0].DifficultyValue()) * star_scaling_factor,
|
StarRating = Math.Sqrt(skills[0].DifficultyValue()) * star_scaling_factor,
|
||||||
Mods = mods,
|
Mods = mods,
|
||||||
ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0,
|
ApproachRate = preempt > 1200.0 ? -(preempt - 1800.0) / 120.0 : -(preempt - 1200.0) / 150.0 + 5.0,
|
||||||
MaxCombo = beatmap.HitObjects.Count(h => h is Fruit) + beatmap.HitObjects.OfType<JuiceStream>().SelectMany(j => j.NestedHitObjects).Count(h => !(h is TinyDroplet)),
|
MaxCombo = beatmap.HitObjects.Count(h => h is Fruit) + beatmap.HitObjects.OfType<JuiceStream>().SelectMany(j => j.NestedHitObjects).Count(h => !(h is TinyDroplet)),
|
||||||
};
|
};
|
||||||
|
|
||||||
|
if (ComputeLegacyScoringValues)
|
||||||
|
{
|
||||||
|
CatchLegacyScoreSimulator sv1Simulator = new CatchLegacyScoreSimulator();
|
||||||
|
sv1Simulator.Simulate(workingBeatmap, beatmap, mods);
|
||||||
|
attributes.LegacyAccuracyScore = sv1Simulator.AccuracyScore;
|
||||||
|
attributes.LegacyComboScore = sv1Simulator.ComboScore;
|
||||||
|
attributes.LegacyBonusScoreRatio = sv1Simulator.BonusScoreRatio;
|
||||||
|
}
|
||||||
|
|
||||||
|
return attributes;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
|
protected override IEnumerable<DifficultyHitObject> CreateDifficultyHitObjects(IBeatmap beatmap, double clockRate)
|
||||||
|
142
osu.Game.Rulesets.Catch/Difficulty/CatchLegacyScoreSimulator.cs
Normal file
142
osu.Game.Rulesets.Catch/Difficulty/CatchLegacyScoreSimulator.cs
Normal file
@ -0,0 +1,142 @@
|
|||||||
|
// 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.Catch.Objects;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Difficulty
|
||||||
|
{
|
||||||
|
internal class CatchLegacyScoreSimulator : ILegacyScoreSimulator
|
||||||
|
{
|
||||||
|
public int AccuracyScore { get; private set; }
|
||||||
|
|
||||||
|
public int ComboScore { get; private set; }
|
||||||
|
|
||||||
|
public double BonusScoreRatio => legacyBonusScore == 0 ? 0 : (double)modernBonusScore / legacyBonusScore;
|
||||||
|
|
||||||
|
private int legacyBonusScore;
|
||||||
|
private int modernBonusScore;
|
||||||
|
private int combo;
|
||||||
|
|
||||||
|
private double scoreMultiplier;
|
||||||
|
|
||||||
|
public void Simulate(IWorkingBeatmap workingBeatmap, IBeatmap playableBeatmap, IReadOnlyList<Mod> mods)
|
||||||
|
{
|
||||||
|
IBeatmap baseBeatmap = workingBeatmap.Beatmap;
|
||||||
|
|
||||||
|
int countNormal = 0;
|
||||||
|
int countSlider = 0;
|
||||||
|
int countSpinner = 0;
|
||||||
|
|
||||||
|
foreach (HitObject obj in baseBeatmap.HitObjects)
|
||||||
|
{
|
||||||
|
switch (obj)
|
||||||
|
{
|
||||||
|
case IHasPath:
|
||||||
|
countSlider++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case IHasDuration:
|
||||||
|
countSpinner++;
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
countNormal++;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int objectCount = countNormal + countSlider + countSpinner;
|
||||||
|
|
||||||
|
int drainLength = 0;
|
||||||
|
|
||||||
|
if (baseBeatmap.HitObjects.Count > 0)
|
||||||
|
{
|
||||||
|
int breakLength = baseBeatmap.Breaks.Select(b => (int)Math.Round(b.EndTime) - (int)Math.Round(b.StartTime)).Sum();
|
||||||
|
drainLength = ((int)Math.Round(baseBeatmap.HitObjects[^1].StartTime) - (int)Math.Round(baseBeatmap.HitObjects[0].StartTime) - breakLength) / 1000;
|
||||||
|
}
|
||||||
|
|
||||||
|
int difficultyPeppyStars = (int)Math.Round(
|
||||||
|
(baseBeatmap.Difficulty.DrainRate
|
||||||
|
+ baseBeatmap.Difficulty.OverallDifficulty
|
||||||
|
+ baseBeatmap.Difficulty.CircleSize
|
||||||
|
+ Math.Clamp((float)objectCount / drainLength * 8, 0, 16)) / 38 * 5);
|
||||||
|
|
||||||
|
scoreMultiplier = difficultyPeppyStars * mods.Aggregate(1.0, (current, mod) => current * mod.ScoreMultiplier);
|
||||||
|
|
||||||
|
foreach (var obj in playableBeatmap.HitObjects)
|
||||||
|
simulateHit(obj);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void simulateHit(HitObject hitObject)
|
||||||
|
{
|
||||||
|
bool increaseCombo = true;
|
||||||
|
bool addScoreComboMultiplier = false;
|
||||||
|
|
||||||
|
bool isBonus = false;
|
||||||
|
HitResult bonusResult = HitResult.None;
|
||||||
|
|
||||||
|
int scoreIncrease = 0;
|
||||||
|
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case TinyDroplet:
|
||||||
|
scoreIncrease = 10;
|
||||||
|
increaseCombo = false;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Droplet:
|
||||||
|
scoreIncrease = 100;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Fruit:
|
||||||
|
scoreIncrease = 300;
|
||||||
|
addScoreComboMultiplier = true;
|
||||||
|
increaseCombo = true;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Banana:
|
||||||
|
scoreIncrease = 1100;
|
||||||
|
increaseCombo = false;
|
||||||
|
isBonus = true;
|
||||||
|
bonusResult = HitResult.LargeBonus;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case JuiceStream:
|
||||||
|
foreach (var nested in hitObject.NestedHitObjects)
|
||||||
|
simulateHit(nested);
|
||||||
|
return;
|
||||||
|
|
||||||
|
case BananaShower:
|
||||||
|
foreach (var nested in hitObject.NestedHitObjects)
|
||||||
|
simulateHit(nested);
|
||||||
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (addScoreComboMultiplier)
|
||||||
|
{
|
||||||
|
// ReSharper disable once PossibleLossOfFraction (intentional to match osu-stable...)
|
||||||
|
ComboScore += (int)(Math.Max(0, combo - 1) * (scoreIncrease / 25 * scoreMultiplier));
|
||||||
|
}
|
||||||
|
|
||||||
|
if (isBonus)
|
||||||
|
{
|
||||||
|
legacyBonusScore += scoreIncrease;
|
||||||
|
modernBonusScore += Judgement.ToNumericResult(bonusResult);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
AccuracyScore += scoreIncrease;
|
||||||
|
|
||||||
|
if (increaseCombo)
|
||||||
|
combo++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -17,6 +17,8 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
|||||||
private double placementStartTime;
|
private double placementStartTime;
|
||||||
private double placementEndTime;
|
private double placementEndTime;
|
||||||
|
|
||||||
|
protected override bool IsValidForPlacement => HitObject.Duration > 0;
|
||||||
|
|
||||||
public BananaShowerPlacementBlueprint()
|
public BananaShowerPlacementBlueprint()
|
||||||
{
|
{
|
||||||
InternalChild = outline = new TimeSpanOutline();
|
InternalChild = outline = new TimeSpanOutline();
|
||||||
@ -49,7 +51,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
|||||||
case PlacementState.Active:
|
case PlacementState.Active:
|
||||||
if (e.Button != MouseButton.Right) break;
|
if (e.Button != MouseButton.Right) break;
|
||||||
|
|
||||||
EndPlacement(HitObject.Duration > 0);
|
EndPlacement(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,7 +6,6 @@ using osu.Game.Rulesets.Catch.Objects;
|
|||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Rulesets.UI.Scrolling;
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
using osuTK;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
||||||
{
|
{
|
||||||
@ -24,7 +23,5 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
|||||||
: base(new THitObject())
|
: base(new THitObject())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public override bool ReceivePositionalInputAt(Vector2 screenSpacePos) => true;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -91,7 +91,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints.Components
|
|||||||
public void UpdateHitObjectFromPath(JuiceStream hitObject)
|
public void UpdateHitObjectFromPath(JuiceStream hitObject)
|
||||||
{
|
{
|
||||||
// The SV setting may need to be changed for the current path.
|
// The SV setting may need to be changed for the current path.
|
||||||
var svBindable = hitObject.DifficultyControlPoint.SliderVelocityBindable;
|
var svBindable = hitObject.SliderVelocityMultiplierBindable;
|
||||||
double svToVelocityFactor = hitObject.Velocity / svBindable.Value;
|
double svToVelocityFactor = hitObject.Velocity / svBindable.Value;
|
||||||
double requiredVelocity = path.ComputeRequiredVelocity();
|
double requiredVelocity = path.ComputeRequiredVelocity();
|
||||||
|
|
||||||
|
@ -24,6 +24,8 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
|||||||
|
|
||||||
private InputManager inputManager = null!;
|
private InputManager inputManager = null!;
|
||||||
|
|
||||||
|
protected override bool IsValidForPlacement => HitObject.Duration > 0;
|
||||||
|
|
||||||
public JuiceStreamPlacementBlueprint()
|
public JuiceStreamPlacementBlueprint()
|
||||||
{
|
{
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
@ -70,7 +72,7 @@ namespace osu.Game.Rulesets.Catch.Edit.Blueprints
|
|||||||
return true;
|
return true;
|
||||||
|
|
||||||
case MouseButton.Right:
|
case MouseButton.Right:
|
||||||
EndPlacement(HitObject.Duration > 0);
|
EndPlacement(true);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
180
osu.Game.Rulesets.Catch/Edit/CatchBeatSnapGrid.cs
Normal file
180
osu.Game.Rulesets.Catch/Edit/CatchBeatSnapGrid.cs
Normal file
@ -0,0 +1,180 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Caching;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Rulesets.Catch.UI;
|
||||||
|
using osu.Game.Rulesets.Edit;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.UI.Scrolling;
|
||||||
|
using osu.Game.Screens.Edit;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Catch.Edit
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A grid which displays coloured beat divisor lines in proximity to the selection or placement cursor.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This class heavily borrows from osu!mania's implementation (ManiaBeatSnapGrid).
|
||||||
|
/// If further changes are to be made, they should also be applied there.
|
||||||
|
/// If the scale of the changes are large enough, abstracting may be a good path.
|
||||||
|
/// </remarks>
|
||||||
|
public partial class CatchBeatSnapGrid : Component
|
||||||
|
{
|
||||||
|
private const double visible_range = 750;
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The range of time values of the current selection.
|
||||||
|
/// </summary>
|
||||||
|
public (double start, double end)? SelectionTimeRange
|
||||||
|
{
|
||||||
|
set
|
||||||
|
{
|
||||||
|
if (value == selectionTimeRange)
|
||||||
|
return;
|
||||||
|
|
||||||
|
selectionTimeRange = value;
|
||||||
|
lineCache.Invalidate();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private EditorBeatmap beatmap { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuColour colours { get; set; } = null!;
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private BindableBeatDivisor beatDivisor { get; set; } = null!;
|
||||||
|
|
||||||
|
private readonly Cached lineCache = new Cached();
|
||||||
|
|
||||||
|
private (double start, double end)? selectionTimeRange;
|
||||||
|
|
||||||
|
private ScrollingHitObjectContainer lineContainer = null!;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(HitObjectComposer composer)
|
||||||
|
{
|
||||||
|
lineContainer = new ScrollingHitObjectContainer();
|
||||||
|
|
||||||
|
((CatchPlayfield)composer.Playfield).UnderlayElements.Add(lineContainer);
|
||||||
|
|
||||||
|
beatDivisor.BindValueChanged(_ => createLines(), true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void Update()
|
||||||
|
{
|
||||||
|
base.Update();
|
||||||
|
|
||||||
|
if (!lineCache.IsValid)
|
||||||
|
{
|
||||||
|
lineCache.Validate();
|
||||||
|
createLines();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private readonly Stack<DrawableGridLine> availableLines = new Stack<DrawableGridLine>();
|
||||||
|
|
||||||
|
private void createLines()
|
||||||
|
{
|
||||||
|
foreach (var line in lineContainer.Objects.OfType<DrawableGridLine>())
|
||||||
|
availableLines.Push(line);
|
||||||
|
|
||||||
|
lineContainer.Clear();
|
||||||
|
|
||||||
|
if (selectionTimeRange == null)
|
||||||
|
return;
|
||||||
|
|
||||||
|
var range = selectionTimeRange.Value;
|
||||||
|
|
||||||
|
var timingPoint = beatmap.ControlPointInfo.TimingPointAt(range.start - visible_range);
|
||||||
|
|
||||||
|
double time = timingPoint.Time;
|
||||||
|
int beat = 0;
|
||||||
|
|
||||||
|
// progress time until in the visible range.
|
||||||
|
while (time < range.start - visible_range)
|
||||||
|
{
|
||||||
|
time += timingPoint.BeatLength / beatDivisor.Value;
|
||||||
|
beat++;
|
||||||
|
}
|
||||||
|
|
||||||
|
while (time < range.end + visible_range)
|
||||||
|
{
|
||||||
|
var nextTimingPoint = beatmap.ControlPointInfo.TimingPointAt(time);
|
||||||
|
|
||||||
|
// switch to the next timing point if we have reached it.
|
||||||
|
if (nextTimingPoint.Time > timingPoint.Time)
|
||||||
|
{
|
||||||
|
beat = 0;
|
||||||
|
time = nextTimingPoint.Time;
|
||||||
|
timingPoint = nextTimingPoint;
|
||||||
|
}
|
||||||
|
|
||||||
|
Color4 colour = BindableBeatDivisor.GetColourFor(
|
||||||
|
BindableBeatDivisor.GetDivisorForBeatIndex(beat, beatDivisor.Value), colours);
|
||||||
|
|
||||||
|
if (!availableLines.TryPop(out var line))
|
||||||
|
line = new DrawableGridLine();
|
||||||
|
|
||||||
|
line.HitObject.StartTime = time;
|
||||||
|
line.Colour = colour;
|
||||||
|
|
||||||
|
lineContainer.Add(line);
|
||||||
|
|
||||||
|
beat++;
|
||||||
|
time += timingPoint.BeatLength / beatDivisor.Value;
|
||||||
|
}
|
||||||
|
|
||||||
|
// required to update ScrollingHitObjectContainer's cache.
|
||||||
|
lineContainer.UpdateSubTree();
|
||||||
|
|
||||||
|
foreach (var line in lineContainer.Objects.OfType<DrawableGridLine>())
|
||||||
|
{
|
||||||
|
time = line.HitObject.StartTime;
|
||||||
|
|
||||||
|
if (time >= range.start && time <= range.end)
|
||||||
|
line.Alpha = 1;
|
||||||
|
else
|
||||||
|
{
|
||||||
|
double timeSeparation = time < range.start ? range.start - time : time - range.end;
|
||||||
|
line.Alpha = (float)Math.Max(0, 1 - timeSeparation / visible_range);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private partial class DrawableGridLine : DrawableHitObject
|
||||||
|
{
|
||||||
|
public DrawableGridLine()
|
||||||
|
: base(new HitObject())
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.X;
|
||||||
|
Height = 2;
|
||||||
|
|
||||||
|
AddInternal(new Box { RelativeSizeAxes = Axes.Both });
|
||||||
|
}
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load()
|
||||||
|
{
|
||||||
|
Origin = Anchor.BottomLeft;
|
||||||
|
Anchor = Anchor.BottomLeft;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void UpdateInitialTransforms()
|
||||||
|
{
|
||||||
|
// don't perform any fading – we are handling that ourselves.
|
||||||
|
LifetimeEnd = HitObject.StartTime + visible_range;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -33,6 +33,8 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
|
|
||||||
private InputManager inputManager = null!;
|
private InputManager inputManager = null!;
|
||||||
|
|
||||||
|
private CatchBeatSnapGrid beatSnapGrid = null!;
|
||||||
|
|
||||||
private readonly BindableDouble timeRangeMultiplier = new BindableDouble(1)
|
private readonly BindableDouble timeRangeMultiplier = new BindableDouble(1)
|
||||||
{
|
{
|
||||||
MinValue = 1,
|
MinValue = 1,
|
||||||
@ -48,7 +50,6 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
private void load()
|
private void load()
|
||||||
{
|
{
|
||||||
// todo: enable distance spacing once catch supports applying it to its existing distance snap grid implementation.
|
// todo: enable distance spacing once catch supports applying it to its existing distance snap grid implementation.
|
||||||
RightSideToolboxContainer.Alpha = 0;
|
|
||||||
DistanceSpacingMultiplier.Disabled = true;
|
DistanceSpacingMultiplier.Disabled = true;
|
||||||
|
|
||||||
LayerBelowRuleset.Add(new PlayfieldBorder
|
LayerBelowRuleset.Add(new PlayfieldBorder
|
||||||
@ -66,6 +67,8 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
Catcher.BASE_DASH_SPEED, -Catcher.BASE_DASH_SPEED,
|
Catcher.BASE_DASH_SPEED, -Catcher.BASE_DASH_SPEED,
|
||||||
Catcher.BASE_WALK_SPEED, -Catcher.BASE_WALK_SPEED,
|
Catcher.BASE_WALK_SPEED, -Catcher.BASE_WALK_SPEED,
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
AddInternal(beatSnapGrid = new CatchBeatSnapGrid());
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
@ -75,6 +78,29 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
inputManager = GetContainingInputManager();
|
inputManager = GetContainingInputManager();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override void UpdateAfterChildren()
|
||||||
|
{
|
||||||
|
base.UpdateAfterChildren();
|
||||||
|
|
||||||
|
if (BlueprintContainer.CurrentTool is SelectTool)
|
||||||
|
{
|
||||||
|
if (EditorBeatmap.SelectedHitObjects.Any())
|
||||||
|
{
|
||||||
|
beatSnapGrid.SelectionTimeRange = (EditorBeatmap.SelectedHitObjects.Min(h => h.StartTime), EditorBeatmap.SelectedHitObjects.Max(h => h.GetEndTime()));
|
||||||
|
}
|
||||||
|
else
|
||||||
|
beatSnapGrid.SelectionTimeRange = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var result = FindSnappedPositionAndTime(inputManager.CurrentState.Mouse.Position);
|
||||||
|
if (result.Time is double time)
|
||||||
|
beatSnapGrid.SelectionTimeRange = (time, time);
|
||||||
|
else
|
||||||
|
beatSnapGrid.SelectionTimeRange = null;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
protected override double ReadCurrentDistanceSnap(HitObject before, HitObject after)
|
protected override double ReadCurrentDistanceSnap(HitObject before, HitObject after)
|
||||||
{
|
{
|
||||||
// osu!catch's distance snap implementation is limited, in that a custom spacing cannot be specified.
|
// osu!catch's distance snap implementation is limited, in that a custom spacing cannot be specified.
|
||||||
@ -133,7 +159,7 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
|
|
||||||
result.ScreenSpacePosition.X = screenSpacePosition.X;
|
result.ScreenSpacePosition.X = screenSpacePosition.X;
|
||||||
|
|
||||||
if (snapType.HasFlagFast(SnapType.Grids))
|
if (snapType.HasFlagFast(SnapType.RelativeGrids))
|
||||||
{
|
{
|
||||||
if (distanceSnapGrid.IsPresent && distanceSnapGrid.GetSnappedPosition(result.ScreenSpacePosition) is SnapResult snapResult &&
|
if (distanceSnapGrid.IsPresent && distanceSnapGrid.GetSnappedPosition(result.ScreenSpacePosition) is SnapResult snapResult &&
|
||||||
Vector2.Distance(snapResult.ScreenSpacePosition, result.ScreenSpacePosition) < distance_snap_radius)
|
Vector2.Distance(snapResult.ScreenSpacePosition, result.ScreenSpacePosition) < distance_snap_radius)
|
||||||
|
@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
{
|
{
|
||||||
public class CatchModDaycore : ModDaycore
|
public class CatchModDaycore : ModDaycore
|
||||||
{
|
{
|
||||||
public override double ScoreMultiplier => 0.3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -16,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
public DifficultyBindable CircleSize { get; } = new DifficultyBindable
|
public DifficultyBindable CircleSize { get; } = new DifficultyBindable
|
||||||
{
|
{
|
||||||
Precision = 0.1f,
|
Precision = 0.1f,
|
||||||
MinValue = 1,
|
MinValue = 0,
|
||||||
MaxValue = 10,
|
MaxValue = 10,
|
||||||
ExtendedMaxValue = 11,
|
ExtendedMaxValue = 11,
|
||||||
ReadCurrentFromDifficulty = diff => diff.CircleSize,
|
ReadCurrentFromDifficulty = diff => diff.CircleSize,
|
||||||
@ -26,7 +26,7 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
public DifficultyBindable ApproachRate { get; } = new DifficultyBindable
|
public DifficultyBindable ApproachRate { get; } = new DifficultyBindable
|
||||||
{
|
{
|
||||||
Precision = 0.1f,
|
Precision = 0.1f,
|
||||||
MinValue = 1,
|
MinValue = 0,
|
||||||
MaxValue = 10,
|
MaxValue = 10,
|
||||||
ExtendedMaxValue = 11,
|
ExtendedMaxValue = 11,
|
||||||
ReadCurrentFromDifficulty = diff => diff.ApproachRate,
|
ReadCurrentFromDifficulty = diff => diff.ApproachRate,
|
||||||
|
@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
{
|
{
|
||||||
public class CatchModDoubleTime : ModDoubleTime
|
public class CatchModDoubleTime : ModDoubleTime
|
||||||
{
|
{
|
||||||
public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -21,10 +21,10 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
|
|
||||||
public void ApplyToDrawableRuleset(DrawableRuleset<CatchHitObject> drawableRuleset)
|
public void ApplyToDrawableRuleset(DrawableRuleset<CatchHitObject> drawableRuleset)
|
||||||
{
|
{
|
||||||
drawableRuleset.Anchor = Anchor.Centre;
|
drawableRuleset.PlayfieldAdjustmentContainer.Anchor = Anchor.Centre;
|
||||||
drawableRuleset.Origin = Anchor.Centre;
|
drawableRuleset.PlayfieldAdjustmentContainer.Origin = Anchor.Centre;
|
||||||
|
|
||||||
drawableRuleset.Scale = new Vector2(1, -1);
|
drawableRuleset.PlayfieldAdjustmentContainer.Scale = new Vector2(1, -1);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,5 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
{
|
{
|
||||||
public class CatchModHalfTime : ModHalfTime
|
public class CatchModHalfTime : ModHalfTime
|
||||||
{
|
{
|
||||||
public override double ScoreMultiplier => 0.3;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,5 @@ namespace osu.Game.Rulesets.Catch.Mods
|
|||||||
{
|
{
|
||||||
public class CatchModNightcore : ModNightcore<CatchHitObject>
|
public class CatchModNightcore : ModNightcore<CatchHitObject>
|
||||||
{
|
{
|
||||||
public override double ScoreMultiplier => UsesDefaultConfiguration ? 1.06 : 1;
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -22,11 +22,11 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
|
|
||||||
public override Judgement CreateJudgement() => new CatchBananaJudgement();
|
public override Judgement CreateJudgement() => new CatchBananaJudgement();
|
||||||
|
|
||||||
private static readonly List<HitSampleInfo> samples = new List<HitSampleInfo> { new BananaHitSampleInfo() };
|
private static readonly IList<HitSampleInfo> default_banana_samples = new List<HitSampleInfo> { new BananaHitSampleInfo() }.AsReadOnly();
|
||||||
|
|
||||||
public Banana()
|
public Banana()
|
||||||
{
|
{
|
||||||
Samples = samples;
|
Samples = default_banana_samples;
|
||||||
}
|
}
|
||||||
|
|
||||||
// override any external colour changes with banananana
|
// override any external colour changes with banananana
|
||||||
@ -47,18 +47,18 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BananaHitSampleInfo : HitSampleInfo, IEquatable<BananaHitSampleInfo>
|
public class BananaHitSampleInfo : HitSampleInfo, IEquatable<BananaHitSampleInfo>
|
||||||
{
|
{
|
||||||
private static readonly string[] lookup_names = { "Gameplay/metronomelow", "Gameplay/catch-banana" };
|
private static readonly string[] lookup_names = { "Gameplay/metronomelow", "Gameplay/catch-banana" };
|
||||||
|
|
||||||
public override IEnumerable<string> LookupNames => lookup_names;
|
public override IEnumerable<string> LookupNames => lookup_names;
|
||||||
|
|
||||||
public BananaHitSampleInfo(int volume = 0)
|
public BananaHitSampleInfo(int volume = 100)
|
||||||
: base(string.Empty, volume: volume)
|
: base(string.Empty, volume: volume)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
public sealed override HitSampleInfo With(Optional<string> newName = default, Optional<string?> newBank = default, Optional<string?> newSuffix = default, Optional<int> newVolume = default)
|
public sealed override HitSampleInfo With(Optional<string> newName = default, Optional<string> newBank = default, Optional<string?> newSuffix = default, Optional<int> newVolume = default)
|
||||||
=> new BananaHitSampleInfo(newVolume.GetOr(Volume));
|
=> new BananaHitSampleInfo(newVolume.GetOr(Volume));
|
||||||
|
|
||||||
public bool Equals(BananaHitSampleInfo? other)
|
public bool Equals(BananaHitSampleInfo? other)
|
||||||
|
@ -1,7 +1,9 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
|
using osu.Game.Audio;
|
||||||
using osu.Game.Rulesets.Judgements;
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Objects.Types;
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
|
||||||
@ -39,6 +41,7 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
{
|
{
|
||||||
StartTime = time,
|
StartTime = time,
|
||||||
BananaIndex = i,
|
BananaIndex = i,
|
||||||
|
Samples = new List<HitSampleInfo> { new Banana.BananaHitSampleInfo(CreateHitSampleInfo().Volume) }
|
||||||
});
|
});
|
||||||
|
|
||||||
time += spacing;
|
time += spacing;
|
||||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Threading;
|
using System.Threading;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
@ -16,7 +17,7 @@ using osu.Game.Rulesets.Objects.Types;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Objects
|
namespace osu.Game.Rulesets.Catch.Objects
|
||||||
{
|
{
|
||||||
public class JuiceStream : CatchHitObject, IHasPathWithRepeats
|
public class JuiceStream : CatchHitObject, IHasPathWithRepeats, IHasSliderVelocity
|
||||||
{
|
{
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Positional distance that results in a duration of one second, before any speed adjustments.
|
/// Positional distance that results in a duration of one second, before any speed adjustments.
|
||||||
@ -27,6 +28,19 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
|
|
||||||
public int RepeatCount { get; set; }
|
public int RepeatCount { get; set; }
|
||||||
|
|
||||||
|
public BindableNumber<double> SliderVelocityMultiplierBindable { get; } = new BindableDouble(1)
|
||||||
|
{
|
||||||
|
Precision = 0.01,
|
||||||
|
MinValue = 0.1,
|
||||||
|
MaxValue = 10
|
||||||
|
};
|
||||||
|
|
||||||
|
public double SliderVelocityMultiplier
|
||||||
|
{
|
||||||
|
get => SliderVelocityMultiplierBindable.Value;
|
||||||
|
set => SliderVelocityMultiplierBindable.Value = value;
|
||||||
|
}
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
private double velocityFactor;
|
private double velocityFactor;
|
||||||
|
|
||||||
@ -34,10 +48,10 @@ namespace osu.Game.Rulesets.Catch.Objects
|
|||||||
private double tickDistanceFactor;
|
private double tickDistanceFactor;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public double Velocity => velocityFactor * DifficultyControlPoint.SliderVelocity;
|
public double Velocity => velocityFactor * SliderVelocityMultiplier;
|
||||||
|
|
||||||
[JsonIgnore]
|
[JsonIgnore]
|
||||||
public double TickDistance => tickDistanceFactor * DifficultyControlPoint.SliderVelocity;
|
public double TickDistance => tickDistanceFactor * SliderVelocityMultiplier;
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// The length of one span of this <see cref="JuiceStream"/>.
|
/// The length of one span of this <see cref="JuiceStream"/>.
|
||||||
|
@ -1,17 +1,30 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Scoring
|
namespace osu.Game.Rulesets.Catch.Scoring
|
||||||
{
|
{
|
||||||
public partial class CatchScoreProcessor : ScoreProcessor
|
public partial class CatchScoreProcessor : ScoreProcessor
|
||||||
{
|
{
|
||||||
|
private const int combo_cap = 200;
|
||||||
|
private const double combo_base = 4;
|
||||||
|
|
||||||
public CatchScoreProcessor()
|
public CatchScoreProcessor()
|
||||||
: base(new CatchRuleset())
|
: base(new CatchRuleset())
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override double ClassicScoreMultiplier => 28;
|
protected override double ComputeTotalScore(double comboProgress, double accuracyProgress, double bonusPortion)
|
||||||
|
{
|
||||||
|
return 600000 * comboProgress
|
||||||
|
+ 400000 * Accuracy.Value * accuracyProgress
|
||||||
|
+ bonusPortion;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override double GetComboScoreChange(JudgementResult result)
|
||||||
|
=> Judgement.ToNumericResult(result.Type) * Math.Min(Math.Max(0.5, Math.Log(result.ComboAfterJudgement, combo_base)), Math.Log(combo_cap, combo_base));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user