Files
mtgodot-poc/project/target_effect_test.gd
T

62 lines
2.5 KiB
GDScript

extends SceneTree
const Anchor = preload("res://fx/target_effect_anchor.gd")
const GameScene = preload("res://game_scene.gd")
class Client extends Node:
func get_main_vid() -> int: return 1
class World extends Node:
var target: Node3D
func node_for(_vid: int) -> Node3D: return target
class Registry extends RefCounted:
var seen: Array = []
func spawn_target(event: Dictionary, target: Node3D, _world: Node3D): seen.append([event, target])
var failures := 0
func check(ok: bool, label: String) -> void:
if not ok:
failures += 1
printerr("FAIL: " + label)
func _init() -> void:
call_deferred("run")
func run() -> void:
var target := Node3D.new()
root.add_child(target)
target.position = Vector3(8, 2, -5)
target.rotation.y = PI * 0.5
var effect := Node3D.new()
root.add_child(effect)
var anchor := Anchor.new()
effect.add_child(anchor)
check(anchor.configure(target, Vector3(100, 0, 100), true), "following target configured")
check(effect.global_position.distance_to(target.to_global(Vector3(1, 1, 0))) < 0.00001, "source Z-up/cm and target rotation")
target.position.x += 3
anchor._process(0)
check(effect.global_position.distance_to(target.to_global(Vector3(1, 1, 0))) < 0.00001, "follows target movement")
anchor.configure(target, Vector3(100, 0, 100), false)
check(effect.global_position.distance_to(target.global_position + Vector3(1, 1, 0)) < 0.00001, "snapshot offset is world-aligned")
var position := effect.global_position
target.position.x += 2
await process_frame
check(effect.global_position == position, "snapshot does not follow")
var game := GameScene.new()
root.add_child(game)
game.client = Client.new()
game.add_child(game.client)
var world := World.new()
game.add_child(world)
world.target = target
game.net_world = world
var registry := Registry.new()
game.fx = registry
game._on_skill_cast_started(1, 2)
world.target = null # selected target later changes, original cast remains.
game._on_local_motion_event_detailed({"type": 10, "effect": "full/path.mse", "sound": "", "pos": Vector3.ZERO})
check(registry.seen.size() == 1 and registry.seen[0][1] == target, "event keeps cast-time target and full path")
check(registry.seen[0][0].effect == "full/path.mse", "path not reduced to basename")
target.free()
game._on_local_motion_event_detailed({"type": 10, "effect": "full/path.mse", "sound": "", "pos": Vector3.ZERO})
check(registry.seen.size() == 1, "despawned target not replaced by caster")
game.free()
effect.free()
await process_frame
print("target_effect_test: failures=%d" % failures)
quit(1 if failures else 0)