extends "res://src/ui/panels/editor_panel.gd" ## Bauen-Tab: Bauteile für eigene Gebäude (Fundament, Wände, Dach, Treppe). Fertige ## Pack-Objekte (Container, Hangar-Tore, Sperren …) gehören in die Objekt-Bibliothek ## unten, NICHT hierher. Ein Klick auf ein Teil startet ## das Platzieren (Vorschau rastet an Zelle/Kante/Ebene, siehe build_snap.gd); jedes ## gesetzte Teil ist ein normales Objekt und gehört zum laufenden Gebäude (Gruppe). ## Gebäude kopieren/löschen/auswählen läuft über die Knöpfe unten — alles Undo-fähig. var bau_buttons: Dictionary = {} # oid → Button var info_label: Label var _group: ButtonGroup static func spec() -> Dictionary: return {"titel": "Bauen", "gruppe": "rechts", "order": 47} func panel_title() -> String: return "Bauen" func build() -> void: _group = ButtonGroup.new() _group.allow_unpress = true add_child(_muted_label("Wähle ein Teil und klicke in die Karte. Wände rasten an die nächste Zellkante, Böden und Dächer in die Zellmitte (Raster 2 m). Klick auf die Oberkante einer Wand stapelt das nächste Geschoss, Klick auf die Seite ersetzt das Teil (z. B. Wand → Tür). R dreht, Esc beendet.")) for gruppe in BauKatalog.GRUPPEN: add_child(_field_label(str(gruppe["label"]))) add_child(_knopf_raster(gruppe["oids"] as Array)) add_child(_separator()) add_child(_header_label("Begehbare Vorlagen")) add_child(_muted_label("Pack-Kaserne, -Checkpoint und -Container sind innen geschlossen. Diese Vorlagen setzen ein begehbares Gebäude mit einem Klick in die Bildmitte (Tür, Fenster, Dach, Strg+Z nimmt alles zurück).")) for key in BauVorlagen.schluessel(): add_child(_aktion("🏠 %s" % BauVorlagen.label(key), str(BauVorlagen.VORLAGEN[key]["info"]), func() -> void: main.call("_bau_vorlage_setzen", key))) add_child(_separator()) add_child(_header_label("Gebäude")) info_label = _muted_label("") add_child(info_label) add_child(_aktion("🏠 Neues Gebäude beginnen", "Das nächste Teil gehört zu einem neuen Gebäude (neue Gruppe).", func() -> void: main.call("_bau_neues_gebaeude"))) add_child(_aktion("🔲 Ganzes Gebäude auswählen", "Wählt alle Teile des Gebäudes, zu dem das markierte Teil gehört — zum Verschieben, Drehen, Kopieren.", func() -> void: main.call("_bau_gebaeude_waehlen"))) add_child(_aktion("📄 Gebäude kopieren", "Kopiert das ganze Gebäude als neues Gebäude (Strg+Z nimmt es zurück).", func() -> void: main.call("_bau_gebaeude_kopieren"))) add_child(_aktion("🗑 Gebäude löschen", "Löscht alle Teile des Gebäudes (Strg+Z holt es zurück).", func() -> void: main.call("_bau_gebaeude_loeschen"))) refresh_info() wrap_in_scroll() func _knopf_raster(oids: Array) -> GridContainer: var grid := GridContainer.new() grid.columns = 2 grid.add_theme_constant_override("h_separation", UIScale.px(8)) grid.add_theme_constant_override("v_separation", UIScale.px(8)) var lib: Dictionary = main.manifest.get("objects", {}) for oid in oids: var btn := Button.new() btn.toggle_mode = true btn.button_group = _group btn.custom_minimum_size = UIScale.v2(148, 44) btn.clip_text = true var poly := int((lib.get(oid, {}) as Dictionary).get("poly", 0)) btn.text = BauKatalog.label(oid) btn.tooltip_text = "%s — %s\n%d Dreiecke" % [BauKatalog.label(oid), str((BauKatalog.KINDS[oid] as Dictionary).get("info", "")), poly] btn.pressed.connect(_on_teil_gedrueckt.bind(str(oid), btn)) bau_buttons[str(oid)] = btn grid.add_child(btn) return grid func _aktion(text: String, tip: String, cb: Callable) -> Button: var b := Button.new() b.text = text b.tooltip_text = tip b.custom_minimum_size = UIScale.v2(0, 44) b.pressed.connect(cb) return b func _on_teil_gedrueckt(oid: String, btn: Button) -> void: if not btn.button_pressed: main.interaction.call("cancel_placement") return main.call("_on_bauteil_gewaehlt", oid) ## Teil-Markierung an den laufenden Platzier-Zustand koppeln (Esc/Abbruch löst sie). func sync_platzierung() -> void: var aktiv := str(main.interaction.get("place_oid")) if bool(main.interaction.get("placing")) else "" for oid in bau_buttons: (bau_buttons[oid] as Button).set_pressed_no_signal(oid == aktiv) ## Info-Zeile: aktuelles Gebäude (Name, Teile, Dreiecke) bzw. Gesamtzahl. func refresh_info() -> void: if info_label == null or main == null or main.doc.is_empty(): return var gebaeude := BauOps.gebaeude_gruppen(main.doc) var text := "%d Gebäude, %d Bauteile in der Map." % [gebaeude.size(), BauOps.teile_zahl(main.doc)] var gid := int(main.interaction.get("build_group_id")) for g in gebaeude: if int(g["gid"]) == gid: text = "Aktuell: %s — %d Teile, %d Dreiecke.\n%s" % [g["name"], (g["indizes"] as Array).size(), int(g["dreiecke"]), text] break info_label.text = text