Passion & UI
This commit is contained in:
184
Assets/Scripts/MainGame/Items/ItemSorter.cs
Normal file
184
Assets/Scripts/MainGame/Items/ItemSorter.cs
Normal file
@@ -0,0 +1,184 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using Cielonos.MainGame.Inventory;
|
||||
using SLSUtilities.General;
|
||||
|
||||
namespace Cielonos.MainGame.Items
|
||||
{
|
||||
/// <summary>
|
||||
/// 物品排序模式。
|
||||
/// </summary>
|
||||
public enum ItemSortMode
|
||||
{
|
||||
/// <summary>
|
||||
/// 默认:按类型(主武器→支援→被动→消耗品)→ 稀有度(高→低)→ 名称。
|
||||
/// Extender 插队到其宿主物品之后。
|
||||
/// </summary>
|
||||
Default,
|
||||
|
||||
/// <summary>按稀有度(高→低)→ 名称。</summary>
|
||||
ByRarity,
|
||||
|
||||
/// <summary>完全按显示名称排序。</summary>
|
||||
ByName
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 物品排序工具类,与 <see cref="ItemFilter"/> 配合使用。
|
||||
/// <para>
|
||||
/// 通过 <see cref="NameResolver"/> 可替换名称解析策略以适配不同的本地化方案。
|
||||
/// 默认使用 <c>ContentData.displayNameKey.Localize()</c>。
|
||||
/// </para>
|
||||
/// </summary>
|
||||
public static class ItemSorter
|
||||
{
|
||||
/// <summary>
|
||||
/// 名称解析委托。排序时通过此方法获取物品的显示名称。
|
||||
/// 替换此委托即可切换本地化或自定义命名策略。
|
||||
/// </summary>
|
||||
public static Func<ItemBase, string> NameResolver { get; set; } = DefaultNameResolver;
|
||||
|
||||
private static string DefaultNameResolver(ItemBase item)
|
||||
{
|
||||
if (item?.contentData == null) return string.Empty;
|
||||
return item.contentData.displayNameKey.Localize("Items");
|
||||
}
|
||||
|
||||
/// <summary>
|
||||
/// 对物品列表就地排序。
|
||||
/// </summary>
|
||||
public static void Sort(List<ItemBase> items, ItemSortMode mode)
|
||||
{
|
||||
if (items == null || items.Count <= 1) return;
|
||||
|
||||
switch (mode)
|
||||
{
|
||||
case ItemSortMode.Default:
|
||||
SortDefault(items);
|
||||
break;
|
||||
case ItemSortMode.ByRarity:
|
||||
SortByRarity(items);
|
||||
break;
|
||||
case ItemSortMode.ByName:
|
||||
SortByName(items);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────── Default ───────────────────
|
||||
|
||||
private static void SortDefault(List<ItemBase> items)
|
||||
{
|
||||
// 1. 分离已绑定宿主的 Extender
|
||||
List<ExtenderBase> attachedExtenders = new List<ExtenderBase>();
|
||||
List<ItemBase> regularItems = new List<ItemBase>();
|
||||
|
||||
foreach (ItemBase item in items)
|
||||
{
|
||||
if (item is ExtenderBase ext && ext.IsAttached)
|
||||
{
|
||||
attachedExtenders.Add(ext);
|
||||
}
|
||||
else
|
||||
{
|
||||
regularItems.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
// 2. 对常规物品排序:类型 → 稀有度(降序)→ 名称
|
||||
regularItems.Sort(CompareByTypeRarityName);
|
||||
|
||||
// 3. Extender 之间按稀有度(降序)→ 名称排序,保证同宿主下多个 Extender 顺序稳定
|
||||
attachedExtenders.Sort((a, b) =>
|
||||
{
|
||||
int cmp = CompareRarityDescending(a, b);
|
||||
return cmp != 0 ? cmp : CompareName(a, b);
|
||||
});
|
||||
|
||||
// 4. 将 Extender 插入到宿主之后
|
||||
items.Clear();
|
||||
items.AddRange(regularItems);
|
||||
|
||||
foreach (ExtenderBase ext in attachedExtenders)
|
||||
{
|
||||
int hostIndex = items.IndexOf(ext.Host);
|
||||
if (hostIndex >= 0)
|
||||
{
|
||||
int insertPos = hostIndex + 1;
|
||||
while (insertPos < items.Count
|
||||
&& items[insertPos] is ExtenderBase sibling
|
||||
&& sibling.IsAttached
|
||||
&& sibling.Host == ext.Host)
|
||||
{
|
||||
insertPos++;
|
||||
}
|
||||
|
||||
items.Insert(insertPos, ext);
|
||||
}
|
||||
else
|
||||
{
|
||||
// 宿主不在列表中(被筛选等情况),追加到末尾
|
||||
items.Add(ext);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// ─────────────────── ByRarity ───────────────────
|
||||
|
||||
private static void SortByRarity(List<ItemBase> items)
|
||||
{
|
||||
items.Sort((a, b) =>
|
||||
{
|
||||
int cmp = CompareRarityDescending(a, b);
|
||||
return cmp != 0 ? cmp : CompareName(a, b);
|
||||
});
|
||||
}
|
||||
|
||||
// ─────────────────── ByName ───────────────────
|
||||
|
||||
private static void SortByName(List<ItemBase> items)
|
||||
{
|
||||
items.Sort(CompareName);
|
||||
}
|
||||
|
||||
// ─────────────────── Comparison Helpers ───────────────────
|
||||
|
||||
private static int CompareByTypeRarityName(ItemBase a, ItemBase b)
|
||||
{
|
||||
int typeA = GetTypePriority(a);
|
||||
int typeB = GetTypePriority(b);
|
||||
if (typeA != typeB) return typeA.CompareTo(typeB);
|
||||
|
||||
int cmp = CompareRarityDescending(a, b);
|
||||
return cmp != 0 ? cmp : CompareName(a, b);
|
||||
}
|
||||
|
||||
/// <summary>稀有度降序比较(高稀有度在前)。</summary>
|
||||
private static int CompareRarityDescending(ItemBase a, ItemBase b)
|
||||
{
|
||||
int ra = a?.contentData != null ? (int)a.contentData.itemRarity : -1;
|
||||
int rb = b?.contentData != null ? (int)b.contentData.itemRarity : -1;
|
||||
return rb.CompareTo(ra);
|
||||
}
|
||||
|
||||
/// <summary>按本地化显示名称比较,使用当前文化区域排序规则。</summary>
|
||||
private static int CompareName(ItemBase a, ItemBase b)
|
||||
{
|
||||
return string.Compare(NameResolver(a), NameResolver(b), StringComparison.CurrentCulture);
|
||||
}
|
||||
|
||||
private static int GetTypePriority(ItemBase item)
|
||||
{
|
||||
if (item?.contentData == null) return int.MaxValue;
|
||||
|
||||
return item.contentData.itemType switch
|
||||
{
|
||||
ItemType.MainWeapon => 0,
|
||||
ItemType.Support => 1,
|
||||
ItemType.Passive => 2,
|
||||
ItemType.Consumable => 3,
|
||||
_ => int.MaxValue
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user