diff --git a/src/core/execution/utils/AiAttackBehavior.ts b/src/core/execution/utils/AiAttackBehavior.ts index 79e0ea674..59efba946 100644 --- a/src/core/execution/utils/AiAttackBehavior.ts +++ b/src/core/execution/utils/AiAttackBehavior.ts @@ -927,7 +927,10 @@ export class AiAttackBehavior { return cap; } - private sendLandAttack(target: Player | TerraNullius): boolean { + private calculateAttackTroops( + target: Player | TerraNullius, + nonBotTroops: (targetTroops: number) => number, + ): number | null { const maxTroops = this.game.config().maxTroops(this.player); const botWithStructures = target.isPlayer() && @@ -950,7 +953,7 @@ export class AiAttackBehavior { this.player.troops() - targetTroops - this.botAttackTroopsSent, ); } else { - troops = this.player.troops() - targetTroops; + troops = nonBotTroops(targetTroops); } // Hard & Impossible: don't drop below neighbor troop threshold (players only) @@ -959,12 +962,12 @@ export class AiAttackBehavior { } if (troops < 1) { - return false; + return null; } // Hard & Impossible: don't attack if we'd send less than 20% of target's troops if (target.isPlayer() && this.isAttackTooWeak(troops, target)) { - return false; + return null; } if (target.isPlayer() && this.player.type() === PlayerType.Nation) { @@ -972,6 +975,18 @@ export class AiAttackBehavior { this.emojiBehavior.maybeSendAttackEmoji(target); } + return troops; + } + + private sendLandAttack(target: Player | TerraNullius): boolean { + const troops = this.calculateAttackTroops( + target, + (targetTroops) => this.player.troops() - targetTroops, + ); + if (troops === null) { + return false; + } + this.game.addExecution( new AttackExecution( troops, @@ -1000,30 +1015,14 @@ export class AiAttackBehavior { return false; } - let troops; - if (target.type() === PlayerType.Bot) { - troops = this.calculateBotAttackTroops(target, this.player.troops() / 5); - } else { - troops = this.player.troops() / 5; - } - - // Hard & Impossible: don't drop below neighbor troop threshold - troops = Math.min(troops, this.troopSendCap()); - - if (troops < 1) { + const troops = this.calculateAttackTroops( + target, + () => this.player.troops() / 5, + ); + if (troops === null) { return false; } - // Hard & Impossible: don't attack if we'd send less than 20% of target's troops - if (this.isAttackTooWeak(troops, target)) { - return false; - } - - if (target.isPlayer() && this.player.type() === PlayerType.Nation) { - if (this.emojiBehavior === undefined) throw new Error("not initialized"); - this.emojiBehavior.maybeSendAttackEmoji(target); - } - this.game.addExecution( new TransportShipExecution(this.player, closest.y, troops), );