mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-22 18:06:39 +00:00
Add curved MIRV trajectory
This commit is contained in:
@@ -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()),
|
||||
|
||||
@@ -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);
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -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,
|
||||
});
|
||||
|
||||
@@ -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);
|
||||
|
||||
@@ -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 };
|
||||
}
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user