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>
104 lines
4.4 KiB
GDScript
104 lines
4.4 KiB
GDScript
class_name LuneUnitCard
|
|
extends Button
|
|
## Purchase card: real-model portrait, name, role, gold price, hotkey and availability.
|
|
## The champion variant uses the copper card style, a hatched portrait field and an
|
|
## "EINMALIG" tag, so temporary attack champions never read like permanent troops.
|
|
|
|
const ROLE_GLYPHS: Dictionary = {"front": "tank", "melee": "melee", "ranged": "ranged", "splash": "splash", "support": "support",
|
|
"schutz": "tank", "druck": "tempo", "siege": "siege"}
|
|
const ROLE_TEXT: Dictionary = {"front": "Tank", "melee": "Nahkampf", "ranged": "Fernkampf", "splash": "Fläche", "support": "Support",
|
|
"schutz": "Schutz", "druck": "Druck", "siege": "Belagerung"}
|
|
|
|
var type_id: String = ""
|
|
var champion: bool = false
|
|
var cost: int = 0
|
|
var reason: String = ""
|
|
var portrait: LunePortraitRect
|
|
var _name: Label
|
|
var _role_glyph: LuneGlyph
|
|
var _role: Label
|
|
var _coin: LuneGlyph
|
|
var _cost: Label
|
|
var _key: Label
|
|
var _tag: HBoxContainer
|
|
var _lock: LuneGlyph
|
|
|
|
func _init() -> void:
|
|
theme_type_variation = "HudCard"
|
|
focus_mode = Control.FOCUS_ALL
|
|
mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
|
|
custom_minimum_size = Vector2(116, 132)
|
|
var column := VBoxContainer.new()
|
|
column.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
|
|
column.offset_left = 6
|
|
column.offset_right = -6
|
|
column.offset_top = 6
|
|
column.offset_bottom = -5
|
|
column.add_theme_constant_override("separation", 1)
|
|
column.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
add_child(column)
|
|
portrait = LunePortraitRect.new()
|
|
portrait.custom_minimum_size = Vector2(0, 62)
|
|
portrait.size_flags_vertical = Control.SIZE_EXPAND_FILL
|
|
column.add_child(portrait)
|
|
_key = LuneUiTheme.label("", "HudCaps", portrait)
|
|
_key.position = Vector2(4, 1)
|
|
_key.add_theme_color_override("font_color", LuneUiTheme.BRONZE_LIGHT)
|
|
_tag = HBoxContainer.new()
|
|
_tag.add_theme_constant_override("separation", 2)
|
|
_tag.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
_tag.visible = false
|
|
portrait.add_child(_tag)
|
|
_tag.set_anchors_and_offsets_preset(Control.PRESET_TOP_RIGHT)
|
|
_tag.grow_horizontal = Control.GROW_DIRECTION_BEGIN
|
|
_tag.offset_right = -3
|
|
_tag.offset_top = 1
|
|
LuneGlyph.make("hourglass", LuneUiTheme.CHAMPION, 13.0, _tag)
|
|
var once := LuneUiTheme.label("1 WELLE", "HudCaps", _tag)
|
|
once.add_theme_color_override("font_color", LuneUiTheme.CHAMPION)
|
|
_lock = LuneGlyph.make("lock", LuneUiTheme.MUTED, 18.0, portrait)
|
|
_lock.set_anchors_and_offsets_preset(Control.PRESET_CENTER)
|
|
_lock.visible = false
|
|
_name = LuneUiTheme.label("", "HudText", column)
|
|
_name.horizontal_alignment = HORIZONTAL_ALIGNMENT_CENTER
|
|
_name.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
|
|
_name.clip_text = true
|
|
var role_row := HBoxContainer.new()
|
|
role_row.alignment = BoxContainer.ALIGNMENT_CENTER
|
|
role_row.add_theme_constant_override("separation", 4)
|
|
role_row.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
column.add_child(role_row)
|
|
_role_glyph = LuneGlyph.make("", LuneUiTheme.MUTED, 14.0, role_row)
|
|
_role = LuneUiTheme.label("", "HudMuted", role_row)
|
|
var cost_row := HBoxContainer.new()
|
|
cost_row.alignment = BoxContainer.ALIGNMENT_CENTER
|
|
cost_row.add_theme_constant_override("separation", 4)
|
|
cost_row.mouse_filter = Control.MOUSE_FILTER_IGNORE
|
|
column.add_child(cost_row)
|
|
_coin = LuneGlyph.make("coin", LuneUiTheme.GOLD, 15.0, cost_row)
|
|
_cost = LuneUiTheme.label("", "HudValue", cost_row)
|
|
|
|
func setup(id: String, model_id: String, title: String, role_key: String, price: int, hotkey: String = "", is_champion: bool = false) -> void:
|
|
type_id = id
|
|
champion = is_champion
|
|
cost = price
|
|
theme_type_variation = "HudChampionCard" if champion else "HudCard"
|
|
portrait.show_model(model_id)
|
|
_name.text = title
|
|
_role_glyph.glyph = ROLE_GLYPHS.get(role_key, "melee")
|
|
_role.text = ROLE_TEXT.get(role_key, role_key)
|
|
_cost.text = str(price)
|
|
_key.text = hotkey
|
|
_key.visible = not hotkey.is_empty()
|
|
_tag.visible = champion
|
|
portrait.hatch = Color(LuneUiTheme.CHAMPION, .13) if champion else Color(0, 0, 0, 0)
|
|
|
|
## ok = purchasable now; otherwise `why` explains it (tooltip) and the card greys out.
|
|
func set_available(ok: bool, why: String = "", locked: bool = false, unaffordable: bool = false) -> void:
|
|
reason = why
|
|
if disabled != (not ok):
|
|
disabled = not ok
|
|
portrait.dimmed = not ok
|
|
_lock.visible = locked
|
|
_cost.add_theme_color_override("font_color", LuneUiTheme.DANGER if unaffordable else LuneUiTheme.BRIGHT)
|
|
_name.add_theme_color_override("font_color", LuneUiTheme.MUTED if not ok else LuneUiTheme.TEXT)
|