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

166 lines
6.5 KiB
GDScript

# test_safebox_storage_keeper_parity.gd —— 40250 仓库保管员金条熔铸与密码保险箱系统回归测试
extends SceneTree
const SystemClass = preload("res://safebox_storage_keeper_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_safebox_storage_keeper_parity (Batch 26 Direction 2) ===")
_test_password_and_open_checks()
_test_password_change()
_test_safebox_storage_operations()
_test_gold_bar_smelting_and_encashment()
_test_safebox_edge_cases()
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_password_and_open_checks() -> void:
print("\n--- Test 1: Safebox Password Authentication & Cooldown/Distance ---")
var box = SystemClass.new()
# 1. Distance > 1000 fails
var r_dist = box.open_safebox("000000", 1500.0)
_assert(r_dist["error_code"] == "TOO_FAR", "Reject opening safebox if distance > 1000")
# 2. Wrong password fails
var r_wrong = box.open_safebox("123456", 200.0)
_assert(r_wrong["error_code"] == "WRONG_PASSWORD", "Reject opening safebox with wrong password")
_assert(box.is_open == false, "Safebox remains closed on wrong password")
# 3. Default password "000000" succeeds
var r_ok = box.open_safebox("000000", 200.0)
_assert(r_ok["success"] == true, "Default password 000000 opens safebox")
_assert(box.is_open == true, "Safebox is open")
# 4. Opening within 10s fails with COOLDOWN_ACTIVE
box.close_safebox()
box.current_time = 1005 # only 5 seconds later
var r_cd = box.open_safebox("000000", 200.0)
_assert(r_cd["error_code"] == "COOLDOWN_ACTIVE", "Reject opening safebox within 10 seconds")
# 5. Opening after 10s succeeds
box.current_time = 1015
var r_cd_ok = box.open_safebox("000000", 200.0)
_assert(r_cd_ok["success"] == true, "Open safebox succeeds after cooldown expires")
func _test_password_change() -> void:
print("\n--- Test 2: Password Change Verification ---")
var box = SystemClass.new()
box.open_safebox("000000", 200.0)
# Old password mismatch
var r_fail = box.change_password("999999", "654321")
_assert(r_fail["error_code"] == "OLD_PASSWORD_MISMATCH", "Reject password change if old password mismatches")
# Change password successfully
var r_succ = box.change_password("000000", "888888")
_assert(r_succ["success"] == true, "Password successfully changed to 888888")
_assert(box.password == "888888", "Internal password updated")
# Re-open with new password
box.close_safebox()
box.current_time += 20
var r_new_open = box.open_safebox("888888", 200.0)
_assert(r_new_open["success"] == true, "Can open safebox with new password")
func _test_safebox_storage_operations() -> void:
print("\n--- Test 3: Storage Deposit, Withdraw & Stacking (45 Slots) ---")
var box = SystemClass.new()
box.open_safebox("000000", 200.0)
var sword = { "vnum": 10, "name": "Sword+0", "count": 1, "stackable": false }
var potion1 = { "vnum": 27001, "name": "Red Potion (S)", "count": 50, "stackable": true }
var potion2 = { "vnum": 27001, "name": "Red Potion (S)", "count": 25, "stackable": true }
# Deposit sword into slot 0
var dep1 = box.deposit_item(0, sword)
_assert(dep1["success"] == true, "Sword deposited into slot 0")
_assert(box.safebox_grid[0]["vnum"] == 10, "Slot 0 holds Sword+0")
# Deposit potion into slot 1
var dep2 = box.deposit_item(1, potion1)
_assert(dep2["success"] == true, "Potion deposited into slot 1")
# Stacking into slot 1
var dep3 = box.deposit_item(1, potion2)
_assert(dep3["success"] == true, "Potion stacked into slot 1")
_assert(box.safebox_grid[1]["count"] == 75, "Slot 1 potion count updated to 75")
# Moving item from slot 0 to slot 5
var move_ok = box.move_safebox_item(0, 5)
_assert(move_ok == true, "Moved item from slot 0 to slot 5")
_assert(box.safebox_grid[0] == null, "Slot 0 is now empty")
_assert(box.safebox_grid[5]["vnum"] == 10, "Slot 5 now holds Sword+0")
# Withdraw item from slot 5
var wd = box.withdraw_item(5)
_assert(wd["success"] == true, "Withdrew item from slot 5")
_assert(wd["item"]["vnum"] == 10, "Withdrawn item is Sword+0")
_assert(box.safebox_grid[5] == null, "Slot 5 is now empty")
func _test_gold_bar_smelting_and_encashment() -> void:
print("\n--- Test 4: Official 1% Smelting Tax & Encashment (80003~80007) ---")
var box = SystemClass.new()
# 1. Smelt 50k bar (80003): cost = 50500 (1% tax)
var player_gold := 100000
var s1 = box.smelt_gold_bar(player_gold, 80003)
_assert(s1["success"] == true, "Smelted 50k silver bar")
_assert(s1["cost"] == 50500, "Cost is exactly 50,500 (1% fee)")
_assert(s1["new_gold"] == 49500, "Player gold reduced to 49,500")
_assert(s1["bar_item"]["face_value"] == 50000, "Bar face value is 50,000")
# 2. Smelt 2M bar (80007): cost = 2,020,000 (1% tax)
player_gold = 3000000
var s2 = box.smelt_gold_bar(player_gold, 80007)
_assert(s2["success"] == true, "Smelted 2M gold bar")
_assert(s2["cost"] == 2020000, "Cost is exactly 2,020,000")
_assert(s2["new_gold"] == 980000, "Player gold reduced to 980,000")
# 3. Insufficient gold rejected
var s_fail = box.smelt_gold_bar(1000, 80003)
_assert(s_fail["error_code"] == "INSUFFICIENT_GOLD", "Reject smelting when gold < cost")
# 4. Encash 2M bar (80007) back to cash: grants 2,000,000 face value
var c1 = box.encash_gold_bar(500000, 80007)
_assert(c1["success"] == true, "Encash 2M gold bar")
_assert(c1["cash_value"] == 2000000, "Cash value is 2,000,000")
_assert(c1["new_gold"] == 2500000, "Player gold increased to 2,500,000")
func _test_safebox_edge_cases() -> void:
print("\n--- Test 5: Closed Safebox Operations & Invalid Slots ---")
var box = SystemClass.new()
# Deposit while closed
var dep_closed = box.deposit_item(0, { "vnum": 1, "count": 1 })
_assert(dep_closed["error_code"] == "NOT_OPEN", "Reject deposit when safebox is closed")
# Withdraw while closed
var wd_closed = box.withdraw_item(0)
_assert(wd_closed["error_code"] == "NOT_OPEN", "Reject withdraw when safebox is closed")
# Open safebox
box.open_safebox("000000", 200.0)
# Invalid slots (< 0 or >= 45)
var dep_inv = box.deposit_item(45, { "vnum": 1, "count": 1 })
_assert(dep_inv["error_code"] == "INVALID_SLOT", "Reject deposit into slot 45 (max 44)")
var wd_inv = box.withdraw_item(-1)
_assert(wd_inv["error_code"] == "INVALID_SLOT", "Reject withdraw from slot -1")