This commit is contained in:
team3
2026-09-16 15:04:02 +02:00
parent 3be22351a3
commit b9d6b115c0
23 changed files with 795 additions and 425 deletions

View File

@@ -35,6 +35,9 @@ var room_code := ""
var in_game := false
## Wunsch für eine neue Solopartie; das frisch geladene Menü löst ihn ein.
var rematch: Dictionary = {}
## Raum und Name nach einem Verbindungsabbruch - für "Zurück in Raum XY".
## Ein bewusstes Verlassen löscht es.
var letzter_raum: Dictionary = {}
# ── Server ───────────────────────────────────────────────────────────────────
var dedicated := false
@@ -100,6 +103,7 @@ func serve(port: int) -> bool:
func leave() -> void:
letzter_raum = {}
if multiplayer.multiplayer_peer != null:
multiplayer.multiplayer_peer.close()
multiplayer.multiplayer_peer = null
@@ -131,6 +135,8 @@ func _on_connect_fail() -> void:
func _on_server_disconnected() -> void:
if in_game and room_code != "" and room_code != SOLO:
letzter_raum = {"code": room_code, "name": player_name}
multiplayer.multiplayer_peer = null
lobby.clear()
owner_id = 0
@@ -252,7 +258,7 @@ func _push_lobby(code: String, data: Dictionary, besitzer: int) -> void:
# ── Start ────────────────────────────────────────────────────────────────────
## Einzelspieler: kein Netzwerk, nur der lokale Spieler und Bots.
func start_singleplayer(pname: String, ai_count: int, stufe := 1) -> void:
func start_singleplayer(pname: String, ai_count: int, stufe := 1, dice := 5) -> void:
player_name = pname
multiplayer.multiplayer_peer = OfflineMultiplayerPeer.new()
room_code = SOLO
@@ -262,16 +268,51 @@ func start_singleplayer(pname: String, ai_count: int, stufe := 1) -> void:
in_game = true
lobby_changed.emit()
game_started.emit(SOLO, {"peers": [1], "names": lobby.duplicate(), "ai": ai_count,
"stufe": stufe})
"stufe": stufe, "dice": dice})
## Der Host bittet den Server um den Start.
func request_start(ai_count: int, stufe := 1) -> void:
_req_start.rpc_id(1, ai_count, stufe)
## Nach einem Abbruch mit demselben Namen zurück in die laufende Partie.
func wieder_rein() -> void:
var r := letzter_raum
letzter_raum = {}
join_room(String(r.code), String(r.name))
## Der Raumbesitzer will nach dem Ende noch eine Partie mit derselben Runde.
func request_rematch() -> void:
_req_rematch.rpc_id(1)
@rpc("any_peer", "reliable")
func _req_start(ai_count: int, stufe: int) -> void:
func _req_rematch() -> void:
if not multiplayer.is_server():
return
var id := multiplayer.get_remote_sender_id()
var code: String = peer_raum.get(id, "")
var raum: Dictionary = raeume.get(code, {})
if raum.is_empty() or not raum.in_game or id != raum.owner:
return
var order: Array = raum.lobby.keys()
order.sort()
if order.size() + int(raum.get("ai", 0)) < 2:
return
raum.bestaetigt = {}
var cfg := {"peers": order, "names": raum.lobby.duplicate(), "ai": int(raum.get("ai", 0)),
"stufe": int(raum.get("stufe", 1)), "dice": int(raum.get("dice", 5)), "rematch": true}
room_closed.emit(code) # alter Spielknoten weg, auf dem Server
_start_zustellen(code, cfg)
game_started.emit(code, cfg)
print("Raum %s spielt noch einmal." % code)
## Der Host bittet den Server um den Start.
## `dice` unter 5 nutzen nur die Tests, für kurze Partien.
func request_start(ai_count: int, stufe := 1, dice := 5) -> void:
_req_start.rpc_id(1, ai_count, stufe, dice)
@rpc("any_peer", "reliable")
func _req_start(ai_count: int, stufe: int, dice: int) -> void:
if not multiplayer.is_server():
return
var id := multiplayer.get_remote_sender_id()
@@ -284,8 +325,11 @@ func _req_start(ai_count: int, stufe: int) -> void:
if order.size() + ai_count < 2:
return
raum.in_game = true
raum.ai = ai_count
raum.stufe = clampi(stufe, 0, 2)
raum.dice = clampi(dice, 1, 5)
var cfg := {"peers": order, "names": raum.lobby.duplicate(), "ai": ai_count,
"stufe": clampi(stufe, 0, 2)}
"stufe": clampi(stufe, 0, 2), "dice": clampi(dice, 1, 5)}
_start_zustellen(code, cfg)
game_started.emit(code, cfg)
@@ -323,7 +367,7 @@ func _start_erhalten() -> void:
@rpc("authority", "reliable")
func _begin(code: String, cfg: Dictionary) -> void:
_start_erhalten.rpc_id(1)
if in_game and room_code == code:
if in_game and room_code == code and not cfg.get("rematch", false):
return # Nachzügler-Paket, die Partie läuft hier schon
in_game = true
room_code = code