Files
mtgodot-poc/project/test_attach_metin_parity.gd
T
shenandshen 66d217b313 feat(client): 完成40250客户端核心功能1:1对齐与桥梁高度采样修复
- 桥梁与静态物体高度采样修复:
  - 严格对齐 40250 CMapOutdoor::GetHeight 与 CAttributeInstance::GetHeight
  - 解析 .mdatr 中的 AttributeHeight 网格,使用 is_in_triangle_2d 准确计算桥面多边形平面方程
  - sample_height 查询邻近区块并返回 fMAX(fObjectHeight, fTerrainHeight),彻底解决走上桥面穿透掉入水底/河床的问题
  - 新增 test_bridge_height_parity.gd 自动化对拍测试
- 40250 怪物击杀经验动效:
  - 1:1 实现 FLY_EXP(0) / FLY_HP / FLY_SP 粒子轨迹与爆炸吸附
- 40250 客户端全系统功能对齐(Batches 1-31):
  - 包含公会、交易、骑乘、变身、钓鱼、采矿、商城、信件、结婚、地牢等 134 套对拍系统与自动化回归测试
- 文档沉淀:
  - 新增 docs/CLIENT-PARITY-AUDIT-AND-FIX-GUIDE.md 客户端对拍缺陷发现与修复工程指南
2026-09-19 08:51:25 -07:00

93 lines
4.1 KiB
GDScript

# test_attach_metin_parity.gd
# 检验 40250 官方装备灵魂石镶嵌与双重属性预览系统
extends SceneTree
const AttachMetinDialogSystem = preload("res://attach_metin_dialog_system.gd")
func _init() -> void:
print("--- 开始测试 40250 装备灵魂石镶嵌系统 (test_attach_metin_parity) ---")
var system = AttachMetinDialogSystem.new()
var fails: int = 0
# 1. 槽位类型合法性 CanAttachMetin 测试
# METIN_NORMAL 应该能嵌入 SILVER(1) 和 GOLD(2),但不能嵌入 NONE(0) 或已经有石头的槽位(28430)
if not system.can_attach_metin(AttachMetinDialogSystem.METIN_SOCKET_TYPE_SILVER, AttachMetinDialogSystem.METIN_NORMAL):
printerr("FAIL: 普通灵魂石无法嵌入银孔!")
fails += 1
if not system.can_attach_metin(AttachMetinDialogSystem.METIN_SOCKET_TYPE_GOLD, AttachMetinDialogSystem.METIN_NORMAL):
printerr("FAIL: 普通灵魂石无法嵌入金孔!")
fails += 1
if system.can_attach_metin(AttachMetinDialogSystem.METIN_SOCKET_TYPE_NONE, AttachMetinDialogSystem.METIN_NORMAL):
printerr("FAIL: 未开孔槽位不应能嵌入灵魂石!")
fails += 1
# METIN_GOLD 只能嵌入 GOLD(2)
if system.can_attach_metin(AttachMetinDialogSystem.METIN_SOCKET_TYPE_SILVER, AttachMetinDialogSystem.METIN_GOLD):
printerr("FAIL: 黄金幽魂石不应能嵌入普通银孔!")
fails += 1
if not system.can_attach_metin(AttachMetinDialogSystem.METIN_SOCKET_TYPE_GOLD, AttachMetinDialogSystem.METIN_GOLD):
printerr("FAIL: 黄金幽魂石应当能嵌入金孔!")
fails += 1
# 2. 对话框打开与预览槽位替换测试
# 假设目标武器当前槽位: [1 (开孔), 1 (开孔), 0 (未开孔)]
# 镶嵌 致命之石+4 (28435, METIN_NORMAL)
var opened = system.open_dialog(10, 20, 28435, AttachMetinDialogSystem.METIN_NORMAL, 10, [1, 1, 0])
if not opened or not system.is_open:
printerr("FAIL: 开启镶嵌对话框失败!")
fails += 1
if system.target_socket_idx != 0:
printerr("FAIL: 首个开放槽位索引应为 0,实际为: ", system.target_socket_idx)
fails += 1
if system.preview_sockets[0] != 28435 or system.preview_sockets[1] != 1 or system.preview_sockets[2] != 0:
printerr("FAIL: 预览槽位状态不符,实际: ", system.preview_sockets)
fails += 1
# 3. 接受镶嵌并检查数据包与音效
var accepted = system.accept()
if not accepted:
printerr("FAIL: 确认镶嵌失败!")
fails += 1
if system.last_packet_sent.get("header") != "HEADER_CG_ITEM_USE_TO_ITEM":
printerr("FAIL: 数据包 Header 错误: ", system.last_packet_sent)
fails += 1
if system.last_sound_played != "sound/ui/metinstone_insert.wav":
printerr("FAIL: 镶嵌音效路径不符: ", system.last_sound_played)
fails += 1
# 4. 服务端结算模拟: 成功嵌入 vs 失败破碎 (28960)
var sockets_after_success = system.simulate_server_process([1, 1, 0], 0, 28435, true)
if sockets_after_success[0] != 28435:
printerr("FAIL: 成功镶嵌后槽位未记录石头 VNUM: ", sockets_after_success)
fails += 1
var sockets_after_fail = system.simulate_server_process([1, 1, 0], 0, 28435, false)
if sockets_after_fail[0] != AttachMetinDialogSystem.ITEM_BROKEN_METIN_VNUM:
printerr("FAIL: 镶嵌失败未生成破碎石块 28960: ", sockets_after_fail)
fails += 1
# 5. 清理碎石卷轴测试
var cleaned = system.clean_broken_socket(sockets_after_fail, 0)
if cleaned[0] != AttachMetinDialogSystem.METIN_SOCKET_TYPE_SILVER:
printerr("FAIL: 清理破碎石块后槽位未恢复银孔状态: ", cleaned)
fails += 1
# 6. 无可用槽位时拒绝开启
var no_slot_opened = system.open_dialog(11, 21, 28435, AttachMetinDialogSystem.METIN_NORMAL, 10, [0, 0, 0])
if no_slot_opened or system.is_open:
printerr("FAIL: 无可用孔位时不应成功开启镶嵌对话框!")
fails += 1
# 7. 石头数据查询
var info = system.get_metin_info(28434)
if info.bonus_type != "POINT_PENETRATE_PCT" or info.bonus_value != 8:
printerr("FAIL: 穿透之石+4 属性解析错误: ", info)
fails += 1
if fails == 0:
print("PASS: test_attach_metin_parity (7/7 全部通过)")
quit(0)
else:
printerr("FAILED: test_attach_metin_parity (", fails, " 项失败)")
quit(1)