beardos-toolbox 0.1.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/LICENSE +21 -0
- package/README.md +2 -0
- package/dist/index.cjs +556 -0
- package/dist/index.cjs.map +7 -0
- package/dist/index.d.ts +105 -0
- package/dist/index.mjs +490 -0
- package/dist/index.mjs.map +7 -0
- package/dist/jsonl.d.ts +8 -0
- package/dist/misc-js-funcs.d.ts +24 -0
- package/dist/s3.d.ts +15 -0
- package/dist/tile-map.d.ts +475 -0
- package/dist/timestamp-gate.d.ts +46 -0
- package/package.json +43 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../s3.ts", "../jsonl.ts", "../misc-js-funcs.ts", "../tile-map.ts", "../index.ts"],
|
|
4
|
+
"sourcesContent": ["/* eslint-disable no-console */\r\nimport { S3Client, PutObjectCommand, GetObjectCommand, ListObjectsV2Command, ListObjectsV2CommandInput, DeleteObjectCommand } from \"@aws-sdk/client-s3\";\r\nlet client: S3Client;\r\n\r\nexport interface IS3Config {\r\n region: string;\r\n bucket: string;\r\n accessKeyId: string;\r\n secretAccessKey: string;\r\n}\r\n\r\nexport const getClient = ({ region, accessKeyId, secretAccessKey }: IS3Config) => {\r\n if (!client) {\r\n client = new S3Client({ region, credentials: { accessKeyId, secretAccessKey } });\r\n }\r\n\r\n return client;\r\n};\r\n\r\nexport const putObject = async(config: IS3Config, data: Buffer | string, key: string, contentType?: string) => {\r\n try {\r\n const cl = getClient(config);\r\n\r\n const params: { Bucket: string; Key: string; Body: Buffer | string; ContentType?: string } = {\r\n Bucket: config.bucket,\r\n Key: key,\r\n Body: typeof data === 'string' ? Buffer.from(data, \"utf-8\") : data\r\n };\r\n if(contentType) {\r\n params.ContentType = contentType\r\n }\r\n\r\n return await cl.send(new PutObjectCommand(params));\r\n } catch (e) {\r\n console.error('Could not upload json file', { error: e });\r\n throw e;\r\n }\r\n};\r\n\r\nexport const getObject = async(config: IS3Config, key: string) => {\r\n const params = {\r\n Bucket: config.bucket,\r\n Key: key,\r\n };\r\n\r\n try {\r\n const cl = getClient(config);\r\n\r\n return await cl.send(new GetObjectCommand(params));\r\n } catch (e) {\r\n console.error('Could not get object from s3', { error: e, params });\r\n throw e;\r\n }\r\n};\r\n\r\nexport const listObjects = async(config: IS3Config, prefix: string, Marker?: string) => {\r\n const params: ListObjectsV2CommandInput = {\r\n Bucket: config.bucket,\r\n Prefix: prefix,\r\n };\r\n if (Marker) {\r\n params.StartAfter = Marker;\r\n }\r\n try {\r\n const cl = getClient(config);\r\n\r\n const response = await cl.send(new ListObjectsV2Command(params));\r\n return { Objects: (response.Contents ?? []), Marker: response.NextContinuationToken };\r\n } catch (e) {\r\n console.error('Could not upload json file', { error: e });\r\n throw e;\r\n }\r\n};\r\n\r\nexport const deleteObject = async(config: IS3Config, Key: string) => {\r\n const params = {\r\n Bucket: config.bucket,\r\n Key,\r\n };\r\n\r\n try {\r\n const cl = getClient(config);\r\n\r\n return await cl.send(new DeleteObjectCommand(params));\r\n } catch (e) {\r\n console.error('Could not delete object from s3', { error: e, params });\r\n throw e;\r\n }\r\n};\r\n", "import { EOL } from 'os'\r\n\r\n/**\r\n * made fairly specifically for arrays when dealing with larger qunatities of data that you may need to concat later\r\n */\r\n\r\nexport default {\r\n stringify: (data: any[]): string => {\r\n return data.map((d) => JSON.stringify(d)).join(EOL);\r\n },\r\n\r\n parse: (data: string): any[] => {\r\n return data.split(EOL).map((d, i) => {\r\n try{\r\n return JSON.parse(d);\r\n } catch (e: any) {\r\n console.error('Could not parse JSONL on line: ' + i, { error: e.message, line: i });\r\n }\r\n });\r\n },\r\n}\r\n \r\n", "const sleep = (ms: number) => new Promise(resolve => setTimeout(resolve, ms));\r\n\r\nconst chunkArray = (source: Array<any>, chunkSize: number = 10) => {\r\n const chunks = source.reduce((resultArray, item, index) => { \r\n const chunkIndex = Math.floor(index/chunkSize)\r\n \r\n if(!resultArray[chunkIndex]) {\r\n resultArray[chunkIndex] = []\r\n }\r\n \r\n resultArray[chunkIndex].push(item)\r\n \r\n return resultArray\r\n }, [])\r\n return chunks\r\n}\r\n\r\nconst settledSeparator = (result: Array<PromiseSettledResult<any>>) => {\r\n const settled = result.filter((r) => r.status === 'fulfilled')\r\n const rejected = result.filter((r) => r.status === 'rejected')\r\n return { settled, rejected, total: result.length }\r\n}\r\n \r\nconst timeFormat = (ms: number) => {\r\n if (ms < 1000) return `${ms} ms`;\r\n if (ms < 60000) return `${(ms / 1000).toFixed(2)} secs`;\r\n if (ms < 3600000) return `${(ms / 60000).toFixed(2)} mins`;\r\n return `${(ms / 3600000).toFixed(2)} hrs`;\r\n}\r\n\r\nconst timeSinceString = (ms: number) => {\r\n return timeFormat(Date.now() - ms);\r\n}\r\n\r\nconst generateRandomString = (length = 8) => {\r\n return Math.random().toString(36).substring(2, 2 + length);\r\n}\r\n\r\n\r\nexport {\r\n sleep,\r\n chunkArray,\r\n settledSeparator,\r\n timeFormat,\r\n timeSinceString,\r\n generateRandomString\r\n}\r\n\r\nexport default {\r\n sleep,\r\n chunkArray,\r\n settledSeparator,\r\n timeFormat,\r\n timeSinceString,\r\n generateRandomString\r\n}\r\n", "// --- types ---\n\n/** A 2-D grid of tiles. `T` is the entity type stored per tile. */\nexport type TileMap<T = unknown> = {\n readonly width: number\n readonly height: number\n readonly size: number\n flags: Uint8Array\n entities: Map<number, T[]>\n}\n\n/**\n * A snapshot of a single tile's state.\n * `index` is the flat array position (`y * width + x`).\n */\nexport type TileInfo<T> = {\n readonly index: number\n readonly x: number\n readonly y: number\n flags: number\n entities: T[]\n}\n\n/** Shape used when collecting tiles or entities within a radius. */\nexport type RangeShape = 'square' | 'circle'\n\n/** Return `true` to pass, `false` to fail. Used by `validateTile` and `validateRange`. */\nexport type TileValidator<T> = (tile: TileInfo<T>) => boolean\n\n/**\n * Predefined single-bit flag constants.\n * Combine multiple flags with the bitwise OR operator:\n * ```ts\n * setFlag(map, x, y, TileFlags.BLOCKED | TileFlags.HAZARD)\n * ```\n * You can define additional custom flags as any unused power-of-two number\n * up to `0b10000000` (Uint8 supports 8 independent bits total).\n */\nexport const TileFlags = {\n NONE: 0b00000000,\n BLOCKED: 0b00000001,\n OCCUPIED: 0b00000010,\n VISIBLE: 0b00000100,\n EXPLORED: 0b00001000,\n WATER: 0b00010000,\n HAZARD: 0b00100000,\n} as const\n\n// --- internal helpers ---\n\nconst _idx = (width: number, x: number, y: number): number => y * width + x\n\nconst _inBounds = (width: number, height: number, x: number, y: number): boolean =>\n x >= 0 && x < width && y >= 0 && y < height\n\n// Packed dx/dy pairs for cardinal then diagonal neighbours\nconst _CARDINAL = new Int8Array([-1, 0, 1, 0, 0, -1, 0, 1])\nconst _ALL_ADJ = new Int8Array([-1, 0, 1, 0, 0, -1, 0, 1, -1, -1, -1, 1, 1, -1, 1, 1])\n\n// --- creation ---\n\n/**\n * Create a new tile map of the given dimensions.\n * All flags start at 0 and no entities are placed.\n * @param width Number of columns.\n * @param height Number of rows.\n * @returns A fresh `TileMap<T>`.\n * @example\n * type Unit = { id: string }\n * const map = createTileMap<Unit>(64, 64)\n */\nexport const createTileMap = <T>(width: number, height: number): TileMap<T> => ({\n width,\n height,\n size: width * height,\n flags: new Uint8Array(width * height),\n entities: new Map(),\n})\n\n// --- tile access ---\n\n/**\n * Convert grid coordinates to a flat array index.\n * Returns `-1` when the coordinates are out of bounds.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getTileIndex = (map: TileMap<unknown>, x: number, y: number): number =>\n _inBounds(map.width, map.height, x, y) ? _idx(map.width, x, y) : -1\n\n/**\n * Return a `TileInfo` snapshot for the tile at `(x, y)`.\n * Returns `null` when the coordinates are out of bounds.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getTileInfo = <T>(map: TileMap<T>, x: number, y: number): TileInfo<T> | null => {\n if (!_inBounds(map.width, map.height, x, y)) return null\n const index = _idx(map.width, x, y)\n return {\n index,\n x,\n y,\n flags: map.flags[index],\n entities: map.entities.get(index) ?? [],\n }\n}\n\n/**\n * Convert a flat array index back to `{ x, y }` grid coordinates.\n * @param map The tile map (used for its `width`).\n * @param index Flat tile index.\n */\nexport const indexToCoords = (map: TileMap<unknown>, index: number): { x: number; y: number } => ({\n x: index % map.width,\n y: (index / map.width) | 0,\n})\n\n// --- flag operations (bitwise, Uint8 supports 8 independent flags) ---\n\n/**\n * Set one or more flags on a tile using bitwise OR.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) from `TileFlags` or a custom power-of-two constant.\n * @example\n * setFlag(map, 3, 5, TileFlags.BLOCKED)\n */\nexport const setFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] |= flag\n}\n\n/**\n * Clear one or more flags on a tile using bitwise AND NOT.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to clear.\n */\nexport const clearFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] &= ~flag\n}\n\n/**\n * Toggle one or more flags on a tile using bitwise XOR.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to toggle.\n */\nexport const toggleFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.flags[_idx(map.width, x, y)] ^= flag\n}\n\n/**\n * Return `true` if **all** supplied flag bits are set on the tile.\n * Returns `false` for out-of-bounds coordinates.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param flag Flag bit(s) to test.\n * @example\n * if (hasFlag(map, x, y, TileFlags.BLOCKED)) { ... }\n */\nexport const hasFlag = (map: TileMap<unknown>, x: number, y: number, flag: number): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n return (map.flags[_idx(map.width, x, y)] & flag) !== 0\n}\n\n// --- entity operations ---\n\n/**\n * Add an entity to the tile at `(x, y)`.\n * Returns `false` when the coordinates are out of bounds (entity is not added).\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param entity The entity to place on the tile.\n */\nexport const addEntity = <T>(map: TileMap<T>, x: number, y: number, entity: T): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n const index = _idx(map.width, x, y)\n const bucket = map.entities.get(index)\n if (bucket) bucket.push(entity)\n else map.entities.set(index, [entity])\n return true\n}\n\n/**\n * Remove the **first** entity on the tile at `(x, y)` for which `predicate` returns `true`.\n * Returns `false` when out of bounds or no matching entity is found.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param predicate Selector \u2014 return `true` for the entity to remove.\n * @example\n * removeEntity(map, x, y, e => e.id === 'hero')\n */\nexport const removeEntity = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n predicate: (e: T) => boolean\n): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n const index = _idx(map.width, x, y)\n const bucket = map.entities.get(index)\n if (!bucket) return false\n for (let i = 0; i < bucket.length; i++) {\n if (predicate(bucket[i])) {\n bucket.splice(i, 1)\n if (bucket.length === 0) map.entities.delete(index)\n return true\n }\n }\n return false\n}\n\n/**\n * Atomically move the **first** matching entity from one tile to another.\n * Returns `false` when either coordinate is out of bounds or no matching entity is found.\n * @param map The tile map.\n * @param fromX Source column.\n * @param fromY Source row.\n * @param toX Destination column.\n * @param toY Destination row.\n * @param predicate Selector \u2014 return `true` for the entity to move.\n * @example\n * moveEntity(map, 2, 3, 2, 4, e => e.id === 'hero')\n */\nexport const moveEntity = <T>(\n map: TileMap<T>,\n fromX: number,\n fromY: number,\n toX: number,\n toY: number,\n predicate: (e: T) => boolean\n): boolean => {\n const { width, height } = map\n if (!_inBounds(width, height, fromX, fromY) || !_inBounds(width, height, toX, toY)) return false\n const srcIndex = _idx(width, fromX, fromY)\n const src = map.entities.get(srcIndex)\n if (!src) return false\n for (let i = 0; i < src.length; i++) {\n if (predicate(src[i])) {\n const entity = src[i]\n src.splice(i, 1)\n if (src.length === 0) map.entities.delete(srcIndex)\n const dstIndex = _idx(width, toX, toY)\n const dst = map.entities.get(dstIndex)\n if (dst) dst.push(entity)\n else map.entities.set(dstIndex, [entity])\n return true\n }\n }\n return false\n}\n\n/**\n * Return all entities on the tile at `(x, y)`.\n * Returns an empty array for out-of-bounds coordinates or tiles with no entities.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const getEntitiesAt = <T>(map: TileMap<T>, x: number, y: number): T[] => {\n if (!_inBounds(map.width, map.height, x, y)) return []\n return map.entities.get(_idx(map.width, x, y)) ?? []\n}\n\n/**\n * Remove all entities from the tile at `(x, y)`.\n * Out-of-bounds coordinates are silently ignored.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n */\nexport const clearEntitiesAt = <T>(map: TileMap<T>, x: number, y: number): void => {\n if (_inBounds(map.width, map.height, x, y)) map.entities.delete(_idx(map.width, x, y))\n}\n\n// --- adjacency ---\n\n/**\n * Return the flat indices of tiles adjacent to `(x, y)`.\n * Only in-bounds neighbours are included.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).\n */\nexport const getAdjacentIndices = (\n map: TileMap<unknown>,\n x: number,\n y: number,\n includeDiagonals = false\n): number[] => {\n const { width, height } = map\n const offsets = includeDiagonals ? _ALL_ADJ : _CARDINAL\n const result: number[] = []\n for (let i = 0; i < offsets.length; i += 2) {\n const nx = x + offsets[i]\n const ny = y + offsets[i + 1]\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) result.push(_idx(width, nx, ny))\n }\n return result\n}\n\n/**\n * Return full `TileInfo` snapshots for all tiles adjacent to `(x, y)`.\n * Only in-bounds neighbours are included.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).\n */\nexport const getAdjacentTiles = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n includeDiagonals = false\n): TileInfo<T>[] => {\n const { width, height } = map\n const offsets = includeDiagonals ? _ALL_ADJ : _CARDINAL\n const result: TileInfo<T>[] = []\n for (let i = 0; i < offsets.length; i += 2) {\n const nx = x + offsets[i]\n const ny = y + offsets[i + 1]\n if (nx >= 0 && nx < width && ny >= 0 && ny < height) {\n const index = _idx(width, nx, ny)\n result.push({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n }\n }\n return result\n}\n\n// --- range queries ---\n\n/**\n * Return the flat indices of all tiles within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * Circle shape uses integer `dx\u00B2 + dy\u00B2 \u2264 range\u00B2` \u2014 no `Math.sqrt`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile itself (default `false`).\n */\nexport const getIndicesInRange = (\n map: TileMap<unknown>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): number[] => {\n const { width, height } = map\n const r2 = range * range\n const result: number[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx >= 0 && nx < width) result.push(_idx(width, nx, ny))\n }\n }\n return result\n}\n\n/**\n * Return full `TileInfo` snapshots for all tiles within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile itself (default `false`).\n */\nexport const getTilesInRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): TileInfo<T>[] => {\n const { width, height } = map\n const r2 = range * range\n const result: TileInfo<T>[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx >= 0 && nx < width) {\n const index = _idx(width, nx, ny)\n result.push({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n }\n }\n }\n return result\n}\n\n/**\n * Collect and return every entity on every tile within `range` of `(x, y)`.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * Tiles with no entities contribute nothing to the result.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include entities on the center tile itself (default `false`).\n * @example\n * const enemies = getEntitiesInRange(map, heroX, heroY, 3, 'circle')\n */\nexport const getEntitiesInRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n shape: RangeShape = 'square',\n includeOrigin = false\n): T[] => {\n const { width, height } = map\n const r2 = range * range\n const result: T[] = []\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx < 0 || nx >= width) continue\n const bucket = map.entities.get(_idx(width, nx, ny))\n if (bucket) for (let i = 0; i < bucket.length; i++) result.push(bucket[i])\n }\n }\n return result\n}\n\n// --- validation ---\n\n/**\n * Test whether the tile at `(x, y)` is in bounds and passes an optional validator.\n * When no `validator` is provided, returns `true` for any in-bounds coordinate.\n * @param map The tile map.\n * @param x Column.\n * @param y Row.\n * @param validator Optional predicate; receives a `TileInfo` snapshot.\n * @example\n * const passable = validateTile(map, x, y, t => !(t.flags & TileFlags.BLOCKED))\n */\nexport const validateTile = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n validator?: TileValidator<T>\n): boolean => {\n if (!_inBounds(map.width, map.height, x, y)) return false\n if (!validator) return true\n const index = _idx(map.width, x, y)\n return validator({ index, x, y, flags: map.flags[index], entities: map.entities.get(index) ?? [] })\n}\n\n/**\n * Test whether **every** tile within `range` of `(x, y)` passes `validator`.\n * Short-circuits on the first failing tile. Out-of-bounds tiles are skipped entirely.\n * The origin tile is excluded unless `includeOrigin` is `true`.\n * @param map The tile map.\n * @param x Center column.\n * @param y Center row.\n * @param range Radius in tiles.\n * @param validator Predicate; receives a `TileInfo` snapshot.\n * @param shape `'square'` (default) or `'circle'`.\n * @param includeOrigin Include the center tile in validation (default `false`).\n * @example\n * const areaClear = validateRange(map, x, y, 2, t => t.entities.length === 0)\n */\nexport const validateRange = <T>(\n map: TileMap<T>,\n x: number,\n y: number,\n range: number,\n validator: TileValidator<T>,\n shape: RangeShape = 'square',\n includeOrigin = false\n): boolean => {\n const { width, height } = map\n const r2 = range * range\n for (let dy = -range; dy <= range; dy++) {\n const ny = y + dy\n if (ny < 0 || ny >= height) continue\n for (let dx = -range; dx <= range; dx++) {\n if (!includeOrigin && dx === 0 && dy === 0) continue\n if (shape === 'circle' && dx * dx + dy * dy > r2) continue\n const nx = x + dx\n if (nx < 0 || nx >= width) continue\n const index = _idx(width, nx, ny)\n if (!validator({ index, x: nx, y: ny, flags: map.flags[index], entities: map.entities.get(index) ?? [] })) return false\n }\n }\n return true\n}\n\n// --- spatial / screen-space ---\n\n/**\n * Pixel dimensions of a single tile and an optional world-space origin offset.\n * Create once and reuse; it never mutates.\n *\n * - `tileWidth` / `tileHeight`: pixels per tile (e.g. 32 for a 32\u00D732 sprite sheet).\n * - `originX` / `originY`: world-pixel offset of tile (0, 0)'s top-left corner.\n * Use this to add margins or align the grid inside a larger world.\n *\n * Non-square tiles (e.g. 64\u00D732 isometric projections) are fully supported.\n */\nexport type SpatialConfig = {\n readonly tileWidth: number\n readonly tileHeight: number\n readonly originX: number\n readonly originY: number\n}\n\n/**\n * Fractional tile-grid position for an entity at an arbitrary world coordinate.\n * `tileX` / `tileY` are the integer grid cell; `fracX` / `fracY` are 0..1 offsets\n * within that cell \u2014 useful for smooth movement interpolation and collision checks.\n */\nexport type TilePosition = {\n tileX: number\n tileY: number\n fracX: number\n fracY: number\n}\n\n/**\n * Create a `SpatialConfig`.\n * @param tileWidth Pixels per tile column.\n * @param tileHeight Pixels per tile row.\n * @param originX World-pixel X of the grid's top-left corner (default `0`).\n * @param originY World-pixel Y of the grid's top-left corner (default `0`).\n * @example\n * const spatial = createSpatialConfig(32, 32)\n * const spatial = createSpatialConfig(64, 32, 128, 64) // offset grid\n */\nexport const createSpatialConfig = (\n tileWidth: number,\n tileHeight: number,\n originX = 0,\n originY = 0\n): SpatialConfig => ({ tileWidth, tileHeight, originX, originY })\n\n/**\n * Convert world-pixel coordinates to integer tile grid coordinates.\n * Fractions are floored, so the result is always the tile the point falls inside.\n * Returns `{ x: -1, y: -1 }` when the world position is before the grid origin.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n */\nexport const worldToTile = (\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): { x: number; y: number } => ({\n x: ((wx - spatial.originX) / spatial.tileWidth) | 0,\n y: ((wy - spatial.originY) / spatial.tileHeight) | 0,\n})\n\n/**\n * Convert tile grid coordinates to the world-pixel position of the tile's **top-left corner**.\n * @param spatial World-to-grid mapping config.\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileToWorld = (\n spatial: SpatialConfig,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX,\n y: ty * spatial.tileHeight + spatial.originY,\n})\n\n/**\n * Convert tile grid coordinates to the world-pixel position of the tile's **center**.\n * Useful for placing sprites, projectile origins, or distance calculations.\n * @param spatial World-to-grid mapping config.\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileCenterWorld = (\n spatial: SpatialConfig,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX + (spatial.tileWidth >> 1),\n y: ty * spatial.tileHeight + spatial.originY + (spatial.tileHeight >> 1),\n})\n\n/**\n * Convert screen-pixel coordinates to world-pixel coordinates using the camera offset.\n * The camera position is the world-space coordinate of the screen's top-left corner.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n */\nexport const screenToWorld = (\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): { x: number; y: number } => ({\n x: sx + cameraX,\n y: sy + cameraY,\n})\n\n/**\n * Convert world-pixel coordinates to screen-pixel coordinates using the camera offset.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n */\nexport const worldToScreen = (\n cameraX: number,\n cameraY: number,\n wx: number,\n wy: number\n): { x: number; y: number } => ({\n x: wx - cameraX,\n y: wy - cameraY,\n})\n\n/**\n * Convert screen-pixel coordinates directly to tile grid coordinates,\n * accounting for both the camera offset and the grid origin.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n */\nexport const screenToTile = (\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): { x: number; y: number } => ({\n x: ((sx + cameraX - spatial.originX) / spatial.tileWidth) | 0,\n y: ((sy + cameraY - spatial.originY) / spatial.tileHeight) | 0,\n})\n\n/**\n * Convert tile grid coordinates to screen-pixel coordinates (top-left of the tile),\n * accounting for the camera offset and grid origin.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param tx Tile column.\n * @param ty Tile row.\n */\nexport const tileToScreen = (\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n tx: number,\n ty: number\n): { x: number; y: number } => ({\n x: tx * spatial.tileWidth + spatial.originX - cameraX,\n y: ty * spatial.tileHeight + spatial.originY - cameraY,\n})\n\n/**\n * Return the exact fractional tile-grid position for a world coordinate.\n * `tileX` / `tileY` are the integer grid cell the point is inside.\n * `fracX` / `fracY` are 0..1 fractions representing how far into the tile the point is \u2014\n * essential for smooth cross-tile movement, linear interpolation animations, and sub-tile collision.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n * @example\n * // Entity smoothly walking; determine which tile it's in and how far across\n * const pos = worldToTileExact(spatial, entity.x, entity.y)\n * // pos.fracX === 0.5 means entity is horizontally centred in its tile\n */\nexport const worldToTileExact = (\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): TilePosition => {\n const fx = (wx - spatial.originX) / spatial.tileWidth\n const fy = (wy - spatial.originY) / spatial.tileHeight\n const tileX = fx | 0\n const tileY = fy | 0\n return { tileX, tileY, fracX: fx - tileX, fracY: fy - tileY }\n}\n\n/**\n * Convenience: return the `TileInfo` for whatever tile a world-pixel position falls on.\n * Returns `null` when out of bounds.\n * @param map The tile map.\n * @param spatial World-to-grid mapping config.\n * @param wx World X in pixels.\n * @param wy World Y in pixels.\n * @example\n * const tile = getTileAtWorld(map, spatial, entity.x, entity.y)\n * if (tile && tile.flags & TileFlags.HAZARD) takeDamage(entity)\n */\nexport const getTileAtWorld = <T>(\n map: TileMap<T>,\n spatial: SpatialConfig,\n wx: number,\n wy: number\n): TileInfo<T> | null => {\n const tx = ((wx - spatial.originX) / spatial.tileWidth) | 0\n const ty = ((wy - spatial.originY) / spatial.tileHeight) | 0\n return getTileInfo(map, tx, ty)\n}\n\n/**\n * Convenience: return the `TileInfo` for whatever tile a screen-pixel position falls on,\n * accounting for the camera offset and grid origin.\n * Returns `null` when out of bounds.\n * @param map The tile map.\n * @param spatial World-to-grid mapping config.\n * @param cameraX Camera world X (scroll offset).\n * @param cameraY Camera world Y (scroll offset).\n * @param sx Screen X in pixels.\n * @param sy Screen Y in pixels.\n * @example\n * // Mouse click \u2192 tile lookup\n * const tile = getTileAtScreen(map, spatial, camera.x, camera.y, mouseX, mouseY)\n */\nexport const getTileAtScreen = <T>(\n map: TileMap<T>,\n spatial: SpatialConfig,\n cameraX: number,\n cameraY: number,\n sx: number,\n sy: number\n): TileInfo<T> | null => {\n const tx = ((sx + cameraX - spatial.originX) / spatial.tileWidth) | 0\n const ty = ((sy + cameraY - spatial.originY) / spatial.tileHeight) | 0\n return getTileInfo(map, tx, ty)\n}\n\n// --- default export ---\n\nexport default {\n TileFlags,\n createTileMap,\n getTileIndex,\n getTileInfo,\n indexToCoords,\n setFlag,\n clearFlag,\n toggleFlag,\n hasFlag,\n addEntity,\n removeEntity,\n moveEntity,\n getEntitiesAt,\n clearEntitiesAt,\n getAdjacentIndices,\n getAdjacentTiles,\n getIndicesInRange,\n getTilesInRange,\n getEntitiesInRange,\n validateTile,\n validateRange,\n createSpatialConfig,\n worldToTile,\n tileToWorld,\n tileCenterWorld,\n screenToWorld,\n worldToScreen,\n screenToTile,\n tileToScreen,\n worldToTileExact,\n getTileAtWorld,\n getTileAtScreen,\n}\n", "import * as s3 from './s3'\r\nexport * from './s3'\r\nimport JSONL from './jsonl'\r\nimport * as jsMisc from './misc-js-funcs'\r\nexport * from './misc-js-funcs'\r\nimport tileMap from './tile-map'\r\nexport * from './tile-map'\r\n\r\nexport {\r\n s3,\r\n JSONL,\r\n tileMap\r\n}\r\n\r\nexport default {\r\n s3,\r\n JSONL,\r\n tileMap,\r\n utils: {\r\n ...jsMisc\r\n }\r\n}\r\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/jsonl.d.ts
ADDED
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
declare const sleep: (ms: number) => Promise<unknown>;
|
|
2
|
+
declare const chunkArray: (source: Array<any>, chunkSize?: number) => any;
|
|
3
|
+
declare const settledSeparator: (result: Array<PromiseSettledResult<any>>) => {
|
|
4
|
+
settled: PromiseFulfilledResult<any>[];
|
|
5
|
+
rejected: PromiseRejectedResult[];
|
|
6
|
+
total: number;
|
|
7
|
+
};
|
|
8
|
+
declare const timeFormat: (ms: number) => string;
|
|
9
|
+
declare const timeSinceString: (ms: number) => string;
|
|
10
|
+
declare const generateRandomString: (length?: number) => string;
|
|
11
|
+
export { sleep, chunkArray, settledSeparator, timeFormat, timeSinceString, generateRandomString };
|
|
12
|
+
declare const _default: {
|
|
13
|
+
sleep: (ms: number) => Promise<unknown>;
|
|
14
|
+
chunkArray: (source: Array<any>, chunkSize?: number) => any;
|
|
15
|
+
settledSeparator: (result: Array<PromiseSettledResult<any>>) => {
|
|
16
|
+
settled: PromiseFulfilledResult<any>[];
|
|
17
|
+
rejected: PromiseRejectedResult[];
|
|
18
|
+
total: number;
|
|
19
|
+
};
|
|
20
|
+
timeFormat: (ms: number) => string;
|
|
21
|
+
timeSinceString: (ms: number) => string;
|
|
22
|
+
generateRandomString: (length?: number) => string;
|
|
23
|
+
};
|
|
24
|
+
export default _default;
|
package/dist/s3.d.ts
ADDED
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
import { S3Client } from "@aws-sdk/client-s3";
|
|
2
|
+
export interface IS3Config {
|
|
3
|
+
region: string;
|
|
4
|
+
bucket: string;
|
|
5
|
+
accessKeyId: string;
|
|
6
|
+
secretAccessKey: string;
|
|
7
|
+
}
|
|
8
|
+
export declare const getClient: ({ region, accessKeyId, secretAccessKey }: IS3Config) => S3Client;
|
|
9
|
+
export declare const putObject: (config: IS3Config, data: Buffer | string, key: string, contentType?: string) => Promise<import("@aws-sdk/client-s3").PutObjectCommandOutput>;
|
|
10
|
+
export declare const getObject: (config: IS3Config, key: string) => Promise<import("@aws-sdk/client-s3").GetObjectCommandOutput>;
|
|
11
|
+
export declare const listObjects: (config: IS3Config, prefix: string, Marker?: string) => Promise<{
|
|
12
|
+
Objects: import("@aws-sdk/client-s3")._Object[];
|
|
13
|
+
Marker: string | undefined;
|
|
14
|
+
}>;
|
|
15
|
+
export declare const deleteObject: (config: IS3Config, Key: string) => Promise<import("@aws-sdk/client-s3").DeleteObjectCommandOutput>;
|
|
@@ -0,0 +1,475 @@
|
|
|
1
|
+
/** A 2-D grid of tiles. `T` is the entity type stored per tile. */
|
|
2
|
+
export type TileMap<T = unknown> = {
|
|
3
|
+
readonly width: number;
|
|
4
|
+
readonly height: number;
|
|
5
|
+
readonly size: number;
|
|
6
|
+
flags: Uint8Array;
|
|
7
|
+
entities: Map<number, T[]>;
|
|
8
|
+
};
|
|
9
|
+
/**
|
|
10
|
+
* A snapshot of a single tile's state.
|
|
11
|
+
* `index` is the flat array position (`y * width + x`).
|
|
12
|
+
*/
|
|
13
|
+
export type TileInfo<T> = {
|
|
14
|
+
readonly index: number;
|
|
15
|
+
readonly x: number;
|
|
16
|
+
readonly y: number;
|
|
17
|
+
flags: number;
|
|
18
|
+
entities: T[];
|
|
19
|
+
};
|
|
20
|
+
/** Shape used when collecting tiles or entities within a radius. */
|
|
21
|
+
export type RangeShape = 'square' | 'circle';
|
|
22
|
+
/** Return `true` to pass, `false` to fail. Used by `validateTile` and `validateRange`. */
|
|
23
|
+
export type TileValidator<T> = (tile: TileInfo<T>) => boolean;
|
|
24
|
+
/**
|
|
25
|
+
* Predefined single-bit flag constants.
|
|
26
|
+
* Combine multiple flags with the bitwise OR operator:
|
|
27
|
+
* ```ts
|
|
28
|
+
* setFlag(map, x, y, TileFlags.BLOCKED | TileFlags.HAZARD)
|
|
29
|
+
* ```
|
|
30
|
+
* You can define additional custom flags as any unused power-of-two number
|
|
31
|
+
* up to `0b10000000` (Uint8 supports 8 independent bits total).
|
|
32
|
+
*/
|
|
33
|
+
export declare const TileFlags: {
|
|
34
|
+
readonly NONE: 0;
|
|
35
|
+
readonly BLOCKED: 1;
|
|
36
|
+
readonly OCCUPIED: 2;
|
|
37
|
+
readonly VISIBLE: 4;
|
|
38
|
+
readonly EXPLORED: 8;
|
|
39
|
+
readonly WATER: 16;
|
|
40
|
+
readonly HAZARD: 32;
|
|
41
|
+
};
|
|
42
|
+
/**
|
|
43
|
+
* Create a new tile map of the given dimensions.
|
|
44
|
+
* All flags start at 0 and no entities are placed.
|
|
45
|
+
* @param width Number of columns.
|
|
46
|
+
* @param height Number of rows.
|
|
47
|
+
* @returns A fresh `TileMap<T>`.
|
|
48
|
+
* @example
|
|
49
|
+
* type Unit = { id: string }
|
|
50
|
+
* const map = createTileMap<Unit>(64, 64)
|
|
51
|
+
*/
|
|
52
|
+
export declare const createTileMap: <T>(width: number, height: number) => TileMap<T>;
|
|
53
|
+
/**
|
|
54
|
+
* Convert grid coordinates to a flat array index.
|
|
55
|
+
* Returns `-1` when the coordinates are out of bounds.
|
|
56
|
+
* @param map The tile map.
|
|
57
|
+
* @param x Column.
|
|
58
|
+
* @param y Row.
|
|
59
|
+
*/
|
|
60
|
+
export declare const getTileIndex: (map: TileMap<unknown>, x: number, y: number) => number;
|
|
61
|
+
/**
|
|
62
|
+
* Return a `TileInfo` snapshot for the tile at `(x, y)`.
|
|
63
|
+
* Returns `null` when the coordinates are out of bounds.
|
|
64
|
+
* @param map The tile map.
|
|
65
|
+
* @param x Column.
|
|
66
|
+
* @param y Row.
|
|
67
|
+
*/
|
|
68
|
+
export declare const getTileInfo: <T>(map: TileMap<T>, x: number, y: number) => TileInfo<T> | null;
|
|
69
|
+
/**
|
|
70
|
+
* Convert a flat array index back to `{ x, y }` grid coordinates.
|
|
71
|
+
* @param map The tile map (used for its `width`).
|
|
72
|
+
* @param index Flat tile index.
|
|
73
|
+
*/
|
|
74
|
+
export declare const indexToCoords: (map: TileMap<unknown>, index: number) => {
|
|
75
|
+
x: number;
|
|
76
|
+
y: number;
|
|
77
|
+
};
|
|
78
|
+
/**
|
|
79
|
+
* Set one or more flags on a tile using bitwise OR.
|
|
80
|
+
* Out-of-bounds coordinates are silently ignored.
|
|
81
|
+
* @param map The tile map.
|
|
82
|
+
* @param x Column.
|
|
83
|
+
* @param y Row.
|
|
84
|
+
* @param flag Flag bit(s) from `TileFlags` or a custom power-of-two constant.
|
|
85
|
+
* @example
|
|
86
|
+
* setFlag(map, 3, 5, TileFlags.BLOCKED)
|
|
87
|
+
*/
|
|
88
|
+
export declare const setFlag: (map: TileMap<unknown>, x: number, y: number, flag: number) => void;
|
|
89
|
+
/**
|
|
90
|
+
* Clear one or more flags on a tile using bitwise AND NOT.
|
|
91
|
+
* Out-of-bounds coordinates are silently ignored.
|
|
92
|
+
* @param map The tile map.
|
|
93
|
+
* @param x Column.
|
|
94
|
+
* @param y Row.
|
|
95
|
+
* @param flag Flag bit(s) to clear.
|
|
96
|
+
*/
|
|
97
|
+
export declare const clearFlag: (map: TileMap<unknown>, x: number, y: number, flag: number) => void;
|
|
98
|
+
/**
|
|
99
|
+
* Toggle one or more flags on a tile using bitwise XOR.
|
|
100
|
+
* Out-of-bounds coordinates are silently ignored.
|
|
101
|
+
* @param map The tile map.
|
|
102
|
+
* @param x Column.
|
|
103
|
+
* @param y Row.
|
|
104
|
+
* @param flag Flag bit(s) to toggle.
|
|
105
|
+
*/
|
|
106
|
+
export declare const toggleFlag: (map: TileMap<unknown>, x: number, y: number, flag: number) => void;
|
|
107
|
+
/**
|
|
108
|
+
* Return `true` if **all** supplied flag bits are set on the tile.
|
|
109
|
+
* Returns `false` for out-of-bounds coordinates.
|
|
110
|
+
* @param map The tile map.
|
|
111
|
+
* @param x Column.
|
|
112
|
+
* @param y Row.
|
|
113
|
+
* @param flag Flag bit(s) to test.
|
|
114
|
+
* @example
|
|
115
|
+
* if (hasFlag(map, x, y, TileFlags.BLOCKED)) { ... }
|
|
116
|
+
*/
|
|
117
|
+
export declare const hasFlag: (map: TileMap<unknown>, x: number, y: number, flag: number) => boolean;
|
|
118
|
+
/**
|
|
119
|
+
* Add an entity to the tile at `(x, y)`.
|
|
120
|
+
* Returns `false` when the coordinates are out of bounds (entity is not added).
|
|
121
|
+
* @param map The tile map.
|
|
122
|
+
* @param x Column.
|
|
123
|
+
* @param y Row.
|
|
124
|
+
* @param entity The entity to place on the tile.
|
|
125
|
+
*/
|
|
126
|
+
export declare const addEntity: <T>(map: TileMap<T>, x: number, y: number, entity: T) => boolean;
|
|
127
|
+
/**
|
|
128
|
+
* Remove the **first** entity on the tile at `(x, y)` for which `predicate` returns `true`.
|
|
129
|
+
* Returns `false` when out of bounds or no matching entity is found.
|
|
130
|
+
* @param map The tile map.
|
|
131
|
+
* @param x Column.
|
|
132
|
+
* @param y Row.
|
|
133
|
+
* @param predicate Selector — return `true` for the entity to remove.
|
|
134
|
+
* @example
|
|
135
|
+
* removeEntity(map, x, y, e => e.id === 'hero')
|
|
136
|
+
*/
|
|
137
|
+
export declare const removeEntity: <T>(map: TileMap<T>, x: number, y: number, predicate: (e: T) => boolean) => boolean;
|
|
138
|
+
/**
|
|
139
|
+
* Atomically move the **first** matching entity from one tile to another.
|
|
140
|
+
* Returns `false` when either coordinate is out of bounds or no matching entity is found.
|
|
141
|
+
* @param map The tile map.
|
|
142
|
+
* @param fromX Source column.
|
|
143
|
+
* @param fromY Source row.
|
|
144
|
+
* @param toX Destination column.
|
|
145
|
+
* @param toY Destination row.
|
|
146
|
+
* @param predicate Selector — return `true` for the entity to move.
|
|
147
|
+
* @example
|
|
148
|
+
* moveEntity(map, 2, 3, 2, 4, e => e.id === 'hero')
|
|
149
|
+
*/
|
|
150
|
+
export declare const moveEntity: <T>(map: TileMap<T>, fromX: number, fromY: number, toX: number, toY: number, predicate: (e: T) => boolean) => boolean;
|
|
151
|
+
/**
|
|
152
|
+
* Return all entities on the tile at `(x, y)`.
|
|
153
|
+
* Returns an empty array for out-of-bounds coordinates or tiles with no entities.
|
|
154
|
+
* @param map The tile map.
|
|
155
|
+
* @param x Column.
|
|
156
|
+
* @param y Row.
|
|
157
|
+
*/
|
|
158
|
+
export declare const getEntitiesAt: <T>(map: TileMap<T>, x: number, y: number) => T[];
|
|
159
|
+
/**
|
|
160
|
+
* Remove all entities from the tile at `(x, y)`.
|
|
161
|
+
* Out-of-bounds coordinates are silently ignored.
|
|
162
|
+
* @param map The tile map.
|
|
163
|
+
* @param x Column.
|
|
164
|
+
* @param y Row.
|
|
165
|
+
*/
|
|
166
|
+
export declare const clearEntitiesAt: <T>(map: TileMap<T>, x: number, y: number) => void;
|
|
167
|
+
/**
|
|
168
|
+
* Return the flat indices of tiles adjacent to `(x, y)`.
|
|
169
|
+
* Only in-bounds neighbours are included.
|
|
170
|
+
* @param map The tile map.
|
|
171
|
+
* @param x Column.
|
|
172
|
+
* @param y Row.
|
|
173
|
+
* @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).
|
|
174
|
+
*/
|
|
175
|
+
export declare const getAdjacentIndices: (map: TileMap<unknown>, x: number, y: number, includeDiagonals?: boolean) => number[];
|
|
176
|
+
/**
|
|
177
|
+
* Return full `TileInfo` snapshots for all tiles adjacent to `(x, y)`.
|
|
178
|
+
* Only in-bounds neighbours are included.
|
|
179
|
+
* @param map The tile map.
|
|
180
|
+
* @param x Column.
|
|
181
|
+
* @param y Row.
|
|
182
|
+
* @param includeDiagonals When `true`, returns up to 8 neighbours; otherwise up to 4 (cardinal only).
|
|
183
|
+
*/
|
|
184
|
+
export declare const getAdjacentTiles: <T>(map: TileMap<T>, x: number, y: number, includeDiagonals?: boolean) => TileInfo<T>[];
|
|
185
|
+
/**
|
|
186
|
+
* Return the flat indices of all tiles within `range` of `(x, y)`.
|
|
187
|
+
* The origin tile is excluded unless `includeOrigin` is `true`.
|
|
188
|
+
* Circle shape uses integer `dx² + dy² ≤ range²` — no `Math.sqrt`.
|
|
189
|
+
* @param map The tile map.
|
|
190
|
+
* @param x Center column.
|
|
191
|
+
* @param y Center row.
|
|
192
|
+
* @param range Radius in tiles.
|
|
193
|
+
* @param shape `'square'` (default) or `'circle'`.
|
|
194
|
+
* @param includeOrigin Include the center tile itself (default `false`).
|
|
195
|
+
*/
|
|
196
|
+
export declare const getIndicesInRange: (map: TileMap<unknown>, x: number, y: number, range: number, shape?: RangeShape, includeOrigin?: boolean) => number[];
|
|
197
|
+
/**
|
|
198
|
+
* Return full `TileInfo` snapshots for all tiles within `range` of `(x, y)`.
|
|
199
|
+
* The origin tile is excluded unless `includeOrigin` is `true`.
|
|
200
|
+
* @param map The tile map.
|
|
201
|
+
* @param x Center column.
|
|
202
|
+
* @param y Center row.
|
|
203
|
+
* @param range Radius in tiles.
|
|
204
|
+
* @param shape `'square'` (default) or `'circle'`.
|
|
205
|
+
* @param includeOrigin Include the center tile itself (default `false`).
|
|
206
|
+
*/
|
|
207
|
+
export declare const getTilesInRange: <T>(map: TileMap<T>, x: number, y: number, range: number, shape?: RangeShape, includeOrigin?: boolean) => TileInfo<T>[];
|
|
208
|
+
/**
|
|
209
|
+
* Collect and return every entity on every tile within `range` of `(x, y)`.
|
|
210
|
+
* The origin tile is excluded unless `includeOrigin` is `true`.
|
|
211
|
+
* Tiles with no entities contribute nothing to the result.
|
|
212
|
+
* @param map The tile map.
|
|
213
|
+
* @param x Center column.
|
|
214
|
+
* @param y Center row.
|
|
215
|
+
* @param range Radius in tiles.
|
|
216
|
+
* @param shape `'square'` (default) or `'circle'`.
|
|
217
|
+
* @param includeOrigin Include entities on the center tile itself (default `false`).
|
|
218
|
+
* @example
|
|
219
|
+
* const enemies = getEntitiesInRange(map, heroX, heroY, 3, 'circle')
|
|
220
|
+
*/
|
|
221
|
+
export declare const getEntitiesInRange: <T>(map: TileMap<T>, x: number, y: number, range: number, shape?: RangeShape, includeOrigin?: boolean) => T[];
|
|
222
|
+
/**
|
|
223
|
+
* Test whether the tile at `(x, y)` is in bounds and passes an optional validator.
|
|
224
|
+
* When no `validator` is provided, returns `true` for any in-bounds coordinate.
|
|
225
|
+
* @param map The tile map.
|
|
226
|
+
* @param x Column.
|
|
227
|
+
* @param y Row.
|
|
228
|
+
* @param validator Optional predicate; receives a `TileInfo` snapshot.
|
|
229
|
+
* @example
|
|
230
|
+
* const passable = validateTile(map, x, y, t => !(t.flags & TileFlags.BLOCKED))
|
|
231
|
+
*/
|
|
232
|
+
export declare const validateTile: <T>(map: TileMap<T>, x: number, y: number, validator?: TileValidator<T>) => boolean;
|
|
233
|
+
/**
|
|
234
|
+
* Test whether **every** tile within `range` of `(x, y)` passes `validator`.
|
|
235
|
+
* Short-circuits on the first failing tile. Out-of-bounds tiles are skipped entirely.
|
|
236
|
+
* The origin tile is excluded unless `includeOrigin` is `true`.
|
|
237
|
+
* @param map The tile map.
|
|
238
|
+
* @param x Center column.
|
|
239
|
+
* @param y Center row.
|
|
240
|
+
* @param range Radius in tiles.
|
|
241
|
+
* @param validator Predicate; receives a `TileInfo` snapshot.
|
|
242
|
+
* @param shape `'square'` (default) or `'circle'`.
|
|
243
|
+
* @param includeOrigin Include the center tile in validation (default `false`).
|
|
244
|
+
* @example
|
|
245
|
+
* const areaClear = validateRange(map, x, y, 2, t => t.entities.length === 0)
|
|
246
|
+
*/
|
|
247
|
+
export declare const validateRange: <T>(map: TileMap<T>, x: number, y: number, range: number, validator: TileValidator<T>, shape?: RangeShape, includeOrigin?: boolean) => boolean;
|
|
248
|
+
/**
|
|
249
|
+
* Pixel dimensions of a single tile and an optional world-space origin offset.
|
|
250
|
+
* Create once and reuse; it never mutates.
|
|
251
|
+
*
|
|
252
|
+
* - `tileWidth` / `tileHeight`: pixels per tile (e.g. 32 for a 32×32 sprite sheet).
|
|
253
|
+
* - `originX` / `originY`: world-pixel offset of tile (0, 0)'s top-left corner.
|
|
254
|
+
* Use this to add margins or align the grid inside a larger world.
|
|
255
|
+
*
|
|
256
|
+
* Non-square tiles (e.g. 64×32 isometric projections) are fully supported.
|
|
257
|
+
*/
|
|
258
|
+
export type SpatialConfig = {
|
|
259
|
+
readonly tileWidth: number;
|
|
260
|
+
readonly tileHeight: number;
|
|
261
|
+
readonly originX: number;
|
|
262
|
+
readonly originY: number;
|
|
263
|
+
};
|
|
264
|
+
/**
|
|
265
|
+
* Fractional tile-grid position for an entity at an arbitrary world coordinate.
|
|
266
|
+
* `tileX` / `tileY` are the integer grid cell; `fracX` / `fracY` are 0..1 offsets
|
|
267
|
+
* within that cell — useful for smooth movement interpolation and collision checks.
|
|
268
|
+
*/
|
|
269
|
+
export type TilePosition = {
|
|
270
|
+
tileX: number;
|
|
271
|
+
tileY: number;
|
|
272
|
+
fracX: number;
|
|
273
|
+
fracY: number;
|
|
274
|
+
};
|
|
275
|
+
/**
|
|
276
|
+
* Create a `SpatialConfig`.
|
|
277
|
+
* @param tileWidth Pixels per tile column.
|
|
278
|
+
* @param tileHeight Pixels per tile row.
|
|
279
|
+
* @param originX World-pixel X of the grid's top-left corner (default `0`).
|
|
280
|
+
* @param originY World-pixel Y of the grid's top-left corner (default `0`).
|
|
281
|
+
* @example
|
|
282
|
+
* const spatial = createSpatialConfig(32, 32)
|
|
283
|
+
* const spatial = createSpatialConfig(64, 32, 128, 64) // offset grid
|
|
284
|
+
*/
|
|
285
|
+
export declare const createSpatialConfig: (tileWidth: number, tileHeight: number, originX?: number, originY?: number) => SpatialConfig;
|
|
286
|
+
/**
|
|
287
|
+
* Convert world-pixel coordinates to integer tile grid coordinates.
|
|
288
|
+
* Fractions are floored, so the result is always the tile the point falls inside.
|
|
289
|
+
* Returns `{ x: -1, y: -1 }` when the world position is before the grid origin.
|
|
290
|
+
* @param spatial World-to-grid mapping config.
|
|
291
|
+
* @param wx World X in pixels.
|
|
292
|
+
* @param wy World Y in pixels.
|
|
293
|
+
*/
|
|
294
|
+
export declare const worldToTile: (spatial: SpatialConfig, wx: number, wy: number) => {
|
|
295
|
+
x: number;
|
|
296
|
+
y: number;
|
|
297
|
+
};
|
|
298
|
+
/**
|
|
299
|
+
* Convert tile grid coordinates to the world-pixel position of the tile's **top-left corner**.
|
|
300
|
+
* @param spatial World-to-grid mapping config.
|
|
301
|
+
* @param tx Tile column.
|
|
302
|
+
* @param ty Tile row.
|
|
303
|
+
*/
|
|
304
|
+
export declare const tileToWorld: (spatial: SpatialConfig, tx: number, ty: number) => {
|
|
305
|
+
x: number;
|
|
306
|
+
y: number;
|
|
307
|
+
};
|
|
308
|
+
/**
|
|
309
|
+
* Convert tile grid coordinates to the world-pixel position of the tile's **center**.
|
|
310
|
+
* Useful for placing sprites, projectile origins, or distance calculations.
|
|
311
|
+
* @param spatial World-to-grid mapping config.
|
|
312
|
+
* @param tx Tile column.
|
|
313
|
+
* @param ty Tile row.
|
|
314
|
+
*/
|
|
315
|
+
export declare const tileCenterWorld: (spatial: SpatialConfig, tx: number, ty: number) => {
|
|
316
|
+
x: number;
|
|
317
|
+
y: number;
|
|
318
|
+
};
|
|
319
|
+
/**
|
|
320
|
+
* Convert screen-pixel coordinates to world-pixel coordinates using the camera offset.
|
|
321
|
+
* The camera position is the world-space coordinate of the screen's top-left corner.
|
|
322
|
+
* @param cameraX Camera world X (scroll offset).
|
|
323
|
+
* @param cameraY Camera world Y (scroll offset).
|
|
324
|
+
* @param sx Screen X in pixels.
|
|
325
|
+
* @param sy Screen Y in pixels.
|
|
326
|
+
*/
|
|
327
|
+
export declare const screenToWorld: (cameraX: number, cameraY: number, sx: number, sy: number) => {
|
|
328
|
+
x: number;
|
|
329
|
+
y: number;
|
|
330
|
+
};
|
|
331
|
+
/**
|
|
332
|
+
* Convert world-pixel coordinates to screen-pixel coordinates using the camera offset.
|
|
333
|
+
* @param cameraX Camera world X (scroll offset).
|
|
334
|
+
* @param cameraY Camera world Y (scroll offset).
|
|
335
|
+
* @param wx World X in pixels.
|
|
336
|
+
* @param wy World Y in pixels.
|
|
337
|
+
*/
|
|
338
|
+
export declare const worldToScreen: (cameraX: number, cameraY: number, wx: number, wy: number) => {
|
|
339
|
+
x: number;
|
|
340
|
+
y: number;
|
|
341
|
+
};
|
|
342
|
+
/**
|
|
343
|
+
* Convert screen-pixel coordinates directly to tile grid coordinates,
|
|
344
|
+
* accounting for both the camera offset and the grid origin.
|
|
345
|
+
* @param spatial World-to-grid mapping config.
|
|
346
|
+
* @param cameraX Camera world X (scroll offset).
|
|
347
|
+
* @param cameraY Camera world Y (scroll offset).
|
|
348
|
+
* @param sx Screen X in pixels.
|
|
349
|
+
* @param sy Screen Y in pixels.
|
|
350
|
+
*/
|
|
351
|
+
export declare const screenToTile: (spatial: SpatialConfig, cameraX: number, cameraY: number, sx: number, sy: number) => {
|
|
352
|
+
x: number;
|
|
353
|
+
y: number;
|
|
354
|
+
};
|
|
355
|
+
/**
|
|
356
|
+
* Convert tile grid coordinates to screen-pixel coordinates (top-left of the tile),
|
|
357
|
+
* accounting for the camera offset and grid origin.
|
|
358
|
+
* @param spatial World-to-grid mapping config.
|
|
359
|
+
* @param cameraX Camera world X (scroll offset).
|
|
360
|
+
* @param cameraY Camera world Y (scroll offset).
|
|
361
|
+
* @param tx Tile column.
|
|
362
|
+
* @param ty Tile row.
|
|
363
|
+
*/
|
|
364
|
+
export declare const tileToScreen: (spatial: SpatialConfig, cameraX: number, cameraY: number, tx: number, ty: number) => {
|
|
365
|
+
x: number;
|
|
366
|
+
y: number;
|
|
367
|
+
};
|
|
368
|
+
/**
|
|
369
|
+
* Return the exact fractional tile-grid position for a world coordinate.
|
|
370
|
+
* `tileX` / `tileY` are the integer grid cell the point is inside.
|
|
371
|
+
* `fracX` / `fracY` are 0..1 fractions representing how far into the tile the point is —
|
|
372
|
+
* essential for smooth cross-tile movement, linear interpolation animations, and sub-tile collision.
|
|
373
|
+
* @param spatial World-to-grid mapping config.
|
|
374
|
+
* @param wx World X in pixels.
|
|
375
|
+
* @param wy World Y in pixels.
|
|
376
|
+
* @example
|
|
377
|
+
* // Entity smoothly walking; determine which tile it's in and how far across
|
|
378
|
+
* const pos = worldToTileExact(spatial, entity.x, entity.y)
|
|
379
|
+
* // pos.fracX === 0.5 means entity is horizontally centred in its tile
|
|
380
|
+
*/
|
|
381
|
+
export declare const worldToTileExact: (spatial: SpatialConfig, wx: number, wy: number) => TilePosition;
|
|
382
|
+
/**
|
|
383
|
+
* Convenience: return the `TileInfo` for whatever tile a world-pixel position falls on.
|
|
384
|
+
* Returns `null` when out of bounds.
|
|
385
|
+
* @param map The tile map.
|
|
386
|
+
* @param spatial World-to-grid mapping config.
|
|
387
|
+
* @param wx World X in pixels.
|
|
388
|
+
* @param wy World Y in pixels.
|
|
389
|
+
* @example
|
|
390
|
+
* const tile = getTileAtWorld(map, spatial, entity.x, entity.y)
|
|
391
|
+
* if (tile && tile.flags & TileFlags.HAZARD) takeDamage(entity)
|
|
392
|
+
*/
|
|
393
|
+
export declare const getTileAtWorld: <T>(map: TileMap<T>, spatial: SpatialConfig, wx: number, wy: number) => TileInfo<T> | null;
|
|
394
|
+
/**
|
|
395
|
+
* Convenience: return the `TileInfo` for whatever tile a screen-pixel position falls on,
|
|
396
|
+
* accounting for the camera offset and grid origin.
|
|
397
|
+
* Returns `null` when out of bounds.
|
|
398
|
+
* @param map The tile map.
|
|
399
|
+
* @param spatial World-to-grid mapping config.
|
|
400
|
+
* @param cameraX Camera world X (scroll offset).
|
|
401
|
+
* @param cameraY Camera world Y (scroll offset).
|
|
402
|
+
* @param sx Screen X in pixels.
|
|
403
|
+
* @param sy Screen Y in pixels.
|
|
404
|
+
* @example
|
|
405
|
+
* // Mouse click → tile lookup
|
|
406
|
+
* const tile = getTileAtScreen(map, spatial, camera.x, camera.y, mouseX, mouseY)
|
|
407
|
+
*/
|
|
408
|
+
export declare const getTileAtScreen: <T>(map: TileMap<T>, spatial: SpatialConfig, cameraX: number, cameraY: number, sx: number, sy: number) => TileInfo<T> | null;
|
|
409
|
+
declare const _default: {
|
|
410
|
+
TileFlags: {
|
|
411
|
+
readonly NONE: 0;
|
|
412
|
+
readonly BLOCKED: 1;
|
|
413
|
+
readonly OCCUPIED: 2;
|
|
414
|
+
readonly VISIBLE: 4;
|
|
415
|
+
readonly EXPLORED: 8;
|
|
416
|
+
readonly WATER: 16;
|
|
417
|
+
readonly HAZARD: 32;
|
|
418
|
+
};
|
|
419
|
+
createTileMap: <T>(width: number, height: number) => TileMap<T>;
|
|
420
|
+
getTileIndex: (map: TileMap<unknown>, x: number, y: number) => number;
|
|
421
|
+
getTileInfo: <T>(map: TileMap<T>, x: number, y: number) => TileInfo<T> | null;
|
|
422
|
+
indexToCoords: (map: TileMap<unknown>, index: number) => {
|
|
423
|
+
x: number;
|
|
424
|
+
y: number;
|
|
425
|
+
};
|
|
426
|
+
setFlag: (map: TileMap<unknown>, x: number, y: number, flag: number) => void;
|
|
427
|
+
clearFlag: (map: TileMap<unknown>, x: number, y: number, flag: number) => void;
|
|
428
|
+
toggleFlag: (map: TileMap<unknown>, x: number, y: number, flag: number) => void;
|
|
429
|
+
hasFlag: (map: TileMap<unknown>, x: number, y: number, flag: number) => boolean;
|
|
430
|
+
addEntity: <T>(map: TileMap<T>, x: number, y: number, entity: T) => boolean;
|
|
431
|
+
removeEntity: <T>(map: TileMap<T>, x: number, y: number, predicate: (e: T) => boolean) => boolean;
|
|
432
|
+
moveEntity: <T>(map: TileMap<T>, fromX: number, fromY: number, toX: number, toY: number, predicate: (e: T) => boolean) => boolean;
|
|
433
|
+
getEntitiesAt: <T>(map: TileMap<T>, x: number, y: number) => T[];
|
|
434
|
+
clearEntitiesAt: <T>(map: TileMap<T>, x: number, y: number) => void;
|
|
435
|
+
getAdjacentIndices: (map: TileMap<unknown>, x: number, y: number, includeDiagonals?: boolean) => number[];
|
|
436
|
+
getAdjacentTiles: <T>(map: TileMap<T>, x: number, y: number, includeDiagonals?: boolean) => TileInfo<T>[];
|
|
437
|
+
getIndicesInRange: (map: TileMap<unknown>, x: number, y: number, range: number, shape?: RangeShape, includeOrigin?: boolean) => number[];
|
|
438
|
+
getTilesInRange: <T>(map: TileMap<T>, x: number, y: number, range: number, shape?: RangeShape, includeOrigin?: boolean) => TileInfo<T>[];
|
|
439
|
+
getEntitiesInRange: <T>(map: TileMap<T>, x: number, y: number, range: number, shape?: RangeShape, includeOrigin?: boolean) => T[];
|
|
440
|
+
validateTile: <T>(map: TileMap<T>, x: number, y: number, validator?: TileValidator<T>) => boolean;
|
|
441
|
+
validateRange: <T>(map: TileMap<T>, x: number, y: number, range: number, validator: TileValidator<T>, shape?: RangeShape, includeOrigin?: boolean) => boolean;
|
|
442
|
+
createSpatialConfig: (tileWidth: number, tileHeight: number, originX?: number, originY?: number) => SpatialConfig;
|
|
443
|
+
worldToTile: (spatial: SpatialConfig, wx: number, wy: number) => {
|
|
444
|
+
x: number;
|
|
445
|
+
y: number;
|
|
446
|
+
};
|
|
447
|
+
tileToWorld: (spatial: SpatialConfig, tx: number, ty: number) => {
|
|
448
|
+
x: number;
|
|
449
|
+
y: number;
|
|
450
|
+
};
|
|
451
|
+
tileCenterWorld: (spatial: SpatialConfig, tx: number, ty: number) => {
|
|
452
|
+
x: number;
|
|
453
|
+
y: number;
|
|
454
|
+
};
|
|
455
|
+
screenToWorld: (cameraX: number, cameraY: number, sx: number, sy: number) => {
|
|
456
|
+
x: number;
|
|
457
|
+
y: number;
|
|
458
|
+
};
|
|
459
|
+
worldToScreen: (cameraX: number, cameraY: number, wx: number, wy: number) => {
|
|
460
|
+
x: number;
|
|
461
|
+
y: number;
|
|
462
|
+
};
|
|
463
|
+
screenToTile: (spatial: SpatialConfig, cameraX: number, cameraY: number, sx: number, sy: number) => {
|
|
464
|
+
x: number;
|
|
465
|
+
y: number;
|
|
466
|
+
};
|
|
467
|
+
tileToScreen: (spatial: SpatialConfig, cameraX: number, cameraY: number, tx: number, ty: number) => {
|
|
468
|
+
x: number;
|
|
469
|
+
y: number;
|
|
470
|
+
};
|
|
471
|
+
worldToTileExact: (spatial: SpatialConfig, wx: number, wy: number) => TilePosition;
|
|
472
|
+
getTileAtWorld: <T>(map: TileMap<T>, spatial: SpatialConfig, wx: number, wy: number) => TileInfo<T> | null;
|
|
473
|
+
getTileAtScreen: <T>(map: TileMap<T>, spatial: SpatialConfig, cameraX: number, cameraY: number, sx: number, sy: number) => TileInfo<T> | null;
|
|
474
|
+
};
|
|
475
|
+
export default _default;
|