Dinger: Kartenspiel in Godot 4.7

Elemente, Kombos, Fallen, KI mit Vorausschau, Kampagne, Hotseat und Netzwerk,
Werkstatt, Erfolge, Tagesaufgaben, Tests und Exporte.

Co-Authored-By: Claude Fable 5.1 <noreply@anthropic.com>
Claude-Session: https://claude.ai/code/session_01QPgKvy5W9WRNFHjkm5QsHx
This commit is contained in:
Team3
2026-09-16 13:22:07 +02:00
commit 536a523f50
84 changed files with 9859 additions and 0 deletions

59
scripts/campaign.gd Normal file
View File

@@ -0,0 +1,59 @@
class_name Campaign
## Kampagne: zehn benannte Magier, jede Stufe mit mehr Gegnern am Tisch.
const STAGES := [
{"name": "Fenn", "title": "Kobold-Zähmer", "elements": ["Feuer"], "extra": 0, "bias": 1.0, "reward": 100, "perk": "feuer_angriff"},
{"name": "Mara", "title": "Gezeitenhexe", "elements": ["Wasser"], "extra": 0, "bias": 1.0, "reward": 100, "perk": "leben_35"},
{"name": "Borin", "title": "Steinfaust", "elements": ["Erde"], "extra": 1, "bias": 1.2, "reward": 150, "perk": "waechter_leben"},
{"name": "Liska", "title": "Windläuferin", "elements": ["Luft"], "extra": 1, "bias": 1.2, "reward": 150, "perk": "flink_angriff"},
{"name": "Vulkar", "title": "Herr der Lava", "elements": ["Feuer", "Erde"], "extra": 2, "bias": 1.5, "reward": 200, "perk": "zauber_schaden"},
{"name": "Nyx", "title": "Sturmruferin", "elements": ["Wasser", "Luft"], "extra": 2, "bias": 1.5, "reward": 200, "perk": "extra_karten"},
{"name": "Ignis", "title": "Inferno-Priester", "elements": ["Feuer"], "extra": 3, "bias": 2.0, "reward": 250, "perk": "resonanz_doppelt"},
{"name": "Thalassa", "title": "Tiefseekönigin", "elements": ["Wasser"], "extra": 3, "bias": 2.0, "reward": 250, "perk": "schild_wesen"},
{"name": "Zephyra", "title": "Blitzkaiserin", "elements": ["Feuer", "Luft"], "extra": 4, "bias": 2.5, "reward": 300, "perk": "alle_flink"},
{"name": "Archimagier", "title": "Meister der Elemente", "elements": ["Erde", "Luft"], "extra": 4, "bias": 3.0, "reward": 500, "perk": "start_energie"},
]
## Kapitel 2: die Magier kehren mit zwei Merkmalen und mehr Gefolge zurück.
const STAGES2 := [
{"name": "Fenn", "title": "Flammenzähmer", "elements": ["Feuer"], "extra": 1, "bias": 2.0, "reward": 300, "perks": ["feuer_angriff", "start_energie"]},
{"name": "Mara", "title": "Herrin der Gezeiten", "elements": ["Wasser"], "extra": 1, "bias": 2.0, "reward": 300, "perks": ["leben_35", "extra_karten"]},
{"name": "Borin", "title": "Fels der Ewigkeit", "elements": ["Erde"], "extra": 2, "bias": 2.2, "reward": 350, "perks": ["waechter_leben", "schild_wesen"]},
{"name": "Liska", "title": "Sturmläuferin", "elements": ["Luft"], "extra": 2, "bias": 2.2, "reward": 350, "perks": ["flink_angriff", "alle_flink"]},
{"name": "Vulkar", "title": "Aschekönig", "elements": ["Feuer", "Erde"], "extra": 3, "bias": 2.5, "reward": 400, "perks": ["zauber_schaden", "feuer_angriff"]},
{"name": "Nyx", "title": "Gewitterruferin", "elements": ["Wasser", "Luft"], "extra": 3, "bias": 2.5, "reward": 400, "perks": ["extra_karten", "flink_angriff"]},
{"name": "Ignis", "title": "Inferno-Erzpriester", "elements": ["Feuer"], "extra": 4, "bias": 3.0, "reward": 450, "perks": ["resonanz_doppelt", "zauber_schaden"]},
{"name": "Thalassa", "title": "Kaiserin der Tiefe", "elements": ["Wasser"], "extra": 4, "bias": 3.0, "reward": 450, "perks": ["schild_wesen", "leben_35"]},
{"name": "Zephyra", "title": "Blitzkaiserin", "elements": ["Feuer", "Luft"], "extra": 5, "bias": 3.5, "reward": 500, "perks": ["alle_flink", "start_energie"]},
{"name": "Archimagier", "title": "Herr aller Elemente", "elements": ["Erde", "Luft"], "extra": 5, "bias": 4.0, "reward": 800, "perks": ["start_energie", "resonanz_doppelt", "extra_karten"]},
]
static func total() -> int:
return STAGES.size() + STAGES2.size()
static func chapter(stage: int) -> int:
return 1 if stage < STAGES.size() else 2
## Stufe mit einheitlichem Feld "perks".
static func stage(i: int) -> Dictionary:
if i < STAGES.size():
var st: Dictionary = STAGES[i].duplicate()
st["perks"] = [st.perk]
return st
return STAGES2[i - STAGES.size()]
static func opponents(stage_index: int, r: RandomNumberGenerator) -> Array:
var st := stage(stage_index)
var life: int = 35 if "leben_35" in st.perks else Game.START_LIFE
var boss := Game.Player.new(st.name, Game.build_opponent_deck(r, st.elements, st.bias), false, life, st.title)
boss.perks = Array(st.perks)
var out := [boss]
var extra: int = mini(st.extra, Game.MAX_OPPONENTS - 1)
for k in extra:
out.append(Game.random_opponent(r, k + 1))
return out