extends SceneTree ## Beweis-Probe (Karte t_5e3e97c9, WEGWERF — nicht Teil der Suite): ## U5 Platzieren: Bildfolge VORHER (Ghost in der Hand) → GESETZT (Marker da, ## Werkzeug aus) → AUSGEWÄHLT (Auswahl-Markierung + Inspektor-Tab sichtbar). ## Der Platzier-Pfad ist der ECHTE: interaction._place_object (gleicher Pfad ## wie ein Linksklick, Karten-Regel: kein simuliertes Umfeld). ## Aufruf: xvfb-run -a godot4 --path . --rendering-driver opengl3 \ ## -s res://tests/probe_u5_place_once_render.gd func _initialize() -> void: _run.call_deferred() func _shot(pfad: String) -> void: await process_frame await RenderingServer.frame_post_draw var img := root.get_viewport().get_texture().get_image() img.save_png(pfad) print("Bild: %s (%dx%d)" % [pfad, img.get_width(), img.get_height()]) ## Rechts-Tabs: den Tab mit „Inspektor“ nach vorn holen (Fallback „Baum“), ## damit die Auswahl im Beweis-Bild sichtbar wird. func _show_selection_tab(main: Node) -> String: var stack: Array = [main] while not stack.is_empty(): var n: Node = stack.pop_back() if n is TabContainer: var tabs := n as TabContainer for i in tabs.get_tab_count(): var titel := tabs.get_tab_title(i) if titel.contains("Auswahl") or titel.contains("Baum"): tabs.current_tab = i return titel stack.append_array(n.get_children()) return "" ## „Modelle fehlen“-AcceptDialog schließen (kommt erst nach 2 Frames von ## utils/modelle_status.gd — mehrfach probieren, mit Wartezeit dazwischen). func _dismiss_dialogs() -> void: for i in 6: await process_frame var stack: Array = [root] while not stack.is_empty(): var n: Node = stack.pop_back() if n is AcceptDialog: (n as AcceptDialog).hide() n.queue_free() stack.append_array(n.get_children()) func _run() -> void: var scene: PackedScene = load("res://core/scenes/main.tscn") var main = scene.instantiate() root.add_child(main) await process_frame await process_frame # „Modelle fehlen“-Hinweis schließen (Beweis-Bilder sollen die Karte zeigen). await _dismiss_dialogs() DisplayServer.window_set_mode(DisplayServer.WINDOW_MODE_WINDOWED) DisplayServer.window_set_size(Vector2i(2328, 1310)) await process_frame DisplayServer.window_set_size(Vector2i(2328, 1310)) var interaction = main.get("interaction") var oid := "" var lib: Dictionary = main.manifest.get("objects", {}) for key in lib: oid = str(key) break if oid == "": print("PROBE_U5_FAIL: kein Manifest-Objekt") quit(1) return main.call("_set_tool_mode", "objects") interaction.call("start_placement", oid) await process_frame await process_frame var cam = main.get("camera") if cam != null: cam.set("distance", 22.0) cam.call("focus_on", Vector3(0.0, 0.0, 0.0)) await process_frame await process_frame # Cursor übers Karte-Zentrum → Ghost sichtbar parken (echter Ghost-Pfad). var vp: SubViewport = null var stack: Array = [main] while not stack.is_empty(): var n: Node = stack.pop_back() if n is SubViewportContainer: vp = n.get_child(0) as SubViewport break stack.append_array(n.get_children()) if vp == null: print("PROBE_U5_FAIL: kein SubViewport") quit(1) return var mm := InputEventMouseMotion.new() mm.position = (vp.size as Vector2) * 0.5 mm.global_position = mm.position vp.push_input(mm) await process_frame await process_frame var dir := "/tmp/u5_beweise" DirAccess.make_dir_recursive_absolute(dir) await _shot(dir + "/u5_1_vorher_ghost.png") print("PRUEF vorher: placing=%s objects=%s" % [ str(bool(interaction.get("placing"))), str((main.doc["objects"] as Array).size())]) # ECHTER Platzier-Pfad (wie Linksklick, ohne Shift → Einmal-Modus). interaction.call("_place_object", mm.position) await process_frame await process_frame await _shot(dir + "/u5_2_gesetzt.png") var placed := (main.doc["objects"] as Array).size() var builder = main.get("view_builder") var sel_mat: StandardMaterial3D = builder.get("_select_mat") var marker = null if placed > 0: marker = builder.object_markers[placed - 1].get_child(0) var hat_auswahl: bool = marker != null and marker.material_override == sel_mat var insp = main.get("inspector") var head_txt := "" if insp != null and insp.get("_head") != null: head_txt = str(insp.get("_head").text) print("PRUEF gesetzt: placing=%s objects=%s selected_index=%s marker_auswahl=%s inspektor='%s'" % [ str(bool(interaction.get("placing"))), str(placed), str(interaction.get("selected_index")), str(hat_auswahl), head_txt]) print("PRUEF status='%s'" % str(main.status_label.text)) # Bild 3: Auswahl im UI sichtbar — Inspektor-Tab nach vorn. var tab := _show_selection_tab(main) await process_frame await process_frame print("PRUEF tab='%s'" % tab) await _shot(dir + "/u5_3_ausgewaehlt_inspektor.png") var ok := not bool(interaction.get("placing")) \ and placed == 1 \ and int(interaction.get("selected_index")) == 0 \ and hat_auswahl \ and str(main.status_label.text).contains("ausgewählt") print("PROBE_U5_%s" % ("OK" if ok else "FAIL")) quit(0 if ok else 1)