From 5e9819a973e346e6c027c9d3d35a1f026efeee57 Mon Sep 17 00:00:00 2001 From: Scott Anderson <662325+scottanderson@users.noreply.github.com> Date: Sat, 12 Apr 2025 02:40:47 -0400 Subject: [PATCH] keep --- src/client/graphics/layers/BuildMenu.ts | 7 +-- src/client/graphics/layers/WinModal.ts | 4 +- src/core/GameRunner.ts | 10 +-- src/core/PseudoRandom.ts | 4 +- src/core/Util.ts | 10 +-- src/core/configuration/DefaultConfig.ts | 58 +++++++++-------- src/core/configuration/PastelTheme.ts | 14 +++-- src/core/configuration/PastelThemeDark.ts | 14 +++-- src/core/execution/AttackExecution.ts | 45 +++++++------- src/core/execution/BotExecution.ts | 8 +-- src/core/execution/BotSpawner.ts | 2 +- src/core/execution/CityExecution.ts | 8 +-- src/core/execution/ConstructionExecution.ts | 12 ++-- src/core/execution/DefensePostExecution.ts | 8 +-- src/core/execution/DonateGoldExecution.ts | 2 +- src/core/execution/DonateTroopExecution.ts | 2 +- src/core/execution/EmbargoExecution.ts | 2 +- src/core/execution/EmojiExecution.ts | 12 ++-- src/core/execution/FakeHumanExecution.ts | 69 +++++++++++---------- src/core/execution/MIRVExecution.ts | 15 ++--- 20 files changed, 161 insertions(+), 145 deletions(-) diff --git a/src/client/graphics/layers/BuildMenu.ts b/src/client/graphics/layers/BuildMenu.ts index 86ab4f8ce..3de88963d 100644 --- a/src/client/graphics/layers/BuildMenu.ts +++ b/src/client/graphics/layers/BuildMenu.ts @@ -295,10 +295,9 @@ export class BuildMenu extends LitElement implements Layer { if (this.game?.myPlayer() === null || this.playerActions === null) { return false; } - const unit = this.playerActions.buildableUnits.filter( - (u) => u.type === item.unitType, - ); - if (!unit) { + const buildableUnits = this.playerActions?.buildableUnits ?? []; + const unit = buildableUnits.filter((u) => u.type === item.unitType); + if (unit.length === 0) { return false; } return unit[0].canBuild; diff --git a/src/client/graphics/layers/WinModal.ts b/src/client/graphics/layers/WinModal.ts index d810556c2..e42c0dd53 100644 --- a/src/client/graphics/layers/WinModal.ts +++ b/src/client/graphics/layers/WinModal.ts @@ -230,7 +230,7 @@ export class WinModal extends LitElement implements Layer { this.eventBus.emit( new SendWinnerEvent(wu.winner as Team, wu.allPlayersStats, "team"), ); - if (wu.winner == this.game.myPlayer()?.team()) { + if (wu.winner === this.game.myPlayer()?.team()) { this._title = "Your team won!"; this.won = true; } else { @@ -248,7 +248,7 @@ export class WinModal extends LitElement implements Layer { new SendWinnerEvent(winnerClient, wu.allPlayersStats, "player"), ); } - if (winner == this.game.myPlayer()) { + if (winner === this.game.myPlayer()) { this._title = "You Won!"; this.won = true; } else { diff --git a/src/core/GameRunner.ts b/src/core/GameRunner.ts index 7b996151c..7240b674c 100644 --- a/src/core/GameRunner.ts +++ b/src/core/GameRunner.ts @@ -40,7 +40,7 @@ export async function createGameRunner( (p) => new PlayerInfo( p.flag, - p.clientID == clientID + p.clientID === clientID ? sanitize(p.username) : fixProfaneUsername(sanitize(p.username)), PlayerType.Human, @@ -122,19 +122,19 @@ export class GameRunner { return; } - if (this.game.inSpawnPhase() && this.game.ticks() % 2 == 0) { + if (this.game.inSpawnPhase() && this.game.ticks() % 2 === 0) { this.game .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)), ); } - if (this.game.ticks() < 3 || this.game.ticks() % 30 == 0) { + if (this.game.ticks() < 3 || this.game.ticks() % 30 === 0) { this.game.players().forEach((p) => { this.playerViewData[p.id()] = placeName(this.game, p); }); @@ -166,7 +166,7 @@ export class GameRunner { buildableUnits: Object.values(UnitType).map((u) => { return { type: u, - canBuild: player.canBuild(u, tile) != false, + canBuild: player.canBuild(u, tile) !== false, cost: this.game.config().unitInfo(u).cost(player), } as BuildableUnit; }), diff --git a/src/core/PseudoRandom.ts b/src/core/PseudoRandom.ts index 985de26fd..2f186cbfb 100644 --- a/src/core/PseudoRandom.ts +++ b/src/core/PseudoRandom.ts @@ -38,14 +38,14 @@ export class PseudoRandom { } randElement(arr: T[]): T { - if (arr.length == 0) { + if (arr.length === 0) { throw new Error("array must not be empty"); } return arr[this.nextInt(0, arr.length)]; } chance(odds: number): boolean { - return this.nextInt(0, odds) == 0; + return this.nextInt(0, odds) === 0; } shuffleArray(array: any[]) { diff --git a/src/core/Util.ts b/src/core/Util.ts index 62378ad5b..34f184d58 100644 --- a/src/core/Util.ts +++ b/src/core/Util.ts @@ -93,7 +93,7 @@ export function closestShoreFromPlayer( const shoreTiles = Array.from(player.borderTiles()).filter((t) => gm.isShore(t), ); - if (shoreTiles.length == 0) { + if (shoreTiles.length === 0) { return null; } @@ -117,7 +117,7 @@ function closestShoreTN( ) .filter((t) => gm.isShore(t)) .sort((a, b) => gm.manhattanDist(tile, a) - gm.manhattanDist(tile, b)); - if (tn.length == 0) { + if (tn.length === 0) { return null; } return tn[0]; @@ -274,12 +274,12 @@ export function createGameRecord( }; for (const turn of turns) { - if (turn.intents.length != 0 || turn.hash != undefined) { + if (turn.intents.length !== 0 || turn.hash !== undefined) { record.turns.push(turn); for (const intent of turn.intents) { - if (intent.type == "spawn") { + if (intent.type === "spawn") { for (const playerRecord of players) { - if (playerRecord.clientID == intent.clientID) { + if (playerRecord.clientID === intent.clientID) { playerRecord.username = intent.name; } } diff --git a/src/core/configuration/DefaultConfig.ts b/src/core/configuration/DefaultConfig.ts index 3afae7ce4..bbbd8302a 100644 --- a/src/core/configuration/DefaultConfig.ts +++ b/src/core/configuration/DefaultConfig.ts @@ -25,7 +25,7 @@ import { pastelThemeDark } from "./PastelThemeDark"; export abstract class DefaultServerConfig implements ServerConfig { region(): string { - if (this.env() == GameEnv.Dev) { + if (this.env() === GameEnv.Dev) { return "dev"; } return process.env.REGION ?? "undefined"; @@ -104,7 +104,7 @@ export abstract class DefaultServerConfig implements ServerConfig { return Math.random() < 0.2 ? 60 : 35; } // world belongs with the ~2 mils, but these amounts never made sense so I assume the insanity is intended. - if (map == GameMapType.World) { + if (map === GameMapType.World) { return Math.random() < 0.2 ? 150 : 60; } // default return for non specified map @@ -229,7 +229,7 @@ export class DefaultConfig implements Config { case UnitType.Warship: return { cost: (p: Player) => - p.type() == PlayerType.Human && this.infiniteGold() + p.type() === PlayerType.Human && this.infiniteGold() ? 0 : Math.min( 1_000_000, @@ -253,7 +253,7 @@ export class DefaultConfig implements Config { case UnitType.Port: return { cost: (p: Player) => - p.type() == PlayerType.Human && this.infiniteGold() + p.type() === PlayerType.Human && this.infiniteGold() ? 0 : Math.min( 1_000_000, @@ -268,19 +268,21 @@ export class DefaultConfig implements Config { case UnitType.AtomBomb: return { cost: (p: Player) => - p.type() == PlayerType.Human && this.infiniteGold() ? 0 : 750_000, + p.type() === PlayerType.Human && this.infiniteGold() ? 0 : 750_000, territoryBound: false, }; case UnitType.HydrogenBomb: return { cost: (p: Player) => - p.type() == PlayerType.Human && this.infiniteGold() ? 0 : 5_000_000, + p.type() === PlayerType.Human && this.infiniteGold() + ? 0 + : 5_000_000, territoryBound: false, }; case UnitType.MIRV: return { cost: (p: Player) => - p.type() == PlayerType.Human && this.infiniteGold() + p.type() === PlayerType.Human && this.infiniteGold() ? 0 : 25_000_000, territoryBound: false, @@ -298,14 +300,16 @@ export class DefaultConfig implements Config { case UnitType.MissileSilo: return { cost: (p: Player) => - p.type() == PlayerType.Human && this.infiniteGold() ? 0 : 1_000_000, + p.type() === PlayerType.Human && this.infiniteGold() + ? 0 + : 1_000_000, territoryBound: true, constructionDuration: this.instantBuild() ? 0 : 10 * 10, }; case UnitType.DefensePost: return { cost: (p: Player) => - p.type() == PlayerType.Human && this.infiniteGold() + p.type() === PlayerType.Human && this.infiniteGold() ? 0 : Math.min( 250_000, @@ -319,7 +323,7 @@ export class DefaultConfig implements Config { case UnitType.SAMLauncher: return { cost: (p: Player) => - p.type() == PlayerType.Human && this.infiniteGold() + p.type() === PlayerType.Human && this.infiniteGold() ? 0 : Math.min( 1_500_000 * 3, @@ -333,7 +337,7 @@ export class DefaultConfig implements Config { case UnitType.City: return { cost: (p: Player) => - p.type() == PlayerType.Human && this.infiniteGold() + p.type() === PlayerType.Human && this.infiniteGold() ? 0 : Math.min( 2_000_000, @@ -379,7 +383,7 @@ export class DefaultConfig implements Config { return 600 * 10; // 10 minutes. } percentageTilesOwnedToWin(): number { - if (this._gameConfig.gameMode == GameMode.Team) { + if (this._gameConfig.gameMode === GameMode.Team) { return 95; } return 80; @@ -388,7 +392,7 @@ export class DefaultConfig implements Config { return 3; } numSpawnPhaseTurns(): number { - return this._gameConfig.gameType == GameType.Singleplayer ? 100 : 300; + return this._gameConfig.gameType === GameType.Singleplayer ? 100 : 300; } numBots(): number { return this.bots(); @@ -433,7 +437,7 @@ export class DefaultConfig implements Config { gm.config().defensePostRange(), UnitType.DefensePost, )) { - if (dp.unit.owner() == defender) { + if (dp.unit.owner() === defender) { mag *= this.defensePostDefenseBonus(); speed *= this.defensePostDefenseBonus(); break; @@ -449,14 +453,14 @@ export class DefaultConfig implements Config { if (attacker.isPlayer() && defender.isPlayer()) { if ( - attacker.type() == PlayerType.Human && - defender.type() == PlayerType.Bot + attacker.type() === PlayerType.Human && + defender.type() === PlayerType.Bot ) { mag *= 0.8; } if ( - attacker.type() == PlayerType.FakeHuman && - defender.type() == PlayerType.Bot + attacker.type() === PlayerType.FakeHuman && + defender.type() === PlayerType.Bot ) { mag *= 0.8; } @@ -489,7 +493,7 @@ export class DefaultConfig implements Config { } else { return { attackerTroopLoss: - attacker.type() == PlayerType.Bot ? mag / 10 : mag / 5, + attacker.type() === PlayerType.Bot ? mag / 10 : mag / 5, defenderTroopLoss: 0, tilesPerTickUsed: within( (2000 * Math.max(10, speed)) / attackTroops, @@ -534,7 +538,7 @@ export class DefaultConfig implements Config { } attackAmount(attacker: Player, defender: Player | TerraNullius) { - if (attacker.type() == PlayerType.Bot) { + if (attacker.type() === PlayerType.Bot) { return attacker.troops() / 20; } else { return attacker.troops() / 5; @@ -542,10 +546,10 @@ export class DefaultConfig implements Config { } startManpower(playerInfo: PlayerInfo): number { - if (playerInfo.playerType == PlayerType.Bot) { + if (playerInfo.playerType === PlayerType.Bot) { return 10_000; } - if (playerInfo.playerType == PlayerType.FakeHuman) { + if (playerInfo.playerType === PlayerType.FakeHuman) { switch (this._gameConfig.difficulty) { case Difficulty.Easy: return 2_500 * (playerInfo?.nation?.strength ?? 1); @@ -562,16 +566,16 @@ export class DefaultConfig implements Config { maxPopulation(player: Player | PlayerView): number { const maxPop = - player.type() == PlayerType.Human && this.infiniteTroops() + player.type() === PlayerType.Human && this.infiniteTroops() ? 1_000_000_000 : 2 * (Math.pow(player.numTilesOwned(), 0.6) * 1000 + 50000) + player.units(UnitType.City).length * this.cityPopulationIncrease(); - if (player.type() == PlayerType.Bot) { + if (player.type() === PlayerType.Bot) { return maxPop / 2; } - if (player.type() == PlayerType.Human) { + if (player.type() === PlayerType.Human) { return maxPop; } @@ -595,11 +599,11 @@ export class DefaultConfig implements Config { const ratio = 1 - player.population() / max; toAdd *= ratio; - if (player.type() == PlayerType.Bot) { + if (player.type() === PlayerType.Bot) { toAdd *= 0.7; } - if (player.type() == PlayerType.FakeHuman) { + if (player.type() === PlayerType.FakeHuman) { switch (this._gameConfig.difficulty) { case Difficulty.Easy: toAdd *= 0.9; diff --git a/src/core/configuration/PastelTheme.ts b/src/core/configuration/PastelTheme.ts index 93fbeacc7..5af1253bd 100644 --- a/src/core/configuration/PastelTheme.ts +++ b/src/core/configuration/PastelTheme.ts @@ -37,26 +37,28 @@ export const pastelTheme = new (class implements Theme { private _spawnHighlightColor = colord({ r: 255, g: 213, b: 79 }); territoryColor(player: PlayerView): Colord { - if (player.team() == Team.Bot) { + if (player.team() === Team.Bot) { return botColor; } - if (player.team() == Team.Red) { + if (player.team() === Team.Red) { return red; } - if (player.team() == Team.Blue) { + if (player.team() === Team.Blue) { return blue; } - if (player.info().playerType == PlayerType.Human) { + if (player.info().playerType === PlayerType.Human) { return humanColors[simpleHash(player.id()) % humanColors.length]; } - if (player.info().playerType == PlayerType.Bot) { + if (player.info().playerType === PlayerType.Bot) { return botColors[simpleHash(player.id()) % botColors.length]; } return territoryColors[simpleHash(player.id()) % territoryColors.length]; } textColor(player: PlayerView): string { - return player.info().playerType == PlayerType.Human ? "#000000" : "#4D4D4D"; + return player.info().playerType === PlayerType.Human + ? "#000000" + : "#4D4D4D"; } specialBuildingColor(player: PlayerView): Colord { diff --git a/src/core/configuration/PastelThemeDark.ts b/src/core/configuration/PastelThemeDark.ts index ad318b5e2..c1ede37c0 100644 --- a/src/core/configuration/PastelThemeDark.ts +++ b/src/core/configuration/PastelThemeDark.ts @@ -37,26 +37,28 @@ export const pastelThemeDark = new (class implements Theme { private _spawnHighlightColor = colord({ r: 255, g: 213, b: 79 }); territoryColor(player: PlayerView): Colord { - if (player.team() == Team.Bot) { + if (player.team() === Team.Bot) { return botColor; } - if (player.team() == Team.Red) { + if (player.team() === Team.Red) { return red; } - if (player.team() == Team.Blue) { + if (player.team() === Team.Blue) { return blue; } - if (player.info().playerType == PlayerType.Human) { + if (player.info().playerType === PlayerType.Human) { return humanColors[simpleHash(player.id()) % humanColors.length]; } - if (player.info().playerType == PlayerType.Bot) { + if (player.info().playerType === PlayerType.Bot) { return botColors[simpleHash(player.id()) % botColors.length]; } return territoryColors[simpleHash(player.id()) % territoryColors.length]; } textColor(player: PlayerView): string { - return player.info().playerType == PlayerType.Human ? "#ffffff" : "#e6e6e6"; + return player.info().playerType === PlayerType.Human + ? "#ffffff" + : "#e6e6e6"; } specialBuildingColor(player: PlayerView): Colord { diff --git a/src/core/execution/AttackExecution.ts b/src/core/execution/AttackExecution.ts index 74e8f4951..6952a70e2 100644 --- a/src/core/execution/AttackExecution.ts +++ b/src/core/execution/AttackExecution.ts @@ -21,8 +21,8 @@ export class AttackExecution implements Execution { private active: boolean = true; private toConquer: PriorityQueue = new PriorityQueue((a: TileContainer, b: TileContainer) => { - if (a.priority == b.priority) { - if (a.tick == b.tick) { + if (a.priority === b.priority) { + if (a.tick === b.tick) { return 0; // return this.random.nextInt(-1, 1) } @@ -68,7 +68,7 @@ export class AttackExecution implements Execution { this.active = false; return; } - if (this._targetID != null && !mg.hasPlayer(this._targetID)) { + if (this._targetID !== null && !mg.hasPlayer(this._targetID)) { console.warn(`target ${this._targetID} not found`); this.active = false; return; @@ -76,22 +76,22 @@ export class AttackExecution implements Execution { this._owner = mg.player(this._ownerID); this.target = - this._targetID == this.mg.terraNullius().id() + this._targetID === this.mg.terraNullius().id() ? mg.terraNullius() : mg.player(this._targetID); if (this.target && this.target.isPlayer()) { const targetPlayer = this.target as Player; if ( - targetPlayer.type() != PlayerType.Bot && - this._owner.type() != PlayerType.Bot + targetPlayer.type() !== PlayerType.Bot && + this._owner.type() !== PlayerType.Bot ) { // Don't let bots embargo since they can't trade anyways. targetPlayer.addEmbargo(this._owner.id()); } } - if (this._owner == this.target) { + if (this._owner === this.target) { console.error(`Player ${this._owner} cannot attack itself`); this.active = false; return; @@ -108,7 +108,7 @@ export class AttackExecution implements Execution { return; } - if (this.startTroops == null) { + if (this.startTroops === null) { this.startTroops = this.mg .config() .attackAmount(this._owner, this.target); @@ -124,7 +124,7 @@ export class AttackExecution implements Execution { ); for (const incoming of this._owner.incomingAttacks()) { - if (incoming.attacker() == this.target) { + if (incoming.attacker() === this.target) { // Target has opposing attack, cancel them out if (incoming.troops() > this.attack.troops()) { incoming.setTroops(incoming.troops() - this.attack.troops()); @@ -139,9 +139,9 @@ export class AttackExecution implements Execution { } for (const outgoing of this._owner.outgoingAttacks()) { if ( - outgoing != this.attack && - outgoing.target() == this.attack.target() && - outgoing.sourceTile() == this.attack.sourceTile() + outgoing !== this.attack && + outgoing.target() === this.attack.target() && + outgoing.sourceTile() === this.attack.sourceTile() ) { // Existing attack on same target, add troops outgoing.setTroops(outgoing.troops() + this.attack.troops()); @@ -151,7 +151,7 @@ export class AttackExecution implements Execution { } } - if (this.sourceTile != null) { + if (this.sourceTile !== null) { this.addNeighbors(this.sourceTile); } else { this.refreshToConquer(); @@ -217,7 +217,7 @@ export class AttackExecution implements Execution { } const alliance = this._owner.allianceWith(this.target as Player); - if (this.breakAlliance && alliance != null) { + if (this.breakAlliance && alliance !== null) { this.breakAlliance = false; this._owner.breakAlliance(alliance); } @@ -245,7 +245,7 @@ export class AttackExecution implements Execution { return; } - if (this.toConquer.size() == 0) { + if (this.toConquer.size() === 0) { this.refreshToConquer(); this.retreat(); return; @@ -257,8 +257,8 @@ export class AttackExecution implements Execution { const onBorder = this.mg .neighbors(tileToConquer) - .filter((t) => this.mg.owner(t) == this._owner).length > 0; - if (this.mg.owner(tileToConquer) != this.target || !onBorder) { + .filter((t) => this.mg.owner(t) === this._owner).length > 0; + if (this.mg.owner(tileToConquer) !== this.target || !onBorder) { continue; } this.addNeighbors(tileToConquer); @@ -283,13 +283,16 @@ export class AttackExecution implements Execution { private addNeighbors(tile: TileRef) { for (const neighbor of this.mg.neighbors(tile)) { - if (this.mg.isWater(neighbor) || this.mg.owner(neighbor) != this.target) { + if ( + this.mg.isWater(neighbor) || + this.mg.owner(neighbor) !== this.target + ) { continue; } this.border.add(neighbor); let numOwnedByMe = this.mg .neighbors(neighbor) - .filter((t) => this.mg.owner(t) == this._owner).length; + .filter((t) => this.mg.owner(t) === this._owner).length; const dist = 0; if (numOwnedByMe > 2) { numOwnedByMe = 10; @@ -334,13 +337,13 @@ export class AttackExecution implements Execution { for (const tile of this.target.tiles()) { const borders = this.mg .neighbors(tile) - .some((t) => this.mg.owner(t) == this._owner); + .some((t) => this.mg.owner(t) === this._owner); if (borders) { this._owner.conquer(tile); } else { for (const neighbor of this.mg.neighbors(tile)) { const no = this.mg.owner(neighbor); - if (no.isPlayer() && no != this.target) { + if (no.isPlayer() && no !== this.target) { this.mg.player(no.id()).conquer(tile); break; } diff --git a/src/core/execution/BotExecution.ts b/src/core/execution/BotExecution.ts index f7321ef93..3e514c00e 100644 --- a/src/core/execution/BotExecution.ts +++ b/src/core/execution/BotExecution.ts @@ -36,7 +36,7 @@ export class BotExecution implements Execution { return; } - if (ticks % this.attackRate != 0) { + if (ticks % this.attackRate !== 0) { return; } @@ -74,9 +74,9 @@ export class BotExecution implements Execution { const border = Array.from(this.bot.borderTiles()) .flatMap((t) => this.mg.neighbors(t)) - .filter((t) => this.mg.hasOwner(t) && this.mg.owner(t) != this.bot); + .filter((t) => this.mg.hasOwner(t) && this.mg.owner(t) !== this.bot); - if (border.length == 0) { + if (border.length === 0) { return; } @@ -87,7 +87,7 @@ export class BotExecution implements Execution { if (this.bot.isFriendly(owner)) { return; } - if (owner.type() == PlayerType.FakeHuman) { + if (owner.type() === PlayerType.FakeHuman) { if (!this.random.chance(2)) { return; } diff --git a/src/core/execution/BotSpawner.ts b/src/core/execution/BotSpawner.ts index 000768ad8..521729a67 100644 --- a/src/core/execution/BotSpawner.ts +++ b/src/core/execution/BotSpawner.ts @@ -27,7 +27,7 @@ export class BotSpawner { } const botName = this.randomBotName(); const spawn = this.spawnBot(botName); - if (spawn != null) { + if (spawn !== null) { this.bots.push(spawn); } else { tries++; diff --git a/src/core/execution/CityExecution.ts b/src/core/execution/CityExecution.ts index 5bf2ca7e4..4782b69af 100644 --- a/src/core/execution/CityExecution.ts +++ b/src/core/execution/CityExecution.ts @@ -12,7 +12,7 @@ import { TileRef } from "../game/GameMap"; export class CityExecution implements Execution { private player: Player; private mg: Game; - private city: Unit; + private city: Unit | null = null; private active: boolean = true; constructor( @@ -31,9 +31,9 @@ export class CityExecution implements Execution { } tick(ticks: number): void { - if (this.city == null) { + if (this.city === null) { const spawnTile = this.player.canBuild(UnitType.City, this.tile); - if (spawnTile == false) { + if (spawnTile === false) { consolex.warn("cannot build city"); this.active = false; return; @@ -45,7 +45,7 @@ export class CityExecution implements Execution { return; } - if (this.player != this.city.owner()) { + if (this.player !== this.city.owner()) { this.player = this.city.owner(); } } diff --git a/src/core/execution/ConstructionExecution.ts b/src/core/execution/ConstructionExecution.ts index c5e73f1f2..ac16f7c7a 100644 --- a/src/core/execution/ConstructionExecution.ts +++ b/src/core/execution/ConstructionExecution.ts @@ -20,7 +20,7 @@ import { WarshipExecution } from "./WarshipExecution"; export class ConstructionExecution implements Execution { private player: Player; - private construction: Unit; + private construction: Unit | null = null; private active: boolean = true; private mg: Game; @@ -45,15 +45,15 @@ export class ConstructionExecution implements Execution { } tick(ticks: number): void { - if (this.construction == null) { + if (this.construction === null) { const info = this.mg.unitInfo(this.constructionType); - if (info.constructionDuration == null) { + if (info.constructionDuration === undefined) { this.completeConstruction(); this.active = false; return; } const spawnTile = this.player.canBuild(this.constructionType, this.tile); - if (spawnTile == false) { + if (spawnTile === false) { consolex.warn(`cannot build ${this.constructionType}`); this.active = false; return; @@ -75,11 +75,11 @@ export class ConstructionExecution implements Execution { return; } - if (this.player != this.construction.owner()) { + if (this.player !== this.construction.owner()) { this.player = this.construction.owner(); } - if (this.ticksUntilComplete == 0) { + if (this.ticksUntilComplete === 0) { this.player = this.construction.owner(); this.construction.delete(false); // refund the cost so player has the gold to build the unit diff --git a/src/core/execution/DefensePostExecution.ts b/src/core/execution/DefensePostExecution.ts index 0da8ef983..85d6d1706 100644 --- a/src/core/execution/DefensePostExecution.ts +++ b/src/core/execution/DefensePostExecution.ts @@ -12,7 +12,7 @@ import { TileRef } from "../game/GameMap"; export class DefensePostExecution implements Execution { private player: Player; private mg: Game; - private post: Unit; + private post: Unit | null = null; private active: boolean = true; constructor( @@ -31,9 +31,9 @@ export class DefensePostExecution implements Execution { } tick(ticks: number): void { - if (this.post == null) { + if (this.post === null) { const spawnTile = this.player.canBuild(UnitType.DefensePost, this.tile); - if (spawnTile == false) { + if (spawnTile === false) { consolex.warn("cannot build Defense Post"); this.active = false; return; @@ -45,7 +45,7 @@ export class DefensePostExecution implements Execution { return; } - if (this.player != this.post.owner()) { + if (this.player !== this.post.owner()) { this.player = this.post.owner(); } } diff --git a/src/core/execution/DonateGoldExecution.ts b/src/core/execution/DonateGoldExecution.ts index 3a64d303a..166f34cde 100644 --- a/src/core/execution/DonateGoldExecution.ts +++ b/src/core/execution/DonateGoldExecution.ts @@ -27,7 +27,7 @@ export class DonateGoldExecution implements Execution { this.sender = mg.player(this.senderID); this.recipient = mg.player(this.recipientID); - if (this.gold == null) { + if (this.gold === null) { this.gold = Math.round(this.sender.gold() / 3); } } diff --git a/src/core/execution/DonateTroopExecution.ts b/src/core/execution/DonateTroopExecution.ts index 2ec355ecb..99dc4ca66 100644 --- a/src/core/execution/DonateTroopExecution.ts +++ b/src/core/execution/DonateTroopExecution.ts @@ -27,7 +27,7 @@ export class DonateTroopsExecution implements Execution { this.sender = mg.player(this.senderID); this.recipient = mg.player(this.recipientID); - if (this.troops == null) { + if (this.troops === null) { this.troops = mg.config().defaultDonationAmount(this.sender); } } diff --git a/src/core/execution/EmbargoExecution.ts b/src/core/execution/EmbargoExecution.ts index 3fb224835..210e92700 100644 --- a/src/core/execution/EmbargoExecution.ts +++ b/src/core/execution/EmbargoExecution.ts @@ -23,7 +23,7 @@ export class EmbargoExecution implements Execution { } tick(_: number): void { - if (this.action == "start") this.player.addEmbargo(this.targetID); + if (this.action === "start") this.player.addEmbargo(this.targetID); else this.player.stopEmbargo(this.targetID); this.active = false; diff --git a/src/core/execution/EmojiExecution.ts b/src/core/execution/EmojiExecution.ts index 60117ac7b..a1218ffc1 100644 --- a/src/core/execution/EmojiExecution.ts +++ b/src/core/execution/EmojiExecution.ts @@ -26,7 +26,7 @@ export class EmojiExecution implements Execution { this.active = false; return; } - if (this.recipientID != AllPlayers && !mg.hasPlayer(this.recipientID)) { + if (this.recipientID !== AllPlayers && !mg.hasPlayer(this.recipientID)) { console.warn(`EmojiExecution: recipient ${this.recipientID} not found`); this.active = false; return; @@ -34,16 +34,18 @@ export class EmojiExecution implements Execution { this.requestor = mg.player(this.senderID); this.recipient = - this.recipientID == AllPlayers ? AllPlayers : mg.player(this.recipientID); + this.recipientID === AllPlayers + ? AllPlayers + : mg.player(this.recipientID); } tick(ticks: number): void { if (this.requestor.canSendEmoji(this.recipient)) { this.requestor.sendEmoji(this.recipient, this.emoji); if ( - this.emoji == "🖕" && - this.recipient != AllPlayers && - this.recipient.type() == PlayerType.FakeHuman + this.emoji === "🖕" && + this.recipient !== AllPlayers && + this.recipient.type() === PlayerType.FakeHuman ) { this.recipient.updateRelation(this.requestor, -100); } diff --git a/src/core/execution/FakeHumanExecution.ts b/src/core/execution/FakeHumanExecution.ts index 7658048bd..3896807e4 100644 --- a/src/core/execution/FakeHumanExecution.ts +++ b/src/core/execution/FakeHumanExecution.ts @@ -61,7 +61,7 @@ export class FakeHumanExecution implements Execution { private updateRelationsFromEmbargos() { const player = this.player; if (player === null) return; - const others = this.mg.players().filter((p) => p.id() != player.id()); + const others = this.mg.players().filter((p) => p.id() !== player.id()); others.forEach((other: Player) => { const embargoMalus = -20; @@ -84,7 +84,7 @@ export class FakeHumanExecution implements Execution { private handleEmbargoesToHostileNations() { const player = this.player; if (player === null) return; - const others = this.mg.players().filter((p) => p.id() != player.id()); + const others = this.mg.players().filter((p) => p.id() !== player.id()); others.forEach((other: Player) => { /* When player is hostile starts embargo. Do not stop until neutral again */ @@ -104,9 +104,9 @@ export class FakeHumanExecution implements Execution { tick(ticks: number) { if (this.mg.inSpawnPhase()) { - if (ticks % this.random.nextInt(5, 30) == 0) { + if (ticks % this.random.nextInt(5, 30) === 0) { const rl = this.randomLand(); - if (rl == null) { + if (rl === null) { consolex.warn(`cannot spawn ${this.playerInfo.name}`); return; } @@ -114,10 +114,10 @@ export class FakeHumanExecution implements Execution { } return; } - if (this.player == null) { + if (this.player === null) { this.player = - this.mg.players().find((p) => p.id() == this.playerInfo.id) ?? null; - if (this.player == null) { + this.mg.players().find((p) => p.id() === this.playerInfo.id) ?? null; + if (this.player === null) { return; } } @@ -131,7 +131,7 @@ export class FakeHumanExecution implements Execution { return; } - if (ticks % this.random.nextInt(40, 80) != 0) { + if (ticks % this.random.nextInt(40, 80) !== 0) { return; } @@ -152,10 +152,10 @@ export class FakeHumanExecution implements Execution { .flatMap((t) => this.mg.neighbors(t)) .filter( (t) => - this.mg.isLand(t) && this.mg.ownerID(t) != this.player?.smallID(), + this.mg.isLand(t) && this.mg.ownerID(t) !== this.player?.smallID(), ); - if (enemyborder.length == 0) { + if (enemyborder.length === 0) { if (this.random.chance(10)) { this.sendBoatRandomly(); } @@ -219,10 +219,13 @@ export class FakeHumanExecution implements Execution { return false; } const difficulty = this.mg.config().gameConfig().difficulty; - if (difficulty == Difficulty.Hard || difficulty == Difficulty.Impossible) { + if ( + difficulty === Difficulty.Hard || + difficulty === Difficulty.Impossible + ) { return false; } - if (other.type() != PlayerType.Human) { + if (other.type() !== PlayerType.Human) { return false; } // Only discourage attacks on Humans who are not traitors on easy or medium difficulty. @@ -240,28 +243,28 @@ export class FakeHumanExecution implements Execution { const target = player .allies() - .filter((ally) => player.relation(ally) == Relation.Friendly) + .filter((ally) => player.relation(ally) === Relation.Friendly) .filter((ally) => ally.targets().length > 0) .map((ally) => ({ ally: ally, t: ally.targets()[0] }))[0] ?? null; if ( - target != null && - target.t != player && + target !== null && + target.t !== player && !player.isAlliedWith(target.t) ) { player.updateRelation(target.ally, -20); this.enemy = target.t; this.lastEnemyUpdateTick = this.mg.ticks(); - if (target.ally.type() == PlayerType.Human) { + if (target.ally.type() === PlayerType.Human) { this.mg.addExecution( new EmojiExecution(player.id(), target.ally.id(), "👍"), ); } } - if (this.enemy == null) { + if (this.enemy === null) { const mostHated = player.allRelationsSorted()[0] ?? null; - if (mostHated != null && mostHated.relation == Relation.Hostile) { + if (mostHated !== null && mostHated.relation === Relation.Hostile) { this.enemy = mostHated.player; this.lastEnemyUpdateTick = this.mg.ticks(); } @@ -286,7 +289,7 @@ export class FakeHumanExecution implements Execution { private maybeSendEmoji() { if (this.player === null) throw new Error("not initialized"); if (this.enemy === null) return; - if (this.enemy.type() != PlayerType.Human) return; + if (this.enemy.type() !== PlayerType.Human) return; const lastSent = this.lastEmojiSent.get(this.enemy) ?? -300; if (this.mg.ticks() - lastSent <= 300) return; this.lastEmojiSent.set(this.enemy, this.mg.ticks()); @@ -302,7 +305,7 @@ export class FakeHumanExecution implements Execution { private maybeSendNuke(other: Player) { if (this.player === null) throw new Error("not initialized"); if ( - this.player.units(UnitType.MissileSilo).length == 0 || + this.player.units(UnitType.MissileSilo).length === 0 || this.player.gold() < this.mg.config().unitInfo(UnitType.AtomBomb).cost(this.player) || this.player.isOnSameTeam(other) @@ -311,12 +314,12 @@ export class FakeHumanExecution implements Execution { } outer: for (let i = 0; i < 10; i++) { const tile = this.randTerritoryTile(other); - if (tile == null) { + if (tile === null) { return; } for (const t of this.mg.bfs(tile, manhattanDistFN(tile, 15))) { // Make sure we nuke at least 15 tiles in border - if (this.mg.owner(t) != other) { + if (this.mg.owner(t) !== other) { continue outer; } } @@ -339,7 +342,7 @@ export class FakeHumanExecution implements Execution { ), Array.from(other.borderTiles()).filter((t) => this.mg.isOceanShore(t)), ); - if (closest == null) { + if (closest === null) { return; } this.mg.addExecution( @@ -356,7 +359,7 @@ export class FakeHumanExecution implements Execution { const player = this.player; if (player === null) return; const ports = player.units(UnitType.Port); - if (ports.length == 0 && player.gold() > this.cost(UnitType.Port)) { + if (ports.length === 0 && player.gold() > this.cost(UnitType.Port)) { const oceanTiles = Array.from(player.borderTiles()).filter((t) => this.mg.isOceanShore(t), ); @@ -401,11 +404,11 @@ export class FakeHumanExecution implements Execution { return; } const tile = this.randTerritoryTile(this.player); - if (tile == null) { + if (tile === null) { return; } const canBuild = this.player.canBuild(type, tile); - if (canBuild == false) { + if (canBuild === false) { return; } this.mg.addExecution(build(tile)); @@ -420,16 +423,16 @@ export class FakeHumanExecution implements Execution { const ships = this.player.units(UnitType.Warship); if ( ports.length > 0 && - ships.length == 0 && + ships.length === 0 && this.player.gold() > this.cost(UnitType.Warship) ) { const port = this.random.randElement(ports); const targetTile = this.warshipSpawnTile(port.tile()); - if (targetTile == null) { + if (targetTile === null) { return false; } const canBuild = this.player.canBuild(UnitType.Warship, targetTile); - if (canBuild == false) { + if (canBuild === false) { consolex.warn("cannot spawn destroyer"); return false; } @@ -455,7 +458,7 @@ export class FakeHumanExecution implements Execution { continue; } const randTile = this.mg.ref(randX, randY); - if (this.mg.owner(randTile) == p) { + if (this.mg.owner(randTile) === p) { return randTile; } } @@ -528,14 +531,14 @@ export class FakeHumanExecution implements Execution { const oceanShore = Array.from(this.player.borderTiles()).filter((t) => this.mg.isOceanShore(t), ); - if (oceanShore.length == 0) { + if (oceanShore.length === 0) { return; } const src = this.random.randElement(oceanShore); const dst = this.randOceanShoreTile(src, 150); - if (dst == null) { + if (dst === null) { return; } @@ -564,7 +567,7 @@ export class FakeHumanExecution implements Execution { const tile = this.mg.ref(x, y); if (this.mg.isLand(tile) && !this.mg.hasOwner(tile)) { if ( - this.mg.terrainType(tile) == TerrainType.Mountain && + this.mg.terrainType(tile) === TerrainType.Mountain && this.random.chance(2) ) { continue; diff --git a/src/core/execution/MIRVExecution.ts b/src/core/execution/MIRVExecution.ts index bd0120c22..04acb8898 100644 --- a/src/core/execution/MIRVExecution.ts +++ b/src/core/execution/MIRVExecution.ts @@ -23,7 +23,7 @@ export class MirvExecution implements Execution { private mg: Game; - private nuke: Unit; + private nuke: Unit | null = null; private mirvRange = 1500; private warheadCount = 350; @@ -64,9 +64,9 @@ export class MirvExecution implements Execution { } tick(ticks: number): void { - if (this.nuke == null) { + if (this.nuke === null) { const spawn = this.player.canBuild(UnitType.MIRV, this.dst); - if (spawn == false) { + if (spawn === false) { consolex.warn(`cannot build MIRV`); this.active = false; return; @@ -112,12 +112,13 @@ export class MirvExecution implements Execution { } private separate() { + if (this.nuke === null) throw new Error("uninitialized"); const dsts: TileRef[] = [this.dst]; let attempts = 1000; while (attempts > 0 && dsts.length < this.warheadCount) { attempts--; const potential = this.randomLand(this.dst, dsts); - if (potential == null) { + if (potential === null) { continue; } dsts.push(potential); @@ -144,10 +145,10 @@ export class MirvExecution implements Execution { } if (this.targetPlayer.isPlayer()) { const alliance = this.player.allianceWith(this.targetPlayer); - if (alliance != null) { + if (alliance !== null) { this.player.breakAlliance(alliance); } - if (this.targetPlayer != this.player) { + if (this.targetPlayer !== this.player) { this.targetPlayer.updateRelation(this.player, -100); } } @@ -178,7 +179,7 @@ export class MirvExecution implements Execution { if (this.mg.euclideanDistSquared(tile, ref) > mirvRange2) { continue; } - if (this.mg.owner(tile) != this.targetPlayer) { + if (this.mg.owner(tile) !== this.targetPlayer) { continue; } for (const t of taken) {