62 lines
2.5 KiB
GDScript
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)
|