UNPKG

malwoden

Version:

![alt text](./coverage/badge-lines.svg) ![alt text](./coverage/badge-statements.svg) ![alt text](./coverage/badge-functions.svg) ![alt text](./coverage/badge-branches.svg)

100 lines 4.26 kB
"use strict"; var __assign = (this && this.__assign) || function () { __assign = Object.assign || function(t) { for (var s, i = 1, n = arguments.length; i < n; i++) { s = arguments[i]; for (var p in s) if (Object.prototype.hasOwnProperty.call(s, p)) t[p] = s[p]; } return t; }; return __assign.apply(this, arguments); }; Object.defineProperty(exports, "__esModule", { value: true }); exports.RangeFinder = void 0; var get_ring_1 = require("../fov/get-ring"); var struct_1 = require("../struct"); /** * Used to find a range from a central point, like movement or ranged attacks in * turn-based games. This uses a search similar to Dijkstra or AStar, but returns * a list of tiles in range of a starting point, rather than a path to a goal. */ var RangeFinder = /** @class */ (function () { /** * @param config - Configuration for the RangeFinder * @param config.topology - four | eight * @param config.getTerrainCallback - Override the distance function for terrain costs or blocked spaces. */ function RangeFinder(config) { this.getTerrain = function () { return 1; }; this.topology = config.topology; if (config.getTerrainCallback) { this.getTerrain = config.getTerrainCallback; } } RangeFinder.prototype.getNeighbors = function (pos) { var neighbors = get_ring_1.getRing4(pos.x, pos.y, 1); if (this.topology === "eight") { neighbors.push({ x: pos.x + 1, y: pos.y - 1 }); neighbors.push({ x: pos.x - 1, y: pos.y - 1 }); neighbors.push({ x: pos.x - 1, y: pos.y + 1 }); neighbors.push({ x: pos.x + 1, y: pos.y + 1 }); } return neighbors; }; /** * Find the range from a given point. * @param config - Configuration for the findRange * @param config.start - Vector2 - The starting point * @param config.maxRange - The maximum range allowed * @param config.minRange - The minimum range allowed (optional) * @returns - RangeVector2[] ({x,y,r}[]) */ RangeFinder.prototype.compute = function (config) { var start = config.start, range = config.maxRange, _a = config.minRange, minRange = _a === void 0 ? 0 : _a; // Nodes we will process neighbors of var horizon = new struct_1.HeapPriorityQueue(function (v) { return v.r; }); horizon.insert(__assign(__assign({}, start), { r: 0 })); var explored = new Map(); explored.set(start.x + ":" + start.y, 0); while (horizon.size()) { // Handle current node first var current = horizon.pop(); // Handle neighbors var neighbors = this.getNeighbors(current); for (var _i = 0, neighbors_1 = neighbors; _i < neighbors_1.length; _i++) { var n = neighbors_1[_i]; var distance = current.r + this.getTerrain(current, n); var neighbor = __assign(__assign({}, n), { r: distance }); // See if it's even in range if (neighbor.r > range) continue; // We pay attention only if we haven't seen it before, // or we just found a shorter path var importantNeighbor = !explored.has(neighbor.x + ":" + neighbor.y) || neighbor.r < explored.get(neighbor.x + ":" + neighbor.y); if (importantNeighbor) { explored.set(neighbor.x + ":" + neighbor.y, neighbor.r); horizon.insert(neighbor); } } } // Return everything in range var result = []; explored.forEach(function (distance, vs) { // Return if not in the right range if (distance < minRange || distance > range) return; var _a = vs.split(":"), x = _a[0], y = _a[1]; result.push({ x: Number.parseInt(x), y: Number.parseInt(y), r: distance, }); }); return result; }; return RangeFinder; }()); exports.RangeFinder = RangeFinder; //# sourceMappingURL=range-finder.js.map