saumwacht-godot/scripts/luneraria/ui/components/item_slot.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

93 lines
4.1 KiB
GDScript

class_name LuneItemSlot
extends Button
## A hero item: either one of the three slots (compact: symbol only) or a card in the item
## shop (symbol, name, cost, main effect, state). States say why something cannot be done:
## equipped, available, unaffordable, incompatible (hero level), unique (already carried),
## slots full, locked (plan committed) or an empty slot.
enum State { EMPTY, EQUIPPED, AVAILABLE, UNAFFORDABLE, INCOMPATIBLE, UNIQUE, FULL, LOCKED }
const STATE_TEXT: Dictionary = {State.EQUIPPED: "AUSGERÜSTET", State.AVAILABLE: "KAUFBAR", State.UNAFFORDABLE: "ZU TEUER",
State.INCOMPATIBLE: "STUFE FEHLT", State.UNIQUE: "GETRAGEN", State.FULL: "PLÄTZE VOLL", State.LOCKED: "GESPERRT", State.EMPTY: "LEER"}
const ITEM_COLORS: Dictionary = {"basaltschild": Color("9fb2c8"), "glutklinge": Color("ff9a5a"), "rankenmantel": Color("8fd08a"),
"funkenfokus": Color("f5d76a"), "quellamulett": Color("7ad6e6"), "kristallsplitter": Color("c7a2ff")}
var item_id: String = ""
var state: int = State.EMPTY
var compact: bool = true
var _glyph: LuneGlyph
var _name: Label
var _effect: Label
var _cost: Label
var _badge: LuneStatusBadge
static func color_of(id: String) -> Color:
return ITEM_COLORS.get(id, LuneUiTheme.MUTED)
func _init(is_compact: bool = true) -> void:
compact = is_compact
theme_type_variation = "HudChip" if compact else "HudCard"
focus_mode = Control.FOCUS_ALL
mouse_default_cursor_shape = Control.CURSOR_POINTING_HAND
if compact:
custom_minimum_size = Vector2(30, 30)
_glyph = LuneGlyph.new()
_glyph.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
_glyph.offset_left = 5
_glyph.offset_top = 5
_glyph.offset_right = -5
_glyph.offset_bottom = -5
add_child(_glyph)
return
custom_minimum_size = Vector2(0, 74)
var row := HBoxContainer.new()
row.set_anchors_and_offsets_preset(Control.PRESET_FULL_RECT)
row.offset_left = 10
row.offset_right = -8
row.offset_top = 6
row.offset_bottom = -6
row.add_theme_constant_override("separation", 10)
row.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(row)
_glyph = LuneGlyph.make("", Color.WHITE, 34.0, row)
var column := VBoxContainer.new()
column.add_theme_constant_override("separation", 0)
column.size_flags_horizontal = Control.SIZE_EXPAND_FILL
column.alignment = BoxContainer.ALIGNMENT_CENTER
column.mouse_filter = Control.MOUSE_FILTER_IGNORE
row.add_child(column)
var head := HBoxContainer.new()
head.add_theme_constant_override("separation", 6)
head.mouse_filter = Control.MOUSE_FILTER_IGNORE
column.add_child(head)
_name = LuneUiTheme.label("", "HudValue", head)
_name.size_flags_horizontal = Control.SIZE_EXPAND_FILL
LuneGlyph.make("coin", LuneUiTheme.GOLD, 14.0, head)
_cost = LuneUiTheme.label("", "HudValue", head)
_effect = LuneUiTheme.label("", "HudMuted", column)
_effect.text_overrun_behavior = TextServer.OVERRUN_TRIM_ELLIPSIS
_effect.clip_text = true
_badge = LuneStatusBadge.new()
column.add_child(_badge)
_badge.size_flags_horizontal = Control.SIZE_SHRINK_BEGIN
func set_item(id: String, new_state: int) -> void:
item_id = id
state = new_state
var item: Dictionary = LuneContent.ITEMS.get(id, {})
var tint: Color = color_of(id)
var usable: bool = new_state in [State.AVAILABLE, State.EQUIPPED]
_glyph.glyph = id if not id.is_empty() else ""
_glyph.color = tint if usable or compact else Color(tint, .45)
if compact:
disabled = id.is_empty()
return
_name.text = str(item.get("name", ""))
_cost.text = str(int(item.get("cost", 0)))
_cost.add_theme_color_override("font_color", LuneUiTheme.DANGER if new_state == State.UNAFFORDABLE else LuneUiTheme.BRIGHT)
_effect.text = str(item.get("text", ""))
var badge_color: Color = LuneUiTheme.GOOD if new_state == State.EQUIPPED else (LuneUiTheme.BRONZE_LIGHT if new_state == State.AVAILABLE else LuneUiTheme.MUTED)
if new_state == State.UNAFFORDABLE:
badge_color = LuneUiTheme.DANGER
var glyphs: Dictionary = {State.EQUIPPED: "check", State.INCOMPATIBLE: "lock", State.LOCKED: "lock", State.UNIQUE: "check"}
_badge.set_state(STATE_TEXT.get(new_state, ""), badge_color, glyphs.get(new_state, ""), new_state == State.EQUIPPED)
disabled = not (new_state == State.AVAILABLE or new_state == State.EQUIPPED)