diff --git a/src/client/ClientGameRunner.ts b/src/client/ClientGameRunner.ts
index 26de903ae..9b225c143 100644
--- a/src/client/ClientGameRunner.ts
+++ b/src/client/ClientGameRunner.ts
@@ -64,13 +64,13 @@ export interface LobbyConfig {
export function joinLobby(
lobbyConfig: LobbyConfig,
- onjoin: () => void
+ onjoin: () => void,
): () => void {
const eventBus = new EventBus();
initRemoteSender(eventBus);
consolex.log(
- `joinging lobby: gameID: ${lobbyConfig.gameID}, clientID: ${lobbyConfig.clientID}, persistentID: ${lobbyConfig.persistentID}`
+ `joinging lobby: gameID: ${lobbyConfig.gameID}, clientID: ${lobbyConfig.clientID}, persistentID: ${lobbyConfig.persistentID}`,
);
const serverConfig = getServerConfig();
@@ -91,7 +91,7 @@ export function joinLobby(
lobbyConfig,
gameConfig,
eventBus,
- serverConfig
+ serverConfig,
);
const onconnect = () => {
@@ -103,7 +103,7 @@ export function joinLobby(
consolex.log("lobby: game started");
onjoin();
createClientGame(lobbyConfig, message.config, eventBus, transport).then(
- (r) => r.start()
+ (r) => r.start(),
);
}
};
@@ -118,7 +118,7 @@ export async function createClientGame(
lobbyConfig: LobbyConfig,
gameConfig: GameConfig,
eventBus: EventBus,
- transport: Transport
+ transport: Transport,
): Promise {
const config = getConfig(gameConfig);
@@ -126,14 +126,14 @@ export async function createClientGame(
const worker = new WorkerClient(
lobbyConfig.gameID,
gameConfig,
- lobbyConfig.clientID
+ lobbyConfig.clientID,
);
await worker.initialize();
const gameView = new GameView(
worker,
config,
gameMap.gameMap,
- lobbyConfig.clientID
+ lobbyConfig.clientID,
);
consolex.log("going to init path finder");
@@ -143,11 +143,11 @@ export async function createClientGame(
canvas,
gameView,
eventBus,
- lobbyConfig.clientID
+ lobbyConfig.clientID,
);
consolex.log(
- `creating private game got difficulty: ${gameConfig.difficulty}`
+ `creating private game got difficulty: ${gameConfig.difficulty}`,
);
return new ClientGameRunner(
@@ -157,7 +157,7 @@ export async function createClientGame(
new InputHandler(canvas, eventBus),
transport,
worker,
- gameView
+ gameView,
);
}
@@ -175,7 +175,7 @@ export class ClientGameRunner {
private input: InputHandler,
private transport: Transport,
private worker: WorkerClient,
- private gameView: GameView
+ private gameView: GameView,
) {}
public start() {
@@ -223,7 +223,7 @@ export class ClientGameRunner {
}
if (this.turnsSeen != message.turn.turnNumber) {
consolex.error(
- `got wrong turn have turns ${this.turnsSeen}, received turn ${message.turn.turnNumber}`
+ `got wrong turn have turns ${this.turnsSeen}, received turn ${message.turn.turnNumber}`,
);
} else {
this.worker.sendTurn(message.turn);
@@ -246,7 +246,7 @@ export class ClientGameRunner {
}
const cell = this.renderer.transformHandler.screenToWorldCoordinates(
event.x,
- event.y
+ event.y,
);
if (!this.gameView.isValidCoord(cell.x, cell.y)) {
return;
@@ -276,8 +276,8 @@ export class ClientGameRunner {
this.eventBus.emit(
new SendAttackIntentEvent(
this.gameView.owner(tile).id(),
- this.myPlayer.troops() * this.renderer.uiState.attackRatio
- )
+ this.myPlayer.troops() * this.renderer.uiState.attackRatio,
+ ),
);
}
});
diff --git a/src/client/HostLobbyModal.ts b/src/client/HostLobbyModal.ts
index 6ed8f9ae5..5951a5aba 100644
--- a/src/client/HostLobbyModal.ts
+++ b/src/client/HostLobbyModal.ts
@@ -355,7 +355,7 @@ export class HostLobbyModal extends LitElement {
.selected=${this.selectedMap === value}
>
- `
+ `,
)}
@@ -381,7 +381,7 @@ export class HostLobbyModal extends LitElement {
${DifficultyDescription[key]}
- `
+ `,
)}
@@ -443,7 +443,7 @@ export class HostLobbyModal extends LitElement {
${this.players.map(
- (player) => html`${player}`
+ (player) => html`${player}`,
)}
@@ -484,7 +484,7 @@ export class HostLobbyModal extends LitElement {
},
bubbles: true,
composed: true,
- })
+ }),
);
});
this.isModalOpen = true;
@@ -545,7 +545,7 @@ export class HostLobbyModal extends LitElement {
private async startGame() {
consolex.log(
- `Starting private game with map: ${GameMapType[this.selectedMap]}`
+ `Starting private game with map: ${GameMapType[this.selectedMap]}`,
);
this.close();
const response = await fetch(`/start_private_lobby/${this.lobbyId}`, {
diff --git a/src/client/InputHandler.ts b/src/client/InputHandler.ts
index 9748d5fef..2162ccdc5 100644
--- a/src/client/InputHandler.ts
+++ b/src/client/InputHandler.ts
@@ -2,31 +2,46 @@ import { EventBus, GameEvent } from "../core/EventBus";
import { Game } from "../core/game/Game";
export class MouseUpEvent implements GameEvent {
- constructor(public readonly x: number, public readonly y: number) {}
+ constructor(
+ public readonly x: number,
+ public readonly y: number,
+ ) {}
}
export class MouseDownEvent implements GameEvent {
- constructor(public readonly x: number, public readonly y: number) {}
+ constructor(
+ public readonly x: number,
+ public readonly y: number,
+ ) {}
}
export class MouseMoveEvent implements GameEvent {
- constructor(public readonly x: number, public readonly y: number) {}
+ constructor(
+ public readonly x: number,
+ public readonly y: number,
+ ) {}
}
export class ContextMenuEvent implements GameEvent {
- constructor(public readonly x: number, public readonly y: number) {}
+ constructor(
+ public readonly x: number,
+ public readonly y: number,
+ ) {}
}
export class ZoomEvent implements GameEvent {
constructor(
public readonly x: number,
public readonly y: number,
- public readonly delta: number
+ public readonly delta: number,
) {}
}
export class DragEvent implements GameEvent {
- constructor(public readonly deltaX: number, public readonly deltaY: number) {}
+ constructor(
+ public readonly deltaX: number,
+ public readonly deltaY: number,
+ ) {}
}
export class AlternateViewEvent implements GameEvent {
@@ -36,7 +51,10 @@ export class AlternateViewEvent implements GameEvent {
export class RefreshGraphicsEvent implements GameEvent {}
export class ShowBuildMenuEvent implements GameEvent {
- constructor(public readonly x: number, public readonly y: number) {}
+ constructor(
+ public readonly x: number,
+ public readonly y: number,
+ ) {}
}
export class InputHandler {
@@ -60,7 +78,10 @@ export class InputHandler {
private readonly PAN_SPEED = 5;
private readonly ZOOM_SPEED = 10;
- constructor(private canvas: HTMLCanvasElement, private eventBus: EventBus) {}
+ constructor(
+ private canvas: HTMLCanvasElement,
+ private eventBus: EventBus,
+ ) {}
initialize() {
this.canvas.addEventListener("pointerdown", (e) => this.onPointerDown(e));
@@ -105,12 +126,12 @@ export class InputHandler {
if (this.activeKeys.has("Minus")) {
this.eventBus.emit(
- new ZoomEvent(screenCenterX, screenCenterY, this.ZOOM_SPEED)
+ new ZoomEvent(screenCenterX, screenCenterY, this.ZOOM_SPEED),
);
}
if (this.activeKeys.has("Equal")) {
this.eventBus.emit(
- new ZoomEvent(screenCenterX, screenCenterY, -this.ZOOM_SPEED)
+ new ZoomEvent(screenCenterX, screenCenterY, -this.ZOOM_SPEED),
);
}
}, 1);
@@ -251,7 +272,7 @@ export class InputHandler {
if (Math.abs(pinchDelta) > 1) {
const zoomCenter = this.getPinchCenter();
this.eventBus.emit(
- new ZoomEvent(zoomCenter.x, zoomCenter.y, -pinchDelta * 2)
+ new ZoomEvent(zoomCenter.x, zoomCenter.y, -pinchDelta * 2),
);
this.lastPinchDistance = currentPinchDistance;
}
diff --git a/src/client/JoinPrivateLobbyModal.ts b/src/client/JoinPrivateLobbyModal.ts
index f6b26bf1b..551754072 100644
--- a/src/client/JoinPrivateLobbyModal.ts
+++ b/src/client/JoinPrivateLobbyModal.ts
@@ -264,7 +264,7 @@ export class JoinPrivateLobbyModal extends LitElement {
${this.players.map(
(player) =>
- html`${player}`
+ html`${player}`,
)}
`
@@ -302,7 +302,7 @@ export class JoinPrivateLobbyModal extends LitElement {
detail: { lobby: this.lobbyIdInput.value },
bubbles: true,
composed: true,
- })
+ }),
);
}
@@ -340,7 +340,7 @@ export class JoinPrivateLobbyModal extends LitElement {
},
bubbles: true,
composed: true,
- })
+ }),
);
this.playersInterval = setInterval(() => this.pollPlayers(), 1000);
} else {
diff --git a/src/client/Main.ts b/src/client/Main.ts
index 3b36a7fe4..490a41c24 100644
--- a/src/client/Main.ts
+++ b/src/client/Main.ts
@@ -1,179 +1,168 @@
-import { ClientGameRunner, joinLobby } from './ClientGameRunner';
-import backgroundImage from '../../resources/images/EuropeBackground.svg';
-import favicon from '../../resources/images/Favicon.svg';
+import { ClientGameRunner, joinLobby } from "./ClientGameRunner";
+import backgroundImage from "../../resources/images/EuropeBackground.svg";
+import favicon from "../../resources/images/Favicon.svg";
-import './PublicLobby';
-import './UsernameInput';
-import './styles.css';
-import { UsernameInput } from './UsernameInput';
-import { SinglePlayerModal } from './SinglePlayerModal';
-import { HostLobbyModal as HostPrivateLobbyModal } from './HostLobbyModal';
-import { JoinPrivateLobbyModal } from './JoinPrivateLobbyModal';
-import { generateID } from '../core/Util';
-import { generateCryptoRandomUUID } from './Utils';
-import { consolex } from '../core/Consolex';
-import './components/FlagInput';
-import { FlagInput } from './components/FlagInput';
+import "./PublicLobby";
+import "./UsernameInput";
+import "./styles.css";
+import { UsernameInput } from "./UsernameInput";
+import { SinglePlayerModal } from "./SinglePlayerModal";
+import { HostLobbyModal as HostPrivateLobbyModal } from "./HostLobbyModal";
+import { JoinPrivateLobbyModal } from "./JoinPrivateLobbyModal";
+import { generateID } from "../core/Util";
+import { generateCryptoRandomUUID } from "./Utils";
+import { consolex } from "../core/Consolex";
+import "./components/FlagInput";
+import { FlagInput } from "./components/FlagInput";
class Client {
- private gameStop: () => void;
+ private gameStop: () => void;
- private usernameInput: UsernameInput | null = null;
- private flagInput: FlagInput | null = null;
+ private usernameInput: UsernameInput | null = null;
+ private flagInput: FlagInput | null = null;
- private joinModal: JoinPrivateLobbyModal;
- constructor() {}
+ private joinModal: JoinPrivateLobbyModal;
+ constructor() {}
- initialize(): void {
- this.flagInput = document.querySelector('flag-input') as FlagInput;
- if (!this.flagInput) {
- consolex.warn('Flag input element not found');
- }
+ initialize(): void {
+ this.flagInput = document.querySelector("flag-input") as FlagInput;
+ if (!this.flagInput) {
+ consolex.warn("Flag input element not found");
+ }
- this.usernameInput = document.querySelector(
- 'username-input'
- ) as UsernameInput;
- if (!this.usernameInput) {
- consolex.warn('Username input element not found');
- }
- window.addEventListener('beforeunload', (event) => {
- consolex.log('Browser is closing');
- if (this.gameStop != null) {
- this.gameStop();
- }
- });
+ this.usernameInput = document.querySelector(
+ "username-input",
+ ) as UsernameInput;
+ if (!this.usernameInput) {
+ consolex.warn("Username input element not found");
+ }
+ window.addEventListener("beforeunload", (event) => {
+ consolex.log("Browser is closing");
+ if (this.gameStop != null) {
+ this.gameStop();
+ }
+ });
- setFavicon();
- document.addEventListener(
- 'join-lobby',
- this.handleJoinLobby.bind(this)
- );
- document.addEventListener(
- 'leave-lobby',
- this.handleLeaveLobby.bind(this)
- );
- document.addEventListener(
- 'single-player',
- this.handleSinglePlayer.bind(this)
- );
+ setFavicon();
+ document.addEventListener("join-lobby", this.handleJoinLobby.bind(this));
+ document.addEventListener("leave-lobby", this.handleLeaveLobby.bind(this));
+ document.addEventListener(
+ "single-player",
+ this.handleSinglePlayer.bind(this),
+ );
- const spModal = document.querySelector(
- 'single-player-modal'
- ) as SinglePlayerModal;
- spModal instanceof SinglePlayerModal;
- document
- .getElementById('single-player')
- .addEventListener('click', () => {
- if (this.usernameInput.isValid()) {
- spModal.open();
- }
- });
+ const spModal = document.querySelector(
+ "single-player-modal",
+ ) as SinglePlayerModal;
+ spModal instanceof SinglePlayerModal;
+ document.getElementById("single-player").addEventListener("click", () => {
+ if (this.usernameInput.isValid()) {
+ spModal.open();
+ }
+ });
- const hostModal = document.querySelector(
- 'host-lobby-modal'
- ) as HostPrivateLobbyModal;
- hostModal instanceof HostPrivateLobbyModal;
- document
- .getElementById('host-lobby-button')
- .addEventListener('click', () => {
- if (this.usernameInput.isValid()) {
- hostModal.open();
- }
- });
+ const hostModal = document.querySelector(
+ "host-lobby-modal",
+ ) as HostPrivateLobbyModal;
+ hostModal instanceof HostPrivateLobbyModal;
+ document
+ .getElementById("host-lobby-button")
+ .addEventListener("click", () => {
+ if (this.usernameInput.isValid()) {
+ hostModal.open();
+ }
+ });
- this.joinModal = document.querySelector(
- 'join-private-lobby-modal'
- ) as JoinPrivateLobbyModal;
- this.joinModal instanceof JoinPrivateLobbyModal;
- document
- .getElementById('join-private-lobby-button')
- .addEventListener('click', () => {
- if (this.usernameInput.isValid()) {
- this.joinModal.open();
- }
- });
- }
+ this.joinModal = document.querySelector(
+ "join-private-lobby-modal",
+ ) as JoinPrivateLobbyModal;
+ this.joinModal instanceof JoinPrivateLobbyModal;
+ document
+ .getElementById("join-private-lobby-button")
+ .addEventListener("click", () => {
+ if (this.usernameInput.isValid()) {
+ this.joinModal.open();
+ }
+ });
+ }
- private async handleJoinLobby(event: CustomEvent) {
- const lobby = event.detail.lobby;
- consolex.log(`joining lobby ${lobby.id}`);
- if (this.gameStop != null) {
- consolex.log('joining lobby, stopping existing game');
- this.gameStop();
- }
- this.gameStop = joinLobby(
- {
- gameType: event.detail.gameType,
- flag: (): string => this.flagInput.getCurrentFlag(),
- playerName: (): string =>
- this.usernameInput.getCurrentUsername(),
- gameID: lobby.id,
- persistentID: getPersistentIDFromCookie(),
- playerID: generateID(),
- clientID: generateID(),
- map: event.detail.map,
- difficulty: event.detail.difficulty,
- disableBots: event.detail.disableBots,
- disableNPCs: event.detail.disableNPCs,
- creativeMode: event.detail.creativeMode,
- },
- () => this.joinModal.close()
- );
- }
+ private async handleJoinLobby(event: CustomEvent) {
+ const lobby = event.detail.lobby;
+ consolex.log(`joining lobby ${lobby.id}`);
+ if (this.gameStop != null) {
+ consolex.log("joining lobby, stopping existing game");
+ this.gameStop();
+ }
+ this.gameStop = joinLobby(
+ {
+ gameType: event.detail.gameType,
+ flag: (): string => this.flagInput.getCurrentFlag(),
+ playerName: (): string => this.usernameInput.getCurrentUsername(),
+ gameID: lobby.id,
+ persistentID: getPersistentIDFromCookie(),
+ playerID: generateID(),
+ clientID: generateID(),
+ map: event.detail.map,
+ difficulty: event.detail.difficulty,
+ disableBots: event.detail.disableBots,
+ disableNPCs: event.detail.disableNPCs,
+ creativeMode: event.detail.creativeMode,
+ },
+ () => this.joinModal.close(),
+ );
+ }
- private async handleLeaveLobby(event: CustomEvent) {
- if (this.gameStop == null) {
- return;
- }
- consolex.log('leaving lobby, cancelling game');
- this.gameStop();
- this.gameStop = null;
- }
+ private async handleLeaveLobby(event: CustomEvent) {
+ if (this.gameStop == null) {
+ return;
+ }
+ consolex.log("leaving lobby, cancelling game");
+ this.gameStop();
+ this.gameStop = null;
+ }
- private async handleSinglePlayer(event: CustomEvent) {
- alert('coming soon');
- }
+ private async handleSinglePlayer(event: CustomEvent) {
+ alert("coming soon");
+ }
}
// Initialize the client when the DOM is loaded
-document.addEventListener('DOMContentLoaded', () => {
- new Client().initialize();
+document.addEventListener("DOMContentLoaded", () => {
+ new Client().initialize();
});
document.body.style.backgroundImage = `url(${backgroundImage})`;
function setFavicon(): void {
- const link = document.createElement('link');
- link.type = 'image/x-icon';
- link.rel = 'shortcut icon';
- link.href = favicon;
- document.head.appendChild(link);
+ const link = document.createElement("link");
+ link.type = "image/x-icon";
+ link.rel = "shortcut icon";
+ link.href = favicon;
+ document.head.appendChild(link);
}
// WARNING: DO NOT EXPOSE THIS ID
export function getPersistentIDFromCookie(): string {
- const COOKIE_NAME = 'player_persistent_id';
+ const COOKIE_NAME = "player_persistent_id";
- // Try to get existing cookie
- const cookies = document.cookie.split(';');
- for (let cookie of cookies) {
- const [cookieName, cookieValue] = cookie
- .split('=')
- .map((c) => c.trim());
- if (cookieName === COOKIE_NAME) {
- return cookieValue;
- }
- }
+ // Try to get existing cookie
+ const cookies = document.cookie.split(";");
+ for (let cookie of cookies) {
+ const [cookieName, cookieValue] = cookie.split("=").map((c) => c.trim());
+ if (cookieName === COOKIE_NAME) {
+ return cookieValue;
+ }
+ }
- // If no cookie exists, create new ID and set cookie
- const newID = generateCryptoRandomUUID();
- document.cookie = [
- `${COOKIE_NAME}=${newID}`,
- `max-age=${5 * 365 * 24 * 60 * 60}`, // 5 years
- 'path=/',
- 'SameSite=Strict',
- 'Secure',
- ].join(';');
+ // If no cookie exists, create new ID and set cookie
+ const newID = generateCryptoRandomUUID();
+ document.cookie = [
+ `${COOKIE_NAME}=${newID}`,
+ `max-age=${5 * 365 * 24 * 60 * 60}`, // 5 years
+ "path=/",
+ "SameSite=Strict",
+ "Secure",
+ ].join(";");
- return newID;
+ return newID;
}
diff --git a/src/client/PublicLobby.ts b/src/client/PublicLobby.ts
index 57fe25289..f1258e2d5 100644
--- a/src/client/PublicLobby.ts
+++ b/src/client/PublicLobby.ts
@@ -20,7 +20,7 @@ export class PublicLobby extends LitElement {
this.fetchAndUpdateLobbies();
this.lobbiesInterval = window.setInterval(
() => this.fetchAndUpdateLobbies(),
- 1000
+ 1000,
);
}
@@ -111,7 +111,7 @@ export class PublicLobby extends LitElement {
},
bubbles: true,
composed: true,
- })
+ }),
);
} else {
this.dispatchEvent(
@@ -119,7 +119,7 @@ export class PublicLobby extends LitElement {
detail: { lobby: this.currLobby },
bubbles: true,
composed: true,
- })
+ }),
);
this.currLobby = null;
}
diff --git a/src/client/SinglePlayerModal.ts b/src/client/SinglePlayerModal.ts
index 966902cfe..16547ac14 100644
--- a/src/client/SinglePlayerModal.ts
+++ b/src/client/SinglePlayerModal.ts
@@ -251,7 +251,7 @@ export class SinglePlayerModal extends LitElement {
.selected=${this.selectedMap === value}
>
- `
+ `,
)}
@@ -277,7 +277,7 @@ export class SinglePlayerModal extends LitElement {
${DifficultyDescription[key]}
- `
+ `,
)}
@@ -363,7 +363,7 @@ export class SinglePlayerModal extends LitElement {
}
private startGame() {
consolex.log(
- `Starting single player game with map: ${GameMapType[this.selectedMap]}`
+ `Starting single player game with map: ${GameMapType[this.selectedMap]}`,
);
this.dispatchEvent(
new CustomEvent("join-lobby", {
@@ -380,7 +380,7 @@ export class SinglePlayerModal extends LitElement {
},
bubbles: true,
composed: true,
- })
+ }),
);
this.close();
}
diff --git a/src/client/Utils.ts b/src/client/Utils.ts
index 744921aa8..6f8ffd47b 100644
--- a/src/client/Utils.ts
+++ b/src/client/Utils.ts
@@ -52,7 +52,7 @@ export function generateCryptoRandomUUID(): string {
(
c ^
(crypto.getRandomValues(new Uint8Array(1))[0] & (15 >> (c / 4)))
- ).toString(16)
+ ).toString(16),
);
}
@@ -64,6 +64,6 @@ export function generateCryptoRandomUUID(): string {
const r: number = (Math.random() * 16) | 0;
const v: number = c === "x" ? r : (r & 0x3) | 0x8;
return v.toString(16);
- }
+ },
);
}
diff --git a/src/client/components/FlagInput.ts b/src/client/components/FlagInput.ts
index 27e31bab7..a17380df1 100644
--- a/src/client/components/FlagInput.ts
+++ b/src/client/components/FlagInput.ts
@@ -1,231 +1,217 @@
-import { LitElement, html, css } from 'lit';
-import { customElement, property, state } from 'lit/decorators.js';
-import Countries from '../data/countries.json';
+import { LitElement, html, css } from "lit";
+import { customElement, property, state } from "lit/decorators.js";
+import Countries from "../data/countries.json";
-const flagKey: string = 'flag';
+const flagKey: string = "flag";
-@customElement('flag-input')
+@customElement("flag-input")
export class FlagInput extends LitElement {
- @state() private flag: string = '';
- @state() private search: string = '';
- @state() private showModal: boolean = false;
+ @state() private flag: string = "";
+ @state() private search: string = "";
+ @state() private showModal: boolean = false;
- static styles = css`
- .hidden {
- display: none;
- }
+ static styles = css`
+ .hidden {
+ display: none;
+ }
- .flag-container {
- display: flex;
- }
+ .flag-container {
+ display: flex;
+ }
- .no-selected-flag {
- position: absolute;
- left: 8px;
- top: 8px;
- height: 50px;
- border-radius: 0.75rem;
- border: none;
- background: none;
- font-size: 1rem;
- cursor: pointer;
- }
+ .no-selected-flag {
+ position: absolute;
+ left: 8px;
+ top: 8px;
+ height: 50px;
+ border-radius: 0.75rem;
+ border: none;
+ background: none;
+ font-size: 1rem;
+ cursor: pointer;
+ }
- .selected-flag {
- width: 48px;
- cursor: pointer;
- position: absolute;
- left: 24px;
- top: 14px;
- border: 1px solid black;
- }
+ .selected-flag {
+ width: 48px;
+ cursor: pointer;
+ position: absolute;
+ left: 24px;
+ top: 14px;
+ border: 1px solid black;
+ }
- .flag-modal {
- display: flex;
- flex-direction: column;
- gap: 0.5rem;
- position: absolute;
- top: 60px;
- left: 0;
- width: 560px;
- height: 500px;
- max-height: 50vh;
- background-color: rgb(35 35 35 / 0.8);
- -webkit-backdrop-filter: blur(12px);
- backdrop-filter: blur(12px);
- padding: 10px;
- border-radius: 8px;
- }
+ .flag-modal {
+ display: flex;
+ flex-direction: column;
+ gap: 0.5rem;
+ position: absolute;
+ top: 60px;
+ left: 0;
+ width: 560px;
+ height: 500px;
+ max-height: 50vh;
+ background-color: rgb(35 35 35 / 0.8);
+ -webkit-backdrop-filter: blur(12px);
+ backdrop-filter: blur(12px);
+ padding: 10px;
+ border-radius: 8px;
+ }
- .flag-search {
- height: 2rem;
- border-radius: 8px;
- border: none;
- text-align: center;
- font-size: 1.3rem;
- }
+ .flag-search {
+ height: 2rem;
+ border-radius: 8px;
+ border: none;
+ text-align: center;
+ font-size: 1.3rem;
+ }
- .flag-dropdown {
- overflow-y: auto;
- display: flex;
- flex-direction: row;
- flex-wrap: wrap;
- gap: 1rem;
- }
+ .flag-dropdown {
+ overflow-y: auto;
+ display: flex;
+ flex-direction: row;
+ flex-wrap: wrap;
+ gap: 1rem;
+ }
- .dropdown-item {
- opacity: 0.7;
- width: calc(100% / 4 - 15px);
- text-align: center;
- color: white;
- cursor: pointer;
- border: none;
- background: none;
- }
+ .dropdown-item {
+ opacity: 0.7;
+ width: calc(100% / 4 - 15px);
+ text-align: center;
+ color: white;
+ cursor: pointer;
+ border: none;
+ background: none;
+ }
- .dropdown-item:hover {
- opacity: 1;
- }
+ .dropdown-item:hover {
+ opacity: 1;
+ }
- .country-flag {
- width: 100%;
- height: auto;
- }
+ .country-flag {
+ width: 100%;
+ height: auto;
+ }
- @media (max-width: 768px) {
- .flag-modal {
- left: 0px;
- width: calc(100% - 16px);
- height: 50vh;
- }
+ @media (max-width: 768px) {
+ .flag-modal {
+ left: 0px;
+ width: calc(100% - 16px);
+ height: 50vh;
+ }
- .dropdown-item {
- width: calc(100% / 3 - 15px);
- }
- }
- `;
+ .dropdown-item {
+ width: calc(100% / 3 - 15px);
+ }
+ }
+ `;
- private handleSearch(e: Event) {
- this.search = String((e.target as HTMLInputElement).value);
- }
+ private handleSearch(e: Event) {
+ this.search = String((e.target as HTMLInputElement).value);
+ }
- private setFlag(flag: string) {
- this.flag = flag;
- this.showModal = false;
- this.storeFlag(flag);
- }
+ private setFlag(flag: string) {
+ this.flag = flag;
+ this.showModal = false;
+ this.storeFlag(flag);
+ }
- public getCurrentFlag(): string {
- return this.flag;
- }
+ public getCurrentFlag(): string {
+ return this.flag;
+ }
- private getStoredFlag(): string {
- const storedFlag = localStorage.getItem(flagKey);
- if (storedFlag) {
- return storedFlag;
- }
- return '';
- }
+ private getStoredFlag(): string {
+ const storedFlag = localStorage.getItem(flagKey);
+ if (storedFlag) {
+ return storedFlag;
+ }
+ return "";
+ }
- private storeFlag(flag: string) {
- if (flag) {
- localStorage.setItem(flagKey, flag);
- } else if (flag === '') {
- localStorage.removeItem(flagKey);
- }
- }
+ private storeFlag(flag: string) {
+ if (flag) {
+ localStorage.setItem(flagKey, flag);
+ } else if (flag === "") {
+ localStorage.removeItem(flagKey);
+ }
+ }
- private dispatchFlagEvent() {
- this.dispatchEvent(
- new CustomEvent('flag-change', {
- detail: { flag: this.flag },
- bubbles: true,
- composed: true,
- })
- );
- }
+ private dispatchFlagEvent() {
+ this.dispatchEvent(
+ new CustomEvent("flag-change", {
+ detail: { flag: this.flag },
+ bubbles: true,
+ composed: true,
+ }),
+ );
+ }
- connectedCallback() {
- super.connectedCallback();
- this.flag = this.getStoredFlag();
- this.dispatchFlagEvent();
- }
+ connectedCallback() {
+ super.connectedCallback();
+ this.flag = this.getStoredFlag();
+ this.dispatchFlagEvent();
+ }
- render() {
- return html`
-
- ${this.flag === ''
- ? html`
`
- : html`

(this.showModal = true)}
- />`}
- ${this.showModal
- ? html`
-
-
-
-
-
- ${Countries.filter(
- (country) =>
- country.name
- .toLowerCase()
- .includes(
- this.search.toLowerCase()
- ) ||
- country.code
- .toLowerCase()
- .includes(
- this.search.toLowerCase()
- )
- ).map(
- (country) => html`
-
- `
- )}
-
-
- `
- : ''}
-
- `;
- }
+ render() {
+ return html`
+
+ ${this.flag === ""
+ ? html`
`
+ : html`

(this.showModal = true)}
+ />`}
+ ${this.showModal
+ ? html`
+
+
+
+
+
+ ${Countries.filter(
+ (country) =>
+ country.name
+ .toLowerCase()
+ .includes(this.search.toLowerCase()) ||
+ country.code
+ .toLowerCase()
+ .includes(this.search.toLowerCase()),
+ ).map(
+ (country) => html`
+
+ `,
+ )}
+
+
+ `
+ : ""}
+
+ `;
+ }
}
diff --git a/src/client/data/countries.json b/src/client/data/countries.json
index a3f9e6234..f67812d9e 100644
--- a/src/client/data/countries.json
+++ b/src/client/data/countries.json
@@ -1,1336 +1,1336 @@
[
- {
- "code": "af",
- "continent": "Asia",
- "name": "Afghanistan"
- },
- {
- "code": "ax",
- "continent": "Europe",
- "name": "Aland Islands"
- },
- {
- "code": "al",
- "continent": "Europe",
- "name": "Albania"
- },
- {
- "code": "dz",
- "continent": "Africa",
- "name": "Algeria"
- },
- {
- "code": "as",
- "continent": "Oceania",
- "name": "American Samoa"
- },
- {
- "code": "ad",
- "continent": "Europe",
- "name": "Andorra"
- },
- {
- "code": "ao",
- "continent": "Africa",
- "name": "Angola"
- },
- {
- "code": "ai",
- "continent": "North America",
- "name": "Anguilla"
- },
- {
- "code": "aq",
- "name": "Antarctica"
- },
- {
- "code": "ag",
- "continent": "North America",
- "name": "Antigua and Barbuda"
- },
- {
- "code": "ar",
- "continent": "South America",
- "name": "Argentina"
- },
- {
- "code": "am",
- "continent": "Asia",
- "name": "Armenia"
- },
- {
- "code": "aw",
- "continent": "South America",
- "name": "Aruba"
- },
- {
- "code": "sh-ac",
- "continent": "Africa",
- "name": "Ascension Island"
- },
- {
- "code": "asean",
- "name": "Association of Southeast Asian Nations"
- },
- {
- "code": "au",
- "continent": "Oceania",
- "name": "Australia"
- },
- {
- "code": "at",
- "continent": "Europe",
- "name": "Austria"
- },
- {
- "code": "az",
- "continent": "Asia",
- "name": "Azerbaijan"
- },
- {
- "code": "bs",
- "continent": "North America",
- "name": "Bahamas"
- },
- {
- "code": "bh",
- "continent": "Asia",
- "name": "Bahrain"
- },
- {
- "code": "bd",
- "continent": "Asia",
- "name": "Bangladesh"
- },
- {
- "code": "bb",
- "continent": "North America",
- "name": "Barbados"
- },
- {
- "code": "es-pv",
- "name": "Basque Country"
- },
- {
- "code": "by",
- "continent": "Europe",
- "name": "Belarus"
- },
- {
- "code": "be",
- "continent": "Europe",
- "name": "Belgium"
- },
- {
- "code": "bz",
- "continent": "North America",
- "name": "Belize"
- },
- {
- "code": "bj",
- "continent": "Africa",
- "name": "Benin"
- },
- {
- "code": "bm",
- "continent": "North America",
- "name": "Bermuda"
- },
- {
- "code": "bt",
- "continent": "Asia",
- "name": "Bhutan"
- },
- {
- "code": "bo",
- "continent": "South America",
- "name": "Bolivia"
- },
- {
- "code": "bq",
- "continent": "South America",
- "name": "Bonaire, Sint Eustatius and Saba"
- },
- {
- "code": "ba",
- "continent": "Europe",
- "name": "Bosnia and Herzegovina"
- },
- {
- "code": "bw",
- "continent": "Africa",
- "name": "Botswana"
- },
- {
- "code": "bv",
- "name": "Bouvet Island"
- },
- {
- "code": "br",
- "continent": "South America",
- "name": "Brazil"
- },
- {
- "code": "io",
- "continent": "Asia",
- "name": "British Indian Ocean Territory"
- },
- {
- "code": "bn",
- "continent": "Asia",
- "name": "Brunei Darussalam"
- },
- {
- "code": "bg",
- "continent": "Europe",
- "name": "Bulgaria"
- },
- {
- "code": "bf",
- "continent": "Africa",
- "name": "Burkina Faso"
- },
- {
- "code": "bi",
- "continent": "Africa",
- "name": "Burundi"
- },
- {
- "code": "cv",
- "continent": "Africa",
- "name": "Cabo Verde"
- },
- {
- "code": "kh",
- "continent": "Asia",
- "name": "Cambodia"
- },
- {
- "code": "cm",
- "continent": "Africa",
- "name": "Cameroon"
- },
- {
- "code": "ca",
- "continent": "North America",
- "name": "Canada"
- },
- {
- "code": "ic",
- "name": "Canary Islands"
- },
- {
- "code": "es-ct",
- "name": "Catalonia"
- },
- {
- "code": "ky",
- "continent": "North America",
- "name": "Cayman Islands"
- },
- {
- "code": "cf",
- "continent": "Africa",
- "name": "Central African Republic"
- },
- {
- "code": "cefta",
- "name": "Central European Free Trade Agreement"
- },
- {
- "code": "td",
- "continent": "Africa",
- "name": "Chad"
- },
- {
- "code": "cl",
- "continent": "South America",
- "name": "Chile"
- },
- {
- "code": "cn",
- "continent": "Asia",
- "name": "China"
- },
- {
- "code": "cx",
- "continent": "Asia",
- "name": "Christmas Island"
- },
- {
- "code": "cp",
- "name": "Clipperton Island"
- },
- {
- "code": "cc",
- "continent": "Asia",
- "name": "Cocos (Keeling) Islands"
- },
- {
- "code": "co",
- "continent": "South America",
- "name": "Colombia"
- },
- {
- "code": "km",
- "continent": "Africa",
- "name": "Comoros"
- },
- {
- "code": "ck",
- "continent": "Oceania",
- "name": "Cook Islands"
- },
- {
- "code": "cr",
- "continent": "North America",
- "name": "Costa Rica"
- },
- {
- "code": "hr",
- "continent": "Europe",
- "name": "Croatia"
- },
- {
- "code": "cu",
- "continent": "North America",
- "name": "Cuba"
- },
- {
- "code": "cw",
- "continent": "South America",
- "name": "Curaçao"
- },
- {
- "code": "cy",
- "continent": "Europe",
- "name": "Cyprus"
- },
- {
- "code": "cz",
- "continent": "Europe",
- "name": "Czech Republic"
- },
- {
- "code": "ci",
- "continent": "Africa",
- "name": "Côte d'Ivoire"
- },
- {
- "code": "cd",
- "continent": "Africa",
- "name": "Democratic Republic of the Congo"
- },
- {
- "code": "dk",
- "continent": "Europe",
- "name": "Denmark"
- },
- {
- "code": "dg",
- "name": "Diego Garcia"
- },
- {
- "code": "dj",
- "continent": "Africa",
- "name": "Djibouti"
- },
- {
- "code": "dm",
- "continent": "North America",
- "name": "Dominica"
- },
- {
- "code": "do",
- "continent": "North America",
- "name": "Dominican Republic"
- },
- {
- "code": "eac",
- "name": "East African Community"
- },
- {
- "code": "ec",
- "continent": "South America",
- "name": "Ecuador"
- },
- {
- "code": "eg",
- "continent": "Africa",
- "name": "Egypt"
- },
- {
- "code": "sv",
- "continent": "North America",
- "name": "El Salvador"
- },
- {
- "code": "gb-eng",
- "continent": "Europe",
- "name": "England"
- },
- {
- "code": "gq",
- "continent": "Africa",
- "name": "Equatorial Guinea"
- },
- {
- "code": "er",
- "continent": "Africa",
- "name": "Eritrea"
- },
- {
- "code": "ee",
- "continent": "Europe",
- "name": "Estonia"
- },
- {
- "code": "sz",
- "continent": "Africa",
- "name": "Eswatini"
- },
- {
- "code": "et",
- "continent": "Africa",
- "name": "Ethiopia"
- },
- {
- "code": "eu",
- "name": "Europe"
- },
- {
- "code": "fk",
- "continent": "South America",
- "name": "Falkland Islands"
- },
- {
- "code": "fo",
- "continent": "Europe",
- "name": "Faroe Islands"
- },
- {
- "code": "fm",
- "continent": "Oceania",
- "name": "Federated States of Micronesia"
- },
- {
- "code": "fj",
- "continent": "Oceania",
- "name": "Fiji"
- },
- {
- "code": "fi",
- "continent": "Europe",
- "name": "Finland"
- },
- {
- "code": "fr",
- "continent": "Europe",
- "name": "France"
- },
- {
- "code": "gf",
- "continent": "South America",
- "name": "French Guiana"
- },
- {
- "code": "pf",
- "continent": "Oceania",
- "name": "French Polynesia"
- },
- {
- "code": "tf",
- "continent": "Africa",
- "name": "French Southern Territories"
- },
- {
- "code": "ga",
- "continent": "Africa",
- "name": "Gabon"
- },
- {
- "code": "es-ga",
- "name": "Galicia"
- },
- {
- "code": "gm",
- "continent": "Africa",
- "name": "Gambia"
- },
- {
- "code": "ge",
- "continent": "Asia",
- "name": "Georgia"
- },
- {
- "code": "de",
- "continent": "Europe",
- "name": "Germany"
- },
- {
- "code": "gh",
- "continent": "Africa",
- "name": "Ghana"
- },
- {
- "code": "gi",
- "continent": "Europe",
- "name": "Gibraltar"
- },
- {
- "code": "gr",
- "continent": "Europe",
- "name": "Greece"
- },
- {
- "code": "gl",
- "continent": "North America",
- "name": "Greenland"
- },
- {
- "code": "gd",
- "continent": "North America",
- "name": "Grenada"
- },
- {
- "code": "gp",
- "continent": "North America",
- "name": "Guadeloupe"
- },
- {
- "code": "gu",
- "continent": "Oceania",
- "name": "Guam"
- },
- {
- "code": "gt",
- "continent": "North America",
- "name": "Guatemala"
- },
- {
- "code": "gg",
- "continent": "Europe",
- "name": "Guernsey"
- },
- {
- "code": "gn",
- "continent": "Africa",
- "name": "Guinea"
- },
- {
- "code": "gw",
- "continent": "Africa",
- "name": "Guinea-Bissau"
- },
- {
- "code": "gy",
- "continent": "South America",
- "name": "Guyana"
- },
- {
- "code": "ht",
- "continent": "North America",
- "name": "Haiti"
- },
- {
- "code": "hm",
- "name": "Heard Island and McDonald Islands"
- },
- {
- "code": "va",
- "continent": "Europe",
- "name": "Holy See"
- },
- {
- "code": "hn",
- "continent": "North America",
- "name": "Honduras"
- },
- {
- "code": "hk",
- "continent": "Asia",
- "name": "Hong Kong"
- },
- {
- "code": "hu",
- "continent": "Europe",
- "name": "Hungary"
- },
- {
- "code": "is",
- "continent": "Europe",
- "name": "Iceland"
- },
- {
- "code": "in",
- "continent": "Asia",
- "name": "India"
- },
- {
- "code": "id",
- "continent": "Asia",
- "name": "Indonesia"
- },
- {
- "code": "ir",
- "continent": "Asia",
- "name": "Iran"
- },
- {
- "code": "iq",
- "continent": "Asia",
- "name": "Iraq"
- },
- {
- "code": "ie",
- "continent": "Europe",
- "name": "Ireland"
- },
- {
- "code": "im",
- "continent": "Europe",
- "name": "Isle of Man"
- },
- {
- "code": "il",
- "continent": "Asia",
- "name": "Israel"
- },
- {
- "code": "it",
- "continent": "Europe",
- "name": "Italy"
- },
- {
- "code": "jm",
- "continent": "North America",
- "name": "Jamaica"
- },
- {
- "code": "jp",
- "continent": "Asia",
- "name": "Japan"
- },
- {
- "code": "je",
- "continent": "Europe",
- "name": "Jersey"
- },
- {
- "code": "jo",
- "continent": "Asia",
- "name": "Jordan"
- },
- {
- "code": "kz",
- "continent": "Asia",
- "name": "Kazakhstan"
- },
- {
- "code": "ke",
- "continent": "Africa",
- "name": "Kenya"
- },
- {
- "code": "ki",
- "continent": "Oceania",
- "name": "Kiribati"
- },
- {
- "code": "xk",
- "continent": "Europe",
- "name": "Kosovo"
- },
- {
- "code": "kw",
- "continent": "Asia",
- "name": "Kuwait"
- },
- {
- "code": "kg",
- "continent": "Asia",
- "name": "Kyrgyzstan"
- },
- {
- "code": "la",
- "continent": "Asia",
- "name": "Laos"
- },
- {
- "code": "lv",
- "continent": "Europe",
- "name": "Latvia"
- },
- {
- "code": "arab",
- "name": "League of Arab States"
- },
- {
- "code": "lb",
- "continent": "Asia",
- "name": "Lebanon"
- },
- {
- "code": "ls",
- "continent": "Africa",
- "name": "Lesotho"
- },
- {
- "code": "lr",
- "continent": "Africa",
- "name": "Liberia"
- },
- {
- "code": "ly",
- "continent": "Africa",
- "name": "Libya"
- },
- {
- "code": "li",
- "continent": "Europe",
- "name": "Liechtenstein"
- },
- {
- "code": "lt",
- "continent": "Europe",
- "name": "Lithuania"
- },
- {
- "code": "lu",
- "continent": "Europe",
- "name": "Luxembourg"
- },
- {
- "code": "mo",
- "continent": "Asia",
- "name": "Macau"
- },
- {
- "code": "mg",
- "continent": "Africa",
- "name": "Madagascar"
- },
- {
- "code": "mw",
- "continent": "Africa",
- "name": "Malawi"
- },
- {
- "code": "my",
- "continent": "Asia",
- "name": "Malaysia"
- },
- {
- "code": "mv",
- "continent": "Asia",
- "name": "Maldives"
- },
- {
- "code": "ml",
- "continent": "Africa",
- "name": "Mali"
- },
- {
- "code": "mt",
- "continent": "Europe",
- "name": "Malta"
- },
- {
- "code": "mh",
- "continent": "Oceania",
- "name": "Marshall Islands"
- },
- {
- "code": "mq",
- "continent": "North America",
- "name": "Martinique"
- },
- {
- "code": "mr",
- "continent": "Africa",
- "name": "Mauritania"
- },
- {
- "code": "mu",
- "continent": "Africa",
- "name": "Mauritius"
- },
- {
- "code": "yt",
- "continent": "Africa",
- "name": "Mayotte"
- },
- {
- "code": "mx",
- "continent": "North America",
- "name": "Mexico"
- },
- {
- "code": "md",
- "continent": "Europe",
- "name": "Moldova"
- },
- {
- "code": "mc",
- "continent": "Europe",
- "name": "Monaco"
- },
- {
- "code": "mn",
- "continent": "Asia",
- "name": "Mongolia"
- },
- {
- "code": "me",
- "continent": "Europe",
- "name": "Montenegro"
- },
- {
- "code": "ms",
- "continent": "North America",
- "name": "Montserrat"
- },
- {
- "code": "ma",
- "continent": "Africa",
- "name": "Morocco"
- },
- {
- "code": "mz",
- "continent": "Africa",
- "name": "Mozambique"
- },
- {
- "code": "mm",
- "continent": "Asia",
- "name": "Myanmar"
- },
- {
- "code": "na",
- "continent": "Africa",
- "name": "Namibia"
- },
- {
- "code": "nr",
- "continent": "Oceania",
- "name": "Nauru"
- },
- {
- "code": "np",
- "continent": "Asia",
- "name": "Nepal"
- },
- {
- "code": "nl",
- "continent": "Europe",
- "name": "Netherlands"
- },
- {
- "code": "nc",
- "continent": "Oceania",
- "name": "New Caledonia"
- },
- {
- "code": "nz",
- "continent": "Oceania",
- "name": "New Zealand"
- },
- {
- "code": "ni",
- "continent": "North America",
- "name": "Nicaragua"
- },
- {
- "code": "ne",
- "continent": "Africa",
- "name": "Niger"
- },
- {
- "code": "ng",
- "continent": "Africa",
- "name": "Nigeria"
- },
- {
- "code": "nu",
- "continent": "Oceania",
- "name": "Niue"
- },
- {
- "code": "nf",
- "continent": "Oceania",
- "name": "Norfolk Island"
- },
- {
- "code": "kp",
- "continent": "Asia",
- "name": "North Korea"
- },
- {
- "code": "mk",
- "continent": "Europe",
- "name": "North Macedonia"
- },
- {
- "code": "gb-nir",
- "continent": "Europe",
- "name": "Northern Ireland"
- },
- {
- "code": "mp",
- "continent": "Oceania",
- "name": "Northern Mariana Islands"
- },
- {
- "code": "no",
- "continent": "Europe",
- "name": "Norway"
- },
- {
- "code": "om",
- "continent": "Asia",
- "name": "Oman"
- },
- {
- "code": "pc",
- "name": "Pacific Community"
- },
- {
- "code": "pk",
- "continent": "Asia",
- "name": "Pakistan"
- },
- {
- "code": "pw",
- "continent": "Oceania",
- "name": "Palau"
- },
- {
- "code": "pa",
- "continent": "North America",
- "name": "Panama"
- },
- {
- "code": "pg",
- "continent": "Oceania",
- "name": "Papua New Guinea"
- },
- {
- "code": "py",
- "continent": "South America",
- "name": "Paraguay"
- },
- {
- "code": "pe",
- "continent": "South America",
- "name": "Peru"
- },
- {
- "code": "ph",
- "continent": "Asia",
- "name": "Philippines"
- },
- {
- "code": "pn",
- "continent": "Oceania",
- "name": "Pitcairn"
- },
- {
- "code": "pl",
- "continent": "Europe",
- "name": "Poland"
- },
- {
- "code": "pt",
- "continent": "Europe",
- "name": "Portugal"
- },
- {
- "code": "pr",
- "continent": "North America",
- "name": "Puerto Rico"
- },
- {
- "code": "qa",
- "continent": "Asia",
- "name": "Qatar"
- },
- {
- "code": "cg",
- "continent": "Africa",
- "name": "Republic of the Congo"
- },
- {
- "code": "ro",
- "continent": "Europe",
- "name": "Romania"
- },
- {
- "code": "ru",
- "continent": "Europe",
- "name": "Russia"
- },
- {
- "code": "rw",
- "continent": "Africa",
- "name": "Rwanda"
- },
- {
- "code": "re",
- "continent": "Africa",
- "name": "Réunion"
- },
- {
- "code": "bl",
- "continent": "North America",
- "name": "Saint Barthélemy"
- },
- {
- "code": "sh-hl",
- "continent": "Africa",
- "name": "Saint Helena"
- },
- {
- "code": "sh",
- "continent": "Africa",
- "name": "Saint Helena, Ascension and Tristan da Cunha"
- },
- {
- "code": "kn",
- "continent": "North America",
- "name": "Saint Kitts and Nevis"
- },
- {
- "code": "lc",
- "continent": "North America",
- "name": "Saint Lucia"
- },
- {
- "code": "mf",
- "continent": "North America",
- "name": "Saint Martin"
- },
- {
- "code": "pm",
- "continent": "North America",
- "name": "Saint Pierre and Miquelon"
- },
- {
- "code": "vc",
- "continent": "North America",
- "name": "Saint Vincent and the Grenadines"
- },
- {
- "code": "ws",
- "continent": "Oceania",
- "name": "Samoa"
- },
- {
- "code": "sm",
- "continent": "Europe",
- "name": "San Marino"
- },
- {
- "code": "st",
- "continent": "Africa",
- "name": "Sao Tome and Principe"
- },
- {
- "code": "sa",
- "continent": "Asia",
- "name": "Saudi Arabia"
- },
- {
- "code": "gb-sct",
- "continent": "Europe",
- "name": "Scotland"
- },
- {
- "code": "sn",
- "continent": "Africa",
- "name": "Senegal"
- },
- {
- "code": "rs",
- "continent": "Europe",
- "name": "Serbia"
- },
- {
- "code": "sc",
- "continent": "Africa",
- "name": "Seychelles"
- },
- {
- "code": "sl",
- "continent": "Africa",
- "name": "Sierra Leone"
- },
- {
- "code": "sg",
- "continent": "Asia",
- "name": "Singapore"
- },
- {
- "code": "sx",
- "continent": "North America",
- "name": "Sint Maarten"
- },
- {
- "code": "sk",
- "continent": "Europe",
- "name": "Slovakia"
- },
- {
- "code": "si",
- "continent": "Europe",
- "name": "Slovenia"
- },
- {
- "code": "sb",
- "continent": "Oceania",
- "name": "Solomon Islands"
- },
- {
- "code": "so",
- "continent": "Africa",
- "name": "Somalia"
- },
- {
- "code": "za",
- "continent": "Africa",
- "name": "South Africa"
- },
- {
- "code": "gs",
- "continent": "Antarctica",
- "name": "South Georgia and the South Sandwich Islands"
- },
- {
- "code": "kr",
- "continent": "Asia",
- "name": "South Korea"
- },
- {
- "code": "ss",
- "continent": "Africa",
- "name": "South Sudan"
- },
- {
- "code": "es",
- "continent": "Europe",
- "name": "Spain"
- },
- {
- "code": "lk",
- "continent": "Asia",
- "name": "Sri Lanka"
- },
- {
- "code": "ps",
- "continent": "Asia",
- "name": "State of Palestine"
- },
- {
- "code": "sd",
- "continent": "Africa",
- "name": "Sudan"
- },
- {
- "code": "sr",
- "continent": "South America",
- "name": "Suriname"
- },
- {
- "code": "sj",
- "continent": "Europe",
- "name": "Svalbard and Jan Mayen"
- },
- {
- "code": "se",
- "continent": "Europe",
- "name": "Sweden"
- },
- {
- "code": "ch",
- "continent": "Europe",
- "name": "Switzerland"
- },
- {
- "code": "sy",
- "continent": "Asia",
- "name": "Syria"
- },
- {
- "code": "tw",
- "continent": "Asia",
- "name": "Taiwan"
- },
- {
- "code": "tj",
- "continent": "Asia",
- "name": "Tajikistan"
- },
- {
- "code": "tz",
- "continent": "Africa",
- "name": "Tanzania"
- },
- {
- "code": "th",
- "continent": "Asia",
- "name": "Thailand"
- },
- {
- "code": "tl",
- "continent": "Asia",
- "name": "Timor-Leste"
- },
- {
- "code": "tg",
- "continent": "Africa",
- "name": "Togo"
- },
- {
- "code": "tk",
- "continent": "Oceania",
- "name": "Tokelau"
- },
- {
- "code": "to",
- "continent": "Oceania",
- "name": "Tonga"
- },
- {
- "code": "tt",
- "continent": "South America",
- "name": "Trinidad and Tobago"
- },
- {
- "code": "sh-ta",
- "continent": "Africa",
- "name": "Tristan da Cunha"
- },
- {
- "code": "tn",
- "continent": "Africa",
- "name": "Tunisia"
- },
- {
- "code": "tm",
- "continent": "Asia",
- "name": "Turkmenistan"
- },
- {
- "code": "tc",
- "continent": "North America",
- "name": "Turks and Caicos Islands"
- },
- {
- "code": "tv",
- "continent": "Oceania",
- "name": "Tuvalu"
- },
- {
- "code": "tr",
- "continent": "Asia",
- "name": "Türkiye"
- },
- {
- "code": "ug",
- "continent": "Africa",
- "name": "Uganda"
- },
- {
- "code": "ua",
- "continent": "Europe",
- "name": "Ukraine"
- },
- {
- "code": "ae",
- "continent": "Asia",
- "name": "United Arab Emirates"
- },
- {
- "code": "gb",
- "continent": "Europe",
- "name": "United Kingdom"
- },
- {
- "code": "un",
- "name": "United Nations"
- },
- {
- "code": "um",
- "continent": "North America",
- "name": "United States Minor Outlying Islands"
- },
- {
- "code": "us",
- "continent": "North America",
- "name": "United States of America"
- },
- {
- "code": "uy",
- "continent": "South America",
- "name": "Uruguay"
- },
- {
- "code": "uz",
- "continent": "Asia",
- "name": "Uzbekistan"
- },
- {
- "code": "vu",
- "continent": "Oceania",
- "name": "Vanuatu"
- },
- {
- "code": "ve",
- "continent": "South America",
- "name": "Venezuela"
- },
- {
- "code": "vn",
- "continent": "Asia",
- "name": "Vietnam"
- },
- {
- "code": "vg",
- "continent": "North America",
- "name": "Virgin Islands (British)"
- },
- {
- "code": "vi",
- "continent": "North America",
- "name": "Virgin Islands (U.S.)"
- },
- {
- "code": "gb-wls",
- "continent": "Europe",
- "name": "Wales"
- },
- {
- "code": "wf",
- "continent": "Oceania",
- "name": "Wallis and Futuna"
- },
- {
- "code": "eh",
- "continent": "Africa",
- "name": "Western Sahara"
- },
- {
- "code": "ye",
- "continent": "Asia",
- "name": "Yemen"
- },
- {
- "code": "zm",
- "continent": "Africa",
- "name": "Zambia"
- },
- {
- "code": "zw",
- "continent": "Africa",
- "name": "Zimbabwe"
- }
+ {
+ "code": "af",
+ "continent": "Asia",
+ "name": "Afghanistan"
+ },
+ {
+ "code": "ax",
+ "continent": "Europe",
+ "name": "Aland Islands"
+ },
+ {
+ "code": "al",
+ "continent": "Europe",
+ "name": "Albania"
+ },
+ {
+ "code": "dz",
+ "continent": "Africa",
+ "name": "Algeria"
+ },
+ {
+ "code": "as",
+ "continent": "Oceania",
+ "name": "American Samoa"
+ },
+ {
+ "code": "ad",
+ "continent": "Europe",
+ "name": "Andorra"
+ },
+ {
+ "code": "ao",
+ "continent": "Africa",
+ "name": "Angola"
+ },
+ {
+ "code": "ai",
+ "continent": "North America",
+ "name": "Anguilla"
+ },
+ {
+ "code": "aq",
+ "name": "Antarctica"
+ },
+ {
+ "code": "ag",
+ "continent": "North America",
+ "name": "Antigua and Barbuda"
+ },
+ {
+ "code": "ar",
+ "continent": "South America",
+ "name": "Argentina"
+ },
+ {
+ "code": "am",
+ "continent": "Asia",
+ "name": "Armenia"
+ },
+ {
+ "code": "aw",
+ "continent": "South America",
+ "name": "Aruba"
+ },
+ {
+ "code": "sh-ac",
+ "continent": "Africa",
+ "name": "Ascension Island"
+ },
+ {
+ "code": "asean",
+ "name": "Association of Southeast Asian Nations"
+ },
+ {
+ "code": "au",
+ "continent": "Oceania",
+ "name": "Australia"
+ },
+ {
+ "code": "at",
+ "continent": "Europe",
+ "name": "Austria"
+ },
+ {
+ "code": "az",
+ "continent": "Asia",
+ "name": "Azerbaijan"
+ },
+ {
+ "code": "bs",
+ "continent": "North America",
+ "name": "Bahamas"
+ },
+ {
+ "code": "bh",
+ "continent": "Asia",
+ "name": "Bahrain"
+ },
+ {
+ "code": "bd",
+ "continent": "Asia",
+ "name": "Bangladesh"
+ },
+ {
+ "code": "bb",
+ "continent": "North America",
+ "name": "Barbados"
+ },
+ {
+ "code": "es-pv",
+ "name": "Basque Country"
+ },
+ {
+ "code": "by",
+ "continent": "Europe",
+ "name": "Belarus"
+ },
+ {
+ "code": "be",
+ "continent": "Europe",
+ "name": "Belgium"
+ },
+ {
+ "code": "bz",
+ "continent": "North America",
+ "name": "Belize"
+ },
+ {
+ "code": "bj",
+ "continent": "Africa",
+ "name": "Benin"
+ },
+ {
+ "code": "bm",
+ "continent": "North America",
+ "name": "Bermuda"
+ },
+ {
+ "code": "bt",
+ "continent": "Asia",
+ "name": "Bhutan"
+ },
+ {
+ "code": "bo",
+ "continent": "South America",
+ "name": "Bolivia"
+ },
+ {
+ "code": "bq",
+ "continent": "South America",
+ "name": "Bonaire, Sint Eustatius and Saba"
+ },
+ {
+ "code": "ba",
+ "continent": "Europe",
+ "name": "Bosnia and Herzegovina"
+ },
+ {
+ "code": "bw",
+ "continent": "Africa",
+ "name": "Botswana"
+ },
+ {
+ "code": "bv",
+ "name": "Bouvet Island"
+ },
+ {
+ "code": "br",
+ "continent": "South America",
+ "name": "Brazil"
+ },
+ {
+ "code": "io",
+ "continent": "Asia",
+ "name": "British Indian Ocean Territory"
+ },
+ {
+ "code": "bn",
+ "continent": "Asia",
+ "name": "Brunei Darussalam"
+ },
+ {
+ "code": "bg",
+ "continent": "Europe",
+ "name": "Bulgaria"
+ },
+ {
+ "code": "bf",
+ "continent": "Africa",
+ "name": "Burkina Faso"
+ },
+ {
+ "code": "bi",
+ "continent": "Africa",
+ "name": "Burundi"
+ },
+ {
+ "code": "cv",
+ "continent": "Africa",
+ "name": "Cabo Verde"
+ },
+ {
+ "code": "kh",
+ "continent": "Asia",
+ "name": "Cambodia"
+ },
+ {
+ "code": "cm",
+ "continent": "Africa",
+ "name": "Cameroon"
+ },
+ {
+ "code": "ca",
+ "continent": "North America",
+ "name": "Canada"
+ },
+ {
+ "code": "ic",
+ "name": "Canary Islands"
+ },
+ {
+ "code": "es-ct",
+ "name": "Catalonia"
+ },
+ {
+ "code": "ky",
+ "continent": "North America",
+ "name": "Cayman Islands"
+ },
+ {
+ "code": "cf",
+ "continent": "Africa",
+ "name": "Central African Republic"
+ },
+ {
+ "code": "cefta",
+ "name": "Central European Free Trade Agreement"
+ },
+ {
+ "code": "td",
+ "continent": "Africa",
+ "name": "Chad"
+ },
+ {
+ "code": "cl",
+ "continent": "South America",
+ "name": "Chile"
+ },
+ {
+ "code": "cn",
+ "continent": "Asia",
+ "name": "China"
+ },
+ {
+ "code": "cx",
+ "continent": "Asia",
+ "name": "Christmas Island"
+ },
+ {
+ "code": "cp",
+ "name": "Clipperton Island"
+ },
+ {
+ "code": "cc",
+ "continent": "Asia",
+ "name": "Cocos (Keeling) Islands"
+ },
+ {
+ "code": "co",
+ "continent": "South America",
+ "name": "Colombia"
+ },
+ {
+ "code": "km",
+ "continent": "Africa",
+ "name": "Comoros"
+ },
+ {
+ "code": "ck",
+ "continent": "Oceania",
+ "name": "Cook Islands"
+ },
+ {
+ "code": "cr",
+ "continent": "North America",
+ "name": "Costa Rica"
+ },
+ {
+ "code": "hr",
+ "continent": "Europe",
+ "name": "Croatia"
+ },
+ {
+ "code": "cu",
+ "continent": "North America",
+ "name": "Cuba"
+ },
+ {
+ "code": "cw",
+ "continent": "South America",
+ "name": "Curaçao"
+ },
+ {
+ "code": "cy",
+ "continent": "Europe",
+ "name": "Cyprus"
+ },
+ {
+ "code": "cz",
+ "continent": "Europe",
+ "name": "Czech Republic"
+ },
+ {
+ "code": "ci",
+ "continent": "Africa",
+ "name": "Côte d'Ivoire"
+ },
+ {
+ "code": "cd",
+ "continent": "Africa",
+ "name": "Democratic Republic of the Congo"
+ },
+ {
+ "code": "dk",
+ "continent": "Europe",
+ "name": "Denmark"
+ },
+ {
+ "code": "dg",
+ "name": "Diego Garcia"
+ },
+ {
+ "code": "dj",
+ "continent": "Africa",
+ "name": "Djibouti"
+ },
+ {
+ "code": "dm",
+ "continent": "North America",
+ "name": "Dominica"
+ },
+ {
+ "code": "do",
+ "continent": "North America",
+ "name": "Dominican Republic"
+ },
+ {
+ "code": "eac",
+ "name": "East African Community"
+ },
+ {
+ "code": "ec",
+ "continent": "South America",
+ "name": "Ecuador"
+ },
+ {
+ "code": "eg",
+ "continent": "Africa",
+ "name": "Egypt"
+ },
+ {
+ "code": "sv",
+ "continent": "North America",
+ "name": "El Salvador"
+ },
+ {
+ "code": "gb-eng",
+ "continent": "Europe",
+ "name": "England"
+ },
+ {
+ "code": "gq",
+ "continent": "Africa",
+ "name": "Equatorial Guinea"
+ },
+ {
+ "code": "er",
+ "continent": "Africa",
+ "name": "Eritrea"
+ },
+ {
+ "code": "ee",
+ "continent": "Europe",
+ "name": "Estonia"
+ },
+ {
+ "code": "sz",
+ "continent": "Africa",
+ "name": "Eswatini"
+ },
+ {
+ "code": "et",
+ "continent": "Africa",
+ "name": "Ethiopia"
+ },
+ {
+ "code": "eu",
+ "name": "Europe"
+ },
+ {
+ "code": "fk",
+ "continent": "South America",
+ "name": "Falkland Islands"
+ },
+ {
+ "code": "fo",
+ "continent": "Europe",
+ "name": "Faroe Islands"
+ },
+ {
+ "code": "fm",
+ "continent": "Oceania",
+ "name": "Federated States of Micronesia"
+ },
+ {
+ "code": "fj",
+ "continent": "Oceania",
+ "name": "Fiji"
+ },
+ {
+ "code": "fi",
+ "continent": "Europe",
+ "name": "Finland"
+ },
+ {
+ "code": "fr",
+ "continent": "Europe",
+ "name": "France"
+ },
+ {
+ "code": "gf",
+ "continent": "South America",
+ "name": "French Guiana"
+ },
+ {
+ "code": "pf",
+ "continent": "Oceania",
+ "name": "French Polynesia"
+ },
+ {
+ "code": "tf",
+ "continent": "Africa",
+ "name": "French Southern Territories"
+ },
+ {
+ "code": "ga",
+ "continent": "Africa",
+ "name": "Gabon"
+ },
+ {
+ "code": "es-ga",
+ "name": "Galicia"
+ },
+ {
+ "code": "gm",
+ "continent": "Africa",
+ "name": "Gambia"
+ },
+ {
+ "code": "ge",
+ "continent": "Asia",
+ "name": "Georgia"
+ },
+ {
+ "code": "de",
+ "continent": "Europe",
+ "name": "Germany"
+ },
+ {
+ "code": "gh",
+ "continent": "Africa",
+ "name": "Ghana"
+ },
+ {
+ "code": "gi",
+ "continent": "Europe",
+ "name": "Gibraltar"
+ },
+ {
+ "code": "gr",
+ "continent": "Europe",
+ "name": "Greece"
+ },
+ {
+ "code": "gl",
+ "continent": "North America",
+ "name": "Greenland"
+ },
+ {
+ "code": "gd",
+ "continent": "North America",
+ "name": "Grenada"
+ },
+ {
+ "code": "gp",
+ "continent": "North America",
+ "name": "Guadeloupe"
+ },
+ {
+ "code": "gu",
+ "continent": "Oceania",
+ "name": "Guam"
+ },
+ {
+ "code": "gt",
+ "continent": "North America",
+ "name": "Guatemala"
+ },
+ {
+ "code": "gg",
+ "continent": "Europe",
+ "name": "Guernsey"
+ },
+ {
+ "code": "gn",
+ "continent": "Africa",
+ "name": "Guinea"
+ },
+ {
+ "code": "gw",
+ "continent": "Africa",
+ "name": "Guinea-Bissau"
+ },
+ {
+ "code": "gy",
+ "continent": "South America",
+ "name": "Guyana"
+ },
+ {
+ "code": "ht",
+ "continent": "North America",
+ "name": "Haiti"
+ },
+ {
+ "code": "hm",
+ "name": "Heard Island and McDonald Islands"
+ },
+ {
+ "code": "va",
+ "continent": "Europe",
+ "name": "Holy See"
+ },
+ {
+ "code": "hn",
+ "continent": "North America",
+ "name": "Honduras"
+ },
+ {
+ "code": "hk",
+ "continent": "Asia",
+ "name": "Hong Kong"
+ },
+ {
+ "code": "hu",
+ "continent": "Europe",
+ "name": "Hungary"
+ },
+ {
+ "code": "is",
+ "continent": "Europe",
+ "name": "Iceland"
+ },
+ {
+ "code": "in",
+ "continent": "Asia",
+ "name": "India"
+ },
+ {
+ "code": "id",
+ "continent": "Asia",
+ "name": "Indonesia"
+ },
+ {
+ "code": "ir",
+ "continent": "Asia",
+ "name": "Iran"
+ },
+ {
+ "code": "iq",
+ "continent": "Asia",
+ "name": "Iraq"
+ },
+ {
+ "code": "ie",
+ "continent": "Europe",
+ "name": "Ireland"
+ },
+ {
+ "code": "im",
+ "continent": "Europe",
+ "name": "Isle of Man"
+ },
+ {
+ "code": "il",
+ "continent": "Asia",
+ "name": "Israel"
+ },
+ {
+ "code": "it",
+ "continent": "Europe",
+ "name": "Italy"
+ },
+ {
+ "code": "jm",
+ "continent": "North America",
+ "name": "Jamaica"
+ },
+ {
+ "code": "jp",
+ "continent": "Asia",
+ "name": "Japan"
+ },
+ {
+ "code": "je",
+ "continent": "Europe",
+ "name": "Jersey"
+ },
+ {
+ "code": "jo",
+ "continent": "Asia",
+ "name": "Jordan"
+ },
+ {
+ "code": "kz",
+ "continent": "Asia",
+ "name": "Kazakhstan"
+ },
+ {
+ "code": "ke",
+ "continent": "Africa",
+ "name": "Kenya"
+ },
+ {
+ "code": "ki",
+ "continent": "Oceania",
+ "name": "Kiribati"
+ },
+ {
+ "code": "xk",
+ "continent": "Europe",
+ "name": "Kosovo"
+ },
+ {
+ "code": "kw",
+ "continent": "Asia",
+ "name": "Kuwait"
+ },
+ {
+ "code": "kg",
+ "continent": "Asia",
+ "name": "Kyrgyzstan"
+ },
+ {
+ "code": "la",
+ "continent": "Asia",
+ "name": "Laos"
+ },
+ {
+ "code": "lv",
+ "continent": "Europe",
+ "name": "Latvia"
+ },
+ {
+ "code": "arab",
+ "name": "League of Arab States"
+ },
+ {
+ "code": "lb",
+ "continent": "Asia",
+ "name": "Lebanon"
+ },
+ {
+ "code": "ls",
+ "continent": "Africa",
+ "name": "Lesotho"
+ },
+ {
+ "code": "lr",
+ "continent": "Africa",
+ "name": "Liberia"
+ },
+ {
+ "code": "ly",
+ "continent": "Africa",
+ "name": "Libya"
+ },
+ {
+ "code": "li",
+ "continent": "Europe",
+ "name": "Liechtenstein"
+ },
+ {
+ "code": "lt",
+ "continent": "Europe",
+ "name": "Lithuania"
+ },
+ {
+ "code": "lu",
+ "continent": "Europe",
+ "name": "Luxembourg"
+ },
+ {
+ "code": "mo",
+ "continent": "Asia",
+ "name": "Macau"
+ },
+ {
+ "code": "mg",
+ "continent": "Africa",
+ "name": "Madagascar"
+ },
+ {
+ "code": "mw",
+ "continent": "Africa",
+ "name": "Malawi"
+ },
+ {
+ "code": "my",
+ "continent": "Asia",
+ "name": "Malaysia"
+ },
+ {
+ "code": "mv",
+ "continent": "Asia",
+ "name": "Maldives"
+ },
+ {
+ "code": "ml",
+ "continent": "Africa",
+ "name": "Mali"
+ },
+ {
+ "code": "mt",
+ "continent": "Europe",
+ "name": "Malta"
+ },
+ {
+ "code": "mh",
+ "continent": "Oceania",
+ "name": "Marshall Islands"
+ },
+ {
+ "code": "mq",
+ "continent": "North America",
+ "name": "Martinique"
+ },
+ {
+ "code": "mr",
+ "continent": "Africa",
+ "name": "Mauritania"
+ },
+ {
+ "code": "mu",
+ "continent": "Africa",
+ "name": "Mauritius"
+ },
+ {
+ "code": "yt",
+ "continent": "Africa",
+ "name": "Mayotte"
+ },
+ {
+ "code": "mx",
+ "continent": "North America",
+ "name": "Mexico"
+ },
+ {
+ "code": "md",
+ "continent": "Europe",
+ "name": "Moldova"
+ },
+ {
+ "code": "mc",
+ "continent": "Europe",
+ "name": "Monaco"
+ },
+ {
+ "code": "mn",
+ "continent": "Asia",
+ "name": "Mongolia"
+ },
+ {
+ "code": "me",
+ "continent": "Europe",
+ "name": "Montenegro"
+ },
+ {
+ "code": "ms",
+ "continent": "North America",
+ "name": "Montserrat"
+ },
+ {
+ "code": "ma",
+ "continent": "Africa",
+ "name": "Morocco"
+ },
+ {
+ "code": "mz",
+ "continent": "Africa",
+ "name": "Mozambique"
+ },
+ {
+ "code": "mm",
+ "continent": "Asia",
+ "name": "Myanmar"
+ },
+ {
+ "code": "na",
+ "continent": "Africa",
+ "name": "Namibia"
+ },
+ {
+ "code": "nr",
+ "continent": "Oceania",
+ "name": "Nauru"
+ },
+ {
+ "code": "np",
+ "continent": "Asia",
+ "name": "Nepal"
+ },
+ {
+ "code": "nl",
+ "continent": "Europe",
+ "name": "Netherlands"
+ },
+ {
+ "code": "nc",
+ "continent": "Oceania",
+ "name": "New Caledonia"
+ },
+ {
+ "code": "nz",
+ "continent": "Oceania",
+ "name": "New Zealand"
+ },
+ {
+ "code": "ni",
+ "continent": "North America",
+ "name": "Nicaragua"
+ },
+ {
+ "code": "ne",
+ "continent": "Africa",
+ "name": "Niger"
+ },
+ {
+ "code": "ng",
+ "continent": "Africa",
+ "name": "Nigeria"
+ },
+ {
+ "code": "nu",
+ "continent": "Oceania",
+ "name": "Niue"
+ },
+ {
+ "code": "nf",
+ "continent": "Oceania",
+ "name": "Norfolk Island"
+ },
+ {
+ "code": "kp",
+ "continent": "Asia",
+ "name": "North Korea"
+ },
+ {
+ "code": "mk",
+ "continent": "Europe",
+ "name": "North Macedonia"
+ },
+ {
+ "code": "gb-nir",
+ "continent": "Europe",
+ "name": "Northern Ireland"
+ },
+ {
+ "code": "mp",
+ "continent": "Oceania",
+ "name": "Northern Mariana Islands"
+ },
+ {
+ "code": "no",
+ "continent": "Europe",
+ "name": "Norway"
+ },
+ {
+ "code": "om",
+ "continent": "Asia",
+ "name": "Oman"
+ },
+ {
+ "code": "pc",
+ "name": "Pacific Community"
+ },
+ {
+ "code": "pk",
+ "continent": "Asia",
+ "name": "Pakistan"
+ },
+ {
+ "code": "pw",
+ "continent": "Oceania",
+ "name": "Palau"
+ },
+ {
+ "code": "pa",
+ "continent": "North America",
+ "name": "Panama"
+ },
+ {
+ "code": "pg",
+ "continent": "Oceania",
+ "name": "Papua New Guinea"
+ },
+ {
+ "code": "py",
+ "continent": "South America",
+ "name": "Paraguay"
+ },
+ {
+ "code": "pe",
+ "continent": "South America",
+ "name": "Peru"
+ },
+ {
+ "code": "ph",
+ "continent": "Asia",
+ "name": "Philippines"
+ },
+ {
+ "code": "pn",
+ "continent": "Oceania",
+ "name": "Pitcairn"
+ },
+ {
+ "code": "pl",
+ "continent": "Europe",
+ "name": "Poland"
+ },
+ {
+ "code": "pt",
+ "continent": "Europe",
+ "name": "Portugal"
+ },
+ {
+ "code": "pr",
+ "continent": "North America",
+ "name": "Puerto Rico"
+ },
+ {
+ "code": "qa",
+ "continent": "Asia",
+ "name": "Qatar"
+ },
+ {
+ "code": "cg",
+ "continent": "Africa",
+ "name": "Republic of the Congo"
+ },
+ {
+ "code": "ro",
+ "continent": "Europe",
+ "name": "Romania"
+ },
+ {
+ "code": "ru",
+ "continent": "Europe",
+ "name": "Russia"
+ },
+ {
+ "code": "rw",
+ "continent": "Africa",
+ "name": "Rwanda"
+ },
+ {
+ "code": "re",
+ "continent": "Africa",
+ "name": "Réunion"
+ },
+ {
+ "code": "bl",
+ "continent": "North America",
+ "name": "Saint Barthélemy"
+ },
+ {
+ "code": "sh-hl",
+ "continent": "Africa",
+ "name": "Saint Helena"
+ },
+ {
+ "code": "sh",
+ "continent": "Africa",
+ "name": "Saint Helena, Ascension and Tristan da Cunha"
+ },
+ {
+ "code": "kn",
+ "continent": "North America",
+ "name": "Saint Kitts and Nevis"
+ },
+ {
+ "code": "lc",
+ "continent": "North America",
+ "name": "Saint Lucia"
+ },
+ {
+ "code": "mf",
+ "continent": "North America",
+ "name": "Saint Martin"
+ },
+ {
+ "code": "pm",
+ "continent": "North America",
+ "name": "Saint Pierre and Miquelon"
+ },
+ {
+ "code": "vc",
+ "continent": "North America",
+ "name": "Saint Vincent and the Grenadines"
+ },
+ {
+ "code": "ws",
+ "continent": "Oceania",
+ "name": "Samoa"
+ },
+ {
+ "code": "sm",
+ "continent": "Europe",
+ "name": "San Marino"
+ },
+ {
+ "code": "st",
+ "continent": "Africa",
+ "name": "Sao Tome and Principe"
+ },
+ {
+ "code": "sa",
+ "continent": "Asia",
+ "name": "Saudi Arabia"
+ },
+ {
+ "code": "gb-sct",
+ "continent": "Europe",
+ "name": "Scotland"
+ },
+ {
+ "code": "sn",
+ "continent": "Africa",
+ "name": "Senegal"
+ },
+ {
+ "code": "rs",
+ "continent": "Europe",
+ "name": "Serbia"
+ },
+ {
+ "code": "sc",
+ "continent": "Africa",
+ "name": "Seychelles"
+ },
+ {
+ "code": "sl",
+ "continent": "Africa",
+ "name": "Sierra Leone"
+ },
+ {
+ "code": "sg",
+ "continent": "Asia",
+ "name": "Singapore"
+ },
+ {
+ "code": "sx",
+ "continent": "North America",
+ "name": "Sint Maarten"
+ },
+ {
+ "code": "sk",
+ "continent": "Europe",
+ "name": "Slovakia"
+ },
+ {
+ "code": "si",
+ "continent": "Europe",
+ "name": "Slovenia"
+ },
+ {
+ "code": "sb",
+ "continent": "Oceania",
+ "name": "Solomon Islands"
+ },
+ {
+ "code": "so",
+ "continent": "Africa",
+ "name": "Somalia"
+ },
+ {
+ "code": "za",
+ "continent": "Africa",
+ "name": "South Africa"
+ },
+ {
+ "code": "gs",
+ "continent": "Antarctica",
+ "name": "South Georgia and the South Sandwich Islands"
+ },
+ {
+ "code": "kr",
+ "continent": "Asia",
+ "name": "South Korea"
+ },
+ {
+ "code": "ss",
+ "continent": "Africa",
+ "name": "South Sudan"
+ },
+ {
+ "code": "es",
+ "continent": "Europe",
+ "name": "Spain"
+ },
+ {
+ "code": "lk",
+ "continent": "Asia",
+ "name": "Sri Lanka"
+ },
+ {
+ "code": "ps",
+ "continent": "Asia",
+ "name": "State of Palestine"
+ },
+ {
+ "code": "sd",
+ "continent": "Africa",
+ "name": "Sudan"
+ },
+ {
+ "code": "sr",
+ "continent": "South America",
+ "name": "Suriname"
+ },
+ {
+ "code": "sj",
+ "continent": "Europe",
+ "name": "Svalbard and Jan Mayen"
+ },
+ {
+ "code": "se",
+ "continent": "Europe",
+ "name": "Sweden"
+ },
+ {
+ "code": "ch",
+ "continent": "Europe",
+ "name": "Switzerland"
+ },
+ {
+ "code": "sy",
+ "continent": "Asia",
+ "name": "Syria"
+ },
+ {
+ "code": "tw",
+ "continent": "Asia",
+ "name": "Taiwan"
+ },
+ {
+ "code": "tj",
+ "continent": "Asia",
+ "name": "Tajikistan"
+ },
+ {
+ "code": "tz",
+ "continent": "Africa",
+ "name": "Tanzania"
+ },
+ {
+ "code": "th",
+ "continent": "Asia",
+ "name": "Thailand"
+ },
+ {
+ "code": "tl",
+ "continent": "Asia",
+ "name": "Timor-Leste"
+ },
+ {
+ "code": "tg",
+ "continent": "Africa",
+ "name": "Togo"
+ },
+ {
+ "code": "tk",
+ "continent": "Oceania",
+ "name": "Tokelau"
+ },
+ {
+ "code": "to",
+ "continent": "Oceania",
+ "name": "Tonga"
+ },
+ {
+ "code": "tt",
+ "continent": "South America",
+ "name": "Trinidad and Tobago"
+ },
+ {
+ "code": "sh-ta",
+ "continent": "Africa",
+ "name": "Tristan da Cunha"
+ },
+ {
+ "code": "tn",
+ "continent": "Africa",
+ "name": "Tunisia"
+ },
+ {
+ "code": "tm",
+ "continent": "Asia",
+ "name": "Turkmenistan"
+ },
+ {
+ "code": "tc",
+ "continent": "North America",
+ "name": "Turks and Caicos Islands"
+ },
+ {
+ "code": "tv",
+ "continent": "Oceania",
+ "name": "Tuvalu"
+ },
+ {
+ "code": "tr",
+ "continent": "Asia",
+ "name": "Türkiye"
+ },
+ {
+ "code": "ug",
+ "continent": "Africa",
+ "name": "Uganda"
+ },
+ {
+ "code": "ua",
+ "continent": "Europe",
+ "name": "Ukraine"
+ },
+ {
+ "code": "ae",
+ "continent": "Asia",
+ "name": "United Arab Emirates"
+ },
+ {
+ "code": "gb",
+ "continent": "Europe",
+ "name": "United Kingdom"
+ },
+ {
+ "code": "un",
+ "name": "United Nations"
+ },
+ {
+ "code": "um",
+ "continent": "North America",
+ "name": "United States Minor Outlying Islands"
+ },
+ {
+ "code": "us",
+ "continent": "North America",
+ "name": "United States of America"
+ },
+ {
+ "code": "uy",
+ "continent": "South America",
+ "name": "Uruguay"
+ },
+ {
+ "code": "uz",
+ "continent": "Asia",
+ "name": "Uzbekistan"
+ },
+ {
+ "code": "vu",
+ "continent": "Oceania",
+ "name": "Vanuatu"
+ },
+ {
+ "code": "ve",
+ "continent": "South America",
+ "name": "Venezuela"
+ },
+ {
+ "code": "vn",
+ "continent": "Asia",
+ "name": "Vietnam"
+ },
+ {
+ "code": "vg",
+ "continent": "North America",
+ "name": "Virgin Islands (British)"
+ },
+ {
+ "code": "vi",
+ "continent": "North America",
+ "name": "Virgin Islands (U.S.)"
+ },
+ {
+ "code": "gb-wls",
+ "continent": "Europe",
+ "name": "Wales"
+ },
+ {
+ "code": "wf",
+ "continent": "Oceania",
+ "name": "Wallis and Futuna"
+ },
+ {
+ "code": "eh",
+ "continent": "Africa",
+ "name": "Western Sahara"
+ },
+ {
+ "code": "ye",
+ "continent": "Asia",
+ "name": "Yemen"
+ },
+ {
+ "code": "zm",
+ "continent": "Africa",
+ "name": "Zambia"
+ },
+ {
+ "code": "zw",
+ "continent": "Africa",
+ "name": "Zimbabwe"
+ }
]
diff --git a/src/client/graphics/GameRenderer.ts b/src/client/graphics/GameRenderer.ts
index 57b5dd0ac..b8e489598 100644
--- a/src/client/graphics/GameRenderer.ts
+++ b/src/client/graphics/GameRenderer.ts
@@ -29,7 +29,7 @@ export function createRenderer(
canvas: HTMLCanvasElement,
game: GameView,
eventBus: EventBus,
- clientID: ClientID
+ clientID: ClientID,
): GameRenderer {
const transformHandler = new TransformHandler(game, eventBus, canvas);
@@ -65,7 +65,7 @@ export function createRenderer(
controlPanel.game = game;
const eventsDisplay = document.querySelector(
- "events-display"
+ "events-display",
) as EventsDisplay;
if (!(eventsDisplay instanceof EventsDisplay)) {
consolex.error("events display not found");
@@ -75,7 +75,7 @@ export function createRenderer(
eventsDisplay.clientID = clientID;
const playerInfo = document.querySelector(
- "player-info-overlay"
+ "player-info-overlay",
) as PlayerInfoOverlay;
if (!(playerInfo instanceof PlayerInfoOverlay)) {
consolex.error("player info overlay not found");
@@ -129,7 +129,7 @@ export function createRenderer(
buildMenu,
uiState,
playerInfo,
- playerPanel
+ playerPanel,
),
new SpawnTimer(game, transformHandler),
leaderboard,
@@ -147,7 +147,7 @@ export function createRenderer(
canvas,
transformHandler,
uiState,
- layers
+ layers,
);
}
@@ -160,7 +160,7 @@ export class GameRenderer {
private canvas: HTMLCanvasElement,
public transformHandler: TransformHandler,
public uiState: UIState,
- private layers: Layer[]
+ private layers: Layer[],
) {
this.context = canvas.getContext("2d");
}
@@ -183,7 +183,7 @@ export class GameRenderer {
this.transformHandler = new TransformHandler(
this.game,
this.eventBus,
- this.canvas
+ this.canvas,
);
requestAnimationFrame(() => this.renderGame());
@@ -229,7 +229,7 @@ export class GameRenderer {
const duration = performance.now() - start;
if (duration > 50) {
console.warn(
- `tick ${this.game.ticks()} took ${duration}ms to render frame`
+ `tick ${this.game.ticks()} took ${duration}ms to render frame`,
);
}
}
diff --git a/src/client/graphics/layers/BuildMenu.ts b/src/client/graphics/layers/BuildMenu.ts
index 8a6e69c2a..765d2def4 100644
--- a/src/client/graphics/layers/BuildMenu.ts
+++ b/src/client/graphics/layers/BuildMenu.ts
@@ -200,7 +200,7 @@ export class BuildMenu extends LitElement {
public onBuildSelected = (item: BuildItemDisplay) => {
this.eventBus.emit(
- new BuildUnitIntentEvent(item.unitType, this.clickedCell)
+ new BuildUnitIntentEvent(item.unitType, this.clickedCell),
);
this.hideMenu();
};
@@ -235,7 +235,7 @@ export class BuildMenu extends LitElement {
? this.game
.unitInfo(item.unitType)
.cost(this.myPlayer)
- : 0
+ : 0,
)}
- `
+ `,
)}
- `
+ `,
)}
`;
diff --git a/src/client/graphics/layers/EmojiTable.ts b/src/client/graphics/layers/EmojiTable.ts
index 89ecd4863..1a7d5978e 100644
--- a/src/client/graphics/layers/EmojiTable.ts
+++ b/src/client/graphics/layers/EmojiTable.ts
@@ -10,7 +10,7 @@ const emojiTable: string[][] = [
["😎", "❤️", "💰", "🤝", "🖕"],
["💥", "🆘", "🕊️", "➡️", "⬅️"],
["↙️", "↖️", "↗️", "⬆️", "↘️"],
- ["⬇️", "❓", "⏳", "☢️", "⚠️"]
+ ["⬇️", "❓", "⏳", "☢️", "⚠️"],
];
@customElement("emoji-table")
@@ -110,10 +110,10 @@ export class EmojiTable extends LitElement {
>
${emoji}
- `
+ `,
)}
- `
+ `,
)}
`;
diff --git a/src/client/graphics/layers/EventsDisplay.ts b/src/client/graphics/layers/EventsDisplay.ts
index b49b22783..c6646edea 100644
--- a/src/client/graphics/layers/EventsDisplay.ts
+++ b/src/client/graphics/layers/EventsDisplay.ts
@@ -150,10 +150,10 @@ export class EventsDisplay extends LitElement implements Layer {
}
const requestor = this.game.playerBySmallID(
- update.requestorID
+ update.requestorID,
) as PlayerView;
const recipient = this.game.playerBySmallID(
- update.recipientID
+ update.recipientID,
) as PlayerView;
this.addEvent({
@@ -164,7 +164,7 @@ export class EventsDisplay extends LitElement implements Layer {
className: "btn",
action: () =>
this.eventBus.emit(
- new SendAllianceReplyIntentEvent(requestor, recipient, true)
+ new SendAllianceReplyIntentEvent(requestor, recipient, true),
),
},
{
@@ -172,7 +172,7 @@ export class EventsDisplay extends LitElement implements Layer {
className: "btn-info",
action: () =>
this.eventBus.emit(
- new SendAllianceReplyIntentEvent(requestor, recipient, false)
+ new SendAllianceReplyIntentEvent(requestor, recipient, false),
),
},
],
@@ -181,7 +181,7 @@ export class EventsDisplay extends LitElement implements Layer {
createdAt: this.game.ticks(),
onDelete: () =>
this.eventBus.emit(
- new SendAllianceReplyIntentEvent(requestor, recipient, false)
+ new SendAllianceReplyIntentEvent(requestor, recipient, false),
),
});
}
@@ -193,7 +193,7 @@ export class EventsDisplay extends LitElement implements Layer {
}
const recipient = this.game.playerBySmallID(
- update.request.recipientID
+ update.request.recipientID,
) as PlayerView;
this.addEvent({
@@ -238,8 +238,8 @@ export class EventsDisplay extends LitElement implements Layer {
update.player1ID === myPlayer.smallID()
? update.player2ID
: update.player2ID === myPlayer.smallID()
- ? update.player1ID
- : null;
+ ? update.player1ID
+ : null;
const other = this.game.playerBySmallID(otherID) as PlayerView;
if (!other || !myPlayer.isAlive() || !other.isAlive()) return;
@@ -275,7 +275,7 @@ export class EventsDisplay extends LitElement implements Layer {
? AllPlayers
: this.game.playerBySmallID(update.emoji.recipientID);
const sender = this.game.playerBySmallID(
- update.emoji.senderID
+ update.emoji.senderID,
) as PlayerView;
if (recipient == myPlayer) {
@@ -333,11 +333,11 @@ export class EventsDisplay extends LitElement implements Layer {
${renderTroops(attack.troops)}
${(
this.game.playerBySmallID(
- attack.attackerID
+ attack.attackerID,
) as PlayerView
)?.name()}
- `
+ `,
)}
@@ -355,7 +355,7 @@ export class EventsDisplay extends LitElement implements Layer {
this.game.playerBySmallID(attack.targetID) as PlayerView
)?.name()}
- `
+ `,
)}
@@ -385,7 +385,7 @@ export class EventsDisplay extends LitElement implements Layer {
(event, index) => html`
|
@@ -410,14 +410,14 @@ export class EventsDisplay extends LitElement implements Layer {
>
${btn.text}
- `
+ `,
)}
`
: ""}
|
- `
+ `,
)}
${this.renderAttacks()}
diff --git a/src/client/graphics/layers/Leaderboard.ts b/src/client/graphics/layers/Leaderboard.ts
index 6a500afcf..4fe61133e 100644
--- a/src/client/graphics/layers/Leaderboard.ts
+++ b/src/client/graphics/layers/Leaderboard.ts
@@ -80,7 +80,7 @@ export class Leaderboard extends LitElement implements Layer {
name: myPlayer.displayName(),
position: place,
score: formatPercentage(
- myPlayer.numTilesOwned() / this.game.numLandTiles()
+ myPlayer.numTilesOwned() / this.game.numLandTiles(),
),
gold: renderNumber(myPlayer.gold()),
isMyPlayer: true,
@@ -205,7 +205,7 @@ export class Leaderboard extends LitElement implements Layer {
${player.score} |
${player.gold} |
- `
+ `,
)}
diff --git a/src/client/graphics/layers/NameLayer.ts b/src/client/graphics/layers/NameLayer.ts
index 542a01390..3a4f78d88 100644
--- a/src/client/graphics/layers/NameLayer.ts
+++ b/src/client/graphics/layers/NameLayer.ts
@@ -26,7 +26,7 @@ class RenderInfo {
public lastRenderCalc: number,
public location: Cell,
public fontSize: number,
- public element: HTMLElement
+ public element: HTMLElement,
) {}
}
@@ -50,7 +50,7 @@ export class NameLayer implements Layer {
private game: GameView,
private theme: Theme,
private transformHandler: TransformHandler,
- private clientID: ClientID
+ private clientID: ClientID,
) {
this.traitorIconImage = new Image();
this.traitorIconImage.src = traitorIcon;
@@ -101,7 +101,13 @@ export class NameLayer implements Layer {
if (!this.seenPlayers.has(player)) {
this.seenPlayers.add(player);
this.renders.push(
- new RenderInfo(player, 0, null, 0, this.createPlayerElement(player))
+ new RenderInfo(
+ player,
+ 0,
+ null,
+ 0,
+ this.createPlayerElement(player),
+ ),
);
}
}
@@ -110,11 +116,11 @@ export class NameLayer implements Layer {
public renderLayer(mainContex: CanvasRenderingContext2D) {
const screenPosOld = this.transformHandler.worldToScreenCoordinates(
- new Cell(0, 0)
+ new Cell(0, 0),
);
const screenPos = new Cell(
screenPosOld.x - window.innerWidth / 2,
- screenPosOld.y - window.innerHeight / 2
+ screenPosOld.y - window.innerHeight / 2,
);
this.container.style.transform = `translate(${screenPos.x}px, ${screenPos.y}px) scale(${this.transformHandler.scale})`;
@@ -131,7 +137,7 @@ export class NameLayer implements Layer {
0,
0,
mainContex.canvas.width,
- mainContex.canvas.height
+ mainContex.canvas.height,
);
}
@@ -205,7 +211,7 @@ export class NameLayer implements Layer {
const oldLocation = render.location;
render.location = new Cell(
render.player.nameLocation().x,
- render.player.nameLocation().y
+ render.player.nameLocation().y,
);
// Calculate base size and scale
@@ -229,10 +235,10 @@ export class NameLayer implements Layer {
// Update text sizes
const nameDiv = render.element.querySelector(
- ".player-name"
+ ".player-name",
) as HTMLDivElement;
const troopsDiv = render.element.querySelector(
- ".player-troops"
+ ".player-troops",
) as HTMLDivElement;
nameDiv.style.fontSize = `${render.fontSize}px`;
troopsDiv.style.fontSize = `${render.fontSize}px`;
@@ -240,7 +246,7 @@ export class NameLayer implements Layer {
// Handle icons
const iconsDiv = render.element.querySelector(
- ".player-icons"
+ ".player-icons",
) as HTMLDivElement;
const iconSize = Math.min(render.fontSize * 1.5, 48);
const myPlayer = this.getPlayer();
@@ -250,7 +256,7 @@ export class NameLayer implements Layer {
if (render.player === this.firstPlace) {
if (!existingCrown) {
iconsDiv.appendChild(
- this.createIconElement(this.crownIconImage.src, iconSize, "crown")
+ this.createIconElement(this.crownIconImage.src, iconSize, "crown"),
);
}
} else if (existingCrown) {
@@ -262,7 +268,11 @@ export class NameLayer implements Layer {
if (render.player.isTraitor()) {
if (!existingTraitor) {
iconsDiv.appendChild(
- this.createIconElement(this.traitorIconImage.src, iconSize, "traitor")
+ this.createIconElement(
+ this.traitorIconImage.src,
+ iconSize,
+ "traitor",
+ ),
);
}
} else if (existingTraitor) {
@@ -277,8 +287,8 @@ export class NameLayer implements Layer {
this.createIconElement(
this.allianceIconImage.src,
iconSize,
- "alliance"
- )
+ "alliance",
+ ),
);
}
} else if (existingAlliance) {
@@ -293,7 +303,7 @@ export class NameLayer implements Layer {
) {
if (!existingTarget) {
iconsDiv.appendChild(
- this.createIconElement(this.targetIconImage.src, iconSize, "target")
+ this.createIconElement(this.targetIconImage.src, iconSize, "target"),
);
}
} else if (existingTarget) {
@@ -307,7 +317,7 @@ export class NameLayer implements Layer {
.filter(
(emoji) =>
emoji.recipientID == AllPlayers ||
- emoji.recipientID == myPlayer?.smallID()
+ emoji.recipientID == myPlayer?.smallID(),
);
if (emojis.length > 0) {
@@ -340,7 +350,7 @@ export class NameLayer implements Layer {
private createIconElement(
src: string,
size: number,
- id: string
+ id: string,
): HTMLImageElement {
const icon = document.createElement("img");
icon.src = src;
diff --git a/src/client/graphics/layers/PlayerInfoOverlay.ts b/src/client/graphics/layers/PlayerInfoOverlay.ts
index 164a9370b..8ba68024f 100644
--- a/src/client/graphics/layers/PlayerInfoOverlay.ts
+++ b/src/client/graphics/layers/PlayerInfoOverlay.ts
@@ -22,7 +22,7 @@ import { renderNumber, renderTroops } from "../../Utils";
function euclideanDistWorld(
coord: { x: number; y: number },
tileRef: TileRef,
- game: GameView
+ game: GameView,
): number {
const x = game.x(tileRef);
const y = game.y(tileRef);
@@ -71,7 +71,7 @@ export class PlayerInfoOverlay extends LitElement implements Layer {
init() {
this.eventBus.on(MouseMoveEvent, (e: MouseMoveEvent) =>
- this.onMouseEvent(e)
+ this.onMouseEvent(e),
);
this._isActive = true;
}
diff --git a/src/client/graphics/layers/PlayerPanel.ts b/src/client/graphics/layers/PlayerPanel.ts
index 4b6433ec0..c34ee53f4 100644
--- a/src/client/graphics/layers/PlayerPanel.ts
+++ b/src/client/graphics/layers/PlayerPanel.ts
@@ -53,7 +53,7 @@ export class PlayerPanel extends LitElement implements Layer {
private handleAllianceClick(
e: Event,
myPlayer: PlayerView,
- other: PlayerView
+ other: PlayerView,
) {
e.stopPropagation();
this.eventBus.emit(new SendAllianceRequestIntentEvent(myPlayer, other));
@@ -63,7 +63,7 @@ export class PlayerPanel extends LitElement implements Layer {
private handleBreakAllianceClick(
e: Event,
myPlayer: PlayerView,
- other: PlayerView
+ other: PlayerView,
) {
e.stopPropagation();
this.eventBus.emit(new SendBreakAllianceIntentEvent(myPlayer, other));
diff --git a/src/client/graphics/layers/RadialMenu.ts b/src/client/graphics/layers/RadialMenu.ts
index 59a4e9507..fc768c354 100644
--- a/src/client/graphics/layers/RadialMenu.ts
+++ b/src/client/graphics/layers/RadialMenu.ts
@@ -99,7 +99,7 @@ export class RadialMenu implements Layer {
private buildMenu: BuildMenu,
private uiState: UIState,
private playerInfoOverlay: PlayerInfoOverlay,
- private playerPanel: PlayerPanel
+ private playerPanel: PlayerPanel,
) {}
init() {
@@ -108,7 +108,7 @@ export class RadialMenu implements Layer {
this.eventBus.on(ShowBuildMenuEvent, (e) => {
const clickedCell = this.transformHandler.screenToWorldCoordinates(
e.x,
- e.y
+ e.y,
);
if (clickedCell == null) {
return;
@@ -144,7 +144,7 @@ export class RadialMenu implements Layer {
.append("g")
.attr(
"transform",
- `translate(${this.menuSize / 2},${this.menuSize / 2})`
+ `translate(${this.menuSize / 2},${this.menuSize / 2})`,
);
const pie = d3
@@ -169,7 +169,7 @@ export class RadialMenu implements Layer {
.append("path")
.attr("d", arc)
.attr("fill", (d) =>
- d.data.disabled ? this.disabledColor : d.data.color
+ d.data.disabled ? this.disabledColor : d.data.color,
)
.attr("stroke", "#ffffff")
.attr("stroke-width", "2")
@@ -294,7 +294,7 @@ export class RadialMenu implements Layer {
this.clickedCell = this.transformHandler.screenToWorldCoordinates(
event.x,
- event.y
+ event.y,
);
if (!this.g.isValidCoord(this.clickedCell.x, this.clickedCell.y)) {
return;
@@ -323,7 +323,7 @@ export class RadialMenu implements Layer {
private handlePlayerActions(
myPlayer: PlayerView,
actions: PlayerActions,
- tile: TileRef
+ tile: TileRef,
) {
this.activateMenuElement(Slot.Build, "#ebe250", buildIcon, () => {
this.buildMenu.showMenu(myPlayer, this.clickedCell);
@@ -341,8 +341,8 @@ export class RadialMenu implements Layer {
new SendBoatAttackIntentEvent(
this.g.owner(tile).id(),
this.clickedCell,
- this.uiState.attackRatio * myPlayer.troops()
- )
+ this.uiState.attackRatio * myPlayer.troops(),
+ ),
);
});
}
@@ -394,8 +394,8 @@ export class RadialMenu implements Layer {
this.eventBus.emit(
new SendAttackIntentEvent(
this.g.owner(clicked).id(),
- this.uiState.attackRatio * myPlayer.troops()
- )
+ this.uiState.attackRatio * myPlayer.troops(),
+ ),
);
}
}
@@ -406,7 +406,7 @@ export class RadialMenu implements Layer {
slot: Slot,
color: string,
icon: string,
- action: () => void
+ action: () => void,
) {
const menuItem = this.menuItems.get(slot);
menuItem.action = action;
diff --git a/src/client/graphics/layers/StructureLayer.ts b/src/client/graphics/layers/StructureLayer.ts
index ff7b1be73..1d6ee47df 100644
--- a/src/client/graphics/layers/StructureLayer.ts
+++ b/src/client/graphics/layers/StructureLayer.ts
@@ -50,7 +50,10 @@ export class StructureLayer implements Layer {
},
};
- constructor(private game: GameView, private eventBus: EventBus) {
+ constructor(
+ private game: GameView,
+ private eventBus: EventBus,
+ ) {
this.theme = game.config().theme();
this.loadIconData();
}
@@ -72,11 +75,11 @@ export class StructureLayer implements Layer {
0,
0,
tempCanvas.width,
- tempCanvas.height
+ tempCanvas.height,
);
this.unitIcons.set(unitType, iconData);
console.log(
- `icond data width height: ${iconData.width}, ${iconData.height}`
+ `icond data width height: ${iconData.width}, ${iconData.height}`,
);
};
});
@@ -89,9 +92,9 @@ export class StructureLayer implements Layer {
tick() {
this.game
.updatesSinceLastTick()
- [GameUpdateType.Unit].forEach((u) =>
- this.handleUnitRendering(this.game.unit(u.id))
- );
+ [
+ GameUpdateType.Unit
+ ].forEach((u) => this.handleUnitRendering(this.game.unit(u.id)));
}
init() {
@@ -113,7 +116,7 @@ export class StructureLayer implements Layer {
-this.game.width() / 2,
-this.game.height() / 2,
this.game.width(),
- this.game.height()
+ this.game.height(),
);
}
@@ -133,7 +136,7 @@ export class StructureLayer implements Layer {
// Clear previous rendering
for (const tile of this.game.bfs(
unit.tile(),
- euclDistFN(unit.tile(), config.borderRadius)
+ euclDistFN(unit.tile(), config.borderRadius),
)) {
this.clearCell(new Cell(this.game.x(tile), this.game.y(tile)));
}
@@ -145,27 +148,27 @@ export class StructureLayer implements Layer {
// Draw border and territory
for (const tile of this.game.bfs(
unit.tile(),
- euclDistFN(unit.tile(), config.borderRadius)
+ euclDistFN(unit.tile(), config.borderRadius),
)) {
this.paintCell(
new Cell(this.game.x(tile), this.game.y(tile)),
unit.type() == UnitType.Construction
? underConstructionColor
: this.theme.borderColor(unit.owner().info()),
- 255
+ 255,
);
}
for (const tile of this.game.bfs(
unit.tile(),
- euclDistFN(unit.tile(), config.territoryRadius)
+ euclDistFN(unit.tile(), config.territoryRadius),
)) {
this.paintCell(
new Cell(this.game.x(tile), this.game.y(tile)),
unit.type() == UnitType.Construction
? underConstructionColor
: this.theme.territoryColor(unit.owner().info()),
- 130
+ 130,
);
}
@@ -181,7 +184,7 @@ export class StructureLayer implements Layer {
startY: number,
width: number,
height: number,
- unit: UnitView
+ unit: UnitView,
) {
let color = this.theme.borderColor(unit.owner().info());
if (unit.type() == UnitType.Construction) {
diff --git a/src/client/graphics/layers/TerritoryLayer.ts b/src/client/graphics/layers/TerritoryLayer.ts
index d22698b64..68eea6138 100644
--- a/src/client/graphics/layers/TerritoryLayer.ts
+++ b/src/client/graphics/layers/TerritoryLayer.ts
@@ -50,7 +50,10 @@ export class TerritoryLayer implements Layer {
private refreshRate = 50;
private lastRefresh = 0;
- constructor(private game: GameView, private eventBus: EventBus) {
+ constructor(
+ private game: GameView,
+ private eventBus: EventBus,
+ ) {
this.theme = game.config().theme();
}
@@ -67,7 +70,7 @@ export class TerritoryLayer implements Layer {
this.game
.bfs(
tile,
- manhattanDistFN(tile, this.game.config().defensePostRange())
+ manhattanDistFN(tile, this.game.config().defensePostRange()),
)
.forEach((t) => {
if (
@@ -91,7 +94,7 @@ export class TerritoryLayer implements Layer {
0,
0,
this.game.width(),
- this.game.height()
+ this.game.height(),
);
const humans = this.game
.playerViews()
@@ -111,7 +114,7 @@ export class TerritoryLayer implements Layer {
this.paintHighlightCell(
new Cell(this.game.x(tile), this.game.y(tile)),
this.theme.spawnHighlightColor(),
- 255
+ 255,
);
}
}
@@ -138,7 +141,7 @@ export class TerritoryLayer implements Layer {
0,
0,
this.game.width(),
- this.game.height()
+ this.game.height(),
);
this.initImageData();
this.canvas.width = this.game.width();
@@ -185,7 +188,7 @@ export class TerritoryLayer implements Layer {
-this.game.width() / 2,
-this.game.height() / 2,
this.game.width(),
- this.game.height()
+ this.game.height(),
);
if (this.game.inSpawnPhase()) {
context.drawImage(
@@ -193,7 +196,7 @@ export class TerritoryLayer implements Layer {
-this.game.width() / 2,
-this.game.height() / 2,
this.game.width(),
- this.game.height()
+ this.game.height(),
);
}
}
@@ -224,7 +227,7 @@ export class TerritoryLayer implements Layer {
this.game.x(tile),
this.game.y(tile),
this.theme.falloutColor(),
- 150
+ 150,
);
return;
}
@@ -241,14 +244,14 @@ export class TerritoryLayer implements Layer {
this.game.x(tile),
this.game.y(tile),
this.theme.defendedBorderColor(owner.info()),
- 255
+ 255,
);
} else {
this.paintCell(
this.game.x(tile),
this.game.y(tile),
this.theme.borderColor(owner.info()),
- 255
+ 255,
);
}
} else {
@@ -256,7 +259,7 @@ export class TerritoryLayer implements Layer {
this.game.x(tile),
this.game.y(tile),
this.theme.territoryColor(owner.info()),
- 150
+ 150,
);
}
}
diff --git a/src/client/graphics/layers/UnitLayer.ts b/src/client/graphics/layers/UnitLayer.ts
index b6eef957d..3373edb61 100644
--- a/src/client/graphics/layers/UnitLayer.ts
+++ b/src/client/graphics/layers/UnitLayer.ts
@@ -36,7 +36,7 @@ export class UnitLayer implements Layer {
constructor(
private game: GameView,
private eventBus: EventBus,
- private clientID: ClientID
+ private clientID: ClientID,
) {
this.theme = game.config().theme();
}
@@ -65,7 +65,7 @@ export class UnitLayer implements Layer {
-this.game.width() / 2,
-this.game.height() / 2,
this.game.width(),
- this.game.height()
+ this.game.height(),
);
}
@@ -131,7 +131,7 @@ export class UnitLayer implements Layer {
// Clear previous area
for (const t of this.game.bfs(
unit.lastTile(),
- euclDistFN(unit.lastTile(), 6)
+ euclDistFN(unit.lastTile(), 6),
)) {
this.clearCell(this.game.x(t), this.game.y(t));
}
@@ -147,21 +147,21 @@ export class UnitLayer implements Layer {
this.game.y(t),
rel,
this.theme.territoryColor(unit.owner().info()),
- 255
+ 255,
);
}
// Paint border
for (const t of this.game.bfs(
unit.tile(),
- manhattanDistFN(unit.tile(), 4)
+ manhattanDistFN(unit.tile(), 4),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.borderColor(unit.owner().info()),
- 255
+ 255,
);
}
@@ -172,7 +172,7 @@ export class UnitLayer implements Layer {
this.game.y(t),
rel,
this.theme.territoryColor(unit.owner().info()),
- 255
+ 255,
);
}
}
@@ -198,14 +198,14 @@ export class UnitLayer implements Layer {
this.game.y(unit.tile()),
rel,
this.theme.borderColor(unit.owner().info()),
- 255
+ 255,
);
this.paintCell(
this.game.x(unit.lastTile()),
this.game.y(unit.lastTile()),
rel,
this.theme.borderColor(unit.owner().info()),
- 255
+ 255,
);
}
@@ -215,7 +215,7 @@ export class UnitLayer implements Layer {
// Clear previous area
for (const t of this.game.bfs(
unit.lastTile(),
- euclDistFN(unit.lastTile(), 2)
+ euclDistFN(unit.lastTile(), 2),
)) {
this.clearCell(this.game.x(t), this.game.y(t));
}
@@ -228,7 +228,7 @@ export class UnitLayer implements Layer {
this.game.y(t),
rel,
this.theme.borderColor(unit.owner().info()),
- 255
+ 255,
);
}
}
@@ -246,7 +246,7 @@ export class UnitLayer implements Layer {
this.game.y(unit.tile()),
rel,
this.theme.borderColor(unit.owner().info()),
- 255
+ 255,
);
}
}
@@ -257,7 +257,7 @@ export class UnitLayer implements Layer {
// Clear previous area
for (const t of this.game.bfs(
unit.lastTile(),
- euclDistFN(unit.lastTile(), 3)
+ euclDistFN(unit.lastTile(), 3),
)) {
this.clearCell(this.game.x(t), this.game.y(t));
}
@@ -266,28 +266,28 @@ export class UnitLayer implements Layer {
// Paint territory
for (const t of this.game.bfs(
unit.tile(),
- manhattanDistFN(unit.tile(), 2)
+ manhattanDistFN(unit.tile(), 2),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.territoryColor(unit.owner().info()),
- 255
+ 255,
);
}
// Paint border
for (const t of this.game.bfs(
unit.tile(),
- manhattanDistFN(unit.tile(), 1)
+ manhattanDistFN(unit.tile(), 1),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.borderColor(unit.owner().info()),
- 255
+ 255,
);
}
}
@@ -305,7 +305,7 @@ export class UnitLayer implements Layer {
// Clear previous area
for (const t of this.game.bfs(
unit.lastTile(),
- manhattanDistFN(unit.lastTile(), 3)
+ manhattanDistFN(unit.lastTile(), 3),
)) {
this.clearCell(this.game.x(t), this.game.y(t));
}
@@ -318,35 +318,35 @@ export class UnitLayer implements Layer {
this.game.y(t),
rel,
this.theme.territoryColor(unit.owner().info()),
- 150
+ 150,
);
}
// Paint border
for (const t of this.game.bfs(
unit.tile(),
- manhattanDistFN(unit.tile(), 2)
+ manhattanDistFN(unit.tile(), 2),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.borderColor(unit.owner().info()),
- 255
+ 255,
);
}
// Paint territory
for (const t of this.game.bfs(
unit.tile(),
- manhattanDistFN(unit.tile(), 1)
+ manhattanDistFN(unit.tile(), 1),
)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.territoryColor(unit.owner().info()),
- 255
+ 255,
);
}
} else {
@@ -362,7 +362,7 @@ export class UnitLayer implements Layer {
y: number,
relationship: Relationship,
color: Colord,
- alpha: number
+ alpha: number,
) {
this.clearCell(x, y);
if (this.alternateView) {
diff --git a/src/core/GameRunner.ts b/src/core/GameRunner.ts
index 38bbaa244..8a95ee462 100644
--- a/src/core/GameRunner.ts
+++ b/src/core/GameRunner.ts
@@ -29,7 +29,7 @@ export async function createGameRunner(
gameID: string,
gameConfig: GameConfig,
clientID: ClientID,
- callBack: (gu: GameUpdateViewData) => void
+ callBack: (gu: GameUpdateViewData) => void,
): Promise {
const config = getConfig(gameConfig);
const gameMap = await loadGameMap(gameConfig.gameMap);
@@ -37,9 +37,13 @@ export async function createGameRunner(
gameMap.gameMap,
gameMap.miniGameMap,
gameMap.nationMap,
- config
+ config,
+ );
+ const gr = new GameRunner(
+ game as Game,
+ new Executor(game, gameID, clientID),
+ callBack,
);
- const gr = new GameRunner(game as Game, new Executor(game, gameID, clientID), callBack);
gr.init();
return gr;
}
@@ -54,13 +58,13 @@ export class GameRunner {
constructor(
public game: Game,
private execManager: Executor,
- private callBack: (gu: GameUpdateViewData | ErrorUpdate) => void
+ private callBack: (gu: GameUpdateViewData | ErrorUpdate) => void,
) {}
init() {
if (this.game.config().spawnBots()) {
this.game.addExecution(
- ...this.execManager.spawnBots(this.game.config().numBots())
+ ...this.execManager.spawnBots(this.game.config().numBots()),
);
}
if (this.game.config().spawnNPCs()) {
@@ -83,7 +87,7 @@ export class GameRunner {
this.isExecuting = true;
this.game.addExecution(
- ...this.execManager.createExecs(this.turns[this.currTurn])
+ ...this.execManager.createExecs(this.turns[this.currTurn]),
);
this.currTurn++;
@@ -107,10 +111,10 @@ export class GameRunner {
.players()
.filter(
(p) =>
- p.type() == PlayerType.Human || p.type() == PlayerType.FakeHuman
+ p.type() == PlayerType.Human || p.type() == PlayerType.FakeHuman,
)
.forEach(
- (p) => (this.playerViewData[p.id()] = placeName(this.game, p))
+ (p) => (this.playerViewData[p.id()] = placeName(this.game, p)),
);
}
@@ -136,7 +140,7 @@ export class GameRunner {
public playerActions(
playerID: PlayerID,
x: number,
- y: number
+ y: number,
): PlayerActions {
const player = this.game.player(playerID);
const tile = this.game.ref(x, y);
@@ -144,7 +148,7 @@ export class GameRunner {
canBoat: player.canBoat(tile),
canAttack: player.canAttack(tile),
buildableUnits: Object.values(UnitType).filter(
- (ut) => player.canBuild(ut, tile) != false
+ (ut) => player.canBuild(ut, tile) != false,
),
canSendEmojiAllPlayers: player.canSendEmoji(AllPlayers),
} as PlayerActions;
diff --git a/src/core/Schemas.ts b/src/core/Schemas.ts
index 9bfae45f5..6ebcc2d7d 100644
--- a/src/core/Schemas.ts
+++ b/src/core/Schemas.ts
@@ -101,7 +101,9 @@ const SafeString = z
.string()
// Remove common dangerous characters and patterns
// The weird \u stuff is to allow emojis
- .regex(/^[a-zA-Z0-9\s.,!?@#$%&*()-_+=\[\]{}|;:"'\/\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff]]+$/)
+ .regex(
+ /^[a-zA-Z0-9\s.,!?@#$%&*()-_+=\[\]{}|;:"'\/\u00a9|\u00ae|[\u2000-\u3300]|\ud83c[\ud000-\udfff]|\ud83d[\ud000-\udfff]|\ud83e[\ud000-\udfff]]+$/,
+ )
// Reasonable max length to prevent DOS
.max(1000);
@@ -111,7 +113,7 @@ const EmojiSchema = z.string().refine(
},
{
message: "Must contain at least one emoji character",
- }
+ },
);
const ID = z
.string()
@@ -324,5 +326,3 @@ export const GameRecordSchema = z.object({
turns: z.array(TurnSchema),
winner: ID.nullable(),
});
-
-
diff --git a/src/core/Util.ts b/src/core/Util.ts
index a31bdb7f5..5fbd32554 100644
--- a/src/core/Util.ts
+++ b/src/core/Util.ts
@@ -16,7 +16,7 @@ import { andFN, GameMap, manhattanDistFN, TileRef } from "./game/GameMap";
export function manhattanDistWrapped(
c1: Cell,
c2: Cell,
- width: number
+ width: number,
): number {
// Calculate x distance
let dx = Math.abs(c1.x - c2.x);
@@ -36,7 +36,7 @@ export function within(value: number, min: number, max: number): number {
export function distSort(
gm: GameMap,
- target: TileRef
+ target: TileRef,
): (a: TileRef, b: TileRef) => number {
return (a: TileRef, b: TileRef) => {
return gm.manhattanDist(a, target) - gm.manhattanDist(b, target);
@@ -45,7 +45,7 @@ export function distSort(
export function distSortUnit(
gm: GameMap,
- target: Unit | TileRef
+ target: Unit | TileRef,
): (a: Unit, b: Unit) => number {
const targetRef = typeof target === "number" ? target : target.tile();
@@ -61,7 +61,7 @@ export function distSortUnit(
export function sourceDstOceanShore(
gm: Game,
src: Player,
- tile: TileRef
+ tile: TileRef,
): [TileRef | null, TileRef | null] {
const dst = gm.owner(tile);
let srcTile = closestOceanShoreFromPlayer(gm, src, tile);
@@ -88,10 +88,10 @@ export function targetTransportTile(gm: Game, tile: TileRef): TileRef | null {
export function closestOceanShoreFromPlayer(
gm: GameMap,
player: Player,
- target: TileRef
+ target: TileRef,
): TileRef | null {
const shoreTiles = Array.from(player.borderTiles()).filter((t) =>
- gm.isOceanShore(t)
+ gm.isOceanShore(t),
);
if (shoreTiles.length == 0) {
return null;
@@ -101,12 +101,12 @@ export function closestOceanShoreFromPlayer(
const closestDistance = manhattanDistWrapped(
gm.cell(target),
gm.cell(closest),
- gm.width()
+ gm.width(),
);
const currentDistance = manhattanDistWrapped(
gm.cell(target),
gm.cell(current),
- gm.width()
+ gm.width(),
);
return currentDistance < closestDistance ? current : closest;
});
@@ -115,13 +115,13 @@ export function closestOceanShoreFromPlayer(
function closestOceanShoreTN(
gm: GameMap,
tile: TileRef,
- searchDist: number
+ searchDist: number,
): TileRef {
const tn = Array.from(
gm.bfs(
tile,
- andFN((_, t) => !gm.hasOwner(t), manhattanDistFN(tile, searchDist))
- )
+ andFN((_, t) => !gm.hasOwner(t), manhattanDistFN(tile, searchDist)),
+ ),
)
.filter((t) => gm.isOceanShore(t))
.sort((a, b) => gm.manhattanDist(tile, a) - gm.manhattanDist(tile, b));
@@ -143,7 +143,7 @@ export function simpleHash(str: string): number {
export function calculateBoundingBox(
gm: GameMap,
- borderTiles: ReadonlySet
+ borderTiles: ReadonlySet,
): { min: Cell; max: Cell } {
let minX = Infinity,
minY = Infinity,
@@ -163,18 +163,18 @@ export function calculateBoundingBox(
export function calculateBoundingBoxCenter(
gm: GameMap,
- borderTiles: ReadonlySet
+ borderTiles: ReadonlySet,
): Cell {
const { min, max } = calculateBoundingBox(gm, borderTiles);
return new Cell(
min.x + Math.floor((max.x - min.x) / 2),
- min.y + Math.floor((max.y - min.y) / 2)
+ min.y + Math.floor((max.y - min.y) / 2),
);
}
export function inscribed(
outer: { min: Cell; max: Cell },
- inner: { min: Cell; max: Cell }
+ inner: { min: Cell; max: Cell },
): boolean {
return (
outer.min.x <= inner.min.x &&
@@ -238,7 +238,7 @@ export function processName(name: string): string {
// Add CSS for the emoji images
const withEmojiStyles = styledHTML.replace(
/
0,
- territoryBound: false,
- };
- case UnitType.Warship:
- return {
- cost: (p: Player) =>
- p.type() == PlayerType.Human && this.creativeMode()
- ? 0
- : (p.units(UnitType.Warship).length + 1) * 250_000,
- territoryBound: false,
- maxHealth: 1000,
- };
- case UnitType.Shell:
- return {
- cost: () => 0,
- territoryBound: false,
- damage: 250,
- };
- case UnitType.Port:
- return {
- cost: (p: Player) =>
- p.type() == PlayerType.Human && this.creativeMode()
- ? 0
- : Math.min(
- 1_000_000,
- Math.pow(2, p.units(UnitType.Port).length) *
- 250_000
- ),
- territoryBound: true,
- constructionDuration: this.creativeMode() ? 0 : 2 * 10,
- };
- case UnitType.AtomBomb:
- return {
- cost: (p: Player) =>
- p.type() == PlayerType.Human && this.creativeMode()
- ? 0
- : 750_000,
- territoryBound: false,
- };
- case UnitType.HydrogenBomb:
- return {
- cost: (p: Player) =>
- p.type() == PlayerType.Human && this.creativeMode()
- ? 0
- : 5_000_000,
- territoryBound: false,
- };
- case UnitType.MIRV:
- return {
- cost: (p: Player) =>
- p.type() == PlayerType.Human && this.creativeMode()
- ? 0
- : 10_000_000,
- territoryBound: false,
- };
- case UnitType.MIRVWarhead:
- return {
- cost: () => 0,
- territoryBound: false,
- };
- case UnitType.TradeShip:
- return {
- cost: () => 0,
- territoryBound: false,
- };
- case UnitType.MissileSilo:
- return {
- cost: (p: Player) =>
- p.type() == PlayerType.Human && this.creativeMode()
- ? 0
- : 1_000_000,
- territoryBound: true,
- constructionDuration: this.creativeMode() ? 0 : 10 * 10,
- };
- case UnitType.DefensePost:
- return {
- cost: (p: Player) =>
- p.type() == PlayerType.Human && this.creativeMode()
- ? 0
- : Math.min(
- 250_000,
- (p.units(UnitType.DefensePost).length + 1) *
- 50_000
- ),
- territoryBound: true,
- constructionDuration: this.creativeMode() ? 0 : 5 * 10,
- };
- case UnitType.City:
- return {
- cost: (p: Player) =>
- p.type() == PlayerType.Human && this.creativeMode()
- ? 0
- : Math.min(
- 1_000_000,
- Math.pow(2, p.units(UnitType.City).length) *
- 125_000
- ),
- territoryBound: true,
- constructionDuration: this.creativeMode() ? 0 : 2 * 10,
- };
- case UnitType.Construction:
- return {
- cost: () => 0,
- territoryBound: true,
- };
- default:
- assertNever(type);
- }
- }
- defaultDonationAmount(sender: Player): number {
- return Math.floor(sender.troops() / 3);
- }
- donateCooldown(): Tick {
- return 10 * 10;
- }
- emojiMessageDuration(): Tick {
- return 5 * 10;
- }
- emojiMessageCooldown(): Tick {
- return 15 * 10;
- }
- targetDuration(): Tick {
- return 10 * 10;
- }
- targetCooldown(): Tick {
- return 15 * 10;
- }
- allianceRequestCooldown(): Tick {
- return 30 * 10;
- }
- allianceDuration(): Tick {
- return 600 * 10;
- }
- percentageTilesOwnedToWin(): number {
- return 80;
- }
- boatMaxNumber(): number {
- return 3;
- }
- boatMaxDistance(): number {
- return 500;
- }
- numSpawnPhaseTurns(): number {
- return this._gameConfig.gameType == GameType.Singleplayer ? 100 : 300;
- }
- numBots(): number {
- return 400;
- }
- theme(): Theme {
- return pastelTheme;
- }
+ unitInfo(type: UnitType): UnitInfo {
+ switch (type) {
+ case UnitType.TransportShip:
+ return {
+ cost: () => 0,
+ territoryBound: false,
+ };
+ case UnitType.Warship:
+ return {
+ cost: (p: Player) =>
+ p.type() == PlayerType.Human && this.creativeMode()
+ ? 0
+ : (p.units(UnitType.Warship).length + 1) * 250_000,
+ territoryBound: false,
+ maxHealth: 1000,
+ };
+ case UnitType.Shell:
+ return {
+ cost: () => 0,
+ territoryBound: false,
+ damage: 250,
+ };
+ case UnitType.Port:
+ return {
+ cost: (p: Player) =>
+ p.type() == PlayerType.Human && this.creativeMode()
+ ? 0
+ : Math.min(
+ 1_000_000,
+ Math.pow(2, p.units(UnitType.Port).length) * 250_000,
+ ),
+ territoryBound: true,
+ constructionDuration: this.creativeMode() ? 0 : 2 * 10,
+ };
+ case UnitType.AtomBomb:
+ return {
+ cost: (p: Player) =>
+ p.type() == PlayerType.Human && this.creativeMode() ? 0 : 750_000,
+ territoryBound: false,
+ };
+ case UnitType.HydrogenBomb:
+ return {
+ cost: (p: Player) =>
+ p.type() == PlayerType.Human && this.creativeMode() ? 0 : 5_000_000,
+ territoryBound: false,
+ };
+ case UnitType.MIRV:
+ return {
+ cost: (p: Player) =>
+ p.type() == PlayerType.Human && this.creativeMode()
+ ? 0
+ : 10_000_000,
+ territoryBound: false,
+ };
+ case UnitType.MIRVWarhead:
+ return {
+ cost: () => 0,
+ territoryBound: false,
+ };
+ case UnitType.TradeShip:
+ return {
+ cost: () => 0,
+ territoryBound: false,
+ };
+ case UnitType.MissileSilo:
+ return {
+ cost: (p: Player) =>
+ p.type() == PlayerType.Human && this.creativeMode() ? 0 : 1_000_000,
+ territoryBound: true,
+ constructionDuration: this.creativeMode() ? 0 : 10 * 10,
+ };
+ case UnitType.DefensePost:
+ return {
+ cost: (p: Player) =>
+ p.type() == PlayerType.Human && this.creativeMode()
+ ? 0
+ : Math.min(
+ 250_000,
+ (p.units(UnitType.DefensePost).length + 1) * 50_000,
+ ),
+ territoryBound: true,
+ constructionDuration: this.creativeMode() ? 0 : 5 * 10,
+ };
+ case UnitType.City:
+ return {
+ cost: (p: Player) =>
+ p.type() == PlayerType.Human && this.creativeMode()
+ ? 0
+ : Math.min(
+ 1_000_000,
+ Math.pow(2, p.units(UnitType.City).length) * 125_000,
+ ),
+ territoryBound: true,
+ constructionDuration: this.creativeMode() ? 0 : 2 * 10,
+ };
+ case UnitType.Construction:
+ return {
+ cost: () => 0,
+ territoryBound: true,
+ };
+ default:
+ assertNever(type);
+ }
+ }
+ defaultDonationAmount(sender: Player): number {
+ return Math.floor(sender.troops() / 3);
+ }
+ donateCooldown(): Tick {
+ return 10 * 10;
+ }
+ emojiMessageDuration(): Tick {
+ return 5 * 10;
+ }
+ emojiMessageCooldown(): Tick {
+ return 15 * 10;
+ }
+ targetDuration(): Tick {
+ return 10 * 10;
+ }
+ targetCooldown(): Tick {
+ return 15 * 10;
+ }
+ allianceRequestCooldown(): Tick {
+ return 30 * 10;
+ }
+ allianceDuration(): Tick {
+ return 600 * 10;
+ }
+ percentageTilesOwnedToWin(): number {
+ return 80;
+ }
+ boatMaxNumber(): number {
+ return 3;
+ }
+ boatMaxDistance(): number {
+ return 500;
+ }
+ numSpawnPhaseTurns(): number {
+ return this._gameConfig.gameType == GameType.Singleplayer ? 100 : 300;
+ }
+ numBots(): number {
+ return 400;
+ }
+ theme(): Theme {
+ return pastelTheme;
+ }
- attackLogic(
- gm: Game,
- attackTroops: number,
- attacker: Player,
- defender: Player | TerraNullius,
- tileToConquer: TileRef
- ): {
- attackerTroopLoss: number;
- defenderTroopLoss: number;
- tilesPerTickUsed: number;
- } {
- let mag = 0;
- let speed = 0;
- const type = gm.terrainType(tileToConquer);
- switch (type) {
- case TerrainType.Plains:
- mag = 80;
- speed = 15;
- break;
- case TerrainType.Highland:
- mag = 100;
- speed = 20;
- break;
- case TerrainType.Mountain:
- mag = 120;
- speed = 25;
- break;
- default:
- throw new Error(`terrain type ${type} not supported`);
- }
- if (defender.isPlayer()) {
- for (const dp of gm.nearbyDefensePosts(tileToConquer)) {
- if (dp.owner() == defender) {
- mag *= this.defensePostDefenseBonus();
- speed *= this.defensePostDefenseBonus();
- break;
- }
- }
- }
+ attackLogic(
+ gm: Game,
+ attackTroops: number,
+ attacker: Player,
+ defender: Player | TerraNullius,
+ tileToConquer: TileRef,
+ ): {
+ attackerTroopLoss: number;
+ defenderTroopLoss: number;
+ tilesPerTickUsed: number;
+ } {
+ let mag = 0;
+ let speed = 0;
+ const type = gm.terrainType(tileToConquer);
+ switch (type) {
+ case TerrainType.Plains:
+ mag = 80;
+ speed = 15;
+ break;
+ case TerrainType.Highland:
+ mag = 100;
+ speed = 20;
+ break;
+ case TerrainType.Mountain:
+ mag = 120;
+ speed = 25;
+ break;
+ default:
+ throw new Error(`terrain type ${type} not supported`);
+ }
+ if (defender.isPlayer()) {
+ for (const dp of gm.nearbyDefensePosts(tileToConquer)) {
+ if (dp.owner() == defender) {
+ mag *= this.defensePostDefenseBonus();
+ speed *= this.defensePostDefenseBonus();
+ break;
+ }
+ }
+ }
- if (gm.hasFallout(tileToConquer)) {
- mag *= this.falloutDefenseModifier();
- speed *= this.falloutDefenseModifier();
- }
+ if (gm.hasFallout(tileToConquer)) {
+ mag *= this.falloutDefenseModifier();
+ speed *= this.falloutDefenseModifier();
+ }
- if (attacker.isPlayer() && defender.isPlayer()) {
- if (
- attacker.type() == PlayerType.Human &&
- defender.type() == PlayerType.Bot
- ) {
- mag *= 0.8;
- }
- if (
- attacker.type() == PlayerType.FakeHuman &&
- defender.type() == PlayerType.Bot
- ) {
- mag *= 0.8;
- }
- }
+ if (attacker.isPlayer() && defender.isPlayer()) {
+ if (
+ attacker.type() == PlayerType.Human &&
+ defender.type() == PlayerType.Bot
+ ) {
+ mag *= 0.8;
+ }
+ if (
+ attacker.type() == PlayerType.FakeHuman &&
+ defender.type() == PlayerType.Bot
+ ) {
+ mag *= 0.8;
+ }
+ }
- if (defender.isPlayer()) {
- return {
- attackerTroopLoss:
- within(defender.troops() / (2.5 * attackTroops), 0.1, 10) *
- mag,
- defenderTroopLoss: defender.troops() / defender.numTilesOwned(),
- tilesPerTickUsed:
- within(defender.troops() / (5 * attackTroops), 0.2, 1.5) *
- speed,
- };
- } else {
- return {
- attackerTroopLoss:
- attacker.type() == PlayerType.Bot ? mag / 10 : mag / 5,
- defenderTroopLoss: 0,
- tilesPerTickUsed: within(
- (2000 * Math.max(10, speed)) / attackTroops,
- 5,
- 100
- ),
- };
- }
- }
+ if (defender.isPlayer()) {
+ return {
+ attackerTroopLoss:
+ within(defender.troops() / (2.5 * attackTroops), 0.1, 10) * mag,
+ defenderTroopLoss: defender.troops() / defender.numTilesOwned(),
+ tilesPerTickUsed:
+ within(defender.troops() / (5 * attackTroops), 0.2, 1.5) * speed,
+ };
+ } else {
+ return {
+ attackerTroopLoss:
+ attacker.type() == PlayerType.Bot ? mag / 10 : mag / 5,
+ defenderTroopLoss: 0,
+ tilesPerTickUsed: within(
+ (2000 * Math.max(10, speed)) / attackTroops,
+ 5,
+ 100,
+ ),
+ };
+ }
+ }
- attackTilesPerTick(
- attackTroops: number,
- attacker: Player,
- defender: Player | TerraNullius,
- numAdjacentTilesWithEnemy: number
- ): number {
- if (defender.isPlayer()) {
- return (
- within(
- ((5 * attackTroops) / defender.troops()) * 2,
- 0.01,
- 0.5
- ) *
- numAdjacentTilesWithEnemy *
- 3
- );
- } else {
- return numAdjacentTilesWithEnemy * 2;
- }
- }
+ attackTilesPerTick(
+ attackTroops: number,
+ attacker: Player,
+ defender: Player | TerraNullius,
+ numAdjacentTilesWithEnemy: number,
+ ): number {
+ if (defender.isPlayer()) {
+ return (
+ within(((5 * attackTroops) / defender.troops()) * 2, 0.01, 0.5) *
+ numAdjacentTilesWithEnemy *
+ 3
+ );
+ } else {
+ return numAdjacentTilesWithEnemy * 2;
+ }
+ }
- boatAttackAmount(
- attacker: Player,
- defender: Player | TerraNullius
- ): number {
- return Math.floor(attacker.troops() / 5);
- }
+ boatAttackAmount(attacker: Player, defender: Player | TerraNullius): number {
+ return Math.floor(attacker.troops() / 5);
+ }
- attackAmount(attacker: Player, defender: Player | TerraNullius) {
- if (attacker.type() == PlayerType.Bot) {
- return attacker.troops() / 20;
- } else {
- return attacker.troops() / 5;
- }
- }
+ attackAmount(attacker: Player, defender: Player | TerraNullius) {
+ if (attacker.type() == PlayerType.Bot) {
+ return attacker.troops() / 20;
+ } else {
+ return attacker.troops() / 5;
+ }
+ }
- startManpower(playerInfo: PlayerInfo): number {
- if (playerInfo.playerType == PlayerType.Bot) {
- return 10_000;
- }
- if (playerInfo.playerType == PlayerType.FakeHuman) {
- switch (this._gameConfig.difficulty) {
- case Difficulty.Easy:
- return 2_500 * (playerInfo?.nation?.strength ?? 1);
- case Difficulty.Medium:
- return 5_000 * (playerInfo?.nation?.strength ?? 1);
- case Difficulty.Hard:
- return 15_000 * (playerInfo?.nation?.strength ?? 1);
- case Difficulty.Impossible:
- return 20_000 * (playerInfo?.nation?.strength ?? 1);
- }
- }
- return this.creativeMode() ? 1_000_000 : 25_000;
- }
+ startManpower(playerInfo: PlayerInfo): number {
+ if (playerInfo.playerType == PlayerType.Bot) {
+ return 10_000;
+ }
+ if (playerInfo.playerType == PlayerType.FakeHuman) {
+ switch (this._gameConfig.difficulty) {
+ case Difficulty.Easy:
+ return 2_500 * (playerInfo?.nation?.strength ?? 1);
+ case Difficulty.Medium:
+ return 5_000 * (playerInfo?.nation?.strength ?? 1);
+ case Difficulty.Hard:
+ return 15_000 * (playerInfo?.nation?.strength ?? 1);
+ case Difficulty.Impossible:
+ return 20_000 * (playerInfo?.nation?.strength ?? 1);
+ }
+ }
+ return this.creativeMode() ? 1_000_000 : 25_000;
+ }
- maxPopulation(player: Player | PlayerView): number {
- let maxPop =
- player.type() == PlayerType.Human && this.creativeMode()
- ? 999_999_999_999
- : 2 * (Math.pow(player.numTilesOwned(), 0.6) * 1000 + 50000) +
- player.units(UnitType.City).length *
- this.cityPopulationIncrease();
+ maxPopulation(player: Player | PlayerView): number {
+ let maxPop =
+ player.type() == PlayerType.Human && this.creativeMode()
+ ? 999_999_999_999
+ : 2 * (Math.pow(player.numTilesOwned(), 0.6) * 1000 + 50000) +
+ player.units(UnitType.City).length * this.cityPopulationIncrease();
- if (player.type() == PlayerType.Bot) {
- return maxPop / 2;
- }
+ if (player.type() == PlayerType.Bot) {
+ return maxPop / 2;
+ }
- if (player.type() == PlayerType.Human) {
- return maxPop;
- }
+ if (player.type() == PlayerType.Human) {
+ return maxPop;
+ }
- switch (this._gameConfig.difficulty) {
- case Difficulty.Easy:
- return maxPop * 0.5;
- case Difficulty.Medium:
- return maxPop * 0.7;
- case Difficulty.Hard:
- return maxPop * 1;
- case Difficulty.Impossible:
- return maxPop * 1.5;
- }
- }
+ switch (this._gameConfig.difficulty) {
+ case Difficulty.Easy:
+ return maxPop * 0.5;
+ case Difficulty.Medium:
+ return maxPop * 0.7;
+ case Difficulty.Hard:
+ return maxPop * 1;
+ case Difficulty.Impossible:
+ return maxPop * 1.5;
+ }
+ }
- populationIncreaseRate(player: Player): number {
- let max = this.maxPopulation(player);
+ populationIncreaseRate(player: Player): number {
+ let max = this.maxPopulation(player);
- let toAdd = 10 + Math.pow(player.population(), 0.73) / 4;
+ let toAdd = 10 + Math.pow(player.population(), 0.73) / 4;
- const ratio = 1 - player.population() / max;
- toAdd *= ratio;
+ const ratio = 1 - player.population() / max;
+ toAdd *= ratio;
- if (player.type() == PlayerType.Bot) {
- toAdd *= 0.7;
- }
+ if (player.type() == PlayerType.Bot) {
+ toAdd *= 0.7;
+ }
- return Math.min(player.population() + toAdd, max) - player.population();
- }
+ return Math.min(player.population() + toAdd, max) - player.population();
+ }
- goldAdditionRate(player: Player): number {
- return Math.sqrt(player.workers() * player.numTilesOwned()) / 200;
- }
+ goldAdditionRate(player: Player): number {
+ return Math.sqrt(player.workers() * player.numTilesOwned()) / 200;
+ }
- troopAdjustmentRate(player: Player): number {
- const maxDiff = this.maxPopulation(player) / 1000;
- const target = player.population() * player.targetTroopRatio();
- const diff = target - player.troops();
- if (Math.abs(diff) < maxDiff) {
- return diff;
- }
- const adjustment = maxDiff * Math.sign(diff);
- // Can ramp down troops much faster
- if (adjustment < 0) {
- return adjustment * 5;
- }
- return adjustment;
- }
+ troopAdjustmentRate(player: Player): number {
+ const maxDiff = this.maxPopulation(player) / 1000;
+ const target = player.population() * player.targetTroopRatio();
+ const diff = target - player.troops();
+ if (Math.abs(diff) < maxDiff) {
+ return diff;
+ }
+ const adjustment = maxDiff * Math.sign(diff);
+ // Can ramp down troops much faster
+ if (adjustment < 0) {
+ return adjustment * 5;
+ }
+ return adjustment;
+ }
}
diff --git a/src/core/execution/AttackExecution.ts b/src/core/execution/AttackExecution.ts
index 9fc77e3d6..b016539e6 100644
--- a/src/core/execution/AttackExecution.ts
+++ b/src/core/execution/AttackExecution.ts
@@ -45,7 +45,7 @@ export class AttackExecution implements Execution {
private _ownerID: PlayerID,
private _targetID: PlayerID | null,
private sourceTile: TileRef | null,
- private removeTroops: boolean = true
+ private removeTroops: boolean = true,
) {}
public targetID(): PlayerID {
@@ -95,7 +95,7 @@ export class AttackExecution implements Execution {
this.attack = this._owner.createAttack(
this.target,
this.startTroops,
- this.sourceTile
+ this.sourceTile,
);
for (const incoming of this._owner.incomingAttacks()) {
@@ -174,7 +174,7 @@ export class AttackExecution implements Execution {
this.attack.troops(),
this._owner,
this.target,
- this.border.size + this.random.nextInt(0, 5)
+ this.border.size + this.random.nextInt(0, 5),
);
// consolex.log(`num tiles per tick: ${numTilesPerTick}`)
// consolex.log(`num execs: ${this.mg.executions().length}`)
@@ -212,7 +212,7 @@ export class AttackExecution implements Execution {
this.attack.troops(),
this._owner,
this.target,
- tileToConquer
+ tileToConquer,
);
numTilesPerTick -= tilesPerTickUsed;
this.attack.setTroops(this.attack.troops() - attackerTroopLoss);
@@ -253,8 +253,8 @@ export class AttackExecution implements Execution {
new TileContainer(
neighbor,
dist / 100 + this.random.nextInt(0, 2) - numOwnedByMe + mag,
- this.mg.ticks()
- )
+ this.mg.ticks(),
+ ),
);
}
}
@@ -264,10 +264,10 @@ export class AttackExecution implements Execution {
const gold = this.target.gold();
this.mg.displayMessage(
`Conquered ${this.target.displayName()} received ${renderNumber(
- gold
+ gold,
)} gold`,
MessageType.SUCCESS,
- this._owner.id()
+ this._owner.id(),
);
this.target.removeGold(gold);
this._owner.addGold(gold);
@@ -306,6 +306,6 @@ class TileContainer {
constructor(
public readonly tile: TileRef,
public readonly priority: number,
- public readonly tick: number
+ public readonly tick: number,
) {}
}
diff --git a/src/core/execution/BotExecution.ts b/src/core/execution/BotExecution.ts
index 8c76c716a..7fde24e19 100644
--- a/src/core/execution/BotExecution.ts
+++ b/src/core/execution/BotExecution.ts
@@ -104,8 +104,8 @@ export class BotExecution implements Execution {
this.bot.id(),
toAttack.isPlayer() ? toAttack.id() : null,
null,
- null
- )
+ null,
+ ),
);
}
diff --git a/src/core/execution/ConstructionExecution.ts b/src/core/execution/ConstructionExecution.ts
index 1b44b35d2..be86ad275 100644
--- a/src/core/execution/ConstructionExecution.ts
+++ b/src/core/execution/ConstructionExecution.ts
@@ -31,7 +31,7 @@ export class ConstructionExecution implements Execution {
constructor(
private ownerId: PlayerID,
private tile: TileRef,
- private constructionType: UnitType
+ private constructionType: UnitType,
) {}
init(mg: Game, ticks: number): void {
@@ -56,7 +56,7 @@ export class ConstructionExecution implements Execution {
this.construction = this.player.buildUnit(
UnitType.Construction,
0,
- spawnTile
+ spawnTile,
);
this.cost = this.mg.unitInfo(this.constructionType).cost(this.player);
this.player.removeGold(this.cost);
@@ -88,7 +88,7 @@ export class ConstructionExecution implements Execution {
case UnitType.AtomBomb:
case UnitType.HydrogenBomb:
this.mg.addExecution(
- new NukeExecution(this.constructionType, player.id(), this.tile)
+ new NukeExecution(this.constructionType, player.id(), this.tile),
);
break;
case UnitType.MIRV:
diff --git a/src/core/execution/DefensePostExecution.ts b/src/core/execution/DefensePostExecution.ts
index 52a690a40..d298ebc1e 100644
--- a/src/core/execution/DefensePostExecution.ts
+++ b/src/core/execution/DefensePostExecution.ts
@@ -16,7 +16,10 @@ export class DefensePostExecution implements Execution {
private post: Unit;
private active: boolean = true;
- constructor(private ownerId: PlayerID, private tile: TileRef) {}
+ constructor(
+ private ownerId: PlayerID,
+ private tile: TileRef,
+ ) {}
init(mg: Game, ticks: number): void {
this.mg = mg;
diff --git a/src/core/execution/ExecutionManager.ts b/src/core/execution/ExecutionManager.ts
index bd9d4c974..b7e3f2c92 100644
--- a/src/core/execution/ExecutionManager.ts
+++ b/src/core/execution/ExecutionManager.ts
@@ -41,7 +41,7 @@ export class Executor {
constructor(
private mg: Game,
private gameID: GameID,
- private clientID: ClientID
+ private clientID: ClientID,
) {
// Add one to avoid id collisions with bots.
this.random = new PseudoRandom(simpleHash(gameID) + 1);
@@ -58,7 +58,7 @@ export class Executor {
intent.troops,
intent.attackerID,
intent.targetID,
- null
+ null,
);
}
case "spawn":
@@ -71,16 +71,16 @@ export class Executor {
: fixProfaneUsername(sanitize(intent.name)),
intent.playerType,
intent.clientID,
- intent.playerID
+ intent.playerID,
),
- this.mg.ref(intent.x, intent.y)
+ this.mg.ref(intent.x, intent.y),
);
case "boat":
return new TransportShipExecution(
intent.attackerID,
intent.targetID,
this.mg.ref(intent.x, intent.y),
- intent.troops
+ intent.troops,
);
case "allianceRequest":
return new AllianceRequestExecution(intent.requestor, intent.recipient);
@@ -88,7 +88,7 @@ export class Executor {
return new AllianceRequestReplyExecution(
intent.requestor,
intent.recipient,
- intent.accept
+ intent.accept,
);
case "breakAlliance":
return new BreakAllianceExecution(intent.requestor, intent.recipient);
@@ -98,13 +98,13 @@ export class Executor {
return new EmojiExecution(
intent.sender,
intent.recipient,
- intent.emoji
+ intent.emoji,
);
case "donate":
return new DonateExecution(
intent.sender,
intent.recipient,
- intent.troops
+ intent.troops,
);
case "troop_ratio":
return new SetTargetTroopRatioExecution(intent.player, intent.ratio);
@@ -112,7 +112,7 @@ export class Executor {
return new ConstructionExecution(
intent.player,
this.mg.ref(intent.x, intent.y),
- intent.unit
+ intent.unit,
);
default:
throw new Error(`intent type ${intent} not found`);
@@ -137,9 +137,9 @@ export class Executor {
PlayerType.FakeHuman,
null,
this.random.nextID(),
- nation
- )
- )
+ nation,
+ ),
+ ),
);
}
return execs;
diff --git a/src/core/execution/FakeHumanExecution.ts b/src/core/execution/FakeHumanExecution.ts
index eb7c7e93f..d3921adca 100644
--- a/src/core/execution/FakeHumanExecution.ts
+++ b/src/core/execution/FakeHumanExecution.ts
@@ -40,9 +40,12 @@ export class FakeHumanExecution implements Execution {
private lastEnemyUpdateTick: number = 0;
private lastEmojiSent = new Map();
- constructor(gameID: GameID, private playerInfo: PlayerInfo) {
+ constructor(
+ gameID: GameID,
+ private playerInfo: PlayerInfo,
+ ) {
this.random = new PseudoRandom(
- simpleHash(playerInfo.id) + simpleHash(gameID)
+ simpleHash(playerInfo.id) + simpleHash(gameID),
);
}
@@ -99,7 +102,7 @@ export class FakeHumanExecution implements Execution {
const enemyborder = Array.from(this.player.borderTiles())
.flatMap((t) => this.mg.neighbors(t))
.filter(
- (t) => this.mg.isLand(t) && this.mg.ownerID(t) != this.player.smallID()
+ (t) => this.mg.isLand(t) && this.mg.ownerID(t) != this.player.smallID(),
);
if (enemyborder.length == 0) {
@@ -114,7 +117,7 @@ export class FakeHumanExecution implements Execution {
}
const enemiesWithTN = enemyborder.map((t) =>
- this.mg.playerBySmallID(this.mg.ownerID(t))
+ this.mg.playerBySmallID(this.mg.ownerID(t)),
);
if (enemiesWithTN.filter((o) => !o.isPlayer()).length > 0) {
this.sendAttack(this.mg.terraNullius());
@@ -194,7 +197,7 @@ export class FakeHumanExecution implements Execution {
this.lastEnemyUpdateTick = this.mg.ticks();
if (target.ally.type() == PlayerType.Human) {
this.mg.addExecution(
- new EmojiExecution(this.player.id(), target.ally.id(), "👍")
+ new EmojiExecution(this.player.id(), target.ally.id(), "👍"),
);
}
}
@@ -215,8 +218,8 @@ export class FakeHumanExecution implements Execution {
new EmojiExecution(
this.player.id(),
this.enemy.id(),
- this.random.randElement(["🤡", "😡"])
- )
+ this.random.randElement(["🤡", "😡"]),
+ ),
);
}
}
@@ -260,7 +263,7 @@ export class FakeHumanExecution implements Execution {
}
if (this.player.canBuild(UnitType.AtomBomb, tile)) {
this.mg.addExecution(
- new NukeExecution(UnitType.AtomBomb, this.player.id(), tile)
+ new NukeExecution(UnitType.AtomBomb, this.player.id(), tile),
);
return;
}
@@ -271,9 +274,9 @@ export class FakeHumanExecution implements Execution {
const closest = closestTwoTiles(
this.mg,
Array.from(this.player.borderTiles()).filter((t) =>
- this.mg.isOceanShore(t)
+ this.mg.isOceanShore(t),
),
- Array.from(other.borderTiles()).filter((t) => this.mg.isOceanShore(t))
+ Array.from(other.borderTiles()).filter((t) => this.mg.isOceanShore(t)),
);
if (closest == null) {
return;
@@ -287,8 +290,8 @@ export class FakeHumanExecution implements Execution {
this.player.id(),
other.id(),
closest.y,
- this.player.troops() / 5
- )
+ this.player.troops() / 5,
+ ),
);
}
}
@@ -297,12 +300,12 @@ export class FakeHumanExecution implements Execution {
const ports = this.player.units(UnitType.Port);
if (ports.length == 0 && this.player.gold() > this.cost(UnitType.Port)) {
const oceanTiles = Array.from(this.player.borderTiles()).filter((t) =>
- this.mg.isOceanShore(t)
+ this.mg.isOceanShore(t),
);
if (oceanTiles.length > 0) {
const buildTile = this.random.randElement(oceanTiles);
this.mg.addExecution(
- new ConstructionExecution(this.player.id(), buildTile, UnitType.Port)
+ new ConstructionExecution(this.player.id(), buildTile, UnitType.Port),
);
}
return;
@@ -310,7 +313,7 @@ export class FakeHumanExecution implements Execution {
this.maybeSpawnStructure(
UnitType.City,
2,
- (t) => new ConstructionExecution(this.player.id(), t, UnitType.City)
+ (t) => new ConstructionExecution(this.player.id(), t, UnitType.City),
);
if (this.maybeSpawnWarship()) {
return;
@@ -319,14 +322,14 @@ export class FakeHumanExecution implements Execution {
UnitType.MissileSilo,
1,
(t) =>
- new ConstructionExecution(this.player.id(), t, UnitType.MissileSilo)
+ new ConstructionExecution(this.player.id(), t, UnitType.MissileSilo),
);
}
private maybeSpawnStructure(
type: UnitType,
maxNum: number,
- build: (tile: TileRef) => Execution
+ build: (tile: TileRef) => Execution,
) {
const units = this.player.units(type);
if (units.length >= maxNum) {
@@ -373,8 +376,8 @@ export class FakeHumanExecution implements Execution {
new ConstructionExecution(
this.player.id(),
targetTile,
- UnitType.Warship
- )
+ UnitType.Warship,
+ ),
);
return true;
}
@@ -403,11 +406,11 @@ export class FakeHumanExecution implements Execution {
for (let attempts = 0; attempts < 50; attempts++) {
const randX = this.random.nextInt(
this.mg.x(portTile) - radius,
- this.mg.x(portTile) + radius
+ this.mg.x(portTile) + radius,
);
const randY = this.random.nextInt(
this.mg.y(portTile) - radius,
- this.mg.y(portTile) + radius
+ this.mg.y(portTile) + radius,
);
if (!this.mg.isValidCoord(randX, randY)) {
continue;
@@ -457,8 +460,8 @@ export class FakeHumanExecution implements Execution {
new AllianceRequestReplyExecution(
req.requestor().id(),
this.player.id(),
- accept
- )
+ accept,
+ ),
);
}
@@ -469,7 +472,7 @@ export class FakeHumanExecution implements Execution {
if (oceanShore == null) {
oceanShore = Array.from(this.player.borderTiles()).filter((t) =>
- this.mg.isOceanShore(t)
+ this.mg.isOceanShore(t),
);
}
if (oceanShore.length == 0) {
@@ -482,9 +485,9 @@ export class FakeHumanExecution implements Execution {
src,
andFN(
(gm, t) => gm.isOcean(t) || gm.isOceanShore(t),
- manhattanDistFN(src, 200)
- )
- )
+ manhattanDistFN(src, 200),
+ ),
+ ),
).filter((t) => this.mg.isOceanShore(t) && this.mg.owner(t) != this.player);
if (otherShore.length == 0) {
@@ -508,8 +511,8 @@ export class FakeHumanExecution implements Execution {
this.player.id(),
this.mg.hasOwner(dst) ? this.mg.owner(dst).id() : null,
dst,
- this.player.troops() / 5
- )
+ this.player.troops() / 5,
+ ),
);
return;
}
@@ -548,8 +551,8 @@ export class FakeHumanExecution implements Execution {
this.player.id(),
toAttack.isPlayer() ? toAttack.id() : null,
null,
- null
- )
+ null,
+ ),
);
}
@@ -557,7 +560,7 @@ export class FakeHumanExecution implements Execution {
return (
this.mg.bfs(
tile,
- andFN((gm, t) => gm.isLand(t), manhattanDistFN(tile, 10))
+ andFN((gm, t) => gm.isLand(t), manhattanDistFN(tile, 10)),
).size < 50
);
}
diff --git a/src/core/execution/MIRVExecution.ts b/src/core/execution/MIRVExecution.ts
index 4f60b0954..b6095ba80 100644
--- a/src/core/execution/MIRVExecution.ts
+++ b/src/core/execution/MIRVExecution.ts
@@ -37,7 +37,10 @@ export class MirvExecution implements Execution {
private separateDst: TileRef;
- constructor(private senderID: PlayerID, private dst: TileRef) {}
+ constructor(
+ private senderID: PlayerID,
+ private dst: TileRef,
+ ) {}
init(mg: Game, ticks: number): void {
this.random = new PseudoRandom(mg.ticks() + simpleHash(this.senderID));
@@ -57,7 +60,7 @@ export class MirvExecution implements Execution {
}
this.nuke = this.player.buildUnit(UnitType.MIRV, 0, spawn);
const x = Math.floor(
- (this.mg.x(this.dst) + this.mg.x(this.mg.x(this.nuke.tile()))) / 2
+ (this.mg.x(this.dst) + this.mg.x(this.mg.x(this.nuke.tile()))) / 2,
);
const y = Math.max(0, this.mg.y(this.dst) - 500) + 50;
this.separateDst = this.mg.ref(x, y);
@@ -66,7 +69,7 @@ export class MirvExecution implements Execution {
for (let i = 0; i < 4; i++) {
const result = this.pathFinder.nextTile(
this.nuke.tile(),
- this.separateDst
+ this.separateDst,
);
switch (result.type) {
case PathFindResultType.Completed:
@@ -81,7 +84,7 @@ export class MirvExecution implements Execution {
break;
case PathFindResultType.PathNotFound:
consolex.warn(
- `nuke cannot find path from ${this.nuke.tile()} to ${this.dst}`
+ `nuke cannot find path from ${this.nuke.tile()} to ${this.dst}`,
);
this.active = false;
return;
@@ -103,7 +106,7 @@ export class MirvExecution implements Execution {
console.log(`dsts: ${dsts.length}`);
dsts.sort(
(a, b) =>
- this.mg.manhattanDist(b, this.dst) - this.mg.manhattanDist(a, this.dst)
+ this.mg.manhattanDist(b, this.dst) - this.mg.manhattanDist(a, this.dst),
);
console.log(`got ${dsts.length} dsts!!`);
@@ -116,8 +119,8 @@ export class MirvExecution implements Execution {
this.nuke.tile(),
15 + Math.floor((i / this.warheadCount) * 5),
// this.random.nextInt(5, 9),
- this.random.nextInt(0, 15)
- )
+ this.random.nextInt(0, 15),
+ ),
);
}
if (this.targetPlayer.isPlayer()) {
@@ -138,11 +141,11 @@ export class MirvExecution implements Execution {
tries++;
const x = this.random.nextInt(
this.mg.x(ref) - this.mirvRange,
- this.mg.x(ref) + this.mirvRange
+ this.mg.x(ref) + this.mirvRange,
);
const y = this.random.nextInt(
this.mg.y(ref) - this.mirvRange,
- this.mg.y(ref) + this.mirvRange
+ this.mg.y(ref) + this.mirvRange,
);
if (!this.mg.isValidCoord(x, y)) {
continue;
diff --git a/src/core/execution/NukeExecution.ts b/src/core/execution/NukeExecution.ts
index dee6155ac..2bb387c0c 100644
--- a/src/core/execution/NukeExecution.ts
+++ b/src/core/execution/NukeExecution.ts
@@ -29,7 +29,7 @@ export class NukeExecution implements Execution {
private dst: TileRef,
private src?: TileRef,
private speed: number = 4,
- private waitTicks = 0
+ private waitTicks = 0,
) {}
init(mg: Game, ticks: number): void {
@@ -77,7 +77,7 @@ export class NukeExecution implements Execution {
let nextY = y;
const ratio = Math.floor(
- 1 + Math.abs(dstY - y) / (Math.abs(dstX - x) + 1)
+ 1 + Math.abs(dstY - y) / (Math.abs(dstX - x) + 1),
);
if (this.random.chance(ratio) && x != dstX) {
@@ -123,7 +123,7 @@ export class NukeExecution implements Execution {
const ratio = Object.fromEntries(
this.mg
.players()
- .map((p) => [p.id(), (p.troops() + p.workers()) / p.numTilesOwned()])
+ .map((p) => [p.id(), (p.troops() + p.workers()) / p.numTilesOwned()]),
);
const attacked = new Map();
for (const tile of toDestroy) {
diff --git a/src/core/execution/PortExecution.ts b/src/core/execution/PortExecution.ts
index b338c7a92..0d0b99815 100644
--- a/src/core/execution/PortExecution.ts
+++ b/src/core/execution/PortExecution.ts
@@ -25,7 +25,10 @@ export class PortExecution implements Execution {
private portPaths = new Map();
private computingPaths = new Map();
- constructor(private _owner: PlayerID, private tile: TileRef) {}
+ constructor(
+ private _owner: PlayerID,
+ private tile: TileRef,
+ ) {}
init(mg: Game, ticks: number): void {
this.mg = mg;
@@ -46,7 +49,7 @@ export class PortExecution implements Execution {
.filter((t) => this.mg.isOceanShore(t) && this.mg.owner(t) == player)
.sort(
(a, b) =>
- this.mg.manhattanDist(a, tile) - this.mg.manhattanDist(b, tile)
+ this.mg.manhattanDist(a, tile) - this.mg.manhattanDist(b, tile),
);
if (spawns.length == 0) {
@@ -68,7 +71,7 @@ export class PortExecution implements Execution {
const alliedPortsSet = new Set(alliedPorts);
const allyConnections = new Set(
- Array.from(this.portPaths.keys()).map((p) => p.owner())
+ Array.from(this.portPaths.keys()).map((p) => p.owner()),
);
allyConnections;
@@ -100,7 +103,7 @@ export class PortExecution implements Execution {
port.tile(),
(tr: TileRef) => this.mg.miniMap().isOcean(tr),
10_000,
- 25
+ 25,
);
this.computingPaths.set(port, pf);
}
@@ -123,7 +126,7 @@ export class PortExecution implements Execution {
if (path != null) {
const pf = PathFinder.Mini(this.mg, 10000, false);
this.mg.addExecution(
- new TradeShipExecution(this.player().id(), this.port, port, pf, path)
+ new TradeShipExecution(this.player().id(), this.port, port, pf, path),
);
}
}
diff --git a/src/core/execution/WarshipExecution.ts b/src/core/execution/WarshipExecution.ts
index 9cd1d40a9..c84cc9823 100644
--- a/src/core/execution/WarshipExecution.ts
+++ b/src/core/execution/WarshipExecution.ts
@@ -37,7 +37,10 @@ export class WarshipExecution implements Execution {
private alreadySentShell = new Set();
- constructor(private playerID: PlayerID, private patrolCenterTile: TileRef) {}
+ constructor(
+ private playerID: PlayerID,
+ private patrolCenterTile: TileRef,
+ ) {}
init(mg: Game, ticks: number): void {
this.pathfinder = PathFinder.Mini(mg, 5000, false);
@@ -68,7 +71,7 @@ export class WarshipExecution implements Execution {
const ships = this.mg
.units(UnitType.TransportShip, UnitType.Warship, UnitType.TradeShip)
.filter(
- (u) => this.mg.manhattanDist(u.tile(), this.warship.tile()) < 130
+ (u) => this.mg.manhattanDist(u.tile(), this.warship.tile()) < 130,
)
.filter((u) => u.owner() != this.warship.owner())
.filter((u) => u != this.warship)
@@ -80,7 +83,7 @@ export class WarshipExecution implements Execution {
// Patrol unless we are hunting down a tradeship
const result = this.pathfinder.nextTile(
this.warship.tile(),
- this.patrolTile
+ this.patrolTile,
);
switch (result.type) {
case PathFindResultType.Completed:
@@ -115,8 +118,8 @@ export class WarshipExecution implements Execution {
this.warship.tile(),
this.warship.owner(),
this.warship,
- this.target
- )
+ this.target,
+ ),
);
if (!this.target.hasHealth()) {
// Don't send multiple shells to target that can be oneshotted
@@ -134,7 +137,7 @@ export class WarshipExecution implements Execution {
const result = this.pathfinder.nextTile(
this.warship.tile(),
this.target.tile(),
- 5
+ 5,
);
switch (result.type) {
case PathFindResultType.Completed:
diff --git a/src/core/execution/alliance/AllianceRequestExecution.ts b/src/core/execution/alliance/AllianceRequestExecution.ts
index 9ad100564..c5a20843a 100644
--- a/src/core/execution/alliance/AllianceRequestExecution.ts
+++ b/src/core/execution/alliance/AllianceRequestExecution.ts
@@ -13,7 +13,10 @@ export class AllianceRequestExecution implements Execution {
private requestor: Player;
private recipient: Player;
- constructor(private requestorID: PlayerID, private recipientID: PlayerID) {}
+ constructor(
+ private requestorID: PlayerID,
+ private recipientID: PlayerID,
+ ) {}
init(mg: Game, ticks: number): void {
this.mg = mg;
diff --git a/src/core/game/AttackImpl.ts b/src/core/game/AttackImpl.ts
index 87d7a0017..7444f6b24 100644
--- a/src/core/game/AttackImpl.ts
+++ b/src/core/game/AttackImpl.ts
@@ -9,7 +9,7 @@ export class AttackImpl implements Attack {
private _target: Player | TerraNullius,
private _attacker: Player,
private _troops: number,
- private _sourceTile: TileRef | null
+ private _sourceTile: TileRef | null,
) {}
sourceTile(): TileRef | null {
diff --git a/src/core/game/DefensePostGrid.ts b/src/core/game/DefensePostGrid.ts
index bafffe6c8..32427982c 100644
--- a/src/core/game/DefensePostGrid.ts
+++ b/src/core/game/DefensePostGrid.ts
@@ -6,13 +6,16 @@ export class DefenseGrid {
private grid: Set[][];
private readonly cellSize = 100;
- constructor(private gm: GameMap, private searchRange: number) {
+ constructor(
+ private gm: GameMap,
+ private searchRange: number,
+ ) {
this.grid = Array(Math.ceil(gm.height() / this.cellSize))
.fill(null)
.map(() =>
Array(Math.ceil(gm.width() / this.cellSize))
.fill(null)
- .map(() => new Set())
+ .map(() => new Set()),
);
}
diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts
index 3f2cb0331..cde3b9360 100644
--- a/src/core/game/Game.ts
+++ b/src/core/game/Game.ts
@@ -89,7 +89,7 @@ export class Nation {
public readonly flag: string,
public readonly name: string,
public readonly cell: Cell,
- public readonly strength: number
+ public readonly strength: number,
) {}
}
@@ -98,7 +98,10 @@ export class Cell {
private strRepr: string;
- constructor(public readonly x, public readonly y) {
+ constructor(
+ public readonly x,
+ public readonly y,
+ ) {
this.strRepr = `Cell[${this.x},${this.y}]`;
}
@@ -176,7 +179,7 @@ export class PlayerInfo {
public readonly clientID: ClientID | null,
// TODO: make player id the small id
public readonly id: PlayerID,
- public readonly nation?: Nation | null
+ public readonly nation?: Nation | null,
) {}
}
@@ -302,7 +305,7 @@ export interface Player {
createAttack(
target: Player | TerraNullius,
troops: number,
- sourceTile: TileRef
+ sourceTile: TileRef,
): Attack;
outgoingAttacks(): Attack[];
incomingAttacks(): Attack[];
@@ -350,7 +353,7 @@ export interface Game extends GameMap {
displayMessage(
message: string,
type: MessageType,
- playerID: PlayerID | null
+ playerID: PlayerID | null,
): void;
// Nations
diff --git a/src/core/game/GameImpl.ts b/src/core/game/GameImpl.ts
index c47b56bbd..ea1a85a97 100644
--- a/src/core/game/GameImpl.ts
+++ b/src/core/game/GameImpl.ts
@@ -35,7 +35,7 @@ export function createGame(
gameMap: GameMap,
miniGameMap: GameMap,
nationMap: NationMap,
- config: Config
+ config: Config,
): Game {
return new GameImpl(gameMap, miniGameMap, nationMap, config);
}
@@ -70,7 +70,7 @@ export class GameImpl implements Game {
private _map: GameMap,
private miniGameMap: GameMap,
nationMap: NationMap,
- private _config: Config
+ private _config: Config,
) {
this._terraNullius = new TerraNulliusImpl();
this._width = _map.width();
@@ -81,12 +81,12 @@ export class GameImpl implements Game {
n.flag || "",
n.name,
new Cell(n.coordinates[0], n.coordinates[1]),
- n.strength
- )
+ n.strength,
+ ),
);
this.defenseGrid = new DefenseGrid(
this._map,
- this._config.defensePostRange()
+ this._config.defensePostRange(),
);
}
@@ -173,11 +173,11 @@ export class GameImpl implements Game {
this,
request.requestor() as PlayerImpl,
request.recipient() as PlayerImpl,
- this._ticks
+ this._ticks,
);
this.alliances_.push(alliance);
(request.requestor() as PlayerImpl).pastOutgoingAllianceRequests.push(
- request
+ request,
);
this.addUpdate({
type: GameUpdateType.AllianceRequestReply,
@@ -189,7 +189,7 @@ export class GameImpl implements Game {
rejectAllianceRequest(request: AllianceRequestImpl) {
this.allianceRequests = this.allianceRequests.filter((ar) => ar != request);
(request.requestor() as PlayerImpl).pastOutgoingAllianceRequests.push(
- request
+ request,
);
this.addUpdate({
type: GameUpdateType.AllianceRequestReply,
@@ -296,7 +296,7 @@ export class GameImpl implements Game {
removeExecution(exec: Execution) {
this.execs = this.execs.filter((execution) => execution !== exec);
this.unInitExecs = this.unInitExecs.filter(
- (execution) => execution !== exec
+ (execution) => execution !== exec,
);
}
@@ -448,7 +448,7 @@ export class GameImpl implements Game {
}
if (!breaker.isAlliedWith(other)) {
throw new Error(
- `${breaker} not allied with ${other}, cannot break alliance`
+ `${breaker} not allied with ${other}, cannot break alliance`,
);
}
if (!other.isTraitor()) {
@@ -459,7 +459,7 @@ export class GameImpl implements Game {
const alliances = other.alliances().filter((a) => breakerSet.has(a));
if (alliances.length != 1) {
throw new Error(
- `must have exactly one alliance, have ${alliances.length}`
+ `must have exactly one alliance, have ${alliances.length}`,
);
}
this.alliances_ = this.alliances_.filter((a) => a != alliances[0]);
@@ -478,7 +478,7 @@ export class GameImpl implements Game {
.filter((a) => p1Set.has(a));
if (alliances.length != 1) {
throw new Error(
- `cannot expire alliance: must have exactly one alliance, have ${alliances.length}`
+ `cannot expire alliance: must have exactly one alliance, have ${alliances.length}`,
);
}
this.alliances_ = this.alliances_.filter((a) => a != alliances[0]);
@@ -506,7 +506,7 @@ export class GameImpl implements Game {
displayMessage(
message: string,
type: MessageType,
- playerID: PlayerID | null
+ playerID: PlayerID | null,
): void {
let id = null;
if (playerID != null) {
@@ -614,7 +614,7 @@ export class GameImpl implements Game {
}
bfs(
tile: TileRef,
- filter: (gm: GameMap, tile: TileRef) => boolean
+ filter: (gm: GameMap, tile: TileRef) => boolean,
): Set {
return this._map.bfs(tile, filter);
}
diff --git a/src/core/game/GameUpdates.ts b/src/core/game/GameUpdates.ts
index 1ced76389..c7f7faafe 100644
--- a/src/core/game/GameUpdates.ts
+++ b/src/core/game/GameUpdates.ts
@@ -80,7 +80,7 @@ export interface PlayerUpdate {
type: GameUpdateType.Player;
nameViewData?: NameViewData;
clientID: ClientID;
- flag: string,
+ flag: string;
name: string;
displayName: string;
id: PlayerID;
diff --git a/src/core/game/GameView.ts b/src/core/game/GameView.ts
index ae893438e..e79922c7c 100644
--- a/src/core/game/GameView.ts
+++ b/src/core/game/GameView.ts
@@ -36,7 +36,10 @@ export class UnitView {
public _wasUpdated = true;
public lastPos: MapPos[] = [];
- constructor(private gameView: GameView, private data: UnitUpdate) {
+ constructor(
+ private gameView: GameView,
+ private data: UnitUpdate,
+ ) {
this.lastPos.push(data.pos);
}
@@ -95,14 +98,14 @@ export class PlayerView {
constructor(
private game: GameView,
public data: PlayerUpdate,
- public nameData: NameViewData
+ public nameData: NameViewData,
) {}
async actions(tile: TileRef): Promise {
return this.game.worker.playerInteraction(
this.id(),
this.game.x(tile),
- this.game.y(tile)
+ this.game.y(tile),
);
}
@@ -156,12 +159,12 @@ export class PlayerView {
}
allies(): PlayerView[] {
return this.data.allies.map(
- (a) => this.game.playerBySmallID(a) as PlayerView
+ (a) => this.game.playerBySmallID(a) as PlayerView,
);
}
targets(): PlayerView[] {
return this.data.targets.map(
- (id) => this.game.playerBySmallID(id) as PlayerView
+ (id) => this.game.playerBySmallID(id) as PlayerView,
);
}
gold(): Gold {
@@ -199,7 +202,13 @@ export class PlayerView {
return this.data.outgoingEmojis;
}
info(): PlayerInfo {
- return new PlayerInfo(this.flag(), this.name(), this.type(), this.clientID(), this.id());
+ return new PlayerInfo(
+ this.flag(),
+ this.name(),
+ this.type(),
+ this.clientID(),
+ this.id(),
+ );
}
}
@@ -218,7 +227,7 @@ export class GameView implements GameMap {
public worker: WorkerClient,
private _config: Config,
private _map: GameMap,
- private _myClientID: ClientID
+ private _myClientID: ClientID,
) {
this.lastUpdate = {
tick: 0,
@@ -250,7 +259,7 @@ export class GameView implements GameMap {
} else {
this._players.set(
pu.id,
- new PlayerView(this, pu, gu.playerNameViewData[pu.id])
+ new PlayerView(this, pu, gu.playerNameViewData[pu.id]),
);
}
});
@@ -347,7 +356,7 @@ export class GameView implements GameMap {
return Array.from(this._units.values()).filter((u) => u.isActive());
}
return Array.from(this._units.values()).filter(
- (u) => u.isActive() && types.includes(u.type())
+ (u) => u.isActive() && types.includes(u.type()),
);
}
unit(id: number): UnitView {
@@ -443,7 +452,7 @@ export class GameView implements GameMap {
}
bfs(
tile: TileRef,
- filter: (gm: GameMap, tile: TileRef) => boolean
+ filter: (gm: GameMap, tile: TileRef) => boolean,
): Set {
return this._map.bfs(tile, filter);
}
diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts
index 279bc4167..20fed8325 100644
--- a/src/core/game/PlayerImpl.ts
+++ b/src/core/game/PlayerImpl.ts
@@ -46,7 +46,10 @@ interface Target {
}
class Donation {
- constructor(public readonly recipient: Player, public readonly tick: Tick) {}
+ constructor(
+ public readonly recipient: Player,
+ public readonly tick: Tick,
+ ) {}
}
export class PlayerImpl implements Player {
@@ -85,7 +88,7 @@ export class PlayerImpl implements Player {
private mg: GameImpl,
private _smallID: number,
private readonly playerInfo: PlayerInfo,
- startPopulation: number
+ startPopulation: number,
) {
this._flag = playerInfo.flag;
this._name = playerInfo.name;
@@ -125,7 +128,7 @@ export class PlayerImpl implements Player {
attackerID: a.attacker().smallID(),
targetID: a.target().smallID(),
troops: a.troops(),
- } as AttackUpdate)
+ }) as AttackUpdate,
),
incomingAttacks: this._incomingAttacks.map(
(a) =>
@@ -133,7 +136,7 @@ export class PlayerImpl implements Player {
attackerID: a.attacker().smallID(),
targetID: a.target().smallID(),
troops: a.troops(),
- } as AttackUpdate)
+ }) as AttackUpdate,
),
};
}
@@ -203,7 +206,7 @@ export class PlayerImpl implements Player {
const owner = this.mg.map().ownerID(neighbor);
if (owner != this.smallID()) {
ns.add(
- this.mg.playerBySmallID(owner) as PlayerImpl | TerraNulliusImpl
+ this.mg.playerBySmallID(owner) as PlayerImpl | TerraNulliusImpl,
);
}
}
@@ -249,7 +252,7 @@ export class PlayerImpl implements Player {
alliances(): MutableAlliance[] {
return this.mg.alliances_.filter(
- (a) => a.requestor() == this || a.recipient() == this
+ (a) => a.requestor() == this || a.recipient() == this,
);
}
@@ -269,7 +272,7 @@ export class PlayerImpl implements Player {
return null;
}
return this.alliances().find(
- (a) => a.recipient() == other || a.requestor() == other
+ (a) => a.recipient() == other || a.requestor() == other,
);
}
@@ -398,7 +401,7 @@ export class PlayerImpl implements Player {
targets(): PlayerImpl[] {
return this.targets_
.filter(
- (t) => this.mg.ticks() - t.tick < this.mg.config().targetDuration()
+ (t) => this.mg.ticks() - t.tick < this.mg.config().targetDuration(),
)
.map((t) => t.target as PlayerImpl);
}
@@ -430,7 +433,7 @@ export class PlayerImpl implements Player {
.filter(
(e) =>
this.mg.ticks() - e.createdAt <
- this.mg.config().emojiMessageDuration()
+ this.mg.config().emojiMessageDuration(),
)
.sort((a, b) => b.createdAt - a.createdAt);
}
@@ -439,7 +442,7 @@ export class PlayerImpl implements Player {
const recipientID =
recipient == AllPlayers ? AllPlayers : recipient.smallID();
const prevMsgs = this.outgoingEmojis_.filter(
- (msg) => msg.recipientID == recipientID
+ (msg) => msg.recipientID == recipientID,
);
for (const msg of prevMsgs) {
if (
@@ -475,12 +478,12 @@ export class PlayerImpl implements Player {
this.mg.displayMessage(
`Sent ${renderTroops(troops)} troops to ${recipient.name()}`,
MessageType.INFO,
- this.id()
+ this.id(),
);
this.mg.displayMessage(
`Recieved ${renderTroops(troops)} troops from ${this.name()}`,
MessageType.SUCCESS,
- recipient.id()
+ recipient.id(),
);
}
@@ -495,7 +498,7 @@ export class PlayerImpl implements Player {
removeGold(toRemove: Gold): void {
if (toRemove > this._gold) {
throw Error(
- `Player ${this} does not enough gold (${toRemove} vs ${this._gold}))`
+ `Player ${this} does not enough gold (${toRemove} vs ${this._gold}))`,
);
}
this._gold -= toRemove;
@@ -521,7 +524,7 @@ export class PlayerImpl implements Player {
setTargetTroopRatio(target: number): void {
if (target < 0 || target > 1) {
throw new Error(
- `invalid targetTroopRatio ${target} set on player ${PlayerImpl}`
+ `invalid targetTroopRatio ${target} set on player ${PlayerImpl}`,
);
}
this._targetTroopRatio = target;
@@ -553,7 +556,7 @@ export class PlayerImpl implements Player {
}
const prev = unit.owner();
(prev as PlayerImpl)._units = (prev as PlayerImpl)._units.filter(
- (u) => u != unit
+ (u) => u != unit,
);
(unit as UnitImpl)._owner = this;
this._units.push(unit as UnitImpl);
@@ -561,12 +564,12 @@ export class PlayerImpl implements Player {
this.mg.displayMessage(
`${unit.type()} captured by ${this.displayName()}`,
MessageType.ERROR,
- prev.id()
+ prev.id(),
);
this.mg.displayMessage(
`Captured ${unit.type()} from ${prev.displayName()}`,
MessageType.SUCCESS,
- this.id()
+ this.id(),
);
}
@@ -578,7 +581,7 @@ export class PlayerImpl implements Player {
spawnTile,
troops,
this.mg.nextUnitID(),
- this
+ this,
);
this._units.push(b);
this.removeGold(cost);
@@ -641,7 +644,7 @@ export class PlayerImpl implements Player {
.filter((t) => this.mg.owner(t) == this && this.mg.isOceanShore(t))
.sort(
(a, b) =>
- this.mg.manhattanDist(a, tile) - this.mg.manhattanDist(b, tile)
+ this.mg.manhattanDist(a, tile) - this.mg.manhattanDist(b, tile),
);
if (spawns.length == 0) {
return false;
@@ -657,12 +660,12 @@ export class PlayerImpl implements Player {
.filter(
(u) =>
this.mg.manhattanDist(u.tile(), tile) <
- this.mg.config().boatMaxDistance()
+ this.mg.config().boatMaxDistance(),
)
.sort(
(a, b) =>
this.mg.manhattanDist(a.tile(), tile) -
- this.mg.manhattanDist(b.tile(), tile)
+ this.mg.manhattanDist(b.tile(), tile),
);
if (spawns.length == 0) {
return false;
@@ -690,7 +693,7 @@ export class PlayerImpl implements Player {
tradeShipSpawn(targetTile: TileRef): TileRef | false {
const spawns = this.units(UnitType.Port).filter(
- (u) => u.tile() == targetTile
+ (u) => u.tile() == targetTile,
);
if (spawns.length == 0) {
return false;
@@ -721,7 +724,7 @@ export class PlayerImpl implements Player {
this.allRelationsSorted().map(({ player, relation }) => [
player.smallID(),
relation,
- ])
+ ]),
),
alliances: this.alliances().map((a) => a.other(this).smallID()),
};
@@ -765,8 +768,8 @@ export class PlayerImpl implements Player {
tile,
andFN(
(gm, t) => gm.ownerID(t) == gm.ownerID(tile) && gm.isLand(t),
- manhattanDistFN(tile, 25)
- )
+ manhattanDistFN(tile, 25),
+ ),
)) {
if (this.mg.isOceanShore(t)) {
nearOcean = true;
@@ -790,7 +793,7 @@ export class PlayerImpl implements Player {
createAttack(
target: Player | TerraNullius,
troops: number,
- sourceTile: TileRef
+ sourceTile: TileRef,
): Attack {
const attack = new AttackImpl(target, this, troops, sourceTile);
this._outgoingAttacks.push(attack);
@@ -835,8 +838,8 @@ export class PlayerImpl implements Player {
tile,
andFN(
(gm, t) => !gm.hasOwner(t) && gm.isLand(t),
- manhattanDistFN(tile, 200)
- )
+ manhattanDistFN(tile, 200),
+ ),
)) {
for (const n of this.mg.neighbors(t)) {
if (this.mg.owner(n) == this) {
diff --git a/src/core/game/UnitImpl.ts b/src/core/game/UnitImpl.ts
index 1cc90a682..5c398ead3 100644
--- a/src/core/game/UnitImpl.ts
+++ b/src/core/game/UnitImpl.ts
@@ -20,7 +20,7 @@ export class UnitImpl implements Unit {
private _tile: TileRef,
private _troops: number,
private _id: number,
- public _owner: PlayerImpl
+ public _owner: PlayerImpl,
) {
// default to half health (or 1 is no health specified)
this._health = (this.mg.unitInfo(_type).maxHealth ?? 2) / 2;
@@ -89,7 +89,7 @@ export class UnitImpl implements Unit {
this.mg.displayMessage(
`Your ${this.type()} was captured by ${newOwner.displayName()}`,
MessageType.ERROR,
- oldOwner.id()
+ oldOwner.id(),
);
}
@@ -111,7 +111,7 @@ export class UnitImpl implements Unit {
this.mg.displayMessage(
`Your ${this.type()} was destroyed`,
MessageType.ERROR,
- this.owner().id()
+ this.owner().id(),
);
}
}
diff --git a/src/core/validations/username.ts b/src/core/validations/username.ts
index c1de0c357..c22ff4fa6 100644
--- a/src/core/validations/username.ts
+++ b/src/core/validations/username.ts
@@ -61,7 +61,8 @@ export function validateUsername(username: string): {
if (!validPattern.test(username)) {
return {
isValid: false,
- error: "Username can only contain letters, numbers, spaces, underscores, and [square brackets].",
+ error:
+ "Username can only contain letters, numbers, spaces, underscores, and [square brackets].",
};
}
diff --git a/src/core/worker/Worker.worker.ts b/src/core/worker/Worker.worker.ts
index e309302b1..544d067c4 100644
--- a/src/core/worker/Worker.worker.ts
+++ b/src/core/worker/Worker.worker.ts
@@ -35,7 +35,7 @@ ctx.addEventListener("message", async (e: MessageEvent) => {
message.gameID,
message.gameConfig,
message.clientID,
- gameUpdate
+ gameUpdate,
).then((gr) => {
sendMessage({
type: "initialized",
@@ -72,7 +72,7 @@ ctx.addEventListener("message", async (e: MessageEvent) => {
const actions = (await gameRunner).playerActions(
message.playerID,
message.x,
- message.y
+ message.y,
);
sendMessage({
type: "player_actions_result",
diff --git a/src/core/worker/WorkerClient.ts b/src/core/worker/WorkerClient.ts
index 843bf0ea2..6a739ddac 100644
--- a/src/core/worker/WorkerClient.ts
+++ b/src/core/worker/WorkerClient.ts
@@ -14,13 +14,13 @@ export class WorkerClient {
private isInitialized = false;
private messageHandlers: Map void>;
private gameUpdateCallback?: (
- update: GameUpdateViewData | ErrorUpdate
+ update: GameUpdateViewData | ErrorUpdate,
) => void;
constructor(
private gameID: GameID,
private gameConfig: GameConfig,
- private clientID: ClientID
+ private clientID: ClientID,
) {
this.worker = new Worker(new URL("./Worker.worker.ts", import.meta.url));
this.messageHandlers = new Map();
@@ -28,7 +28,7 @@ export class WorkerClient {
// Set up global message handler
this.worker.addEventListener(
"message",
- this.handleWorkerMessage.bind(this)
+ this.handleWorkerMessage.bind(this),
);
}
@@ -135,7 +135,7 @@ export class WorkerClient {
playerInteraction(
playerID: PlayerID,
x: number,
- y: number
+ y: number,
): Promise {
return new Promise((resolve, reject) => {
if (!this.isInitialized) {
diff --git a/src/server/GameManager.ts b/src/server/GameManager.ts
index 0e0c6d80e..49de68163 100644
--- a/src/server/GameManager.ts
+++ b/src/server/GameManager.ts
@@ -52,7 +52,7 @@ export class GameManager {
disableBots: false,
disableNPCs: false,
creativeMode: false,
- })
+ }),
);
return id;
}
@@ -60,7 +60,7 @@ export class GameManager {
hasActiveGame(gameID: GameID): boolean {
const game = this.games
.filter(
- (g) => g.phase() == GamePhase.Lobby || g.phase() == GamePhase.Active
+ (g) => g.phase() == GamePhase.Lobby || g.phase() == GamePhase.Active,
)
.find((g) => g.id == gameID);
return game != null;
@@ -93,7 +93,7 @@ export class GameManager {
disableBots: false,
disableNPCs: false,
creativeMode: false,
- })
+ }),
);
}
diff --git a/src/server/Server.ts b/src/server/Server.ts
index 1931b2d31..a81464a0a 100644
--- a/src/server/Server.ts
+++ b/src/server/Server.ts
@@ -134,7 +134,7 @@ wss.on("connection", (ws, req) => {
ws.on("message", (message: string) => {
try {
const clientMsg: ClientMessage = ClientMessageSchema.parse(
- JSON.parse(message)
+ JSON.parse(message),
);
if (clientMsg.type == "join") {
const forwarded = req.headers["x-forwarded-for"];
@@ -147,7 +147,7 @@ wss.on("connection", (ws, req) => {
const { isValid, error } = validateUsername(clientMsg.username);
if (!isValid) {
console.log(
- `game ${clientMsg.gameID}, client ${clientMsg.clientID} received invalid username, ${error}`
+ `game ${clientMsg.gameID}, client ${clientMsg.clientID} received invalid username, ${error}`,
);
return;
}
@@ -158,10 +158,10 @@ wss.on("connection", (ws, req) => {
clientMsg.persistentID,
ip,
clientMsg.username,
- ws
+ ws,
),
clientMsg.gameID,
- clientMsg.lastTurn
+ clientMsg.lastTurn,
);
}
if (clientMsg.type == "log") {