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)