OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / gate_curve_g_mode.gd

104 lines · gd ref:
extends Node
## GATE — G ON A SELECTED CURVE, BY SELECT MODE (#120 §17.7 Q4, §17.8 step 1).
##   C1  switching select mode keeps a selected curve (a curve is a whole object; only an
##       element selection is cleared, being a set of planes)
##   C2  vertex mode (1): G starts Edit curve on the point nearest the pointer
##   C3  ... the point is the one aimed at, not the first
##   C4  brush mode (4): G moves the whole curve (§16 step 4b)
##   C5  with no curve selected, vertex-mode G is not Edit curve
##
## RUN AS A SCENE: "$HYPER_TPS_GODOT" --headless res://scenes/test/gate_curve_g_mode.tscn

var fails := 0
var checks := 0
var map: Node3D
var cam: Camera3D


func _ok(what: String, cond: bool, note: Variant = "") -> void:
	checks += 1
	if not cond:
		fails += 1
	print("  %-64s %s  %s" % [what, "OK" if cond else "**FAIL**", str(note)])


func _ready() -> void:
	var gs: Node = get_tree().root.get_node_or_null("/root/GameState")
	gs.route("world:level:*", 1, "peer")
	var keet: Node = get_tree().root.get_node_or_null("/root/KeetService")
	if keet != null:
		keet.current_member_id = "gate-author"
	get_tree().root.get_node("/root/GameMode").set_mode("build")
	map = (load("res://scenes/maps/map_dev_test.tscn") as PackedScene).instantiate()
	add_child(map)
	cam = Camera3D.new()
	add_child(cam)
	cam.current = true
	for i in 6:
		await get_tree().process_frame
	await _run()
	get_tree().root.get_node("/root/GameMode").set_mode("play")
	if checks < 6:
		print("  **FAIL** only %d checks ran -- setup died before the assertions" % checks)
		fails += 1
	print("\nGATE curve_g_mode: %s (%d checks, %d failed)" % ["PASS" if fails == 0 else "FAIL", checks, fails])
	get_tree().quit(0 if fails == 0 else 1)


func _aim_at(at: Vector3) -> void:
	cam.global_position = at + Vector3(0.01, 4.0, 0.01)
	cam.look_at(at, Vector3.UP)
	await get_tree().process_frame
	map.set("_wrap_offset", get_viewport().get_visible_rect().size * 0.5 - get_viewport().get_mouse_position())


func _g() -> void:
	var ev := InputEventAction.new()
	ev.action = "builder.move"
	ev.pressed = true
	map._unhandled_input(ev)
	await get_tree().process_frame


func _run() -> void:
	var ops: Node = map.call("_ensure_ops")
	var O0 := Vector3(150.137, 1.31, 149.873)
	var c: String = map.create_curve([CurveMath.point(O0), CurveMath.point(O0 + Vector3(4.1, 0, 0)),
		CurveMath.point(O0 + Vector3(4.1, 0, 3.3))], false, "G mode")
	_ok("setup: a curve", map.curve_states().has(c))

	# ---- C1 ----
	map.select_curve(c)
	map.set_select_mode("vertex")
	_ok("C1 switching to vertex mode keeps the selected curve", map.selected_curve() == c, map.selected_curve())

	# ---- C2 / C3 ----
	var p2: Vector3 = (map.curve_states()[c]["points"] as Array)[2]["p"]
	await _aim_at(p2)
	await _g()
	var ce: Node = map.get("_curve_edit")
	_ok("C2 vertex mode: G starts Edit curve", ops.get("active") == ce, ops.get("active"))
	_ok("C3 ... on the point aimed at (3 of 3)", ops.get("active") == ce and String(ce.status()).contains("point: 3 of 3"),
		ce.status() if ops.get("active") == ce else "")
	ops.cancel()
	await get_tree().process_frame

	# ---- C4 ----
	map.set_select_mode("brush")
	map.select_curve(c)
	await _g()
	var mv: Node = map.get("_move")
	_ok("C4 brush mode: G moves the whole curve", ops.get("active") == mv and String(mv.get("_curve")) == c,
		[ops.get("active"), mv.get("_curve") if ops.get("active") == mv else ""])
	ops.cancel()
	await get_tree().process_frame

	# ---- C5 ----
	map.set_select_mode("vertex")
	map.clear_selection()
	await _g()
	_ok("C5 no curve selected: vertex-mode G is not Edit curve", ops.get("active") != ce, ops.get("active"))
	if ops.get("active") != null:
		ops.cancel()
	map.set_select_mode("brush")