Add team size details to Public Lobby UI

## Description:

- Introduced new methods in PublicLobby to calculate team size and total based on game configuration.
- Updated UI to display detailed team information, including the number of players per team.
- Added a new localization entry for "players_per_team" in en.json to support the new feature.

## Please complete the following:

- [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.

## Please put your Discord username so you can be contacted if a bug or regression is found:

YourUsername
This commit is contained in:
scamiv
2025-12-09 15:05:07 +01:00
parent ab53ee687f
commit f34545ddc6
2 changed files with 96 additions and 11 deletions
+2 -1
View File
@@ -238,7 +238,8 @@
"teams_Trios": "Trios (teams of 3)",
"teams_Quads": "Quads (teams of 4)",
"teams_hvn": "Humans Vs Nations",
"teams": "{num} teams"
"teams": "{num} teams",
"players_per_team": "{num} Players per Team"
},
"matchmaking_modal": {
"title": "Matchmaking",
+94 -10
View File
@@ -1,7 +1,14 @@
import { LitElement, html } from "lit";
import { customElement, state } from "lit/decorators.js";
import { renderDuration, translateText } from "../client/Utils";
import { GameMapType, GameMode, HumansVsNations } from "../core/game/Game";
import {
Duos,
GameMapType,
GameMode,
HumansVsNations,
Quads,
Trios,
} from "../core/game/Game";
import { GameID, GameInfo } from "../core/Schemas";
import { generateID } from "../core/Util";
import { JoinLobbyEvent } from "./Main";
@@ -122,6 +129,20 @@ export class PublicLobby extends LitElement {
? (lobby.gameConfig.playerTeams ?? 0)
: null;
const maxPlayers = lobby.gameConfig.maxPlayers ?? 0;
const teamSize = this.getTeamSize(teamCount, maxPlayers);
const teamTotal = this.getTeamTotal(teamCount, teamSize, maxPlayers);
const modeLabel = this.getModeLabel(
lobby.gameConfig.gameMode,
teamCount,
teamTotal,
);
const teamDetailLabel = this.getTeamDetailLabel(
lobby.gameConfig.gameMode,
teamCount,
teamTotal,
teamSize,
);
const mapImageSrc = this.mapImages.get(lobby.gameID);
return html`
@@ -159,16 +180,17 @@ export class PublicLobby extends LitElement {
? "text-green-600"
: "text-blue-600"} bg-white rounded-sm px-1"
>
${lobby.gameConfig.gameMode === GameMode.Team
? typeof teamCount === "string"
? teamCount === HumansVsNations
? translateText("public_lobby.teams_hvn")
: translateText(`public_lobby.teams_${teamCount}`)
: translateText("public_lobby.teams", {
num: teamCount ?? 0,
})
: translateText("game_mode.ffa")}</span
${modeLabel}</span
>
${teamDetailLabel
? html`<span
class="text-sm ${this.isLobbyHighlighted
? "text-green-600"
: "text-blue-600"} bg-white rounded-sm px-1 ml-1"
>
${teamDetailLabel}
</span>`
: ""}
<span
>${translateText(
`map.${lobby.gameConfig.gameMap.toLowerCase().replace(/\s+/g, "")}`,
@@ -193,6 +215,68 @@ export class PublicLobby extends LitElement {
this.currLobby = null;
}
private getTeamSize(
teamCount: number | string | null,
maxPlayers: number,
): number | undefined {
if (typeof teamCount === "string") {
if (teamCount === Duos) return 2;
if (teamCount === Trios) return 3;
if (teamCount === Quads) return 4;
if (teamCount === HumansVsNations) return Math.floor(maxPlayers / 2);
return undefined;
}
if (typeof teamCount === "number" && teamCount > 0) {
return Math.floor(maxPlayers / teamCount);
}
return undefined;
}
private getTeamTotal(
teamCount: number | string | null,
teamSize: number | undefined,
maxPlayers: number,
): number | undefined {
if (typeof teamCount === "number") return teamCount;
if (teamCount === HumansVsNations) return 2;
if (teamSize && teamSize > 0) return Math.floor(maxPlayers / teamSize);
return undefined;
}
private getModeLabel(
gameMode: GameMode,
teamCount: number | string | null,
teamTotal: number | undefined,
): string {
if (gameMode !== GameMode.Team) return translateText("game_mode.ffa");
if (teamCount === HumansVsNations)
return translateText("public_lobby.teams_hvn");
const totalTeams =
teamTotal ?? (typeof teamCount === "number" ? teamCount : 0);
return translateText("public_lobby.teams", { num: totalTeams });
}
private getTeamDetailLabel(
gameMode: GameMode,
teamCount: number | string | null,
teamTotal: number | undefined,
teamSize: number | undefined,
): string | null {
if (gameMode !== GameMode.Team) return null;
if (typeof teamCount === "string" && teamCount !== HumansVsNations) {
const teamKey = `public_lobby.teams_${teamCount}`;
const maybeTranslated = translateText(teamKey);
if (maybeTranslated !== teamKey) return maybeTranslated;
}
if (teamTotal !== undefined && teamSize !== undefined) {
return translateText("public_lobby.players_per_team", { num: teamSize });
}
return null;
}
private lobbyClicked(lobby: GameInfo) {
if (this.isButtonDebounced) {
return;