mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-06-21 11:30:43 +00:00
106 lines
3.6 KiB
TypeScript
106 lines
3.6 KiB
TypeScript
import { Game } from "../game/Game";
|
|
import { GameMap, TileRef } from "../game/GameMap";
|
|
import { TrainStation } from "../game/TrainStation";
|
|
import { AStarRail } from "./algorithms/AStar.Rail";
|
|
import { AStarWater } from "./algorithms/AStar.Water";
|
|
import { AirPathFinder } from "./PathFinder.Air";
|
|
import {
|
|
ParabolaOptions,
|
|
ParabolaUniversalPathFinder,
|
|
} from "./PathFinder.Parabola";
|
|
import { StationPathFinder } from "./PathFinder.Station";
|
|
import { PathFinderBuilder } from "./PathFinderBuilder";
|
|
import { StepperConfig } from "./PathFinderStepper";
|
|
import { ComponentCheckTransformer } from "./transformers/ComponentCheckTransformer";
|
|
import { MiniMapTransformer } from "./transformers/MiniMapTransformer";
|
|
import { ShoreCoercingTransformer } from "./transformers/ShoreCoercingTransformer";
|
|
import { SmoothingWaterTransformer } from "./transformers/SmoothingWaterTransformer";
|
|
import { PathStatus, SteppingPathFinder } from "./types";
|
|
|
|
/**
|
|
* Pathfinders that work with GameMap - usable in both simulation and UI layers
|
|
*/
|
|
export class UniversalPathFinding {
|
|
static Parabola(
|
|
gameMap: GameMap,
|
|
options?: ParabolaOptions,
|
|
): ParabolaUniversalPathFinder {
|
|
return new ParabolaUniversalPathFinder(gameMap, options);
|
|
}
|
|
}
|
|
|
|
/**
|
|
* Pathfinders that require Game - simulation layer only
|
|
*/
|
|
export class PathFinding {
|
|
static Water(game: Game): SteppingPathFinder<TileRef> {
|
|
const pf = game.miniWaterHPA();
|
|
const graph = game.miniWaterGraph();
|
|
|
|
if (!pf || !graph || graph.nodeCount < 100) {
|
|
return PathFinding.WaterSimple(game);
|
|
}
|
|
|
|
const miniMap = game.miniMap();
|
|
const componentCheckFn = (t: TileRef) => graph.getComponentId(t);
|
|
|
|
return PathFinderBuilder.create(pf)
|
|
.wrap((pf) => new ComponentCheckTransformer(pf, componentCheckFn))
|
|
.wrap((pf) => new SmoothingWaterTransformer(pf, miniMap))
|
|
.wrap((pf) => new ShoreCoercingTransformer(pf, miniMap))
|
|
.wrap((pf) => new MiniMapTransformer(pf, game.map(), miniMap))
|
|
.buildWithStepper(tileStepperConfig(game));
|
|
}
|
|
|
|
static WaterSimple(game: Game): SteppingPathFinder<TileRef> {
|
|
const miniMap = game.miniMap();
|
|
const pf = new AStarWater(miniMap);
|
|
|
|
return PathFinderBuilder.create(pf)
|
|
.wrap((pf) => new SmoothingWaterTransformer(pf, miniMap))
|
|
.wrap((pf) => new ShoreCoercingTransformer(pf, miniMap))
|
|
.wrap((pf) => new MiniMapTransformer(pf, game.map(), miniMap))
|
|
.buildWithStepper(tileStepperConfig(game));
|
|
}
|
|
|
|
static Rail(game: Game): SteppingPathFinder<TileRef> {
|
|
const miniMap = game.miniMap();
|
|
const pf = new AStarRail(miniMap);
|
|
|
|
return PathFinderBuilder.create(pf)
|
|
.wrap((pf) => new MiniMapTransformer(pf, game.map(), miniMap))
|
|
.buildWithStepper(tileStepperConfig(game));
|
|
}
|
|
|
|
static Stations(game: Game): SteppingPathFinder<TrainStation> {
|
|
const pf = new StationPathFinder(game);
|
|
|
|
return PathFinderBuilder.create(pf).buildWithStepper({
|
|
equals: (a, b) => a.id === b.id,
|
|
distance: (a, b) => game.manhattanDist(a.tile(), b.tile()),
|
|
});
|
|
}
|
|
|
|
static Air(game: Game): SteppingPathFinder<TileRef> {
|
|
const pf = new AirPathFinder(game);
|
|
|
|
return PathFinderBuilder.create(pf).buildWithStepper({
|
|
equals: (a, b) => a === b,
|
|
});
|
|
}
|
|
}
|
|
|
|
function tileStepperConfig(game: Game): StepperConfig<TileRef> {
|
|
return {
|
|
equals: (a, b) => a === b,
|
|
distance: (a, b) => game.manhattanDist(a, b),
|
|
preCheck: (from, to) =>
|
|
typeof from !== "number" ||
|
|
typeof to !== "number" ||
|
|
!game.isValidRef(from) ||
|
|
!game.isValidRef(to)
|
|
? { status: PathStatus.NOT_FOUND }
|
|
: null,
|
|
};
|
|
}
|