saumwacht-godot/scripts/autoload/game_state.gd
Martin Stickelbroeck c2b447610c Baseline: Saumwacht 0.15.0 (Phase 20A) vor dem Umbau zu Champions of Luneraria
Unveränderter Ausgangsstand inklusive Masterprompt und Konzeptbildern
unter assets/. .godot/ und docs/screenshots/ bleiben laut .gitignore
unversioniert; letztere sind unter ../backups gesichert.

Co-Authored-By: Claude Opus 5.5 <noreply@anthropic.com>
2026-09-27 20:00:36 +02:00

83 lines
2 KiB
GDScript

extends Node
## Persistent match state. Only WaveManager advances phases or resolves results.
signal phase_changed(phase: int)
signal changed
enum Phase { MENU, BUILD, COMBAT, RESULTS, GAME_OVER }
const CORE_MAX_HP := 3000
const ONGOING := -2
const DRAW := -1
const AI_LEARNING := 0
const AI_STANDARD := 1
const MODE_SHORT := "short"
const MODE_EXPEDITION := "expedition"
var phase: int = Phase.MENU
var wave: int = 0
var core_hp: Array = [CORE_MAX_HP, CORE_MAX_HP]
var paused: bool = false
var speed: int = 1
var outcome: int = ONGOING
var last_reports: Array = [{}, {}]
var ai_level: int = AI_LEARNING
var timed_build: bool = false
var factions: Array[String] = ["wurzelbund", "glutpakt"]
var match_mode: String = MODE_EXPEDITION
func select_mode(value: String) -> bool:
if phase not in [Phase.MENU, Phase.GAME_OVER] or value not in [MODE_SHORT, MODE_EXPEDITION]:
return false
match_mode = value
changed.emit()
return true
func reset_match() -> void:
wave = 0
core_hp = [CORE_MAX_HP, CORE_MAX_HP]
paused = false
speed = 1
outcome = ONGOING
last_reports = [{}, {}]
set_phase(Phase.MENU)
func set_phase(next_phase: int) -> void:
phase = next_phase
phase_changed.emit(phase)
changed.emit()
func apply_core_damage(damage: Array) -> void:
# Both lanes are applied before anyone checks the winner.
for team in range(2):
core_hp[team] = maxi(0, int(core_hp[team]) - maxi(0, int(damage[team])))
changed.emit()
func decide_winner(final_wave: bool = false) -> int:
if core_hp[0] <= 0 and core_hp[1] <= 0:
return DRAW
if core_hp[0] <= 0:
return 1
if core_hp[1] <= 0:
return 0
if not final_wave:
return ONGOING
if core_hp[0] == core_hp[1]:
return DRAW
return 0 if core_hp[0] > core_hp[1] else 1
func phase_name() -> String:
return ["VORBEREITUNG", "BAUPHASE", "AUTOKAMPF", "ABRECHNUNG", "PARTIE BEENDET"][phase]
func select_faction(team: int, faction: String) -> bool:
if phase not in [Phase.MENU, Phase.GAME_OVER] or team < 0 or team > 1 or faction not in DataCatalog.FACTIONS:
return false
factions[team] = faction
changed.emit()
return true