Set a targetable status for nukes (#1174)

## Description:

Set a targetable status for units (specifically atom bomb and hydro)
A nuke is targetable near launch and target but is untargetable mid air.
An untargetable unit is half transparent to show that it cannot be
destroyed.


![targetable](https://github.com/user-attachments/assets/cc6769ff-95ab-4294-9a8e-10f909711f68)

## 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
- [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:

Vivacious Box
This commit is contained in:
Vivacious Box
2025-06-15 08:23:13 +02:00
committed by GitHub
parent 4317285b17
commit 7fa11ed035
9 changed files with 107 additions and 16 deletions
+30 -3
View File
@@ -133,10 +133,37 @@ describe("SAM", () => {
expect([sam1, sam2].filter((s) => s.isInCooldown())).toHaveLength(1);
});
test("SAMs should target only nukes aimed at nearby targets", async () => {
test("SAMs should target close to launch site", async () => {
const targetDistance = 199;
// Close SAM: should not intercept anything
const sam1 = defender.buildUnit(UnitType.SAMLauncher, game.ref(1, 1), {});
// Close SAM: should intercept the nuke
const sam = defender.buildUnit(UnitType.SAMLauncher, game.ref(1, 1), {});
game.addExecution(new SAMLauncherExecution(defender, null, sam));
const nukeExecution = new NukeExecution(
UnitType.AtomBomb,
attacker,
game.ref(targetDistance, 1),
null,
);
game.addExecution(nukeExecution);
// Long distance nuke: compute the proper number of ticks
const ticksToExecute = Math.ceil(
targetDistance / game.config().defaultNukeSpeed(),
);
executeTicks(game, ticksToExecute);
expect(nukeExecution.isActive()).toBeFalsy();
expect(sam.isInCooldown()).toBeTruthy();
});
test("SAMs should target only nukes aimed at nearby targets if not close to launch site", async () => {
const targetDistance = 199;
// Middle SAM: should not intercept the nuke
const sam1 = defender.buildUnit(
UnitType.SAMLauncher,
game.ref(targetDistance / 2, 1),
{},
);
game.addExecution(new SAMLauncherExecution(defender, null, sam1));
// Far SAM: Should intercept the nuke. Use the far_defender so the SAM can be built
@@ -69,4 +69,27 @@ describe("NukeExecution", () => {
expect(sam.touch).toHaveBeenCalled();
expect(defensePost.touch).not.toHaveBeenCalled();
});
test("nuke should only be targetable near src and dst", async () => {
const nukeExec = new NukeExecution(
UnitType.AtomBomb,
player,
game.ref(199, 199),
game.ref(1, 1),
);
game.addExecution(nukeExec);
// targetable distance is 14400
//near launch should be targetable (distance src < 14400)
executeTicks(game, 2);
expect(nukeExec.getNuke()!.isTargetable()).toBeTruthy();
//mid air should not be targetable (distance src > 14400, distance target > 14400)
executeTicks(game, 38);
expect(nukeExec.getNuke()!.isTargetable()).toBeFalsy();
//near target should be targetable (distance target < 14400)
executeTicks(game, 10);
expect(nukeExec.getNuke()!.isTargetable()).toBeTruthy();
});
});