mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 03:22:55 +08:00
Merge branch 'master' into diffcalc/skill-mods
This commit is contained in:
commit
5b6018295d
@ -195,3 +195,6 @@ dotnet_diagnostic.IDE0069.severity = none
|
|||||||
|
|
||||||
#Disable operator overloads requiring alternate named methods
|
#Disable operator overloads requiring alternate named methods
|
||||||
dotnet_diagnostic.CA2225.severity = none
|
dotnet_diagnostic.CA2225.severity = none
|
||||||
|
|
||||||
|
# Banned APIs
|
||||||
|
dotnet_diagnostic.RS0030.severity = error
|
2
.github/ISSUE_TEMPLATE/01-bug-issues.md
vendored
2
.github/ISSUE_TEMPLATE/01-bug-issues.md
vendored
@ -13,4 +13,6 @@ about: Issues regarding encountered bugs.
|
|||||||
*please attach logs here, which are located at:*
|
*please attach logs here, which are located at:*
|
||||||
- `%AppData%/osu/logs` *(on Windows),*
|
- `%AppData%/osu/logs` *(on Windows),*
|
||||||
- `~/.local/share/osu/logs` *(on Linux & macOS).*
|
- `~/.local/share/osu/logs` *(on Linux & macOS).*
|
||||||
|
- `Android/Data/sh.ppy.osulazer/logs` *(on Android)*,
|
||||||
|
- on iOS they can be obtained by connecting your device to your desktop and copying the `logs` directory from the app's own document storage using iTunes. (https://support.apple.com/en-us/HT201301#copy-to-computer)
|
||||||
-->
|
-->
|
||||||
|
2
.github/ISSUE_TEMPLATE/02-crash-issues.md
vendored
2
.github/ISSUE_TEMPLATE/02-crash-issues.md
vendored
@ -13,6 +13,8 @@ about: Issues regarding crashes or permanent freezes.
|
|||||||
*please attach logs here, which are located at:*
|
*please attach logs here, which are located at:*
|
||||||
- `%AppData%/osu/logs` *(on Windows),*
|
- `%AppData%/osu/logs` *(on Windows),*
|
||||||
- `~/.local/share/osu/logs` *(on Linux & macOS).*
|
- `~/.local/share/osu/logs` *(on Linux & macOS).*
|
||||||
|
- `Android/Data/sh.ppy.osulazer/logs` *(on Android)*,
|
||||||
|
- on iOS they can be obtained by connecting your device to your desktop and copying the `logs` directory from the app's own document storage using iTunes. (https://support.apple.com/en-us/HT201301#copy-to-computer)
|
||||||
-->
|
-->
|
||||||
|
|
||||||
**Computer Specifications:**
|
**Computer Specifications:**
|
||||||
|
@ -7,3 +7,4 @@ M:osu.Framework.Graphics.Sprites.SpriteText.#ctor;Use OsuSpriteText.
|
|||||||
M:osu.Framework.Bindables.IBindableList`1.GetBoundCopy();Fails on iOS. Use manual ctor + BindTo instead. (see https://github.com/mono/mono/issues/19900)
|
M:osu.Framework.Bindables.IBindableList`1.GetBoundCopy();Fails on iOS. Use manual ctor + BindTo instead. (see https://github.com/mono/mono/issues/19900)
|
||||||
T:Microsoft.EntityFrameworkCore.Internal.EnumerableExtensions;Don't use internal extension methods.
|
T:Microsoft.EntityFrameworkCore.Internal.EnumerableExtensions;Don't use internal extension methods.
|
||||||
T:Microsoft.EntityFrameworkCore.Internal.TypeExtensions;Don't use internal extension methods.
|
T:Microsoft.EntityFrameworkCore.Internal.TypeExtensions;Don't use internal extension methods.
|
||||||
|
M:System.Enum.HasFlag(System.Enum);Use osu.Framework.Extensions.EnumExtensions.HasFlagFast<T>() instead.
|
@ -18,7 +18,7 @@
|
|||||||
<ItemGroup Label="Code Analysis">
|
<ItemGroup Label="Code Analysis">
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.2" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.CodeAnalysis.BannedApiAnalyzers" Version="3.3.2" PrivateAssets="All" />
|
||||||
<AdditionalFiles Include="$(MSBuildThisFileDirectory)CodeAnalysis\BannedSymbols.txt" />
|
<AdditionalFiles Include="$(MSBuildThisFileDirectory)CodeAnalysis\BannedSymbols.txt" />
|
||||||
<PackageReference Include="Microsoft.CodeAnalysis.FxCopAnalyzers" Version="3.3.2" PrivateAssets="All" />
|
<PackageReference Include="Microsoft.CodeAnalysis.NetAnalyzers" Version="5.0.3" PrivateAssets="All" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Code Analysis">
|
<PropertyGroup Label="Code Analysis">
|
||||||
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodeAnalysis\osu.ruleset</CodeAnalysisRuleSet>
|
<CodeAnalysisRuleSet>$(MSBuildThisFileDirectory)CodeAnalysis\osu.ruleset</CodeAnalysisRuleSet>
|
||||||
|
@ -52,6 +52,6 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.211.1" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2021.211.1" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.219.1" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2021.302.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
</Project>
|
</Project>
|
||||||
|
@ -17,7 +17,7 @@ using osu.Game.Database;
|
|||||||
|
|
||||||
namespace osu.Android
|
namespace osu.Android
|
||||||
{
|
{
|
||||||
[Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.FullUser, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize, HardwareAccelerated = false, LaunchMode = LaunchMode.SingleInstance)]
|
[Activity(Theme = "@android:style/Theme.NoTitleBar", MainLauncher = true, ScreenOrientation = ScreenOrientation.FullUser, SupportsPictureInPicture = false, ConfigurationChanges = ConfigChanges.Orientation | ConfigChanges.ScreenSize, HardwareAccelerated = false, LaunchMode = LaunchMode.SingleInstance, Exported = true)]
|
||||||
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osz", DataHost = "*", DataMimeType = "*/*")]
|
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osz", DataHost = "*", DataMimeType = "*/*")]
|
||||||
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osk", DataHost = "*", DataMimeType = "*/*")]
|
[IntentFilter(new[] { Intent.ActionView }, Categories = new[] { Intent.CategoryDefault }, DataScheme = "content", DataPathPattern = ".*\\\\.osk", DataHost = "*", DataMimeType = "*/*")]
|
||||||
[IntentFilter(new[] { Intent.ActionSend, Intent.ActionSendMultiple }, Categories = new[] { Intent.CategoryDefault }, DataMimeTypes = new[] { "application/zip", "application/octet-stream", "application/download", "application/x-zip", "application/x-zip-compressed" })]
|
[IntentFilter(new[] { Intent.ActionSend, Intent.ActionSendMultiple }, Categories = new[] { Intent.CategoryDefault }, DataMimeTypes = new[] { "application/zip", "application/octet-stream", "application/download", "application/x-zip", "application/x-zip-compressed" })]
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -21,6 +21,7 @@ using osu.Game.Rulesets.Difficulty;
|
|||||||
using osu.Game.Rulesets.Scoring;
|
using osu.Game.Rulesets.Scoring;
|
||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using System;
|
using System;
|
||||||
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
using osu.Game.Rulesets.Catch.Skinning.Legacy;
|
using osu.Game.Rulesets.Catch.Skinning.Legacy;
|
||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
|
|
||||||
@ -50,40 +51,40 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
|
|
||||||
public override IEnumerable<Mod> ConvertFromLegacyMods(LegacyMods mods)
|
public override IEnumerable<Mod> ConvertFromLegacyMods(LegacyMods mods)
|
||||||
{
|
{
|
||||||
if (mods.HasFlag(LegacyMods.Nightcore))
|
if (mods.HasFlagFast(LegacyMods.Nightcore))
|
||||||
yield return new CatchModNightcore();
|
yield return new CatchModNightcore();
|
||||||
else if (mods.HasFlag(LegacyMods.DoubleTime))
|
else if (mods.HasFlagFast(LegacyMods.DoubleTime))
|
||||||
yield return new CatchModDoubleTime();
|
yield return new CatchModDoubleTime();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Perfect))
|
if (mods.HasFlagFast(LegacyMods.Perfect))
|
||||||
yield return new CatchModPerfect();
|
yield return new CatchModPerfect();
|
||||||
else if (mods.HasFlag(LegacyMods.SuddenDeath))
|
else if (mods.HasFlagFast(LegacyMods.SuddenDeath))
|
||||||
yield return new CatchModSuddenDeath();
|
yield return new CatchModSuddenDeath();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Cinema))
|
if (mods.HasFlagFast(LegacyMods.Cinema))
|
||||||
yield return new CatchModCinema();
|
yield return new CatchModCinema();
|
||||||
else if (mods.HasFlag(LegacyMods.Autoplay))
|
else if (mods.HasFlagFast(LegacyMods.Autoplay))
|
||||||
yield return new CatchModAutoplay();
|
yield return new CatchModAutoplay();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Easy))
|
if (mods.HasFlagFast(LegacyMods.Easy))
|
||||||
yield return new CatchModEasy();
|
yield return new CatchModEasy();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Flashlight))
|
if (mods.HasFlagFast(LegacyMods.Flashlight))
|
||||||
yield return new CatchModFlashlight();
|
yield return new CatchModFlashlight();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.HalfTime))
|
if (mods.HasFlagFast(LegacyMods.HalfTime))
|
||||||
yield return new CatchModHalfTime();
|
yield return new CatchModHalfTime();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.HardRock))
|
if (mods.HasFlagFast(LegacyMods.HardRock))
|
||||||
yield return new CatchModHardRock();
|
yield return new CatchModHardRock();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Hidden))
|
if (mods.HasFlagFast(LegacyMods.Hidden))
|
||||||
yield return new CatchModHidden();
|
yield return new CatchModHidden();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.NoFail))
|
if (mods.HasFlagFast(LegacyMods.NoFail))
|
||||||
yield return new CatchModNoFail();
|
yield return new CatchModNoFail();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Relax))
|
if (mods.HasFlagFast(LegacyMods.Relax))
|
||||||
yield return new CatchModRelax();
|
yield return new CatchModRelax();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -6,6 +6,7 @@ using NUnit.Framework;
|
|||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.Color4Extensions;
|
using osu.Framework.Extensions.Color4Extensions;
|
||||||
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
@ -97,7 +98,7 @@ namespace osu.Game.Rulesets.Mania.Tests
|
|||||||
}
|
}
|
||||||
|
|
||||||
private bool verifyAnchors(DrawableHitObject hitObject, Anchor expectedAnchor)
|
private bool verifyAnchors(DrawableHitObject hitObject, Anchor expectedAnchor)
|
||||||
=> hitObject.Anchor.HasFlag(expectedAnchor) && hitObject.Origin.HasFlag(expectedAnchor);
|
=> hitObject.Anchor.HasFlagFast(expectedAnchor) && hitObject.Origin.HasFlagFast(expectedAnchor);
|
||||||
|
|
||||||
private bool verifyAnchors(DrawableHoldNote holdNote, Anchor expectedAnchor)
|
private bool verifyAnchors(DrawableHoldNote holdNote, Anchor expectedAnchor)
|
||||||
=> verifyAnchors((DrawableHitObject)holdNote, expectedAnchor) && holdNote.NestedHitObjects.All(n => verifyAnchors(n, expectedAnchor));
|
=> verifyAnchors((DrawableHitObject)holdNote, expectedAnchor) && holdNote.NestedHitObjects.All(n => verifyAnchors(n, expectedAnchor));
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -5,6 +5,7 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Diagnostics;
|
using System.Diagnostics;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Mania.MathUtils;
|
using osu.Game.Rulesets.Mania.MathUtils;
|
||||||
@ -141,7 +142,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
if (ConversionDifficulty > 6.5)
|
if (ConversionDifficulty > 6.5)
|
||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlagFast(PatternType.LowProbability))
|
||||||
return generateNRandomNotes(StartTime, 0.78, 0.3, 0);
|
return generateNRandomNotes(StartTime, 0.78, 0.3, 0);
|
||||||
|
|
||||||
return generateNRandomNotes(StartTime, 0.85, 0.36, 0.03);
|
return generateNRandomNotes(StartTime, 0.85, 0.36, 0.03);
|
||||||
@ -149,7 +150,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
if (ConversionDifficulty > 4)
|
if (ConversionDifficulty > 4)
|
||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlagFast(PatternType.LowProbability))
|
||||||
return generateNRandomNotes(StartTime, 0.43, 0.08, 0);
|
return generateNRandomNotes(StartTime, 0.43, 0.08, 0);
|
||||||
|
|
||||||
return generateNRandomNotes(StartTime, 0.56, 0.18, 0);
|
return generateNRandomNotes(StartTime, 0.56, 0.18, 0);
|
||||||
@ -157,13 +158,13 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
if (ConversionDifficulty > 2.5)
|
if (ConversionDifficulty > 2.5)
|
||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlagFast(PatternType.LowProbability))
|
||||||
return generateNRandomNotes(StartTime, 0.3, 0, 0);
|
return generateNRandomNotes(StartTime, 0.3, 0, 0);
|
||||||
|
|
||||||
return generateNRandomNotes(StartTime, 0.37, 0.08, 0);
|
return generateNRandomNotes(StartTime, 0.37, 0.08, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlagFast(PatternType.LowProbability))
|
||||||
return generateNRandomNotes(StartTime, 0.17, 0, 0);
|
return generateNRandomNotes(StartTime, 0.17, 0, 0);
|
||||||
|
|
||||||
return generateNRandomNotes(StartTime, 0.27, 0, 0);
|
return generateNRandomNotes(StartTime, 0.27, 0, 0);
|
||||||
@ -221,7 +222,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
if (convertType.HasFlagFast(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
nextColumn = FindAvailableColumn(nextColumn, PreviousPattern);
|
nextColumn = FindAvailableColumn(nextColumn, PreviousPattern);
|
||||||
|
|
||||||
int lastColumn = nextColumn;
|
int lastColumn = nextColumn;
|
||||||
@ -373,7 +374,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
static bool isDoubleSample(HitSampleInfo sample) => sample.Name == HitSampleInfo.HIT_CLAP || sample.Name == HitSampleInfo.HIT_FINISH;
|
static bool isDoubleSample(HitSampleInfo sample) => sample.Name == HitSampleInfo.HIT_CLAP || sample.Name == HitSampleInfo.HIT_FINISH;
|
||||||
|
|
||||||
bool canGenerateTwoNotes = !convertType.HasFlag(PatternType.LowProbability);
|
bool canGenerateTwoNotes = !convertType.HasFlagFast(PatternType.LowProbability);
|
||||||
canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(StartTime).Any(isDoubleSample);
|
canGenerateTwoNotes &= HitObject.Samples.Any(isDoubleSample) || sampleInfoListAt(StartTime).Any(isDoubleSample);
|
||||||
|
|
||||||
if (canGenerateTwoNotes)
|
if (canGenerateTwoNotes)
|
||||||
@ -406,7 +407,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
int endTime = startTime + SegmentDuration * SpanCount;
|
int endTime = startTime + SegmentDuration * SpanCount;
|
||||||
|
|
||||||
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int nextColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
if (convertType.HasFlagFast(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
nextColumn = FindAvailableColumn(nextColumn, PreviousPattern);
|
nextColumn = FindAvailableColumn(nextColumn, PreviousPattern);
|
||||||
|
|
||||||
for (int i = 0; i < columnRepeat; i++)
|
for (int i = 0; i < columnRepeat; i++)
|
||||||
@ -435,7 +436,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
int holdColumn = GetColumn((HitObject as IHasXPosition)?.X ?? 0, true);
|
||||||
if (convertType.HasFlag(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
if (convertType.HasFlagFast(PatternType.ForceNotStack) && PreviousPattern.ColumnWithObjects < TotalColumns)
|
||||||
holdColumn = FindAvailableColumn(holdColumn, PreviousPattern);
|
holdColumn = FindAvailableColumn(holdColumn, PreviousPattern);
|
||||||
|
|
||||||
// Create the hold note
|
// Create the hold note
|
||||||
|
@ -4,6 +4,7 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
@ -78,7 +79,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
else
|
else
|
||||||
convertType |= PatternType.LowProbability;
|
convertType |= PatternType.LowProbability;
|
||||||
|
|
||||||
if (!convertType.HasFlag(PatternType.KeepSingle))
|
if (!convertType.HasFlagFast(PatternType.KeepSingle))
|
||||||
{
|
{
|
||||||
if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH) && TotalColumns != 8)
|
if (HitObject.Samples.Any(s => s.Name == HitSampleInfo.HIT_FINISH) && TotalColumns != 8)
|
||||||
convertType |= PatternType.Mirror;
|
convertType |= PatternType.Mirror;
|
||||||
@ -101,7 +102,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
int lastColumn = PreviousPattern.HitObjects.FirstOrDefault()?.Column ?? 0;
|
int lastColumn = PreviousPattern.HitObjects.FirstOrDefault()?.Column ?? 0;
|
||||||
|
|
||||||
if (convertType.HasFlag(PatternType.Reverse) && PreviousPattern.HitObjects.Any())
|
if (convertType.HasFlagFast(PatternType.Reverse) && PreviousPattern.HitObjects.Any())
|
||||||
{
|
{
|
||||||
// Generate a new pattern by copying the last hit objects in reverse-column order
|
// Generate a new pattern by copying the last hit objects in reverse-column order
|
||||||
for (int i = RandomStart; i < TotalColumns; i++)
|
for (int i = RandomStart; i < TotalColumns; i++)
|
||||||
@ -113,7 +114,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convertType.HasFlag(PatternType.Cycle) && PreviousPattern.HitObjects.Count() == 1
|
if (convertType.HasFlagFast(PatternType.Cycle) && PreviousPattern.HitObjects.Count() == 1
|
||||||
// If we convert to 7K + 1, let's not overload the special key
|
// If we convert to 7K + 1, let's not overload the special key
|
||||||
&& (TotalColumns != 8 || lastColumn != 0)
|
&& (TotalColumns != 8 || lastColumn != 0)
|
||||||
// Make sure the last column was not the centre column
|
// Make sure the last column was not the centre column
|
||||||
@ -126,7 +127,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convertType.HasFlag(PatternType.ForceStack) && PreviousPattern.HitObjects.Any())
|
if (convertType.HasFlagFast(PatternType.ForceStack) && PreviousPattern.HitObjects.Any())
|
||||||
{
|
{
|
||||||
// Generate a new pattern by placing on the already filled columns
|
// Generate a new pattern by placing on the already filled columns
|
||||||
for (int i = RandomStart; i < TotalColumns; i++)
|
for (int i = RandomStart; i < TotalColumns; i++)
|
||||||
@ -140,7 +141,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
if (PreviousPattern.HitObjects.Count() == 1)
|
if (PreviousPattern.HitObjects.Count() == 1)
|
||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.Stair))
|
if (convertType.HasFlagFast(PatternType.Stair))
|
||||||
{
|
{
|
||||||
// Generate a new pattern by placing on the next column, cycling back to the start if there is no "next"
|
// Generate a new pattern by placing on the next column, cycling back to the start if there is no "next"
|
||||||
int targetColumn = lastColumn + 1;
|
int targetColumn = lastColumn + 1;
|
||||||
@ -151,7 +152,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
return pattern;
|
return pattern;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convertType.HasFlag(PatternType.ReverseStair))
|
if (convertType.HasFlagFast(PatternType.ReverseStair))
|
||||||
{
|
{
|
||||||
// Generate a new pattern by placing on the previous column, cycling back to the end if there is no "previous"
|
// Generate a new pattern by placing on the previous column, cycling back to the end if there is no "previous"
|
||||||
int targetColumn = lastColumn - 1;
|
int targetColumn = lastColumn - 1;
|
||||||
@ -163,10 +164,10 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
if (convertType.HasFlag(PatternType.KeepSingle))
|
if (convertType.HasFlagFast(PatternType.KeepSingle))
|
||||||
return generateRandomNotes(1);
|
return generateRandomNotes(1);
|
||||||
|
|
||||||
if (convertType.HasFlag(PatternType.Mirror))
|
if (convertType.HasFlagFast(PatternType.Mirror))
|
||||||
{
|
{
|
||||||
if (ConversionDifficulty > 6.5)
|
if (ConversionDifficulty > 6.5)
|
||||||
return generateRandomPatternWithMirrored(0.12, 0.38, 0.12);
|
return generateRandomPatternWithMirrored(0.12, 0.38, 0.12);
|
||||||
@ -178,7 +179,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
if (ConversionDifficulty > 6.5)
|
if (ConversionDifficulty > 6.5)
|
||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlagFast(PatternType.LowProbability))
|
||||||
return generateRandomPattern(0.78, 0.42, 0, 0);
|
return generateRandomPattern(0.78, 0.42, 0, 0);
|
||||||
|
|
||||||
return generateRandomPattern(1, 0.62, 0, 0);
|
return generateRandomPattern(1, 0.62, 0, 0);
|
||||||
@ -186,7 +187,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
if (ConversionDifficulty > 4)
|
if (ConversionDifficulty > 4)
|
||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlagFast(PatternType.LowProbability))
|
||||||
return generateRandomPattern(0.35, 0.08, 0, 0);
|
return generateRandomPattern(0.35, 0.08, 0, 0);
|
||||||
|
|
||||||
return generateRandomPattern(0.52, 0.15, 0, 0);
|
return generateRandomPattern(0.52, 0.15, 0, 0);
|
||||||
@ -194,7 +195,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
if (ConversionDifficulty > 2)
|
if (ConversionDifficulty > 2)
|
||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.LowProbability))
|
if (convertType.HasFlagFast(PatternType.LowProbability))
|
||||||
return generateRandomPattern(0.18, 0, 0, 0);
|
return generateRandomPattern(0.18, 0, 0, 0);
|
||||||
|
|
||||||
return generateRandomPattern(0.45, 0, 0, 0);
|
return generateRandomPattern(0.45, 0, 0, 0);
|
||||||
@ -207,9 +208,9 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
foreach (var obj in p.HitObjects)
|
foreach (var obj in p.HitObjects)
|
||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.Stair) && obj.Column == TotalColumns - 1)
|
if (convertType.HasFlagFast(PatternType.Stair) && obj.Column == TotalColumns - 1)
|
||||||
StairType = PatternType.ReverseStair;
|
StairType = PatternType.ReverseStair;
|
||||||
if (convertType.HasFlag(PatternType.ReverseStair) && obj.Column == RandomStart)
|
if (convertType.HasFlagFast(PatternType.ReverseStair) && obj.Column == RandomStart)
|
||||||
StairType = PatternType.Stair;
|
StairType = PatternType.Stair;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -229,7 +230,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
{
|
{
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
|
||||||
bool allowStacking = !convertType.HasFlag(PatternType.ForceNotStack);
|
bool allowStacking = !convertType.HasFlagFast(PatternType.ForceNotStack);
|
||||||
|
|
||||||
if (!allowStacking)
|
if (!allowStacking)
|
||||||
noteCount = Math.Min(noteCount, TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects);
|
noteCount = Math.Min(noteCount, TotalColumns - RandomStart - PreviousPattern.ColumnWithObjects);
|
||||||
@ -249,7 +250,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
|
|
||||||
int getNextColumn(int last)
|
int getNextColumn(int last)
|
||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.Gathered))
|
if (convertType.HasFlagFast(PatternType.Gathered))
|
||||||
{
|
{
|
||||||
last++;
|
last++;
|
||||||
if (last == TotalColumns)
|
if (last == TotalColumns)
|
||||||
@ -296,7 +297,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps.Patterns.Legacy
|
|||||||
/// <returns>The <see cref="Pattern"/> containing the hit objects.</returns>
|
/// <returns>The <see cref="Pattern"/> containing the hit objects.</returns>
|
||||||
private Pattern generateRandomPatternWithMirrored(double centreProbability, double p2, double p3)
|
private Pattern generateRandomPatternWithMirrored(double centreProbability, double p2, double p3)
|
||||||
{
|
{
|
||||||
if (convertType.HasFlag(PatternType.ForceNotStack))
|
if (convertType.HasFlagFast(PatternType.ForceNotStack))
|
||||||
return generateRandomPattern(1 / 2f + p2 / 2, p2, (p2 + p3) / 2, p3);
|
return generateRandomPattern(1 / 2f + p2 / 2, p2, (p2 + p3) / 2, p3);
|
||||||
|
|
||||||
var pattern = new Pattern();
|
var pattern = new Pattern();
|
||||||
|
@ -45,6 +45,7 @@ namespace osu.Game.Rulesets.Mania.Edit
|
|||||||
int minColumn = int.MaxValue;
|
int minColumn = int.MaxValue;
|
||||||
int maxColumn = int.MinValue;
|
int maxColumn = int.MinValue;
|
||||||
|
|
||||||
|
// find min/max in an initial pass before actually performing the movement.
|
||||||
foreach (var obj in EditorBeatmap.SelectedHitObjects.OfType<ManiaHitObject>())
|
foreach (var obj in EditorBeatmap.SelectedHitObjects.OfType<ManiaHitObject>())
|
||||||
{
|
{
|
||||||
if (obj.Column < minColumn)
|
if (obj.Column < minColumn)
|
||||||
@ -55,8 +56,11 @@ namespace osu.Game.Rulesets.Mania.Edit
|
|||||||
|
|
||||||
columnDelta = Math.Clamp(columnDelta, -minColumn, maniaPlayfield.TotalColumns - 1 - maxColumn);
|
columnDelta = Math.Clamp(columnDelta, -minColumn, maniaPlayfield.TotalColumns - 1 - maxColumn);
|
||||||
|
|
||||||
foreach (var obj in EditorBeatmap.SelectedHitObjects.OfType<ManiaHitObject>())
|
EditorBeatmap.PerformOnSelection(h =>
|
||||||
obj.Column += columnDelta;
|
{
|
||||||
|
if (h is ManiaHitObject maniaObj)
|
||||||
|
maniaObj.Column += columnDelta;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -9,6 +9,7 @@ using osu.Game.Rulesets.Mods;
|
|||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Input.Bindings;
|
using osu.Framework.Input.Bindings;
|
||||||
@ -59,76 +60,76 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
|
|
||||||
public override IEnumerable<Mod> ConvertFromLegacyMods(LegacyMods mods)
|
public override IEnumerable<Mod> ConvertFromLegacyMods(LegacyMods mods)
|
||||||
{
|
{
|
||||||
if (mods.HasFlag(LegacyMods.Nightcore))
|
if (mods.HasFlagFast(LegacyMods.Nightcore))
|
||||||
yield return new ManiaModNightcore();
|
yield return new ManiaModNightcore();
|
||||||
else if (mods.HasFlag(LegacyMods.DoubleTime))
|
else if (mods.HasFlagFast(LegacyMods.DoubleTime))
|
||||||
yield return new ManiaModDoubleTime();
|
yield return new ManiaModDoubleTime();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Perfect))
|
if (mods.HasFlagFast(LegacyMods.Perfect))
|
||||||
yield return new ManiaModPerfect();
|
yield return new ManiaModPerfect();
|
||||||
else if (mods.HasFlag(LegacyMods.SuddenDeath))
|
else if (mods.HasFlagFast(LegacyMods.SuddenDeath))
|
||||||
yield return new ManiaModSuddenDeath();
|
yield return new ManiaModSuddenDeath();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Cinema))
|
if (mods.HasFlagFast(LegacyMods.Cinema))
|
||||||
yield return new ManiaModCinema();
|
yield return new ManiaModCinema();
|
||||||
else if (mods.HasFlag(LegacyMods.Autoplay))
|
else if (mods.HasFlagFast(LegacyMods.Autoplay))
|
||||||
yield return new ManiaModAutoplay();
|
yield return new ManiaModAutoplay();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Easy))
|
if (mods.HasFlagFast(LegacyMods.Easy))
|
||||||
yield return new ManiaModEasy();
|
yield return new ManiaModEasy();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.FadeIn))
|
if (mods.HasFlagFast(LegacyMods.FadeIn))
|
||||||
yield return new ManiaModFadeIn();
|
yield return new ManiaModFadeIn();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Flashlight))
|
if (mods.HasFlagFast(LegacyMods.Flashlight))
|
||||||
yield return new ManiaModFlashlight();
|
yield return new ManiaModFlashlight();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.HalfTime))
|
if (mods.HasFlagFast(LegacyMods.HalfTime))
|
||||||
yield return new ManiaModHalfTime();
|
yield return new ManiaModHalfTime();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.HardRock))
|
if (mods.HasFlagFast(LegacyMods.HardRock))
|
||||||
yield return new ManiaModHardRock();
|
yield return new ManiaModHardRock();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Hidden))
|
if (mods.HasFlagFast(LegacyMods.Hidden))
|
||||||
yield return new ManiaModHidden();
|
yield return new ManiaModHidden();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Key1))
|
if (mods.HasFlagFast(LegacyMods.Key1))
|
||||||
yield return new ManiaModKey1();
|
yield return new ManiaModKey1();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Key2))
|
if (mods.HasFlagFast(LegacyMods.Key2))
|
||||||
yield return new ManiaModKey2();
|
yield return new ManiaModKey2();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Key3))
|
if (mods.HasFlagFast(LegacyMods.Key3))
|
||||||
yield return new ManiaModKey3();
|
yield return new ManiaModKey3();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Key4))
|
if (mods.HasFlagFast(LegacyMods.Key4))
|
||||||
yield return new ManiaModKey4();
|
yield return new ManiaModKey4();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Key5))
|
if (mods.HasFlagFast(LegacyMods.Key5))
|
||||||
yield return new ManiaModKey5();
|
yield return new ManiaModKey5();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Key6))
|
if (mods.HasFlagFast(LegacyMods.Key6))
|
||||||
yield return new ManiaModKey6();
|
yield return new ManiaModKey6();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Key7))
|
if (mods.HasFlagFast(LegacyMods.Key7))
|
||||||
yield return new ManiaModKey7();
|
yield return new ManiaModKey7();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Key8))
|
if (mods.HasFlagFast(LegacyMods.Key8))
|
||||||
yield return new ManiaModKey8();
|
yield return new ManiaModKey8();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Key9))
|
if (mods.HasFlagFast(LegacyMods.Key9))
|
||||||
yield return new ManiaModKey9();
|
yield return new ManiaModKey9();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.KeyCoop))
|
if (mods.HasFlagFast(LegacyMods.KeyCoop))
|
||||||
yield return new ManiaModDualStages();
|
yield return new ManiaModDualStages();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.NoFail))
|
if (mods.HasFlagFast(LegacyMods.NoFail))
|
||||||
yield return new ManiaModNoFail();
|
yield return new ManiaModNoFail();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Random))
|
if (mods.HasFlagFast(LegacyMods.Random))
|
||||||
yield return new ManiaModRandom();
|
yield return new ManiaModRandom();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Mirror))
|
if (mods.HasFlagFast(LegacyMods.Mirror))
|
||||||
yield return new ManiaModMirror();
|
yield return new ManiaModMirror();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -1,18 +1,20 @@
|
|||||||
// 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.Sprites;
|
using System;
|
||||||
using osu.Game.Graphics;
|
using System.Linq;
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
public class ManiaModFadeIn : ManiaModHidden
|
public class ManiaModFadeIn : ManiaModPlayfieldCover
|
||||||
{
|
{
|
||||||
public override string Name => "Fade In";
|
public override string Name => "Fade In";
|
||||||
public override string Acronym => "FI";
|
public override string Acronym => "FI";
|
||||||
public override IconUsage? Icon => OsuIcon.ModHidden;
|
|
||||||
public override string Description => @"Keys appear out of nowhere!";
|
public override string Description => @"Keys appear out of nowhere!";
|
||||||
|
public override double ScoreMultiplier => 1;
|
||||||
|
|
||||||
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ManiaModHidden)).ToArray();
|
||||||
|
|
||||||
protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AlongScroll;
|
protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AlongScroll;
|
||||||
}
|
}
|
||||||
|
@ -3,43 +3,17 @@
|
|||||||
|
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Graphics;
|
|
||||||
using osu.Framework.Graphics.Containers;
|
|
||||||
using osu.Game.Rulesets.Mania.Objects;
|
|
||||||
using osu.Game.Rulesets.Mania.UI;
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
using osu.Game.Rulesets.Mods;
|
|
||||||
using osu.Game.Rulesets.UI;
|
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Mods
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
{
|
{
|
||||||
public class ManiaModHidden : ModHidden, IApplicableToDrawableRuleset<ManiaHitObject>
|
public class ManiaModHidden : ManiaModPlayfieldCover
|
||||||
{
|
{
|
||||||
public override string Description => @"Keys fade out before you hit them!";
|
public override string Description => @"Keys fade out before you hit them!";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight<ManiaHitObject>) };
|
|
||||||
|
|
||||||
/// <summary>
|
public override Type[] IncompatibleMods => base.IncompatibleMods.Append(typeof(ManiaModFadeIn)).ToArray();
|
||||||
/// The direction in which the cover should expand.
|
|
||||||
/// </summary>
|
|
||||||
protected virtual CoverExpandDirection ExpandDirection => CoverExpandDirection.AgainstScroll;
|
|
||||||
|
|
||||||
public virtual void ApplyToDrawableRuleset(DrawableRuleset<ManiaHitObject> drawableRuleset)
|
protected override CoverExpandDirection ExpandDirection => CoverExpandDirection.AgainstScroll;
|
||||||
{
|
|
||||||
ManiaPlayfield maniaPlayfield = (ManiaPlayfield)drawableRuleset.Playfield;
|
|
||||||
|
|
||||||
foreach (Column column in maniaPlayfield.Stages.SelectMany(stage => stage.Columns))
|
|
||||||
{
|
|
||||||
HitObjectContainer hoc = column.HitObjectArea.HitObjectContainer;
|
|
||||||
Container hocParent = (Container)hoc.Parent;
|
|
||||||
|
|
||||||
hocParent.Remove(hoc);
|
|
||||||
hocParent.Add(new PlayfieldCoveringWrapper(hoc).With(c =>
|
|
||||||
{
|
|
||||||
c.RelativeSizeAxes = Axes.Both;
|
|
||||||
c.Direction = ExpandDirection;
|
|
||||||
c.Coverage = 0.5f;
|
|
||||||
}));
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
43
osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs
Normal file
43
osu.Game.Rulesets.Mania/Mods/ManiaModPlayfieldCover.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// 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.Linq;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Game.Rulesets.Mania.Objects;
|
||||||
|
using osu.Game.Rulesets.Mania.UI;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
|
using osu.Game.Rulesets.UI;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Mania.Mods
|
||||||
|
{
|
||||||
|
public abstract class ManiaModPlayfieldCover : ModHidden, IApplicableToDrawableRuleset<ManiaHitObject>
|
||||||
|
{
|
||||||
|
public override Type[] IncompatibleMods => new[] { typeof(ModFlashlight<ManiaHitObject>) };
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// The direction in which the cover should expand.
|
||||||
|
/// </summary>
|
||||||
|
protected abstract CoverExpandDirection ExpandDirection { get; }
|
||||||
|
|
||||||
|
public virtual void ApplyToDrawableRuleset(DrawableRuleset<ManiaHitObject> drawableRuleset)
|
||||||
|
{
|
||||||
|
ManiaPlayfield maniaPlayfield = (ManiaPlayfield)drawableRuleset.Playfield;
|
||||||
|
|
||||||
|
foreach (Column column in maniaPlayfield.Stages.SelectMany(stage => stage.Columns))
|
||||||
|
{
|
||||||
|
HitObjectContainer hoc = column.HitObjectArea.HitObjectContainer;
|
||||||
|
Container hocParent = (Container)hoc.Parent;
|
||||||
|
|
||||||
|
hocParent.Remove(hoc);
|
||||||
|
hocParent.Add(new PlayfieldCoveringWrapper(hoc).With(c =>
|
||||||
|
{
|
||||||
|
c.RelativeSizeAxes = Axes.Both;
|
||||||
|
c.Direction = ExpandDirection;
|
||||||
|
c.Coverage = 0.5f;
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -22,7 +22,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
public override ModType Type => ModType.Automation;
|
public override ModType Type => ModType.Automation;
|
||||||
public override string Description => @"Automatic cursor movement - just follow the rhythm.";
|
public override string Description => @"Automatic cursor movement - just follow the rhythm.";
|
||||||
public override double ScoreMultiplier => 1;
|
public override double ScoreMultiplier => 1;
|
||||||
public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModSuddenDeath), typeof(ModNoFail), typeof(ModAutoplay) };
|
public override Type[] IncompatibleMods => new[] { typeof(OsuModSpunOut), typeof(ModRelax), typeof(ModFailCondition), typeof(ModNoFail), typeof(ModAutoplay) };
|
||||||
|
|
||||||
public bool PerformFail() => false;
|
public bool PerformFail() => false;
|
||||||
|
|
||||||
|
@ -11,7 +11,7 @@ using osu.Game.Rulesets.Osu.Skinning.Default;
|
|||||||
|
|
||||||
namespace osu.Game.Rulesets.Osu.Mods
|
namespace osu.Game.Rulesets.Osu.Mods
|
||||||
{
|
{
|
||||||
internal class OsuModTraceable : ModWithVisibilityAdjustment
|
public class OsuModTraceable : ModWithVisibilityAdjustment
|
||||||
{
|
{
|
||||||
public override string Name => "Traceable";
|
public override string Name => "Traceable";
|
||||||
public override string Acronym => "TC";
|
public override string Acronym => "TC";
|
||||||
|
@ -29,6 +29,7 @@ using osu.Game.Scoring;
|
|||||||
using osu.Game.Skinning;
|
using osu.Game.Skinning;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.Osu.Skinning.Legacy;
|
using osu.Game.Rulesets.Osu.Skinning.Legacy;
|
||||||
using osu.Game.Rulesets.Osu.Statistics;
|
using osu.Game.Rulesets.Osu.Statistics;
|
||||||
@ -58,52 +59,52 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
|
|
||||||
public override IEnumerable<Mod> ConvertFromLegacyMods(LegacyMods mods)
|
public override IEnumerable<Mod> ConvertFromLegacyMods(LegacyMods mods)
|
||||||
{
|
{
|
||||||
if (mods.HasFlag(LegacyMods.Nightcore))
|
if (mods.HasFlagFast(LegacyMods.Nightcore))
|
||||||
yield return new OsuModNightcore();
|
yield return new OsuModNightcore();
|
||||||
else if (mods.HasFlag(LegacyMods.DoubleTime))
|
else if (mods.HasFlagFast(LegacyMods.DoubleTime))
|
||||||
yield return new OsuModDoubleTime();
|
yield return new OsuModDoubleTime();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Perfect))
|
if (mods.HasFlagFast(LegacyMods.Perfect))
|
||||||
yield return new OsuModPerfect();
|
yield return new OsuModPerfect();
|
||||||
else if (mods.HasFlag(LegacyMods.SuddenDeath))
|
else if (mods.HasFlagFast(LegacyMods.SuddenDeath))
|
||||||
yield return new OsuModSuddenDeath();
|
yield return new OsuModSuddenDeath();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Autopilot))
|
if (mods.HasFlagFast(LegacyMods.Autopilot))
|
||||||
yield return new OsuModAutopilot();
|
yield return new OsuModAutopilot();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Cinema))
|
if (mods.HasFlagFast(LegacyMods.Cinema))
|
||||||
yield return new OsuModCinema();
|
yield return new OsuModCinema();
|
||||||
else if (mods.HasFlag(LegacyMods.Autoplay))
|
else if (mods.HasFlagFast(LegacyMods.Autoplay))
|
||||||
yield return new OsuModAutoplay();
|
yield return new OsuModAutoplay();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Easy))
|
if (mods.HasFlagFast(LegacyMods.Easy))
|
||||||
yield return new OsuModEasy();
|
yield return new OsuModEasy();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Flashlight))
|
if (mods.HasFlagFast(LegacyMods.Flashlight))
|
||||||
yield return new OsuModFlashlight();
|
yield return new OsuModFlashlight();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.HalfTime))
|
if (mods.HasFlagFast(LegacyMods.HalfTime))
|
||||||
yield return new OsuModHalfTime();
|
yield return new OsuModHalfTime();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.HardRock))
|
if (mods.HasFlagFast(LegacyMods.HardRock))
|
||||||
yield return new OsuModHardRock();
|
yield return new OsuModHardRock();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Hidden))
|
if (mods.HasFlagFast(LegacyMods.Hidden))
|
||||||
yield return new OsuModHidden();
|
yield return new OsuModHidden();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.NoFail))
|
if (mods.HasFlagFast(LegacyMods.NoFail))
|
||||||
yield return new OsuModNoFail();
|
yield return new OsuModNoFail();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Relax))
|
if (mods.HasFlagFast(LegacyMods.Relax))
|
||||||
yield return new OsuModRelax();
|
yield return new OsuModRelax();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.SpunOut))
|
if (mods.HasFlagFast(LegacyMods.SpunOut))
|
||||||
yield return new OsuModSpunOut();
|
yield return new OsuModSpunOut();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Target))
|
if (mods.HasFlagFast(LegacyMods.Target))
|
||||||
yield return new OsuModTarget();
|
yield return new OsuModTarget();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.TouchDevice))
|
if (mods.HasFlagFast(LegacyMods.TouchDevice))
|
||||||
yield return new OsuModTouchDevice();
|
yield return new OsuModTouchDevice();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
|
|||||||
|
|
||||||
public string Text
|
public string Text
|
||||||
{
|
{
|
||||||
get => number.Text;
|
get => number.Text.ToString();
|
||||||
set => number.Text = value;
|
set => number.Text = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -2,7 +2,7 @@
|
|||||||
<Import Project="..\osu.TestProject.props" />
|
<Import Project="..\osu.TestProject.props" />
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
|
@ -52,32 +52,24 @@ namespace osu.Game.Rulesets.Taiko.Edit
|
|||||||
|
|
||||||
public void SetStrongState(bool state)
|
public void SetStrongState(bool state)
|
||||||
{
|
{
|
||||||
var hits = EditorBeatmap.SelectedHitObjects.OfType<Hit>();
|
EditorBeatmap.PerformOnSelection(h =>
|
||||||
|
|
||||||
EditorBeatmap.BeginChange();
|
|
||||||
|
|
||||||
foreach (var h in hits)
|
|
||||||
{
|
{
|
||||||
if (h.IsStrong != state)
|
if (!(h is Hit taikoHit)) return;
|
||||||
{
|
|
||||||
h.IsStrong = state;
|
|
||||||
EditorBeatmap.Update(h);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
EditorBeatmap.EndChange();
|
if (taikoHit.IsStrong != state)
|
||||||
|
{
|
||||||
|
taikoHit.IsStrong = state;
|
||||||
|
EditorBeatmap.Update(taikoHit);
|
||||||
|
}
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SetRimState(bool state)
|
public void SetRimState(bool state)
|
||||||
{
|
{
|
||||||
var hits = EditorBeatmap.SelectedHitObjects.OfType<Hit>();
|
EditorBeatmap.PerformOnSelection(h =>
|
||||||
|
{
|
||||||
EditorBeatmap.BeginChange();
|
if (h is Hit taikoHit) taikoHit.Type = state ? HitType.Rim : HitType.Centre;
|
||||||
|
});
|
||||||
foreach (var h in hits)
|
|
||||||
h.Type = state ? HitType.Rim : HitType.Centre;
|
|
||||||
|
|
||||||
EditorBeatmap.EndChange();
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IEnumerable<MenuItem> GetContextMenuItemsForSelection(IEnumerable<SelectionBlueprint> selection)
|
protected override IEnumerable<MenuItem> GetContextMenuItemsForSelection(IEnumerable<SelectionBlueprint> selection)
|
||||||
|
@ -22,6 +22,7 @@ using osu.Game.Rulesets.Taiko.Scoring;
|
|||||||
using osu.Game.Scoring;
|
using osu.Game.Scoring;
|
||||||
using System;
|
using System;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
using osu.Game.Rulesets.Edit;
|
using osu.Game.Rulesets.Edit;
|
||||||
using osu.Game.Rulesets.Taiko.Edit;
|
using osu.Game.Rulesets.Taiko.Edit;
|
||||||
using osu.Game.Rulesets.Taiko.Objects;
|
using osu.Game.Rulesets.Taiko.Objects;
|
||||||
@ -57,43 +58,43 @@ namespace osu.Game.Rulesets.Taiko
|
|||||||
|
|
||||||
public override IEnumerable<Mod> ConvertFromLegacyMods(LegacyMods mods)
|
public override IEnumerable<Mod> ConvertFromLegacyMods(LegacyMods mods)
|
||||||
{
|
{
|
||||||
if (mods.HasFlag(LegacyMods.Nightcore))
|
if (mods.HasFlagFast(LegacyMods.Nightcore))
|
||||||
yield return new TaikoModNightcore();
|
yield return new TaikoModNightcore();
|
||||||
else if (mods.HasFlag(LegacyMods.DoubleTime))
|
else if (mods.HasFlagFast(LegacyMods.DoubleTime))
|
||||||
yield return new TaikoModDoubleTime();
|
yield return new TaikoModDoubleTime();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Perfect))
|
if (mods.HasFlagFast(LegacyMods.Perfect))
|
||||||
yield return new TaikoModPerfect();
|
yield return new TaikoModPerfect();
|
||||||
else if (mods.HasFlag(LegacyMods.SuddenDeath))
|
else if (mods.HasFlagFast(LegacyMods.SuddenDeath))
|
||||||
yield return new TaikoModSuddenDeath();
|
yield return new TaikoModSuddenDeath();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Cinema))
|
if (mods.HasFlagFast(LegacyMods.Cinema))
|
||||||
yield return new TaikoModCinema();
|
yield return new TaikoModCinema();
|
||||||
else if (mods.HasFlag(LegacyMods.Autoplay))
|
else if (mods.HasFlagFast(LegacyMods.Autoplay))
|
||||||
yield return new TaikoModAutoplay();
|
yield return new TaikoModAutoplay();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Easy))
|
if (mods.HasFlagFast(LegacyMods.Easy))
|
||||||
yield return new TaikoModEasy();
|
yield return new TaikoModEasy();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Flashlight))
|
if (mods.HasFlagFast(LegacyMods.Flashlight))
|
||||||
yield return new TaikoModFlashlight();
|
yield return new TaikoModFlashlight();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.HalfTime))
|
if (mods.HasFlagFast(LegacyMods.HalfTime))
|
||||||
yield return new TaikoModHalfTime();
|
yield return new TaikoModHalfTime();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.HardRock))
|
if (mods.HasFlagFast(LegacyMods.HardRock))
|
||||||
yield return new TaikoModHardRock();
|
yield return new TaikoModHardRock();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Hidden))
|
if (mods.HasFlagFast(LegacyMods.Hidden))
|
||||||
yield return new TaikoModHidden();
|
yield return new TaikoModHidden();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.NoFail))
|
if (mods.HasFlagFast(LegacyMods.NoFail))
|
||||||
yield return new TaikoModNoFail();
|
yield return new TaikoModNoFail();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Relax))
|
if (mods.HasFlagFast(LegacyMods.Relax))
|
||||||
yield return new TaikoModRelax();
|
yield return new TaikoModRelax();
|
||||||
|
|
||||||
if (mods.HasFlag(LegacyMods.Random))
|
if (mods.HasFlagFast(LegacyMods.Random))
|
||||||
yield return new TaikoModRandom();
|
yield return new TaikoModRandom();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -71,7 +71,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
||||||
<PackageReference Include="Moq" Version="4.16.0" />
|
<PackageReference Include="Moq" Version="4.16.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath)\Xamarin\Android\Xamarin.Android.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
@ -45,7 +45,7 @@
|
|||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
||||||
<PackageReference Include="Moq" Version="4.16.0" />
|
<PackageReference Include="Moq" Version="4.16.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
|
<Import Project="$(MSBuildExtensionsPath)\Xamarin\iOS\Xamarin.iOS.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
@ -852,6 +852,21 @@ namespace osu.Game.Tests.Beatmaps.IO
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public static async Task<BeatmapSetInfo> LoadQuickOszIntoOsu(OsuGameBase osu)
|
||||||
|
{
|
||||||
|
var temp = TestResources.GetQuickTestBeatmapForImport();
|
||||||
|
|
||||||
|
var manager = osu.Dependencies.Get<BeatmapManager>();
|
||||||
|
|
||||||
|
var importedSet = await manager.Import(new ImportTask(temp));
|
||||||
|
|
||||||
|
ensureLoaded(osu);
|
||||||
|
|
||||||
|
waitForOrAssert(() => !File.Exists(temp), "Temporary file still exists after standard import", 5000);
|
||||||
|
|
||||||
|
return manager.GetAllUsableBeatmapSets().Find(beatmapSet => beatmapSet.ID == importedSet.ID);
|
||||||
|
}
|
||||||
|
|
||||||
public static async Task<BeatmapSetInfo> LoadOszIntoOsu(OsuGameBase osu, string path = null, bool virtualTrack = false)
|
public static async Task<BeatmapSetInfo> LoadOszIntoOsu(OsuGameBase osu, string path = null, bool virtualTrack = false)
|
||||||
{
|
{
|
||||||
var temp = path ?? TestResources.GetTestBeatmapForImport(virtualTrack);
|
var temp = path ?? TestResources.GetTestBeatmapForImport(virtualTrack);
|
||||||
|
@ -13,6 +13,7 @@ using osu.Framework.Graphics.Audio;
|
|||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.IO.Stores;
|
using osu.Framework.IO.Stores;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Audio;
|
using osu.Game.Audio;
|
||||||
using osu.Game.IO;
|
using osu.Game.IO;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -90,6 +91,7 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
public void TestSamplePlaybackWithRateMods(Type expectedMod, double expectedRate)
|
public void TestSamplePlaybackWithRateMods(Type expectedMod, double expectedRate)
|
||||||
{
|
{
|
||||||
GameplayClockContainer gameplayContainer = null;
|
GameplayClockContainer gameplayContainer = null;
|
||||||
|
StoryboardSampleInfo sampleInfo = null;
|
||||||
TestDrawableStoryboardSample sample = null;
|
TestDrawableStoryboardSample sample = null;
|
||||||
|
|
||||||
Mod testedMod = Activator.CreateInstance(expectedMod) as Mod;
|
Mod testedMod = Activator.CreateInstance(expectedMod) as Mod;
|
||||||
@ -101,7 +103,7 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
break;
|
break;
|
||||||
|
|
||||||
case ModTimeRamp m:
|
case ModTimeRamp m:
|
||||||
m.InitialRate.Value = m.FinalRate.Value = expectedRate;
|
m.FinalRate.Value = m.InitialRate.Value = expectedRate;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -117,7 +119,7 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
Child = beatmapSkinSourceContainer
|
Child = beatmapSkinSourceContainer
|
||||||
});
|
});
|
||||||
|
|
||||||
beatmapSkinSourceContainer.Add(sample = new TestDrawableStoryboardSample(new StoryboardSampleInfo("test-sample", 1, 1))
|
beatmapSkinSourceContainer.Add(sample = new TestDrawableStoryboardSample(sampleInfo = new StoryboardSampleInfo("test-sample", 1, 1))
|
||||||
{
|
{
|
||||||
Clock = gameplayContainer.GameplayClock
|
Clock = gameplayContainer.GameplayClock
|
||||||
});
|
});
|
||||||
@ -125,7 +127,10 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
|
|
||||||
AddStep("start", () => gameplayContainer.Start());
|
AddStep("start", () => gameplayContainer.Start());
|
||||||
|
|
||||||
AddAssert("sample playback rate matches mod rates", () => sample.ChildrenOfType<DrawableSample>().First().AggregateFrequency.Value == expectedRate);
|
AddAssert("sample playback rate matches mod rates", () =>
|
||||||
|
testedMod != null && Precision.AlmostEquals(
|
||||||
|
sample.ChildrenOfType<DrawableSample>().First().AggregateFrequency.Value,
|
||||||
|
((IApplicableToRate)testedMod).ApplyToRate(sampleInfo.StartTime)));
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestSkin : LegacySkin
|
private class TestSkin : LegacySkin
|
||||||
|
44
osu.Game.Tests/Mods/SettingsSourceAttributeTest.cs
Normal file
44
osu.Game.Tests/Mods/SettingsSourceAttributeTest.cs
Normal file
@ -0,0 +1,44 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Game.Configuration;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Mods
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class SettingsSourceAttributeTest
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestOrdering()
|
||||||
|
{
|
||||||
|
var objectWithSettings = new ClassWithSettings();
|
||||||
|
|
||||||
|
var orderedSettings = objectWithSettings.GetOrderedSettingsSourceProperties().ToArray();
|
||||||
|
|
||||||
|
Assert.That(orderedSettings, Has.Length.EqualTo(4));
|
||||||
|
|
||||||
|
Assert.That(orderedSettings[0].Item2.Name, Is.EqualTo(nameof(ClassWithSettings.FirstSetting)));
|
||||||
|
Assert.That(orderedSettings[1].Item2.Name, Is.EqualTo(nameof(ClassWithSettings.SecondSetting)));
|
||||||
|
Assert.That(orderedSettings[2].Item2.Name, Is.EqualTo(nameof(ClassWithSettings.ThirdSetting)));
|
||||||
|
Assert.That(orderedSettings[3].Item2.Name, Is.EqualTo(nameof(ClassWithSettings.UnorderedSetting)));
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ClassWithSettings
|
||||||
|
{
|
||||||
|
[SettingSource("Unordered setting", "Should be last")]
|
||||||
|
public BindableFloat UnorderedSetting { get; set; } = new BindableFloat();
|
||||||
|
|
||||||
|
[SettingSource("Second setting", "Another description", 2)]
|
||||||
|
public BindableBool SecondSetting { get; set; } = new BindableBool();
|
||||||
|
|
||||||
|
[SettingSource("First setting", "A description", 1)]
|
||||||
|
public BindableDouble FirstSetting { get; set; } = new BindableDouble();
|
||||||
|
|
||||||
|
[SettingSource("Third setting", "Yet another description", 3)]
|
||||||
|
public BindableInt ThirdSetting { get; set; } = new BindableInt();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -52,7 +52,7 @@ namespace osu.Game.Tests.Online
|
|||||||
{
|
{
|
||||||
beatmaps.AllowImport = new TaskCompletionSource<bool>();
|
beatmaps.AllowImport = new TaskCompletionSource<bool>();
|
||||||
|
|
||||||
testBeatmapFile = TestResources.GetTestBeatmapForImport();
|
testBeatmapFile = TestResources.GetQuickTestBeatmapForImport();
|
||||||
|
|
||||||
testBeatmapInfo = getTestBeatmapInfo(testBeatmapFile);
|
testBeatmapInfo = getTestBeatmapInfo(testBeatmapFile);
|
||||||
testBeatmapSet = testBeatmapInfo.BeatmapSet;
|
testBeatmapSet = testBeatmapInfo.BeatmapSet;
|
||||||
|
Binary file not shown.
@ -15,6 +15,28 @@ namespace osu.Game.Tests.Resources
|
|||||||
|
|
||||||
public static Stream GetTestBeatmapStream(bool virtualTrack = false) => OpenResource($"Archives/241526 Soleily - Renatus{(virtualTrack ? "_virtual" : "")}.osz");
|
public static Stream GetTestBeatmapStream(bool virtualTrack = false) => OpenResource($"Archives/241526 Soleily - Renatus{(virtualTrack ? "_virtual" : "")}.osz");
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve a path to a copy of a shortened (~10 second) beatmap archive with a virtual track.
|
||||||
|
/// </summary>
|
||||||
|
/// <remarks>
|
||||||
|
/// This is intended for use in tests which need to run to completion as soon as possible and don't need to test a full length beatmap.</remarks>
|
||||||
|
/// <returns>A path to a copy of a beatmap archive (osz). Should be deleted after use.</returns>
|
||||||
|
public static string GetQuickTestBeatmapForImport()
|
||||||
|
{
|
||||||
|
var tempPath = Path.GetTempFileName() + ".osz";
|
||||||
|
using (var stream = OpenResource("Archives/241526 Soleily - Renatus_virtual_quick.osz"))
|
||||||
|
using (var newFile = File.Create(tempPath))
|
||||||
|
stream.CopyTo(newFile);
|
||||||
|
|
||||||
|
Assert.IsTrue(File.Exists(tempPath));
|
||||||
|
return tempPath;
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Retrieve a path to a copy of a full-fledged beatmap archive.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="virtualTrack">Whether the audio track should be virtual.</param>
|
||||||
|
/// <returns>A path to a copy of a beatmap archive (osz). Should be deleted after use.</returns>
|
||||||
public static string GetTestBeatmapForImport(bool virtualTrack = false)
|
public static string GetTestBeatmapForImport(bool virtualTrack = false)
|
||||||
{
|
{
|
||||||
var tempPath = Path.GetTempFileName() + ".osz";
|
var tempPath = Path.GetTempFileName() + ".osz";
|
||||||
|
@ -118,6 +118,10 @@ namespace osu.Game.Tests.Rulesets
|
|||||||
public BindableNumber<double> Frequency => throw new NotImplementedException();
|
public BindableNumber<double> Frequency => throw new NotImplementedException();
|
||||||
public BindableNumber<double> Tempo => throw new NotImplementedException();
|
public BindableNumber<double> Tempo => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public void BindAdjustments(IAggregateAudioAdjustment component) => throw new NotImplementedException();
|
||||||
|
|
||||||
|
public void UnbindAdjustments(IAggregateAudioAdjustment component) => throw new NotImplementedException();
|
||||||
|
|
||||||
public void AddAdjustment(AdjustableProperty type, IBindable<double> adjustBindable) => throw new NotImplementedException();
|
public void AddAdjustment(AdjustableProperty type, IBindable<double> adjustBindable) => throw new NotImplementedException();
|
||||||
|
|
||||||
public void RemoveAdjustment(AdjustableProperty type, IBindable<double> adjustBindable) => throw new NotImplementedException();
|
public void RemoveAdjustment(AdjustableProperty type, IBindable<double> adjustBindable) => throw new NotImplementedException();
|
||||||
|
@ -51,7 +51,7 @@ namespace osu.Game.Tests.Visual.Background
|
|||||||
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default));
|
Dependencies.Cache(manager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default));
|
||||||
Dependencies.Cache(new OsuConfigManager(LocalStorage));
|
Dependencies.Cache(new OsuConfigManager(LocalStorage));
|
||||||
|
|
||||||
manager.Import(TestResources.GetTestBeatmapForImport()).Wait();
|
manager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
|
||||||
|
|
||||||
Beatmap.SetDefault();
|
Beatmap.SetDefault();
|
||||||
}
|
}
|
||||||
|
@ -38,13 +38,13 @@ namespace osu.Game.Tests.Visual.Collections
|
|||||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||||
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, host, Beatmap.Default));
|
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, host, Beatmap.Default));
|
||||||
|
|
||||||
beatmapManager.Import(TestResources.GetTestBeatmapForImport()).Wait();
|
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
|
||||||
|
|
||||||
base.Content.AddRange(new Drawable[]
|
base.Content.AddRange(new Drawable[]
|
||||||
{
|
{
|
||||||
manager = new CollectionManager(LocalStorage),
|
manager = new CollectionManager(LocalStorage),
|
||||||
Content,
|
Content,
|
||||||
dialogOverlay = new DialogOverlay()
|
dialogOverlay = new DialogOverlay(),
|
||||||
});
|
});
|
||||||
|
|
||||||
Dependencies.Cache(manager);
|
Dependencies.Cache(manager);
|
||||||
@ -134,6 +134,27 @@ namespace osu.Game.Tests.Visual.Collections
|
|||||||
assertCollectionName(0, "2");
|
assertCollectionName(0, "2");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestCollectionNameCollisions()
|
||||||
|
{
|
||||||
|
AddStep("add dropdown", () =>
|
||||||
|
{
|
||||||
|
Add(new CollectionFilterDropdown
|
||||||
|
{
|
||||||
|
Anchor = Anchor.TopRight,
|
||||||
|
Origin = Anchor.TopRight,
|
||||||
|
RelativeSizeAxes = Axes.X,
|
||||||
|
Width = 0.4f,
|
||||||
|
}
|
||||||
|
);
|
||||||
|
});
|
||||||
|
AddStep("add two collections with same name", () => manager.Collections.AddRange(new[]
|
||||||
|
{
|
||||||
|
new BeatmapCollection { Name = { Value = "1" } },
|
||||||
|
new BeatmapCollection { Name = { Value = "1" }, Beatmaps = { beatmapManager.GetAllUsableBeatmapSets().First().Beatmaps[0] } },
|
||||||
|
}));
|
||||||
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestRemoveCollectionViaButton()
|
public void TestRemoveCollectionViaButton()
|
||||||
{
|
{
|
||||||
|
@ -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.Collections.Generic;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
@ -8,21 +9,17 @@ using osu.Framework.Platform;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Storyboards;
|
||||||
|
using osu.Game.Tests.Beatmaps;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Tests.Visual.Gameplay
|
namespace osu.Game.Tests.Visual.Gameplay
|
||||||
{
|
{
|
||||||
[HeadlessTest] // we alter unsafe properties on the game host to test inactive window state.
|
[HeadlessTest] // we alter unsafe properties on the game host to test inactive window state.
|
||||||
public class TestScenePauseWhenInactive : OsuPlayerTestScene
|
public class TestScenePauseWhenInactive : OsuPlayerTestScene
|
||||||
{
|
{
|
||||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
|
||||||
{
|
|
||||||
var beatmap = (Beatmap)base.CreateBeatmap(ruleset);
|
|
||||||
|
|
||||||
beatmap.HitObjects.RemoveAll(h => h.StartTime < 30000);
|
|
||||||
|
|
||||||
return beatmap;
|
|
||||||
}
|
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
private GameHost host { get; set; }
|
private GameHost host { get; set; }
|
||||||
|
|
||||||
@ -33,10 +30,57 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
AddStep("resume player", () => Player.GameplayClockContainer.Start());
|
AddStep("resume player", () => Player.GameplayClockContainer.Start());
|
||||||
AddAssert("ensure not paused", () => !Player.GameplayClockContainer.IsPaused.Value);
|
AddAssert("ensure not paused", () => !Player.GameplayClockContainer.IsPaused.Value);
|
||||||
|
|
||||||
|
AddStep("progress time to gameplay", () => Player.GameplayClockContainer.Seek(Player.DrawableRuleset.GameplayStartTime));
|
||||||
|
AddUntilStep("wait for pause", () => Player.GameplayClockContainer.IsPaused.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Tests that if a pause from focus lose is performed while in pause cooldown,
|
||||||
|
/// the player will still pause after the cooldown is finished.
|
||||||
|
/// </summary>
|
||||||
|
[Test]
|
||||||
|
public void TestPauseWhileInCooldown()
|
||||||
|
{
|
||||||
|
AddStep("move cursor outside", () => InputManager.MoveMouseTo(Player.ScreenSpaceDrawQuad.TopLeft - new Vector2(10)));
|
||||||
|
|
||||||
|
AddStep("resume player", () => Player.GameplayClockContainer.Start());
|
||||||
|
AddStep("skip to gameplay", () => Player.GameplayClockContainer.Seek(Player.DrawableRuleset.GameplayStartTime));
|
||||||
|
|
||||||
|
AddStep("set inactive", () => ((Bindable<bool>)host.IsActive).Value = false);
|
||||||
|
AddUntilStep("wait for pause", () => Player.GameplayClockContainer.IsPaused.Value);
|
||||||
|
|
||||||
|
AddStep("set active", () => ((Bindable<bool>)host.IsActive).Value = true);
|
||||||
|
|
||||||
|
AddStep("resume player", () => Player.Resume());
|
||||||
|
AddAssert("unpaused", () => !Player.GameplayClockContainer.IsPaused.Value);
|
||||||
|
|
||||||
|
bool pauseCooldownActive = false;
|
||||||
|
|
||||||
|
AddStep("set inactive again", () =>
|
||||||
|
{
|
||||||
|
pauseCooldownActive = Player.PauseCooldownActive;
|
||||||
|
((Bindable<bool>)host.IsActive).Value = false;
|
||||||
|
});
|
||||||
|
AddAssert("pause cooldown active", () => pauseCooldownActive);
|
||||||
AddUntilStep("wait for pause", () => Player.GameplayClockContainer.IsPaused.Value);
|
AddUntilStep("wait for pause", () => Player.GameplayClockContainer.IsPaused.Value);
|
||||||
AddAssert("time of pause is after gameplay start time", () => Player.GameplayClockContainer.GameplayClock.CurrentTime >= Player.DrawableRuleset.GameplayStartTime);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(true, true, true);
|
protected override TestPlayer CreatePlayer(Ruleset ruleset) => new TestPlayer(true, true, true);
|
||||||
|
|
||||||
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset)
|
||||||
|
{
|
||||||
|
return new Beatmap
|
||||||
|
{
|
||||||
|
HitObjects = new List<HitObject>
|
||||||
|
{
|
||||||
|
new HitCircle { StartTime = 30000 },
|
||||||
|
new HitCircle { StartTime = 35000 },
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
protected override WorkingBeatmap CreateWorkingBeatmap(IBeatmap beatmap, Storyboard storyboard = null)
|
||||||
|
=> new TestWorkingBeatmap(beatmap, storyboard, Audio);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -7,17 +7,23 @@ using System.Linq;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Audio;
|
using osu.Framework.Audio;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
|
using osu.Framework.Extensions.TypeExtensions;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Framework.Screens;
|
using osu.Framework.Screens;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Overlays.Mods;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Catch;
|
using osu.Game.Rulesets.Catch;
|
||||||
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osu.Game.Rulesets.Taiko;
|
using osu.Game.Rulesets.Taiko;
|
||||||
using osu.Game.Rulesets.Taiko.Mods;
|
using osu.Game.Rulesets.Taiko.Mods;
|
||||||
|
using osu.Game.Screens.OnlinePlay;
|
||||||
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
using osu.Game.Screens.OnlinePlay.Multiplayer;
|
||||||
using osu.Game.Screens.Select;
|
using osu.Game.Screens.Select;
|
||||||
|
|
||||||
@ -137,8 +143,30 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
AddAssert("mods not changed", () => SelectedMods.Value.Single() is TaikoModDoubleTime);
|
AddAssert("mods not changed", () => SelectedMods.Value.Single() is TaikoModDoubleTime);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[TestCase(typeof(OsuModHidden), typeof(OsuModHidden))] // Same mod.
|
||||||
|
[TestCase(typeof(OsuModHidden), typeof(OsuModTraceable))] // Incompatible.
|
||||||
|
public void TestAllowedModDeselectedWhenRequired(Type allowedMod, Type requiredMod)
|
||||||
|
{
|
||||||
|
AddStep($"select {allowedMod.ReadableName()} as allowed", () => songSelect.FreeMods.Value = new[] { (Mod)Activator.CreateInstance(allowedMod) });
|
||||||
|
AddStep($"select {requiredMod.ReadableName()} as required", () => songSelect.Mods.Value = new[] { (Mod)Activator.CreateInstance(requiredMod) });
|
||||||
|
|
||||||
|
AddAssert("freemods empty", () => songSelect.FreeMods.Value.Count == 0);
|
||||||
|
assertHasFreeModButton(allowedMod, false);
|
||||||
|
assertHasFreeModButton(requiredMod, false);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void assertHasFreeModButton(Type type, bool hasButton = true)
|
||||||
|
{
|
||||||
|
AddAssert($"{type.ReadableName()} {(hasButton ? "displayed" : "not displayed")} in freemod overlay",
|
||||||
|
() => songSelect.ChildrenOfType<FreeModSelectOverlay>().Single().ChildrenOfType<ModButton>().All(b => b.Mod.GetType() != type));
|
||||||
|
}
|
||||||
|
|
||||||
private class TestMultiplayerMatchSongSelect : MultiplayerMatchSongSelect
|
private class TestMultiplayerMatchSongSelect : MultiplayerMatchSongSelect
|
||||||
{
|
{
|
||||||
|
public new Bindable<IReadOnlyList<Mod>> Mods => base.Mods;
|
||||||
|
|
||||||
|
public new Bindable<IReadOnlyList<Mod>> FreeMods => base.FreeMods;
|
||||||
|
|
||||||
public new BeatmapCarousel Carousel => base.Carousel;
|
public new BeatmapCarousel Carousel => base.Carousel;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
{
|
{
|
||||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||||
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default));
|
Dependencies.Cache(beatmaps = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, audio, host, Beatmap.Default));
|
||||||
beatmaps.Import(TestResources.GetTestBeatmapForImport(true)).Wait();
|
beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
|
||||||
|
|
||||||
Add(beatmapTracker = new OnlinePlayBeatmapAvailablilityTracker
|
Add(beatmapTracker = new OnlinePlayBeatmapAvailablilityTracker
|
||||||
{
|
{
|
||||||
|
@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
|
|
||||||
PushAndConfirm(() => new TestSongSelect());
|
PushAndConfirm(() => new TestSongSelect());
|
||||||
|
|
||||||
AddStep("import beatmap", () => ImportBeatmapTest.LoadOszIntoOsu(Game, virtualTrack: true).Wait());
|
AddStep("import beatmap", () => ImportBeatmapTest.LoadQuickOszIntoOsu(Game).Wait());
|
||||||
|
|
||||||
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
|
AddUntilStep("wait for selected", () => !Game.Beatmap.IsDefault);
|
||||||
|
|
||||||
@ -61,7 +61,7 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
|
|
||||||
AddStep("press enter", () => InputManager.Key(Key.Enter));
|
AddStep("press enter", () => InputManager.Key(Key.Enter));
|
||||||
AddUntilStep("wait for player", () => (player = Game.ScreenStack.CurrentScreen as Player) != null);
|
AddUntilStep("wait for player", () => (player = Game.ScreenStack.CurrentScreen as Player) != null);
|
||||||
AddStep("seek to end", () => beatmap().Track.Seek(beatmap().Track.Length));
|
AddStep("seek to end", () => player.ChildrenOfType<GameplayClockContainer>().First().Seek(beatmap().Track.Length));
|
||||||
AddUntilStep("wait for pass", () => (results = Game.ScreenStack.CurrentScreen as ResultsScreen) != null && results.IsLoaded);
|
AddUntilStep("wait for pass", () => (results = Game.ScreenStack.CurrentScreen as ResultsScreen) != null && results.IsLoaded);
|
||||||
AddStep("attempt to retry", () => results.ChildrenOfType<HotkeyRetryOverlay>().First().Action());
|
AddStep("attempt to retry", () => results.ChildrenOfType<HotkeyRetryOverlay>().First().Action());
|
||||||
AddUntilStep("wait for player", () => Game.ScreenStack.CurrentScreen != player && Game.ScreenStack.CurrentScreen is Player);
|
AddUntilStep("wait for player", () => Game.ScreenStack.CurrentScreen != player && Game.ScreenStack.CurrentScreen is Player);
|
||||||
@ -214,6 +214,21 @@ namespace osu.Game.Tests.Visual.Navigation
|
|||||||
AddAssert("Options overlay still visible", () => songSelect.BeatmapOptionsOverlay.State.Value == Visibility.Visible);
|
AddAssert("Options overlay still visible", () => songSelect.BeatmapOptionsOverlay.State.Value == Visibility.Visible);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestSettingsViaHotkeyFromMainMenu()
|
||||||
|
{
|
||||||
|
AddAssert("toolbar not displayed", () => Game.Toolbar.State.Value == Visibility.Hidden);
|
||||||
|
|
||||||
|
AddStep("press settings hotkey", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.ControlLeft);
|
||||||
|
InputManager.Key(Key.O);
|
||||||
|
InputManager.ReleaseKey(Key.ControlLeft);
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("settings displayed", () => Game.Settings.State.Value == Visibility.Visible);
|
||||||
|
}
|
||||||
|
|
||||||
private void pushEscape() =>
|
private void pushEscape() =>
|
||||||
AddStep("Press escape", () => InputManager.Key(Key.Escape));
|
AddStep("Press escape", () => InputManager.Key(Key.Escape));
|
||||||
|
|
||||||
|
@ -42,7 +42,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
ensureSoleilyRemoved();
|
ensureSoleilyRemoved();
|
||||||
createButtonWithBeatmap(createSoleily());
|
createButtonWithBeatmap(createSoleily());
|
||||||
AddAssert("button state not downloaded", () => downloadButton.DownloadState == DownloadState.NotDownloaded);
|
AddAssert("button state not downloaded", () => downloadButton.DownloadState == DownloadState.NotDownloaded);
|
||||||
AddStep("import soleily", () => beatmaps.Import(TestResources.GetTestBeatmapForImport()));
|
AddStep("import soleily", () => beatmaps.Import(TestResources.GetQuickTestBeatmapForImport()));
|
||||||
AddUntilStep("wait for beatmap import", () => beatmaps.GetAllUsableBeatmapSets().Any(b => b.OnlineBeatmapSetID == 241526));
|
AddUntilStep("wait for beatmap import", () => beatmaps.GetAllUsableBeatmapSets().Any(b => b.OnlineBeatmapSetID == 241526));
|
||||||
createButtonWithBeatmap(createSoleily());
|
createButtonWithBeatmap(createSoleily());
|
||||||
AddAssert("button state downloaded", () => downloadButton.DownloadState == DownloadState.LocallyAvailable);
|
AddAssert("button state downloaded", () => downloadButton.DownloadState == DownloadState.LocallyAvailable);
|
||||||
|
@ -5,7 +5,6 @@ using System;
|
|||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using System.Net;
|
using System.Net;
|
||||||
using System.Threading.Tasks;
|
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
@ -76,7 +75,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
AddStep("bind user score info handler", () =>
|
AddStep("bind user score info handler", () =>
|
||||||
{
|
{
|
||||||
userScore = new TestScoreInfo(new OsuRuleset().RulesetInfo) { OnlineScoreID = currentScoreId++ };
|
userScore = new TestScoreInfo(new OsuRuleset().RulesetInfo) { OnlineScoreID = currentScoreId++ };
|
||||||
bindHandler(3000, userScore);
|
bindHandler(true, userScore);
|
||||||
});
|
});
|
||||||
|
|
||||||
createResults(() => userScore);
|
createResults(() => userScore);
|
||||||
@ -89,7 +88,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestShowNullUserScoreWithDelay()
|
public void TestShowNullUserScoreWithDelay()
|
||||||
{
|
{
|
||||||
AddStep("bind delayed handler", () => bindHandler(3000));
|
AddStep("bind delayed handler", () => bindHandler(true));
|
||||||
|
|
||||||
createResults();
|
createResults();
|
||||||
waitForDisplay();
|
waitForDisplay();
|
||||||
@ -103,7 +102,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
createResults();
|
createResults();
|
||||||
waitForDisplay();
|
waitForDisplay();
|
||||||
|
|
||||||
AddStep("bind delayed handler", () => bindHandler(3000));
|
AddStep("bind delayed handler", () => bindHandler(true));
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
@ -134,7 +133,7 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
createResults(() => userScore);
|
createResults(() => userScore);
|
||||||
waitForDisplay();
|
waitForDisplay();
|
||||||
|
|
||||||
AddStep("bind delayed handler", () => bindHandler(3000));
|
AddStep("bind delayed handler", () => bindHandler(true));
|
||||||
|
|
||||||
for (int i = 0; i < 2; i++)
|
for (int i = 0; i < 2; i++)
|
||||||
{
|
{
|
||||||
@ -169,13 +168,17 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
AddWaitStep("wait for display", 5);
|
AddWaitStep("wait for display", 5);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void bindHandler(double delay = 0, ScoreInfo userScore = null, bool failRequests = false) => ((DummyAPIAccess)API).HandleRequest = request =>
|
private void bindHandler(bool delayed = false, ScoreInfo userScore = null, bool failRequests = false) => ((DummyAPIAccess)API).HandleRequest = request =>
|
||||||
{
|
{
|
||||||
requestComplete = false;
|
requestComplete = false;
|
||||||
|
|
||||||
|
double delay = delayed ? 3000 : 0;
|
||||||
|
|
||||||
|
Scheduler.AddDelayed(() =>
|
||||||
|
{
|
||||||
if (failRequests)
|
if (failRequests)
|
||||||
{
|
{
|
||||||
triggerFail(request, delay);
|
triggerFail(request);
|
||||||
return;
|
return;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -183,57 +186,30 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
{
|
{
|
||||||
case ShowPlaylistUserScoreRequest s:
|
case ShowPlaylistUserScoreRequest s:
|
||||||
if (userScore == null)
|
if (userScore == null)
|
||||||
triggerFail(s, delay);
|
triggerFail(s);
|
||||||
else
|
else
|
||||||
triggerSuccess(s, createUserResponse(userScore), delay);
|
triggerSuccess(s, createUserResponse(userScore));
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case IndexPlaylistScoresRequest i:
|
case IndexPlaylistScoresRequest i:
|
||||||
triggerSuccess(i, createIndexResponse(i), delay);
|
triggerSuccess(i, createIndexResponse(i));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
}, delay);
|
||||||
};
|
};
|
||||||
|
|
||||||
private void triggerSuccess<T>(APIRequest<T> req, T result, double delay)
|
private void triggerSuccess<T>(APIRequest<T> req, T result)
|
||||||
where T : class
|
where T : class
|
||||||
{
|
|
||||||
if (delay == 0)
|
|
||||||
success();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Task.Run(async () =>
|
|
||||||
{
|
|
||||||
await Task.Delay(TimeSpan.FromMilliseconds(delay));
|
|
||||||
Schedule(success);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void success()
|
|
||||||
{
|
{
|
||||||
requestComplete = true;
|
requestComplete = true;
|
||||||
req.TriggerSuccess(result);
|
req.TriggerSuccess(result);
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private void triggerFail(APIRequest req, double delay)
|
private void triggerFail(APIRequest req)
|
||||||
{
|
|
||||||
if (delay == 0)
|
|
||||||
fail();
|
|
||||||
else
|
|
||||||
{
|
|
||||||
Task.Run(async () =>
|
|
||||||
{
|
|
||||||
await Task.Delay(TimeSpan.FromMilliseconds(delay));
|
|
||||||
Schedule(fail);
|
|
||||||
});
|
|
||||||
}
|
|
||||||
|
|
||||||
void fail()
|
|
||||||
{
|
{
|
||||||
requestComplete = true;
|
requestComplete = true;
|
||||||
req.TriggerFailure(new WebException("Failed."));
|
req.TriggerFailure(new WebException("Failed."));
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
private MultiplayerScore createUserResponse([NotNull] ScoreInfo userScore)
|
private MultiplayerScore createUserResponse([NotNull] ScoreInfo userScore)
|
||||||
{
|
{
|
||||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
Beatmap = createTestBeatmap(author)
|
Beatmap = createTestBeatmap(author)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
AddAssert("mapper name present", () => this.ChildrenOfType<OsuSpriteText>().Any(spriteText => spriteText.Text == "mapper_name"));
|
AddAssert("mapper name present", () => this.ChildrenOfType<OsuSpriteText>().Any(spriteText => spriteText.Current.Value == "mapper_name"));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual.Ranking
|
|||||||
}));
|
}));
|
||||||
|
|
||||||
AddAssert("mapped by text not present", () =>
|
AddAssert("mapped by text not present", () =>
|
||||||
this.ChildrenOfType<OsuSpriteText>().All(spriteText => !containsAny(spriteText.Text, "mapped", "by")));
|
this.ChildrenOfType<OsuSpriteText>().All(spriteText => !containsAny(spriteText.Current.Value, "mapped", "by")));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void showPanel(ScoreInfo score) => Child = new ExpandedPanelMiddleContentContainer(score);
|
private void showPanel(ScoreInfo score) => Child = new ExpandedPanelMiddleContentContainer(score);
|
||||||
|
@ -78,7 +78,7 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
|
|
||||||
clickClearButton();
|
clickClearButton();
|
||||||
|
|
||||||
AddAssert("first binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().Text.Text));
|
AddAssert("first binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().First().Text.Text.ToString()));
|
||||||
|
|
||||||
AddStep("click second binding", () =>
|
AddStep("click second binding", () =>
|
||||||
{
|
{
|
||||||
@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
|
|
||||||
clickClearButton();
|
clickClearButton();
|
||||||
|
|
||||||
AddAssert("second binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1).Text.Text));
|
AddAssert("second binding cleared", () => string.IsNullOrEmpty(multiBindingRow.ChildrenOfType<KeyBindingRow.KeyButton>().ElementAt(1).Text.Text.ToString()));
|
||||||
|
|
||||||
void clickClearButton()
|
void clickClearButton()
|
||||||
{
|
{
|
||||||
|
43
osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs
Normal file
43
osu.Game.Tests/Visual/Settings/TestSceneSettingsItem.cs
Normal file
@ -0,0 +1,43 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Bindables;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Overlays.Settings;
|
||||||
|
|
||||||
|
namespace osu.Game.Tests.Visual.Settings
|
||||||
|
{
|
||||||
|
[TestFixture]
|
||||||
|
public class TestSceneSettingsItem : OsuTestScene
|
||||||
|
{
|
||||||
|
[Test]
|
||||||
|
public void TestRestoreDefaultValueButtonVisibility()
|
||||||
|
{
|
||||||
|
TestSettingsTextBox textBox = null;
|
||||||
|
|
||||||
|
AddStep("create settings item", () => Child = textBox = new TestSettingsTextBox
|
||||||
|
{
|
||||||
|
Current = new Bindable<string>
|
||||||
|
{
|
||||||
|
Default = "test",
|
||||||
|
Value = "test"
|
||||||
|
}
|
||||||
|
});
|
||||||
|
AddAssert("restore button hidden", () => textBox.RestoreDefaultValueButton.Alpha == 0);
|
||||||
|
|
||||||
|
AddStep("change value from default", () => textBox.Current.Value = "non-default");
|
||||||
|
AddUntilStep("restore button shown", () => textBox.RestoreDefaultValueButton.Alpha > 0);
|
||||||
|
|
||||||
|
AddStep("restore default", () => textBox.Current.SetDefault());
|
||||||
|
AddUntilStep("restore button hidden", () => textBox.RestoreDefaultValueButton.Alpha == 0);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class TestSettingsTextBox : SettingsTextBox
|
||||||
|
{
|
||||||
|
public new Drawable RestoreDefaultValueButton => this.ChildrenOfType<RestoreDefaultValueButton>().Single();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -7,6 +7,7 @@ using JetBrains.Annotations;
|
|||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Allocation;
|
using osu.Framework.Allocation;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
@ -103,27 +104,27 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
private void testBeatmapLabels(Ruleset ruleset)
|
private void testBeatmapLabels(Ruleset ruleset)
|
||||||
{
|
{
|
||||||
AddAssert("check version", () => infoWedge.Info.VersionLabel.Text == $"{ruleset.ShortName}Version");
|
AddAssert("check version", () => infoWedge.Info.VersionLabel.Current.Value == $"{ruleset.ShortName}Version");
|
||||||
AddAssert("check title", () => infoWedge.Info.TitleLabel.Text == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title");
|
AddAssert("check title", () => infoWedge.Info.TitleLabel.Current.Value == $"{ruleset.ShortName}Source — {ruleset.ShortName}Title");
|
||||||
AddAssert("check artist", () => infoWedge.Info.ArtistLabel.Text == $"{ruleset.ShortName}Artist");
|
AddAssert("check artist", () => infoWedge.Info.ArtistLabel.Current.Value == $"{ruleset.ShortName}Artist");
|
||||||
AddAssert("check author", () => infoWedge.Info.MapperContainer.Children.OfType<OsuSpriteText>().Any(s => s.Text == $"{ruleset.ShortName}Author"));
|
AddAssert("check author", () => infoWedge.Info.MapperContainer.Children.OfType<OsuSpriteText>().Any(s => s.Current.Value == $"{ruleset.ShortName}Author"));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void testInfoLabels(int expectedCount)
|
private void testInfoLabels(int expectedCount)
|
||||||
{
|
{
|
||||||
AddAssert("check info labels exists", () => infoWedge.Info.InfoLabelContainer.Children.Any());
|
AddAssert("check info labels exists", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.BufferedWedgeInfo.InfoLabel>().Any());
|
||||||
AddAssert("check info labels count", () => infoWedge.Info.InfoLabelContainer.Children.Count == expectedCount);
|
AddAssert("check info labels count", () => infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.BufferedWedgeInfo.InfoLabel>().Count() == expectedCount);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestNullBeatmap()
|
public void TestNullBeatmap()
|
||||||
{
|
{
|
||||||
selectBeatmap(null);
|
selectBeatmap(null);
|
||||||
AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Text));
|
AddAssert("check empty version", () => string.IsNullOrEmpty(infoWedge.Info.VersionLabel.Current.Value));
|
||||||
AddAssert("check default title", () => infoWedge.Info.TitleLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Title);
|
AddAssert("check default title", () => infoWedge.Info.TitleLabel.Current.Value == Beatmap.Default.BeatmapInfo.Metadata.Title);
|
||||||
AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Text == Beatmap.Default.BeatmapInfo.Metadata.Artist);
|
AddAssert("check default artist", () => infoWedge.Info.ArtistLabel.Current.Value == Beatmap.Default.BeatmapInfo.Metadata.Artist);
|
||||||
AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any());
|
AddAssert("check empty author", () => !infoWedge.Info.MapperContainer.Children.Any());
|
||||||
AddAssert("check no info labels", () => !infoWedge.Info.InfoLabelContainer.Children.Any());
|
AddAssert("check no info labels", () => !infoWedge.Info.ChildrenOfType<BeatmapInfoWedge.BufferedWedgeInfo.InfoLabel>().Any());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
Dependencies.Cache(rulesets = new RulesetStore(ContextFactory));
|
||||||
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, host, Beatmap.Default));
|
Dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesets, null, Audio, host, Beatmap.Default));
|
||||||
|
|
||||||
beatmapManager.Import(TestResources.GetTestBeatmapForImport()).Wait();
|
beatmapManager.Import(TestResources.GetQuickTestBeatmapForImport()).Wait();
|
||||||
|
|
||||||
base.Content.AddRange(new Drawable[]
|
base.Content.AddRange(new Drawable[]
|
||||||
{
|
{
|
||||||
|
@ -84,7 +84,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), dependencies.Get<GameHost>(), Beatmap.Default));
|
dependencies.Cache(beatmapManager = new BeatmapManager(LocalStorage, ContextFactory, rulesetStore, null, dependencies.Get<AudioManager>(), dependencies.Get<GameHost>(), Beatmap.Default));
|
||||||
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, null, ContextFactory));
|
dependencies.Cache(scoreManager = new ScoreManager(rulesetStore, () => beatmapManager, LocalStorage, null, ContextFactory));
|
||||||
|
|
||||||
beatmap = beatmapManager.Import(new ImportTask(TestResources.GetTestBeatmapForImport())).Result.Beatmaps[0];
|
beatmap = beatmapManager.Import(new ImportTask(TestResources.GetQuickTestBeatmapForImport())).Result.Beatmaps[0];
|
||||||
|
|
||||||
for (int i = 0; i < 50; i++)
|
for (int i = 0; i < 50; i++)
|
||||||
{
|
{
|
||||||
@ -145,7 +145,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
AddStep("click delete option", () =>
|
AddStep("click delete option", () =>
|
||||||
{
|
{
|
||||||
InputManager.MoveMouseTo(contextMenuContainer.ChildrenOfType<DrawableOsuMenuItem>().First(i => i.Item.Text.Value.ToLowerInvariant() == "delete"));
|
InputManager.MoveMouseTo(contextMenuContainer.ChildrenOfType<DrawableOsuMenuItem>().First(i => i.Item.Text.Value.ToString().ToLowerInvariant() == "delete"));
|
||||||
InputManager.Click(MouseButton.Left);
|
InputManager.Click(MouseButton.Left);
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
var multiplier = mods.Aggregate(1.0, (current, mod) => current * mod.ScoreMultiplier);
|
var multiplier = mods.Aggregate(1.0, (current, mod) => current * mod.ScoreMultiplier);
|
||||||
var expectedValue = multiplier.Equals(1.0) ? string.Empty : $"{multiplier:N2}x";
|
var expectedValue = multiplier.Equals(1.0) ? string.Empty : $"{multiplier:N2}x";
|
||||||
|
|
||||||
return expectedValue == footerButtonMods.MultiplierText.Text;
|
return expectedValue == footerButtonMods.MultiplierText.Current.Value;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestFooterButtonMods : FooterButtonMods
|
private class TestFooterButtonMods : FooterButtonMods
|
||||||
|
@ -3,11 +3,11 @@
|
|||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
<PackageReference Include="DeepEqual" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
<PackageReference Update="Microsoft.EntityFrameworkCore.Sqlite" Version="2.1.4" />
|
||||||
<PackageReference Include="Moq" Version="4.16.0" />
|
<PackageReference Include="Moq" Version="4.16.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<PropertyGroup Label="Project">
|
<PropertyGroup Label="Project">
|
||||||
<OutputType>WinExe</OutputType>
|
<OutputType>WinExe</OutputType>
|
||||||
|
35
osu.Game.Tournament.Tests/Screens/TestSceneDrawingsScreen.cs
Normal file
35
osu.Game.Tournament.Tests/Screens/TestSceneDrawingsScreen.cs
Normal file
@ -0,0 +1,35 @@
|
|||||||
|
// 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 osu.Framework.Allocation;
|
||||||
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Platform;
|
||||||
|
using osu.Game.Graphics.Cursor;
|
||||||
|
using osu.Game.Tournament.Screens.Drawings;
|
||||||
|
|
||||||
|
namespace osu.Game.Tournament.Tests.Screens
|
||||||
|
{
|
||||||
|
public class TestSceneDrawingsScreen : TournamentTestScene
|
||||||
|
{
|
||||||
|
[BackgroundDependencyLoader]
|
||||||
|
private void load(Storage storage)
|
||||||
|
{
|
||||||
|
using (var stream = storage.GetStream("drawings.txt", FileAccess.Write))
|
||||||
|
using (var writer = new StreamWriter(stream))
|
||||||
|
{
|
||||||
|
writer.WriteLine("KR : South Korea : KOR");
|
||||||
|
writer.WriteLine("US : United States : USA");
|
||||||
|
writer.WriteLine("PH : Philippines : PHL");
|
||||||
|
writer.WriteLine("BR : Brazil : BRA");
|
||||||
|
writer.WriteLine("JP : Japan : JPN");
|
||||||
|
}
|
||||||
|
|
||||||
|
Add(new OsuContextMenuContainer
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Child = new DrawingsScreen()
|
||||||
|
});
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -5,7 +5,7 @@
|
|||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup Label="Package References">
|
<ItemGroup Label="Package References">
|
||||||
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
<PackageReference Include="Appveyor.TestLogger" Version="2.0.0" />
|
||||||
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.8.3" />
|
<PackageReference Include="Microsoft.NET.Test.Sdk" Version="16.9.1" />
|
||||||
<PackageReference Include="NUnit" Version="3.13.1" />
|
<PackageReference Include="NUnit" Version="3.13.1" />
|
||||||
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
<PackageReference Include="NUnit3TestAdapter" Version="3.17.0" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
|
@ -74,9 +74,9 @@ namespace osu.Game.Tournament.Components
|
|||||||
{
|
{
|
||||||
new TournamentSpriteText
|
new TournamentSpriteText
|
||||||
{
|
{
|
||||||
Text = new LocalisedString((
|
Text = new RomanisableString(
|
||||||
$"{Beatmap.Metadata.ArtistUnicode ?? Beatmap.Metadata.Artist} - {Beatmap.Metadata.TitleUnicode ?? Beatmap.Metadata.Title}",
|
$"{Beatmap.Metadata.ArtistUnicode ?? Beatmap.Metadata.Artist} - {Beatmap.Metadata.TitleUnicode ?? Beatmap.Metadata.Title}",
|
||||||
$"{Beatmap.Metadata.Artist} - {Beatmap.Metadata.Title}")),
|
$"{Beatmap.Metadata.Artist} - {Beatmap.Metadata.Title}"),
|
||||||
Font = OsuFont.Torus.With(weight: FontWeight.Bold),
|
Font = OsuFont.Torus.With(weight: FontWeight.Bold),
|
||||||
},
|
},
|
||||||
new FillFlowContainer
|
new FillFlowContainer
|
||||||
|
@ -345,7 +345,7 @@ namespace osu.Game.Tournament.Screens.Drawings.Components
|
|||||||
|
|
||||||
Flag.Anchor = Anchor.Centre;
|
Flag.Anchor = Anchor.Centre;
|
||||||
Flag.Origin = Anchor.Centre;
|
Flag.Origin = Anchor.Centre;
|
||||||
Flag.Scale = new Vector2(0.9f);
|
Flag.Scale = new Vector2(0.7f);
|
||||||
|
|
||||||
InternalChildren = new Drawable[]
|
InternalChildren = new Drawable[]
|
||||||
{
|
{
|
||||||
|
@ -69,8 +69,8 @@ namespace osu.Game.Beatmaps
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to get the difficulty of.</param>
|
/// <param name="beatmapInfo">The <see cref="BeatmapInfo"/> to get the difficulty of.</param>
|
||||||
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="BeatmapInfo"/>.</param>
|
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="BeatmapInfo"/>.</param>
|
||||||
/// <returns>A bindable that is updated to contain the star difficulty when it becomes available.</returns>
|
/// <returns>A bindable that is updated to contain the star difficulty when it becomes available. Will be null while in an initial calculating state (but not during updates to ruleset and mods if a stale value is already propagated).</returns>
|
||||||
public IBindable<StarDifficulty> GetBindableDifficulty([NotNull] BeatmapInfo beatmapInfo, CancellationToken cancellationToken = default)
|
public IBindable<StarDifficulty?> GetBindableDifficulty([NotNull] BeatmapInfo beatmapInfo, CancellationToken cancellationToken = default)
|
||||||
{
|
{
|
||||||
var bindable = createBindable(beatmapInfo, currentRuleset.Value, currentMods.Value, cancellationToken);
|
var bindable = createBindable(beatmapInfo, currentRuleset.Value, currentMods.Value, cancellationToken);
|
||||||
|
|
||||||
@ -90,8 +90,8 @@ namespace osu.Game.Beatmaps
|
|||||||
/// <param name="rulesetInfo">The <see cref="RulesetInfo"/> to get the difficulty with. If <c>null</c>, the <paramref name="beatmapInfo"/>'s ruleset is used.</param>
|
/// <param name="rulesetInfo">The <see cref="RulesetInfo"/> to get the difficulty with. If <c>null</c>, the <paramref name="beatmapInfo"/>'s ruleset is used.</param>
|
||||||
/// <param name="mods">The <see cref="Mod"/>s to get the difficulty with. If <c>null</c>, no mods will be assumed.</param>
|
/// <param name="mods">The <see cref="Mod"/>s to get the difficulty with. If <c>null</c>, no mods will be assumed.</param>
|
||||||
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="BeatmapInfo"/>.</param>
|
/// <param name="cancellationToken">An optional <see cref="CancellationToken"/> which stops updating the star difficulty for the given <see cref="BeatmapInfo"/>.</param>
|
||||||
/// <returns>A bindable that is updated to contain the star difficulty when it becomes available.</returns>
|
/// <returns>A bindable that is updated to contain the star difficulty when it becomes available. Will be null while in an initial calculating state.</returns>
|
||||||
public IBindable<StarDifficulty> GetBindableDifficulty([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo rulesetInfo, [CanBeNull] IEnumerable<Mod> mods,
|
public IBindable<StarDifficulty?> GetBindableDifficulty([NotNull] BeatmapInfo beatmapInfo, [CanBeNull] RulesetInfo rulesetInfo, [CanBeNull] IEnumerable<Mod> mods,
|
||||||
CancellationToken cancellationToken = default)
|
CancellationToken cancellationToken = default)
|
||||||
=> createBindable(beatmapInfo, rulesetInfo, mods, cancellationToken);
|
=> createBindable(beatmapInfo, rulesetInfo, mods, cancellationToken);
|
||||||
|
|
||||||
@ -313,7 +313,7 @@ namespace osu.Game.Beatmaps
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class BindableStarDifficulty : Bindable<StarDifficulty>
|
private class BindableStarDifficulty : Bindable<StarDifficulty?>
|
||||||
{
|
{
|
||||||
public readonly BeatmapInfo Beatmap;
|
public readonly BeatmapInfo Beatmap;
|
||||||
public readonly CancellationToken CancellationToken;
|
public readonly CancellationToken CancellationToken;
|
||||||
|
@ -20,6 +20,7 @@ using osu.Framework.IO.Stores;
|
|||||||
using osu.Framework.Lists;
|
using osu.Framework.Lists;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
|
using osu.Framework.Statistics;
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps.Formats;
|
using osu.Game.Beatmaps.Formats;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
@ -311,6 +312,9 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
workingCache.Add(working = new BeatmapManagerWorkingBeatmap(beatmapInfo, this));
|
workingCache.Add(working = new BeatmapManagerWorkingBeatmap(beatmapInfo, this));
|
||||||
|
|
||||||
|
// best effort; may be higher than expected.
|
||||||
|
GlobalStatistics.Get<int>(nameof(Beatmaps), $"Cached {nameof(WorkingBeatmap)}s").Value = workingCache.Count();
|
||||||
|
|
||||||
return working;
|
return working;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -151,7 +151,7 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
this.mods = mods;
|
this.mods = mods;
|
||||||
}
|
}
|
||||||
|
|
||||||
private IBindable<StarDifficulty> localStarDifficulty;
|
private IBindable<StarDifficulty?> localStarDifficulty;
|
||||||
|
|
||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load()
|
private void load()
|
||||||
@ -160,7 +160,11 @@ namespace osu.Game.Beatmaps.Drawables
|
|||||||
localStarDifficulty = ruleset != null
|
localStarDifficulty = ruleset != null
|
||||||
? difficultyCache.GetBindableDifficulty(beatmap, ruleset, mods, difficultyCancellation.Token)
|
? difficultyCache.GetBindableDifficulty(beatmap, ruleset, mods, difficultyCancellation.Token)
|
||||||
: difficultyCache.GetBindableDifficulty(beatmap, difficultyCancellation.Token);
|
: difficultyCache.GetBindableDifficulty(beatmap, difficultyCancellation.Token);
|
||||||
localStarDifficulty.BindValueChanged(difficulty => StarDifficulty.Value = difficulty.NewValue);
|
localStarDifficulty.BindValueChanged(d =>
|
||||||
|
{
|
||||||
|
if (d.NewValue is StarDifficulty diff)
|
||||||
|
StarDifficulty.Value = diff;
|
||||||
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void Dispose(bool isDisposing)
|
protected override void Dispose(bool isDisposing)
|
||||||
|
@ -6,6 +6,7 @@ using System.Collections.Generic;
|
|||||||
using System.IO;
|
using System.IO;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Game.Beatmaps.Legacy;
|
using osu.Game.Beatmaps.Legacy;
|
||||||
using osu.Game.Beatmaps.Timing;
|
using osu.Game.Beatmaps.Timing;
|
||||||
@ -348,8 +349,8 @@ namespace osu.Game.Beatmaps.Formats
|
|||||||
if (split.Length >= 8)
|
if (split.Length >= 8)
|
||||||
{
|
{
|
||||||
LegacyEffectFlags effectFlags = (LegacyEffectFlags)Parsing.ParseInt(split[7]);
|
LegacyEffectFlags effectFlags = (LegacyEffectFlags)Parsing.ParseInt(split[7]);
|
||||||
kiaiMode = effectFlags.HasFlag(LegacyEffectFlags.Kiai);
|
kiaiMode = effectFlags.HasFlagFast(LegacyEffectFlags.Kiai);
|
||||||
omitFirstBarSignature = effectFlags.HasFlag(LegacyEffectFlags.OmitFirstBarLine);
|
omitFirstBarSignature = effectFlags.HasFlagFast(LegacyEffectFlags.OmitFirstBarLine);
|
||||||
}
|
}
|
||||||
|
|
||||||
string stringSampleSet = sampleSet.ToString().ToLowerInvariant();
|
string stringSampleSet = sampleSet.ToString().ToLowerInvariant();
|
||||||
|
@ -12,7 +12,6 @@ using osu.Framework.Audio;
|
|||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using osu.Framework.Graphics.Textures;
|
using osu.Framework.Graphics.Textures;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Framework.Statistics;
|
|
||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Rulesets;
|
using osu.Game.Rulesets;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
@ -34,8 +33,6 @@ namespace osu.Game.Beatmaps
|
|||||||
|
|
||||||
protected AudioManager AudioManager { get; }
|
protected AudioManager AudioManager { get; }
|
||||||
|
|
||||||
private static readonly GlobalStatistic<int> total_count = GlobalStatistics.Get<int>(nameof(Beatmaps), $"Total {nameof(WorkingBeatmap)}s");
|
|
||||||
|
|
||||||
protected WorkingBeatmap(BeatmapInfo beatmapInfo, AudioManager audioManager)
|
protected WorkingBeatmap(BeatmapInfo beatmapInfo, AudioManager audioManager)
|
||||||
{
|
{
|
||||||
AudioManager = audioManager;
|
AudioManager = audioManager;
|
||||||
@ -47,8 +44,6 @@ namespace osu.Game.Beatmaps
|
|||||||
waveform = new RecyclableLazy<Waveform>(GetWaveform);
|
waveform = new RecyclableLazy<Waveform>(GetWaveform);
|
||||||
storyboard = new RecyclableLazy<Storyboard>(GetStoryboard);
|
storyboard = new RecyclableLazy<Storyboard>(GetStoryboard);
|
||||||
skin = new RecyclableLazy<ISkin>(GetSkin);
|
skin = new RecyclableLazy<ISkin>(GetSkin);
|
||||||
|
|
||||||
total_count.Value++;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected virtual Track GetVirtualTrack(double emptyLength = 0)
|
protected virtual Track GetVirtualTrack(double emptyLength = 0)
|
||||||
@ -331,11 +326,6 @@ namespace osu.Game.Beatmaps
|
|||||||
protected virtual ISkin GetSkin() => new DefaultSkin();
|
protected virtual ISkin GetSkin() => new DefaultSkin();
|
||||||
private readonly RecyclableLazy<ISkin> skin;
|
private readonly RecyclableLazy<ISkin> skin;
|
||||||
|
|
||||||
~WorkingBeatmap()
|
|
||||||
{
|
|
||||||
total_count.Value--;
|
|
||||||
}
|
|
||||||
|
|
||||||
public class RecyclableLazy<T>
|
public class RecyclableLazy<T>
|
||||||
{
|
{
|
||||||
private Lazy<T> lazy;
|
private Lazy<T> lazy;
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Graphics;
|
|||||||
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.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
@ -121,7 +122,7 @@ namespace osu.Game.Collections
|
|||||||
Current.TriggerChange();
|
Current.TriggerChange();
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override string GenerateItemText(CollectionFilterMenuItem item) => item.CollectionName.Value;
|
protected override LocalisableString GenerateItemText(CollectionFilterMenuItem item) => item.CollectionName.Value;
|
||||||
|
|
||||||
protected sealed override DropdownHeader CreateHeader() => CreateCollectionHeader().With(d =>
|
protected sealed override DropdownHeader CreateHeader() => CreateCollectionHeader().With(d =>
|
||||||
{
|
{
|
||||||
@ -139,7 +140,7 @@ namespace osu.Game.Collections
|
|||||||
public readonly Bindable<CollectionFilterMenuItem> SelectedItem = new Bindable<CollectionFilterMenuItem>();
|
public readonly Bindable<CollectionFilterMenuItem> SelectedItem = new Bindable<CollectionFilterMenuItem>();
|
||||||
private readonly Bindable<string> collectionName = new Bindable<string>();
|
private readonly Bindable<string> collectionName = new Bindable<string>();
|
||||||
|
|
||||||
protected override string Label
|
protected override LocalisableString Label
|
||||||
{
|
{
|
||||||
get => base.Label;
|
get => base.Label;
|
||||||
set { } // See updateText().
|
set { } // See updateText().
|
||||||
|
@ -36,7 +36,19 @@ namespace osu.Game.Collections
|
|||||||
}
|
}
|
||||||
|
|
||||||
public bool Equals(CollectionFilterMenuItem other)
|
public bool Equals(CollectionFilterMenuItem other)
|
||||||
=> other != null && CollectionName.Value == other.CollectionName.Value;
|
{
|
||||||
|
if (other == null)
|
||||||
|
return false;
|
||||||
|
|
||||||
|
// collections may have the same name, so compare first on reference equality.
|
||||||
|
// this relies on the assumption that only one instance of the BeatmapCollection exists game-wide, managed by CollectionManager.
|
||||||
|
if (Collection != null)
|
||||||
|
return Collection == other.Collection;
|
||||||
|
|
||||||
|
// fallback to name-based comparison.
|
||||||
|
// this is required for special dropdown items which don't have a collection (all beatmaps / manage collections items below).
|
||||||
|
return CollectionName.Value == other.CollectionName.Value;
|
||||||
|
}
|
||||||
|
|
||||||
public override int GetHashCode() => CollectionName.Value.GetHashCode();
|
public override int GetHashCode() => CollectionName.Value.GetHashCode();
|
||||||
}
|
}
|
||||||
|
@ -138,10 +138,10 @@ namespace osu.Game.Collections
|
|||||||
|
|
||||||
PostNotification?.Invoke(notification);
|
PostNotification?.Invoke(notification);
|
||||||
|
|
||||||
var collection = readCollections(stream, notification);
|
var collections = readCollections(stream, notification);
|
||||||
await importCollections(collection);
|
await importCollections(collections);
|
||||||
|
|
||||||
notification.CompletionText = $"Imported {collection.Count} collections";
|
notification.CompletionText = $"Imported {collections.Count} collections";
|
||||||
notification.State = ProgressNotificationState.Completed;
|
notification.State = ProgressNotificationState.Completed;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -155,7 +155,7 @@ namespace osu.Game.Collections
|
|||||||
{
|
{
|
||||||
foreach (var newCol in newCollections)
|
foreach (var newCol in newCollections)
|
||||||
{
|
{
|
||||||
var existing = Collections.FirstOrDefault(c => c.Name == newCol.Name);
|
var existing = Collections.FirstOrDefault(c => c.Name.Value == newCol.Name.Value);
|
||||||
if (existing == null)
|
if (existing == null)
|
||||||
Collections.Add(existing = new BeatmapCollection { Name = { Value = newCol.Name.Value } });
|
Collections.Add(existing = new BeatmapCollection { Name = { Value = newCol.Name.Value } });
|
||||||
|
|
||||||
|
@ -8,6 +8,7 @@ using System.Reflection;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Overlays.Settings;
|
||||||
|
|
||||||
namespace osu.Game.Configuration
|
namespace osu.Game.Configuration
|
||||||
@ -22,9 +23,9 @@ namespace osu.Game.Configuration
|
|||||||
/// </remarks>
|
/// </remarks>
|
||||||
[MeansImplicitUse]
|
[MeansImplicitUse]
|
||||||
[AttributeUsage(AttributeTargets.Property)]
|
[AttributeUsage(AttributeTargets.Property)]
|
||||||
public class SettingSourceAttribute : Attribute
|
public class SettingSourceAttribute : Attribute, IComparable<SettingSourceAttribute>
|
||||||
{
|
{
|
||||||
public string Label { get; }
|
public LocalisableString Label { get; }
|
||||||
|
|
||||||
public string Description { get; }
|
public string Description { get; }
|
||||||
|
|
||||||
@ -41,6 +42,21 @@ namespace osu.Game.Configuration
|
|||||||
{
|
{
|
||||||
OrderPosition = orderPosition;
|
OrderPosition = orderPosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
public int CompareTo(SettingSourceAttribute other)
|
||||||
|
{
|
||||||
|
if (OrderPosition == other.OrderPosition)
|
||||||
|
return 0;
|
||||||
|
|
||||||
|
// unordered items come last (are greater than any ordered items).
|
||||||
|
if (OrderPosition == null)
|
||||||
|
return 1;
|
||||||
|
if (other.OrderPosition == null)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
// ordered items are sorted by the order value.
|
||||||
|
return OrderPosition.Value.CompareTo(other.OrderPosition);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static class SettingSourceExtensions
|
public static class SettingSourceExtensions
|
||||||
@ -136,14 +152,9 @@ namespace osu.Game.Configuration
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static IEnumerable<(SettingSourceAttribute, PropertyInfo)> GetOrderedSettingsSourceProperties(this object obj)
|
public static ICollection<(SettingSourceAttribute, PropertyInfo)> GetOrderedSettingsSourceProperties(this object obj)
|
||||||
{
|
=> obj.GetSettingsSourceProperties()
|
||||||
var original = obj.GetSettingsSourceProperties();
|
.OrderBy(attr => attr.Item1)
|
||||||
|
.ToArray();
|
||||||
var orderedRelative = original.Where(attr => attr.Item1.OrderPosition != null).OrderBy(attr => attr.Item1.OrderPosition);
|
|
||||||
var unordered = original.Except(orderedRelative);
|
|
||||||
|
|
||||||
return orderedRelative.Concat(unordered);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -141,6 +141,13 @@ namespace osu.Game.Database
|
|||||||
|
|
||||||
protected async Task<IEnumerable<TModel>> Import(ProgressNotification notification, params ImportTask[] tasks)
|
protected async Task<IEnumerable<TModel>> Import(ProgressNotification notification, params ImportTask[] tasks)
|
||||||
{
|
{
|
||||||
|
if (tasks.Length == 0)
|
||||||
|
{
|
||||||
|
notification.CompletionText = $"No {HumanisedModelName}s were found to import!";
|
||||||
|
notification.State = ProgressNotificationState.Completed;
|
||||||
|
return Enumerable.Empty<TModel>();
|
||||||
|
}
|
||||||
|
|
||||||
notification.Progress = 0;
|
notification.Progress = 0;
|
||||||
notification.Text = $"{HumanisedModelName.Humanize(LetterCasing.Title)} import is initialising...";
|
notification.Text = $"{HumanisedModelName.Humanize(LetterCasing.Title)} import is initialising...";
|
||||||
|
|
||||||
|
@ -54,10 +54,5 @@ namespace osu.Game.Database
|
|||||||
Dispose(true);
|
Dispose(true);
|
||||||
GC.SuppressFinalize(this);
|
GC.SuppressFinalize(this);
|
||||||
}
|
}
|
||||||
|
|
||||||
~DatabaseWriteUsage()
|
|
||||||
{
|
|
||||||
Dispose(false);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -6,6 +6,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Colour;
|
using osu.Framework.Graphics.Colour;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.Sprites
|
namespace osu.Game.Graphics.Sprites
|
||||||
@ -14,7 +15,7 @@ namespace osu.Game.Graphics.Sprites
|
|||||||
{
|
{
|
||||||
private readonly OsuSpriteText spriteText, blurredText;
|
private readonly OsuSpriteText spriteText, blurredText;
|
||||||
|
|
||||||
public string Text
|
public LocalisableString Text
|
||||||
{
|
{
|
||||||
get => spriteText.Text;
|
get => spriteText.Text;
|
||||||
set => blurredText.Text = spriteText.Text = value;
|
set => blurredText.Text = spriteText.Text = value;
|
||||||
|
@ -6,6 +6,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
@ -24,11 +25,11 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
direction = value;
|
direction = value;
|
||||||
base.Direction = direction.HasFlag(BarDirection.Horizontal) ? FillDirection.Vertical : FillDirection.Horizontal;
|
base.Direction = direction.HasFlagFast(BarDirection.Horizontal) ? FillDirection.Vertical : FillDirection.Horizontal;
|
||||||
|
|
||||||
foreach (var bar in Children)
|
foreach (var bar in Children)
|
||||||
{
|
{
|
||||||
bar.Size = direction.HasFlag(BarDirection.Horizontal) ? new Vector2(1, 1.0f / Children.Count) : new Vector2(1.0f / Children.Count, 1);
|
bar.Size = direction.HasFlagFast(BarDirection.Horizontal) ? new Vector2(1, 1.0f / Children.Count) : new Vector2(1.0f / Children.Count, 1);
|
||||||
bar.Direction = direction;
|
bar.Direction = direction;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -56,14 +57,14 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
if (bar.Bar != null)
|
if (bar.Bar != null)
|
||||||
{
|
{
|
||||||
bar.Bar.Length = length;
|
bar.Bar.Length = length;
|
||||||
bar.Bar.Size = direction.HasFlag(BarDirection.Horizontal) ? new Vector2(1, size) : new Vector2(size, 1);
|
bar.Bar.Size = direction.HasFlagFast(BarDirection.Horizontal) ? new Vector2(1, size) : new Vector2(size, 1);
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
Add(new Bar
|
Add(new Bar
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Size = direction.HasFlag(BarDirection.Horizontal) ? new Vector2(1, size) : new Vector2(size, 1),
|
Size = direction.HasFlagFast(BarDirection.Horizontal) ? new Vector2(1, size) : new Vector2(size, 1),
|
||||||
Length = length,
|
Length = length,
|
||||||
Direction = Direction,
|
Direction = Direction,
|
||||||
});
|
});
|
||||||
|
@ -10,6 +10,7 @@ using osu.Framework.Graphics.Containers;
|
|||||||
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;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -105,7 +106,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
protected class TextContainer : Container, IHasText
|
protected class TextContainer : Container, IHasText
|
||||||
{
|
{
|
||||||
public string Text
|
public LocalisableString Text
|
||||||
{
|
{
|
||||||
get => NormalText.Text;
|
get => NormalText.Text;
|
||||||
set
|
set
|
||||||
|
@ -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;
|
||||||
using osuTK.Graphics;
|
using osuTK.Graphics;
|
||||||
|
|
||||||
@ -21,9 +22,9 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
/// </summary>
|
/// </summary>
|
||||||
public class OsuButton : Button
|
public class OsuButton : Button
|
||||||
{
|
{
|
||||||
public string Text
|
public LocalisableString Text
|
||||||
{
|
{
|
||||||
get => SpriteText?.Text;
|
get => SpriteText?.Text ?? default;
|
||||||
set
|
set
|
||||||
{
|
{
|
||||||
if (SpriteText != null)
|
if (SpriteText != null)
|
||||||
|
@ -9,6 +9,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Graphics.UserInterface;
|
using osu.Framework.Graphics.UserInterface;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -168,7 +169,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
|
|
||||||
protected new class Content : FillFlowContainer, IHasText
|
protected new class Content : FillFlowContainer, IHasText
|
||||||
{
|
{
|
||||||
public string Text
|
public LocalisableString Text
|
||||||
{
|
{
|
||||||
get => Label.Text;
|
get => Label.Text;
|
||||||
set => Label.Text = value;
|
set => Label.Text = value;
|
||||||
@ -215,7 +216,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
{
|
{
|
||||||
protected readonly SpriteText Text;
|
protected readonly SpriteText Text;
|
||||||
|
|
||||||
protected override string Label
|
protected override LocalisableString Label
|
||||||
{
|
{
|
||||||
get => Text.Text;
|
get => Text.Text;
|
||||||
set => Text.Text = value;
|
set => Text.Text = value;
|
||||||
|
@ -11,6 +11,7 @@ using osu.Game.Graphics.Sprites;
|
|||||||
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;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
@ -35,7 +36,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Text
|
public LocalisableString Text
|
||||||
{
|
{
|
||||||
get => text.Text;
|
get => text.Text;
|
||||||
set => text.Text = value;
|
set => text.Text = value;
|
||||||
|
@ -11,6 +11,7 @@ using osu.Game.Graphics.Sprites;
|
|||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Graphics.UserInterface
|
namespace osu.Game.Graphics.UserInterface
|
||||||
{
|
{
|
||||||
@ -18,7 +19,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
{
|
{
|
||||||
private const int duration = 200;
|
private const int duration = 200;
|
||||||
|
|
||||||
public string Text
|
public LocalisableString Text
|
||||||
{
|
{
|
||||||
get => text.Text;
|
get => text.Text;
|
||||||
set => text.Text = value;
|
set => text.Text = value;
|
||||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
public virtual IEnumerable<string> FilterTerms => new[] { Text };
|
public virtual IEnumerable<string> FilterTerms => new[] { Text.ToString() };
|
||||||
|
|
||||||
public bool MatchingFilter
|
public bool MatchingFilter
|
||||||
{
|
{
|
||||||
|
@ -12,6 +12,7 @@ using osu.Game.Graphics.Containers;
|
|||||||
using osu.Game.Beatmaps.ControlPoints;
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
using osu.Framework.Audio.Track;
|
using osu.Framework.Audio.Track;
|
||||||
using System;
|
using System;
|
||||||
|
using osu.Framework.Extensions.EnumExtensions;
|
||||||
using osu.Framework.Graphics.Effects;
|
using osu.Framework.Graphics.Effects;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Input.Events;
|
using osu.Framework.Input.Events;
|
||||||
@ -56,15 +57,15 @@ namespace osu.Game.Graphics.UserInterface
|
|||||||
set
|
set
|
||||||
{
|
{
|
||||||
base.Origin = value;
|
base.Origin = value;
|
||||||
c1.Origin = c1.Anchor = value.HasFlag(Anchor.x2) ? Anchor.TopLeft : Anchor.TopRight;
|
c1.Origin = c1.Anchor = value.HasFlagFast(Anchor.x2) ? Anchor.TopLeft : Anchor.TopRight;
|
||||||
c2.Origin = c2.Anchor = value.HasFlag(Anchor.x2) ? Anchor.TopRight : Anchor.TopLeft;
|
c2.Origin = c2.Anchor = value.HasFlagFast(Anchor.x2) ? Anchor.TopRight : Anchor.TopLeft;
|
||||||
|
|
||||||
X = value.HasFlag(Anchor.x2) ? SIZE_RETRACTED.X * shear.X * 0.5f : 0;
|
X = value.HasFlagFast(Anchor.x2) ? SIZE_RETRACTED.X * shear.X * 0.5f : 0;
|
||||||
|
|
||||||
Remove(c1);
|
Remove(c1);
|
||||||
Remove(c2);
|
Remove(c2);
|
||||||
c1.Depth = value.HasFlag(Anchor.x2) ? 0 : 1;
|
c1.Depth = value.HasFlagFast(Anchor.x2) ? 0 : 1;
|
||||||
c2.Depth = value.HasFlag(Anchor.x2) ? 1 : 0;
|
c2.Depth = value.HasFlagFast(Anchor.x2) ? 1 : 0;
|
||||||
Add(c1);
|
Add(c1);
|
||||||
Add(c2);
|
Add(c2);
|
||||||
}
|
}
|
||||||
|
@ -10,6 +10,7 @@ using System.Net.Sockets;
|
|||||||
using System.Threading;
|
using System.Threading;
|
||||||
using System.Threading.Tasks;
|
using System.Threading.Tasks;
|
||||||
using Newtonsoft.Json.Linq;
|
using Newtonsoft.Json.Linq;
|
||||||
|
using osu.Framework;
|
||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Extensions.ExceptionExtensions;
|
using osu.Framework.Extensions.ExceptionExtensions;
|
||||||
using osu.Framework.Extensions.ObjectExtensions;
|
using osu.Framework.Extensions.ObjectExtensions;
|
||||||
@ -246,7 +247,14 @@ namespace osu.Game.Online.API
|
|||||||
this.password = password;
|
this.password = password;
|
||||||
}
|
}
|
||||||
|
|
||||||
public IHubClientConnector GetHubConnector(string clientName, string endpoint) => new HubClientConnector(clientName, endpoint, this, versionHash);
|
public IHubClientConnector GetHubConnector(string clientName, string endpoint)
|
||||||
|
{
|
||||||
|
// disabled until the underlying runtime issue is resolved, see https://github.com/mono/mono/issues/20805.
|
||||||
|
if (RuntimeInfo.OS == RuntimeInfo.Platform.iOS)
|
||||||
|
return null;
|
||||||
|
|
||||||
|
return new HubClientConnector(clientName, endpoint, this, versionHash);
|
||||||
|
}
|
||||||
|
|
||||||
public RegistrationRequest.RegistrationRequestErrors CreateAccount(string email, string username, string password)
|
public RegistrationRequest.RegistrationRequestErrors CreateAccount(string email, string username, string password)
|
||||||
{
|
{
|
||||||
@ -373,7 +381,13 @@ namespace osu.Game.Online.API
|
|||||||
|
|
||||||
public void Queue(APIRequest request)
|
public void Queue(APIRequest request)
|
||||||
{
|
{
|
||||||
lock (queue) queue.Enqueue(request);
|
lock (queue)
|
||||||
|
{
|
||||||
|
if (state.Value == APIState.Offline)
|
||||||
|
return;
|
||||||
|
|
||||||
|
queue.Enqueue(request);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private void flushQueue(bool failOldRequests = true)
|
private void flushQueue(bool failOldRequests = true)
|
||||||
@ -394,8 +408,6 @@ namespace osu.Game.Online.API
|
|||||||
|
|
||||||
public void Logout()
|
public void Logout()
|
||||||
{
|
{
|
||||||
flushQueue();
|
|
||||||
|
|
||||||
password = null;
|
password = null;
|
||||||
authentication.Clear();
|
authentication.Clear();
|
||||||
|
|
||||||
@ -407,6 +419,7 @@ namespace osu.Game.Online.API
|
|||||||
});
|
});
|
||||||
|
|
||||||
state.Value = APIState.Offline;
|
state.Value = APIState.Offline;
|
||||||
|
flushQueue();
|
||||||
}
|
}
|
||||||
|
|
||||||
private static User createGuestUser() => new GuestUser();
|
private static User createGuestUser() => new GuestUser();
|
||||||
|
@ -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 osu.Framework.IO.Network;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
|
|
||||||
namespace osu.Game.Online.API.Requests
|
namespace osu.Game.Online.API.Requests
|
||||||
@ -15,6 +16,13 @@ namespace osu.Game.Online.API.Requests
|
|||||||
this.noVideo = noVideo;
|
this.noVideo = noVideo;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
protected override WebRequest CreateWebRequest()
|
||||||
|
{
|
||||||
|
var req = base.CreateWebRequest();
|
||||||
|
req.Timeout = 60000;
|
||||||
|
return req;
|
||||||
|
}
|
||||||
|
|
||||||
protected override string Target => $@"beatmapsets/{Model.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}";
|
protected override string Target => $@"beatmapsets/{Model.OnlineBeatmapSetID}/download{(noVideo ? "?noVideo=1" : "")}";
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -152,7 +152,7 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
createNewPrivateMessageRequest.Failure += exception =>
|
createNewPrivateMessageRequest.Failure += exception =>
|
||||||
{
|
{
|
||||||
Logger.Error(exception, "Posting message failed.");
|
handlePostException(exception);
|
||||||
target.ReplaceMessage(message, null);
|
target.ReplaceMessage(message, null);
|
||||||
dequeueAndRun();
|
dequeueAndRun();
|
||||||
};
|
};
|
||||||
@ -171,7 +171,7 @@ namespace osu.Game.Online.Chat
|
|||||||
|
|
||||||
req.Failure += exception =>
|
req.Failure += exception =>
|
||||||
{
|
{
|
||||||
Logger.Error(exception, "Posting message failed.");
|
handlePostException(exception);
|
||||||
target.ReplaceMessage(message, null);
|
target.ReplaceMessage(message, null);
|
||||||
dequeueAndRun();
|
dequeueAndRun();
|
||||||
};
|
};
|
||||||
@ -184,6 +184,14 @@ namespace osu.Game.Online.Chat
|
|||||||
dequeueAndRun();
|
dequeueAndRun();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void handlePostException(Exception exception)
|
||||||
|
{
|
||||||
|
if (exception is APIException apiException)
|
||||||
|
Logger.Log(apiException.Message, level: LogLevel.Important);
|
||||||
|
else
|
||||||
|
Logger.Error(exception, "Posting message failed.");
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Posts a command locally. Commands like /help will result in a help message written in the current channel.
|
/// Posts a command locally. Commands like /help will result in a help message written in the current channel.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -361,14 +361,6 @@ namespace osu.Game
|
|||||||
|
|
||||||
PerformFromScreen(screen =>
|
PerformFromScreen(screen =>
|
||||||
{
|
{
|
||||||
// we might already be at song select, so a check is required before performing the load to solo.
|
|
||||||
if (screen is MainMenu)
|
|
||||||
menuScreen.LoadToSolo();
|
|
||||||
|
|
||||||
// we might even already be at the song
|
|
||||||
if (Beatmap.Value.BeatmapSetInfo.Hash == databasedSet.Hash && (difficultyCriteria?.Invoke(Beatmap.Value.BeatmapInfo) ?? true))
|
|
||||||
return;
|
|
||||||
|
|
||||||
// Find beatmaps that match our predicate.
|
// Find beatmaps that match our predicate.
|
||||||
var beatmaps = databasedSet.Beatmaps.Where(b => difficultyCriteria?.Invoke(b) ?? true).ToList();
|
var beatmaps = databasedSet.Beatmaps.Where(b => difficultyCriteria?.Invoke(b) ?? true).ToList();
|
||||||
|
|
||||||
@ -381,9 +373,16 @@ namespace osu.Game
|
|||||||
?? beatmaps.FirstOrDefault(b => b.Ruleset.Equals(Ruleset.Value))
|
?? beatmaps.FirstOrDefault(b => b.Ruleset.Equals(Ruleset.Value))
|
||||||
?? beatmaps.First();
|
?? beatmaps.First();
|
||||||
|
|
||||||
|
if (screen is IHandlePresentBeatmap presentableScreen)
|
||||||
|
{
|
||||||
|
presentableScreen.PresentBeatmap(BeatmapManager.GetWorkingBeatmap(selection), selection.Ruleset);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
Ruleset.Value = selection.Ruleset;
|
Ruleset.Value = selection.Ruleset;
|
||||||
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(selection);
|
Beatmap.Value = BeatmapManager.GetWorkingBeatmap(selection);
|
||||||
}, validScreens: new[] { typeof(SongSelect) });
|
}
|
||||||
|
}, validScreens: new[] { typeof(SongSelect), typeof(IHandlePresentBeatmap) });
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
|
@ -84,14 +84,14 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
|
|||||||
{
|
{
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)),
|
Text = new RomanisableString(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title),
|
||||||
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true)
|
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = new LocalisedString((SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist)),
|
Text = new RomanisableString(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist),
|
||||||
Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true)
|
Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true)
|
||||||
},
|
},
|
||||||
},
|
},
|
||||||
|
@ -107,14 +107,14 @@ namespace osu.Game.Overlays.BeatmapListing.Panels
|
|||||||
{
|
{
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = new LocalisedString((SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title)),
|
Text = new RomanisableString(SetInfo.Metadata.TitleUnicode, SetInfo.Metadata.Title),
|
||||||
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true)
|
Font = OsuFont.GetFont(size: 18, weight: FontWeight.Bold, italics: true)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = new LocalisedString((SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist)),
|
Text = new RomanisableString(SetInfo.Metadata.ArtistUnicode, SetInfo.Metadata.Artist),
|
||||||
Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true)
|
Font = OsuFont.GetFont(weight: FontWeight.Bold, italics: true)
|
||||||
},
|
},
|
||||||
}
|
}
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@ -96,7 +97,7 @@ namespace osu.Game.Overlays.BeatmapSet
|
|||||||
|
|
||||||
public string TooltipText { get; }
|
public string TooltipText { get; }
|
||||||
|
|
||||||
public string Value
|
public LocalisableString Value
|
||||||
{
|
{
|
||||||
get => value.Text;
|
get => value.Text;
|
||||||
set => this.value.Text = value;
|
set => this.value.Text = value;
|
||||||
|
@ -9,7 +9,6 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@ -204,7 +203,7 @@ namespace osu.Game.Overlays.BeatmapSet.Scores
|
|||||||
this.text = text;
|
this.text = text;
|
||||||
}
|
}
|
||||||
|
|
||||||
public LocalisedString Text
|
public string Text
|
||||||
{
|
{
|
||||||
set => text.Text = value;
|
set => text.Text = value;
|
||||||
}
|
}
|
||||||
|
@ -4,19 +4,17 @@
|
|||||||
using System;
|
using System;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using osuTK;
|
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osu.Game.Online.Chat;
|
using osu.Game.Online.Chat;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Chat.Selection
|
namespace osu.Game.Overlays.Chat.Selection
|
||||||
{
|
{
|
||||||
public class ChannelSection : Container, IHasFilterableChildren
|
public class ChannelSection : Container, IHasFilterableChildren
|
||||||
{
|
{
|
||||||
private readonly OsuSpriteText header;
|
|
||||||
|
|
||||||
public readonly FillFlowContainer<ChannelListItem> ChannelFlow;
|
public readonly FillFlowContainer<ChannelListItem> ChannelFlow;
|
||||||
|
|
||||||
public IEnumerable<IFilterable> FilterableChildren => ChannelFlow.Children;
|
public IEnumerable<IFilterable> FilterableChildren => ChannelFlow.Children;
|
||||||
@ -29,12 +27,6 @@ namespace osu.Game.Overlays.Chat.Selection
|
|||||||
|
|
||||||
public bool FilteringActive { get; set; }
|
public bool FilteringActive { get; set; }
|
||||||
|
|
||||||
public string Header
|
|
||||||
{
|
|
||||||
get => header.Text;
|
|
||||||
set => header.Text = value.ToUpperInvariant();
|
|
||||||
}
|
|
||||||
|
|
||||||
public IEnumerable<Channel> Channels
|
public IEnumerable<Channel> Channels
|
||||||
{
|
{
|
||||||
set => ChannelFlow.ChildrenEnumerable = value.Select(c => new ChannelListItem(c));
|
set => ChannelFlow.ChildrenEnumerable = value.Select(c => new ChannelListItem(c));
|
||||||
@ -47,9 +39,10 @@ namespace osu.Game.Overlays.Chat.Selection
|
|||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
header = new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold),
|
Font = OsuFont.GetFont(size: 15, weight: FontWeight.Bold),
|
||||||
|
Text = "All Channels".ToUpperInvariant()
|
||||||
},
|
},
|
||||||
ChannelFlow = new FillFlowContainer<ChannelListItem>
|
ChannelFlow = new FillFlowContainer<ChannelListItem>
|
||||||
{
|
{
|
||||||
|
@ -131,11 +131,7 @@ namespace osu.Game.Overlays.Chat.Selection
|
|||||||
{
|
{
|
||||||
sectionsFlow.ChildrenEnumerable = new[]
|
sectionsFlow.ChildrenEnumerable = new[]
|
||||||
{
|
{
|
||||||
new ChannelSection
|
new ChannelSection { Channels = channels, },
|
||||||
{
|
|
||||||
Header = "All Channels",
|
|
||||||
Channels = channels,
|
|
||||||
},
|
|
||||||
};
|
};
|
||||||
|
|
||||||
foreach (ChannelSection s in sectionsFlow.Children)
|
foreach (ChannelSection s in sectionsFlow.Children)
|
||||||
|
@ -6,6 +6,7 @@ using osu.Framework.Graphics;
|
|||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
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;
|
||||||
@ -16,7 +17,7 @@ namespace osu.Game.Overlays.Comments.Buttons
|
|||||||
{
|
{
|
||||||
public abstract class CommentRepliesButton : CompositeDrawable
|
public abstract class CommentRepliesButton : CompositeDrawable
|
||||||
{
|
{
|
||||||
protected string Text
|
protected LocalisableString Text
|
||||||
{
|
{
|
||||||
get => text.Text;
|
get => text.Text;
|
||||||
set => text.Text = value;
|
set => text.Text = value;
|
||||||
|
42
osu.Game/Overlays/Dialog/ConfirmDialog.cs
Normal file
42
osu.Game/Overlays/Dialog/ConfirmDialog.cs
Normal file
@ -0,0 +1,42 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System;
|
||||||
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
|
||||||
|
namespace osu.Game.Overlays.Dialog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// A dialog which confirms a user action.
|
||||||
|
/// </summary>
|
||||||
|
public class ConfirmDialog : PopupDialog
|
||||||
|
{
|
||||||
|
/// <summary>
|
||||||
|
/// Construct a new confirmation dialog.
|
||||||
|
/// </summary>
|
||||||
|
/// <param name="message">The description of the action to be displayed to the user.</param>
|
||||||
|
/// <param name="onConfirm">An action to perform on confirmation.</param>
|
||||||
|
/// <param name="onCancel">An optional action to perform on cancel.</param>
|
||||||
|
public ConfirmDialog(string message, Action onConfirm, Action onCancel = null)
|
||||||
|
{
|
||||||
|
HeaderText = message;
|
||||||
|
BodyText = "Last chance to turn back";
|
||||||
|
|
||||||
|
Icon = FontAwesome.Solid.ExclamationTriangle;
|
||||||
|
|
||||||
|
Buttons = new PopupDialogButton[]
|
||||||
|
{
|
||||||
|
new PopupDialogOkButton
|
||||||
|
{
|
||||||
|
Text = @"Yes",
|
||||||
|
Action = onConfirm
|
||||||
|
},
|
||||||
|
new PopupDialogCancelButton
|
||||||
|
{
|
||||||
|
Text = @"Cancel",
|
||||||
|
Action = onCancel
|
||||||
|
},
|
||||||
|
};
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -51,7 +51,7 @@ namespace osu.Game.Overlays.KeyBinding
|
|||||||
private FillFlowContainer cancelAndClearButtons;
|
private FillFlowContainer cancelAndClearButtons;
|
||||||
private FillFlowContainer<KeyButton> buttons;
|
private FillFlowContainer<KeyButton> buttons;
|
||||||
|
|
||||||
public IEnumerable<string> FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend((string)text.Text);
|
public IEnumerable<string> FilterTerms => bindings.Select(b => b.KeyCombination.ReadableString()).Prepend(text.Text.ToString());
|
||||||
|
|
||||||
public KeyBindingRow(object action, IEnumerable<Framework.Input.Bindings.KeyBinding> bindings)
|
public KeyBindingRow(object action, IEnumerable<Framework.Input.Bindings.KeyBinding> bindings)
|
||||||
{
|
{
|
||||||
|
@ -23,13 +23,15 @@ namespace osu.Game.Overlays.Mods
|
|||||||
|
|
||||||
public FillFlowContainer<ModButtonEmpty> ButtonsContainer { get; }
|
public FillFlowContainer<ModButtonEmpty> ButtonsContainer { get; }
|
||||||
|
|
||||||
|
protected IReadOnlyList<ModButton> Buttons { get; private set; } = Array.Empty<ModButton>();
|
||||||
|
|
||||||
public Action<Mod> Action;
|
public Action<Mod> Action;
|
||||||
|
|
||||||
public Key[] ToggleKeys;
|
public Key[] ToggleKeys;
|
||||||
|
|
||||||
public readonly ModType ModType;
|
public readonly ModType ModType;
|
||||||
|
|
||||||
public IEnumerable<Mod> SelectedMods => buttons.Select(b => b.SelectedMod).Where(m => m != null);
|
public IEnumerable<Mod> SelectedMods => Buttons.Select(b => b.SelectedMod).Where(m => m != null);
|
||||||
|
|
||||||
private CancellationTokenSource modsLoadCts;
|
private CancellationTokenSource modsLoadCts;
|
||||||
|
|
||||||
@ -77,7 +79,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
ButtonsContainer.ChildrenEnumerable = c;
|
ButtonsContainer.ChildrenEnumerable = c;
|
||||||
}, (modsLoadCts = new CancellationTokenSource()).Token);
|
}, (modsLoadCts = new CancellationTokenSource()).Token);
|
||||||
|
|
||||||
buttons = modContainers.OfType<ModButton>().ToArray();
|
Buttons = modContainers.OfType<ModButton>().ToArray();
|
||||||
|
|
||||||
header.FadeIn(200);
|
header.FadeIn(200);
|
||||||
this.FadeIn(200);
|
this.FadeIn(200);
|
||||||
@ -88,8 +90,6 @@ namespace osu.Game.Overlays.Mods
|
|||||||
{
|
{
|
||||||
}
|
}
|
||||||
|
|
||||||
private ModButton[] buttons = Array.Empty<ModButton>();
|
|
||||||
|
|
||||||
protected override bool OnKeyDown(KeyDownEvent e)
|
protected override bool OnKeyDown(KeyDownEvent e)
|
||||||
{
|
{
|
||||||
if (e.ControlPressed) return false;
|
if (e.ControlPressed) return false;
|
||||||
@ -97,8 +97,8 @@ namespace osu.Game.Overlays.Mods
|
|||||||
if (ToggleKeys != null)
|
if (ToggleKeys != null)
|
||||||
{
|
{
|
||||||
var index = Array.IndexOf(ToggleKeys, e.Key);
|
var index = Array.IndexOf(ToggleKeys, e.Key);
|
||||||
if (index > -1 && index < buttons.Length)
|
if (index > -1 && index < Buttons.Count)
|
||||||
buttons[index].SelectNext(e.ShiftPressed ? -1 : 1);
|
Buttons[index].SelectNext(e.ShiftPressed ? -1 : 1);
|
||||||
}
|
}
|
||||||
|
|
||||||
return base.OnKeyDown(e);
|
return base.OnKeyDown(e);
|
||||||
@ -141,7 +141,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
{
|
{
|
||||||
pendingSelectionOperations.Clear();
|
pendingSelectionOperations.Clear();
|
||||||
|
|
||||||
foreach (var button in buttons.Where(b => !b.Selected))
|
foreach (var button in Buttons.Where(b => !b.Selected))
|
||||||
pendingSelectionOperations.Enqueue(() => button.SelectAt(0));
|
pendingSelectionOperations.Enqueue(() => button.SelectAt(0));
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -151,7 +151,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
public void DeselectAll()
|
public void DeselectAll()
|
||||||
{
|
{
|
||||||
pendingSelectionOperations.Clear();
|
pendingSelectionOperations.Clear();
|
||||||
DeselectTypes(buttons.Select(b => b.SelectedMod?.GetType()).Where(t => t != null));
|
DeselectTypes(Buttons.Select(b => b.SelectedMod?.GetType()).Where(t => t != null));
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -161,7 +161,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
/// <param name="immediate">Whether the deselection should happen immediately. Should only be used when required to ensure correct selection flow.</param>
|
/// <param name="immediate">Whether the deselection should happen immediately. Should only be used when required to ensure correct selection flow.</param>
|
||||||
public void DeselectTypes(IEnumerable<Type> modTypes, bool immediate = false)
|
public void DeselectTypes(IEnumerable<Type> modTypes, bool immediate = false)
|
||||||
{
|
{
|
||||||
foreach (var button in buttons)
|
foreach (var button in Buttons)
|
||||||
{
|
{
|
||||||
if (button.SelectedMod == null) continue;
|
if (button.SelectedMod == null) continue;
|
||||||
|
|
||||||
@ -184,7 +184,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
/// <param name="newSelectedMods">The new list of selected mods to select.</param>
|
/// <param name="newSelectedMods">The new list of selected mods to select.</param>
|
||||||
public void UpdateSelectedButtons(IReadOnlyList<Mod> newSelectedMods)
|
public void UpdateSelectedButtons(IReadOnlyList<Mod> newSelectedMods)
|
||||||
{
|
{
|
||||||
foreach (var button in buttons)
|
foreach (var button in Buttons)
|
||||||
updateButtonSelection(button, newSelectedMods);
|
updateButtonSelection(button, newSelectedMods);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -456,6 +456,7 @@ namespace osu.Game.Overlays.Mods
|
|||||||
}
|
}
|
||||||
|
|
||||||
updateSelectedButtons();
|
updateSelectedButtons();
|
||||||
|
OnAvailableModsChanged();
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
@ -533,6 +534,13 @@ namespace osu.Game.Overlays.Mods
|
|||||||
private void playSelectedSound() => sampleOn?.Play();
|
private void playSelectedSound() => sampleOn?.Play();
|
||||||
private void playDeselectedSound() => sampleOff?.Play();
|
private void playDeselectedSound() => sampleOff?.Play();
|
||||||
|
|
||||||
|
/// <summary>
|
||||||
|
/// Invoked after <see cref="availableMods"/> has changed.
|
||||||
|
/// </summary>
|
||||||
|
protected virtual void OnAvailableModsChanged()
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
/// <summary>
|
/// <summary>
|
||||||
/// Invoked when a new <see cref="Mod"/> has been selected.
|
/// Invoked when a new <see cref="Mod"/> has been selected.
|
||||||
/// </summary>
|
/// </summary>
|
||||||
|
@ -48,8 +48,8 @@ namespace osu.Game.Overlays.Music
|
|||||||
artistColour = colours.Gray9;
|
artistColour = colours.Gray9;
|
||||||
HandleColour = colours.Gray5;
|
HandleColour = colours.Gray5;
|
||||||
|
|
||||||
title = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.TitleUnicode, Model.Metadata.Title)));
|
title = localisation.GetLocalisedString(new RomanisableString(Model.Metadata.TitleUnicode, Model.Metadata.Title));
|
||||||
artist = localisation.GetLocalisedString(new LocalisedString((Model.Metadata.ArtistUnicode, Model.Metadata.Artist)));
|
artist = localisation.GetLocalisedString(new RomanisableString(Model.Metadata.ArtistUnicode, Model.Metadata.Artist));
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
|
@ -8,10 +8,11 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Extensions.IEnumerableExtensions;
|
using osu.Framework.Extensions.IEnumerableExtensions;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
|
using osu.Game.Graphics.Containers;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Game.Graphics.Containers;
|
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Notifications
|
namespace osu.Game.Overlays.Notifications
|
||||||
{
|
{
|
||||||
@ -37,7 +38,7 @@ namespace osu.Game.Overlays.Notifications
|
|||||||
|
|
||||||
public NotificationSection(string title, string clearButtonText)
|
public NotificationSection(string title, string clearButtonText)
|
||||||
{
|
{
|
||||||
this.clearButtonText = clearButtonText;
|
this.clearButtonText = clearButtonText.ToUpperInvariant();
|
||||||
titleText = title;
|
titleText = title;
|
||||||
}
|
}
|
||||||
|
|
||||||
@ -121,7 +122,20 @@ namespace osu.Game.Overlays.Notifications
|
|||||||
{
|
{
|
||||||
base.Update();
|
base.Update();
|
||||||
|
|
||||||
countDrawable.Text = notifications.Children.Count(c => c.Alpha > 0.99f).ToString();
|
countDrawable.Text = getVisibleCount().ToString();
|
||||||
|
}
|
||||||
|
|
||||||
|
private int getVisibleCount()
|
||||||
|
{
|
||||||
|
int count = 0;
|
||||||
|
|
||||||
|
foreach (var c in notifications)
|
||||||
|
{
|
||||||
|
if (c.Alpha > 0.99f)
|
||||||
|
count++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ClearAllButton : OsuClickableContainer
|
private class ClearAllButton : OsuClickableContainer
|
||||||
@ -138,10 +152,10 @@ namespace osu.Game.Overlays.Notifications
|
|||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Text
|
public LocalisableString Text
|
||||||
{
|
{
|
||||||
get => text.Text;
|
get => text.Text;
|
||||||
set => text.Text = value.ToUpperInvariant();
|
set => text.Text = value;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -293,8 +293,8 @@ namespace osu.Game.Overlays
|
|||||||
else
|
else
|
||||||
{
|
{
|
||||||
BeatmapMetadata metadata = beatmap.Metadata;
|
BeatmapMetadata metadata = beatmap.Metadata;
|
||||||
title.Text = new LocalisedString((metadata.TitleUnicode, metadata.Title));
|
title.Text = new RomanisableString(metadata.TitleUnicode, metadata.Title);
|
||||||
artist.Text = new LocalisedString((metadata.ArtistUnicode, metadata.Artist));
|
artist.Text = new RomanisableString(metadata.ArtistUnicode, metadata.Artist);
|
||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -17,6 +17,7 @@ using osu.Game.Overlays.Comments;
|
|||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using System;
|
using System;
|
||||||
using osu.Framework.Extensions;
|
using osu.Framework.Extensions;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays
|
namespace osu.Game.Overlays
|
||||||
{
|
{
|
||||||
@ -30,7 +31,7 @@ namespace osu.Game.Overlays
|
|||||||
set => current.Current = value;
|
set => current.Current = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
public string Title
|
public LocalisableString Title
|
||||||
{
|
{
|
||||||
get => text.Text;
|
get => text.Text;
|
||||||
set => text.Text = value;
|
set => text.Text = value;
|
||||||
|
@ -5,7 +5,6 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
using osu.Framework.Localisation;
|
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Beatmaps.Drawables;
|
using osu.Game.Beatmaps.Drawables;
|
||||||
using osu.Game.Graphics;
|
using osu.Game.Graphics;
|
||||||
@ -13,6 +12,7 @@ using osu.Game.Graphics.Containers;
|
|||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
using osu.Framework.Graphics.Cursor;
|
using osu.Framework.Graphics.Cursor;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Profile.Sections.Historical
|
namespace osu.Game.Overlays.Profile.Sections.Historical
|
||||||
{
|
{
|
||||||
@ -129,14 +129,14 @@ namespace osu.Game.Overlays.Profile.Sections.Historical
|
|||||||
{
|
{
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = new LocalisedString((
|
Text = new RomanisableString(
|
||||||
$"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} [{beatmap.Version}] ",
|
$"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} [{beatmap.Version}] ",
|
||||||
$"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} [{beatmap.Version}] ")),
|
$"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} [{beatmap.Version}] "),
|
||||||
Font = OsuFont.GetFont(weight: FontWeight.Bold)
|
Font = OsuFont.GetFont(weight: FontWeight.Bold)
|
||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Text = "by " + new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist)),
|
Text = "by " + new RomanisableString(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist),
|
||||||
Font = OsuFont.GetFont(weight: FontWeight.Regular)
|
Font = OsuFont.GetFont(weight: FontWeight.Regular)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -256,16 +256,16 @@ namespace osu.Game.Overlays.Profile.Sections.Ranks
|
|||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Text = new LocalisedString((
|
Text = new RomanisableString(
|
||||||
$"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} ",
|
$"{beatmap.Metadata.TitleUnicode ?? beatmap.Metadata.Title} ",
|
||||||
$"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} ")),
|
$"{beatmap.Metadata.Title ?? beatmap.Metadata.TitleUnicode} "),
|
||||||
Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true)
|
Font = OsuFont.GetFont(size: 14, weight: FontWeight.SemiBold, italics: true)
|
||||||
},
|
},
|
||||||
new OsuSpriteText
|
new OsuSpriteText
|
||||||
{
|
{
|
||||||
Anchor = Anchor.BottomLeft,
|
Anchor = Anchor.BottomLeft,
|
||||||
Origin = Anchor.BottomLeft,
|
Origin = Anchor.BottomLeft,
|
||||||
Text = "by " + new LocalisedString((beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist)),
|
Text = "by " + new RomanisableString(beatmap.Metadata.ArtistUnicode, beatmap.Metadata.Artist),
|
||||||
Font = OsuFont.GetFont(size: 12, italics: true)
|
Font = OsuFont.GetFont(size: 12, italics: true)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
@ -6,6 +6,7 @@ using osu.Framework.Audio;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
|
|
||||||
namespace osu.Game.Overlays.Settings.Sections.Audio
|
namespace osu.Game.Overlays.Settings.Sections.Audio
|
||||||
@ -76,7 +77,7 @@ namespace osu.Game.Overlays.Settings.Sections.Audio
|
|||||||
|
|
||||||
private class AudioDeviceDropdownControl : DropdownControl
|
private class AudioDeviceDropdownControl : DropdownControl
|
||||||
{
|
{
|
||||||
protected override string GenerateItemText(string item)
|
protected override LocalisableString GenerateItemText(string item)
|
||||||
=> string.IsNullOrEmpty(item) ? "Default" : base.GenerateItemText(item);
|
=> string.IsNullOrEmpty(item) ? "Default" : base.GenerateItemText(item);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -11,6 +11,7 @@ using osu.Framework.Extensions.IEnumerableExtensions;
|
|||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Containers;
|
using osu.Framework.Graphics.Containers;
|
||||||
using osu.Framework.Graphics.Shapes;
|
using osu.Framework.Graphics.Shapes;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Platform;
|
using osu.Framework.Platform;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.Containers;
|
using osu.Game.Graphics.Containers;
|
||||||
@ -234,7 +235,7 @@ namespace osu.Game.Overlays.Settings.Sections.Graphics
|
|||||||
|
|
||||||
private class ResolutionDropdownControl : DropdownControl
|
private class ResolutionDropdownControl : DropdownControl
|
||||||
{
|
{
|
||||||
protected override string GenerateItemText(Size item)
|
protected override LocalisableString GenerateItemText(Size item)
|
||||||
{
|
{
|
||||||
if (item == new Size(9999, 9999))
|
if (item == new Size(9999, 9999))
|
||||||
return "Default";
|
return "Default";
|
||||||
|
@ -17,7 +17,11 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
protected override string Header => "Mouse";
|
protected override string Header => "Mouse";
|
||||||
|
|
||||||
private readonly BindableBool rawInputToggle = new BindableBool();
|
private readonly BindableBool rawInputToggle = new BindableBool();
|
||||||
private Bindable<double> sensitivityBindable = new BindableDouble();
|
|
||||||
|
private Bindable<double> configSensitivity;
|
||||||
|
|
||||||
|
private Bindable<double> localSensitivity;
|
||||||
|
|
||||||
private Bindable<string> ignoredInputHandlers;
|
private Bindable<string> ignoredInputHandlers;
|
||||||
|
|
||||||
private Bindable<WindowMode> windowMode;
|
private Bindable<WindowMode> windowMode;
|
||||||
@ -26,12 +30,12 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
[BackgroundDependencyLoader]
|
[BackgroundDependencyLoader]
|
||||||
private void load(OsuConfigManager osuConfig, FrameworkConfigManager config)
|
private void load(OsuConfigManager osuConfig, FrameworkConfigManager config)
|
||||||
{
|
{
|
||||||
var configSensitivity = config.GetBindable<double>(FrameworkSetting.CursorSensitivity);
|
|
||||||
|
|
||||||
// use local bindable to avoid changing enabled state of game host's bindable.
|
// use local bindable to avoid changing enabled state of game host's bindable.
|
||||||
sensitivityBindable = configSensitivity.GetUnboundCopy();
|
configSensitivity = config.GetBindable<double>(FrameworkSetting.CursorSensitivity);
|
||||||
configSensitivity.BindValueChanged(val => sensitivityBindable.Value = val.NewValue);
|
localSensitivity = configSensitivity.GetUnboundCopy();
|
||||||
sensitivityBindable.BindValueChanged(val => configSensitivity.Value = val.NewValue);
|
|
||||||
|
windowMode = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode);
|
||||||
|
ignoredInputHandlers = config.GetBindable<string>(FrameworkSetting.IgnoredInputHandlers);
|
||||||
|
|
||||||
Children = new Drawable[]
|
Children = new Drawable[]
|
||||||
{
|
{
|
||||||
@ -43,7 +47,7 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
new SensitivitySetting
|
new SensitivitySetting
|
||||||
{
|
{
|
||||||
LabelText = "Cursor sensitivity",
|
LabelText = "Cursor sensitivity",
|
||||||
Current = sensitivityBindable
|
Current = localSensitivity
|
||||||
},
|
},
|
||||||
new SettingsCheckbox
|
new SettingsCheckbox
|
||||||
{
|
{
|
||||||
@ -66,14 +70,35 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons)
|
Current = osuConfig.GetBindable<bool>(OsuSetting.MouseDisableButtons)
|
||||||
},
|
},
|
||||||
};
|
};
|
||||||
|
}
|
||||||
|
|
||||||
windowMode = config.GetBindable<WindowMode>(FrameworkSetting.WindowMode);
|
protected override void LoadComplete()
|
||||||
windowMode.BindValueChanged(mode => confineMouseModeSetting.Alpha = mode.NewValue == WindowMode.Fullscreen ? 0 : 1, true);
|
{
|
||||||
|
base.LoadComplete();
|
||||||
|
|
||||||
|
configSensitivity.BindValueChanged(val => localSensitivity.Value = val.NewValue, true);
|
||||||
|
localSensitivity.BindValueChanged(val => configSensitivity.Value = val.NewValue);
|
||||||
|
|
||||||
|
windowMode.BindValueChanged(mode =>
|
||||||
|
{
|
||||||
|
var isFullscreen = mode.NewValue == WindowMode.Fullscreen;
|
||||||
|
|
||||||
|
if (isFullscreen)
|
||||||
|
{
|
||||||
|
confineMouseModeSetting.Current.Disabled = true;
|
||||||
|
confineMouseModeSetting.TooltipText = "Not applicable in full screen mode";
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
confineMouseModeSetting.Current.Disabled = false;
|
||||||
|
confineMouseModeSetting.TooltipText = string.Empty;
|
||||||
|
}
|
||||||
|
}, true);
|
||||||
|
|
||||||
if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows)
|
if (RuntimeInfo.OS != RuntimeInfo.Platform.Windows)
|
||||||
{
|
{
|
||||||
rawInputToggle.Disabled = true;
|
rawInputToggle.Disabled = true;
|
||||||
sensitivityBindable.Disabled = true;
|
localSensitivity.Disabled = true;
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -86,12 +111,11 @@ namespace osu.Game.Overlays.Settings.Sections.Input
|
|||||||
ignoredInputHandlers.Value = enabled.NewValue ? standard_mouse_handlers : raw_mouse_handler;
|
ignoredInputHandlers.Value = enabled.NewValue ? standard_mouse_handlers : raw_mouse_handler;
|
||||||
};
|
};
|
||||||
|
|
||||||
ignoredInputHandlers = config.GetBindable<string>(FrameworkSetting.IgnoredInputHandlers);
|
|
||||||
ignoredInputHandlers.ValueChanged += handler =>
|
ignoredInputHandlers.ValueChanged += handler =>
|
||||||
{
|
{
|
||||||
bool raw = !handler.NewValue.Contains("Raw");
|
bool raw = !handler.NewValue.Contains("Raw");
|
||||||
rawInputToggle.Value = raw;
|
rawInputToggle.Value = raw;
|
||||||
sensitivityBindable.Disabled = !raw;
|
localSensitivity.Disabled = !raw;
|
||||||
};
|
};
|
||||||
|
|
||||||
ignoredInputHandlers.TriggerChange();
|
ignoredInputHandlers.TriggerChange();
|
||||||
|
@ -8,6 +8,7 @@ using osu.Framework.Allocation;
|
|||||||
using osu.Framework.Bindables;
|
using osu.Framework.Bindables;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Framework.Graphics.Sprites;
|
using osu.Framework.Graphics.Sprites;
|
||||||
|
using osu.Framework.Localisation;
|
||||||
using osu.Framework.Logging;
|
using osu.Framework.Logging;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
@ -178,7 +179,7 @@ namespace osu.Game.Overlays.Settings.Sections
|
|||||||
|
|
||||||
private class SkinDropdownControl : DropdownControl
|
private class SkinDropdownControl : DropdownControl
|
||||||
{
|
{
|
||||||
protected override string GenerateItemText(SkinInfo item) => item.ToString();
|
protected override LocalisableString GenerateItemText(SkinInfo item) => item.ToString();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user