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

100 lines
3.9 KiB
GDScript

# test_private_shop_bundle_parity.gd —— 验证方向 4:束发包袱皮与个人私有商店摆摊 40250 1:1 对齐
extends SceneTree
const PrivateShopSystem = preload("res://private_shop_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_private_shop_bundle_parity (Direction 4: Private Shop Bundle 1:1) ===")
test_bundle_item_check()
test_prerequisites()
test_sign_validation()
test_item_stocking()
test_shop_build_and_stall_vnum()
print("\n=== SUMMARY: %d passed, %d failed ===" % [_passed, _failed])
if _failed > 0:
printerr("TEST FAILED!")
quit(1)
else:
print("ALL TESTS PASSED!")
quit(0)
func test_bundle_item_check() -> void:
print("\n--- Test 1: Bundle Item Vnum Check (50200) ---")
_assert(PrivateShopSystem.is_bundle(50200), "50200 is Bundle (ITEM_BUNDLE)")
_assert(not PrivateShopSystem.is_bundle(10), "Sword is not a bundle")
_assert(not PrivateShopSystem.is_bundle(27001), "Potion is not a bundle")
func test_prerequisites() -> void:
print("\n--- Test 2: Shop Opening Prerequisites (Battle, Mount, Death) ---")
# Fails when dead
var r_dead := PrivateShopSystem.can_open_private_shop(false, false, true)
_assert(not r_dead.ok and r_dead.code == "CANNOT_DEAD", "Rejected while dead")
# Fails when mounted
var r_mount := PrivateShopSystem.can_open_private_shop(false, true, false)
_assert(not r_mount.ok and r_mount.code == "CANNOT_MOUNTED", "Rejected while mounted")
# Fails when fighting
var r_fight := PrivateShopSystem.can_open_private_shop(true, false, false)
_assert(not r_fight.ok and r_fight.code == "CANNOT_FIGHTING", "Rejected while in battle")
# Succeeds when peaceful
var r_ok := PrivateShopSystem.can_open_private_shop(false, false, false)
_assert(r_ok.ok, "Can open shop when peaceful on foot")
func test_sign_validation() -> void:
print("\n--- Test 3: Shop Sign Text Validation ---")
var v_empty := PrivateShopSystem.validate_sign("")
_assert(not v_empty.ok and v_empty.code == "SIGN_EMPTY", "Empty sign rejected")
var long_sign := "这是一个超级无敌非常长长长长长长长长长长长长长长长长的名字" # > 25 chars
var v_long := PrivateShopSystem.validate_sign(long_sign)
_assert(not v_long.ok and v_long.code == "SIGN_TOO_LONG", "Sign > 25 chars rejected")
var v_valid := PrivateShopSystem.validate_sign("神装特价店")
_assert(v_valid.ok and v_valid.sign == "神装特价店", "Valid sign accepted")
func test_item_stocking() -> void:
print("\n--- Test 4: Staging Items with Price into Stock ---")
var stock := {}
var sword_item := {"cell": 0, "vnum": 10, "count": 1}
# Zero/negative price rejected
var r_zero := PrivateShopSystem.add_item_to_stock(stock, 0, sword_item, 0)
_assert(not r_zero.ok and r_zero.code == "INVALID_PRICE", "Zero price rejected")
# Valid add
var r_add := PrivateShopSystem.add_item_to_stock(stock, 0, sword_item, 5000)
_assert(r_add.ok and stock.has(0), "Item added to stock slot 0")
_assert(stock[0].price == 5000, "Price set to 5000 gold")
# Remove from stock
_assert(PrivateShopSystem.remove_item_from_stock(stock, 0), "Item removed from stock slot 0")
_assert(not stock.has(0), "Stock slot 0 is now empty")
func test_shop_build_and_stall_vnum() -> void:
print("\n--- Test 5: Shop Build & Stall Model (Vnum 30000) ---")
var stock := {
0: {"cell": 0, "vnum": 10, "count": 1, "price": 5000}
}
var stall_pos := Vector3(120, 0, 80)
var res_build := PrivateShopSystem.build_private_shop("平民杂货摊", stock, stall_pos)
_assert(res_build.ok and res_build.code == "SHOP_OPENED", "Shop opened successfully")
_assert(res_build.stall_vnum == PrivateShopSystem.VNUM_SHOP_HOST_STALL,
"Stall model is 30000 (SHOP_HOST)")
_assert(res_build.items_count == 1, "Staged item count is 1")
_assert(res_build.position == stall_pos, "Stall spawned at current position")