This commit is contained in:
team3
2026-09-16 13:21:56 +02:00
parent 7979d5c336
commit 3be22351a3
25 changed files with 734 additions and 195 deletions

View File

@@ -34,6 +34,7 @@ var _muenze_laeuft := false ## eine Münze wird gerade aufgelöst
var _wurf_nr := 0 ## zählt die Würfe übers Spiel, damit das HUD neue erkennt
var _klang_phase := "" ## letzte Phase, für die ein Klang lief
var _gezaehlt_gezeigt := false ## Hervorhebung beim Aufdecken lief schon
var _topf_ziel := -1 ## wer den Topf gerade genommen hat, für den Flug der Münzen
var last_bids: Dictionary = {} ## seat -> letzte Ansage dieser Runde
var log_lines: Array = []
var phase := "lobby"
@@ -56,13 +57,20 @@ func _ready() -> void:
func setup(cfg: Dictionary) -> void:
DiceAI.stufe = int(cfg.get("stufe", 1))
seats.clear()
var peers: Array = cfg.peers
for p in peers:
seats.append({"peer": int(p), "name": String(cfg.names[p]), "ai": false,
"count": START_DICE, "alive": true})
for i in int(cfg.ai):
seats.append({"peer": 0, "name": "Bot %d" % (i + 1), "ai": true,
"count": START_DICE, "alive": true})
if cfg.has("seats"):
# Rückkehrer: die laufende Aufstellung, Platz für Platz, in der
# Reihenfolge des Servers - daran hängen alle Indizes im Zustand.
for s in cfg.seats:
seats.append({"peer": int(s.peer), "name": String(s.name), "ai": bool(s.ai),
"count": int(s.count), "alive": bool(s.alive), "verwaist": false})
else:
var peers: Array = cfg.peers
for p in peers:
seats.append({"peer": int(p), "name": String(cfg.names[p]), "ai": false,
"count": START_DICE, "alive": true, "verwaist": false})
for i in int(cfg.ai):
seats.append({"peer": 0, "name": "Bot %d" % (i + 1), "ai": true,
"count": START_DICE, "alive": true, "verwaist": false})
# Der Spielserver spielt nicht mit und bekommt deshalb keinen Platz.
var me := multiplayer.get_unique_id()
@@ -93,7 +101,7 @@ func setup(cfg: Dictionary) -> void:
# Die Startmünze zieht nur der Host. Beim Client kommt sie mit dem
# ersten Zustand, sonst läge dort kurz eine andere.
hand[i] = [BoosterDB.zieh(rng)] if multiplayer.is_server() else []
table.set_dice_count(i, START_DICE)
table.set_dice_count(i, seats[i].count)
table.set_dice_visible(i, false)
table.set_cup_down(i, i != local_seat)
host_values.append([])
@@ -110,10 +118,44 @@ func _on_peer_lost(peer: int) -> void:
return
seats[seat].ai = true
seats[seat].peer = 0
seats[seat].verwaist = true
_log("%s hat das Spiel verlassen - übernimmt ein Bot." % seats[seat].name)
_push_state()
## Nur Server: ein Rückkehrer mit diesem Namen bekommt seinen Platz zurück.
## Gibt die Aufstellung für seinen Client zurück, oder {} wenn es keinen
## verwaisten Platz mit dem Namen gibt.
func wiedereinstieg(peer: int, pname: String) -> Dictionary:
for i in seats.size():
var s = seats[i]
if not s.verwaist or String(s.name).to_lower() != pname.to_lower():
continue
s.peer = peer
s.ai = false
s.verwaist = false
_log("%s ist zurück und übernimmt wieder." % s.name)
var aufstellung: Array = []
for t in seats:
aufstellung.append({"peer": t.peer, "name": t.name, "ai": t.ai,
"count": t.count, "alive": t.alive})
_nachliefern(i)
return {"seats": aufstellung, "stufe": DiceAI.stufe}
return {}
## Dem Rückkehrer Zustand und Würfellage schicken - kurz verzögert, damit
## sein Spielknoten steht, bevor das erste Paket dort ankommt.
func _nachliefern(seat: int) -> void:
await _sleep(0.6)
if not _alive():
return
_refresh_labels()
_push_state()
if _peer_live(seats[seat].peer):
_dice_snapshot.rpc_id(seats[seat].peer, _pack(seat))
func _refresh_labels() -> void:
for i in seats.size():
var s = seats[i]
@@ -214,6 +256,7 @@ func _phase_roll() -> void:
gezaehlt.clear()
verlauf.clear()
must_bid.clear()
_topf_ziel = -1
banner = ""
_log("--- Neue Runde ---")
@@ -670,6 +713,7 @@ func _topf_an(winner: int) -> void:
return
var h: Array = hand.get(winner, [])
var genommen := 0
_topf_ziel = winner
while not topf.is_empty() and h.size() < BoosterDB.HANDLIMIT:
h.append(String(topf.pop_front().id))
genommen += 1
@@ -832,6 +876,8 @@ func _state_for(seat: int) -> Dictionary:
"actual": reveal_total if phase == "reveal" else 0,
"bids": _seat_bids(),
"verlauf": verlauf.duplicate(true),
"topf_an": _topf_ziel,
"log": log_lines.duplicate(),
"hand": (hand.get(seat, []) as Array).duplicate(),
}
@@ -865,7 +911,7 @@ func _apply_state(st: Dictionary) -> void:
table.set_cup_down(i, seats[i].alive)
table.set_dice_visible(local_seat, true)
_refresh_labels()
table.set_topf(st.get("boosts", []))
table.set_topf(st.get("boosts", []), int(st.get("topf_an", -1)))
if phase == "reveal" and int(st.get("actual", -1)) >= 0 and not _gezaehlt_gezeigt:
_gezaehlt_gezeigt = true
if not bid.is_empty():