diff --git a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs b/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs index 4486c8a9f0..94c7a3aac6 100644 --- a/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs +++ b/osu.Game/Skinning/BeatmapSkinProvidingContainer.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; @@ -17,9 +15,9 @@ namespace osu.Game.Skinning /// public partial class BeatmapSkinProvidingContainer : SkinProvidingContainer { - private Bindable beatmapSkins; - private Bindable beatmapColours; - private Bindable beatmapHitsounds; + private Bindable beatmapSkins = null!; + private Bindable beatmapColours = null!; + private Bindable beatmapHitsounds = null!; protected override bool AllowConfigurationLookup { @@ -68,11 +66,15 @@ namespace osu.Game.Skinning } private readonly ISkin skin; + private readonly ISkin? classicFallback; - public BeatmapSkinProvidingContainer(ISkin skin) + private Bindable currentSkin = null!; + + public BeatmapSkinProvidingContainer(ISkin skin, ISkin? classicFallback = null) : base(skin) { this.skin = skin; + this.classicFallback = classicFallback; } protected override IReadOnlyDependencyContainer CreateChildDependencies(IReadOnlyDependencyContainer parent) @@ -93,15 +95,19 @@ namespace osu.Game.Skinning beatmapColours.BindValueChanged(_ => TriggerSourceChanged()); beatmapHitsounds.BindValueChanged(_ => TriggerSourceChanged()); - // If the beatmap skin looks to have skinnable resources, add the default classic skin as a fallback opportunity. - if (skin is LegacySkinTransformer legacySkin && legacySkin.IsProvidingLegacyResources) + currentSkin = skins.CurrentSkin.GetBoundCopy(); + currentSkin.BindValueChanged(_ => { - SetSources(new[] - { - skin, - skins.DefaultClassicSkin - }); - } + bool userSkinIsLegacy = skins.CurrentSkin.Value is LegacySkin; + bool beatmapProvidingResources = skin is LegacySkinTransformer legacySkin && legacySkin.IsProvidingLegacyResources; + + // If the beatmap skin looks to have skinnable resources and the user's skin choice is not a legacy skin, + // add the default classic skin as a fallback opportunity. + if (!userSkinIsLegacy && beatmapProvidingResources && classicFallback != null) + SetSources(new[] { skin, classicFallback }); + else + SetSources(new[] { skin }); + }, true); } } } diff --git a/osu.Game/Skinning/RulesetSkinProvidingContainer.cs b/osu.Game/Skinning/RulesetSkinProvidingContainer.cs index 07e238243b..d736f4cdb5 100644 --- a/osu.Game/Skinning/RulesetSkinProvidingContainer.cs +++ b/osu.Game/Skinning/RulesetSkinProvidingContainer.cs @@ -28,25 +28,33 @@ namespace osu.Game.Skinning protected readonly Ruleset Ruleset; protected readonly IBeatmap Beatmap; + [CanBeNull] + private readonly ISkin beatmapSkin; + /// /// This container already re-exposes all parent sources in a ruleset-usable form. /// Therefore disallow falling back to any parent any further. /// protected override bool AllowFallingBackToParent => false; - protected override Container Content { get; } + protected override Container Content { get; } = new Container + { + RelativeSizeAxes = Axes.Both, + }; public RulesetSkinProvidingContainer(Ruleset ruleset, IBeatmap beatmap, [CanBeNull] ISkin beatmapSkin) { Ruleset = ruleset; Beatmap = beatmap; + this.beatmapSkin = beatmapSkin; + } - InternalChild = new BeatmapSkinProvidingContainer(GetRulesetTransformedSkin(beatmapSkin)) + [BackgroundDependencyLoader] + private void load(SkinManager skinManager) + { + InternalChild = new BeatmapSkinProvidingContainer(GetRulesetTransformedSkin(beatmapSkin), GetRulesetTransformedSkin(skinManager.DefaultClassicSkin)) { - Child = Content = new Container - { - RelativeSizeAxes = Axes.Both, - } + Child = Content, }; }