cache unreachable nukes and filter targeted nukes earlier

This commit is contained in:
abodc
2026-02-17 18:22:22 +02:00
parent b3a153b8d2
commit 20f9bbcce9
+13 -8
View File
@@ -27,7 +27,9 @@ 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 tick.
private readonly precomputedNukes: Map<number, InterceptionTile> = new Map();
// Null interception tile means there are no interception tiles in range. Store it to
private readonly precomputedNukes: Map<number, InterceptionTile | null> =
new Map();
private readonly missileSpeed: number;
constructor(
@@ -89,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()
);
},
);
@@ -102,6 +105,10 @@ class SAMTargetingSystem {
const nukeId = nuke.unit.id();
const cached = this.precomputedNukes.get(nukeId);
if (cached !== undefined) {
if (cached === null) {
// Already computed as unreachable, skip
continue;
}
if (cached.tick === ticks) {
// Time to shoot!
targets.push({ tile: cached.tile, unit: nuke.unit });
@@ -128,16 +135,14 @@ class SAMTargetingSystem {
tile: interceptionTile.tile,
});
}
} else {
// Store unreachable nukes in order to prevent useless interception computation
this.precomputedNukes.set(nukeId, null);
}
// Don't permanently cache unreachable nukes, the nuke moves each tick
// and may become interceptable from a different angle on a future tick
}
// Filter out nukes already being targeted by another SAM
const available = targets.filter((t) => !t.unit.targetedBySAM());
return (
available.sort((a: Target, b: Target) => {
targets.sort((a: Target, b: Target) => {
// Prioritize Hydrogen Bombs
if (
a.unit.type() === UnitType.HydrogenBomb &&