mirror of
https://github.com/ppy/osu.git
synced 2025-02-13 00:42:55 +08:00
Merge branch 'master' into fix-mania-editor-crash
This commit is contained in:
commit
418dbf3f3e
@ -2,12 +2,6 @@
|
|||||||
"version": 1,
|
"version": 1,
|
||||||
"isRoot": true,
|
"isRoot": true,
|
||||||
"tools": {
|
"tools": {
|
||||||
"cake.tool": {
|
|
||||||
"version": "0.35.0",
|
|
||||||
"commands": [
|
|
||||||
"dotnet-cake"
|
|
||||||
]
|
|
||||||
},
|
|
||||||
"dotnet-format": {
|
"dotnet-format": {
|
||||||
"version": "3.1.37601",
|
"version": "3.1.37601",
|
||||||
"commands": [
|
"commands": [
|
||||||
@ -20,14 +14,14 @@
|
|||||||
"jb"
|
"jb"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"nvika": {
|
"smoogipoo.nvika": {
|
||||||
"version": "2.0.0",
|
"version": "1.0.1",
|
||||||
"commands": [
|
"commands": [
|
||||||
"nvika"
|
"nvika"
|
||||||
]
|
]
|
||||||
},
|
},
|
||||||
"codefilesanity": {
|
"codefilesanity": {
|
||||||
"version": "15.0.0",
|
"version": "0.0.36",
|
||||||
"commands": [
|
"commands": [
|
||||||
"CodeFileSanity"
|
"CodeFileSanity"
|
||||||
]
|
]
|
||||||
@ -39,4 +33,4 @@
|
|||||||
]
|
]
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
93
.github/workflows/ci.yml
vendored
Normal file
93
.github/workflows/ci.yml
vendored
Normal file
@ -0,0 +1,93 @@
|
|||||||
|
on: [push, pull_request]
|
||||||
|
name: Continuous Integration
|
||||||
|
|
||||||
|
jobs:
|
||||||
|
test:
|
||||||
|
name: Test
|
||||||
|
runs-on: ${{matrix.os.fullname}}
|
||||||
|
env:
|
||||||
|
OSU_EXECUTION_MODE: ${{matrix.threadingMode}}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- { prettyname: Windows, fullname: windows-latest }
|
||||||
|
- { prettyname: macOS, fullname: macos-latest }
|
||||||
|
- { prettyname: Linux, fullname: ubuntu-latest }
|
||||||
|
threadingMode: ['SingleThread', 'MultiThreaded']
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
- name: Install .NET 5.0.x
|
||||||
|
uses: actions/setup-dotnet@v1
|
||||||
|
with:
|
||||||
|
dotnet-version: "5.0.x"
|
||||||
|
|
||||||
|
# FIXME: libavformat is not included in Ubuntu. Let's fix that.
|
||||||
|
# https://github.com/ppy/osu-framework/issues/4349
|
||||||
|
# Remove this once https://github.com/actions/virtual-environments/issues/3306 has been resolved.
|
||||||
|
- name: Install libavformat-dev
|
||||||
|
if: ${{matrix.os.fullname == 'ubuntu-latest'}}
|
||||||
|
run: |
|
||||||
|
sudo apt-get update && \
|
||||||
|
sudo apt-get -y install libavformat-dev
|
||||||
|
|
||||||
|
- name: Compile
|
||||||
|
run: dotnet build -c Debug -warnaserror osu.Desktop.slnf
|
||||||
|
|
||||||
|
- name: Test
|
||||||
|
run: dotnet test $pwd/*.Tests/bin/Debug/*/*.Tests.dll --logger "trx;LogFileName=TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx"
|
||||||
|
shell: pwsh
|
||||||
|
|
||||||
|
# Attempt to upload results even if test fails.
|
||||||
|
# https://docs.github.com/en/actions/reference/context-and-expression-syntax-for-github-actions#always
|
||||||
|
- name: Upload Test Results
|
||||||
|
uses: actions/upload-artifact@v2
|
||||||
|
if: ${{ always() }}
|
||||||
|
with:
|
||||||
|
name: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
|
||||||
|
path: ${{github.workspace}}/TestResults/TestResults-${{matrix.os.prettyname}}-${{matrix.threadingMode}}.trx
|
||||||
|
|
||||||
|
inspect-code:
|
||||||
|
name: Code Quality
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
steps:
|
||||||
|
- name: Checkout
|
||||||
|
uses: actions/checkout@v2
|
||||||
|
|
||||||
|
# FIXME: Tools won't run in .NET 5.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
|
||||||
|
- name: Install .NET 3.1.x LTS
|
||||||
|
uses: actions/setup-dotnet@v1
|
||||||
|
with:
|
||||||
|
dotnet-version: "3.1.x"
|
||||||
|
|
||||||
|
- name: Install .NET 5.0.x
|
||||||
|
uses: actions/setup-dotnet@v1
|
||||||
|
with:
|
||||||
|
dotnet-version: "5.0.x"
|
||||||
|
|
||||||
|
- name: Restore Tools
|
||||||
|
run: dotnet tool restore
|
||||||
|
|
||||||
|
- name: Restore Packages
|
||||||
|
run: dotnet restore
|
||||||
|
|
||||||
|
- name: CodeFileSanity
|
||||||
|
run: |
|
||||||
|
# TODO: Add ignore filters and GitHub Workflow Command Reporting in CFS. That way we don't have to do this workaround.
|
||||||
|
# FIXME: Suppress warnings from templates project
|
||||||
|
dotnet codefilesanity | while read -r line; do
|
||||||
|
echo "::warning::$line"
|
||||||
|
done
|
||||||
|
|
||||||
|
# Temporarily disabled due to test failures, but it won't work anyway until the tool is upgraded.
|
||||||
|
# - name: .NET Format (Dry Run)
|
||||||
|
# run: dotnet format --dry-run --check
|
||||||
|
|
||||||
|
- name: InspectCode
|
||||||
|
run: dotnet jb inspectcode $(pwd)/osu.Desktop.slnf --output=$(pwd)/inspectcodereport.xml --cachesDir=$(pwd)/inspectcode --verbosity=WARN
|
||||||
|
|
||||||
|
- name: NVika
|
||||||
|
run: dotnet nvika parsereport "${{github.workspace}}/inspectcodereport.xml" --treatwarningsaserrors
|
31
.github/workflows/report-nunit.yml
vendored
Normal file
31
.github/workflows/report-nunit.yml
vendored
Normal file
@ -0,0 +1,31 @@
|
|||||||
|
# This is a workaround to allow PRs to report their coverage. This will run inside the base repository.
|
||||||
|
# See:
|
||||||
|
# * https://github.com/dorny/test-reporter#recommended-setup-for-public-repositories
|
||||||
|
# * https://docs.github.com/en/actions/reference/authentication-in-a-workflow#permissions-for-the-github_token
|
||||||
|
name: Annotate CI run with test results
|
||||||
|
on:
|
||||||
|
workflow_run:
|
||||||
|
workflows: ["Continuous Integration"]
|
||||||
|
types:
|
||||||
|
- completed
|
||||||
|
jobs:
|
||||||
|
annotate:
|
||||||
|
name: Annotate CI run with test results
|
||||||
|
runs-on: ubuntu-latest
|
||||||
|
if: ${{ github.event.workflow_run.conclusion != 'cancelled' }}
|
||||||
|
strategy:
|
||||||
|
fail-fast: false
|
||||||
|
matrix:
|
||||||
|
os:
|
||||||
|
- { prettyname: Windows }
|
||||||
|
- { prettyname: macOS }
|
||||||
|
- { prettyname: Linux }
|
||||||
|
threadingMode: ['SingleThread', 'MultiThreaded']
|
||||||
|
steps:
|
||||||
|
- name: Annotate CI run with test results
|
||||||
|
uses: dorny/test-reporter@v1.4.2
|
||||||
|
with:
|
||||||
|
artifact: osu-test-results-${{matrix.os.prettyname}}-${{matrix.threadingMode}}
|
||||||
|
name: Test Results (${{matrix.os.prettyname}}, ${{matrix.threadingMode}})
|
||||||
|
path: "*.trx"
|
||||||
|
reporter: dotnet-trx
|
14
.vscode/launch.json
vendored
14
.vscode/launch.json
vendored
@ -113,20 +113,6 @@
|
|||||||
"cwd": "${workspaceRoot}",
|
"cwd": "${workspaceRoot}",
|
||||||
"preLaunchTask": "Build benchmarks",
|
"preLaunchTask": "Build benchmarks",
|
||||||
"console": "internalConsole"
|
"console": "internalConsole"
|
||||||
},
|
|
||||||
{
|
|
||||||
"name": "Cake: Debug Script",
|
|
||||||
"type": "coreclr",
|
|
||||||
"request": "launch",
|
|
||||||
"program": "${workspaceRoot}/build/tools/Cake.CoreCLR/0.30.0/Cake.dll",
|
|
||||||
"args": [
|
|
||||||
"${workspaceRoot}/build/build.cake",
|
|
||||||
"--debug",
|
|
||||||
"--verbosity=diagnostic"
|
|
||||||
],
|
|
||||||
"cwd": "${workspaceRoot}/build",
|
|
||||||
"stopAtEntry": true,
|
|
||||||
"externalConsole": false
|
|
||||||
}
|
}
|
||||||
]
|
]
|
||||||
}
|
}
|
||||||
|
@ -1,27 +1,11 @@
|
|||||||
[CmdletBinding()]
|
|
||||||
Param(
|
|
||||||
[string]$Target,
|
|
||||||
[string]$Configuration,
|
|
||||||
[ValidateSet("Quiet", "Minimal", "Normal", "Verbose", "Diagnostic")]
|
|
||||||
[string]$Verbosity,
|
|
||||||
[switch]$ShowDescription,
|
|
||||||
[Alias("WhatIf", "Noop")]
|
|
||||||
[switch]$DryRun,
|
|
||||||
[Parameter(Position = 0, Mandatory = $false, ValueFromRemainingArguments = $true)]
|
|
||||||
[string[]]$ScriptArgs
|
|
||||||
)
|
|
||||||
|
|
||||||
# Build Cake arguments
|
|
||||||
$cakeArguments = "";
|
|
||||||
if ($Target) { $cakeArguments += "-target=$Target" }
|
|
||||||
if ($Configuration) { $cakeArguments += "-configuration=$Configuration" }
|
|
||||||
if ($Verbosity) { $cakeArguments += "-verbosity=$Verbosity" }
|
|
||||||
if ($ShowDescription) { $cakeArguments += "-showdescription" }
|
|
||||||
if ($DryRun) { $cakeArguments += "-dryrun" }
|
|
||||||
if ($Experimental) { $cakeArguments += "-experimental" }
|
|
||||||
$cakeArguments += $ScriptArgs
|
|
||||||
|
|
||||||
dotnet tool restore
|
dotnet tool restore
|
||||||
dotnet cake ./build/InspectCode.cake --bootstrap
|
|
||||||
dotnet cake ./build/InspectCode.cake $cakeArguments
|
# Temporarily disabled until the tool is upgraded to 5.0.
|
||||||
exit $LASTEXITCODE
|
# The version specified in .config/dotnet-tools.json (3.1.37601) won't run on .NET hosts >=5.0.7.
|
||||||
|
# - cmd: dotnet format --dry-run --check
|
||||||
|
|
||||||
|
dotnet CodeFileSanity
|
||||||
|
dotnet jb inspectcode "osu.Desktop.slnf" --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN
|
||||||
|
dotnet nvika parsereport "inspectcodereport.xml" --treatwarningsaserrors
|
||||||
|
|
||||||
|
exit $LASTEXITCODE
|
||||||
|
6
InspectCode.sh
Executable file
6
InspectCode.sh
Executable file
@ -0,0 +1,6 @@
|
|||||||
|
#!/bin/bash
|
||||||
|
|
||||||
|
dotnet tool restore
|
||||||
|
dotnet CodeFileSanity
|
||||||
|
dotnet jb inspectcode "osu.Desktop.slnf" --output="inspectcodereport.xml" --caches-home="inspectcode" --verbosity=WARN
|
||||||
|
dotnet nvika parsereport "inspectcodereport.xml" --treatwarningsaserrors
|
19
appveyor.yml
19
appveyor.yml
@ -1,28 +1,27 @@
|
|||||||
clone_depth: 1
|
clone_depth: 1
|
||||||
version: '{branch}-{build}'
|
version: '{branch}-{build}'
|
||||||
image: Visual Studio 2019
|
image: Visual Studio 2019
|
||||||
|
cache:
|
||||||
|
- '%LOCALAPPDATA%\NuGet\v3-cache -> appveyor.yml'
|
||||||
|
|
||||||
dotnet_csproj:
|
dotnet_csproj:
|
||||||
patch: true
|
patch: true
|
||||||
file: 'osu.Game\osu.Game.csproj' # Use wildcard when it's able to exclude Xamarin projects
|
file: 'osu.Game\osu.Game.csproj' # Use wildcard when it's able to exclude Xamarin projects
|
||||||
version: '0.0.{build}'
|
version: '0.0.{build}'
|
||||||
cache:
|
|
||||||
- '%LOCALAPPDATA%\NuGet\v3-cache -> appveyor.yml'
|
|
||||||
before_build:
|
before_build:
|
||||||
- ps: dotnet --info # Useful when version mismatch between CI and local
|
- cmd: dotnet --info # Useful when version mismatch between CI and local
|
||||||
- ps: nuget restore -verbosity quiet # Only nuget.exe knows both new (.NET Core) and old (Xamarin) projects
|
- cmd: nuget restore -verbosity quiet # Only nuget.exe knows both new (.NET Core) and old (Xamarin) projects
|
||||||
|
|
||||||
build:
|
build:
|
||||||
project: osu.sln
|
project: osu.sln
|
||||||
parallel: true
|
parallel: true
|
||||||
verbosity: minimal
|
verbosity: minimal
|
||||||
publish_nuget: true
|
publish_nuget: true
|
||||||
|
|
||||||
after_build:
|
after_build:
|
||||||
- ps: dotnet tool restore
|
|
||||||
|
|
||||||
# Temporarily disabled until the tool is upgraded to 5.0.
|
|
||||||
# The version specified in .config/dotnet-tools.json (3.1.37601) won't run on .NET hosts >=5.0.7.
|
|
||||||
# - ps: dotnet format --dry-run --check
|
|
||||||
|
|
||||||
- ps: .\InspectCode.ps1
|
- ps: .\InspectCode.ps1
|
||||||
|
|
||||||
test:
|
test:
|
||||||
assemblies:
|
assemblies:
|
||||||
except:
|
except:
|
||||||
|
@ -1,17 +0,0 @@
|
|||||||
<Project Sdk="Microsoft.Build.Traversal">
|
|
||||||
<ItemGroup>
|
|
||||||
<ProjectReference Include="..\osu.Desktop\osu.Desktop.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch.Tests\osu.Game.Rulesets.Catch.Tests.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Catch\osu.Game.Rulesets.Catch.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Mania.Tests\osu.Game.Rulesets.Mania.Tests.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Mania\osu.Game.Rulesets.Mania.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu.Tests\osu.Game.Rulesets.Osu.Tests.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Osu\osu.Game.Rulesets.Osu.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Taiko.Tests\osu.Game.Rulesets.Taiko.Tests.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game.Rulesets.Taiko\osu.Game.Rulesets.Taiko.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game.Tests\osu.Game.Tests.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game.Tournament.Tests\osu.Game.Tournament.Tests.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game.Tournament\osu.Game.Tournament.csproj" />
|
|
||||||
<ProjectReference Include="..\osu.Game\osu.Game.csproj" />
|
|
||||||
</ItemGroup>
|
|
||||||
</Project>
|
|
@ -1,41 +0,0 @@
|
|||||||
#addin "nuget:?package=CodeFileSanity&version=0.0.36"
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// ARGUMENTS
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
var target = Argument("target", "CodeAnalysis");
|
|
||||||
var configuration = Argument("configuration", "Release");
|
|
||||||
|
|
||||||
var rootDirectory = new DirectoryPath("..");
|
|
||||||
var sln = rootDirectory.CombineWithFilePath("osu.sln");
|
|
||||||
var desktopSlnf = rootDirectory.CombineWithFilePath("osu.Desktop.slnf");
|
|
||||||
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
// TASKS
|
|
||||||
///////////////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
Task("InspectCode")
|
|
||||||
.Does(() => {
|
|
||||||
var inspectcodereport = "inspectcodereport.xml";
|
|
||||||
var cacheDir = "inspectcode";
|
|
||||||
var verbosity = AppVeyor.IsRunningOnAppVeyor ? "WARN" : "INFO"; // Don't flood CI output
|
|
||||||
|
|
||||||
DotNetCoreTool(rootDirectory.FullPath,
|
|
||||||
"jb", $@"inspectcode ""{desktopSlnf}"" --output=""{inspectcodereport}"" --caches-home=""{cacheDir}"" --verbosity={verbosity}");
|
|
||||||
DotNetCoreTool(rootDirectory.FullPath, "nvika", $@"parsereport ""{inspectcodereport}"" --treatwarningsaserrors");
|
|
||||||
});
|
|
||||||
|
|
||||||
Task("CodeFileSanity")
|
|
||||||
.Does(() => {
|
|
||||||
ValidateCodeSanity(new ValidateCodeSanitySettings {
|
|
||||||
RootDirectory = rootDirectory.FullPath,
|
|
||||||
IsAppveyorBuild = AppVeyor.IsRunningOnAppVeyor
|
|
||||||
});
|
|
||||||
});
|
|
||||||
|
|
||||||
Task("CodeAnalysis")
|
|
||||||
.IsDependentOn("CodeFileSanity")
|
|
||||||
.IsDependentOn("InspectCode");
|
|
||||||
|
|
||||||
RunTarget(target);
|
|
@ -1,5 +0,0 @@
|
|||||||
|
|
||||||
[Nuget]
|
|
||||||
Source=https://api.nuget.org/v3/index.json
|
|
||||||
UseInProcessClient=true
|
|
||||||
LoadDependencies=true
|
|
@ -51,7 +51,7 @@
|
|||||||
<Reference Include="Java.Interop" />
|
<Reference Include="Java.Interop" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.611.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.614.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.614.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.616.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
102
osu.Game.Rulesets.Osu/Mods/OsuModApproachDifferent.cs
Normal file
102
osu.Game.Rulesets.Osu/Mods/OsuModApproachDifferent.cs
Normal file
@ -0,0 +1,102 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
|
{
|
||||||
|
public class OsuModApproachDifferent : Mod, IApplicableToDrawableHitObjects
|
||||||
|
{
|
||||||
|
public override string Name => "Approach Different";
|
||||||
|
public override string Acronym => "AD";
|
||||||
|
public override string Description => "Never trust the approach circles...";
|
||||||
|
public override double ScoreMultiplier => 1;
|
||||||
|
public override IconUsage? Icon { get; } = FontAwesome.Regular.Circle;
|
||||||
|
|
||||||
|
[SettingSource("Initial size", "Change the initial size of the approach circle, relative to hit circles.", 0)]
|
||||||
|
public BindableFloat Scale { get; } = new BindableFloat(4)
|
||||||
|
{
|
||||||
|
Precision = 0.1f,
|
||||||
|
MinValue = 2,
|
||||||
|
MaxValue = 10,
|
||||||
|
};
|
||||||
|
|
||||||
|
[SettingSource("Style", "Change the animation style of the approach circles.", 1)]
|
||||||
|
public Bindable<AnimationStyle> Style { get; } = new Bindable<AnimationStyle>();
|
||||||
|
|
||||||
|
public void ApplyToDrawableHitObjects(IEnumerable<DrawableHitObject> drawables)
|
||||||
|
{
|
||||||
|
drawables.ForEach(drawable =>
|
||||||
|
{
|
||||||
|
drawable.ApplyCustomUpdateState += (drawableObject, state) =>
|
||||||
|
{
|
||||||
|
if (!(drawableObject is DrawableHitCircle drawableHitCircle)) return;
|
||||||
|
|
||||||
|
var hitCircle = drawableHitCircle.HitObject;
|
||||||
|
|
||||||
|
drawableHitCircle.ApproachCircle.ClearTransforms(targetMember: nameof(Scale));
|
||||||
|
|
||||||
|
using (drawableHitCircle.BeginAbsoluteSequence(hitCircle.StartTime - hitCircle.TimePreempt))
|
||||||
|
drawableHitCircle.ApproachCircle.ScaleTo(Scale.Value).ScaleTo(1f, hitCircle.TimePreempt, getEasing(Style.Value));
|
||||||
|
};
|
||||||
|
});
|
||||||
|
}
|
||||||
|
|
||||||
|
private Easing getEasing(AnimationStyle style)
|
||||||
|
{
|
||||||
|
switch (style)
|
||||||
|
{
|
||||||
|
default:
|
||||||
|
return Easing.None;
|
||||||
|
|
||||||
|
case AnimationStyle.Accelerate1:
|
||||||
|
return Easing.In;
|
||||||
|
|
||||||
|
case AnimationStyle.Accelerate2:
|
||||||
|
return Easing.InCubic;
|
||||||
|
|
||||||
|
case AnimationStyle.Accelerate3:
|
||||||
|
return Easing.InQuint;
|
||||||
|
|
||||||
|
case AnimationStyle.Gravity:
|
||||||
|
return Easing.InBack;
|
||||||
|
|
||||||
|
case AnimationStyle.Decelerate1:
|
||||||
|
return Easing.Out;
|
||||||
|
|
||||||
|
case AnimationStyle.Decelerate2:
|
||||||
|
return Easing.OutCubic;
|
||||||
|
|
||||||
|
case AnimationStyle.Decelerate3:
|
||||||
|
return Easing.OutQuint;
|
||||||
|
|
||||||
|
case AnimationStyle.InOut1:
|
||||||
|
return Easing.InOutCubic;
|
||||||
|
|
||||||
|
case AnimationStyle.InOut2:
|
||||||
|
return Easing.InOutQuint;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public enum AnimationStyle
|
||||||
|
{
|
||||||
|
Gravity,
|
||||||
|
InOut1,
|
||||||
|
InOut2,
|
||||||
|
Accelerate1,
|
||||||
|
Accelerate2,
|
||||||
|
Accelerate3,
|
||||||
|
Decelerate1,
|
||||||
|
Decelerate2,
|
||||||
|
Decelerate3,
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -187,6 +187,7 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
new MultiMod(new ModWindUp(), new ModWindDown()),
|
new MultiMod(new ModWindUp(), new ModWindDown()),
|
||||||
new OsuModTraceable(),
|
new OsuModTraceable(),
|
||||||
new OsuModBarrelRoll(),
|
new OsuModBarrelRoll(),
|
||||||
|
new OsuModApproachDifferent(),
|
||||||
};
|
};
|
||||||
|
|
||||||
case ModType.System:
|
case ModType.System:
|
||||||
|
@ -12,6 +12,7 @@ using osu.Game.Rulesets.Osu.Objects;
|
|||||||
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
using osu.Game.Rulesets.Osu.Objects.Drawables;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
||||||
{
|
{
|
||||||
@ -40,6 +41,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
Anchor = Anchor.TopCentre,
|
Anchor = Anchor.TopCentre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Texture = source.GetTexture("spinner-background"),
|
Texture = source.GetTexture("spinner-background"),
|
||||||
|
Colour = source.GetConfig<OsuSkinColour, Color4>(OsuSkinColour.SpinnerBackground)?.Value ?? new Color4(100, 100, 100, 255),
|
||||||
Scale = new Vector2(SPRITE_SCALE),
|
Scale = new Vector2(SPRITE_SCALE),
|
||||||
Y = SPINNER_Y_CENTRE,
|
Y = SPINNER_Y_CENTRE,
|
||||||
},
|
},
|
||||||
|
@ -7,6 +7,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
|
|||||||
{
|
{
|
||||||
SliderTrackOverride,
|
SliderTrackOverride,
|
||||||
SliderBorder,
|
SliderBorder,
|
||||||
SliderBall
|
SliderBall,
|
||||||
|
SpinnerBackground,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
12
osu.Game.Rulesets.Taiko.Tests/Mods/TaikoModTestScene.cs
Normal file
12
osu.Game.Rulesets.Taiko.Tests/Mods/TaikoModTestScene.cs
Normal file
@ -0,0 +1,12 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Tests.Mods
|
||||||
|
{
|
||||||
|
public abstract class TaikoModTestScene : ModTestScene
|
||||||
|
{
|
||||||
|
protected sealed override Ruleset CreatePlayerRuleset() => new TaikoRuleset();
|
||||||
|
}
|
||||||
|
}
|
@ -0,0 +1,24 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Game.Rulesets.Taiko.Mods;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Taiko.Tests.Mods
|
||||||
|
{
|
||||||
|
public class TestSceneTaikoModHidden : TaikoModTestScene
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestDefaultBeatmapTest() => CreateModTest(new ModTestData
|
||||||
|
{
|
||||||
|
Mod = new TaikoModHidden(),
|
||||||
|
Autoplay = true,
|
||||||
|
PassCondition = checkSomeAutoplayHits
|
||||||
|
});
|
||||||
|
|
||||||
|
private bool checkSomeAutoplayHits()
|
||||||
|
=> Player.ScoreProcessor.JudgedHits >= 4
|
||||||
|
&& Player.Results.All(result => result.Type == result.Judgement.MaxResult);
|
||||||
|
}
|
||||||
|
}
|
@ -1,23 +1,93 @@
|
|||||||
// 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 osu.Framework.Graphics;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
using osu.Game.Rulesets.Objects.Drawables;
|
using osu.Game.Rulesets.Objects.Drawables;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Rulesets.Taiko.Objects.Drawables;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Mods
|
namespace osu.Game.Rulesets.Taiko.Mods
|
||||||
{
|
{
|
||||||
public class TaikoModHidden : ModHidden
|
public class TaikoModHidden : ModHidden, IApplicableToDifficulty
|
||||||
{
|
{
|
||||||
public override string Description => @"Beats fade out before you hit them!";
|
public override string Description => @"Beats fade out before you hit them!";
|
||||||
public override double ScoreMultiplier => 1.06;
|
public override double ScoreMultiplier => 1.06;
|
||||||
public override bool HasImplementation => false;
|
|
||||||
|
/// <summary>
|
||||||
|
/// In osu-stable, the hit position is 160, so the active playfield is essentially 160 pixels shorter
|
||||||
|
/// than the actual screen width. The normalized playfield height is 480, so on a 4:3 screen the
|
||||||
|
/// playfield ratio of the active area up to the hit position will actually be (640 - 160) / 480 = 1.
|
||||||
|
/// For custom resolutions/aspect ratios (x:y), the screen width given the normalized height becomes 480 * x / y instead,
|
||||||
|
/// and the playfield ratio becomes (480 * x / y - 160) / 480 = x / y - 1/3.
|
||||||
|
/// This constant is equal to the playfield ratio on 4:3 screens divided by the playfield ratio on 16:9 screens.
|
||||||
|
/// </summary>
|
||||||
|
private const double hd_sv_scale = (4.0 / 3.0 - 1.0 / 3.0) / (16.0 / 9.0 - 1.0 / 3.0);
|
||||||
|
|
||||||
|
private double originalSliderMultiplier;
|
||||||
|
|
||||||
|
private ControlPointInfo controlPointInfo;
|
||||||
|
|
||||||
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
protected override void ApplyIncreasedVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
||||||
{
|
{
|
||||||
|
ApplyNormalVisibilityState(hitObject, state);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected double MultiplierAt(double position)
|
||||||
|
{
|
||||||
|
double beatLength = controlPointInfo.TimingPointAt(position).BeatLength;
|
||||||
|
double speedMultiplier = controlPointInfo.DifficultyPointAt(position).SpeedMultiplier;
|
||||||
|
|
||||||
|
return originalSliderMultiplier * speedMultiplier * TimingControlPoint.DEFAULT_BEAT_LENGTH / beatLength;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
protected override void ApplyNormalVisibilityState(DrawableHitObject hitObject, ArmedState state)
|
||||||
{
|
{
|
||||||
|
switch (hitObject)
|
||||||
|
{
|
||||||
|
case DrawableDrumRollTick _:
|
||||||
|
case DrawableHit _:
|
||||||
|
double preempt = 10000 / MultiplierAt(hitObject.HitObject.StartTime);
|
||||||
|
double start = hitObject.HitObject.StartTime - preempt * 0.6;
|
||||||
|
double duration = preempt * 0.3;
|
||||||
|
|
||||||
|
using (hitObject.BeginAbsoluteSequence(start))
|
||||||
|
{
|
||||||
|
hitObject.FadeOut(duration);
|
||||||
|
|
||||||
|
// DrawableHitObject sets LifetimeEnd to LatestTransformEndTime if it isn't manually changed.
|
||||||
|
// in order for the object to not be killed before its actual end time (as the latest transform ends earlier), set lifetime end explicitly.
|
||||||
|
hitObject.LifetimeEnd = state == ArmedState.Idle || !hitObject.AllJudged
|
||||||
|
? hitObject.HitObject.GetEndTime() + hitObject.HitObject.HitWindows.WindowFor(HitResult.Miss)
|
||||||
|
: hitObject.HitStateUpdateTime;
|
||||||
|
}
|
||||||
|
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ReadFromDifficulty(BeatmapDifficulty difficulty)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
public void ApplyToDifficulty(BeatmapDifficulty difficulty)
|
||||||
|
{
|
||||||
|
// needs to be read after all processing has been run (TaikoBeatmapConverter applies an adjustment which would otherwise be omitted).
|
||||||
|
originalSliderMultiplier = difficulty.SliderMultiplier;
|
||||||
|
|
||||||
|
// osu-stable has an added playfield cover that essentially forces a 4:3 playfield ratio, by cutting off all objects past that size.
|
||||||
|
// This is not yet implemented; instead a playfield adjustment container is present which maintains a 16:9 ratio.
|
||||||
|
// For now, increase the slider multiplier proportionally so that the notes stay on the screen for the same amount of time as on stable.
|
||||||
|
// Note that this means that the notes will scroll faster as they have a longer distance to travel on the screen in that same amount of time.
|
||||||
|
difficulty.SliderMultiplier /= hd_sv_scale;
|
||||||
|
}
|
||||||
|
|
||||||
|
public override void ApplyToBeatmap(IBeatmap beatmap)
|
||||||
|
{
|
||||||
|
controlPointInfo = beatmap.ControlPointInfo;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -113,7 +113,6 @@ namespace osu.Game.Tests.Collections.IO
|
|||||||
await importCollectionsFromStream(osu, ms);
|
await importCollectionsFromStream(osu, ms);
|
||||||
}
|
}
|
||||||
|
|
||||||
Assert.That(host.UpdateThread.Running, Is.True);
|
|
||||||
Assert.That(exceptionThrown, Is.False);
|
Assert.That(exceptionThrown, Is.False);
|
||||||
Assert.That(osu.CollectionManager.Collections.Count, Is.EqualTo(0));
|
Assert.That(osu.CollectionManager.Collections.Count, Is.EqualTo(0));
|
||||||
}
|
}
|
||||||
|
@ -161,15 +161,18 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
|
|
||||||
private void loadNextBackground()
|
private void loadNextBackground()
|
||||||
{
|
{
|
||||||
|
SeasonalBackground previousBackground = null;
|
||||||
SeasonalBackground background = null;
|
SeasonalBackground background = null;
|
||||||
|
|
||||||
AddStep("create next background", () =>
|
AddStep("create next background", () =>
|
||||||
{
|
{
|
||||||
|
previousBackground = (SeasonalBackground)backgroundContainer.SingleOrDefault();
|
||||||
background = backgroundLoader.LoadNextBackground();
|
background = backgroundLoader.LoadNextBackground();
|
||||||
LoadComponentAsync(background, bg => backgroundContainer.Child = bg);
|
LoadComponentAsync(background, bg => backgroundContainer.Child = bg);
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("background loaded", () => background.IsLoaded);
|
AddUntilStep("background loaded", () => background.IsLoaded);
|
||||||
|
AddAssert("background is different", () => !background.Equals(previousBackground));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void assertAnyBackground()
|
private void assertAnyBackground()
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Lists;
|
using osu.Framework.Lists;
|
||||||
@ -66,6 +67,7 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="time">The time to find the difficulty control point at.</param>
|
/// <param name="time">The time to find the difficulty control point at.</param>
|
||||||
/// <returns>The difficulty control point.</returns>
|
/// <returns>The difficulty control point.</returns>
|
||||||
|
[NotNull]
|
||||||
public DifficultyControlPoint DifficultyPointAt(double time) => binarySearchWithFallback(DifficultyPoints, time, DifficultyControlPoint.DEFAULT);
|
public DifficultyControlPoint DifficultyPointAt(double time) => binarySearchWithFallback(DifficultyPoints, time, DifficultyControlPoint.DEFAULT);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -73,6 +75,7 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="time">The time to find the effect control point at.</param>
|
/// <param name="time">The time to find the effect control point at.</param>
|
||||||
/// <returns>The effect control point.</returns>
|
/// <returns>The effect control point.</returns>
|
||||||
|
[NotNull]
|
||||||
public EffectControlPoint EffectPointAt(double time) => binarySearchWithFallback(EffectPoints, time, EffectControlPoint.DEFAULT);
|
public EffectControlPoint EffectPointAt(double time) => binarySearchWithFallback(EffectPoints, time, EffectControlPoint.DEFAULT);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -80,6 +83,7 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="time">The time to find the sound control point at.</param>
|
/// <param name="time">The time to find the sound control point at.</param>
|
||||||
/// <returns>The sound control point.</returns>
|
/// <returns>The sound control point.</returns>
|
||||||
|
[NotNull]
|
||||||
public SampleControlPoint SamplePointAt(double time) => binarySearchWithFallback(SamplePoints, time, SamplePoints.Count > 0 ? SamplePoints[0] : SampleControlPoint.DEFAULT);
|
public SampleControlPoint SamplePointAt(double time) => binarySearchWithFallback(SamplePoints, time, SamplePoints.Count > 0 ? SamplePoints[0] : SampleControlPoint.DEFAULT);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -87,6 +91,7 @@ namespace osu.Game.Beatmaps.ControlPoints
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="time">The time to find the timing control point at.</param>
|
/// <param name="time">The time to find the timing control point at.</param>
|
||||||
/// <returns>The timing control point.</returns>
|
/// <returns>The timing control point.</returns>
|
||||||
|
[NotNull]
|
||||||
public TimingControlPoint TimingPointAt(double time) => binarySearchWithFallback(TimingPoints, time, TimingPoints.Count > 0 ? TimingPoints[0] : TimingControlPoint.DEFAULT);
|
public TimingControlPoint TimingPointAt(double time) => binarySearchWithFallback(TimingPoints, time, TimingPoints.Count > 0 ? TimingPoints[0] : TimingControlPoint.DEFAULT);
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -101,10 +101,20 @@ namespace osu.Game.Beatmaps
|
|||||||
/// Rulesets ordered descending by their respective recommended difficulties.
|
/// Rulesets ordered descending by their respective recommended difficulties.
|
||||||
/// The currently selected ruleset will always be first.
|
/// The currently selected ruleset will always be first.
|
||||||
/// </returns>
|
/// </returns>
|
||||||
private IEnumerable<RulesetInfo> orderedRulesets =>
|
private IEnumerable<RulesetInfo> orderedRulesets
|
||||||
recommendedDifficultyMapping
|
{
|
||||||
.OrderByDescending(pair => pair.Value).Select(pair => pair.Key).Where(r => !r.Equals(ruleset.Value))
|
get
|
||||||
.Prepend(ruleset.Value);
|
{
|
||||||
|
if (LoadState < LoadState.Ready || ruleset.Value == null)
|
||||||
|
return Enumerable.Empty<RulesetInfo>();
|
||||||
|
|
||||||
|
return recommendedDifficultyMapping
|
||||||
|
.OrderByDescending(pair => pair.Value)
|
||||||
|
.Select(pair => pair.Key)
|
||||||
|
.Where(r => !r.Equals(ruleset.Value))
|
||||||
|
.Prepend(ruleset.Value);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
private void onlineStateChanged(ValueChangedEvent<APIState> state) => Schedule(() =>
|
private void onlineStateChanged(ValueChangedEvent<APIState> state) => Schedule(() =>
|
||||||
{
|
{
|
||||||
|
33
osu.Game/Extensions/LanguageExtensions.cs
Normal file
33
osu.Game/Extensions/LanguageExtensions.cs
Normal file
@ -0,0 +1,33 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using System.Globalization;
|
||||||
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
|
namespace osu.Game.Extensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Conversion utilities for the <see cref="Language"/> enum.
|
||||||
|
/// </summary>
|
||||||
|
public static class LanguageExtensions
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Returns the culture code of the <see cref="CultureInfo"/> that corresponds to the supplied <paramref name="language"/>.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is required as enum member names are not allowed to contain hyphens.
|
||||||
|
/// </remarks>
|
||||||
|
public static string ToCultureCode(this Language language)
|
||||||
|
=> language.ToString().Replace("_", "-");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Attempts to parse the supplied <paramref name="cultureCode"/> to a <see cref="Language"/> value.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="cultureCode">The code of the culture to parse.</param>
|
||||||
|
/// <param name="language">The parsed <see cref="Language"/>. Valid only if the return value of the method is <see langword="true" />.</param>
|
||||||
|
/// <returns>Whether the parsing succeeded.</returns>
|
||||||
|
public static bool TryParseCultureCode(string cultureCode, out Language language)
|
||||||
|
=> Enum.TryParse(cultureCode.Replace("-", "_"), out language);
|
||||||
|
}
|
||||||
|
}
|
@ -99,5 +99,14 @@ namespace osu.Game.Graphics.Backgrounds
|
|||||||
// ensure we're not loading in without a transition.
|
// ensure we're not loading in without a transition.
|
||||||
this.FadeInFromZero(200, Easing.InOutSine);
|
this.FadeInFromZero(200, Easing.InOutSine);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public override bool Equals(Background other)
|
||||||
|
{
|
||||||
|
if (ReferenceEquals(null, other)) return false;
|
||||||
|
if (ReferenceEquals(this, other)) return true;
|
||||||
|
|
||||||
|
return other.GetType() == GetType()
|
||||||
|
&& ((SeasonalBackground)other).url == url;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -160,7 +160,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
Margin = new MarginPadding { Top = 5, Bottom = 5 },
|
Margin = new MarginPadding { Top = 5, Bottom = 5 },
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Text = (value as IHasDescription)?.Description ?? (value as Enum)?.GetDescription() ?? value.ToString(),
|
Text = (value as IHasDescription)?.Description ?? (value as Enum)?.GetLocalisableDescription() ?? value.ToString(),
|
||||||
Font = OsuFont.GetFont(size: 14)
|
Font = OsuFont.GetFont(size: 14)
|
||||||
},
|
},
|
||||||
Bar = new Box
|
Bar = new Box
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
@ -81,7 +82,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
Active.BindValueChanged(active => Text.Font = Text.Font.With(Typeface.Torus, weight: active.NewValue ? FontWeight.Bold : FontWeight.Medium), true);
|
Active.BindValueChanged(active => Text.Font = Text.Font.With(Typeface.Torus, weight: active.NewValue ? FontWeight.Bold : FontWeight.Medium), true);
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual string CreateText() => (Value as Enum)?.GetDescription() ?? Value.ToString();
|
protected virtual LocalisableString CreateText() => (Value as Enum)?.GetLocalisableDescription() ?? Value.ToString();
|
||||||
|
|
||||||
protected override bool OnHover(HoverEvent e)
|
protected override bool OnHover(HoverEvent e)
|
||||||
{
|
{
|
||||||
|
@ -10,7 +10,104 @@ namespace osu.Game.Localisation
|
|||||||
[Description(@"English")]
|
[Description(@"English")]
|
||||||
en,
|
en,
|
||||||
|
|
||||||
|
// TODO: Requires Arabic glyphs to be added to resources (and possibly also RTL support).
|
||||||
|
// [Description(@"اَلْعَرَبِيَّةُ")]
|
||||||
|
// ar,
|
||||||
|
|
||||||
|
// TODO: Some accented glyphs are missing. Revisit when adding Inter.
|
||||||
|
// [Description(@"Беларуская мова")]
|
||||||
|
// be,
|
||||||
|
|
||||||
|
[Description(@"Български")]
|
||||||
|
bg,
|
||||||
|
|
||||||
|
[Description(@"Česky")]
|
||||||
|
cs,
|
||||||
|
|
||||||
|
[Description(@"Dansk")]
|
||||||
|
da,
|
||||||
|
|
||||||
|
[Description(@"Deutsch")]
|
||||||
|
de,
|
||||||
|
|
||||||
|
// TODO: Some accented glyphs are missing. Revisit when adding Inter.
|
||||||
|
// [Description(@"Ελληνικά")]
|
||||||
|
// el,
|
||||||
|
|
||||||
|
[Description(@"español")]
|
||||||
|
es,
|
||||||
|
|
||||||
|
[Description(@"Suomi")]
|
||||||
|
fi,
|
||||||
|
|
||||||
|
[Description(@"français")]
|
||||||
|
fr,
|
||||||
|
|
||||||
|
[Description(@"Magyar")]
|
||||||
|
hu,
|
||||||
|
|
||||||
|
[Description(@"Bahasa Indonesia")]
|
||||||
|
id,
|
||||||
|
|
||||||
|
[Description(@"Italiano")]
|
||||||
|
it,
|
||||||
|
|
||||||
[Description(@"日本語")]
|
[Description(@"日本語")]
|
||||||
ja
|
ja,
|
||||||
|
|
||||||
|
[Description(@"한국어")]
|
||||||
|
ko,
|
||||||
|
|
||||||
|
[Description(@"Nederlands")]
|
||||||
|
nl,
|
||||||
|
|
||||||
|
[Description(@"Norsk")]
|
||||||
|
no,
|
||||||
|
|
||||||
|
[Description(@"polski")]
|
||||||
|
pl,
|
||||||
|
|
||||||
|
[Description(@"Português")]
|
||||||
|
pt,
|
||||||
|
|
||||||
|
[Description(@"Português (Brasil)")]
|
||||||
|
pt_br,
|
||||||
|
|
||||||
|
[Description(@"Română")]
|
||||||
|
ro,
|
||||||
|
|
||||||
|
[Description(@"Русский")]
|
||||||
|
ru,
|
||||||
|
|
||||||
|
[Description(@"Slovenčina")]
|
||||||
|
sk,
|
||||||
|
|
||||||
|
[Description(@"Svenska")]
|
||||||
|
sv,
|
||||||
|
|
||||||
|
[Description(@"ไทย")]
|
||||||
|
th,
|
||||||
|
|
||||||
|
[Description(@"Tagalog")]
|
||||||
|
tl,
|
||||||
|
|
||||||
|
[Description(@"Türkçe")]
|
||||||
|
tr,
|
||||||
|
|
||||||
|
// TODO: Some accented glyphs are missing. Revisit when adding Inter.
|
||||||
|
// [Description(@"Українська мова")]
|
||||||
|
// uk,
|
||||||
|
|
||||||
|
[Description(@"Tiếng Việt")]
|
||||||
|
vi,
|
||||||
|
|
||||||
|
[Description(@"简体中文")]
|
||||||
|
zh,
|
||||||
|
|
||||||
|
[Description(@"繁體中文(香港)")]
|
||||||
|
zh_hk,
|
||||||
|
|
||||||
|
[Description(@"繁體中文(台灣)")]
|
||||||
|
zh_tw
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -50,8 +50,10 @@ using osu.Game.Updater;
|
|||||||
using osu.Game.Utils;
|
using osu.Game.Utils;
|
||||||
using LogLevel = osu.Framework.Logging.LogLevel;
|
using LogLevel = osu.Framework.Logging.LogLevel;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Extensions;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
|
using osu.Game.Performance;
|
||||||
using osu.Game.Skinning.Editor;
|
using osu.Game.Skinning.Editor;
|
||||||
|
|
||||||
namespace osu.Game
|
namespace osu.Game
|
||||||
@ -426,9 +428,12 @@ namespace osu.Game
|
|||||||
{
|
{
|
||||||
// The given ScoreInfo may have missing properties if it was retrieved from online data. Re-retrieve it from the database
|
// The given ScoreInfo may have missing properties if it was retrieved from online data. Re-retrieve it from the database
|
||||||
// to ensure all the required data for presenting a replay are present.
|
// to ensure all the required data for presenting a replay are present.
|
||||||
var databasedScoreInfo = score.OnlineScoreID != null
|
ScoreInfo databasedScoreInfo = null;
|
||||||
? ScoreManager.Query(s => s.OnlineScoreID == score.OnlineScoreID)
|
|
||||||
: ScoreManager.Query(s => s.Hash == score.Hash);
|
if (score.OnlineScoreID != null)
|
||||||
|
databasedScoreInfo = ScoreManager.Query(s => s.OnlineScoreID == score.OnlineScoreID);
|
||||||
|
|
||||||
|
databasedScoreInfo ??= ScoreManager.Query(s => s.Hash == score.Hash);
|
||||||
|
|
||||||
if (databasedScoreInfo == null)
|
if (databasedScoreInfo == null)
|
||||||
{
|
{
|
||||||
@ -484,6 +489,8 @@ namespace osu.Game
|
|||||||
|
|
||||||
protected virtual UpdateManager CreateUpdateManager() => new UpdateManager();
|
protected virtual UpdateManager CreateUpdateManager() => new UpdateManager();
|
||||||
|
|
||||||
|
protected virtual HighPerformanceSession CreateHighPerformanceSession() => new HighPerformanceSession();
|
||||||
|
|
||||||
protected override Container CreateScalingContainer() => new ScalingContainer(ScalingMode.Everything);
|
protected override Container CreateScalingContainer() => new ScalingContainer(ScalingMode.Everything);
|
||||||
|
|
||||||
#region Beatmap progression
|
#region Beatmap progression
|
||||||
@ -577,7 +584,7 @@ namespace osu.Game
|
|||||||
|
|
||||||
foreach (var language in Enum.GetValues(typeof(Language)).OfType<Language>())
|
foreach (var language in Enum.GetValues(typeof(Language)).OfType<Language>())
|
||||||
{
|
{
|
||||||
var cultureCode = language.ToString();
|
var cultureCode = language.ToCultureCode();
|
||||||
Localisation.AddLanguage(cultureCode, new ResourceManagerLocalisationStore(cultureCode));
|
Localisation.AddLanguage(cultureCode, new ResourceManagerLocalisationStore(cultureCode));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -712,7 +719,6 @@ namespace osu.Game
|
|||||||
PostNotification = n => notifications.Post(n),
|
PostNotification = n => notifications.Post(n),
|
||||||
}, Add, true);
|
}, Add, true);
|
||||||
|
|
||||||
loadComponentSingleFile(difficultyRecommender, Add);
|
|
||||||
loadComponentSingleFile(stableImportManager, Add);
|
loadComponentSingleFile(stableImportManager, Add);
|
||||||
|
|
||||||
loadComponentSingleFile(screenshotManager, Add);
|
loadComponentSingleFile(screenshotManager, Add);
|
||||||
@ -753,8 +759,11 @@ namespace osu.Game
|
|||||||
loadComponentSingleFile(new AccountCreationOverlay(), topMostOverlayContent.Add, true);
|
loadComponentSingleFile(new AccountCreationOverlay(), topMostOverlayContent.Add, true);
|
||||||
loadComponentSingleFile(new DialogOverlay(), topMostOverlayContent.Add, true);
|
loadComponentSingleFile(new DialogOverlay(), topMostOverlayContent.Add, true);
|
||||||
|
|
||||||
|
loadComponentSingleFile(CreateHighPerformanceSession(), Add);
|
||||||
|
|
||||||
chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;
|
chatOverlay.State.ValueChanged += state => channelManager.HighPollRate.Value = state.NewValue == Visibility.Visible;
|
||||||
|
|
||||||
|
Add(difficultyRecommender);
|
||||||
Add(externalLinkOpener = new ExternalLinkOpener());
|
Add(externalLinkOpener = new ExternalLinkOpener());
|
||||||
Add(new MusicKeyBindingHandler());
|
Add(new MusicKeyBindingHandler());
|
||||||
|
|
||||||
|
@ -14,6 +14,7 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
@ -126,15 +127,15 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
Padding = new MarginPadding { Horizontal = 10 },
|
Padding = new MarginPadding { Horizontal = 10 },
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
generalFilter = new BeatmapSearchMultipleSelectionFilterRow<SearchGeneral>(@"General"),
|
generalFilter = new BeatmapSearchMultipleSelectionFilterRow<SearchGeneral>(BeatmapsStrings.ListingSearchFiltersGeneral),
|
||||||
modeFilter = new BeatmapSearchRulesetFilterRow(),
|
modeFilter = new BeatmapSearchRulesetFilterRow(),
|
||||||
categoryFilter = new BeatmapSearchFilterRow<SearchCategory>(@"Categories"),
|
categoryFilter = new BeatmapSearchFilterRow<SearchCategory>(BeatmapsStrings.ListingSearchFiltersStatus),
|
||||||
genreFilter = new BeatmapSearchFilterRow<SearchGenre>(@"Genre"),
|
genreFilter = new BeatmapSearchFilterRow<SearchGenre>(BeatmapsStrings.ListingSearchFiltersGenre),
|
||||||
languageFilter = new BeatmapSearchFilterRow<SearchLanguage>(@"Language"),
|
languageFilter = new BeatmapSearchFilterRow<SearchLanguage>(BeatmapsStrings.ListingSearchFiltersLanguage),
|
||||||
extraFilter = new BeatmapSearchMultipleSelectionFilterRow<SearchExtra>(@"Extra"),
|
extraFilter = new BeatmapSearchMultipleSelectionFilterRow<SearchExtra>(BeatmapsStrings.ListingSearchFiltersExtra),
|
||||||
ranksFilter = new BeatmapSearchScoreFilterRow(),
|
ranksFilter = new BeatmapSearchScoreFilterRow(),
|
||||||
playedFilter = new BeatmapSearchFilterRow<SearchPlayed>(@"Played"),
|
playedFilter = new BeatmapSearchFilterRow<SearchPlayed>(BeatmapsStrings.ListingSearchFiltersPlayed),
|
||||||
explicitContentFilter = new BeatmapSearchFilterRow<SearchExplicit>(@"Explicit Content"),
|
explicitContentFilter = new BeatmapSearchFilterRow<SearchExplicit>(BeatmapsStrings.ListingSearchFiltersNsfw),
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -172,7 +173,7 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
|
|
||||||
public BeatmapSearchTextBox()
|
public BeatmapSearchTextBox()
|
||||||
{
|
{
|
||||||
PlaceholderText = @"type in keywords...";
|
PlaceholderText = BeatmapsStrings.ListingSearchPrompt;
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override bool OnKeyDown(KeyDownEvent e)
|
protected override bool OnKeyDown(KeyDownEvent e)
|
||||||
|
@ -11,8 +11,8 @@ using osu.Game.Graphics;
|
|||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using Humanizer;
|
|
||||||
using osu.Framework.Extensions.EnumExtensions;
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
{
|
{
|
||||||
@ -26,7 +26,7 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
set => current.Current = value;
|
set => current.Current = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public BeatmapSearchFilterRow(string headerName)
|
public BeatmapSearchFilterRow(LocalisableString header)
|
||||||
{
|
{
|
||||||
Drawable filter;
|
Drawable filter;
|
||||||
AutoSizeAxes = Axes.Y;
|
AutoSizeAxes = Axes.Y;
|
||||||
@ -53,7 +53,7 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Font = OsuFont.GetFont(size: 13),
|
Font = OsuFont.GetFont(size: 13),
|
||||||
Text = headerName.Titleize()
|
Text = header
|
||||||
},
|
},
|
||||||
filter = CreateFilter()
|
filter = CreateFilter()
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ using osu.Framework.Bindables;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
@ -19,8 +20,8 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
|
|
||||||
private MultipleSelectionFilter filter;
|
private MultipleSelectionFilter filter;
|
||||||
|
|
||||||
public BeatmapSearchMultipleSelectionFilterRow(string headerName)
|
public BeatmapSearchMultipleSelectionFilterRow(LocalisableString header)
|
||||||
: base(headerName)
|
: base(header)
|
||||||
{
|
{
|
||||||
Current.BindTo(filter.Current);
|
Current.BindTo(filter.Current);
|
||||||
}
|
}
|
||||||
|
@ -3,6 +3,7 @@
|
|||||||
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
@ -10,7 +11,7 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
public class BeatmapSearchRulesetFilterRow : BeatmapSearchFilterRow<RulesetInfo>
|
public class BeatmapSearchRulesetFilterRow : BeatmapSearchFilterRow<RulesetInfo>
|
||||||
{
|
{
|
||||||
public BeatmapSearchRulesetFilterRow()
|
public BeatmapSearchRulesetFilterRow()
|
||||||
: base(@"Mode")
|
: base(BeatmapsStrings.ListingSearchFiltersMode)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -4,6 +4,8 @@
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
@ -11,7 +13,7 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
public class BeatmapSearchScoreFilterRow : BeatmapSearchMultipleSelectionFilterRow<ScoreRank>
|
public class BeatmapSearchScoreFilterRow : BeatmapSearchMultipleSelectionFilterRow<ScoreRank>
|
||||||
{
|
{
|
||||||
public BeatmapSearchScoreFilterRow()
|
public BeatmapSearchScoreFilterRow()
|
||||||
: base(@"Rank Achieved")
|
: base(BeatmapsStrings.ListingSearchFiltersRank)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -31,20 +33,7 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string LabelFor(ScoreRank value)
|
protected override LocalisableString LabelFor(ScoreRank value) => value.GetLocalisableDescription();
|
||||||
{
|
|
||||||
switch (value)
|
|
||||||
{
|
|
||||||
case ScoreRank.XH:
|
|
||||||
return @"Silver SS";
|
|
||||||
|
|
||||||
case ScoreRank.SH:
|
|
||||||
return @"Silver S";
|
|
||||||
|
|
||||||
default:
|
|
||||||
return value.GetDescription();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,6 +7,7 @@ using osu.Framework.Extensions;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
@ -66,7 +67,7 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
/// <summary>
|
/// <summary>
|
||||||
/// Returns the label text to be used for the supplied <paramref name="value"/>.
|
/// Returns the label text to be used for the supplied <paramref name="value"/>.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
protected virtual string LabelFor(T value) => (value as Enum)?.GetDescription() ?? value.ToString();
|
protected virtual LocalisableString LabelFor(T value) => (value as Enum)?.GetLocalisableDescription() ?? value.ToString();
|
||||||
|
|
||||||
private void updateState()
|
private void updateState()
|
||||||
{
|
{
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
{
|
{
|
||||||
|
[LocalisableEnum(typeof(SearchCategoryEnumLocalisationMapper))]
|
||||||
public enum SearchCategory
|
public enum SearchCategory
|
||||||
{
|
{
|
||||||
Any,
|
Any,
|
||||||
@ -23,4 +27,43 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
[Description("My Maps")]
|
[Description("My Maps")]
|
||||||
Mine,
|
Mine,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SearchCategoryEnumLocalisationMapper : EnumLocalisationMapper<SearchCategory>
|
||||||
|
{
|
||||||
|
public override LocalisableString Map(SearchCategory value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case SearchCategory.Any:
|
||||||
|
return BeatmapsStrings.StatusAny;
|
||||||
|
|
||||||
|
case SearchCategory.Leaderboard:
|
||||||
|
return BeatmapsStrings.StatusLeaderboard;
|
||||||
|
|
||||||
|
case SearchCategory.Ranked:
|
||||||
|
return BeatmapsStrings.StatusRanked;
|
||||||
|
|
||||||
|
case SearchCategory.Qualified:
|
||||||
|
return BeatmapsStrings.StatusQualified;
|
||||||
|
|
||||||
|
case SearchCategory.Loved:
|
||||||
|
return BeatmapsStrings.StatusLoved;
|
||||||
|
|
||||||
|
case SearchCategory.Favourites:
|
||||||
|
return BeatmapsStrings.StatusFavourites;
|
||||||
|
|
||||||
|
case SearchCategory.Pending:
|
||||||
|
return BeatmapsStrings.StatusPending;
|
||||||
|
|
||||||
|
case SearchCategory.Graveyard:
|
||||||
|
return BeatmapsStrings.StatusGraveyard;
|
||||||
|
|
||||||
|
case SearchCategory.Mine:
|
||||||
|
return BeatmapsStrings.StatusMine;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,11 +1,34 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
{
|
{
|
||||||
|
[LocalisableEnum(typeof(SearchExplicitEnumLocalisationMapper))]
|
||||||
public enum SearchExplicit
|
public enum SearchExplicit
|
||||||
{
|
{
|
||||||
Hide,
|
Hide,
|
||||||
Show
|
Show
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SearchExplicitEnumLocalisationMapper : EnumLocalisationMapper<SearchExplicit>
|
||||||
|
{
|
||||||
|
public override LocalisableString Map(SearchExplicit value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case SearchExplicit.Hide:
|
||||||
|
return BeatmapsStrings.NsfwExclude;
|
||||||
|
|
||||||
|
case SearchExplicit.Show:
|
||||||
|
return BeatmapsStrings.NsfwInclude;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
{
|
{
|
||||||
|
[LocalisableEnum(typeof(SearchExtraEnumLocalisationMapper))]
|
||||||
public enum SearchExtra
|
public enum SearchExtra
|
||||||
{
|
{
|
||||||
[Description("Has Video")]
|
[Description("Has Video")]
|
||||||
@ -13,4 +17,22 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
[Description("Has Storyboard")]
|
[Description("Has Storyboard")]
|
||||||
Storyboard
|
Storyboard
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SearchExtraEnumLocalisationMapper : EnumLocalisationMapper<SearchExtra>
|
||||||
|
{
|
||||||
|
public override LocalisableString Map(SearchExtra value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case SearchExtra.Video:
|
||||||
|
return BeatmapsStrings.ExtraVideo;
|
||||||
|
|
||||||
|
case SearchExtra.Storyboard:
|
||||||
|
return BeatmapsStrings.ExtraStoryboard;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
{
|
{
|
||||||
|
[LocalisableEnum(typeof(SearchGeneralEnumLocalisationMapper))]
|
||||||
public enum SearchGeneral
|
public enum SearchGeneral
|
||||||
{
|
{
|
||||||
[Description("Recommended difficulty")]
|
[Description("Recommended difficulty")]
|
||||||
@ -16,4 +20,25 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
[Description("Subscribed mappers")]
|
[Description("Subscribed mappers")]
|
||||||
Follows
|
Follows
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SearchGeneralEnumLocalisationMapper : EnumLocalisationMapper<SearchGeneral>
|
||||||
|
{
|
||||||
|
public override LocalisableString Map(SearchGeneral value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case SearchGeneral.Recommended:
|
||||||
|
return BeatmapsStrings.GeneralRecommended;
|
||||||
|
|
||||||
|
case SearchGeneral.Converts:
|
||||||
|
return BeatmapsStrings.GeneralConverts;
|
||||||
|
|
||||||
|
case SearchGeneral.Follows:
|
||||||
|
return BeatmapsStrings.GeneralFollows;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
{
|
{
|
||||||
|
[LocalisableEnum(typeof(SearchGenreEnumLocalisationMapper))]
|
||||||
public enum SearchGenre
|
public enum SearchGenre
|
||||||
{
|
{
|
||||||
Any = 0,
|
Any = 0,
|
||||||
@ -26,4 +30,58 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
Folk = 13,
|
Folk = 13,
|
||||||
Jazz = 14
|
Jazz = 14
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SearchGenreEnumLocalisationMapper : EnumLocalisationMapper<SearchGenre>
|
||||||
|
{
|
||||||
|
public override LocalisableString Map(SearchGenre value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case SearchGenre.Any:
|
||||||
|
return BeatmapsStrings.GenreAny;
|
||||||
|
|
||||||
|
case SearchGenre.Unspecified:
|
||||||
|
return BeatmapsStrings.GenreUnspecified;
|
||||||
|
|
||||||
|
case SearchGenre.VideoGame:
|
||||||
|
return BeatmapsStrings.GenreVideoGame;
|
||||||
|
|
||||||
|
case SearchGenre.Anime:
|
||||||
|
return BeatmapsStrings.GenreAnime;
|
||||||
|
|
||||||
|
case SearchGenre.Rock:
|
||||||
|
return BeatmapsStrings.GenreRock;
|
||||||
|
|
||||||
|
case SearchGenre.Pop:
|
||||||
|
return BeatmapsStrings.GenrePop;
|
||||||
|
|
||||||
|
case SearchGenre.Other:
|
||||||
|
return BeatmapsStrings.GenreOther;
|
||||||
|
|
||||||
|
case SearchGenre.Novelty:
|
||||||
|
return BeatmapsStrings.GenreNovelty;
|
||||||
|
|
||||||
|
case SearchGenre.HipHop:
|
||||||
|
return BeatmapsStrings.GenreHipHop;
|
||||||
|
|
||||||
|
case SearchGenre.Electronic:
|
||||||
|
return BeatmapsStrings.GenreElectronic;
|
||||||
|
|
||||||
|
case SearchGenre.Metal:
|
||||||
|
return BeatmapsStrings.GenreMetal;
|
||||||
|
|
||||||
|
case SearchGenre.Classical:
|
||||||
|
return BeatmapsStrings.GenreClassical;
|
||||||
|
|
||||||
|
case SearchGenre.Folk:
|
||||||
|
return BeatmapsStrings.GenreFolk;
|
||||||
|
|
||||||
|
case SearchGenre.Jazz:
|
||||||
|
return BeatmapsStrings.GenreJazz;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
{
|
{
|
||||||
|
[LocalisableEnum(typeof(SearchLanguageEnumLocalisationMapper))]
|
||||||
[HasOrderedElements]
|
[HasOrderedElements]
|
||||||
public enum SearchLanguage
|
public enum SearchLanguage
|
||||||
{
|
{
|
||||||
@ -53,4 +57,61 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
[Order(13)]
|
[Order(13)]
|
||||||
Other
|
Other
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SearchLanguageEnumLocalisationMapper : EnumLocalisationMapper<SearchLanguage>
|
||||||
|
{
|
||||||
|
public override LocalisableString Map(SearchLanguage value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case SearchLanguage.Any:
|
||||||
|
return BeatmapsStrings.LanguageAny;
|
||||||
|
|
||||||
|
case SearchLanguage.Unspecified:
|
||||||
|
return BeatmapsStrings.LanguageUnspecified;
|
||||||
|
|
||||||
|
case SearchLanguage.English:
|
||||||
|
return BeatmapsStrings.LanguageEnglish;
|
||||||
|
|
||||||
|
case SearchLanguage.Japanese:
|
||||||
|
return BeatmapsStrings.LanguageJapanese;
|
||||||
|
|
||||||
|
case SearchLanguage.Chinese:
|
||||||
|
return BeatmapsStrings.LanguageChinese;
|
||||||
|
|
||||||
|
case SearchLanguage.Instrumental:
|
||||||
|
return BeatmapsStrings.LanguageInstrumental;
|
||||||
|
|
||||||
|
case SearchLanguage.Korean:
|
||||||
|
return BeatmapsStrings.LanguageKorean;
|
||||||
|
|
||||||
|
case SearchLanguage.French:
|
||||||
|
return BeatmapsStrings.LanguageFrench;
|
||||||
|
|
||||||
|
case SearchLanguage.German:
|
||||||
|
return BeatmapsStrings.LanguageGerman;
|
||||||
|
|
||||||
|
case SearchLanguage.Swedish:
|
||||||
|
return BeatmapsStrings.LanguageSwedish;
|
||||||
|
|
||||||
|
case SearchLanguage.Spanish:
|
||||||
|
return BeatmapsStrings.LanguageSpanish;
|
||||||
|
|
||||||
|
case SearchLanguage.Italian:
|
||||||
|
return BeatmapsStrings.LanguageItalian;
|
||||||
|
|
||||||
|
case SearchLanguage.Russian:
|
||||||
|
return BeatmapsStrings.LanguageRussian;
|
||||||
|
|
||||||
|
case SearchLanguage.Polish:
|
||||||
|
return BeatmapsStrings.LanguagePolish;
|
||||||
|
|
||||||
|
case SearchLanguage.Other:
|
||||||
|
return BeatmapsStrings.LanguageOther;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,12 +1,38 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
{
|
{
|
||||||
|
[LocalisableEnum(typeof(SearchPlayedEnumLocalisationMapper))]
|
||||||
public enum SearchPlayed
|
public enum SearchPlayed
|
||||||
{
|
{
|
||||||
Any,
|
Any,
|
||||||
Played,
|
Played,
|
||||||
Unplayed
|
Unplayed
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SearchPlayedEnumLocalisationMapper : EnumLocalisationMapper<SearchPlayed>
|
||||||
|
{
|
||||||
|
public override LocalisableString Map(SearchPlayed value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case SearchPlayed.Any:
|
||||||
|
return BeatmapsStrings.PlayedAny;
|
||||||
|
|
||||||
|
case SearchPlayed.Played:
|
||||||
|
return BeatmapsStrings.PlayedPlayed;
|
||||||
|
|
||||||
|
case SearchPlayed.Unplayed:
|
||||||
|
return BeatmapsStrings.PlayedUnplayed;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,8 +1,13 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.BeatmapListing
|
namespace osu.Game.Overlays.BeatmapListing
|
||||||
{
|
{
|
||||||
|
[LocalisableEnum(typeof(SortCriteriaLocalisationMapper))]
|
||||||
public enum SortCriteria
|
public enum SortCriteria
|
||||||
{
|
{
|
||||||
Title,
|
Title,
|
||||||
@ -14,4 +19,40 @@ namespace osu.Game.Overlays.BeatmapListing
|
|||||||
Favourites,
|
Favourites,
|
||||||
Relevance
|
Relevance
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class SortCriteriaLocalisationMapper : EnumLocalisationMapper<SortCriteria>
|
||||||
|
{
|
||||||
|
public override LocalisableString Map(SortCriteria value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case SortCriteria.Title:
|
||||||
|
return BeatmapsStrings.ListingSearchSortingTitle;
|
||||||
|
|
||||||
|
case SortCriteria.Artist:
|
||||||
|
return BeatmapsStrings.ListingSearchSortingArtist;
|
||||||
|
|
||||||
|
case SortCriteria.Difficulty:
|
||||||
|
return BeatmapsStrings.ListingSearchSortingDifficulty;
|
||||||
|
|
||||||
|
case SortCriteria.Ranked:
|
||||||
|
return BeatmapsStrings.ListingSearchSortingRanked;
|
||||||
|
|
||||||
|
case SortCriteria.Rating:
|
||||||
|
return BeatmapsStrings.ListingSearchSortingRating;
|
||||||
|
|
||||||
|
case SortCriteria.Plays:
|
||||||
|
return BeatmapsStrings.ListingSearchSortingPlays;
|
||||||
|
|
||||||
|
case SortCriteria.Favourites:
|
||||||
|
return BeatmapsStrings.ListingSearchSortingFavourites;
|
||||||
|
|
||||||
|
case SortCriteria.Relevance:
|
||||||
|
return BeatmapsStrings.ListingSearchSortingRelevance;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,7 @@ using osu.Game.Beatmaps;
|
|||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Overlays.BeatmapListing;
|
using osu.Game.Overlays.BeatmapListing;
|
||||||
using osu.Game.Overlays.BeatmapListing.Panels;
|
using osu.Game.Overlays.BeatmapListing.Panels;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -232,7 +233,7 @@ namespace osu.Game.Overlays
|
|||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Text = @"... nope, nothing found.",
|
Text = BeatmapsStrings.ListingSearchNotFoundQuote,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -18,6 +18,7 @@ using JetBrains.Annotations;
|
|||||||
using System;
|
using System;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
using osu.Framework.Localisation;
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Overlays
|
namespace osu.Game.Overlays
|
||||||
{
|
{
|
||||||
@ -54,7 +55,7 @@ namespace osu.Game.Overlays
|
|||||||
Anchor = Anchor.CentreLeft,
|
Anchor = Anchor.CentreLeft,
|
||||||
Origin = Anchor.CentreLeft,
|
Origin = Anchor.CentreLeft,
|
||||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold),
|
Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold),
|
||||||
Text = @"Sort by"
|
Text = SortStrings.Default
|
||||||
},
|
},
|
||||||
CreateControl().With(c =>
|
CreateControl().With(c =>
|
||||||
{
|
{
|
||||||
@ -143,7 +144,7 @@ namespace osu.Game.Overlays
|
|||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold),
|
Font = OsuFont.GetFont(size: 12, weight: FontWeight.SemiBold),
|
||||||
Text = (value as Enum)?.GetDescription() ?? value.ToString()
|
Text = (value as Enum)?.GetLocalisableDescription() ?? value.ToString()
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
@ -1,11 +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.
|
||||||
|
|
||||||
using System;
|
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Configuration;
|
using osu.Framework.Configuration;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Game.Extensions;
|
||||||
using osu.Game.Localisation;
|
using osu.Game.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.General
|
namespace osu.Game.Overlays.Settings.Sections.General
|
||||||
@ -35,11 +35,11 @@ namespace osu.Game.Overlays.Settings.Sections.General
|
|||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
|
||||||
if (!Enum.TryParse<Language>(frameworkLocale.Value, out var locale))
|
if (!LanguageExtensions.TryParseCultureCode(frameworkLocale.Value, out var locale))
|
||||||
locale = Language.en;
|
locale = Language.en;
|
||||||
languageSelection.Current.Value = locale;
|
languageSelection.Current.Value = locale;
|
||||||
|
|
||||||
languageSelection.Current.BindValueChanged(val => frameworkLocale.Value = val.NewValue.ToString());
|
languageSelection.Current.BindValueChanged(val => frameworkLocale.Value = val.NewValue.ToCultureCode());
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -19,6 +19,8 @@ namespace osu.Game.Overlays.Settings
|
|||||||
Margin = new MarginPadding { Top = 5 };
|
Margin = new MarginPadding { Top = 5 };
|
||||||
RelativeSizeAxes = Axes.X;
|
RelativeSizeAxes = Axes.X;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override DropdownMenu CreateMenu() => base.CreateMenu().With(m => m.MaxHeight = 200);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -2,16 +2,20 @@
|
|||||||
// 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 osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings
|
namespace osu.Game.Overlays.Settings
|
||||||
{
|
{
|
||||||
public class SettingsNumberBox : SettingsItem<string>
|
public class SettingsNumberBox : SettingsItem<string>
|
||||||
{
|
{
|
||||||
protected override Drawable CreateControl() => new OsuNumberBox
|
protected override Drawable CreateControl() => new NumberBox
|
||||||
{
|
{
|
||||||
Margin = new MarginPadding { Top = 5 },
|
Margin = new MarginPadding { Top = 5 },
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public class NumberBox : SettingsTextBox.TextBox
|
||||||
|
{
|
||||||
|
protected override bool CanAddCharacter(char character) => char.IsNumber(character);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,18 +1,60 @@
|
|||||||
// 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 osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Input.Events;
|
||||||
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
using osuTK.Graphics;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings
|
namespace osu.Game.Overlays.Settings
|
||||||
{
|
{
|
||||||
public class SettingsTextBox : SettingsItem<string>
|
public class SettingsTextBox : SettingsItem<string>
|
||||||
{
|
{
|
||||||
protected override Drawable CreateControl() => new OsuTextBox
|
protected override Drawable CreateControl() => new TextBox
|
||||||
{
|
{
|
||||||
Margin = new MarginPadding { Top = 5 },
|
Margin = new MarginPadding { Top = 5 },
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
CommitOnFocusLost = true,
|
CommitOnFocusLost = true,
|
||||||
};
|
};
|
||||||
|
|
||||||
|
public class TextBox : OsuTextBox
|
||||||
|
{
|
||||||
|
private const float border_thickness = 3;
|
||||||
|
|
||||||
|
private Color4 borderColourFocused;
|
||||||
|
private Color4 borderColourUnfocused;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuColour colour)
|
||||||
|
{
|
||||||
|
borderColourUnfocused = colour.Gray4.Opacity(0.5f);
|
||||||
|
borderColourFocused = BorderColour;
|
||||||
|
|
||||||
|
updateBorder();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFocus(FocusEvent e)
|
||||||
|
{
|
||||||
|
base.OnFocus(e);
|
||||||
|
|
||||||
|
updateBorder();
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void OnFocusLost(FocusLostEvent e)
|
||||||
|
{
|
||||||
|
base.OnFocusLost(e);
|
||||||
|
|
||||||
|
updateBorder();
|
||||||
|
}
|
||||||
|
|
||||||
|
private void updateBorder()
|
||||||
|
{
|
||||||
|
BorderThickness = border_thickness;
|
||||||
|
BorderColour = HasFocus ? borderColourFocused : borderColourUnfocused;
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -106,7 +106,19 @@ namespace osu.Game.Overlays
|
|||||||
public OverlayHeaderTabItem(T value)
|
public OverlayHeaderTabItem(T value)
|
||||||
: base(value)
|
: base(value)
|
||||||
{
|
{
|
||||||
Text.Text = ((Value as Enum)?.GetDescription() ?? Value.ToString()).ToLower();
|
if (!(Value is Enum enumValue))
|
||||||
|
Text.Text = Value.ToString().ToLower();
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var localisableDescription = enumValue.GetLocalisableDescription();
|
||||||
|
var nonLocalisableDescription = enumValue.GetDescription();
|
||||||
|
|
||||||
|
// If localisable == non-localisable, then we must have a basic string, so .ToLower() is used.
|
||||||
|
Text.Text = localisableDescription.Equals(nonLocalisableDescription)
|
||||||
|
? nonLocalisableDescription.ToLower()
|
||||||
|
: localisableDescription;
|
||||||
|
}
|
||||||
|
|
||||||
Text.Font = OsuFont.GetFont(size: 14);
|
Text.Font = OsuFont.GetFont(size: 14);
|
||||||
Text.Margin = new MarginPadding { Vertical = 16.5f }; // 15px padding + 1.5px line-height difference compensation
|
Text.Margin = new MarginPadding { Vertical = 16.5f }; // 15px padding + 1.5px line-height difference compensation
|
||||||
Bar.Margin = new MarginPadding { Bottom = bar_height };
|
Bar.Margin = new MarginPadding { Bottom = bar_height };
|
||||||
|
47
osu.Game/Performance/HighPerformanceSession.cs
Normal file
47
osu.Game/Performance/HighPerformanceSession.cs
Normal file
@ -0,0 +1,47 @@
|
|||||||
|
// 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.Runtime;
|
||||||
|
using osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
|
||||||
|
namespace osu.Game.Performance
|
||||||
|
{
|
||||||
|
public class HighPerformanceSession : Component
|
||||||
|
{
|
||||||
|
private readonly IBindable<bool> localUserPlaying = new Bindable<bool>();
|
||||||
|
private GCLatencyMode originalGCMode;
|
||||||
|
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(OsuGame game)
|
||||||
|
{
|
||||||
|
localUserPlaying.BindTo(game.LocalUserPlaying);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override void LoadComplete()
|
||||||
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
localUserPlaying.BindValueChanged(playing =>
|
||||||
|
{
|
||||||
|
if (playing.NewValue)
|
||||||
|
EnableHighPerformanceSession();
|
||||||
|
else
|
||||||
|
DisableHighPerformanceSession();
|
||||||
|
}, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void EnableHighPerformanceSession()
|
||||||
|
{
|
||||||
|
originalGCMode = GCSettings.LatencyMode;
|
||||||
|
GCSettings.LatencyMode = GCLatencyMode.LowLatency;
|
||||||
|
}
|
||||||
|
|
||||||
|
protected virtual void DisableHighPerformanceSession()
|
||||||
|
{
|
||||||
|
if (GCSettings.LatencyMode == GCLatencyMode.LowLatency)
|
||||||
|
GCSettings.LatencyMode = originalGCMode;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -8,7 +8,6 @@ using osu.Framework.Graphics.Sprites;
|
|||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.UserInterface;
|
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mods
|
namespace osu.Game.Rulesets.Mods
|
||||||
@ -50,7 +49,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private readonly OsuNumberBox seedNumberBox;
|
private readonly SettingsNumberBox.NumberBox seedNumberBox;
|
||||||
|
|
||||||
public SeedControl()
|
public SeedControl()
|
||||||
{
|
{
|
||||||
@ -76,7 +75,7 @@ namespace osu.Game.Rulesets.Mods
|
|||||||
{
|
{
|
||||||
new Drawable[]
|
new Drawable[]
|
||||||
{
|
{
|
||||||
seedNumberBox = new OsuNumberBox
|
seedNumberBox = new SettingsNumberBox.NumberBox
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.X,
|
RelativeSizeAxes = Axes.X,
|
||||||
CommitOnFocusLost = true
|
CommitOnFocusLost = true
|
||||||
|
@ -1,10 +1,14 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
using System.ComponentModel;
|
using System.ComponentModel;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
using osu.Game.Resources.Localisation.Web;
|
||||||
|
|
||||||
namespace osu.Game.Scoring
|
namespace osu.Game.Scoring
|
||||||
{
|
{
|
||||||
|
[LocalisableEnum(typeof(ScoreRankEnumLocalisationMapper))]
|
||||||
public enum ScoreRank
|
public enum ScoreRank
|
||||||
{
|
{
|
||||||
[Description(@"D")]
|
[Description(@"D")]
|
||||||
@ -31,4 +35,40 @@ namespace osu.Game.Scoring
|
|||||||
[Description(@"SS+")]
|
[Description(@"SS+")]
|
||||||
XH,
|
XH,
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public class ScoreRankEnumLocalisationMapper : EnumLocalisationMapper<ScoreRank>
|
||||||
|
{
|
||||||
|
public override LocalisableString Map(ScoreRank value)
|
||||||
|
{
|
||||||
|
switch (value)
|
||||||
|
{
|
||||||
|
case ScoreRank.XH:
|
||||||
|
return BeatmapsStrings.RankXH;
|
||||||
|
|
||||||
|
case ScoreRank.X:
|
||||||
|
return BeatmapsStrings.RankX;
|
||||||
|
|
||||||
|
case ScoreRank.SH:
|
||||||
|
return BeatmapsStrings.RankSH;
|
||||||
|
|
||||||
|
case ScoreRank.S:
|
||||||
|
return BeatmapsStrings.RankS;
|
||||||
|
|
||||||
|
case ScoreRank.A:
|
||||||
|
return BeatmapsStrings.RankA;
|
||||||
|
|
||||||
|
case ScoreRank.B:
|
||||||
|
return BeatmapsStrings.RankB;
|
||||||
|
|
||||||
|
case ScoreRank.C:
|
||||||
|
return BeatmapsStrings.RankC;
|
||||||
|
|
||||||
|
case ScoreRank.D:
|
||||||
|
return BeatmapsStrings.RankD;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new ArgumentOutOfRangeException(nameof(value), value, null);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
@ -18,6 +18,8 @@ namespace osu.Game.Skinning
|
|||||||
|
|
||||||
private readonly BindableList<ISkinnableDrawable> components = new BindableList<ISkinnableDrawable>();
|
private readonly BindableList<ISkinnableDrawable> components = new BindableList<ISkinnableDrawable>();
|
||||||
|
|
||||||
|
public bool ComponentsLoaded { get; private set; }
|
||||||
|
|
||||||
public SkinnableTargetContainer(SkinnableTarget target)
|
public SkinnableTargetContainer(SkinnableTarget target)
|
||||||
{
|
{
|
||||||
Target = target;
|
Target = target;
|
||||||
@ -30,6 +32,7 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
ClearInternal();
|
ClearInternal();
|
||||||
components.Clear();
|
components.Clear();
|
||||||
|
ComponentsLoaded = false;
|
||||||
|
|
||||||
content = CurrentSkin.GetDrawableComponent(new SkinnableTargetComponent(Target)) as SkinnableTargetComponentsContainer;
|
content = CurrentSkin.GetDrawableComponent(new SkinnableTargetComponent(Target)) as SkinnableTargetComponentsContainer;
|
||||||
|
|
||||||
@ -39,8 +42,11 @@ namespace osu.Game.Skinning
|
|||||||
{
|
{
|
||||||
AddInternal(wrapper);
|
AddInternal(wrapper);
|
||||||
components.AddRange(wrapper.Children.OfType<ISkinnableDrawable>());
|
components.AddRange(wrapper.Children.OfType<ISkinnableDrawable>());
|
||||||
|
ComponentsLoaded = true;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
else
|
||||||
|
ComponentsLoaded = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <inheritdoc cref="ISkinnableTarget"/>
|
/// <inheritdoc cref="ISkinnableTarget"/>
|
||||||
|
@ -1,6 +1,7 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
@ -47,6 +48,8 @@ namespace osu.Game.Tests.Visual
|
|||||||
LegacySkin.ResetDrawableTarget(t);
|
LegacySkin.ResetDrawableTarget(t);
|
||||||
t.Reload();
|
t.Reload();
|
||||||
}));
|
}));
|
||||||
|
|
||||||
|
AddUntilStep("wait for components to load", () => this.ChildrenOfType<SkinnableTargetContainer>().All(t => t.ComponentsLoaded));
|
||||||
}
|
}
|
||||||
|
|
||||||
public class SkinProvidingPlayer : TestPlayer
|
public class SkinProvidingPlayer : TestPlayer
|
||||||
|
@ -350,7 +350,7 @@ namespace osu.Game.Tests.Visual
|
|||||||
if (CurrentTime >= Length)
|
if (CurrentTime >= Length)
|
||||||
{
|
{
|
||||||
Stop();
|
Stop();
|
||||||
RaiseCompleted();
|
// `RaiseCompleted` is not called here to prevent transitioning to the next song.
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -34,8 +34,8 @@
|
|||||||
<PrivateAssets>all</PrivateAssets>
|
<PrivateAssets>all</PrivateAssets>
|
||||||
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
<IncludeAssets>runtime; build; native; contentfiles; analyzers; buildtransitive</IncludeAssets>
|
||||||
</PackageReference>
|
</PackageReference>
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2021.614.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.616.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.611.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.614.0" />
|
||||||
<PackageReference Include="Sentry" Version="3.4.0" />
|
<PackageReference Include="Sentry" Version="3.4.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.28.2" />
|
<PackageReference Include="SharpCompress" Version="0.28.2" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||||
|
@ -70,8 +70,8 @@
|
|||||||
<Reference Include="System.Net.Http" />
|
<Reference Include="System.Net.Http" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.614.0" />
|
<PackageReference Include="ppy.osu.Framework.iOS" Version="2021.616.0" />
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.611.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.614.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
<!-- See https://github.com/dotnet/runtime/issues/35988 (can be removed after Xamarin uses net5.0 / net6.0) -->
|
||||||
<PropertyGroup>
|
<PropertyGroup>
|
||||||
@ -93,7 +93,7 @@
|
|||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite" Version="2.2.6" />
|
||||||
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
<PackageReference Include="Microsoft.EntityFrameworkCore.Sqlite.Core" Version="2.2.6" />
|
||||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
<PackageReference Include="Newtonsoft.Json" Version="13.0.1" />
|
||||||
<PackageReference Include="ppy.osu.Framework" Version="2021.614.0" />
|
<PackageReference Include="ppy.osu.Framework" Version="2021.616.0" />
|
||||||
<PackageReference Include="SharpCompress" Version="0.28.2" />
|
<PackageReference Include="SharpCompress" Version="0.28.2" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.2" />
|
<PackageReference Include="NUnit" Version="3.13.2" />
|
||||||
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
<PackageReference Include="SharpRaven" Version="2.4.0" />
|
||||||
|
Loading…
Reference in New Issue
Block a user