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-09-19 13:37:12 +02:00
parent 89db101137
commit 8944fdd017
21 changed files with 62 additions and 562 deletions

View File

@@ -1,12 +1,11 @@
class_name BattleScreen
extends Control
## Kampf: Zustand, Eingabe und Abgleich der Ansicht. Layout in BattleLayout, Animationen in BattleFx.
## Modi: Einzelspieler, Kampagne, Anleitung, Netzwerk (Host, Mitspieler oder Zuschauer).
## Modi: Einzelspieler, Kampagne, Netzwerk (Host, Mitspieler oder Zuschauer).
var app
var n_opp: int
var stage := -1 # Kampagnenstufe oder -1
var tutorial := false
var net_play := false # Netzwerkspiel (auch als Zuschauer)
var online_seat := -1 # Netzwerk: eigener Platz, Zuschauer -1
var net: Net
@@ -26,11 +25,6 @@ var ended := false
var zoom_player = null
var preview_timer := 0.0
var played_ids: Array = [] # vom Menschen gespielte Karten (Statistik)
var guide: BattleTutorial
var tutorial_part := 1
var tutorial_step: int:
get:
return guide.step if guide != null else 0
var pad: BattleGamepad
var gp_zone: String:
get:
@@ -96,26 +90,9 @@ var mulligan_selected: Array:
get:
return mulligan.selected
var cursor_layer: Control
var tutorial_panel: Panel
var tutorial_text: RichTextLabel
var b_tut_next: Button
var wait_label: Label
var b_skip: Button
var b_undo: Button
var highlight_layer: Control
## Pulsierender Rahmen für die Anleitung.
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 _init(n: int = 2, campaign_stage: int = -1) -> void:
@@ -130,13 +107,6 @@ static func online(seat: int) -> BattleScreen:
return b
static func guided(part: int = 1) -> BattleScreen:
var b := BattleScreen.new(1, -1)
b.tutorial = true
b.tutorial_part = part
return b
## Unterbrochenen Kampf aus der Datei fortsetzen (siehe save_battle).
static func resume(data: Dictionary) -> BattleScreen:
var s := BattleScreen.new(int(data.get("n_opp", 1)), int(data.get("stage", -1)))
@@ -183,13 +153,6 @@ func _ready() -> void:
return # der erste Zustand kommt vom Host
elif saved_game != null:
game = saved_game
elif tutorial:
guide = BattleTutorial.new(self, tutorial_part)
var r := Game.make_rng()
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)
elif stage >= 0:
var r := Game.make_rng()
game = Game.new_battle_with(app.profile.deck_cards(), Campaign.opponents(stage, r, app.profile.target_rating()), r, false, own_rules())
@@ -235,22 +198,6 @@ func _build_static() -> void:
log_box.add_theme_font_size_override("normal_font_size", 13)
log_box.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(log_box)
if tutorial:
tutorial_panel = Style.panel(self, Rect2(10, 205, 320, 150), Style.PANEL, 8, Style.GOLD, 2)
tutorial_panel.mouse_filter = Control.MOUSE_FILTER_STOP
Style.label(self, "Anleitung", 14, Style.GOLD, Rect2(20, 209, 200, 20), "left", true)
tutorial_text = RichTextLabel.new()
tutorial_text.position = Vector2(20, 230)
tutorial_text.size = Vector2(300, 90)
tutorial_text.bbcode_enabled = false
tutorial_text.scroll_active = false
tutorial_text.add_theme_font_size_override("normal_font_size", 13)
tutorial_text.mouse_filter = Control.MOUSE_FILTER_IGNORE
add_child(tutorial_text)
b_tut_next = Style.button(self, "Weiter", Rect2(230, 318, 90, 30), tutorial_next)
b_tut_next.add_theme_font_size_override("font_size", 14)
log_box.position = Vector2(18, 365)
log_box.size = Vector2(304, 173)
b_giveup = Style.button(self, "Aufgeben", Rect2(10, 553, 150, 40), func(): confirm.visible = true)
Style.panel(self, Rect2(950, 205, 320, 380))
preview_hint = Style.label(self, "Karte überfahren für Details", 14, Style.MUTED, Rect2(950, 345, 320, 24), "center")
@@ -275,7 +222,6 @@ func _build_static() -> void:
trap_layer = _layer()
hand_layer = _layer()
preview_holder = _layer()
highlight_layer = _layer()
zoom_layer = _layer()
fx_layer = _layer()
cursor_layer = _layer()
@@ -313,7 +259,7 @@ func _overlay() -> Control:
## Einzelspieler-Kämpfe (auch Kampagne) lassen sich unterbrechen und fortsetzen.
func resumable() -> bool:
return counts_for_profile() and not tutorial
return counts_for_profile()
func save_battle() -> void:
@@ -336,12 +282,6 @@ func leave() -> void:
net.leave()
if resumable() and game != null and game.winner == "":
app.clear_battle_save() # aufgegeben
if tutorial:
if tutorial_part == 1:
app.profile.tutorial_done = true
else:
app.profile.tutorial2_done = true
app.save()
app.show_screen(MenuScreen.new())
@@ -466,8 +406,6 @@ func _input(event: InputEvent) -> void:
do_mulligan([])
elif overlay.visible:
leave()
elif tutorial and b_tut_next.visible:
tutorial_next()
_:
if event.keycode >= KEY_1 and event.keycode <= KEY_9 and my_turn() and not any_overlay():
var idx: int = event.keycode - KEY_1
@@ -555,13 +493,8 @@ func _exit_tree() -> void:
func _finish() -> void:
var won := game.winner == "human"
if counts_for_profile():
var factor: float = float(app.profile.difficulty().reward) if stage < 0 and not tutorial else 1.0
var factor: float = float(app.profile.difficulty().reward) if stage < 0 else 1.0
reward = app.profile.record_battle(won, n_opp, app.profile.deck_cards(), stage, played_ids, game.turn, factor, game.human.life)
if tutorial:
if tutorial_part == 1:
app.profile.tutorial_done = true
else:
app.profile.tutorial2_done = true
app.save()
app.sfx.play("win" if won else "lose")
app.clear_battle_save()
@@ -846,30 +779,6 @@ func _note_events(evs: Array) -> void:
app.profile.daily_event("combo")
# --- Anleitung ------------------------------------------------------------------------------
func tutorial_next() -> void:
if guide != null and guide.next():
app.sfx.play("click")
refresh()
func _tutorial_refresh() -> void:
guide.advance()
tutorial_text.text = guide.text()
b_tut_next.visible = not guide.finished()
func _tutorial_highlights(mine: bool) -> void:
Style.clear(highlight_layer)
for r in guide.highlight_rects(mine):
var hl := Highlight.new()
hl.position = r.position - Vector2(4, 4)
hl.size = r.size + Vector2(8, 8)
hl.mouse_filter = Control.MOUSE_FILTER_IGNORE
highlight_layer.add_child(hl)
# --- Ansicht angleichen --------------------------------------------------------------------
func refresh() -> void:
@@ -1022,9 +931,6 @@ func refresh() -> void:
else:
lines.append(line)
log_box.text = "\n".join(lines)
if tutorial:
_tutorial_refresh()
_tutorial_highlights(mine)
pad.draw_cursor()
Style.clear(zoom_layer)