# skill_fx_test —— 技能特效表(skill id / 内建 id → .mse)headless 自检。 # godot --headless --path project --script skill_fx_test.gd extends SceneTree const SkillFx = preload("res://fx/skill_fx.gd") const SkillTable = preload("res://ui/skill_table.gd") # 假 EffectRegistry:记录 resolve / spawn,指定哪些名字「存在」 class FakeFxr extends RefCounted: var exists := {} # name -> true var spawned := [] func resolve(name: String) -> String: return "res://fake/%s.mse" % name if exists.get(name, false) else "" func spawn(name: String, _parent, _one := true): spawned.append(name) return null var _fail := 0 func _ck(c: bool, m: String) -> void: if not c: _fail += 1 printerr("FAIL: " + m) func _init() -> void: _run() if _fail == 0: print("PASS: skill_fx_test") quit(0) else: printerr("%d check(s) failed" % _fail) quit(1) func _run() -> void: # 用真 skilldesc.txt(有就用,没有用桩表) var st: RefCounted = SkillTable.new() var assets := AssetRoot.path() var have_real := false for lang in ["en", "common"]: if st.load_file(assets.path_join("locale/locale/%s/skilldesc.txt" % lang)): have_real = true break var fxr := FakeFxr.new() var host := Node3D.new() get_root().add_child(host) var sfx: RefCounted = SkillFx.new() sfx.setup(fxr, st) if have_real: # skill 1 = Three-Way Cut, motion_name samyeon # 后缀 = clamp(2 + master, 2, 4):m0->_2, m1->_3, m2/m3->_4 _ck(sfx.skill_effect_name(1, 0) == "samyeon_2", "skill 1 m0 -> samyeon_2") _ck(sfx.skill_effect_name(1, 1) == "samyeon_3", "skill 1 m1(M) -> samyeon_3") _ck(sfx.skill_effect_name(1, 2) == "samyeon_4", "skill 1 m2(G) -> samyeon_4") _ck(sfx.skill_effect_name(1, 9) == "samyeon_4", "master 夹到 4") # 主特效存在 + 一个子特效存在 -> 播 2 个 fxr.exists = {"samyeon_4": true, "samyeon_blow_4": true, "samyeon_hand_4": false} var n: int = sfx.spawn_skill(1, 3, host) _ck(n == 2 and fxr.spawned.has("samyeon_4") and fxr.spawned.has("samyeon_blow_4"), "spawn_skill 播主 + 存在的子特效 (%d: %s)" % [n, fxr.spawned]) # motion 查不到 -> 空 _ck(sfx.skill_effect_name(99999, 0) == "", "未知 skill -> 空名") else: print(" (skip real skilldesc checks: 无资产)") # 桩:手塞一条 st._by_id[7] = {"id": 7, "motion": "testmo", "job": "WARRIOR", "name": "T"} _ck(sfx.skill_effect_name(7, 1) == "testmo_2", "桩 skill -> testmo_2") # 内建特效:SE_AUTO_HPUP(19) -> drugup_red fxr.spawned.clear() fxr.exists = {"drugup_red": true, "drugup_blue": true} _ck(sfx.spawn_special(19, host) and fxr.spawned == ["drugup_red"], "special 19 (SE_AUTO_HPUP) -> drugup_red") _ck(sfx.spawn_special(20, host) and fxr.spawned[-1] == "drugup_blue", "special 20 (SE_AUTO_SPUP) -> drugup_blue") # 没映射的 id / 文件不存在 -> false _ck(sfx.spawn_special(255, host) == false, "未映射 special id -> false") fxr.exists = {} _ck(sfx.spawn_special(19, host) == false, "文件不存在 -> false")