diff --git a/src/client/ClientGameRunner.ts b/src/client/ClientGameRunner.ts index 12e21b1d6..ebee81856 100644 --- a/src/client/ClientGameRunner.ts +++ b/src/client/ClientGameRunner.ts @@ -7,7 +7,6 @@ import { GameStartInfo, PlayerRecord, ServerMessage, - Winner, } from "../core/Schemas"; import { createGameRecord } from "../core/Util"; import { ServerConfig } from "../core/configuration/Config"; @@ -200,13 +199,6 @@ export class ClientGameRunner { this.lastMessageTime = Date.now(); } - private getWinner(update: WinUpdate): Winner { - if (update.winner[0] !== "player") return update.winner; - const clientId = this.gameView.playerBySmallID(update.winner[1]).clientID(); - if (clientId === null) return; - return ["player", clientId]; - } - private saveGame(update: WinUpdate) { if (this.myPlayer === null) { return; @@ -219,7 +211,6 @@ export class ClientGameRunner { stats: update.allPlayersStats[this.lobby.clientID], }, ]; - const winner = this.getWinner(update); if (this.lobby.gameStartInfo === undefined) { throw new Error("missing gameStartInfo"); @@ -232,7 +223,7 @@ export class ClientGameRunner { [], startTime(), Date.now(), - winner, + update.winner, ); endGame(record); } diff --git a/src/client/graphics/layers/WinModal.ts b/src/client/graphics/layers/WinModal.ts index c22dea5f9..2e3b4667b 100644 --- a/src/client/graphics/layers/WinModal.ts +++ b/src/client/graphics/layers/WinModal.ts @@ -249,7 +249,9 @@ export class WinModal extends LitElement implements Layer { const updates = this.game.updatesSinceLastTick(); const winUpdates = updates !== null ? updates[GameUpdateType.Win] : []; winUpdates.forEach((wu) => { - if (wu.winner[0] === "team") { + if (wu.winner === undefined) { + // ... + } else if (wu.winner[0] === "team") { this.eventBus.emit(new SendWinnerEvent(wu.winner, wu.allPlayersStats)); if (wu.winner[1] === this.game.myPlayer()?.team()) { this._title = translateText("win_modal.your_team"); @@ -260,8 +262,8 @@ export class WinModal extends LitElement implements Layer { } this.show(); } else { - const winner = this.game.playerBySmallID(wu.winner[1]); - if (!winner.isPlayer()) return; + const winner = this.game.playerByClientID(wu.winner[1]); + if (!winner?.isPlayer()) return; const winnerClient = winner.clientID(); if (winnerClient !== null) { this.eventBus.emit( diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts index 5b726ea74..2697fe560 100644 --- a/src/core/Schemas.ts +++ b/src/core/Schemas.ts @@ -393,8 +393,8 @@ export const GameStartInfoSchema = z.object({ export const WinnerSchema = z .union([ - z.tuple([z.literal("player"), ID]), - z.tuple([z.literal("team"), SafeString]), + z.tuple([z.literal("player"), ID]).rest(ID), + z.tuple([z.literal("team"), SafeString]).rest(ID), ]) .optional(); export type Winner = z.infer; diff --git a/src/core/game/GameImpl.ts b/src/core/game/GameImpl.ts index d1deab5fb..151ea84a7 100644 --- a/src/core/game/GameImpl.ts +++ b/src/core/game/GameImpl.ts @@ -1,5 +1,5 @@ import { Config } from "../configuration/Config"; -import { AllPlayersStats, ClientID } from "../Schemas"; +import { AllPlayersStats, ClientID, Winner } from "../Schemas"; import { simpleHash } from "../Util"; import { AllianceImpl } from "./AllianceImpl"; import { AllianceRequestImpl } from "./AllianceRequestImpl"; @@ -614,14 +614,31 @@ export class GameImpl implements Game { setWinner(winner: Player | Team, allPlayersStats: AllPlayersStats): void { this.addUpdate({ type: GameUpdateType.Win, - winner: - typeof winner === "string" - ? ["team", winner] - : ["player", winner.smallID()], + winner: this.makeWinner(winner), allPlayersStats, }); } + private makeWinner(winner: string | Player): Winner | undefined { + if (typeof winner === "string") { + return [ + "team", + winner, + ...this.players() + .filter((p) => p.team() === winner && p.clientID() !== null) + .map((p) => p.clientID()!), + ]; + } else { + const clientId = winner.clientID(); + if (clientId === null) return; + return [ + "player", + clientId, + // TODO: Assists (vote for peace) + ]; + } + } + teams(): Team[] { if (this._config.gameConfig().gameMode !== GameMode.Team) { return []; diff --git a/src/core/game/GameUpdates.ts b/src/core/game/GameUpdates.ts index a471c41df..c3150fa8b 100644 --- a/src/core/game/GameUpdates.ts +++ b/src/core/game/GameUpdates.ts @@ -1,4 +1,4 @@ -import { AllPlayersStats, ClientID } from "../Schemas"; +import { AllPlayersStats, ClientID, Winner } from "../Schemas"; import { EmojiMessage, GameUpdates, @@ -232,8 +232,7 @@ export type DisplayChatMessageUpdate = { export interface WinUpdate { type: GameUpdateType.Win; allPlayersStats: AllPlayersStats; - // Player id or team name. - winner: ["player", number] | ["team", Team]; + winner: Winner; } export interface HashUpdate {