Nations can overwhelm SAMs now 💥 (+ 3 little nation improvements) (#3246)

## Description:

### SAM Overwhelming (`NationNukeBehavior.ts`)

On Impossible difficulty, nations can now destroy enemy SAMs by
overwhelming them with coordinated atom bomb salvos. When no good nuke
target is found (all trajectories intercepted by SAMs), the nations
will:

- Identify the easiest enemy SAM to destroy (lowest level first)
- Calculate the total interception capacity of all covering SAMs and
send enough bombs to overwhelm them (+1 extra per 5 needed to account
for enemy building more SAMs during flight)
- Plan launches in NukeExecution's Manhattan-distance silo order,
tracking which silos have interceptable trajectories (wasted bombs)
- Use a sliding window over parabolic flight times to find the best
cluster of bombs that can arrive within half the SAM cooldown window
- Compute per-bomb wait ticks to synchronize arrivals from silos at
different distances
- Skip launching if a salvo is already in flight
- Upgrade the best SAM-protected silo when silo capacity is
insufficient; wait and save gold when only gold is lacking


https://github.com/user-attachments/assets/14fa592f-2902-4604-8e37-1eba2b2f0b85

### 2-Player Endgame Handling (`NationNukeBehavior.ts`)

- On Hard/Impossible with only 2 players remaining,
`findBestNukeTarget()` directly targets the other player (bypasses all
priority logic)
- `getPerceivedNukeCost()` returns actual cost (no MIRV saving
inflation) when only 2 players are left

### SAM Build Rate (`NationStructureBehavior.ts`)

- Reduced SAM perceived cost increase per owned from 1.0 to 0.5, so
nations build more SAMs

### Island Attack Variety (`AiAttackBehavior.ts`)

- `findNearestIslandEnemy()` now collects up to 2 reachable candidates
and has a 33% chance to pick the second-nearest, adding variety to boat
attack targeting

## 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

## Please put your Discord username so you can be contacted if a bug or
regression is found:

FloPinguin
This commit is contained in:
FloPinguin
2026-02-20 23:16:03 -06:00
committed by GitHub
parent ea2a76609f
commit f09d9a3a5f
4 changed files with 463 additions and 6 deletions
+13 -3
View File
@@ -608,7 +608,8 @@ export class AiAttackBehavior {
})
.sort((a, b) => a.distance - b.distance); // Sort by distance (ascending)
// Try players in order of distance until we find one reachable by boat
// Try players in order of distance until we find reachable candidates
const reachablePlayers: Player[] = [];
for (const entry of sortedPlayers) {
const closest = closestTwoTiles(
this.game,
@@ -622,11 +623,20 @@ export class AiAttackBehavior {
if (closest === null) continue;
if (canBuildTransportShip(this.game, this.player, closest.y)) {
return entry.player;
reachablePlayers.push(entry.player);
// We only need up to 2 reachable candidates
if (reachablePlayers.length >= 2) break;
}
}
return null;
if (reachablePlayers.length === 0) return null;
// 33% chance to pick the second-nearest player if available
if (reachablePlayers.length >= 2 && this.random.chance(3)) {
return reachablePlayers[1];
}
return reachablePlayers[0];
}
private getPlayerCenter(player: Player) {