1
0
mirror of https://github.com/ppy/osu.git synced 2025-03-15 17:47:18 +08:00

Add new default skin "argon"

This commit is contained in:
Dean Herbert 2022-09-15 16:02:57 +09:00
parent f6b29d8ebc
commit 0f7b38f4c3
8 changed files with 234 additions and 17 deletions

View File

@ -104,6 +104,7 @@ namespace osu.Game.Overlays.Settings.Sections
// In the future we should change this to properly handle ChangeSet events.
dropdownItems.Clear();
dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.ARGON_SKIN).ToLive(realm));
dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.TRIANGLES_SKIN).ToLive(realm));
dropdownItems.Add(sender.Single(s => s.ID == SkinInfo.CLASSIC_SKIN).ToLive(realm));

View File

@ -129,11 +129,19 @@ namespace osu.Game.Screens.Backgrounds
}
case BackgroundSource.Skin:
// default skins should use the default background rotation, which won't be the case if a SkinBackground is created for them.
if (skin.Value is TrianglesSkin || skin.Value is DefaultLegacySkin)
break;
switch (skin.Value)
{
case TrianglesSkin:
case ArgonSkin:
case DefaultLegacySkin:
// default skins should use the default background rotation, which won't be the case if a SkinBackground is created for them.
break;
default:
newBackground = new SkinBackground(skin.Value, getBackgroundTextureName());
break;
}
newBackground = new SkinBackground(skin.Value, getBackgroundTextureName());
break;
}
}

View File

