Lava abgeschwächt, Archetypen aus Datei mit CI-Messlauf, Kartentext folgt Schriftgröße, Gamepad in Menüs, Anleitung 2 mit sicherem Angriff, Übersetzungsprüfung, Lint und gestaffelte CI
Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com> Claude-Session: https://claude.ai/code/session_01QPgKvy5W9WRNFHjkm5QsHx
This commit is contained in:
@@ -196,7 +196,7 @@ func _ready() -> void:
|
||||
var opps := Campaign.opponents(guide.stage_index(), r, Game.deck_rating(app.profile.deck_cards()))
|
||||
opps[0].perks = []
|
||||
game = Game.new_battle_with(app.profile.deck_cards(), opps, r, true)
|
||||
guide.inject_cards(game.human.hand)
|
||||
guide.inject_cards(game)
|
||||
elif not challenge.is_empty():
|
||||
var rules: Dictionary = challenge.rules.duplicate()
|
||||
rules["target_rating"] = Game.deck_rating(app.profile.deck_cards())
|
||||
|
||||
@@ -8,7 +8,7 @@ const STEPS1 := [
|
||||
["Wesen greifen erst ab dem nächsten Zug an. Beende deinen Zug mit dem Knopf rechts oder der Leertaste.", "turn_passed"],
|
||||
["Grüne Rahmen zeigen angriffsbereite Wesen. Klicke ein Wesen und dann Fenn oder eines seiner Wesen. Wächter müssen zuerst fallen.", "attacked"],
|
||||
["Resonanz: Wesen mit gleichem Element geben sich gegenseitig Angriff. Spiele ein zweites Feuer- oder Erde-Wesen.", "resonance"],
|
||||
["Feldkombo: Ein Wesen neben einem eigenen Wesen mit anderem Element löst einen Effekt aus. Lava macht 1 Schaden an alle gegnerischen Wesen.", "combo"],
|
||||
["Feldkombo: Ein Wesen neben einem eigenen Wesen mit anderem Element löst einen Effekt aus. Lava macht 1 Schaden an das stärkste gegnerische Wesen.", "combo"],
|
||||
["Zauber wirken sofort. Funke oder Feuerball treffen auch Fenn direkt. Ziele wählst du per Klick, Rechtsklick bricht ab.", "spell"],
|
||||
["Fenn verliert bei 0 Leben. Tausche im ersten Zug einer Partie schwache Starthände (Mulligan). Viel Erfolg!", ""],
|
||||
]
|
||||
@@ -38,11 +38,13 @@ func stage_index() -> int:
|
||||
return 0 if part == 1 else 1
|
||||
|
||||
|
||||
## Teil 2 bekommt die Lehrkarten auf die Hand.
|
||||
func inject_cards(hand: Array) -> void:
|
||||
## Teil 2: Lehrkarten auf die eigene Hand; Mara bekommt Wesen, damit sie sicher in die Falle läuft.
|
||||
func inject_cards(g: Game) -> void:
|
||||
if part == 2:
|
||||
hand.append(Cards.by_id("w_falle"))
|
||||
hand.append(Cards.by_id("w_reiter"))
|
||||
g.human.hand.append(Cards.by_id("w_falle"))
|
||||
g.human.hand.append(Cards.by_id("w_reiter"))
|
||||
for i in 2:
|
||||
g.opponents[0].hand.append(Cards.by_id("w_reiter"))
|
||||
|
||||
|
||||
func condition(kind: String) -> bool:
|
||||
@@ -86,7 +88,7 @@ func next() -> bool:
|
||||
|
||||
|
||||
func text() -> String:
|
||||
return "%d/%d %s" % [step + 1, steps().size(), steps()[step][0]]
|
||||
return "%d/%d %s" % [step + 1, steps().size(), screen.tr(steps()[step][0])]
|
||||
|
||||
|
||||
func finished() -> bool:
|
||||
|
||||
@@ -46,17 +46,22 @@ func _draw() -> void:
|
||||
if mid:
|
||||
var sub: String = (card.combo() + " · " + card.kind) if card.is_combo() else card.kind
|
||||
Style.text(self, sub, f_text, Color("e6e6e6"), Vector2(size.x / 2, 2 * r + 4), "midtop")
|
||||
# Textfeld: Höhe folgt dem umbrochenen Text und der Schriftgröße, das Bild bekommt den Rest
|
||||
var tsize := Style.fs(f_text)
|
||||
var text_w: float = size.x - 20
|
||||
var needed: float = Style.FONT.get_multiline_string_size(card.text(), HORIZONTAL_ALIGNMENT_LEFT, text_w, tsize).y + 8 if card.text() != "" else size.y * 0.42
|
||||
var box_bottom: float = size.y - (28 if big else 22)
|
||||
var box_top: float = maxf(size.y * 0.30, box_bottom - maxf(needed, size.y * 0.42))
|
||||
var box := Rect2(6, box_top, size.x - 12, box_bottom - box_top)
|
||||
# Bild
|
||||
var band_top: float = 2 * r + 4 + (f_text + 6 if mid else 0)
|
||||
var band_bottom: float = size.y * 0.42 - 4
|
||||
var band_bottom: float = box_top - 4
|
||||
if band_bottom - band_top > 14:
|
||||
var gsize: float = minf(band_bottom - band_top, size.x * 0.42)
|
||||
Style.glyph(self, card, Vector2(size.x / 2, (band_top + band_bottom) / 2), gsize)
|
||||
# Textfeld
|
||||
var box := Rect2(6, size.y * 0.42, size.x - 12, size.y * 0.42)
|
||||
draw_rect(box, Color(0.06, 0.06, 0.09, 0.67))
|
||||
draw_multiline_string(Style.FONT, Vector2(box.position.x + 4, box.position.y + 4 + Style.FONT.get_ascent(f_text)),
|
||||
card.text(), HORIZONTAL_ALIGNMENT_LEFT, box.size.x - 8, f_text, 6 if big else 4, Style.TEXT)
|
||||
draw_multiline_string(Style.FONT, Vector2(box.position.x + 4, box.position.y + 4 + Style.FONT.get_ascent(tsize)),
|
||||
card.text(), HORIZONTAL_ALIGNMENT_LEFT, box.size.x - 8, tsize, -1, Style.TEXT)
|
||||
# Werte
|
||||
if card.is_creature():
|
||||
Style.text(self, str(card.attack), f_stat, Style.YELLOW, Vector2(10, size.y - 6), "bottomleft", true)
|
||||
|
||||
@@ -54,6 +54,41 @@ func show_screen(s: Control) -> void:
|
||||
s.app = self
|
||||
s.set_anchors_preset(Control.PRESET_FULL_RECT)
|
||||
add_child(s)
|
||||
if pad_mode:
|
||||
focus_first_button.call_deferred()
|
||||
|
||||
|
||||
var pad_mode := false # zuletzt Gamepad benutzt: Fokusrahmen sichtbar, Steuerkreuz wechselt Knöpfe
|
||||
|
||||
|
||||
## Gamepad in Menüs: erster Tastendruck setzt den Fokus, Maus nimmt ihn wieder weg.
|
||||
func _input(event: InputEvent) -> void:
|
||||
if event is InputEventJoypadButton or (event is InputEventJoypadMotion and absf(event.axis_value) > 0.5):
|
||||
if not pad_mode:
|
||||
pad_mode = true
|
||||
if get_viewport().gui_get_focus_owner() == null:
|
||||
focus_first_button()
|
||||
elif event is InputEventMouseMotion and pad_mode:
|
||||
pad_mode = false
|
||||
get_viewport().gui_release_focus()
|
||||
|
||||
|
||||
func focus_first_button() -> void:
|
||||
if screen == null or screen is BattleScreen:
|
||||
return
|
||||
var b := _first_button(screen)
|
||||
if b != null:
|
||||
b.grab_focus()
|
||||
|
||||
|
||||
func _first_button(node: Node) -> Button:
|
||||
for c in node.get_children():
|
||||
if c is Button and not c.disabled and c.is_visible_in_tree():
|
||||
return c
|
||||
var found := _first_button(c)
|
||||
if found != null:
|
||||
return found
|
||||
return null
|
||||
|
||||
|
||||
func save() -> void:
|
||||
|
||||
@@ -34,7 +34,7 @@ func _ready() -> void:
|
||||
var r := Style.row(col, 16)
|
||||
r.alignment = BoxContainer.ALIGNMENT_CENTER
|
||||
Style.cbutton(r, "%d Gegner" % n, Vector2(150, 46), func(): start(n), Color("285a3c"))
|
||||
var info := ("Duell" if n == 1 else "%d am Tisch" % (n + 1)) + " · %d Münzen" % Profile.REWARD_WIN[n]
|
||||
var info := (tr("Duell") if n == 1 else tr("%d am Tisch") % (n + 1)) + " · " + tr("%d Münzen") % Profile.REWARD_WIN[n]
|
||||
Style.clabel(r, info, 13, Style.MUTED, "left", false, 150)
|
||||
preview_labels[n] = Style.clabel(r, "", 13, Style.TEXT, "left", false, 600)
|
||||
Style.spacer(col, 4)
|
||||
@@ -82,8 +82,8 @@ func refresh(reroll: bool = false) -> void:
|
||||
rating_label.text = tr("Deine Deckstärke %.1f · Gegnerdecks %.1f · %s · Münzen x%.2f · KI: %s") % [
|
||||
p.deck_rating(), p.target_rating(), arche, d.reward, tr("Vorausschau") if d.smart else tr("einfach")]
|
||||
var tip := p.suggest_difficulty()
|
||||
tip_label.text = (tr("Tipp: %s") % (("%d Siege in Folge, versuche %s" % [p.records.streak, Profile.DIFFICULTIES[tip].name]) if p.records.streak >= 3
|
||||
else ("%d Niederlagen in Folge, versuche %s" % [p.records.loss_streak, Profile.DIFFICULTIES[tip].name]))) if tip != "" else ""
|
||||
tip_label.text = (tr("Tipp: %s") % ((tr("%d Siege in Folge, versuche %s") % [p.records.streak, tr(Profile.DIFFICULTIES[tip].name)]) if p.records.streak >= 3
|
||||
else (tr("%d Niederlagen in Folge, versuche %s") % [p.records.loss_streak, tr(Profile.DIFFICULTIES[tip].name)]))) if tip != "" else ""
|
||||
b_tip.visible = tip != ""
|
||||
if reroll:
|
||||
var r := Game.make_rng()
|
||||
|
||||
@@ -48,7 +48,7 @@ static func make_theme() -> Theme:
|
||||
t.set_stylebox("hover", "Button", box(lighter(PANEL_LIGHT), 8, MUTED, 2))
|
||||
t.set_stylebox("pressed", "Button", box(darker(PANEL_LIGHT), 8, MUTED, 2))
|
||||
t.set_stylebox("disabled", "Button", box(darker(PANEL, 0.9), 8, PANEL, 2))
|
||||
t.set_stylebox("focus", "Button", StyleBoxEmpty.new())
|
||||
t.set_stylebox("focus", "Button", box(Color(0, 0, 0, 0), 8, GOLD, 3))
|
||||
for name in ["font_color", "font_hover_color", "font_pressed_color", "font_focus_color", "font_hover_pressed_color"]:
|
||||
t.set_color(name, "Button", TEXT)
|
||||
t.set_color("font_disabled_color", "Button", MUTED)
|
||||
@@ -259,7 +259,7 @@ static func rules_text() -> String:
|
||||
"Kombokarten sind seltener und stärker, Dreifach-Kombos sind mythisch. Ein Deck darf höchstens 2 Elemente enthalten.",
|
||||
Cards.RESONANCE_TEXT,
|
||||
"Feldkombo: Spielst du ein Wesen neben ein eigenes Wesen mit anderem Element, löst eine Kombo aus (eine je Ausspielen):",
|
||||
" Dampf friert das stärkste gegnerische Wesen, Lava macht 1 Schaden an alle gegnerischen Wesen, Blitz 2 Schaden",
|
||||
" Dampf friert das stärkste gegnerische Wesen, Lava macht 1 Schaden an das stärkste gegnerische Wesen, Blitz 2 Schaden",
|
||||
" an den schwächsten Gegner, Schlamm heilt dich um 3, Sturm zieht 1 Karte, Sand gibt dem neuen Wesen Schild.",
|
||||
"",
|
||||
"Schlüsselwörter:",
|
||||
|
||||
Reference in New Issue
Block a user