This commit is contained in:
1brucben
2025-04-23 22:10:41 +02:00
5 changed files with 70 additions and 84 deletions
+9 -21
View File
@@ -10,8 +10,7 @@ import {
UnitType,
} from "../game/Game";
import { TileRef } from "../game/GameMap";
import { PathFindResultType } from "../pathfinding/AStar";
import { PathFinder } from "../pathfinding/PathFinding";
import { AirPathFinder } from "../pathfinding/PathFinding";
import { PseudoRandom } from "../PseudoRandom";
import { simpleHash } from "../Util";
import { NukeExecution } from "./NukeExecution";
@@ -30,7 +29,7 @@ export class MirvExecution implements Execution {
private random: PseudoRandom;
private pathFinder: PathFinder;
private pathFinder: AirPathFinder;
private targetPlayer: Player | TerraNullius;
@@ -50,7 +49,7 @@ export class MirvExecution implements Execution {
this.random = new PseudoRandom(mg.ticks() + simpleHash(this.senderID));
this.mg = mg;
this.pathFinder = PathFinder.Mini(mg, 10_000);
this.pathFinder = new AirPathFinder(mg, this.random);
this.player = mg.player(this.senderID);
this.targetPlayer = this.mg.owner(this.dst);
@@ -90,23 +89,12 @@ export class MirvExecution implements Execution {
this.nuke.tile(),
this.separateDst,
);
switch (result.type) {
case PathFindResultType.Completed:
this.nuke.move(result.tile);
this.separate();
this.active = false;
return;
case PathFindResultType.NextTile:
this.nuke.move(result.tile);
break;
case PathFindResultType.Pending:
break;
case PathFindResultType.PathNotFound:
consolex.warn(
`nuke cannot find path from ${this.nuke.tile()} to ${this.dst}`,
);
this.active = false;
return;
if (result === true) {
this.separate();
this.active = false;
return;
} else {
this.nuke.move(result);
}
}
}
+6 -34
View File
@@ -11,6 +11,7 @@ import {
UnitType,
} from "../game/Game";
import { TileRef } from "../game/GameMap";
import { AirPathFinder } from "../pathfinding/PathFinding";
import { PseudoRandom } from "../PseudoRandom";
export class NukeExecution implements Execution {
@@ -20,6 +21,7 @@ export class NukeExecution implements Execution {
private nuke: Unit;
private random: PseudoRandom;
private pathFinder: AirPathFinder;
constructor(
private type: NukeType,
@@ -43,6 +45,7 @@ export class NukeExecution implements Execution {
if (this.speed == -1) {
this.speed = this.mg.config().defaultNukeSpeed();
}
this.pathFinder = new AirPathFinder(mg, this.random);
}
public target(): Player | TerraNullius {
@@ -143,45 +146,14 @@ export class NukeExecution implements Execution {
return;
}
const r = (this.mg.y(this.dst) * this.mg.x(this.dst)) % 10;
const s = this.speed + (this.mg.ticks() % r);
for (let i = 0; i < this.speed; i++) {
const x = this.mg.x(this.nuke.tile());
const y = this.mg.y(this.nuke.tile());
const dstX = this.mg.x(this.dst);
const dstY = this.mg.y(this.dst);
// If we've reached the destination, detonate
if (x === dstX && y === dstY) {
// Move to next tile
const nextTile = this.pathFinder.nextTile(this.nuke.tile(), this.dst);
if (nextTile === true) {
this.detonate();
return;
}
// Calculate next position
let nextX = x;
let nextY = y;
const ratio = Math.floor(
1 + Math.abs(dstY - y) / (Math.abs(dstX - x) + 1),
);
if (this.random.chance(ratio) && x != dstX) {
if (x < dstX) nextX++;
else if (x > dstX) nextX--;
} else {
if (y < dstY) nextY++;
else if (y > dstY) nextY--;
}
// Move to next tile
const nextTile = this.mg.ref(nextX, nextY);
if (nextTile !== undefined) {
this.nuke.move(nextTile);
} else {
consolex.warn(`invalid tile position ${nextX},${nextY}`);
this.active = false;
return;
}
}
}
+16 -27
View File
@@ -1,4 +1,3 @@
import { consolex } from "../Consolex";
import {
Execution,
Game,
@@ -8,12 +7,12 @@ import {
UnitType,
} from "../game/Game";
import { TileRef } from "../game/GameMap";
import { PathFindResultType } from "../pathfinding/AStar";
import { PathFinder } from "../pathfinding/PathFinding";
import { AirPathFinder } from "../pathfinding/PathFinding";
import { PseudoRandom } from "../PseudoRandom";
export class SAMMissileExecution implements Execution {
private active = true;
private pathFinder: PathFinder;
private pathFinder: AirPathFinder;
private SAMMissile: Unit;
private mg: Game;
@@ -26,7 +25,7 @@ export class SAMMissileExecution implements Execution {
) {}
init(mg: Game, ticks: number): void {
this.pathFinder = PathFinder.Mini(mg, 2000, 10);
this.pathFinder = new AirPathFinder(mg, new PseudoRandom(mg.ticks()));
this.mg = mg;
}
@@ -58,29 +57,19 @@ export class SAMMissileExecution implements Execution {
const result = this.pathFinder.nextTile(
this.SAMMissile.tile(),
this.target.tile(),
3,
);
switch (result.type) {
case PathFindResultType.Completed:
this.mg.displayMessage(
`Missile intercepted ${this.target.type()}`,
MessageType.SUCCESS,
this._owner.id(),
);
this.active = false;
this.target.delete();
this.SAMMissile.delete(false);
return;
case PathFindResultType.NextTile:
this.SAMMissile.move(result.tile);
break;
case PathFindResultType.Pending:
return;
case PathFindResultType.PathNotFound:
consolex.log(`Missile ${this.SAMMissile} could not find target`);
this.active = false;
this.SAMMissile.delete(false);
return;
if (result === true) {
this.mg.displayMessage(
`Missile intercepted ${this.target.type()}`,
MessageType.SUCCESS,
this._owner.id(),
);
this.active = false;
this.target.delete();
this.SAMMissile.delete(false);
return;
} else {
this.SAMMissile.move(result);
}
}
}
+38 -1
View File
@@ -1,9 +1,46 @@
import { consolex } from "../Consolex";
import { Game } from "../game/Game";
import { TileRef } from "../game/GameMap";
import { GameMap, TileRef } from "../game/GameMap";
import { PseudoRandom } from "../PseudoRandom";
import { AStar, PathFindResultType, TileResult } from "./AStar";
import { MiniAStar } from "./MiniAStar";
export class AirPathFinder {
constructor(
private mg: GameMap,
private random: PseudoRandom,
) {}
nextTile(tile: TileRef, dst: TileRef): TileRef | true {
const x = this.mg.x(tile);
const y = this.mg.y(tile);
const dstX = this.mg.x(dst);
const dstY = this.mg.y(dst);
if (x === dstX && y === dstY) {
return true;
}
// Calculate next position
let nextX = x;
let nextY = y;
const ratio = Math.floor(1 + Math.abs(dstY - y) / (Math.abs(dstX - x) + 1));
if (this.random.chance(ratio) && x != dstX) {
if (x < dstX) nextX++;
else if (x > dstX) nextX--;
} else {
if (y < dstY) nextY++;
else if (y > dstY) nextY--;
}
if (nextX == x && nextY == y) {
return true;
}
return this.mg.ref(nextX, nextY);
}
}
export class PathFinder {
private curr: TileRef = null;
private dst: TileRef = null;
+1 -1
View File
@@ -356,7 +356,7 @@ export class GameServer {
client.ws.close(1000, "game has ended");
}
});
if (!this._hasPrestarted || !this._hasStarted) {
if (!this._hasPrestarted && !this._hasStarted) {
this.log.info(`game not started, not archiving game`);
return;
}