diff --git a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs index a191dee1ca..0052fd8b78 100644 --- a/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Mania/Skinning/Argon/ArgonJudgementPiece.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Mania.Skinning.Argon { - public partial class ArgonJudgementPiece : JudgementPiece, IAnimatableJudgement + public partial class ArgonJudgementPiece : TextJudgementPiece, IAnimatableJudgement { private const float judgement_y_position = 160; diff --git a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs index d64fb0bcc6..73c061afbd 100644 --- a/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs +++ b/osu.Game.Rulesets.Osu/Objects/Drawables/DrawableSliderTick.cs @@ -18,7 +18,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { public const double ANIM_DURATION = 150; - private const float default_tick_size = 16; + public const float DEFAULT_TICK_SIZE = 16; protected DrawableSlider DrawableSlider => (DrawableSlider)ParentHitObject; @@ -44,8 +44,8 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables { Masking = true, Origin = Anchor.Centre, - Size = new Vector2(default_tick_size), - BorderThickness = default_tick_size / 4, + Size = new Vector2(DEFAULT_TICK_SIZE), + BorderThickness = DEFAULT_TICK_SIZE / 4, BorderColour = Color4.White, Child = new Box { @@ -88,8 +88,7 @@ namespace osu.Game.Rulesets.Osu.Objects.Drawables break; case ArmedState.Miss: - this.FadeOut(ANIM_DURATION); - this.TransformBindableTo(AccentColour, Color4.Red, 0); + this.FadeOut(ANIM_DURATION, Easing.OutQuint); break; case ArmedState.Hit: diff --git a/osu.Game.Rulesets.Osu/OsuRuleset.cs b/osu.Game.Rulesets.Osu/OsuRuleset.cs index 0496d1f680..6752712be1 100644 --- a/osu.Game.Rulesets.Osu/OsuRuleset.cs +++ b/osu.Game.Rulesets.Osu/OsuRuleset.cs @@ -28,6 +28,7 @@ using osu.Game.Rulesets.Osu.Objects; using osu.Game.Rulesets.Osu.Replays; using osu.Game.Rulesets.Osu.Scoring; using osu.Game.Rulesets.Osu.Skinning.Argon; +using osu.Game.Rulesets.Osu.Skinning.Default; using osu.Game.Rulesets.Osu.Skinning.Legacy; using osu.Game.Rulesets.Osu.Statistics; using osu.Game.Rulesets.Osu.UI; @@ -254,6 +255,9 @@ namespace osu.Game.Rulesets.Osu case ArgonSkin: return new OsuArgonSkinTransformer(skin); + + case TrianglesSkin: + return new OsuTrianglesSkinTransformer(skin); } return null; diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs index 9a5abba4fb..83992fc785 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPiece.cs @@ -16,7 +16,7 @@ using osuTK; namespace osu.Game.Rulesets.Osu.Skinning.Argon { - public partial class ArgonJudgementPiece : JudgementPiece, IAnimatableJudgement + public partial class ArgonJudgementPiece : TextJudgementPiece, IAnimatableJudgement { private RingExplosion? ringExplosion; diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPieceSliderTickMiss.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPieceSliderTickMiss.cs new file mode 100644 index 0000000000..878e8dbfc2 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonJudgementPieceSliderTickMiss.cs @@ -0,0 +1,51 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Scoring; +using osuTK; + +namespace osu.Game.Rulesets.Osu.Skinning.Argon +{ + public partial class ArgonJudgementPieceSliderTickMiss : CompositeDrawable, IAnimatableJudgement + { + private readonly HitResult result; + private Circle piece = null!; + + [Resolved] + private OsuColour colours { get; set; } = null!; + + public ArgonJudgementPieceSliderTickMiss(HitResult result) + { + this.result = result; + } + + [BackgroundDependencyLoader] + private void load() + { + AddInternal(piece = new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Colour = colours.ForHitResult(result), + Size = new Vector2(ArgonSliderScorePoint.SIZE) + }); + } + + public void PlayAnimation() + { + this.ScaleTo(1.4f); + this.ScaleTo(1f, 150, Easing.Out); + + this.FadeOutFromOne(400); + } + + public Drawable? GetAboveHitObjectsProxiedContent() => piece.CreateProxy(); + } +} diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderScorePoint.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderScorePoint.cs index 7479c2aced..e9ee432bac 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderScorePoint.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/ArgonSliderScorePoint.cs @@ -16,14 +16,14 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon { private Bindable accentColour = null!; - private const float size = 12; + public const float SIZE = 12; [BackgroundDependencyLoader] private void load(DrawableHitObject hitObject) { Masking = true; Origin = Anchor.Centre; - Size = new Vector2(size); + Size = new Vector2(SIZE); BorderThickness = 3; BorderColour = Color4.White; Child = new Box diff --git a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs index 0f9c97059c..ec63e1194d 100644 --- a/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs +++ b/osu.Game.Rulesets.Osu/Skinning/Argon/OsuArgonSkinTransformer.cs @@ -19,11 +19,21 @@ namespace osu.Game.Rulesets.Osu.Skinning.Argon switch (lookup) { case GameplaySkinComponentLookup resultComponent: + HitResult result = resultComponent.Component; + // This should eventually be moved to a skin setting, when supported. - if (Skin is ArgonProSkin && (resultComponent.Component == HitResult.Great || resultComponent.Component == HitResult.Perfect)) + if (Skin is ArgonProSkin && (result == HitResult.Great || result == HitResult.Perfect)) return Drawable.Empty(); - return new ArgonJudgementPiece(resultComponent.Component); + switch (result) + { + case HitResult.IgnoreMiss: + case HitResult.LargeTickMiss: + return new ArgonJudgementPieceSliderTickMiss(result); + + default: + return new ArgonJudgementPiece(result); + } case OsuSkinComponentLookup osuComponent: // TODO: Once everything is finalised, consider throwing UnsupportedSkinComponentException on missing entries. diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/DefaultJudgementPieceSliderTickMiss.cs b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultJudgementPieceSliderTickMiss.cs new file mode 100644 index 0000000000..9fc71852ba --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/Default/DefaultJudgementPieceSliderTickMiss.cs @@ -0,0 +1,52 @@ +// 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.Graphics; +using osu.Framework.Graphics.Containers; +using osu.Framework.Graphics.Shapes; +using osu.Game.Graphics; +using osu.Game.Rulesets.Judgements; +using osu.Game.Rulesets.Osu.Objects.Drawables; +using osu.Game.Rulesets.Scoring; +using osuTK; + +namespace osu.Game.Rulesets.Osu.Skinning.Default +{ + public partial class DefaultJudgementPieceSliderTickMiss : CompositeDrawable, IAnimatableJudgement + { + private readonly HitResult result; + private Circle piece = null!; + + [Resolved] + private OsuColour colours { get; set; } = null!; + + public DefaultJudgementPieceSliderTickMiss(HitResult result) + { + this.result = result; + } + + [BackgroundDependencyLoader] + private void load() + { + AddInternal(piece = new Circle + { + Anchor = Anchor.Centre, + Origin = Anchor.Centre, + Blending = BlendingParameters.Additive, + Colour = colours.ForHitResult(result), + Size = new Vector2(DrawableSliderTick.DEFAULT_TICK_SIZE) + }); + } + + public void PlayAnimation() + { + this.ScaleTo(1.4f); + this.ScaleTo(1f, 150, Easing.Out); + + this.FadeOutFromOne(400); + } + + public Drawable? GetAboveHitObjectsProxiedContent() => piece.CreateProxy(); + } +} diff --git a/osu.Game.Rulesets.Osu/Skinning/Default/OsuTrianglesSkinTransformer.cs b/osu.Game.Rulesets.Osu/Skinning/Default/OsuTrianglesSkinTransformer.cs new file mode 100644 index 0000000000..7a4c768aa2 --- /dev/null +++ b/osu.Game.Rulesets.Osu/Skinning/Default/OsuTrianglesSkinTransformer.cs @@ -0,0 +1,38 @@ +// 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; +using osu.Game.Skinning; + +namespace osu.Game.Rulesets.Osu.Skinning.Default +{ + public class OsuTrianglesSkinTransformer : SkinTransformer + { + public OsuTrianglesSkinTransformer(ISkin skin) + : base(skin) + { + } + + public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) + { + switch (lookup) + { + case GameplaySkinComponentLookup resultComponent: + HitResult result = resultComponent.Component; + + switch (result) + { + case HitResult.IgnoreMiss: + case HitResult.LargeTickMiss: + // use argon judgement piece for new tick misses because i don't want to design another one for triangles. + return new DefaultJudgementPieceSliderTickMiss(result); + } + + break; + } + + return base.GetDrawableComponent(lookup); + } + } +} diff --git a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs index bbd62ff85b..724e387cc7 100644 --- a/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs +++ b/osu.Game.Rulesets.Taiko/Skinning/Argon/ArgonJudgementPiece.cs @@ -17,7 +17,7 @@ using osuTK.Graphics; namespace osu.Game.Rulesets.Taiko.Skinning.Argon { - public partial class ArgonJudgementPiece : JudgementPiece, IAnimatableJudgement + public partial class ArgonJudgementPiece : TextJudgementPiece, IAnimatableJudgement { private RingExplosion? ringExplosion; diff --git a/osu.Game/Graphics/OsuColour.cs b/osu.Game/Graphics/OsuColour.cs index 1b5877b966..985898958c 100644 --- a/osu.Game/Graphics/OsuColour.cs +++ b/osu.Game/Graphics/OsuColour.cs @@ -77,7 +77,7 @@ namespace osu.Game.Graphics { case HitResult.IgnoreMiss: case HitResult.SmallTickMiss: - return Orange1; + return Color4.Gray; case HitResult.Miss: case HitResult.LargeTickMiss: diff --git a/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs b/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs index 7330f138ce..61b72a6066 100644 --- a/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs +++ b/osu.Game/Rulesets/Judgements/DefaultJudgementPiece.cs @@ -10,7 +10,7 @@ using osuTK; namespace osu.Game.Rulesets.Judgements { - public partial class DefaultJudgementPiece : JudgementPiece, IAnimatableJudgement + public partial class DefaultJudgementPiece : TextJudgementPiece, IAnimatableJudgement { public DefaultJudgementPiece(HitResult result) : base(result) @@ -38,20 +38,6 @@ namespace osu.Game.Rulesets.Judgements /// public virtual void PlayAnimation() { - // TODO: make these better. currently they are using a text `-` and it's not centered properly. - // Should be an explicit drawable. - // - // When this is done, remove the [Description] attributes from HitResults which were added for this purpose. - if (Result == HitResult.IgnoreMiss || Result == HitResult.LargeTickMiss) - { - this.RotateTo(-45); - this.ScaleTo(1.6f); - this.ScaleTo(1.2f, 100, Easing.In); - - this.FadeOutFromOne(400); - return; - } - if (Result.IsMiss()) { this.ScaleTo(1.6f); diff --git a/osu.Game/Rulesets/Judgements/JudgementPiece.cs b/osu.Game/Rulesets/Judgements/TextJudgementPiece.cs similarity index 88% rename from osu.Game/Rulesets/Judgements/JudgementPiece.cs rename to osu.Game/Rulesets/Judgements/TextJudgementPiece.cs index 03f211c318..42527705eb 100644 --- a/osu.Game/Rulesets/Judgements/JudgementPiece.cs +++ b/osu.Game/Rulesets/Judgements/TextJudgementPiece.cs @@ -10,7 +10,7 @@ using osu.Game.Rulesets.Scoring; namespace osu.Game.Rulesets.Judgements { - public abstract partial class JudgementPiece : CompositeDrawable + public abstract partial class TextJudgementPiece : CompositeDrawable { protected readonly HitResult Result; @@ -19,7 +19,7 @@ namespace osu.Game.Rulesets.Judgements [Resolved] private OsuColour colours { get; set; } = null!; - protected JudgementPiece(HitResult result) + protected TextJudgementPiece(HitResult result) { Result = result; } diff --git a/osu.Game/Rulesets/Scoring/HitResult.cs b/osu.Game/Rulesets/Scoring/HitResult.cs index 7e58df3cfa..20ec3c4946 100644 --- a/osu.Game/Rulesets/Scoring/HitResult.cs +++ b/osu.Game/Rulesets/Scoring/HitResult.cs @@ -86,7 +86,6 @@ namespace osu.Game.Rulesets.Scoring /// Indicates a large tick miss. /// [EnumMember(Value = "large_tick_miss")] - [Description("-")] [Order(11)] LargeTickMiss, @@ -118,7 +117,6 @@ namespace osu.Game.Rulesets.Scoring /// Indicates a miss that should be ignored for scoring purposes. /// [EnumMember(Value = "ignore_miss")] - [Description("-")] [Order(14)] IgnoreMiss, diff --git a/osu.Game/Skinning/LegacyJudgementPieceOld.cs b/osu.Game/Skinning/LegacyJudgementPieceOld.cs index a9f68bd378..edfb5a23ec 100644 --- a/osu.Game/Skinning/LegacyJudgementPieceOld.cs +++ b/osu.Game/Skinning/LegacyJudgementPieceOld.cs @@ -46,15 +46,10 @@ namespace osu.Game.Skinning const double fade_out_length = 600; this.FadeInFromZero(fade_in_length); - this.Delay(fade_out_delay).FadeOut(fade_out_length); // legacy judgements don't play any transforms if they are an animation.... UNLESS they are the temporary displayed judgement from new piece. if (animation?.FrameCount > 1 && !forceTransforms) - { - if (isMissedTick()) - applyMissedTickScaling(); return; - } if (result.IsMiss()) { @@ -84,6 +79,8 @@ namespace osu.Game.Skinning this.RotateTo(0); this.RotateTo(rotation, fade_in_length) .Then().RotateTo(rotation * 2, fade_out_delay + fade_out_length - fade_in_length, Easing.In); + + this.Delay(fade_out_delay).FadeOut(fade_out_length); } } else @@ -97,17 +94,13 @@ namespace osu.Game.Skinning // so we need to force the current value to be correct at 1.2 (0.95) then complete the // second half of the transform. .ScaleTo(0.95f).ScaleTo(finalScale, fade_in_length * 0.2f); // t = 1.4 + + this.Delay(fade_out_delay).FadeOut(fade_out_length); } } private bool isMissedTick() => result.IsMiss() && result != HitResult.Miss; - private void applyMissedTickScaling() - { - this.ScaleTo(0.6f); - this.ScaleTo(0.3f, 100, Easing.In); - } - public Drawable GetAboveHitObjectsProxiedContent() => CreateProxy(); } }