Use the correct token shape
This commit is contained in:
+17
-15
@@ -2,14 +2,15 @@ import {getCenterFromGridPositionObj, getGridPositionFromPixelsObj, getPixelsFro
|
|||||||
import {moveWithoutAnimation, togglePathfinding} from "./keybindings.js";
|
import {moveWithoutAnimation, togglePathfinding} from "./keybindings.js";
|
||||||
import {debugGraphics} from "./main.js";
|
import {debugGraphics} from "./main.js";
|
||||||
import {settingsKey} from "./settings.js";
|
import {settingsKey} from "./settings.js";
|
||||||
import {getSnapPointForTokenObj, iterPairs} from "./util.js";
|
import {getSnapPointForTokenObj, getTokenShape, getTokenShapeId, iterPairs} from "./util.js";
|
||||||
|
|
||||||
import * as GridlessPathfinding from "../wasm/gridless_pathfinding.js";
|
import * as GridlessPathfinding from "../wasm/gridless_pathfinding.js";
|
||||||
import {PriorityQueueSet} from "./data_structures.js";
|
import {PriorityQueueSet} from "./data_structures.js";
|
||||||
import { buildCostFunction } from "./api.js";
|
import { buildCostFunction } from "./api.js";
|
||||||
import { measure } from "./foundry_imports.js";
|
import { measure } from "./foundry_imports.js";
|
||||||
|
|
||||||
let cachedNodes = undefined;
|
// TODO Account for changing terrain per token in the caches
|
||||||
|
let caches = new Map();
|
||||||
let cacheElevation;
|
let cacheElevation;
|
||||||
let use5105 = false;
|
let use5105 = false;
|
||||||
let gridlessPathfinders = new Map();
|
let gridlessPathfinders = new Map();
|
||||||
@@ -53,8 +54,7 @@ export function findPath(from, to, token, previousWaypoints) {
|
|||||||
let endNode = getCenterFromGridPositionObj(currentNode.node);
|
let endNode = getCenterFromGridPositionObj(currentNode.node);
|
||||||
let oldPath = [{ray: new Ray(startNode, middleNode)}, {ray: new Ray(middleNode, endNode)}];
|
let oldPath = [{ray: new Ray(startNode, middleNode)}, {ray: new Ray(middleNode, endNode)}];
|
||||||
let newPath = [{ray: new Ray(startNode, endNode)}];
|
let newPath = [{ray: new Ray(startNode, endNode)}];
|
||||||
// TODO Use correct token shape
|
let costFunction = buildCostFunction(token, getTokenShape(token));
|
||||||
let costFunction = buildCostFunction(token, [{x: 0, y: 0}]);
|
|
||||||
// TODO Cache the used measurement for use in the next loop to improve performance
|
// TODO Cache the used measurement for use in the next loop to improve performance
|
||||||
let oldDistance = terrainRuler.measureDistances(oldPath, {costFunction}).reduce((a, b) => a + b);
|
let oldDistance = terrainRuler.measureDistances(oldPath, {costFunction}).reduce((a, b) => a + b);
|
||||||
let newDistance = terrainRuler.measureDistances(newPath, {costFunction})[0];
|
let newDistance = terrainRuler.measureDistances(newPath, {costFunction})[0];
|
||||||
@@ -84,15 +84,19 @@ export function findPath(from, to, token, previousWaypoints) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function getNode(pos, token, initialize=true) {
|
function getNode(pos, token, initialize=true) {
|
||||||
if (!cachedNodes)
|
let shapeId = getTokenShapeId(token);
|
||||||
cachedNodes = new Array(gridHeight);
|
let cache = caches.get(shapeId);
|
||||||
if (!cachedNodes[pos.y])
|
if (!cache) {
|
||||||
cachedNodes[pos.y] = new Array(gridWidth);
|
cache = new Array(gridHeight);
|
||||||
if (!cachedNodes[pos.y][pos.x]) {
|
caches.set(shapeId, cache);
|
||||||
cachedNodes[pos.y][pos.x] = pos;
|
}
|
||||||
|
if (!cache[pos.y])
|
||||||
|
cache[pos.y] = new Array(gridWidth);
|
||||||
|
if (!cache[pos.y][pos.x]) {
|
||||||
|
cache[pos.y][pos.x] = pos;
|
||||||
}
|
}
|
||||||
|
|
||||||
const node = cachedNodes[pos.y][pos.x];
|
const node = cache[pos.y][pos.x];
|
||||||
if (initialize && !node.edges) {
|
if (initialize && !node.edges) {
|
||||||
node.edges = [];
|
node.edges = [];
|
||||||
for (const neighborPos of canvas.grid.grid.getNeighbors(pos.y, pos.x).map(([y, x]) => {return {x, y};})) {
|
for (const neighborPos of canvas.grid.grid.getNeighbors(pos.y, pos.x).map(([y, x]) => {return {x, y};})) {
|
||||||
@@ -105,10 +109,8 @@ function getNode(pos, token, initialize=true) {
|
|||||||
const isDiagonal = node.x !== neighborPos.x && node.y !== neighborPos.y && canvas.grid.type === CONST.GRID_TYPES.SQUARE;
|
const isDiagonal = node.x !== neighborPos.x && node.y !== neighborPos.y && canvas.grid.type === CONST.GRID_TYPES.SQUARE;
|
||||||
let edgeCost;
|
let edgeCost;
|
||||||
if (window.terrainRuler) {
|
if (window.terrainRuler) {
|
||||||
// TODO Additional cache for each token shape
|
|
||||||
// TODO Use the correct token shape
|
|
||||||
let ray = new Ray(getCenterFromGridPositionObj(neighborPos), getCenterFromGridPositionObj(pos));
|
let ray = new Ray(getCenterFromGridPositionObj(neighborPos), getCenterFromGridPositionObj(pos));
|
||||||
let measuredDistance = terrainRuler.measureDistances([{ray}], {costFunction: buildCostFunction(token, [{x: 0, y: 0}])})[0];
|
let measuredDistance = terrainRuler.measureDistances([{ray}], {costFunction: buildCostFunction(token, getTokenShape(token))})[0];
|
||||||
edgeCost = Math.round(measuredDistance / canvas.dimensions.distance);
|
edgeCost = Math.round(measuredDistance / canvas.dimensions.distance);
|
||||||
if (ray.terrainRulerFinalState?.noDiagonals === 1) {
|
if (ray.terrainRulerFinalState?.noDiagonals === 1) {
|
||||||
edgeCost = 1.5;
|
edgeCost = 1.5;
|
||||||
@@ -200,7 +202,7 @@ function stepCollidesWithWall(from, to, token) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
export function wipePathfindingCache() {
|
export function wipePathfindingCache() {
|
||||||
cachedNodes = undefined;
|
caches.clear();
|
||||||
for (const pathfinder of gridlessPathfinders.values()) {
|
for (const pathfinder of gridlessPathfinders.values()) {
|
||||||
GridlessPathfinding.free(pathfinder);
|
GridlessPathfinding.free(pathfinder);
|
||||||
}
|
}
|
||||||
|
|||||||
+25
@@ -157,6 +157,31 @@ export function getAreaFromPositionAndShape(position, shape) {
|
|||||||
});
|
});
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
|
export function getTokenShapeId(token) {
|
||||||
|
if (token.scene.data.gridType === CONST.GRID_TYPES.GRIDLESS) {
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
else if (token.scene.data.gridType === CONST.GRID_TYPES.SQUARE) {
|
||||||
|
return `${token.data.width}x${token.data.height}`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
// Hex grids
|
||||||
|
if (game.modules.get("hex-size-support")?.active && CONFIG.hexSizeSupport.getAltSnappingFlag(token)) {
|
||||||
|
const borderSize = token.data.flags["hex-size-support"].borderSize;
|
||||||
|
|
||||||
|
let inversionFlag = "";
|
||||||
|
if (Boolean(CONFIG.hexSizeSupport.getAltOrientationFlag(token)) !== canvas.grid.grid.options.columns)
|
||||||
|
inversionFlag = "i";
|
||||||
|
|
||||||
|
return `${borderSize}${inversionFlag}`;
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
return "1";
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
export function getTokenShape(token) {
|
export function getTokenShape(token) {
|
||||||
if (token.scene.data.gridType === CONST.GRID_TYPES.GRIDLESS) {
|
if (token.scene.data.gridType === CONST.GRID_TYPES.GRIDLESS) {
|
||||||
return [{x: 0, y: 0}]
|
return [{x: 0, y: 0}]
|
||||||
|
|||||||
Reference in New Issue
Block a user