mirror of
https://github.com/openfrontio/OpenFrontIO.git
synced 2026-07-01 12:22:11 +00:00
created path finding web worker
This commit is contained in:
+18
-5
@@ -131,7 +131,21 @@ export class PlayerInfo {
|
||||
) { }
|
||||
}
|
||||
|
||||
export interface Tile {
|
||||
export interface SearchNode {
|
||||
cost(): number;
|
||||
cell(): Cell
|
||||
}
|
||||
|
||||
export interface TerrainMap {
|
||||
terrain(cell: Cell): TerrainTile
|
||||
neighbors(terrainTile: TerrainTile): TerrainTile[]
|
||||
}
|
||||
|
||||
export interface TerrainTile extends SearchNode {
|
||||
terrainType(): TerrainType
|
||||
}
|
||||
|
||||
export interface Tile extends SearchNode {
|
||||
isLand(): boolean
|
||||
isShore(): boolean
|
||||
isOceanShore(): boolean
|
||||
@@ -150,8 +164,6 @@ export interface Tile {
|
||||
neighbors(): Tile[]
|
||||
neighborsWrapped(): Tile[]
|
||||
onShore(): boolean
|
||||
x(): number
|
||||
y(): number
|
||||
}
|
||||
|
||||
export interface Unit {
|
||||
@@ -279,7 +291,7 @@ export interface Game {
|
||||
displayMessage(message: string, type: MessageType, playerID: PlayerID | null): void
|
||||
units(...types: UnitType[]): Unit[]
|
||||
unitInfo(type: UnitType): UnitInfo
|
||||
searchMap(): SharedArrayBuffer
|
||||
terrainMap(): TerrainMap
|
||||
}
|
||||
|
||||
export interface MutableGame extends Game {
|
||||
@@ -325,4 +337,5 @@ export class TargetPlayerEvent implements GameEvent {
|
||||
|
||||
export class EmojiMessageEvent implements GameEvent {
|
||||
constructor(public readonly message: EmojiMessage) { }
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+10
-12
@@ -2,7 +2,7 @@ import { info } from "console";
|
||||
import { Config } from "../configuration/Config";
|
||||
import { EventBus } from "../EventBus";
|
||||
import { Cell, Execution, MutableGame, Game, MutablePlayer, PlayerEvent, PlayerID, PlayerInfo, Player, TerraNullius, Tile, TileEvent, Unit, UnitEvent as UnitEvent, PlayerType, MutableAllianceRequest, AllianceRequestReplyEvent, AllianceRequestEvent, BrokeAllianceEvent, MutableAlliance, Alliance, AllianceExpiredEvent, Nation, UnitType, UnitInfo } from "./Game";
|
||||
import { TerrainMap } from "./TerrainMapLoader";
|
||||
import { TerrainMapImpl } from "./TerrainMapLoader";
|
||||
import { PlayerImpl } from "./PlayerImpl";
|
||||
import { TerraNulliusImpl } from "./TerraNulliusImpl";
|
||||
import { TileImpl } from "./TileImpl";
|
||||
@@ -12,7 +12,7 @@ import { ClientID } from "../Schemas";
|
||||
import { DisplayMessageEvent, MessageType } from "../../client/graphics/layers/EventsDisplay";
|
||||
import { UnitImpl } from "./UnitImpl";
|
||||
|
||||
export function createGame(terrainMap: TerrainMap, eventBus: EventBus, config: Config): Game {
|
||||
export function createGame(terrainMap: TerrainMapImpl, eventBus: EventBus, config: Config): Game {
|
||||
return new GameImpl(terrainMap, eventBus, config)
|
||||
}
|
||||
|
||||
@@ -34,26 +34,24 @@ export class GameImpl implements MutableGame {
|
||||
private _height: number
|
||||
private _numLandTiles: number
|
||||
_terraNullius: TerraNulliusImpl
|
||||
private _searchMap: SharedArrayBuffer
|
||||
|
||||
allianceRequests: AllianceRequestImpl[] = []
|
||||
alliances_: AllianceImpl[] = []
|
||||
|
||||
constructor(terrainMap: TerrainMap, public eventBus: EventBus, private _config: Config) {
|
||||
constructor(private _terrainMap: TerrainMapImpl, public eventBus: EventBus, private _config: Config) {
|
||||
this._terraNullius = new TerraNulliusImpl(this)
|
||||
this._width = terrainMap.width();
|
||||
this._height = terrainMap.height();
|
||||
this._numLandTiles = terrainMap.numLandTiles
|
||||
this._searchMap = terrainMap.searchBuffer
|
||||
this._width = _terrainMap.width();
|
||||
this._height = _terrainMap.height();
|
||||
this._numLandTiles = _terrainMap.numLandTiles
|
||||
this.map = new Array(this._width);
|
||||
for (let x = 0; x < this._width; x++) {
|
||||
this.map[x] = new Array(this._height);
|
||||
for (let y = 0; y < this._height; y++) {
|
||||
let cell = new Cell(x, y);
|
||||
this.map[x][y] = new TileImpl(this, this._terraNullius, cell, terrainMap.terrain(cell));
|
||||
this.map[x][y] = new TileImpl(this, this._terraNullius, cell, _terrainMap.terrain(cell));
|
||||
}
|
||||
}
|
||||
this.nations_ = terrainMap.nationMap.nations
|
||||
this.nations_ = _terrainMap.nationMap.nations
|
||||
.map(n => new Nation(
|
||||
n.name,
|
||||
new Cell(n.coordinates[0], n.coordinates[1]),
|
||||
@@ -396,8 +394,8 @@ export class GameImpl implements MutableGame {
|
||||
this.eventBus.emit(new AllianceExpiredEvent(alliance.requestor(), alliance.recipient()))
|
||||
}
|
||||
|
||||
public searchMap(): SharedArrayBuffer {
|
||||
return this._searchMap
|
||||
public terrainMap(): TerrainMapImpl {
|
||||
return this._terrainMap
|
||||
}
|
||||
|
||||
displayMessage(message: string, type: MessageType, playerID: PlayerID | null): void {
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { Cell, GameMap, TerrainType } from './Game';
|
||||
import { Cell, GameMap, SearchNode, TerrainMap, TerrainTile, TerrainType } from './Game';
|
||||
import europeBin from "!!binary-loader!../../../resources/maps/Europe.bin";
|
||||
import europeInfo from "../../../resources/maps/Europe.json"
|
||||
|
||||
@@ -13,7 +13,7 @@ const maps = new Map()
|
||||
.set(GameMap.Europe, { bin: europeBin, info: europeInfo })
|
||||
.set(GameMap.Mena, { bin: menaBin, info: menaInfo });
|
||||
|
||||
const loadedMaps = new Map<GameMap, TerrainMap>()
|
||||
const loadedMaps = new Map<GameMap, TerrainMapImpl>()
|
||||
|
||||
export interface NationMap {
|
||||
name: string;
|
||||
@@ -29,15 +29,57 @@ export interface Nation {
|
||||
}
|
||||
|
||||
|
||||
export class TerrainMap {
|
||||
export class TerrainTileImpl implements TerrainTile {
|
||||
public shoreline: boolean = false
|
||||
public magnitude: number = 0
|
||||
public ocean = false
|
||||
public land = false
|
||||
private _neighbors: TerrainTile[] | null = null
|
||||
|
||||
constructor(public type: TerrainType, private _cell: Cell) { }
|
||||
|
||||
terrainType(): TerrainType {
|
||||
return this.type
|
||||
}
|
||||
|
||||
cost(): number {
|
||||
return this.magnitude < 10 ? 2 : 1
|
||||
}
|
||||
|
||||
cell(): Cell {
|
||||
return this._cell
|
||||
}
|
||||
|
||||
initNeighbors(map: TerrainMapImpl): TerrainTile[] {
|
||||
if (this._neighbors === null) {
|
||||
const positions = [
|
||||
{ x: this._cell.x - 1, y: this._cell.y }, // Left
|
||||
{ x: this._cell.x + 1, y: this._cell.y }, // Right
|
||||
{ x: this._cell.x, y: this._cell.y - 1 }, // Up
|
||||
{ x: this._cell.x, y: this._cell.y + 1 } // Down
|
||||
];
|
||||
|
||||
this._neighbors = positions
|
||||
.filter(pos => pos.x >= 0 && pos.x < map.width() &&
|
||||
pos.y >= 0 && pos.y < map.height())
|
||||
.map(pos => map.terrain(new Cell(pos.x, pos.y)));
|
||||
}
|
||||
return this._neighbors;
|
||||
}
|
||||
}
|
||||
|
||||
export class TerrainMapImpl implements TerrainMap {
|
||||
constructor(
|
||||
public readonly tiles: Terrain[][],
|
||||
public readonly tiles: TerrainTileImpl[][],
|
||||
public readonly numLandTiles: number,
|
||||
public readonly nationMap: NationMap,
|
||||
public searchBuffer: SharedArrayBuffer
|
||||
) { }
|
||||
|
||||
terrain(cell: Cell): Terrain {
|
||||
neighbors(terrainTile: TerrainTile): TerrainTile[] {
|
||||
return (terrainTile as TerrainTileImpl).initNeighbors(this);
|
||||
}
|
||||
|
||||
terrain(cell: Cell): TerrainTileImpl {
|
||||
return this.tiles[cell.x][cell.y]
|
||||
}
|
||||
|
||||
@@ -50,15 +92,7 @@ export class TerrainMap {
|
||||
}
|
||||
}
|
||||
|
||||
export class Terrain {
|
||||
public shoreline: boolean = false
|
||||
public magnitude: number = 0
|
||||
public ocean = false
|
||||
public land = false
|
||||
constructor(public type: TerrainType) { }
|
||||
}
|
||||
|
||||
export async function loadTerrainMap(map: GameMap): Promise<TerrainMap> {
|
||||
export async function loadTerrainMap(map: GameMap): Promise<TerrainMapImpl> {
|
||||
if (loadedMaps.has(map)) {
|
||||
return loadedMaps.get(map)
|
||||
}
|
||||
@@ -83,7 +117,7 @@ export async function loadTerrainMap(map: GameMap): Promise<TerrainMap> {
|
||||
throw new Error(`Invalid data: buffer size ${fileData.length} incorrect for ${width}x${height} terrain plus 4 bytes for dimensions.`);
|
||||
}
|
||||
|
||||
const terrain: Terrain[][] = Array(width).fill(null).map(() => Array(height).fill(null));
|
||||
const terrain: TerrainTileImpl[][] = Array(width).fill(null).map(() => Array(height).fill(null));
|
||||
let numLand = 0
|
||||
|
||||
// Start from the 5th byte (index 4) when processing terrain data
|
||||
@@ -115,19 +149,19 @@ export async function loadTerrainMap(map: GameMap): Promise<TerrainMap> {
|
||||
}
|
||||
}
|
||||
|
||||
terrain[x][y] = new Terrain(type);
|
||||
terrain[x][y] = new TerrainTileImpl(type, new Cell(x, y));
|
||||
terrain[x][y].shoreline = shoreline;
|
||||
terrain[x][y].magnitude = magnitude;
|
||||
terrain[x][y].ocean = ocean
|
||||
terrain[x][y].land = land
|
||||
}
|
||||
}
|
||||
const encoder = new TextEncoder();
|
||||
const encoded = encoder.encode(fileData);
|
||||
const buffer = new SharedArrayBuffer(encoded.length);
|
||||
const view = new Uint8Array(buffer);
|
||||
view.set(encoded)
|
||||
const m = new TerrainMap(terrain, numLand, mapData.info, buffer);
|
||||
// const encoder = new TextEncoder();
|
||||
// const encoded = encoder.encode(fileData);
|
||||
// const buffer = new SharedArrayBuffer(encoded.length);
|
||||
// const view = new Uint8Array(buffer);
|
||||
// view.set(encoded)
|
||||
const m = new TerrainMapImpl(terrain, numLand, mapData.info);
|
||||
loadedMaps.set(map, m)
|
||||
return m
|
||||
}
|
||||
|
||||
@@ -1,4 +1,4 @@
|
||||
import { TerrainMap } from "./TerrainMapLoader";
|
||||
import { TerrainMapImpl } from "./TerrainMapLoader";
|
||||
export enum SearchMapTileType {
|
||||
Land,
|
||||
Shore,
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
import { Tile, Cell, TerrainType, Player, TerraNullius, MutablePlayer } from "./Game";
|
||||
import { Terrain } from "./TerrainMapLoader";
|
||||
import { Tile, Cell, TerrainType, Player, TerraNullius, MutablePlayer, SearchNode, TerrainTile } from "./Game";
|
||||
import { TerrainTileImpl } from "./TerrainMapLoader";
|
||||
import { GameImpl } from "./GameImpl";
|
||||
import { PlayerImpl } from "./PlayerImpl";
|
||||
import { TerraNulliusImpl } from "./TerraNulliusImpl";
|
||||
@@ -14,7 +14,7 @@ export class TileImpl implements Tile {
|
||||
private readonly gs: GameImpl,
|
||||
public _owner: PlayerImpl | TerraNulliusImpl,
|
||||
private readonly _cell: Cell,
|
||||
private readonly _terrain: Terrain
|
||||
private readonly _terrain: TerrainTileImpl
|
||||
) { }
|
||||
|
||||
neighborsWrapped(): Tile[] {
|
||||
@@ -108,4 +108,8 @@ export class TileImpl implements Tile {
|
||||
}
|
||||
return this._neighbors;
|
||||
}
|
||||
|
||||
cost(): number {
|
||||
return this.magnitude() < 10 ? 2 : 1
|
||||
};
|
||||
}
|
||||
|
||||
Reference in New Issue
Block a user