saumwacht-godot/scripts/luneraria/ui/components/team_panel.gd
Martin Stickelbroeck 1b540f2a55 G3 (Zwischenstand): neues Ingame-HUD; Projekt wechselt nach Unity
Nicht abgenommen: Nach dem ersten Spieltest wurde entschieden, Champions of
Luneraria nach Unity 6 zu portieren. Dieser Stand ist die Referenz für das
HUD im Unity-Projekt (../luneraria-unity).

- HUD neu aus Komponenten mit eigenem Theme, Porträts aus den echten Modellen
  (einmal gerendert, zwischengespeichert), Lane-Übersicht mit deterministischer
  Bedrohung aus öffentlichem Zustand, Bossgrotte, nächste Welle, Ereignisse,
  Minimap mit zusammengefassten Armeen, Held/Items/Talente, Einheitendetails,
  Angriffschampions, Bereit-Sperre, UI-Größe, Team-Formen statt nur Farben
- Privatsphäre über LuneHudModel: fremdes Gold und fremde Entwürfe erscheinen nie
- Keine Regeländerung: Regeln 91/91, M2 73/73, Netz 43/43; verify_g3 715/715;
  verify_m1 38/38 und verify_m2 14/14 mit angepassten UI-Treibern
- Spieltest bis Welle 8 über die echte Oberfläche, Befunde in G3-HUD.md
- HELDEN-KONZEPT.md: vom Projektinhaber vorgegebene Helden (nicht umgesetzt)

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-29 19:59:55 +02:00

89 lines
4.3 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.

class_name LuneTeamPanel
extends VBoxContainer
## The own team: per seat the name, lane, hero (committed hero of the others, own draft for
## the viewer), readiness during planning and whether a human, a bot or – after a disconnect –
## a bot on a human's seat plays it. Gold or plans of the others are never shown.
var _rows: Array[Dictionary] = []
var _header: Label
var _emblem: LuneGlyph
var _signature: String = ""
func _init() -> void:
add_theme_constant_override("separation", 3)
mouse_filter = Control.MOUSE_FILTER_IGNORE
var head := HBoxContainer.new()
head.add_theme_constant_override("separation", 6)
head.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(head)
_emblem = LuneGlyph.make("emblem_0", LuneUiTheme.TEAM[0], 15.0, head)
_header = LuneUiTheme.label("DEIN TEAM", "HudCaps", head)
for index: int in range(3):
var row := HBoxContainer.new()
row.add_theme_constant_override("separation", 6)
row.mouse_filter = Control.MOUSE_FILTER_PASS
row.custom_minimum_size.y = 28
add_child(row)
var status := LuneGlyph.make("human", LuneUiTheme.MUTED, 15.0, row)
var portrait := LunePortraitRect.new()
portrait.custom_minimum_size = Vector2(26, 26)
portrait.size_flags_vertical = Control.SIZE_SHRINK_CENTER
row.add_child(portrait)
var name_label := LuneUiTheme.label("", "HudText", row)
name_label.size_flags_horizontal = Control.SIZE_EXPAND_FILL
name_label.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
name_label.clip_text = true
var lane_label := LuneUiTheme.label("", "HudMuted", row)
var badge := LuneStatusBadge.new()
row.add_child(badge)
var entry: Dictionary = {"row": row, "status": status, "portrait": portrait, "name": name_label, "lane": lane_label, "badge": badge, "data": {}}
_rows.append(entry)
LuneTooltip.attach(row, _tip.bind(index))
func apply(members: Array, team: int, planning: bool, networked: bool) -> void:
var signature: String = "%s|%d|%s|%s" % [str(members), team, planning, networked]
if signature == _signature:
return
_signature = signature
_emblem.glyph = "emblem_%d" % team
_emblem.color = LuneUiTheme.team_color(team)
_header.text = "DEIN TEAM · %s" % LuneUiTheme.team_name(team).to_upper()
for index: int in range(mini(3, members.size())):
var member: Dictionary = members[index]
var row: Dictionary = _rows[index]
row.data = member
var status: String = str(member.status)
(row.status as LuneGlyph).glyph = {"self": "star", "human": "human", "bot": "bot", "offline": "offline"}.get(status, "human")
(row.status as LuneGlyph).color = LuneUiTheme.BRONZE_LIGHT if status == "self" else (LuneUiTheme.DANGER if status == "offline" else LuneUiTheme.MUTED)
var name_label: Label = row.name
name_label.text = str(member.name)
name_label.add_theme_color_override("font_color", LuneUiTheme.BRONZE_LIGHT if member.is_self else LuneUiTheme.TEXT)
(row.lane as Label).text = LuneMap.LANE_NAMES[member.lane].to_upper()
var portrait: LunePortraitRect = row.portrait
var hero_id: String = str(member.hero_id)
portrait.visible = not hero_id.is_empty()
if not hero_id.is_empty():
portrait.show_model(str(LuneContent.HEROES[hero_id].model))
var badge: LuneStatusBadge = row.badge
if status == "offline":
badge.set_state("BOT ÜBERNIMMT", LuneUiTheme.DANGER, "offline")
elif status == "bot":
badge.set_state("BOT", LuneUiTheme.MUTED, "bot")
elif planning and member.ready:
badge.set_state("BEREIT", LuneUiTheme.GOOD, "check")
elif planning:
badge.set_state("PLANT", LuneUiTheme.WARN, "clock")
else:
badge.set_state("IM KAMPF", LuneUiTheme.INFO)
func _tip(index: int) -> Dictionary:
var member: Dictionary = _rows[index].data
if member.is_empty():
return {}
var kind: String = {"self": "Du", "human": "Mensch", "bot": "Bot", "offline": "Verbindung getrennt – ein Bot spielt den Platz weiter"}.get(str(member.status), "")
var hero: String = "kein Held"
if not str(member.hero_id).is_empty():
hero = "%s · Stufe %d" % [LuneContent.HEROES[member.hero_id].name, int(member.hero_level)]
return {"title": str(member.name), "subtitle": "%s-Lane · %s" % [LuneMap.LANE_NAMES[member.lane], DataCatalog.FACTION_NAMES.get(member.bund, "")],
"stats": [["human", "Spieler", kind], ["crown", "Held", hero], ["check", "Planung", "bereit" if member.ready else "plant noch"]],
"note": "Gold und laufende Planung anderer Spieler bleiben privat." if not member.is_self else ""}