extends Node
## GATE — A FACE SET DROPS A DELETED BRUSH'S FACE (#129 deferred bug; docs §14.4).
## A removed brush is a TOMBSTONE that brush_by_key / get_brush still return, so the face
## set (Alt+J, Alt+E, the cable bundle) resolved faces of deleted brushes. The edge set
## checks get_live_brush_ids (gate_edge_set E8); the face set must too.
## F1 two faces in the set: both resolve
## F2 one brush deleted: only the live one's face resolves
##
## RUN AS A SCENE: "$HYPER_TPS_GODOT" --headless res://scenes/test/gate_face_set_live.tscn
var fails := 0
var checks := 0
var map: Node3D
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
_run()
get_tree().root.get_node("/root/GameMode").set_mode("play")
if checks < 2:
print(" **FAIL** only %d checks ran -- setup died before the assertions" % checks)
fails += 1
print("\nGATE face_set_live: %s (%d checks, %d failed)" % ["PASS" if fails == 0 else "FAIL", checks, fails])
get_tree().quit(0 if fails == 0 else 1)
static func _box_planes(lo: Vector3, hi: Vector3) -> Array:
return [-1, 0, 0, -lo.x, 1, 0, 0, hi.x, 0, -1, 0, -lo.y, 0, 1, 0, hi.y, 0, 0, -1, -lo.z, 0, 0, 1, hi.z]
func _run() -> void:
var persist: Node = map.get("_persist")
var level: Node = map.get("level")
persist.begin_gesture("two")
for x: float in [700.0, 704.0]:
persist.record("brush.create", {"planes": _box_planes(Vector3(x, 0, 700), Vector3(x + 1, 1, 701)), "proj": [],
"material_id": 1, "level_id": 0, "sky": false, "clearance": false, "group": "", "face_tex": []})
persist.end_gesture()
persist.refold()
var ids: Array = []
for b: int in (level.get_live_brush_ids() as PackedInt32Array):
var c: Vector3 = (level.get_brush(b)["aabb_min"] as Vector3)
if c.z > 699.0 and c.z < 701.0:
ids.append(b)
# TYPED, as the map's: set() with an untyped Array on an Array[Dictionary] property
# silently leaves it as it was.
var faces: Array[Dictionary] = []
for b: int in ids:
var pk: PackedStringArray = level.get_brush(b).get("plane_keys", PackedStringArray())
faces.append({"b": String(level.get_brush_key(b)), "p": pk[3]}) # the top face
map.set("_sel_faces", faces)
_ok("F1 two faces in the set resolve", ids.size() == 2 and (map.call("_selected_face_polys") as Array).size() == 2,
[ids.size(), (map.call("_selected_face_polys") as Array).size()])
persist.begin_gesture("del")
persist.record("brush.remove", {"brush_key": String(faces[1]["b"])})
persist.end_gesture()
persist.refold()
map.set("_sel_faces", faces) # as a selection that outlived the delete
_ok("F2 the deleted brush's face drops out", (map.call("_selected_face_polys") as Array).size() == 1,
(map.call("_selected_face_polys") as Array).size())