OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / gate_union_ops.gd

122 lines · gd ref:
extends Node
## GATE — X AND H ON A UNION SELECTION, 5b (#120 §17.10).
##   O1  X on a box + a light + a curve deletes all three in ONE gesture
##   O2  ... and one Ctrl+Z brings all three back
##   O3  X on several curves (Shift-picked) is one gesture
##   O4  A then X: a cable's curve goes WITH its cable (no "used" refusal), one gesture
##   O5  H on a box + a light + a curve hides all three; Alt+H shows them again
##
## RUN AS A SCENE: "$HYPER_TPS_GODOT" --headless res://scenes/test/gate_union_ops.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 < 8:
		print("  **FAIL** only %d checks ran -- setup died before the assertions" % checks)
		fails += 1
	print("\nGATE union_ops: %s (%d checks, %d failed)" % ["PASS" if fails == 0 else "FAIL", checks, fails])
	get_tree().quit(0 if fails == 0 else 1)


## ALL gestures, discarded ones too: gestures() drops an undone gesture once a newer one
## exists, so after an undo a new gesture would count as -1 + 1 = 0.
func _gestures() -> int:
	return (persist.gestures(true) as Array).size()


func _run() -> void:
	persist = map.get("_persist")
	var P := Vector3(400.1, 1.0, 400.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 light: String = map.create_object(PrefabCatalogue.ids()[0], Transform3D(Basis.IDENTITY, P + Vector3(3, 0, 0)))
	var c1: String = map.create_curve([CurveMath.point(P + Vector3(0, 0, 4)), CurveMath.point(P + Vector3(2.1, 0, 4))], false, "C1")
	var c2: String = map.create_curve([CurveMath.point(P + Vector3(0, 0, 6)), CurveMath.point(P + Vector3(2.1, 0, 6))], false, "C2")
	_ok("setup: a box, an object, two curves", box != "" and light != "" and c1 != "" and c2 != "")

	# ---- O1 / O2 ----
	map.select_shape(box)
	map.select_object(light, true)
	map.select_curve(c1, true)
	var g0 := _gestures()
	map.delete_selection()
	var gone: bool = not (persist.live_shapes() as Dictionary).has(box) and map.object_node(light) == null \
		and not map.curve_states().has(c1)
	_ok("O1 X deletes the box, the object and the curve", gone, [(persist.live_shapes() as Dictionary).has(box),
		map.object_node(light) != null, map.curve_states().has(c1)])
	_ok("O1 ... in ONE gesture", _gestures() == g0 + 1, _gestures() - g0)
	persist.undo_last()
	persist.refold()
	_ok("O2 one Ctrl+Z brings all three back", (persist.live_shapes() as Dictionary).has(box)
		and map.object_node(light) != null and map.curve_states().has(c1))

	# ---- O3 ----
	map.select_curve(c1)
	map.select_curve(c2, true)
	var g1 := _gestures()
	map.delete_selection()
	_ok("O3 X on two curves: both gone, one gesture", not map.curve_states().has(c1) and not map.curve_states().has(c2)
		and _gestures() == g1 + 1, _gestures() - g1)
	persist.undo_last()
	persist.refold()

	# ---- O4 ----
	var cable: String = map.add_cable([CurveMath.point(P + Vector3(0, 0, 9)), CurveMath.point(P + Vector3(3.3, 0, 9))],
		false, {"radius": 0.05})
	var cc := String(persist.shape_state(cable)["params"]["curve"])
	map.clear_selection()
	map.select_shape(cable)
	map.select_curve(cc, true)
	var g2 := _gestures()
	map.delete_selection()
	_ok("O4 a cable and its curve selected together both go", not (persist.live_shapes() as Dictionary).has(cable)
		and not map.curve_states().has(cc) and _gestures() == g2 + 1, [(persist.live_shapes() as Dictionary).has(cable),
		map.curve_states().has(cc), _gestures() - g2])
	persist.undo_last()
	persist.refold()

	# ---- O5 ----
	map.select_shape(box)
	map.select_object(light, true)
	map.select_curve(c1, true)
	map.hide_selection()
	var lvl: Node = map.get("level")
	var hidden_ids: PackedInt32Array = lvl.get_hidden_brush_ids()
	var pieces: PackedInt32Array = lvl.get_group_brush_ids(box)
	var all_hidden: bool = not pieces.is_empty() and Array(pieces).all(func(b: int) -> bool: return hidden_ids.has(b)) \
		and not (map.object_node(light) as Node3D).visible and map.is_curve_hidden(c1)
	_ok("O5 H hides the box, the object and the curve", all_hidden, [hidden_ids.size(),
		(map.object_node(light) as Node3D).visible, map.is_curve_hidden(c1)])
	map.unhide_all()
	_ok("O5 ... Alt+H shows them again", (lvl.get_hidden_brush_ids() as PackedInt32Array).is_empty()
		and (map.object_node(light) as Node3D).visible and not map.is_curve_hidden(c1))
	var panel: Node = map.get("_outliner")
	panel.model.save(String(panel.get("_save_key")))