109 lines
3.5 KiB
GDScript
109 lines
3.5 KiB
GDScript
extends RefCounted
|
|
## Das Aufdecken in drei Etappen: Becher hoch, zählen, Urteil. Dazu Genau
|
|
## und die Vergabe des Topfs. Arbeitet auf dem Spiel `g`.
|
|
|
|
var g: Node
|
|
|
|
|
|
func _init(spiel: Node) -> void:
|
|
g = spiel
|
|
|
|
func _phase_reveal(result: Dictionary) -> void:
|
|
g.phase = "reveal"
|
|
g.deadline = 0.0
|
|
var b: Dictionary = result.bid
|
|
var rufer: int = result.challenger
|
|
var genau: bool = result.get("exact", false)
|
|
var total: int = g._count_face(int(b.face))
|
|
|
|
# 1. Becher hoch. Noch kein Urteil - erst schauen.
|
|
g.reveal_total = -1
|
|
g.banner = "Genau?" if genau else "Aufdecken"
|
|
for i in g._alive_seats():
|
|
g.table.arrange_and_show(i, g.host_values[i], g.rng)
|
|
g.table.set_cup_down(i, false)
|
|
# Gezielt an die Mitspieler am Tisch: ein Peer, der nur in der Lobby sitzt,
|
|
# hat keinen Spielknoten und würde das Paket ins Leere laufen lassen.
|
|
var values := _all_values()
|
|
for i in g.seats.size():
|
|
var peer: int = g.seats[i].peer
|
|
if g._peer_live(peer):
|
|
g._reveal.rpc_id(peer, values, g.banner)
|
|
g._push_state()
|
|
await g._sleep(g.ZEIT_BECHER)
|
|
if not g._alive():
|
|
return
|
|
|
|
# 2. Zählen. Die Ansage in der Mitte färbt sich jetzt ein.
|
|
g.reveal_total = total
|
|
g.banner = "%d gefunden, %d angesagt" % [total, b.count]
|
|
g._push_state()
|
|
await g._sleep(g.ZEIT_ZAEHLEN)
|
|
if not g._alive():
|
|
return
|
|
|
|
# 3. Urteil. Bei "Genau" trifft es alle anderen - oder nur den Rufer.
|
|
var verlierer: Array = []
|
|
var winner: int
|
|
var bonus := -1
|
|
if genau and total == int(b.count):
|
|
# Fester Schwung von zwei, egal wie viele am Tisch sitzen: der Ansager
|
|
# verliert einen, der Rufer bekommt einen. Mehr als eine Anfechtung
|
|
# bringt, weniger als "alle anderen" - das kippte bei vielen Spielern.
|
|
verlierer = [int(b.seat)]
|
|
winner = rufer
|
|
# Der Bonuswürfel füllt nur auf: wer schon seine Startzahl hat, bekommt keinen.
|
|
if g.seats[rufer].count < g.dice_start:
|
|
bonus = rufer
|
|
g.banner = "Genau! %s verliert, %s bekommt einen Würfel" % [
|
|
g.seats[int(b.seat)].name, g.seats[rufer].name]
|
|
else:
|
|
g.banner = "Genau! %s verliert" % g.seats[int(b.seat)].name
|
|
elif genau:
|
|
verlierer = [rufer]
|
|
winner = int(b.seat)
|
|
g.banner = "Daneben - %s verliert" % g.seats[rufer].name
|
|
else:
|
|
var loser := rufer if total >= int(b.count) else int(b.seat)
|
|
verlierer = [loser]
|
|
winner = int(b.seat) if loser == rufer else rufer
|
|
g.banner = "%s verliert" % g.seats[loser].name
|
|
g._log("%d x %d angesagt - tatsächlich %d. %s" % [b.count, b.face, total, g.banner])
|
|
g._topf_an(winner)
|
|
g._push_state()
|
|
await g._sleep(g.ZEIT_URTEIL)
|
|
if not g._alive():
|
|
return
|
|
|
|
for l: int in verlierer:
|
|
g.seats[l].count -= 1
|
|
if g.seats[l].count <= 0:
|
|
g.seats[l].alive = false
|
|
g.seats[l].count = 0
|
|
g.host_values[l] = []
|
|
g.table.set_dice_count(l, 0)
|
|
g._log("%s scheidet aus." % g.seats[l].name)
|
|
else:
|
|
g._zieh_muenze(l)
|
|
if bonus >= 0 and g.seats[bonus].alive:
|
|
g.seats[bonus].count += 1
|
|
g.host_values[bonus].append(g.rng.randi_range(1, 6))
|
|
g.table.set_dice_count(bonus, g.seats[bonus].count)
|
|
# Nach einem Treffer beginnt der Rufer, sonst der Verlierer.
|
|
var naechster: int = winner if genau and total == int(b.count) else verlierer[0]
|
|
g.starter = naechster if g.seats[naechster].alive else g._next_alive(naechster)
|
|
# Nur wer noch spielt, bekommt den Becher wieder. Auf einer leeren Zone
|
|
# sähe er aus, als lägen dort noch Würfel.
|
|
for i in g.seats.size():
|
|
g.table.set_dice_visible(i, false)
|
|
g.table.set_cup_down(i, g.seats[i].alive)
|
|
g.banner = ""
|
|
g._push_state()
|
|
|
|
|
|
func _all_values() -> Array:
|
|
var out: Array = []
|
|
for i in g.seats.size():
|
|
out.append(g.host_values[i] if g.seats[i].alive else [])
|
|
return out
|