class_name BoosterScreen extends Control const CARD_W := 200 const CARD_H := 280 var app var cards: Array = [] var revealed := {} var new_ids := {} var coins_label: Label var msg_label: Label var b_buy: Button var b_all: Button var b_improve: Button var suggestion := "" var slots: Control var element_buttons: Array = [] class CardBack extends Control: signal clicked func _init(sz: Vector2) -> void: size = sz custom_minimum_size = sz mouse_filter = Control.MOUSE_FILTER_STOP focus_mode = Control.FOCUS_ALL focus_entered.connect(queue_redraw) focus_exited.connect(queue_redraw) func _gui_input(event: InputEvent) -> void: if event is InputEventMouseButton and event.pressed and event.button_index == MOUSE_BUTTON_LEFT: accept_event() clicked.emit() elif has_focus() and event.is_action_pressed("ui_accept"): accept_event() clicked.emit() func _draw() -> void: var rect := Rect2(Vector2.ZERO, size) draw_style_box(Style.box(Color("3c285a"), 8, Style.GOLD, 5 if has_focus() else 3), rect) Style.border(self, rect.grow(-15), Color("5a3c82"), 2, 6) Style.text(self, "?", 48, Style.GOLD, size / 2, "center", true) func slot_rect(i: int) -> Rect2: var gap := 20 var x0 := (1280 - 5 * CARD_W - 4 * gap) / 2 return Rect2(x0 + i * (CARD_W + gap), 230, CARD_W, CARD_H) func _ready() -> void: Style.label(self, "Booster", 36, Style.GOLD, Rect2(0, 20, 1280, 50), "center", true) coins_label = Style.label(self, "", 22, Style.GOLD, Rect2(0, 78, 1280, 30), "center") Style.label(self, "5 Karten pro Booster, mindestens eine seltene. Klicke auf eine Karte zum Aufdecken.", 16, Style.MUTED, Rect2(0, 115, 1280, 24), "center") Style.label(self, "Elementbooster (%d Münzen): nur Karten des Elements und seiner Kombos" % Profile.ELEMENT_BOOSTER_COST, 14, Style.MUTED, Rect2(0, 586, 1280, 22), "center") for i in Cards.ELEMENTS.size(): var e: String = Cards.ELEMENTS[i] element_buttons.append(Style.button(self, e, Rect2(322 + i * 162, 612, 150, 38), buy.bind(e), Style.darker(Cards.ELEMENT_COLORS[e], 0.8))) slots = Control.new() slots.mouse_filter = Control.MOUSE_FILTER_IGNORE add_child(slots) msg_label = Style.label(self, "", 17, Style.RED, Rect2(0, 700, 1280, 22), "center") b_buy = Style.button(self, "Booster kaufen (%d Münzen)" % Profile.BOOSTER_COST, Rect2(290, 720, 330, 48), buy, Color("5a4628")) b_all = Style.button(self, "Alle aufdecken", Rect2(640, 720, 200, 48), reveal_all) b_improve = Style.button(self, "", Rect2(360, 650, 560, 44), improve, Color("285a3c")) b_improve.visible = false Style.button(self, "Zurück", Rect2(860, 720, 130, 48), func(): app.show_screen(MenuScreen.new())) refresh() func _input(event: InputEvent) -> void: if event is InputEventKey and event.pressed and event.keycode == KEY_ESCAPE: app.show_screen(MenuScreen.new()) func buy(element: String = "") -> void: var p: Profile = app.profile var before: Dictionary = p.collection.duplicate() var got: Array = p.open_booster(null, element) if got.is_empty(): msg_label.text = "Nicht genug Münzen" msg_label.add_theme_color_override("font_color", Style.RED) return app.save() app.sfx.play("play") cards = got revealed = {} new_ids = {} for c in cards: if before.get(c.id, 0) == 0: new_ids[c.id] = true var notes: Array[String] = p.take_notices() msg_label.text = " · ".join(notes) msg_label.add_theme_color_override("font_color", Style.GREEN) refresh() func reveal(i: int) -> void: revealed[i] = true app.sfx.play("click") refresh() func reveal_all() -> void: for i in 5: revealed[i] = true refresh() ## Nimmt die vorgeschlagene Karte ins aktive Deck (ersetzt die schwächste). func improve() -> void: if suggestion == "": return var err: String = app.profile.improve_deck_with(suggestion) if err == "": app.save() msg_label.text = tr("%s ist jetzt im Deck %s") % [Cards.by_id(suggestion).title(), app.profile.deck_name()] msg_label.add_theme_color_override("font_color", Style.GREEN) suggestion = "" else: msg_label.text = err msg_label.add_theme_color_override("font_color", Style.RED) refresh() func refresh() -> void: var p: Profile = app.profile coins_label.text = "Münzen: %d" % p.coins b_buy.disabled = p.coins < Profile.BOOSTER_COST for b in element_buttons: b.disabled = p.coins < Profile.ELEMENT_BOOSTER_COST b_all.disabled = cards.is_empty() or revealed.size() >= 5 # Deck-Vorschlag, sobald alle Karten offen liegen suggestion = "" if not cards.is_empty() and revealed.size() >= 5: var ids: Array = cards.map(func(c): return c.id) var better: Array = p.deck_suggestions(ids) if not better.is_empty(): suggestion = better[0] b_improve.visible = suggestion != "" if suggestion != "": b_improve.text = tr("Deck verbessern: %s ins aktive Deck (%s)") % [Cards.by_id(suggestion).title(), p.deck_name()] Style.clear(slots) for i in 5: var r := slot_rect(i) if cards.is_empty(): Style.panel(slots, r, Style.PANEL, 8, Style.PANEL_LIGHT, 2) elif revealed.has(i): var c: Cards.Card = cards[i] var v := CardView.new(c, r.size) v.position = r.position slots.add_child(v) Style.label(slots, tr(c.rarity), 16, Cards.RARITY_COLORS[c.rarity], Rect2(r.position.x, r.end.y + 8, r.size.x, 24), "center", true) if new_ids.has(c.id): Style.label(slots, "Neu!", 16, Style.GREEN, Rect2(r.position.x, r.end.y + 32, r.size.x, 24), "center", true) else: Style.label(slots, "jetzt %dx" % p.collection[c.id], 14, Style.MUTED, Rect2(r.position.x, r.end.y + 32, r.size.x, 24), "center") else: var back := CardBack.new(r.size) back.position = r.position back.clicked.connect(reveal.bind(i)) slots.add_child(back)