- 桥梁与静态物体高度采样修复: - 严格对齐 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 客户端对拍缺陷发现与修复工程指南
93 lines
3.5 KiB
GDScript
93 lines
3.5 KiB
GDScript
# test_portable_service_parity.gd —— 40250 随身便民服务道具 1:1 纯净回归测试套件
|
|
extends SceneTree
|
|
|
|
const PortableServiceSystem = preload("res://portable_service_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_portable_service_parity (Direction 2: Portable Services 1:1) ===")
|
|
_test_portable_safebox_usage()
|
|
_test_portable_blacksmith_usage()
|
|
_test_portable_store_and_buying()
|
|
_finish()
|
|
|
|
func _test_portable_safebox_usage() -> void:
|
|
print("\n--- Test 1: Portable Safebox (70005) ---")
|
|
var pss := PortableServiceSystem.new()
|
|
var inv: Array = [
|
|
{"vnum": PortableServiceSystem.ITEM_PORTABLE_SAFEBOX, "name": "随身仓库卷轴", "count": 3}
|
|
]
|
|
|
|
var open_signal := {"fired": false, "svc": ""}
|
|
pss.service_opened.connect(func(s: String):
|
|
open_signal["fired"] = true
|
|
open_signal["svc"] = s
|
|
)
|
|
|
|
var res = pss.use_portable_safebox(0, inv)
|
|
_assert(res["ok"] == true, "Portable safebox opened")
|
|
_assert(pss.active_service == "safebox", "active_service is safebox")
|
|
_assert(inv[0]["count"] == 2, "1 scroll consumed (3 -> 2)")
|
|
_assert(open_signal["fired"] == true and open_signal["svc"] == "safebox", "service_opened signal fired")
|
|
|
|
func _test_portable_blacksmith_usage() -> void:
|
|
print("\n--- Test 2: Portable Blacksmith (70006) ---")
|
|
var pss := PortableServiceSystem.new()
|
|
var inv: Array = [
|
|
{"vnum": PortableServiceSystem.ITEM_PORTABLE_BLACKSMITH, "name": "随身铁匠手稿", "count": 1}
|
|
]
|
|
|
|
var res = pss.use_portable_blacksmith(0, inv)
|
|
_assert(res["ok"] == true, "Portable blacksmith opened")
|
|
_assert(pss.active_service == "blacksmith", "active_service is blacksmith")
|
|
_assert(inv[0] == null, "Single scroll consumed to null")
|
|
|
|
func _test_portable_store_and_buying() -> void:
|
|
print("\n--- Test 3: Portable General Store (70007) & Purchasing ---")
|
|
var pss := PortableServiceSystem.new()
|
|
var player_data := {"gold": 1000} # Less than 3200
|
|
var inv: Array = [
|
|
{"vnum": PortableServiceSystem.ITEM_PORTABLE_GENERAL_STORE, "name": "随身杂货铺契约", "count": 1},
|
|
null
|
|
]
|
|
|
|
# 1. Open store
|
|
var r_open = pss.use_portable_store(0, inv)
|
|
_assert(r_open["ok"] == true, "Portable store opened")
|
|
_assert(pss.active_service == "store", "active_service is store")
|
|
_assert(r_open["goods"].size() == 4, "Store offers 4 items")
|
|
|
|
# 2. Buy with insufficient Yang
|
|
var r_poor = pss.buy_goods_from_portable_store(0, player_data, inv)
|
|
_assert(r_poor["ok"] == false and r_poor["reason"] == "INSUFFICIENT_YANG", "Blocked with insufficient Yang")
|
|
|
|
# 3. Buy 200x Big Red Potions (price: 3200) with 10,000 Yang
|
|
player_data["gold"] = 10000
|
|
var r_buy = pss.buy_goods_from_portable_store(0, player_data, inv)
|
|
_assert(r_buy["ok"] == true, "Purchased red potions")
|
|
_assert(player_data["gold"] == 6800, "3200 Yang deducted (10000 -> 6800)")
|
|
|
|
# Notice slot 0 was emptied when using the scroll, so purchase goes to slot 0!
|
|
var purchased_slot = r_buy["slot"]
|
|
_assert(purchased_slot >= 0 and inv[purchased_slot]["vnum"] == 27003, "Red potions received into inventory")
|
|
_assert(inv[purchased_slot]["count"] == 200, "200 count received")
|
|
|
|
func _finish() -> void:
|
|
print("\n==========================================")
|
|
print("Portable Service Parity Test Results: %d Passed, %d Failed" % [_passed, _failed])
|
|
print("==========================================")
|
|
if _failed > 0:
|
|
quit(1)
|
|
else:
|
|
quit(0)
|