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:
parent
f6b29d8ebc
commit
0f7b38f4c3
@ -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));
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
198
osu.Game/Skinning/ArgonSkin.cs
Normal file
198
osu.Game/Skinning/ArgonSkin.cs
Normal 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];
|
||||
}
|
||||
}
|
@ -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
|
||||
|
@ -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");
|
||||
|
||||
|
@ -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;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -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);
|
||||
}
|
||||
|
@ -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),
|
||||
},
|
||||
|
Loading…
x
Reference in New Issue
Block a user