This commit is contained in:
Ryan Barlow
2026-03-01 14:26:21 +00:00
parent 15bcc0241e
commit cd17df29fe
8 changed files with 23 additions and 61 deletions
+2 -1
View File
@@ -726,7 +726,8 @@
"warships": "Warships",
"cities": "Cities",
"show_control": "Show Control",
"show_units": "Show Units"
"show_units": "Show Units",
"show_competitive": "Show Competitive"
},
"events_display": {
"events": "Events",
+1 -1
View File
@@ -782,7 +782,7 @@ export class HostLobbyModal extends BaseModal {
: undefined,
startingGold:
this.startingGold === true ? this.startingGoldValue : undefined,
competitiveScoring: this.competitiveScoring || undefined,
competitiveScoring: this.competitiveScoring ? true : undefined,
} satisfies Partial<GameConfig>,
},
bubbles: true,
+2 -6
View File
@@ -93,13 +93,9 @@ export function getPlayerIcons(
// Crown icon: in competitive mode, all members of the crown team get it;
// otherwise only the individual first-place player.
if (
crownTeam !== null &&
crownTeam !== undefined &&
player.team() === crownTeam
) {
if (crownTeam !== null && player.team() === crownTeam) {
icons.push({ id: "crown", kind: "image", src: crownIcon });
} else if (crownTeam === null || crownTeam === undefined) {
} else if (crownTeam === null) {
if (player === firstPlace) {
icons.push({ id: "crown", kind: "image", src: crownIcon });
}
+1 -1
View File
@@ -269,7 +269,7 @@ export class TeamStats extends LitElement implements Layer {
case "control":
return translateText("leaderboard.show_units");
case "units":
return "Show Competitive";
return translateText("leaderboard.show_competitive");
case "competitive":
return translateText("leaderboard.show_control");
}
+2 -1
View File
@@ -18,6 +18,7 @@ import { assertNever } from "../Util";
import { FlatBinaryHeap } from "./utils/FlatBinaryHeap"; // adjust path if needed
const malusForRetreat = 25;
const CROWN_ATTACK_BONUS = 0.25;
export class AttackExecution implements Execution {
private active: boolean = true;
private toConquer = new FlatBinaryHeap();
@@ -133,7 +134,7 @@ export class AttackExecution implements Execution {
targetTeam === crownTeam &&
attackerTeam !== crownTeam
) {
const bonus = Math.floor(this.attack.troops() * 0.25);
const bonus = Math.floor(this.attack.troops() * CROWN_ATTACK_BONUS);
this.attack.setTroops(this.attack.troops() + bonus);
}
}
@@ -1,44 +0,0 @@
import { Execution, Game, GameMode, Team } from "../game/Game";
/**
* Tracks which team holds the "crown" (most total tiles) and accumulates
* crown ticks per team for competition scoring.
*
* Crown time contributes 20% of a team's competition score.
* Only active in Team game mode.
*/
export class CrownTrackingExecution implements Execution {
private active = true;
private mg: Game | null = null;
init(mg: Game, _ticks: number) {
this.mg = mg;
// Only relevant in team mode
if (mg.config().gameConfig().gameMode !== GameMode.Team) {
this.active = false;
}
}
tick(ticks: number) {
if (ticks % 10 !== 0) return;
if (this.mg === null) throw new Error("Not initialized");
const crown = this.computeCrownTeam();
if (crown !== null) {
this.mg.addCrownTick(crown, 10);
}
}
private computeCrownTeam(): Team | null {
if (this.mg === null) return null;
return this.mg.crownTeam();
}
isActive(): boolean {
return this.active;
}
activeDuringSpawnPhase(): boolean {
return false;
}
}
+13 -5
View File
@@ -28,6 +28,8 @@ export class WinCheckExecution implements Execution {
init(mg: Game, ticks: number) {
this.mg = mg;
// Seed alive teams so eliminations on the very first tick are detected.
this.knownAliveTeams = this.computeAliveTeams();
}
tick(ticks: number) {
@@ -46,17 +48,23 @@ export class WinCheckExecution implements Execution {
}
}
private trackTeamEliminations(): void {
if (this.mg === null) return;
const currentAlive = new Set<Team>();
private computeAliveTeams(): Set<Team> {
const alive = new Set<Team>();
if (this.mg === null) return alive;
for (const player of this.mg.players()) {
const team = player.team();
if (team === null || team === ColoredTeams.Bot) continue;
if (player.numTilesOwned() > 0) {
currentAlive.add(team);
alive.add(team);
}
}
return alive;
}
private trackTeamEliminations(): void {
if (this.mg === null) return;
const currentAlive = this.computeAliveTeams();
// Record teams that just died
for (const team of this.knownAliveTeams) {
+2 -2
View File
@@ -1277,7 +1277,7 @@ export class GameImpl implements Game {
}
allTeamCrownTicks(): ReadonlyMap<Team, number> {
return this._teamCrownTicks;
return new Map(this._teamCrownTicks);
}
addCrownTick(team: Team, amount: number): void {
@@ -1299,7 +1299,7 @@ export class GameImpl implements Game {
}
teamEliminationOrder(): Team[] {
return this._teamEliminationOrder;
return [...this._teamEliminationOrder];
}
recordTeamElimination(team: Team): void {