Files
elements-autochess/scripts/ui/InfoColumn.gd
2026-09-16 12:09:33 +02:00

172 lines
6.2 KiB
GDScript

class_name InfoColumn
extends Control
## Linke Spalte: Elemente im Team, Kombinationen, gewählte Einheit, Rückblick.
signal upgrade_pressed
const PANEL_BG := Color(0.14, 0.15, 0.19)
var traits_box: VBoxContainer
var info_box: VBoxContainer
var log_box: VBoxContainer
var _text_w := 240.0
func build(x: float, y: float, w: float, h: float) -> void:
position = Vector2(x, y)
size = Vector2(w, h)
_text_w = w - 46.0
mouse_filter = Control.MOUSE_FILTER_IGNORE
var p := UiKit.panel(PANEL_BG)
p.size = size
p.clip_contents = true
add_child(p)
var sc := ScrollContainer.new()
sc.horizontal_scroll_mode = ScrollContainer.SCROLL_MODE_DISABLED
p.add_child(sc)
var col := VBoxContainer.new()
col.add_theme_constant_override("separation", 10)
col.size_flags_horizontal = Control.SIZE_EXPAND_FILL
sc.add_child(col)
traits_box = VBoxContainer.new()
info_box = VBoxContainer.new()
log_box = VBoxContainer.new()
for b in [traits_box, info_box, log_box]:
b.add_theme_constant_override("separation", 3)
b.size_flags_horizontal = Control.SIZE_EXPAND_FILL
col.add_child(b)
col.add_child(HSeparator.new())
func refresh(game: Game, avatar: Avatar, hex: Vector2i) -> void:
_refresh_traits(game)
_refresh_info(game, avatar, hex)
_refresh_log(game)
func _wrapped(text: String, size: int, col: Color) -> Label:
var l := UiKit.label(text, size, col)
l.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
l.custom_minimum_size = Vector2(_text_w, 0)
l.size_flags_horizontal = Control.SIZE_FILL
return l
func _clear(box: Node) -> void:
for c in box.get_children():
box.remove_child(c)
c.queue_free()
func _refresh_traits(game: Game) -> void:
_clear(traits_box)
traits_box.add_child(UiKit.label("Elemente im Team", 15, Color(0.75, 0.8, 0.95)))
var counts := game.human.trait_counts()
var any := false
for e in Data.ELEMENT_COUNT:
var c: int = counts.get(e, 0)
if c == 0:
continue
any = true
var tier := Data.trait_tier(e, c)
var col: Color = Data.ELEMENT_COLORS[e]
var row := HBoxContainer.new()
var dot := ColorRect.new()
dot.color = col if tier > 0 else col.darkened(0.55)
dot.custom_minimum_size = Vector2(12, 12)
row.add_child(dot)
var txt := " %s %d" % [Data.ELEMENT_NAMES[e], c]
if tier > 0:
txt += " - " + Data.ELEMENT_TRAITS[e]["desc"][tier - 1]
else:
txt += " (ab 2 aktiv)"
var el := UiKit.label(txt, 13, Color(0.9, 0.9, 0.95) if tier > 0 else Color(0.55, 0.55, 0.6))
el.autowrap_mode = TextServer.AUTOWRAP_WORD_SMART
el.custom_minimum_size = Vector2(_text_w - 20.0, 0)
row.add_child(el)
traits_box.add_child(row)
if not any:
traits_box.add_child(_wrapped("Noch nichts aufgestellt.", 13, Color(0.55, 0.55, 0.6)))
traits_box.add_child(UiKit.label("\nKombinationen", 15, Color(0.75, 0.8, 0.95)))
var keys := []
for c in game.human.active_combos():
keys.append(c["key"])
for c in Data.COMBO_TRAITS:
var on: bool = keys.has(c["key"])
var t := "%s (%s+%s): %s" % [c["name"], Data.ELEMENT_NAMES[c["a"]],
Data.ELEMENT_NAMES[c["b"]], c["desc"]]
traits_box.add_child(_wrapped(t, 12, Color(0.6, 0.95, 0.7) if on else Color(0.45, 0.45, 0.5)))
func _refresh_info(game: Game, a: Avatar, hex: Vector2i) -> void:
_clear(info_box)
info_box.add_child(UiKit.label("Einheit", 15, Color(0.75, 0.8, 0.95)))
if a == null:
info_box.add_child(_wrapped("Einheit auf dem Feld oder der Bank anklicken.", 13,
Color(0.55, 0.55, 0.6)))
return
var s := a.base_stats()
info_box.add_child(_wrapped("%s %d-Star" % [a.display_name(), a.star], 14, a.color()))
info_box.add_child(_wrapped("%s: %s" % [Data.ELEMENT_NAMES[a.primary_element()],
Data.PROFILE_HINT[a.primary_element()]], 12, Color(0.75, 0.8, 0.9)))
var crit := " Krit %d%%" % int(s["crit"] * 100.0) if s["crit"] > 0.0 else ""
info_box.add_child(_wrapped("Leben %d Angriff %d Rüstung %d%%\nTempo %.2f Reichweite %d%s"
% [int(s["hp"]), int(s["atk"]), int(s["armor"] * 100.0), s["aspd"], s["range"], crit], 12,
Color(0.9, 0.9, 0.95)))
info_box.add_child(_wrapped(a.ability_text(), 12, Color(0.8, 0.85, 1.0)))
if hex.x < 0:
info_box.add_child(_wrapped("Zum Aufwerten aufs Feld ziehen.", 12, Color(0.85, 0.85, 0.9)))
return
var cost := a.upgrade_cost()
if cost.is_empty():
info_box.add_child(_wrapped("Maximale Stufe.", 12, Color(1.0, 0.85, 0.35)))
return
var p := game.human
var missing := p.upgrade_missing(hex)
var need := []
for e in cost:
need.append("%dx %s" % [cost[e], Data.ELEMENT_NAMES[e]])
info_box.add_child(_wrapped("Aufwerten braucht: " + ", ".join(need), 12, Color(0.85, 0.85, 0.9)))
if missing.is_empty():
var b := UiKit.button("Aufwerten", Color(0.28, 0.55, 0.36))
b.custom_minimum_size = Vector2(140, 26)
b.pressed.connect(func(): upgrade_pressed.emit())
info_box.add_child(b)
else:
var miss := []
for e in missing:
miss.append("%dx %s" % [missing[e], Data.ELEMENT_NAMES[e]])
info_box.add_child(_wrapped("Es fehlt: " + ", ".join(miss), 12, Color(0.95, 0.6, 0.5)))
func _refresh_log(game: Game) -> void:
_clear(log_box)
log_box.add_child(UiKit.label("Letzte Runde", 15, Color(0.75, 0.8, 0.95)))
var r := game.human_recap
if not r.is_empty():
var verdict := "unentschieden"
var col := Color(0.85, 0.85, 0.9)
if r["result"] > 0:
verdict = "gewonnen"
col = Color(0.6, 0.95, 0.7)
elif r["result"] < 0:
verdict = "verloren (-%d Leben)" % r["damage"]
col = Color(1.0, 0.6, 0.55)
log_box.add_child(_wrapped("Gegen %s: %s" % [r["opponent"], verdict], 13, col))
if r["total"] == 0:
log_box.add_child(_wrapped("Du hattest keine Einheiten aufgestellt.", 12,
Color(0.95, 0.75, 0.7)))
else:
log_box.add_child(_wrapped("%d von %d Einheiten überlebt, %.0f s" %
[r["alive"], r["total"], r["duration"]], 12, Color(0.8, 0.8, 0.86)))
var best := "Stärkste: %s (%d Schaden" % [r["best_name"], r["best_dealt"]]
best += ", %d geheilt)" % r["best_healed"] if r["best_healed"] > 0 else ")"
log_box.add_child(_wrapped(best, 12, Color(0.8, 0.8, 0.86)))
log_box.add_child(_wrapped("Gefährlichster Gegner: %s (%d Schaden)" %
[r["enemy_name"], r["enemy_dealt"]], 12, Color(0.95, 0.75, 0.7)))
if game.last_round_log.is_empty() and r.is_empty():
log_box.add_child(UiKit.label("-", 12, Color(0.55, 0.55, 0.6)))
for line in game.last_round_log:
log_box.add_child(_wrapped(line, 11, Color(0.6, 0.6, 0.68)))