# weapon_trace_multi_part_parity_test —— 40250 AttachWeapon 的多部件语义。 # # CActorInstance::AttachWeapon 会分别对 PART_WEAPON / PART_WEAPON_LEFT # 创建 CWeaponTrace;匕首(以及骑马扇)可能同时有右手与左手部件。 # 当前端不能只查找单个 Weapon 节点,否则第二条刀光会永久缺失。 extends SceneTree const PlayerView = preload("res://ui/player_view.gd") var _fail := 0 func _ck(condition: bool, message: String) -> void: if not condition: _fail += 1 printerr("FAIL: " + message) func _init() -> void: call_deferred("_run") func _run() -> void: var pv := PlayerView.new() root.add_child(pv) await process_frame # 用两个带几何体的挂点模拟 Metin2Model 的 Weapon / Shield 部件, # 不依赖 native GR2 资产即可验证 AttachWeapon 的部件枚举。 var model := Node3D.new() model.name = "Metin2Model" pv.add_child(model) var weapon := MeshInstance3D.new() weapon.name = "Weapon" var weapon_box := BoxMesh.new() weapon_box.size = Vector3(0.1, 0.1, 1.0) weapon.mesh = weapon_box model.add_child(weapon) var shield := MeshInstance3D.new() shield.name = "Shield" var shield_box := BoxMesh.new() shield_box.size = Vector3(0.1, 0.1, 1.0) shield.mesh = shield_box model.add_child(shield) pv.model = model pv._refresh_weapon_trace() var state: Dictionary = pv.weapon_trace_state() _ck(int(state.get("count", 0)) == 2, "Weapon and Shield parts each create a WeaponTrace") pv.set_weapon_trace_enabled(false) await process_frame _ck(int(pv.weapon_trace_state().get("count", 0)) == 0, "disabling traces destroys every weapon-part trace") if _fail == 0: print("PASS: weapon_trace_multi_part_parity_test (Weapon + Shield traces)") quit(0) else: printerr("%d check(s) failed" % _fail) quit(1)