mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 09:30:45 +00:00
Fix sam targetting everything (#1280)
## Description: There was a regression on how sam targets nukes. This fixes it ## 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:
@@ -153,6 +153,8 @@ export interface Config {
|
||||
traitorDuration(): number;
|
||||
nukeMagnitudes(unitType: UnitType): NukeMagnitude;
|
||||
defaultNukeSpeed(): number;
|
||||
defaultNukeTargetableRange(): number;
|
||||
defaultSamRange(): number;
|
||||
nukeDeathFactor(humans: number, tilesOwned: number): number;
|
||||
structureMinDist(): number;
|
||||
isReplay(): boolean;
|
||||
|
||||
@@ -790,6 +790,14 @@ export class DefaultConfig implements Config {
|
||||
return 6;
|
||||
}
|
||||
|
||||
defaultNukeTargetableRange(): number {
|
||||
return 120;
|
||||
}
|
||||
|
||||
defaultSamRange(): number {
|
||||
return 80;
|
||||
}
|
||||
|
||||
// Humans can be population, soldiers attacking, soldiers in boat etc.
|
||||
nukeDeathFactor(humans: number, tilesOwned: number): number {
|
||||
return (5 * humans) / Math.max(1, tilesOwned);
|
||||
|
||||
@@ -13,8 +13,6 @@ import { ParabolaPathFinder } from "../pathfinding/PathFinding";
|
||||
import { PseudoRandom } from "../PseudoRandom";
|
||||
import { NukeType } from "../StatsSchemas";
|
||||
|
||||
const NUKE_TARGETABLE_RADIUS = 120;
|
||||
|
||||
const SPRITE_RADIUS = 16;
|
||||
|
||||
export class NukeExecution implements Execution {
|
||||
@@ -179,7 +177,9 @@ export class NukeExecution implements Execution {
|
||||
if (this.nuke === null || this.nuke.targetTile() === undefined) {
|
||||
return;
|
||||
}
|
||||
const targetRangeSquared = NUKE_TARGETABLE_RADIUS * NUKE_TARGETABLE_RADIUS;
|
||||
const targetRangeSquared =
|
||||
this.mg.config().defaultNukeTargetableRange() *
|
||||
this.mg.config().defaultNukeTargetableRange();
|
||||
const targetTile = this.nuke.targetTile();
|
||||
this.nuke.setTargetable(
|
||||
this.mg.euclideanDistSquared(this.nuke.tile(), targetTile!) <
|
||||
|
||||
@@ -14,8 +14,6 @@ export class SAMLauncherExecution implements Execution {
|
||||
private mg: Game;
|
||||
private active: boolean = true;
|
||||
|
||||
private searchRangeRadius = 80;
|
||||
private targetRangeRadius = 120; // Nuke's target should be in this range to be focusable
|
||||
// As MIRV go very fast we have to detect them very early but we only
|
||||
// shoot the one targeting very close (MIRVWarheadProtectionRadius)
|
||||
private MIRVWarheadSearchRadius = 400;
|
||||
@@ -41,7 +39,7 @@ export class SAMLauncherExecution implements Execution {
|
||||
if (this.sam === null) return null;
|
||||
const nukes = this.mg.nearbyUnits(
|
||||
this.sam.tile(),
|
||||
this.searchRangeRadius,
|
||||
this.mg.config().defaultSamRange(),
|
||||
[UnitType.AtomBomb, UnitType.HydrogenBomb],
|
||||
({ unit }) =>
|
||||
unit.owner() !== this.player &&
|
||||
|
||||
@@ -684,8 +684,14 @@ export class GameImpl implements Game {
|
||||
tile: TileRef,
|
||||
searchRange: number,
|
||||
types: UnitType | UnitType[],
|
||||
predicate?: (value: { unit: Unit; distSquared: number }) => boolean,
|
||||
): Array<{ unit: Unit; distSquared: number }> {
|
||||
return this.unitGrid.nearbyUnits(tile, searchRange, types) as Array<{
|
||||
return this.unitGrid.nearbyUnits(
|
||||
tile,
|
||||
searchRange,
|
||||
types,
|
||||
predicate,
|
||||
) as Array<{
|
||||
unit: Unit;
|
||||
distSquared: number;
|
||||
}>;
|
||||
|
||||
@@ -82,18 +82,18 @@ describe("NukeExecution", () => {
|
||||
game.ref(1, 1),
|
||||
);
|
||||
game.addExecution(nukeExec);
|
||||
// targetable distance is 14400
|
||||
// targetable distance is 400
|
||||
|
||||
//near launch should be targetable (distance src < 14400)
|
||||
//near launch should be targetable (distance src < 400)
|
||||
executeTicks(game, 2);
|
||||
expect(nukeExec.getNuke()!.isTargetable()).toBeTruthy();
|
||||
|
||||
//mid air should not be targetable (distance src > 14400, distance target > 14400)
|
||||
//mid air should not be targetable (distance src > 400, distance target > 400)
|
||||
executeTicks(game, 38);
|
||||
expect(nukeExec.getNuke()!.isTargetable()).toBeFalsy();
|
||||
|
||||
//near target should be targetable (distance target < 14400)
|
||||
executeTicks(game, 10);
|
||||
//near target should be targetable (distance target < 400)
|
||||
executeTicks(game, 35);
|
||||
expect(nukeExec.getNuke()!.isTargetable()).toBeTruthy();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -1,21 +1,22 @@
|
||||
import { NukeExecution } from "../src/core/execution/NukeExecution";
|
||||
import { SAMLauncherExecution } from "../src/core/execution/SAMLauncherExecution";
|
||||
import { SpawnExecution } from "../src/core/execution/SpawnExecution";
|
||||
import { UpgradeStructureExecution } from "../src/core/execution/UpgradeStructureExecution";
|
||||
import { NukeExecution } from "../../../src/core/execution/NukeExecution";
|
||||
import { SAMLauncherExecution } from "../../../src/core/execution/SAMLauncherExecution";
|
||||
import { SpawnExecution } from "../../../src/core/execution/SpawnExecution";
|
||||
import { UpgradeStructureExecution } from "../../../src/core/execution/UpgradeStructureExecution";
|
||||
import {
|
||||
Game,
|
||||
Player,
|
||||
PlayerInfo,
|
||||
PlayerType,
|
||||
UnitType,
|
||||
} from "../src/core/game/Game";
|
||||
import { setup } from "./util/Setup";
|
||||
import { constructionExecution, executeTicks } from "./util/utils";
|
||||
} from "../../../src/core/game/Game";
|
||||
import { setup } from "../../util/Setup";
|
||||
import { constructionExecution, executeTicks } from "../../util/utils";
|
||||
|
||||
let game: Game;
|
||||
let attacker: Player;
|
||||
let defender: Player;
|
||||
let far_defender: Player;
|
||||
let middle_defender: Player;
|
||||
|
||||
describe("SAM", () => {
|
||||
beforeEach(async () => {
|
||||
@@ -31,6 +32,14 @@ describe("SAM", () => {
|
||||
null,
|
||||
"defender_id",
|
||||
);
|
||||
const middle_defender_info = new PlayerInfo(
|
||||
undefined,
|
||||
"us",
|
||||
"middle_defender_id",
|
||||
PlayerType.Human,
|
||||
null,
|
||||
"middle_defender_id",
|
||||
);
|
||||
const far_defender_info = new PlayerInfo(
|
||||
undefined,
|
||||
"us",
|
||||
@@ -48,11 +57,16 @@ describe("SAM", () => {
|
||||
"attacker_id",
|
||||
);
|
||||
game.addPlayer(defender_info);
|
||||
game.addPlayer(middle_defender_info);
|
||||
game.addPlayer(far_defender_info);
|
||||
game.addPlayer(attacker_info);
|
||||
|
||||
game.addExecution(
|
||||
new SpawnExecution(game.player(defender_info.id).info(), game.ref(1, 1)),
|
||||
new SpawnExecution(
|
||||
game.player(middle_defender_info.id).info(),
|
||||
game.ref(50, 1),
|
||||
),
|
||||
new SpawnExecution(
|
||||
game.player(far_defender_info.id).info(),
|
||||
game.ref(199, 1),
|
||||
@@ -66,6 +80,7 @@ describe("SAM", () => {
|
||||
|
||||
attacker = game.player("attacker_id");
|
||||
defender = game.player("defender_id");
|
||||
middle_defender = game.player("middle_defender_id");
|
||||
far_defender = game.player("far_defender_id");
|
||||
|
||||
constructionExecution(game, attacker, 7, 7, UnitType.MissileSilo);
|
||||
@@ -165,9 +180,9 @@ describe("SAM", () => {
|
||||
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(
|
||||
const sam1 = middle_defender.buildUnit(
|
||||
UnitType.SAMLauncher,
|
||||
game.ref(targetDistance / 2, 1),
|
||||
game.ref(50, 1),
|
||||
{},
|
||||
);
|
||||
game.addExecution(new SAMLauncherExecution(defender, null, sam1));
|
||||
@@ -192,7 +207,6 @@ describe("SAM", () => {
|
||||
targetDistance / game.config().defaultNukeSpeed(),
|
||||
);
|
||||
executeTicks(game, ticksToExecute);
|
||||
|
||||
expect(nukeExecution.isActive()).toBeFalsy();
|
||||
expect(sam1.isInCooldown()).toBeFalsy();
|
||||
expect(sam2.isInCooldown()).toBeTruthy();
|
||||
@@ -42,6 +42,14 @@ export class TestConfig extends DefaultConfig {
|
||||
return this._defaultNukeSpeed;
|
||||
}
|
||||
|
||||
defaultNukeTargetableRange(): number {
|
||||
return 20;
|
||||
}
|
||||
|
||||
defaultSamRange(): number {
|
||||
return 20;
|
||||
}
|
||||
|
||||
spawnImmunityDuration(): Tick {
|
||||
return 0;
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user