update
Some checks failed
Tests / headless (push) Has been cancelled
Tests / fenster-schnell (push) Has been cancelled
Tests / fenster-voll (push) Has been cancelled
Tests / balance (push) Has been cancelled

This commit is contained in:
team3
2026-10-03 01:17:27 +02:00
parent 24a03ed1ee
commit 5f9442497a
27 changed files with 1040 additions and 871 deletions

View File

@@ -54,11 +54,11 @@ func right_click() -> void:
await right_click_at(Vector2(5, 5))
func right_click_at(pos: Vector2) -> void:
func right_click_at(pos: Vector2, button: int = MOUSE_BUTTON_RIGHT) -> void:
var down := InputEventMouseButton.new()
down.position = pos
down.global_position = pos
down.button_index = MOUSE_BUTTON_RIGHT
down.button_index = button
down.pressed = true
get_viewport().push_input(down)
var up: InputEventMouseButton = down.duplicate()
@@ -219,20 +219,42 @@ func target_view(scr, valid: Array) -> Control:
return null
## Nimmt alle offenen Wahlen des Spielers (immer die erste Karte), auch über das Netz.
func pick_all(scr) -> void:
var guard := 0
while scr.game != null and not scr.perspective.offer.is_empty() and guard < 60:
guard += 1
if scr.pick_views.is_empty():
await frames(1)
continue
var n: int = scr.perspective.offer.size()
await click(scr.pick_views[0])
var w := 0
while scr.game != null and scr.perspective.offer.size() == n and w < 120:
await frames(1)
w += 1
## Zieht eine Karte oder Kachel auf eine andere und hält sie dort, bis die beiden verschmelzen.
func drag_fuse(scr, from: Control, to: Control) -> void:
await frames(20) # Kacheln sind noch unterwegs (Einfliegen, Nachrücken)
await settle(scr)
var a := from.get_global_rect().get_center()
var b := to.get_global_rect().get_center()
var down := InputEventMouseButton.new()
down.position = a
down.global_position = a
down.button_index = MOUSE_BUTTON_LEFT
down.pressed = true
get_viewport().push_input(down)
await frames(1)
for i in range(1, 6):
var m := InputEventMouseMotion.new()
m.position = a.lerp(b, i / 5.0)
m.global_position = m.position
m.button_mask = MOUSE_BUTTON_MASK_LEFT
get_viewport().push_input(m)
await frames(1)
check(scr.drag_ghost != null and scr.drag_target != null, "Karte schwebt über einem Verschmelzungsziel")
var waited := 0
while scr.drag_ghost != null and waited < 240:
var still := InputEventMouseMotion.new() # die Maus bleibt auf dem Ziel, auch wenn die echte zuckt
still.position = b
still.global_position = b
still.button_mask = MOUSE_BUTTON_MASK_LEFT
get_viewport().push_input(still)
await frames(1)
waited += 1
var up: InputEventMouseButton = down.duplicate()
up.pressed = false
up.position = b
up.global_position = b
get_viewport().push_input(up)
await frames(2)
## Legt, was bezahlbar ist.
@@ -257,10 +279,9 @@ func human_turn(scr) -> void:
if g.winner != "" or not g.can_draw(g.human)[0]:
break
var mana: int = g.human.energy
var hand: int = g.human.hand.size()
await click(scr.deck)
check(g.human.energy == mana - Game.DRAW_COST and not scr.pick_views.is_empty(), "gezogen: drei zur Wahl")
await pick_all(scr)
check(scr.pick_views.is_empty(), "gewählt")
check(g.human.energy == mana - Game.DRAW_COST and g.human.hand.size() == hand + 1, "gezogen: eine Karte")
for i in 12:
var ready: Array = scr.own_views.filter(func(v): return v.creature.can_attack())
if ready.is_empty() or g.winner != "":
@@ -284,7 +305,7 @@ func human_turn(scr) -> void:
targets.append(c)
await settle(scr)
await click(target_view(scr, targets))
check(scr.selected == null and cr.attacks_left < cr.attacks_per_turn(), "Angriff ausgeführt")
check(scr.selected == null and cr.attacks_done > 0, "Angriff ausgeführt")
if g.winner == "":
await click(scr.b_end)
@@ -293,7 +314,6 @@ func start_battle() -> void:
await click(find_button("Einzelspieler"))
check(screen() is OpponentSelectScreen, "Gegnerauswahl")
await click(find_button("Starten"))
await pick_all(screen())
func test_gegnerauswahl() -> void:
@@ -310,12 +330,9 @@ func test_gegnerauswahl() -> void:
check(hard is BattleScreen and hard.game.players.size() == 2, "Duell gestartet")
var opp: Game.Player = hard.game.opponent
check(opp.max_life == Profile.DIFFICULTIES.schwer.life and hard.smart_ai, "Schwer: Gegner mit %d Leben, Vorausschau-KI" % Profile.DIFFICULTIES.schwer.life)
check(hard.game.human.offer.size() == Game.START_OFFER and hard.game.human.hand.is_empty() and hard.pick_layer.visible,
"Start: fünf Karten zur Wahl, Hand leer")
check(hard.game.human.offer.all(func(c): return c.cost <= Game.START_MANA + 1), "alle fünf sind im ersten Zug spielbar")
await shot("05_startwahl")
await pick_all(hard)
check(hard.game.human.hand.size() == Game.START_PICKS and not hard.pick_layer.visible, "drei behalten, Wahl geschlossen")
check(hard.game.human.hand.size() == Game.START_HAND and hard.hand_views.size() == Game.START_HAND, "Start: fünf Karten auf der Hand")
check(hard.game.human.hand.all(func(c): return c.cost <= Game.START_MANA + 1), "alle fünf sind im ersten Zug spielbar")
await shot("05_starthand")
check(hard.hero_panels[opp].position == BattleLayout.OPP_BOX.position, "der Gegner steht oben in der Mitte")
await shot("11_kampf")
await give_up()
@@ -323,7 +340,6 @@ func test_gegnerauswahl() -> void:
await click(find_button("Leicht"))
await click(find_button("Starten"))
var easy = screen()
await pick_all(easy)
opp = easy.game.opponent
check(opp.max_life == Profile.DIFFICULTIES.leicht.life and not easy.smart_ai, "Leicht: Gegner mit %d Leben, einfache KI" % Profile.DIFFICULTIES.leicht.life)
check(easy.game.players[0].max_energy == Game.START_MANA and easy.game.human.life == Game.START_LIFE, "gleiche Regeln für beide")
@@ -393,21 +409,21 @@ func test_sammlung() -> void:
await frames(1)
var phoenix = scr.grid.views().filter(func(v): return v.card.id == "ff_phoenix")[0]
await click(phoenix)
check(scr.selected.id == "ff_phoenix" and p.rarity("ff_phoenix") == "gewöhnlich", "Karte gewählt, noch gewöhnlich")
check(scr.selected.id == "ff_phoenix" and p.rarity("ff_phoenix") == "Common", "Karte gewählt, noch Common")
await click(scr.b_upgrade)
check(p.level("ff_phoenix") == 1 and p.dust == 5000 - Profile.DUST_UPGRADE["selten"], "auf selten aufgewertet")
check(p.level("ff_phoenix") == 1 and p.dust == 5000 - Profile.DUST_UPGRADE["Rare"], "auf Rare aufgewertet")
scr.search_box.text = ""
scr.search_box.text_changed.emit("")
await frames(1)
var first: CardView = scr.grid.views()[0]
check(first.card.id == "ff_phoenix" and first.rarity == "selten", "die aufgewertete Karte steht vorn in der Sammlung")
var front: Array = scr.grid.views().slice(0, p.upgraded_count())
check(front.all(func(v): return v.rarity != "Common") and front.any(func(v): return v.card.id == "ff_phoenix" and v.rarity == "Rare"), "aufgewertete Karten stehen vorn in der Sammlung, der Phönix als Rare dabei")
scr.search_box.text = "Phönix"
scr.search_box.text_changed.emit("Phönix")
await frames(1)
check(Profile.load_or_new(SAVE).level("ff_phoenix") == 1, "Sammlung gespeichert")
var dust: int = p.dust
await click(scr.b_dismantle)
check(p.level("ff_phoenix") == 0 and p.dust == dust + Profile.DUST_DISMANTLE["selten"], "wieder zerlegt")
check(p.level("ff_phoenix") == 0 and p.dust == dust + Profile.DUST_DISMANTLE["Rare"], "wieder zerlegt")
await shot("20_sammlung")
await click(find_button("Zurück"))
check(screen() is MenuScreen, "zurück im Menü")
@@ -487,22 +503,21 @@ func test_kampf_steuerung() -> void:
scr.ai_delay = 0.0
await wait_for_human(scr)
var g: Game = scr.game
g.human.energy = 20 # die Wahl ist zufällig, hier soll nur die Steuerung geprüft werden
g.human.hand = [Cards.by_id("f_wolf")]
g.human.energy = 20 # die Starthand ist zufällig, hier soll nur die Steuerung geprüft werden
g.human.hand = [Cards.by_id("f_wolf").copy()]
scr.refresh()
check(scr.hand_views.size() == 1 and scr.deck.enabled and scr.pick_views.is_empty(), "eine Handkarte, Stapel bereit, keine Wahl offen")
# Ziehen: 1 Mana weg, drei zur Wahl, eine landet auf der Hand
check(scr.hand_views.size() == 1 and scr.deck.enabled, "eine Handkarte, Stapel bereit")
# Ziehen: 1 Mana weg, eine Karte landet auf der Hand
var mana: int = g.human.energy
await click(scr.deck)
check(g.human.energy == mana - Game.DRAW_COST and scr.pick_views.size() == Game.OFFER_SIZE and scr.pick_layer.visible, "gezogen: drei Karten zur Wahl")
var wanted: Cards.Card = scr.pick_views[1].card
await click(scr.pick_views[1])
check(g.human.hand.size() == 2 and g.human.hand[1].id == wanted.id and not scr.pick_layer.visible, "gewählt, liegt auf der Hand")
# Ausspielen kostet die Kartenkosten
check(g.human.energy == mana - Game.DRAW_COST and g.human.hand.size() == 2 and scr.hand_views.size() == 2, "gezogen: eine Karte auf der Hand")
check(g.human.hand[1].cost <= g.human.max_energy, "nur bezahlbare Karten")
# Ausspielen kostet die Kartenkosten; das Wesen greift noch nicht an
var board_before: int = g.human.board.size()
mana = g.human.energy
await key(KEY_1)
check(g.human.board.size() == board_before + 1 and g.human.energy == mana - Cards.by_id("f_wolf").cost, "Wesen per Taste gespielt, Kosten bezahlt")
check(not g.human.board.back().can_attack(), "frisch gelegt greift es noch nicht an")
# Rückgängig: Wesen zurück auf die Hand, Mana zurück
check(scr.b_undo.visible, "Rückgängig angeboten")
await click(scr.b_undo)
@@ -513,21 +528,16 @@ func test_kampf_steuerung() -> void:
check(g.human.board.size() == board_before + 1, "erneut gespielt")
# Ziehen per Taste
mana = g.human.energy
var hand_before: int = g.human.hand.size()
await key(KEY_Z)
check(g.human.energy == mana - Game.DRAW_COST and scr.pick_layer.visible, "Z zieht")
await key(KEY_1)
check(not scr.pick_layer.visible, "1 wählt die erste Karte")
check(g.human.energy == mana - Game.DRAW_COST and g.human.hand.size() == hand_before + 1, "Z zieht")
await shot("22_kampf_steuerung")
# Gamepad: A auf dem Stapel zieht, Steuerkreuz wählt die zweite Karte, A nimmt sie
# Gamepad: A auf dem Stapel zieht
await pad(JOY_BUTTON_DPAD_LEFT)
check(scr.gp_zone == "deck" and scr.cursor_layer.get_child_count() == 1, "Gamepad-Zeiger auf dem Stapel")
var hand_before: int = g.human.hand.size()
hand_before = g.human.hand.size()
await pad(JOY_BUTTON_A)
check(scr.pick_layer.visible, "Gamepad A zieht")
await pad(JOY_BUTTON_DPAD_RIGHT)
check(scr.gp_zone == "pick" and scr.gp_index == 1, "Zeiger auf der zweiten Karte der Wahl")
await pad(JOY_BUTTON_A)
check(g.human.hand.size() == hand_before + 1 and not scr.pick_layer.visible, "Gamepad A nimmt die Karte")
check(g.human.hand.size() == hand_before + 1, "Gamepad A zieht")
scr.ai_delay = 0.75
await key(KEY_SPACE)
check(g.current() != g.human or g.turn >= 2, "Zug per Leertaste beendet")
@@ -562,7 +572,6 @@ func test_kampf_grenzen() -> void:
while g.human.hand.size() < Game.MAX_HAND and guard < 30:
guard += 1
await click(scr.deck)
await pick_all(scr)
check(g.human.hand.size() == Game.MAX_HAND, "Hand auf %d gefüllt" % Game.MAX_HAND)
check(not scr.deck.enabled, "bei voller Hand lässt sich nichts ziehen")
await click(scr.deck)
@@ -573,20 +582,17 @@ func test_kampf_grenzen() -> void:
guard += 1
if g.human.hand.is_empty():
await click(scr.deck)
await pick_all(scr)
await key(KEY_1)
check(g.human.board.size() == Game.MAX_BOARD, "Feld mit %d Wesen voll" % Game.MAX_BOARD)
if g.human.hand.is_empty():
await click(scr.deck)
await pick_all(scr)
await key(KEY_1)
check(scr.msg_label.text == tr("Dein Feld ist voll"), "Meldung bei vollem Feld: " + scr.msg_label.text)
await shot("25_kampf_voll")
# Verschmelzen macht wieder Platz
# Verschmelzen per Ziehen macht wieder Platz
var before: int = g.human.board.size()
await click(scr.b_fuse)
await click(scr.own_views[0])
await click(scr.own_views[1])
scr.hold_time = 0.3
await drag_fuse(scr, scr.own_views[0], scr.own_views[1])
check(g.human.board.size() == before - 1, "Verschmelzen macht einen Platz frei")
# Ohne Mana kein Ziehen
g.human.energy = 0
@@ -596,12 +602,13 @@ func test_kampf_grenzen() -> void:
await give_up()
## Elementregel, verdeckt legen, Kartenmenü und Verschmelzen im Kampf.
## Elementboni, verdeckt legen, Kartenmenü und Verschmelzen (per Ziehen und per Menü) im Kampf.
func test_kampf_elemente_und_verschmelzen() -> void:
await start_battle()
var scr = screen()
check(scr is BattleScreen, "Kampf gestartet")
scr.ai_delay = 0.0
scr.hold_time = 0.3
await wait_for_human(scr)
var g: Game = scr.game
g.human.board.clear()
@@ -609,7 +616,7 @@ func test_kampf_elemente_und_verschmelzen() -> void:
var put := func(p: Game.Player, id: String, hidden: bool = false) -> Game.Creature:
var cr := Game.Creature.new(Cards.by_id(id).copy(), p, g.next_uid)
g.next_uid += 1
cr.attacks_left = 1
cr.ready = true
cr.hidden = hidden
p.board.append(cr)
return cr
@@ -620,56 +627,70 @@ func test_kampf_elemente_und_verschmelzen() -> void:
var secret: Game.Creature = put.call(scr.opponent(), "f_kobold", true)
g.human.hand = [Cards.by_id("f_kobold").copy(), Cards.by_id("l_wind").copy()]
g.human.energy = 20
g.human.looks = {"w_reiter": 3}
g.apply_auras()
scr.refresh()
await frames(2)
check(scr.element_view.text() == "Feuer 2 · Wasser 1 · Erde 0 · Luft 1", "Zähler ohne das verdeckte Wesen: " + scr.element_view.text())
check(scr.tiles[secret.uid].secret and scr.hand_views[0].bonus == 0, "fremdes verdecktes Wesen zeigt nur den Rücken, noch kein Bonus in Sicht")
# verdeckt legen über das Kartenmenü (Rechtsklick auf die Handkarte)
var menu_text := "Verdeckt legen ◆ %d" % Cards.by_id("f_kobold").cost
check(scr.element_view.text() == "Feuer 2 (Doppelschlag) · Wasser 1 · Erde 0 · Luft 1", "Zähler ohne das verdeckte Wesen, Feuerpaar: " + scr.element_view.text())
check(g.human.board[0].keywords() == ["Doppelschlag"] and scr.tiles[secret.uid].secret and scr.hand_views[0].bonus == 1, "Feuerpaar gibt Doppelschlag; fremdes Verdecktes zeigt den Rücken; der Kobold würde den Stapel voll machen")
# Rechtsklick auf die Handkarte: Menü mit Verdeckt legen und Eigenschaften, ohne Verschmelzen
await hover(scr.hand_views[0])
await right_click_at(scr.hand_views[0].get_global_rect().get_center())
check(scr.menu_layer.visible and find_button(menu_text, scr.menu_layer) != null, "Rechtsklick öffnet das Kartenmenü mit „Verdeckt legen“")
check(scr.menu_layer.visible and find_button("Verdeckt legen ◆ 1", scr.menu_layer) != null and find_button("Spott ◆ 2", scr.menu_layer) != null, "Rechtsklick öffnet das Kartenmenü")
check(find_button("Verschmelzen mit … ◆ 1", scr.menu_layer) == null, "kein Verschmelzen im Rechtsklick-Menü")
await shot("23_kartenmenue")
await click(find_button(menu_text, scr.menu_layer))
await right_click()
check(not scr.menu_layer.visible, "Rechtsklick schließt das Menü")
# Mittlere Maustaste legt die Handkarte verdeckt
var mana: int = g.human.energy
await right_click_at(scr.hand_views[0].get_global_rect().get_center(), MOUSE_BUTTON_MIDDLE)
var mine_hidden: Game.Creature = g.human.board[3]
check(mine_hidden.hidden and not scr.menu_layer.visible and scr.element_view.text().begins_with("Feuer 2"), "verdeckt gelegt, zählt nicht")
# aufdecken per Klick auf das eigene verdeckte Wesen (erst, wenn es aus der Hand angekommen ist)
check(mine_hidden.hidden and g.human.energy == mana - 1 and scr.element_view.text().begins_with("Feuer 2"), "mittlere Maustaste legt verdeckt, zählt nicht")
# Rechtsklick auf ein eigenes Wesen: Eigenschaften kaufen
await right_click_at(scr.own_views[0].get_global_rect().get_center())
check(scr.menu_layer.visible and find_button("Doppelschlag ◆ 4", scr.menu_layer) != null and find_button("Verschmelzen mit … ◆ 1", scr.menu_layer) == null, "Wesen-Menü mit Eigenschaften, ohne Verschmelzen")
var wolf: Game.Creature = g.human.board[0]
await click(find_button("Spott ◆ %d" % Cards.KEYWORD_COST["Spott"], scr.menu_layer))
check(wolf.has("Spott") and "Spott" in wolf.card.keywords and g.human.energy == mana - 1 - Cards.KEYWORD_COST["Spott"], "Spott gekauft")
while scr.own_views[3].busy:
await frames(1)
await click(scr.own_views[3])
check(not mine_hidden.hidden and scr.element_view.text().begins_with("Feuer 3"), "aufgedeckt, zählt jetzt")
put.call(g.human, "f_kobold")
g.apply_auras()
scr.refresh()
await frames(2)
check(scr.element_view.text().begins_with("Feuer 4 (+1/+1)") and "Luft 1 (-1/-1)" in scr.element_view.text(), "vier Feuer: Bonus und Malus angezeigt: " + scr.element_view.text())
check(g.human.board[0].power() == 4 and falke.power() == 2, "Feuerwesen +1, Luftwesen -1")
check(scr.hand_views[0].bonus == -1, "die Luftkarte auf der Hand zeigt -1")
await shot("23b_vier_feuer")
# Verbessern über das Menü
var wolf: Game.Creature = g.human.board[0]
scr.open_menu(wolf, Rect2(scr.own_views[0].slot, scr.own_views[0].size))
var mana: int = g.human.energy
await click(find_button("Schild ◆ %d" % Cards.KEYWORD_COST["Schild"], scr.menu_layer))
check(wolf.shield and "Schild" in wolf.card.keywords and g.human.energy == mana - Cards.KEYWORD_COST["Schild"], "Schild gekauft")
check(mine_hidden.hidden and scr.msg_label.text == "Feuerkobold kann erst im nächsten Zug aufgedeckt werden", "im Legezug nicht aufzudecken: " + scr.msg_label.text)
mine_hidden.ready = true
await click(scr.own_views[3])
check(not mine_hidden.hidden and scr.element_view.text().begins_with("Feuer 3 (+1/+1)"), "aufgedeckt: drei Feuer, +1/+1: " + scr.element_view.text())
check(wolf.power() == 4 and falke.power() == 3 and mine_hidden.can_attack(), "Feuerwesen +1, kein Malus für Luft, aufgedeckt greift sofort an")
check(scr.hand_views[0].bonus == 0, "die Luftkarte auf der Hand zeigt keinen Bonus")
await shot("23b_drei_feuer")
# Angriffsziel: Elementvorteil, verdeckte ohne Anzeige, Held gesperrt
await click(scr.own_views[0])
check(scr.selected == wolf and scr.tiles[falke.uid].matchup == 1 and scr.tiles[secret.uid].matchup == 0, "Angreifer gewählt: +1 gegen Luft, nichts gegen Verdeckte")
check(not g.can_attack(wolf, scr.opponent())[0], "Held nicht angreifbar, solange Wesen stehen")
await click(scr.tiles[secret.uid])
check(not secret.hidden and not (secret in scr.opponent().board), "Angriff deckt auf und tötet den Kobold")
check(wolf.attacks_left() == 1, "Doppelschlag: ein Angriff bleibt")
await right_click()
# Verschmelzen
await click(scr.b_fuse)
check(scr.fusing and scr.b_fuse.text == "Abbrechen", "Verschmelzen ausgewählt")
await click(scr.own_views[1])
check(scr.fuse_first != null, "erstes Wesen gewählt")
await shot("24_verschmelzen")
# Verschmelzen per Ziehen: den Aschekrieger auf den Wellenreiter ziehen und kurz halten
mana = g.human.energy
await click(scr.own_views[2])
check(g.human.board.any(func(c): return c.name == "Dampf") and g.human.energy == mana - 1, "zu Dampf verschmolzen, 1 Mana bezahlt")
check(not scr.fusing, "Modus beendet")
var before: int = g.human.board.size()
await drag_fuse(scr, scr.own_views[1], scr.own_views[2])
check(g.human.board.size() == before - 1 and g.human.board.any(func(c): return c.name == "Dampf") and g.human.energy == mana - 1, "zu Dampf verschmolzen, 1 Mana bezahlt")
var dampf: Game.Creature = g.human.board.filter(func(c): return c.name == "Dampf")[0]
check(scr.tiles[dampf.uid].rarity() == "Ultra Rare" and dampf.card.look == 3, "die Fusion trägt die höhere Stufe (Wellenreiter war Ultra Rare)")
await shot("24_verschmelzen")
# Verschmelzen auf der Hand per Ziehen
g.human.hand = [Cards.by_id("f_kobold").copy(), Cards.by_id("f_kobold").copy(), Cards.by_id("l_wind").copy()]
scr.refresh()
await frames(1)
await drag_fuse(scr, scr.hand_views[0], scr.hand_views[1])
check(g.human.hand.size() == 2 and g.human.hand[0].name == "Inferno" and g.human.hand[0].attack == 3 and g.human.hand[0].health == 2, "zwei Kobolde auf der Hand zu Inferno 3/2")
# Gamepad-Menü (Y) bietet Verdeckt legen und Verschmelzen mit …
scr.open_menu(g.human.hand[0], Rect2(scr.hand_views[0].position, scr.hand_views[0].size), true)
check(find_button("Verdeckt legen ◆ 2", scr.menu_layer) != null, "Gamepad-Menü: Verdeckt legen")
await click(find_button("Verschmelzen mit … ◆ 2", scr.menu_layer))
check(scr.fuse_first == g.human.hand[0], "Partner wählen")
await click(scr.hand_views[1])
check(g.human.hand.size() == 1 and g.human.hand[0].name == "Blitz", "Inferno und Windgeist zu Blitz")
await give_up()
@@ -701,7 +722,6 @@ func test_netzwerk() -> void:
var b = screen()
check(b is BattleScreen and b.is_online() and not b.is_client(), "Netzwerkkampf als Host")
b.ai_delay = 0.0
await pick_all(b)
var rounds := 0
while b.game != null and b.game.winner == "" and rounds < 2:
if b.game.current() == b.perspective:
@@ -807,7 +827,6 @@ func test_host_wechsel() -> void:
await frames(1)
w += 1
check(b.game != null and main.net.i_am_successor and not main.net.backup.is_empty(), "Nachfolger kennt den vollen Spielstand")
await pick_all(b)
main.net.rejoin_seconds = 3.0
_bot_quit(true)
w = 0
@@ -881,7 +900,6 @@ func test_kampagne() -> void:
await click(find_button("Kämpfen"))
var battle = screen()
check(battle is BattleScreen and battle.stage == 0, "Kampagnenkampf gestartet")
await pick_all(battle)
check(battle.game.opponent.name == "Fenn", "Fenn ist der Gegner")
check(battle.game.opponent.perks == ["feuer_angriff"] and battle.game.log.any(func(l): return l.begins_with("Fenn: Feuerwesen")), "Boss-Merkmal aktiv")
await shot("16_kampagne_kampf")
@@ -897,7 +915,6 @@ func test_kampagne() -> void:
await shot("27_kampagne_kapitel2")
await click(find_button("Kämpfen"))
var b2 = screen()
await pick_all(b2)
check(b2 is BattleScreen and b2.stage == 10 and b2.game.opponent.perks.size() == 2 and b2.game.opponent.life == 22, "Kapitel-2-Boss mit zwei Merkmalen und 22 Leben")
check(b2.game.human.perks == [main.profile.perk], "eigenes Merkmal im Kampf")
await give_up()
@@ -951,16 +968,17 @@ func test_kampf_abbrechen() -> void:
# Kartenvorschau: aufgewertete Karten zeigen ihre Seltenheit
g.human.energy = 10
var wolf := Game.Creature.new(Cards.by_id("f_wolf"), g.human, 9000)
wolf.ready = true
g.human.board.append(wolf)
g.human.hand.append(Cards.by_id("w_reiter"))
g.human.looks["w_reiter"] = Cards.RARITIES.find("episch")
g.human.looks["w_reiter"] = Cards.RARITIES.find("Super Rare")
scr.refresh()
var reiter_view = scr.hand_views.filter(func(v): return v.card.id == "w_reiter")[0]
check(reiter_view.rarity == "episch", "Handkarte trägt die eigene Stufe")
check(reiter_view.rarity == "Super Rare", "Handkarte trägt die eigene Stufe")
await hover(scr.element_view) # erst weg von der Hand, damit das Betreten sicher ausgelöst wird
await hover(reiter_view)
var previews = scr.preview_holder.get_children().filter(func(c): return c is CardView)
check(previews.size() == 1 and previews[0].rarity == "episch", "Vorschau ebenfalls")
check(previews.size() == 1 and previews[0].rarity == "Super Rare", "Vorschau ebenfalls")
await shot("21_kampf_vorschau")
if not scr.own_views.is_empty():
await click(scr.own_views[0])