// Copyright (c) ppy Pty Ltd . Licensed under the MIT Licence. // See the LICENCE file in the repository root for full licence text. using System.Linq; using osu.Framework.Bindables; using osu.Framework.Graphics; using osu.Framework.Graphics.Containers; using osu.Game.Skinning; using osuTK; using osuTK.Graphics; namespace osu.Game.Rulesets.Catch.Skinning.Legacy { public class CatchLegacySkinTransformer : LegacySkinTransformer { public override bool IsProvidingLegacyResources => base.IsProvidingLegacyResources || hasPear; private bool hasPear => GetTexture("fruit-pear") != null; /// /// For simplicity, let's use legacy combo font texture existence as a way to identify legacy skins from default. /// private bool providesComboCounter => this.HasFont(LegacyFont.Combo); public CatchLegacySkinTransformer(ISkin skin) : base(skin) { } public override Drawable? GetDrawableComponent(ISkinComponentLookup lookup) { switch (lookup) { case SkinComponentsContainerLookup containerLookup: if (containerLookup.Target != SkinComponentsContainerLookup.TargetArea.MainHUDComponents) return base.GetDrawableComponent(lookup); // Modifications for global components. if (containerLookup.Ruleset == null) { var components = base.GetDrawableComponent(lookup) as Container; if (providesComboCounter && components != null) { // catch may provide its own combo counter; hide the default. // todo: this should be done in an elegant way per ruleset, defining which HUD skin components should be displayed. foreach (var legacyComboCounter in components.OfType()) legacyComboCounter.HiddenByRulesetImplementation = false; } return components; } // Skin has configuration. if (base.GetDrawableComponent(lookup) is Drawable d) return d; // Our own ruleset components default. return new DefaultSkinComponentsContainer(container => { var keyCounter = container.OfType().FirstOrDefault(); if (keyCounter != null) { // set the anchor to top right so that it won't squash to the return button to the top keyCounter.Anchor = Anchor.CentreRight; keyCounter.Origin = Anchor.CentreRight; keyCounter.X = 0; // 340px is the default height inherit from stable keyCounter.Y = container.ToLocalSpace(new Vector2(0, container.ScreenSpaceDrawQuad.Centre.Y - 340f)).Y; } }) { Children = new Drawable[] { new LegacyKeyCounterDisplay(), } }; case CatchSkinComponentLookup catchSkinComponent: switch (catchSkinComponent.Component) { case CatchSkinComponents.Fruit: if (hasPear) return new LegacyFruitPiece(); return null; case CatchSkinComponents.Banana: if (GetTexture("fruit-bananas") != null) return new LegacyBananaPiece(); return null; case CatchSkinComponents.Droplet: if (GetTexture("fruit-drop") != null) return new LegacyDropletPiece(); return null; case CatchSkinComponents.Catcher: decimal version = GetConfig(SkinConfiguration.LegacySetting.Version)?.Value ?? 1; if (version < 2.3m) { if (hasOldStyleCatcherSprite()) return new LegacyCatcherOld(); } if (hasNewStyleCatcherSprite()) return new LegacyCatcherNew(); return null; case CatchSkinComponents.CatchComboCounter: if (providesComboCounter) return new LegacyCatchComboCounter(); return null; case CatchSkinComponents.HitExplosion: if (hasOldStyleCatcherSprite() || hasNewStyleCatcherSprite()) return new LegacyHitExplosion(); return null; default: throw new UnsupportedSkinComponentException(lookup); } } return base.GetDrawableComponent(lookup); } private bool hasOldStyleCatcherSprite() => GetTexture(@"fruit-ryuuta") != null || GetTexture(@"fruit-ryuuta-0") != null; private bool hasNewStyleCatcherSprite() => GetTexture(@"fruit-catcher-idle") != null || GetTexture(@"fruit-catcher-idle-0") != null; public override IBindable? GetConfig(TLookup lookup) { switch (lookup) { case CatchSkinColour colour: var result = (Bindable?)base.GetConfig(new SkinCustomColourLookup(colour)); if (result == null) return null; result.Value = LegacyColourCompatibility.DisallowZeroAlpha(result.Value); return (IBindable)result; } return base.GetConfig(lookup); } } }