extends "res://core/ui/panels/editor_panel.gd" ## Spawn-Check + Spawn-Zonen-Werkzeug-Panel (aus main.gd ausgezogen, Karte ## t_eaccbfed U1 — Logik unverändert, Karte t_c4162c5d): Live-Validierung ## (Loader-Regeln, IMMER sichtbar) + großer Werkzeug-Button + Team/Radius/ ## Löschen. Werkzeug-Ein/Aus bleibt im Koordinator (main.gd). var spawn_edit_btn: Button var spawn_panel: VBoxContainer var spawn_team_blue: Button var spawn_team_red: Button var spawn_radius_slider: HSlider var spawn_radius_label: Label var spawn_status: Label # Live-Validierung (IMMER sichtbar, Loader-Regeln) var spawn_sel_label: Label # Welche Zone ist an? var spawn_delete_btn: Button var spawn_yaw_row: HBoxContainer var spawn_yaw_spin: SpinBox var spawn_yaw_reset: Button static func spec() -> Dictionary: return {"titel": "Spawn-Zonen", "gruppe": "map", "order": 10} func panel_title() -> String: return "Prüfen" ## Bau (aus der alten main.gd/_build_right_panel übernommen, Logik identisch): ## Live-Status IMMER sichtbar + Werkzeug-Button + Bedien-Panel (Team/Radius/ ## Auswahl/Löschen). Ein/Aus des Werkzeugs bleibt beim Koordinator (main.gd). func build() -> void: add_child(_header_label("Spawn-Zonen")) # --- Spawn-Zonen (Karte t_c4162c5d): Live-Status IMMER sichtbar --- spawn_status = Label.new() spawn_status.text = "" spawn_status.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART spawn_status.custom_minimum_size = UIScale.v2(0, 44) add_child(spawn_status) # --- Spawn-Zonen-Werkzeug: großer Button + Bedien-Panel --- spawn_edit_btn = Button.new() spawn_edit_btn.text = "🚩 Spawn-Zonen malen" spawn_edit_btn.custom_minimum_size = UIScale.v2(0, 48) spawn_edit_btn.toggle_mode = true spawn_edit_btn.tooltip_text = "Startzonen für Team Blau und Rot auf den Boden malen (TDM)" spawn_edit_btn.pressed.connect(_on_spawn_btn_pressed) add_child(spawn_edit_btn) spawn_panel = VBoxContainer.new() spawn_panel.add_theme_constant_override("separation", UIScale.px(8)) # U7-Raster spawn_panel.visible = false add_child(spawn_panel) spawn_panel.add_child(_field_label("Team:")) var team_row := HBoxContainer.new() team_row.add_theme_constant_override("separation", UIScale.px(8)) # U7-Raster spawn_panel.add_child(team_row) var team_group := ButtonGroup.new() spawn_team_blue = _spawn_team_button("🔵 Team Blau", team_group, 0) spawn_team_red = _spawn_team_button("🔴 Team Rot", team_group, 1) spawn_team_blue.button_pressed = true team_row.add_child(spawn_team_blue) team_row.add_child(spawn_team_red) spawn_radius_label = _field_label("Zonen-Radius: 6 m") spawn_panel.add_child(spawn_radius_label) spawn_radius_slider = HSlider.new() spawn_radius_slider.min_value = SpawnOps.MIN_ZONE_RADIUS spawn_radius_slider.max_value = SpawnOps.MAX_ZONE_RADIUS spawn_radius_slider.step = 1.0 spawn_radius_slider.value = SpawnOps.DEFAULT_ZONE_RADIUS spawn_radius_slider.custom_minimum_size = UIScale.v2(0, 32) spawn_radius_slider.value_changed.connect(_on_spawn_radius_changed) spawn_panel.add_child(spawn_radius_slider) spawn_sel_label = Label.new() spawn_sel_label.text = "Keine Zone ausgewählt." spawn_sel_label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART spawn_panel.add_child(spawn_sel_label) spawn_yaw_row = HBoxContainer.new() spawn_yaw_row.add_theme_constant_override("separation", UIScale.px(8)) spawn_yaw_row.add_child(_field_label("Blickrichtung °")) spawn_yaw_spin = SpinBox.new() spawn_yaw_spin.min_value = 0.0 spawn_yaw_spin.max_value = 359.0 spawn_yaw_spin.step = 1.0 spawn_yaw_spin.tooltip_text = "Wohin Spieler und Bots hier beim Spawnen schauen. Geht auch im Bild: Pfeilspitze ziehen." spawn_yaw_spin.size_flags_horizontal = Control.SIZE_EXPAND_FILL spawn_yaw_spin.value_changed.connect(_on_spawn_yaw_changed) spawn_yaw_row.add_child(spawn_yaw_spin) spawn_yaw_reset = Button.new() spawn_yaw_reset.text = "Standard" spawn_yaw_reset.tooltip_text = "Keine feste Richtung: Spieler schauen zur Kartenmitte, Bots zum Gegner (grauer Pfeil)" spawn_yaw_reset.pressed.connect(func() -> void: main.spawn_tool.call("set_selected_yaw", null)) spawn_yaw_row.add_child(spawn_yaw_reset) spawn_panel.add_child(spawn_yaw_row) spawn_delete_btn = Button.new() spawn_delete_btn.text = "Zone löschen (Entf)" spawn_delete_btn.custom_minimum_size = UIScale.v2(0, 40) spawn_delete_btn.tooltip_text = "Die ausgewählte Spawn-Zone löschen (Strg+Z holt sie zurück)" spawn_delete_btn.pressed.connect(_on_spawn_delete_pressed) spawn_panel.add_child(spawn_delete_btn) func _spawn_team_button(text: String, group: ButtonGroup, team: int) -> Button: var btn := Button.new() btn.text = text btn.toggle_mode = true btn.button_group = group btn.custom_minimum_size = UIScale.v2(0, 40) # U7: Werkzeugname im Tooltip (Team, in das neue Zonen gemalt werden). btn.tooltip_text = "Zonen für %s malen" % ("Team Blau" if team == 0 else "Team Rot") btn.pressed.connect(_on_spawn_team_changed.bind(team)) return btn func _on_spawn_btn_pressed() -> void: if spawn_edit_btn.button_pressed: main.call("_set_tool_mode", "spawns") else: main.call("_set_tool_mode", "objects") func _selected_spawn_team() -> int: return 1 if spawn_team_red.button_pressed else 0 func _on_spawn_team_changed(team: int) -> void: if main.spawn_tool != null and str(main.get("tool_mode")) == "spawns": main.spawn_tool.call("set_team", team) func _on_spawn_radius_changed(value: float) -> void: spawn_radius_label.text = "Zonen-Radius: %d m" % int(value) if main.spawn_tool != null and str(main.get("tool_mode")) == "spawns": main.spawn_tool.call("set_radius", value) func _on_spawn_yaw_changed(value: float) -> void: if str(main.get("tool_mode")) == "spawns": main.spawn_tool.call("set_selected_yaw", value) func _on_spawn_delete_pressed() -> void: if str(main.get("tool_mode")) == "spawns": main.spawn_tool.call("delete_selected") ## Panel-Zeile „Welche Zone ist angewählt?“ — WIRD vom Spawn-Tool gerufen. func sync_spawn_selection() -> void: if main.spawn_tool == null: return var team: int = main.spawn_tool.get("selected_team") var pid: String = str(main.spawn_tool.get("selected_id")) if team < 0 or pid == "": spawn_sel_label.text = "Keine Zone ausgewählt.\nKlicke im Viewport auf einen Kreis." spawn_delete_btn.disabled = true spawn_yaw_row.visible = false return spawn_yaw_row.visible = true for p in SpawnOps.points(main.doc, team): if p is Dictionary and str(p.get("id", "")) == pid: spawn_yaw_spin.set_value_no_signal(SpawnOps.effective_yaw(main.doc, p)) spawn_yaw_reset.disabled = not SpawnOps.has_yaw(p) spawn_sel_label.text = "Ausgewählt: %s (%s)\nVerschieben: klicken+ziehen · Radius: Regler oben" % [ pid, SpawnOps.team_label(team)] spawn_delete_btn.disabled = false ## LIVE-Validierung (Loader-Regeln) — immer sichtbar, nach JEDEM Struktur-Wechsel. func refresh_spawn_status() -> void: if main.doc.is_empty() or spawn_status == null: return spawn_status.text = SpawnOps.live_status(main.doc, main.manifest)