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

73 lines
2.4 KiB
GDScript

extends SceneTree
const CharSelectScreen = preload("res://ui/char_select_screen.gd")
class FakeClient extends Node:
func get_slot_count() -> int: return 4
func get_empire() -> int: return 1
var _fail := 0
func _ck(c: bool, m: String) -> void:
if not c:
_fail += 1
printerr("FAIL: " + m)
func _initialize() -> void:
call_deferred("_run")
func _run() -> void:
var client := FakeClient.new()
root.add_child(client)
var assets := AssetRoot.path()
var screen := CharSelectScreen.new()
root.add_child(screen)
screen.setup(client, assets, [
{"index": 0, "name": "WarriorTest", "job": 0, "level": 50, "guild_name": "TestGuild",
"play_minutes": 120, "ht": 40, "iq": 20, "st": 50, "dx": 30, "main_part": 0, "hair_part": 0}
])
for _i in 10:
await process_frame
_ck(screen._pv != null, "PlayerView created on stage")
_ck(not screen._starting, "Screen not initially starting")
_ck(screen._pv.anim != null and String(screen._pv.anim.get("anim_path")).ends_with("intro/wait.msa"),
"Initial animation is wait.msa")
_ck(bool(screen._pv.anim.get("loop")) == true, "wait.msa is looping")
var result := {"slot": -1}
screen.select_requested.connect(func(slot: int):
print("Test received select_requested signal with slot = ", slot)
result.slot = slot
)
# 触发开始流程
screen._do_start()
_ck(screen._starting, "Screen entered _starting state")
_ck(screen._btn_start.disabled, "Start button disabled during selection")
_ck(screen._pv.anim != null and String(screen._pv.anim.get("anim_path")).ends_with("intro/selected.msa"),
"Selected animation changed to intro/selected.msa")
_ck(bool(screen._pv.anim.get("loop")) == false, "intro/selected.msa is non-looping")
# 40250 原生逻辑:选角开始时仅播放角色动作与语音,无脚底光环粒子特效
var fx_nodes: Array = screen._pivot.find_children("fx_*", "Node3D", true, false)
_ck(fx_nodes.is_empty(), "40250 parity: no extraneous ground particle halo spawned")
# 等待动作完成与 select_requested 信号触发(基于真实时间)
var t0 := Time.get_ticks_msec()
var frames := 0
while result.slot == -1 and (Time.get_ticks_msec() - t0) < 4000:
await process_frame
frames += 1
_ck(result.slot == 0, "select_requested emitted with slot 0 after animation finishes")
if _fail == 0:
print("PASS: char_select_start_motion_test (selected.msa motion + sound script + 40250 clean parity)")
quit(0)
else:
printerr("%d check(s) failed" % _fail)
quit(1)