Visual improvements

This commit is contained in:
2026-09-17 00:56:59 +02:00
parent bc727c408f
commit b08074a2f3
19 changed files with 610 additions and 49 deletions
+55 -3
View File
@@ -160,9 +160,19 @@ export class GameServer extends EventEmitter {
onPeerJoined(peerId, playerName = "") {
if (!this._configured) return;
this._assignCiv(peerId, playerName);
const civ = this.peerCiv.has(peerId) ? this.peerCiv.get(peerId) : -1;
this.network.send(peerId, { t: "game_state", state: this.state.snapshot(civ) });
// A returning player keeps the nation they claimed before.
if (this._reclaimIdentity(peerId, playerName)) {
this.network.send(peerId, { t: "game_state", state: this.state.snapshot(this.peerCiv.get(peerId)) });
return;
}
// Otherwise offer every nation no one has claimed yet and let the player
// pick. They stay a spectator (civ -1) until they answer.
this.peerCiv.set(peerId, -1);
const options = this.availableCivs();
this.network.send(peerId, { t: "choose_civ", civs: options });
if (options.length === 0) {
this.network.send(peerId, { t: "game_state", state: this.state.snapshot(-1) });
}
}
onPeerLeft(peerId) {
@@ -170,6 +180,48 @@ export class GameServer extends EventEmitter {
this.peerNames.delete(peerId);
}
// Indices of the civilisations no connected peer has claimed.
availableCivs() {
if (!this._configured || !this.state) return [];
const used = new Set(this.peerCiv.values());
const options = [];
for (let i = 0; i < this.state.civilisations.length; i++) {
if (used.has(i)) continue;
const civ = this.state.civilisations[i];
options.push({ index: i, id: civ.id, name: civ.name });
}
return options;
}
// Claims one of the offered civilisations for a joining peer. Rejects an
// index that is out of range or already taken by someone else.
claimCiv(peerId, index) {
if (!this._configured || !this.state) return false;
const choice = Number(index);
if (!Number.isInteger(choice) || choice < 0 || choice >= this.state.civilisations.length) {
return false;
}
if (Array.from(this.peerCiv.values()).includes(choice)) return false;
this.peerCiv.set(peerId, choice);
const name = this.peerNames.get(peerId);
if (name) this.identityCiv.set(name, choice);
this.network.send(peerId, { t: "civ_assigned", civ: choice });
this._broadcastState();
return true;
}
// Re-attaches a known player to the nation they held before, as long as no
// one else has claimed it in the meantime.
_reclaimIdentity(peerId, playerName) {
if (!playerName || !this.identityCiv.has(playerName)) return false;
const choice = this.identityCiv.get(playerName);
if (choice < 0 || choice >= this.state.civilisations.length) return false;
if (Array.from(this.peerCiv.values()).includes(choice)) return false;
this.peerCiv.set(peerId, choice);
this.network.send(peerId, { t: "civ_assigned", civ: choice });
return true;
}
_assignCiv(peerId, playerName = "") {
if (this._configured === false || this.state == null) return;
const used = Array.from(this.peerCiv.values());
+3
View File
@@ -132,6 +132,9 @@ export function startServer({ port = 27015, bind = "127.0.0.1", log = console.lo
peer.send(JSON.stringify({ t: "game_configured" }));
}
break;
case "claim_civ":
gameServer.claimCiv(connection.id, message.civ);
break;
case "order":
gameServer.handleOrder(connection.id, message.order || {});
break;