Add curved MIRV trajectory

This commit is contained in:
Tom
2025-05-11 21:30:58 +02:00
parent 6482fba2e5
commit 59e71c83f2
5 changed files with 35 additions and 39 deletions
-11
View File
@@ -399,17 +399,6 @@ export class UnitLayer implements Layer {
trail.push(unit.lastTile());
}
// Paint new trail
for (const t of trail.slice(-newTrailSize)) {
this.paintCell(
this.game.x(t),
this.game.y(t),
rel,
this.theme.territoryColor(unit.owner()),
150,
this.unitTrailContext,
);
}
this.drawTrail(
trail.slice(-newTrailSize),
this.theme.territoryColor(unit.owner()),
+14 -15
View File
@@ -10,7 +10,7 @@ import {
UnitType,
} from "../game/Game";
import { TileRef } from "../game/GameMap";
import { AirPathFinder } from "../pathfinding/PathFinding";
import { ParabolaPathFinder } from "../pathfinding/PathFinding";
import { PseudoRandom } from "../PseudoRandom";
import { simpleHash } from "../Util";
import { NukeExecution } from "./NukeExecution";
@@ -29,12 +29,14 @@ export class MirvExecution implements Execution {
private random: PseudoRandom;
private pathFinder: AirPathFinder;
private pathFinder: ParabolaPathFinder;
private targetPlayer: Player | TerraNullius;
private separateDst: TileRef;
private speed: number = -1;
constructor(
private senderID: PlayerID,
private dst: TileRef,
@@ -49,9 +51,10 @@ export class MirvExecution implements Execution {
this.random = new PseudoRandom(mg.ticks() + simpleHash(this.senderID));
this.mg = mg;
this.pathFinder = new AirPathFinder(mg, this.random);
this.pathFinder = new ParabolaPathFinder(mg);
this.player = mg.player(this.senderID);
this.targetPlayer = this.mg.owner(this.dst);
this.speed = this.mg.config().defaultNukeSpeed();
this.mg
.stats()
@@ -76,6 +79,7 @@ export class MirvExecution implements Execution {
);
const y = Math.max(0, this.mg.y(this.dst) - 500) + 50;
this.separateDst = this.mg.ref(x, y);
this.pathFinder.computeControlPoints(spawn, this.separateDst);
this.mg.displayMessage(
`⚠️⚠️⚠️ ${this.player.name()} - MIRV INBOUND ⚠️⚠️⚠️`,
@@ -84,18 +88,13 @@ export class MirvExecution implements Execution {
);
}
for (let i = 0; i < 4; i++) {
const result = this.pathFinder.nextTile(
this.nuke.tile(),
this.separateDst,
);
if (result === true) {
this.separate();
this.active = false;
return;
} else {
this.nuke.move(result);
}
const result = this.pathFinder.nextTile(this.speed);
if (result === true) {
this.separate();
this.active = false;
return;
} else {
this.nuke.move(result);
}
}
+6 -1
View File
@@ -95,7 +95,12 @@ export class NukeExecution implements Execution {
this.active = false;
return;
}
this.pathFinder.computeControlPoints(spawn, this.dst);
const maxVertex = this.type == UnitType.MIRVWarhead ? 0 : null;
this.pathFinder.computeControlPoints(
spawn,
this.dst,
this.type != UnitType.MIRVWarhead,
);
this.nuke = this.player.buildUnit(this.type, 0, spawn, {
detonationDst: this.dst,
});
+8 -9
View File
@@ -11,7 +11,11 @@ export class ParabolaPathFinder {
private curve: BezierCurve;
private distance: number;
computeControlPoints(orig: TileRef, dst: TileRef) {
computeControlPoints(
orig: TileRef,
dst: TileRef,
distanceBasedVertex = true,
) {
const origX = this.mg.x(orig);
const origY = this.mg.y(orig);
const dstX = this.mg.x(dst);
@@ -23,15 +27,10 @@ export class ParabolaPathFinder {
this.distance = Math.sqrt(dx * dx + dy * dy);
const x0 = origX + (dstX - origX) / 4;
const y0 = Math.max(
origY + (dstY - origY) / 4 - Math.max(this.distance / 3, 50),
0,
);
const maxVertex = distanceBasedVertex ? Math.max(this.distance / 3, 50) : 0;
const y0 = Math.max(origY + (dstY - origY) / 4 - maxVertex, 0);
const x1 = origX + ((dstX - origX) * 3) / 4;
const y1 = Math.max(
origY + ((dstY - origY) * 3) / 4 - Math.max(this.distance / 3, 50),
0,
);
const y1 = Math.max(origY + ((dstY - origY) * 3) / 4 - maxVertex, 0);
this.curve.setControlPoint0(x0, y0);
this.curve.setControlPoint1(x1, y1);
+7 -3
View File
@@ -48,10 +48,14 @@ export class BezierCurve {
private x0: number,
private y0: number,
private x1: number,
private y2: number,
private y1: number,
) {
this.controlPoint0X = x0;
this.controlPoint0Y = y0;
this.controlPoint1X = x1;
this.controlPoint1Y = y1;
const dx = this.x1 - this.x0;
const dy = this.y2 - this.y0;
const dy = this.y1 - this.y0;
const dist = Math.abs(this.x1 - this.x0);
}
@@ -87,7 +91,7 @@ export class BezierCurve {
Math.pow(1 - this.t, 3) * this.y0 +
3 * Math.pow(1 - this.t, 2) * this.t * this.controlPoint0Y +
3 * (1 - this.t) * Math.pow(this.t, 2) * this.controlPoint1Y +
Math.pow(this.t, 3) * this.y2;
Math.pow(this.t, 3) * this.y1;
return { x: nextX, y: nextY };
}
}