update
This commit is contained in:
@@ -2,14 +2,24 @@ class_name Cards
|
||||
## Elemente, Kombonamen, Schlüsselwörter und der Kartenpool.
|
||||
|
||||
const ELEMENTS: Array[String] = ["Feuer", "Wasser", "Erde", "Luft"]
|
||||
# Neutral ist kein Element: nie im Vorteil oder Nachteil, zählt nicht für Paare und Zähler.
|
||||
# Verschmolzen mit einem Element nimmt das Wesen im schlechten Matchup die neutrale Seite.
|
||||
const NEUTRAL := "Neutral"
|
||||
const NEUTRAL_TEXT := "Nie im Vorteil oder Nachteil"
|
||||
const ELEMENT_COLORS := {
|
||||
"Feuer": Color("be3c23"),
|
||||
"Wasser": Color("2d64be"),
|
||||
"Erde": Color("73552d"),
|
||||
"Luft": Color("78aac8"),
|
||||
"Neutral": Color("6e7382"),
|
||||
}
|
||||
# Jede Karte hat genau ein Element. Kombos sind die Namen verschmolzener Wesen.
|
||||
# Jede Karte hat genau ein Element (oder ist neutral). Kombos sind die Namen verschmolzener Wesen.
|
||||
const COMBOS := {
|
||||
"Neutral+Neutral": "Veteran",
|
||||
"Feuer+Neutral": "Feuerritter",
|
||||
"Wasser+Neutral": "Wasserritter",
|
||||
"Erde+Neutral": "Erdritter",
|
||||
"Luft+Neutral": "Luftritter",
|
||||
"Feuer+Feuer": "Inferno",
|
||||
"Wasser+Wasser": "Tiefsee",
|
||||
"Erde+Erde": "Berg",
|
||||
@@ -47,9 +57,15 @@ const ELEMENT_KEYWORD := {"Erde": "Spott", "Luft": "Flink", "Wasser": "Regenerat
|
||||
const DATA_PATH := "res://data/karten.json"
|
||||
|
||||
|
||||
## Reihenfolge der Elemente in Namen und Darstellung: wie ELEMENTS, Neutral zuletzt.
|
||||
static func element_order(e: String) -> int:
|
||||
var i := ELEMENTS.find(e)
|
||||
return i if i >= 0 else ELEMENTS.size()
|
||||
|
||||
|
||||
static func combo_key(elements: Array) -> String:
|
||||
var sorted := elements.duplicate()
|
||||
sorted.sort_custom(func(a, b): return ELEMENTS.find(a) < ELEMENTS.find(b))
|
||||
sorted.sort_custom(func(a, b): return element_order(a) < element_order(b))
|
||||
return "+".join(sorted)
|
||||
|
||||
|
||||
@@ -98,11 +114,10 @@ static func cost_of(attack: int, health: int) -> int:
|
||||
return mini(10, (2 * attack + health) / 3)
|
||||
|
||||
|
||||
## Wert eines verschmolzenen Wesens: der bessere Wert plus ein Drittel des schwächeren (mindestens 1),
|
||||
## aufgerundet. Bei gleichen Werten sind das zwei Drittel der Summe, sonst mehr; nie schlechter
|
||||
## als das stärkere Wesen, und jeder Partner bringt mindestens +1, auch mit 0.
|
||||
## Wert eines verschmolzenen Wesens aus den Grundwerten der Eltern: die aufgerundete Hälfte der
|
||||
## Summe plus eins. Ein starker und ein schwacher Partner ergeben also weniger als der starke.
|
||||
static func fusion_value(a: int, b: int) -> int:
|
||||
return maxi(a, b) + maxi(1, ceili(mini(a, b) / 3.0))
|
||||
return ceili((a + b) / 2.0) + 1
|
||||
|
||||
|
||||
## Name des verschmolzenen Wesens: die Kombo seiner Elemente (ein Element zählt doppelt).
|
||||
@@ -110,18 +125,18 @@ static func fusion_name(elements: Array) -> String:
|
||||
return combo_name(elements if elements.size() >= 2 else [elements[0], elements[0]])
|
||||
|
||||
|
||||
## Karte des verschmolzenen Wesens: Elemente und Eigenschaften beider Karten, Werte nach
|
||||
## fusion_value (oder die übergebenen), eine Verschmelzung mehr als der erfahrenere Elternteil.
|
||||
static func fused(a: Card, b: Card, attack: int = -1, health: int = -1) -> Card:
|
||||
if attack < 0:
|
||||
attack = fusion_value(a.attack, b.attack)
|
||||
if health < 0:
|
||||
health = fusion_value(a.health, b.health)
|
||||
## Verschmelzung zweier Karten: Elemente (sortiert) und Eigenschaften beider, Angriff und Leben
|
||||
## nach fusion_value aus den Grundwerten, Kosten daraus wie bei jeder Karte; dann die Stufe level
|
||||
## mit ihrem +1/+1 (ohne Angabe die höhere der Eltern). Das Bild trägt der stärkere Elternteil
|
||||
## (Angriff plus Leben).
|
||||
static func fused(a: Card, b: Card, level: int = -1) -> Card:
|
||||
var attack := fusion_value(a.base_attack(), b.base_attack())
|
||||
var health := fusion_value(a.base_health(), b.base_health())
|
||||
var els := []
|
||||
for e in a.elements + b.elements:
|
||||
if not (e in els):
|
||||
els.append(e)
|
||||
els.sort_custom(func(x, y): return ELEMENTS.find(x) < ELEMENTS.find(y))
|
||||
els.sort_custom(func(x, y): return element_order(x) < element_order(y))
|
||||
var c := Card.new()
|
||||
c.id = "fus_%s_%s" % [a.id, b.id]
|
||||
c.name = fusion_name(els)
|
||||
@@ -132,8 +147,9 @@ static func fused(a: Card, b: Card, attack: int = -1, health: int = -1) -> Card:
|
||||
for k in KEYWORDS:
|
||||
if k in a.keywords or k in b.keywords:
|
||||
c.keywords.append(k)
|
||||
c.look = maxi(a.look, b.look) # die höhere Stufe gewinnt
|
||||
return c
|
||||
var strong := a if a.attack + a.health >= b.attack + b.health else b
|
||||
c.art = strong.art_card().id
|
||||
return c.leveled(maxi(level, maxi(maxi(a.look, b.look), 0)))
|
||||
|
||||
|
||||
## Platzhalter für ein verdecktes gegnerisches Wesen: unbekanntes Element, geschätzte Werte.
|
||||
@@ -159,6 +175,7 @@ class Card extends RefCounted:
|
||||
var cost: int = 0 # abgeleitet: (2 · Angriff + Leben) / 3, abgerundet, höchstens 10 (aus den Grundwerten)
|
||||
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 art := "" # verschmolzen: Karte, deren Bild das Wesen trägt (der stärkere Elternteil)
|
||||
|
||||
func to_dict() -> Dictionary:
|
||||
var d := {"id": id, "name": name, "name_en": name_en, "elements": elements, "attack": attack, "health": health}
|
||||
@@ -166,10 +183,24 @@ class Card extends RefCounted:
|
||||
d["keywords"] = keywords
|
||||
if look >= 0:
|
||||
d["look"] = look
|
||||
if art != "":
|
||||
d["art"] = art
|
||||
if cost != Cards.cost_of(attack, health):
|
||||
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.
|
||||
func value() -> int:
|
||||
return (Cards.cost_of(attack, health) - cost + 1) * 100
|
||||
|
||||
## Grundwerte ohne den Stufenbonus.
|
||||
func base_attack() -> int:
|
||||
return attack - maxi(look, 0)
|
||||
|
||||
func base_health() -> int:
|
||||
return health - maxi(look, 0)
|
||||
|
||||
## Stufe dieser Karte für einen Besitzer mit dieser Sammlung (Game.Player.looks).
|
||||
func rarity_in(looks: Dictionary) -> String:
|
||||
return Cards.RARITIES[look if look >= 0 else int(looks.get(id, 0))]
|
||||
@@ -185,8 +216,13 @@ class Card extends RefCounted:
|
||||
c.cost = int(d.get("cost", Cards.cost_of(c.attack, c.health)))
|
||||
c.keywords = Array(d.get("keywords", []))
|
||||
c.look = int(d.get("look", -1))
|
||||
c.art = str(d.get("art", ""))
|
||||
return c
|
||||
|
||||
## Karte, deren Bild gezeichnet wird: bei Verschmelzungen der stärkere Elternteil, sonst sie selbst.
|
||||
func art_card() -> Card:
|
||||
return Cards.by_id(art) if art != "" and Cards._by_id.has(art) else self
|
||||
|
||||
## Eigenes Exemplar (Hand, Brett): Schlüsselwörter gehören dem Exemplar, nicht dem Pool.
|
||||
func copy() -> Card:
|
||||
return Card.from_dict(to_dict())
|
||||
@@ -212,14 +248,19 @@ class Card extends RefCounted:
|
||||
func combo() -> String:
|
||||
return Cards.combo_name(elements)
|
||||
|
||||
## Kartentext: die festen Eigenschaften.
|
||||
func is_neutral() -> bool:
|
||||
return Cards.NEUTRAL in elements
|
||||
|
||||
## Kartentext: Neutral und die festen Eigenschaften.
|
||||
func text() -> String:
|
||||
if keywords.is_empty():
|
||||
return ""
|
||||
var kws: Array[String] = []
|
||||
if is_neutral():
|
||||
kws.append(tr(Cards.NEUTRAL))
|
||||
for k in Cards.KEYWORDS:
|
||||
if k in keywords:
|
||||
kws.append(tr(k))
|
||||
if kws.is_empty():
|
||||
return ""
|
||||
return ", ".join(kws) + "."
|
||||
|
||||
|
||||
|
||||
Reference in New Issue
Block a user