mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 09:48:10 +00:00
wip
This commit is contained in:
+3
-3
@@ -226,11 +226,11 @@ export const SpawnIntentSchema = BaseIntentSchema.extend({
|
||||
export const BoatAttackIntentSchema = BaseIntentSchema.extend({
|
||||
type: z.literal("boat"),
|
||||
targetID: ID.nullable(),
|
||||
troops: z.number().nullable(),
|
||||
troops: z.number(),
|
||||
dstX: z.number(),
|
||||
dstY: z.number(),
|
||||
srcX: z.number().nullable().optional(),
|
||||
srcY: z.number().nullable().optional(),
|
||||
srcX: z.number().nullable(),
|
||||
srcY: z.number().nullable(),
|
||||
});
|
||||
|
||||
export const AllianceRequestIntentSchema = BaseIntentSchema.extend({
|
||||
|
||||
@@ -283,7 +283,7 @@ export class AttackExecution implements Execution {
|
||||
this.border.add(neighbor);
|
||||
const numOwnedByMe = this.mg
|
||||
.neighbors(neighbor)
|
||||
.filter((t) => this.mg.owner(t) == this._owner).length;
|
||||
.filter((t) => this.mg.owner(t) === this._owner).length;
|
||||
let mag = 0;
|
||||
switch (this.mg.terrainType(tile)) {
|
||||
case TerrainType.Plains:
|
||||
|
||||
@@ -33,7 +33,7 @@ export class BotExecution implements Execution {
|
||||
}
|
||||
|
||||
tick(ticks: number) {
|
||||
if (ticks % this.attackRate != this.attackTick) return;
|
||||
if (ticks % this.attackRate !== this.attackTick) return;
|
||||
|
||||
if (!this.bot.isAlive()) {
|
||||
this.active = false;
|
||||
|
||||
@@ -16,7 +16,7 @@ export class DefensePostExecution implements Execution {
|
||||
private post: Unit | null = null;
|
||||
private active: boolean = true;
|
||||
|
||||
private target: Unit = null;
|
||||
private target: Unit | null = null;
|
||||
private lastShellAttack = 0;
|
||||
|
||||
private alreadySentShell = new Set<Unit>();
|
||||
@@ -37,6 +37,8 @@ export class DefensePostExecution implements Execution {
|
||||
}
|
||||
|
||||
private shoot() {
|
||||
if (this.post === null) return;
|
||||
if (this.target === null) return;
|
||||
const shellAttackRate = this.mg.config().defensePostShellAttackRate();
|
||||
if (this.mg.ticks() - this.lastShellAttack > shellAttackRate) {
|
||||
this.lastShellAttack = this.mg.ticks();
|
||||
@@ -76,7 +78,7 @@ export class DefensePostExecution implements Execution {
|
||||
this.player = this.post.owner();
|
||||
}
|
||||
|
||||
if (this.target != null && !this.target.isActive()) {
|
||||
if (this.target !== null && !this.target.isActive()) {
|
||||
this.target = null;
|
||||
}
|
||||
|
||||
@@ -117,7 +119,7 @@ export class DefensePostExecution implements Execution {
|
||||
return distA - distB;
|
||||
})[0]?.unit ?? null;
|
||||
|
||||
if (this.target == null || !this.target.isActive()) {
|
||||
if (this.target === null || !this.target.isActive()) {
|
||||
this.target = null;
|
||||
return;
|
||||
} else {
|
||||
|
||||
@@ -42,13 +42,16 @@ export class EmojiExecution implements Execution {
|
||||
|
||||
tick(ticks: number): void {
|
||||
const emojiString = flattenedEmojiTable.at(this.emoji);
|
||||
|
||||
if (this.requestor.canSendEmoji(this.recipient)) {
|
||||
if (emojiString === undefined) {
|
||||
consolex.warn(
|
||||
`cannot send emoji ${this.emoji} from ${this.requestor} to ${this.recipient}`,
|
||||
);
|
||||
} else if (this.requestor.canSendEmoji(this.recipient)) {
|
||||
this.requestor.sendEmoji(this.recipient, emojiString);
|
||||
if (
|
||||
emojiString == "🖕" &&
|
||||
this.recipient != AllPlayers &&
|
||||
this.recipient.type() == PlayerType.FakeHuman
|
||||
emojiString === "🖕" &&
|
||||
this.recipient !== AllPlayers &&
|
||||
this.recipient.type() === PlayerType.FakeHuman
|
||||
) {
|
||||
this.recipient.updateRelation(this.requestor, -100);
|
||||
}
|
||||
|
||||
@@ -1,4 +1,5 @@
|
||||
import { Execution, Game } from "../game/Game";
|
||||
import { TileRef } from "../game/GameMap";
|
||||
import { PseudoRandom } from "../PseudoRandom";
|
||||
import { ClientID, GameID, Intent, Turn } from "../Schemas";
|
||||
import { simpleHash } from "../Util";
|
||||
@@ -66,8 +67,8 @@ export class Executor {
|
||||
this.mg.ref(intent.x, intent.y),
|
||||
);
|
||||
case "boat":
|
||||
let src = null;
|
||||
if (intent.srcX != null || intent.srcY != null) {
|
||||
let src: TileRef | null = null;
|
||||
if (intent.srcX !== null && intent.srcY !== null) {
|
||||
src = this.mg.ref(intent.srcX, intent.srcY);
|
||||
}
|
||||
return new TransportShipExecution(
|
||||
|
||||
@@ -111,11 +111,11 @@ export class FakeHumanExecution implements Execution {
|
||||
}
|
||||
|
||||
tick(ticks: number) {
|
||||
if (ticks % this.attackRate != this.attackTick) return;
|
||||
if (ticks % this.attackRate !== this.attackTick) return;
|
||||
|
||||
if (this.mg.inSpawnPhase()) {
|
||||
const rl = this.randomLand();
|
||||
if (rl == null) {
|
||||
if (rl === null) {
|
||||
consolex.warn(`cannot spawn ${this.nation.playerInfo.name}`);
|
||||
return;
|
||||
}
|
||||
@@ -123,11 +123,11 @@ export class FakeHumanExecution implements Execution {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.player == null) {
|
||||
this.player = this.mg
|
||||
.players()
|
||||
.find((p) => p.id() == this.nation.playerInfo.id);
|
||||
if (this.player == null) {
|
||||
if (this.player === null) {
|
||||
this.player =
|
||||
this.mg.players().find((p) => p.id() === this.nation.playerInfo.id) ??
|
||||
null;
|
||||
if (this.player === null) {
|
||||
return;
|
||||
}
|
||||
}
|
||||
@@ -170,6 +170,9 @@ export class FakeHumanExecution implements Execution {
|
||||
}
|
||||
|
||||
private maybeAttack() {
|
||||
if (this.player === null || this.behavior === null) {
|
||||
throw new Error("not initialized");
|
||||
}
|
||||
const enemyborder = Array.from(this.player.borderTiles())
|
||||
.flatMap((t) => this.mg.neighbors(t))
|
||||
.filter(
|
||||
@@ -255,6 +258,9 @@ export class FakeHumanExecution implements Execution {
|
||||
}
|
||||
|
||||
handleEnemies() {
|
||||
if (this.player === null || this.behavior === null) {
|
||||
throw new Error("not initialized");
|
||||
}
|
||||
this.behavior.forgetOldEnemies();
|
||||
this.behavior.checkIncomingAttacks();
|
||||
this.behavior.assistAllies();
|
||||
@@ -270,7 +276,8 @@ export class FakeHumanExecution implements Execution {
|
||||
}
|
||||
|
||||
private maybeSendEmoji(enemy: Player) {
|
||||
if (enemy.type() != PlayerType.Human) return;
|
||||
if (this.player === null) throw new Error("not initialized");
|
||||
if (enemy.type() !== PlayerType.Human) return;
|
||||
const lastSent = this.lastEmojiSent.get(enemy) ?? -300;
|
||||
if (this.mg.ticks() - lastSent <= 300) return;
|
||||
this.lastEmojiSent.set(enemy, this.mg.ticks());
|
||||
@@ -284,11 +291,12 @@ export class FakeHumanExecution implements Execution {
|
||||
}
|
||||
|
||||
private maybeSendNuke(other: Player) {
|
||||
if (this.player === null) throw new Error("not initialized");
|
||||
const silos = this.player.units(UnitType.MissileSilo);
|
||||
if (
|
||||
silos.length == 0 ||
|
||||
silos.length === 0 ||
|
||||
this.player.gold() < this.cost(UnitType.AtomBomb) ||
|
||||
other.type() == PlayerType.Bot ||
|
||||
other.type() === PlayerType.Bot ||
|
||||
this.player.isOnSameTeam(other)
|
||||
) {
|
||||
return;
|
||||
@@ -302,17 +310,17 @@ export class FakeHumanExecution implements Execution {
|
||||
UnitType.SAMLauncher,
|
||||
);
|
||||
const structureTiles = structures.map((u) => u.tile());
|
||||
const randomTiles: TileRef[] = new Array(10);
|
||||
const randomTiles: (TileRef | null)[] = new Array(10);
|
||||
for (let i = 0; i < randomTiles.length; i++) {
|
||||
randomTiles[i] = this.randTerritoryTile(other);
|
||||
}
|
||||
const allTiles = randomTiles.concat(structureTiles);
|
||||
|
||||
let bestTile = null;
|
||||
let bestTile: TileRef | null = null;
|
||||
let bestValue = 0;
|
||||
this.removeOldNukeEvents();
|
||||
outer: for (const tile of new Set(allTiles)) {
|
||||
if (tile == null) continue;
|
||||
if (tile === null) continue;
|
||||
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) {
|
||||
@@ -321,12 +329,12 @@ export class FakeHumanExecution implements Execution {
|
||||
}
|
||||
if (!this.player.canBuild(UnitType.AtomBomb, tile)) continue;
|
||||
const value = this.nukeTileScore(tile, silos, structures);
|
||||
if (value > bestTile) {
|
||||
if (value > bestValue) {
|
||||
bestTile = tile;
|
||||
bestValue = value;
|
||||
}
|
||||
}
|
||||
if (bestTile != null) {
|
||||
if (bestTile !== null) {
|
||||
this.sendNuke(bestTile);
|
||||
}
|
||||
}
|
||||
@@ -343,6 +351,7 @@ export class FakeHumanExecution implements Execution {
|
||||
}
|
||||
|
||||
private sendNuke(tile: TileRef) {
|
||||
if (this.player === null) throw new Error("not initialized");
|
||||
const tick = this.mg.ticks();
|
||||
this.lastNukeSent.push([tick, tile]);
|
||||
this.mg.addExecution(
|
||||
@@ -375,7 +384,9 @@ export class FakeHumanExecution implements Execution {
|
||||
|
||||
// Prefer tiles that are closer to a silo
|
||||
const siloTiles = silos.map((u) => u.tile());
|
||||
const { x: closestSilo } = closestTwoTiles(this.mg, siloTiles, [tile]);
|
||||
const result = closestTwoTiles(this.mg, siloTiles, [tile]);
|
||||
if (result === null) throw new Error("Missing result");
|
||||
const { x: closestSilo } = result;
|
||||
const distanceSquared = this.mg.euclideanDistSquared(tile, closestSilo);
|
||||
const distanceToClosestSilo = Math.sqrt(distanceSquared);
|
||||
tileValue -= distanceToClosestSilo * 30;
|
||||
@@ -437,6 +448,7 @@ export class FakeHumanExecution implements Execution {
|
||||
}
|
||||
|
||||
private maybeSpawnStructure(type: UnitType, maxNum: number) {
|
||||
if (this.player === null) throw new Error("not initialized");
|
||||
const units = this.player.units(type);
|
||||
if (units.length >= maxNum) {
|
||||
return;
|
||||
|
||||
@@ -32,7 +32,10 @@ export class MissileSiloExecution implements Execution {
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (this.silo == null) {
|
||||
if (this.player === null || this.mg === null) {
|
||||
throw new Error("Not initialized");
|
||||
}
|
||||
if (this.silo === null) {
|
||||
const spawn = this.player.canBuild(UnitType.MissileSilo, this.tile);
|
||||
if (spawn === false) {
|
||||
consolex.warn(
|
||||
|
||||
@@ -111,7 +111,7 @@ export class NukeExecution implements Execution {
|
||||
this.pathFinder.computeControlPoints(
|
||||
spawn,
|
||||
this.dst,
|
||||
this.type != UnitType.MIRVWarhead,
|
||||
this.type !== UnitType.MIRVWarhead,
|
||||
);
|
||||
this.nuke = this.player.buildUnit(this.type, spawn, {
|
||||
detonationDst: this.dst,
|
||||
|
||||
@@ -30,7 +30,7 @@ export class SAMLauncherExecution implements Execution {
|
||||
private tile: TileRef,
|
||||
private sam: Unit | null = null,
|
||||
) {
|
||||
if (sam != null) {
|
||||
if (sam !== null) {
|
||||
this.tile = sam.tile();
|
||||
}
|
||||
}
|
||||
@@ -46,6 +46,7 @@ export class SAMLauncherExecution implements Execution {
|
||||
}
|
||||
|
||||
private getSingleTarget(): Unit | null {
|
||||
if (this.sam === null) return null;
|
||||
const nukes = this.mg
|
||||
.nearbyUnits(this.sam.tile(), this.searchRangeRadius, [
|
||||
UnitType.AtomBomb,
|
||||
@@ -80,11 +81,11 @@ export class SAMLauncherExecution implements Execution {
|
||||
}
|
||||
|
||||
private isHit(type: UnitType, random: number): boolean {
|
||||
if (type == UnitType.AtomBomb) {
|
||||
if (type === UnitType.AtomBomb) {
|
||||
return true;
|
||||
}
|
||||
|
||||
if (type == UnitType.MIRVWarhead) {
|
||||
if (type === UnitType.MIRVWarhead) {
|
||||
return random < this.mg.config().samWarheadHittingChance();
|
||||
}
|
||||
|
||||
@@ -130,14 +131,18 @@ export class SAMLauncherExecution implements Execution {
|
||||
(unit) =>
|
||||
unit.owner() !== this.player && !this.player.isFriendly(unit.owner()),
|
||||
)
|
||||
.filter(
|
||||
(unit) =>
|
||||
this.mg.manhattanDist(unit.detonationDst(), this.sam.tile()) <
|
||||
this.MIRVWarheadProtectionRadius,
|
||||
);
|
||||
.filter((unit) => {
|
||||
const dst = unit.detonationDst();
|
||||
return (
|
||||
this.sam !== null &&
|
||||
dst !== null &&
|
||||
this.mg.manhattanDist(dst, this.sam.tile()) <
|
||||
this.MIRVWarheadProtectionRadius
|
||||
);
|
||||
});
|
||||
|
||||
let target: Unit | null = null;
|
||||
if (mirvWarheadTargets.length == 0) {
|
||||
if (mirvWarheadTargets.length === 0) {
|
||||
target = this.getSingleTarget();
|
||||
}
|
||||
|
||||
@@ -155,7 +160,8 @@ export class SAMLauncherExecution implements Execution {
|
||||
) {
|
||||
this.sam.setCooldown(true);
|
||||
const type =
|
||||
mirvWarheadTargets.length > 0 ? UnitType.MIRVWarhead : target.type();
|
||||
mirvWarheadTargets.length > 0 ? UnitType.MIRVWarhead : target?.type();
|
||||
if (type === undefined) throw new Error("Unknown unit type");
|
||||
const random = this.pseudoRandom.next();
|
||||
const hit = this.isHit(type, random);
|
||||
if (!hit) {
|
||||
@@ -174,7 +180,7 @@ export class SAMLauncherExecution implements Execution {
|
||||
);
|
||||
// Delete warheads
|
||||
mirvWarheadTargets.forEach((u) => u.delete());
|
||||
} else {
|
||||
} else if (target !== null) {
|
||||
target.setTargetedBySAM(true);
|
||||
this.mg.addExecution(
|
||||
new SAMMissileExecution(
|
||||
@@ -184,6 +190,8 @@ export class SAMLauncherExecution implements Execution {
|
||||
target,
|
||||
),
|
||||
);
|
||||
} else {
|
||||
throw new Error("target is null");
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -6,7 +6,7 @@ import { PseudoRandom } from "../PseudoRandom";
|
||||
export class ShellExecution implements Execution {
|
||||
private active = true;
|
||||
private pathFinder: AirPathFinder;
|
||||
private shell: Unit;
|
||||
private shell: Unit | undefined;
|
||||
private mg: Game;
|
||||
private destroyAtTick: number = -1;
|
||||
|
||||
@@ -23,7 +23,7 @@ export class ShellExecution implements Execution {
|
||||
}
|
||||
|
||||
tick(ticks: number): void {
|
||||
if (this.shell == null) {
|
||||
if (this.shell === undefined) {
|
||||
this.shell = this._owner.buildUnit(UnitType.Shell, this.spawn, {});
|
||||
}
|
||||
if (!this.shell.isActive()) {
|
||||
@@ -40,7 +40,7 @@ export class ShellExecution implements Execution {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.destroyAtTick == -1 && !this.ownerUnit.isActive()) {
|
||||
if (this.destroyAtTick === -1 && !this.ownerUnit.isActive()) {
|
||||
this.destroyAtTick = this.mg.ticks() + this.mg.config().shellLifetime();
|
||||
}
|
||||
|
||||
@@ -61,8 +61,8 @@ export class ShellExecution implements Execution {
|
||||
}
|
||||
|
||||
private effectOnTarget(): number {
|
||||
const baseDamage: number = this.mg.config().unitInfo(UnitType.Shell).damage;
|
||||
return baseDamage;
|
||||
const { damage } = this.mg.config().unitInfo(UnitType.Shell);
|
||||
return damage ?? 0;
|
||||
}
|
||||
|
||||
isActive(): boolean {
|
||||
|
||||
@@ -59,7 +59,7 @@ export class TradeShipExecution implements Execution {
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.origOwner != this.tradeShip.owner()) {
|
||||
if (this.origOwner !== this.tradeShip.owner()) {
|
||||
// Store as variable in case ship is recaptured by previous owner
|
||||
this.wasCaptured = true;
|
||||
}
|
||||
|
||||
@@ -39,7 +39,7 @@ export class TransportShipExecution implements Execution {
|
||||
private attackerID: PlayerID,
|
||||
private targetID: PlayerID | null,
|
||||
private ref: TileRef,
|
||||
private troops: number | null,
|
||||
private troops: number,
|
||||
private src: TileRef | null,
|
||||
) {}
|
||||
|
||||
@@ -120,19 +120,19 @@ export class TransportShipExecution implements Execution {
|
||||
UnitType.TransportShip,
|
||||
this.dst,
|
||||
);
|
||||
if (closestTileSrc == false) {
|
||||
if (closestTileSrc === false) {
|
||||
consolex.warn(`can't build transport ship`);
|
||||
this.active = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (this.src == null) {
|
||||
if (this.src === null) {
|
||||
// Only update the src if it's not already set
|
||||
// because we assume that the src is set to the best spawn tile
|
||||
this.src = closestTileSrc;
|
||||
} else {
|
||||
if (
|
||||
this.mg.owner(this.src) != this.attacker ||
|
||||
this.mg.owner(this.src) !== this.attacker ||
|
||||
!this.mg.isShore(this.src)
|
||||
) {
|
||||
console.warn(
|
||||
|
||||
@@ -79,7 +79,7 @@ export class WinCheckExecution implements Execution {
|
||||
this.mg.numLandTiles() - this.mg.numTilesWithFallout();
|
||||
const percentage = (max[1] / numTilesWithoutFallout) * 100;
|
||||
if (percentage > this.mg.config().percentageTilesOwnedToWin()) {
|
||||
if (max[0] == ColoredTeams.Bot) return;
|
||||
if (max[0] === ColoredTeams.Bot) return;
|
||||
this.mg.setWinner(max[0], this.mg.stats().stats());
|
||||
console.log(`${max[0]} has won the game`);
|
||||
this.active = false;
|
||||
|
||||
@@ -111,8 +111,8 @@ export class BotBehavior {
|
||||
|
||||
// Select the most hated player
|
||||
if (this.enemy === null) {
|
||||
const mostHated = this.player.allRelationsSorted()[0] ?? null;
|
||||
if (mostHated != null && mostHated.relation === Relation.Hostile) {
|
||||
const mostHated = this.player.allRelationsSorted()[0];
|
||||
if (mostHated !== undefined && mostHated.relation === Relation.Hostile) {
|
||||
this.enemy = mostHated.player;
|
||||
this.enemyUpdated = this.game.ticks();
|
||||
}
|
||||
@@ -137,7 +137,7 @@ export class BotBehavior {
|
||||
for (const neighbor of this.random.shuffleArray(neighbors)) {
|
||||
if (!neighbor.isPlayer()) continue;
|
||||
if (this.player.isFriendly(neighbor)) continue;
|
||||
if (neighbor.type() == PlayerType.FakeHuman) {
|
||||
if (neighbor.type() === PlayerType.FakeHuman) {
|
||||
if (this.random.chance(2)) {
|
||||
continue;
|
||||
}
|
||||
|
||||
@@ -762,6 +762,7 @@ export class PlayerImpl implements Player {
|
||||
case UnitType.MIRVWarhead:
|
||||
return targetTile;
|
||||
case UnitType.Port:
|
||||
if (validTiles === null) throw new Error("validTiles is required");
|
||||
return this.portSpawn(targetTile, validTiles);
|
||||
case UnitType.Warship:
|
||||
return this.warshipSpawn(targetTile);
|
||||
|
||||
+16
-15
@@ -16,13 +16,12 @@ import { PlayerImpl } from "./PlayerImpl";
|
||||
export class UnitImpl implements Unit {
|
||||
private _active = true;
|
||||
private _health: bigint;
|
||||
private _lastTile: TileRef = null;
|
||||
private _target: Unit = null;
|
||||
private _moveTarget: TileRef = null;
|
||||
private _lastTile: TileRef;
|
||||
private _moveTarget: TileRef | null = null;
|
||||
private _targetedBySAM = false;
|
||||
private _safeFromPiratesCooldown: number; // Only for trade ships
|
||||
private _lastSetSafeFromPirates: number; // Only for trade ships
|
||||
private _constructionType: UnitType = undefined;
|
||||
private _constructionType: UnitType | undefined;
|
||||
|
||||
private _troops: number;
|
||||
private _cooldownTick: Tick | null = null;
|
||||
@@ -45,12 +44,14 @@ export class UnitImpl implements Unit {
|
||||
.config()
|
||||
.safeFromPiratesCooldownMax();
|
||||
|
||||
this._troops = "troops" in params ? params.troops : 0;
|
||||
this._dstPort = "dstPort" in params ? params.dstPort : null;
|
||||
this._troops = "troops" in params ? (params.troops ?? 0) : 0;
|
||||
this._dstPort = "dstPort" in params ? params.dstPort : undefined;
|
||||
this._cooldownDuration =
|
||||
"cooldownDuration" in params ? params.cooldownDuration : null;
|
||||
"cooldownDuration" in params ? params.cooldownDuration : undefined;
|
||||
this._lastSetSafeFromPirates =
|
||||
"lastSetSafeFromPirates" in params ? params.lastSetSafeFromPirates : 0;
|
||||
"lastSetSafeFromPirates" in params
|
||||
? (params.lastSetSafeFromPirates ?? 0)
|
||||
: 0;
|
||||
}
|
||||
|
||||
id() {
|
||||
@@ -93,7 +94,7 @@ export class UnitImpl implements Unit {
|
||||
}
|
||||
|
||||
move(tile: TileRef): void {
|
||||
if (tile == null) {
|
||||
if (tile === null) {
|
||||
throw new Error("tile cannot be null");
|
||||
}
|
||||
this.mg.removeUnit(this);
|
||||
@@ -112,7 +113,7 @@ export class UnitImpl implements Unit {
|
||||
return Number(this._health);
|
||||
}
|
||||
hasHealth(): boolean {
|
||||
return this.info().maxHealth != undefined;
|
||||
return this.info().maxHealth !== undefined;
|
||||
}
|
||||
tile(): TileRef {
|
||||
return this._tile;
|
||||
@@ -127,7 +128,7 @@ export class UnitImpl implements Unit {
|
||||
|
||||
setOwner(newOwner: Player): void {
|
||||
const oldOwner = this._owner;
|
||||
oldOwner._units = oldOwner._units.filter((u) => u != this);
|
||||
oldOwner._units = oldOwner._units.filter((u) => u !== this);
|
||||
this._owner = newOwner as PlayerImpl;
|
||||
this.mg.addUpdate(this.toUpdate());
|
||||
this.mg.displayMessage(
|
||||
@@ -149,11 +150,11 @@ export class UnitImpl implements Unit {
|
||||
if (!this.isActive()) {
|
||||
throw new Error(`cannot delete ${this} not active`);
|
||||
}
|
||||
this._owner._units = this._owner._units.filter((b) => b != this);
|
||||
this._owner._units = this._owner._units.filter((b) => b !== this);
|
||||
this._active = false;
|
||||
this.mg.addUpdate(this.toUpdate());
|
||||
this.mg.removeUnit(this);
|
||||
if (displayMessage && this.type() != UnitType.MIRVWarhead) {
|
||||
if (displayMessage && this.type() !== UnitType.MIRVWarhead) {
|
||||
this.mg.displayMessage(
|
||||
`Your ${this.type()} was destroyed`,
|
||||
MessageType.ERROR,
|
||||
@@ -166,14 +167,14 @@ export class UnitImpl implements Unit {
|
||||
}
|
||||
|
||||
constructionType(): UnitType | null {
|
||||
if (this.type() != UnitType.Construction) {
|
||||
if (this.type() !== UnitType.Construction) {
|
||||
throw new Error(`Cannot get construction type on ${this.type()}`);
|
||||
}
|
||||
return this._constructionType ?? null;
|
||||
}
|
||||
|
||||
setConstructionType(type: UnitType): void {
|
||||
if (this.type() != UnitType.Construction) {
|
||||
if (this.type() !== UnitType.Construction) {
|
||||
throw new Error(`Cannot set construction type on ${this.type()}`);
|
||||
}
|
||||
this._constructionType = type;
|
||||
|
||||
Reference in New Issue
Block a user