update
This commit is contained in:
@@ -9,7 +9,6 @@ const SHOP_SIZE := 5 # so viele Karten liegen im Laden
|
||||
const REROLL_COST := 1
|
||||
# Jeder gegen jeden: alle Spieler haben dieselben Regeln und dasselbe Startleben.
|
||||
const START_LIFE := 30
|
||||
const MAX_OPPONENTS := 5
|
||||
|
||||
# Merkmale der Kampagnen-Bosse (Player.perks).
|
||||
const PERKS := {
|
||||
@@ -18,7 +17,7 @@ const PERKS := {
|
||||
"waechter_leben": "Wächter kommen mit +2 Leben",
|
||||
"wesen_leben": "Wesen kommen mit +1 Leben",
|
||||
"extra_mana": "Bekommt jeden Zug 1 Mana mehr",
|
||||
"leben_35": "Beginnt mit 35 Leben",
|
||||
"leben_35": "Beginnt mit 5 Leben mehr",
|
||||
"schild_wesen": "Wesen kommen mit Schild",
|
||||
"alle_flink": "Alle Wesen sind flink",
|
||||
"start_energie": "Beginnt mit 3 Mana",
|
||||
@@ -151,8 +150,8 @@ class Player extends RefCounted:
|
||||
|
||||
|
||||
var human: Player # der (erste) menschliche Spieler
|
||||
var humans: Array = [] # alle menschlichen Spieler (im Netz mehrere)
|
||||
var opponents: Array = [] # alle außer dem ersten Menschen
|
||||
var humans: Array = [] # alle menschlichen Spieler (im Netz zwei)
|
||||
var opponent: Player # der andere am Tisch
|
||||
var players: Array = [] # in Zugreihenfolge
|
||||
var winner_player: Player = null
|
||||
var rng: RandomNumberGenerator
|
||||
@@ -167,10 +166,10 @@ var field_element := "" # gemeinsames Feld aller am Tisch, "" = neutral
|
||||
var field_charge := {} # Element -> gespielte Karten seit dem letzten Wechsel
|
||||
|
||||
|
||||
func _init(h: Player, opps: Array, r: RandomNumberGenerator = null) -> void:
|
||||
func _init(h: Player, o: Player, r: RandomNumberGenerator = null) -> void:
|
||||
human = h
|
||||
opponents = opps
|
||||
players = [h] + opps
|
||||
opponent = o
|
||||
players = [h, o]
|
||||
humans = players.filter(func(p): return p.is_human)
|
||||
if r == null:
|
||||
r = make_rng()
|
||||
@@ -199,11 +198,15 @@ func ref_of(target) -> Dictionary:
|
||||
return {"kind": "player", "index": players.find(target)}
|
||||
|
||||
|
||||
## Jeder gegen jeden: alle anderen lebenden Spieler sind Gegner.
|
||||
## Der Gegner von p, solange er lebt (als Liste, damit Effekte einheitlich bleiben).
|
||||
func enemies_of(p: Player) -> Array:
|
||||
return players.filter(func(o): return o != p and o.alive())
|
||||
|
||||
|
||||
func enemy_of(p: Player) -> Player:
|
||||
return opponent if p == human else human
|
||||
|
||||
|
||||
func find_creature(uid: int) -> Creature:
|
||||
for p in players:
|
||||
for c in p.board:
|
||||
@@ -218,7 +221,7 @@ func clone() -> Game:
|
||||
for p in players:
|
||||
copies.append(p.clone())
|
||||
var idx := players.find(human)
|
||||
var g := Game.new(copies[idx], copies.slice(0, idx) + copies.slice(idx + 1), RandomNumberGenerator.new())
|
||||
var g := Game.new(copies[idx], copies[1 - idx], RandomNumberGenerator.new())
|
||||
g.players = copies # gleiche Zugreihenfolge wie das Original
|
||||
g.turn = turn
|
||||
g.current_idx = current_idx
|
||||
@@ -483,6 +486,26 @@ static func resonance_for(partners: int) -> int:
|
||||
return DeckGen.RESONANCE_STEPS[mini(partners, DeckGen.RESONANCE_STEPS.size() - 1)]
|
||||
|
||||
|
||||
## Vorschau fürs Ausspielen: Angriffsbonus aus Resonanz und Feld sowie die Feldkombo,
|
||||
## die die Karte mit dem ersten eigenen Wesen aus anderem Element auslösen würde.
|
||||
func forecast(p: Player, card: Cards.Card) -> Dictionary:
|
||||
var partners := 0
|
||||
var combo := ""
|
||||
var partner: Creature = null
|
||||
for o in p.board:
|
||||
if o.card.elements.any(func(e): return e in card.elements):
|
||||
partners += 1
|
||||
if combo == "":
|
||||
for e1 in card.elements:
|
||||
for e2 in o.card.elements:
|
||||
if e1 != e2 and combo == "":
|
||||
combo = Cards.combo_name([e1, e2])
|
||||
partner = o
|
||||
var resonance := resonance_for(partners) * (2 if "resonanz_doppelt" in p.perks else 1)
|
||||
var field := 1 if field_element != "" and field_element in card.elements else 0
|
||||
return {"resonance": resonance, "field": field, "combo": combo, "partner": partner}
|
||||
|
||||
|
||||
## Resonanz: abnehmender Angriffsbonus je Partner mit gleichem Element (siehe resonance_for).
|
||||
func update_resonance() -> void:
|
||||
for p in players:
|
||||
@@ -642,20 +665,19 @@ func cleanup() -> void:
|
||||
update_resonance()
|
||||
|
||||
|
||||
## Ende: nur noch ein Spieler übrig, oder kein Mensch mehr am Tisch.
|
||||
## Ende: einer von beiden hat kein Leben mehr.
|
||||
func check_end() -> void:
|
||||
if winner != "":
|
||||
return
|
||||
var alive := players.filter(func(p): return p.alive())
|
||||
var humans_alive := alive.filter(func(p): return p.is_human)
|
||||
if humans_alive.is_empty():
|
||||
winner = "opponents"
|
||||
winner_player = alive[0] if alive.size() == 1 else null
|
||||
say("Du wurdest besiegt." if humans.size() == 1 else "Alle Spieler sind besiegt, die KI gewinnt.")
|
||||
elif alive.size() == 1:
|
||||
winner = "human"
|
||||
winner_player = alive[0]
|
||||
say("Alle Gegner sind besiegt!" if humans.size() == 1 else "%s gewinnt!" % winner_player.name)
|
||||
if alive.size() != 1:
|
||||
return
|
||||
winner_player = alive[0]
|
||||
winner = "human" if winner_player.is_human else "opponents"
|
||||
if humans.size() == 1:
|
||||
say("Der Gegner ist besiegt!" if winner == "human" else "Du wurdest besiegt.")
|
||||
else:
|
||||
say("%s gewinnt!" % winner_player.name)
|
||||
|
||||
|
||||
# --- Zustand für das Netzwerk (siehe NetState) ------------------------------------
|
||||
@@ -678,28 +700,23 @@ static func shuffle(arr: Array, r: RandomNumberGenerator) -> void:
|
||||
arr[j] = tmp
|
||||
|
||||
|
||||
## rules: {"human_perks": [...], "opponent_life": int, "looks": {...}}
|
||||
static func new_battle(n_opp: int, r: RandomNumberGenerator = null, rules: Dictionary = {}) -> Game:
|
||||
assert(n_opp >= 1 and n_opp <= MAX_OPPONENTS, "1 bis 5 Gegner")
|
||||
## Duell gegen einen zufälligen Gegner. rules: {"human_perks": [...], "opponent_life": int, "looks": {...}}
|
||||
static func new_battle(r: RandomNumberGenerator = null, rules: Dictionary = {}) -> Game:
|
||||
if r == null:
|
||||
r = make_rng()
|
||||
var life: int = int(rules.get("opponent_life", START_LIFE))
|
||||
var opps := []
|
||||
for i in n_opp:
|
||||
opps.append(DeckGen.random_opponent(i + 1, life))
|
||||
return new_battle_with(opps, r, false, rules)
|
||||
return new_battle_with(DeckGen.random_opponent(int(rules.get("opponent_life", START_LIFE))), r, false, rules)
|
||||
|
||||
|
||||
static func new_battle_with(opps: Array, r: RandomNumberGenerator = null, fixed_order: bool = false, rules: Dictionary = {}) -> Game:
|
||||
static func new_battle_with(opp: Player, r: RandomNumberGenerator = null, fixed_order: bool = false, rules: Dictionary = {}) -> Game:
|
||||
if r == null:
|
||||
r = make_rng()
|
||||
var human := Player.new("Spieler", true, START_LIFE)
|
||||
human.perks = Array(rules.get("human_perks", []))
|
||||
human.looks = rules.get("looks", {})
|
||||
var g := Game.new(human, opps, r)
|
||||
var g := Game.new(human, opp, r)
|
||||
for p in g.players:
|
||||
if "leben_35" in p.perks and p.life == START_LIFE:
|
||||
p.life = 35
|
||||
p.max_life = 35
|
||||
if "leben_35" in p.perks:
|
||||
p.life += 5
|
||||
p.max_life += 5
|
||||
g.start(fixed_order)
|
||||
return g
|
||||
|
||||
Reference in New Issue
Block a user