1
0
mirror of https://github.com/ppy/osu.git synced 2026-05-13 20:33:35 +08:00
Files
osu-lazer/osu.Game/Skinning/BeatmapSkinProvidingContainer.cs
T
Dean Herbert 0457cb924a Don't consider user toggles for beatmap skin/samples when in editor (#37662)
As far as I can tell this matches stable expectations. As with most
things editor, it doesn't make sense to skin a beatmap and then want to
edit the beatmap without that skin applied, ever.

---

As mentioned in https://github.com/ppy/osu/discussions/37607.

Could probably be implemented in five different ways, this is just the
simplest that came to me. Well aware this is adding even more faff on
top of the config/disable/toggles for this stuff, but feels required for
editor sanity.

---------

Co-authored-by: Bartłomiej Dach <dach.bartlomiej@gmail.com>
2026-05-08 12:21:43 +02:00

72 lines
3.4 KiB
C#

// Copyright (c) ppy Pty Ltd <contact@ppy.sh>. Licensed under the MIT Licence.
// See the LICENCE file in the repository root for full licence text.
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Game.Audio;
namespace osu.Game.Skinning
{
/// <summary>
/// A container which overrides existing skin options with beatmap-local values.
/// </summary>
public partial class BeatmapSkinProvidingContainer : SkinProvidingContainer
{
public BindableWithCurrent<bool> BeatmapSkins = new BindableWithCurrent<bool>(true);
public BindableWithCurrent<bool> BeatmapColours = new BindableWithCurrent<bool>(true);
public BindableWithCurrent<bool> BeatmapHitsounds = new BindableWithCurrent<bool>(true);
protected override bool AllowConfigurationLookup => BeatmapSkins.Value;
protected override bool AllowColourLookup => BeatmapColours.Value;
protected override bool AllowDrawableLookup(ISkinComponentLookup lookup) => BeatmapSkins.Value;
protected override bool AllowTextureLookup(string componentName) => BeatmapSkins.Value;
protected override bool AllowSampleLookup(ISampleInfo sampleInfo) => BeatmapHitsounds.Value;
private readonly ISkin skin;
private readonly ISkin? classicFallback;
private Bindable<Skin> currentSkin = null!;
public BeatmapSkinProvidingContainer(ISkin skin, ISkin? classicFallback = null)
: base(skin)
{
this.skin = skin;
this.classicFallback = classicFallback;
}
[BackgroundDependencyLoader]
private void load(SkinManager skins)
{
BeatmapSkins.BindValueChanged(_ => TriggerSourceChanged());
BeatmapColours.BindValueChanged(_ => TriggerSourceChanged());
BeatmapHitsounds.BindValueChanged(_ => TriggerSourceChanged());
currentSkin = skins.CurrentSkin.GetBoundCopy();
currentSkin.BindValueChanged(_ =>
{
bool userSkinIsLegacy = skins.CurrentSkin.Value is LegacySkin;
bool beatmapProvidingResources = skin is LegacySkinTransformer legacySkin && legacySkin.IsProvidingLegacyResources;
// Some beatmaps provide a limited selection of skin elements to add some visual flair.
// In stable, these elements will take lookup priority over the selected skin (whether that be a user skin or default).
//
// To replicate this we need to pay special attention to the fallback order.
// If a user has a non-legacy skin (argon, triangles) selected, the game won't normally fall back to a legacy skin.
// In turn this can create an unexpected visual experience.
//
// So here, check what skin the user has selected. If it's already a legacy skin then we don't need to do anything special.
// If it isn't, we insert the classic default. Note that this is only done if the beatmap seems to be providing skin elements,
// as we only want to override the user's (non-legacy) skin choice when required for beatmap skin visuals.
if (!userSkinIsLegacy && beatmapProvidingResources && classicFallback != null)
SetSources(new[] { skin, classicFallback });
else
SetSources(new[] { skin });
}, true);
}
}
}