Skip to content

Made intercepting multiple warheads actually increase the cool down by the required amount #4638

Open
TKTK123456 wants to merge 6 commits into
openfrontio:mainfrom
TKTK123456:MIRV
Open

Made intercepting multiple warheads actually increase the cool down by the required amount #4638
TKTK123456 wants to merge 6 commits into
openfrontio:mainfrom
TKTK123456:MIRV

Conversation

@TKTK123456

Copy link
Copy Markdown
Contributor

Before opening a PR: discuss new features on Discord first, and file bugs or small improvements as issues. You must be assigned to an approved issue — unsolicited PRs will be auto-closed.

Add approved & assigned issue number here:

Resolves #4508

Description:

Made intercepting multiple warheads actually increase the cool down by the required amount (doesn't perfectly resolve the issue but its as good as I could get it to be)

Please complete the following:

  • I have added screenshots for all UI updates
  • I process any text displayed to the user through translateText() and I've added it to the en.json file
  • I have added relevant tests to the test directory

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

tktk1234567

@coderabbitai

coderabbitai Bot commented Jul 18, 2026

Copy link
Copy Markdown
Contributor

Review Change Stack

Note

Reviews paused

It looks like this branch is under active development. To avoid overwhelming you with review comments due to an influx of new commits, CodeRabbit has automatically paused this review. You can configure this behavior by changing the reviews.auto_review.auto_pause_after_reviewed_commits setting.

Use the following commands to manage reviews:

  • @coderabbitai resume to resume automatic reviews.
  • @coderabbitai review to trigger a single review.

Use the checkboxes below for quick actions:

  • ▶️ Resume reviews
  • ✅ Review completed - (🔄 Check again to review again)

Walkthrough

MIRV interception eligibility now uses the SAM’s level-based Manhattan range. Later intercepted warheads may trigger additional SAM launches when the launcher is not cooling down, while all intercepted warheads are deleted and statistics count launches that occurred.

Changes

MIRV SAM interception

Layer / File(s) Summary
MIRV interception targeting and launches
src/core/execution/SAMLauncherExecution.ts
Removes the obsolete protection-radius field, filters MIRV targets by SAM-level range, conditionally launches for later warheads outside cooldown, and records the number of additional launches.

Estimated code review effort: 2 (Simple) | ~10 minutes

Possibly related PRs

Poem

MIRVs cross the sky,
SAMs launch when cooldowns fly.
Warheads fade from sight,
Stats record each extra flight.

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Linked Issues check ⚠️ Warning The PR improves MIRV interception cooldown, but it does not clearly make MIRV warheads behave like atom bombs. Update MIRV warhead handling to reuse atom-bomb behavior and verify the full acceptance criteria for #4508.
✅ Passed checks (4 passed)
Check name Status Explanation
Title check ✅ Passed The title matches the main change: multi-warhead interception now affects cooldown.
Description check ✅ Passed The description is on-topic and describes the cooldown fix tied to issue #4508.
Out of Scope Changes check ✅ Passed All shown changes stay within MIRV interception and cooldown handling.
Docstring Coverage ✅ Passed No functions found in the changed files to evaluate docstring coverage. Skipping docstring coverage check.

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/core/execution/SAMLauncherExecution.ts (1)

323-351: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Track exact interceptions and break properly when on cooldown.

A return inside forEach acts like a continue statement, failing to stop the loop when the SAM is on cooldown. Additionally, stats and messages use mirvWarheadTargets.length before verifying how many warheads were actually intercepted.

Using a standard for loop lets us break securely when the cooldown is reached and track the exact interceptedCount. It also removes the need for this.sam !== null checks since we avoid a closure block.

🛠️ Proposed fix
-        // Message
-        this.mg.displayMessage(
-          "events_display.mirv_warheads_intercepted",
-          MessageType.SAM_HIT,
-          samOwner.id(),
-          undefined,
-          { count: mirvWarheadTargets.length },
-        );
-
-        mirvWarheadTargets.forEach(({ unit: u }, i) => {
-          if (this.sam !== null && i > 0) {
-            if (this.sam.isInCooldown()) {
-              return;
-            }
-            this.sam.launch();
-          }
-
-          // Delete warheads
-          u.delete();
-        });
-
-        // Record stats
-        this.mg
-          .stats()
-          .bombIntercept(
-            samOwner,
-            UnitType.MIRVWarhead,
-            mirvWarheadTargets.length,
-          );
+        let interceptedCount = 0;
+
+        for (let i = 0; i < mirvWarheadTargets.length; i++) {
+          const u = mirvWarheadTargets[i].unit;
+          if (i > 0) {
+            if (this.sam.isInCooldown()) {
+              break;
+            }
+            this.sam.launch();
+          }
+          u.delete();
+          interceptedCount++;
+        }
+
+        // Message
+        this.mg.displayMessage(
+          "events_display.mirv_warheads_intercepted",
+          MessageType.SAM_HIT,
+          samOwner.id(),
+          undefined,
+          { count: interceptedCount },
+        );
+
+        // Record stats
+        this.mg
+          .stats()
+          .bombIntercept(
+            samOwner,
+            UnitType.MIRVWarhead,
+            interceptedCount,
+          );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/execution/SAMLauncherExecution.ts` around lines 323 - 351, Replace
the mirvWarheadTargets.forEach callback with a standard loop that stops with
break when this.sam.isInCooldown() is reached, while preserving SAM launch
behavior. Track the number actually deleted in an interceptedCount variable, and
use that count for the interception message and bombIntercept stats instead of
mirvWarheadTargets.length; structure the loop so redundant this.sam !== null
checks are unnecessary.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/core/execution/SAMLauncherExecution.ts`:
- Around line 274-306: Update the MIRV warhead target collection in the
execution method to use const, remove the redundant level-based filter, and
delete the console.log debug statement. Leave target selection to the
interception loop’s existing cooldown-aware break behavior.

---

Outside diff comments:
In `@src/core/execution/SAMLauncherExecution.ts`:
- Around line 323-351: Replace the mirvWarheadTargets.forEach callback with a
standard loop that stops with break when this.sam.isInCooldown() is reached,
while preserving SAM launch behavior. Track the number actually deleted in an
interceptedCount variable, and use that count for the interception message and
bombIntercept stats instead of mirvWarheadTargets.length; structure the loop so
redundant this.sam !== null checks are unnecessary.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7391fd5b-f626-4406-b294-27349225e6fa

📥 Commits

Reviewing files that changed from the base of the PR and between eee7d79 and c43480f.

📒 Files selected for processing (1)
  • src/core/execution/SAMLauncherExecution.ts

Comment thread src/core/execution/SAMLauncherExecution.ts Outdated
@github-project-automation github-project-automation Bot moved this from Triage to Development in OpenFront Release Management Jul 18, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/core/execution/SAMLauncherExecution.ts (1)

113-117: 🎯 Functional Correctness | 🟡 Minor | ⚡ Quick win

Add a regression test for the expanded detection range. The current 199-distance case is still inside the old 2× range (300), so it does not cover this change. Use a target beyond 300 and within 600.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/execution/SAMLauncherExecution.ts` around lines 113 - 117, Add a
regression test covering the expanded detection range used by
SAMLauncherExecution, placing the target at a distance greater than 300 and no
more than 600 from the SAM tile so the test fails with the former 2× range but
passes with the current 4× range.

Source: Coding guidelines

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/core/execution/SAMLauncherExecution.ts`:
- Around line 113-117: Add a regression test covering the expanded detection
range used by SAMLauncherExecution, placing the target at a distance greater
than 300 and no more than 600 from the SAM tile so the test fails with the
former 2× range but passes with the current 4× range.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 33e4f4bc-f08c-410e-ab46-12d5ade0941e

📥 Commits

Reviewing files that changed from the base of the PR and between c43480f and e6b37d7.

📒 Files selected for processing (1)
  • src/core/execution/SAMLauncherExecution.ts

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/core/execution/SAMLauncherExecution.ts (1)

318-346: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Fix the interception loop and the stat count.

The forEach loop uses return, which skips to the next item instead of breaking the loop. This means the code skips launching missiles when on cooldown, but still iterates and skips deleting the remaining warheads. Also, the stats and message use mirvWarheadTargets.length, which reports the total targets found instead of the ones actually intercepted and deleted.

Using a cleaner for...of loop with break stops the iteration correctly. We can then use the actual intercepted count for the stats and message.

♻️ Proposed fix
-        // Message
-        this.mg.displayMessage(
-          "events_display.mirv_warheads_intercepted",
-          MessageType.SAM_HIT,
-          samOwner.id(),
-          undefined,
-          { count: mirvWarheadTargets.length },
-        );
-
-        mirvWarheadTargets.forEach(({ unit: u }, i) => {
-          if (this.sam !== null && i > 0) {
-            if (this.sam.isInCooldown()) {
-              return;
-            }
-            this.sam.launch();
-          }
-
-          // Delete warheads
-          u.delete();
-        });
-
-        // Record stats
-        this.mg
-          .stats()
-          .bombIntercept(
-            samOwner,
-            UnitType.MIRVWarhead,
-            mirvWarheadTargets.length,
-          );
+        let interceptedCount = 0;
+
+        for (const { unit: u } of mirvWarheadTargets) {
+          if (interceptedCount > 0) {
+            if (this.sam.isInCooldown()) {
+              break;
+            }
+            this.sam.launch();
+          }
+
+          u.delete();
+          interceptedCount++;
+        }
+
+        // Message
+        this.mg.displayMessage(
+          "events_display.mirv_warheads_intercepted",
+          MessageType.SAM_HIT,
+          samOwner.id(),
+          undefined,
+          { count: interceptedCount },
+        );
+
+        // Record stats
+        this.mg
+          .stats()
+          .bombIntercept(
+            samOwner,
+            UnitType.MIRVWarhead,
+            interceptedCount,
+          );
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/execution/SAMLauncherExecution.ts` around lines 318 - 346, Update
the MIRV interception loop in the SAM execution flow to use a breakable
iteration, such as for...of, so cooldown stops processing additional warheads
rather than merely skipping one callback. Track the number actually launched and
deleted, then use that intercepted count instead of mirvWarheadTargets.length in
both displayMessage and bombIntercept.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/core/execution/SAMLauncherExecution.ts`:
- Around line 318-346: Update the MIRV interception loop in the SAM execution
flow to use a breakable iteration, such as for...of, so cooldown stops
processing additional warheads rather than merely skipping one callback. Track
the number actually launched and deleted, then use that intercepted count
instead of mirvWarheadTargets.length in both displayMessage and bombIntercept.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 526cf52d-f057-4a1e-b0f8-1a2829ed46bc

📥 Commits

Reviewing files that changed from the base of the PR and between e6b37d7 and b8866be.

📒 Files selected for processing (1)
  • src/core/execution/SAMLauncherExecution.ts

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 18, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (2)
src/core/execution/SAMLauncherExecution.ts (2)

297-300: 📐 Maintainability & Code Quality | 🟠 Major | 🏗️ Heavy lift

Keep the core range check integer-only and add deterministic tests.

samRange() in src/core/configuration/Config.ts uses division, so this new MIRV comparison relies on floating-point math in src/core. Prefer an integer-scaled comparison or integer range helper. Add tests for inside, outside, and boundary targets, plus the new multi-warhead cooldown behavior.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/execution/SAMLauncherExecution.ts` around lines 297 - 300, Update
the MIRV range comparison in SAMLauncherExecution to use integer-only arithmetic
or an existing integer range helper instead of the floating-point samRange()
result. Add deterministic tests covering inside-range, outside-range, and
exact-boundary targets, along with the new multi-warhead cooldown behavior.

Source: Coding guidelines


326-335: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Always delete the current warhead.

return only exits the forEach callback. When the SAM is already in cooldown, u.delete() is skipped, leaving that warhead active and eligible for processing again.

🐛 Proposed fix
         mirvWarheadTargets.forEach(({ unit: u }, i) => {
           if (this.sam !== null && i > 0) {
-            if (this.sam.isInCooldown()) {
-              return;
+            if (!this.sam.isInCooldown()) {
+              this.sam.launch();
             }
-            this.sam.launch();
           }

           // Delete warheads
           u.delete();
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/execution/SAMLauncherExecution.ts` around lines 326 - 335, Update
the forEach callback in the mirvWarheadTargets processing flow so a SAM cooldown
does not bypass the current warhead cleanup. Preserve the cooldown early exit
for launching, but ensure u.delete() executes for every warhead, including those
encountered while this.sam.isInCooldown() is true.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/core/execution/SAMLauncherExecution.ts`:
- Around line 297-300: Update the MIRV range comparison in SAMLauncherExecution
to use integer-only arithmetic or an existing integer range helper instead of
the floating-point samRange() result. Add deterministic tests covering
inside-range, outside-range, and exact-boundary targets, along with the new
multi-warhead cooldown behavior.
- Around line 326-335: Update the forEach callback in the mirvWarheadTargets
processing flow so a SAM cooldown does not bypass the current warhead cleanup.
Preserve the cooldown early exit for launching, but ensure u.delete() executes
for every warhead, including those encountered while this.sam.isInCooldown() is
true.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: b619acb6-e879-4728-893d-0530860a2646

📥 Commits

Reviewing files that changed from the base of the PR and between b8866be and c485fd5.

📒 Files selected for processing (1)
  • src/core/execution/SAMLauncherExecution.ts

coderabbitai[bot]
coderabbitai Bot previously approved these changes Jul 18, 2026

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (3)
src/core/execution/SAMLauncherExecution.ts (3)

297-300: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Add tests for the new MIRV range boundary.

Please add or confirm tests covering targets inside, exactly at, and outside samRange(this.sam.level()). Changes under src/core/ must include tests.

🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/execution/SAMLauncherExecution.ts` around lines 297 - 300, Add tests
for the MIRV range logic around the samRange(this.sam.level()) boundary in
SAMLauncherExecution, covering targets inside the range, exactly at the
boundary, and outside it. Place the tests in the established test suite for this
execution flow and preserve the expected behavior for each case.

Source: Coding guidelines


325-345: 🗄️ Data Integrity & Integration | 🟡 Minor | ⚡ Quick win

Count the initial SAM launch in interception statistics.

this.sam.launch() already runs before the loop, but amountOfWarheads starts at zero and counts only later launches. bombIntercept therefore undercounts every non-empty MIRV interception by one.

Proposed fix
-let amountOfWarheads = 0;
+let amountOfWarheads = 1; // initial launch above
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/execution/SAMLauncherExecution.ts` around lines 325 - 345, Update
the MIRV interception accounting around amountOfWarheads and bombIntercept so
the initial this.sam.launch() is included in the recorded count. Initialize or
increment amountOfWarheads to account for that first launch while preserving the
existing cooldown handling and subsequent-warhead loop behavior.

325-337: 🎯 Functional Correctness | 🟠 Major | ⚡ Quick win

Always delete intercepted warheads, even during cooldown.

When isInCooldown() is true, the callback returns before u.delete(). The warhead remains active and can be intercepted again on a later tick. Skip only the additional launch; keep deletion unconditional.

Proposed fix
 let amountOfWarheads = 0;
 mirvWarheadTargets.forEach(({ unit: u }, i) => {
-  if (this.sam !== null && i > 0) {
-    if (this.sam.isInCooldown()) {
-      return;
-    }
+  if (this.sam !== null && i > 0 && !this.sam.isInCooldown()) {
     amountOfWarheads++;
     this.sam.launch();
   }

-  // Delete warheads
   u.delete();
 });
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/core/execution/SAMLauncherExecution.ts` around lines 325 - 337, Update
the mirvWarheadTargets callback so cooldown only prevents the additional
this.sam.launch() and amountOfWarheads increment, not the subsequent u.delete().
Remove or restructure the early return from the isInCooldown() branch, while
preserving the existing first-warhead behavior and ensuring every intercepted
warhead is deleted.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Outside diff comments:
In `@src/core/execution/SAMLauncherExecution.ts`:
- Around line 297-300: Add tests for the MIRV range logic around the
samRange(this.sam.level()) boundary in SAMLauncherExecution, covering targets
inside the range, exactly at the boundary, and outside it. Place the tests in
the established test suite for this execution flow and preserve the expected
behavior for each case.
- Around line 325-345: Update the MIRV interception accounting around
amountOfWarheads and bombIntercept so the initial this.sam.launch() is included
in the recorded count. Initialize or increment amountOfWarheads to account for
that first launch while preserving the existing cooldown handling and
subsequent-warhead loop behavior.
- Around line 325-337: Update the mirvWarheadTargets callback so cooldown only
prevents the additional this.sam.launch() and amountOfWarheads increment, not
the subsequent u.delete(). Remove or restructure the early return from the
isInCooldown() branch, while preserving the existing first-warhead behavior and
ensuring every intercepted warhead is deleted.

ℹ️ Review info
⚙️ Run configuration

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

Run ID: 7eb24434-fe62-4750-9cd1-262e911b126c

📥 Commits

Reviewing files that changed from the base of the PR and between c485fd5 and 3ad0763.

📒 Files selected for processing (1)
  • src/core/execution/SAMLauncherExecution.ts

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I thought we were planning on making mirv warheads have the same logic as regular nukes anyways?

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

It wasn't working, unless do you mean that we change there movement speed? (I would advise not unless we want them to be launched directly from the silo)

Copy link
Copy Markdown
Collaborator

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

yeah we can change their movement stpeed

Copy link
Copy Markdown
Contributor Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

if we change the movement speed then we need to have the MIRV warheads launch directly from the silo

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

Status: Development

Development

Successfully merging this pull request may close these issues.

Make MIRV warheads work like atom bombs

2 participants