164 lines
5.0 KiB
GDScript
164 lines
5.0 KiB
GDScript
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.deck] if screen.deck.visible else []
|
|
"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", null)
|
|
"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)
|
|
|
|
|