From 256ac3b1b89fe85a63e098fc74b3e3dc74d627c6 Mon Sep 17 00:00:00 2001 From: DevelopingTom Date: Fri, 23 May 2025 05:47:06 +0200 Subject: [PATCH] SAM not working against MIRV warhead (#818) ## Description: The nukes are setting a `detonationDst` that is never used in UnitImpl. Without the target tile, SAM launchers ignore the MIRV warheads. Illustration with 50 SAM vs 2 warhead: ![image](https://github.com/user-attachments/assets/cac20dc6-9a28-4801-a834-364fa36b612d) The nuke icon is also staying white while being nuked: ![image](https://github.com/user-attachments/assets/badf6630-9a5e-4491-b1b7-1008d32f5efc) ## Please complete the following: - [x] I have added screenshots for all UI updates - [x] I confirm I have thoroughly tested these changes and take full responsibility for any bugs introduced - [x] I understand that submitting code with bugs that could have been caught through manual testing blocks releases and new features for all contributors ## Please put your Discord username so you can be contacted if a bug or regression is found: IngloriousTom --- src/core/execution/NukeExecution.ts | 2 +- src/core/game/Game.ts | 12 +++++++++--- src/core/game/UnitImpl.ts | 3 ++- tests/SAM.test.ts | 8 ++++---- 4 files changed, 16 insertions(+), 9 deletions(-) diff --git a/src/core/execution/NukeExecution.ts b/src/core/execution/NukeExecution.ts index 74e38ca35..daa50dca1 100644 --- a/src/core/execution/NukeExecution.ts +++ b/src/core/execution/NukeExecution.ts @@ -119,7 +119,7 @@ export class NukeExecution implements Execution { this.type !== UnitType.MIRVWarhead, ); this.nuke = this.player.buildUnit(this.type, spawn, { - detonationDst: this.dst, + targetTile: this.dst, }); if (this.mg.hasOwner(this.dst)) { const target = this.mg.owner(this.dst); diff --git a/src/core/game/Game.ts b/src/core/game/Game.ts index 31f581586..ea983b7e0 100644 --- a/src/core/game/Game.ts +++ b/src/core/game/Game.ts @@ -164,9 +164,13 @@ export interface UnitParamsMap { [UnitType.Port]: {}; - [UnitType.AtomBomb]: {}; + [UnitType.AtomBomb]: { + targetTile?: number; + }; - [UnitType.HydrogenBomb]: {}; + [UnitType.HydrogenBomb]: { + targetTile?: number; + }; [UnitType.TradeShip]: { dstPort: Unit; @@ -185,7 +189,9 @@ export interface UnitParamsMap { [UnitType.MIRV]: {}; - [UnitType.MIRVWarhead]: {}; + [UnitType.MIRVWarhead]: { + targetTile?: number; + }; [UnitType.Construction]: {}; } diff --git a/src/core/game/UnitImpl.ts b/src/core/game/UnitImpl.ts index a68f566d7..9c9f965e6 100644 --- a/src/core/game/UnitImpl.ts +++ b/src/core/game/UnitImpl.ts @@ -39,7 +39,8 @@ export class UnitImpl implements Unit { ) { this._lastTile = _tile; this._health = toInt(this.mg.unitInfo(_type).maxHealth ?? 1); - + this._targetTile = + "targetTile" in params ? (params.targetTile ?? undefined) : undefined; this._troops = "troops" in params ? (params.troops ?? 0) : 0; this._lastSetSafeFromPirates = "lastSetSafeFromPirates" in params diff --git a/tests/SAM.test.ts b/tests/SAM.test.ts index 1da6e9114..d8eb2d325 100644 --- a/tests/SAM.test.ts +++ b/tests/SAM.test.ts @@ -63,10 +63,10 @@ describe("SAM", () => { const sam = defender.buildUnit(UnitType.SAMLauncher, game.ref(1, 1), {}); game.addExecution(new SAMLauncherExecution(defender.id(), null, sam)); attacker.buildUnit(UnitType.AtomBomb, game.ref(2, 1), { - detonationDst: game.ref(2, 1), + targetTile: game.ref(2, 1), }); attacker.buildUnit(UnitType.AtomBomb, game.ref(1, 2), { - detonationDst: game.ref(1, 2), + targetTile: game.ref(1, 2), }); expect(attacker.units(UnitType.AtomBomb)).toHaveLength(2); @@ -80,7 +80,7 @@ describe("SAM", () => { game.addExecution(new SAMLauncherExecution(defender.id(), null, sam)); expect(sam.isInCooldown()).toBeFalsy(); const nuke = attacker.buildUnit(UnitType.AtomBomb, game.ref(1, 2), { - detonationDst: game.ref(1, 2), + targetTile: game.ref(1, 2), }); executeTicks(game, 3); @@ -104,7 +104,7 @@ describe("SAM", () => { const sam2 = defender.buildUnit(UnitType.SAMLauncher, game.ref(1, 2), {}); game.addExecution(new SAMLauncherExecution(defender.id(), null, sam2)); const nuke = attacker.buildUnit(UnitType.AtomBomb, game.ref(2, 2), { - detonationDst: game.ref(2, 2), + targetTile: game.ref(2, 2), }); executeTicks(game, 3);