saumwacht-godot/scripts/luneraria/ui/lune_reinforce_panel.gd
Martin Stickelbroeck f53859a298 M2: Helden, Items, Talente, Angriffschampions und Bossgrotte
Drei Helden mit Nähe-/Teilnahme-XP, Talenten und drei Itemplätzen,
drei Angriffschampions mit Buchung n -> n+1, Bossgrotte mit Streitfall,
ruhendem Boss, idempotenter Eroberung, einmaliger Entsendung für das
Siegerteam, hohem Kopfgeld und Sperre bis Sieg+4. HUD-Reiter, Porträt
aus echtem Modell, Grotten-Asset, Bots für alle Systeme. Regeln M2 73/73,
M1 91/91, App M2 15/15 und M1 38/38, Bossszenarien dokumentiert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 22:33:11 +02:00

113 lines
4.9 KiB
GDScript
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

extends VBoxContainer
## Reinforcement tab: book attack champions for the next round, see this round's public
## announcements, and steer a conquered boss if you are its chooser.
signal command_requested(command: Dictionary)
var match_state: LuneMatch
var slot: int = 0
var _lane: String = "mid"
var _signature: String = "@"
func _ready() -> void:
add_theme_constant_override("separation", 8)
func _process(_delta: float) -> void:
if match_state == null or match_state.phase != LuneMatch.Phase.PLANNING:
return
var draft: Dictionary = match_state.players[slot].draft
var signature: String = JSON.stringify([draft.gold, draft.new_bookings, draft.boss_lane, match_state.round_number, _lane, match_state.boss])
if signature != _signature:
_signature = signature
_rebuild()
func _label(text_value: String, variation: String, size: int = 0) -> Label:
var label := Label.new()
label.text = text_value
label.theme_type_variation = variation
label.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
if size > 0:
label.add_theme_font_size_override("font_size", size)
add_child(label)
return label
func _rebuild() -> void:
for child: Node in get_children():
child.free()
var draft: Dictionary = match_state.players[slot].draft
_label("ANGRIFFSCHAMPIONS · Kauf jetzt, Einsatz nächste Runde", "SectionLabel")
var lanes := HBoxContainer.new()
add_child(lanes)
var lane_label := Label.new()
lane_label.text = "Ziel-Lane"
lane_label.theme_type_variation = "MutedLabel"
lane_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
lanes.add_child(lane_label)
for lane: String in LuneMap.LANES:
var button := Button.new()
button.text = LuneMap.LANE_NAMES[lane]
button.theme_type_variation = "ChoiceButton"
button.toggle_mode = true
button.button_pressed = lane == _lane
button.pressed.connect(func() -> void: _lane = lane)
lanes.add_child(button)
for champion_id: String in LuneContent.CHAMPIONS:
var spec: Dictionary = LuneContent.CHAMPIONS[champion_id]
var row := HBoxContainer.new()
add_child(row)
var text := VBoxContainer.new()
text.size_flags_horizontal = Control.SIZE_EXPAND_FILL
text.add_theme_constant_override("separation", 0)
row.add_child(text)
var name := Label.new()
name.text = "%s · %s" % [spec.name, spec.role]
text.add_child(name)
var info := Label.new()
info.text = spec.text
info.theme_type_variation = "MutedLabel"
info.add_theme_font_size_override("font_size", 14)
info.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
text.add_child(info)
var book := Button.new()
book.text = "%d G" % int(spec.cost)
book.disabled = int(draft.gold) < int(spec.cost) or (draft.new_bookings as Array).size() >= LuneContent.MAX_BOOKINGS
book.tooltip_text = "%s für Runde %d auf %s buchen" % [spec.name, match_state.round_number + 1, LuneMap.LANE_NAMES[_lane]]
book.pressed.connect(func() -> void: command_requested.emit({"type": "champion_book", "champion_id": champion_id, "lane": _lane}))
row.add_child(book)
for booking: Dictionary in draft.new_bookings:
var row := HBoxContainer.new()
add_child(row)
var label := Label.new()
label.text = "Gebucht: %s · %s · Runde %d" % [LuneContent.CHAMPIONS[booking.champion_id].name, LuneMap.LANE_NAMES[booking.lane], match_state.round_number + 1]
label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
row.add_child(label)
var cancel := Button.new()
cancel.text = "×"
cancel.tooltip_text = "Buchung zurücknehmen (volle Erstattung)"
var uid: String = booking.uid
cancel.pressed.connect(func() -> void: command_requested.emit({"type": "champion_cancel", "uid": uid}))
row.add_child(cancel)
add_child(HSeparator.new())
_label("ANGEKÜNDIGT FÜR DIESE RUNDE", "SectionLabel")
var lines: PackedStringArray = []
for entry: Dictionary in match_state.announcements():
var team: String = "Blau" if int(entry.team) == 0 else "Rot"
if entry.kind == "boss":
lines.append("%s: Schlundkrone greift über %s an · Kopfgeld für die Verteidiger %d Gold" % [team, LuneMap.LANE_NAMES[entry.lane], int(entry.bounty)])
else:
lines.append("%s: %s auf %s" % [team, LuneContent.CHAMPIONS[entry.champion_id].name, LuneMap.LANE_NAMES[entry.lane]])
_label("\n".join(lines) if not lines.is_empty() else "Keine Angriffschampions und kein Boss angekündigt.", "MutedLabel", 15)
var claim: Dictionary = match_state.boss.claim
if not claim.is_empty() and int(claim.chooser_slot) == slot and int(claim.deploy_round) == match_state.round_number:
_label("DEIN BOSS · wähle die Angriffs-Lane", "SectionLabel")
var row := HBoxContainer.new()
add_child(row)
var chosen: String = str(draft.boss_lane) if not str(draft.boss_lane).is_empty() else str(claim.lane)
for lane: String in LuneMap.LANES:
var button := Button.new()
button.text = LuneMap.LANE_NAMES[lane]
button.theme_type_variation = "ChoiceButton"
button.toggle_mode = true
button.button_pressed = lane == chosen
button.pressed.connect(func() -> void: command_requested.emit({"type": "boss_lane", "lane": lane}))
row.add_child(button)