# epic_refine_system.gd —— Metin2 40250 修元平史诗级神装升阶转换锻造 1:1 # 对照 40250 服务端 refine.cpp, char_item.cpp, NPC 20091 (修元平 Seon-Pyeong) class_name EpicRefineSystem extends RefCounted signal epic_refine_succeeded(old_vnum: int, new_vnum: int, item_data: Dictionary) signal epic_refine_failed(reason: String) const NPC_SEON_PYEONG := 20091 const ITEM_DRAGON_SCALE := 71123 # 龙鳞 const ITEM_DRAGON_CLAW := 71129 # 龙爪 const REQUIRED_SCALE_COUNT := 3 const REQUIRED_CLAW_COUNT := 4 const REQUIRED_YANG := 200000 # 官方 40250 经典史诗升阶配方表 const EPIC_RECIPES: Dictionary = { # 武器篇:65 级 +9 武器 -> 80~90 级 +0 史诗神兵 169: { "target_vnum": 279, "name": "崔顿之剑+0", "desc": "战神之剑+9 升阶为 崔顿之剑+0" }, 3159: { "target_vnum": 3209, "name": "神圣之剑+0", "desc": "鬼牙刃+9 升阶为 神圣之剑+0" }, 1109: { "target_vnum": 1139, "name": "太阳之刃+0", "desc": "党人斧+9 升阶为 太阳之刃+0" }, 1119: { "target_vnum": 1129, "name": "龙神刀+0", "desc": "龙刀+9 升阶为 龙神刀+0" }, 2149: { "target_vnum": 2159, "name": "巨鸦弓+0", "desc": "黄龙弓+9 升阶为 巨鸦弓+0" }, 5109: { "target_vnum": 5119, "name": "恶魔之杖+0", "desc": "救赎之杖+9 升阶为 恶魔之杖+0" }, # 铠甲篇:66 级 +9 黑钢铠甲 -> 90 级 +0 蓝钢铠甲 11299: { "target_vnum": 12019, "name": "蓝钢甲+0", "desc": "黑钢甲+9 升阶为 蓝钢甲+0" }, 11499: { "target_vnum": 12029, "name": "蓝风甲+0", "desc": "黑风甲+9 升阶为 蓝风甲+0" }, 11699: { "target_vnum": 12039, "name": "蓝仙袍+0", "desc": "黑仙袍+9 升阶为 蓝仙袍+0" }, 11899: { "target_vnum": 12049, "name": "蓝龙袍+0", "desc": "黑龙袍+9 升阶为 蓝龙袍+0" } } # 判定物品是否可进行史诗升阶 func can_epic_refine(item: Dictionary) -> bool: if item.is_empty(): return false var vnum: int = int(item.get("vnum", 0)) return EPIC_RECIPES.has(vnum) # 获取升阶配方详情 func get_recipe(vnum: int) -> Dictionary: return EPIC_RECIPES.get(vnum, {}) # 执行史诗装备升阶转换锻造 func do_epic_refine( target_slot: int, inventory: Array, player_data: Dictionary ) -> Dictionary: if target_slot < 0 or target_slot >= inventory.size(): return {"ok": false, "reason": "INVALID_SLOT", "msg": "无效的装备栏位!"} var base_item = inventory[target_slot] if base_item == null: return {"ok": false, "reason": "EMPTY_SLOT", "msg": "该格子上没有装备!"} # 安全锁拦截 if base_item.get("is_locked", false): return {"ok": false, "reason": "ITEM_LOCKED", "msg": "已加锁的装备无法进行史诗锻造!"} var base_vnum: int = int(base_item.get("vnum", 0)) if not EPIC_RECIPES.has(base_vnum): return {"ok": false, "reason": "NOT_AN_EPIC_BASE_ITEM", "msg": "该物品无法进行修元平史诗升阶!"} var recipe: Dictionary = EPIC_RECIPES[base_vnum] # 1. 检查金币 (Yang) var current_yang: int = int(player_data.get("gold", 0)) if current_yang < REQUIRED_YANG: return { "ok": false, "reason": "INSUFFICIENT_YANG", "required_yang": REQUIRED_YANG, "current_yang": current_yang, "msg": "史诗锻造需要 200,000 金币!你的金币不足。" } # 2. 统计并收集龙鳞与龙爪 var scale_slots: Array = [] var claw_slots: Array = [] var total_scales: int = 0 var total_claws: int = 0 for i in range(inventory.size()): var item = inventory[i] if item == null: continue var v: int = int(item.get("vnum", 0)) var cnt: int = int(item.get("count", 1)) if v == ITEM_DRAGON_SCALE: total_scales += cnt scale_slots.append({"slot": i, "count": cnt}) elif v == ITEM_DRAGON_CLAW: total_claws += cnt claw_slots.append({"slot": i, "count": cnt}) if total_scales < REQUIRED_SCALE_COUNT: return { "ok": false, "reason": "MISSING_DRAGON_SCALES", "required": REQUIRED_SCALE_COUNT, "current": total_scales, "msg": "史诗锻造需要 3 个龙鳞!当前只有 %d 个。" % total_scales } if total_claws < REQUIRED_CLAW_COUNT: return { "ok": false, "reason": "MISSING_DRAGON_CLAWS", "required": REQUIRED_CLAW_COUNT, "current": total_claws, "msg": "史诗锻造需要 4 个龙爪!当前只有 %d 个。" % total_claws } # 3. 扣除金币 player_data["gold"] = current_yang - REQUIRED_YANG # 4. 扣除材料 (龙鳞 3, 龙爪 4) _consume_materials(inventory, scale_slots, REQUIRED_SCALE_COUNT) _consume_materials(inventory, claw_slots, REQUIRED_CLAW_COUNT) # 5. 生成新史诗装备,1:1 完整继承 5 条附加属性与已镶嵌灵石! var new_vnum: int = recipe["target_vnum"] var inherited_attrs: Array = [] if base_item.has("attributes"): for attr in base_item["attributes"]: inherited_attrs.append(attr.duplicate()) var inherited_sockets: Array = [] if base_item.has("sockets"): for sock in base_item["sockets"]: inherited_sockets.append(sock) var epic_item: Dictionary = { "vnum": new_vnum, "name": recipe["name"], "count": 1, "attributes": inherited_attrs, "sockets": inherited_sockets, "socket_count": base_item.get("socket_count", 3), "is_locked": false } # 替换背包中原位置的装备 inventory[target_slot] = epic_item epic_refine_succeeded.emit(base_vnum, new_vnum, epic_item) return { "ok": true, "old_vnum": base_vnum, "new_vnum": new_vnum, "item": epic_item, "msg": "恭喜!修元平大师成功将装备升阶锻造为【%s】!" % recipe["name"] } # 辅助函数:按需从多个格子中扣除材料数量 func _consume_materials(inventory: Array, slots_info: Array, count_needed: int) -> void: var needed := count_needed for info in slots_info: var s: int = info["slot"] var have: int = info["count"] if have <= needed: needed -= have inventory[s] = null else: inventory[s]["count"] = have - needed needed = 0 if needed <= 0: break