extends SceneTree const NetPlay = preload("res://net_play.gd") class FakeClient extends Node: signal entity_main_set(vid: int) signal entity_moved(vid: int) signal points_changed(points: Dictionary) signal vitals_changed(vid: int) signal target_info(vid: int, hp_percent: int) signal entity_despawned(vid: int) signal entity_dead(vid: int) var in_game := false var target := -1 var entities := {} func is_in_game() -> bool: return in_game func get_entity(vid: int) -> Dictionary: return entities.get(vid, {}) func set_target(vid: int) -> bool: target = vid return true class FakePlayerController extends Node: signal target_selected(node: Node3D) signal moved(pos: Vector3) signal anim_state(state: String) var player: Node3D var failures := 0 func _initialize() -> void: call_deferred("run") func check(ok: bool, message: String) -> void: if not ok: failures += 1 printerr("FAIL: " + message) func run() -> void: var client := FakeClient.new() var pc := FakePlayerController.new() var nw := Node.new() root.add_child(client) root.add_child(pc) root.add_child(nw) var play := NetPlay.new() root.add_child(play) play.setup(client, pc, nw) client.entities[10] = {"vid": 10, "kind": 2, "race": 2301, "dead": false, "hp": 100, "max_hp": 100} check(not play.select_target(10), "target selection is blocked while disconnected") client.in_game = true check(play.select_target(10), "target selection uses production target path") check(client.target == 10, "target selection sends the selected VID") check(not play.select_target(999), "missing target is rejected") check(client.target == 0, "invalid target clears server target") print("playable_adapter_test: failures=%d" % failures) quit(1 if failures else 0)