scopedvr-map-core/ui/panels/check_panel.gd
2026-11-01 19:31:33 +01:00

176 lines
6.9 KiB
GDScript

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)