mirror of
https://github.com/ppy/osu.git
synced 2024-12-15 04:53:21 +08:00
Merge branch 'master' into FL-diffspike
This commit is contained in:
commit
7d743994bc
@ -16,3 +16,6 @@ M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Linq.IQueryable
|
|||||||
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Generic.IList{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IList<T>,NotificationCallbackDelegate<T>) instead.
|
M:Realms.CollectionExtensions.SubscribeForNotifications`1(System.Collections.Generic.IList{``0},Realms.NotificationCallbackDelegate{``0});Use osu.Game.Database.RealmObjectExtensions.QueryAsyncWithNotifications(IList<T>,NotificationCallbackDelegate<T>) instead.
|
||||||
M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks.
|
M:System.Threading.Tasks.Task.Wait();Don't use Task.Wait. Use Task.WaitSafely() to ensure we avoid deadlocks.
|
||||||
P:System.Threading.Tasks.Task`1.Result;Don't use Task.Result. Use Task.GetResultSafely() to ensure we avoid deadlocks.
|
P:System.Threading.Tasks.Task`1.Result;Don't use Task.Result. Use Task.GetResultSafely() to ensure we avoid deadlocks.
|
||||||
|
M:System.Threading.ManualResetEventSlim.Wait();Specify a timeout to avoid waiting forever.
|
||||||
|
M:System.String.ToLower();string.ToLower() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToLowerInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString.
|
||||||
|
M:System.String.ToUpper();string.ToUpper() changes behaviour depending on CultureInfo.CurrentCulture. Use string.ToUpperInvariant() instead. If wanting culture-sensitive behaviour, explicitly provide CultureInfo.CurrentCulture or use LocalisableString.
|
||||||
|
@ -1,7 +1,7 @@
|
|||||||
<!-- Contains required properties for osu!framework projects. -->
|
<!-- Contains required properties for osu!framework projects. -->
|
||||||
<Project>
|
<Project>
|
||||||
<PropertyGroup Label="C#">
|
<PropertyGroup Label="C#">
|
||||||
<LangVersion>8.0</LangVersion>
|
<LangVersion>9.0</LangVersion>
|
||||||
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
<TreatWarningsAsErrors>true</TreatWarningsAsErrors>
|
||||||
<Nullable>enable</Nullable>
|
<Nullable>enable</Nullable>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
|
60
Gemfile.lock
60
Gemfile.lock
@ -8,20 +8,20 @@ GEM
|
|||||||
artifactory (3.0.15)
|
artifactory (3.0.15)
|
||||||
atomos (0.1.3)
|
atomos (0.1.3)
|
||||||
aws-eventstream (1.2.0)
|
aws-eventstream (1.2.0)
|
||||||
aws-partitions (1.570.0)
|
aws-partitions (1.601.0)
|
||||||
aws-sdk-core (3.130.0)
|
aws-sdk-core (3.131.2)
|
||||||
aws-eventstream (~> 1, >= 1.0.2)
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
aws-partitions (~> 1, >= 1.525.0)
|
aws-partitions (~> 1, >= 1.525.0)
|
||||||
aws-sigv4 (~> 1.1)
|
aws-sigv4 (~> 1.1)
|
||||||
jmespath (~> 1.0)
|
jmespath (~> 1, >= 1.6.1)
|
||||||
aws-sdk-kms (1.55.0)
|
aws-sdk-kms (1.57.0)
|
||||||
aws-sdk-core (~> 3, >= 3.127.0)
|
aws-sdk-core (~> 3, >= 3.127.0)
|
||||||
aws-sigv4 (~> 1.1)
|
aws-sigv4 (~> 1.1)
|
||||||
aws-sdk-s3 (1.113.0)
|
aws-sdk-s3 (1.114.0)
|
||||||
aws-sdk-core (~> 3, >= 3.127.0)
|
aws-sdk-core (~> 3, >= 3.127.0)
|
||||||
aws-sdk-kms (~> 1)
|
aws-sdk-kms (~> 1)
|
||||||
aws-sigv4 (~> 1.4)
|
aws-sigv4 (~> 1.4)
|
||||||
aws-sigv4 (1.4.0)
|
aws-sigv4 (1.5.0)
|
||||||
aws-eventstream (~> 1, >= 1.0.2)
|
aws-eventstream (~> 1, >= 1.0.2)
|
||||||
babosa (1.0.4)
|
babosa (1.0.4)
|
||||||
claide (1.1.0)
|
claide (1.1.0)
|
||||||
@ -36,7 +36,7 @@ GEM
|
|||||||
unf (>= 0.0.5, < 1.0.0)
|
unf (>= 0.0.5, < 1.0.0)
|
||||||
dotenv (2.7.6)
|
dotenv (2.7.6)
|
||||||
emoji_regex (3.2.3)
|
emoji_regex (3.2.3)
|
||||||
excon (0.92.1)
|
excon (0.92.3)
|
||||||
faraday (1.10.0)
|
faraday (1.10.0)
|
||||||
faraday-em_http (~> 1.0)
|
faraday-em_http (~> 1.0)
|
||||||
faraday-em_synchrony (~> 1.0)
|
faraday-em_synchrony (~> 1.0)
|
||||||
@ -56,8 +56,8 @@ GEM
|
|||||||
faraday-em_synchrony (1.0.0)
|
faraday-em_synchrony (1.0.0)
|
||||||
faraday-excon (1.1.0)
|
faraday-excon (1.1.0)
|
||||||
faraday-httpclient (1.0.1)
|
faraday-httpclient (1.0.1)
|
||||||
faraday-multipart (1.0.3)
|
faraday-multipart (1.0.4)
|
||||||
multipart-post (>= 1.2, < 3)
|
multipart-post (~> 2)
|
||||||
faraday-net_http (1.0.1)
|
faraday-net_http (1.0.1)
|
||||||
faraday-net_http_persistent (1.2.0)
|
faraday-net_http_persistent (1.2.0)
|
||||||
faraday-patron (1.0.0)
|
faraday-patron (1.0.0)
|
||||||
@ -66,7 +66,7 @@ GEM
|
|||||||
faraday_middleware (1.2.0)
|
faraday_middleware (1.2.0)
|
||||||
faraday (~> 1.0)
|
faraday (~> 1.0)
|
||||||
fastimage (2.2.6)
|
fastimage (2.2.6)
|
||||||
fastlane (2.205.1)
|
fastlane (2.206.2)
|
||||||
CFPropertyList (>= 2.3, < 4.0.0)
|
CFPropertyList (>= 2.3, < 4.0.0)
|
||||||
addressable (>= 2.8, < 3.0.0)
|
addressable (>= 2.8, < 3.0.0)
|
||||||
artifactory (~> 3.0)
|
artifactory (~> 3.0)
|
||||||
@ -110,9 +110,9 @@ GEM
|
|||||||
souyuz (= 0.11.1)
|
souyuz (= 0.11.1)
|
||||||
fastlane-plugin-xamarin (0.6.3)
|
fastlane-plugin-xamarin (0.6.3)
|
||||||
gh_inspector (1.1.3)
|
gh_inspector (1.1.3)
|
||||||
google-apis-androidpublisher_v3 (0.16.0)
|
google-apis-androidpublisher_v3 (0.23.0)
|
||||||
google-apis-core (>= 0.4, < 2.a)
|
google-apis-core (>= 0.6, < 2.a)
|
||||||
google-apis-core (0.4.2)
|
google-apis-core (0.6.0)
|
||||||
addressable (~> 2.5, >= 2.5.1)
|
addressable (~> 2.5, >= 2.5.1)
|
||||||
googleauth (>= 0.16.2, < 2.a)
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
httpclient (>= 2.8.1, < 3.a)
|
httpclient (>= 2.8.1, < 3.a)
|
||||||
@ -121,19 +121,19 @@ GEM
|
|||||||
retriable (>= 2.0, < 4.a)
|
retriable (>= 2.0, < 4.a)
|
||||||
rexml
|
rexml
|
||||||
webrick
|
webrick
|
||||||
google-apis-iamcredentials_v1 (0.10.0)
|
google-apis-iamcredentials_v1 (0.12.0)
|
||||||
google-apis-core (>= 0.4, < 2.a)
|
google-apis-core (>= 0.6, < 2.a)
|
||||||
google-apis-playcustomapp_v1 (0.7.0)
|
google-apis-playcustomapp_v1 (0.9.0)
|
||||||
google-apis-core (>= 0.4, < 2.a)
|
google-apis-core (>= 0.6, < 2.a)
|
||||||
google-apis-storage_v1 (0.11.0)
|
google-apis-storage_v1 (0.16.0)
|
||||||
google-apis-core (>= 0.4, < 2.a)
|
google-apis-core (>= 0.6, < 2.a)
|
||||||
google-cloud-core (1.6.0)
|
google-cloud-core (1.6.0)
|
||||||
google-cloud-env (~> 1.0)
|
google-cloud-env (~> 1.0)
|
||||||
google-cloud-errors (~> 1.0)
|
google-cloud-errors (~> 1.0)
|
||||||
google-cloud-env (1.6.0)
|
google-cloud-env (1.6.0)
|
||||||
faraday (>= 0.17.3, < 3.0)
|
faraday (>= 0.17.3, < 3.0)
|
||||||
google-cloud-errors (1.2.0)
|
google-cloud-errors (1.2.0)
|
||||||
google-cloud-storage (1.36.1)
|
google-cloud-storage (1.36.2)
|
||||||
addressable (~> 2.8)
|
addressable (~> 2.8)
|
||||||
digest-crc (~> 0.4)
|
digest-crc (~> 0.4)
|
||||||
google-apis-iamcredentials_v1 (~> 0.1)
|
google-apis-iamcredentials_v1 (~> 0.1)
|
||||||
@ -141,7 +141,7 @@ GEM
|
|||||||
google-cloud-core (~> 1.6)
|
google-cloud-core (~> 1.6)
|
||||||
googleauth (>= 0.16.2, < 2.a)
|
googleauth (>= 0.16.2, < 2.a)
|
||||||
mini_mime (~> 1.0)
|
mini_mime (~> 1.0)
|
||||||
googleauth (1.1.2)
|
googleauth (1.2.0)
|
||||||
faraday (>= 0.17.3, < 3.a)
|
faraday (>= 0.17.3, < 3.a)
|
||||||
jwt (>= 1.4, < 3.0)
|
jwt (>= 1.4, < 3.0)
|
||||||
memoist (~> 0.16)
|
memoist (~> 0.16)
|
||||||
@ -149,12 +149,12 @@ GEM
|
|||||||
os (>= 0.9, < 2.0)
|
os (>= 0.9, < 2.0)
|
||||||
signet (>= 0.16, < 2.a)
|
signet (>= 0.16, < 2.a)
|
||||||
highline (2.0.3)
|
highline (2.0.3)
|
||||||
http-cookie (1.0.4)
|
http-cookie (1.0.5)
|
||||||
domain_name (~> 0.5)
|
domain_name (~> 0.5)
|
||||||
httpclient (2.8.3)
|
httpclient (2.8.3)
|
||||||
jmespath (1.6.1)
|
jmespath (1.6.1)
|
||||||
json (2.6.1)
|
json (2.6.2)
|
||||||
jwt (2.3.0)
|
jwt (2.4.1)
|
||||||
memoist (0.16.2)
|
memoist (0.16.2)
|
||||||
mini_magick (4.11.0)
|
mini_magick (4.11.0)
|
||||||
mini_mime (1.1.2)
|
mini_mime (1.1.2)
|
||||||
@ -169,10 +169,10 @@ GEM
|
|||||||
optparse (0.1.1)
|
optparse (0.1.1)
|
||||||
os (1.1.4)
|
os (1.1.4)
|
||||||
plist (3.6.0)
|
plist (3.6.0)
|
||||||
public_suffix (4.0.6)
|
public_suffix (4.0.7)
|
||||||
racc (1.6.0)
|
racc (1.6.0)
|
||||||
rake (13.0.6)
|
rake (13.0.6)
|
||||||
representable (3.1.1)
|
representable (3.2.0)
|
||||||
declarative (< 0.1.0)
|
declarative (< 0.1.0)
|
||||||
trailblazer-option (>= 0.1.1, < 0.2.0)
|
trailblazer-option (>= 0.1.1, < 0.2.0)
|
||||||
uber (< 0.2.0)
|
uber (< 0.2.0)
|
||||||
@ -182,9 +182,9 @@ GEM
|
|||||||
ruby2_keywords (0.0.5)
|
ruby2_keywords (0.0.5)
|
||||||
rubyzip (2.3.2)
|
rubyzip (2.3.2)
|
||||||
security (0.1.3)
|
security (0.1.3)
|
||||||
signet (0.16.1)
|
signet (0.17.0)
|
||||||
addressable (~> 2.8)
|
addressable (~> 2.8)
|
||||||
faraday (>= 0.17.5, < 3.0)
|
faraday (>= 0.17.5, < 3.a)
|
||||||
jwt (>= 1.5, < 3.0)
|
jwt (>= 1.5, < 3.0)
|
||||||
multi_json (~> 1.10)
|
multi_json (~> 1.10)
|
||||||
simctl (1.6.8)
|
simctl (1.6.8)
|
||||||
@ -205,11 +205,11 @@ GEM
|
|||||||
uber (0.1.0)
|
uber (0.1.0)
|
||||||
unf (0.1.4)
|
unf (0.1.4)
|
||||||
unf_ext
|
unf_ext
|
||||||
unf_ext (0.0.8.1)
|
unf_ext (0.0.8.2)
|
||||||
unicode-display_width (1.8.0)
|
unicode-display_width (1.8.0)
|
||||||
webrick (1.7.0)
|
webrick (1.7.0)
|
||||||
word_wrap (1.0.0)
|
word_wrap (1.0.0)
|
||||||
xcodeproj (1.21.0)
|
xcodeproj (1.22.0)
|
||||||
CFPropertyList (>= 2.3.3, < 4.0)
|
CFPropertyList (>= 2.3.3, < 4.0)
|
||||||
atomos (~> 0.1.3)
|
atomos (~> 0.1.3)
|
||||||
claide (>= 1.0.2, < 2.0)
|
claide (>= 1.0.2, < 2.0)
|
||||||
|
@ -51,8 +51,8 @@
|
|||||||
<Reference Include="Java.Interop" />
|
<Reference Include="Java.Interop" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.616.0" />
|
<PackageReference Include="ppy.osu.Game.Resources" Version="2022.628.0" />
|
||||||
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.615.0" />
|
<PackageReference Include="ppy.osu.Framework.Android" Version="2022.628.1" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup Label="Transitive Dependencies">
|
<ItemGroup Label="Transitive Dependencies">
|
||||||
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
<!-- Realm needs to be directly referenced in all Xamarin projects, as it will not pull in its transitive dependencies otherwise. -->
|
||||||
|
@ -57,7 +57,7 @@ namespace osu.Desktop
|
|||||||
client.OnReady += onReady;
|
client.OnReady += onReady;
|
||||||
|
|
||||||
// safety measure for now, until we performance test / improve backoff for failed connections.
|
// safety measure for now, until we performance test / improve backoff for failed connections.
|
||||||
client.OnConnectionFailed += (_, __) => client.Deinitialize();
|
client.OnConnectionFailed += (_, _) => client.Deinitialize();
|
||||||
|
|
||||||
client.OnError += (_, e) => Logger.Log($"An error occurred with Discord RPC Client: {e.Code} {e.Message}", LoggingTarget.Network);
|
client.OnError += (_, e) => Logger.Log($"An error occurred with Discord RPC Client: {e.Code} {e.Message}", LoggingTarget.Network);
|
||||||
|
|
||||||
|
@ -129,18 +129,18 @@ namespace osu.Desktop
|
|||||||
[SupportedOSPlatform("windows")]
|
[SupportedOSPlatform("windows")]
|
||||||
private static void setupSquirrel()
|
private static void setupSquirrel()
|
||||||
{
|
{
|
||||||
SquirrelAwareApp.HandleEvents(onInitialInstall: (version, tools) =>
|
SquirrelAwareApp.HandleEvents(onInitialInstall: (_, tools) =>
|
||||||
{
|
{
|
||||||
tools.CreateShortcutForThisExe();
|
tools.CreateShortcutForThisExe();
|
||||||
tools.CreateUninstallerRegistryEntry();
|
tools.CreateUninstallerRegistryEntry();
|
||||||
}, onAppUpdate: (version, tools) =>
|
}, onAppUpdate: (_, tools) =>
|
||||||
{
|
{
|
||||||
tools.CreateUninstallerRegistryEntry();
|
tools.CreateUninstallerRegistryEntry();
|
||||||
}, onAppUninstall: (version, tools) =>
|
}, onAppUninstall: (_, tools) =>
|
||||||
{
|
{
|
||||||
tools.RemoveShortcutForThisExe();
|
tools.RemoveShortcutForThisExe();
|
||||||
tools.RemoveUninstallerRegistryEntry();
|
tools.RemoveUninstallerRegistryEntry();
|
||||||
}, onEveryRun: (version, tools, firstRun) =>
|
}, onEveryRun: (_, _, _) =>
|
||||||
{
|
{
|
||||||
// While setting the `ProcessAppUserModelId` fixes duplicate icons/shortcuts on the taskbar, it currently
|
// While setting the `ProcessAppUserModelId` fixes duplicate icons/shortcuts on the taskbar, it currently
|
||||||
// causes the right-click context menu to function incorrectly.
|
// causes the right-click context menu to function incorrectly.
|
||||||
|
@ -31,7 +31,7 @@ namespace osu.Game.Benchmarks
|
|||||||
|
|
||||||
realm = new RealmAccess(storage, OsuGameBase.CLIENT_DATABASE_FILENAME);
|
realm = new RealmAccess(storage, OsuGameBase.CLIENT_DATABASE_FILENAME);
|
||||||
|
|
||||||
realm.Run(r =>
|
realm.Run(_ =>
|
||||||
{
|
{
|
||||||
realm.Write(c => c.Add(TestResources.CreateTestBeatmapSetInfo(rulesets: new[] { new OsuRuleset().RulesetInfo })));
|
realm.Write(c => c.Add(TestResources.CreateTestBeatmapSetInfo(rulesets: new[] { new OsuRuleset().RulesetInfo })));
|
||||||
});
|
});
|
||||||
@ -76,7 +76,7 @@ namespace osu.Game.Benchmarks
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
done.Wait();
|
done.Wait(60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
[Benchmark]
|
||||||
@ -115,7 +115,7 @@ namespace osu.Game.Benchmarks
|
|||||||
}
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
done.Wait();
|
done.Wait(60000);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Benchmark]
|
[Benchmark]
|
||||||
|
@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
new JuiceStreamPathVertex(20, -5)
|
new JuiceStreamPathVertex(20, -5)
|
||||||
}));
|
}));
|
||||||
|
|
||||||
removeCount = path.RemoveVertices((_, i) => true);
|
removeCount = path.RemoveVertices((_, _) => true);
|
||||||
Assert.That(removeCount, Is.EqualTo(1));
|
Assert.That(removeCount, Is.EqualTo(1));
|
||||||
Assert.That(path.Vertices, Is.EqualTo(new[]
|
Assert.That(path.Vertices, Is.EqualTo(new[]
|
||||||
{
|
{
|
||||||
|
@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
AddStep("change component scale", () => Player.ChildrenOfType<LegacyScoreCounter>().First().Scale = new Vector2(2f));
|
AddStep("change component scale", () => Player.ChildrenOfType<LegacyScoreCounter>().First().Scale = new Vector2(2f));
|
||||||
AddStep("update target", () => Player.ChildrenOfType<SkinnableTargetContainer>().ForEach(LegacySkin.UpdateDrawableTarget));
|
AddStep("update target", () => Player.ChildrenOfType<SkinnableTargetContainer>().ForEach(LegacySkin.UpdateDrawableTarget));
|
||||||
AddStep("exit player", () => Player.Exit());
|
AddStep("exit player", () => Player.Exit());
|
||||||
CreateTest(null);
|
CreateTest();
|
||||||
}
|
}
|
||||||
|
|
||||||
AddAssert("legacy HUD combo counter hidden", () =>
|
AddAssert("legacy HUD combo counter hidden", () =>
|
||||||
|
@ -33,7 +33,7 @@ namespace osu.Game.Rulesets.Catch.Tests
|
|||||||
hyperDashCount = 0;
|
hyperDashCount = 0;
|
||||||
|
|
||||||
// this needs to be done within the frame stable context due to how quickly hyperdash state changes occur.
|
// this needs to be done within the frame stable context due to how quickly hyperdash state changes occur.
|
||||||
Player.DrawableRuleset.FrameStableComponents.OnUpdate += d =>
|
Player.DrawableRuleset.FrameStableComponents.OnUpdate += _ =>
|
||||||
{
|
{
|
||||||
var catcher = Player.ChildrenOfType<Catcher>().FirstOrDefault();
|
var catcher = Player.ChildrenOfType<Catcher>().FirstOrDefault();
|
||||||
|
|
||||||
|
@ -16,6 +16,6 @@ namespace osu.Game.Rulesets.Catch
|
|||||||
|
|
||||||
protected override string RulesetPrefix => "catch"; // todo: use CatchRuleset.SHORT_NAME;
|
protected override string RulesetPrefix => "catch"; // todo: use CatchRuleset.SHORT_NAME;
|
||||||
|
|
||||||
protected override string ComponentName => Component.ToString().ToLower();
|
protected override string ComponentName => Component.ToString().ToLowerInvariant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Catch.Difficulty
|
namespace osu.Game.Rulesets.Catch.Difficulty
|
||||||
@ -31,9 +30,9 @@ namespace osu.Game.Rulesets.Catch.Difficulty
|
|||||||
yield return (ATTRIB_ID_MAX_COMBO, MaxCombo);
|
yield return (ATTRIB_ID_MAX_COMBO, MaxCombo);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values)
|
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo)
|
||||||
{
|
{
|
||||||
base.FromDatabaseAttributes(values);
|
base.FromDatabaseAttributes(values, onlineInfo);
|
||||||
|
|
||||||
StarRating = values[ATTRIB_ID_AIM];
|
StarRating = values[ATTRIB_ID_AIM];
|
||||||
ApproachRate = values[ATTRIB_ID_APPROACH_RATE];
|
ApproachRate = values[ATTRIB_ID_APPROACH_RATE];
|
||||||
|
@ -135,15 +135,15 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
{
|
{
|
||||||
switch (BlueprintContainer.CurrentTool)
|
switch (BlueprintContainer.CurrentTool)
|
||||||
{
|
{
|
||||||
case SelectTool _:
|
case SelectTool:
|
||||||
if (EditorBeatmap.SelectedHitObjects.Count == 0)
|
if (EditorBeatmap.SelectedHitObjects.Count == 0)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
double minTime = EditorBeatmap.SelectedHitObjects.Min(hitObject => hitObject.StartTime);
|
double minTime = EditorBeatmap.SelectedHitObjects.Min(hitObject => hitObject.StartTime);
|
||||||
return getLastSnappableHitObject(minTime);
|
return getLastSnappableHitObject(minTime);
|
||||||
|
|
||||||
case FruitCompositionTool _:
|
case FruitCompositionTool:
|
||||||
case JuiceStreamCompositionTool _:
|
case JuiceStreamCompositionTool:
|
||||||
if (!CursorInPlacementArea)
|
if (!CursorInPlacementArea)
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
|
@ -42,10 +42,10 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
case Droplet droplet:
|
case Droplet droplet:
|
||||||
return droplet is TinyDroplet ? PositionRange.EMPTY : new PositionRange(droplet.OriginalX);
|
return droplet is TinyDroplet ? PositionRange.EMPTY : new PositionRange(droplet.OriginalX);
|
||||||
|
|
||||||
case JuiceStream _:
|
case JuiceStream:
|
||||||
return GetPositionRange(hitObject.NestedHitObjects);
|
return GetPositionRange(hitObject.NestedHitObjects);
|
||||||
|
|
||||||
case BananaShower _:
|
case BananaShower:
|
||||||
// A banana shower occupies the whole screen width.
|
// A banana shower occupies the whole screen width.
|
||||||
return new PositionRange(0, CatchPlayfield.WIDTH);
|
return new PositionRange(0, CatchPlayfield.WIDTH);
|
||||||
|
|
||||||
|
@ -131,7 +131,7 @@ namespace osu.Game.Rulesets.Catch.Edit
|
|||||||
{
|
{
|
||||||
switch (hitObject)
|
switch (hitObject)
|
||||||
{
|
{
|
||||||
case BananaShower _:
|
case BananaShower:
|
||||||
return false;
|
return false;
|
||||||
|
|
||||||
case JuiceStream juiceStream:
|
case JuiceStream juiceStream:
|
||||||
|
@ -389,13 +389,13 @@ namespace osu.Game.Rulesets.Catch.UI
|
|||||||
{
|
{
|
||||||
switch (source)
|
switch (source)
|
||||||
{
|
{
|
||||||
case Fruit _:
|
case Fruit:
|
||||||
return caughtFruitPool.Get();
|
return caughtFruitPool.Get();
|
||||||
|
|
||||||
case Banana _:
|
case Banana:
|
||||||
return caughtBananaPool.Get();
|
return caughtBananaPool.Get();
|
||||||
|
|
||||||
case Droplet _:
|
case Droplet:
|
||||||
return caughtDropletPool.Get();
|
return caughtDropletPool.Get();
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -173,7 +173,7 @@ namespace osu.Game.Rulesets.Mania.Beatmaps
|
|||||||
|
|
||||||
switch (original)
|
switch (original)
|
||||||
{
|
{
|
||||||
case IHasDistance _:
|
case IHasDistance:
|
||||||
{
|
{
|
||||||
var generator = new DistanceObjectPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap);
|
var generator = new DistanceObjectPatternGenerator(Random, original, beatmap, lastPattern, originalBeatmap);
|
||||||
conversion = generator;
|
conversion = generator;
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Mania.Difficulty
|
namespace osu.Game.Rulesets.Mania.Difficulty
|
||||||
@ -37,9 +36,9 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
|||||||
yield return (ATTRIB_ID_SCORE_MULTIPLIER, ScoreMultiplier);
|
yield return (ATTRIB_ID_SCORE_MULTIPLIER, ScoreMultiplier);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values)
|
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo)
|
||||||
{
|
{
|
||||||
base.FromDatabaseAttributes(values);
|
base.FromDatabaseAttributes(values, onlineInfo);
|
||||||
|
|
||||||
MaxCombo = (int)values[ATTRIB_ID_MAX_COMBO];
|
MaxCombo = (int)values[ATTRIB_ID_MAX_COMBO];
|
||||||
StarRating = values[ATTRIB_ID_DIFFICULTY];
|
StarRating = values[ATTRIB_ID_DIFFICULTY];
|
||||||
|
@ -156,9 +156,9 @@ namespace osu.Game.Rulesets.Mania.Difficulty
|
|||||||
{
|
{
|
||||||
switch (m)
|
switch (m)
|
||||||
{
|
{
|
||||||
case ManiaModNoFail _:
|
case ManiaModNoFail:
|
||||||
case ManiaModEasy _:
|
case ManiaModEasy:
|
||||||
case ManiaModHalfTime _:
|
case ManiaModHalfTime:
|
||||||
scoreMultiplier *= 0.5;
|
scoreMultiplier *= 0.5;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -146,56 +146,56 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
{
|
{
|
||||||
switch (mod)
|
switch (mod)
|
||||||
{
|
{
|
||||||
case ManiaModKey1 _:
|
case ManiaModKey1:
|
||||||
value |= LegacyMods.Key1;
|
value |= LegacyMods.Key1;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModKey2 _:
|
case ManiaModKey2:
|
||||||
value |= LegacyMods.Key2;
|
value |= LegacyMods.Key2;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModKey3 _:
|
case ManiaModKey3:
|
||||||
value |= LegacyMods.Key3;
|
value |= LegacyMods.Key3;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModKey4 _:
|
case ManiaModKey4:
|
||||||
value |= LegacyMods.Key4;
|
value |= LegacyMods.Key4;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModKey5 _:
|
case ManiaModKey5:
|
||||||
value |= LegacyMods.Key5;
|
value |= LegacyMods.Key5;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModKey6 _:
|
case ManiaModKey6:
|
||||||
value |= LegacyMods.Key6;
|
value |= LegacyMods.Key6;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModKey7 _:
|
case ManiaModKey7:
|
||||||
value |= LegacyMods.Key7;
|
value |= LegacyMods.Key7;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModKey8 _:
|
case ManiaModKey8:
|
||||||
value |= LegacyMods.Key8;
|
value |= LegacyMods.Key8;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModKey9 _:
|
case ManiaModKey9:
|
||||||
value |= LegacyMods.Key9;
|
value |= LegacyMods.Key9;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModDualStages _:
|
case ManiaModDualStages:
|
||||||
value |= LegacyMods.KeyCoop;
|
value |= LegacyMods.KeyCoop;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModFadeIn _:
|
case ManiaModFadeIn:
|
||||||
value |= LegacyMods.FadeIn;
|
value |= LegacyMods.FadeIn;
|
||||||
value &= ~LegacyMods.Hidden; // this is toggled on in the base call due to inheritance, but we don't want that.
|
value &= ~LegacyMods.Hidden; // this is toggled on in the base call due to inheritance, but we don't want that.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModMirror _:
|
case ManiaModMirror:
|
||||||
value |= LegacyMods.Mirror;
|
value |= LegacyMods.Mirror;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaModRandom _:
|
case ManiaModRandom:
|
||||||
value |= LegacyMods.Random;
|
value |= LegacyMods.Random;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania
|
|||||||
|
|
||||||
protected override string RulesetPrefix => ManiaRuleset.SHORT_NAME;
|
protected override string RulesetPrefix => ManiaRuleset.SHORT_NAME;
|
||||||
|
|
||||||
protected override string ComponentName => Component.ToString().ToLower();
|
protected override string ComponentName => Component.ToString().ToLowerInvariant();
|
||||||
}
|
}
|
||||||
|
|
||||||
public enum ManiaSkinComponents
|
public enum ManiaSkinComponents
|
||||||
|
@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Mania.Mods
|
|||||||
var rng = new Random((int)Seed.Value);
|
var rng = new Random((int)Seed.Value);
|
||||||
|
|
||||||
int availableColumns = ((ManiaBeatmap)beatmap).TotalColumns;
|
int availableColumns = ((ManiaBeatmap)beatmap).TotalColumns;
|
||||||
var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(item => rng.Next()).ToList();
|
var shuffledColumns = Enumerable.Range(0, availableColumns).OrderBy(_ => rng.Next()).ToList();
|
||||||
|
|
||||||
beatmap.HitObjects.OfType<ManiaHitObject>().ForEach(h => h.Column = shuffledColumns[h.Column]);
|
beatmap.HitObjects.OfType<ManiaHitObject>().ForEach(h => h.Column = shuffledColumns[h.Column]);
|
||||||
}
|
}
|
||||||
|
@ -57,11 +57,11 @@ namespace osu.Game.Rulesets.Mania.Replays
|
|||||||
{
|
{
|
||||||
switch (point)
|
switch (point)
|
||||||
{
|
{
|
||||||
case HitPoint _:
|
case HitPoint:
|
||||||
actions.Add(columnActions[point.Column]);
|
actions.Add(columnActions[point.Column]);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ReleasePoint _:
|
case ReleasePoint:
|
||||||
actions.Remove(columnActions[point.Column]);
|
actions.Remove(columnActions[point.Column]);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -10,7 +10,6 @@ using osu.Framework.Input;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Framework.Utils;
|
using osu.Framework.Utils;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Edit;
|
|
||||||
using osu.Game.Rulesets.Osu.Objects;
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
using osu.Game.Rulesets.UI;
|
using osu.Game.Rulesets.UI;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
@ -41,10 +40,6 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
|
|
||||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset, false);
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset, false);
|
||||||
|
|
||||||
private bool editorComponentsReady => editor.ChildrenOfType<HitObjectComposer>().FirstOrDefault()?.IsLoaded == true
|
|
||||||
&& editor.ChildrenOfType<TimelineArea>().FirstOrDefault()?.IsLoaded == true
|
|
||||||
&& editor?.ChildrenOfType<Playfield>().FirstOrDefault()?.IsLoaded == true;
|
|
||||||
|
|
||||||
[TestCase(true)]
|
[TestCase(true)]
|
||||||
[TestCase(false)]
|
[TestCase(false)]
|
||||||
public void TestVelocityChangeSavesCorrectly(bool adjustVelocity)
|
public void TestVelocityChangeSavesCorrectly(bool adjustVelocity)
|
||||||
@ -52,7 +47,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
double? velocity = null;
|
double? velocity = null;
|
||||||
|
|
||||||
AddStep("enter editor", () => Game.ScreenStack.Push(new EditorLoader()));
|
AddStep("enter editor", () => Game.ScreenStack.Push(new EditorLoader()));
|
||||||
AddUntilStep("wait for editor load", () => editorComponentsReady);
|
AddUntilStep("wait for editor load", () => editor?.ReadyForUse == true);
|
||||||
|
|
||||||
AddStep("seek to first control point", () => editorClock.Seek(editorBeatmap.ControlPointInfo.TimingPoints.First().Time));
|
AddStep("seek to first control point", () => editorClock.Seek(editorBeatmap.ControlPointInfo.TimingPoints.First().Time));
|
||||||
AddStep("enter slider placement mode", () => InputManager.Key(Key.Number3));
|
AddStep("enter slider placement mode", () => InputManager.Key(Key.Number3));
|
||||||
@ -91,7 +86,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor
|
|||||||
AddStep("exit", () => InputManager.Key(Key.Escape));
|
AddStep("exit", () => InputManager.Key(Key.Escape));
|
||||||
|
|
||||||
AddStep("enter editor (again)", () => Game.ScreenStack.Push(new EditorLoader()));
|
AddStep("enter editor (again)", () => Game.ScreenStack.Push(new EditorLoader()));
|
||||||
AddUntilStep("wait for editor load", () => editorComponentsReady);
|
AddUntilStep("wait for editor load", () => editor?.ReadyForUse == true);
|
||||||
|
|
||||||
AddStep("seek to slider", () => editorClock.Seek(slider.StartTime));
|
AddStep("seek to slider", () => editorClock.Seek(slider.StartTime));
|
||||||
AddAssert("slider has correct velocity", () => slider.Velocity == velocity);
|
AddAssert("slider has correct velocity", () => slider.Velocity == velocity);
|
||||||
|
@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
skin.Setup(s => s.GetTexture(It.IsAny<string>())).CallBase();
|
skin.Setup(s => s.GetTexture(It.IsAny<string>())).CallBase();
|
||||||
|
|
||||||
skin.Setup(s => s.GetTexture(It.IsIn(textureFilenames), It.IsAny<WrapMode>(), It.IsAny<WrapMode>()))
|
skin.Setup(s => s.GetTexture(It.IsIn(textureFilenames), It.IsAny<WrapMode>(), It.IsAny<WrapMode>()))
|
||||||
.Returns((string componentName, WrapMode _, WrapMode __) => new Texture(1, 1) { AssetName = componentName });
|
.Returns((string componentName, WrapMode _, WrapMode _) => new Texture(1, 1) { AssetName = componentName });
|
||||||
|
|
||||||
Child = new DependencyProvidingContainer
|
Child = new DependencyProvidingContainer
|
||||||
{
|
{
|
||||||
|
@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
|
|||||||
lastResult = null;
|
lastResult = null;
|
||||||
|
|
||||||
spinner = nextSpinner;
|
spinner = nextSpinner;
|
||||||
spinner.OnNewResult += (o, result) => lastResult = result;
|
spinner.OnNewResult += (_, result) => lastResult = result;
|
||||||
}
|
}
|
||||||
|
|
||||||
return lastResult?.Type == HitResult.Great;
|
return lastResult?.Type == HitResult.Great;
|
||||||
@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Mods
|
|||||||
return false;
|
return false;
|
||||||
|
|
||||||
spinner = nextSpinner;
|
spinner = nextSpinner;
|
||||||
spinner.OnNewResult += (o, result) => results.Add(result);
|
spinner.OnNewResult += (_, result) => results.Add(result);
|
||||||
|
|
||||||
results.Clear();
|
results.Clear();
|
||||||
}
|
}
|
||||||
|
120
osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs
Normal file
120
osu.Game.Rulesets.Osu.Tests/TestSceneSliderFollowCircleInput.cs
Normal file
@ -0,0 +1,120 @@
|
|||||||
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
|
using System.Collections.Generic;
|
||||||
|
using System.Linq;
|
||||||
|
using NUnit.Framework;
|
||||||
|
using osu.Framework.Screens;
|
||||||
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
|
using osu.Game.Beatmaps.ControlPoints;
|
||||||
|
using osu.Game.Replays;
|
||||||
|
using osu.Game.Rulesets.Judgements;
|
||||||
|
using osu.Game.Rulesets.Objects;
|
||||||
|
using osu.Game.Rulesets.Objects.Types;
|
||||||
|
using osu.Game.Rulesets.Osu.Objects;
|
||||||
|
using osu.Game.Rulesets.Osu.Replays;
|
||||||
|
using osu.Game.Rulesets.Replays;
|
||||||
|
using osu.Game.Rulesets.Scoring;
|
||||||
|
using osu.Game.Scoring;
|
||||||
|
using osu.Game.Screens.Play;
|
||||||
|
using osu.Game.Tests.Visual;
|
||||||
|
using osuTK;
|
||||||
|
|
||||||
|
namespace osu.Game.Rulesets.Osu.Tests
|
||||||
|
{
|
||||||
|
[HeadlessTest]
|
||||||
|
public class TestSceneSliderFollowCircleInput : RateAdjustedBeatmapTestScene
|
||||||
|
{
|
||||||
|
private List<JudgementResult>? judgementResults;
|
||||||
|
private ScoreAccessibleReplayPlayer? currentPlayer;
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestMaximumDistanceTrackingWithoutMovement(
|
||||||
|
[Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)]
|
||||||
|
float circleSize,
|
||||||
|
[Values(0, 1, 2, 3, 4, 5, 6, 7, 8, 9, 10)]
|
||||||
|
double velocity)
|
||||||
|
{
|
||||||
|
const double time_slider_start = 1000;
|
||||||
|
|
||||||
|
float circleRadius = OsuHitObject.OBJECT_RADIUS * (1.0f - 0.7f * (circleSize - 5) / 5) / 2;
|
||||||
|
float followCircleRadius = circleRadius * 1.2f;
|
||||||
|
|
||||||
|
performTest(new Beatmap<OsuHitObject>
|
||||||
|
{
|
||||||
|
HitObjects =
|
||||||
|
{
|
||||||
|
new Slider
|
||||||
|
{
|
||||||
|
StartTime = time_slider_start,
|
||||||
|
Position = new Vector2(0, 0),
|
||||||
|
DifficultyControlPoint = new DifficultyControlPoint { SliderVelocity = velocity },
|
||||||
|
Path = new SliderPath(PathType.Linear, new[]
|
||||||
|
{
|
||||||
|
Vector2.Zero,
|
||||||
|
new Vector2(followCircleRadius, 0),
|
||||||
|
}, followCircleRadius),
|
||||||
|
},
|
||||||
|
},
|
||||||
|
BeatmapInfo =
|
||||||
|
{
|
||||||
|
Difficulty = new BeatmapDifficulty
|
||||||
|
{
|
||||||
|
CircleSize = circleSize,
|
||||||
|
SliderTickRate = 1
|
||||||
|
},
|
||||||
|
Ruleset = new OsuRuleset().RulesetInfo
|
||||||
|
},
|
||||||
|
}, new List<ReplayFrame>
|
||||||
|
{
|
||||||
|
new OsuReplayFrame { Position = new Vector2(-circleRadius + 1, 0), Actions = { OsuAction.LeftButton }, Time = time_slider_start },
|
||||||
|
});
|
||||||
|
|
||||||
|
AddAssert("Tracking kept", assertMaxJudge);
|
||||||
|
}
|
||||||
|
|
||||||
|
private bool assertMaxJudge() => judgementResults?.Any() == true && judgementResults.All(t => t.Type == t.Judgement.MaxResult);
|
||||||
|
|
||||||
|
private void performTest(Beatmap<OsuHitObject> beatmap, List<ReplayFrame> frames)
|
||||||
|
{
|
||||||
|
AddStep("load player", () =>
|
||||||
|
{
|
||||||
|
Beatmap.Value = CreateWorkingBeatmap(beatmap);
|
||||||
|
|
||||||
|
var p = new ScoreAccessibleReplayPlayer(new Score { Replay = new Replay { Frames = frames } });
|
||||||
|
|
||||||
|
p.OnLoadComplete += _ =>
|
||||||
|
{
|
||||||
|
p.ScoreProcessor.NewJudgement += result =>
|
||||||
|
{
|
||||||
|
if (currentPlayer == p) judgementResults?.Add(result);
|
||||||
|
};
|
||||||
|
};
|
||||||
|
|
||||||
|
LoadScreen(currentPlayer = p);
|
||||||
|
judgementResults = new List<JudgementResult>();
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("Beatmap at 0", () => Beatmap.Value.Track.CurrentTime == 0);
|
||||||
|
AddUntilStep("Wait until player is loaded", () => currentPlayer.IsCurrentScreen());
|
||||||
|
AddUntilStep("Wait for completion", () => currentPlayer?.ScoreProcessor.HasCompleted.Value == true);
|
||||||
|
}
|
||||||
|
|
||||||
|
private class ScoreAccessibleReplayPlayer : ReplayPlayer
|
||||||
|
{
|
||||||
|
public new ScoreProcessor ScoreProcessor => base.ScoreProcessor;
|
||||||
|
|
||||||
|
protected override bool PauseOnFocusLost => false;
|
||||||
|
|
||||||
|
public ScoreAccessibleReplayPlayer(Score score)
|
||||||
|
: base(score, new PlayerConfiguration
|
||||||
|
{
|
||||||
|
AllowPause = false,
|
||||||
|
ShowResults = false,
|
||||||
|
})
|
||||||
|
{
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
@ -66,10 +66,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
drawableSlider = null;
|
drawableSlider = null;
|
||||||
});
|
});
|
||||||
|
|
||||||
[SetUpSteps]
|
protected override bool HasCustomSteps => true;
|
||||||
public override void SetUpSteps()
|
|
||||||
{
|
|
||||||
}
|
|
||||||
|
|
||||||
[TestCase(0)]
|
[TestCase(0)]
|
||||||
[TestCase(1)]
|
[TestCase(1)]
|
||||||
@ -77,7 +74,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
public void TestSnakingEnabled(int sliderIndex)
|
public void TestSnakingEnabled(int sliderIndex)
|
||||||
{
|
{
|
||||||
AddStep("enable autoplay", () => autoplay = true);
|
AddStep("enable autoplay", () => autoplay = true);
|
||||||
base.SetUpSteps();
|
CreateTest();
|
||||||
AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning);
|
AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning);
|
||||||
|
|
||||||
retrieveSlider(sliderIndex);
|
retrieveSlider(sliderIndex);
|
||||||
@ -101,7 +98,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
public void TestSnakingDisabled(int sliderIndex)
|
public void TestSnakingDisabled(int sliderIndex)
|
||||||
{
|
{
|
||||||
AddStep("have autoplay", () => autoplay = true);
|
AddStep("have autoplay", () => autoplay = true);
|
||||||
base.SetUpSteps();
|
CreateTest();
|
||||||
AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning);
|
AddUntilStep("wait for track to start running", () => Beatmap.Value.Track.IsRunning);
|
||||||
|
|
||||||
retrieveSlider(sliderIndex);
|
retrieveSlider(sliderIndex);
|
||||||
@ -121,8 +118,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
AddStep("enable autoplay", () => autoplay = true);
|
AddStep("enable autoplay", () => autoplay = true);
|
||||||
setSnaking(true);
|
setSnaking(true);
|
||||||
base.SetUpSteps();
|
CreateTest();
|
||||||
|
|
||||||
// repeat might have a chance to update its position depending on where in the frame its hit,
|
// repeat might have a chance to update its position depending on where in the frame its hit,
|
||||||
// so some leniency is allowed here instead of checking strict equality
|
// so some leniency is allowed here instead of checking strict equality
|
||||||
addCheckPositionChangeSteps(() => 16600, getSliderRepeat, positionAlmostSame);
|
addCheckPositionChangeSteps(() => 16600, getSliderRepeat, positionAlmostSame);
|
||||||
@ -133,15 +129,14 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
{
|
{
|
||||||
AddStep("disable autoplay", () => autoplay = false);
|
AddStep("disable autoplay", () => autoplay = false);
|
||||||
setSnaking(true);
|
setSnaking(true);
|
||||||
base.SetUpSteps();
|
CreateTest();
|
||||||
|
|
||||||
addCheckPositionChangeSteps(() => 16600, getSliderRepeat, positionDecreased);
|
addCheckPositionChangeSteps(() => 16600, getSliderRepeat, positionDecreased);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void retrieveSlider(int index)
|
private void retrieveSlider(int index)
|
||||||
{
|
{
|
||||||
AddStep("retrieve slider at index", () => slider = (Slider)beatmap.HitObjects[index]);
|
AddStep("retrieve slider at index", () => slider = (Slider)beatmap.HitObjects[index]);
|
||||||
addSeekStep(() => slider);
|
addSeekStep(() => slider.StartTime);
|
||||||
AddUntilStep("retrieve drawable slider", () =>
|
AddUntilStep("retrieve drawable slider", () =>
|
||||||
(drawableSlider = (DrawableSlider)Player.DrawableRuleset.Playfield.AllHitObjects.SingleOrDefault(d => d.HitObject == slider)) != null);
|
(drawableSlider = (DrawableSlider)Player.DrawableRuleset.Playfield.AllHitObjects.SingleOrDefault(d => d.HitObject == slider)) != null);
|
||||||
}
|
}
|
||||||
@ -161,7 +156,7 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
=> addCheckPositionChangeSteps(timeAtRepeat(startTime, repeatIndex), positionAtRepeat(repeatIndex), positionRemainsSame);
|
=> addCheckPositionChangeSteps(timeAtRepeat(startTime, repeatIndex), positionAtRepeat(repeatIndex), positionRemainsSame);
|
||||||
|
|
||||||
private Func<double> timeAtRepeat(Func<double> startTime, int repeatIndex) => () => startTime() + 100 + duration_of_span * repeatIndex;
|
private Func<double> timeAtRepeat(Func<double> startTime, int repeatIndex) => () => startTime() + 100 + duration_of_span * repeatIndex;
|
||||||
private Func<Vector2> positionAtRepeat(int repeatIndex) => repeatIndex % 2 == 0 ? (Func<Vector2>)getSliderStart : getSliderEnd;
|
private Func<Vector2> positionAtRepeat(int repeatIndex) => repeatIndex % 2 == 0 ? getSliderStart : getSliderEnd;
|
||||||
|
|
||||||
private List<Vector2> getSliderCurve() => ((PlaySliderBody)drawableSlider.Body.Drawable).CurrentCurve;
|
private List<Vector2> getSliderCurve() => ((PlaySliderBody)drawableSlider.Body.Drawable).CurrentCurve;
|
||||||
private Vector2 getSliderStart() => getSliderCurve().First();
|
private Vector2 getSliderStart() => getSliderCurve().First();
|
||||||
@ -205,16 +200,10 @@ namespace osu.Game.Rulesets.Osu.Tests
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
private void addSeekStep(Func<Slider> slider)
|
private void addSeekStep(Func<double> getTime)
|
||||||
{
|
{
|
||||||
AddStep("seek to slider", () => Player.GameplayClockContainer.Seek(slider().StartTime));
|
AddStep("seek to time", () => Player.GameplayClockContainer.Seek(getTime()));
|
||||||
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(slider().StartTime, Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(getTime(), Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
||||||
}
|
|
||||||
|
|
||||||
private void addSeekStep(Func<double> time)
|
|
||||||
{
|
|
||||||
AddStep("seek to time", () => Player.GameplayClockContainer.Seek(time()));
|
|
||||||
AddUntilStep("wait for seek to finish", () => Precision.AlmostEquals(time(), Player.DrawableRuleset.FrameStableClock.CurrentTime, 100));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new Beatmap { HitObjects = createHitObjects() };
|
protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new Beatmap { HitObjects = createHitObjects() };
|
||||||
|
@ -1,12 +1,11 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using System.Linq;
|
using System.Linq;
|
||||||
using JetBrains.Annotations;
|
using JetBrains.Annotations;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
|
|
||||||
@ -96,9 +95,9 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
yield return (ATTRIB_ID_SLIDER_FACTOR, SliderFactor);
|
yield return (ATTRIB_ID_SLIDER_FACTOR, SliderFactor);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values)
|
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo)
|
||||||
{
|
{
|
||||||
base.FromDatabaseAttributes(values);
|
base.FromDatabaseAttributes(values, onlineInfo);
|
||||||
|
|
||||||
AimDifficulty = values[ATTRIB_ID_AIM];
|
AimDifficulty = values[ATTRIB_ID_AIM];
|
||||||
SpeedDifficulty = values[ATTRIB_ID_SPEED];
|
SpeedDifficulty = values[ATTRIB_ID_SPEED];
|
||||||
@ -108,6 +107,11 @@ namespace osu.Game.Rulesets.Osu.Difficulty
|
|||||||
StarRating = values[ATTRIB_ID_DIFFICULTY];
|
StarRating = values[ATTRIB_ID_DIFFICULTY];
|
||||||
FlashlightDifficulty = values.GetValueOrDefault(ATTRIB_ID_FLASHLIGHT);
|
FlashlightDifficulty = values.GetValueOrDefault(ATTRIB_ID_FLASHLIGHT);
|
||||||
SliderFactor = values[ATTRIB_ID_SLIDER_FACTOR];
|
SliderFactor = values[ATTRIB_ID_SLIDER_FACTOR];
|
||||||
|
|
||||||
|
DrainRate = onlineInfo.DrainRate;
|
||||||
|
HitCircleCount = onlineInfo.CircleCount;
|
||||||
|
SliderCount = onlineInfo.SliderCount;
|
||||||
|
SpinnerCount = onlineInfo.SpinnerCount;
|
||||||
}
|
}
|
||||||
|
|
||||||
#region Newtonsoft.Json implicit ShouldSerialize() methods
|
#region Newtonsoft.Json implicit ShouldSerialize() methods
|
||||||
|
@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
});
|
});
|
||||||
|
|
||||||
selectedHitObjects = EditorBeatmap.SelectedHitObjects.GetBoundCopy();
|
selectedHitObjects = EditorBeatmap.SelectedHitObjects.GetBoundCopy();
|
||||||
selectedHitObjects.CollectionChanged += (_, __) => updateDistanceSnapGrid();
|
selectedHitObjects.CollectionChanged += (_, _) => updateDistanceSnapGrid();
|
||||||
|
|
||||||
placementObject = EditorBeatmap.PlacementObject.GetBoundCopy();
|
placementObject = EditorBeatmap.PlacementObject.GetBoundCopy();
|
||||||
placementObject.ValueChanged += _ => updateDistanceSnapGrid();
|
placementObject.ValueChanged += _ => updateDistanceSnapGrid();
|
||||||
@ -204,7 +204,7 @@ namespace osu.Game.Rulesets.Osu.Edit
|
|||||||
|
|
||||||
switch (BlueprintContainer.CurrentTool)
|
switch (BlueprintContainer.CurrentTool)
|
||||||
{
|
{
|
||||||
case SelectTool _:
|
case SelectTool:
|
||||||
if (!EditorBeatmap.SelectedHitObjects.Any())
|
if (!EditorBeatmap.SelectedHitObjects.Any())
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
public void ApplyToDrawableHitObject(DrawableHitObject drawable)
|
public void ApplyToDrawableHitObject(DrawableHitObject drawable)
|
||||||
{
|
{
|
||||||
drawable.ApplyCustomUpdateState += (drawableObject, state) =>
|
drawable.ApplyCustomUpdateState += (drawableObject, _) =>
|
||||||
{
|
{
|
||||||
if (!(drawableObject is DrawableHitCircle drawableHitCircle)) return;
|
if (!(drawableObject is DrawableHitCircle drawableHitCircle)) return;
|
||||||
|
|
||||||
|
@ -30,9 +30,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
[SettingSource("Apply classic note lock", "Applies note lock to the full hit window.")]
|
[SettingSource("Apply classic note lock", "Applies note lock to the full hit window.")]
|
||||||
public Bindable<bool> ClassicNoteLock { get; } = new BindableBool(true);
|
public Bindable<bool> ClassicNoteLock { get; } = new BindableBool(true);
|
||||||
|
|
||||||
[SettingSource("Use fixed slider follow circle hit area", "Makes the slider follow circle track its final size at all times.")]
|
|
||||||
public Bindable<bool> FixedFollowCircleHitArea { get; } = new BindableBool(true);
|
|
||||||
|
|
||||||
[SettingSource("Always play a slider's tail sample", "Always plays a slider's tail sample regardless of whether it was hit or not.")]
|
[SettingSource("Always play a slider's tail sample", "Always plays a slider's tail sample regardless of whether it was hit or not.")]
|
||||||
public Bindable<bool> AlwaysPlayTailSample { get; } = new BindableBool(true);
|
public Bindable<bool> AlwaysPlayTailSample { get; } = new BindableBool(true);
|
||||||
|
|
||||||
@ -62,10 +59,6 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
switch (obj)
|
switch (obj)
|
||||||
{
|
{
|
||||||
case DrawableSlider slider:
|
|
||||||
slider.Ball.InputTracksVisualSize = !FixedFollowCircleHitArea.Value;
|
|
||||||
break;
|
|
||||||
|
|
||||||
case DrawableSliderHead head:
|
case DrawableSliderHead head:
|
||||||
head.TrackFollowCircle = !NoSliderHeadMovement.Value;
|
head.TrackFollowCircle = !NoSliderHeadMovement.Value;
|
||||||
break;
|
break;
|
||||||
|
@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
switch (drawableObject)
|
switch (drawableObject)
|
||||||
{
|
{
|
||||||
case DrawableSliderTail _:
|
case DrawableSliderTail:
|
||||||
using (drawableObject.BeginAbsoluteSequence(fadeStartTime))
|
using (drawableObject.BeginAbsoluteSequence(fadeStartTime))
|
||||||
drawableObject.FadeOut(fadeDuration);
|
drawableObject.FadeOut(fadeDuration);
|
||||||
|
|
||||||
@ -165,14 +165,14 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
|
|
||||||
switch (hitObject)
|
switch (hitObject)
|
||||||
{
|
{
|
||||||
case Slider _:
|
case Slider:
|
||||||
return (fadeOutStartTime, longFadeDuration);
|
return (fadeOutStartTime, longFadeDuration);
|
||||||
|
|
||||||
case SliderTick _:
|
case SliderTick:
|
||||||
double tickFadeOutDuration = Math.Min(hitObject.TimePreempt - DrawableSliderTick.ANIM_DURATION, 1000);
|
double tickFadeOutDuration = Math.Min(hitObject.TimePreempt - DrawableSliderTick.ANIM_DURATION, 1000);
|
||||||
return (hitObject.StartTime - tickFadeOutDuration, tickFadeOutDuration);
|
return (hitObject.StartTime - tickFadeOutDuration, tickFadeOutDuration);
|
||||||
|
|
||||||
case Spinner _:
|
case Spinner:
|
||||||
return (fadeOutStartTime + longFadeDuration, fadeOutDuration);
|
return (fadeOutStartTime + longFadeDuration, fadeOutDuration);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -44,13 +44,13 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
// apply grow effect
|
// apply grow effect
|
||||||
switch (drawable)
|
switch (drawable)
|
||||||
{
|
{
|
||||||
case DrawableSliderHead _:
|
case DrawableSliderHead:
|
||||||
case DrawableSliderTail _:
|
case DrawableSliderTail:
|
||||||
// special cases we should *not* be scaling.
|
// special cases we should *not* be scaling.
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DrawableSlider _:
|
case DrawableSlider:
|
||||||
case DrawableHitCircle _:
|
case DrawableHitCircle:
|
||||||
{
|
{
|
||||||
using (drawable.BeginAbsoluteSequence(h.StartTime - h.TimePreempt))
|
using (drawable.BeginAbsoluteSequence(h.StartTime - h.TimePreempt))
|
||||||
drawable.ScaleTo(StartScale.Value).Then().ScaleTo(EndScale, h.TimePreempt, Easing.OutSine);
|
drawable.ScaleTo(StartScale.Value).Then().ScaleTo(EndScale, h.TimePreempt, Easing.OutSine);
|
||||||
|
@ -374,7 +374,7 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
int i = 0;
|
int i = 0;
|
||||||
double currentTime = timingPoint.Time;
|
double currentTime = timingPoint.Time;
|
||||||
|
|
||||||
while (!definitelyBigger(currentTime, mapEndTime) && controlPointInfo.TimingPointAt(currentTime) == timingPoint)
|
while (!definitelyBigger(currentTime, mapEndTime) && ReferenceEquals(controlPointInfo.TimingPointAt(currentTime), timingPoint))
|
||||||
{
|
{
|
||||||
beats.Add(Math.Floor(currentTime));
|
beats.Add(Math.Floor(currentTime));
|
||||||
i++;
|
i++;
|
||||||
|
@ -34,10 +34,10 @@ namespace osu.Game.Rulesets.Osu.Mods
|
|||||||
{
|
{
|
||||||
switch (drawable)
|
switch (drawable)
|
||||||
{
|
{
|
||||||
case DrawableSliderHead _:
|
case DrawableSliderHead:
|
||||||
case DrawableSliderTail _:
|
case DrawableSliderTail:
|
||||||
case DrawableSliderTick _:
|
case DrawableSliderTick:
|
||||||
case DrawableSliderRepeat _:
|
case DrawableSliderRepeat:
|
||||||
return;
|
return;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -156,7 +156,7 @@ namespace osu.Game.Rulesets.Osu.Objects
|
|||||||
|
|
||||||
public Slider()
|
public Slider()
|
||||||
{
|
{
|
||||||
SamplesBindable.CollectionChanged += (_, __) => UpdateNestedSamples();
|
SamplesBindable.CollectionChanged += (_, _) => UpdateNestedSamples();
|
||||||
Path.Version.ValueChanged += _ => updateNestedPositions();
|
Path.Version.ValueChanged += _ => updateNestedPositions();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -120,19 +120,19 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
{
|
{
|
||||||
switch (mod)
|
switch (mod)
|
||||||
{
|
{
|
||||||
case OsuModAutopilot _:
|
case OsuModAutopilot:
|
||||||
value |= LegacyMods.Autopilot;
|
value |= LegacyMods.Autopilot;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OsuModSpunOut _:
|
case OsuModSpunOut:
|
||||||
value |= LegacyMods.SpunOut;
|
value |= LegacyMods.SpunOut;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OsuModTarget _:
|
case OsuModTarget:
|
||||||
value |= LegacyMods.Target;
|
value |= LegacyMods.Target;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case OsuModTouchDevice _:
|
case OsuModTouchDevice:
|
||||||
value |= LegacyMods.TouchDevice;
|
value |= LegacyMods.TouchDevice;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -16,6 +16,6 @@ namespace osu.Game.Rulesets.Osu
|
|||||||
|
|
||||||
protected override string RulesetPrefix => OsuRuleset.SHORT_NAME;
|
protected override string RulesetPrefix => OsuRuleset.SHORT_NAME;
|
||||||
|
|
||||||
protected override string ComponentName => Component.ToString().ToLower();
|
protected override string ComponentName => Component.ToString().ToLowerInvariant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -107,7 +107,7 @@ namespace osu.Game.Rulesets.Osu.Replays
|
|||||||
hitWindows = slider.TailCircle.HitWindows;
|
hitWindows = slider.TailCircle.HitWindows;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Spinner _:
|
case Spinner:
|
||||||
hitWindows = defaultHitWindows;
|
hitWindows = defaultHitWindows;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Osu.Scoring
|
|||||||
{
|
{
|
||||||
switch (hitObject)
|
switch (hitObject)
|
||||||
{
|
{
|
||||||
case HitCircle _:
|
case HitCircle:
|
||||||
return new OsuHitCircleJudgementResult(hitObject, judgement);
|
return new OsuHitCircleJudgementResult(hitObject, judgement);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -34,13 +34,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
|
|||||||
set => ball.Colour = value;
|
set => ball.Colour = value;
|
||||||
}
|
}
|
||||||
|
|
||||||
/// <summary>
|
|
||||||
/// Whether to track accurately to the visual size of this <see cref="SliderBall"/>.
|
|
||||||
/// If <c>false</c>, tracking will be performed at the final scale at all times.
|
|
||||||
/// </summary>
|
|
||||||
public bool InputTracksVisualSize = true;
|
|
||||||
|
|
||||||
private readonly Drawable followCircle;
|
private readonly Drawable followCircle;
|
||||||
|
private readonly Drawable fullSizeFollowCircle;
|
||||||
private readonly DrawableSlider drawableSlider;
|
private readonly DrawableSlider drawableSlider;
|
||||||
private readonly Drawable ball;
|
private readonly Drawable ball;
|
||||||
|
|
||||||
@ -62,6 +57,13 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
|
|||||||
Alpha = 0,
|
Alpha = 0,
|
||||||
Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()),
|
Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle()),
|
||||||
},
|
},
|
||||||
|
fullSizeFollowCircle = new CircularContainer
|
||||||
|
{
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Masking = true
|
||||||
|
},
|
||||||
ball = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall())
|
ball = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall())
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
@ -104,14 +106,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
|
|||||||
|
|
||||||
tracking = value;
|
tracking = value;
|
||||||
|
|
||||||
if (InputTracksVisualSize)
|
fullSizeFollowCircle.Scale = new Vector2(tracking ? 2.4f : 1f);
|
||||||
followCircle.ScaleTo(tracking ? 2.4f : 1f, 300, Easing.OutQuint);
|
|
||||||
else
|
|
||||||
{
|
|
||||||
// We need to always be tracking the final size, at both endpoints. For now, this is achieved by removing the scale duration.
|
|
||||||
followCircle.ScaleTo(tracking ? 2.4f : 1f);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
followCircle.ScaleTo(tracking ? 2.4f : 1f, 300, Easing.OutQuint);
|
||||||
followCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint);
|
followCircle.FadeTo(tracking ? 1f : 0, 300, Easing.OutQuint);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@ -170,7 +167,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
|
|||||||
// in valid time range
|
// in valid time range
|
||||||
Time.Current >= drawableSlider.HitObject.StartTime && Time.Current < drawableSlider.HitObject.EndTime &&
|
Time.Current >= drawableSlider.HitObject.StartTime && Time.Current < drawableSlider.HitObject.EndTime &&
|
||||||
// in valid position range
|
// in valid position range
|
||||||
lastScreenSpaceMousePosition.HasValue && followCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) &&
|
lastScreenSpaceMousePosition.HasValue && fullSizeFollowCircle.ReceivePositionalInputAt(lastScreenSpaceMousePosition.Value) &&
|
||||||
// valid action
|
// valid action
|
||||||
(actions?.Any(isValidTrackingAction) ?? false);
|
(actions?.Any(isValidTrackingAction) ?? false);
|
||||||
|
|
||||||
|
@ -126,7 +126,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
|
|||||||
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DrawableSpinnerBonusTick _:
|
case DrawableSpinnerBonusTick:
|
||||||
if (state == ArmedState.Hit)
|
if (state == ArmedState.Hit)
|
||||||
glow.FlashColour(Color4.White, 200);
|
glow.FlashColour(Color4.White, 200);
|
||||||
|
|
||||||
|
@ -37,7 +37,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
|
|
||||||
switch (obj)
|
switch (obj)
|
||||||
{
|
{
|
||||||
case DrawableSpinner _:
|
case DrawableSpinner:
|
||||||
continue;
|
continue;
|
||||||
|
|
||||||
case DrawableSlider slider:
|
case DrawableSlider slider:
|
||||||
|
@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.UI
|
|||||||
// note: `Slider`'s `ProxiedLayer` is added when its nested `DrawableHitCircle` is loaded.
|
// note: `Slider`'s `ProxiedLayer` is added when its nested `DrawableHitCircle` is loaded.
|
||||||
switch (drawable)
|
switch (drawable)
|
||||||
{
|
{
|
||||||
case DrawableSpinner _:
|
case DrawableSpinner:
|
||||||
spinnerProxies.Add(drawable.CreateProxy());
|
spinnerProxies.Add(drawable.CreateProxy());
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -88,11 +88,11 @@ namespace osu.Game.Rulesets.Osu.Utils
|
|||||||
|
|
||||||
switch (hitObject)
|
switch (hitObject)
|
||||||
{
|
{
|
||||||
case HitCircle _:
|
case HitCircle:
|
||||||
shift = clampHitCircleToPlayfield(current);
|
shift = clampHitCircleToPlayfield(current);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case Slider _:
|
case Slider:
|
||||||
shift = clampSliderToPlayfield(current);
|
shift = clampSliderToPlayfield(current);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
@ -144,7 +144,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
|||||||
createDrawableRuleset();
|
createDrawableRuleset();
|
||||||
|
|
||||||
assertStateAfterResult(new JudgementResult(new Swell(), new TaikoSwellJudgement()) { Type = HitResult.Great }, TaikoMascotAnimationState.Clear);
|
assertStateAfterResult(new JudgementResult(new Swell(), new TaikoSwellJudgement()) { Type = HitResult.Great }, TaikoMascotAnimationState.Clear);
|
||||||
AddUntilStep($"state reverts to {expectedStateAfterClear.ToString().ToLower()}", () => allMascotsIn(expectedStateAfterClear));
|
AddUntilStep($"state reverts to {expectedStateAfterClear.ToString().ToLowerInvariant()}", () => allMascotsIn(expectedStateAfterClear));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBeatmap(bool kiai = false)
|
private void setBeatmap(bool kiai = false)
|
||||||
@ -195,7 +195,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
|||||||
{
|
{
|
||||||
TaikoMascotAnimationState[] mascotStates = null;
|
TaikoMascotAnimationState[] mascotStates = null;
|
||||||
|
|
||||||
AddStep($"{judgementResult.Type.ToString().ToLower()} result for {judgementResult.Judgement.GetType().Name.Humanize(LetterCasing.LowerCase)}",
|
AddStep($"{judgementResult.Type.ToString().ToLowerInvariant()} result for {judgementResult.Judgement.GetType().Name.Humanize(LetterCasing.LowerCase)}",
|
||||||
() =>
|
() =>
|
||||||
{
|
{
|
||||||
applyNewResult(judgementResult);
|
applyNewResult(judgementResult);
|
||||||
@ -204,7 +204,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
|
|||||||
Schedule(() => mascotStates = animatedMascots.Select(mascot => mascot.State.Value).ToArray());
|
Schedule(() => mascotStates = animatedMascots.Select(mascot => mascot.State.Value).ToArray());
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert($"state is {expectedState.ToString().ToLower()}", () => mascotStates.All(state => state == expectedState));
|
AddAssert($"state is {expectedState.ToString().ToLowerInvariant()}", () => mascotStates.All(state => state == expectedState));
|
||||||
}
|
}
|
||||||
|
|
||||||
private void applyNewResult(JudgementResult judgementResult)
|
private void applyNewResult(JudgementResult judgementResult)
|
||||||
|
@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Taiko.Tests
|
|||||||
AddStep("Setup judgements", () =>
|
AddStep("Setup judgements", () =>
|
||||||
{
|
{
|
||||||
judged = false;
|
judged = false;
|
||||||
Player.ScoreProcessor.NewJudgement += b => judged = true;
|
Player.ScoreProcessor.NewJudgement += _ => judged = true;
|
||||||
});
|
});
|
||||||
AddUntilStep("swell judged", () => judged);
|
AddUntilStep("swell judged", () => judged);
|
||||||
AddAssert("failed", () => Player.GameplayState.HasFailed);
|
AddAssert("failed", () => Player.GameplayState.HasFailed);
|
||||||
|
@ -1,10 +1,9 @@
|
|||||||
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
|
||||||
// See the LICENCE file in the repository root for full licence text.
|
// See the LICENCE file in the repository root for full licence text.
|
||||||
|
|
||||||
#nullable disable
|
|
||||||
|
|
||||||
using System.Collections.Generic;
|
using System.Collections.Generic;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Rulesets.Difficulty;
|
using osu.Game.Rulesets.Difficulty;
|
||||||
|
|
||||||
namespace osu.Game.Rulesets.Taiko.Difficulty
|
namespace osu.Game.Rulesets.Taiko.Difficulty
|
||||||
@ -57,9 +56,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
|
|||||||
yield return (ATTRIB_ID_GREAT_HIT_WINDOW, GreatHitWindow);
|
yield return (ATTRIB_ID_GREAT_HIT_WINDOW, GreatHitWindow);
|
||||||
}
|
}
|
||||||
|
|
||||||
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values)
|
public override void FromDatabaseAttributes(IReadOnlyDictionary<int, double> values, IBeatmapOnlineInfo onlineInfo)
|
||||||
{
|
{
|
||||||
base.FromDatabaseAttributes(values);
|
base.FromDatabaseAttributes(values, onlineInfo);
|
||||||
|
|
||||||
MaxCombo = (int)values[ATTRIB_ID_MAX_COMBO];
|
MaxCombo = (int)values[ATTRIB_ID_MAX_COMBO];
|
||||||
StarRating = values[ATTRIB_ID_DIFFICULTY];
|
StarRating = values[ATTRIB_ID_DIFFICULTY];
|
||||||
|
@ -48,8 +48,8 @@ namespace osu.Game.Rulesets.Taiko.Mods
|
|||||||
{
|
{
|
||||||
switch (hitObject)
|
switch (hitObject)
|
||||||
{
|
{
|
||||||
case DrawableDrumRollTick _:
|
case DrawableDrumRollTick:
|
||||||
case DrawableHit _:
|
case DrawableHit:
|
||||||
double preempt = drawableRuleset.TimeRange.Value / drawableRuleset.ControlPointAt(hitObject.HitObject.StartTime).Multiplier;
|
double preempt = drawableRuleset.TimeRange.Value / drawableRuleset.ControlPointAt(hitObject.HitObject.StartTime).Multiplier;
|
||||||
double start = hitObject.HitObject.StartTime - preempt * fade_out_start_time;
|
double start = hitObject.HitObject.StartTime - preempt * fade_out_start_time;
|
||||||
double duration = preempt * fade_out_duration;
|
double duration = preempt * fade_out_duration;
|
||||||
|
@ -38,7 +38,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
DisplayColour.Value = Type == HitType.Centre ? COLOUR_CENTRE : COLOUR_RIM;
|
DisplayColour.Value = Type == HitType.Centre ? COLOUR_CENTRE : COLOUR_RIM;
|
||||||
});
|
});
|
||||||
|
|
||||||
SamplesBindable.BindCollectionChanged((_, __) => updateTypeFromSamples());
|
SamplesBindable.BindCollectionChanged((_, _) => updateTypeFromSamples());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTypeFromSamples()
|
private void updateTypeFromSamples()
|
||||||
|
@ -41,7 +41,7 @@ namespace osu.Game.Rulesets.Taiko.Objects
|
|||||||
protected TaikoStrongableHitObject()
|
protected TaikoStrongableHitObject()
|
||||||
{
|
{
|
||||||
IsStrongBindable.BindValueChanged(_ => updateSamplesFromType());
|
IsStrongBindable.BindValueChanged(_ => updateSamplesFromType());
|
||||||
SamplesBindable.BindCollectionChanged((_, __) => updateTypeFromSamples());
|
SamplesBindable.BindCollectionChanged((_, _) => updateTypeFromSamples());
|
||||||
}
|
}
|
||||||
|
|
||||||
private void updateTypeFromSamples()
|
private void updateTypeFromSamples()
|
||||||
|
@ -16,6 +16,6 @@ namespace osu.Game.Rulesets.Taiko
|
|||||||
|
|
||||||
protected override string RulesetPrefix => TaikoRuleset.SHORT_NAME;
|
protected override string RulesetPrefix => TaikoRuleset.SHORT_NAME;
|
||||||
|
|
||||||
protected override string ComponentName => Component.ToString().ToLower();
|
protected override string ComponentName => Component.ToString().ToLowerInvariant();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -139,10 +139,10 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
|
|
||||||
private static Texture getAnimationFrame(ISkin skin, TaikoMascotAnimationState state, int frameIndex)
|
private static Texture getAnimationFrame(ISkin skin, TaikoMascotAnimationState state, int frameIndex)
|
||||||
{
|
{
|
||||||
var texture = skin.GetTexture($"pippidon{state.ToString().ToLower()}{frameIndex}");
|
var texture = skin.GetTexture($"pippidon{state.ToString().ToLowerInvariant()}{frameIndex}");
|
||||||
|
|
||||||
if (frameIndex == 0 && texture == null)
|
if (frameIndex == 0 && texture == null)
|
||||||
texture = skin.GetTexture($"pippidon{state.ToString().ToLower()}");
|
texture = skin.GetTexture($"pippidon{state.ToString().ToLowerInvariant()}");
|
||||||
|
|
||||||
return texture;
|
return texture;
|
||||||
}
|
}
|
||||||
|
@ -245,7 +245,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
barLinePlayfield.Add(barLine);
|
barLinePlayfield.Add(barLine);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case DrawableTaikoHitObject _:
|
case DrawableTaikoHitObject:
|
||||||
base.Add(h);
|
base.Add(h);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
@ -261,7 +261,7 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
case DrawableBarLine barLine:
|
case DrawableBarLine barLine:
|
||||||
return barLinePlayfield.Remove(barLine);
|
return barLinePlayfield.Remove(barLine);
|
||||||
|
|
||||||
case DrawableTaikoHitObject _:
|
case DrawableTaikoHitObject:
|
||||||
return base.Remove(h);
|
return base.Remove(h);
|
||||||
|
|
||||||
default:
|
default:
|
||||||
@ -280,12 +280,12 @@ namespace osu.Game.Rulesets.Taiko.UI
|
|||||||
|
|
||||||
switch (result.Judgement)
|
switch (result.Judgement)
|
||||||
{
|
{
|
||||||
case TaikoStrongJudgement _:
|
case TaikoStrongJudgement:
|
||||||
if (result.IsHit)
|
if (result.IsHit)
|
||||||
hitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == ((DrawableStrongNestedHit)judgedObject).ParentHitObject)?.VisualiseSecondHit(result);
|
hitExplosionContainer.Children.FirstOrDefault(e => e.JudgedObject == ((DrawableStrongNestedHit)judgedObject).ParentHitObject)?.VisualiseSecondHit(result);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TaikoDrumRollTickJudgement _:
|
case TaikoDrumRollTickJudgement:
|
||||||
if (!result.IsHit)
|
if (!result.IsHit)
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -157,7 +157,7 @@ namespace osu.Game.Tests.Beatmaps
|
|||||||
[TestCase(8.3, DifficultyRating.ExpertPlus)]
|
[TestCase(8.3, DifficultyRating.ExpertPlus)]
|
||||||
public void TestDifficultyRatingMapping(double starRating, DifficultyRating expectedBracket)
|
public void TestDifficultyRatingMapping(double starRating, DifficultyRating expectedBracket)
|
||||||
{
|
{
|
||||||
var actualBracket = BeatmapDifficultyCache.GetDifficultyRating(starRating);
|
var actualBracket = StarDifficulty.GetDifficultyRating(starRating);
|
||||||
|
|
||||||
Assert.AreEqual(expectedBracket, actualBracket);
|
Assert.AreEqual(expectedBracket, actualBracket);
|
||||||
}
|
}
|
||||||
|
@ -99,7 +99,7 @@ namespace osu.Game.Tests.Collections.IO
|
|||||||
public async Task TestImportMalformedDatabase()
|
public async Task TestImportMalformedDatabase()
|
||||||
{
|
{
|
||||||
bool exceptionThrown = false;
|
bool exceptionThrown = false;
|
||||||
UnhandledExceptionEventHandler setException = (_, __) => exceptionThrown = true;
|
UnhandledExceptionEventHandler setException = (_, _) => exceptionThrown = true;
|
||||||
|
|
||||||
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
|
using (HeadlessGameHost host = new CleanRunHeadlessGameHost())
|
||||||
{
|
{
|
||||||
|
@ -607,6 +607,12 @@ namespace osu.Game.Tests.Database
|
|||||||
using (var outStream = File.Open(brokenTempFilename, FileMode.CreateNew))
|
using (var outStream = File.Open(brokenTempFilename, FileMode.CreateNew))
|
||||||
using (var zip = ZipArchive.Open(brokenOsz))
|
using (var zip = ZipArchive.Open(brokenOsz))
|
||||||
{
|
{
|
||||||
|
foreach (var entry in zip.Entries.ToArray())
|
||||||
|
{
|
||||||
|
if (entry.Key.EndsWith(".osu", StringComparison.InvariantCulture))
|
||||||
|
zip.RemoveEntry(entry);
|
||||||
|
}
|
||||||
|
|
||||||
zip.AddEntry("broken.osu", brokenOsu, false);
|
zip.AddEntry("broken.osu", brokenOsu, false);
|
||||||
zip.SaveTo(outStream, CompressionType.Deflate);
|
zip.SaveTo(outStream, CompressionType.Deflate);
|
||||||
}
|
}
|
||||||
@ -627,7 +633,7 @@ namespace osu.Game.Tests.Database
|
|||||||
|
|
||||||
checkSingleReferencedFileCount(realm.Realm, 18);
|
checkSingleReferencedFileCount(realm.Realm, 18);
|
||||||
|
|
||||||
Assert.AreEqual(1, loggedExceptionCount);
|
Assert.AreEqual(0, loggedExceptionCount);
|
||||||
|
|
||||||
File.Delete(brokenTempFilename);
|
File.Delete(brokenTempFilename);
|
||||||
});
|
});
|
||||||
|
@ -46,7 +46,7 @@ namespace osu.Game.Tests.Database
|
|||||||
|
|
||||||
realm.RegisterCustomSubscription(r =>
|
realm.RegisterCustomSubscription(r =>
|
||||||
{
|
{
|
||||||
var subscription = r.All<BeatmapInfo>().QueryAsyncWithNotifications((sender, changes, error) =>
|
var subscription = r.All<BeatmapInfo>().QueryAsyncWithNotifications((_, _, _) =>
|
||||||
{
|
{
|
||||||
realm.Run(_ =>
|
realm.Run(_ =>
|
||||||
{
|
{
|
||||||
@ -79,11 +79,11 @@ namespace osu.Game.Tests.Database
|
|||||||
{
|
{
|
||||||
hasThreadedUsage.Set();
|
hasThreadedUsage.Set();
|
||||||
|
|
||||||
stopThreadedUsage.Wait();
|
stopThreadedUsage.Wait(60000);
|
||||||
});
|
});
|
||||||
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler);
|
}, TaskCreationOptions.LongRunning | TaskCreationOptions.HideScheduler);
|
||||||
|
|
||||||
hasThreadedUsage.Wait();
|
hasThreadedUsage.Wait(60000);
|
||||||
|
|
||||||
Assert.Throws<TimeoutException>(() =>
|
Assert.Throws<TimeoutException>(() =>
|
||||||
{
|
{
|
||||||
|
@ -189,7 +189,7 @@ namespace osu.Game.Tests.Database
|
|||||||
});
|
});
|
||||||
|
|
||||||
// Can't be used, even from within a valid context.
|
// Can't be used, even from within a valid context.
|
||||||
realm.Run(threadContext =>
|
realm.Run(_ =>
|
||||||
{
|
{
|
||||||
Assert.Throws<InvalidOperationException>(() =>
|
Assert.Throws<InvalidOperationException>(() =>
|
||||||
{
|
{
|
||||||
|
@ -192,7 +192,7 @@ namespace osu.Game.Tests.Gameplay
|
|||||||
AddStep("apply perfect hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = HitResult.Perfect }));
|
AddStep("apply perfect hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = HitResult.Perfect }));
|
||||||
AddAssert("not failed", () => !processor.HasFailed);
|
AddAssert("not failed", () => !processor.HasFailed);
|
||||||
|
|
||||||
AddStep($"apply {resultApplied.ToString().ToLower()} hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = resultApplied }));
|
AddStep($"apply {resultApplied.ToString().ToLowerInvariant()} hit result", () => processor.ApplyResult(new JudgementResult(beatmap.HitObjects[0], new Judgement()) { Type = resultApplied }));
|
||||||
AddAssert("failed", () => processor.HasFailed);
|
AddAssert("failed", () => processor.HasFailed);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -254,7 +254,7 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
Assert.That(File.Exists(Path.Combine(customPath, OsuGameBase.CLIENT_DATABASE_FILENAME)));
|
Assert.That(File.Exists(Path.Combine(customPath, OsuGameBase.CLIENT_DATABASE_FILENAME)));
|
||||||
|
|
||||||
Directory.CreateDirectory(customPath2);
|
Directory.CreateDirectory(customPath2);
|
||||||
File.Copy(Path.Combine(customPath, OsuGameBase.CLIENT_DATABASE_FILENAME), Path.Combine(customPath2, OsuGameBase.CLIENT_DATABASE_FILENAME));
|
File.WriteAllText(Path.Combine(customPath2, OsuGameBase.CLIENT_DATABASE_FILENAME), "I am a text");
|
||||||
|
|
||||||
// Fails because file already exists.
|
// Fails because file already exists.
|
||||||
Assert.Throws<ArgumentException>(() => osu.Migrate(customPath2));
|
Assert.Throws<ArgumentException>(() => osu.Migrate(customPath2));
|
||||||
|
@ -83,14 +83,14 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
|
|
||||||
public override event Action<JudgementResult> NewResult
|
public override event Action<JudgementResult> NewResult
|
||||||
{
|
{
|
||||||
add => throw new InvalidOperationException();
|
add => throw new InvalidOperationException($"{nameof(NewResult)} operations not supported in test context");
|
||||||
remove => throw new InvalidOperationException();
|
remove => throw new InvalidOperationException($"{nameof(NewResult)} operations not supported in test context");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override event Action<JudgementResult> RevertResult
|
public override event Action<JudgementResult> RevertResult
|
||||||
{
|
{
|
||||||
add => throw new InvalidOperationException();
|
add => throw new InvalidOperationException($"{nameof(RevertResult)} operations not supported in test context");
|
||||||
remove => throw new InvalidOperationException();
|
remove => throw new InvalidOperationException($"{nameof(RevertResult)} operations not supported in test context");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Playfield Playfield { get; }
|
public override Playfield Playfield { get; }
|
||||||
|
@ -364,12 +364,12 @@ namespace osu.Game.Tests.NonVisual
|
|||||||
|
|
||||||
private void confirmCurrentFrame(int? frame)
|
private void confirmCurrentFrame(int? frame)
|
||||||
{
|
{
|
||||||
Assert.AreEqual(frame is int x ? replay.Frames[x].Time : (double?)null, handler.CurrentFrame?.Time, "Unexpected current frame");
|
Assert.AreEqual(frame is int x ? replay.Frames[x].Time : null, handler.CurrentFrame?.Time, "Unexpected current frame");
|
||||||
}
|
}
|
||||||
|
|
||||||
private void confirmNextFrame(int? frame)
|
private void confirmNextFrame(int? frame)
|
||||||
{
|
{
|
||||||
Assert.AreEqual(frame is int x ? replay.Frames[x].Time : (double?)null, handler.NextFrame?.Time, "Unexpected next frame");
|
Assert.AreEqual(frame is int x ? replay.Frames[x].Time : null, handler.NextFrame?.Time, "Unexpected next frame");
|
||||||
}
|
}
|
||||||
|
|
||||||
private class TestReplayFrame : ReplayFrame
|
private class TestReplayFrame : ReplayFrame
|
||||||
|
@ -157,7 +157,7 @@ namespace osu.Game.Tests.NonVisual.Skinning
|
|||||||
{
|
{
|
||||||
// use an incrementing width to allow assertion matching on correct textures as they turn from uploads into actual textures.
|
// use an incrementing width to allow assertion matching on correct textures as they turn from uploads into actual textures.
|
||||||
int width = 1;
|
int width = 1;
|
||||||
Textures = fileNames.ToDictionary(fileName => fileName, fileName => new TextureUpload(new Image<Rgba32>(width, width++)));
|
Textures = fileNames.ToDictionary(fileName => fileName, _ => new TextureUpload(new Image<Rgba32>(width, width++)));
|
||||||
}
|
}
|
||||||
|
|
||||||
public TextureUpload Get(string name) => Textures.GetValueOrDefault(name);
|
public TextureUpload Get(string name) => Textures.GetValueOrDefault(name);
|
||||||
|
@ -58,7 +58,7 @@ namespace osu.Game.Tests.Skins
|
|||||||
{
|
{
|
||||||
AddStep($"Set beatmap skin enabled to {allowBeatmapLookups}", () => config.SetValue(OsuSetting.BeatmapSkins, allowBeatmapLookups));
|
AddStep($"Set beatmap skin enabled to {allowBeatmapLookups}", () => config.SetValue(OsuSetting.BeatmapSkins, allowBeatmapLookups));
|
||||||
|
|
||||||
ISkin expected() => allowBeatmapLookups ? (ISkin)beatmapSource : userSource;
|
ISkin expected() => allowBeatmapLookups ? beatmapSource : userSource;
|
||||||
|
|
||||||
AddAssert("Check lookup is from correct source", () => requester.FindProvider(s => s.GetDrawableComponent(new TestSkinComponent()) != null) == expected());
|
AddAssert("Check lookup is from correct source", () => requester.FindProvider(s => s.GetDrawableComponent(new TestSkinComponent()) != null) == expected());
|
||||||
}
|
}
|
||||||
|
@ -36,8 +36,6 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
{
|
{
|
||||||
protected override Ruleset CreateEditorRuleset() => new OsuRuleset();
|
protected override Ruleset CreateEditorRuleset() => new OsuRuleset();
|
||||||
|
|
||||||
protected override bool EditorComponentsReady => Editor.ChildrenOfType<SetupScreen>().SingleOrDefault()?.IsLoaded == true;
|
|
||||||
|
|
||||||
protected override bool IsolateSavingFromDatabase => false;
|
protected override bool IsolateSavingFromDatabase => false;
|
||||||
|
|
||||||
[Resolved]
|
[Resolved]
|
||||||
@ -95,18 +93,23 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
string extractedFolder = $"{temp}_extracted";
|
string extractedFolder = $"{temp}_extracted";
|
||||||
Directory.CreateDirectory(extractedFolder);
|
Directory.CreateDirectory(extractedFolder);
|
||||||
|
|
||||||
using (var zip = ZipArchive.Open(temp))
|
try
|
||||||
zip.WriteToDirectory(extractedFolder);
|
{
|
||||||
|
using (var zip = ZipArchive.Open(temp))
|
||||||
|
zip.WriteToDirectory(extractedFolder);
|
||||||
|
|
||||||
bool success = setup.ChildrenOfType<ResourcesSection>().First().ChangeAudioTrack(new FileInfo(Path.Combine(extractedFolder, "03. Renatus - Soleily 192kbps.mp3")));
|
bool success = setup.ChildrenOfType<ResourcesSection>().First().ChangeAudioTrack(new FileInfo(Path.Combine(extractedFolder, "03. Renatus - Soleily 192kbps.mp3")));
|
||||||
|
|
||||||
File.Delete(temp);
|
// ensure audio file is copied to beatmap as "audio.mp3" rather than original filename.
|
||||||
Directory.Delete(extractedFolder, true);
|
Assert.That(Beatmap.Value.Metadata.AudioFile == "audio.mp3");
|
||||||
|
|
||||||
// ensure audio file is copied to beatmap as "audio.mp3" rather than original filename.
|
return success;
|
||||||
Assert.That(Beatmap.Value.Metadata.AudioFile == "audio.mp3");
|
}
|
||||||
|
finally
|
||||||
return success;
|
{
|
||||||
|
File.Delete(temp);
|
||||||
|
Directory.Delete(extractedFolder, true);
|
||||||
|
}
|
||||||
});
|
});
|
||||||
|
|
||||||
AddAssert("track length changed", () => Beatmap.Value.Track.Length > 60000);
|
AddAssert("track length changed", () => Beatmap.Value.Track.Length > 60000);
|
||||||
|
@ -9,6 +9,7 @@ using osu.Framework.Extensions.ObjectExtensions;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Database;
|
using osu.Game.Database;
|
||||||
|
using osu.Game.Overlays.Notifications;
|
||||||
using osu.Game.Rulesets.Mania;
|
using osu.Game.Rulesets.Mania;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Screens.Edit;
|
using osu.Game.Screens.Edit;
|
||||||
@ -35,10 +36,12 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
() => Game.Beatmap.Value.BeatmapSetInfo.Equals(beatmapSet)
|
() => Game.Beatmap.Value.BeatmapSetInfo.Equals(beatmapSet)
|
||||||
&& Game.ScreenStack.CurrentScreen is PlaySongSelect songSelect
|
&& Game.ScreenStack.CurrentScreen is PlaySongSelect songSelect
|
||||||
&& songSelect.IsLoaded);
|
&& songSelect.IsLoaded);
|
||||||
|
AddUntilStep("wait for completion notification", () => Game.Notifications.ChildrenOfType<ProgressCompletionNotification>().Count() == 1);
|
||||||
|
AddStep("dismiss notifications", () => Game.Notifications.Hide());
|
||||||
AddStep("switch ruleset", () => Game.Ruleset.Value = new ManiaRuleset().RulesetInfo);
|
AddStep("switch ruleset", () => Game.Ruleset.Value = new ManiaRuleset().RulesetInfo);
|
||||||
|
|
||||||
AddStep("open editor", () => ((PlaySongSelect)Game.ScreenStack.CurrentScreen).Edit(beatmapSet.Beatmaps.First(beatmap => beatmap.Ruleset.OnlineID == 0)));
|
AddStep("open editor", () => ((PlaySongSelect)Game.ScreenStack.CurrentScreen).Edit(beatmapSet.Beatmaps.First(beatmap => beatmap.Ruleset.OnlineID == 0)));
|
||||||
AddUntilStep("wait for editor open", () => Game.ScreenStack.CurrentScreen is Editor editor && editor.IsLoaded);
|
AddUntilStep("wait for editor open", () => Game.ScreenStack.CurrentScreen is Editor editor && editor.ReadyForUse);
|
||||||
AddStep("test gameplay", () =>
|
AddStep("test gameplay", () =>
|
||||||
{
|
{
|
||||||
var testGameplayButton = this.ChildrenOfType<TestGameplayButton>().Single();
|
var testGameplayButton = this.ChildrenOfType<TestGameplayButton>().Single();
|
||||||
|
@ -117,8 +117,8 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
|
|
||||||
// After placement these must be non-default as defaults are read-only.
|
// After placement these must be non-default as defaults are read-only.
|
||||||
AddAssert("Placed object has non-default control points", () =>
|
AddAssert("Placed object has non-default control points", () =>
|
||||||
EditorBeatmap.HitObjects[0].SampleControlPoint != SampleControlPoint.DEFAULT &&
|
!ReferenceEquals(EditorBeatmap.HitObjects[0].SampleControlPoint, SampleControlPoint.DEFAULT) &&
|
||||||
EditorBeatmap.HitObjects[0].DifficultyControlPoint != DifficultyControlPoint.DEFAULT);
|
!ReferenceEquals(EditorBeatmap.HitObjects[0].DifficultyControlPoint, DifficultyControlPoint.DEFAULT));
|
||||||
|
|
||||||
ReloadEditorToSameBeatmap();
|
ReloadEditorToSameBeatmap();
|
||||||
|
|
||||||
@ -126,8 +126,8 @@ namespace osu.Game.Tests.Visual.Editing
|
|||||||
|
|
||||||
// After placement these must be non-default as defaults are read-only.
|
// After placement these must be non-default as defaults are read-only.
|
||||||
AddAssert("Placed object still has non-default control points", () =>
|
AddAssert("Placed object still has non-default control points", () =>
|
||||||
EditorBeatmap.HitObjects[0].SampleControlPoint != SampleControlPoint.DEFAULT &&
|
!ReferenceEquals(EditorBeatmap.HitObjects[0].SampleControlPoint, SampleControlPoint.DEFAULT) &&
|
||||||
EditorBeatmap.HitObjects[0].DifficultyControlPoint != DifficultyControlPoint.DEFAULT);
|
!ReferenceEquals(EditorBeatmap.HitObjects[0].DifficultyControlPoint, DifficultyControlPoint.DEFAULT));
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -322,8 +322,8 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
switch (h)
|
switch (h)
|
||||||
{
|
{
|
||||||
case TestPooledHitObject _:
|
case TestPooledHitObject:
|
||||||
case TestPooledParentHitObject _:
|
case TestPooledParentHitObject:
|
||||||
return null;
|
return null;
|
||||||
|
|
||||||
case TestParentHitObject p:
|
case TestParentHitObject p:
|
||||||
|
@ -53,7 +53,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
HealthProcessor.FailConditions += (_, __) => true;
|
HealthProcessor.FailConditions += (_, _) => true;
|
||||||
}
|
}
|
||||||
|
|
||||||
private double lastFrequency = double.MaxValue;
|
private double lastFrequency = double.MaxValue;
|
||||||
|
@ -49,7 +49,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
protected override void LoadComplete()
|
protected override void LoadComplete()
|
||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
HealthProcessor.FailConditions += (_, __) => true;
|
HealthProcessor.FailConditions += (_, _) => true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -273,14 +273,14 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
public override event Action<JudgementResult> NewResult
|
public override event Action<JudgementResult> NewResult
|
||||||
{
|
{
|
||||||
add => throw new InvalidOperationException();
|
add => throw new InvalidOperationException($"{nameof(NewResult)} operations not supported in test context");
|
||||||
remove => throw new InvalidOperationException();
|
remove => throw new InvalidOperationException($"{nameof(NewResult)} operations not supported in test context");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override event Action<JudgementResult> RevertResult
|
public override event Action<JudgementResult> RevertResult
|
||||||
{
|
{
|
||||||
add => throw new InvalidOperationException();
|
add => throw new InvalidOperationException($"{nameof(RevertResult)} operations not supported in test context");
|
||||||
remove => throw new InvalidOperationException();
|
remove => throw new InvalidOperationException($"{nameof(RevertResult)} operations not supported in test context");
|
||||||
}
|
}
|
||||||
|
|
||||||
public override Playfield Playfield { get; }
|
public override Playfield Playfield { get; }
|
||||||
|
@ -45,7 +45,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestToggleEditor()
|
public void TestToggleEditor()
|
||||||
{
|
{
|
||||||
AddToggleStep("toggle editor visibility", visible => skinEditor.ToggleVisibility());
|
AddToggleStep("toggle editor visibility", _ => skinEditor.ToggleVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -103,7 +103,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
Child = new SkinProvidingContainer(secondarySource)
|
Child = new SkinProvidingContainer(secondarySource)
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Child = consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"))
|
Child = consumer = new SkinConsumer("test", _ => new NamedBox("Default Implementation"))
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
});
|
});
|
||||||
@ -132,7 +132,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("add permissive", () => target.Add(consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"))));
|
AddStep("add permissive", () => target.Add(consumer = new SkinConsumer("test", _ => new NamedBox("Default Implementation"))));
|
||||||
AddAssert("consumer using override source", () => consumer.Drawable is SecondarySourceBox);
|
AddAssert("consumer using override source", () => consumer.Drawable is SecondarySourceBox);
|
||||||
AddAssert("skinchanged only called once", () => consumer.SkinChangedCount == 1);
|
AddAssert("skinchanged only called once", () => consumer.SkinChangedCount == 1);
|
||||||
}
|
}
|
||||||
@ -155,7 +155,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
};
|
};
|
||||||
});
|
});
|
||||||
|
|
||||||
AddStep("add permissive", () => target.Add(consumer = new SkinConsumer("test", name => new NamedBox("Default Implementation"))));
|
AddStep("add permissive", () => target.Add(consumer = new SkinConsumer("test", _ => new NamedBox("Default Implementation"))));
|
||||||
AddAssert("consumer using override source", () => consumer.Drawable is SecondarySourceBox);
|
AddAssert("consumer using override source", () => consumer.Drawable is SecondarySourceBox);
|
||||||
AddStep("disable", () => target.Disable());
|
AddStep("disable", () => target.Disable());
|
||||||
AddAssert("consumer using base source", () => consumer.Drawable is BaseSourceBox);
|
AddAssert("consumer using base source", () => consumer.Drawable is BaseSourceBox);
|
||||||
|
@ -167,11 +167,16 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
AddStep("start failing sends", () =>
|
AddStep("start failing sends", () =>
|
||||||
{
|
{
|
||||||
spectatorClient.ShouldFailSendingFrames = true;
|
spectatorClient.ShouldFailSendingFrames = true;
|
||||||
framesReceivedSoFar = replay.Frames.Count;
|
|
||||||
frameSendAttemptsSoFar = spectatorClient.FrameSendAttempts;
|
frameSendAttemptsSoFar = spectatorClient.FrameSendAttempts;
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for send attempts", () => spectatorClient.FrameSendAttempts > frameSendAttemptsSoFar + 5);
|
AddUntilStep("wait for next send attempt", () =>
|
||||||
|
{
|
||||||
|
framesReceivedSoFar = replay.Frames.Count;
|
||||||
|
return spectatorClient.FrameSendAttempts > frameSendAttemptsSoFar + 1;
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for more send attempts", () => spectatorClient.FrameSendAttempts > frameSendAttemptsSoFar + 10);
|
||||||
AddAssert("frames did not increase", () => framesReceivedSoFar == replay.Frames.Count);
|
AddAssert("frames did not increase", () => framesReceivedSoFar == replay.Frames.Count);
|
||||||
|
|
||||||
AddStep("stop failing sends", () => spectatorClient.ShouldFailSendingFrames = false);
|
AddStep("stop failing sends", () => spectatorClient.ShouldFailSendingFrames = false);
|
||||||
|
@ -121,7 +121,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
|
|
||||||
private void createPlayerTest()
|
private void createPlayerTest()
|
||||||
{
|
{
|
||||||
CreateTest(null);
|
CreateTest();
|
||||||
|
|
||||||
AddAssert("storyboard loaded", () => Player.Beatmap.Value.Storyboard != null);
|
AddAssert("storyboard loaded", () => Player.Beatmap.Value.Storyboard != null);
|
||||||
waitUntilStoryboardSamplesPlay();
|
waitUntilStoryboardSamplesPlay();
|
||||||
|
@ -44,7 +44,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
base.SetUpSteps();
|
base.SetUpSteps();
|
||||||
AddStep("enable storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, true));
|
AddStep("enable storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, true));
|
||||||
AddStep("set dim level to 0", () => LocalConfig.SetValue<double>(OsuSetting.DimLevel, 0));
|
AddStep("set dim level to 0", () => LocalConfig.SetValue<double>(OsuSetting.DimLevel, 0));
|
||||||
AddStep("reset fail conditions", () => currentFailConditions = (_, __) => false);
|
AddStep("reset fail conditions", () => currentFailConditions = (_, _) => false);
|
||||||
AddStep("set storyboard duration to 2s", () => currentStoryboardDuration = 2000);
|
AddStep("set storyboard duration to 2s", () => currentStoryboardDuration = 2000);
|
||||||
AddStep("set ShowResults = true", () => showResults = true);
|
AddStep("set ShowResults = true", () => showResults = true);
|
||||||
}
|
}
|
||||||
@ -52,17 +52,18 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestStoryboardSkipOutro()
|
public void TestStoryboardSkipOutro()
|
||||||
{
|
{
|
||||||
CreateTest(null);
|
AddStep("set storyboard duration to long", () => currentStoryboardDuration = 200000);
|
||||||
|
CreateTest();
|
||||||
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
|
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
|
||||||
AddStep("skip outro", () => InputManager.Key(osuTK.Input.Key.Space));
|
AddStep("skip outro", () => InputManager.Key(osuTK.Input.Key.Space));
|
||||||
AddAssert("player is no longer current screen", () => !Player.IsCurrentScreen());
|
AddUntilStep("player is no longer current screen", () => !Player.IsCurrentScreen());
|
||||||
AddUntilStep("wait for score shown", () => Player.IsScoreShown);
|
AddUntilStep("wait for score shown", () => Player.IsScoreShown);
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestStoryboardNoSkipOutro()
|
public void TestStoryboardNoSkipOutro()
|
||||||
{
|
{
|
||||||
CreateTest(null);
|
CreateTest();
|
||||||
AddUntilStep("storyboard ends", () => Player.GameplayClockContainer.GameplayClock.CurrentTime >= currentStoryboardDuration);
|
AddUntilStep("storyboard ends", () => Player.GameplayClockContainer.GameplayClock.CurrentTime >= currentStoryboardDuration);
|
||||||
AddUntilStep("wait for score shown", () => Player.IsScoreShown);
|
AddUntilStep("wait for score shown", () => Player.IsScoreShown);
|
||||||
}
|
}
|
||||||
@ -70,7 +71,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestStoryboardExitDuringOutroStillExits()
|
public void TestStoryboardExitDuringOutroStillExits()
|
||||||
{
|
{
|
||||||
CreateTest(null);
|
CreateTest();
|
||||||
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
|
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
|
||||||
AddStep("exit via pause", () => Player.ExitViaPause());
|
AddStep("exit via pause", () => Player.ExitViaPause());
|
||||||
AddAssert("player exited", () => !Player.IsCurrentScreen() && Player.GetChildScreen() == null);
|
AddAssert("player exited", () => !Player.IsCurrentScreen() && Player.GetChildScreen() == null);
|
||||||
@ -80,7 +81,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[TestCase(true)]
|
[TestCase(true)]
|
||||||
public void TestStoryboardToggle(bool enabledAtBeginning)
|
public void TestStoryboardToggle(bool enabledAtBeginning)
|
||||||
{
|
{
|
||||||
CreateTest(null);
|
CreateTest();
|
||||||
AddStep($"{(enabledAtBeginning ? "enable" : "disable")} storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, enabledAtBeginning));
|
AddStep($"{(enabledAtBeginning ? "enable" : "disable")} storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, enabledAtBeginning));
|
||||||
AddStep("toggle storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, !enabledAtBeginning));
|
AddStep("toggle storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, !enabledAtBeginning));
|
||||||
AddUntilStep("wait for score shown", () => Player.IsScoreShown);
|
AddUntilStep("wait for score shown", () => Player.IsScoreShown);
|
||||||
@ -91,7 +92,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
CreateTest(() =>
|
CreateTest(() =>
|
||||||
{
|
{
|
||||||
AddStep("fail on first judgement", () => currentFailConditions = (_, __) => true);
|
AddStep("fail on first judgement", () => currentFailConditions = (_, _) => true);
|
||||||
|
|
||||||
// Fail occurs at 164ms with the provided beatmap.
|
// Fail occurs at 164ms with the provided beatmap.
|
||||||
// Fail animation runs for 2.5s realtime but the gameplay time change is *variable* due to the frequency transform being applied, so we need a bit of lenience.
|
// Fail animation runs for 2.5s realtime but the gameplay time change is *variable* due to the frequency transform being applied, so we need a bit of lenience.
|
||||||
@ -129,7 +130,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
{
|
{
|
||||||
SkipOverlay.FadeContainer fadeContainer() => Player.ChildrenOfType<SkipOverlay.FadeContainer>().First();
|
SkipOverlay.FadeContainer fadeContainer() => Player.ChildrenOfType<SkipOverlay.FadeContainer>().First();
|
||||||
|
|
||||||
CreateTest(null);
|
CreateTest();
|
||||||
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
|
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
|
||||||
AddUntilStep("skip overlay content becomes visible", () => fadeContainer().State == Visibility.Visible);
|
AddUntilStep("skip overlay content becomes visible", () => fadeContainer().State == Visibility.Visible);
|
||||||
|
|
||||||
@ -143,7 +144,7 @@ namespace osu.Game.Tests.Visual.Gameplay
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestPerformExitNoOutro()
|
public void TestPerformExitNoOutro()
|
||||||
{
|
{
|
||||||
CreateTest(null);
|
CreateTest();
|
||||||
AddStep("disable storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, false));
|
AddStep("disable storyboard", () => LocalConfig.SetValue(OsuSetting.ShowStoryboard, false));
|
||||||
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
|
AddUntilStep("completion set by processor", () => Player.ScoreProcessor.HasCompleted.Value);
|
||||||
AddStep("exit via pause", () => Player.ExitViaPause());
|
AddStep("exit via pause", () => Player.ExitViaPause());
|
||||||
|
@ -57,7 +57,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
|
|
||||||
// To emulate `MultiplayerClient.CurrentMatchPlayingUserIds` we need a bindable list of *only IDs*.
|
// To emulate `MultiplayerClient.CurrentMatchPlayingUserIds` we need a bindable list of *only IDs*.
|
||||||
// This tracks the list of users 1:1.
|
// This tracks the list of users 1:1.
|
||||||
MultiplayerUsers.BindCollectionChanged((c, e) =>
|
MultiplayerUsers.BindCollectionChanged((_, e) =>
|
||||||
{
|
{
|
||||||
switch (e.Action)
|
switch (e.Action)
|
||||||
{
|
{
|
||||||
|
@ -42,11 +42,11 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
var mockLounge = new Mock<LoungeSubScreen>();
|
var mockLounge = new Mock<LoungeSubScreen>();
|
||||||
mockLounge
|
mockLounge
|
||||||
.Setup(l => l.Join(It.IsAny<Room>(), It.IsAny<string>(), It.IsAny<Action<Room>>(), It.IsAny<Action<string>>()))
|
.Setup(l => l.Join(It.IsAny<Room>(), It.IsAny<string>(), It.IsAny<Action<Room>>(), It.IsAny<Action<string>>()))
|
||||||
.Callback<Room, string, Action<Room>, Action<string>>((a, b, c, d) =>
|
.Callback<Room, string, Action<Room>, Action<string>>((_, _, _, d) =>
|
||||||
{
|
{
|
||||||
Task.Run(() =>
|
Task.Run(() =>
|
||||||
{
|
{
|
||||||
allowResponseCallback.Wait();
|
allowResponseCallback.Wait(10000);
|
||||||
allowResponseCallback.Reset();
|
allowResponseCallback.Reset();
|
||||||
Schedule(() => d?.Invoke("Incorrect password"));
|
Schedule(() => d?.Invoke("Incorrect password"));
|
||||||
});
|
});
|
||||||
|
@ -90,7 +90,7 @@ namespace osu.Game.Tests.Visual.Multiplayer
|
|||||||
setRoomCountdown(countdownStart.Duration);
|
setRoomCountdown(countdownStart.Duration);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case StopCountdownRequest _:
|
case StopCountdownRequest:
|
||||||
multiplayerRoom.Countdown = null;
|
multiplayerRoom.Countdown = null;
|
||||||
raiseRoomUpdated();
|
raiseRoomUpdated();
|
||||||
break;
|
break;
|
||||||
|
@ -40,7 +40,6 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
private ChannelManager channelManager;
|
private ChannelManager channelManager;
|
||||||
|
|
||||||
private APIUser testUser;
|
private APIUser testUser;
|
||||||
private Channel testPMChannel;
|
|
||||||
private Channel[] testChannels;
|
private Channel[] testChannels;
|
||||||
|
|
||||||
private Channel testChannel1 => testChannels[0];
|
private Channel testChannel1 => testChannels[0];
|
||||||
@ -53,7 +52,6 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
public void SetUp() => Schedule(() =>
|
public void SetUp() => Schedule(() =>
|
||||||
{
|
{
|
||||||
testUser = new APIUser { Username = "test user", Id = 5071479 };
|
testUser = new APIUser { Username = "test user", Id = 5071479 };
|
||||||
testPMChannel = new Channel(testUser);
|
|
||||||
testChannels = Enumerable.Range(1, 10).Select(createPublicChannel).ToArray();
|
testChannels = Enumerable.Range(1, 10).Select(createPublicChannel).ToArray();
|
||||||
|
|
||||||
Child = new DependencyProvidingContainer
|
Child = new DependencyProvidingContainer
|
||||||
@ -80,6 +78,14 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
switch (req)
|
switch (req)
|
||||||
{
|
{
|
||||||
|
case CreateChannelRequest createRequest:
|
||||||
|
createRequest.TriggerSuccess(new APIChatChannel
|
||||||
|
{
|
||||||
|
ChannelID = ((int)createRequest.Channel.Id),
|
||||||
|
RecentMessages = new List<Message>()
|
||||||
|
});
|
||||||
|
return true;
|
||||||
|
|
||||||
case GetUpdatesRequest getUpdates:
|
case GetUpdatesRequest getUpdates:
|
||||||
getUpdates.TriggerFailure(new WebException());
|
getUpdates.TriggerFailure(new WebException());
|
||||||
return true;
|
return true;
|
||||||
@ -181,7 +187,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
AddStep("Show overlay", () => chatOverlay.Show());
|
AddStep("Show overlay", () => chatOverlay.Show());
|
||||||
AddAssert("Listing is visible", () => listingIsVisible);
|
AddAssert("Listing is visible", () => listingIsVisible);
|
||||||
AddStep("Join channel 1", () => channelManager.JoinChannel(testChannel1));
|
joinTestChannel(0);
|
||||||
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
||||||
waitForChannel1Visible();
|
waitForChannel1Visible();
|
||||||
}
|
}
|
||||||
@ -203,12 +209,11 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestChannelCloseButton()
|
public void TestChannelCloseButton()
|
||||||
{
|
{
|
||||||
|
var testPMChannel = new Channel(testUser);
|
||||||
|
|
||||||
AddStep("Show overlay", () => chatOverlay.Show());
|
AddStep("Show overlay", () => chatOverlay.Show());
|
||||||
AddStep("Join PM and public channels", () =>
|
joinTestChannel(0);
|
||||||
{
|
joinChannel(testPMChannel);
|
||||||
channelManager.JoinChannel(testChannel1);
|
|
||||||
channelManager.JoinChannel(testPMChannel);
|
|
||||||
});
|
|
||||||
AddStep("Select PM channel", () => clickDrawable(getChannelListItem(testPMChannel)));
|
AddStep("Select PM channel", () => clickDrawable(getChannelListItem(testPMChannel)));
|
||||||
AddStep("Click close button", () =>
|
AddStep("Click close button", () =>
|
||||||
{
|
{
|
||||||
@ -229,7 +234,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
public void TestChatCommand()
|
public void TestChatCommand()
|
||||||
{
|
{
|
||||||
AddStep("Show overlay", () => chatOverlay.Show());
|
AddStep("Show overlay", () => chatOverlay.Show());
|
||||||
AddStep("Join channel 1", () => channelManager.JoinChannel(testChannel1));
|
joinTestChannel(0);
|
||||||
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
||||||
AddStep("Open chat with user", () => channelManager.PostCommand($"chat {testUser.Username}"));
|
AddStep("Open chat with user", () => channelManager.PostCommand($"chat {testUser.Username}"));
|
||||||
AddAssert("PM channel is selected", () =>
|
AddAssert("PM channel is selected", () =>
|
||||||
@ -248,14 +253,16 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestMultiplayerChannelIsNotShown()
|
public void TestMultiplayerChannelIsNotShown()
|
||||||
{
|
{
|
||||||
Channel multiplayerChannel = null;
|
Channel multiplayerChannel;
|
||||||
|
|
||||||
AddStep("Show overlay", () => chatOverlay.Show());
|
AddStep("Show overlay", () => chatOverlay.Show());
|
||||||
AddStep("Join multiplayer channel", () => channelManager.JoinChannel(multiplayerChannel = new Channel(new APIUser())
|
|
||||||
|
joinChannel(multiplayerChannel = new Channel(new APIUser())
|
||||||
{
|
{
|
||||||
Name = "#mp_1",
|
Name = "#mp_1",
|
||||||
Type = ChannelType.Multiplayer,
|
Type = ChannelType.Multiplayer,
|
||||||
}));
|
});
|
||||||
|
|
||||||
AddAssert("Channel is joined", () => channelManager.JoinedChannels.Contains(multiplayerChannel));
|
AddAssert("Channel is joined", () => channelManager.JoinedChannels.Contains(multiplayerChannel));
|
||||||
AddUntilStep("Channel not present in listing", () => !chatOverlay.ChildrenOfType<ChannelListingItem>()
|
AddUntilStep("Channel not present in listing", () => !chatOverlay.ChildrenOfType<ChannelListingItem>()
|
||||||
.Where(item => item.IsPresent)
|
.Where(item => item.IsPresent)
|
||||||
@ -269,7 +276,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Message message = null;
|
Message message = null;
|
||||||
|
|
||||||
AddStep("Show overlay", () => chatOverlay.Show());
|
AddStep("Show overlay", () => chatOverlay.Show());
|
||||||
AddStep("Join channel 1", () => channelManager.JoinChannel(testChannel1));
|
joinTestChannel(0);
|
||||||
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
||||||
AddStep("Send message in channel 1", () =>
|
AddStep("Send message in channel 1", () =>
|
||||||
{
|
{
|
||||||
@ -291,8 +298,8 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Message message = null;
|
Message message = null;
|
||||||
|
|
||||||
AddStep("Show overlay", () => chatOverlay.Show());
|
AddStep("Show overlay", () => chatOverlay.Show());
|
||||||
AddStep("Join channel 1", () => channelManager.JoinChannel(testChannel1));
|
joinTestChannel(0);
|
||||||
AddStep("Join channel 2", () => channelManager.JoinChannel(testChannel2));
|
joinTestChannel(1);
|
||||||
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
||||||
AddStep("Send message in channel 2", () =>
|
AddStep("Send message in channel 2", () =>
|
||||||
{
|
{
|
||||||
@ -314,8 +321,8 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Message message = null;
|
Message message = null;
|
||||||
|
|
||||||
AddStep("Show overlay", () => chatOverlay.Show());
|
AddStep("Show overlay", () => chatOverlay.Show());
|
||||||
AddStep("Join channel 1", () => channelManager.JoinChannel(testChannel1));
|
joinTestChannel(0);
|
||||||
AddStep("Join channel 2", () => channelManager.JoinChannel(testChannel2));
|
joinTestChannel(1);
|
||||||
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
||||||
AddStep("Send message in channel 2", () =>
|
AddStep("Send message in channel 2", () =>
|
||||||
{
|
{
|
||||||
@ -337,7 +344,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
Message message = null;
|
Message message = null;
|
||||||
|
|
||||||
AddStep("Join channel 1", () => channelManager.JoinChannel(testChannel1));
|
joinTestChannel(0);
|
||||||
AddStep("Send message in channel 1", () =>
|
AddStep("Send message in channel 1", () =>
|
||||||
{
|
{
|
||||||
testChannel1.AddNewMessages(message = new Message
|
testChannel1.AddNewMessages(message = new Message
|
||||||
@ -357,7 +364,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
Message message = null;
|
Message message = null;
|
||||||
|
|
||||||
AddStep("Join channel 1", () => channelManager.JoinChannel(testChannel1));
|
joinTestChannel(0);
|
||||||
AddStep("Send message in channel 1", () =>
|
AddStep("Send message in channel 1", () =>
|
||||||
{
|
{
|
||||||
testChannel1.AddNewMessages(message = new Message
|
testChannel1.AddNewMessages(message = new Message
|
||||||
@ -378,7 +385,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
AddStep("Show overlay", () => chatOverlay.Show());
|
AddStep("Show overlay", () => chatOverlay.Show());
|
||||||
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
|
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
|
||||||
AddStep("Join channel 1", () => channelManager.JoinChannel(testChannel1));
|
joinTestChannel(0);
|
||||||
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
||||||
waitForChannel1Visible();
|
waitForChannel1Visible();
|
||||||
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
|
AddAssert("TextBox is focused", () => InputManager.FocusedDrawable == chatOverlayTextBox);
|
||||||
@ -404,11 +411,11 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
chatOverlay.Show();
|
chatOverlay.Show();
|
||||||
chatOverlay.SlowLoading = true;
|
chatOverlay.SlowLoading = true;
|
||||||
});
|
});
|
||||||
AddStep("Join channel 1", () => channelManager.JoinChannel(testChannel1));
|
joinTestChannel(0);
|
||||||
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
||||||
AddUntilStep("Channel 1 loading", () => !channelIsVisible && chatOverlay.GetSlowLoadingChannel(testChannel1).LoadState == LoadState.Loading);
|
AddUntilStep("Channel 1 loading", () => !channelIsVisible && chatOverlay.GetSlowLoadingChannel(testChannel1).LoadState == LoadState.Loading);
|
||||||
|
|
||||||
AddStep("Join channel 2", () => channelManager.JoinChannel(testChannel2));
|
joinTestChannel(1);
|
||||||
AddStep("Select channel 2", () => clickDrawable(getChannelListItem(testChannel2)));
|
AddStep("Select channel 2", () => clickDrawable(getChannelListItem(testChannel2)));
|
||||||
AddUntilStep("Channel 2 loading", () => !channelIsVisible && chatOverlay.GetSlowLoadingChannel(testChannel2).LoadState == LoadState.Loading);
|
AddUntilStep("Channel 2 loading", () => !channelIsVisible && chatOverlay.GetSlowLoadingChannel(testChannel2).LoadState == LoadState.Loading);
|
||||||
|
|
||||||
@ -461,19 +468,17 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
Channel pmChannel1 = createPrivateChannel();
|
Channel pmChannel1 = createPrivateChannel();
|
||||||
Channel pmChannel2 = createPrivateChannel();
|
Channel pmChannel2 = createPrivateChannel();
|
||||||
|
|
||||||
AddStep("Show overlay with channels", () =>
|
joinTestChannel(0);
|
||||||
{
|
joinTestChannel(1);
|
||||||
channelManager.JoinChannel(testChannel1);
|
joinChannel(pmChannel1);
|
||||||
channelManager.JoinChannel(testChannel2);
|
joinChannel(pmChannel2);
|
||||||
channelManager.JoinChannel(pmChannel1);
|
joinChannel(announceChannel);
|
||||||
channelManager.JoinChannel(pmChannel2);
|
|
||||||
channelManager.JoinChannel(announceChannel);
|
AddStep("Show overlay", () => chatOverlay.Show());
|
||||||
chatOverlay.Show();
|
|
||||||
});
|
|
||||||
|
|
||||||
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
AddStep("Select channel 1", () => clickDrawable(getChannelListItem(testChannel1)));
|
||||||
|
|
||||||
waitForChannel1Visible();
|
waitForChannel1Visible();
|
||||||
|
|
||||||
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
|
AddStep("Press document next keys", () => InputManager.Keys(PlatformAction.DocumentNext));
|
||||||
waitForChannel2Visible();
|
waitForChannel2Visible();
|
||||||
|
|
||||||
@ -490,6 +495,18 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
waitForChannel1Visible();
|
waitForChannel1Visible();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private void joinTestChannel(int i)
|
||||||
|
{
|
||||||
|
AddStep($"Join test channel {i}", () => channelManager.JoinChannel(testChannels[i]));
|
||||||
|
AddUntilStep("wait for join completed", () => testChannels[i].Joined.Value);
|
||||||
|
}
|
||||||
|
|
||||||
|
private void joinChannel(Channel channel)
|
||||||
|
{
|
||||||
|
AddStep($"Join channel {channel}", () => channelManager.JoinChannel(channel));
|
||||||
|
AddUntilStep("wait for join completed", () => channel.Joined.Value);
|
||||||
|
}
|
||||||
|
|
||||||
private void waitForChannel1Visible() =>
|
private void waitForChannel1Visible() =>
|
||||||
AddUntilStep("Channel 1 is visible", () => channelIsVisible && currentDrawableChannel?.Channel == testChannel1);
|
AddUntilStep("Channel 1 is visible", () => channelIsVisible && currentDrawableChannel?.Channel == testChannel1);
|
||||||
|
|
||||||
@ -549,7 +566,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
|
|
||||||
private Channel createPrivateChannel()
|
private Channel createPrivateChannel()
|
||||||
{
|
{
|
||||||
int id = RNG.Next(0, 10000);
|
int id = RNG.Next(0, DummyAPIAccess.DUMMY_USER_ID - 1);
|
||||||
return new Channel(new APIUser
|
return new Channel(new APIUser
|
||||||
{
|
{
|
||||||
Id = id,
|
Id = id,
|
||||||
@ -559,7 +576,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
|
|
||||||
private Channel createAnnounceChannel()
|
private Channel createAnnounceChannel()
|
||||||
{
|
{
|
||||||
int id = RNG.Next(0, 10000);
|
int id = RNG.Next(0, DummyAPIAccess.DUMMY_USER_ID - 1);
|
||||||
return new Channel
|
return new Channel
|
||||||
{
|
{
|
||||||
Name = $"Announce {id}",
|
Name = $"Announce {id}",
|
||||||
|
@ -219,7 +219,7 @@ namespace osu.Game.Tests.Visual.Online
|
|||||||
{
|
{
|
||||||
base.LoadComplete();
|
base.LoadComplete();
|
||||||
|
|
||||||
Metadata.BindValueChanged(metadata =>
|
Metadata.BindValueChanged(_ =>
|
||||||
{
|
{
|
||||||
foreach (var b in this.ChildrenOfType<YearButton>())
|
foreach (var b in this.ChildrenOfType<YearButton>())
|
||||||
b.Action = () => YearChanged?.Invoke(b.Year);
|
b.Action = () => YearChanged?.Invoke(b.Year);
|
||||||
|
@ -187,8 +187,8 @@ namespace osu.Game.Tests.Visual.Playlists
|
|||||||
// pre-check for requests we should be handling (as they are scheduled below).
|
// pre-check for requests we should be handling (as they are scheduled below).
|
||||||
switch (request)
|
switch (request)
|
||||||
{
|
{
|
||||||
case ShowPlaylistUserScoreRequest _:
|
case ShowPlaylistUserScoreRequest:
|
||||||
case IndexPlaylistScoresRequest _:
|
case IndexPlaylistScoresRequest:
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
@ -76,7 +76,7 @@ namespace osu.Game.Tests.Visual.Settings
|
|||||||
public void ToggleVisibility()
|
public void ToggleVisibility()
|
||||||
{
|
{
|
||||||
AddWaitStep("wait some", 5);
|
AddWaitStep("wait some", 5);
|
||||||
AddToggleStep("toggle visibility", visible => settings.ToggleVisibility());
|
AddToggleStep("toggle visibility", _ => settings.ToggleVisibility());
|
||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
|
@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
{
|
{
|
||||||
AddStep("set beatmap", () => advancedStats.BeatmapInfo = new BeatmapInfo
|
AddStep("set beatmap", () => advancedStats.BeatmapInfo = new BeatmapInfo
|
||||||
{
|
{
|
||||||
Ruleset = rulesets.GetRuleset(3) ?? throw new InvalidOperationException(),
|
Ruleset = rulesets.GetRuleset(3) ?? throw new InvalidOperationException("osu!mania ruleset not found"),
|
||||||
Difficulty = new BeatmapDifficulty
|
Difficulty = new BeatmapDifficulty
|
||||||
{
|
{
|
||||||
CircleSize = 5,
|
CircleSize = 5,
|
||||||
|
@ -91,19 +91,19 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
|
|
||||||
switch (instance)
|
switch (instance)
|
||||||
{
|
{
|
||||||
case OsuRuleset _:
|
case OsuRuleset:
|
||||||
testInfoLabels(5);
|
testInfoLabels(5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case TaikoRuleset _:
|
case TaikoRuleset:
|
||||||
testInfoLabels(5);
|
testInfoLabels(5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case CatchRuleset _:
|
case CatchRuleset:
|
||||||
testInfoLabels(5);
|
testInfoLabels(5);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case ManiaRuleset _:
|
case ManiaRuleset:
|
||||||
testInfoLabels(4);
|
testInfoLabels(4);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
@ -872,10 +872,10 @@ namespace osu.Game.Tests.Visual.SongSelect
|
|||||||
return set != null;
|
return set != null;
|
||||||
});
|
});
|
||||||
|
|
||||||
FilterableGroupedDifficultyIcon groupIcon = null;
|
GroupedDifficultyIcon groupIcon = null;
|
||||||
AddUntilStep("Find group icon for different ruleset", () =>
|
AddUntilStep("Find group icon for different ruleset", () =>
|
||||||
{
|
{
|
||||||
return (groupIcon = set.ChildrenOfType<FilterableGroupedDifficultyIcon>()
|
return (groupIcon = set.ChildrenOfType<GroupedDifficultyIcon>()
|
||||||
.FirstOrDefault(icon => icon.Items.First().BeatmapInfo.Ruleset.OnlineID == 3)) != null;
|
.FirstOrDefault(icon => icon.Items.First().BeatmapInfo.Ruleset.OnlineID == 3)) != null;
|
||||||
});
|
});
|
||||||
|
|
||||||
|
@ -70,7 +70,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
AddStep("Set time before zero", () =>
|
AddStep("Set time before zero", () =>
|
||||||
{
|
{
|
||||||
beatContainer.NewBeat = (i, timingControlPoint, effectControlPoint, channelAmplitudes) =>
|
beatContainer.NewBeat = (i, timingControlPoint, _, _) =>
|
||||||
{
|
{
|
||||||
lastActuationTime = gameplayClockContainer.CurrentTime;
|
lastActuationTime = gameplayClockContainer.CurrentTime;
|
||||||
lastTimingPoint = timingControlPoint;
|
lastTimingPoint = timingControlPoint;
|
||||||
@ -105,7 +105,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
AddStep("Set time before zero", () =>
|
AddStep("Set time before zero", () =>
|
||||||
{
|
{
|
||||||
beatContainer.NewBeat = (i, timingControlPoint, effectControlPoint, channelAmplitudes) =>
|
beatContainer.NewBeat = (i, timingControlPoint, _, _) =>
|
||||||
{
|
{
|
||||||
lastBeatIndex = i;
|
lastBeatIndex = i;
|
||||||
lastBpm = timingControlPoint.BPM;
|
lastBpm = timingControlPoint.BPM;
|
||||||
@ -126,7 +126,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
AddStep("bind event", () =>
|
AddStep("bind event", () =>
|
||||||
{
|
{
|
||||||
beatContainer.NewBeat = (i, timingControlPoint, effectControlPoint, channelAmplitudes) => lastBpm = timingControlPoint.BPM;
|
beatContainer.NewBeat = (_, timingControlPoint, _, _) => lastBpm = timingControlPoint.BPM;
|
||||||
});
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for trigger", () => lastBpm != null);
|
AddUntilStep("wait for trigger", () => lastBpm != null);
|
||||||
@ -157,7 +157,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
actualEffectPoint = null;
|
actualEffectPoint = null;
|
||||||
beatContainer.AllowMistimedEventFiring = false;
|
beatContainer.AllowMistimedEventFiring = false;
|
||||||
|
|
||||||
beatContainer.NewBeat = (i, timingControlPoint, effectControlPoint, channelAmplitudes) =>
|
beatContainer.NewBeat = (_, _, effectControlPoint, _) =>
|
||||||
{
|
{
|
||||||
if (Precision.AlmostEquals(gameplayClockContainer.CurrentTime + earlyActivationMilliseconds, expectedEffectPoint.Time, BeatSyncedContainer.MISTIMED_ALLOWANCE))
|
if (Precision.AlmostEquals(gameplayClockContainer.CurrentTime + earlyActivationMilliseconds, expectedEffectPoint.Time, BeatSyncedContainer.MISTIMED_ALLOWANCE))
|
||||||
actualEffectPoint = effectControlPoint;
|
actualEffectPoint = effectControlPoint;
|
||||||
@ -269,7 +269,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
private TimingControlPoint getNextTimingPoint(TimingControlPoint current)
|
private TimingControlPoint getNextTimingPoint(TimingControlPoint current)
|
||||||
{
|
{
|
||||||
if (timingPoints[^1] == current)
|
if (ReferenceEquals(timingPoints[^1], current))
|
||||||
return current;
|
return current;
|
||||||
|
|
||||||
int index = timingPoints.IndexOf(current); // -1 means that this is a "default beat"
|
int index = timingPoints.IndexOf(current); // -1 means that this is a "default beat"
|
||||||
@ -281,7 +281,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
if (timingPoints.Count == 0) return 0;
|
if (timingPoints.Count == 0) return 0;
|
||||||
|
|
||||||
if (timingPoints[^1] == current)
|
if (ReferenceEquals(timingPoints[^1], current))
|
||||||
{
|
{
|
||||||
Debug.Assert(BeatSyncSource.Clock != null);
|
Debug.Assert(BeatSyncSource.Clock != null);
|
||||||
|
|
||||||
|
@ -77,13 +77,13 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
};
|
};
|
||||||
|
|
||||||
control.Query.BindValueChanged(q => query.Text = $"Query: {q.NewValue}", true);
|
control.Query.BindValueChanged(q => query.Text = $"Query: {q.NewValue}", true);
|
||||||
control.General.BindCollectionChanged((u, v) => general.Text = $"General: {(control.General.Any() ? string.Join('.', control.General.Select(i => i.ToString().Underscore())) : "")}", true);
|
control.General.BindCollectionChanged((_, _) => general.Text = $"General: {(control.General.Any() ? string.Join('.', control.General.Select(i => i.ToString().Underscore())) : "")}", true);
|
||||||
control.Ruleset.BindValueChanged(r => ruleset.Text = $"Ruleset: {r.NewValue}", true);
|
control.Ruleset.BindValueChanged(r => ruleset.Text = $"Ruleset: {r.NewValue}", true);
|
||||||
control.Category.BindValueChanged(c => category.Text = $"Category: {c.NewValue}", true);
|
control.Category.BindValueChanged(c => category.Text = $"Category: {c.NewValue}", true);
|
||||||
control.Genre.BindValueChanged(g => genre.Text = $"Genre: {g.NewValue}", true);
|
control.Genre.BindValueChanged(g => genre.Text = $"Genre: {g.NewValue}", true);
|
||||||
control.Language.BindValueChanged(l => language.Text = $"Language: {l.NewValue}", true);
|
control.Language.BindValueChanged(l => language.Text = $"Language: {l.NewValue}", true);
|
||||||
control.Extra.BindCollectionChanged((u, v) => extra.Text = $"Extra: {(control.Extra.Any() ? string.Join('.', control.Extra.Select(i => i.ToString().ToLowerInvariant())) : "")}", true);
|
control.Extra.BindCollectionChanged((_, _) => extra.Text = $"Extra: {(control.Extra.Any() ? string.Join('.', control.Extra.Select(i => i.ToString().ToLowerInvariant())) : "")}", true);
|
||||||
control.Ranks.BindCollectionChanged((u, v) => ranks.Text = $"Ranks: {(control.Ranks.Any() ? string.Join('.', control.Ranks.Select(i => i.ToString())) : "")}", true);
|
control.Ranks.BindCollectionChanged((_, _) => ranks.Text = $"Ranks: {(control.Ranks.Any() ? string.Join('.', control.Ranks.Select(i => i.ToString())) : "")}", true);
|
||||||
control.Played.BindValueChanged(p => played.Text = $"Played: {p.NewValue}", true);
|
control.Played.BindValueChanged(p => played.Text = $"Played: {p.NewValue}", true);
|
||||||
control.ExplicitContent.BindValueChanged(e => explicitMap.Text = $"Explicit Maps: {e.NewValue}", true);
|
control.ExplicitContent.BindValueChanged(e => explicitMap.Text = $"Explicit Maps: {e.NewValue}", true);
|
||||||
});
|
});
|
||||||
|
@ -54,7 +54,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
notificationOverlay.Reset();
|
notificationOverlay.Reset();
|
||||||
|
|
||||||
performer.Setup(g => g.PerformFromScreen(It.IsAny<Action<IScreen>>(), It.IsAny<IEnumerable<Type>>()))
|
performer.Setup(g => g.PerformFromScreen(It.IsAny<Action<IScreen>>(), It.IsAny<IEnumerable<Type>>()))
|
||||||
.Callback((Action<IScreen> action, IEnumerable<Type> types) => action(null));
|
.Callback((Action<IScreen> action, IEnumerable<Type> _) => action(null));
|
||||||
|
|
||||||
notificationOverlay.Setup(n => n.Post(It.IsAny<Notification>()))
|
notificationOverlay.Setup(n => n.Post(It.IsAny<Notification>()))
|
||||||
.Callback((Notification n) => lastNotification = n);
|
.Callback((Notification n) => lastNotification = n);
|
||||||
|
@ -78,7 +78,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
Width = 500,
|
Width = 500,
|
||||||
AutoSizeAxes = Axes.Y,
|
AutoSizeAxes = Axes.Y,
|
||||||
Child = component = padded ? (LabelledDrawable<Drawable>)new PaddedLabelledDrawable() : new NonPaddedLabelledDrawable(),
|
Child = component = padded ? new PaddedLabelledDrawable() : new NonPaddedLabelledDrawable(),
|
||||||
};
|
};
|
||||||
|
|
||||||
component.Label = "a sample component";
|
component.Label = "a sample component";
|
||||||
|
@ -9,9 +9,11 @@ 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.Testing;
|
using osu.Framework.Testing;
|
||||||
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Overlays;
|
using osu.Game.Overlays;
|
||||||
using osu.Game.Overlays.Mods;
|
using osu.Game.Overlays.Mods;
|
||||||
|
using osu.Game.Overlays.Mods.Input;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu;
|
using osu.Game.Rulesets.Osu;
|
||||||
using osu.Game.Utils;
|
using osu.Game.Utils;
|
||||||
@ -25,6 +27,9 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
[Cached]
|
[Cached]
|
||||||
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
|
private OverlayColourProvider colourProvider = new OverlayColourProvider(OverlayColourScheme.Green);
|
||||||
|
|
||||||
|
[Resolved]
|
||||||
|
private OsuConfigManager configManager { get; set; } = null!;
|
||||||
|
|
||||||
[TestCase(ModType.DifficultyReduction)]
|
[TestCase(ModType.DifficultyReduction)]
|
||||||
[TestCase(ModType.DifficultyIncrease)]
|
[TestCase(ModType.DifficultyIncrease)]
|
||||||
[TestCase(ModType.Conversion)]
|
[TestCase(ModType.Conversion)]
|
||||||
@ -132,14 +137,16 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
}
|
}
|
||||||
|
|
||||||
[Test]
|
[Test]
|
||||||
public void TestKeyboardSelection()
|
public void TestSequentialKeyboardSelection()
|
||||||
{
|
{
|
||||||
|
AddStep("set sequential hotkey mode", () => configManager.SetValue(OsuSetting.ModSelectHotkeyStyle, ModSelectHotkeyStyle.Sequential));
|
||||||
|
|
||||||
ModColumn column = null!;
|
ModColumn column = null!;
|
||||||
AddStep("create content", () => Child = new Container
|
AddStep("create content", () => Child = new Container
|
||||||
{
|
{
|
||||||
RelativeSizeAxes = Axes.Both,
|
RelativeSizeAxes = Axes.Both,
|
||||||
Padding = new MarginPadding(30),
|
Padding = new MarginPadding(30),
|
||||||
Child = column = new ModColumn(ModType.DifficultyReduction, true, new[] { Key.Q, Key.W, Key.E, Key.R, Key.T, Key.Y, Key.U, Key.I, Key.O, Key.P })
|
Child = column = new ModColumn(ModType.DifficultyReduction, true)
|
||||||
{
|
{
|
||||||
Anchor = Anchor.Centre,
|
Anchor = Anchor.Centre,
|
||||||
Origin = Anchor.Centre,
|
Origin = Anchor.Centre,
|
||||||
@ -158,9 +165,12 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("set filter to NF", () => setFilter(mod => mod.Acronym == "NF"));
|
AddStep("set filter to NF", () => setFilter(mod => mod.Acronym == "NF"));
|
||||||
|
|
||||||
AddStep("press W", () => InputManager.Key(Key.W));
|
AddStep("press W", () => InputManager.Key(Key.W));
|
||||||
|
AddAssert("NF panel not selected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NF").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press Q", () => InputManager.Key(Key.Q));
|
||||||
AddAssert("NF panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NF").Active.Value);
|
AddAssert("NF panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NF").Active.Value);
|
||||||
|
|
||||||
AddStep("press W again", () => InputManager.Key(Key.W));
|
AddStep("press Q again", () => InputManager.Key(Key.Q));
|
||||||
AddAssert("NF panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NF").Active.Value);
|
AddAssert("NF panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NF").Active.Value);
|
||||||
|
|
||||||
AddStep("filter out everything", () => setFilter(_ => false));
|
AddStep("filter out everything", () => setFilter(_ => false));
|
||||||
@ -171,6 +181,113 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddStep("clear filter", () => setFilter(null));
|
AddStep("clear filter", () => setFilter(null));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestClassicKeyboardExclusiveSelection()
|
||||||
|
{
|
||||||
|
AddStep("set classic hotkey mode", () => configManager.SetValue(OsuSetting.ModSelectHotkeyStyle, ModSelectHotkeyStyle.Classic));
|
||||||
|
|
||||||
|
ModColumn column = null!;
|
||||||
|
AddStep("create content", () => Child = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding(30),
|
||||||
|
Child = column = new ModColumn(ModType.DifficultyIncrease, false)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AvailableMods = getExampleModsFor(ModType.DifficultyIncrease)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for panel load", () => column.IsLoaded && column.ItemsLoaded);
|
||||||
|
|
||||||
|
AddStep("press A", () => InputManager.Key(Key.A));
|
||||||
|
AddAssert("HR panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "HR").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press A again", () => InputManager.Key(Key.A));
|
||||||
|
AddAssert("HR panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "HR").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press D", () => InputManager.Key(Key.D));
|
||||||
|
AddAssert("DT panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "DT").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press D again", () => InputManager.Key(Key.D));
|
||||||
|
AddAssert("DT panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "DT").Active.Value);
|
||||||
|
AddAssert("NC panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NC").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press D again", () => InputManager.Key(Key.D));
|
||||||
|
AddAssert("DT panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "DT").Active.Value);
|
||||||
|
AddAssert("NC panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NC").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press Shift-D", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.ShiftLeft);
|
||||||
|
InputManager.Key(Key.D);
|
||||||
|
InputManager.ReleaseKey(Key.ShiftLeft);
|
||||||
|
});
|
||||||
|
AddAssert("DT panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "DT").Active.Value);
|
||||||
|
AddAssert("NC panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NC").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press J", () => InputManager.Key(Key.J));
|
||||||
|
AddAssert("no change", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Active.Value).Mod.Acronym == "NC");
|
||||||
|
|
||||||
|
AddStep("filter everything but NC", () => setFilter(mod => mod.Acronym == "NC"));
|
||||||
|
|
||||||
|
AddStep("press A", () => InputManager.Key(Key.A));
|
||||||
|
AddAssert("no change", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Active.Value).Mod.Acronym == "NC");
|
||||||
|
}
|
||||||
|
|
||||||
|
[Test]
|
||||||
|
public void TestClassicKeyboardIncompatibleSelection()
|
||||||
|
{
|
||||||
|
AddStep("set classic hotkey mode", () => configManager.SetValue(OsuSetting.ModSelectHotkeyStyle, ModSelectHotkeyStyle.Classic));
|
||||||
|
|
||||||
|
ModColumn column = null!;
|
||||||
|
AddStep("create content", () => Child = new Container
|
||||||
|
{
|
||||||
|
RelativeSizeAxes = Axes.Both,
|
||||||
|
Padding = new MarginPadding(30),
|
||||||
|
Child = column = new ModColumn(ModType.DifficultyIncrease, true)
|
||||||
|
{
|
||||||
|
Anchor = Anchor.Centre,
|
||||||
|
Origin = Anchor.Centre,
|
||||||
|
AvailableMods = getExampleModsFor(ModType.DifficultyIncrease)
|
||||||
|
}
|
||||||
|
});
|
||||||
|
|
||||||
|
AddUntilStep("wait for panel load", () => column.IsLoaded && column.ItemsLoaded);
|
||||||
|
|
||||||
|
AddStep("press A", () => InputManager.Key(Key.A));
|
||||||
|
AddAssert("HR panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "HR").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press A again", () => InputManager.Key(Key.A));
|
||||||
|
AddAssert("HR panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "HR").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press D", () => InputManager.Key(Key.D));
|
||||||
|
AddAssert("DT panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "DT").Active.Value);
|
||||||
|
AddAssert("NC panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NC").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press D again", () => InputManager.Key(Key.D));
|
||||||
|
AddAssert("DT panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "DT").Active.Value);
|
||||||
|
AddAssert("NC panel deselected", () => !this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NC").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press Shift-D", () =>
|
||||||
|
{
|
||||||
|
InputManager.PressKey(Key.ShiftLeft);
|
||||||
|
InputManager.Key(Key.D);
|
||||||
|
InputManager.ReleaseKey(Key.ShiftLeft);
|
||||||
|
});
|
||||||
|
AddAssert("DT panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "DT").Active.Value);
|
||||||
|
AddAssert("NC panel selected", () => this.ChildrenOfType<ModPanel>().Single(panel => panel.Mod.Acronym == "NC").Active.Value);
|
||||||
|
|
||||||
|
AddStep("press J", () => InputManager.Key(Key.J));
|
||||||
|
AddAssert("no change", () => this.ChildrenOfType<ModPanel>().Count(panel => panel.Active.Value) == 2);
|
||||||
|
|
||||||
|
AddStep("filter everything but NC", () => setFilter(mod => mod.Acronym == "NC"));
|
||||||
|
|
||||||
|
AddStep("press A", () => InputManager.Key(Key.A));
|
||||||
|
AddAssert("no change", () => this.ChildrenOfType<ModPanel>().Count(panel => panel.Active.Value) == 2);
|
||||||
|
}
|
||||||
|
|
||||||
private void setFilter(Func<Mod, bool>? filter)
|
private void setFilter(Func<Mod, bool>? filter)
|
||||||
{
|
{
|
||||||
foreach (var modState in this.ChildrenOfType<ModColumn>().Single().AvailableMods)
|
foreach (var modState in this.ChildrenOfType<ModColumn>().Single().AvailableMods)
|
||||||
@ -181,8 +298,8 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
public new bool SelectionAnimationRunning => base.SelectionAnimationRunning;
|
public new bool SelectionAnimationRunning => base.SelectionAnimationRunning;
|
||||||
|
|
||||||
public TestModColumn(ModType modType, bool allowBulkSelection)
|
public TestModColumn(ModType modType, bool allowIncompatibleSelection)
|
||||||
: base(modType, allowBulkSelection)
|
: base(modType, allowIncompatibleSelection)
|
||||||
{
|
{
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
@ -13,7 +13,7 @@ using osu.Framework.Graphics.Shapes;
|
|||||||
using osu.Framework.Testing;
|
using osu.Framework.Testing;
|
||||||
using osu.Game.Beatmaps;
|
using osu.Game.Beatmaps;
|
||||||
using osu.Game.Configuration;
|
using osu.Game.Configuration;
|
||||||
using osu.Game.Overlays.Settings;
|
using osu.Game.Graphics.UserInterface;
|
||||||
using osu.Game.Rulesets.Mods;
|
using osu.Game.Rulesets.Mods;
|
||||||
using osu.Game.Rulesets.Osu.Mods;
|
using osu.Game.Rulesets.Osu.Mods;
|
||||||
using osuTK;
|
using osuTK;
|
||||||
@ -246,7 +246,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
AddStep($"Set {name} slider to {value}", () =>
|
AddStep($"Set {name} slider to {value}", () =>
|
||||||
this.ChildrenOfType<DifficultyAdjustSettingsControl>().First(c => c.LabelText == name)
|
this.ChildrenOfType<DifficultyAdjustSettingsControl>().First(c => c.LabelText == name)
|
||||||
.ChildrenOfType<SettingsSlider<float>>().First().Current.Value = value);
|
.ChildrenOfType<OsuSliderBar<float>>().First().Current.Value = value);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void checkBindableAtValue(string name, float? expectedValue)
|
private void checkBindableAtValue(string name, float? expectedValue)
|
||||||
@ -260,7 +260,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
{
|
{
|
||||||
AddAssert($"Slider {name} at {expectedValue}", () =>
|
AddAssert($"Slider {name} at {expectedValue}", () =>
|
||||||
this.ChildrenOfType<DifficultyAdjustSettingsControl>().First(c => c.LabelText == name)
|
this.ChildrenOfType<DifficultyAdjustSettingsControl>().First(c => c.LabelText == name)
|
||||||
.ChildrenOfType<SettingsSlider<float>>().First().Current.Value == expectedValue);
|
.ChildrenOfType<OsuSliderBar<float>>().First().Current.Value == expectedValue);
|
||||||
}
|
}
|
||||||
|
|
||||||
private void setBeatmapWithDifficultyParameters(float value)
|
private void setBeatmapWithDifficultyParameters(float value)
|
||||||
|
@ -230,7 +230,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
createScreen();
|
createScreen();
|
||||||
AddStep("select diff adjust", () => SelectedMods.Value = new Mod[] { new OsuModDifficultyAdjust() });
|
AddStep("select diff adjust", () => SelectedMods.Value = new Mod[] { new OsuModDifficultyAdjust() });
|
||||||
|
|
||||||
AddStep("set setting", () => modSelectOverlay.ChildrenOfType<SettingsSlider<float>>().First().Current.Value = 8);
|
AddStep("set setting", () => modSelectOverlay.ChildrenOfType<OsuSliderBar<float>>().First().Current.Value = 8);
|
||||||
|
|
||||||
AddAssert("ensure setting is propagated", () => SelectedMods.Value.OfType<OsuModDifficultyAdjust>().Single().CircleSize.Value == 8);
|
AddAssert("ensure setting is propagated", () => SelectedMods.Value.OfType<OsuModDifficultyAdjust>().Single().CircleSize.Value == 8);
|
||||||
|
|
||||||
@ -387,7 +387,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddUntilStep("double time not visible", () => modSelectOverlay.ChildrenOfType<ModPanel>().Where(panel => panel.Mod is OsuModDoubleTime).All(panel => panel.Filtered.Value));
|
AddUntilStep("double time not visible", () => modSelectOverlay.ChildrenOfType<ModPanel>().Where(panel => panel.Mod is OsuModDoubleTime).All(panel => panel.Filtered.Value));
|
||||||
AddAssert("nightcore still visible", () => modSelectOverlay.ChildrenOfType<ModPanel>().Where(panel => panel.Mod is OsuModNightcore).Any(panel => !panel.Filtered.Value));
|
AddAssert("nightcore still visible", () => modSelectOverlay.ChildrenOfType<ModPanel>().Where(panel => panel.Mod is OsuModNightcore).Any(panel => !panel.Filtered.Value));
|
||||||
|
|
||||||
AddStep("make double time valid again", () => modSelectOverlay.IsValidMod = m => true);
|
AddStep("make double time valid again", () => modSelectOverlay.IsValidMod = _ => true);
|
||||||
AddUntilStep("double time visible", () => modSelectOverlay.ChildrenOfType<ModPanel>().Where(panel => panel.Mod is OsuModDoubleTime).Any(panel => !panel.Filtered.Value));
|
AddUntilStep("double time visible", () => modSelectOverlay.ChildrenOfType<ModPanel>().Where(panel => panel.Mod is OsuModDoubleTime).Any(panel => !panel.Filtered.Value));
|
||||||
AddAssert("nightcore still visible", () => modSelectOverlay.ChildrenOfType<ModPanel>().Where(b => b.Mod is OsuModNightcore).Any(panel => !panel.Filtered.Value));
|
AddAssert("nightcore still visible", () => modSelectOverlay.ChildrenOfType<ModPanel>().Where(b => b.Mod is OsuModNightcore).Any(panel => !panel.Filtered.Value));
|
||||||
}
|
}
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Graphics.Sprites;
|
using osu.Game.Graphics.Sprites;
|
||||||
@ -89,7 +88,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddToggleStep("toggle enabled", toggle =>
|
AddToggleStep("toggle enabled", toggle =>
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
button.Action = toggle ? () => { } : (Action)null;
|
button.Action = toggle ? () => { } : null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -3,7 +3,6 @@
|
|||||||
|
|
||||||
#nullable disable
|
#nullable disable
|
||||||
|
|
||||||
using System;
|
|
||||||
using NUnit.Framework;
|
using NUnit.Framework;
|
||||||
using osu.Framework.Graphics;
|
using osu.Framework.Graphics;
|
||||||
using osu.Game.Graphics.UserInterface;
|
using osu.Game.Graphics.UserInterface;
|
||||||
@ -29,7 +28,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
AddToggleStep("toggle enabled", toggle =>
|
AddToggleStep("toggle enabled", toggle =>
|
||||||
{
|
{
|
||||||
for (int i = 0; i < 6; i++)
|
for (int i = 0; i < 6; i++)
|
||||||
button.Action = toggle ? () => { } : (Action)null;
|
button.Action = toggle ? () => { } : null;
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -27,6 +27,8 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
private Live<BeatmapSetInfo> first;
|
private Live<BeatmapSetInfo> first;
|
||||||
|
|
||||||
|
private const int item_count = 100;
|
||||||
|
|
||||||
[SetUp]
|
[SetUp]
|
||||||
public void Setup() => Schedule(() =>
|
public void Setup() => Schedule(() =>
|
||||||
{
|
{
|
||||||
@ -46,7 +48,7 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
|
|
||||||
beatmapSets.Clear();
|
beatmapSets.Clear();
|
||||||
|
|
||||||
for (int i = 0; i < 100; i++)
|
for (int i = 0; i < item_count; i++)
|
||||||
{
|
{
|
||||||
beatmapSets.Add(TestResources.CreateTestBeatmapSetInfo().ToLiveUnmanaged());
|
beatmapSets.Add(TestResources.CreateTestBeatmapSetInfo().ToLiveUnmanaged());
|
||||||
}
|
}
|
||||||
@ -59,6 +61,13 @@ namespace osu.Game.Tests.Visual.UserInterface
|
|||||||
[Test]
|
[Test]
|
||||||
public void TestRearrangeItems()
|
public void TestRearrangeItems()
|
||||||
{
|
{
|
||||||
|
AddUntilStep("wait for load complete", () =>
|
||||||
|
{
|
||||||
|
return this
|
||||||
|
.ChildrenOfType<PlaylistItem>()
|
||||||
|
.Count(i => i.ChildrenOfType<DelayedLoadWrapper>().First().DelayedLoadCompleted) > 6;
|
||||||
|
});
|
||||||
|
|
||||||
AddUntilStep("wait for animations to complete", () => !playlistOverlay.Transforms.Any());
|
AddUntilStep("wait for animations to complete", () => !playlistOverlay.Transforms.Any());
|
||||||
|
|
||||||
AddStep("hold 1st item handle", () =>
|
AddStep("hold 1st item handle", () =>
|
||||||
|
@ -30,7 +30,7 @@ namespace osu.Game.Tournament.Components
|
|||||||
{
|
{
|
||||||
base.Current = new Bindable<string>(string.Empty);
|
base.Current = new Bindable<string>(string.Empty);
|
||||||
|
|
||||||
((OsuTextBox)Control).OnCommit += (sender, newText) =>
|
((OsuTextBox)Control).OnCommit += (sender, _) =>
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -45,7 +45,7 @@ namespace osu.Game.Tournament.Components
|
|||||||
FillMode = FillMode.Fill
|
FillMode = FillMode.Fill
|
||||||
};
|
};
|
||||||
|
|
||||||
(flag = team.FlagName.GetBoundCopy()).BindValueChanged(acronym => flagSprite.Texture = textures.Get($@"Flags/{team.FlagName}"), true);
|
(flag = team.FlagName.GetBoundCopy()).BindValueChanged(_ => flagSprite.Texture = textures.Get($@"Flags/{team.FlagName}"), true);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user