diff --git a/osu.Game/Skinning/LegacyJudgementPieceNew.cs b/osu.Game/Skinning/LegacyJudgementPieceNew.cs new file mode 100644 index 0000000000..de77df9e10 --- /dev/null +++ b/osu.Game/Skinning/LegacyJudgementPieceNew.cs @@ -0,0 +1,93 @@ +// 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.Graphics; +using osu.Framework.Graphics.Animations; +using osu.Framework.Graphics.Containers; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; +using osuTK; + +namespace osu.Game.Skinning +{ + public class LegacyJudgementPieceNew : CompositeDrawable, IAnimatableJudgement + { + private readonly HitResult result; + + private readonly LegacyJudgementPieceOld temporaryOldStyle; + + private readonly Drawable mainPiece; + + public LegacyJudgementPieceNew(HitResult result, Func createMainDrawable, Drawable particleDrawable) + { + this.result = result; + + AutoSizeAxes = Axes.Both; + Origin = Anchor.Centre; + + InternalChildren = new[] + { + mainPiece = createMainDrawable().With(d => + { + d.Anchor = Anchor.Centre; + d.Origin = Anchor.Centre; + }) + }; + + if (result != HitResult.Miss) + { + //new judgement shows old as a temporary effect + AddInternal(temporaryOldStyle = new LegacyJudgementPieceOld(result, createMainDrawable, 1.05f) + { + Blending = BlendingParameters.Additive, + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + }); + } + } + + public void PlayAnimation() + { + var animation = mainPiece as IFramedAnimation; + + animation?.GotoFrame(0); + + this.RotateTo(0); + this.MoveTo(Vector2.Zero); + + if (temporaryOldStyle != null) + { + temporaryOldStyle.PlayAnimation(); + + temporaryOldStyle.Hide(); + temporaryOldStyle.Delay(-16) + .FadeTo(0.5f, 56, Easing.Out).Then() + .FadeOut(300); + } + + // legacy judgements don't play any transforms if they are an animation. + if (animation?.FrameCount > 1) + return; + + switch (result) + { + case HitResult.Miss: + mainPiece.ScaleTo(1.6f); + mainPiece.ScaleTo(1, 100, Easing.In); + + mainPiece.MoveToOffset(new Vector2(0, 100), 800, Easing.InQuint); + + mainPiece.RotateTo(40, 800, Easing.InQuint); + break; + + default: + const double animation_length = 1100; + + mainPiece.ScaleTo(0.9f); + mainPiece.ScaleTo(1.05f, animation_length); + break; + } + } + } +} diff --git a/osu.Game/Skinning/LegacyJudgementPiece.cs b/osu.Game/Skinning/LegacyJudgementPieceOld.cs similarity index 61% rename from osu.Game/Skinning/LegacyJudgementPiece.cs rename to osu.Game/Skinning/LegacyJudgementPieceOld.cs index 44aa5106e2..63d2c44dd9 100644 --- a/osu.Game/Skinning/LegacyJudgementPiece.cs +++ b/osu.Game/Skinning/LegacyJudgementPieceOld.cs @@ -1,6 +1,7 @@ // 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.Graphics; using osu.Framework.Graphics.Animations; using osu.Framework.Graphics.Containers; @@ -10,20 +11,21 @@ using osuTK; namespace osu.Game.Skinning { - public class LegacyJudgementPiece : CompositeDrawable, IAnimatableJudgement + public class LegacyJudgementPieceOld : CompositeDrawable, IAnimatableJudgement { private readonly HitResult result; - private bool hasParticle; + private readonly float finalScale; - public LegacyJudgementPiece(HitResult result, Drawable drawable) + public LegacyJudgementPieceOld(HitResult result, Func createMainDrawable, float finalScale = 1f) { this.result = result; + this.finalScale = finalScale; AutoSizeAxes = Axes.Both; Origin = Anchor.Centre; - InternalChild = drawable; + InternalChild = createMainDrawable(); } public virtual void PlayAnimation() @@ -39,8 +41,6 @@ namespace osu.Game.Skinning if (animation?.FrameCount > 1) return; - const double animation_length = 500; - switch (result) { case HitResult.Miss: @@ -53,19 +53,14 @@ namespace osu.Game.Skinning break; default: - if (!hasParticle) - { - this.ScaleTo(0.6f).Then() - .ScaleTo(1.1f, animation_length * 0.8f).Then() - .ScaleTo(0.9f, animation_length * 0.4f).Then() - .ScaleTo(1f, animation_length * 0.2f); - } - else - { - this.ScaleTo(0.9f); - this.ScaleTo(1.05f, animation_length); - } + const double animation_length = 120; + this.ScaleTo(0.6f).Then() + .ScaleTo(1.1f, animation_length * 0.8f).Then() + // this is actually correct to match stable; there were overlapping transforms. + .ScaleTo(0.9f).Delay(animation_length * 0.2f) + .ScaleTo(1.1f).ScaleTo(0.9f, animation_length * 0.2f).Then() + .ScaleTo(0.95f).ScaleTo(finalScale, animation_length * 0.2f); break; } } diff --git a/osu.Game/Skinning/LegacySkin.cs b/osu.Game/Skinning/LegacySkin.cs index ca8bb58023..ce1a736f0a 100644 --- a/osu.Game/Skinning/LegacySkin.cs +++ b/osu.Game/Skinning/LegacySkin.cs @@ -371,9 +371,16 @@ namespace osu.Game.Skinning } case GameplaySkinComponent resultComponent: - var drawable = getJudgementAnimation(resultComponent.Component); - if (drawable != null) - return new LegacyJudgementPiece(resultComponent.Component, drawable); + Func createDrawable = () => getJudgementAnimation(resultComponent.Component); + + if (createDrawable() != null) + { + var particles = getParticleTexture(resultComponent.Component); + if (particles != null) + return new LegacyJudgementPieceNew(resultComponent.Component, createDrawable, getParticleTexture(resultComponent.Component)); + else + return new LegacyJudgementPieceOld(resultComponent.Component, createDrawable); + } break; } @@ -381,6 +388,23 @@ namespace osu.Game.Skinning return this.GetAnimation(component.LookupName, false, false); } + private Drawable getParticleTexture(HitResult result) + { + switch (result) + { + case HitResult.Meh: + return this.GetAnimation("particle50", false, false); + + case HitResult.Ok: + return this.GetAnimation("particle100", false, false); + + case HitResult.Great: + return this.GetAnimation("particle300", false, false); + } + + return null; + } + private Drawable getJudgementAnimation(HitResult result) { switch (result)