@ -0,0 +1,198 @@
// 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.
#nullable disable
using System.Collections.Generic;
using System.Linq;
using JetBrains.Annotations;
using osu.Framework.Audio.Sample;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Graphics.Textures;
using osu.Game.Audio;
using osu.Game.Beatmaps.Formats;
using osu.Game.Extensions;
using osu.Game.IO;
using osu.Game.Screens.Play.HUD;
using osu.Game.Screens.Play.HUD.HitErrorMeters;
using osuTK;
using osuTK.Graphics;
namespace osu.Game.Skinning
{
public class ArgonSkin : Skin
{
public static SkinInfo CreateInfo() => new SkinInfo
{
ID = osu.Game.Skinning.SkinInfo.ARGON_SKIN,
Name = "osu! \"argon\" (2022)",
Creator = "team osu!",
Protected = true,
InstantiationInfo = typeof(ArgonSkin).GetInvariantInstantiationInfo()
};
private readonly IStorageResourceProvider resources;
public ArgonSkin(IStorageResourceProvider resources)
: this(CreateInfo(), resources)
{
}
[UsedImplicitly(ImplicitUseKindFlags.InstantiatedWithFixedConstructorSignature)]
public ArgonSkin(SkinInfo skin, IStorageResourceProvider resources)
: base(skin, resources)
{
this.resources = resources;
}
public override Texture GetTexture(string componentName, WrapMode wrapModeS, WrapMode wrapModeT) => Textures?.Get(componentName, wrapModeS, wrapModeT);
public override ISample GetSample(ISampleInfo sampleInfo)
{
foreach (string lookup in sampleInfo.LookupNames)
{
var sample = Samples?.Get(lookup) ?? resources.AudioManager?.Samples.Get(lookup);
if (sample != null)
return sample;
}
return null;
}
public override Drawable GetDrawableComponent(ISkinComponent component)
{
if (base.GetDrawableComponent(component) is Drawable c)
return c;
switch (component)
{
case SkinnableTargetComponent target:
switch (target.Target)
{
case SkinnableTarget.SongSelect:
var songSelectComponents = new SkinnableTargetComponentsContainer(_ =>
{
// do stuff when we need to.
});
return songSelectComponents;
case SkinnableTarget.MainHUDComponents:
var skinnableTargetWrapper = new SkinnableTargetComponentsContainer(container =>
{
var score = container.OfType<DefaultScoreCounter>().FirstOrDefault();
var accuracy = container.OfType<DefaultAccuracyCounter>().FirstOrDefault();
var combo = container.OfType<DefaultComboCounter>().FirstOrDefault();
var ppCounter = container.OfType<PerformancePointsCounter>().FirstOrDefault();
if (score != null)
{
score.Anchor = Anchor.TopCentre;
score.Origin = Anchor.TopCentre;
// elements default to beneath the health bar
const float vertical_offset = 30;
const float horizontal_padding = 20;
score.Position = new Vector2(0, vertical_offset);
if (ppCounter != null)
{
ppCounter.Y = score.Position.Y + ppCounter.ScreenSpaceDeltaToParentSpace(score.ScreenSpaceDrawQuad.Size).Y - 4;
ppCounter.Origin = Anchor.TopCentre;
ppCounter.Anchor = Anchor.TopCentre;
}
if (accuracy != null)
{
accuracy.Position = new Vector2(-accuracy.ScreenSpaceDeltaToParentSpace(score.ScreenSpaceDrawQuad.Size).X / 2 - horizontal_padding, vertical_offset + 5);
accuracy.Origin = Anchor.TopRight;
accuracy.Anchor = Anchor.TopCentre;
if (combo != null)
{
combo.Position = new Vector2(accuracy.ScreenSpaceDeltaToParentSpace(score.ScreenSpaceDrawQuad.Size).X / 2 + horizontal_padding, vertical_offset + 5);
combo.Anchor = Anchor.TopCentre;
}
}
var hitError = container.OfType<HitErrorMeter>().FirstOrDefault();
if (hitError != null)
{
hitError.Anchor = Anchor.CentreLeft;
hitError.Origin = Anchor.CentreLeft;
}
var hitError2 = container.OfType<HitErrorMeter>().LastOrDefault();
if (hitError2 != null)
{
hitError2.Anchor = Anchor.CentreRight;
hitError2.Scale = new Vector2(-1, 1);
// origin flipped to match scale above.
hitError2.Origin = Anchor.CentreLeft;
}
}
})
{
Children = new Drawable[]
{
new DefaultComboCounter(),
new DefaultScoreCounter(),
new DefaultAccuracyCounter(),
new DefaultHealthDisplay(),
new DefaultSongProgress(),
new BarHitErrorMeter(),
new BarHitErrorMeter(),
new PerformancePointsCounter()
}
};
return skinnableTargetWrapper;
}
return null;
}
switch (component.LookupName)
{
// Temporary until default skin has a valid hit lighting.
case @"lighting":
return Drawable.Empty();
}
if (GetTexture(component.LookupName) is Texture t)
return new Sprite { Texture = t };
return null;
}
public override IBindable<TValue> GetConfig<TLookup, TValue>(TLookup lookup)
{
// todo: this code is pulled from LegacySkin and should not exist.
// will likely change based on how databased storage of skin configuration goes.
switch (lookup)
{
case GlobalSkinColours global:
switch (global)
{
case GlobalSkinColours.ComboColours:
return SkinUtils.As<TValue>(new Bindable<IReadOnlyList<Color4>>(Configuration.ComboColours));
}
break;
case SkinComboColourLookup comboColour:
return SkinUtils.As<TValue>(new Bindable<Color4>(getComboColour(Configuration, comboColour.ColourIndex)));
}
return null;
}
private static Color4 getComboColour(IHasComboColours source, int colourIndex)
=> source.ComboColours[colourIndex % source.ComboColours.Count];
}
}

View File

@ -81,6 +81,7 @@ namespace osu.Game.Skinning
}
}
// TODO: check
int lastDefaultSkinIndex = sources.IndexOf(sources.OfType<TrianglesSkin>().LastOrDefault());
// Ruleset resources should be given the ability to override game-wide defaults

View File

