diff --git a/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonclear.png b/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonclear.png new file mode 100644 index 0000000000..c5bcdbd3fc Binary files /dev/null and b/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonclear.png differ diff --git a/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonfail.png b/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonfail.png new file mode 100644 index 0000000000..39cf737285 Binary files /dev/null and b/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonfail.png differ diff --git a/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonidle.png b/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonidle.png new file mode 100644 index 0000000000..4c3b2bfec9 Binary files /dev/null and b/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonidle.png differ diff --git a/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonkiai.png b/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonkiai.png new file mode 100644 index 0000000000..7de00b5390 Binary files /dev/null and b/osu.Game.Rulesets.Taiko.Tests/Resources/special-skin/pippidonkiai.png differ diff --git a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs index cb6a0decde..47d8a5c012 100644 --- a/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs +++ b/osu.Game.Rulesets.Taiko.Tests/Skinning/TestSceneDrawableTaikoMascot.cs @@ -8,6 +8,7 @@ using NUnit.Framework; using osu.Framework.Allocation; using osu.Framework.Extensions.IEnumerableExtensions; using osu.Framework.Graphics; +using osu.Framework.Graphics.Animations; using osu.Framework.Testing; using osu.Game.Beatmaps; using osu.Game.Beatmaps.ControlPoints; @@ -36,6 +37,10 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning private TaikoScoreProcessor scoreProcessor; private IEnumerable mascots => this.ChildrenOfType(); + + private IEnumerable animatedMascots => + mascots.Where(mascot => mascot.ChildrenOfType().All(animation => animation.FrameCount > 0)); + private IEnumerable playfields => this.ChildrenOfType(); [SetUp] @@ -72,11 +77,11 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning AddStep("set clear state", () => mascots.ForEach(mascot => mascot.State.Value = TaikoMascotAnimationState.Clear)); AddStep("miss", () => mascots.ForEach(mascot => mascot.LastResult.Value = new JudgementResult(new Hit(), new TaikoJudgement()) { Type = HitResult.Miss })); - AddAssert("skins with animations remain in clear state", () => someMascotsIn(TaikoMascotAnimationState.Clear)); + AddAssert("skins with animations remain in clear state", () => animatedMascotsIn(TaikoMascotAnimationState.Clear)); AddUntilStep("state reverts to fail", () => allMascotsIn(TaikoMascotAnimationState.Fail)); AddStep("set clear state again", () => mascots.ForEach(mascot => mascot.State.Value = TaikoMascotAnimationState.Clear)); - AddAssert("skins with animations change to clear", () => someMascotsIn(TaikoMascotAnimationState.Clear)); + AddAssert("skins with animations change to clear", () => animatedMascotsIn(TaikoMascotAnimationState.Clear)); } [Test] @@ -186,10 +191,18 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning private void assertStateAfterResult(JudgementResult judgementResult, TaikoMascotAnimationState expectedState) { - AddStep($"{judgementResult.Type.ToString().ToLower()} result for {judgementResult.Judgement.GetType().Name.Humanize(LetterCasing.LowerCase)}", - () => applyNewResult(judgementResult)); + TaikoMascotAnimationState[] mascotStates = null; - AddAssert($"state is {expectedState.ToString().ToLower()}", () => allMascotsIn(expectedState)); + AddStep($"{judgementResult.Type.ToString().ToLower()} result for {judgementResult.Judgement.GetType().Name.Humanize(LetterCasing.LowerCase)}", + () => + { + applyNewResult(judgementResult); + // store the states as soon as possible, so that the delay between steps doesn't incorrectly fail the test + // due to not checking if the state changed quickly enough. + Schedule(() => mascotStates = animatedMascots.Select(mascot => mascot.State.Value).ToArray()); + }); + + AddAssert($"state is {expectedState.ToString().ToLower()}", () => mascotStates.All(state => state == expectedState)); } private void applyNewResult(JudgementResult judgementResult) @@ -211,6 +224,6 @@ namespace osu.Game.Rulesets.Taiko.Tests.Skinning } private bool allMascotsIn(TaikoMascotAnimationState state) => mascots.All(d => d.State.Value == state); - private bool someMascotsIn(TaikoMascotAnimationState state) => mascots.Any(d => d.State.Value == state); + private bool animatedMascotsIn(TaikoMascotAnimationState state) => animatedMascots.Any(d => d.State.Value == state); } } diff --git a/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs b/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs index 23d675cfb0..f032c5f485 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/TaikoLegacySkinTransformer.cs @@ -91,10 +91,7 @@ namespace osu.Game.Rulesets.Taiko.Skinning return null; case TaikoSkinComponents.Mascot: - if (GetTexture("pippidonclear0") != null) - return new DrawableTaikoMascot(); - - return null; + return new DrawableTaikoMascot(); } return Source.GetDrawableComponent(component); diff --git a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs index 6f25a5f662..9c76aea54c 100644 --- a/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs +++ b/osu.Game.Rulesets.Taiko/UI/TaikoMascotAnimation.cs @@ -128,6 +128,13 @@ namespace osu.Game.Rulesets.Taiko.UI } private static Texture getAnimationFrame(ISkin skin, TaikoMascotAnimationState state, int frameIndex) - => skin.GetTexture($"pippidon{state.ToString().ToLower()}{frameIndex}"); + { + var texture = skin.GetTexture($"pippidon{state.ToString().ToLower()}{frameIndex}"); + + if (frameIndex == 0 && texture == null) + texture = skin.GetTexture($"pippidon{state.ToString().ToLower()}"); + + return texture; + } } }