export interface Point { x: number; y: number; z?: number; } export type Point3D = Required; export type DistanceMetric = 'euclidean' | 'manhattan' | 'chebyshev'; export type DiagonalCost = 'uniform' | 'alternating' | number; export interface TerrainCostMap { /** * Returns the movement cost multiplier for a given tile. * @returns 1 = normal terrain, 2 = difficult terrain, Infinity = impassable */ getTileCost(point: Point): number; } export interface PathfindingOptions { /** Maximum number of iterations to prevent infinite loops. Default: 10000 */ maxIterations?: number; /** * Diagonal movement cost. * - 'uniform': cost 1 (default, Chebyshev) * - 'alternating': D&D 5e "5-10-5" rule (cost 1.5 average) * - number: custom cost for diagonal moves */ diagonalCost?: DiagonalCost; /** * Custom movement cost function. Overrides diagonalCost if provided. * @param from Starting point * @param to Destination point * @returns Movement cost (typically 1 for normal, higher for difficult) */ movementCostFn?: (from: Point, to: Point) => number; /** * Terrain cost map for variable terrain costs (difficult terrain, water, etc.) */ terrainCosts?: TerrainCostMap; /** * Optional grid boundaries for validation. */ bounds?: { min: Point; max: Point; }; } export declare class SpatialEngine { private circleCache; private readonly MAX_CACHED_RADIUS; /** * Validates that a point has finite numeric coordinates and is within optional bounds. * @throws Error if coordinates are not finite numbers or out of bounds */ private validatePoint; /** * Calculates distance between two points using the specified metric. * Automatically handles 2D and 3D points. * * @param p1 First point * @param p2 Second point * @param metric Distance metric to use (default: 'euclidean') * @returns Distance between points * * @example * ```typescript * const engine = new SpatialEngine(); * // 2D * engine.getDistance({x: 0, y: 0}, {x: 3, y: 4}); // 5 * // 3D * engine.getDistance({x: 0, y: 0, z: 0}, {x: 3, y: 4, z: 12}); // 13 * ``` */ getDistance(p1: Point, p2: Point, metric?: DistanceMetric): number; /** * Returns all tiles within a given radius of a center point. * Uses Euclidean distance for circular shape. * Automatically caches results for radii <= 10 for performance. * * @param center Center point of the circle * @param radius Radius in grid units (must be non-negative) * @param useCache Whether to use caching (default: true) * @returns Array of points within the radius * * @example * ```typescript * const engine = new SpatialEngine(); * // Get tiles in a 5-unit radius (cached) * const tiles = engine.getCircleTiles({x: 10, y: 10}, 5); * // Large radius without caching * const largeTiles = engine.getCircleTiles({x: 0, y: 0}, 50, false); * ``` */ getCircleTiles(center: Point, radius: number, useCache?: boolean): Point[]; /** * Internal method to compute circle tiles without caching. * @private */ private computeCircleTiles; /** * Returns tiles within a cone defined by origin, direction, length, and angle. * * @param origin Origin point of the cone (typically the caster's position) * @param direction Direction vector (NOT a target point). For example, {x: 1, y: 0} points East. * @param length Maximum distance from origin in grid units * @param angleDegrees Total angle of the cone in degrees (e.g., 90 for a quarter-circle) * @returns Array of points within the cone * * @example * ```typescript * const engine = new SpatialEngine(); * // 90-degree cone facing East, 10 units long * const tiles = engine.getConeTiles( * {x: 0, y: 0}, // origin * {x: 1, y: 0}, // direction vector (East) * 10, // length * 90 // angle in degrees * ); * ``` */ getConeTiles(origin: Point, direction: Point, length: number, angleDegrees: number): Point[]; /** * Helper to check if a point is within a cone. * @private */ private isInCone; /** * Returns tiles along a line from start to end using Bresenham's algorithm. * * @param start Start point of the line * @param end End point of the line * @returns Array of points along the line (including endpoints) */ getLineTiles(start: Point, end: Point): Point[]; /** * Finds the shortest path between start and end using A* algorithm with binary heap optimization. * Supports custom movement costs including diagonal costs and terrain modifiers. * * @param start Starting point * @param end Target point * @param obstacles Set of blocked tiles in "x,y" or "x,y,z" format * @param options Optional configuration * @returns Array of points representing the path, or null if no path exists * * @example * ```typescript * const engine = new SpatialEngine(); * const obstacles = new Set(['5,5', '5,6', '5,7']); // Wall * * // Basic pathfinding * const path1 = engine.findPath({x: 0, y: 0}, {x: 10, y: 0}, obstacles); * * // With D&D 5e diagonal costs * const path2 = engine.findPath({x: 0, y: 0}, {x: 10, y: 10}, obstacles, { * diagonalCost: 'alternating' // 5-10-5 rule * }); * * // With terrain costs * const terrainMap = { getTileCost: (p) => p.y > 5 ? 2 : 1 }; // Difficult terrain above y=5 * const path3 = engine.findPath({x: 0, y: 0}, {x: 10, y: 10}, obstacles, { * terrainCosts: terrainMap * }); * ``` */ findPath(start: Point, end: Point, obstacles: Set, options?: PathfindingOptions): Point[] | null; /** * Creates a cost function based on pathfinding options. * @private */ private createCostFunction; /** * Gets neighboring tiles (8 for 2D, 26 for 3D). * @private */ private getNeighbors; /** * Smooths a path by removing unnecessary waypoints using line-of-sight checks. * Uses the "string pulling" algorithm. * * @param path Original path from pathfinding * @param obstacles Obstacle set used for LOS checks * @returns Smoothed path with fewer waypoints * * @example * ```typescript * const obstacles = new Set(['5,5']); * const path = engine.findPath({x: 0, y: 0}, {x: 10, y: 10}, obstacles); * const smoothed = engine.smoothPath(path!, obstacles); * // smoothed.length <= path.length * ``` */ smoothPath(path: Point[], obstacles: Set): Point[]; /** * Computes field of view (all visible tiles) from an origin using shadowcasting. * This is much more efficient than calling hasLineOfSight multiple times. * * @param origin Viewer position * @param range Maximum vision range * @param obstacles Set of opaque tiles * @returns Set of visible tile keys in "x,y" format * * @example * ```typescript * const obstacles = new Set(['5,5', '6,5']); * const fov = engine.getFieldOfView({x: 0, y: 0}, 10, obstacles); * console.log(fov.has('3,3')); // true - visible * console.log(fov.has('7,5')); // false - blocked by wall * ``` */ getFieldOfView(origin: Point, range: number, obstacles: Set): Set; /** * Recursive shadowcasting for one octant. * Based on the algorithm by Björn Bergström. * @private */ private castLight; /** * Transforms coordinates based on octant for shadowcasting. * @private */ private transformOctant; /** * Checks if there is a clear line of sight between start and end points. * Uses Bresenham's line algorithm to check for obstacles on the path. * The start and end points themselves are not checked (you can see *to* an obstacle). * * @param start The starting point (viewer position) * @param end The ending point (target position) * @param obstacles Set of blocked tiles in "x,y" format * @returns true if the path is clear, false if blocked */ hasLineOfSight(start: Point, end: Point, obstacles: Set): boolean; /** * Bresenham's line algorithm implementation. * Returns all points on the line from start to end (inclusive). * * @private * @param start Start point * @param end End point * @returns Array of points on the line */ private bresenhamLine; /** * Reconstructs the path from A* cameFrom map. * * @private * @param cameFrom Map of point keys to their predecessors * @param current The goal point * @returns Array of points from start to goal */ private reconstructPath; /** * Converts a point to a string key. * @private */ private pointToKey; /** * Checks if two points are equal. * @private */ private pointsEqual; } //# sourceMappingURL=engine.d.ts.map