Files
mtgodot-poc/project/test_equipment_inspect_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

117 lines
4.2 KiB
GDScript

# test_equipment_inspect_parity.gd —— 40250 装备透视检视与 GM 监察系统回归测试
extends SceneTree
const SystemClass = preload("res://equipment_inspect_system.gd")
var _passed: int = 0
var _failed: int = 0
func _assert(cond: bool, msg: String) -> void:
if cond:
_passed += 1
print(" [PASS] %s" % msg)
else:
_failed += 1
printerr(" [FAIL] %s" % msg)
func _init() -> void:
print("\n=== Running test_equipment_inspect_parity (Batch 28 Direction 2) ===")
_test_open_and_load_slots()
_test_privacy_and_gm_bypass()
_test_slot_tooltip_generation()
_test_close_lifecycle()
print("\n=== Result: %d Passed, %d Failed ===" % [_passed, _failed])
if _failed == 0:
print("ALL TESTS PASSED!\n")
else:
printerr("SOME TESTS FAILED!\n")
quit(0 if _failed == 0 else 1)
func _test_open_and_load_slots() -> void:
print("\n--- Test 1: Open Dialog & Equipment Slots Loading ---")
var ins = SystemClass.new()
var dummy_equips = {
SystemClass.WEAR_WEAPON: {
"vnum": 189,
"name": "毒剑+9 (Poison Sword+9)",
"sockets": [28430, 28431, 28432],
"attributes": [{ "type": 72, "value": 42 }]
},
SystemClass.WEAR_BODY: {
"vnum": 11299,
"name": "黑铁战甲+9 (Black Steel Armor+9)",
"sockets": [28440, 28441, 0],
"attributes": [{ "type": 1, "value": 2000 }]
},
SystemClass.WEAR_COSTUME_BODY: {
"vnum": 41001,
"name": "沙漠武士服 (Desert Warrior Body)",
"attributes": [{ "type": 1, "value": 1500 }]
}
}
var r = ins.open_dialog(1001, "TargetWarrior", dummy_equips, true, false)
_assert(r["success"] == true, "Opened inspect dialog for TargetWarrior")
_assert(ins.is_open == true, "Inspect dialog is open")
_assert(ins.inspected_vid == 1001, "Target VID is 1001")
# Verify Weapon Slot
var wpn = ins.get_slot_item(SystemClass.WEAR_WEAPON)
_assert(wpn["vnum"] == 189, "Weapon Vnum matches 189")
_assert(wpn["sockets"].size() == 3, "Weapon has 3 sockets")
# Verify Costume Body Slot
var cst = ins.get_slot_item(SystemClass.WEAR_COSTUME_BODY)
_assert(cst["vnum"] == 41001, "Costume body loaded")
func _test_privacy_and_gm_bypass() -> void:
print("\n--- Test 2: Privacy Shield & GM Privilege Bypass ---")
var ins = SystemClass.new()
var dummy_equips = { SystemClass.WEAR_WEAPON: { "vnum": 10, "name": "Sword+0" } }
# 1. Normal player inspecting private player -> REJECTED
var r_fail = ins.open_dialog(1002, "PrivateLord", dummy_equips, false, false)
_assert(r_fail["error_code"] == "INSPECT_FORBIDDEN", "Reject inspection if target hidden privacy")
_assert(ins.is_open == false, "Dialog remains closed")
# 2. GM inspecting private player -> BYPASS SUCCESS
var r_gm = ins.open_dialog(1002, "PrivateLord", dummy_equips, false, true)
_assert(r_gm["success"] == true, "GM successfully bypassed privacy shield")
_assert(ins.is_open == true, "Dialog opened for GM")
func _test_slot_tooltip_generation() -> void:
print("\n--- Test 3: Slot Tooltip Generation on Hover ---")
var ins = SystemClass.new()
var dummy_equips = {
SystemClass.WEAR_WEAPON: {
"vnum": 189,
"name": "Poison Sword+9",
"sockets": [28430, 28431, 0],
"attributes": [{ "type": 72, "value": 45 }]
}
}
ins.open_dialog(1001, "TargetWarrior", dummy_equips, true, false)
# Equipped weapon tooltip
var tip_wpn = ins.build_slot_tooltip(SystemClass.WEAR_WEAPON)
_assert(tip_wpn.contains("Poison Sword+9"), "Tooltip contains weapon name")
_assert(tip_wpn.contains("部位: 武器"), "Tooltip contains slot title")
_assert(tip_wpn.contains("属性 72 +45"), "Tooltip contains bonus attribute")
# Empty shield slot tooltip
var tip_shield = ins.build_slot_tooltip(SystemClass.WEAR_SHIELD)
_assert(tip_shield.contains("[盾牌] 未佩戴装备"), "Empty slot displays placeholder notice")
func _test_close_lifecycle() -> void:
print("\n--- Test 4: Close Dialog & Memory Cleanup ---")
var ins = SystemClass.new()
ins.open_dialog(1001, "Target", { SystemClass.WEAR_BODY: { "vnum": 1, "name": "Armor" } })
_assert(ins.is_open == true, "Dialog open")
ins.close_dialog()
_assert(ins.is_open == false, "Dialog closed")
_assert(ins.equipment_slots.is_empty(), "Slots wiped on close")
_assert(ins.get_slot_item(SystemClass.WEAR_BODY).is_empty(), "Cannot retrieve slot when closed")