Embrace the aftergame! 😄 (#3410)

## Description:

In v30 we have the following change to prevent teammates from destroying
your structures:

**Block nuking teammate structures** - Nukes blocked if they'd hit a
teammate's structure (that was possible by nuking oceans / rivers) (by
@FloPinguin)

Original idea was from Wonder.
I think it makes sense, but it has a side effect: The aftergame, which
many players love, will be dead because of this change.

<img width="835" height="103" alt="image"
src="https://github.com/user-attachments/assets/521b7915-be28-4d83-8d45-65835e7385ab"
/>

<img width="1101" height="105" alt="image"
src="https://github.com/user-attachments/assets/db74a9c6-da12-44a2-aa06-f042b8e58b8a"
/>

I think a lot of complaints will follow after v30 is live. 

So why not add a little bit of logic for the aftergame?
After a team wins/loses, players can nuke their teammates. No longer
need to aim for water. SAMs also intercept teammate nukes in this phase.

## 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-03-12 04:39:39 +01:00
committed by GitHub
parent 36572b69b5
commit 3013133d08
2 changed files with 33 additions and 10 deletions
+26 -7
View File
@@ -116,12 +116,20 @@ class SAMTargetingSystem {
detectionRange,
[UnitType.AtomBomb, UnitType.HydrogenBomb],
({ unit }) => {
return (
isUnit(unit) &&
unit.owner() !== this.sam.owner() &&
!this.sam.owner().isFriendly(unit.owner()) &&
!unit.targetedBySAM()
);
if (!isUnit(unit) || unit.targetedBySAM()) return false;
if (unit.owner() === this.sam.owner()) return false;
const samOwner = this.sam.owner();
const nukeOwner = unit.owner();
// After game-over in team games, SAMs also target teammate nukes (aftergame fun)
if (samOwner.isFriendly(nukeOwner)) {
return (
this.mg.getWinner() !== null && samOwner.isOnSameTeam(nukeOwner)
);
}
return true;
},
);
@@ -271,7 +279,18 @@ export class SAMLauncherExecution implements Execution {
({ unit }) => {
if (!isUnit(unit)) return false;
if (unit.owner() === this.player) return false;
if (this.player.isFriendly(unit.owner())) return false;
// After game-over in team games, SAMs also target teammate MIRVs (aftergame fun)
const nukeOwner = unit.owner();
if (this.player.isFriendly(nukeOwner)) {
if (
this.mg.getWinner() === null ||
!this.player.isOnSameTeam(nukeOwner)
) {
return false;
}
}
const dst = unit.targetTile();
return (
this.sam !== null &&
+7 -3
View File
@@ -1180,16 +1180,20 @@ export class PlayerImpl implements Player {
return false;
}
const owner = this.mg.owner(tile);
// Allow nuking teammates after the game is over (aftergame fun)
const gameOver = this.mg.getWinner() !== null;
if (owner.isPlayer()) {
if (this.isOnSameTeam(owner)) {
if (this.isOnSameTeam(owner) && !gameOver) {
return false;
}
}
// Prevent launching nukes that would hit teammate structures (only in team games)
// Prevent launching nukes that would hit teammate structures (only in team games).
// Disabled after game-over so players can nuke teammates in the aftergame.
if (
this.mg.config().gameConfig().gameMode === GameMode.Team &&
nukeType !== UnitType.MIRV
nukeType !== UnitType.MIRV &&
!gameOver
) {
const magnitude = this.mg.config().nukeMagnitudes(nukeType);
const wouldHitTeammate = this.mg.anyUnitNearby(