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

174 lines
7.3 KiB
GDScript

# test_item_enchant_manager_parity.gd —— 40250 装备附魔洗炼与稀有词条重铸 1:1 回归测试套件
extends SceneTree
const ItemEnchantSystem = preload("res://item_enchant_system.gd")
var _passed := 0
var _failed := 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_item_enchant_manager_parity (Direction 3: Item Enchant & Rare Reforge 1:1) ===")
_test_scroll_and_item_compatibility()
_test_add_1_to_4_attributes()
_test_blessing_marble_5th_attribute()
_test_change_attributes()
_test_rare_6th_and_7th_attributes()
_finish()
func _test_scroll_and_item_compatibility() -> void:
print("\n--- Test 1: Scroll & Equipment Compatibility ---")
_assert(ItemEnchantSystem.is_enchant_scroll(71085), "71085 is enchant scroll")
_assert(ItemEnchantSystem.is_enchant_scroll(71084), "71084 is enchant scroll")
_assert(ItemEnchantSystem.is_enchant_scroll(70024), "70024 is enchant scroll")
_assert(ItemEnchantSystem.is_enchant_scroll(71151), "71151 is enchant scroll")
_assert(ItemEnchantSystem.is_enchant_scroll(71152), "71152 is enchant scroll")
_assert(not ItemEnchantSystem.is_enchant_scroll(27001), "Potion is not enchant scroll")
var sword := {"vnum": 10, "type": 1, "attrs": []}
var arrow := {"vnum": 8000, "type": 1, "attrs": []}
var locked_armor := {"vnum": 11299, "type": 2, "is_locked": true, "attrs": []}
_assert(ItemEnchantSystem.is_enchantable_item(sword), "Sword is enchantable")
_assert(not ItemEnchantSystem.is_enchantable_item(arrow), "Arrow (8000) cannot be enchanted")
_assert(not ItemEnchantSystem.is_enchantable_item(locked_armor), "Locked armor is protected from enchanting")
func _test_add_1_to_4_attributes() -> void:
print("\n--- Test 2: Add 1st~4th Attributes (71085) ---")
var sys := ItemEnchantSystem.new()
var inv: Array = [
{"vnum": ItemEnchantSystem.VNUM_ATTR_ADD, "name": "添加属性秘籍", "count": 10},
{"vnum": 10, "name": "巨剑+9", "type": 1, "attrs": []}
]
var sig_data := {"fired": false, "slot": -1, "success": false}
sys.enchant_applied.connect(func(slot: int, _svnum: int, succ: bool, _attrs: Array):
sig_data["fired"] = true
sig_data["slot"] = slot
sig_data["success"] = succ
)
# Add 1st attribute (force_success = true)
var res1 = sys.apply_scroll(0, 1, inv, true)
_assert(res1["ok"] == true and res1["success"] == true, "1st attribute added")
_assert(inv[1]["attrs"].size() == 1, "Sword has 1 attribute")
_assert(inv[0]["count"] == 9, "Scroll count decreased 10 -> 9")
_assert(sig_data["fired"] == true and sig_data["slot"] == 1, "enchant_applied signal emitted")
# Add 2nd, 3rd, 4th attributes
sys.apply_scroll(0, 1, inv, true)
sys.apply_scroll(0, 1, inv, true)
sys.apply_scroll(0, 1, inv, true)
_assert(inv[1]["attrs"].size() == 4, "Sword has 4 attributes")
_assert(inv[0]["count"] == 6, "Scroll count is now 6")
# 5th attempt with 71085 must be rejected
var res5 = sys.apply_scroll(0, 1, inv, true)
_assert(res5["ok"] == false and res5["reason"] == "MAX_BASE_ATTRS_REACHED", "5th attempt rejected by 71085")
_assert(inv[0]["count"] == 6, "Scroll count NOT consumed on failure")
func _test_blessing_marble_5th_attribute() -> void:
print("\n--- Test 3: Blessing Marble 5th Attribute (70024) ---")
var sys := ItemEnchantSystem.new()
var inv: Array = [
{"vnum": ItemEnchantSystem.VNUM_BLESSING_MARBLE, "name": "祝福宝珠", "count": 2},
{"vnum": 10, "name": "巨剑+9", "type": 1, "attrs": [{"type": 1, "name": "最大生命", "value": 2000}]} # only 1 attr
]
# Using on item with < 4 attrs must fail
var fail_res = sys.apply_scroll(0, 1, inv, true)
_assert(fail_res["ok"] == false and fail_res["reason"] == "NEED_4_ATTRS_FIRST", "Blessing marble requires 4 attrs first")
# Fill up to 4 attrs
inv[1]["attrs"] = [
{"type": 1, "name": "HP", "value": 2000},
{"type": 5, "name": "STR", "value": 12},
{"type": 15, "name": "Crit", "value": 10},
{"type": 16, "name": "Pen", "value": 10}
]
# Now use blessing marble
var res5 = sys.apply_scroll(0, 1, inv, true)
_assert(res5["ok"] == true and res5["success"] == true, "5th attribute added by Blessing Marble")
_assert(inv[1]["attrs"].size() == 5, "Item now has exactly 5 attributes")
_assert(inv[0]["count"] == 1, "Marble consumed (2 -> 1)")
# 6th attempt with blessing marble must be rejected
var res6 = sys.apply_scroll(0, 1, inv, true)
_assert(res6["ok"] == false and res6["reason"] == "ALREADY_HAS_5_ATTRS", "Blessing marble rejected when 5 attrs exist")
func _test_change_attributes() -> void:
print("\n--- Test 4: Change All Attributes (71084) ---")
var sys := ItemEnchantSystem.new()
var old_attrs: Array = [
{"type": 1, "name": "HP", "value": 500},
{"type": 2, "name": "SP", "value": 100},
{"type": 7, "name": "AtkSpeed", "value": 2}
]
var inv: Array = [
{"vnum": ItemEnchantSystem.VNUM_ATTR_CHANGE, "name": "属性改变秘籍", "count": 1},
{"vnum": 10, "name": "巨剑+9", "type": 1, "attrs": old_attrs.duplicate(true)}
]
var res = sys.apply_scroll(0, 1, inv)
_assert(res["ok"] == true and res["success"] == true, "Attributes rerolled")
_assert(inv[1]["attrs"].size() == 3, "Still has exactly 3 attributes")
_assert(inv[0] == null, "Single scroll consumed to null")
func _test_rare_6th_and_7th_attributes() -> void:
print("\n--- Test 5: 6th & 7th Rare Attributes (71151 / 71152) ---")
var sys := ItemEnchantSystem.new()
var inv: Array = [
{"vnum": ItemEnchantSystem.VNUM_RARE_ADD, "name": "稀有属性秘籍", "count": 3},
{"vnum": ItemEnchantSystem.VNUM_RARE_CHANGE, "name": "稀有属性改变", "count": 1},
{"vnum": 10, "name": "巨剑+9", "type": 1, "attrs": [{"type": 1, "name": "HP", "value": 2000}], "rare_attrs": []}
]
var rare_sig := {"fired": false, "rares": []}
sys.rare_enchant_applied.connect(func(_slot: int, _succ: bool, rares: Array):
rare_sig["fired"] = true
rare_sig["rares"] = rares
)
# Add 6th attribute (1st rare)
var r1 = sys.apply_scroll(0, 2, inv, true)
_assert(r1["ok"] == true and r1["success"] == true, "6th attribute (1st rare) added")
_assert(inv[2]["rare_attrs"].size() == 1, "1 rare attribute present")
_assert(inv[2]["attrs"].size() == 1, "Base attrs untouched")
_assert(rare_sig["fired"] == true, "rare_enchant_applied signal emitted")
# Add 7th attribute (2nd rare)
var r2 = sys.apply_scroll(0, 2, inv, true)
_assert(r2["ok"] == true and r2["success"] == true, "7th attribute (2nd rare) added")
_assert(inv[2]["rare_attrs"].size() == 2, "2 rare attributes present")
# 3rd rare must be rejected
var r3 = sys.apply_scroll(0, 2, inv, true)
_assert(r3["ok"] == false and r3["reason"] == "MAX_RARE_ATTRS", "3rd rare rejected")
# Change rare attributes (71152)
var rc = sys.apply_scroll(1, 2, inv)
_assert(rc["ok"] == true and rc["success"] == true, "Rare attributes rerolled")
_assert(inv[2]["rare_attrs"].size() == 2, "2 rare attributes preserved after reroll")
_assert(inv[2]["attrs"].size() == 1, "Base attrs remain intact")
_assert(inv[1] == null, "71152 scroll consumed")
func _finish() -> void:
print("\n==========================================")
print("Item Enchant Manager Parity Tests Finished:")
print("Passed: %d, Failed: %d" % [_passed, _failed])
print("==========================================")
if _failed > 0:
printerr("FAILED: Some tests did not pass.")
quit(1)
else:
print("SUCCESS: All Item Enchant Manager parity tests passed!")
quit(0)