From 3013133d0882ac7503d22ec8edbdd2cb8d36e9e3 Mon Sep 17 00:00:00 2001 From: FloPinguin <25036848+FloPinguin@users.noreply.github.com> Date: Thu, 12 Mar 2026 04:39:39 +0100 Subject: [PATCH] =?UTF-8?q?Embrace=20the=20aftergame!=20=F0=9F=98=84=20(#3?= =?UTF-8?q?410)?= MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit ## 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. image image 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 --- src/core/execution/SAMLauncherExecution.ts | 33 +++++++++++++++++----- src/core/game/PlayerImpl.ts | 10 +++++-- 2 files changed, 33 insertions(+), 10 deletions(-) diff --git a/src/core/execution/SAMLauncherExecution.ts b/src/core/execution/SAMLauncherExecution.ts index 2e1682abb..7d8faefff 100644 --- a/src/core/execution/SAMLauncherExecution.ts +++ b/src/core/execution/SAMLauncherExecution.ts @@ -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 && diff --git a/src/core/game/PlayerImpl.ts b/src/core/game/PlayerImpl.ts index 975d5a70f..f8c5b88cb 100644 --- a/src/core/game/PlayerImpl.ts +++ b/src/core/game/PlayerImpl.ts @@ -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(