extends Node ## Direct icon/model comparisons; original PNGs stay unchanged. const STAGE: Script = preload("res://tools/model_gallery_stage.gd") var _sheet: Control func _ready() -> void: get_tree().create_timer(90).timeout.connect(func(): get_tree().quit(1)) var faction: String = "glutpakt" for arg: String in OS.get_cmdline_user_args(): if arg.begins_with("--faction="): faction = arg.trim_prefix("--faction=") var data: Dictionary = JSON.parse_string(FileAccess.get_file_as_string("res://assets/phase4_manifest.json")) var icons: Dictionary = JSON.parse_string(FileAccess.get_file_as_string("res://assets/phase3_manifest.json")) var paths: Dictionary = {} for asset: Dictionary in icons["assets"]: paths[str(asset["id"])] = str(asset["resource_path"]) paths["worker"] = paths.get("worker_funkenleser", "") var selected: Array[Dictionary] = [] for asset: Dictionary in data["assets"]: if str(asset["faction"]) == faction and paths.has(str(asset["id"])): selected.append(asset) get_window().size = Vector2i(1600, 960) for start: int in range(0, selected.size(), 2): _sheet = Control.new() _sheet.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) add_child(_sheet) var backdrop: ColorRect = ColorRect.new() backdrop.color = Color("10141b") backdrop.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) _sheet.add_child(backdrop) var margin: MarginContainer = MarginContainer.new() margin.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT) for edge: String in ["left", "top", "right", "bottom"]: margin.add_theme_constant_override("margin_" + edge, 24) _sheet.add_child(margin) var layout: VBoxContainer = VBoxContainer.new() layout.add_theme_constant_override("separation", 16) margin.add_child(layout) layout.add_child(_label("SAUMWACHT / " + faction.to_upper(), 29, Color("ddc898"))) layout.add_child(_label("Bildreferenz und überarbeitetes 3D-Modell · Gleiche Einheit, direkte Gegenüberstellung", 18, Color("adb6c5"))) var row: HBoxContainer = HBoxContainer.new() row.size_flags_vertical = Control.SIZE_EXPAND_FILL row.add_theme_constant_override("separation", 12) layout.add_child(row) for index: int in range(start, mini(start + 2, selected.size())): var asset: Dictionary = selected[index] for reference: bool in [true, false]: var card: VBoxContainer = VBoxContainer.new() card.size_flags_horizontal = Control.SIZE_EXPAND_FILL row.add_child(card) card.add_child(_label("ICON · PHASE 3" if reference else "3D-MODELL", 16, Color("aab3c2"))) if reference: var icon: TextureRect = TextureRect.new() # Compare against native PNG pixels, not the 256px gameplay import. var source_image: Image = Image.load_from_file(str(paths[str(asset["id"])])) icon.texture = ImageTexture.create_from_image(source_image) icon.expand_mode = TextureRect.EXPAND_IGNORE_SIZE icon.stretch_mode = TextureRect.STRETCH_KEEP_ASPECT_CENTERED icon.custom_minimum_size.x = 350 icon.size_flags_vertical = Control.SIZE_EXPAND_FILL card.add_child(icon) else: var view: Dictionary = STAGE.create(card, Vector2(350, 450)) STAGE.show_asset(view, asset) (view["camera"] as Camera3D).size = 3.5 card.add_child(_label(str(asset["id"]).to_upper() + " · " + str(asset["name"]), 19, Color("eee6d8"))) card.add_child(_label("Originalillustration" if reference else str(int(asset["triangles"])) + " Dreiecke · GLB", 15, Color("9ca9bc"))) layout.add_child(_label("3D-Darstellung aus Godot · Modellierte Formdetails und PBR-Materialien · Bearbeitbare Blender-Quellen", 14, Color("8491a3"))) await get_tree().process_frame await get_tree().process_frame await RenderingServer.frame_post_draw await get_tree().create_timer(0.2).timeout var output: String = "res://docs/screenshots/phase4/reference-" + str(selected[start]["id"]) + ".png" var error: Error = get_viewport().get_texture().get_image().save_png(output) if error != OK: printerr("Reference screenshot failed: ", output) get_tree().quit(1) return print("REFERENCE_CAPTURED ", output) _sheet.free() get_tree().quit(0) func _label(text: String, size: int, color: Color) -> Label: var label: Label = Label.new() label.text = text label.add_theme_font_size_override("font_size", size) label.add_theme_color_override("font_color", color) return label