142 lines
No EOL
5 KiB
GDScript
142 lines
No EOL
5 KiB
GDScript
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) |