1
0
mirror of https://github.com/ppy/osu.git synced 2024-09-21 19:27:24 +08:00

Merge pull request #3652 from WebFreak001/shuffle-skin

Add "random skin" option to skin setting dropdown
This commit is contained in:
Dan Balasescu 2020-11-11 15:47:00 +09:00 committed by GitHub
commit 09324c4598
No known key found for this signature in database
GPG Key ID: 4AEE18F83AFDEB23
4 changed files with 57 additions and 5 deletions

View File

@ -2,12 +2,14 @@
// See the LICENCE file in the repository root for full licence text.
using System;
using System.Collections.Generic;
using System.Linq;
using osu.Framework.Allocation;
using osu.Framework.Bindables;
using osu.Framework.Graphics;
using osu.Framework.Graphics.Sprites;
using osu.Framework.Logging;
using osu.Framework.Utils;
using osu.Game.Configuration;
using osu.Game.Graphics.UserInterface;
using osu.Game.Skinning;
@ -29,6 +31,14 @@ namespace osu.Game.Overlays.Settings.Sections
private readonly Bindable<SkinInfo> dropdownBindable = new Bindable<SkinInfo> { Default = SkinInfo.Default };
private readonly Bindable<int> configBindable = new Bindable<int>();
private static readonly SkinInfo random_skin_info = new SkinInfo
{
ID = SkinInfo.RANDOM_SKIN,
Name = "<Random Skin>",
};
private List<SkinInfo> skinItems;
[Resolved]
private SkinManager skins { get; set; }
@ -82,14 +92,51 @@ namespace osu.Game.Overlays.Settings.Sections
config.BindWith(OsuSetting.Skin, configBindable);
skinDropdown.Current = dropdownBindable;
skinDropdown.Items = skins.GetAllUsableSkins().ToArray();
updateItems();
// Todo: This should not be necessary when OsuConfigManager is databased
if (skinDropdown.Items.All(s => s.ID != configBindable.Value))
configBindable.Value = 0;
configBindable.BindValueChanged(id => dropdownBindable.Value = skinDropdown.Items.Single(s => s.ID == id.NewValue), true);
dropdownBindable.BindValueChanged(skin => configBindable.Value = skin.NewValue.ID);
dropdownBindable.BindValueChanged(skin =>
{
if (skin.NewValue == random_skin_info)
{
randomizeSkin();
return;
}
configBindable.Value = skin.NewValue.ID;
});
}
private void randomizeSkin()
{
// choose from only user skins, removing the current selection to ensure a new one is chosen.
var randomChoices = skinItems.Where(s => s.ID > 0 && s.ID != configBindable.Value).ToArray();
if (randomChoices.Length == 0)
{
configBindable.Value = SkinInfo.Default.ID;
return;
}
configBindable.Value = randomChoices.ElementAt(RNG.Next(0, randomChoices.Length)).ID;
}
private void updateItems()
{
skinItems = skins.GetAllUsableSkins();
// insert after lazer built-in skins
int firstNonDefault = skinItems.FindIndex(s => s.ID > 0);
if (firstNonDefault < 0)
firstNonDefault = skinItems.Count;
skinItems.Insert(firstNonDefault, random_skin_info);
skinDropdown.Items = skinItems;
}
private void itemUpdated(ValueChangedEvent<WeakReference<SkinInfo>> weakItem)

View File

@ -25,7 +25,7 @@ namespace osu.Game.Skinning
public static SkinInfo Info { get; } = new SkinInfo
{
ID = -1, // this is temporary until database storage is decided upon.
ID = SkinInfo.CLASSIC_SKIN, // this is temporary until database storage is decided upon.
Name = "osu!classic",
Creator = "team osu!"
};

View File

@ -10,6 +10,10 @@ namespace osu.Game.Skinning
{
public class SkinInfo : IHasFiles<SkinFileInfo>, IEquatable<SkinInfo>, IHasPrimaryKey, ISoftDelete
{
internal const int DEFAULT_SKIN = 0;
internal const int CLASSIC_SKIN = -1;
internal const int RANDOM_SKIN = -2;
public int ID { get; set; }
public string Name { get; set; }
@ -26,6 +30,7 @@ namespace osu.Game.Skinning
public static SkinInfo Default { get; } = new SkinInfo
{
ID = DEFAULT_SKIN,
Name = "osu!lazer",
Creator = "team osu!"
};

View File

@ -72,7 +72,7 @@ namespace osu.Game.Skinning
/// <summary>
/// Returns a list of all usable <see cref="SkinInfo"/>s. Includes the special default skin plus all skins from <see cref="GetAllUserSkins"/>.
/// </summary>
/// <returns>A list of available <see cref="SkinInfo"/>.</returns>
/// <returns>A newly allocated list of available <see cref="SkinInfo"/>.</returns>
public List<SkinInfo> GetAllUsableSkins()
{
var userSkins = GetAllUserSkins();
@ -84,7 +84,7 @@ namespace osu.Game.Skinning
/// <summary>
/// Returns a list of all usable <see cref="SkinInfo"/>s that have been loaded by the user.
/// </summary>
/// <returns>A list of available <see cref="SkinInfo"/>.</returns>
/// <returns>A newly allocated list of available <see cref="SkinInfo"/>.</returns>
public List<SkinInfo> GetAllUserSkins() => ModelStore.ConsumableItems.Where(s => !s.DeletePending).ToList();
protected override SkinInfo CreateModel(ArchiveReader archive) => new SkinInfo { Name = archive.Name };