feat: Nuke trajectory prediction now accounts for alliance breakage. (#2912)

## Description:

Nuke trajectory prediction now will show interception with allied SAMs
if the alliance will break on nuke launch.

Code was also refactored to be shared a bit more. 

In addition, if an incoming alliance would break if accepted, the nuke
launch will break the alliance.

<img width="1199" height="1002" alt="nukepr"
src="https://github.com/user-attachments/assets/c31066d9-66cf-4eaa-be3c-e2fbcfe7965a"
/>

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

bibizu
This commit is contained in:
bibizu
2026-01-18 23:56:43 -05:00
committed by GitHub
parent 969b301aac
commit 3dadfbd23d
3 changed files with 63 additions and 29 deletions
@@ -1,4 +1,5 @@
import { EventBus } from "../../../core/EventBus";
import { listNukeBreakAlliance } from "../../../core/execution/Util";
import { UnitType } from "../../../core/game/Game";
import { TileRef } from "../../../core/game/GameMap";
import { GameView } from "../../../core/game/GameView";
@@ -258,6 +259,18 @@ export class NukeTrajectoryPreviewLayer implements Layer {
break;
}
}
const playersToBreakAllianceWith = listNukeBreakAlliance({
game: this.game,
targetTile,
magnitude: this.game.config().nukeMagnitudes(ghostStructure),
allySmallIds: new Set(
this.game
.myPlayer()
?.allies()
.map((a) => a.smallID()),
),
threshold: this.game.config().nukeAllianceBreakThreshold(),
});
// Find the point where SAM can intercept
this.targetedIndex = this.trajectoryPoints.length;
// Check trajectory
@@ -270,7 +283,8 @@ export class NukeTrajectoryPreviewLayer implements Layer {
)) {
if (
sam.unit.owner().isMe() ||
this.game.myPlayer()?.isFriendly(sam.unit.owner())
(this.game.myPlayer()?.isFriendly(sam.unit.owner()) &&
!playersToBreakAllianceWith.has(sam.unit.owner().smallID()))
) {
continue;
}