OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / gate_union_move.gd

136 lines · gd ref:
extends Node
## GATE — G AND SHIFT+D ON A UNION SELECTION, 5c (#120 §17.10).
##   V1  G on a box + an object + a curve moves all three by the same delta, ONE gesture
##   V2  Esc puts all three back and writes nothing
##   V3  Shift+D copies all three in ONE gesture; the copies are selected and Move is up
##   V4  ... confirming that Move moves the copies; the originals stay
##
## RUN AS A SCENE: "$HYPER_TPS_GODOT" --headless res://scenes/test/gate_union_move.tscn

var fails := 0
var checks := 0
var map: Node3D
var persist: Node


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)
	for i in 6:
		await get_tree().process_frame
	await _run()
	get_tree().root.get_node("/root/GameMode").set_mode("play")
	if checks < 9:
		print("  **FAIL** only %d checks ran -- setup died before the assertions" % checks)
		fails += 1
	print("\nGATE union_move: %s (%d checks, %d failed)" % ["PASS" if fails == 0 else "FAIL", checks, fails])
	get_tree().quit(0 if fails == 0 else 1)


func _gestures() -> int:
	return (persist.gestures(true) as Array).size()


func _box_at(d: String) -> Vector3:
	return (persist.shape_state(d)["frame"] as Transform3D).origin


func _obj_at(d: String) -> Vector3:
	return (map.object_node(d) as Node3D).global_position


func _curve_at(d: String) -> Vector3:
	return (map.curve_states()[d]["points"] as Array)[0]["p"]


func _select_three(box: String, obj: String, c: String) -> void:
	map.select_shape(box)
	map.select_object(obj, true)
	map.select_curve(c, true)


func _run() -> void:
	persist = map.get("_persist")
	var ops: Node = map.call("_ensure_ops")
	var mv: Node = map.get("_move")
	var P := Vector3(500.1, 1.0, 500.3)
	persist.begin_gesture("box")
	var box: String = persist.record("shape.create", {"type": "box", "gv": 1, "params": {},
		"frame": SceneObjects.xform_to(Transform3D(Basis.IDENTITY, P)), "size": [1, 1, 1],
		"material_id": 2, "level_id": 0})
	persist.end_gesture()
	persist.refold()
	var obj: String = map.create_object(PrefabCatalogue.ids()[0], Transform3D(Basis.IDENTITY, P + Vector3(3, 0, 0)))
	var c: String = map.create_curve([CurveMath.point(P + Vector3(0, 0, 4)), CurveMath.point(P + Vector3(2.1, 0, 4))], false, "V")
	_ok("setup", box != "" and obj != "" and c != "")
	var b0 := _box_at(box)
	var o0 := _obj_at(obj)
	var c0 := _curve_at(c)

	# ---- V1 ----
	_select_three(box, obj, c)
	var g0 := _gestures()
	_ok("V1 G starts on the union", ops.activate(mv))
	mv.set_tool_setting("axis", 0)
	mv.set_tool_setting("distance", 4)
	ops.confirm()
	persist.refold()
	var db := _box_at(box) - b0
	var do := _obj_at(obj) - o0
	var dc := _curve_at(c) - c0
	_ok("V1 all three moved by the same +x", db.x > 0.0 and db.is_equal_approx(do) and db.is_equal_approx(dc), [db, do, dc])
	_ok("V1 ... in ONE gesture", _gestures() == g0 + 1, _gestures() - g0)

	# ---- V2 ----
	var b1 := _box_at(box)
	var o1 := _obj_at(obj)
	var c1 := _curve_at(c)
	_select_three(box, obj, c)
	var g1 := _gestures()
	ops.activate(mv)
	mv.set_tool_setting("distance", 3)
	await get_tree().process_frame
	ops.cancel()
	persist.refold()
	_ok("V2 Esc: all three back, nothing written", _box_at(box).is_equal_approx(b1) and _obj_at(obj).is_equal_approx(o1)
		and _curve_at(c).is_equal_approx(c1) and _gestures() == g1)

	# ---- V3 / V4 ----
	_select_three(box, obj, c)
	var shapes0: Array = (persist.live_shapes() as Dictionary).keys()
	var curves0: Array = map.curve_states().keys()
	var objs0: Array = (map.get_node("SceneObjects").entries() as Array).map(func(e: Dictionary) -> String: return String(e["dot"]))
	var g2 := _gestures()
	map.duplicate_selection()
	var new_shapes: Array = (persist.live_shapes() as Dictionary).keys().filter(func(d: String) -> bool: return not shapes0.has(d))
	var new_curves: Array = map.curve_states().keys().filter(func(d: String) -> bool: return not curves0.has(d))
	var new_objs: Array = (map.get_node("SceneObjects").entries() as Array).map(func(e: Dictionary) -> String: return String(e["dot"])) \
		.filter(func(d: String) -> bool: return not objs0.has(d))
	_ok("V3 Shift+D copies all three", new_shapes.size() == 1 and new_curves.size() == 1 and new_objs.size() == 1,
		[new_shapes, new_curves, new_objs])
	_ok("V3 ... in ONE gesture", _gestures() == g2 + 1, _gestures() - g2)
	_ok("V3 ... the copies are selected and Move is up", ops.get("active") == mv and map.selected_objects() == new_objs
		and map.selected_curves() == new_curves and new_shapes.size() == 1 and map.selected_shape() == String(new_shapes[0]),
		[ops.get("active"), map.selected_objects(), map.selected_curves()])
	if new_shapes.size() == 1 and new_curves.size() == 1 and new_objs.size() == 1:
		mv.set_tool_setting("axis", 2)
		mv.set_tool_setting("distance", 5)
		ops.confirm()
		persist.refold()
		_ok("V4 the copies moved, the originals stayed", _box_at(String(new_shapes[0])).z > _box_at(box).z + 0.5
			and _obj_at(String(new_objs[0])).z > _obj_at(obj).z + 0.5 and _curve_at(String(new_curves[0])).z > _curve_at(c).z + 0.5
			and _box_at(box).is_equal_approx(b1))