class_name BattleGamepad extends RefCounted ## Gamepad-Steuerung des Kampfes: Steuerkreuz bewegt einen Zeiger über Stapel, Hand, eigene Wesen ## und Ziele, A bestätigt, B bricht ab, Start beendet den Zug, Y öffnet das Kartenmenü (im ## Gegnerzug: überspringen), X macht rückgängig. Verschmelzen: im Menü „Verschmelzen mit …“, ## dann A auf dem Partner. var screen # BattleScreen var active := false var zone := "deck" var index := 0 var targets: Array = [] func _init(s) -> void: screen = s func button(button: int) -> void: active = true if screen.game == null: return match button: JOY_BUTTON_START: if screen.my_turn() and not screen.any_overlay(): screen.end_turn() JOY_BUTTON_B: if screen.confirm.visible: screen.confirm.visible = false screen.cancel_all() zone = "deck" JOY_BUTTON_Y: if screen.b_skip.visible: screen.skip_ai = true elif screen.menu_layer.visible: screen.close_menu() else: var items := items() if not items.is_empty() and zone in ["hand", "own"]: var item = items[clampi(index, 0, items.size() - 1)] if zone == "hand": screen.open_menu(item.card, Rect2(item.position, item.size), true) else: screen.open_menu(item.creature, Rect2(item.slot, item.size), true) JOY_BUTTON_X: if screen.b_undo.visible: screen.undo() JOY_BUTTON_A: confirm() JOY_BUTTON_DPAD_LEFT: move(-1) JOY_BUTTON_DPAD_RIGHT: move(1) JOY_BUTTON_DPAD_UP, JOY_BUTTON_DPAD_DOWN: if zone != "target": _next_zone(1 if button == JOY_BUTTON_DPAD_DOWN else -1) screen.refresh() ## Wechselt den Bereich und überspringt leere (eine leere Hand ist keine Station). ## step 0: beim aktuellen Bereich bleiben, falls er etwas enthält. func _next_zone(step: int) -> void: var order := ["deck", "hand", "own"] var at := order.find(zone) index = 0 if step == 0 and not items().is_empty(): return var dir := -1 if step < 0 else 1 for i in order.size(): at = posmod(at + dir, order.size()) zone = order[at] if not items().is_empty(): return func items() -> Array: match zone: "deck": return screen.offer_views "hand": return screen.hand_views "own": return screen.own_views "target": return targets return [] func move(dir: int) -> void: var n := items().size() if n > 0: index = posmod(index + dir, n) func confirm() -> void: if screen.overlay.visible: screen.leave() return if screen.confirm.visible: return var items := items() if items.is_empty(): return index = clampi(index, 0, items.size() - 1) var item = items[index] match zone: "deck": screen.on_click("deck", index) "hand": screen.on_click("hand", item.card) "own": screen.on_click("own", item.creature) if screen.selected != null: targets = [] for v in screen.enemy_views: if screen.game.can_attack(screen.selected, v.creature)[0]: targets.append(v) for o in screen.others(): if o.alive() and screen.game.can_attack(screen.selected, o)[0]: targets.append(screen.hero_panels[o]) zone = "target" index = 0 "target": if item is CreatureView: screen.on_tile_click(item.creature) else: for o in screen.hero_panels: if screen.hero_panels[o] == item: screen.on_click("hero", o) zone = "own" _next_zone(0) ## Pulsierender Rahmen als Zeiger. class Highlight extends Control: var t := 0.0 func _process(delta: float) -> void: t += delta queue_redraw() func _draw() -> void: var a := 0.55 + 0.45 * sin(t * 6.0) Style.border(self, Rect2(Vector2.ZERO, size), Color(Style.GOLD, a), 4, 8) func draw_cursor() -> void: Style.clear(screen.cursor_layer) if not active or screen.game == null or not screen.my_turn(): return var items := items() if items.is_empty(): return index = clampi(index, 0, items.size() - 1) var item = items[index] var r: Rect2 = Rect2(item.slot, item.size) if item is CreatureView else Rect2(item.position, item.size) var hl := Highlight.new() hl.position = r.position - Vector2(6, 6) hl.size = r.size + Vector2(12, 12) hl.mouse_filter = Control.MOUSE_FILTER_IGNORE screen.cursor_layer.add_child(hl)