OverviewFilesCommitsIssuesDocsReleasesPeers

hyper-tps / scenes / test / gate_view3d_rect.gd

112 lines · gd ref:
extends SceneTree
## GATE — the 3D view is the free rectangle R for the POINTER (hyper-games #124, B2 as cut
## by the user 2026-10-18: "lets skip the recentering work for now" — the image is not
## re-centred in R; only hover and the tool wrap respect it).
##   V1  hover: the pointer over a PANEL highlights nothing behind it
##   V2  ... inside R it aims what is under it
##   V3  a pointer-following tool (G) wraps at R's edge, not the window's
##
## RUN: CI=true HYPERTPS_DAEMON_TCP=127.0.0.1:1 "$GODOT" --headless --path . --script res://scenes/test/gate_view3d_rect.gd

var _frame := 0
var _map: Node = null
var _dock: Node = null
var _cam: Camera3D = null
var _brush := -1
var _step := 0
var fails := 0
var checks := 0
var _warped := Vector2(-1, -1)


func _p(c: bool, m: String, got: Variant = "") -> void:
	checks += 1
	if not c:
		fails += 1
	print("  %-68s %s  %s" % [m, "OK" if c else "**FAIL**", str(got)])


func _box(lo: Vector3, hi: Vector3) -> Array:
	return [1, 0, 0, hi.x, -1, 0, 0, -lo.x, 0, 1, 0, hi.y, 0, -1, 0, -lo.y, 0, 0, 1, hi.z, 0, 0, -1, -lo.z]


func _r() -> Rect2:
	return _dock.view_rect()


## Put the map's pointer at `at`. A headless viewport keeps its mouse at (0, 0) whatever
## is pushed, so — as gate_curve_tool does — the map's wrap offset carries it there: the
## map's pointer is mouse + _wrap_offset everywhere it aims.
func _point(at: Vector2) -> void:
	_map.set("_wrap_offset", at - root.get_mouse_position())


func _aimed() -> int:
	var bv: Node = _map.get("_brush_view")
	if bv == null or bv.get("_aimed_id") == null:
		return -99
	return int(bv.get("_aimed_id"))


func _process(_d: float) -> bool:
	_frame += 1
	if _frame == 1:
		root.size = Vector2i(1920, 1080)
		var keet: Node = root.get_node_or_null("/root/KeetService")
		if keet != null:
			keet.current_member_id = "gate-author"
		var gs: Node = root.get_node_or_null("/root/GameState")
		if gs != null:
			gs.route("world:level:*", 1, "peer")
		root.get_node("/root/GameMode").set_mode("build")
		_map = (load("res://scenes/maps/map_flat.tscn") as PackedScene).instantiate()
		root.add_child(_map)
		_dock = root.get_node("/root/BuildDock")
		_cam = Camera3D.new()
		root.add_child(_cam)
		_cam.current = true
		_cam.fov = 70.0
		_cam.global_transform = Transform3D(Basis.IDENTITY, Vector3(0, 3, 30))   # looking down -Z
		return false
	if _frame < 40 or _frame % 5 != 0:
		return false
	match _step:
		0:
			# A wall filling the whole window in front of the camera: behind every panel
			# too, so a pointer over a panel is over the wall.
			var persist: Node = _map.get("_persist")
			var dot: String = persist.record("brush.create", {"planes": _box(Vector3(-200, -50, -1), Vector3(200, 100, 0)),
				"proj": [], "material_id": 0, "level_id": 0, "sky": false})
			persist.refold()
			_brush = _map.get("level").brush_by_key(dot)
			_point((_dock._sides["left"]["frame"] as Control).get_global_rect().get_center())
		1:
			_p(_aimed() == -1, "V1 hover over a panel highlights nothing behind it", _aimed())
			_point(_r().get_center())
		2:
			_p(_aimed() == _brush, "V2 ... inside R it aims the wall", [_aimed(), _brush])
			_map.select_brushes(PackedInt32Array([_brush]))
			var g := InputEventKey.new()
			g.keycode = KEY_G
			g.physical_keycode = KEY_G
			g.pressed = true
			_map._unhandled_key_input(g)
			_map.set("pointer_warp", func(p: Vector2) -> void: _warped = p)
			var at := Vector2(_r().position.x + 1.0, _r().get_center().y)
			_map.call("_update_pointer_wrap_at", at)
			_map.call("_update_pointer_wrap_at", at)
		3:
			var r := _r()
			_p(_warped.x > r.get_center().x and _warped.x < r.end.x,
				"V3 G: the pointer at R's left edge wraps to R's right side (not the window's)", [_warped, r])
			(_map.call("_ensure_ops") as Node).call("cancel")
		_:
			if checks < 3:
				print("  **FAIL** only %d checks ran -- setup died before the assertions" % checks)
				fails += 1
			print("\nGATE view3d_rect: %s (%d checks, %d failed)" % ["PASS" if fails == 0 else "FAIL", checks, fails])
			quit(0 if fails == 0 else 1)
			return true
	_step += 1
	return false