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 }; } } }