extends SceneTree
## GATE — the active grid drawn on the aimed surface (#31: TrenchBroom GridRenderer).
## G1 hidden while playing; shown while building, in the Level editor
## G2 a patch of (2*RADIUS+2) lines each way, every vertex on the world lattice,
## lifted off the aimed plane along its normal
## G3 aiming inside one cell does not rebuild; the next cell, a new step or a new
## surface axis does
## G4 a wall hit lays the grid on the wall's plane (x constant)
## G5 hidden in the Bot editor
## G6 the toggle key flips the per-player pref and hides it
## Through _update_editor_grid with explicit hits (headless has no crosshair camera).
##
## Run: CI=true HYPERTPS_DAEMON_TCP=127.0.0.1:1 "$HYPER_TPS_GODOT" --headless --path . --script res://scenes/test/gate_editor_grid.gd
var ok := true
var checks := 0
var _frame := 0
var _map: Node
func _p(c: bool, m: String, got: Variant = "") -> void:
checks += 1
print(("ok " if c else "FAIL: ") + m + ("" if str(got) == "" else " (" + str(got) + ")"))
if not c:
ok = false
func _process(_d: float) -> bool:
_frame += 1
if _frame == 1:
var dock := root.get_node("/root/BuildDock")
dock.set_pref("snap", true)
dock.set_pref("grid", 5)
dock.set_pref("grid_view", true)
_map = (load("res://scenes/maps/map_flat.tscn") as PackedScene).instantiate()
root.add_child(_map)
return false
if _frame < 30:
return false
_run()
print("\n%d checks — %s" % [checks, "PASS" if ok else "FAIL"])
quit(0 if ok else 1)
return true
func _on_lattice(v: float, step: float) -> bool:
return absf(v / step - roundf(v / step)) < 1.0e-3
func _run() -> void:
var gm := root.get_node("/root/GameMode")
var dock := root.get_node("/root/BuildDock")
var lvl: Node = _map
var floor_hit := {"position": Vector3(3.3, 0.0, -2.1), "normal": Vector3.UP}
# ---- G1 ----
gm.set_mode("play")
lvl._update_editor_grid(floor_hit)
var g: EditorGrid = lvl.get("_editor_grid")
_p(g == null or not g.visible, "G1 no grid while playing")
gm.set_mode("build")
dock.set_workspace(dock.WS_LEVEL)
lvl._update_editor_grid(floor_hit)
g = lvl.get("_editor_grid")
_p(g != null and g.visible, "G1 grid shown while building in the Level editor")
if g == null:
return
# ---- G2 ----
var step: float = lvl._grid_step()
var want := 2 * (2 * EditorGrid.RADIUS + 2)
_p(g.line_count() == want, "G2 %d lines" % want, g.line_count())
var lattice := true
var lifted := true
var vs := g.verts()
for v: Vector3 in vs:
if not (_on_lattice(v.x, step) and _on_lattice(v.z, step)):
lattice = false
if absf(v.y - EditorGrid.LIFT) > 1.0e-5:
lifted = false
_p(lattice, "G2 every vertex on the world lattice (step %.4f)" % step)
_p(lifted, "G2 lifted LIFT above the plane, along the normal")
var spans_aim := false
for i in range(0, vs.size(), 2):
var a: Vector3 = vs[i]
var b: Vector3 = vs[i + 1]
if is_equal_approx(a.x, b.x) and minf(a.z, b.z) <= -2.1 and maxf(a.z, b.z) >= -2.1 \
and absf(a.x - 3.3) < step:
spans_aim = true
_p(spans_aim, "G2 the patch is around the aimed point")
# ---- G3 ----
var same_cell := floor_hit["position"] as Vector3
same_cell.x = floorf(same_cell.x / step) * step + step * 0.5
_p(not g.show_at(same_cell, Vector3.UP, step), "G3 same cell: no rebuild")
_p(g.show_at(same_cell + Vector3(step, 0, 0), Vector3.UP, step), "G3 next cell: rebuild")
_p(g.show_at(same_cell + Vector3(step, 0, 0), Vector3.UP, step * 2.0), "G3 new step: rebuild")
_p(g.show_at(same_cell + Vector3(step, 0, 0), Vector3.RIGHT, step * 2.0), "G3 new axis: rebuild")
# ---- G4 ----
lvl._update_editor_grid({"position": Vector3(7.0, 1.2, 0.4), "normal": Vector3(-1, 0.1, 0)})
var wall := true
for v: Vector3 in g.verts():
if absf(v.x - (7.0 - EditorGrid.LIFT)) > 1.0e-5:
wall = false
_p(wall and g.line_count() == want, "G4 wall hit: grid on x = 7, lifted toward the viewer")
# ---- G5 ----
dock.set_workspace(dock.WS_BOT)
lvl._update_editor_grid(floor_hit)
_p(not g.visible, "G5 hidden in the Bot editor")
dock.set_workspace(dock.WS_LEVEL)
lvl._update_editor_grid(floor_hit)
_p(g.visible, "G5 back in the Level editor: shown")
# ---- G6 ----
var e := InputEventKey.new()
var kc: int = int(root.get_node("/root/Keymap").binding_of("builder.grid_view").get("key", 0))
_p(kc == KEY_APOSTROPHE, "G6 bound to apostrophe", kc)
e.physical_keycode = kc
e.keycode = kc
e.pressed = true
_map._unhandled_key_input(e)
_p(dock.pref("grid_view", true) == false, "G6 key turns the pref off")
lvl._update_editor_grid(floor_hit)
_p(not g.visible, "G6 grid hidden with the pref off")
_map._unhandled_key_input(e)
lvl._update_editor_grid(floor_hit)
_p(dock.pref("grid_view", false) == true and g.visible, "G6 key turns it back on")
gm.set_mode("play")