# inventory_sort_system.gd —— Metin2 40250 多页背包智能自动整理与堆叠合并 1:1 # 对照 40250 服务端 char_item.cpp, uiinventory.py, item.cpp class_name InventorySortSystem extends RefCounted signal inventory_sorted(total_items: int, merged_stacks: int) signal page_switched(new_page: int) const PAGE_SIZE := 45 const TOTAL_PAGES := 2 const TOTAL_SLOTS := 90 # 45 x 2 const MAX_STACK_LIMIT := 200 # 排序优先级分类 enum ItemCategory { WEAPON = 1, # 武器 ARMOR = 2, # 铠甲防具 JEWELRY = 3, # 饰品首饰 CONSUMABLE = 4, # 药水与消耗品 MATERIAL = 5, # 强化升阶材料 CHEST_KEY = 6, # 宝箱与钥匙 OTHER = 7 # 其他 } var current_page: int = 0 # 切换当前显示背包页 (0 或 1) func switch_page(page_idx: int) -> Dictionary: if page_idx < 0 or page_idx >= TOTAL_PAGES: return {"ok": false, "reason": "INVALID_PAGE", "msg": "无效的背包页码!"} current_page = page_idx page_switched.emit(page_idx) return { "ok": true, "page": page_idx, "slot_start": page_idx * PAGE_SIZE, "slot_end": (page_idx + 1) * PAGE_SIZE - 1 } # 获取物品所属排序大类 static func get_item_category(item: Dictionary) -> int: var it_type: String = item.get("item_type", "") match it_type: "weapon": return ItemCategory.WEAPON "armor", "shield", "helmet": return ItemCategory.ARMOR "jewelry", "necklace", "earrings", "bracelet", "shoes", "belt": return ItemCategory.JEWELRY "potion", "consumable", "dew", "elixir": return ItemCategory.CONSUMABLE "material", "fragment", "scroll": return ItemCategory.MATERIAL "chest", "key": return ItemCategory.CHEST_KEY _: # 根据 vnum 范围与特征推断 var vnum: int = int(item.get("vnum", 0)) if vnum < 3000 and vnum >= 10: return ItemCategory.WEAPON elif vnum >= 11000 and vnum < 13200: return ItemCategory.ARMOR elif (vnum >= 27000 and vnum < 28000) or (vnum >= 50800 and vnum < 50900) or (vnum >= 72700 and vnum < 72800): return ItemCategory.CONSUMABLE elif (vnum >= 50000 and vnum < 50200) or (vnum >= 30000 and vnum < 30400): return ItemCategory.CHEST_KEY elif vnum >= 71000 and vnum < 72000: return ItemCategory.MATERIAL return ItemCategory.OTHER # 判定物品是否可堆叠 static func is_item_stackable(item: Dictionary) -> bool: if item.get("is_stackable", false): return true var it_type: String = item.get("item_type", "") if ["potion", "consumable", "dew", "elixir", "material", "fragment", "scroll", "arrow"].has(it_type): return true var cnt: int = int(item.get("count", 1)) return cnt > 1 # 自动合并碎片堆叠 (Auto-Stack Merge) func merge_stacks(inventory: Array) -> int: var merged_count := 0 for i in range(inventory.size()): var base = inventory[i] if base == null or not is_item_stackable(base): continue var b_vnum: int = int(base.get("vnum", 0)) var b_count: int = int(base.get("count", 1)) if b_count >= MAX_STACK_LIMIT: continue for j in range(i + 1, inventory.size()): var other = inventory[j] if other == null or int(other.get("vnum", 0)) != b_vnum: continue var o_count: int = int(other.get("count", 1)) var space := MAX_STACK_LIMIT - b_count if o_count <= space: b_count += o_count base["count"] = b_count inventory[j] = null merged_count += 1 else: b_count = MAX_STACK_LIMIT base["count"] = MAX_STACK_LIMIT other["count"] = o_count - space merged_count += 1 break return merged_count # 一键智能整理背包 (堆叠合并 + 分类前置紧凑排序) func sort_inventory(inventory: Array) -> Dictionary: # 1. 先进行碎片堆叠合并 var merged := merge_stacks(inventory) # 2. 收集所有有效物品并打上排序权重标签 var items_to_sort: Array = [] for i in range(inventory.size()): var it = inventory[i] if it != null: var cat := get_item_category(it) var vnum: int = int(it.get("vnum", 0)) var level: int = int(it.get("level", 0)) items_to_sort.append({ "item": it, "category": cat, "vnum": vnum, "level": level }) # 3. 排序比较器:类别升序 (1~7),同类内 vnum 升序/降序排列 items_to_sort.sort_custom(func(a: Dictionary, b: Dictionary) -> bool: if a["category"] != b["category"]: return a["category"] < b["category"] if a["vnum"] != b["vnum"]: return a["vnum"] < b["vnum"] return int(a["item"].get("count", 1)) > int(b["item"].get("count", 1)) ) # 4. 紧凑回填背包并清空末尾 var total_items := items_to_sort.size() for i in range(inventory.size()): if i < total_items: inventory[i] = items_to_sort[i]["item"] else: inventory[i] = null inventory_sorted.emit(total_items, merged) return { "ok": true, "total_items": total_items, "merged_stacks": merged, "msg": "背包整理完成!共归纳 %d 件物品,合并 %d 处堆叠。" % [total_items, merged] }