- 桥梁与静态物体高度采样修复: - 严格对齐 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 客户端对拍缺陷发现与修复工程指南
144 lines
5.3 KiB
GDScript
144 lines
5.3 KiB
GDScript
# test_event_manager_parity.gd —— 40250 全服掉落活动与倍率调度器 1:1 纯净回归测试套件
|
|
extends SceneTree
|
|
|
|
const EventManagerSystem = preload("res://event_manager_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_event_manager_parity (Direction 4: Solo Event Manager 1:1) ===")
|
|
_test_rate_adjustments()
|
|
_test_event_toggling()
|
|
_test_event_drop_chances()
|
|
_test_box_opening()
|
|
_finish()
|
|
|
|
func _test_rate_adjustments() -> void:
|
|
print("\n--- Test 1: Rate Adjustments (EXP, Drop, Yang) ---")
|
|
var ems := EventManagerSystem.new()
|
|
|
|
# Invalid multipliers
|
|
var r_bad1 = ems.set_rate("exp", 0.5)
|
|
_assert(r_bad1["ok"] == false and r_bad1["reason"] == "INVALID_MULTIPLIER", "< 1.0 multiplier rejected")
|
|
|
|
var r_bad2 = ems.set_rate("exp", 10.0)
|
|
_assert(r_bad2["ok"] == false and r_bad2["reason"] == "INVALID_MULTIPLIER", "> 5.0 multiplier rejected")
|
|
|
|
var rate_signal := {"fired": false, "type": "", "mult": 0.0}
|
|
ems.rate_changed.connect(func(t: String, m: float):
|
|
rate_signal["fired"] = true
|
|
rate_signal["type"] = t
|
|
rate_signal["mult"] = m
|
|
)
|
|
|
|
# 1. EXP Rate 2.0x
|
|
var r_exp = ems.set_rate("exp", 2.0)
|
|
_assert(r_exp["ok"] == true, "EXP rate set to 2.0x")
|
|
_assert(ems.calculate_exp(1000) == 2000, "1000 base EXP doubled to 2000")
|
|
_assert(rate_signal["fired"] == true and rate_signal["type"] == "exp", "rate_changed signal fired")
|
|
|
|
# 2. Gold Rate 3.0x
|
|
var r_gold = ems.set_rate("gold", 3.0)
|
|
_assert(r_gold["ok"] == true, "Gold rate set to 3.0x")
|
|
_assert(ems.calculate_gold(500) == 1500, "500 base Gold tripled to 1500")
|
|
|
|
# 3. Drop Rate 1.5x
|
|
var r_drop = ems.set_rate("drop", 1.5)
|
|
_assert(r_drop["ok"] == true, "Drop rate set to 1.5x")
|
|
_assert(ems.drop_rate == 1.5, "drop_rate is 1.5")
|
|
|
|
func _test_event_toggling() -> void:
|
|
print("\n--- Test 2: Event Toggling (Moonlight & Hexagonal) ---")
|
|
var ems := EventManagerSystem.new()
|
|
|
|
var ev_signal := {"fired": false, "name": "", "active": false}
|
|
ems.event_state_changed.connect(func(n: String, act: bool):
|
|
ev_signal["fired"] = true
|
|
ev_signal["name"] = n
|
|
ev_signal["active"] = act
|
|
)
|
|
|
|
# Invalid event
|
|
var r_bad = ems.toggle_event("christmas", true)
|
|
_assert(r_bad["ok"] == false and r_bad["reason"] == "INVALID_EVENT_NAME", "Invalid event name rejected")
|
|
|
|
# Toggle Moonlight event ON
|
|
var r1 = ems.toggle_event("moonlight", true)
|
|
_assert(r1["ok"] == true and ems.is_moonlight_active == true, "Moonlight event enabled")
|
|
_assert(ev_signal["fired"] == true and ev_signal["name"] == "moonlight" and ev_signal["active"] == true, "event_state_changed signal fired")
|
|
|
|
# Toggle Hexagonal event ON
|
|
var r2 = ems.toggle_event("hexagonal", true)
|
|
_assert(r2["ok"] == true and ems.is_hexagonal_active == true, "Hexagonal event enabled")
|
|
|
|
# Toggle Moonlight event OFF
|
|
ems.toggle_event("moonlight", false)
|
|
_assert(ems.is_moonlight_active == false, "Moonlight event disabled")
|
|
|
|
func _test_event_drop_chances() -> void:
|
|
print("\n--- Test 3: Event Box Drops on Mob Kills ---")
|
|
var ems := EventManagerSystem.new()
|
|
ems.toggle_event("moonlight", true)
|
|
ems.toggle_event("hexagonal", true)
|
|
|
|
var drop_signal := {"fired": false, "vnum": 0}
|
|
ems.event_box_dropped.connect(func(v: int, _n: String):
|
|
drop_signal["fired"] = true
|
|
drop_signal["vnum"] = v
|
|
)
|
|
|
|
# 1. Level difference > 15 (Mob Lv 10 vs Player Lv 50) -> No drop
|
|
var drops_far = ems.check_event_drops(10, 50, 0.01)
|
|
_assert(drops_far.is_empty(), "Level diff > 15 drops nothing")
|
|
|
|
# 2. Level difference <= 15 with winning rolls
|
|
# Moonlight chance = 10% (0.10). Forced roll = 0.05 -> drops 50011
|
|
# Hexagonal chance = 15% (0.15). Forced roll = 0.05 -> drops 50037
|
|
var drops = ems.check_event_drops(50, 52, 0.05)
|
|
_assert(drops.size() == 2, "Both Moonlight and Hexagonal boxes dropped on winning roll")
|
|
_assert(drops[0]["vnum"] == EventManagerSystem.ITEM_MOONLIGHT_BOX, "Moonlight Box (50011) dropped")
|
|
_assert(drops[1]["vnum"] == EventManagerSystem.ITEM_HEXAGONAL_BOX, "Hexagonal Box (50037) dropped")
|
|
_assert(drop_signal["fired"] == true, "event_box_dropped signal fired")
|
|
|
|
# 3. Losing roll (e.g. 0.80) -> No drop
|
|
var drops_fail = ems.check_event_drops(50, 52, 0.80)
|
|
_assert(drops_fail.is_empty(), "Losing roll drops nothing")
|
|
|
|
func _test_box_opening() -> void:
|
|
print("\n--- Test 4: Event Box Opening (50011 Loot Pool) ---")
|
|
var ems := EventManagerSystem.new()
|
|
var inv: Array = [
|
|
{"vnum": EventManagerSystem.ITEM_MOONLIGHT_BOX, "name": "月光宝盒", "count": 1},
|
|
null
|
|
]
|
|
|
|
# Open Moonlight Box at slot 0
|
|
var res = ems.open_event_box(0, inv)
|
|
_assert(res["ok"] == true, "Moonlight box opened successfully")
|
|
|
|
var reward = res["reward"]
|
|
_assert(reward.has("vnum") and reward.has("name"), "Valid reward drawn from pool")
|
|
print(" Drew Moonlight Box reward: %s (vnum: %d)" % [reward["name"], reward["vnum"]])
|
|
|
|
var stored_slot = res["stored_slot"]
|
|
_assert(stored_slot >= 0 and inv[stored_slot] != null, "Reward saved in inventory")
|
|
_assert(inv[stored_slot]["vnum"] == reward["vnum"], "Inventory item matches reward")
|
|
|
|
func _finish() -> void:
|
|
print("\n==========================================")
|
|
print("Event Manager Parity Test Results: %d Passed, %d Failed" % [_passed, _failed])
|
|
print("==========================================")
|
|
if _failed > 0:
|
|
quit(1)
|
|
else:
|
|
quit(0)
|