mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 13:00:42 +00:00
🔴 Major SAM Targeting Fix (#3223)
## Description: Bug (before): In multi-nuke scenarios (e.g., 6 incoming nukes), SAMs, when stacked, could behave like they only engage one nuke at a time, letting other nukes slip through and wipe the SAM stack. This was most noticeable when nukes entered from certain angles/entry sides (from what I’ve noticed, it happens more often in the 2 o’clock to 6 o’clock direction). <img width="734" height="743" alt="asadasada" src="https://github.com/user-attachments/assets/7ca6c9ef-b2b4-47ea-bed2-249a84c8f5ed" /> What was fixed: 1- Removed permanent "unreachable" caching: When a nuke was out of SAM range on first evaluation, it was cached as null (permanently unreachable) and never re-evaluated. Since nukes move each tick, they could later enter interception range but would be ignored. The fix removes this permanent cache, so nukes are re-evaluated every tick. 2 - Moved targetedBySAM filter into the targeting system: The targetedBySAM() check was at the launch decision, if the highest-priority nuke was already claimed by another SAM, the launcher skipped firing entirely instead of falling back to the next best target. The fix moves the filter inside getSingleTarget() so claimed nukes are excluded before ranking. 3 - Cleared targetedBySAM flag on SAM missile abort: When a SAM missile aborted (for example target became allied), the targetedBySAM flag was never cleared. This permanently prevented all other SAMs from targeting that nuke. The fix calls setTargetedBySAM(false) on abort so the nuke becomes available for re-targeting. **Videos:** I uploaded a before/after clip showing SAM performance intercepting 6 nukes, before the fix, nukes could break through, but after the fix, SAMs consistently intercept as expected. Before: https://github.com/user-attachments/assets/d5a85354-f35c-4aca-82f8-902f5966312b after: https://github.com/user-attachments/assets/54074c09-fbdf-44d5-a88c-b1d54b20fee2 - Deployed for further testing ## 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: abodcraft1 --------- Co-authored-by: Ryan <7389646+ryanbarlow97@users.noreply.github.com>
This commit is contained in:
@@ -26,8 +26,8 @@ type InterceptionTile = {
|
||||
*/
|
||||
class SAMTargetingSystem {
|
||||
// Interception tiles are computed a single time, but it may not be reachable yet.
|
||||
// Store the result so it can be intercepted at the proper time, rather than recomputing each ticks
|
||||
// Null interception tile means there are no interception tiles in range. Store it to
|
||||
// Store the result so it can be intercepted at the proper time, rather than recomputing each tick.
|
||||
// Null interception tile means there are no interception tiles in range. Store it to avoid recomputing.
|
||||
private readonly precomputedNukes: Map<number, InterceptionTile | null> =
|
||||
new Map();
|
||||
private readonly missileSpeed: number;
|
||||
@@ -91,7 +91,8 @@ class SAMTargetingSystem {
|
||||
return (
|
||||
isUnit(unit) &&
|
||||
unit.owner() !== this.sam.owner() &&
|
||||
!this.sam.owner().isFriendly(unit.owner())
|
||||
!this.sam.owner().isFriendly(unit.owner()) &&
|
||||
!unit.targetedBySAM()
|
||||
);
|
||||
},
|
||||
);
|
||||
@@ -105,7 +106,7 @@ class SAMTargetingSystem {
|
||||
const cached = this.precomputedNukes.get(nukeId);
|
||||
if (cached !== undefined) {
|
||||
if (cached === null) {
|
||||
// Known unreachable, skip.
|
||||
// Already computed as unreachable, skip
|
||||
continue;
|
||||
}
|
||||
if (cached.tick === ticks) {
|
||||
@@ -259,8 +260,8 @@ export class SAMLauncherExecution implements Execution {
|
||||
}
|
||||
}
|
||||
|
||||
const isSingleTarget = target && !target.unit.targetedBySAM();
|
||||
if (isSingleTarget || mirvWarheadTargets.length > 0) {
|
||||
// target is already filtered to exclude nukes targeted by other SAMs
|
||||
if (target || mirvWarheadTargets.length > 0) {
|
||||
this.sam.launch();
|
||||
const type =
|
||||
mirvWarheadTargets.length > 0
|
||||
|
||||
@@ -50,6 +50,10 @@ export class SAMMissileExecution implements Execution {
|
||||
this.target.owner() === this.SAMMissile.owner() ||
|
||||
!nukesWhitelist.includes(this.target.type())
|
||||
) {
|
||||
// Clear the flag so other SAMs can re-target this nuke
|
||||
if (this.target.isActive()) {
|
||||
this.target.setTargetedBySAM(false);
|
||||
}
|
||||
this.SAMMissile.delete(false);
|
||||
this.active = false;
|
||||
return;
|
||||
|
||||
Reference in New Issue
Block a user