Enable various eslint rules (#1773)

## Description:

Enable various eslint rules.

## Please complete the following:

- [x] I have added screenshots for all UI updates
- [x] I process any text displayed to the user through translateText()
and I've added it to the en.json file
- [x] I have added relevant tests to the test directory
- [x] I confirm I have thoroughly tested these changes and take full
responsibility for any bugs introduced
This commit is contained in:
Scott Anderson
2025-08-11 22:14:00 -04:00
committed by GitHub
parent 8a41919ed7
commit ce49599229
109 changed files with 471 additions and 460 deletions
+3 -3
View File
@@ -1,8 +1,8 @@
export type GameEvent = object;
export interface EventConstructor<T extends GameEvent = GameEvent> {
new (...args: any[]): T;
}
export type EventConstructor<T extends GameEvent = GameEvent> = new (
...args: any[]
) => T;
export class EventBus {
private listeners: Map<EventConstructor, Array<(event: GameEvent) => void>> =
+1 -1
View File
@@ -198,7 +198,7 @@ export class GameRunner {
canTarget: player.canTarget(other),
sharedBorder: player.sharesBorderWith(other),
};
const alliance = player.allianceWith(other as Player);
const alliance = player.allianceWith(other);
if (alliance) {
actions.interaction.allianceExpiresAt = alliance.expiresAt();
}
+3 -3
View File
@@ -4,9 +4,9 @@ export class PseudoRandom {
private state1: number;
// Keep these variables to maintain the exact same interface
private m: number = 0x80000000; // 2**31
private a: number = 1103515245;
private c: number = 12345;
private m = 0x80000000; // 2**31
private a = 1103515245;
private c = 12345;
private state: number;
private static readonly POW36_8 = Math.pow(36, 8); // Pre-compute 36^8
+8 -8
View File
@@ -26,7 +26,7 @@ export enum GameEnv {
Prod,
}
export interface ServerConfig {
export type ServerConfig = {
turnIntervalMs(): number;
gameCreationRate(): number;
lobbyMaxPlayers(
@@ -62,14 +62,14 @@ export interface ServerConfig {
cloudflareCredsPath(): string;
stripePublishableKey(): string;
allowedFlares(): string[] | undefined;
}
};
export interface NukeMagnitude {
export type NukeMagnitude = {
inner: number;
outer: number;
}
};
export interface Config {
export type Config = {
samHittingChance(): number;
samWarheadHittingChance(): number;
spawnImmunityDuration(): Tick;
@@ -170,9 +170,9 @@ export interface Config {
structureMinDist(): number;
isReplay(): boolean;
allianceExtensionPromptOffset(): number;
}
};
export interface Theme {
export type Theme = {
teamColor(team: Team): Colord;
territoryColor(playerInfo: PlayerView): Colord;
specialBuildingColor(playerInfo: PlayerView): Colord;
@@ -190,4 +190,4 @@ export interface Theme {
allyColor(): Colord;
enemyColor(): Colord;
spawnHighlightColor(): Colord;
}
};
+1 -1
View File
@@ -12,7 +12,7 @@ export let cachedSC: ServerConfig | null = null;
export async function getConfig(
gameConfig: GameConfig,
userSettings: UserSettings | null,
isReplay: boolean = false,
isReplay = false,
): Promise<Config> {
const sc = await getServerConfigFromClient();
switch (sc.env()) {
+3 -3
View File
@@ -18,7 +18,7 @@ const malusForRetreat = 25;
export class AttackExecution implements Execution {
private breakAlliance = false;
private wasAlliedAtInit = false; // Store alliance state at initialization
private active: boolean = true;
private active = true;
private toConquer = new FlatBinaryHeap();
private random = new PseudoRandom(123);
@@ -34,7 +34,7 @@ export class AttackExecution implements Execution {
private _owner: Player,
private _targetID: PlayerID | null,
private sourceTile: TileRef | null = null,
private removeTroops: boolean = true,
private removeTroops = true,
) {}
public targetID(): PlayerID | null {
@@ -69,7 +69,7 @@ export class AttackExecution implements Execution {
}
if (this.target && this.target.isPlayer()) {
const targetPlayer = this.target as Player;
const targetPlayer = this.target;
if (
targetPlayer.type() !== PlayerType.Bot &&
this._owner.type() !== PlayerType.Bot
+2 -2
View File
@@ -5,7 +5,7 @@ import { TrainStationExecution } from "./TrainStationExecution";
export class CityExecution implements Execution {
private mg: Game;
private city: Unit | null = null;
private active: boolean = true;
private active = true;
constructor(
private player: Player,
@@ -48,7 +48,7 @@ export class CityExecution implements Execution {
createStation(): void {
if (this.city !== null) {
const nearbyFactory = this.mg.hasUnitNearby(
this.city.tile()!,
this.city.tile(),
this.mg.config().trainStationMaxRange(),
UnitType.Factory,
this.player.id(),
+1 -1
View File
@@ -20,7 +20,7 @@ import { WarshipExecution } from "./WarshipExecution";
export class ConstructionExecution implements Execution {
private construction: Unit | null = null;
private active: boolean = true;
private active = true;
private mg: Game;
private ticksUntilComplete: Tick;
+1 -1
View File
@@ -5,7 +5,7 @@ import { ShellExecution } from "./ShellExecution";
export class DefensePostExecution implements Execution {
private mg: Game;
private post: Unit | null = null;
private active: boolean = true;
private active = true;
private target: Unit | null = null;
private lastShellAttack = 0;
+1 -1
View File
@@ -1,7 +1,7 @@
import { Execution, Game, MessageType, Player } from "../game/Game";
export class DeleteUnitExecution implements Execution {
private active: boolean = true;
private active = true;
private mg: Game;
constructor(
+2 -2
View File
@@ -4,7 +4,7 @@ import { TrainStationExecution } from "./TrainStationExecution";
export class FactoryExecution implements Execution {
private factory: Unit | null = null;
private active: boolean = true;
private active = true;
private game: Game;
constructor(
private player: Player,
@@ -47,7 +47,7 @@ export class FactoryExecution implements Execution {
createStation(): void {
if (this.factory !== null) {
const structures = this.game.nearbyUnits(
this.factory.tile()!,
this.factory.tile(),
this.game.config().trainStationMaxRange(),
[UnitType.City, UnitType.Port, UnitType.Factory],
);
+1 -1
View File
@@ -31,7 +31,7 @@ export class MirvExecution implements Execution {
private separateDst: TileRef;
private speed: number = -1;
private speed = -1;
constructor(
private player: Player,
+1 -1
View File
@@ -28,7 +28,7 @@ export class NukeExecution implements Execution {
private player: Player,
private dst: TileRef,
private src?: TileRef | null,
private speed: number = -1,
private speed = -1,
private waitTicks = 0,
) {}
+3 -3
View File
@@ -28,11 +28,11 @@ export class PlayerExecution implements Execution {
tick(ticks: number) {
this.player.decayRelations();
this.player.units().forEach((u) => {
const tileOwner = this.mg!.owner(u.tile());
const tileOwner = this.mg.owner(u.tile());
if (u.info().territoryBound) {
if (tileOwner.isPlayer()) {
if (tileOwner !== this.player) {
this.mg!.player(tileOwner.id()).captureUnit(u);
this.mg.player(tileOwner.id()).captureUnit(u);
}
} else {
u.delete();
@@ -218,7 +218,7 @@ export class PlayerExecution implements Execution {
}
let largestNeighborAttack: Player | null = null;
let largestTroopCount: number = 0;
let largestTroopCount = 0;
for (const id of neighborsIDs) {
const neighbor = this.mg.playerBySmallID(id);
if (!neighbor.isPlayer() || this.player.isFriendly(neighbor)) {
+1 -1
View File
@@ -90,7 +90,7 @@ export class PortExecution implements Execution {
createStation(): void {
if (this.port !== null) {
const nearbyFactory = this.mg.hasUnitNearby(
this.port.tile()!,
this.port.tile(),
this.mg.config().trainStationMaxRange(),
UnitType.Factory,
this.player.id(),
+4 -4
View File
@@ -5,10 +5,10 @@ import { Railroad } from "../game/Railroad";
export class RailroadExecution implements Execution {
private mg: Game;
private active: boolean = true;
private headIndex: number = 0;
private tailIndex: number = 0;
private increment: number = 3;
private active = true;
private headIndex = 0;
private tailIndex = 0;
private increment = 3;
private railTiles: RailTile[] = [];
constructor(private railRoad: Railroad) {
this.tailIndex = railRoad.tiles.length;
+1 -1
View File
@@ -128,7 +128,7 @@ class SAMTargetingSystem {
export class SAMLauncherExecution implements Execution {
private mg: Game;
private active: boolean = true;
private active = true;
// As MIRV go very fast we have to detect them very early but we only
// shoot the one targeting very close (MIRVWarheadProtectionRadius)
+1 -1
View File
@@ -16,7 +16,7 @@ export class SAMMissileExecution implements Execution {
private pathFinder: AirPathFinder;
private SAMMissile: Unit | undefined;
private mg: Game;
private speed: number = 0;
private speed = 0;
constructor(
private spawn: TileRef,
+1 -1
View File
@@ -8,7 +8,7 @@ export class ShellExecution implements Execution {
private pathFinder: AirPathFinder;
private shell: Unit | undefined;
private mg: Game;
private destroyAtTick: number = -1;
private destroyAtTick = -1;
private random: PseudoRandom;
constructor(
+1 -1
View File
@@ -5,7 +5,7 @@ import { PlayerExecution } from "./PlayerExecution";
import { getSpawnTiles } from "./Util";
export class SpawnExecution implements Execution {
active: boolean = true;
active = true;
private mg: Game;
constructor(
+3 -3
View File
@@ -16,13 +16,13 @@ export class TrainExecution implements Execution {
private mg: Game | null = null;
private train: Unit | null = null;
private cars: Unit[] = [];
private hasCargo: boolean = false;
private currentTile: number = 0;
private hasCargo = false;
private currentTile = 0;
private spacing = 2;
private usedTiles: TileRef[] = []; // used for cars behind
private stations: TrainStation[] = [];
private currentRailroad: OrientedRailroad | null = null;
private speed: number = 2;
private speed = 2;
constructor(
private railNetwork: RailNetwork,
+5 -5
View File
@@ -5,12 +5,12 @@ import { TrainExecution } from "./TrainExecution";
export class TrainStationExecution implements Execution {
private mg: Game;
private active: boolean = true;
private active = true;
private random: PseudoRandom;
private station: TrainStation | null = null;
private numCars: number = 5;
private lastSpawnTick: number = 0;
private ticksCooldown: number = 10; // Minimum cooldown between two trains
private numCars = 5;
private lastSpawnTick = 0;
private ticksCooldown = 10; // Minimum cooldown between two trains
constructor(
private unit: Unit,
private spawnTrains?: boolean, // If set, the station will spawn trains
@@ -50,7 +50,7 @@ export class TrainStationExecution implements Execution {
private shouldSpawnTrain(clusterSize: number): boolean {
const spawnRate = this.mg.config().trainSpawnRate(clusterSize);
for (let i = 0; i < this.unit!.level(); i++) {
for (let i = 0; i < this.unit.level(); i++) {
if (this.random.chance(spawnRate)) {
return true;
}
+5 -5
View File
@@ -79,7 +79,7 @@ export class WarshipExecution implements Execution {
const patrolRangeSquared = this.mg.config().warshipPatrolRange() ** 2;
const ships = this.mg.nearbyUnits(
this.warship.tile()!,
this.warship.tile(),
this.mg.config().warshipTargettingRange(),
[UnitType.TransportShip, UnitType.Warship, UnitType.TradeShip],
);
@@ -238,11 +238,11 @@ export class WarshipExecution implements Execution {
return false;
}
randomTile(allowShoreline: boolean = false): TileRef | undefined {
randomTile(allowShoreline = false): TileRef | undefined {
let warshipPatrolRange = this.mg.config().warshipPatrolRange();
const maxAttemptBeforeExpand: number = 500;
let attempts: number = 0;
let expandCount: number = 0;
const maxAttemptBeforeExpand = 500;
let attempts = 0;
let expandCount = 0;
while (expandCount < 3) {
const x =
this.mg.x(this.warship.patrolTile()!) +
+2 -2
View File
@@ -1,8 +1,8 @@
import { Game, MutableAlliance, Player, Tick } from "./Game";
export class AllianceImpl implements MutableAlliance {
private extensionRequestedRequestor_: boolean = false;
private extensionRequestedRecipient_: boolean = false;
private extensionRequestedRequestor_ = false;
private extensionRequestedRecipient_ = false;
private expiresAt_: Tick;
+4 -4
View File
@@ -2,13 +2,13 @@ import { GameMapType } from "./Game";
import { GameMapLoader, MapData } from "./GameMapLoader";
import { MapManifest } from "./TerrainMapLoader";
export interface BinModule {
export type BinModule = {
default: string;
}
};
interface NationMapModule {
type NationMapModule = {
default: MapManifest;
}
};
export class BinaryLoaderGameMapLoader implements GameMapLoader {
private maps: Map<GameMapType, MapData>;
+42 -42
View File
@@ -26,10 +26,10 @@ export type GameUpdates = {
[K in GameUpdateType]: UpdateTypeMap<K>[];
};
export interface MapPos {
export type MapPos = {
x: number;
y: number;
}
};
export enum Difficulty {
Easy = "Easy",
@@ -141,7 +141,7 @@ export enum GameMode {
Team = "Team",
}
export interface UnitInfo {
export type UnitInfo = {
cost: (player: Player) => Gold;
// Determines if its owner changes when its tile is conquered.
territoryBound: boolean;
@@ -151,7 +151,7 @@ export interface UnitInfo {
upgradable?: boolean;
canBuildTrainStation?: boolean;
experimental?: boolean;
}
};
export enum UnitType {
TransportShip = "Transport",
@@ -191,15 +191,15 @@ export function isStructureType(type: UnitType): boolean {
return _structureTypes.has(type);
}
export interface OwnerComp {
export type OwnerComp = {
owner: Player;
}
};
export type TrajectoryTile = {
tile: TileRef;
targetable: boolean;
};
export interface UnitParamsMap {
export type UnitParamsMap = {
[UnitType.TransportShip]: {
troops?: number;
destination?: TileRef;
@@ -253,7 +253,7 @@ export interface UnitParamsMap {
};
[UnitType.Construction]: Record<string, never>;
}
};
// Type helper to get params type for a specific unit type
export type UnitParams<T extends UnitType> = UnitParamsMap[T];
@@ -320,14 +320,14 @@ export enum PlayerType {
FakeHuman = "FAKEHUMAN",
}
export interface Execution {
export type Execution = {
isActive(): boolean;
activeDuringSpawnPhase(): boolean;
init(mg: Game, ticks: number): void;
tick(ticks: number): void;
}
};
export interface Attack {
export type Attack = {
id(): string;
retreating(): boolean;
retreated(): boolean;
@@ -346,25 +346,25 @@ export interface Attack {
clearBorder(): void;
borderSize(): number;
averagePosition(): Cell | null;
}
};
export interface AllianceRequest {
export type AllianceRequest = {
accept(): void;
reject(): void;
requestor(): Player;
recipient(): Player;
createdAt(): Tick;
}
};
export interface Alliance {
export type Alliance = {
requestor(): Player;
recipient(): Player;
createdAt(): Tick;
expiresAt(): Tick;
other(player: Player): Player;
}
};
export interface MutableAlliance extends Alliance {
export type MutableAlliance = {
expire(): void;
other(player: Player): Player;
bothAgreedToExtend(): boolean;
@@ -372,7 +372,7 @@ export interface MutableAlliance extends Alliance {
id(): number;
extend(): void;
onlyOneAgreedToExtend(): boolean;
}
} & Alliance;
export class PlayerInfo {
public readonly clan: string | null;
@@ -406,7 +406,7 @@ export function isUnit(unit: unknown): unit is Unit {
);
}
export interface Unit {
export type Unit = {
isUnit(): this is Unit;
// Common properties.
@@ -480,22 +480,22 @@ export interface Unit {
// Warships
setPatrolTile(tile: TileRef): void;
patrolTile(): TileRef | undefined;
}
};
export interface TerraNullius {
export type TerraNullius = {
isPlayer(): false;
id(): null;
clientID(): ClientID;
smallID(): number;
}
};
export interface Embargo {
export type Embargo = {
createdAt: Tick;
isTemporary: boolean;
target: PlayerID;
}
};
export interface Player {
export type Player = {
// Basic Info
smallID(): number;
info(): PlayerInfo;
@@ -629,9 +629,9 @@ export interface Player {
tradingPorts(port: Unit): Unit[];
// WARNING: this operation is expensive.
bestTransportShipSpawn(tile: TileRef): TileRef | false;
}
};
export interface Game extends GameMap {
export type Game = {
// Map & Dimensions
isOnMap(cell: Cell): boolean;
width(): number;
@@ -715,33 +715,33 @@ export interface Game extends GameMap {
addUpdate(update: GameUpdate): void;
railNetwork(): RailNetwork;
conquerPlayer(conqueror: Player, conquered: Player): void;
}
} & GameMap;
export interface PlayerActions {
export type PlayerActions = {
canAttack: boolean;
buildableUnits: BuildableUnit[];
canSendEmojiAllPlayers: boolean;
interaction?: PlayerInteraction;
}
};
export interface BuildableUnit {
export type BuildableUnit = {
canBuild: TileRef | false;
// unit id of the existing unit that can be upgraded, or false if it cannot be upgraded.
canUpgrade: number | false;
type: UnitType;
cost: Gold;
}
};
export interface PlayerProfile {
export type PlayerProfile = {
relations: Record<number, Relation>;
alliances: number[];
}
};
export interface PlayerBorderTiles {
export type PlayerBorderTiles = {
borderTiles: ReadonlySet<TileRef>;
}
};
export interface PlayerInteraction {
export type PlayerInteraction = {
sharedBorder: boolean;
canSendEmoji: boolean;
canSendAllianceRequest: boolean;
@@ -751,14 +751,14 @@ export interface PlayerInteraction {
canDonateTroops: boolean;
canEmbargo: boolean;
allianceExpiresAt?: Tick;
}
};
export interface EmojiMessage {
export type EmojiMessage = {
message: string;
senderID: number;
recipientID: number | typeof AllPlayers;
createdAt: Tick;
}
};
export enum MessageType {
ATTACK_FAILED,
@@ -832,8 +832,8 @@ export function getMessageCategory(messageType: MessageType): MessageCategory {
return MESSAGE_TYPE_CATEGORIES[messageType];
}
export interface NameViewData {
export type NameViewData = {
x: number;
y: number;
size: number;
}
};
+1 -1
View File
@@ -82,7 +82,7 @@ export class GameImpl implements Game {
private _railNetwork: RailNetwork = createRailNetwork(this);
// Used to assign unique IDs to each new alliance
private nextAllianceID: number = 0;
private nextAllianceID = 0;
constructor(
private _humans: PlayerInfo[],
+7 -7
View File
@@ -3,7 +3,7 @@ import { Cell, TerrainType } from "./Game";
export type TileRef = number;
export type TileUpdate = bigint;
export interface GameMap {
export type GameMap = {
ref(x: number, y: number): TileRef;
isValidRef(ref: TileRef): boolean;
x(ref: TileRef): number;
@@ -48,7 +48,7 @@ export interface GameMap {
updateTile(tu: TileUpdate): TileRef;
numTilesWithFallout(): number;
}
};
export class GameMapImpl implements GameMap {
private _numTilesWithFallout = 0;
@@ -341,7 +341,7 @@ export class GameMapImpl implements GameMap {
export function euclDistFN(
root: TileRef,
dist: number,
center: boolean = false,
center = false,
): (gm: GameMap, tile: TileRef) => boolean {
const dist2 = dist * dist;
if (!center) {
@@ -364,7 +364,7 @@ export function euclDistFN(
export function manhattanDistFN(
root: TileRef,
dist: number,
center: boolean = false,
center = false,
): (gm: GameMap, tile: TileRef) => boolean {
if (!center) {
return (gm: GameMap, n: TileRef) => gm.manhattanDist(root, n) <= dist;
@@ -382,7 +382,7 @@ export function manhattanDistFN(
export function rectDistFN(
root: TileRef,
dist: number,
center: boolean = false,
center = false,
): (gm: GameMap, tile: TileRef) => boolean {
if (!center) {
return (gm: GameMap, n: TileRef) => {
@@ -415,7 +415,7 @@ function isInIsometricTile(
export function isometricDistFN(
root: TileRef,
dist: number,
center: boolean = false,
center = false,
): (gm: GameMap, tile: TileRef) => boolean {
if (!center) {
return (gm: GameMap, n: TileRef) => gm.manhattanDist(root, n) <= dist;
@@ -437,7 +437,7 @@ export function isometricDistFN(
export function hexDistFN(
root: TileRef,
dist: number,
center: boolean = false,
center = false,
): (gm: GameMap, tile: TileRef) => boolean {
if (!center) {
return (gm: GameMap, n: TileRef) => {
+4 -4
View File
@@ -1,13 +1,13 @@
import { GameMapType } from "./Game";
import { MapManifest } from "./TerrainMapLoader";
export interface GameMapLoader {
export type GameMapLoader = {
getMapData(map: GameMapType): MapData;
}
};
export interface MapData {
export type MapData = {
mapBin: () => Promise<Uint8Array>;
miniMapBin: () => Promise<Uint8Array>;
manifest: () => Promise<MapManifest>;
webpPath: () => Promise<string>;
}
};
+44 -44
View File
@@ -14,17 +14,17 @@ import {
} from "./Game";
import { TileRef, TileUpdate } from "./GameMap";
export interface GameUpdateViewData {
export type GameUpdateViewData = {
tick: number;
updates: GameUpdates;
packedTileUpdates: BigUint64Array;
playerNameViewData: Record<string, NameViewData>;
}
};
export interface ErrorUpdate {
export type ErrorUpdate = {
errMsg: string;
stack?: string;
}
};
export enum GameUpdateType {
Tile,
@@ -67,13 +67,13 @@ export type GameUpdate =
| RailroadUpdate
| ConquestUpdate;
export interface BonusEventUpdate {
export type BonusEventUpdate = {
type: GameUpdateType.BonusEvent;
player: PlayerID;
tile: TileRef;
gold: number;
troops: number;
}
};
export enum RailType {
VERTICAL,
@@ -84,30 +84,30 @@ export enum RailType {
BOTTOM_RIGHT,
}
export interface RailTile {
export type RailTile = {
tile: TileRef;
railType: RailType;
}
};
export interface RailroadUpdate {
export type RailroadUpdate = {
type: GameUpdateType.RailroadEvent;
isActive: boolean;
railTiles: RailTile[];
}
};
export interface ConquestUpdate {
export type ConquestUpdate = {
type: GameUpdateType.ConquestEvent;
conquerorId: PlayerID;
conqueredId: PlayerID;
gold: Gold;
}
};
export interface TileUpdateWrapper {
export type TileUpdateWrapper = {
type: GameUpdateType.Tile;
update: TileUpdate;
}
};
export interface UnitUpdate {
export type UnitUpdate = {
type: GameUpdateType.Unit;
unitType: UnitType;
troops: number;
@@ -130,17 +130,17 @@ export interface UnitUpdate {
hasTrainStation: boolean;
trainType?: TrainType; // Only for trains
loaded?: boolean; // Only for trains
}
};
export interface AttackUpdate {
export type AttackUpdate = {
attackerID: number;
targetID: number;
troops: number;
id: string;
retreating: boolean;
}
};
export interface PlayerUpdate {
export type PlayerUpdate = {
type: GameUpdateType.Player;
nameViewData?: NameViewData;
clientID: ClientID | null;
@@ -166,65 +166,65 @@ export interface PlayerUpdate {
alliances: AllianceView[];
hasSpawned: boolean;
betrayals?: bigint;
}
};
export interface AllianceView {
export type AllianceView = {
id: number;
other: PlayerID;
createdAt: Tick;
expiresAt: Tick;
}
};
export interface AllianceRequestUpdate {
export type AllianceRequestUpdate = {
type: GameUpdateType.AllianceRequest;
requestorID: number;
recipientID: number;
createdAt: Tick;
}
};
export interface AllianceRequestReplyUpdate {
export type AllianceRequestReplyUpdate = {
type: GameUpdateType.AllianceRequestReply;
request: AllianceRequestUpdate;
accepted: boolean;
}
};
export interface BrokeAllianceUpdate {
export type BrokeAllianceUpdate = {
type: GameUpdateType.BrokeAlliance;
traitorID: number;
betrayedID: number;
}
};
export interface AllianceExpiredUpdate {
export type AllianceExpiredUpdate = {
type: GameUpdateType.AllianceExpired;
player1ID: number;
player2ID: number;
}
};
export interface AllianceExtensionUpdate {
export type AllianceExtensionUpdate = {
type: GameUpdateType.AllianceExtension;
playerID: number;
allianceID: number;
}
};
export interface TargetPlayerUpdate {
export type TargetPlayerUpdate = {
type: GameUpdateType.TargetPlayer;
playerID: number;
targetID: number;
}
};
export interface EmojiUpdate {
export type EmojiUpdate = {
type: GameUpdateType.Emoji;
emoji: EmojiMessage;
}
};
export interface DisplayMessageUpdate {
export type DisplayMessageUpdate = {
type: GameUpdateType.DisplayEvent;
message: string;
messageType: MessageType;
goldAmount?: bigint;
playerID: number | null;
params?: Record<string, string | number>;
}
};
export type DisplayChatMessageUpdate = {
type: GameUpdateType.DisplayChatEvent;
@@ -236,22 +236,22 @@ export type DisplayChatMessageUpdate = {
recipient: string;
};
export interface WinUpdate {
export type WinUpdate = {
type: GameUpdateType.Win;
allPlayersStats: AllPlayersStats;
winner: Winner;
}
};
export interface HashUpdate {
export type HashUpdate = {
type: GameUpdateType.Hash;
tick: Tick;
hash: number;
}
};
export interface UnitIncomingUpdate {
export type UnitIncomingUpdate = {
type: GameUpdateType.UnitIncoming;
unitID: number;
message: string;
messageType: MessageType;
playerID: number;
}
};
+3 -3
View File
@@ -39,10 +39,10 @@ import { UserSettings } from "./UserSettings";
const userSettings: UserSettings = new UserSettings();
interface PlayerCosmetics {
type PlayerCosmetics = {
pattern?: string | undefined;
flag?: string | undefined;
}
};
export class UnitView {
public _wasUpdated = true;
@@ -106,7 +106,7 @@ export class UnitView {
return this.data.pos;
}
owner(): PlayerView {
return this.gameView.playerBySmallID(this.data.ownerID)! as PlayerView;
return this.gameView.playerBySmallID(this.data.ownerID) as PlayerView;
}
isActive(): boolean {
return this.data.isActive;
+4 -4
View File
@@ -53,10 +53,10 @@ import {
} from "./TransportShipUtils";
import { UnitImpl } from "./UnitImpl";
interface Target {
type Target = {
tick: Tick;
target: Player;
}
};
class Donation {
constructor(
@@ -66,7 +66,7 @@ class Donation {
}
export class PlayerImpl implements Player {
public _lastTileChange: number = 0;
public _lastTileChange = 0;
public _pseudo_random: PseudoRandom;
private _gold: bigint;
@@ -278,7 +278,7 @@ export class PlayerImpl implements Player {
}
tiles(): ReadonlySet<TileRef> {
return new Set(this._tiles.values()) as Set<TileRef>;
return new Set(this._tiles.values());
}
borderTiles(): ReadonlySet<TileRef> {
+2 -2
View File
@@ -1,8 +1,8 @@
import { Unit } from "./Game";
import { TrainStation } from "./TrainStation";
export interface RailNetwork {
export type RailNetwork = {
connectStation(station: TrainStation): void;
removeStation(unit: Unit): void;
findStationsPath(from: TrainStation, to: TrainStation): TrainStation[];
}
};
+5 -5
View File
@@ -13,12 +13,12 @@ import { Cluster, TrainStation, TrainStationMapAdapter } from "./TrainStation";
* but it would be expensive to look through the graph to find a station.
* This class stores the existing stations for quick access
*/
export interface StationManager {
export type StationManager = {
addStation(station: TrainStation): void;
removeStation(station: TrainStation): void;
findStation(unit: Unit): TrainStation | null;
getAll(): Set<TrainStation>;
}
};
export class StationManagerImpl implements StationManager {
private stations: Set<TrainStation> = new Set();
@@ -43,10 +43,10 @@ export class StationManagerImpl implements StationManager {
}
}
export interface RailPathFinderService {
export type RailPathFinderService = {
findTilePath(from: TileRef, to: TileRef): TileRef[];
findStationsPath(from: TrainStation, to: TrainStation): TrainStation[];
}
};
class RailPathFinderServiceImpl implements RailPathFinderService {
constructor(private game: Game) {}
@@ -88,7 +88,7 @@ export function createRailNetwork(game: Game): RailNetwork {
}
export class RailNetworkImpl implements RailNetwork {
private maxConnectionDistance: number = 4;
private maxConnectionDistance = 4;
constructor(
private game: Game,
+2 -2
View File
@@ -2,7 +2,7 @@ import { AllPlayersStats } from "../Schemas";
import { NukeType, OtherUnitType, PlayerStats } from "../StatsSchemas";
import { Player, TerraNullius } from "./Game";
export interface Stats {
export type Stats = {
getPlayerStats(player: Player): PlayerStats | null;
stats(): AllPlayersStats;
@@ -93,4 +93,4 @@ export interface Stats {
// Player loses a unit of type
unitLose(player: Player, type: OtherUnitType): void;
}
};
+5 -5
View File
@@ -9,16 +9,16 @@ import { Railroad } from "./Railroad";
/**
* Handle train stops at various station types
*/
interface TrainStopHandler {
type TrainStopHandler = {
onStop(mg: Game, station: TrainStation, trainExecution: TrainExecution): void;
}
};
/**
* All stop handlers share the same logic for the time being
* Behavior to be defined
*/
class CityStopHandler implements TrainStopHandler {
private factor: bigint = BigInt(2);
private factor = BigInt(2);
onStop(
mg: Game,
station: TrainStation,
@@ -38,7 +38,7 @@ class CityStopHandler implements TrainStopHandler {
}
class PortStopHandler implements TrainStopHandler {
private factor: bigint = BigInt(2);
private factor = BigInt(2);
constructor(private random: PseudoRandom) {}
onStop(
mg: Game,
@@ -59,7 +59,7 @@ class PortStopHandler implements TrainStopHandler {
}
class FactoryStopHandler implements TrainStopHandler {
private factor: bigint = BigInt(2);
private factor = BigInt(2);
onStop(
mg: Game,
station: TrainStation,
+3 -3
View File
@@ -102,7 +102,7 @@ export function sourceDstOceanShore(
const srcTile = closestShoreFromPlayer(gm, src, tile);
let dstTile: TileRef | null = null;
if (dst.isPlayer()) {
dstTile = closestShoreFromPlayer(gm, dst as Player, tile);
dstTile = closestShoreFromPlayer(gm, dst, tile);
} else {
dstTile = closestShoreTN(gm, tile, 50);
}
@@ -113,7 +113,7 @@ export function targetTransportTile(gm: Game, tile: TileRef): TileRef | null {
const dst = gm.playerBySmallID(gm.ownerID(tile));
let dstTile: TileRef | null = null;
if (dst.isPlayer()) {
dstTile = closestShoreFromPlayer(gm, dst as Player, tile);
dstTile = closestShoreFromPlayer(gm, dst, tile);
} else {
dstTile = closestShoreTN(gm, tile, 50);
}
@@ -235,7 +235,7 @@ export function candidateShoreTiles(
extremumTiles.maxX,
extremumTiles.maxY,
...sampledTiles,
].filter(Boolean) as number[];
].filter(Boolean);
return candidates;
}
+5 -5
View File
@@ -21,7 +21,7 @@ export class UnitImpl implements Unit {
private _targetUnit: Unit | undefined;
private _health: bigint;
private _lastTile: TileRef;
private _retreating: boolean = false;
private _retreating = false;
private _targetedBySAM = false;
private _reachedTarget = false;
private _lastSetSafeFromPirates: number; // Only for trade ships
@@ -30,14 +30,14 @@ export class UnitImpl implements Unit {
private _troops: number;
// Number of missiles in cooldown, if empty all missiles are ready.
private _missileTimerQueue: number[] = [];
private _hasTrainStation: boolean = false;
private _hasTrainStation = false;
private _patrolTile: TileRef | undefined;
private _level: number = 1;
private _targetable: boolean = true;
private _level = 1;
private _targetable = true;
private _loaded: boolean | undefined;
private _trainType: TrainType | undefined;
// Nuke only
private _trajectoryIndex: number = 0;
private _trajectoryIndex = 0;
private _trajectory: TrajectoryTile[];
constructor(
+4 -4
View File
@@ -1,7 +1,7 @@
export interface AStar<NodeType> {
export type AStar<NodeType> = {
compute(): PathFindResultType;
reconstructPath(): NodeType[];
}
};
export enum PathFindResultType {
NextTile,
@@ -25,7 +25,7 @@ export type AStarResult<NodeType> =
type: PathFindResultType.PathNotFound;
};
export interface Point {
export type Point = {
x: number;
y: number;
}
};
+3 -3
View File
@@ -36,8 +36,8 @@ export class MiniAStar implements AStar<TileRef> {
private dst: TileRef,
iterations: number,
maxTries: number,
waterPath: boolean = true,
directionChangePenalty: number = 0,
waterPath = true,
directionChangePenalty = 0,
) {
const srcArray: TileRef[] = Array.isArray(src) ? src : [src];
const miniSrc = srcArray.map((srcPoint) =>
@@ -113,7 +113,7 @@ function fixExtremes(upscaled: Cell[], cellDst: Cell, cellSrc?: Cell): Cell[] {
return upscaled;
}
function upscalePath(path: Cell[], scaleFactor: number = 2): Cell[] {
function upscalePath(path: Cell[], scaleFactor = 2): Cell[] {
// Scale up each point
const scaledPath = path.map(
(point) => new Cell(point.x * scaleFactor, point.y * scaleFactor),
+4 -4
View File
@@ -14,7 +14,7 @@ export class ParabolaPathFinder {
computeControlPoints(
orig: TileRef,
dst: TileRef,
increment: number = 3,
increment = 3,
distanceBasedHeight = true,
) {
const p0 = { x: this.mg.x(orig), y: this.mg.y(orig) };
@@ -117,8 +117,8 @@ export class PathFinder {
public static Mini(
game: Game,
iterations: number,
waterPath: boolean = true,
maxTries: number = 20,
waterPath = true,
maxTries = 20,
) {
return new PathFinder(game, (curr: TileRef, dst: TileRef) => {
return new MiniAStar(
@@ -136,7 +136,7 @@ export class PathFinder {
nextTile(
curr: TileRef | null,
dst: TileRef | null,
dist: number = 1,
dist = 1,
): AStarResult<TileRef> {
if (curr === null) {
console.error("curr is null");
+3 -3
View File
@@ -4,12 +4,12 @@ import { AStar, PathFindResultType } from "./AStar";
/**
* Implement this interface with your graph to find paths with A*
*/
export interface GraphAdapter<NodeType> {
export type GraphAdapter<NodeType> = {
neighbors(node: NodeType): NodeType[];
cost(node: NodeType): number;
position(node: NodeType): { x: number; y: number };
isTraversable(from: NodeType, to: NodeType): boolean;
}
};
export class SerialAStar<NodeType> implements AStar<NodeType> {
private fwdOpenSet: FastPriorityQueue<{
@@ -37,7 +37,7 @@ export class SerialAStar<NodeType> implements AStar<NodeType> {
private iterations: number,
private maxTries: number,
private graph: GraphAdapter<NodeType>,
private directionChangePenalty: number = 0,
private directionChangePenalty = 0,
) {
this.fwdOpenSet = new FastPriorityQueue((a, b) => a.fScore < b.fScore);
this.bwdOpenSet = new FastPriorityQueue((a, b) => a.fScore < b.fScore);
+2 -2
View File
@@ -77,9 +77,9 @@ export class CubicBezierCurve {
* Useful to compute regular steps based on the curve rather than a t
*/
export class DistanceBasedBezierCurve extends CubicBezierCurve {
private totalDistance: number = 0;
private totalDistance = 0;
private cachedPoints: Point[] = [];
private currentIndex: number = 0;
private currentIndex = 0;
constructor(
p0: Point,
+32 -32
View File
@@ -26,91 +26,91 @@ export type WorkerMessageType =
| "transport_ship_spawn_result";
// Base interface for all messages
interface BaseWorkerMessage {
type BaseWorkerMessage = {
type: WorkerMessageType;
id?: string;
}
};
export interface HeartbeatMessage extends BaseWorkerMessage {
export type HeartbeatMessage = {
type: "heartbeat";
}
} & BaseWorkerMessage;
// Messages from main thread to worker
export interface InitMessage extends BaseWorkerMessage {
export type InitMessage = {
type: "init";
gameStartInfo: GameStartInfo;
clientID: ClientID;
}
} & BaseWorkerMessage;
export interface TurnMessage extends BaseWorkerMessage {
export type TurnMessage = {
type: "turn";
turn: Turn;
}
} & BaseWorkerMessage;
// Messages from worker to main thread
export interface InitializedMessage extends BaseWorkerMessage {
export type InitializedMessage = {
type: "initialized";
}
} & BaseWorkerMessage;
export interface GameUpdateMessage extends BaseWorkerMessage {
export type GameUpdateMessage = {
type: "game_update";
gameUpdate: GameUpdateViewData;
}
} & BaseWorkerMessage;
export interface PlayerActionsMessage extends BaseWorkerMessage {
export type PlayerActionsMessage = {
type: "player_actions";
playerID: PlayerID;
x: number;
y: number;
}
} & BaseWorkerMessage;
export interface PlayerActionsResultMessage extends BaseWorkerMessage {
export type PlayerActionsResultMessage = {
type: "player_actions_result";
result: PlayerActions;
}
} & BaseWorkerMessage;
export interface PlayerProfileMessage extends BaseWorkerMessage {
export type PlayerProfileMessage = {
type: "player_profile";
playerID: number;
}
} & BaseWorkerMessage;
export interface PlayerProfileResultMessage extends BaseWorkerMessage {
export type PlayerProfileResultMessage = {
type: "player_profile_result";
result: PlayerProfile;
}
} & BaseWorkerMessage;
export interface PlayerBorderTilesMessage extends BaseWorkerMessage {
export type PlayerBorderTilesMessage = {
type: "player_border_tiles";
playerID: PlayerID;
}
} & BaseWorkerMessage;
export interface PlayerBorderTilesResultMessage extends BaseWorkerMessage {
export type PlayerBorderTilesResultMessage = {
type: "player_border_tiles_result";
result: PlayerBorderTiles;
}
} & BaseWorkerMessage;
export interface AttackAveragePositionMessage extends BaseWorkerMessage {
export type AttackAveragePositionMessage = {
type: "attack_average_position";
playerID: number;
attackID: string;
}
} & BaseWorkerMessage;
export interface AttackAveragePositionResultMessage extends BaseWorkerMessage {
export type AttackAveragePositionResultMessage = {
type: "attack_average_position_result";
x: number | null;
y: number | null;
}
} & BaseWorkerMessage;
export interface TransportShipSpawnMessage extends BaseWorkerMessage {
export type TransportShipSpawnMessage = {
type: "transport_ship_spawn";
playerID: PlayerID;
targetTile: TileRef;
}
} & BaseWorkerMessage;
export interface TransportShipSpawnResultMessage extends BaseWorkerMessage {
export type TransportShipSpawnResultMessage = {
type: "transport_ship_spawn_result";
result: TileRef | false;
}
} & BaseWorkerMessage;
// Union types for type safety
export type MainThreadMessage =