diff --git a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj
index 936808f38b..52b728a115 100644
--- a/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj
+++ b/Templates/Rulesets/ruleset-empty/osu.Game.Rulesets.EmptyFreeform.Tests/osu.Game.Rulesets.EmptyFreeform.Tests.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
index 35e7742172..95b96adab0 100644
--- a/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
+++ b/Templates/Rulesets/ruleset-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj
index c1044965b5..d12403016d 100644
--- a/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj
+++ b/Templates/Rulesets/ruleset-scrolling-empty/osu.Game.Rulesets.EmptyScrolling.Tests/osu.Game.Rulesets.EmptyScrolling.Tests.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
index 35e7742172..95b96adab0 100644
--- a/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
+++ b/Templates/Rulesets/ruleset-scrolling-example/osu.Game.Rulesets.Pippidon.Tests/osu.Game.Rulesets.Pippidon.Tests.csproj
@@ -11,7 +11,7 @@
-
+
diff --git a/UseLocalFramework.ps1 b/UseLocalFramework.ps1
new file mode 100644
index 0000000000..837685f310
--- /dev/null
+++ b/UseLocalFramework.ps1
@@ -0,0 +1,17 @@
+# Run this script to use a local copy of osu-framework rather than fetching it from nuget.
+# It expects the osu-framework directory to be at the same level as the osu directory
+#
+# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects
+
+$CSPROJ="osu.Game/osu.Game.csproj"
+$SLN="osu.sln"
+
+dotnet remove $CSPROJ package ppy.osu.Framework;
+dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj;
+dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj
+
+$SLNF=Get-Content "osu.Desktop.slnf" | ConvertFrom-Json
+$TMP=New-TemporaryFile
+$SLNF.solution.projects += ("../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj")
+ConvertTo-Json $SLNF | Out-File $TMP -Encoding UTF8
+Move-Item -Path $TMP -Destination "osu.Desktop.slnf" -Force
diff --git a/UseLocalFramework.sh b/UseLocalFramework.sh
new file mode 100755
index 0000000000..4fd1fdfd1b
--- /dev/null
+++ b/UseLocalFramework.sh
@@ -0,0 +1,18 @@
+#!/bin/sh
+
+# Run this script to use a local copy of osu-framework rather than fetching it from nuget.
+# It expects the osu-framework directory to be at the same level as the osu directory
+#
+# https://github.com/ppy/osu-framework/wiki/Testing-local-framework-checkout-with-other-projects
+
+CSPROJ="osu.Game/osu.Game.csproj"
+SLN="osu.sln"
+
+dotnet remove $CSPROJ package ppy.osu.Framework
+dotnet sln $SLN add ../osu-framework/osu.Framework/osu.Framework.csproj ../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj
+dotnet add $CSPROJ reference ../osu-framework/osu.Framework/osu.Framework.csproj
+
+SLNF="osu.Desktop.slnf"
+tmp=$(mktemp)
+jq '.solution.projects += ["../osu-framework/osu.Framework/osu.Framework.csproj", "../osu-framework/osu.Framework.NativeLibs/osu.Framework.NativeLibs.csproj"]' osu.Desktop.slnf > $tmp
+mv -f $tmp $SLNF
diff --git a/osu.Android.props b/osu.Android.props
index 8711ceec64..8237a570ff 100644
--- a/osu.Android.props
+++ b/osu.Android.props
@@ -51,11 +51,11 @@
-
-
+
+
-
+
diff --git a/osu.Desktop/osu.Desktop.csproj b/osu.Desktop/osu.Desktop.csproj
index 3f926ed45a..1f4544098b 100644
--- a/osu.Desktop/osu.Desktop.csproj
+++ b/osu.Desktop/osu.Desktop.csproj
@@ -27,7 +27,7 @@
-
+
diff --git a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
index d62d422f33..f47b069373 100644
--- a/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
+++ b/osu.Game.Benchmarks/osu.Game.Benchmarks.csproj
@@ -9,7 +9,7 @@
-
+
diff --git a/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs b/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs
index 16361d12c6..ef34a5d664 100644
--- a/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs
+++ b/osu.Game.Rulesets.Catch.Tests/Editor/Checks/TestCheckBananaShowerGap.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Tests.Editor.Checks
[TestFixture]
public class TestCheckBananaShowerGap
{
- private CheckBananaShowerGap check;
+ private CheckBananaShowerGap check = null!;
[SetUp]
public void Setup()
diff --git a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs
index a4b2b26624..a2d4e7fb1e 100644
--- a/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs
+++ b/osu.Game.Rulesets.Catch.Tests/TestSceneCatchSkinConfiguration.cs
@@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Catch.Tests
public bool FlipCatcherPlate { get; set; }
public TestSkin()
- : base(null)
+ : base(null!)
{
}
diff --git a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
index c9db824615..5a2e8e0bf0 100644
--- a/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
+++ b/osu.Game.Rulesets.Catch.Tests/osu.Game.Rulesets.Catch.Tests.csproj
@@ -3,7 +3,7 @@
-
+
WinExe
diff --git a/osu.Game.Rulesets.Catch/CatchInputManager.cs b/osu.Game.Rulesets.Catch/CatchInputManager.cs
index 5b62154a34..0f76953003 100644
--- a/osu.Game.Rulesets.Catch/CatchInputManager.cs
+++ b/osu.Game.Rulesets.Catch/CatchInputManager.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.ComponentModel;
using osu.Framework.Allocation;
using osu.Framework.Input.Bindings;
diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs b/osu.Game.Rulesets.Catch/CatchSkinComponentLookup.cs
similarity index 73%
rename from osu.Game.Rulesets.Catch/CatchSkinComponent.cs
rename to osu.Game.Rulesets.Catch/CatchSkinComponentLookup.cs
index e79da667da..149aae1cb4 100644
--- a/osu.Game.Rulesets.Catch/CatchSkinComponent.cs
+++ b/osu.Game.Rulesets.Catch/CatchSkinComponentLookup.cs
@@ -1,15 +1,13 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Catch
{
- public class CatchSkinComponent : GameplaySkinComponent
+ public class CatchSkinComponentLookup : GameplaySkinComponentLookup
{
- public CatchSkinComponent(CatchSkinComponents component)
+ public CatchSkinComponentLookup(CatchSkinComponents component)
: base(component)
{
}
diff --git a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs
index 7587de5803..371e901c69 100644
--- a/osu.Game.Rulesets.Catch/CatchSkinComponents.cs
+++ b/osu.Game.Rulesets.Catch/CatchSkinComponents.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
namespace osu.Game.Rulesets.Catch
{
public enum CatchSkinComponents
diff --git a/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs b/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs
index 00fd74c9a8..4b2933c0e1 100644
--- a/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs
+++ b/osu.Game.Rulesets.Catch/Edit/Checks/CheckBananaShowerGap.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Collections.Generic;
using osu.Game.Beatmaps;
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs
index ddfbb34435..8ac5eac227 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawables/CaughtObject.cs
@@ -37,8 +37,8 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
public override bool RemoveWhenNotAlive => true;
- protected CaughtObject(CatchSkinComponents skinComponent, Func defaultImplementation)
- : base(new CatchSkinComponent(skinComponent), defaultImplementation)
+ protected CaughtObject(CatchSkinComponents skinComponent, Func defaultImplementation)
+ : base(new CatchSkinComponentLookup(skinComponent), defaultImplementation)
{
Origin = Anchor.Centre;
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs
index b46a452bd0..80a4150d98 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableBanana.cs
@@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
private void load()
{
ScalingContainer.Child = new SkinnableDrawable(
- new CatchSkinComponent(CatchSkinComponents.Banana),
+ new CatchSkinComponentLookup(CatchSkinComponents.Banana),
_ => new BananaPiece());
}
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs
index d367ad0a00..a81d87480a 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableDroplet.cs
@@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
private void load()
{
ScalingContainer.Child = new SkinnableDrawable(
- new CatchSkinComponent(CatchSkinComponents.Droplet),
+ new CatchSkinComponentLookup(CatchSkinComponents.Droplet),
_ => new DropletPiece());
}
diff --git a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs
index ce4c7e5aff..d7fd79929b 100644
--- a/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs
+++ b/osu.Game.Rulesets.Catch/Objects/Drawables/DrawableFruit.cs
@@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Catch.Objects.Drawables
private void load()
{
ScalingContainer.Child = new SkinnableDrawable(
- new CatchSkinComponent(CatchSkinComponents.Fruit),
+ new CatchSkinComponentLookup(CatchSkinComponents.Fruit),
_ => new FruitPiece());
}
diff --git a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs
index 8dae0a2b78..520c2de248 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Argon/CatchArgonSkinTransformer.cs
@@ -13,11 +13,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon
{
}
- public override Drawable? GetDrawableComponent(ISkinComponent component)
+ public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup)
{
- switch (component)
+ switch (lookup)
{
- case CatchSkinComponent catchComponent:
+ case CatchSkinComponentLookup catchComponent:
// TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries.
switch (catchComponent.Component)
{
@@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Argon
break;
}
- return base.GetDrawableComponent(component);
+ return base.GetDrawableComponent(lookup);
}
}
}
diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs b/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs
index d038ccb31c..4506111498 100644
--- a/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/CatchSkinColour.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
namespace osu.Game.Rulesets.Catch.Skinning
{
public enum CatchSkinColour
diff --git a/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs b/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs
index 65d6acd88d..ea8d742b1a 100644
--- a/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/CatchSkinConfiguration.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
namespace osu.Game.Rulesets.Catch.Skinning
{
public enum CatchSkinConfiguration
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs
index ffeed80615..ee1cc68f7d 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/BananaPulpFormation.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osuTK;
namespace osu.Game.Rulesets.Catch.Skinning.Default
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs
index 60a13bee59..8d8ee49af7 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/BorderPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics;
using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Catch.Objects;
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs
index 3b8df6ee6f..e84e4d4ad2 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/CatchHitObjectPiece.cs
@@ -1,10 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
-using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -21,19 +18,17 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default
public readonly Bindable IndexInBeatmap = new Bindable();
[Resolved]
- protected IHasCatchObjectState ObjectState { get; private set; }
+ protected IHasCatchObjectState ObjectState { get; private set; } = null!;
///
/// A part of this piece that will be faded out while falling in the playfield.
///
- [CanBeNull]
- protected virtual Drawable BorderPiece => null;
+ protected virtual Drawable? BorderPiece => null;
///
/// A part of this piece that will be only visible when is true.
///
- [CanBeNull]
- protected virtual Drawable HyperBorderPiece => null;
+ protected virtual Drawable? HyperBorderPiece => null;
protected override void LoadComplete()
{
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs
index 4148fed11c..e423f21b98 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultCatcher.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs
index 7ea99b3ed9..2650ba765b 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/DefaultHitExplosion.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
@@ -18,10 +16,10 @@ namespace osu.Game.Rulesets.Catch.Skinning.Default
{
public class DefaultHitExplosion : CompositeDrawable, IHitExplosion
{
- private CircularContainer largeFaint;
- private CircularContainer smallFaint;
- private CircularContainer directionalGlow1;
- private CircularContainer directionalGlow2;
+ private CircularContainer largeFaint = null!;
+ private CircularContainer smallFaint = null!;
+ private CircularContainer directionalGlow1 = null!;
+ private CircularContainer directionalGlow2 = null!;
[BackgroundDependencyLoader]
private void load()
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs
index b8ae062382..59e74bff74 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/DropletPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics;
using osu.Game.Rulesets.Catch.Objects;
using osuTK;
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs
index adee960c3c..3bd8032649 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Catch.Objects;
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs
index db51195f11..f097361d2a 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/FruitPulpFormation.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Bindables;
using osu.Game.Rulesets.Catch.Objects;
using osuTK;
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs
index 42b0b85495..c8895f32f4 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/HyperBorderPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics;
using osu.Game.Rulesets.Catch.UI;
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs
index 29cb339625..53a487b97f 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/HyperDropletBorderPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
namespace osu.Game.Rulesets.Catch.Skinning.Default
{
public class HyperDropletBorderPiece : HyperBorderPiece
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs b/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs
index 8ea54617d9..96c6233b41 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/Pulp.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs b/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs
index aa5ef5fb66..8753aa4077 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Default/PulpFormation.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs
index a73b34c9b6..08ac55508a 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/CatchLegacySkinTransformer.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Linq;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -27,14 +25,14 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
{
}
- public override Drawable GetDrawableComponent(ISkinComponent component)
+ public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup)
{
- if (component is SkinnableTargetComponent targetComponent)
+ if (lookup is GlobalSkinComponentLookup targetComponent)
{
- switch (targetComponent.Target)
+ switch (targetComponent.Lookup)
{
- case SkinnableTarget.MainHUDComponents:
- var components = base.GetDrawableComponent(component) as SkinnableTargetComponentsContainer;
+ case GlobalSkinComponentLookup.LookupType.MainHUDComponents:
+ var components = base.GetDrawableComponent(lookup) as SkinnableTargetComponentsContainer;
if (providesComboCounter && components != null)
{
@@ -48,7 +46,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
}
}
- if (component is CatchSkinComponent catchSkinComponent)
+ if (lookup is CatchSkinComponentLookup catchSkinComponent)
{
switch (catchSkinComponent.Component)
{
@@ -97,11 +95,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
return null;
default:
- throw new UnsupportedSkinComponentException(component);
+ throw new UnsupportedSkinComponentException(lookup);
}
}
- return base.GetDrawableComponent(component);
+ return base.GetDrawableComponent(lookup);
}
private bool hasOldStyleCatcherSprite() =>
@@ -112,12 +110,12 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
GetTexture(@"fruit-catcher-idle") != null
|| GetTexture(@"fruit-catcher-idle-0") != null;
- public override IBindable GetConfig(TLookup lookup)
+ public override IBindable? GetConfig(TLookup lookup)
{
switch (lookup)
{
case CatchSkinColour colour:
- var result = (Bindable)base.GetConfig(new SkinCustomColourLookup(colour));
+ var result = (Bindable?)base.GetConfig(new SkinCustomColourLookup(colour));
if (result == null)
return null;
@@ -129,7 +127,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
{
case CatchSkinConfiguration.FlipCatcherPlate:
// Don't flip catcher plate contents if the catcher is provided by this legacy skin.
- if (GetDrawableComponent(new CatchSkinComponent(CatchSkinComponents.Catcher)) != null)
+ if (GetDrawableComponent(new CatchSkinComponentLookup(CatchSkinComponents.Catcher)) != null)
return (IBindable)new Bindable();
break;
diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs
index 9f64a2129e..310da8bf78 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyBananaPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics.Textures;
namespace osu.Game.Rulesets.Catch.Skinning.Legacy
@@ -13,8 +11,8 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
{
base.LoadComplete();
- Texture texture = Skin.GetTexture("fruit-bananas");
- Texture overlayTexture = Skin.GetTexture("fruit-bananas-overlay");
+ Texture? texture = Skin.GetTexture("fruit-bananas");
+ Texture? overlayTexture = Skin.GetTexture("fruit-bananas-overlay");
SetTexture(texture, overlayTexture);
}
diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs
index 5a5288105d..1231ed6d5a 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatchHitObjectPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -19,19 +17,20 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
{
public abstract class LegacyCatchHitObjectPiece : PoolableDrawable
{
- public readonly Bindable AccentColour = new Bindable();
- public readonly Bindable HyperDash = new Bindable();
- public readonly Bindable IndexInBeatmap = new Bindable();
+ protected readonly Bindable IndexInBeatmap = new Bindable();
+
+ private readonly Bindable accentColour = new Bindable();
+ private readonly Bindable hyperDash = new Bindable();
private readonly Sprite colouredSprite;
private readonly Sprite overlaySprite;
private readonly Sprite hyperSprite;
[Resolved]
- protected ISkinSource Skin { get; private set; }
+ protected ISkinSource Skin { get; private set; } = null!;
[Resolved]
- protected IHasCatchObjectState ObjectState { get; private set; }
+ protected IHasCatchObjectState ObjectState { get; private set; } = null!;
protected LegacyCatchHitObjectPiece()
{
@@ -65,26 +64,26 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
{
base.LoadComplete();
- AccentColour.BindTo(ObjectState.AccentColour);
- HyperDash.BindTo(ObjectState.HyperDash);
+ accentColour.BindTo(ObjectState.AccentColour);
+ hyperDash.BindTo(ObjectState.HyperDash);
IndexInBeatmap.BindTo(ObjectState.IndexInBeatmap);
hyperSprite.Colour = Skin.GetConfig(CatchSkinColour.HyperDashFruit)?.Value ??
Skin.GetConfig(CatchSkinColour.HyperDash)?.Value ??
Catcher.DEFAULT_HYPER_DASH_COLOUR;
- AccentColour.BindValueChanged(colour =>
+ accentColour.BindValueChanged(colour =>
{
colouredSprite.Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue);
}, true);
- HyperDash.BindValueChanged(hyper =>
+ hyperDash.BindValueChanged(hyper =>
{
hyperSprite.Alpha = hyper.NewValue ? 0.7f : 0;
}, true);
}
- protected void SetTexture(Texture texture, Texture overlayTexture)
+ protected void SetTexture(Texture? texture, Texture? overlayTexture)
{
colouredSprite.Texture = texture;
overlaySprite.Texture = overlayTexture;
diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs
index 93d79f00d3..667622e6f2 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherNew.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Collections.Generic;
using System.Linq;
@@ -20,11 +18,11 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
public class LegacyCatcherNew : CompositeDrawable
{
[Resolved]
- private Bindable currentState { get; set; }
+ private Bindable currentState { get; set; } = null!;
private readonly Dictionary drawables = new Dictionary();
- private Drawable currentDrawable;
+ private Drawable currentDrawable = null!;
public LegacyCatcherNew()
{
@@ -51,7 +49,8 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
Drawable getDrawableFor(CatcherAnimationState state) =>
skin.GetAnimation(@$"fruit-catcher-{state.ToString().ToLowerInvariant()}", true, true, true) ??
- skin.GetAnimation(@"fruit-catcher-idle", true, true, true);
+ skin.GetAnimation(@"fruit-catcher-idle", true, true, true) ??
+ Empty();
}
protected override void LoadComplete()
diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs
index 736e9cfddf..5f09d1e254 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyCatcherOld.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -21,7 +19,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
{
- InternalChild = skin.GetAnimation(@"fruit-ryuuta", true, true, true).With(d =>
+ InternalChild = (skin.GetAnimation(@"fruit-ryuuta", true, true, true) ?? Empty()).With(d =>
{
d.Anchor = Anchor.TopCentre;
d.Origin = Anchor.TopCentre;
diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs
index f99cedab3f..7007f1cc29 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyDropletPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics.Textures;
using osuTK;
@@ -19,8 +17,8 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
{
base.LoadComplete();
- Texture texture = Skin.GetTexture("fruit-drop");
- Texture overlayTexture = Skin.GetTexture("fruit-drop-overlay");
+ Texture? texture = Skin.GetTexture("fruit-drop");
+ Texture? overlayTexture = Skin.GetTexture("fruit-drop-overlay");
SetTexture(texture, overlayTexture);
}
diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs
index 125a96a446..f002bab219 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyFruitPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Game.Rulesets.Catch.Objects;
namespace osu.Game.Rulesets.Catch.Skinning.Legacy
diff --git a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs
index 8f46bdbe6e..393a1076af 100644
--- a/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs
+++ b/osu.Game.Rulesets.Catch/Skinning/Legacy/LegacyHitExplosion.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Catch.Skinning.Legacy
public class LegacyHitExplosion : CompositeDrawable, IHitExplosion
{
[Resolved]
- private Catcher catcher { get; set; }
+ private Catcher catcher { get; set; } = null!;
private const float catch_margin = (1 - Catcher.ALLOWED_CATCH_RANGE) / 2;
diff --git a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs
index a5b7d8d0af..03f0bc6a55 100644
--- a/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs
+++ b/osu.Game.Rulesets.Catch/UI/CatchComboDisplay.cs
@@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI
private readonly IBindable showCombo = new BindableBool(true);
public CatchComboDisplay()
- : base(new CatchSkinComponent(CatchSkinComponents.CatchComboCounter), _ => Empty())
+ : base(new CatchSkinComponentLookup(CatchSkinComponents.CatchComboCounter), _ => Empty())
{
}
diff --git a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs
index 1ea188d463..9b32893efe 100644
--- a/osu.Game.Rulesets.Catch/UI/HitExplosion.cs
+++ b/osu.Game.Rulesets.Catch/UI/HitExplosion.cs
@@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Catch.UI
Anchor = Anchor.BottomCentre;
Origin = Anchor.BottomCentre;
- InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinComponent(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion())
+ InternalChild = skinnableExplosion = new SkinnableDrawable(new CatchSkinComponentLookup(CatchSkinComponents.HitExplosion), _ => new DefaultHitExplosion())
{
CentreComponent = false,
Anchor = Anchor.BottomCentre,
diff --git a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs
index 25bbc814bf..fa6ccf6bd6 100644
--- a/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs
+++ b/osu.Game.Rulesets.Catch/UI/SkinnableCatcher.cs
@@ -25,7 +25,7 @@ namespace osu.Game.Rulesets.Catch.UI
public readonly Bindable AnimationState = new Bindable();
public SkinnableCatcher()
- : base(new CatchSkinComponent(CatchSkinComponents.Catcher), _ => new DefaultCatcher())
+ : base(new CatchSkinComponentLookup(CatchSkinComponents.Catcher), _ => new DefaultCatcher())
{
Anchor = Anchor.TopCentre;
// Sets the origin roughly to the centre of the catcher's plate to allow for correct scaling.
diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs
index cd26e2a9de..3dece20308 100644
--- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs
+++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneColumnBackground.cs
@@ -30,7 +30,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{
RelativeSizeAxes = Axes.Both,
Width = 0.5f,
- Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground())
+ Child = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground())
{
RelativeSizeAxes = Axes.Both
}
@@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
{
RelativeSizeAxes = Axes.Both,
Width = 0.5f,
- Child = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground())
+ Child = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground())
{
RelativeSizeAxes = Axes.Both
}
diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs
index 0744d7e2e7..5c8e038eed 100644
--- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs
+++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageBackground.cs
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
[BackgroundDependencyLoader]
private void load()
{
- SetContents(_ => new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageBackground),
+ SetContents(_ => new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageBackground),
_ => new DefaultStageBackground())
{
Anchor = Anchor.Centre,
diff --git a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs
index 979c90c802..f9c17ee7f4 100644
--- a/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs
+++ b/osu.Game.Rulesets.Mania.Tests/Skinning/TestSceneStageForeground.cs
@@ -14,7 +14,7 @@ namespace osu.Game.Rulesets.Mania.Tests.Skinning
[BackgroundDependencyLoader]
private void load()
{
- SetContents(_ => new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageForeground), _ => null)
+ SetContents(_ => new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageForeground), _ => null)
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
diff --git a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
index 0d7b03d830..be51dc0e4c 100644
--- a/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
+++ b/osu.Game.Rulesets.Mania.Tests/osu.Game.Rulesets.Mania.Tests.csproj
@@ -3,7 +3,7 @@
-
+
WinExe
diff --git a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs b/osu.Game.Rulesets.Mania/ManiaSkinComponentLookup.cs
similarity index 77%
rename from osu.Game.Rulesets.Mania/ManiaSkinComponent.cs
rename to osu.Game.Rulesets.Mania/ManiaSkinComponentLookup.cs
index f05edb4677..c9ee5af809 100644
--- a/osu.Game.Rulesets.Mania/ManiaSkinComponent.cs
+++ b/osu.Game.Rulesets.Mania/ManiaSkinComponentLookup.cs
@@ -1,19 +1,17 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Mania
{
- public class ManiaSkinComponent : GameplaySkinComponent
+ public class ManiaSkinComponentLookup : GameplaySkinComponentLookup
{
///
- /// Creates a new .
+ /// Creates a new .
///
/// The component.
- public ManiaSkinComponent(ManiaSkinComponents component)
+ public ManiaSkinComponentLookup(ManiaSkinComponents component)
: base(component)
{
}
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs
index 14dbc432ff..c68eec610c 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableHoldNote.cs
@@ -105,7 +105,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
headContainer = new Container { RelativeSizeAxes = Axes.Both }
}
},
- bodyPiece = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HoldNoteBody), _ => new DefaultBodyPiece
+ bodyPiece = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.HoldNoteBody), _ => new DefaultBodyPiece
{
RelativeSizeAxes = Axes.Both,
})
diff --git a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs
index 3c8b1b53b7..cf3149b065 100644
--- a/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs
+++ b/osu.Game.Rulesets.Mania/Objects/Drawables/DrawableNote.cs
@@ -54,7 +54,7 @@ namespace osu.Game.Rulesets.Mania.Objects.Drawables
{
rulesetConfig?.BindWith(ManiaRulesetSetting.TimingBasedNoteColouring, configTimingBasedNoteColouring);
- AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinComponent(Component), _ => new DefaultNotePiece())
+ AddInternal(headPiece = new SkinnableDrawable(new ManiaSkinComponentLookup(Component), _ => new DefaultNotePiece())
{
RelativeSizeAxes = Axes.X,
AutoSizeAxes = Axes.Y
diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs
index ae313e0b91..eb7f63fbe2 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ManiaArgonSkinTransformer.cs
@@ -22,14 +22,14 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
this.beatmap = (ManiaBeatmap)beatmap;
}
- public override Drawable? GetDrawableComponent(ISkinComponent component)
+ public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup)
{
- switch (component)
+ switch (lookup)
{
- case GameplaySkinComponent resultComponent:
+ case GameplaySkinComponentLookup resultComponent:
return new ArgonJudgementPiece(resultComponent.Component);
- case ManiaSkinComponent maniaComponent:
+ case ManiaSkinComponentLookup maniaComponent:
// TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries.
switch (maniaComponent.Component)
{
@@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Argon
break;
}
- return base.GetDrawableComponent(component);
+ return base.GetDrawableComponent(lookup);
}
public override IBindable? GetConfig(TLookup lookup)
diff --git a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs
index 7476af3c3c..f0e214b190 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultBodyPiece.cs
@@ -1,10 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
-using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
@@ -27,8 +24,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default
protected readonly Bindable AccentColour = new Bindable();
protected readonly IBindable IsHitting = new Bindable();
- protected Drawable Background { get; private set; }
- private Container foregroundContainer;
+ protected Drawable Background { get; private set; } = null!;
+ private Container foregroundContainer = null!;
public DefaultBodyPiece()
{
@@ -36,7 +33,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default
}
[BackgroundDependencyLoader(true)]
- private void load([CanBeNull] DrawableHitObject drawableObject)
+ private void load(DrawableHitObject? drawableObject)
{
InternalChildren = new[]
{
@@ -74,9 +71,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default
private readonly LayoutValue subtractionCache = new LayoutValue(Invalidation.DrawSize);
- private BufferedContainer foregroundBuffer;
- private BufferedContainer subtractionBuffer;
- private Container subtractionLayer;
+ private BufferedContainer foregroundBuffer = null!;
+ private BufferedContainer subtractionBuffer = null!;
+ private Container subtractionLayer = null!;
public ForegroundPiece()
{
diff --git a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs
index 72bb05de49..569740deee 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Default/DefaultNotePiece.cs
@@ -1,9 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
-using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
@@ -53,7 +50,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Default
}
[BackgroundDependencyLoader(true)]
- private void load([NotNull] IScrollingInfo scrollingInfo, [CanBeNull] DrawableHitObject drawableObject)
+ private void load(IScrollingInfo scrollingInfo, DrawableHitObject? drawableObject)
{
direction.BindTo(scrollingInfo.Direction);
direction.BindValueChanged(onDirectionChanged, true);
diff --git a/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs b/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs
index 9168a96b95..1f290f1f1c 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Default/IHoldNoteBody.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
namespace osu.Game.Rulesets.Mania.Skinning.Default
{
///
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs
index 362a265789..3c89e2c04a 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/HitTargetInsetContainer.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs
index 49ba503cb5..52bca2aaa0 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyBodyPiece.cs
@@ -1,12 +1,10 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
-using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
+using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
using osu.Framework.Graphics.Textures;
@@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
{
public class LegacyBodyPiece : LegacyManiaColumnElement
{
- private DrawableHoldNote holdNote;
+ private DrawableHoldNote holdNote = null!;
private readonly IBindable direction = new Bindable();
private readonly IBindable isHitting = new Bindable();
@@ -31,14 +29,11 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
///
private readonly Bindable missFadeTime = new Bindable();
- [CanBeNull]
- private Drawable bodySprite;
+ private Drawable? bodySprite;
- [CanBeNull]
- private Drawable lightContainer;
+ private Drawable? lightContainer;
- [CanBeNull]
- private Drawable light;
+ private Drawable? light;
public LegacyBodyPiece()
{
@@ -214,7 +209,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
{
base.Dispose(isDisposing);
- if (holdNote != null)
+ if (holdNote.IsNotNull())
holdNote.ApplyCustomUpdateState -= applyCustomUpdateState;
lightContainer?.Expire();
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs
index f35cedab08..0ed96cf6f1 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyColumnBackground.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -21,8 +19,8 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
{
private readonly IBindable direction = new Bindable();
- private Container lightContainer;
- private Sprite light;
+ private Container lightContainer = null!;
+ private Sprite light = null!;
public LegacyColumnBackground()
{
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs
index 278cf0707c..6b0e1e5d8a 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitExplosion.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@@ -23,7 +21,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
private readonly IBindable direction = new Bindable();
- private Drawable explosion;
+ private Drawable? explosion;
public LegacyHitExplosion()
{
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs
index 611dac30b3..ed78cb6086 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHitTarget.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
{
private readonly IBindable direction = new Bindable();
- private Container directionContainer;
+ private Container directionContainer = null!;
[BackgroundDependencyLoader]
private void load(ISkinSource skin, IScrollingInfo scrollingInfo)
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs
index a653e2ce36..c3ed0111be 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteHeadPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics;
using osu.Game.Skinning;
@@ -10,7 +8,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
{
public class LegacyHoldNoteHeadPiece : LegacyNotePiece
{
- protected override Drawable GetAnimation(ISkinSource skin)
+ protected override Drawable? GetAnimation(ISkinSource skin)
{
// TODO: Should fallback to the head from default legacy skin instead of note.
return GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.HoldNoteHeadImage)
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs
index 7511b008f0..13edc6e495 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyHoldNoteTailPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Game.Rulesets.UI.Scrolling;
@@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
: new ValueChangedEvent(ScrollingDirection.Up, ScrollingDirection.Up));
}
- protected override Drawable GetAnimation(ISkinSource skin)
+ protected override Drawable? GetAnimation(ISkinSource skin)
{
// TODO: Should fallback to the head from default legacy skin instead of note.
return GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.HoldNoteTailImage)
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs
index dfd5af89c1..e7dca3d946 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyKeyArea.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -21,12 +19,12 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
{
private readonly IBindable direction = new Bindable();
- private Container directionContainer;
- private Sprite upSprite;
- private Sprite downSprite;
+ private Container directionContainer = null!;
+ private Sprite upSprite = null!;
+ private Sprite downSprite = null!;
[Resolved]
- private Column column { get; set; }
+ private Column column { get; set; } = null!;
public LegacyKeyArea()
{
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs
index e227c80845..4ffef18781 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaColumnElement.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@@ -19,15 +17,15 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
public class LegacyManiaColumnElement : CompositeDrawable
{
[Resolved]
- protected Column Column { get; private set; }
+ protected Column Column { get; private set; } = null!;
[Resolved]
- private StageDefinition stage { get; set; }
+ private StageDefinition stage { get; set; } = null!;
///
/// The column type identifier to use for texture lookups, in the case of no user-provided configuration.
///
- protected string FallbackColumnIndex { get; private set; }
+ protected string FallbackColumnIndex { get; private set; } = null!;
[BackgroundDependencyLoader]
private void load()
@@ -41,7 +39,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
}
}
- protected IBindable GetColumnSkinConfig(ISkin skin, LegacyManiaSkinConfigurationLookups lookup)
+ protected IBindable? GetColumnSkinConfig(ISkin skin, LegacyManiaSkinConfigurationLookups lookup) where T : notnull
=> skin.GetManiaSkinConfig(lookup, Column.Index);
}
}
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs
index d09a73a693..670a0aad6e 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyManiaJudgementPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
@@ -41,21 +39,15 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
Y = scorePosition ?? 0;
- if (animation != null)
+ InternalChild = animation.With(d =>
{
- InternalChild = animation.With(d =>
- {
- d.Anchor = Anchor.Centre;
- d.Origin = Anchor.Centre;
- });
- }
+ d.Anchor = Anchor.Centre;
+ d.Origin = Anchor.Centre;
+ });
}
public void PlayAnimation()
{
- if (animation == null)
- return;
-
(animation as IFramedAnimation)?.GotoFrame(0);
this.FadeInFromZero(20, Easing.Out)
@@ -86,6 +78,6 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
}
}
- public Drawable GetAboveHitObjectsProxiedContent() => null;
+ public Drawable? GetAboveHitObjectsProxiedContent() => null;
}
}
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs
index 41e149ea2f..8c5a594b3b 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyNotePiece.cs
@@ -1,9 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
-using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -21,10 +18,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
{
private readonly IBindable direction = new Bindable();
- private Container directionContainer;
+ private Container directionContainer = null!;
- [CanBeNull]
- private Drawable noteAnimation;
+ private Drawable noteAnimation = null!;
private float? minimumColumnWidth;
@@ -55,7 +51,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
{
base.Update();
- Texture texture = null;
+ Texture? texture = null;
if (noteAnimation is Sprite sprite)
texture = sprite.Texture;
@@ -84,11 +80,9 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
}
}
- [CanBeNull]
- protected virtual Drawable GetAnimation(ISkinSource skin) => GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.NoteImage);
+ protected virtual Drawable? GetAnimation(ISkinSource skin) => GetAnimationFromLookup(skin, LegacyManiaSkinConfigurationLookups.NoteImage);
- [CanBeNull]
- protected Drawable GetAnimationFromLookup(ISkin skin, LegacyManiaSkinConfigurationLookups lookup)
+ protected Drawable? GetAnimationFromLookup(ISkin skin, LegacyManiaSkinConfigurationLookups lookup)
{
string suffix = string.Empty;
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs
index f7c611d551..8e72e970ab 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/LegacyStageForeground.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -17,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
{
private readonly IBindable direction = new Bindable();
- private Drawable sprite;
+ private Drawable? sprite;
public LegacyStageForeground()
{
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs
index e57927897c..be3372fe58 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaClassicSkinTransformer.cs
@@ -15,7 +15,7 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
{
}
- public override IBindable GetConfig(TLookup lookup)
+ public override IBindable? GetConfig(TLookup lookup)
{
if (lookup is ManiaSkinConfigurationLookup maniaLookup)
{
diff --git a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs
index a07dbea368..f8519beb22 100644
--- a/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/Legacy/ManiaLegacySkinTransformer.cs
@@ -74,14 +74,14 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
});
}
- public override Drawable GetDrawableComponent(ISkinComponent component)
+ public override Drawable GetDrawableComponent(ISkinComponentLookup lookup)
{
- switch (component)
+ switch (lookup)
{
- case GameplaySkinComponent resultComponent:
+ case GameplaySkinComponentLookup resultComponent:
return getResult(resultComponent.Component);
- case ManiaSkinComponent maniaComponent:
+ case ManiaSkinComponentLookup maniaComponent:
if (!isLegacySkin.Value || !hasKeyTexture.Value)
return null;
@@ -120,11 +120,11 @@ namespace osu.Game.Rulesets.Mania.Skinning.Legacy
return new LegacyStageForeground();
default:
- throw new UnsupportedSkinComponentException(component);
+ throw new UnsupportedSkinComponentException(lookup);
}
}
- return base.GetDrawableComponent(component);
+ return base.GetDrawableComponent(lookup);
}
private Drawable getResult(HitResult result)
diff --git a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs
index e22bf63049..0f15bfe12b 100644
--- a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigExtensions.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Bindables;
using osu.Game.Skinning;
@@ -16,8 +14,8 @@ namespace osu.Game.Rulesets.Mania.Skinning
/// The skin from which configuration is retrieved.
/// The value to retrieve.
/// If not null, denotes the index of the column to which the entry applies.
- public static IBindable GetManiaSkinConfig(this ISkin skin, LegacyManiaSkinConfigurationLookups lookup, int? columnIndex = null)
- => skin.GetConfig(
- new ManiaSkinConfigurationLookup(lookup, columnIndex));
+ public static IBindable? GetManiaSkinConfig(this ISkin skin, LegacyManiaSkinConfigurationLookups lookup, int? columnIndex = null)
+ where T : notnull
+ => skin.GetConfig(new ManiaSkinConfigurationLookup(lookup, columnIndex));
}
}
diff --git a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs
index 59188f02f9..6c39ffdcc3 100644
--- a/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs
+++ b/osu.Game.Rulesets.Mania/Skinning/ManiaSkinConfigurationLookup.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Game.Rulesets.Mania.UI;
using osu.Game.Skinning;
diff --git a/osu.Game.Rulesets.Mania/UI/Column.cs b/osu.Game.Rulesets.Mania/UI/Column.cs
index 3d46bdaa7b..de7424773b 100644
--- a/osu.Game.Rulesets.Mania/UI/Column.cs
+++ b/osu.Game.Rulesets.Mania/UI/Column.cs
@@ -76,7 +76,7 @@ namespace osu.Game.Rulesets.Mania.UI
skin.SourceChanged += onSourceChanged;
onSourceChanged();
- Drawable background = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground())
+ Drawable background = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.ColumnBackground), _ => new DefaultColumnBackground())
{
RelativeSizeAxes = Axes.Both,
};
@@ -88,7 +88,7 @@ namespace osu.Game.Rulesets.Mania.UI
// For input purposes, the background is added at the highest depth, but is then proxied back below all other elements
background.CreateProxy(),
HitObjectArea,
- keyArea = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea())
+ keyArea = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.KeyArea), _ => new DefaultKeyArea())
{
RelativeSizeAxes = Axes.Both,
},
diff --git a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
index b26b62f8a5..e5a9ca1e85 100644
--- a/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
+++ b/osu.Game.Rulesets.Mania/UI/Components/ColumnHitObjectArea.cs
@@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Mania.UI.Components
RelativeSizeAxes = Axes.Both,
Depth = 2,
},
- hitTarget = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget())
+ hitTarget = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.HitTarget), _ => new DefaultHitTarget())
{
RelativeSizeAxes = Axes.X,
Depth = 1
diff --git a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs
index a7b94f9f22..8e5c8f9b75 100644
--- a/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs
+++ b/osu.Game.Rulesets.Mania/UI/PoolableHitExplosion.cs
@@ -27,7 +27,7 @@ namespace osu.Game.Rulesets.Mania.UI
[BackgroundDependencyLoader]
private void load()
{
- InternalChild = skinnableExplosion = new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.HitExplosion), _ => new DefaultHitExplosion())
+ InternalChild = skinnableExplosion = new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.HitExplosion), _ => new DefaultHitExplosion())
{
RelativeSizeAxes = Axes.Both
};
diff --git a/osu.Game.Rulesets.Mania/UI/Stage.cs b/osu.Game.Rulesets.Mania/UI/Stage.cs
index 1273cb3d32..8aeaa9cf35 100644
--- a/osu.Game.Rulesets.Mania/UI/Stage.cs
+++ b/osu.Game.Rulesets.Mania/UI/Stage.cs
@@ -73,7 +73,7 @@ namespace osu.Game.Rulesets.Mania.UI
AutoSizeAxes = Axes.X,
Children = new Drawable[]
{
- new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground())
+ new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageBackground), _ => new DefaultStageBackground())
{
RelativeSizeAxes = Axes.Both
},
@@ -98,7 +98,7 @@ namespace osu.Game.Rulesets.Mania.UI
RelativeSizeAxes = Axes.Y,
}
},
- new SkinnableDrawable(new ManiaSkinComponent(ManiaSkinComponents.StageForeground), _ => null)
+ new SkinnableDrawable(new ManiaSkinComponentLookup(ManiaSkinComponents.StageForeground), _ => null)
{
RelativeSizeAxes = Axes.Both
},
diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs
index 7a361b0821..d035d2bc17 100644
--- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs
+++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckLowDiffOverlapsTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using Moq;
@@ -21,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks
[TestFixture]
public class CheckLowDiffOverlapsTest
{
- private CheckLowDiffOverlaps check;
+ private CheckLowDiffOverlaps check = null!;
[SetUp]
public void Setup()
diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs
index a778b76c67..a72aaa966c 100644
--- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs
+++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckOffscreenObjectsTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@@ -23,7 +21,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks
{
private static readonly Vector2 playfield_centre = OsuPlayfield.BASE_SIZE * 0.5f;
- private CheckOffscreenObjects check;
+ private CheckOffscreenObjects check = null!;
[SetUp]
public void Setup()
diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs
index 4e8be75779..348243326d 100644
--- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs
+++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTimeDistanceEqualityTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using Moq;
@@ -21,7 +19,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks
[TestFixture]
public class CheckTimeDistanceEqualityTest
{
- private CheckTimeDistanceEquality check;
+ private CheckTimeDistanceEquality check = null!;
[SetUp]
public void Setup()
diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs
index 39a9d5e798..2ec3637bb7 100644
--- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs
+++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSlidersTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@@ -20,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks
[TestFixture]
public class CheckTooShortSlidersTest
{
- private CheckTooShortSliders check;
+ private CheckTooShortSliders check = null!;
[SetUp]
public void Setup()
diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs
index d044ae732a..f215255bab 100644
--- a/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs
+++ b/osu.Game.Rulesets.Osu.Tests/Editor/Checks/CheckTooShortSpinnersTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@@ -19,8 +17,8 @@ namespace osu.Game.Rulesets.Osu.Tests.Editor.Checks
[TestFixture]
public class CheckTooShortSpinnersTest
{
- private CheckTooShortSpinners check;
- private IBeatmapDifficultyInfo difficulty;
+ private CheckTooShortSpinners check = null!;
+ private IBeatmapDifficultyInfo difficulty = null!;
[SetUp]
public void Setup()
diff --git a/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs
new file mode 100644
index 0000000000..800e6c0711
--- /dev/null
+++ b/osu.Game.Rulesets.Osu.Tests/Editor/TestSceneOsuComposerSelection.cs
@@ -0,0 +1,117 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using System.Linq;
+using NUnit.Framework;
+using osu.Framework.Graphics.Cursor;
+using osu.Framework.Graphics.UserInterface;
+using osu.Framework.Testing;
+using osu.Game.Beatmaps;
+using osu.Game.Graphics.UserInterface;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components;
+using osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders.Components;
+using osu.Game.Rulesets.Osu.Objects;
+using osu.Game.Screens.Edit.Compose.Components;
+using osu.Game.Tests.Beatmaps;
+using osuTK;
+using osuTK.Input;
+
+namespace osu.Game.Rulesets.Osu.Tests.Editor
+{
+ [TestFixture]
+ public class TestSceneOsuComposerSelection : TestSceneOsuEditor
+ {
+ protected override IBeatmap CreateBeatmap(RulesetInfo ruleset) => new TestBeatmap(ruleset, false);
+
+ [Test]
+ public void TestContextMenuShownCorrectlyForSelectedSlider()
+ {
+ var slider = new Slider
+ {
+ StartTime = 0,
+ Position = new Vector2(100, 100),
+ Path = new SliderPath
+ {
+ ControlPoints =
+ {
+ new PathControlPoint(),
+ new PathControlPoint(new Vector2(100))
+ }
+ }
+ };
+ AddStep("add slider", () => EditorBeatmap.Add(slider));
+
+ moveMouseToObject(() => slider);
+ AddStep("left click", () => InputManager.Click(MouseButton.Left));
+ AddUntilStep("slider selected", () => EditorBeatmap.SelectedHitObjects.Single() == slider);
+
+ AddStep("move mouse to centre", () => InputManager.MoveMouseTo(blueprintContainer.ChildrenOfType().Single().ScreenSpaceDrawQuad.Centre));
+ AddStep("right click", () => InputManager.Click(MouseButton.Right));
+ AddUntilStep("context menu is visible", () => contextMenuContainer.ChildrenOfType().Single().State == MenuState.Open);
+ }
+
+ [Test]
+ public void TestSelectionIncludingSliderPreservedOnClick()
+ {
+ var firstSlider = new Slider
+ {
+ StartTime = 0,
+ Position = new Vector2(0, 0),
+ Path = new SliderPath
+ {
+ ControlPoints =
+ {
+ new PathControlPoint(),
+ new PathControlPoint(new Vector2(100))
+ }
+ }
+ };
+ var secondSlider = new Slider
+ {
+ StartTime = 1000,
+ Position = new Vector2(100, 100),
+ Path = new SliderPath
+ {
+ ControlPoints =
+ {
+ new PathControlPoint(),
+ new PathControlPoint(new Vector2(100, -100))
+ }
+ }
+ };
+ var hitCircle = new HitCircle
+ {
+ StartTime = 200,
+ Position = new Vector2(300, 0)
+ };
+
+ AddStep("add objects", () => EditorBeatmap.AddRange(new HitObject[] { firstSlider, secondSlider, hitCircle }));
+ AddStep("select last 2 objects", () => EditorBeatmap.SelectedHitObjects.AddRange(new HitObject[] { secondSlider, hitCircle }));
+
+ moveMouseToObject(() => secondSlider);
+ AddStep("click left mouse", () => InputManager.Click(MouseButton.Left));
+ AddAssert("selection preserved", () => EditorBeatmap.SelectedHitObjects.Count == 2);
+ }
+
+ private ComposeBlueprintContainer blueprintContainer
+ => Editor.ChildrenOfType().First();
+
+ private ContextMenuContainer contextMenuContainer
+ => Editor.ChildrenOfType().First();
+
+ private void moveMouseToObject(Func targetFunc)
+ {
+ AddStep("move mouse to object", () =>
+ {
+ var pos = blueprintContainer.SelectionBlueprints
+ .First(s => s.Item == targetFunc())
+ .ChildrenOfType()
+ .First().ScreenSpaceDrawQuad.Centre;
+
+ InputManager.MoveMouseTo(pos);
+ });
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs
index d3e70a0a01..30f0891344 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneCursorTrail.cs
@@ -96,7 +96,7 @@ namespace osu.Game.Rulesets.Osu.Tests
RelativeSizeAxes = Axes.Both;
}
- public Drawable GetDrawableComponent(ISkinComponent component) => null;
+ public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => null;
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT)
{
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs
index 360815afbf..628082c2a9 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneGameplayCursor.cs
@@ -116,7 +116,7 @@ namespace osu.Game.Rulesets.Osu.Tests
private class TopLeftCursorSkin : ISkin
{
- public Drawable GetDrawableComponent(ISkinComponent component) => null;
+ public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => null;
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => null;
public ISample GetSample(ISampleInfo sampleInfo) => null;
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs
index 57734236da..20aed514db 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneHitCircleArea.cs
@@ -35,7 +35,7 @@ namespace osu.Game.Rulesets.Osu.Tests
hitCircle.ApplyDefaults(new ControlPointInfo(), new BeatmapDifficulty());
- Child = new SkinProvidingContainer(new TrianglesSkin(null))
+ Child = new SkinProvidingContainer(new TrianglesSkin(null!))
{
RelativeSizeAxes = Axes.Both,
Child = drawableHitCircle = new DrawableHitCircle(hitCircle)
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs
index 1767d25e77..bb28b2b217 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneLegacyBeatmapSkin.cs
@@ -31,6 +31,8 @@ namespace osu.Game.Rulesets.Osu.Tests
{
config.BindWith(OsuSetting.BeatmapSkins, BeatmapSkins);
config.BindWith(OsuSetting.BeatmapColours, BeatmapColours);
+
+ config.SetValue(OsuSetting.ComboColourNormalisationAmount, 0f);
}
[TestCase(true, true)]
diff --git a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs
index 036f90b962..878150e467 100644
--- a/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs
+++ b/osu.Game.Rulesets.Osu.Tests/TestSceneSkinFallbacks.cs
@@ -149,11 +149,11 @@ namespace osu.Game.Rulesets.Osu.Tests
this.identifier = identifier;
}
- public Drawable GetDrawableComponent(ISkinComponent component)
+ public Drawable GetDrawableComponent(ISkinComponentLookup lookup)
{
if (!enabled) return null;
- if (component is OsuSkinComponent osuComponent && osuComponent.Component == OsuSkinComponents.SliderBody)
+ if (lookup is OsuSkinComponentLookup osuComponent && osuComponent.Component == OsuSkinComponents.SliderBody)
return null;
return new OsuSpriteText
diff --git a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
index 1eb1c85d93..c10c3ffb15 100644
--- a/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
+++ b/osu.Game.Rulesets.Osu.Tests/osu.Game.Rulesets.Osu.Tests.csproj
@@ -4,7 +4,7 @@
-
+
WinExe
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs
index 71cdbc276e..f16b6c138e 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/HitCircles/Components/HitCircleOverlapMarker.cs
@@ -4,9 +4,12 @@
#nullable disable
using osu.Framework.Allocation;
+using osu.Framework.Bindables;
using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
using osu.Framework.Utils;
+using osu.Game.Configuration;
using osu.Game.Rulesets.Objects.Types;
using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Skinning.Default;
@@ -27,31 +30,45 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components
private readonly RingPiece ring;
+ private readonly Container content;
+
[Resolved]
private EditorClock editorClock { get; set; }
+ private Bindable showHitMarkers;
+
public HitCircleOverlapMarker()
{
Origin = Anchor.Centre;
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
- InternalChildren = new Drawable[]
+ InternalChild = content = new Container
{
- new Circle
+ RelativeSizeAxes = Axes.Both,
+ Children = new Drawable[]
{
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Colour = Color4.White,
- },
- ring = new RingPiece
- {
- BorderThickness = 4,
+ new Circle
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.White,
+ },
+ ring = new RingPiece
+ {
+ BorderThickness = 4,
+ }
}
};
}
+ [BackgroundDependencyLoader]
+ private void load(OsuConfigManager config)
+ {
+ showHitMarkers = config.GetBindable(OsuSetting.EditorShowHitMarkers);
+ }
+
[Resolved]
private ISkinSource skin { get; set; }
@@ -68,21 +85,26 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.HitCircles.Components
double hitObjectTime = hitObject.StartTime;
bool hasReachedObject = editorTime >= hitObjectTime;
- if (hasReachedObject)
+ if (hasReachedObject && showHitMarkers.Value)
{
float alpha = Interpolation.ValueAt(editorTime, 0, 1f, hitObjectTime, hitObjectTime + FADE_OUT_EXTENSION, Easing.In);
float ringScale = MathHelper.Clamp(Interpolation.ValueAt(editorTime, 0, 1f, hitObjectTime, hitObjectTime + FADE_OUT_EXTENSION / 2, Easing.OutQuint), 0, 1);
ring.Scale = new Vector2(1 + 0.1f * ringScale);
- Alpha = 0.9f * (1 - alpha);
+ content.Alpha = 0.9f * (1 - alpha);
}
else
- Alpha = 0;
+ content.Alpha = 0;
+ }
+
+ public override void Show()
+ {
+ // intentional no op so SelectionBlueprint Selection/Deselection logic doesn't touch us.
}
public override void Hide()
{
- // intentional no op so we are not hidden when not selected.
+ // intentional no op so SelectionBlueprint Selection/Deselection logic doesn't touch us.
}
}
}
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs
index 422287918e..11527c9537 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/OsuSelectionBlueprint.cs
@@ -24,7 +24,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints
protected override bool AlwaysShowWhenSelected => true;
protected override bool ShouldBeAlive => base.ShouldBeAlive
- || (editorClock.CurrentTime >= Item.StartTime && editorClock.CurrentTime - Item.GetEndTime() < HitCircleOverlapMarker.FADE_OUT_EXTENSION);
+ || (ShowHitMarkers.Value && editorClock.CurrentTime >= Item.StartTime && editorClock.CurrentTime - Item.GetEndTime() < HitCircleOverlapMarker.FADE_OUT_EXTENSION);
protected OsuSelectionBlueprint(T hitObject)
: base(hitObject)
diff --git a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
index 36ee7c2460..3718f0c6bc 100644
--- a/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Blueprints/Sliders/SliderSelectionBlueprint.cs
@@ -105,8 +105,6 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
return true;
}
- private bool hasSingleObjectSelected => selectedObjects.Count == 1;
-
protected override void Update()
{
base.Update();
@@ -119,10 +117,7 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
{
updateVisualDefinition();
- // In the case more than a single object is selected, block hover from arriving at sliders behind this one.
- // Without doing this, the path visualisers of potentially hundreds of sliders will render, which is not only
- // visually noisy but also functionally useless.
- return !hasSingleObjectSelected;
+ return base.OnHover(e);
}
protected override void OnHoverLost(HoverLostEvent e)
@@ -147,8 +142,8 @@ namespace osu.Game.Rulesets.Osu.Edit.Blueprints.Sliders
private void updateVisualDefinition()
{
- // To reduce overhead of drawing these blueprints, only add extra detail when hovered or when only this slider is selected.
- if (IsSelected && (hasSingleObjectSelected || IsHovered))
+ // To reduce overhead of drawing these blueprints, only add extra detail when only this slider is selected.
+ if (IsSelected && selectedObjects.Count < 2)
{
if (ControlPointVisualiser == null)
{
diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs
index 57e6a6ad1d..084a3e5ea1 100644
--- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckLowDiffOverlaps.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs
index af3521c35c..a342c2a821 100644
--- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckOffscreenObjects.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Checks.Components;
diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs
index 753ddba710..585bd35bd9 100644
--- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTimeDistanceEquality.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Collections.Generic;
using System.Linq;
diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs
index 75eeb91918..159498c479 100644
--- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSliders.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using osu.Game.Beatmaps;
using osu.Game.Rulesets.Edit;
diff --git a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs
index 6b4dc01ab1..f0aade1b7f 100644
--- a/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs
+++ b/osu.Game.Rulesets.Osu/Edit/Checks/CheckTooShortSpinners.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using osu.Game.Rulesets.Edit;
using osu.Game.Rulesets.Edit.Checks.Components;
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
index 36d8ba0189..8c95da9be1 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/Connections/FollowPoint.cs
@@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables.Connections
{
Origin = Anchor.Centre;
- InternalChild = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.FollowPoint), _ => new CircularContainer
+ InternalChild = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.FollowPoint), _ => new CircularContainer
{
Masking = true,
AutoSizeAxes = Axes.Both,
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
index 841a52da7b..6201199cc3 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableHitCircle.cs
@@ -24,7 +24,7 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
- public class DrawableHitCircle : DrawableOsuHitObject, IHasMainCirclePiece, IHasApproachCircle
+ public class DrawableHitCircle : DrawableOsuHitObject, IHasApproachCircle
{
public OsuAction? HitAction => HitArea.HitAction;
protected virtual OsuSkinComponents CirclePieceComponent => OsuSkinComponents.HitCircle;
@@ -81,12 +81,12 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
- CirclePiece = new SkinnableDrawable(new OsuSkinComponent(CirclePieceComponent), _ => new MainCirclePiece())
+ CirclePiece = new SkinnableDrawable(new OsuSkinComponentLookup(CirclePieceComponent), _ => new MainCirclePiece())
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
},
- ApproachCircle = new ProxyableSkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ApproachCircle), _ => new DefaultApproachCircle())
+ ApproachCircle = new ProxyableSkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.ApproachCircle), _ => new DefaultApproachCircle())
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -278,8 +278,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
public override bool RemoveWhenNotAlive => false;
- public ProxyableSkinnableDrawable(ISkinComponent component, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling)
- : base(component, defaultImplementation, confineMode)
+ public ProxyableSkinnableDrawable(ISkinComponentLookup lookup, Func defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling)
+ : base(lookup, defaultImplementation, confineMode)
{
}
}
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs
index e137a503a5..b4abdde911 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableOsuJudgement.cs
@@ -52,7 +52,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Lighting.Alpha = 0;
- if (hitLightingEnabled && Lighting.Drawable != null)
+ if (hitLightingEnabled)
{
// todo: this animation changes slightly based on new/old legacy skin versions.
Lighting.ScaleTo(0.8f).ScaleTo(1.2f, 600, Easing.Out);
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
index 785d15c15b..a4745b365b 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSlider.cs
@@ -83,7 +83,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
- Body = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling),
+ Body = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderBody), _ => new DefaultSliderBody(), confineMode: ConfineMode.NoScaling),
tailContainer = new Container { RelativeSizeAxes = Axes.Both },
tickContainer = new Container { RelativeSizeAxes = Axes.Both },
repeatContainer = new Container { RelativeSizeAxes = Axes.Both },
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs
index 9966ad3a90..35d5c1f478 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderBall.cs
@@ -40,7 +40,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Children = new[]
{
- new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle())
+ new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderFollowCircle), _ => new DefaultFollowCircle())
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
@@ -53,7 +53,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
RelativeSizeAxes = Axes.Both,
Masking = true
},
- ball = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall())
+ ball = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderBall), _ => new DefaultSliderBall())
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs
index 7b9c0c7e40..08602e168c 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderRepeat.cs
@@ -17,7 +17,7 @@ using osuTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
- public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking, IHasMainCirclePiece
+ public class DrawableSliderRepeat : DrawableOsuHitObject, ITrackSnaking
{
public new SliderRepeat HitObject => (SliderRepeat)base.HitObject;
@@ -60,7 +60,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Children = new Drawable[]
{
// no default for this; only visible in legacy skins.
- CirclePiece = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderTailHitCircle), _ => Empty())
+ CirclePiece = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty())
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs
index 063d297f5a..a59cd92d62 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTail.cs
@@ -10,13 +10,12 @@ using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Types;
-using osu.Game.Rulesets.Osu.Skinning.Default;
using osu.Game.Skinning;
using osuTK;
namespace osu.Game.Rulesets.Osu.Objects.Drawables
{
- public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking, IHasMainCirclePiece
+ public class DrawableSliderTail : DrawableOsuHitObject, IRequireTracking
{
public new SliderTailCircle HitObject => (SliderTailCircle)base.HitObject;
@@ -68,7 +67,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Children = new Drawable[]
{
// no default for this; only visible in legacy skins.
- CirclePiece = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderTailHitCircle), _ => Empty())
+ CirclePiece = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderTailHitCircle), _ => Empty())
}
},
});
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs
index 4bd98fc8b2..563c7e85aa 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs
@@ -44,7 +44,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
Origin = Anchor.Centre;
- AddInternal(scaleContainer = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer
+ AddInternal(scaleContainer = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SliderScorePoint), _ => new CircularContainer
{
Masking = true,
Origin = Anchor.Centre,
diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
index 6ae9d5bc34..83a9408570 100644
--- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
+++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSpinner.cs
@@ -92,7 +92,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables
RelativeSizeAxes = Axes.Y,
Children = new Drawable[]
{
- Body = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()),
+ Body = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.SpinnerBody), _ => new DefaultSpinner()),
RotationTracker = new SpinnerRotationTracker(this)
}
},
diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs b/osu.Game.Rulesets.Osu/OsuSkinComponentLookup.cs
similarity index 73%
rename from osu.Game.Rulesets.Osu/OsuSkinComponent.cs
rename to osu.Game.Rulesets.Osu/OsuSkinComponentLookup.cs
index 0abaf2c924..81d5811f85 100644
--- a/osu.Game.Rulesets.Osu/OsuSkinComponent.cs
+++ b/osu.Game.Rulesets.Osu/OsuSkinComponentLookup.cs
@@ -1,15 +1,13 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Osu
{
- public class OsuSkinComponent : GameplaySkinComponent
+ public class OsuSkinComponentLookup : GameplaySkinComponentLookup
{
- public OsuSkinComponent(OsuSkinComponents component)
+ public OsuSkinComponentLookup(OsuSkinComponents component)
: base(component)
{
}
diff --git a/osu.Game.Rulesets.Osu/OsuSkinComponents.cs b/osu.Game.Rulesets.Osu/OsuSkinComponents.cs
index 4248cce55a..8fdf3821fa 100644
--- a/osu.Game.Rulesets.Osu/OsuSkinComponents.cs
+++ b/osu.Game.Rulesets.Osu/OsuSkinComponents.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
namespace osu.Game.Rulesets.Osu
{
public enum OsuSkinComponents
diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs
index 4669b5b913..f99d4275bd 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerDisc.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
-using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.ObjectExtensions;
@@ -16,7 +15,6 @@ using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osu.Game.Rulesets.Osu.Skinning.Default;
using osuTK;
-using osuTK.Graphics;
namespace osu.Game.Rulesets.Osu.Skinning.Argon
{
@@ -52,6 +50,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
private Container centre = null!;
private CircularContainer fill = null!;
+ private Container ticksContainer = null!;
+ private ArgonSpinnerTicks ticks = null!;
+
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableHitObject)
{
@@ -70,41 +71,85 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
RelativeSizeAxes = Axes.Both,
Children = new Drawable[]
{
- fill = new CircularContainer
+ new Container
{
- Name = @"Fill",
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
RelativeSizeAxes = Axes.Both,
- Masking = true,
- EdgeEffect = new EdgeEffectParameters
+ Padding = new MarginPadding(8f),
+ Children = new[]
{
- Type = EdgeEffectType.Shadow,
- Colour = Colour4.FromHex("FC618F").Opacity(1f),
- Radius = 40,
+ fill = new CircularContainer
+ {
+ Name = @"Fill",
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Masking = true,
+ EdgeEffect = new EdgeEffectParameters
+ {
+ Type = EdgeEffectType.Shadow,
+ Colour = Colour4.FromHex("FC618F").Opacity(1f),
+ Radius = 40,
+ },
+ Child = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0f,
+ AlwaysPresent = true,
+ }
+ },
+ ticksContainer = new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Child = ticks = new ArgonSpinnerTicks(),
+ }
},
- Child = new Box
- {
- RelativeSizeAxes = Axes.Both,
- Alpha = 0f,
- AlwaysPresent = true,
- }
},
- new CircularContainer
+ new Container
{
Name = @"Ring",
Masking = true,
- BorderColour = Color4.White,
- BorderThickness = 5,
RelativeSizeAxes = Axes.Both,
- Child = new Box
+ Padding = new MarginPadding(8f),
+ Children = new[]
{
- RelativeSizeAxes = Axes.Both,
- Alpha = 0,
- AlwaysPresent = true,
+ new ArgonSpinnerRingArc
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Name = "Top Arc",
+ },
+ new ArgonSpinnerRingArc
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Name = "Bottom Arc",
+ Scale = new Vector2(1, -1),
+ },
+ }
+ },
+ new Container
+ {
+ Name = @"Sides",
+ RelativeSizeAxes = Axes.Both,
+ Children = new[]
+ {
+ new ArgonSpinnerProgressArc
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Name = "Left Bar"
+ },
+ new ArgonSpinnerProgressArc
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Name = "Right Bar",
+ Scale = new Vector2(-1, 1),
+ },
}
},
- new ArgonSpinnerTicks(),
}
},
centre = new Container
@@ -138,6 +183,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
updateStateTransforms(drawableSpinner, drawableSpinner.State.Value);
}
+ private float trackingElementInterpolation;
+
protected override void Update()
{
base.Update();
@@ -157,17 +204,18 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
}
else
{
- fill.Alpha = (float)Interpolation.Damp(fill.Alpha, drawableSpinner.RotationTracker.Tracking ? tracking_alpha : idle_alpha, 0.98f, (float)Math.Abs(Clock.ElapsedFrameTime));
- }
+ trackingElementInterpolation =
+ (float)Interpolation.Damp(trackingElementInterpolation, drawableSpinner.RotationTracker.Tracking ? 1 : 0, 0.985f, (float)Math.Abs(Clock.ElapsedFrameTime));
- if (centre.Width == idle_centre_size && drawableSpinner.Result?.TimeStarted != null)
- updateCentrePieceSize();
+ fill.Alpha = trackingElementInterpolation * (tracking_alpha - idle_alpha) + idle_alpha;
+ centre.Size = new Vector2(trackingElementInterpolation * (tracking_centre_size - idle_centre_size) + idle_centre_size);
+ }
const float initial_fill_scale = 0.1f;
float targetScale = initial_fill_scale + (0.98f - initial_fill_scale) * drawableSpinner.Progress;
fill.Scale = new Vector2((float)Interpolation.Lerp(fill.Scale.X, targetScale, Math.Clamp(Math.Abs(Time.Elapsed) / 100, 0, 1)));
- disc.Rotation = drawableSpinner.RotationTracker.Rotation;
+ ticks.Rotation = drawableSpinner.RotationTracker.Rotation;
}
private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
@@ -180,35 +228,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt))
{
this.ScaleTo(initial_scale);
- this.RotateTo(0);
+ ticksContainer.RotateTo(0);
+ centre.ScaleTo(0);
+ disc.ScaleTo(0);
using (BeginDelayedSequence(spinner.TimePreempt / 2))
{
// constant ambient rotation to give the spinner "spinning" character.
- this.RotateTo((float)(25 * spinner.Duration / 2000), spinner.TimePreempt + spinner.Duration);
+ ticksContainer.RotateTo((float)(25 * spinner.Duration / 2000), spinner.TimePreempt + spinner.Duration);
}
- using (BeginDelayedSequence(spinner.TimePreempt + spinner.Duration + drawableHitObject.Result.TimeOffset))
- {
- switch (state)
- {
- case ArmedState.Hit:
- this.ScaleTo(initial_scale * 1.2f, 320, Easing.Out);
- this.RotateTo(Rotation + 180, 320);
- break;
-
- case ArmedState.Miss:
- this.ScaleTo(initial_scale * 0.8f, 320, Easing.In);
- break;
- }
- }
- }
-
- using (BeginAbsoluteSequence(spinner.StartTime - spinner.TimePreempt))
- {
- centre.ScaleTo(0);
- disc.ScaleTo(0);
-
using (BeginDelayedSequence(spinner.TimePreempt / 2))
{
centre.ScaleTo(0.3f, spinner.TimePreempt / 4, Easing.OutQuint);
@@ -220,20 +249,22 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
disc.ScaleTo(1, spinner.TimePreempt / 2, Easing.OutQuint);
}
}
+
+ using (BeginDelayedSequence(spinner.TimePreempt + spinner.Duration + drawableHitObject.Result.TimeOffset))
+ {
+ switch (state)
+ {
+ case ArmedState.Hit:
+ disc.ScaleTo(initial_scale * 1.2f, 320, Easing.Out);
+ ticksContainer.RotateTo(ticksContainer.Rotation + 180, 320);
+ break;
+
+ case ArmedState.Miss:
+ disc.ScaleTo(initial_scale * 0.8f, 320, Easing.In);
+ break;
+ }
+ }
}
-
- if (drawableSpinner.Result?.TimeStarted != null)
- updateCentrePieceSize();
- }
-
- private void updateCentrePieceSize()
- {
- Debug.Assert(drawableSpinner.Result?.TimeStarted != null);
-
- Spinner spinner = drawableSpinner.HitObject;
-
- using (BeginAbsoluteSequence(drawableSpinner.Result.TimeStarted.Value))
- centre.ResizeTo(new Vector2(tracking_centre_size), spinner.TimePreempt / 2, Easing.OutQuint);
}
protected override void Dispose(bool isDisposing)
diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs
new file mode 100644
index 0000000000..e998f55755
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerProgressArc.cs
@@ -0,0 +1,71 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using osu.Framework.Allocation;
+using osu.Framework.Extensions.Color4Extensions;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.UserInterface;
+using osu.Framework.Utils;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
+using osuTK.Graphics;
+
+namespace osu.Game.Rulesets.Osu.Skinning.Argon
+{
+ public class ArgonSpinnerProgressArc : CompositeDrawable
+ {
+ private const float arc_fill = 0.15f;
+ private const float arc_radius = 0.12f;
+
+ private CircularProgress fill = null!;
+
+ private DrawableSpinner spinner = null!;
+
+ private CircularProgress background = null!;
+
+ [BackgroundDependencyLoader]
+ private void load(DrawableHitObject drawableHitObject)
+ {
+ RelativeSizeAxes = Axes.Both;
+
+ spinner = (DrawableSpinner)drawableHitObject;
+
+ InternalChildren = new Drawable[]
+ {
+ background = new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Colour = Color4.White.Opacity(0.25f),
+ RelativeSizeAxes = Axes.Both,
+ Current = { Value = arc_fill },
+ Rotation = 90 - arc_fill * 180,
+ InnerRadius = arc_radius,
+ RoundedCaps = true,
+ },
+ fill = new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ InnerRadius = arc_radius,
+ RoundedCaps = true,
+ }
+ };
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+
+ background.Alpha = spinner.Progress >= 1 ? 0 : 1;
+
+ fill.Alpha = (float)Interpolation.DampContinuously(fill.Alpha, spinner.Progress > 0 && spinner.Progress < 1 ? 1 : 0, 40f, (float)Math.Abs(Time.Elapsed));
+ fill.Current.Value = (float)Interpolation.DampContinuously(fill.Current.Value, spinner.Progress >= 1 ? 0 : arc_fill * spinner.Progress, 40f, (float)Math.Abs(Time.Elapsed));
+
+ fill.Rotation = (float)(90 - fill.Current.Value * 180);
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs
new file mode 100644
index 0000000000..57fb57a09e
--- /dev/null
+++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSpinnerRingArc.cs
@@ -0,0 +1,53 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.UserInterface;
+using osu.Framework.Utils;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Osu.Objects.Drawables;
+
+namespace osu.Game.Rulesets.Osu.Skinning.Argon
+{
+ public class ArgonSpinnerRingArc : CompositeDrawable
+ {
+ private const float arc_fill = 0.31f;
+ private const float arc_fill_complete = 0.50f;
+
+ private const float arc_radius = 0.02f;
+
+ private DrawableSpinner spinner = null!;
+ private CircularProgress fill = null!;
+
+ [BackgroundDependencyLoader]
+ private void load(DrawableHitObject drawableHitObject)
+ {
+ RelativeSizeAxes = Axes.Both;
+
+ spinner = (DrawableSpinner)drawableHitObject;
+ InternalChild = fill = new CircularProgress
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Current = { Value = arc_fill },
+ Rotation = -arc_fill * 180,
+ InnerRadius = arc_radius,
+ RoundedCaps = true,
+ };
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+
+ fill.Current.Value = (float)Interpolation.DampContinuously(fill.Current.Value, spinner.Progress >= 1 ? arc_fill_complete : arc_fill, 40f, (float)Math.Abs(Time.Elapsed));
+ fill.InnerRadius = (float)Interpolation.DampContinuously(fill.InnerRadius, spinner.Progress >= 1 ? arc_radius * 2.2f : arc_radius, 40f, (float)Math.Abs(Time.Elapsed));
+
+ fill.Rotation = (float)(-fill.Current.Value * 180);
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs
index bf507db50c..86194d2c43 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs
@@ -14,14 +14,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
{
}
- public override Drawable? GetDrawableComponent(ISkinComponent component)
+ public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup)
{
- switch (component)
+ switch (lookup)
{
- case GameplaySkinComponent resultComponent:
+ case GameplaySkinComponentLookup resultComponent:
return new ArgonJudgementPiece(resultComponent.Component);
- case OsuSkinComponent osuComponent:
+ case OsuSkinComponentLookup osuComponent:
// TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries.
switch (osuComponent.Component)
{
@@ -62,7 +62,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon
break;
}
- return base.GetDrawableComponent(component);
+ return base.GetDrawableComponent(lookup);
}
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs
index 40e9f69963..4a679cda2c 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/CirclePiece.cs
@@ -1,9 +1,8 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
+using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@@ -17,9 +16,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
public class CirclePiece : CompositeDrawable
{
[Resolved]
- private DrawableHitObject drawableObject { get; set; }
+ private DrawableHitObject drawableObject { get; set; } = null!;
- private TrianglesPiece triangles;
+ private TrianglesPiece triangles = null!;
public CirclePiece()
{
@@ -72,7 +71,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
base.Dispose(isDisposing);
- if (drawableObject != null)
+ if (drawableObject.IsNotNull())
drawableObject.HitObjectApplied -= onHitObjectApplied;
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs
index 251fd8d948..3a67ad526e 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultApproachCircle.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
private readonly IBindable accentColour = new Bindable();
[Resolved]
- private DrawableHitObject drawableObject { get; set; }
+ private DrawableHitObject drawableObject { get; set; } = null!;
public DefaultApproachCircle()
: base("Gameplay/osu/approachcircle")
@@ -37,9 +35,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
accentColour.BindValueChanged(colour => Colour = colour.NewValue, true);
}
- protected override Drawable CreateDefault(ISkinComponent component)
+ protected override Drawable CreateDefault(ISkinComponentLookup lookup)
{
- var drawable = base.CreateDefault(component);
+ var drawable = base.CreateDefault(lookup);
// Although this is a non-legacy component, osu-resources currently stores approach circle as a legacy-like texture.
// See LegacyApproachCircle for documentation as to why this is required.
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs
index a215b3b1f0..a975030630 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinner.cs
@@ -1,12 +1,11 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Globalization;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
+using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Graphics;
@@ -18,12 +17,12 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
public class DefaultSpinner : CompositeDrawable
{
- private DrawableSpinner drawableSpinner;
+ private DrawableSpinner drawableSpinner = null!;
- private OsuSpriteText bonusCounter;
+ private OsuSpriteText bonusCounter = null!;
- private Container spmContainer;
- private OsuSpriteText spmCounter;
+ private Container spmContainer = null!;
+ private OsuSpriteText spmCounter = null!;
public DefaultSpinner()
{
@@ -81,8 +80,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
});
}
- private IBindable gainedBonus;
- private IBindable spinsPerMinute;
+ private IBindable gainedBonus = null!;
+ private IBindable spinsPerMinute = null!;
protected override void LoadComplete()
{
@@ -135,7 +134,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
base.Dispose(isDisposing);
- if (drawableSpinner != null)
+ if (drawableSpinner.IsNotNull())
drawableSpinner.ApplyCustomUpdateState -= updateStateTransforms;
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs
index 60489c1b22..b58daf7174 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultSpinnerDisc.cs
@@ -1,12 +1,11 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Extensions.Color4Extensions;
+using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Utils;
@@ -21,7 +20,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
public class DefaultSpinnerDisc : CompositeDrawable
{
- private DrawableSpinner drawableSpinner;
+ private DrawableSpinner drawableSpinner = null!;
private const float initial_scale = 1.3f;
private const float idle_alpha = 0.2f;
@@ -30,15 +29,15 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
private Color4 normalColour;
private Color4 completeColour;
- private SpinnerTicks ticks;
+ private SpinnerTicks ticks = null!;
private int wholeRotationCount;
private readonly BindableBool complete = new BindableBool();
- private SpinnerFill fill;
- private Container mainContainer;
- private SpinnerCentreLayer centre;
- private SpinnerBackgroundLayer background;
+ private SpinnerFill fill = null!;
+ private Container mainContainer = null!;
+ private SpinnerCentreLayer centre = null!;
+ private SpinnerBackgroundLayer background = null!;
public DefaultSpinnerDisc()
{
@@ -214,7 +213,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
base.Dispose(isDisposing);
- if (drawableSpinner != null)
+ if (drawableSpinner.IsNotNull())
drawableSpinner.ApplyCustomUpdateState -= updateStateTransforms;
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs
index e3a83a9280..883524f334 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/DrawableSliderPath.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics.Lines;
using osuTK.Graphics;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs
index 6ee8a12132..f8010a9971 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/ExplodePiece.cs
@@ -1,9 +1,8 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
+using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Objects.Drawables;
@@ -15,9 +14,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
public class ExplodePiece : Container
{
[Resolved]
- private DrawableHitObject drawableObject { get; set; }
+ private DrawableHitObject drawableObject { get; set; } = null!;
- private TrianglesPiece triangles;
+ private TrianglesPiece triangles = null!;
public ExplodePiece()
{
@@ -56,7 +55,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
base.Dispose(isDisposing);
- if (drawableObject != null)
+ if (drawableObject.IsNotNull())
drawableObject.HitObjectApplied -= onHitObjectApplied;
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs
index 98a8b39f6f..06ee64d8b3 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/FlashPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs
index 2360bc2238..f5e01b802e 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/GlowPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/IHasMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/IHasMainCirclePiece.cs
deleted file mode 100644
index 0ba7998d43..0000000000
--- a/osu.Game.Rulesets.Osu/Skinning/Default/IHasMainCirclePiece.cs
+++ /dev/null
@@ -1,14 +0,0 @@
-// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
-// See the LICENCE file in the repository root for full licence text.
-
-#nullable disable
-
-using osu.Game.Skinning;
-
-namespace osu.Game.Rulesets.Osu.Skinning.Default
-{
- public interface IHasMainCirclePiece
- {
- SkinnableDrawable CirclePiece { get; }
- }
-}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs b/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs
index a1cfd170a6..506f679836 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/KiaiFlash.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Audio.Track;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs
index 4acc406ae1..6d56d21349 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/MainCirclePiece.cs
@@ -1,10 +1,9 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Bindables;
+using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Objects.Drawables;
@@ -46,7 +45,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
private readonly IBindable indexInCurrentCombo = new Bindable();
[Resolved]
- private DrawableHitObject drawableObject { get; set; }
+ private DrawableHitObject drawableObject { get; set; } = null!;
[BackgroundDependencyLoader]
private void load()
@@ -113,7 +112,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
base.Dispose(isDisposing);
- if (drawableObject != null)
+ if (drawableObject.IsNotNull())
drawableObject.ApplyCustomUpdateState -= updateStateTransforms;
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs
index 8d8d9e0d94..d73c94eb9b 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/ManualSliderBody.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using osuTK;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs
index f6759c1093..60cfecfb5a 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/NumberPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -41,7 +39,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
Colour = Color4.White.Opacity(0.5f),
},
},
- number = new SkinnableSpriteText(new OsuSkinComponent(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText
+ number = new SkinnableSpriteText(new OsuSkinComponentLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText
{
Font = OsuFont.Numeric.With(size: 40),
UseFullGlyphHeight = false,
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs
index 6c422cf127..96af59abe2 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/PlaySliderBody.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Rulesets.Objects.Drawables;
@@ -20,10 +18,10 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
protected IBindable AccentColourBindable { get; private set; } = null!;
- private IBindable pathVersion;
+ private IBindable pathVersion = null!;
[Resolved(CanBeNull = true)]
- private OsuRulesetConfigManager config { get; set; }
+ private OsuRulesetConfigManager? config { get; set; }
private readonly Bindable configSnakingOut = new Bindable();
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs
index 8f682d02f6..222e8d4348 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/ReverseArrowPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Graphics;
@@ -19,7 +17,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
public class ReverseArrowPiece : BeatSyncedContainer
{
[Resolved]
- private DrawableHitObject drawableRepeat { get; set; }
+ private DrawableHitObject drawableRepeat { get; set; } = null!;
public ReverseArrowPiece()
{
@@ -31,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
Size = new Vector2(OsuHitObject.OBJECT_RADIUS * 2);
- Child = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon
+ Child = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.ReverseArrow), _ => new SpriteIcon
{
RelativeSizeAxes = Axes.Both,
Blending = BlendingParameters.Additive,
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs
index a9b7ddf86f..a1184a15cd 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerBackgroundLayer.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs
index ef7b4c2c96..3dd5aed6ae 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerCentreLayer.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -19,11 +17,11 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
public class SpinnerCentreLayer : CompositeDrawable, IHasAccentColour
{
- private DrawableSpinner spinner;
+ private DrawableSpinner spinner = null!;
- private CirclePiece circle;
- private GlowPiece glow;
- private SpriteIcon symbol;
+ private CirclePiece circle = null!;
+ private GlowPiece glow = null!;
+ private SpriteIcon symbol = null!;
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableHitObject)
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs
index b7ec9e9799..f574ae589e 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerFill.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Effects;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs
index 97cebc3123..3a9f73404d 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerRotationTracker.cs
@@ -1,11 +1,10 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
+using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Input.Events;
@@ -23,6 +22,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
private readonly DrawableSpinner drawableSpinner;
+ private Vector2 mousePosition;
+
+ private float lastAngle;
+ private float currentRotation;
+
+ private bool rotationTransferred;
+
+ [Resolved(canBeNull: true)]
+ private IGameplayClock? gameplayClock { get; set; }
+
public SpinnerRotationTracker(DrawableSpinner drawableSpinner)
{
this.drawableSpinner = drawableSpinner;
@@ -51,16 +60,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
return base.OnMouseMove(e);
}
- private Vector2 mousePosition;
-
- private float lastAngle;
- private float currentRotation;
-
- private bool rotationTransferred;
-
- [Resolved(canBeNull: true)]
- private IGameplayClock gameplayClock { get; set; }
-
protected override void Update()
{
base.Update();
@@ -126,7 +125,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
base.Dispose(isDisposing);
- if (drawableSpinner != null)
+ if (drawableSpinner.IsNotNull())
drawableSpinner.HitObjectApplied -= resetState;
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs
index df72223214..9feaa0966a 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerSpmCalculator.cs
@@ -1,12 +1,11 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
+using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Utils;
using osu.Game.Rulesets.Objects.Drawables;
@@ -26,7 +25,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
private readonly Bindable result = new BindableDouble();
[Resolved]
- private DrawableHitObject drawableSpinner { get; set; }
+ private DrawableHitObject drawableSpinner { get; set; } = null!;
protected override void LoadComplete()
{
@@ -66,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
{
base.Dispose(isDisposing);
- if (drawableSpinner != null)
+ if (drawableSpinner.IsNotNull())
drawableSpinner.HitObjectApplied -= resetState;
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs
index b66cbe41b6..e518ae1da8 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/SpinnerTicks.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Linq;
using osu.Framework.Extensions.Color4Extensions;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs
index 7399ddbd1b..fa23c60d57 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Default/TrianglesPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Game.Graphics.Backgrounds;
namespace osu.Game.Rulesets.Osu.Skinning.Default
diff --git a/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs
index 8ebab97503..5ddca03fa1 100644
--- a/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/IHasApproachCircle.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics;
namespace osu.Game.Rulesets.Osu.Skinning
@@ -15,6 +13,6 @@ namespace osu.Game.Rulesets.Osu.Skinning
///
/// The approach circle drawable.
///
- Drawable ApproachCircle { get; }
+ Drawable? ApproachCircle { get; }
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs
index 03406d37ff..4dd4f9562a 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyApproachCircle.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -18,7 +16,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
private readonly IBindable accentColour = new Bindable();
[Resolved]
- private DrawableHitObject drawableObject { get; set; }
+ private DrawableHitObject drawableObject { get; set; } = null!;
public LegacyApproachCircle()
: base("Gameplay/osu/approachcircle")
@@ -37,9 +35,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
accentColour.BindValueChanged(colour => Colour = LegacyColourCompatibility.DisallowZeroAlpha(colour.NewValue), true);
}
- protected override Drawable CreateDefault(ISkinComponent component)
+ protected override Drawable CreateDefault(ISkinComponentLookup lookup)
{
- var drawable = base.CreateDefault(component);
+ var drawable = base.CreateDefault(lookup);
// account for the sprite being used for the default approach circle being taken from stable,
// when hitcircles have 5px padding on each size. this should be removed if we update the sprite.
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs
index 4465f9c266..b2ffc171be 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursor.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Rulesets.Osu.UI.Cursor;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs
index ee75b8a857..a28b480753 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorParticles.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Linq;
using osu.Framework.Allocation;
@@ -27,19 +25,19 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
public class LegacyCursorParticles : CompositeDrawable, IKeyBindingHandler
{
- public bool Active => breakSpewer?.Active.Value == true || kiaiSpewer?.Active.Value == true;
+ public bool Active => breakSpewer.Active.Value || kiaiSpewer.Active.Value;
- private LegacyCursorParticleSpewer breakSpewer;
- private LegacyCursorParticleSpewer kiaiSpewer;
+ private LegacyCursorParticleSpewer breakSpewer = null!;
+ private LegacyCursorParticleSpewer kiaiSpewer = null!;
[Resolved(canBeNull: true)]
- private Player player { get; set; }
+ private Player? player { get; set; }
[Resolved(canBeNull: true)]
- private OsuPlayfield playfield { get; set; }
+ private OsuPlayfield? playfield { get; set; }
[Resolved(canBeNull: true)]
- private GameplayState gameplayState { get; set; }
+ private GameplayState? gameplayState { get; set; }
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
@@ -79,7 +77,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
if (playfield == null || gameplayState == null) return;
- DrawableHitObject kiaiHitObject = null;
+ DrawableHitObject? kiaiHitObject = null;
// Check whether currently in a kiai section first. This is only done as an optimisation to avoid enumerating AliveObjects when not necessary.
if (gameplayState.Beatmap.ControlPointInfo.EffectPointAt(Time.Current).KiaiMode)
@@ -152,7 +150,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
protected override bool CanSpawnParticles => base.CanSpawnParticles && cursorScreenPosition.HasValue;
protected override float ParticleGravity => 240;
- public LegacyCursorParticleSpewer(Texture texture, int perSecond)
+ public LegacyCursorParticleSpewer(Texture? texture, int perSecond)
: base(texture, perSecond, particle_duration_max)
{
Active.BindValueChanged(_ => resetVelocityCalculation());
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs
index e62754c6ce..9a59fd73b2 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyCursorTrail.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@@ -22,7 +20,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
private bool disjointTrail;
private double lastTrailTime;
- private IBindable cursorSize;
+
+ private IBindable cursorSize = null!;
private Vector2? currentPosition;
@@ -34,6 +33,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
[BackgroundDependencyLoader]
private void load(OsuConfigManager config)
{
+ cursorSize = config.GetBindable(OsuSetting.GameplayCursorSize).GetBoundCopy();
+
Texture = skin.GetTexture("cursortrail");
disjointTrail = skin.GetTexture("cursormiddle") == null;
@@ -54,8 +55,6 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
// stable "magic ratio". see OsuPlayfieldAdjustmentContainer for full explanation.
Texture.ScaleAdjust *= 1.6f;
}
-
- cursorSize = config.GetBindable(OsuSetting.GameplayCursorSize).GetBoundCopy();
}
protected override double FadeDuration => disjointTrail ? 150 : 500;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs
index a6e62b83e4..e155c1b816 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyMainCirclePiece.cs
@@ -87,7 +87,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
if (hasNumber)
{
- OverlayLayer.Add(hitCircleText = new SkinnableSpriteText(new OsuSkinComponent(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText
+ OverlayLayer.Add(hitCircleText = new SkinnableSpriteText(new OsuSkinComponentLookup(OsuSkinComponents.HitCircleText), _ => new OsuSpriteText
{
Font = OsuFont.Numeric.With(size: 40),
UseFullGlyphHeight = false,
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs
index 71c3e4c9f0..f950d3e43e 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyNewStyleSpinner.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -23,15 +21,15 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
///
public class LegacyNewStyleSpinner : LegacySpinner
{
- private Sprite glow;
- private Sprite discBottom;
- private Sprite discTop;
- private Sprite spinningMiddle;
- private Sprite fixedMiddle;
+ private Sprite glow = null!;
+ private Sprite discBottom = null!;
+ private Sprite discTop = null!;
+ private Sprite spinningMiddle = null!;
+ private Sprite fixedMiddle = null!;
private readonly Color4 glowColour = new Color4(3, 151, 255, 255);
- private Container scaleContainer;
+ private Container scaleContainer = null!;
[BackgroundDependencyLoader]
private void load(ISkinSource source)
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs
index a5a765fc02..e5efb668bc 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyOldStyleSpinner.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -23,9 +21,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
///
public class LegacyOldStyleSpinner : LegacySpinner
{
- private Sprite disc;
- private Sprite metreSprite;
- private Container metre;
+ private Sprite disc = null!;
+ private Sprite metreSprite = null!;
+ private Container metre = null!;
private bool spinnerBlink;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs
index ff384ee7fc..773cc7ae3c 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacyReverseArrow.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -16,16 +14,16 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
public class LegacyReverseArrow : CompositeDrawable
{
[Resolved(canBeNull: true)]
- private DrawableHitObject drawableHitObject { get; set; }
+ private DrawableHitObject? drawableHitObject { get; set; }
- private Drawable proxy;
+ private Drawable proxy = null!;
[BackgroundDependencyLoader]
private void load(ISkinSource skinSource)
{
AutoSizeAxes = Axes.Both;
- string lookupName = new OsuSkinComponent(OsuSkinComponents.ReverseArrow).LookupName;
+ string lookupName = new OsuSkinComponentLookup(OsuSkinComponents.ReverseArrow).LookupName;
var skin = skinSource.FindProvider(s => s.GetTexture(lookupName) != null);
InternalChild = skin?.GetAnimation(lookupName, true, true) ?? Empty();
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs
index dbfec14eb2..29a0745193 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderBody.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Extensions.Color4Extensions;
using osu.Game.Rulesets.Osu.Objects;
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs
index ab39d7c6ef..08b579697c 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySliderHeadHitCircle.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Diagnostics;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -14,9 +12,9 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
public class LegacySliderHeadHitCircle : LegacyMainCirclePiece
{
[Resolved(canBeNull: true)]
- private DrawableHitObject drawableHitObject { get; set; }
+ private DrawableHitObject? drawableHitObject { get; set; }
- private Drawable proxiedOverlayLayer;
+ private Drawable proxiedOverlayLayer = null!;
public LegacySliderHeadHitCircle()
: base("sliderstartcircle")
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs
index a817e5f2b7..66b195962b 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/LegacySpinner.cs
@@ -1,12 +1,11 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Globalization;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
+using osu.Framework.Extensions.ObjectExtensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Sprites;
@@ -32,17 +31,17 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
private const float spm_hide_offset = 50f;
- protected DrawableSpinner DrawableSpinner { get; private set; }
+ protected DrawableSpinner DrawableSpinner { get; private set; } = null!;
- public Drawable ApproachCircle { get; protected set; }
+ public Drawable? ApproachCircle { get; protected set; }
- private Sprite spin;
- private Sprite clear;
+ private Sprite spin = null!;
+ private Sprite clear = null!;
- private LegacySpriteText bonusCounter;
+ private LegacySpriteText bonusCounter = null!;
- private Sprite spmBackground;
- private LegacySpriteText spmCounter;
+ private Sprite spmBackground = null!;
+ private LegacySpriteText spmCounter = null!;
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableHitObject, ISkinSource source)
@@ -108,8 +107,8 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
});
}
- private IBindable gainedBonus;
- private IBindable spinsPerMinute;
+ private IBindable gainedBonus = null!;
+ private IBindable spinsPerMinute = null!;
private readonly Bindable completed = new Bindable();
@@ -207,7 +206,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
{
base.Dispose(isDisposing);
- if (DrawableSpinner != null)
+ if (DrawableSpinner.IsNotNull())
DrawableSpinner.ApplyCustomUpdateState -= UpdateStateTransforms;
}
}
diff --git a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs
index 856ccb5044..620540b8ef 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/Legacy/OsuLegacySkinTransformer.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -30,17 +28,17 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
hasHitCircle = new Lazy(() => GetTexture("hitcircle") != null);
}
- public override Drawable GetDrawableComponent(ISkinComponent component)
+ public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup)
{
- if (component is OsuSkinComponent osuComponent)
+ if (lookup is OsuSkinComponentLookup osuComponent)
{
switch (osuComponent.Component)
{
case OsuSkinComponents.FollowPoint:
- return this.GetAnimation(component.LookupName, true, true, true, startAtCurrentTime: false);
+ return this.GetAnimation("followpoint", true, true, true, startAtCurrentTime: false);
case OsuSkinComponents.SliderScorePoint:
- return this.GetAnimation(component.LookupName, false, false);
+ return this.GetAnimation("sliderscorepoint", false, false);
case OsuSkinComponents.SliderFollowCircle:
var followCircleContent = this.GetAnimation("sliderfollowcircle", true, true, true);
@@ -138,14 +136,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Legacy
return new LegacyApproachCircle();
default:
- throw new UnsupportedSkinComponentException(component);
+ throw new UnsupportedSkinComponentException(lookup);
}
}
- return base.GetDrawableComponent(component);
+ return base.GetDrawableComponent(lookup);
}
- public override IBindable GetConfig(TLookup lookup)
+ public override IBindable? GetConfig(TLookup lookup)
{
switch (lookup)
{
diff --git a/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs b/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs
index 0b45c770ba..2a13f07cdb 100644
--- a/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/NonPlayfieldSprite.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Rulesets.UI;
@@ -15,7 +13,7 @@ namespace osu.Game.Rulesets.Osu.Skinning
///
public class NonPlayfieldSprite : Sprite
{
- public override Texture Texture
+ public override Texture? Texture
{
get => base.Texture;
set
diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs
index 5d8a2ff606..24f9217a5f 100644
--- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinColour.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
namespace osu.Game.Rulesets.Osu.Skinning
{
public enum OsuSkinColour
diff --git a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs
index 1c0a62454b..77fea9d8f7 100644
--- a/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/OsuSkinConfiguration.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
namespace osu.Game.Rulesets.Osu.Skinning
{
public enum OsuSkinConfiguration
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs
similarity index 97%
rename from osu.Game.Rulesets.Osu/Skinning/Default/SliderBody.cs
rename to osu.Game.Rulesets.Osu/Skinning/SliderBody.cs
index 9841cc7cdf..1411b27c09 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/SliderBody.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/SliderBody.cs
@@ -8,10 +8,11 @@ using System.Collections.Generic;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Lines;
+using osu.Game.Rulesets.Osu.Skinning.Default;
using osuTK;
using osuTK.Graphics;
-namespace osu.Game.Rulesets.Osu.Skinning.Default
+namespace osu.Game.Rulesets.Osu.Skinning
{
public abstract class SliderBody : CompositeDrawable
{
diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/SnakingSliderBody.cs b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs
similarity index 95%
rename from osu.Game.Rulesets.Osu/Skinning/Default/SnakingSliderBody.cs
rename to osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs
index 86dd5f5c74..8ba9e75d19 100644
--- a/osu.Game.Rulesets.Osu/Skinning/Default/SnakingSliderBody.cs
+++ b/osu.Game.Rulesets.Osu/Skinning/SnakingSliderBody.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.Collections.Generic;
using osu.Framework.Allocation;
@@ -14,7 +12,7 @@ using osu.Game.Rulesets.Osu.Objects;
using osu.Game.Rulesets.Osu.Objects.Drawables;
using osuTK;
-namespace osu.Game.Rulesets.Osu.Skinning.Default
+namespace osu.Game.Rulesets.Osu.Skinning
{
///
/// A which changes its curve depending on the snaking progress.
@@ -55,7 +53,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
///
private Vector2 snakedPathOffset;
- private DrawableSlider drawableSlider;
+ private DrawableSlider drawableSlider = null!;
[BackgroundDependencyLoader]
private void load(DrawableHitObject drawableObject)
@@ -67,7 +65,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
public void UpdateProgress(double completionProgress)
{
- if (drawableSlider?.HitObject == null)
+ if (drawableSlider.HitObject == null)
return;
Slider slider = drawableSlider.HitObject;
@@ -96,7 +94,7 @@ namespace osu.Game.Rulesets.Osu.Skinning.Default
public void Refresh()
{
- if (drawableSlider?.HitObject == null)
+ if (drawableSlider.HitObject == null)
return;
// Generate the entire curve
diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs
index 15ef7e538b..6d435f01b0 100644
--- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs
+++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursor.cs
@@ -46,7 +46,7 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
RelativeSizeAxes = Axes.Both,
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
- Child = cursorSprite = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling)
+ Child = cursorSprite = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.Cursor), _ => new DefaultCursor(), confineMode: ConfineMode.NoScaling)
{
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
diff --git a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs
index 533db3ddfe..26fe08972e 100644
--- a/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs
+++ b/osu.Game.Rulesets.Osu/UI/Cursor/OsuCursorContainer.cs
@@ -47,8 +47,8 @@ namespace osu.Game.Rulesets.Osu.UI.Cursor
RelativeSizeAxes = Axes.Both,
Children = new[]
{
- cursorTrail = new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling),
- new SkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling),
+ cursorTrail = new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorTrail), _ => new DefaultCursorTrail(), confineMode: ConfineMode.NoScaling),
+ new SkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorParticles), confineMode: ConfineMode.NoScaling),
}
};
}
diff --git a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs
index beba834e88..bf5618dc90 100644
--- a/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs
+++ b/osu.Game.Rulesets.Osu/UI/SmokeContainer.cs
@@ -29,7 +29,7 @@ namespace osu.Game.Rulesets.Osu.UI
{
if (e.Action == OsuAction.Smoke)
{
- AddInternal(currentSegmentSkinnable = new SmokeSkinnableDrawable(new OsuSkinComponent(OsuSkinComponents.CursorSmoke), _ => new DefaultSmokeSegment()));
+ AddInternal(currentSegmentSkinnable = new SmokeSkinnableDrawable(new OsuSkinComponentLookup(OsuSkinComponents.CursorSmoke), _ => new DefaultSmokeSegment()));
// Add initial position immediately.
addPosition();
@@ -68,8 +68,8 @@ namespace osu.Game.Rulesets.Osu.UI
public override double LifetimeStart => Drawable.LifetimeStart;
public override double LifetimeEnd => Drawable.LifetimeEnd;
- public SmokeSkinnableDrawable(ISkinComponent component, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling)
- : base(component, defaultImplementation, confineMode)
+ public SmokeSkinnableDrawable(ISkinComponentLookup lookup, Func? defaultImplementation = null, ConfineMode confineMode = ConfineMode.NoScaling)
+ : base(lookup, defaultImplementation, confineMode)
{
}
}
diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs
index 8e9c487c2f..eb2b6c1d74 100644
--- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs
+++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableHit.cs
@@ -30,23 +30,24 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
Origin = Anchor.Centre,
}));
- AddStep("Rim hit", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime())
+ AddStep("Rim hit", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime(rim: true))
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
}));
- AddStep("Rim hit (strong)", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime(true))
+ AddStep("Rim hit (strong)", () => SetContents(_ => new DrawableHit(createHitAtCurrentTime(true, true))
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
}));
}
- private Hit createHitAtCurrentTime(bool strong = false)
+ private Hit createHitAtCurrentTime(bool strong = false, bool rim = false)
{
var hit = new Hit
{
+ Type = rim ? HitType.Rim : HitType.Centre,
IsStrong = strong,
StartTime = Time.Current + 3000,
};
diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs
index f87e0355ad..0ddc607336 100644
--- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs
+++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneHitExplosion.cs
@@ -13,6 +13,7 @@ using osu.Game.Rulesets.Objects;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.UI;
+using osu.Game.Screens.Ranking;
namespace osu.Game.Rulesets.Taiko.Tests.Skinning
{
@@ -49,11 +50,19 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
// the hit needs to be added to hierarchy in order for nested objects to be created correctly.
// setting zero alpha is supposed to prevent the test from looking broken.
hit.With(h => h.Alpha = 0),
- new HitExplosion(hit.Type)
+
+ new AspectContainer
{
+ RelativeSizeAxes = Axes.X,
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
- }.With(explosion => explosion.Apply(hit))
+ Child =
+ new HitExplosion(hit.Type)
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ }.With(explosion => explosion.Apply(hit))
+ }
}
};
}
diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs
index 954b4be7f3..a9304b01ad 100644
--- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs
+++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneTaikoScroller.cs
@@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning
public TestSceneTaikoScroller()
{
AddStep("Load scroller", () => SetContents(_ =>
- new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Scroller), _ => Empty())
+ new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Scroller), _ => Empty())
{
Clock = new FramedClock(clock),
Height = 0.4f,
diff --git a/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs b/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs
index 425f72cadc..5685ac0f60 100644
--- a/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs
+++ b/osu.Game.Rulesets.Taiko.Tests/TaikoDifficultyCalculatorTest.cs
@@ -16,13 +16,13 @@ namespace osu.Game.Rulesets.Taiko.Tests
{
protected override string ResourceAssembly => "osu.Game.Rulesets.Taiko";
- [TestCase(3.1098944660126882d, 200, "diffcalc-test")]
- [TestCase(3.1098944660126882d, 200, "diffcalc-test-strong")]
+ [TestCase(3.0920212594351191d, 200, "diffcalc-test")]
+ [TestCase(3.0920212594351191d, 200, "diffcalc-test-strong")]
public void Test(double expectedStarRating, int expectedMaxCombo, string name)
=> base.Test(expectedStarRating, expectedMaxCombo, name);
- [TestCase(4.0974106752474251d, 200, "diffcalc-test")]
- [TestCase(4.0974106752474251d, 200, "diffcalc-test-strong")]
+ [TestCase(4.0789820318081444d, 200, "diffcalc-test")]
+ [TestCase(4.0789820318081444d, 200, "diffcalc-test-strong")]
public void TestClockRateAdjusted(double expectedStarRating, int expectedMaxCombo, string name)
=> Test(expectedStarRating, expectedMaxCombo, name, new TaikoModDoubleTime());
diff --git a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
index 38e61f5624..6af1beff69 100644
--- a/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
+++ b/osu.Game.Rulesets.Taiko.Tests/osu.Game.Rulesets.Taiko.Tests.csproj
@@ -3,7 +3,7 @@
-
+
WinExe
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs
index 7d88be2f70..9f63e84867 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/ColourEvaluator.cs
@@ -54,11 +54,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
TaikoDifficultyHitObjectColour colour = ((TaikoDifficultyHitObject)hitObject).Colour;
double difficulty = 0.0d;
- if (colour.MonoStreak != null) // Difficulty for MonoStreak
+ if (colour.MonoStreak?.FirstHitObject == hitObject) // Difficulty for MonoStreak
difficulty += EvaluateDifficultyOf(colour.MonoStreak);
- if (colour.AlternatingMonoPattern != null) // Difficulty for AlternatingMonoPattern
+ if (colour.AlternatingMonoPattern?.FirstHitObject == hitObject) // Difficulty for AlternatingMonoPattern
difficulty += EvaluateDifficultyOf(colour.AlternatingMonoPattern);
- if (colour.RepeatingHitPattern != null) // Difficulty for RepeatingHitPattern
+ if (colour.RepeatingHitPattern?.FirstHitObject == hitObject) // Difficulty for RepeatingHitPattern
difficulty += EvaluateDifficultyOf(colour.RepeatingHitPattern);
return difficulty;
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs
index 49b3ae2e19..84d5de4c63 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Evaluators/StaminaEvaluator.cs
@@ -11,22 +11,43 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
public class StaminaEvaluator
{
///
- /// Applies a speed bonus dependent on the time since the last hit performed using this key.
+ /// Applies a speed bonus dependent on the time since the last hit performed using this finger.
///
- /// The interval between the current and previous note hit using the same key.
+ /// The interval between the current and previous note hit using the same finger.
private static double speedBonus(double interval)
{
- // Cap to 600bpm 1/4, 25ms note interval, 50ms key interval
- // Interval will be capped at a very small value to avoid infinite/negative speed bonuses.
- // TODO - This is a temporary measure as we need to implement methods of detecting playstyle-abuse of SpeedBonus.
- interval = Math.Max(interval, 50);
+ // Interval is capped at a very small value to prevent infinite values.
+ interval = Math.Max(interval, 1);
return 30 / interval;
}
+ ///
+ /// Determines the number of fingers available to hit the current .
+ /// Any mono notes that is more than 300ms apart from a colour change will be considered to have more than 2
+ /// fingers available, since players can hit the same key with multiple fingers.
+ ///
+ private static int availableFingersFor(TaikoDifficultyHitObject hitObject)
+ {
+ DifficultyHitObject? previousColourChange = hitObject.Colour.PreviousColourChange;
+ DifficultyHitObject? nextColourChange = hitObject.Colour.NextColourChange;
+
+ if (previousColourChange != null && hitObject.StartTime - previousColourChange.StartTime < 300)
+ {
+ return 2;
+ }
+
+ if (nextColourChange != null && nextColourChange.StartTime - hitObject.StartTime < 300)
+ {
+ return 2;
+ }
+
+ return 4;
+ }
+
///
/// Evaluates the minimum mechanical stamina required to play the current object. This is calculated using the
- /// maximum possible interval between two hits using the same key, by alternating 2 keys for each colour.
+ /// maximum possible interval between two hits using the same key, by alternating available fingers for each colour.
///
public static double EvaluateDifficultyOf(DifficultyHitObject current)
{
@@ -35,13 +56,14 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Evaluators
return 0.0;
}
- // Find the previous hit object hit by the current key, which is two notes of the same colour prior.
+ // Find the previous hit object hit by the current finger, which is n notes prior, n being the number of
+ // available fingers.
TaikoDifficultyHitObject taikoCurrent = (TaikoDifficultyHitObject)current;
- TaikoDifficultyHitObject? keyPrevious = taikoCurrent.PreviousMono(1);
+ TaikoDifficultyHitObject? keyPrevious = taikoCurrent.PreviousMono(availableFingersFor(taikoCurrent) - 1);
if (keyPrevious == null)
{
- // There is no previous hit object hit by the current key
+ // There is no previous hit object hit by the current finger
return 0.0;
}
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs
index 174988bed7..c01a0f6686 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/MonoStreak.cs
@@ -33,6 +33,11 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data
///
public TaikoDifficultyHitObject FirstHitObject => HitObjects[0];
+ ///
+ /// The last in this .
+ ///
+ public TaikoDifficultyHitObject LastHitObject => HitObjects[^1];
+
///
/// The hit type of all objects encoded within this
///
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs
index fe0dc6dd9a..468a9ab876 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/Data/RepeatingHitPatterns.cs
@@ -23,7 +23,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour.Data
public readonly List AlternatingMonoPatterns = new List();
///
- /// The parent in this
+ /// The first in this
///
public TaikoDifficultyHitObject FirstHitObject => AlternatingMonoPatterns[0].FirstHitObject;
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs
index d19e05f4e0..18a299ae92 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoColourDifficultyPreprocessor.cs
@@ -15,19 +15,15 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour
{
///
/// Processes and encodes a list of s into a list of s,
- /// assigning the appropriate s to each ,
- /// and pre-evaluating colour difficulty of each .
+ /// assigning the appropriate s to each .
///
public static void ProcessAndAssign(List hitObjects)
{
List hitPatterns = encode(hitObjects);
- // Assign indexing and encoding data to all relevant objects. Only the first note of each encoding type is
- // assigned with the relevant encodings.
+ // Assign indexing and encoding data to all relevant objects.
foreach (var repeatingHitPattern in hitPatterns)
{
- repeatingHitPattern.FirstHitObject.Colour.RepeatingHitPattern = repeatingHitPattern;
-
// The outermost loop is kept a ForEach loop since it doesn't need index information, and we want to
// keep i and j for AlternatingMonoPattern's and MonoStreak's index respectively, to keep it in line with
// documentation.
@@ -36,14 +32,19 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour
AlternatingMonoPattern monoPattern = repeatingHitPattern.AlternatingMonoPatterns[i];
monoPattern.Parent = repeatingHitPattern;
monoPattern.Index = i;
- monoPattern.FirstHitObject.Colour.AlternatingMonoPattern = monoPattern;
for (int j = 0; j < monoPattern.MonoStreaks.Count; ++j)
{
MonoStreak monoStreak = monoPattern.MonoStreaks[j];
monoStreak.Parent = monoPattern;
monoStreak.Index = j;
- monoStreak.FirstHitObject.Colour.MonoStreak = monoStreak;
+
+ foreach (var hitObject in monoStreak.HitObjects)
+ {
+ hitObject.Colour.RepeatingHitPattern = repeatingHitPattern;
+ hitObject.Colour.AlternatingMonoPattern = monoPattern;
+ hitObject.Colour.MonoStreak = monoStreak;
+ }
}
}
}
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs
index 9c147eee9c..abf6fb3672 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Preprocessing/Colour/TaikoDifficultyHitObjectColour.cs
@@ -11,18 +11,28 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Preprocessing.Colour
public class TaikoDifficultyHitObjectColour
{
///
- /// The that encodes this note, only present if this is the first note within a
+ /// The that encodes this note.
///
public MonoStreak? MonoStreak;
///
- /// The that encodes this note, only present if this is the first note within a
+ /// The that encodes this note.
///
public AlternatingMonoPattern? AlternatingMonoPattern;
///
- /// The that encodes this note, only present if this is the first note within a
+ /// The that encodes this note.
///
public RepeatingHitPatterns? RepeatingHitPattern;
+
+ ///
+ /// The closest past that's not the same colour.
+ ///
+ public TaikoDifficultyHitObject? PreviousColourChange => MonoStreak?.FirstHitObject.PreviousNote(0);
+
+ ///
+ /// The closest future that's not the same colour.
+ ///
+ public TaikoDifficultyHitObject? NextColourChange => MonoStreak?.LastHitObject.NextNote(0);
}
}
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs
index 344004bcf6..d04c028fec 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/Skills/Stamina.cs
@@ -13,9 +13,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty.Skills
///
/// Calculates the stamina coefficient of taiko difficulty.
///
- ///
- /// The reference play style chosen uses two hands, with full alternating (the hand changes after every hit).
- ///
public class Stamina : StrainDecaySkill
{
protected override double SkillMultiplier => 1.1;
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs
index 2b0b563323..24b5f5939a 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoDifficultyCalculator.cs
@@ -83,15 +83,6 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
double combinedRating = combined.DifficultyValue() * difficulty_multiplier;
double starRating = rescale(combinedRating * 1.4);
- // TODO: This is temporary measure as we don't detect abuse of multiple-input playstyles of converts within the current system.
- if (beatmap.BeatmapInfo.Ruleset.OnlineID == 0)
- {
- starRating *= 0.925;
- // For maps with low colour variance and high stamina requirement, multiple inputs are more likely to be abused.
- if (colourRating < 2 && staminaRating > 8)
- starRating *= 0.80;
- }
-
HitWindows hitWindows = new TaikoHitWindows();
hitWindows.SetDifficulty(beatmap.Difficulty.OverallDifficulty);
diff --git a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs
index dc7bad2f75..2d1b2903c9 100644
--- a/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs
+++ b/osu.Game.Rulesets.Taiko/Difficulty/TaikoPerformanceCalculator.cs
@@ -43,6 +43,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
if (totalSuccessfulHits > 0)
effectiveMissCount = Math.Max(1.0, 1000.0 / totalSuccessfulHits) * countMiss;
+ // TODO: The detection of rulesets is temporary until the leftover old skills have been reworked.
+ bool isConvert = score.BeatmapInfo.Ruleset.OnlineID != 1;
+
double multiplier = 1.13;
if (score.Mods.Any(m => m is ModHidden))
@@ -51,8 +54,8 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
if (score.Mods.Any(m => m is ModEasy))
multiplier *= 0.975;
- double difficultyValue = computeDifficultyValue(score, taikoAttributes);
- double accuracyValue = computeAccuracyValue(score, taikoAttributes);
+ double difficultyValue = computeDifficultyValue(score, taikoAttributes, isConvert);
+ double accuracyValue = computeAccuracyValue(score, taikoAttributes, isConvert);
double totalValue =
Math.Pow(
Math.Pow(difficultyValue, 1.1) +
@@ -68,7 +71,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
};
}
- private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes)
+ private double computeDifficultyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool isConvert)
{
double difficultyValue = Math.Pow(5 * Math.Max(1.0, attributes.StarRating / 0.115) - 4.0, 2.25) / 1150.0;
@@ -80,7 +83,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
if (score.Mods.Any(m => m is ModEasy))
difficultyValue *= 0.985;
- if (score.Mods.Any(m => m is ModHidden))
+ if (score.Mods.Any(m => m is ModHidden) && !isConvert)
difficultyValue *= 1.025;
if (score.Mods.Any(m => m is ModHardRock))
@@ -92,7 +95,7 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
return difficultyValue * Math.Pow(accuracy, 2.0);
}
- private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes)
+ private double computeAccuracyValue(ScoreInfo score, TaikoDifficultyAttributes attributes, bool isConvert)
{
if (attributes.GreatHitWindow <= 0)
return 0;
@@ -102,9 +105,9 @@ namespace osu.Game.Rulesets.Taiko.Difficulty
double lengthBonus = Math.Min(1.15, Math.Pow(totalHits / 1500.0, 0.3));
accuracyValue *= lengthBonus;
- // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values
- if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden))
- accuracyValue *= Math.Max(1.050, 1.075 * lengthBonus);
+ // Slight HDFL Bonus for accuracy. A clamp is used to prevent against negative values.
+ if (score.Mods.Any(m => m is ModFlashlight) && score.Mods.Any(m => m is ModHidden) && !isConvert)
+ accuracyValue *= Math.Max(1.0, 1.1 * lengthBonus);
return accuracyValue;
}
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs
index e4806c4a12..2405d5b73f 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableBarLine.cs
@@ -1,17 +1,12 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
-using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
-using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Shapes;
using osu.Game.Rulesets.Objects;
-using osuTK;
using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Skinning.Default;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.Objects.Drawables
@@ -28,35 +23,15 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
///
private const float tracker_width = 2f;
- ///
- /// The vertical offset of the triangles from the line tracker.
- ///
- private const float triangle_offset = 10f;
-
- ///
- /// The size of the triangles.
- ///
- private const float triangle_size = 20f;
-
- ///
- /// The visual line tracker.
- ///
- private SkinnableDrawable line;
-
- ///
- /// Container with triangles. Only visible for major lines.
- ///
- private Container triangleContainer;
-
- private readonly Bindable major = new Bindable();
+ public readonly Bindable Major = new Bindable();
public DrawableBarLine()
: this(null)
{
}
- public DrawableBarLine([CanBeNull] BarLine barLine)
- : base(barLine)
+ public DrawableBarLine(BarLine? barLine)
+ : base(barLine!)
{
}
@@ -69,69 +44,23 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
RelativeSizeAxes = Axes.Y;
Width = tracker_width;
- AddRangeInternal(new Drawable[]
+ AddInternal(new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.BarLine), _ => new DefaultBarLine())
{
- line = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.BarLine), _ => new Box
- {
- RelativeSizeAxes = Axes.Both,
- EdgeSmoothness = new Vector2(0.5f, 0),
- })
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- },
- triangleContainer = new Container
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Children = new[]
- {
- new EquilateralTriangle
- {
- Name = "Top",
- Anchor = Anchor.TopCentre,
- Origin = Anchor.TopCentre,
- Position = new Vector2(0, -triangle_offset),
- Size = new Vector2(-triangle_size),
- EdgeSmoothness = new Vector2(1),
- },
- new EquilateralTriangle
- {
- Name = "Bottom",
- Anchor = Anchor.BottomCentre,
- Origin = Anchor.TopCentre,
- Position = new Vector2(0, triangle_offset),
- Size = new Vector2(triangle_size),
- EdgeSmoothness = new Vector2(1),
- }
- }
- }
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
});
}
- protected override void LoadComplete()
- {
- base.LoadComplete();
- major.BindValueChanged(updateMajor, true);
- }
-
- private void updateMajor(ValueChangedEvent major)
- {
- line.Alpha = major.NewValue ? 1f : 0.75f;
- triangleContainer.Alpha = major.NewValue ? 1 : 0;
- }
-
protected override void OnApply()
{
base.OnApply();
- major.BindTo(HitObject.MajorBindable);
+ Major.BindTo(HitObject.MajorBindable);
}
protected override void OnFree()
{
base.OnFree();
- major.UnbindFrom(HitObject.MajorBindable);
+ Major.UnbindFrom(HitObject.MajorBindable);
}
protected override void UpdateHitStateTransforms(ArmedState state)
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
index 98dad96cf6..0bb14c791e 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRoll.cs
@@ -115,7 +115,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
return base.CreateNestedHitObject(hitObject);
}
- protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollBody),
+ protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollBody),
_ => new ElongatedCirclePiece());
public override bool OnPressed(KeyBindingPressEvent e) => false;
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
index 451c5a793b..4aed8212e8 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableDrumRollTick.cs
@@ -5,6 +5,7 @@
using System;
using JetBrains.Annotations;
+using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Input.Events;
using osu.Game.Rulesets.Objects;
@@ -16,6 +17,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
{
public class DrawableDrumRollTick : DrawableTaikoStrongableHitObject
{
+ public BindableBool IsFirstTick = new BindableBool();
+
///
/// The hit type corresponding to the that the user pressed to hit this .
///
@@ -32,14 +35,17 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
FillMode = FillMode.Fit;
}
- protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick),
- _ => new TickPiece
- {
- Filled = HitObject.FirstTick
- });
+ protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick), _ => new TickPiece());
public override double MaximumJudgementOffset => HitObject.HitWindow;
+ protected override void OnApply()
+ {
+ base.OnApply();
+
+ IsFirstTick.Value = HitObject.FirstTick;
+ }
+
protected override void CheckForResult(bool userTriggered, double timeOffset)
{
if (!userTriggered)
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
index 484f125a09..59c9640beb 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableHit.cs
@@ -90,8 +90,8 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
}
protected override SkinnableDrawable CreateMainPiece() => HitObject.Type == HitType.Centre
- ? new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit)
- : new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit);
+ ? new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.CentreHit), _ => new CentreHitCirclePiece(), confineMode: ConfineMode.ScaleToFit)
+ : new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.RimHit), _ => new RimHitCirclePiece(), confineMode: ConfineMode.ScaleToFit);
public override IEnumerable GetSamples()
{
@@ -201,12 +201,9 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
break;
case ArmedState.Hit:
- // If we're far enough away from the left stage, we should bring outselves in front of it
+ // If we're far enough away from the left stage, we should bring ourselves in front of it
ProxyContent();
- var flash = (MainPiece.Drawable as CirclePiece)?.FlashBox;
- flash?.FadeTo(0.9f).FadeOut(300);
-
const float gravity_time = 300;
const float gravity_travel_height = 200;
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
index a6f6edba09..753f85f23f 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwell.cs
@@ -125,7 +125,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
targetRing.BorderColour = colours.YellowDark.Opacity(0.25f);
}
- protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Swell),
+ protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Swell),
_ => new SwellCirclePiece
{
// to allow for rotation transform
diff --git a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs
index b2a54176fb..5d44fce254 100644
--- a/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs
+++ b/osu.Game.Rulesets.Taiko/Objects/Drawables/DrawableSwellTick.cs
@@ -39,7 +39,7 @@ namespace osu.Game.Rulesets.Taiko.Objects.Drawables
public override bool OnPressed(KeyBindingPressEvent e) => false;
- protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.DrumRollTick),
+ protected override SkinnableDrawable CreateMainPiece() => new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.DrumRollTick),
_ => new TickPiece());
}
}
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs
index b91d5cfe8d..339ab35795 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CentreHitCirclePiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -41,12 +39,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
Children = new[]
{
- new CircularContainer
- {
- RelativeSizeAxes = Axes.Both,
- Masking = true,
- Children = new[] { new Box { RelativeSizeAxes = Axes.Both } }
- }
+ new Circle { RelativeSizeAxes = Axes.Both }
};
}
}
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs
index 6b5a9ae6d2..ccde8e6ac9 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/CirclePiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Extensions.Color4Extensions;
@@ -36,6 +34,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
private const float flash_opacity = 0.3f;
+ [Resolved]
+ private DrawableHitObject drawableHitObject { get; set; } = null!;
+
private Color4 accentColour;
///
@@ -76,7 +77,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
private readonly Container background;
- public Box FlashBox;
+ private readonly Box flashBox;
protected CirclePiece()
{
@@ -122,7 +123,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
Masking = true,
Children = new[]
{
- FlashBox = new Box
+ flashBox = new Box
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
@@ -144,6 +145,25 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
});
}
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ drawableHitObject.ApplyCustomUpdateState += updateStateTransforms;
+ updateStateTransforms(drawableHitObject, drawableHitObject.State.Value);
+ }
+
+ private void updateStateTransforms(DrawableHitObject drawableHitObject, ArmedState state)
+ {
+ switch (state)
+ {
+ case ArmedState.Hit:
+ using (BeginAbsoluteSequence(drawableHitObject.HitStateUpdateTime))
+ flashBox.FadeTo(0.9f).FadeOut(300);
+ break;
+ }
+ }
+
private const float edge_alpha_kiai = 0.5f;
private void resetEdgeEffects()
@@ -156,9 +176,6 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
};
}
- [Resolved]
- private DrawableHitObject drawableHitObject { get; set; }
-
protected override void OnNewBeat(int beatIndex, TimingControlPoint timingPoint, EffectControlPoint effectPoint, ChannelAmplitudes amplitudes)
{
if (!effectPoint.KiaiMode)
@@ -166,7 +183,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
if (drawableHitObject.State.Value == ArmedState.Idle)
{
- FlashBox
+ flashBox
.FadeTo(flash_opacity)
.Then()
.FadeOut(timingPoint.BeatLength * 0.75, Easing.OutSine);
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs
new file mode 100644
index 0000000000..973e685bc7
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultBarLine.cs
@@ -0,0 +1,94 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Objects.Drawables;
+using osuTK;
+
+namespace osu.Game.Rulesets.Taiko.Skinning.Default
+{
+ public class DefaultBarLine : CompositeDrawable
+ {
+ ///
+ /// The vertical offset of the triangles from the line tracker.
+ ///
+ private const float triangle_offset = 10f;
+
+ ///
+ /// The size of the triangles.
+ ///
+ private const float triangle_size = 20f;
+
+ ///
+ /// Container with triangles. Only visible for major lines.
+ ///
+ private Container triangleContainer = null!;
+
+ private Bindable major = null!;
+
+ [BackgroundDependencyLoader]
+ private void load(DrawableHitObject drawableHitObject)
+ {
+ RelativeSizeAxes = Axes.Both;
+
+ InternalChildren = new Drawable[]
+ {
+ line = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ EdgeSmoothness = new Vector2(0.5f, 0),
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ },
+ triangleContainer = new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Children = new[]
+ {
+ new EquilateralTriangle
+ {
+ Name = "Top",
+ Anchor = Anchor.TopCentre,
+ Origin = Anchor.TopCentre,
+ Position = new Vector2(0, -triangle_offset),
+ Size = new Vector2(-triangle_size),
+ EdgeSmoothness = new Vector2(1),
+ },
+ new EquilateralTriangle
+ {
+ Name = "Bottom",
+ Anchor = Anchor.BottomCentre,
+ Origin = Anchor.TopCentre,
+ Position = new Vector2(0, triangle_offset),
+ Size = new Vector2(triangle_size),
+ EdgeSmoothness = new Vector2(1),
+ }
+ }
+ }
+ };
+
+ major = ((DrawableBarLine)drawableHitObject).Major.GetBoundCopy();
+ }
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+ major.BindValueChanged(updateMajor, true);
+ }
+
+ private Box line = null!;
+
+ private void updateMajor(ValueChangedEvent major)
+ {
+ line.Alpha = major.NewValue ? 1f : 0.75f;
+ triangleContainer.Alpha = major.NewValue ? 1 : 0;
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko/UI/DefaultHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs
similarity index 87%
rename from osu.Game.Rulesets.Taiko/UI/DefaultHitExplosion.cs
rename to osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs
index 687c8f788f..b7ba76effa 100644
--- a/osu.Game.Rulesets.Taiko/UI/DefaultHitExplosion.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultHitExplosion.cs
@@ -1,9 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
-using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -12,19 +9,19 @@ using osu.Game.Graphics;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects;
+using osu.Game.Rulesets.Taiko.UI;
using osuTK.Graphics;
-namespace osu.Game.Rulesets.Taiko.UI
+namespace osu.Game.Rulesets.Taiko.Skinning.Default
{
internal class DefaultHitExplosion : CircularContainer, IAnimatableHitExplosion
{
private readonly HitResult result;
- [CanBeNull]
- private Box body;
+ private Box? body;
[Resolved]
- private OsuColour colours { get; set; }
+ private OsuColour colours { get; set; } = null!;
public DefaultHitExplosion(HitResult result)
{
@@ -58,7 +55,7 @@ namespace osu.Game.Rulesets.Taiko.UI
updateColour();
}
- private void updateColour([CanBeNull] DrawableHitObject judgedObject = null)
+ private void updateColour(DrawableHitObject? judgedObject = null)
{
if (body == null)
return;
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs
new file mode 100644
index 0000000000..3d0578dbc0
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultInputDrum.cs
@@ -0,0 +1,180 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using System;
+using osu.Framework.Allocation;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Sprites;
+using osu.Framework.Graphics.Textures;
+using osu.Framework.Input.Bindings;
+using osu.Framework.Input.Events;
+using osu.Game.Graphics;
+using osu.Game.Screens.Ranking;
+using osuTK;
+
+namespace osu.Game.Rulesets.Taiko.Skinning.Default
+{
+ public class DefaultInputDrum : AspectContainer
+ {
+ public DefaultInputDrum()
+ {
+ RelativeSizeAxes = Axes.Y;
+ }
+
+ [BackgroundDependencyLoader]
+ private void load()
+ {
+ const float middle_split = 0.025f;
+
+ InternalChild = new Container
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Scale = new Vector2(0.9f),
+ Children = new[]
+ {
+ new TaikoHalfDrum(false)
+ {
+ Name = "Left Half",
+ Anchor = Anchor.Centre,
+ Origin = Anchor.CentreRight,
+ RelativeSizeAxes = Axes.Both,
+ RelativePositionAxes = Axes.X,
+ X = -middle_split / 2,
+ RimAction = TaikoAction.LeftRim,
+ CentreAction = TaikoAction.LeftCentre
+ },
+ new TaikoHalfDrum(true)
+ {
+ Name = "Right Half",
+ Anchor = Anchor.Centre,
+ Origin = Anchor.CentreLeft,
+ RelativeSizeAxes = Axes.Both,
+ RelativePositionAxes = Axes.X,
+ X = middle_split / 2,
+ RimAction = TaikoAction.RightRim,
+ CentreAction = TaikoAction.RightCentre
+ }
+ }
+ };
+ }
+
+ ///
+ /// A half-drum. Contains one centre and one rim hit.
+ ///
+ private class TaikoHalfDrum : Container, IKeyBindingHandler
+ {
+ ///
+ /// The key to be used for the rim of the half-drum.
+ ///
+ public TaikoAction RimAction;
+
+ ///
+ /// The key to be used for the centre of the half-drum.
+ ///
+ public TaikoAction CentreAction;
+
+ private readonly Sprite rim;
+ private readonly Sprite rimHit;
+ private readonly Sprite centre;
+ private readonly Sprite centreHit;
+
+ public TaikoHalfDrum(bool flipped)
+ {
+ Masking = true;
+
+ Children = new Drawable[]
+ {
+ rim = new Sprite
+ {
+ Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both
+ },
+ rimHit = new Sprite
+ {
+ Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Alpha = 0,
+ Blending = BlendingParameters.Additive,
+ },
+ centre = new Sprite
+ {
+ Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Size = new Vector2(0.7f)
+ },
+ centreHit = new Sprite
+ {
+ Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
+ Origin = Anchor.Centre,
+ RelativeSizeAxes = Axes.Both,
+ Size = new Vector2(0.7f),
+ Alpha = 0,
+ Blending = BlendingParameters.Additive
+ }
+ };
+ }
+
+ [BackgroundDependencyLoader]
+ private void load(TextureStore textures, OsuColour colours)
+ {
+ rim.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer");
+ rimHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer-hit");
+ centre.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner");
+ centreHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner-hit");
+
+ rimHit.Colour = colours.Blue;
+ centreHit.Colour = colours.Pink;
+ }
+
+ public bool OnPressed(KeyBindingPressEvent e)
+ {
+ Drawable? target = null;
+ Drawable? back = null;
+
+ if (e.Action == CentreAction)
+ {
+ target = centreHit;
+ back = centre;
+ }
+ else if (e.Action == RimAction)
+ {
+ target = rimHit;
+ back = rim;
+ }
+
+ if (target != null)
+ {
+ const float scale_amount = 0.05f;
+ const float alpha_amount = 0.5f;
+
+ const float down_time = 40;
+ const float up_time = 1000;
+
+ back.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint)
+ .Then()
+ .ScaleTo(1, up_time, Easing.OutQuint);
+
+ target.Animate(
+ t => t.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint),
+ t => t.FadeTo(Math.Min(target.Alpha + alpha_amount, 1), down_time, Easing.OutQuint)
+ ).Then(
+ t => t.ScaleTo(1, up_time, Easing.OutQuint),
+ t => t.FadeOut(up_time, Easing.OutQuint)
+ );
+ }
+
+ return false;
+ }
+
+ public void OnReleased(KeyBindingReleaseEvent e)
+ {
+ }
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs
new file mode 100644
index 0000000000..c85a8db788
--- /dev/null
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultJudgementPiece.cs
@@ -0,0 +1,35 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Graphics;
+using osu.Game.Rulesets.Scoring;
+
+namespace osu.Game.Rulesets.Taiko.Skinning.Default
+{
+ public class DefaultJudgementPiece : Rulesets.Judgements.DefaultJudgementPiece
+ {
+ public DefaultJudgementPiece(HitResult result)
+ : base(result)
+ {
+ RelativePositionAxes = Axes.Both;
+ }
+
+ public override void PlayAnimation()
+ {
+ if (Result != HitResult.Miss)
+ {
+ this
+ .MoveToY(-0.6f)
+ .MoveToY(-1.5f, 500);
+
+ JudgementText
+ .ScaleTo(0.9f)
+ .ScaleTo(1, 500, Easing.OutElastic);
+
+ this.FadeOutFromOne(800, Easing.OutQuint);
+ }
+ else
+ base.PlayAnimation();
+ }
+ }
+}
diff --git a/osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs
similarity index 96%
rename from osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs
rename to osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs
index e91475d87b..ae68d63d97 100644
--- a/osu.Game.Rulesets.Taiko/UI/DefaultKiaiHitExplosion.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/DefaultKiaiHitExplosion.cs
@@ -1,9 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
-using osuTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -11,8 +8,9 @@ using osu.Framework.Graphics.Effects;
using osu.Framework.Graphics.Shapes;
using osu.Game.Graphics;
using osu.Game.Rulesets.Taiko.Objects;
+using osuTK;
-namespace osu.Game.Rulesets.Taiko.UI
+namespace osu.Game.Rulesets.Taiko.Skinning.Default
{
public class DefaultKiaiHitExplosion : CircularContainer
{
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs
index ba2679fe97..210841bca0 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/ElongatedCirclePiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Game.Graphics;
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs
index 63269f1267..c6165495d8 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/RimHitCirclePiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs
index d19dc4c887..2f59cac3ff 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/SwellSymbolPiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs
index 7d3268f777..a1eaef53ba 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Default/TickPiece.cs
@@ -1,11 +1,13 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
+using osu.Framework.Allocation;
+using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Shapes;
+using osu.Game.Rulesets.Objects.Drawables;
+using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osuTK;
using osuTK.Graphics;
@@ -24,20 +26,10 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
///
private const float tick_size = 0.35f;
- private bool filled;
-
- public bool Filled
- {
- get => filled;
- set
- {
- filled = value;
- fillBox.Alpha = filled ? 1 : 0;
- }
- }
-
private readonly Box fillBox;
+ private Bindable isFirstTick = null!;
+
public TickPiece()
{
Anchor = Anchor.Centre;
@@ -64,5 +56,19 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Default
}
};
}
+
+ [Resolved]
+ private DrawableHitObject drawableHitObject { get; set; } = null!;
+
+ protected override void LoadComplete()
+ {
+ base.LoadComplete();
+
+ if (drawableHitObject is DrawableDrumRollTick drumRollTick)
+ {
+ isFirstTick = drumRollTick.IsFirstTick.GetBoundCopy();
+ isFirstTick.BindValueChanged(first => fillBox.Alpha = first.NewValue ? 1 : 0, true);
+ }
+ }
}
}
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs
index 97e0a340dd..2b528ae8ce 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyBarLine.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs
index 6bbeb0ed4c..6b2576a564 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyCirclePiece.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
@@ -19,7 +17,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
{
public class LegacyCirclePiece : CompositeDrawable, IHasAccentColour
{
- private Drawable backgroundLayer;
+ private Drawable backgroundLayer = null!;
// required for editor blueprints (not sure why these circle pieces are zero size).
public override Quad ScreenSpaceDrawQuad => backgroundLayer.ScreenSpaceDrawQuad;
@@ -32,7 +30,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
[BackgroundDependencyLoader]
private void load(ISkinSource skin, DrawableHitObject drawableHitObject)
{
- Drawable getDrawableFor(string lookup)
+ Drawable? getDrawableFor(string lookup)
{
const string normal_hit = "taikohit";
const string big_hit = "taikobig";
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs
index 040d8ff965..1249231d92 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyDrumRoll.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -28,11 +26,11 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
}
}
- private LegacyCirclePiece headCircle;
+ private LegacyCirclePiece headCircle = null!;
- private Sprite body;
+ private Sprite body = null!;
- private Sprite tailCircle;
+ private Sprite tailCircle = null!;
public LegacyDrumRoll()
{
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs
index b4277f86bb..d93317f0e2 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHit.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Game.Skinning;
using osuTK.Graphics;
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs
index 87ed2e2e60..ff1546381b 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyHitExplosion.cs
@@ -1,9 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
-using JetBrains.Annotations;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Animations;
@@ -17,8 +14,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
{
private readonly Drawable sprite;
- [CanBeNull]
- private readonly Drawable strongSprite;
+ private readonly Drawable? strongSprite;
///
/// Creates a new legacy hit explosion.
@@ -29,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
///
/// The normal legacy explosion sprite.
/// The strong legacy explosion sprite.
- public LegacyHitExplosion(Drawable sprite, [CanBeNull] Drawable strongSprite = null)
+ public LegacyHitExplosion(Drawable sprite, Drawable? strongSprite = null)
{
this.sprite = sprite;
this.strongSprite = strongSprite;
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs
index 101f70b97a..0abb365750 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyInputDrum.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -20,9 +18,9 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
///
internal class LegacyInputDrum : Container
{
- private Container content;
- private LegacyHalfDrum left;
- private LegacyHalfDrum right;
+ private Container content = null!;
+ private LegacyHalfDrum left = null!;
+ private LegacyHalfDrum right = null!;
public LegacyInputDrum()
{
@@ -142,7 +140,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
public bool OnPressed(KeyBindingPressEvent e)
{
- Drawable target = null;
+ Drawable? target = null;
if (e.Action == CentreAction)
{
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs
index bd4a2f8935..4a2426bff5 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/LegacyTaikoScroller.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
@@ -27,7 +25,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
}
[BackgroundDependencyLoader(true)]
- private void load(GameplayState gameplayState)
+ private void load(GameplayState? gameplayState)
{
if (gameplayState != null)
((IBindable)LastResult).BindTo(gameplayState.LastJudgementResult);
@@ -91,8 +89,8 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
private class ScrollerSprite : CompositeDrawable
{
- private Sprite passingSprite;
- private Sprite failingSprite;
+ private Sprite passingSprite = null!;
+ private Sprite failingSprite = null!;
private bool passing = true;
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs
index a48cdf47f6..21102f6eec 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyHitTarget.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
@@ -15,7 +13,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
{
public class TaikoLegacyHitTarget : CompositeDrawable
{
- private Container content;
+ private Container content = null!;
[BackgroundDependencyLoader]
private void load(ISkinSource skin)
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs
index f425a410a4..3186f615a7 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacyPlayfieldBackgroundRight.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
using osu.Framework.Graphics;
@@ -16,7 +14,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
{
public class TaikoLegacyPlayfieldBackgroundRight : BeatSyncedContainer
{
- private Sprite kiai;
+ private Sprite kiai = null!;
private bool kiaiDisplayed;
diff --git a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs
index 020cdab4dc..7bf99306f0 100644
--- a/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs
+++ b/osu.Game.Rulesets.Taiko/Skinning/Legacy/TaikoLegacySkinTransformer.cs
@@ -27,16 +27,16 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
hasExplosion = new Lazy(() => GetTexture(getHitName(TaikoSkinComponents.TaikoExplosionGreat)) != null);
}
- public override Drawable? GetDrawableComponent(ISkinComponent component)
+ public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup)
{
- if (component is GameplaySkinComponent)
+ if (lookup is GameplaySkinComponentLookup)
{
// if a taiko skin is providing explosion sprites, hide the judgements completely
if (hasExplosion.Value)
return Drawable.Empty().With(d => d.Expire());
}
- if (component is TaikoSkinComponent taikoComponent)
+ if (lookup is TaikoSkinComponentLookup taikoComponent)
{
switch (taikoComponent.Component)
{
@@ -130,11 +130,11 @@ namespace osu.Game.Rulesets.Taiko.Skinning.Legacy
return new DrawableTaikoMascot();
default:
- throw new UnsupportedSkinComponentException(component);
+ throw new UnsupportedSkinComponentException(lookup);
}
}
- return base.GetDrawableComponent(component);
+ return base.GetDrawableComponent(lookup);
}
private string getHitName(TaikoSkinComponents component)
diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponentLookup.cs
similarity index 72%
rename from osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs
rename to osu.Game.Rulesets.Taiko/TaikoSkinComponentLookup.cs
index 63314a6822..c35971e9fd 100644
--- a/osu.Game.Rulesets.Taiko/TaikoSkinComponent.cs
+++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponentLookup.cs
@@ -1,15 +1,13 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko
{
- public class TaikoSkinComponent : GameplaySkinComponent
+ public class TaikoSkinComponentLookup : GameplaySkinComponentLookup
{
- public TaikoSkinComponent(TaikoSkinComponents component)
+ public TaikoSkinComponentLookup(TaikoSkinComponents component)
: base(component)
{
}
diff --git a/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs
index d231dc7e4f..bf48898dd2 100644
--- a/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs
+++ b/osu.Game.Rulesets.Taiko/TaikoSkinComponents.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
namespace osu.Game.Rulesets.Taiko
{
public enum TaikoSkinComponents
diff --git a/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs b/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs
index 071808a044..cb878e8ea0 100644
--- a/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs
+++ b/osu.Game.Rulesets.Taiko/UI/BarLinePlayfield.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Game.Rulesets.Taiko.Objects;
using osu.Game.Rulesets.Taiko.Objects.Drawables;
diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs
index 264e4db54e..24d2fd7be7 100644
--- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs
+++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoJudgement.cs
@@ -1,11 +1,11 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics;
using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Scoring;
+using osuTK;
+using DefaultJudgementPiece = osu.Game.Rulesets.Taiko.Skinning.Default.DefaultJudgementPiece;
namespace osu.Game.Rulesets.Taiko.UI
{
@@ -14,31 +14,15 @@ namespace osu.Game.Rulesets.Taiko.UI
///
public class DrawableTaikoJudgement : DrawableJudgement
{
- protected override void ApplyHitAnimations()
+ public DrawableTaikoJudgement()
{
- this.MoveToY(-100, 500);
- base.ApplyHitAnimations();
+ Anchor = Anchor.Centre;
+ Origin = Anchor.Centre;
+
+ RelativeSizeAxes = Axes.Both;
+ Size = Vector2.One;
}
- protected override Drawable CreateDefaultJudgement(HitResult result) => new TaikoJudgementPiece(result);
-
- private class TaikoJudgementPiece : DefaultJudgementPiece
- {
- public TaikoJudgementPiece(HitResult result)
- : base(result)
- {
- }
-
- public override void PlayAnimation()
- {
- if (Result != HitResult.Miss)
- {
- JudgementText.ScaleTo(0.9f);
- JudgementText.ScaleTo(1, 500, Easing.OutElastic);
- }
-
- base.PlayAnimation();
- }
- }
+ protected override Drawable CreateDefaultJudgement(HitResult result) => new DefaultJudgementPiece(result);
}
}
diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs
index 8bedca19d8..dd0b61cdf5 100644
--- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs
+++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoMascot.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
@@ -24,7 +22,8 @@ namespace osu.Game.Rulesets.Taiko.UI
public readonly Bindable LastResult;
private readonly Dictionary animations;
- private TaikoMascotAnimation currentAnimation;
+
+ private TaikoMascotAnimation? currentAnimation;
private bool lastObjectHit = true;
private bool kiaiMode;
@@ -40,7 +39,7 @@ namespace osu.Game.Rulesets.Taiko.UI
}
[BackgroundDependencyLoader(true)]
- private void load(GameplayState gameplayState)
+ private void load(GameplayState? gameplayState)
{
InternalChildren = new[]
{
diff --git a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs
index 58e703b8be..c3d93a344d 100644
--- a/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs
+++ b/osu.Game.Rulesets.Taiko/UI/DrawableTaikoRuleset.cs
@@ -51,7 +51,7 @@ namespace osu.Game.Rulesets.Taiko.UI
{
new BarLineGenerator(Beatmap).BarLines.ForEach(bar => Playfield.Add(bar));
- FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Scroller), _ => Empty())
+ FrameStableComponents.Add(scroller = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Scroller), _ => Empty())
{
RelativeSizeAxes = Axes.X,
Depth = float.MaxValue
diff --git a/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs b/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs
index e0d5a3c680..ae37840825 100644
--- a/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs
+++ b/osu.Game.Rulesets.Taiko/UI/DrumRollHitContainer.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Game.Rulesets.Taiko.Objects.Drawables;
using osu.Game.Rulesets.UI.Scrolling;
diff --git a/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs b/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs
index ef5bd1d7f0..3279d128d3 100644
--- a/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs
+++ b/osu.Game.Rulesets.Taiko/UI/DrumSampleTriggerSource.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Game.Audio;
using osu.Game.Rulesets.Taiko.Objects;
diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs
index 046b3a6fd0..d2b5811b56 100644
--- a/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs
+++ b/osu.Game.Rulesets.Taiko/UI/HitExplosion.cs
@@ -1,10 +1,7 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
-using JetBrains.Annotations;
using osuTK;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
@@ -13,6 +10,7 @@ using osu.Game.Rulesets.Judgements;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Scoring;
using osu.Game.Rulesets.Taiko.Objects;
+using osu.Game.Rulesets.Taiko.Skinning.Default;
using osu.Game.Skinning;
namespace osu.Game.Rulesets.Taiko.UI
@@ -29,10 +27,9 @@ namespace osu.Game.Rulesets.Taiko.UI
private double? secondHitTime;
- [CanBeNull]
- public DrawableHitObject JudgedObject;
+ public DrawableHitObject? JudgedObject;
- private SkinnableDrawable skinnable;
+ private SkinnableDrawable skinnable = null!;
///
/// This constructor only exists to meet the new() type constraint of .
@@ -58,11 +55,11 @@ namespace osu.Game.Rulesets.Taiko.UI
[BackgroundDependencyLoader]
private void load()
{
- InternalChild = skinnable = new SkinnableDrawable(new TaikoSkinComponent(getComponentName(result)), _ => new DefaultHitExplosion(result));
+ InternalChild = skinnable = new SkinnableDrawable(new TaikoSkinComponentLookup(getComponentName(result)), _ => new DefaultHitExplosion(result));
skinnable.OnSkinChanged += runAnimation;
}
- public void Apply([CanBeNull] DrawableHitObject drawableHitObject)
+ public void Apply(DrawableHitObject? drawableHitObject)
{
JudgedObject = drawableHitObject;
secondHitTime = null;
diff --git a/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs b/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs
index 8707f7e840..badf34554c 100644
--- a/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs
+++ b/osu.Game.Rulesets.Taiko/UI/HitExplosionPool.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Graphics.Pooling;
using osu.Game.Rulesets.Scoring;
diff --git a/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs
index 6a9d43a0ab..cf0f5f9fb6 100644
--- a/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs
+++ b/osu.Game.Rulesets.Taiko/UI/IAnimatableHitExplosion.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Game.Rulesets.Objects.Drawables;
namespace osu.Game.Rulesets.Taiko.UI
diff --git a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
index 054f98e18f..2f42a5aaf6 100644
--- a/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
+++ b/osu.Game.Rulesets.Taiko/UI/InputDrum.cs
@@ -1,20 +1,11 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
-using System;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
-using osu.Framework.Graphics.Sprites;
-using osu.Framework.Graphics.Textures;
-using osu.Framework.Input.Bindings;
-using osu.Framework.Input.Events;
-using osu.Game.Graphics;
-using osu.Game.Screens.Ranking;
+using osu.Game.Rulesets.Taiko.Skinning.Default;
using osu.Game.Skinning;
-using osuTK;
namespace osu.Game.Rulesets.Taiko.UI
{
@@ -23,8 +14,6 @@ namespace osu.Game.Rulesets.Taiko.UI
///
internal class InputDrum : Container
{
- private const float middle_split = 0.025f;
-
public InputDrum()
{
AutoSizeAxes = Axes.X;
@@ -36,173 +25,12 @@ namespace osu.Game.Rulesets.Taiko.UI
{
Children = new Drawable[]
{
- new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum())
+ new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.InputDrum), _ => new DefaultInputDrum())
{
RelativeSizeAxes = Axes.Y,
AutoSizeAxes = Axes.X,
},
};
}
-
- private class DefaultInputDrum : AspectContainer
- {
- public DefaultInputDrum()
- {
- RelativeSizeAxes = Axes.Y;
- }
-
- [BackgroundDependencyLoader]
- private void load()
- {
- InternalChild = new Container
- {
- Anchor = Anchor.Centre,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Scale = new Vector2(0.9f),
- Children = new[]
- {
- new TaikoHalfDrum(false)
- {
- Name = "Left Half",
- Anchor = Anchor.Centre,
- Origin = Anchor.CentreRight,
- RelativeSizeAxes = Axes.Both,
- RelativePositionAxes = Axes.X,
- X = -middle_split / 2,
- RimAction = TaikoAction.LeftRim,
- CentreAction = TaikoAction.LeftCentre
- },
- new TaikoHalfDrum(true)
- {
- Name = "Right Half",
- Anchor = Anchor.Centre,
- Origin = Anchor.CentreLeft,
- RelativeSizeAxes = Axes.Both,
- RelativePositionAxes = Axes.X,
- X = middle_split / 2,
- RimAction = TaikoAction.RightRim,
- CentreAction = TaikoAction.RightCentre
- }
- }
- };
- }
-
- ///
- /// A half-drum. Contains one centre and one rim hit.
- ///
- private class TaikoHalfDrum : Container, IKeyBindingHandler
- {
- ///
- /// The key to be used for the rim of the half-drum.
- ///
- public TaikoAction RimAction;
-
- ///
- /// The key to be used for the centre of the half-drum.
- ///
- public TaikoAction CentreAction;
-
- private readonly Sprite rim;
- private readonly Sprite rimHit;
- private readonly Sprite centre;
- private readonly Sprite centreHit;
-
- public TaikoHalfDrum(bool flipped)
- {
- Masking = true;
-
- Children = new Drawable[]
- {
- rim = new Sprite
- {
- Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both
- },
- rimHit = new Sprite
- {
- Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Alpha = 0,
- Blending = BlendingParameters.Additive,
- },
- centre = new Sprite
- {
- Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Size = new Vector2(0.7f)
- },
- centreHit = new Sprite
- {
- Anchor = flipped ? Anchor.CentreLeft : Anchor.CentreRight,
- Origin = Anchor.Centre,
- RelativeSizeAxes = Axes.Both,
- Size = new Vector2(0.7f),
- Alpha = 0,
- Blending = BlendingParameters.Additive
- }
- };
- }
-
- [BackgroundDependencyLoader]
- private void load(TextureStore textures, OsuColour colours)
- {
- rim.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer");
- rimHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-outer-hit");
- centre.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner");
- centreHit.Texture = textures.Get(@"Gameplay/taiko/taiko-drum-inner-hit");
-
- rimHit.Colour = colours.Blue;
- centreHit.Colour = colours.Pink;
- }
-
- public bool OnPressed(KeyBindingPressEvent e)
- {
- Drawable target = null;
- Drawable back = null;
-
- if (e.Action == CentreAction)
- {
- target = centreHit;
- back = centre;
- }
- else if (e.Action == RimAction)
- {
- target = rimHit;
- back = rim;
- }
-
- if (target != null)
- {
- const float scale_amount = 0.05f;
- const float alpha_amount = 0.5f;
-
- const float down_time = 40;
- const float up_time = 1000;
-
- back.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint)
- .Then()
- .ScaleTo(1, up_time, Easing.OutQuint);
-
- target.Animate(
- t => t.ScaleTo(target.Scale.X - scale_amount, down_time, Easing.OutQuint),
- t => t.FadeTo(Math.Min(target.Alpha + alpha_amount, 1), down_time, Easing.OutQuint)
- ).Then(
- t => t.ScaleTo(1, up_time, Easing.OutQuint),
- t => t.FadeOut(up_time, Easing.OutQuint)
- );
- }
-
- return false;
- }
-
- public void OnReleased(KeyBindingReleaseEvent e)
- {
- }
- }
- }
}
}
diff --git a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs
index 319d8979ae..627e06e186 100644
--- a/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs
+++ b/osu.Game.Rulesets.Taiko/UI/KiaiHitExplosion.cs
@@ -1,13 +1,12 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Taiko.Objects;
+using osu.Game.Rulesets.Taiko.Skinning.Default;
using osu.Game.Skinning;
using osuTK;
@@ -22,7 +21,7 @@ namespace osu.Game.Rulesets.Taiko.UI
private readonly HitType hitType;
- private SkinnableDrawable skinnable;
+ private SkinnableDrawable skinnable = null!;
public override double LifetimeStart => skinnable.Drawable.LifetimeStart;
@@ -33,7 +32,7 @@ namespace osu.Game.Rulesets.Taiko.UI
JudgedObject = judgedObject;
this.hitType = hitType;
- Anchor = Anchor.CentreLeft;
+ Anchor = Anchor.Centre;
Origin = Anchor.Centre;
RelativeSizeAxes = Axes.Both;
@@ -43,7 +42,7 @@ namespace osu.Game.Rulesets.Taiko.UI
[BackgroundDependencyLoader]
private void load()
{
- Child = skinnable = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType));
+ Child = skinnable = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.TaikoExplosionKiai), _ => new DefaultKiaiHitExplosion(hitType));
}
}
}
diff --git a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs
index db1094e100..2a8890a95d 100644
--- a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs
+++ b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundLeft.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs
index 43252e2e77..44bfdacf37 100644
--- a/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs
+++ b/osu.Game.Rulesets.Taiko/UI/PlayfieldBackgroundRight.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Framework.Allocation;
using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs b/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs
index f48ed2c941..6401c6d09f 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoHitTarget.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osuTK;
using osuTK.Graphics;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs
index 26a37fc464..0f214b8436 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Allocation;
using osu.Framework.Audio.Track;
@@ -89,7 +87,7 @@ namespace osu.Game.Rulesets.Taiko.UI
[BackgroundDependencyLoader]
private void load(ISkinSource source)
{
- ISkin skin = source.FindProvider(s => getAnimationFrame(s, state, 0) != null);
+ ISkin? skin = source.FindProvider(s => getAnimationFrame(s, state, 0) != null);
if (skin == null) return;
@@ -120,7 +118,7 @@ namespace osu.Game.Rulesets.Taiko.UI
[BackgroundDependencyLoader]
private void load(ISkinSource source)
{
- ISkin skin = source.FindProvider(s => getAnimationFrame(s, TaikoMascotAnimationState.Clear, 0) != null);
+ ISkin? skin = source.FindProvider(s => getAnimationFrame(s, TaikoMascotAnimationState.Clear, 0) != null);
if (skin == null) return;
@@ -137,7 +135,7 @@ 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().ToLowerInvariant()}{frameIndex}");
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs
index 717f0d725a..02bf245b7b 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimationState.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
namespace osu.Game.Rulesets.Taiko.UI
{
public enum TaikoMascotAnimationState
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
index cc71ba5401..45a3b80931 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfield.cs
@@ -60,8 +60,9 @@ namespace osu.Game.Rulesets.Taiko.UI
///
private BarLinePlayfield barLinePlayfield;
- private Container playfieldContent;
- private Container playfieldOverlay;
+ private Container barLineContent;
+ private Container hitObjectContent;
+ private Container overlayContent;
[BackgroundDependencyLoader]
private void load(OsuColour colours)
@@ -76,7 +77,7 @@ namespace osu.Game.Rulesets.Taiko.UI
InternalChildren = new[]
{
- new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()),
+ new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.PlayfieldBackgroundRight), _ => new PlayfieldBackgroundRight()),
new Container
{
Name = "Left overlay",
@@ -85,11 +86,11 @@ namespace osu.Game.Rulesets.Taiko.UI
BorderColour = colours.Gray0,
Children = new[]
{
- new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()),
+ new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.PlayfieldBackgroundLeft), _ => new PlayfieldBackgroundLeft()),
inputDrum.CreateProxy(),
}
},
- mascot = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.Mascot), _ => Empty())
+ mascot = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.Mascot), _ => Empty())
{
Origin = Anchor.BottomLeft,
Anchor = Anchor.TopLeft,
@@ -115,28 +116,26 @@ namespace osu.Game.Rulesets.Taiko.UI
{
RelativeSizeAxes = Axes.Both,
},
- HitTarget = new SkinnableDrawable(new TaikoSkinComponent(TaikoSkinComponents.HitTarget), _ => new TaikoHitTarget())
+ HitTarget = new SkinnableDrawable(new TaikoSkinComponentLookup(TaikoSkinComponents.HitTarget), _ => new TaikoHitTarget())
{
RelativeSizeAxes = Axes.Both,
}
}
},
- new Container
+ barLineContent = new Container
+ {
+ Name = "Bar line content",
+ RelativeSizeAxes = Axes.Both,
+ Child = barLinePlayfield = new BarLinePlayfield(),
+ },
+ hitObjectContent = new Container
{
Name = "Masked hit objects content",
RelativeSizeAxes = Axes.Both,
Masking = true,
- Child = playfieldContent = new Container
- {
- RelativeSizeAxes = Axes.Both,
- Children = new Drawable[]
- {
- barLinePlayfield = new BarLinePlayfield(),
- HitObjectContainer,
- }
- }
+ Child = HitObjectContainer,
},
- playfieldOverlay = new Container
+ overlayContent = new Container
{
Name = "Elements after hit objects",
RelativeSizeAxes = Axes.Both,
@@ -146,13 +145,16 @@ namespace osu.Game.Rulesets.Taiko.UI
kiaiExplosionContainer = new Container
{
Name = "Kiai hit explosions",
+ Origin = Anchor.TopCentre,
RelativeSizeAxes = Axes.Both,
FillMode = FillMode.Fit,
},
judgementContainer = new JudgementContainer
{
Name = "Judgements",
- RelativeSizeAxes = Axes.Y,
+ Origin = Anchor.TopCentre,
+ RelativeSizeAxes = Axes.Both,
+ FillMode = FillMode.Fit,
},
}
},
@@ -215,8 +217,9 @@ namespace osu.Game.Rulesets.Taiko.UI
// Padding is required to be updated for elements which are based on "absolute" X sized elements.
// This is basically allowing for correct alignment as relative pieces move around them.
rightArea.Padding = new MarginPadding { Left = inputDrum.Width };
- playfieldContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
- playfieldOverlay.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
+ barLineContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
+ hitObjectContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
+ overlayContent.Padding = new MarginPadding { Left = HitTarget.DrawWidth / 2 };
mascot.Scale = new Vector2(DrawHeight / DEFAULT_HEIGHT);
}
@@ -320,15 +323,7 @@ namespace osu.Game.Rulesets.Taiko.UI
if (!result.Type.IsScorable())
break;
- judgementContainer.Add(judgementPools[result.Type].Get(j =>
- {
- j.Apply(result, judgedObject);
-
- j.Anchor = result.IsHit ? Anchor.TopLeft : Anchor.CentreLeft;
- j.Origin = result.IsHit ? Anchor.BottomCentre : Anchor.Centre;
- j.RelativePositionAxes = Axes.X;
- j.X = result.IsHit ? judgedObject.Position.X : 0;
- }));
+ judgementContainer.Add(judgementPools[result.Type].Get(j => j.Apply(result, judgedObject)));
var type = (judgedObject.HitObject as Hit)?.Type ?? HitType.Centre;
addExplosion(judgedObject, result.Type, type);
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs
index 8e99a82b1b..9cf530e903 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoPlayfieldAdjustmentContainer.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs b/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs
index a76adc495d..e6391d1386 100644
--- a/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs
+++ b/osu.Game.Rulesets.Taiko/UI/TaikoReplayRecorder.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using osu.Game.Rulesets.Replays;
using osu.Game.Rulesets.Taiko.Replays;
diff --git a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
index fdd0167ed3..c6bdd25e8b 100644
--- a/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
+++ b/osu.Game.Tests/Beatmaps/Formats/LegacyBeatmapDecoderTest.cs
@@ -308,7 +308,7 @@ namespace osu.Game.Tests.Beatmaps.Formats
new Color4(255, 177, 140, 255),
new Color4(100, 100, 100, 255), // alpha is specified as 100, but should be ignored.
};
- Assert.AreEqual(expectedColors.Length, comboColors.Count);
+ Assert.AreEqual(expectedColors.Length, comboColors?.Count);
for (int i = 0; i < expectedColors.Length; i++)
Assert.AreEqual(expectedColors[i], comboColors[i]);
}
diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs
index 947e884494..9774a8ebb6 100644
--- a/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckAudioInVideoTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.IO;
using System.Linq;
using Moq;
@@ -20,8 +18,8 @@ namespace osu.Game.Tests.Editing.Checks
[TestFixture]
public class CheckAudioInVideoTest
{
- private CheckAudioInVideo check;
- private IBeatmap beatmap;
+ private CheckAudioInVideo check = null!;
+ private IBeatmap beatmap = null!;
[SetUp]
public void Setup()
@@ -84,7 +82,7 @@ namespace osu.Game.Tests.Editing.Checks
Assert.That(issues.Single().Template is CheckAudioInVideo.IssueTemplateMissingFile);
}
- private BeatmapVerifierContext getContext(Stream resourceStream)
+ private BeatmapVerifierContext getContext(Stream? resourceStream)
{
var storyboard = new Storyboard();
var layer = storyboard.GetLayer("Video");
diff --git a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs
index 50e6087526..61ee6a3663 100644
--- a/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckAudioQualityTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Linq;
using Moq;
using NUnit.Framework;
@@ -19,8 +17,8 @@ namespace osu.Game.Tests.Editing.Checks
[TestFixture]
public class CheckAudioQualityTest
{
- private CheckAudioQuality check;
- private IBeatmap beatmap;
+ private CheckAudioQuality check = null!;
+ private IBeatmap beatmap = null!;
[SetUp]
public void Setup()
@@ -43,7 +41,7 @@ namespace osu.Game.Tests.Editing.Checks
var mock = new Mock();
mock.SetupGet(w => w.Beatmap).Returns(beatmap);
- mock.SetupGet(w => w.Track).Returns((Track)null);
+ mock.SetupGet(w => w.Track).Returns((Track)null!);
Assert.That(check.Run(new BeatmapVerifierContext(beatmap, mock.Object)), Is.Empty);
}
diff --git a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs
index f91e83a556..295a10ba5b 100644
--- a/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckBackgroundQualityTest.cs
@@ -1,12 +1,9 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System;
using System.IO;
using System.Linq;
-using JetBrains.Annotations;
using Moq;
using NUnit.Framework;
using osu.Framework.Graphics.Rendering.Dummy;
@@ -21,8 +18,8 @@ namespace osu.Game.Tests.Editing.Checks
[TestFixture]
public class CheckBackgroundQualityTest
{
- private CheckBackgroundQuality check;
- private IBeatmap beatmap;
+ private CheckBackgroundQuality check = null!;
+ private IBeatmap beatmap = null!;
[SetUp]
public void Setup()
@@ -48,7 +45,7 @@ namespace osu.Game.Tests.Editing.Checks
{
// While this is a problem, it is out of scope for this check and is caught by a different one.
beatmap.Metadata.BackgroundFile = string.Empty;
- var context = getContext(null, new MemoryStream(Array.Empty()));
+ var context = getContext(null!, new MemoryStream(Array.Empty()));
Assert.That(check.Run(context), Is.Empty);
}
@@ -118,7 +115,7 @@ namespace osu.Game.Tests.Editing.Checks
stream.Verify(x => x.Close(), Times.Once());
}
- private BeatmapVerifierContext getContext(Texture background, [CanBeNull] Stream stream = null)
+ private BeatmapVerifierContext getContext(Texture background, Stream? stream = null)
{
return new BeatmapVerifierContext(beatmap, getMockWorkingBeatmap(background, stream).Object);
}
@@ -128,7 +125,7 @@ namespace osu.Game.Tests.Editing.Checks
///
/// The texture of the background.
/// The stream representing the background file.
- private Mock getMockWorkingBeatmap(Texture background, [CanBeNull] Stream stream = null)
+ private Mock getMockWorkingBeatmap(Texture background, Stream? stream = null)
{
stream ??= new MemoryStream(new byte[1024 * 1024]);
diff --git a/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs
index 9c1dd2c1e8..b5c6568583 100644
--- a/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckConcurrentObjectsTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using Moq;
@@ -21,7 +19,7 @@ namespace osu.Game.Tests.Editing.Checks
[TestFixture]
public class CheckConcurrentObjectsTest
{
- private CheckConcurrentObjects check;
+ private CheckConcurrentObjects check = null!;
[SetUp]
public void Setup()
diff --git a/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs b/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs
index 82bb2e59c9..01781b98ad 100644
--- a/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckFewHitsoundsTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@@ -20,10 +18,10 @@ namespace osu.Game.Tests.Editing.Checks
[TestFixture]
public class CheckFewHitsoundsTest
{
- private CheckFewHitsounds check;
+ private CheckFewHitsounds check = null!;
- private List notHitsounded;
- private List hitsounded;
+ private List notHitsounded = null!;
+ private List hitsounded = null!;
[SetUp]
public void Setup()
diff --git a/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs b/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs
index 2f18720a5b..89bb2f9396 100644
--- a/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckFilePresenceTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Linq;
using NUnit.Framework;
using osu.Game.Beatmaps;
@@ -16,8 +14,8 @@ namespace osu.Game.Tests.Editing.Checks
[TestFixture]
public class CheckFilePresenceTest
{
- private CheckBackgroundPresence check;
- private IBeatmap beatmap;
+ private CheckBackgroundPresence check = null!;
+ private IBeatmap beatmap = null!;
[SetUp]
public void Setup()
diff --git a/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs
index 622386405a..1e1c214c30 100644
--- a/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckMutedObjectsTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using NUnit.Framework;
@@ -21,8 +19,8 @@ namespace osu.Game.Tests.Editing.Checks
[TestFixture]
public class CheckMutedObjectsTest
{
- private CheckMutedObjects check;
- private ControlPointInfo cpi;
+ private CheckMutedObjects check = null!;
+ private ControlPointInfo cpi = null!;
private const int volume_regular = 50;
private const int volume_low = 15;
diff --git a/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs b/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs
index 405738cd55..9067714ff9 100644
--- a/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckTestHelpers.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using osu.Game.Models;
namespace osu.Game.Tests.Editing.Checks
diff --git a/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs
index 7d33b92dbe..4918369460 100644
--- a/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckTooShortAudioFilesTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Diagnostics;
using System.IO;
using System.Linq;
@@ -22,8 +20,8 @@ namespace osu.Game.Tests.Editing.Checks
[TestFixture]
public class CheckTooShortAudioFilesTest
{
- private CheckTooShortAudioFiles check;
- private IBeatmap beatmap;
+ private CheckTooShortAudioFiles check = null!;
+ private IBeatmap beatmap = null!;
[SetUp]
public void Setup()
@@ -109,7 +107,7 @@ namespace osu.Game.Tests.Editing.Checks
}
}
- private BeatmapVerifierContext getContext(Stream resourceStream)
+ private BeatmapVerifierContext getContext(Stream? resourceStream)
{
var mockWorkingBeatmap = new Mock(beatmap, null, null);
mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns(resourceStream);
diff --git a/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs
index f647bf8d8e..c9335dcda5 100644
--- a/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckUnsnappedObjectsTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using Moq;
@@ -21,8 +19,8 @@ namespace osu.Game.Tests.Editing.Checks
[TestFixture]
public class CheckUnsnappedObjectsTest
{
- private CheckUnsnappedObjects check;
- private ControlPointInfo cpi;
+ private CheckUnsnappedObjects check = null!;
+ private ControlPointInfo cpi = null!;
[SetUp]
public void Setup()
diff --git a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs
index 793cc70a3f..a39ef22b72 100644
--- a/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckZeroByteFilesTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.IO;
using System.Linq;
using Moq;
@@ -17,8 +15,8 @@ namespace osu.Game.Tests.Editing.Checks
[TestFixture]
public class CheckZeroByteFilesTest
{
- private CheckZeroByteFiles check;
- private IBeatmap beatmap;
+ private CheckZeroByteFiles check = null!;
+ private IBeatmap beatmap = null!;
[SetUp]
public void Setup()
@@ -74,7 +72,7 @@ namespace osu.Game.Tests.Editing.Checks
private BeatmapVerifierContext getContextMissing()
{
var mockWorkingBeatmap = new Mock();
- mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns((Stream)null);
+ mockWorkingBeatmap.Setup(w => w.GetStream(It.IsAny())).Returns((Stream)null!);
return new BeatmapVerifierContext(beatmap, mockWorkingBeatmap.Object);
}
diff --git a/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs b/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs
index 1c1965ab56..648f02839f 100644
--- a/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs
+++ b/osu.Game.Tests/Editing/Checks/CheckZeroLengthObjectsTest.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Linq;
using Moq;
@@ -21,7 +19,7 @@ namespace osu.Game.Tests.Editing.Checks
[TestFixture]
public class CheckZeroLengthObjectsTest
{
- private CheckZeroLengthObjects check;
+ private CheckZeroLengthObjects check = null!;
[SetUp]
public void Setup()
diff --git a/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs b/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs
index 6c0306d63d..29938839d3 100644
--- a/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs
+++ b/osu.Game.Tests/Editing/Checks/MockNestableHitObject.cs
@@ -1,8 +1,6 @@
// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
-#nullable disable
-
using System.Collections.Generic;
using System.Threading;
using osu.Game.Rulesets.Objects;
diff --git a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs
index 9701a32951..255d6400c8 100644
--- a/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs
+++ b/osu.Game.Tests/Gameplay/TestSceneHitObjectAccentColour.cs
@@ -6,6 +6,7 @@
using System;
using System.Collections.Generic;
using NUnit.Framework;
+using osu.Framework.Allocation;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
@@ -13,6 +14,7 @@ using osu.Framework.Graphics.Containers;
using osu.Framework.Graphics.Textures;
using osu.Framework.Testing;
using osu.Game.Audio;
+using osu.Game.Configuration;
using osu.Game.Rulesets.Objects.Drawables;
using osu.Game.Rulesets.Objects.Legacy;
using osu.Game.Rulesets.Objects.Types;
@@ -25,10 +27,20 @@ namespace osu.Game.Tests.Gameplay
[HeadlessTest]
public class TestSceneHitObjectAccentColour : OsuTestScene
{
+ [Resolved]
+ private OsuConfigManager config { get; set; }
+
private Container skinContainer;
[SetUp]
- public void Setup() => Schedule(() => Child = skinContainer = new SkinProvidingContainer(new TestSkin()));
+ public void Setup()
+ {
+ Schedule(() =>
+ {
+ config.SetValue(OsuSetting.ComboColourNormalisationAmount, 0f);
+ Child = skinContainer = new SkinProvidingContainer(new TestSkin());
+ });
+ }
[Test]
public void TestChangeComboIndexBeforeLoad()
@@ -126,7 +138,7 @@ namespace osu.Game.Tests.Gameplay
Color4.Green
};
- public Drawable GetDrawableComponent(ISkinComponent component) => throw new NotImplementedException();
+ public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => throw new NotImplementedException();
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException();
diff --git a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs
index 6297d9cdc7..5c247bace9 100644
--- a/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs
+++ b/osu.Game.Tests/NonVisual/Skinning/LegacySkinAnimationTest.cs
@@ -73,7 +73,7 @@ namespace osu.Game.Tests.NonVisual.Skinning
return lookup_names.Contains(componentName) ? renderer.WhitePixel : null;
}
- public Drawable GetDrawableComponent(ISkinComponent component) => throw new NotSupportedException();
+ public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => throw new NotSupportedException();
public ISample GetSample(ISampleInfo sampleInfo) => throw new NotSupportedException();
public IBindable GetConfig(TLookup lookup) => throw new NotSupportedException();
}
diff --git a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs
index 320373699d..a29fc9f1fb 100644
--- a/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs
+++ b/osu.Game.Tests/Rulesets/TestSceneRulesetSkinProvidingContainer.cs
@@ -78,7 +78,7 @@ namespace osu.Game.Tests.Rulesets
OnLoadAsync?.Invoke();
}
- public Drawable GetDrawableComponent(ISkinComponent component) => skin.GetDrawableComponent(component);
+ public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => skin.GetDrawableComponent(lookup);
public Texture GetTexture(string componentName, WrapMode wrapModeS = default, WrapMode wrapModeT = default) => skin.GetTexture(componentName);
diff --git a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs
index 6756f27ecd..9466fdf888 100644
--- a/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs
+++ b/osu.Game.Tests/Skins/LegacySkinDecoderTest.cs
@@ -32,7 +32,7 @@ namespace osu.Game.Tests.Skins
new Color4(100, 100, 100, 255), // alpha is specified as 100, but should be ignored.
};
- Assert.AreEqual(expectedColors.Count, comboColors.Count);
+ Assert.AreEqual(expectedColors.Count, comboColors?.Count);
for (int i = 0; i < expectedColors.Count; i++)
Assert.AreEqual(expectedColors[i], comboColors[i]);
}
@@ -49,7 +49,7 @@ namespace osu.Game.Tests.Skins
var comboColors = decoder.Decode(stream).ComboColours;
var expectedColors = SkinConfiguration.DefaultComboColours;
- Assert.AreEqual(expectedColors.Count, comboColors.Count);
+ Assert.AreEqual(expectedColors.Count, comboColors?.Count);
for (int i = 0; i < expectedColors.Count; i++)
Assert.AreEqual(expectedColors[i], comboColors[i]);
}
diff --git a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs
index 989459632e..cd6895b176 100644
--- a/osu.Game.Tests/Skins/SkinDeserialisationTest.cs
+++ b/osu.Game.Tests/Skins/SkinDeserialisationTest.cs
@@ -80,7 +80,7 @@ namespace osu.Game.Tests.Skins
var skin = new TestSkin(new SkinInfo(), null, storage);
Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2));
- Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents], Has.Length.EqualTo(9));
+ Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(9));
}
}
@@ -93,10 +93,10 @@ namespace osu.Game.Tests.Skins
var skin = new TestSkin(new SkinInfo(), null, storage);
Assert.That(skin.DrawableComponentInfo, Has.Count.EqualTo(2));
- Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents], Has.Length.EqualTo(6));
- Assert.That(skin.DrawableComponentInfo[SkinnableTarget.SongSelect], Has.Length.EqualTo(1));
+ Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(6));
+ Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.SongSelect], Has.Length.EqualTo(1));
- var skinnableInfo = skin.DrawableComponentInfo[SkinnableTarget.SongSelect].First();
+ var skinnableInfo = skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.SongSelect].First();
Assert.That(skinnableInfo.Type, Is.EqualTo(typeof(SkinnableSprite)));
Assert.That(skinnableInfo.Settings.First().Key, Is.EqualTo("sprite_name"));
@@ -107,10 +107,10 @@ namespace osu.Game.Tests.Skins
using (var storage = new ZipArchiveReader(stream))
{
var skin = new TestSkin(new SkinInfo(), null, storage);
- Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents], Has.Length.EqualTo(8));
- Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter)));
- Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter)));
- Assert.That(skin.DrawableComponentInfo[SkinnableTarget.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress)));
+ Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents], Has.Length.EqualTo(8));
+ Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(UnstableRateCounter)));
+ Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(ColourHitErrorMeter)));
+ Assert.That(skin.DrawableComponentInfo[GlobalSkinComponentLookup.LookupType.MainHUDComponents].Select(i => i.Type), Contains.Item(typeof(LegacySongProgress)));
}
}
diff --git a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs
index 004e253c1f..a31c624f78 100644
--- a/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs
+++ b/osu.Game.Tests/Skins/TestSceneBeatmapSkinLookupDisables.cs
@@ -48,7 +48,7 @@ namespace osu.Game.Tests.Skins
string expected = allowBeatmapLookups ? "beatmap" : "user";
- AddAssert($"Check lookup is from {expected}", () => requester.GetDrawableComponent(new TestSkinComponent())?.Name == expected);
+ AddAssert($"Check lookup is from {expected}", () => requester.GetDrawableComponent(new TestSkinComponentLookup())?.Name == expected);
}
[TestCase(false)]
@@ -59,7 +59,7 @@ namespace osu.Game.Tests.Skins
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 TestSkinComponentLookup()) != null) == expected());
}
public class UserSkinSource : LegacySkin
@@ -69,7 +69,7 @@ namespace osu.Game.Tests.Skins
{
}
- public override Drawable GetDrawableComponent(ISkinComponent component)
+ public override Drawable GetDrawableComponent(ISkinComponentLookup lookup)
{
return new Container { Name = "user" };
}
@@ -82,7 +82,7 @@ namespace osu.Game.Tests.Skins
{
}
- public override Drawable GetDrawableComponent(ISkinComponent component)
+ public override Drawable GetDrawableComponent(ISkinComponentLookup lookup)
{
return new Container { Name = "beatmap" };
}
@@ -98,7 +98,7 @@ namespace osu.Game.Tests.Skins
this.skin = skin;
}
- public Drawable GetDrawableComponent(ISkinComponent component) => skin.GetDrawableComponent(component);
+ public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => skin.GetDrawableComponent(lookup);
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => skin.GetTexture(componentName, wrapModeS, wrapModeT);
@@ -109,7 +109,7 @@ namespace osu.Game.Tests.Skins
public ISkin FindProvider(Func lookupFunction) => skin.FindProvider(lookupFunction);
}
- private class TestSkinComponent : ISkinComponent
+ private class TestSkinComponentLookup : ISkinComponentLookup
{
public string LookupName => string.Empty;
}
diff --git a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs
index b0c26f7280..8c6f137dc0 100644
--- a/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs
+++ b/osu.Game.Tests/Skins/TestSceneSkinConfigurationLookup.cs
@@ -146,7 +146,8 @@ namespace osu.Game.Tests.Skins
AddStep("Disallow default colours fallback in beatmap skin", () => beatmapSource.Configuration.AllowDefaultComboColoursFallback = false);
AddAssert("Check retrieved combo colours from user skin", () =>
- requester.GetConfig>(GlobalSkinColours.ComboColours)?.Value?.SequenceEqual(userSource.Configuration.ComboColours) ?? false);
+ userSource.Configuration.ComboColours != null &&
+ (requester.GetConfig>(GlobalSkinColours.ComboColours)?.Value?.SequenceEqual(userSource.Configuration.ComboColours) ?? false));
}
[Test]
@@ -220,7 +221,7 @@ namespace osu.Game.Tests.Skins
this.skin = skin;
}
- public Drawable GetDrawableComponent(ISkinComponent component) => skin.GetDrawableComponent(component);
+ public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => skin.GetDrawableComponent(lookup);
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => skin.GetTexture(componentName, wrapModeS, wrapModeT);
diff --git a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs
index f7c88643fe..ad71296a11 100644
--- a/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs
+++ b/osu.Game.Tests/Skins/TestSceneSkinProvidingContainer.cs
@@ -87,7 +87,7 @@ namespace osu.Game.Tests.Skins
this.renderer = renderer;
}
- public Drawable GetDrawableComponent(ISkinComponent component) => throw new System.NotImplementedException();
+ public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => throw new System.NotImplementedException();
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT)
{
diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs
index 10515fd95f..82e18e45bb 100644
--- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardDownloadButton.cs
@@ -59,8 +59,9 @@ namespace osu.Game.Tests.Visual.Beatmaps
{
Anchor = Anchor.Centre,
Origin = Anchor.Centre,
+ Size = new Vector2(25f, 50f),
+ Scale = new Vector2(2f),
State = { Value = DownloadState.NotDownloaded },
- Scale = new Vector2(2)
};
});
}
diff --git a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs
index 2fe2264348..9540d9e4f7 100644
--- a/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs
+++ b/osu.Game.Tests/Visual/Beatmaps/TestSceneBeatmapCardFavouriteButton.cs
@@ -37,7 +37,11 @@ namespace osu.Game.Tests.Visual.Beatmaps
beatmapSetInfo = CreateAPIBeatmapSet(Ruleset.Value);
beatmapSetInfo.HasFavourited = favourited;
});
- AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) { Scale = new Vector2(2) });
+ AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo)
+ {
+ Size = new Vector2(25f, 50f),
+ Scale = new Vector2(2f),
+ });
assertCorrectIcon(favourited);
AddAssert("correct tooltip text", () => button.TooltipText == (favourited ? BeatmapsetsStrings.ShowDetailsUnfavourite : BeatmapsetsStrings.ShowDetailsFavourite));
@@ -51,7 +55,11 @@ namespace osu.Game.Tests.Visual.Beatmaps
BeatmapFavouriteAction? lastRequestAction = null;
AddStep("create beatmap set", () => beatmapSetInfo = CreateAPIBeatmapSet(Ruleset.Value));
- AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo) { Scale = new Vector2(2) });
+ AddStep("create button", () => Child = button = new FavouriteButton(beatmapSetInfo)
+ {
+ Size = new Vector2(25f, 50f),
+ Scale = new Vector2(2f),
+ });
assertCorrectIcon(false);
diff --git a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs
index a5d115331d..981967e413 100644
--- a/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs
+++ b/osu.Game.Tests/Visual/Editing/TestSceneEditorTestGameplay.cs
@@ -7,10 +7,12 @@ using System;
using System.Linq;
using NUnit.Framework;
using osu.Framework.Allocation;
+using osu.Framework.Bindables;
using osu.Framework.Extensions;
using osu.Framework.Screens;
using osu.Framework.Testing;
using osu.Game.Beatmaps;
+using osu.Game.Configuration;
using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
@@ -21,7 +23,6 @@ using osu.Game.Screens.Edit.GameplayTest;
using osu.Game.Screens.Play;
using osu.Game.Storyboards;
using osu.Game.Tests.Beatmaps.IO;
-using osuTK.Graphics;
using osuTK.Input;
namespace osu.Game.Tests.Visual.Editing
@@ -40,6 +41,14 @@ namespace osu.Game.Tests.Visual.Editing
private BeatmapSetInfo importedBeatmapSet;
+ private Bindable editorDim;
+
+ [BackgroundDependencyLoader]
+ private void load(OsuConfigManager config)
+ {
+ editorDim = config.GetBindable(OsuSetting.EditorDim);
+ }
+
public override void SetUpSteps()
{
AddStep("import test beatmap", () => importedBeatmapSet = BeatmapImportHelper.LoadOszIntoOsu(game).GetResultSafely());
@@ -77,7 +86,7 @@ namespace osu.Game.Tests.Visual.Editing
// this test cares about checking the background belonging to the editor specifically, so check that using reference equality
// (as `.Equals()` cannot discern between the two, as they technically share the same database GUID).
var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo));
- return background.Colour == Color4.DarkGray && background.BlurAmount.Value == 0;
+ return background.DimWhenUserSettingsIgnored.Value == editorDim.Value && background.BlurAmount.Value == 0;
});
AddAssert("no mods selected", () => SelectedMods.Value.Count == 0);
}
@@ -110,7 +119,7 @@ namespace osu.Game.Tests.Visual.Editing
// this test cares about checking the background belonging to the editor specifically, so check that using reference equality
// (as `.Equals()` cannot discern between the two, as they technically share the same database GUID).
var background = this.ChildrenOfType().Single(b => ReferenceEquals(b.Beatmap.BeatmapInfo, EditorBeatmap.BeatmapInfo));
- return background.Colour == Color4.DarkGray && background.BlurAmount.Value == 0;
+ return background.DimWhenUserSettingsIgnored.Value == editorDim.Value && background.BlurAmount.Value == 0;
});
AddStep("start track", () => EditorClock.Start());
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs
index 01cc856a4a..8ad97eb33c 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBeatmapSkinFallbacks.cs
@@ -40,7 +40,7 @@ namespace osu.Game.Tests.Visual.Gameplay
{
CreateSkinTest(TrianglesSkin.CreateInfo(), () => new LegacyBeatmapSkin(new BeatmapInfo(), null));
AddUntilStep("wait for hud load", () => Player.ChildrenOfType().All(c => c.ComponentsLoaded));
- AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(SkinnableTarget.MainHUDComponents, skinManager.CurrentSkin.Value));
+ AddAssert("hud from default skin", () => AssertComponentsFromExpectedSource(GlobalSkinComponentLookup.LookupType.MainHUDComponents, skinManager.CurrentSkin.Value));
}
protected void CreateSkinTest(SkinInfo gameCurrentSkin, Func getBeatmapSkin)
@@ -55,7 +55,7 @@ namespace osu.Game.Tests.Visual.Gameplay
});
}
- protected bool AssertComponentsFromExpectedSource(SkinnableTarget target, ISkin expectedSource)
+ protected bool AssertComponentsFromExpectedSource(GlobalSkinComponentLookup.LookupType target, ISkin expectedSource)
{
var actualComponentsContainer = Player.ChildrenOfType().First(s => s.Target == target)
.ChildrenOfType().SingleOrDefault();
@@ -65,7 +65,7 @@ namespace osu.Game.Tests.Visual.Gameplay
var actualInfo = actualComponentsContainer.CreateSkinnableInfo();
- var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new SkinnableTargetComponent(target));
+ var expectedComponentsContainer = (SkinnableTargetComponentsContainer)expectedSource.GetDrawableComponent(new GlobalSkinComponentLookup(target));
if (expectedComponentsContainer == null)
return false;
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs
new file mode 100644
index 0000000000..28a9d17882
--- /dev/null
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneBezierConverter.cs
@@ -0,0 +1,190 @@
+// Copyright (c) ppy Pty Ltd . 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.Bindables;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Lines;
+using osu.Game.Rulesets.Objects;
+using osu.Game.Rulesets.Objects.Types;
+using osuTK;
+
+namespace osu.Game.Tests.Visual.Gameplay
+{
+ public class TestSceneBezierConverter : OsuTestScene
+ {
+ private readonly SmoothPath drawablePath;
+ private readonly SmoothPath controlPointDrawablePath;
+ private readonly SmoothPath convertedDrawablePath;
+ private readonly SmoothPath convertedControlPointDrawablePath;
+
+ private SliderPath path = null!;
+ private SliderPath convertedPath = null!;
+
+ public TestSceneBezierConverter()
+ {
+ Children = new Drawable[]
+ {
+ new Container
+ {
+ Children =
+ new Drawable[]
+ {
+ drawablePath = new SmoothPath(),
+ controlPointDrawablePath = new SmoothPath
+ {
+ Colour = Colour4.Magenta,
+ PathRadius = 1f
+ }
+ },
+ Position = new Vector2(100)
+ },
+ new Container
+ {
+ Children =
+ new Drawable[]
+ {
+ convertedDrawablePath = new SmoothPath(),
+ convertedControlPointDrawablePath = new SmoothPath
+ {
+ Colour = Colour4.Magenta,
+ PathRadius = 1f
+ }
+ },
+ Position = new Vector2(100, 300)
+ }
+ };
+
+ resetPath();
+ }
+
+ [SetUp]
+ public void Setup() => Schedule(resetPath);
+
+ private void resetPath()
+ {
+ path = new SliderPath();
+ convertedPath = new SliderPath();
+
+ path.Version.ValueChanged += getConvertedControlPoints;
+ }
+
+ private void getConvertedControlPoints(ValueChangedEvent obj)
+ {
+ convertedPath.ControlPoints.Clear();
+ convertedPath.ControlPoints.AddRange(BezierConverter.ConvertToModernBezier(path.ControlPoints));
+ }
+
+ protected override void Update()
+ {
+ base.Update();
+
+ List vertices = new List();
+
+ path.GetPathToProgress(vertices, 0, 1);
+
+ drawablePath.Vertices = vertices;
+ controlPointDrawablePath.Vertices = path.ControlPoints.Select(o => o.Position).ToList();
+
+ if (controlPointDrawablePath.Vertices.Count > 0)
+ {
+ controlPointDrawablePath.Position =
+ drawablePath.PositionInBoundingBox(drawablePath.Vertices[0]) - controlPointDrawablePath.PositionInBoundingBox(controlPointDrawablePath.Vertices[0]);
+ }
+
+ vertices.Clear();
+
+ convertedPath.GetPathToProgress(vertices, 0, 1);
+
+ convertedDrawablePath.Vertices = vertices;
+ convertedControlPointDrawablePath.Vertices = convertedPath.ControlPoints.Select(o => o.Position).ToList();
+
+ if (convertedControlPointDrawablePath.Vertices.Count > 0)
+ {
+ convertedControlPointDrawablePath.Position = convertedDrawablePath.PositionInBoundingBox(convertedDrawablePath.Vertices[0])
+ - convertedControlPointDrawablePath.PositionInBoundingBox(convertedControlPointDrawablePath.Vertices[0]);
+ }
+ }
+
+ [Test]
+ public void TestEmptyPath()
+ {
+ }
+
+ [TestCase(PathType.Linear)]
+ [TestCase(PathType.Bezier)]
+ [TestCase(PathType.Catmull)]
+ [TestCase(PathType.PerfectCurve)]
+ public void TestSingleSegment(PathType type)
+ => AddStep("create path", () => path.ControlPoints.AddRange(createSegment(type, Vector2.Zero, new Vector2(0, 100), new Vector2(100))));
+
+ [TestCase(PathType.Linear)]
+ [TestCase(PathType.Bezier)]
+ [TestCase(PathType.Catmull)]
+ [TestCase(PathType.PerfectCurve)]
+ public void TestMultipleSegment(PathType type)
+ {
+ AddStep("create path", () =>
+ {
+ path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero));
+ path.ControlPoints.AddRange(createSegment(type, new Vector2(0, 100), new Vector2(100), Vector2.Zero));
+ });
+ }
+
+ [Test]
+ public void TestComplex()
+ {
+ AddStep("create path", () =>
+ {
+ path.ControlPoints.AddRange(createSegment(PathType.Linear, Vector2.Zero, new Vector2(100, 0)));
+ path.ControlPoints.AddRange(createSegment(PathType.Bezier, new Vector2(100, 0), new Vector2(150, 30), new Vector2(100, 100)));
+ path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, new Vector2(100, 100), new Vector2(25, 50), Vector2.Zero));
+ });
+ }
+
+ [TestCase(0, 100)]
+ [TestCase(1, 100)]
+ [TestCase(5, 100)]
+ [TestCase(10, 100)]
+ [TestCase(30, 100)]
+ [TestCase(50, 100)]
+ [TestCase(100, 100)]
+ [TestCase(100, 1)]
+ public void TestPerfectCurveAngles(float height, float width)
+ {
+ AddStep("create path", () =>
+ {
+ path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(width / 2, height), new Vector2(width, 0)));
+ });
+ }
+
+ [TestCase(2)]
+ [TestCase(4)]
+ public void TestPerfectCurveFallbackScenarios(int points)
+ {
+ AddStep("create path", () =>
+ {
+ switch (points)
+ {
+ case 2:
+ path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(0, 100)));
+ break;
+
+ case 4:
+ path.ControlPoints.AddRange(createSegment(PathType.PerfectCurve, Vector2.Zero, new Vector2(0, 100), new Vector2(100), new Vector2(100, 0)));
+ break;
+ }
+ });
+ }
+
+ private List createSegment(PathType type, params Vector2[] controlPoints)
+ {
+ var points = controlPoints.Select(p => new PathControlPoint { Position = p }).ToList();
+ points[0].Type = type;
+ return points;
+ }
+ }
+}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs
index d4fba76c37..97974d2368 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableDrawable.cs
@@ -164,7 +164,7 @@ namespace osu.Game.Tests.Visual.Gameplay
{
private bool allow = true;
- protected override bool AllowDrawableLookup(ISkinComponent component) => allow;
+ protected override bool AllowDrawableLookup(ISkinComponentLookup lookup) => allow;
public void Disable()
{
@@ -182,8 +182,8 @@ namespace osu.Game.Tests.Visual.Gameplay
{
public new Drawable Drawable => base.Drawable;
- public ExposedSkinnableDrawable(string name, Func defaultImplementation, ConfineMode confineMode = ConfineMode.ScaleToFit)
- : base(new TestSkinComponent(name), defaultImplementation, confineMode)
+ public ExposedSkinnableDrawable(string name, Func defaultImplementation, ConfineMode confineMode = ConfineMode.ScaleToFit)
+ : base(new TestSkinComponentLookup(name), defaultImplementation, confineMode)
{
}
}
@@ -251,8 +251,8 @@ namespace osu.Game.Tests.Visual.Gameplay
public new Drawable Drawable => base.Drawable;
public int SkinChangedCount { get; private set; }
- public SkinConsumer(string name, Func defaultImplementation)
- : base(new TestSkinComponent(name), defaultImplementation)
+ public SkinConsumer(string name, Func defaultImplementation)
+ : base(new TestSkinComponentLookup(name), defaultImplementation)
{
}
@@ -288,8 +288,8 @@ namespace osu.Game.Tests.Visual.Gameplay
this.size = size;
}
- public Drawable GetDrawableComponent(ISkinComponent componentName) =>
- componentName.LookupName == "available"
+ public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) =>
+ (componentLookupName as TestSkinComponentLookup)?.LookupName == "available"
? new DrawWidthBox
{
Colour = Color4.Yellow,
@@ -306,7 +306,7 @@ namespace osu.Game.Tests.Visual.Gameplay
private class SecondarySource : ISkin
{
- public Drawable GetDrawableComponent(ISkinComponent componentName) => new SecondarySourceBox();
+ public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) => new SecondarySourceBox();
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException();
@@ -318,7 +318,7 @@ namespace osu.Game.Tests.Visual.Gameplay
[Cached(typeof(ISkinSource))]
private class SkinSourceContainer : Container, ISkinSource
{
- public Drawable GetDrawableComponent(ISkinComponent componentName) => new BaseSourceBox();
+ public Drawable GetDrawableComponent(ISkinComponentLookup componentLookupName) => new BaseSourceBox();
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => throw new NotImplementedException();
@@ -337,9 +337,9 @@ namespace osu.Game.Tests.Visual.Gameplay
}
}
- private class TestSkinComponent : ISkinComponent
+ private class TestSkinComponentLookup : ISkinComponentLookup
{
- public TestSkinComponent(string name)
+ public TestSkinComponentLookup(string name)
{
LookupName = name;
}
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs
index 0ba112ec40..8122d8defb 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkinnableSound.cs
@@ -142,7 +142,7 @@ namespace osu.Game.Tests.Visual.Gameplay
IBindable ISamplePlaybackDisabler.SamplePlaybackDisabled => SamplePlaybackDisabled;
- public Drawable GetDrawableComponent(ISkinComponent component) => source?.GetDrawableComponent(component);
+ public Drawable GetDrawableComponent(ISkinComponentLookup lookup) => source?.GetDrawableComponent(lookup);
public Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => source?.GetTexture(componentName, wrapModeS, wrapModeT);
public ISample GetSample(ISampleInfo sampleInfo) => source?.GetSample(sampleInfo);
public IBindable GetConfig(TLookup lookup) => source?.GetConfig(lookup);
diff --git a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs
index 6b02449aa3..1bba62a5cf 100644
--- a/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs
+++ b/osu.Game.Tests/Visual/Gameplay/TestSceneSkipOverlay.cs
@@ -93,6 +93,15 @@ namespace osu.Game.Tests.Visual.Gameplay
checkRequestCount(1);
}
+ [Test]
+ public void TestAutomaticSkipActuatesOnce()
+ {
+ createTest();
+ AddStep("start automated skip", () => skip.SkipWhenReady());
+ AddUntilStep("wait for button disabled", () => !skip.IsButtonVisible);
+ checkRequestCount(1);
+ }
+
[Test]
public void TestClickOnlyActuatesOnce()
{
@@ -110,6 +119,16 @@ namespace osu.Game.Tests.Visual.Gameplay
checkRequestCount(1);
}
+ [Test]
+ public void TestAutomaticSkipActuatesMultipleTimes()
+ {
+ createTest();
+ AddStep("set increment lower", () => increment = 3000);
+ AddStep("start automated skip", () => skip.SkipWhenReady());
+ AddUntilStep("wait for button disabled", () => !skip.IsButtonVisible);
+ checkRequestCount(2);
+ }
+
[Test]
public void TestClickOnlyActuatesMultipleTimes()
{
@@ -137,8 +156,11 @@ namespace osu.Game.Tests.Visual.Gameplay
checkRequestCount(0);
}
- private void checkRequestCount(int expected) =>
- AddAssert($"request count is {expected}", () => requestCount == expected);
+ private void checkRequestCount(int expected)
+ {
+ AddAssert($"skip count is {expected}", () => skip.SkipCount, () => Is.EqualTo(expected));
+ AddAssert($"request count is {expected}", () => requestCount, () => Is.EqualTo(expected));
+ }
private class TestSkipOverlay : SkipOverlay
{
diff --git a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
index 8fce43f9b0..d58887c090 100644
--- a/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
+++ b/osu.Game.Tests/Visual/Navigation/TestSceneScreenNavigation.cs
@@ -513,6 +513,40 @@ namespace osu.Game.Tests.Visual.Navigation
AddWaitStep("wait two frames", 2);
}
+ [Test]
+ public void TestMainOverlaysClosesNotificationOverlay()
+ {
+ ChangelogOverlay getChangelogOverlay() => Game.ChildrenOfType().FirstOrDefault();
+
+ AddUntilStep("Wait for notifications to load", () => Game.Notifications.IsLoaded);
+ AddStep("Show notifications", () => Game.Notifications.Show());
+ AddUntilStep("wait for notifications shown", () => Game.Notifications.IsPresent && Game.Notifications.State.Value == Visibility.Visible);
+ AddStep("Show changelog listing", () => Game.ShowChangelogListing());
+ AddUntilStep("wait for changelog shown", () => getChangelogOverlay()?.IsPresent == true && getChangelogOverlay()?.State.Value == Visibility.Visible);
+ AddAssert("Notifications is hidden", () => Game.Notifications.State.Value == Visibility.Hidden);
+
+ AddStep("Show notifications", () => Game.Notifications.Show());
+ AddUntilStep("wait for notifications shown", () => Game.Notifications.State.Value == Visibility.Visible);
+ AddUntilStep("changelog still visible", () => getChangelogOverlay().State.Value == Visibility.Visible);
+ }
+
+ [Test]
+ public void TestMainOverlaysClosesSettingsOverlay()
+ {
+ ChangelogOverlay getChangelogOverlay() => Game.ChildrenOfType().FirstOrDefault();
+
+ AddUntilStep("Wait for settings to load", () => Game.Settings.IsLoaded);
+ AddStep("Show settings", () => Game.Settings.Show());
+ AddUntilStep("wait for settings shown", () => Game.Settings.IsPresent && Game.Settings.State.Value == Visibility.Visible);
+ AddStep("Show changelog listing", () => Game.ShowChangelogListing());
+ AddUntilStep("wait for changelog shown", () => getChangelogOverlay()?.IsPresent == true && getChangelogOverlay()?.State.Value == Visibility.Visible);
+ AddAssert("Settings is hidden", () => Game.Settings.State.Value == Visibility.Hidden);
+
+ AddStep("Show settings", () => Game.Settings.Show());
+ AddUntilStep("wait for settings shown", () => Game.Settings.State.Value == Visibility.Visible);
+ AddUntilStep("changelog still visible", () => getChangelogOverlay().State.Value == Visibility.Visible);
+ }
+
[Test]
public void TestOverlayClosing()
{
diff --git a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs
index 2c9b34e4a7..1e0a09d37a 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneBeatmapListingOverlay.cs
@@ -198,13 +198,13 @@ namespace osu.Game.Tests.Visual.Online
beatmapSet = CreateAPIBeatmapSet(Ruleset.Value);
beatmapSet.Title = "last beatmap of first page";
- fetchFor(getManyBeatmaps(49).Append(beatmapSet).ToArray(), true);
+ fetchFor(getManyBeatmaps(49).Append(new APIBeatmapSet { Title = "last beatmap of first page", OnlineID = beatmapSet.OnlineID }).ToArray(), true);
});
AddUntilStep("wait for loaded", () => this.ChildrenOfType().Count() == 50);
- AddStep("set next page", () => setSearchResponse(getManyBeatmaps(49).Prepend(beatmapSet).ToArray(), false));
+ AddStep("set next page", () => setSearchResponse(getManyBeatmaps(49).Prepend(new APIBeatmapSet { Title = "this shouldn't show up", OnlineID = beatmapSet.OnlineID }).ToArray(), false));
AddStep("scroll to end", () => overlay.ChildrenOfType().Single().ScrollToEnd());
- AddUntilStep("wait for loaded", () => this.ChildrenOfType().Count() == 99);
+ AddUntilStep("wait for loaded", () => this.ChildrenOfType().Count() >= 99);
AddAssert("beatmap not duplicated", () => overlay.ChildrenOfType().Count(c => c.BeatmapSet.Equals(beatmapSet)) == 1);
}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs
index bf01d3b0ac..b4ffcd42b5 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneCommentActions.cs
@@ -10,10 +10,12 @@ using NUnit.Framework;
using osu.Framework.Allocation;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Cursor;
using osu.Framework.Testing;
using osu.Game.Graphics.Containers;
using osu.Game.Graphics.Sprites;
using osu.Game.Graphics.UserInterface;
+using osu.Game.Graphics.UserInterfaceV2;
using osu.Game.Online.API;
using osu.Game.Online.API.Requests;
using osu.Game.Online.API.Requests.Responses;
@@ -37,14 +39,20 @@ namespace osu.Game.Tests.Visual.Online
private CommentsContainer commentsContainer = null!;
+ private readonly ManualResetEventSlim requestLock = new ManualResetEventSlim();
+
[BackgroundDependencyLoader]
private void load()
{
base.Content.AddRange(new Drawable[]
{
- content = new OsuScrollContainer
+ new PopoverContainer
{
- RelativeSizeAxes = Axes.Both
+ RelativeSizeAxes = Axes.Both,
+ Child = content = new OsuScrollContainer
+ {
+ RelativeSizeAxes = Axes.Both
+ }
},
dialogOverlay
});
@@ -80,8 +88,6 @@ namespace osu.Game.Tests.Visual.Online
});
}
- private readonly ManualResetEventSlim deletionPerformed = new ManualResetEventSlim();
-
[Test]
public void TestDeletion()
{
@@ -105,7 +111,7 @@ namespace osu.Game.Tests.Visual.Online
});
AddStep("Setup request handling", () =>
{
- deletionPerformed.Reset();
+ requestLock.Reset();
dummyAPI.HandleRequest = request =>
{
@@ -138,7 +144,7 @@ namespace osu.Game.Tests.Visual.Online
Task.Run(() =>
{
- deletionPerformed.Wait(10000);
+ requestLock.Wait(10000);
req.TriggerSuccess(cb);
});
@@ -149,7 +155,7 @@ namespace osu.Game.Tests.Visual.Online
AddAssert("Loading spinner shown", () => commentsContainer.ChildrenOfType().Any(d => d.IsPresent));
- AddStep("Complete request", () => deletionPerformed.Set());
+ AddStep("Complete request", () => requestLock.Set());
AddUntilStep("Comment is deleted locally", () => this.ChildrenOfType().Single(x => x.Comment.Id == 1).WasDeleted);
}
@@ -204,6 +210,74 @@ namespace osu.Game.Tests.Visual.Online
});
}
+ [Test]
+ public void TestReport()
+ {
+ const string report_text = "I don't like this comment";
+ DrawableComment? targetComment = null;
+ CommentReportRequest? request = null;
+
+ addTestComments();
+ AddUntilStep("Comment exists", () =>
+ {
+ var comments = this.ChildrenOfType();
+ targetComment = comments.SingleOrDefault(x => x.Comment.Id == 2);
+ return targetComment != null;
+ });
+ AddStep("Setup request handling", () =>
+ {
+ requestLock.Reset();
+
+ dummyAPI.HandleRequest = r =>
+ {
+ if (!(r is CommentReportRequest req))
+ return false;
+
+ Task.Run(() =>
+ {
+ request = req;
+ requestLock.Wait(10000);
+ req.TriggerSuccess();
+ });
+
+ return true;
+ };
+ });
+ AddStep("Click the button", () =>
+ {
+ var btn = targetComment.ChildrenOfType().Single(x => x.Text == "Report");
+ InputManager.MoveMouseTo(btn);
+ InputManager.Click(MouseButton.Left);
+ });
+ AddStep("Try to report", () =>
+ {
+ var btn = this.ChildrenOfType().Single().ChildrenOfType().Single();
+ InputManager.MoveMouseTo(btn);
+ InputManager.Click(MouseButton.Left);
+ });
+ AddWaitStep("Wait", 3);
+ AddAssert("Nothing happened", () => this.ChildrenOfType().Any());
+ AddStep("Set report data", () =>
+ {
+ var field = this.ChildrenOfType().Single();
+ field.Current.Value = report_text;
+ var reason = this.ChildrenOfType>().Single();
+ reason.Current.Value = CommentReportReason.Other;
+ });
+ AddStep("Try to report", () =>
+ {
+ var btn = this.ChildrenOfType().Single().ChildrenOfType().Single();
+ InputManager.MoveMouseTo(btn);
+ InputManager.Click(MouseButton.Left);
+ });
+ AddWaitStep("Wait", 3);
+ AddAssert("Overlay closed", () => !this.ChildrenOfType().Any());
+ AddAssert("Loading spinner shown", () => targetComment.ChildrenOfType().Any(d => d.IsPresent));
+ AddStep("Complete request", () => requestLock.Set());
+ AddUntilStep("Request sent", () => request != null);
+ AddAssert("Request is correct", () => request != null && request.CommentID == 2 && request.Comment == report_text && request.Reason == CommentReportReason.Other);
+ }
+
private void addTestComments()
{
AddStep("set up response", () =>
diff --git a/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs b/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs
new file mode 100644
index 0000000000..fb56a41507
--- /dev/null
+++ b/osu.Game.Tests/Visual/Online/TestSceneCommentReportButton.cs
@@ -0,0 +1,46 @@
+// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence.
+// See the LICENCE file in the repository root for full licence text.
+
+using osu.Framework.Extensions;
+using osu.Framework.Graphics;
+using osu.Framework.Graphics.Cursor;
+using osu.Framework.Testing;
+using osu.Game.Online.API;
+using osu.Game.Online.API.Requests;
+using osu.Game.Online.API.Requests.Responses;
+using osu.Game.Overlays.Comments;
+using osu.Game.Tests.Visual.UserInterface;
+using osuTK;
+
+namespace osu.Game.Tests.Visual.Online
+{
+ public class TestSceneCommentReportButton : ThemeComparisonTestScene
+ {
+ [SetUpSteps]
+ public void SetUpSteps()
+ {
+ AddStep("setup API", () => ((DummyAPIAccess)API).HandleRequest += req =>
+ {
+ switch (req)
+ {
+ case CommentReportRequest report:
+ Scheduler.AddDelayed(report.TriggerSuccess, 1000);
+ return true;
+ }
+
+ return false;
+ });
+ }
+
+ protected override Drawable CreateContent() => new PopoverContainer
+ {
+ RelativeSizeAxes = Axes.Both,
+ Child = new CommentReportButton(new Comment { User = new APIUser { Username = "Someone" } })
+ {
+ Anchor = Anchor.Centre,
+ Origin = Anchor.Centre,
+ Scale = new Vector2(2f),
+ }.With(b => Schedule(b.ShowPopover)),
+ };
+ }
+}
diff --git a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs
index caa2d2571d..7064a08151 100644
--- a/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs
+++ b/osu.Game.Tests/Visual/Online/TestSceneUserProfileOverlay.cs
@@ -52,8 +52,15 @@ namespace osu.Game.Tests.Visual.Online
{
AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569),
Description = "Outstanding help by being a voluntary test subject.",
- ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg"
- }
+ ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg",
+ Url = "https://osu.ppy.sh/wiki/en/People/Community_Contributors",
+ },
+ new Badge
+ {
+ AwardedAt = DateTimeOffset.FromUnixTimeSeconds(1505741569),
+ Description = "Badge without a url.",
+ ImageUrl = "https://assets.ppy.sh/profile-badges/contributor.jpg",
+ },
},
Title = "osu!volunteer",
Colour = "ff0000",
diff --git a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs
index 9791bb6248..ad60c98e05 100644
--- a/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs
+++ b/osu.Game.Tests/Visual/Settings/TestSceneSettingsPanel.cs
@@ -35,13 +35,19 @@ namespace osu.Game.Tests.Visual.Settings
State = { Value = Visibility.Visible }
});
});
+ }
- AddStep("reset mouse", () => InputManager.MoveMouseTo(settings));
+ [Test]
+ public void TestBasic()
+ {
+ AddStep("do nothing", () => { });
}
[Test]
public void TestFiltering([Values] bool beforeLoad)
{
+ AddStep("reset mouse", () => InputManager.MoveMouseTo(settings));
+
if (beforeLoad)
AddStep("set filter", () => settings.SectionsContainer.ChildrenOfType().First().Current.Value = "scaling");
@@ -67,6 +73,8 @@ namespace osu.Game.Tests.Visual.Settings
[Test]
public void TestFilterAfterLoad()
{
+ AddStep("reset mouse", () => InputManager.MoveMouseTo(settings));
+
AddUntilStep("wait for items to load", () => settings.SectionsContainer.ChildrenOfType().Any());
AddStep("set filter", () => settings.SectionsContainer.ChildrenOfType().First().Current.Value = "scaling");
@@ -75,6 +83,8 @@ namespace osu.Game.Tests.Visual.Settings
[Test]
public void ToggleVisibility()
{
+ AddStep("reset mouse", () => InputManager.MoveMouseTo(settings));
+
AddWaitStep("wait some", 5);
AddToggleStep("toggle visibility", _ => settings.ToggleVisibility());
}
@@ -82,6 +92,8 @@ namespace osu.Game.Tests.Visual.Settings
[Test]
public void TestTextboxFocusAfterNestedPanelBackButton()
{
+ AddStep("reset mouse", () => InputManager.MoveMouseTo(settings));
+
AddUntilStep("sections loaded", () => settings.SectionsContainer.Children.Count > 0);
AddUntilStep("top-level textbox focused", () => settings.SectionsContainer.ChildrenOfType().FirstOrDefault()?.HasFocus == true);
@@ -107,6 +119,8 @@ namespace osu.Game.Tests.Visual.Settings
[Test]
public void TestTextboxFocusAfterNestedPanelEscape()
{
+ AddStep("reset mouse", () => InputManager.MoveMouseTo(settings));
+
AddUntilStep("sections loaded", () => settings.SectionsContainer.Children.Count > 0);
AddUntilStep("top-level textbox focused", () => settings.SectionsContainer.ChildrenOfType().FirstOrDefault()?.HasFocus == true);
diff --git a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs
index cc8746959b..63532fdba8 100644
--- a/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs
+++ b/osu.Game.Tests/Visual/SongSelect/TestScenePlaySongSelect.cs
@@ -2,7 +2,6 @@
// See the LICENCE file in the repository root for full licence text.
using System;
-using System.Collections.Generic;
using System.Diagnostics;
using System.Linq;
using System.Threading.Tasks;
@@ -32,7 +31,6 @@ using osu.Game.Rulesets;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
-using osu.Game.Rulesets.Taiko;
using osu.Game.Scoring;
using osu.Game.Screens.Play;
using osu.Game.Screens.Select;
@@ -538,36 +536,6 @@ namespace osu.Game.Tests.Visual.SongSelect
AddUntilStep("selection shown on wedge", () => songSelect!.CurrentBeatmapDetailsBeatmap.BeatmapInfo.MatchesOnlineID(target));
}
- [Test]
- public void TestRulesetChangeResetsMods()
- {
- createSongSelect();
- changeRuleset(0);
-
- changeMods(new OsuModHardRock());
-
- int actionIndex = 0;
- int modChangeIndex = 0;
- int rulesetChangeIndex = 0;
-
- AddStep("change ruleset", () =>
- {
- SelectedMods.ValueChanged += onModChange;
- songSelect!.Ruleset.ValueChanged += onRulesetChange;
-
- Ruleset.Value = new TaikoRuleset().RulesetInfo;
-
- SelectedMods.ValueChanged -= onModChange;
- songSelect!.Ruleset.ValueChanged -= onRulesetChange;
- });
-
- AddAssert("mods changed before ruleset", () => modChangeIndex < rulesetChangeIndex);
- AddAssert("empty mods", () => !SelectedMods.Value.Any());
-
- void onModChange(ValueChangedEvent> e) => modChangeIndex = actionIndex++;
- void onRulesetChange(ValueChangedEvent e) => rulesetChangeIndex = actionIndex++;
- }
-
[Test]
public void TestModsRetainedBetweenSongSelect()
{
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs
index e5f3aea2f7..5548375af2 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneLabelledSliderBar.cs
@@ -38,6 +38,14 @@ namespace osu.Game.Tests.Visual.UserInterface
AddStep("revert back", () => this.ChildrenOfType>().ForEach(l => l.ResizeWidthTo(1, 200, Easing.OutQuint)));
}
+ [Test]
+ public void TestDisable()
+ {
+ createSliderBar();
+ AddStep("set disabled", () => this.ChildrenOfType>().ForEach(l => l.Current.Disabled = true));
+ AddStep("unset disabled", () => this.ChildrenOfType>().ForEach(l => l.Current.Disabled = false));
+ }
+
private void createSliderBar()
{
AddStep("create component", () =>
diff --git a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
index 4c43a2fdcd..0292ce5905 100644
--- a/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
+++ b/osu.Game.Tests/Visual/UserInterface/TestSceneModSelectOverlay.cs
@@ -17,6 +17,7 @@ using osu.Game.Graphics.UserInterface;
using osu.Game.Overlays.Mods;
using osu.Game.Overlays.Settings;
using osu.Game.Rulesets;
+using osu.Game.Rulesets.Catch.Mods;
using osu.Game.Rulesets.Mods;
using osu.Game.Rulesets.Osu;
using osu.Game.Rulesets.Osu.Mods;
@@ -338,26 +339,36 @@ namespace osu.Game.Tests.Visual.UserInterface
}
[Test]
- public void TestRulesetChanges()
+ public void TestCommonModsMaintainedOnRulesetChange()
{
createScreen();
changeRuleset(0);
- var noFailMod = new OsuRuleset().GetModsFor(ModType.DifficultyReduction).FirstOrDefault(m => m is OsuModNoFail);
-
- AddStep("set mods externally", () => { SelectedMods.Value = new[] { noFailMod }; });
+ AddStep("select relax mod", () => SelectedMods.Value = new[] { Ruleset.Value.CreateInstance().CreateMod() });
changeRuleset(0);
+ AddAssert("ensure mod still selected", () => SelectedMods.Value.SingleOrDefault() is OsuModRelax);
- AddAssert("ensure mods still selected", () => SelectedMods.Value.SingleOrDefault(m => m is OsuModNoFail) != null);
+ changeRuleset(2);
+ AddAssert("catch variant selected", () => SelectedMods.Value.SingleOrDefault() is CatchModRelax);
changeRuleset(3);
+ AddAssert("no mod selected", () => SelectedMods.Value.Count == 0);
+ }
- AddAssert("ensure mods not selected", () => SelectedMods.Value.Count == 0);
-
+ [Test]
+ public void TestUncommonModsDiscardedOnRulesetChange()
+ {
+ createScreen();
changeRuleset(0);
- AddAssert("ensure mods not selected", () => SelectedMods.Value.Count == 0);
+ AddStep("select single tap mod", () => SelectedMods.Value = new[] { new OsuModSingleTap() });
+
+ changeRuleset(0);
+ AddAssert("ensure mod still selected", () => SelectedMods.Value.SingleOrDefault() is OsuModSingleTap);
+
+ changeRuleset(3);
+ AddAssert("no mod selected", () => SelectedMods.Value.Count == 0);
}
[Test]
diff --git a/osu.Game.Tests/osu.Game.Tests.csproj b/osu.Game.Tests/osu.Game.Tests.csproj
index bdf8cc5136..24969414d0 100644
--- a/osu.Game.Tests/osu.Game.Tests.csproj
+++ b/osu.Game.Tests/osu.Game.Tests.csproj
@@ -1,11 +1,11 @@
-
+
-
+
diff --git a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
index bdef46a6b2..9f2a088a4b 100644
--- a/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
+++ b/osu.Game.Tournament.Tests/osu.Game.Tournament.Tests.csproj
@@ -6,7 +6,7 @@
-
+
WinExe
diff --git a/osu.Game.Tournament/Models/SeedingBeatmap.cs b/osu.Game.Tournament/Models/SeedingBeatmap.cs
index fb0e20556c..0ac312342c 100644
--- a/osu.Game.Tournament/Models/SeedingBeatmap.cs
+++ b/osu.Game.Tournament/Models/SeedingBeatmap.cs
@@ -18,7 +18,7 @@ namespace osu.Game.Tournament.Models
public Bindable Seed = new BindableInt
{
MinValue = 1,
- MaxValue = 64
+ MaxValue = 256
};
}
}
diff --git a/osu.Game.Tournament/Models/SeedingResult.cs b/osu.Game.Tournament/Models/SeedingResult.cs
index 71e52b3324..2a404153e6 100644
--- a/osu.Game.Tournament/Models/SeedingResult.cs
+++ b/osu.Game.Tournament/Models/SeedingResult.cs
@@ -17,7 +17,7 @@ namespace osu.Game.Tournament.Models
public Bindable Seed = new BindableInt
{
MinValue = 1,
- MaxValue = 64
+ MaxValue = 256
};
}
}
diff --git a/osu.Game.Tournament/Models/TournamentTeam.cs b/osu.Game.Tournament/Models/TournamentTeam.cs
index ac57f748da..1beea517d5 100644
--- a/osu.Game.Tournament/Models/TournamentTeam.cs
+++ b/osu.Game.Tournament/Models/TournamentTeam.cs
@@ -54,7 +54,7 @@ namespace osu.Game.Tournament.Models
public Bindable LastYearPlacing = new BindableInt
{
MinValue = 1,
- MaxValue = 64
+ MaxValue = 256
};
[JsonProperty]
diff --git a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
index 1b670f4b69..0bd5ddb257 100644
--- a/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
+++ b/osu.Game.Tournament/Screens/Editors/RoundEditorScreen.cs
@@ -256,7 +256,7 @@ namespace osu.Game.Tournament.Screens.Editors
mods.BindValueChanged(modString => Model.Mods = modString.NewValue);
}
- private void updatePanel()
+ private void updatePanel() => Schedule(() =>
{
drawableContainer.Clear();
@@ -269,7 +269,7 @@ namespace osu.Game.Tournament.Screens.Editors
Width = 300
};
}
- }
+ });
}
}
}
diff --git a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
index 9262cab098..ba75b6a2ed 100644
--- a/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
+++ b/osu.Game.Tournament/Screens/TeamIntro/SeedingScreen.cs
@@ -26,6 +26,9 @@ namespace osu.Game.Tournament.Screens.TeamIntro
private readonly Bindable currentTeam = new Bindable();
+ private TourneyButton showFirstTeamButton;
+ private TourneyButton showSecondTeamButton;
+
[BackgroundDependencyLoader]
private void load()
{
@@ -46,13 +49,13 @@ namespace osu.Game.Tournament.Screens.TeamIntro
{
Children = new Drawable[]
{
- new TourneyButton
+ showFirstTeamButton = new TourneyButton
{
RelativeSizeAxes = Axes.X,
Text = "Show first team",
Action = () => currentTeam.Value = CurrentMatch.Value.Team1.Value,
},
- new TourneyButton
+ showSecondTeamButton = new TourneyButton
{
RelativeSizeAxes = Axes.X,
Text = "Show second team",
@@ -70,35 +73,48 @@ namespace osu.Game.Tournament.Screens.TeamIntro
currentTeam.BindValueChanged(teamChanged, true);
}
- private void teamChanged(ValueChangedEvent team) => Scheduler.AddOnce(() =>
- {
- if (team.NewValue == null)
- {
- mainContainer.Clear();
- return;
- }
+ private void teamChanged(ValueChangedEvent team) => updateTeamDisplay();
- showTeam(team.NewValue);
- });
+ public override void Show()
+ {
+ base.Show();
+
+ // Changes could have been made on editor screen.
+ // Rather than trying to track all the possibilities (teams / players / scores) just force a full refresh.
+ updateTeamDisplay();
+ }
protected override void CurrentMatchChanged(ValueChangedEvent match)
{
base.CurrentMatchChanged(match);
if (match.NewValue == null)
+ {
+ showFirstTeamButton.Enabled.Value = false;
+ showSecondTeamButton.Enabled.Value = false;
return;
+ }
+
+ showFirstTeamButton.Enabled.Value = true;
+ showSecondTeamButton.Enabled.Value = true;
currentTeam.Value = match.NewValue.Team1.Value;
}
- private void showTeam(TournamentTeam team)
+ private void updateTeamDisplay() => Scheduler.AddOnce(() =>
{
+ if (currentTeam.Value == null)
+ {
+ mainContainer.Clear();
+ return;
+ }
+
mainContainer.Children = new Drawable[]
{
- new LeftInfo(team) { Position = new Vector2(55, 150), },
- new RightInfo(team) { Position = new Vector2(500, 150), },
+ new LeftInfo(currentTeam.Value) { Position = new Vector2(55, 150), },
+ new RightInfo(currentTeam.Value) { Position = new Vector2(500, 150), },
};
- }
+ });
private class RightInfo : CompositeDrawable
{
diff --git a/osu.Game.Tournament/TournamentGameBase.cs b/osu.Game.Tournament/TournamentGameBase.cs
index 1861e39c60..98ba3ca60f 100644
--- a/osu.Game.Tournament/TournamentGameBase.cs
+++ b/osu.Game.Tournament/TournamentGameBase.cs
@@ -238,7 +238,7 @@ namespace osu.Game.Tournament
var beatmapsRequiringPopulation = ladder.Teams
.SelectMany(r => r.SeedingResults)
.SelectMany(r => r.Beatmaps)
- .Where(b => b.Beatmap?.OnlineID == 0 && b.ID > 0).ToList();
+ .Where(b => (b.Beatmap == null || b.Beatmap.OnlineID == 0) && b.ID > 0).ToList();
if (beatmapsRequiringPopulation.Count == 0)
return false;
diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs
index 70312a1535..b9e0a4e6cb 100644
--- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs
+++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCard.cs
@@ -14,7 +14,7 @@ using osu.Game.Overlays;
namespace osu.Game.Beatmaps.Drawables.Cards
{
- public abstract class BeatmapCard : OsuClickableContainer, IEquatable
+ public abstract class BeatmapCard : OsuClickableContainer
{
public const float TRANSITION_DURATION = 400;
public const float CORNER_RADIUS = 10;
@@ -96,16 +96,5 @@ namespace osu.Game.Beatmaps.Drawables.Cards
throw new ArgumentOutOfRangeException(nameof(size), size, @"Unsupported card size");
}
}
-
- public bool Equals(BeatmapCard? other)
- {
- if (ReferenceEquals(null, other)) return false;
- if (ReferenceEquals(this, other)) return true;
-
- return BeatmapSet.Equals(other.BeatmapSet);
- }
-
- public override bool Equals(object obj) => obj is BeatmapCard other && Equals(other);
- public override int GetHashCode() => BeatmapSet.GetHashCode();
}
}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs
index 4b9e5d9ae4..646c990564 100644
--- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs
+++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardExtra.cs
@@ -81,7 +81,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards
FavouriteState = { BindTarget = FavouriteState },
ButtonsCollapsedWidth = CORNER_RADIUS,
ButtonsExpandedWidth = 30,
- ButtonsPadding = new MarginPadding { Vertical = 35 },
Children = new Drawable[]
{
new FillFlowContainer
diff --git a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs
index d9ce64879f..addc88700c 100644
--- a/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs
+++ b/osu.Game/Beatmaps/Drawables/Cards/BeatmapCardNormal.cs
@@ -82,7 +82,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards
FavouriteState = { BindTarget = FavouriteState },
ButtonsCollapsedWidth = CORNER_RADIUS,
ButtonsExpandedWidth = 30,
- ButtonsPadding = new MarginPadding { Vertical = 17.5f },
Children = new Drawable[]
{
new FillFlowContainer
diff --git a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs
index c5b251cc2b..af1a8eb06a 100644
--- a/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs
+++ b/osu.Game/Beatmaps/Drawables/Cards/Buttons/BeatmapCardIconButton.cs
@@ -4,13 +4,16 @@
#nullable disable
using osu.Framework.Allocation;
+using osu.Framework.Extensions.Color4Extensions;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Containers;
+using osu.Framework.Graphics.Shapes;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Input.Events;
using osu.Game.Graphics.Containers;
using osu.Game.Overlays;
using osuTK;
+using osuTK.Graphics;
namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
{
@@ -59,6 +62,7 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
protected override Container Content => content;
private readonly Container content;
+ private readonly Box hover;
protected BeatmapCardIconButton()
{
@@ -69,19 +73,27 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
{
RelativeSizeAxes = Axes.Both,
Masking = true,
+ CornerRadius = BeatmapCard.CORNER_RADIUS,
+ Scale = new Vector2(0.8f),
Origin = Anchor.Centre,
Anchor = Anchor.Centre,
Children = new Drawable[]
{
+ hover = new Box
+ {
+ RelativeSizeAxes = Axes.Both,
+ Colour = Color4.White.Opacity(0.1f),
+ Blending = BlendingParameters.Additive,
+ },
Icon = new SpriteIcon
{
Origin = Anchor.Centre,
- Anchor = Anchor.Centre
- }
+ Anchor = Anchor.Centre,
+ Scale = new Vector2(1.2f),
+ },
}
});
- Size = new Vector2(24);
IconSize = 12;
}
@@ -116,8 +128,9 @@ namespace osu.Game.Beatmaps.Drawables.Cards.Buttons
{
bool isHovered = IsHovered && Enabled.Value;
- content.ScaleTo(isHovered ? 1.2f : 1, 500, Easing.OutQuint);
- content.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint);
+ hover.FadeTo(isHovered ? 1f : 0f, 500, Easing.OutQuint);
+ content.ScaleTo(isHovered ? 1 : 0.8f, 500, Easing.OutQuint);
+ Icon.FadeColour(isHovered ? HoverColour : IdleColour, BeatmapCard.TRANSITION_DURATION, Easing.OutQuint);
}
}
}
diff --git a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs
index 107c126eb5..9b200d62aa 100644
--- a/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs
+++ b/osu.Game/Beatmaps/Drawables/Cards/CollapsibleButtonContainer.cs
@@ -48,12 +48,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards
}
}
- public MarginPadding ButtonsPadding
- {
- get => buttons.Padding;
- set => buttons.Padding = value;
- }
-
protected override Container Content => mainContent;
private readonly Container background;
@@ -86,9 +80,6 @@ namespace osu.Game.Beatmaps.Drawables.Cards
RelativeSizeAxes = Axes.Both,
Anchor = Anchor.CentreRight,
Origin = Anchor.CentreRight,
- // workaround for masking artifacts at the top & bottom of card,
- // which become especially visible on downloaded beatmaps (when the icon area has a lime background).
- Padding = new MarginPadding { Vertical = 1 },
Child = new Box
{
RelativeSizeAxes = Axes.Both,
@@ -104,25 +95,34 @@ namespace osu.Game.Beatmaps.Drawables.Cards
Child = buttons = new Container