@ -20,6 +20,7 @@ namespace osu.Game.Skinning
public class SkinInfo : RealmObject, IHasRealmFiles, IEquatable<SkinInfo>, IHasGuidPrimaryKey, ISoftDelete, IHasNamedFiles
{
internal static readonly Guid TRIANGLES_SKIN = new Guid("2991CFD8-2140-469A-BCB9-2EC23FBCE4AD");
internal static readonly Guid ARGON_SKIN = new Guid("CFFA69DE-B3E3-4DEE-8563-3C4F425C05D0");
internal static readonly Guid CLASSIC_SKIN = new Guid("81F02CD3-EEC6-4865-AC23-FAE26A386187");
internal static readonly Guid RANDOM_SKIN = new Guid("D39DFEFB-477C-4372-B1EA-2BCEA5FB8908");

View File

@ -49,10 +49,7 @@ namespace osu.Game.Skinning
public readonly Bindable<Skin> CurrentSkin = new Bindable<Skin>();
public readonly Bindable<Live<SkinInfo>> CurrentSkinInfo = new Bindable<Live<SkinInfo>>(TrianglesSkin.CreateInfo().ToLiveUnmanaged())
{
Default = TrianglesSkin.CreateInfo().ToLiveUnmanaged()
};
public readonly Bindable<Live<SkinInfo>> CurrentSkinInfo = new Bindable<Live<SkinInfo>>(ArgonSkin.CreateInfo().ToLiveUnmanaged());
private readonly SkinImporter skinImporter;
@ -61,7 +58,12 @@ namespace osu.Game.Skinning
/// <summary>
/// The default "triangles" skin.
/// </summary>
public Skin DefaultSkinTriangles { get; }
private Skin argonSkin { get; }
/// <summary>
/// The default skin (old).
/// </summary>
private Skin trianglesSkin { get; }
/// <summary>
/// The default "classic" skin.
@ -86,7 +88,8 @@ namespace osu.Game.Skinning
var defaultSkins = new[]
{
DefaultClassicSkin = new DefaultLegacySkin(this),
DefaultSkinTriangles = new TrianglesSkin(this),
trianglesSkin = new TrianglesSkin(this),
argonSkin = new ArgonSkin(this),
};
// Ensure the default entries are present.
@ -104,7 +107,7 @@ namespace osu.Game.Skinning
CurrentSkin.Value = skin.NewValue.PerformRead(GetSkin);
};
CurrentSkin.Value = DefaultSkinTriangles;
CurrentSkin.Value = argonSkin;
CurrentSkin.ValueChanged += skin =>
{
if (!skin.NewValue.SkinInfo.Equals(CurrentSkinInfo.Value))
@ -125,7 +128,7 @@ namespace osu.Game.Skinning
if (randomChoices.Length == 0)
{
CurrentSkinInfo.Value = TrianglesSkin.CreateInfo().ToLiveUnmanaged();
CurrentSkinInfo.Value = ArgonSkin.CreateInfo().ToLiveUnmanaged();
return;
}
@ -229,11 +232,15 @@ namespace osu.Game.Skinning
{
yield return CurrentSkin.Value;
// Skin manager provides default fallbacks.
// This handles cases where a user skin doesn't have the required resources for complete display of
// certain elements.
if (CurrentSkin.Value is LegacySkin && CurrentSkin.Value != DefaultClassicSkin)
yield return DefaultClassicSkin;
if (CurrentSkin.Value != DefaultSkinTriangles)
yield return DefaultSkinTriangles;
if (CurrentSkin.Value != trianglesSkin)
yield return trianglesSkin;
}
}
@ -294,7 +301,7 @@ namespace osu.Game.Skinning
Guid currentUserSkin = CurrentSkinInfo.Value.ID;
if (items.Any(s => s.ID == currentUserSkin))
scheduler.Add(() => CurrentSkinInfo.Value = TrianglesSkin.CreateInfo().ToLiveUnmanaged());
scheduler.Add(() => CurrentSkinInfo.Value = ArgonSkin.CreateInfo().ToLiveUnmanaged());
Delete(items.ToList(), silent);
});
@ -313,7 +320,7 @@ namespace osu.Game.Skinning
skinInfo = DefaultClassicSkin.SkinInfo;
}
CurrentSkinInfo.Value = skinInfo ?? DefaultSkinTriangles.SkinInfo;
CurrentSkinInfo.Value = skinInfo ?? trianglesSkin.SkinInfo;
}
}
}

View File

@ -113,6 +113,7 @@ namespace osu.Game.Skinning
// Temporarily used to exclude undesirable ISkin implementations
static bool isUserSkin(ISkin skin)
=> skin.GetType() == typeof(TrianglesSkin)
|| skin.GetType() == typeof(ArgonSkin)
|| skin.GetType() == typeof(DefaultLegacySkin)
|| skin.GetType() == typeof(LegacySkin);
}

View File

@ -104,7 +104,7 @@ namespace osu.Game.Tests.Visual
},
new OsuSpriteText
{
Text = skin?.SkinInfo.Value.Name ?? "none",
Text = skin.SkinInfo.Value.Name,
Scale = new Vector2(1.5f),
Padding = new MarginPadding(5),
},