155 lines
5.8 KiB
GDScript
155 lines
5.8 KiB
GDScript
extends "res://src/ui/panels/editor_panel.gd"
|
|
## Map-Inhalt-Baum (aus main.gd ausgezogen, Karte t_eaccbfed U1 — Logik
|
|
## unverändert). U2 baut hier den hierarchischen Szenen-Baum aus; diese Karte
|
|
## zieht nur um: Der Baum lebt jetzt im LINKEN TabContainer (Registry-Gruppe
|
|
## "links"), Zustand/Signale wie vorher.
|
|
|
|
var content_tree: Tree
|
|
var _tree_select_lock := false # verhindert Rückkopplung Auswahl ↔ Baum
|
|
|
|
|
|
static func spec() -> Dictionary:
|
|
return {"titel": "Map-Inhalt", "gruppe": "links", "order": 10}
|
|
|
|
|
|
func build() -> void:
|
|
add_child(_header_label("Map-Inhalt"))
|
|
|
|
content_tree = Tree.new()
|
|
content_tree.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
|
content_tree.custom_minimum_size = UIScale.v2(0, 160)
|
|
content_tree.allow_reselect = true
|
|
content_tree.select_mode = Tree.SELECT_MULTI # Strg+Klick im Baum = Mehrfachauswahl (t_c46d31c2)
|
|
content_tree.hide_root = true
|
|
content_tree.item_selected.connect(_on_tree_selected)
|
|
add_child(content_tree)
|
|
|
|
|
|
## Der Baum ruft zurück, wenn der Nutzer dort ein Objekt auswählt.
|
|
## SELECT_MULTI (Karte t_c46d31c2): einfacher Klick = Ersatz-Auswahl,
|
|
## Strg+Klick addiert/entfernt nativ — ALLE markierten Objekt-Zeilen spiegeln
|
|
## sich in die Viewport-Auswahl (Baum und Szene sind immer synchron).
|
|
func _on_tree_selected() -> void:
|
|
if _tree_select_lock:
|
|
return
|
|
var item := content_tree.get_selected()
|
|
if item == null:
|
|
return
|
|
if item.has_meta("gebaeude_index"):
|
|
_on_tree_selected_gebaeude(int(item.get_meta("gebaeude_index")))
|
|
return
|
|
var indices: Array = []
|
|
var walk := content_tree.get_next_selected(null)
|
|
while walk != null:
|
|
if walk.has_meta("obj_index"):
|
|
indices.append(int(walk.get_meta("obj_index")))
|
|
walk = content_tree.get_next_selected(walk)
|
|
if indices.is_empty():
|
|
return
|
|
var objects: Array = main.doc.get("objects", [])
|
|
var valid: Array = []
|
|
for idx in indices:
|
|
if idx >= 0 and idx < objects.size():
|
|
valid.append(idx)
|
|
if valid.is_empty():
|
|
return
|
|
if valid.size() == 1:
|
|
main.interaction.select_object(valid[0], true)
|
|
main.call("_set_status", "%s ausgewählt — ziehen zum Verschieben, R/Mausrad zum Drehen, Entf zum Löschen. Strg+Klick markiert weitere dazu." % main.object_label(str(objects[valid[0]].get("id", ""))))
|
|
else:
|
|
main.interaction.select_many(valid)
|
|
main.call("_set_status", "%d Objekte im Baum markiert — Entf löscht ALLE, Strg+D dupliziert ALLE (jeweils EIN Undo-Schritt)." % valid.size())
|
|
|
|
|
|
## Baum: Bauteil-Klick → Bauen-Modus + Teil anwählen (Karte t_97ea59c5).
|
|
func _on_tree_selected_gebaeude(gi: int) -> void:
|
|
if str(main.get("tool_mode")) != "bauen":
|
|
main.call("_set_tool_mode", "bauen")
|
|
main.build_tool.call("select_index", gi)
|
|
|
|
|
|
func mark_tree_selection(idx: int) -> void:
|
|
mark_tree_selection_multi([idx])
|
|
|
|
|
|
func mark_tree_selection_multi(indices: Array) -> void:
|
|
_tree_select_lock = true
|
|
var wanted := {}
|
|
for i in indices:
|
|
wanted[int(i)] = true
|
|
_mark_tree_selection_walk(content_tree.get_root(), wanted)
|
|
var primary: Variant = main.interaction.get("selected_index") if main.interaction != null else -1
|
|
if primary is int and primary >= 0:
|
|
_ensure_tree_visible(content_tree.get_root(), primary)
|
|
_tree_select_lock = false
|
|
|
|
|
|
func _mark_tree_selection_walk(item: TreeItem, wanted: Dictionary) -> void:
|
|
if item == null:
|
|
return
|
|
if item.has_meta("obj_index"):
|
|
var idx := int(item.get_meta("obj_index"))
|
|
if wanted.has(idx):
|
|
item.select(0)
|
|
elif item.is_selected(0):
|
|
item.deselect(0)
|
|
for child in item.get_children():
|
|
_mark_tree_selection_walk(child, wanted)
|
|
|
|
|
|
func _ensure_tree_visible(item: TreeItem, idx: int) -> void:
|
|
if item == null:
|
|
return
|
|
if item.has_meta("obj_index") and int(item.get_meta("obj_index")) == idx:
|
|
# Fix (beim Inspektor-Einbau gefunden, Vorbestand t_f6f29d86): Tree
|
|
# und TreeItem haben KEIN ensure_visible — die Godot-4-API heißt
|
|
# Tree.scroll_to_item. Der alte Ruf warf bei JEDER Auswahl einen
|
|
# SCRIPT ERROR und scrollte den Baum nie zur Auswahl.
|
|
content_tree.scroll_to_item(item)
|
|
return
|
|
for child in item.get_children():
|
|
_ensure_tree_visible(child, idx)
|
|
|
|
|
|
func refresh_tree() -> void:
|
|
content_tree.clear()
|
|
var root := content_tree.create_item()
|
|
var objects: Array = main.doc.get("objects", [])
|
|
|
|
var obj_item := content_tree.create_item(root)
|
|
obj_item.set_text(0, "Objekte (%d)" % objects.size())
|
|
for i in objects.size():
|
|
var obj = objects[i]
|
|
var item := content_tree.create_item(obj_item)
|
|
if obj is Dictionary:
|
|
item.set_text(0, "%s #%d" % [main.object_label(str(obj.get("id", "?"))), i + 1])
|
|
item.set_meta("obj_index", i)
|
|
else:
|
|
item.set_text(0, "ungültig #%d" % (i + 1))
|
|
|
|
var zones: Dictionary = main.doc.get("spawn_zones", {})
|
|
var spawn_item := content_tree.create_item(root)
|
|
spawn_item.set_text(0, "Spawn-Zonen")
|
|
for team_key in ["0", "1"]:
|
|
if not zones.has(team_key):
|
|
continue
|
|
var zone: Dictionary = zones[team_key]
|
|
var team_item := content_tree.create_item(spawn_item)
|
|
var team_name := "Team Blau" if team_key == "0" else "Team Rot"
|
|
team_item.set_text(0, "%s (%d Punkte)" % [team_name, (zone.get("points", []) as Array).size()])
|
|
for p in (zone.get("points", []) as Array):
|
|
if p is Dictionary:
|
|
var point_item := content_tree.create_item(team_item)
|
|
point_item.set_text(0, "%s (%.0f, %.0f)" % [
|
|
str(p.get("id", "?")), float(p.get("pos", [0, 0, 0])[0]), float(p.get("pos", [0, 0, 0])[2])])
|
|
|
|
# Gebäude (Karte t_97ea59c5): Bauteile im Baum — Klick wählt das Teil an.
|
|
var geb_list: Array = BuildOps.pieces(main.doc)
|
|
if not geb_list.is_empty():
|
|
var geb_item := content_tree.create_item(root)
|
|
geb_item.set_text(0, "Gebäude (%d Bauteile)" % geb_list.size())
|
|
for i in geb_list.size():
|
|
var teil: Dictionary = geb_list[i]
|
|
var g_child := content_tree.create_item(geb_item)
|
|
g_child.set_text(0, "%s #%d" % [BuildOps.kind_label(str(teil.get("id", "?"))), i + 1])
|
|
g_child.set_meta("gebaeude_index", i)
|