update
This commit is contained in:
123
scripts/game.gd
123
scripts/game.gd
@@ -4,14 +4,13 @@ extends RefCounted
|
||||
## Elementboni und Verschmelzen.
|
||||
|
||||
const MAX_BOARD := 5
|
||||
const MAX_HAND := 5
|
||||
const START_HAND := 5 # Startkarten, alle im ersten Zug bezahlbar
|
||||
const START_HAND := 5 # Startkarten: die obersten des eigenen Stapels
|
||||
const START_MANA := 1 # Mana in Zug 1; jede Runde eins mehr, ohne Grenze; Rest verfällt
|
||||
const DECK_MIN := 40 # Karten je Stapel: mindestens so viele (Gegner und Startdecks genau so viele)
|
||||
const DECK_MAX := 60 # und höchstens so viele
|
||||
const START_LIFE := 30
|
||||
const ELEMENT_PAIR := 2 # so viele eigene offene Wesen eines Elements: Sondereffekt des Elements
|
||||
const ELEMENT_COUNT := 5 # je so viele ausgespielte Karten eines Elements: +1/+1 für die eigenen Wesen des Elements
|
||||
const ELEMENT_COUNT := 3 # je so viele ausgespielte Karten eines Elements: +1/+1 für die eigenen Wesen des Elements
|
||||
const DISCARD_GAIN := 1 # Abwerfen einer Handkarte bringt so viel Mana
|
||||
|
||||
# Merkmale der Kampagnen-Bosse (Player.perks).
|
||||
@@ -154,23 +153,11 @@ class Player extends RefCounted:
|
||||
func alive() -> bool:
|
||||
return life > 0
|
||||
|
||||
## Eine Karte vom eigenen Stapel als Exemplar in der eigenen Stufe; null, wenn er leer ist.
|
||||
## Mit max_cost kommt die oberste bezahlbare, zu teure wandern nach unten (Starthand).
|
||||
func draw_from_deck(max_cost: int = 99) -> Cards.Card:
|
||||
var skipped := []
|
||||
var id := ""
|
||||
while not deck.is_empty():
|
||||
var top: String = deck.pop_back()
|
||||
if Cards.by_id(top).cost <= max_cost:
|
||||
id = top
|
||||
break
|
||||
skipped.append(top)
|
||||
if id == "" and not skipped.is_empty(): # nichts Bezahlbares: dann eben die oberste
|
||||
id = skipped.pop_front()
|
||||
for sk in skipped:
|
||||
deck.insert(0, sk)
|
||||
if id == "":
|
||||
## Die oberste Karte des eigenen Stapels als Exemplar in der eigenen Stufe; null, wenn er leer ist.
|
||||
func draw_from_deck() -> Cards.Card:
|
||||
if deck.is_empty():
|
||||
return null
|
||||
var id: String = deck.pop_back()
|
||||
return Cards.by_id(id).leveled(int(looks.get(id, 0)))
|
||||
|
||||
## Offene eigene Wesen mit diesem Element.
|
||||
@@ -295,8 +282,8 @@ func masked_clone(viewer: Player) -> Game:
|
||||
|
||||
# --- Zugablauf ---------------------------------------------------------------
|
||||
|
||||
## Jeder spielt mit seinem eigenen Stapel (leer: ein zufälliger); die Starthand sind fünf im
|
||||
## ersten Zug bezahlbare Karten daraus.
|
||||
## Jeder spielt mit seinem eigenen Stapel (leer: ein zufälliger); die Starthand sind die
|
||||
## obersten fünf Karten daraus, wie gemischt.
|
||||
func start(fixed_order: bool = false) -> void:
|
||||
if not fixed_order:
|
||||
shuffle(players, rng) # zufällige Zugreihenfolge
|
||||
@@ -307,7 +294,7 @@ func start(fixed_order: bool = false) -> void:
|
||||
p.deck = DeckGen.random_deck(rng)
|
||||
shuffle(p.deck, rng)
|
||||
for k in START_HAND:
|
||||
var c := p.draw_from_deck(START_MANA)
|
||||
var c := p.draw_from_deck()
|
||||
if c != null:
|
||||
p.hand.append(c)
|
||||
turn = 1
|
||||
@@ -324,8 +311,6 @@ func start(fixed_order: bool = false) -> void:
|
||||
func can_draw(p: Player) -> Array:
|
||||
if winner != "" or p != current():
|
||||
return [false, "Nicht dein Zug"]
|
||||
if p.hand.size() >= MAX_HAND:
|
||||
return [false, "Deine Hand ist voll"]
|
||||
if p.deck.is_empty():
|
||||
return [false, "Dein Stapel ist leer"]
|
||||
if p.energy < draw_cost(p):
|
||||
@@ -497,75 +482,51 @@ static func look_of(p: Player, c: Cards.Card) -> int:
|
||||
return c.look if c.look >= 0 else int(p.looks.get(c.id, 0))
|
||||
|
||||
|
||||
## Kosten: die Hälfte der Manasumme beider Karten, aufgerundet.
|
||||
static func fusion_cost(a, b) -> int:
|
||||
return ceili((card_of(a).cost + card_of(b).cost) / 2.0)
|
||||
|
||||
|
||||
## a und b: zwei eigene Wesen auf dem Brett oder zwei eigene Handkarten.
|
||||
## a und b: zwei verschiedene eigene Karten, auf der Hand oder als Wesen auf dem Brett, auch
|
||||
## gemischt. Verschmelzen kostet kein Mana.
|
||||
func can_fuse(p: Player, a, b) -> Array:
|
||||
if winner != "" or p != current():
|
||||
return [false, "Nicht dein Zug"]
|
||||
if a == null or b == null or a == b:
|
||||
return [false, "Zwei verschiedene Karten wählen"]
|
||||
if a is Creature and b is Creature:
|
||||
if not (a in p.board) or not (b in p.board):
|
||||
return [false, "Nur eigene Wesen"]
|
||||
elif a is Creature or b is Creature:
|
||||
return [false, "Nur Hand mit Hand oder Brett mit Brett"]
|
||||
elif not (a in p.hand) or not (b in p.hand):
|
||||
return [false, "Nicht auf der Hand"]
|
||||
if p.energy < fusion_cost(a, b):
|
||||
return [false, "Nicht genug Mana"]
|
||||
for x in [a, b]:
|
||||
if not ((x in p.board) if x is Creature else (x in p.hand)):
|
||||
return [false, "Nur eigene Karten"]
|
||||
return [true, ""]
|
||||
|
||||
|
||||
## Verschmilzt zwei Handkarten zu einer oder zwei eigene Wesen zu einem offenen: Elemente und
|
||||
## Eigenschaften beider, Werte nach Cards.fusion_value, Kosten folgen den Werten.
|
||||
## Die Karte, die aus a und b entsteht (siehe Cards.fused), in der höheren Stufe der Eltern.
|
||||
static func fusion_result(p: Player, a, b) -> Cards.Card:
|
||||
return Cards.fused(card_of(a), card_of(b), maxi(look_of(p, card_of(a)), look_of(p, card_of(b))))
|
||||
|
||||
|
||||
## Verschmilzt zwei eigene Karten zu einer neuen Handkarte: Wesen verlassen das Brett, die neue
|
||||
## Karte ist unverletzt und wird wie jede andere ausgespielt. Sie landet am Platz der vorderen
|
||||
## Handkarte, sonst hinten.
|
||||
func fuse(p: Player, a, b) -> String:
|
||||
var ok := can_fuse(p, a, b)
|
||||
if not ok[0]:
|
||||
return ok[1]
|
||||
p.energy -= fusion_cost(a, b)
|
||||
if a is Creature:
|
||||
return _fuse_board(p, a, b)
|
||||
var card := Cards.fused(a, b)
|
||||
card.look = maxi(look_of(p, a), look_of(p, b))
|
||||
var at := p.hand.find(a)
|
||||
p.hand.erase(a)
|
||||
p.hand.erase(b)
|
||||
var card := fusion_result(p, a, b)
|
||||
var at := p.hand.size()
|
||||
var gone := []
|
||||
for x in [a, b]:
|
||||
if x is Creature:
|
||||
p.board.erase(x)
|
||||
gone.append(x.uid)
|
||||
else:
|
||||
at = mini(at, p.hand.find(x))
|
||||
p.hand.erase(x)
|
||||
p.hand.insert(mini(at, p.hand.size()), card)
|
||||
say("%s und %s verschmelzen auf der Hand zu %s (%d/%d)." % [a.name, b.name, card.name, card.attack, card.health])
|
||||
emit({"type": "fuse", "player": players.find(p), "uid": -1, "gone": []})
|
||||
return ""
|
||||
|
||||
|
||||
## Auf dem Brett zählen die Werte der Wesen (ohne Elementbonus, den bekommt das neue selbst);
|
||||
## das Ergebnis ist nur angriffsbereit, wenn beide es waren.
|
||||
func _fuse_board(p: Player, a: Creature, b: Creature) -> String:
|
||||
var card := Cards.fused(a.card, b.card, Cards.fusion_value(a.attack, b.attack),
|
||||
Cards.fusion_value(a.max_health - a.aura, b.max_health - b.aura))
|
||||
card.look = maxi(look_of(p, a.card), look_of(p, b.card))
|
||||
var cr := Creature.new(card, p, next_uid)
|
||||
next_uid += 1
|
||||
cr.health = mini(card.health, Cards.fusion_value(mini(a.health, a.max_health - a.aura), mini(b.health, b.max_health - b.aura)))
|
||||
cr.ready = a.ready and b.ready
|
||||
cr.attacks_done = maxi(a.attacks_done, b.attacks_done)
|
||||
var at := p.board.find(a)
|
||||
p.board.erase(a)
|
||||
p.board.erase(b)
|
||||
p.board.insert(mini(at, p.board.size()), cr)
|
||||
say("%s und %s verschmelzen zu %s (%d/%d)." % [a.name, b.name, cr.name, cr.attack, cr.health])
|
||||
emit({"type": "fuse", "player": players.find(p), "uid": cr.uid, "gone": [a.uid, b.uid]})
|
||||
apply_auras()
|
||||
cleanup()
|
||||
check_end()
|
||||
say("%s und %s verschmelzen zu %s (%d/%d) auf der Hand." % [a.name, b.name, card.name, card.attack, card.health])
|
||||
emit({"type": "fuse", "player": players.find(p), "uid": -1, "gone": gone})
|
||||
return ""
|
||||
|
||||
|
||||
# --- Elementboni ---------------------------------------------------------------
|
||||
|
||||
## +1/+1 je volle ELEMENT_COUNT ausgespielte Karten eines Elements des Spielers; mehrere Elemente zählen alle.
|
||||
## +1/+1 je volle ELEMENT_COUNT ausgespielte Karten eines Elements des Spielers; mehrere Elemente
|
||||
## zählen alle, auch Neutral (eigener Zähler, aber kein Paar).
|
||||
static func aura_of(elements: Array, played: Dictionary) -> int:
|
||||
var a := 0
|
||||
for e in elements:
|
||||
@@ -648,12 +609,18 @@ func attack(cr: Creature, target) -> String:
|
||||
return ""
|
||||
|
||||
|
||||
## Elementvorteil beim Zuschlagen und beim Konter: +1 im Vorteil, -1 im Nachteil,
|
||||
## gegen Helden gibt es keinen.
|
||||
## Elementvorteil beim Zuschlagen und beim Konter: im Vorteil zählt der Stapelbonus des Ziels
|
||||
## nicht (so viel Schaden mehr), im Nachteil der eigene nicht (so viel weniger). Gegen Helden
|
||||
## gibt es keinen.
|
||||
static func matchup_bonus(source: Creature, target) -> int:
|
||||
if not (target is Creature):
|
||||
return 0
|
||||
return Cards.matchup(source.card.elements, target.card.elements)
|
||||
var m := Cards.matchup(source.card.elements, target.card.elements)
|
||||
if m > 0:
|
||||
return target.aura
|
||||
if m < 0:
|
||||
return -source.aura
|
||||
return 0
|
||||
|
||||
|
||||
func damage(target, amount: int) -> void:
|
||||
|
||||
Reference in New Issue
Block a user