using System;
using System.Collections.Generic;
using Cielonos.MainGame.Inventory;
using SLSUtilities.General;
namespace Cielonos.MainGame.Items
{
///
/// 物品排序模式。
///
public enum ItemSortMode
{
///
/// 默认:按类型(主武器→支援→被动→消耗品)→ 稀有度(高→低)→ 名称。
/// Extender 插队到其宿主物品之后。
///
Default,
/// 按稀有度(高→低)→ 名称。
ByRarity,
/// 完全按显示名称排序。
ByName
}
///
/// 物品排序工具类,与 配合使用。
///
/// 通过 可替换名称解析策略以适配不同的本地化方案。
/// 默认使用 ContentData.displayNameKey.Localize()。
///
///
public static class ItemSorter
{
///
/// 名称解析委托。排序时通过此方法获取物品的显示名称。
/// 替换此委托即可切换本地化或自定义命名策略。
///
public static Func NameResolver { get; set; } = DefaultNameResolver;
private static string DefaultNameResolver(ItemBase item)
{
if (item?.contentData == null) return string.Empty;
return item.contentData.displayNameKey.Localize("Items");
}
///
/// 对物品列表就地排序。
///
public static void Sort(List 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 items)
{
// 1. 分离已绑定宿主的 Extender
List attachedExtenders = new List();
List regularItems = new List();
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 items)
{
items.Sort((a, b) =>
{
int cmp = CompareRarityDescending(a, b);
return cmp != 0 ? cmp : CompareName(a, b);
});
}
// ─────────────────── ByName ───────────────────
private static void SortByName(List 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);
}
/// 稀有度降序比较(高稀有度在前)。
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);
}
/// 按本地化显示名称比较,使用当前文化区域排序规则。
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
};
}
}
}