diff --git a/src/client/components/baseComponents/ranking/GameInfoRanking.ts b/src/client/components/baseComponents/ranking/GameInfoRanking.ts index 015d6ae40..fa78d36f0 100644 --- a/src/client/components/baseComponents/ranking/GameInfoRanking.ts +++ b/src/client/components/baseComponents/ranking/GameInfoRanking.ts @@ -2,6 +2,8 @@ import { AnalyticsRecord, PlayerRecord } from "../../../../core/Schemas"; import { GOLD_INDEX_STEAL, GOLD_INDEX_TRADE, + GOLD_INDEX_TRAIN_OTHER, + GOLD_INDEX_TRAIN_SELF, GOLD_INDEX_WAR, } from "../../../../core/StatsSchemas"; @@ -12,7 +14,8 @@ export enum RankType { MIRV = "MIRV", TotalGold = "TotalGold", StolenGold = "StolenGold", - TradedGold = "TradedGold", + NavalTrade = "NavalTrade", + TrainTrade = "TrainTrade", ConqueredGold = "ConqueredGold", Lifetime = "Lifetime", } @@ -134,10 +137,15 @@ export class Ranking { return Number(player.gold.reduce((sum, gold) => sum + gold, 0n)); case RankType.StolenGold: return Number(player.gold[GOLD_INDEX_STEAL] ?? 0n); - case RankType.TradedGold: + case RankType.NavalTrade: return Number(player.gold[GOLD_INDEX_TRADE] ?? 0n); case RankType.ConqueredGold: return Number(player.gold[GOLD_INDEX_WAR] ?? 0n); + case RankType.TrainTrade: { + const ownTrains = player.gold[GOLD_INDEX_TRAIN_SELF] ?? 0n; + const otherTrains = player.gold[GOLD_INDEX_TRAIN_OTHER] ?? 0n; + return Number(ownTrains + otherTrains); + } } } diff --git a/src/client/components/baseComponents/ranking/PlayerRow.ts b/src/client/components/baseComponents/ranking/PlayerRow.ts index 2ebe635ed..9989962a9 100644 --- a/src/client/components/baseComponents/ranking/PlayerRow.ts +++ b/src/client/components/baseComponents/ranking/PlayerRow.ts @@ -1,5 +1,10 @@ import { LitElement, html } from "lit"; import { customElement, property } from "lit/decorators.js"; +import { + GOLD_INDEX_TRADE, + GOLD_INDEX_TRAIN_OTHER, + GOLD_INDEX_TRAIN_SELF, +} from "src/core/StatsSchemas"; import { renderNumber } from "../../../Utils"; import { PlayerInfo, RankType } from "./GameInfoRanking"; @@ -67,10 +72,12 @@ export class PlayerRow extends LitElement { case RankType.MIRV: return this.renderBombScore(); case RankType.TotalGold: - case RankType.TradedGold: case RankType.ConqueredGold: case RankType.StolenGold: return this.renderGoldScore(); + case RankType.NavalTrade: + case RankType.TrainTrade: + return this.renderTradeScore(); default: return html``; } @@ -109,14 +116,15 @@ export class PlayerRow extends LitElement { `; } - private renderBombType(value: number, highlight: boolean) { + + private renderMultiScoreType(value: number, highlight: boolean) { return html`
- ${value} + ${renderNumber(value)}
`; } @@ -124,17 +132,17 @@ export class PlayerRow extends LitElement { private renderAllBombs() { return html`
- ${this.renderBombType( + ${this.renderMultiScoreType( this.player.atoms, this.rankType === RankType.Atoms, )} / - ${this.renderBombType( + ${this.renderMultiScoreType( this.player.hydros, this.rankType === RankType.Hydros, )} / - ${this.renderBombType( + ${this.renderMultiScoreType( this.player.mirv, this.rankType === RankType.MIRV, )} @@ -142,9 +150,28 @@ export class PlayerRow extends LitElement { `; } + private renderAllTrades() { + const navalTrade = this.player.gold[GOLD_INDEX_TRADE] ?? 0n; + const ownTrainTrade = this.player.gold[GOLD_INDEX_TRAIN_SELF] ?? 0n; + const otherTrainTrade = this.player.gold[GOLD_INDEX_TRAIN_OTHER] ?? 0n; + return html` +
+ ${this.renderMultiScoreType( + Number(navalTrade), + this.rankType === RankType.NavalTrade, + )} + / + ${this.renderMultiScoreType( + Number(ownTrainTrade + otherTrainTrade), + this.rankType === RankType.TrainTrade, + )} +
+ `; + } + private renderBombScore() { return html` -
+
${this.renderPlayerIcon()}
${this.renderPlayerName()} ${this.renderAllBombs()} @@ -157,13 +184,12 @@ export class PlayerRow extends LitElement { return html`
${this.renderPlayerIcon()} -
- ${this.renderPlayerName()} -
+
${this.renderPlayerName()}
+
${renderNumber(this.score)}
@@ -172,6 +198,24 @@ export class PlayerRow extends LitElement { `; } + private renderTradeScore() { + return html` +
+ ${this.renderPlayerIcon()} +
${this.renderPlayerName()}
+
+ +
+
+ ${this.renderAllTrades()} +
+ +
+ `; + } + private renderPlayerName() { return html`
diff --git a/src/client/components/baseComponents/ranking/RankingControls.ts b/src/client/components/baseComponents/ranking/RankingControls.ts index 59e3ea76c..25321d8aa 100644 --- a/src/client/components/baseComponents/ranking/RankingControls.ts +++ b/src/client/components/baseComponents/ranking/RankingControls.ts @@ -7,8 +7,10 @@ const economyRankings = new Set([ RankType.TotalGold, RankType.StolenGold, RankType.ConqueredGold, - RankType.TradedGold, + RankType.NavalTrade, + RankType.TrainTrade, ]); +const tradeRankings = new Set([RankType.NavalTrade, RankType.TrainTrade]); const bombRankings = new Set([RankType.Atoms, RankType.Hydros, RankType.MIRV]); const warRankings = new Set([ RankType.Conquests, @@ -18,6 +20,7 @@ const warRankings = new Set([ ]); const isEconomyRanking = (t: RankType) => economyRankings.has(t); +const isTradeRanking = (t: RankType) => tradeRankings.has(t); const isBombRanking = (t: RankType) => bombRankings.has(t); const isWarRanking = (t: RankType) => warRankings.has(t); @@ -87,7 +90,6 @@ export class RankingControls extends LitElement { if (!isEconomyRanking(this.rankType)) return ""; const econButtons = [ - [RankType.TradedGold, "game_info_modal.trade"], [RankType.StolenGold, "game_info_modal.pirate"], [RankType.ConqueredGold, "game_info_modal.conquered"], [RankType.TotalGold, "game_info_modal.total_gold"], @@ -95,6 +97,11 @@ export class RankingControls extends LitElement { return html`
+ ${this.renderSubButton( + RankType.NavalTrade, + isTradeRanking(this.rankType), + "game_info_modal.trade", + )} ${econButtons.map(([type, label]) => this.renderSubButton(type as RankType, this.rankType === type, label), )} diff --git a/src/client/components/baseComponents/ranking/RankingHeader.ts b/src/client/components/baseComponents/ranking/RankingHeader.ts index 881de1101..6869b9526 100644 --- a/src/client/components/baseComponents/ranking/RankingHeader.ts +++ b/src/client/components/baseComponents/ranking/RankingHeader.ts @@ -36,17 +36,17 @@ export class RankingHeader extends LitElement { case RankType.MIRV: return html`
- ${this.renderBombHeaderButton( + ${this.renderMultipleChoiceHeaderButton( translateText("game_info_modal.atoms"), RankType.Atoms, )} / - ${this.renderBombHeaderButton( + ${this.renderMultipleChoiceHeaderButton( translateText("game_info_modal.hydros"), RankType.Hydros, )} / - ${this.renderBombHeaderButton( + ${this.renderMultipleChoiceHeaderButton( translateText("game_info_modal.mirv"), RankType.MIRV, )} @@ -56,10 +56,15 @@ export class RankingHeader extends LitElement { return html`
${translateText("game_info_modal.all_gold")}
`; - case RankType.TradedGold: - return html`
- ${translateText("game_info_modal.trade")} -
`; + case RankType.NavalTrade: + case RankType.TrainTrade: + return html` +
+ ${this.renderMultipleChoiceHeaderButton("🚂", RankType.TrainTrade)} + / + ${this.renderMultipleChoiceHeaderButton("🚢", RankType.NavalTrade)} +
+ `; case RankType.ConqueredGold: return html`
${translateText("game_info_modal.conquest_gold")} @@ -74,13 +79,13 @@ export class RankingHeader extends LitElement { } } - private renderBombHeaderButton(label: string, type: RankType) { + private renderMultipleChoiceHeaderButton(label: string, type: RankType) { return html` diff --git a/tests/GameInfoRanking.test.ts b/tests/GameInfoRanking.test.ts index 7955fb807..1e523ae93 100644 --- a/tests/GameInfoRanking.test.ts +++ b/tests/GameInfoRanking.test.ts @@ -13,6 +13,8 @@ import { AnalyticsRecord } from "../src/core/Schemas"; import { GOLD_INDEX_STEAL, GOLD_INDEX_TRADE, + GOLD_INDEX_TRAIN_OTHER, + GOLD_INDEX_TRAIN_SELF, GOLD_INDEX_WAR, } from "../src/core/StatsSchemas"; @@ -55,7 +57,7 @@ describe("Ranking class", () => { stats: { units: { port: [2n, 0n, 0n, 2n] }, conquests: 5n, - gold: [0n, 100n, 20n, 0n], // total 120 + gold: [0n, 100n, 20n, 0n, 15n, 5n], // total 140 bombs: { abomb: [1n], hbomb: [1n], @@ -70,7 +72,7 @@ describe("Ranking class", () => { stats: { units: { city: [2n, 0n, 0n, 2n] }, conquests: 8n, - gold: [0n, 50n, 10n, 5n], // total 65 + gold: [0n, 50n, 10n, 5n], // total 65, no train trade bombs: { abomb: [0n], hbomb: [2n], @@ -86,7 +88,7 @@ describe("Ranking class", () => { // no units, but has conquests/killedAt to count as played conquests: 8n, killedAt: BigInt(600), - gold: [0n, 10n, 2n, 10n], // total 22 + gold: [0n, 10n, 2n, 10n, 0n, 5n], // total 27 bombs: {}, }, persistentID: null, @@ -178,9 +180,14 @@ describe("Ranking class", () => { expect(r.score(p1, RankType.StolenGold)).toBe( Number(p1.gold[GOLD_INDEX_STEAL] ?? 0n), ); - expect(r.score(p1, RankType.TradedGold)).toBe( + expect(r.score(p1, RankType.NavalTrade)).toBe( Number(p1.gold[GOLD_INDEX_TRADE] ?? 0n), ); + const ownTrain = p1.gold[GOLD_INDEX_TRAIN_SELF] ?? 0n; + const otherTrain = p1.gold[GOLD_INDEX_TRAIN_OTHER] ?? 0n; + expect(r.score(p1, RankType.TrainTrade)).toBe( + Number(ownTrain + otherTrain), + ); expect(r.score(p1, RankType.ConqueredGold)).toBe( Number(p1.gold[GOLD_INDEX_WAR] ?? 0n), );