extends Node
## GATE — R ON A UNION SELECTION, 5d (#120 §17.10).
## W1 R 90 deg about Y on a box + an object + a curve turns all three about ONE pivot
## (their combined centre): each one's place turns by the same rotation
## W2 ... in ONE gesture
## W3 Esc puts all three back and writes nothing
##
## RUN AS A SCENE: "$HYPER_TPS_GODOT" --headless res://scenes/test/gate_union_rotate.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 < 5:
print(" **FAIL** only %d checks ran -- setup died before the assertions" % checks)
fails += 1
print("\nGATE union_rotate: %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()
## A box's CENTRE (frame origin is its min corner; size along the frame's axes).
func _box_c(d: String) -> Vector3:
var st: Dictionary = persist.shape_state(d)
return (st["frame"] as Transform3D) * ((st["size"] as Vector3) * 0.5)
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 _run() -> void:
persist = map.get("_persist")
var ops: Node = map.call("_ensure_ops")
var rt: Node = map.get("_rotate")
var P := Vector3(600.0, 1.0, 600.0)
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": [2, 2, 2],
"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(6, 1, 0)))
var c: String = map.create_curve([CurveMath.point(P + Vector3(1, 1, 6)), CurveMath.point(P + Vector3(3, 1, 6))], false, "W")
_ok("setup", box != "" and obj != "" and c != "")
var b0 := _box_c(box)
var o0 := _obj_at(obj)
var c0 := _curve_at(c)
# ---- W1 / W2 ----
map.select_shape(box)
map.select_object(obj, true)
map.select_curve(c, true)
var g0 := _gestures()
_ok("W1 R starts on the union", ops.activate(rt))
var pivot: Vector3 = rt.get("_pivot")
rt.set_tool_setting("angle", 90.0)
ops.confirm()
persist.refold()
var r := Basis(Vector3.UP, deg_to_rad(90.0))
var ok_b := _box_c(box).is_equal_approx(pivot + r * (b0 - pivot))
var ok_o := _obj_at(obj).is_equal_approx(pivot + r * (o0 - pivot))
var ok_c := _curve_at(c).is_equal_approx(pivot + r * (c0 - pivot))
_ok("W1 all three turned 90 deg about one pivot", ok_b and ok_o and ok_c, [ok_b, ok_o, ok_c, pivot])
_ok("W2 ... in ONE gesture", _gestures() == g0 + 1, _gestures() - g0)
# ---- W3 ----
var b1 := _box_c(box)
var o1 := _obj_at(obj)
var c1 := _curve_at(c)
map.select_shape(box)
map.select_object(obj, true)
map.select_curve(c, true)
var g1 := _gestures()
ops.activate(rt)
rt.set_tool_setting("angle", 45.0)
await get_tree().process_frame
ops.cancel()
persist.refold()
_ok("W3 Esc: all three back, nothing written", _box_c(box).is_equal_approx(b1) and _obj_at(obj).is_equal_approx(o1)
and _curve_at(c).is_equal_approx(c1) and _gestures() == g1)