- 桥梁与静态物体高度采样修复: - 严格对齐 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 客户端对拍缺陷发现与修复工程指南
145 lines
5.3 KiB
GDScript
145 lines
5.3 KiB
GDScript
# test_mining_refinery_smelt_parity.gd —— 40250 矿石采掘熔炼与首饰宝石镶嵌 1:1 回归测试套件
|
|
extends SceneTree
|
|
|
|
const MiningRefinerySmeltSystem = preload("res://mining_refinery_smelt_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_mining_refinery_smelt_parity (Direction 1: Mining Refinery & Smelt 1:1) ===")
|
|
_test_smelt_ore_success()
|
|
_test_smelt_validations()
|
|
_test_open_jewelry_sockets()
|
|
_test_embed_gems()
|
|
_finish()
|
|
|
|
func _test_smelt_ore_success() -> void:
|
|
print("\n--- Test 1: Smelting Ore into Refined Gems ---")
|
|
var sys := MiningRefinerySmeltSystem.new()
|
|
var player := {"gold": 50000}
|
|
var inv: Array = [
|
|
{"vnum": 50621, "name": "钻石原石", "count": 100},
|
|
{"vnum": 28030, "name": "战士灵石+0", "count": 1}
|
|
]
|
|
|
|
var smelt_sig := {"fired": false, "succ": false, "gem": 0}
|
|
sys.ore_smelted.connect(func(succ: bool, gvnum: int, _gn: String):
|
|
smelt_sig["fired"] = true
|
|
smelt_sig["succ"] = succ
|
|
smelt_sig["gem"] = gvnum
|
|
)
|
|
|
|
# Smelt Diamond Ore (force_success = true)
|
|
var res = sys.smelt_ore(0, 1, inv, player, false, true)
|
|
_assert(res["ok"] == true and res["success"] == true, "Smelt succeeded")
|
|
_assert(res["gem_vnum"] == 50634, "Produced Diamond Gem (50634)")
|
|
_assert(player["gold"] == 40000, "10,000 gold deducted (50000 -> 40000)")
|
|
_assert(smelt_sig["fired"] == true and smelt_sig["gem"] == 50634, "ore_smelted signal emitted")
|
|
|
|
var has_gem := false
|
|
for it in inv:
|
|
if it != null and it.get("vnum", 0) == 50634:
|
|
has_gem = true
|
|
break
|
|
_assert(has_gem, "Diamond Gem found in inventory")
|
|
|
|
func _test_smelt_validations() -> void:
|
|
print("\n--- Test 2: Smelting Input Validations ---")
|
|
var sys := MiningRefinerySmeltSystem.new()
|
|
var player := {"gold": 5000} # Less than 10,000
|
|
var inv: Array = [
|
|
{"vnum": 50623, "name": "乌木原石", "count": 50}, # Less than 100
|
|
{"vnum": 28030, "count": 1}
|
|
]
|
|
|
|
# Fail on not enough ore
|
|
var fail_ore = sys.smelt_ore(0, 1, inv, player)
|
|
_assert(fail_ore["ok"] == false and fail_ore["reason"] == "NOT_ENOUGH_ORE", "Rejected: ore count < 100")
|
|
|
|
# Fail on not enough gold
|
|
inv[0]["count"] = 100
|
|
var fail_gold = sys.smelt_ore(0, 1, inv, player)
|
|
_assert(fail_gold["ok"] == false and fail_gold["reason"] == "NOT_ENOUGH_GOLD", "Rejected: gold < 10000")
|
|
|
|
func _test_open_jewelry_sockets() -> void:
|
|
print("\n--- Test 3: Opening Jewelry Sockets with Diamond (50634) ---")
|
|
var sys := MiningRefinerySmeltSystem.new()
|
|
var inv: Array = [
|
|
{"vnum": 50634, "name": "纯净钻石", "count": 5},
|
|
{"vnum": 14009, "name": "白金手镯+9", "jewelry_sockets": []}
|
|
]
|
|
|
|
var sock_sig := {"fired": false, "idx": 0}
|
|
sys.jewelry_socket_opened.connect(func(_slot: int, idx: int):
|
|
sock_sig["fired"] = true
|
|
sock_sig["idx"] = idx
|
|
)
|
|
|
|
# Open 1st socket (100% success)
|
|
var s1 = sys.open_jewelry_socket(0, 1, inv, true)
|
|
_assert(s1["ok"] == true and s1["success"] == true, "1st socket opened")
|
|
_assert(inv[1]["jewelry_sockets"].size() == 1, "Bracelet has 1 socket")
|
|
_assert(sock_sig["fired"] == true and sock_sig["idx"] == 1, "jewelry_socket_opened emitted")
|
|
|
|
# Open 2nd and 3rd sockets
|
|
sys.open_jewelry_socket(0, 1, inv, true)
|
|
sys.open_jewelry_socket(0, 1, inv, true)
|
|
_assert(inv[1]["jewelry_sockets"].size() == 3, "Bracelet has 3 sockets (Max)")
|
|
_assert(inv[0]["count"] == 2, "3 diamonds consumed (5 -> 2)")
|
|
|
|
# 4th socket attempt must be rejected
|
|
var fail_4th = sys.open_jewelry_socket(0, 1, inv, true)
|
|
_assert(fail_4th["ok"] == false and fail_4th["reason"] == "MAX_SOCKETS_REACHED", "Max 3 sockets enforced")
|
|
|
|
func _test_embed_gems() -> void:
|
|
print("\n--- Test 4: Embedding Refined Gems into Sockets ---")
|
|
var sys := MiningRefinerySmeltSystem.new()
|
|
var inv: Array = [
|
|
{"vnum": 50641, "name": "白金精炼石", "count": 3},
|
|
{"vnum": 14009, "name": "白金手镯+9", "jewelry_sockets": [null, null]} # 2 open sockets
|
|
]
|
|
|
|
var embed_sig := {"fired": false, "name": ""}
|
|
sys.gem_embedded.connect(func(_slot: int, gname: String, _b: float):
|
|
embed_sig["fired"] = true
|
|
embed_sig["name"] = gname
|
|
)
|
|
|
|
# Embed into socket 0
|
|
var em1 = sys.embed_gem_into_socket(0, 1, inv)
|
|
_assert(em1["ok"] == true, "1st gem embedded")
|
|
_assert(inv[1]["jewelry_sockets"][0] != null, "Socket 0 occupied")
|
|
_assert(inv[1]["jewelry_sockets"][0]["vnum"] == 50641, "Socket 0 has White Gold Gem")
|
|
_assert(embed_sig["fired"] == true and embed_sig["name"] == "白金精炼石", "gem_embedded signal fired")
|
|
|
|
# Embed into socket 1
|
|
var em2 = sys.embed_gem_into_socket(0, 1, inv)
|
|
_assert(em2["ok"] == true, "2nd gem embedded")
|
|
_assert(inv[1]["jewelry_sockets"][1] != null, "Socket 1 occupied")
|
|
_assert(inv[0]["count"] == 1, "Gem count decreased 3 -> 1")
|
|
|
|
# 3rd embed when all sockets occupied must fail
|
|
var fail_em = sys.embed_gem_into_socket(0, 1, inv)
|
|
_assert(fail_em["ok"] == false and fail_em["reason"] == "ALL_SOCKETS_OCCUPIED", "Rejected when sockets are full")
|
|
|
|
func _finish() -> void:
|
|
print("\n==========================================")
|
|
print("Mining Refinery Smelt 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 Mining Refinery Smelt parity tests passed!")
|
|
quit(0)
|