# attach_metin_dialog_system.gd # 40250 官方 1:1 装备幽魂石/灵魂石镶嵌与双重属性对比预览系统 # 对照: uiattachmetin.py, attachstonedialog.py, char_item.cpp class_name AttachMetinDialogSystem extends RefCounted const METIN_SOCKET_MAX_NUM: int = 3 const METIN_NORMAL: int = 0 const METIN_GOLD: int = 1 const METIN_SOCKET_TYPE_NONE: int = 0 const METIN_SOCKET_TYPE_SILVER: int = 1 const METIN_SOCKET_TYPE_GOLD: int = 2 const ITEM_BROKEN_METIN_VNUM: int = 28960 # 经典灵魂石属性对照表 (40250 canonical metin stones 28000~28443) const METIN_STONES: Dictionary = { 28030: {"name": "战神之石+0", "bonus_type": "ATT_BONUS_TO_WARRIOR", "bonus_value": 5}, 28130: {"name": "战神之石+1", "bonus_type": "ATT_BONUS_TO_WARRIOR", "bonus_value": 8}, 28230: {"name": "战神之石+2", "bonus_type": "ATT_BONUS_TO_WARRIOR", "bonus_value": 12}, 28330: {"name": "战神之石+3", "bonus_type": "ATT_BONUS_TO_WARRIOR", "bonus_value": 17}, 28430: {"name": "战神之石+4", "bonus_type": "ATT_BONUS_TO_WARRIOR", "bonus_value": 25}, 28434: {"name": "穿透之石+4", "bonus_type": "POINT_PENETRATE_PCT", "bonus_value": 8}, 28435: {"name": "致命之石+4", "bonus_type": "POINT_CRITICAL_PCT", "bonus_value": 8}, 28438: {"name": "防御之石+4", "bonus_type": "POINT_DEF_GRADE_BONUS", "bonus_value": 15}, 28442: {"name": "加速之石+4", "bonus_type": "POINT_MOV_SPEED", "bonus_value": 30}, 28960: {"name": "破碎的石头碎块", "bonus_type": "NONE", "bonus_value": 0} } var is_open: bool = false var metin_pos: int = -1 var target_pos: int = -1 var metin_vnum: int = 0 var metin_subtype: int = METIN_NORMAL var target_item_vnum: int = 0 var current_sockets: Array = [0, 0, 0] var preview_sockets: Array = [0, 0, 0] var target_socket_idx: int = -1 var last_packet_sent: Dictionary = {} var last_sound_played: String = "" signal dialog_opened(metin_pos: int, target_pos: int, preview_sockets: Array) signal dialog_closed() signal metin_attached(metin_pos: int, target_pos: int, target_slot_idx: int) signal attach_failed(reason: String) func can_attach_metin(slot_type: int, metin_type: int) -> bool: if metin_type == METIN_NORMAL: if slot_type == METIN_SOCKET_TYPE_SILVER or slot_type == METIN_SOCKET_TYPE_GOLD: return true elif metin_type == METIN_GOLD: if slot_type == METIN_SOCKET_TYPE_GOLD: return true return false func open_dialog(p_metin_pos: int, p_target_pos: int, p_metin_vnum: int, p_metin_subtype: int, p_target_vnum: int, p_sockets: Array) -> bool: metin_pos = p_metin_pos target_pos = p_target_pos metin_vnum = p_metin_vnum metin_subtype = p_metin_subtype target_item_vnum = p_target_vnum current_sockets = [0, 0, 0] preview_sockets = [0, 0, 0] target_socket_idx = -1 for i in range(mini(p_sockets.size(), METIN_SOCKET_MAX_NUM)): current_sockets[i] = p_sockets[i] preview_sockets[i] = p_sockets[i] # 寻找首个符合条件的开放槽位 var found_slot: bool = false for i in range(METIN_SOCKET_MAX_NUM): var slot_state: int = current_sockets[i] if can_attach_metin(slot_state, metin_subtype): preview_sockets[i] = metin_vnum target_socket_idx = i found_slot = true break if not found_slot: attach_failed.emit("NO_AVAILABLE_SOCKET") return false is_open = true dialog_opened.emit(metin_pos, target_pos, preview_sockets) return true func accept() -> bool: if not is_open: return false if target_socket_idx < 0: attach_failed.emit("INVALID_SOCKET") return false # 40250 发送 net.SendItemUseToItemPacket(self.metinItemPos, self.targetItemPos) last_packet_sent = { "header": "HEADER_CG_ITEM_USE_TO_ITEM", "metin_pos": metin_pos, "target_pos": target_pos, "target_socket_idx": target_socket_idx, "metin_vnum": metin_vnum } # 官方原版音效 last_sound_played = "sound/ui/metinstone_insert.wav" metin_attached.emit(metin_pos, target_pos, target_socket_idx) close_dialog() return true func close_dialog() -> void: is_open = false metin_pos = -1 target_pos = -1 dialog_closed.emit() # 模拟服务端结算镶嵌 (支持成功率判定: 成功直接嵌入,失败产生破碎石块 28960) func simulate_server_process(target_sockets: Array, socket_idx: int, attached_metin_vnum: int, success: bool) -> Array: var result_sockets: Array = target_sockets.duplicate() if socket_idx >= 0 and socket_idx < result_sockets.size(): if success: result_sockets[socket_idx] = attached_metin_vnum else: result_sockets[socket_idx] = ITEM_BROKEN_METIN_VNUM return result_sockets # 模拟卷轴清理破碎石头 (vnum 71083 / Scroll of Cleansing) func clean_broken_socket(target_sockets: Array, socket_idx: int) -> Array: var result_sockets: Array = target_sockets.duplicate() if socket_idx >= 0 and socket_idx < result_sockets.size(): if result_sockets[socket_idx] == ITEM_BROKEN_METIN_VNUM: result_sockets[socket_idx] = METIN_SOCKET_TYPE_SILVER return result_sockets func get_metin_info(vnum: int) -> Dictionary: if METIN_STONES.has(vnum): return METIN_STONES[vnum] return {"name": "未知幽魂石", "bonus_type": "UNKNOWN", "bonus_value": 0}