mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 11:40:42 +00:00
Merge branch 'v29'
This commit is contained in:
@@ -228,6 +228,8 @@
|
||||
"total_gold": "Total",
|
||||
"all_gold": "All gold",
|
||||
"trade": "Trade",
|
||||
"train_trade": "Train",
|
||||
"naval_trade": "Tradeship",
|
||||
"conquest_gold": "Conquered player gold",
|
||||
"stolen_gold": "Stolen with warships",
|
||||
"num_of_conquests": "Number of conquered players",
|
||||
|
||||
@@ -49,7 +49,9 @@ export class GameInfoModal extends LitElement {
|
||||
title="${translateText("game_info_modal.title")}"
|
||||
translationKey="main.game_info"
|
||||
>
|
||||
<div class="flex flex-col items-center px-25 text-center mb-4">
|
||||
<div
|
||||
class="h-full flex flex-col items-center px-25 text-center mb-4 scrollbar-thin scrollbar-thumb-white/20 scrollbar-track-transparent"
|
||||
>
|
||||
<div class="w-75 sm:w-125">
|
||||
${this.isLoadingGame
|
||||
? this.renderLoadingAnimation()
|
||||
@@ -108,7 +110,7 @@ export class GameInfoModal extends LitElement {
|
||||
const isUnusualThumbnailSize = hasUnusualThumbnailSize(info.config.gameMap);
|
||||
return html`
|
||||
<div
|
||||
class="h-37.5 flex relative justify-between rounded-xl bg-blue-600 items-center"
|
||||
class="h-37.5 flex relative justify-between rounded-xl bg-black/20 items-center"
|
||||
>
|
||||
${this.mapImage
|
||||
? html`<img
|
||||
@@ -140,7 +142,7 @@ export class GameInfoModal extends LitElement {
|
||||
const bestScore =
|
||||
this.rankedPlayers.length > 0 ? this.score(this.rankedPlayers[0]) : 0;
|
||||
return html`
|
||||
<ul class="">
|
||||
<ul>
|
||||
<ranking-header
|
||||
.rankType=${this.rankType}
|
||||
@sort=${this.sort}
|
||||
|
||||
@@ -1,4 +1,6 @@
|
||||
import version from "resources/version.txt?raw";
|
||||
import { FetchGameMapLoader } from "../core/game/FetchGameMapLoader";
|
||||
|
||||
export const terrainMapFileLoader = new FetchGameMapLoader(`/maps`, version);
|
||||
export const terrainMapFileLoader = new FetchGameMapLoader(
|
||||
`/maps`,
|
||||
window.GIT_COMMIT,
|
||||
);
|
||||
|
||||
@@ -63,7 +63,7 @@ export class OModal extends LitElement {
|
||||
render() {
|
||||
const backdropClass = this.inline
|
||||
? "relative z-10 w-full h-full flex items-stretch bg-transparent"
|
||||
: "fixed inset-0 z-[9999] bg-black/70 flex items-center justify-center overflow-hidden";
|
||||
: "fixed inset-0 z-[9999] bg-black/60 flex items-center justify-center overflow-hidden";
|
||||
|
||||
const wrapperClass = this.inline
|
||||
? "relative flex flex-col w-full h-full m-0 max-w-full max-h-none shadow-none"
|
||||
@@ -95,7 +95,7 @@ export class OModal extends LitElement {
|
||||
</div>`}
|
||||
${!this.hideHeader && this.title
|
||||
? html`<div
|
||||
class="px-[1.4rem] py-[1rem] pt-0 text-2xl font-bold text-white"
|
||||
class="px-[1.4rem] py-[1rem] text-2xl font-bold text-white"
|
||||
>
|
||||
${this.title}
|
||||
</div>`
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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";
|
||||
|
||||
@@ -22,15 +27,13 @@ export class PlayerRow extends LitElement {
|
||||
const visibleBorder = player.winner || this.currentPlayer;
|
||||
return html`
|
||||
<li
|
||||
class="${player.winner
|
||||
? "bg-linear-to-r via-none from-sky-400 to-blue-700"
|
||||
: "bg-slate-700"} border-2
|
||||
class="${player.winner ? "bg-black/20" : "bg-black/20"} border-b-1
|
||||
${player.winner
|
||||
? "border-yellow-500"
|
||||
? "border-yellow-500 border-1 box-content"
|
||||
: visibleBorder
|
||||
? "border-yellow-50"
|
||||
: "border-yellow-50/0"}
|
||||
relative pt-1 pb-1 pr-2 pl-2 sm:pl-5 sm:pr-5 mb-1.25 rounded-lg flex justify-between items-center hover:bg-slate-500 transition duration-150 ease-in-out"
|
||||
? "border-white/5"
|
||||
: "border-transparent"}
|
||||
relative pt-1 pb-1 pr-2 pl-2 sm:pl-5 sm:pr-5 flex justify-between items-center hover:bg-white/[0.07] transition-colors duration-150 ease-in-out"
|
||||
>
|
||||
<div
|
||||
class="font-bold text-right w-7.5 text-lg text-white absolute -left-10"
|
||||
@@ -67,10 +70,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``;
|
||||
}
|
||||
@@ -86,7 +91,7 @@ export class PlayerRow extends LitElement {
|
||||
</div>
|
||||
<div>
|
||||
<div
|
||||
class="font-bold rounded-[50%] size-7.5 leading-[1.6rem] border border-gray-200 text-center bg-white text-black"
|
||||
class="font-bold rounded-[50%] size-7.5 leading-[1.6rem] border border-white/10 text-center bg-white/5 text-white/80"
|
||||
>
|
||||
${Number(this.score).toFixed(0)}
|
||||
</div>
|
||||
@@ -99,24 +104,25 @@ export class PlayerRow extends LitElement {
|
||||
const width = Math.min(Math.max((this.score / bestScore) * 100, 0), 100);
|
||||
return html`
|
||||
<div class="w-full pr-2.5 m-auto">
|
||||
<div class="h-1.75 bg-neutral-800 w-full">
|
||||
<div class="h-1.75 bg-white/10 w-full">
|
||||
<!-- bar background -->
|
||||
<div
|
||||
class="h-1.75 bg-white w-(--width)"
|
||||
class="h-1.75 bg-blue-500/50 w-(--width)"
|
||||
style="--width: ${width}%;"
|
||||
></div>
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
private renderBombType(value: number, highlight: boolean) {
|
||||
|
||||
private renderMultiScoreType(value: number, highlight: boolean) {
|
||||
return html`
|
||||
<div
|
||||
class="${highlight
|
||||
? "font-bold text-[18px]"
|
||||
: ""} min-w-7.5 sm:min-w-15 inline-block text-center"
|
||||
? "font-bold text-[18px] text-white/80"
|
||||
: "leading-[24px] text-white/40"} min-w-7.5 sm:min-w-15 inline-block text-center"
|
||||
>
|
||||
${value}
|
||||
${renderNumber(value)}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
@@ -124,17 +130,17 @@ export class PlayerRow extends LitElement {
|
||||
private renderAllBombs() {
|
||||
return html`
|
||||
<div class="flex justify-between text-sm sm:pr-20">
|
||||
${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 +148,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`
|
||||
<div class="flex justify-between text-sm align-baseline">
|
||||
${this.renderMultiScoreType(
|
||||
Number(ownTrainTrade + otherTrainTrade),
|
||||
this.rankType === RankType.TrainTrade,
|
||||
)}
|
||||
/
|
||||
${this.renderMultiScoreType(
|
||||
Number(navalTrade),
|
||||
this.rankType === RankType.NavalTrade,
|
||||
)}
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderBombScore() {
|
||||
return html`
|
||||
<div class="flex gap-3 items-center w-full">
|
||||
<div class="flex gap-3 items-center align-baseline w-full">
|
||||
${this.renderPlayerIcon()}
|
||||
<div class="flex flex-col sm:flex-row gap-1 text-left w-full">
|
||||
${this.renderPlayerName()} ${this.renderAllBombs()}
|
||||
@@ -157,13 +182,12 @@ export class PlayerRow extends LitElement {
|
||||
return html`
|
||||
<div class="flex gap-3 items-center">
|
||||
${this.renderPlayerIcon()}
|
||||
<div class="text-left w-31.25 sm:w-62.5">
|
||||
${this.renderPlayerName()}
|
||||
</div>
|
||||
<div class="text-left w-31.25 sm:w-50">${this.renderPlayerName()}</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2">
|
||||
<div
|
||||
class="font-bold rounded-md w-15 shrink-0 h-7.5 text-sm sm:w-25 sm:h-7.5 leading-[1.9rem] text-center"
|
||||
class="font-bold rounded-md w-15 text-white/80 text-sm sm:w-25 leading-[1.9rem] text-center"
|
||||
>
|
||||
${renderNumber(this.score)}
|
||||
</div>
|
||||
@@ -172,12 +196,32 @@ export class PlayerRow extends LitElement {
|
||||
`;
|
||||
}
|
||||
|
||||
private renderTradeScore() {
|
||||
return html`
|
||||
<div class="flex flex-col sm:flex-row gap-1 text-left w-full">
|
||||
<div class="flex gap-3 items-center">
|
||||
${this.renderPlayerIcon()}
|
||||
<div class="text-left w-31.25 sm:w-50">
|
||||
${this.renderPlayerName()}
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<div class="flex gap-2 justify-between items-center w-full">
|
||||
<div class="rounded-md text-sm leading-[1.9rem] text-center w-full">
|
||||
${this.renderAllTrades()}
|
||||
</div>
|
||||
<img src="/images/GoldCoinIcon.svg" class="w-5 size-3.5 sm:size-5" />
|
||||
</div>
|
||||
</div>
|
||||
`;
|
||||
}
|
||||
|
||||
private renderPlayerName() {
|
||||
return html`
|
||||
<div class="flex gap-1 items-center w-50 shrink-0">
|
||||
${this.player.tag ? this.renderTag(this.player.tag) : ""}
|
||||
<div
|
||||
class="text-xs sm:text-sm font-bold text-ellipsis w-37.5 shrink-0 overflow-hidden whitespace-nowrap"
|
||||
class="text-xs sm:text-sm font-bold tracking-wide text-white/80 text-ellipsis w-37.5 shrink-0 overflow-hidden whitespace-nowrap"
|
||||
>
|
||||
${this.player.username}
|
||||
</div>
|
||||
@@ -188,7 +232,7 @@ export class PlayerRow extends LitElement {
|
||||
private renderTag(tag: string) {
|
||||
return html`
|
||||
<div
|
||||
class="bg-white text-black rounded-lg sm:rounded-xl border border-gray-200 text-xs leading-3 sm:leading-4.5 text-blue-900 h-3.75 px-1 sm:h-5 sm:px-2 font-bold"
|
||||
class="px-2.5 py-1 rounded bg-blue-500/10 border border-blue-500/20 text-blue-300 font-bold text-xs tracking-wide group-hover:bg-blue-500/20 transition-colors"
|
||||
>
|
||||
${tag}
|
||||
</div>
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -54,9 +57,9 @@ export class RankingControls extends LitElement {
|
||||
private renderButton(type: RankType, active: boolean, label: string) {
|
||||
return html`
|
||||
<button
|
||||
class="rounded-lg bg-blue-600 text-white text-lg p-3 hover:bg-blue-400 ${active
|
||||
? "active outline-2 outline-white font-bold"
|
||||
: ""}"
|
||||
class="px-6 py-2 text-xs font-bold transition-all duration-200 rounded-lg uppercase tracking-widest hover:text-white hover:bg-white/5 border ${active
|
||||
? "bg-blue-500/20 text-blue-400 border-blue-500/30 shadow-[0_0_15px_rgba(59,130,246,0.2)]"
|
||||
: "text-white/40 border-transparent"}"
|
||||
@click=${() => this.onSort(type)}
|
||||
>
|
||||
${translateText(label)}
|
||||
@@ -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`
|
||||
<div class="flex justify-center gap-3 pb-1">
|
||||
${this.renderSubButton(
|
||||
RankType.NavalTrade,
|
||||
isTradeRanking(this.rankType),
|
||||
"game_info_modal.trade",
|
||||
)}
|
||||
${econButtons.map(([type, label]) =>
|
||||
this.renderSubButton(type as RankType, this.rankType === type, label),
|
||||
)}
|
||||
@@ -106,8 +113,8 @@ export class RankingControls extends LitElement {
|
||||
return html`
|
||||
<button
|
||||
@click=${() => this.onSort(type)}
|
||||
class="rounded-md bg-blue-50 text-black text-sm p-2 hover:bg-blue-200 ${active
|
||||
? "outline-2 outline-white font-bold"
|
||||
class="text-[10px] font-bold uppercase tracking-wider bg-white/5 border border-white/10 hover:bg-white/20 px-3 py-1 rounded text-white/60 hover:text-white transition-colors ${active
|
||||
? "outline-1 outline-white/80 font-bold"
|
||||
: ""}"
|
||||
>
|
||||
${translateText(label)}
|
||||
|
||||
@@ -14,7 +14,7 @@ export class RankingHeader extends LitElement {
|
||||
render() {
|
||||
return html`
|
||||
<li
|
||||
class="text-lg bg-gray-800 font-bold relative pt-2 pb-2 pr-5 pl-5 mb-1.25 rounded-md flex justify-between items-center"
|
||||
class="text-lg border-white/5 bg-white/[0.02] text-white/60 text-xs uppercase tracking-wider relative pt-2 pb-2 pr-5 pl-5 flex justify-between items-center"
|
||||
>
|
||||
${this.renderHeaderContent()}
|
||||
</li>
|
||||
@@ -36,17 +36,17 @@ export class RankingHeader extends LitElement {
|
||||
case RankType.MIRV:
|
||||
return html`
|
||||
<div class="flex justify-between sm:px-17.5 w-full">
|
||||
${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,21 @@ export class RankingHeader extends LitElement {
|
||||
return html`<div class="w-full">
|
||||
${translateText("game_info_modal.all_gold")}
|
||||
</div>`;
|
||||
case RankType.TradedGold:
|
||||
return html`<div class="w-full">
|
||||
${translateText("game_info_modal.trade")}
|
||||
</div>`;
|
||||
case RankType.NavalTrade:
|
||||
case RankType.TrainTrade:
|
||||
return html`
|
||||
<div class="flex justify-between sm:px-17.5 w-full">
|
||||
${this.renderMultipleChoiceHeaderButton(
|
||||
translateText("game_info_modal.train_trade"),
|
||||
RankType.TrainTrade,
|
||||
)}
|
||||
/
|
||||
${this.renderMultipleChoiceHeaderButton(
|
||||
translateText("game_info_modal.naval_trade"),
|
||||
RankType.NavalTrade,
|
||||
)}
|
||||
</div>
|
||||
`;
|
||||
case RankType.ConqueredGold:
|
||||
return html`<div class="w-full">
|
||||
${translateText("game_info_modal.conquest_gold")}
|
||||
@@ -74,7 +85,7 @@ export class RankingHeader extends LitElement {
|
||||
}
|
||||
}
|
||||
|
||||
private renderBombHeaderButton(label: string, type: RankType) {
|
||||
private renderMultipleChoiceHeaderButton(label: string, type: RankType) {
|
||||
return html`
|
||||
<button
|
||||
@click=${() => this.onSort(type)}
|
||||
|
||||
@@ -92,6 +92,7 @@ export function createGrid(
|
||||
const tile = game.ref(cell.x, cell.y);
|
||||
grid[x - scaledBoundingBox.min.x][y - scaledBoundingBox.min.y] =
|
||||
game.isLake(tile) ||
|
||||
game.isShore(tile) ||
|
||||
game.owner(tile) === player ||
|
||||
game.hasFallout(tile);
|
||||
}
|
||||
|
||||
@@ -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),
|
||||
);
|
||||
|
||||
Reference in New Issue
Block a user