mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:50:43 +00:00
Show max troops in PlayerInfoOverlay and leaderboard 🖌️ (#2625)
## Description: In the main discord, people seem to be divided in their opinions about this. But lets see what the playtest-people are saying, we can easily roll this back. <img width="197" height="312" alt="Screenshot 2025-12-15 220648" src="https://github.com/user-attachments/assets/c6acd1f8-03b1-4949-b15e-6a32f8460e18" /> <img width="405" height="323" alt="Screenshot 2025-12-15 220623" src="https://github.com/user-attachments/assets/21190a6f-1a0b-4db3-b6d0-c0722e98902a" /> ## 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 ## Please put your Discord username so you can be contacted if a bug or regression is found: FloPinguin
This commit is contained in:
@@ -557,7 +557,7 @@
|
||||
"team": "Team",
|
||||
"owned": "Owned",
|
||||
"gold": "Gold",
|
||||
"troops": "Troops",
|
||||
"maxtroops": "Max troops",
|
||||
"launchers": "Launchers",
|
||||
"sams": "SAMs",
|
||||
"warships": "Warships",
|
||||
@@ -573,6 +573,7 @@
|
||||
"team": "Team",
|
||||
"alliance_timeout": "Alliance ends in",
|
||||
"troops": "Troops",
|
||||
"maxtroops": "Max troops",
|
||||
"a_troops": "Attacking troops",
|
||||
"gold": "Gold",
|
||||
"ports": "Ports",
|
||||
|
||||
@@ -1,7 +1,7 @@
|
||||
import { LitElement, html } from "lit";
|
||||
import { customElement, property, state } from "lit/decorators.js";
|
||||
import { repeat } from "lit/directives/repeat.js";
|
||||
import { translateText } from "../../../client/Utils";
|
||||
import { renderTroops, translateText } from "../../../client/Utils";
|
||||
import { EventBus, GameEvent } from "../../../core/EventBus";
|
||||
import { GameView, PlayerView, UnitView } from "../../../core/game/GameView";
|
||||
import { renderNumber } from "../../Utils";
|
||||
@@ -12,7 +12,7 @@ interface Entry {
|
||||
position: number;
|
||||
score: string;
|
||||
gold: string;
|
||||
troops: string;
|
||||
maxTroops: string;
|
||||
isMyPlayer: boolean;
|
||||
isOnSameTeam: boolean;
|
||||
player: PlayerView;
|
||||
@@ -44,7 +44,7 @@ export class Leaderboard extends LitElement implements Layer {
|
||||
private showTopFive = true;
|
||||
|
||||
@state()
|
||||
private _sortKey: "tiles" | "gold" | "troops" = "tiles";
|
||||
private _sortKey: "tiles" | "gold" | "maxtroops" = "tiles";
|
||||
|
||||
@state()
|
||||
private _sortOrder: "asc" | "desc" = "desc";
|
||||
@@ -63,7 +63,7 @@ export class Leaderboard extends LitElement implements Layer {
|
||||
}
|
||||
}
|
||||
|
||||
private setSort(key: "tiles" | "gold" | "troops") {
|
||||
private setSort(key: "tiles" | "gold" | "maxtroops") {
|
||||
if (this._sortKey === key) {
|
||||
this._sortOrder = this._sortOrder === "asc" ? "desc" : "asc";
|
||||
} else {
|
||||
@@ -82,14 +82,16 @@ export class Leaderboard extends LitElement implements Layer {
|
||||
const compare = (a: number, b: number) =>
|
||||
this._sortOrder === "asc" ? a - b : b - a;
|
||||
|
||||
const maxTroops = (p: PlayerView) => this.game!.config().maxTroops(p);
|
||||
|
||||
switch (this._sortKey) {
|
||||
case "gold":
|
||||
sorted = sorted.sort((a, b) =>
|
||||
compare(Number(a.gold()), Number(b.gold())),
|
||||
);
|
||||
break;
|
||||
case "troops":
|
||||
sorted = sorted.sort((a, b) => compare(a.troops(), b.troops()));
|
||||
case "maxtroops":
|
||||
sorted = sorted.sort((a, b) => compare(maxTroops(a), maxTroops(b)));
|
||||
break;
|
||||
default:
|
||||
sorted = sorted.sort((a, b) =>
|
||||
@@ -106,7 +108,7 @@ export class Leaderboard extends LitElement implements Layer {
|
||||
: alivePlayers;
|
||||
|
||||
this.players = playersToShow.map((player, index) => {
|
||||
const troops = player.troops() / 10;
|
||||
const maxTroops = this.game!.config().maxTroops(player);
|
||||
return {
|
||||
name: player.displayName(),
|
||||
position: index + 1,
|
||||
@@ -114,7 +116,7 @@ export class Leaderboard extends LitElement implements Layer {
|
||||
player.numTilesOwned() / numTilesWithoutFallout,
|
||||
),
|
||||
gold: renderNumber(player.gold()),
|
||||
troops: renderNumber(troops),
|
||||
maxTroops: renderTroops(maxTroops),
|
||||
isMyPlayer: player === myPlayer,
|
||||
isOnSameTeam:
|
||||
myPlayer !== null &&
|
||||
@@ -136,7 +138,7 @@ export class Leaderboard extends LitElement implements Layer {
|
||||
}
|
||||
|
||||
if (myPlayer.isAlive()) {
|
||||
const myPlayerTroops = myPlayer.troops() / 10;
|
||||
const myPlayerMaxTroops = this.game!.config().maxTroops(myPlayer);
|
||||
this.players.pop();
|
||||
this.players.push({
|
||||
name: myPlayer.displayName(),
|
||||
@@ -145,7 +147,7 @@ export class Leaderboard extends LitElement implements Layer {
|
||||
myPlayer.numTilesOwned() / this.game.numLandTiles(),
|
||||
),
|
||||
gold: renderNumber(myPlayer.gold()),
|
||||
troops: renderNumber(myPlayerTroops),
|
||||
maxTroops: renderTroops(myPlayerMaxTroops),
|
||||
isMyPlayer: true,
|
||||
isOnSameTeam: true,
|
||||
player: myPlayer,
|
||||
@@ -181,17 +183,19 @@ export class Leaderboard extends LitElement implements Layer {
|
||||
>
|
||||
<div
|
||||
class="grid bg-gray-800/70 w-full text-xs md:text-xs lg:text-sm"
|
||||
style="grid-template-columns: 30px 100px 70px 55px 75px;"
|
||||
style="grid-template-columns: 30px 100px 70px 55px 105px;"
|
||||
>
|
||||
<div class="contents font-bold bg-gray-700/50">
|
||||
<div class="py-1 md:py-2 text-center border-b border-slate-500">
|
||||
#
|
||||
</div>
|
||||
<div class="py-1 md:py-2 text-center border-b border-slate-500">
|
||||
<div
|
||||
class="py-1 md:py-2 text-center border-b border-slate-500 truncate"
|
||||
>
|
||||
${translateText("leaderboard.player")}
|
||||
</div>
|
||||
<div
|
||||
class="py-1 md:py-2 text-center border-b border-slate-500 cursor-pointer whitespace-nowrap"
|
||||
class="py-1 md:py-2 text-center border-b border-slate-500 cursor-pointer whitespace-nowrap truncate"
|
||||
@click=${() => this.setSort("tiles")}
|
||||
>
|
||||
${translateText("leaderboard.owned")}
|
||||
@@ -202,7 +206,7 @@ export class Leaderboard extends LitElement implements Layer {
|
||||
: ""}
|
||||
</div>
|
||||
<div
|
||||
class="py-1 md:py-2 text-center border-b border-slate-500 cursor-pointer whitespace-nowrap"
|
||||
class="py-1 md:py-2 text-center border-b border-slate-500 cursor-pointer whitespace-nowrap truncate"
|
||||
@click=${() => this.setSort("gold")}
|
||||
>
|
||||
${translateText("leaderboard.gold")}
|
||||
@@ -213,11 +217,11 @@ export class Leaderboard extends LitElement implements Layer {
|
||||
: ""}
|
||||
</div>
|
||||
<div
|
||||
class="py-1 md:py-2 text-center border-b border-slate-500 cursor-pointer whitespace-nowrap"
|
||||
@click=${() => this.setSort("troops")}
|
||||
class="py-1 md:py-2 text-center border-b border-slate-500 cursor-pointer whitespace-nowrap truncate"
|
||||
@click=${() => this.setSort("maxtroops")}
|
||||
>
|
||||
${translateText("leaderboard.troops")}
|
||||
${this._sortKey === "troops"
|
||||
${translateText("leaderboard.maxtroops")}
|
||||
${this._sortKey === "maxtroops"
|
||||
? this._sortOrder === "asc"
|
||||
? "⬆️"
|
||||
: "⬇️"
|
||||
@@ -250,7 +254,7 @@ export class Leaderboard extends LitElement implements Layer {
|
||||
${player.gold}
|
||||
</div>
|
||||
<div class="py-1 md:py-2 text-center border-b border-slate-500">
|
||||
${player.troops}
|
||||
${player.maxTroops}
|
||||
</div>
|
||||
</div>
|
||||
`,
|
||||
|
||||
@@ -254,6 +254,7 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
const isFriendly = myPlayer?.isFriendly(player);
|
||||
const isAllied = myPlayer?.isAlliedWith(player);
|
||||
let relationHtml: TemplateResult | null = null;
|
||||
const maxTroops = this.game.config().maxTroops(player);
|
||||
const attackingTroops = player
|
||||
.outgoingAttacks()
|
||||
.map((a) => a.troops)
|
||||
@@ -359,6 +360,17 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
|
||||
</span>
|
||||
</div>`
|
||||
: ""}
|
||||
${maxTroops >= 1
|
||||
? html`<div
|
||||
class="flex gap-2 text-sm opacity-80"
|
||||
translate="no"
|
||||
>
|
||||
${translateText("player_info_overlay.maxtroops")}
|
||||
<span class="ml-auto mr-0 font-bold">
|
||||
${renderTroops(maxTroops)}
|
||||
</span>
|
||||
</div>`
|
||||
: ""}
|
||||
${attackingTroops >= 1
|
||||
? html`<div
|
||||
class="flex gap-2 text-sm opacity-80"
|
||||
|
||||
Reference in New Issue
Block a user