mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 15:10:43 +00:00
Extend winner schema (#1333)
## Description: Extend the winner schema to support multi-player wins (vote for peace, teams). ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I process any text displayed to the user through translateText() and I've added it to the en.json file - [x] I have added relevant tests to the test directory - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors
This commit is contained in:
@@ -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);
|
||||
}
|
||||
|
||||
@@ -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(
|
||||
|
||||
+2
-2
@@ -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<typeof WinnerSchema>;
|
||||
|
||||
@@ -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 [];
|
||||
|
||||
@@ -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 {
|
||||
|
||||
Reference in New Issue
Block a user