update
Tests / headless (push) Waiting to run
Tests / fenster-schnell (push) Waiting to run
Tests / fenster-voll (push) Skipped
Tests / balance (push) Skipped

This commit is contained in:
team3 committed 2026-10-15 17:16:01 +02:00
1 parent 1d563b9eec
commit 04fe9716e8
22 files changed
+764 -151

No files matched your search

+81 -8
View File
@@ -109,9 +109,74 @@ static func best_element(own: Array, other: Array) -> String:
return best
## Kosten einer Karte: zwei Drittel Angriff plus ein Drittel Leben, abgerundet, höchstens 10 (0/2 kostet nichts).
## Das stärkste Element einer Karte (für das Bild): das, das die meisten der anderen Elemente der
## Karte schlägt; bei Gleichstand entscheidet seed (fest je Karte, damit das Bild nicht wechselt).
static func strongest_element(elements: Array, seed: int) -> String:
var best: Array = []
var best_score := -99
for e in elements:
var score := 0
for o in elements:
score += duel(e, o)
if score > best_score:
best = [e]
best_score = score
elif score == best_score:
best.append(e)
return best[absi(seed) % best.size()]
## Kosten einer Karte: zwei Drittel Angriff plus ein Drittel Leben, abgerundet, ohne Obergrenze (0/2 kostet nichts).
static func cost_of(attack: int, health: int) -> int:
return mini(10, (2 * attack + health) / 3)
return (2 * attack + health) / 3
## Mehrkosten einer Eigenschaft: Doppelschlag bezahlt den Angriff noch einmal (2·Angriff/3), Flink ein
## Drittel Angriff, Regeneration ein Drittel Leben, Spott 1; abgerundet, nie unter 1.
static func keyword_cost(kw: String, attack: int, health: int) -> int:
match kw:
"Doppelschlag":
return maxi(1, 2 * attack / 3)
"Flink":
return maxi(1, attack / 3)
"Regeneration":
return maxi(1, health / 3)
return 1
## Mehrkosten weiterer Elemente: das zweite 1, das dritte 2, das vierte 3 … (zusammen 1, 3, 6, 10).
static func element_cost(count: int) -> int:
return count * (count - 1) / 2
## Kosten einer Karte mit Eigenschaften und Elementen: Grundkosten plus keyword_cost je Eigenschaft
## plus element_cost, ohne Obergrenze (Werkstatt und Effektkarten der Kapitel 6 bis 10).
static func cost_with(attack: int, health: int, keywords: Array, elements: Array) -> int:
var c := cost_of(attack, health) + element_cost(elements.size())
for k in keywords:
c += keyword_cost(k, attack, health)
return c
## Eigene oder erzeugte Karte (IDs c_… aus der Werkstatt, g_… für Gegner) mit Kosten nach cost_with.
static func custom(id: String, name: String, elements: Array, attack: int, health: int, keywords: Array) -> Card:
var c := Card.new()
c.id = id
c.name = name
c.name_en = name
c.elements = elements.duplicate()
c.attack = attack
c.health = health
c.keywords = keywords.duplicate()
c.cost = cost_with(attack, health, keywords, elements)
return c
## Nimmt eine Karte ins Register (by_id) auf, ohne sie in den Pool (all) zu legen.
static func register(c: Card) -> void:
if _all.is_empty():
_build()
_by_id[c.id] = c
## Wert eines verschmolzenen Wesens aus den Grundwerten der Eltern: die aufgerundete Hälfte der
@@ -172,9 +237,11 @@ class Card extends RefCounted:
var elements: Array
var attack: int = 0
var health: int = 0
var cost: int = 0 # abgeleitet: (2 · Angriff + Leben) / 3, abgerundet, höchstens 10 (aus den Grundwerten)
var cost: int = 0 # abgeleitet: (2 · Angriff + Leben) / 3, abgerundet, plus Eigenschaften und zweites Element
var keywords: Array = [] # feste Eigenschaften der Karte (Elementpaare geben ihre zur Laufzeit)
var look := -1 # Seltenheitsstufe des Exemplars (gibt +1/+1 je Stufe); -1: Grundkarte aus dem Pool
var boost_attack := 0 # Skill Stark auf diesem Exemplar, kein Grundwert
var boost_health := 0 # Skill Zäh
var art := "" # verschmolzen: Karte, deren Bild das Wesen trägt (der stärkere Elternteil)
func to_dict() -> Dictionary:
@@ -189,17 +256,23 @@ class Card extends RefCounted:
d["cost"] = cost
return d
## Wert der Karte: was sie über ihre Manakosten hinaus bringt, mal 100. Grundkarten liegen
## bei 100, jede Seltenheitsstufe gibt 100 dazu (Ultimate Rare 500); Fusionen aus ihren Werten.
## Wert der Karte: was sie über ihre Manakosten hinaus bringt (gegen die fairen Kosten cost_with),
## mal 100, plus 100 je Eigenschaft. Grundkarten und Eigenbauten ohne Eigenschaften liegen bei 100,
## jede Seltenheitsstufe gibt 100 dazu (Ultimate Rare 500); Fusionen bringen ihr zweites Element
## und geerbte Eigenschaften umsonst mit und sind entsprechend mehr wert.
func value() -> int:
return (Cards.cost_of(attack, health) - cost + 1) * 100
return (Cards.cost_with(attack, health, keywords, elements) - cost + 1) * 100 + 100 * keywords.size()
## Eigenbau (Werkstatt) oder erzeugte Gegnerkarte, nicht aus dem Pool.
func is_custom() -> bool:
return id.begins_with("c_") or id.begins_with("g_")
## Grundwerte ohne den Stufenbonus.
func base_attack() -> int:
return attack - maxi(look, 0)
return attack - maxi(look, 0) - boost_attack
func base_health() -> int:
return health - maxi(look, 0)
return health - maxi(look, 0) - boost_health
## Stufe dieser Karte für einen Besitzer mit dieser Sammlung (Game.Player.looks).
func rarity_in(looks: Dictionary) -> String: