Files
pirate-dice/scripts/aufdecken.gd
2026-09-16 17:55:28 +02:00

112 lines
3.7 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 geht nur an den, der hinten liegt: weniger Würfel als
# der Ansager. Sonst schiebt Genau nur hin und her, und der Tisch wird
# nie leerer - gemessen an Partien mit über 50 Runden.
if g.seats[rufer].count < g.seats[int(b.seat)].count:
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.ausgeschieden.append(l)
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