Skip to content

Commit

Permalink
Make offsets hex-aware (fixes #3)
Browse files Browse the repository at this point in the history
  • Loading branch information
manuelVo committed Oct 18, 2022
1 parent 4ae21da commit ae5449e
Show file tree
Hide file tree
Showing 2 changed files with 49 additions and 5 deletions.
16 changes: 11 additions & 5 deletions js/pathfinder.js
Original file line number Diff line number Diff line change
@@ -1,7 +1,13 @@
import {cache, stepCollidesWithWall} from "./cache.js";
import {PriorityQueueSet} from "./data_structures.js";
import {getCenterFromGridPositionObj} from "./foundry_fixes.js";
import {getAreaFromPositionAndShape, getTokenShapeForTokenData, nodeId} from "./util.js";
import {
applyOffset,
buildOffset,
getAreaFromPositionAndShape,
getTokenShapeForTokenData,
nodeId,
} from "./util.js";

import * as GridlessPathfinding from "../wasm/gridless_pathfinding.js";

Expand Down Expand Up @@ -70,7 +76,7 @@ export class GriddedPathfinder {
}
let cost;
if (window.terrainRuler && !this.ignoreTerrain) {
const offset = {x: neighbor.x - currentNode.node.x, y: neighbor.y - currentNode.node.y};
const offset = buildOffset(currentNode.node, neighbor);
cost = this.terrainCostForStep(tokenArea, offset, currentNode.cost);
} else {
// Count 5-10-5 diagonals as 1.5 (so two add up to 3) and 5-5-5 diagonals as 1.0001 (to discourage unnecessary diagonals)
Expand All @@ -91,7 +97,7 @@ export class GriddedPathfinder {
terrainCostForStep(tokenArea, offset, previousDistance = 0) {
let distance = 0;
for (const srcCell of tokenArea) {
const dstCell = {x: srcCell.x + offset.x, y: srcCell.y + offset.y};
const dstCell = applyOffset(srcCell, offset);
// TODO Cache the result of source->destination measurements to speed up the pathfinding for large tokens
const ray = new Ray(
getCenterFromGridPositionObj(srcCell),
Expand Down Expand Up @@ -134,9 +140,9 @@ export class GriddedPathfinder {
x: middleNode.x - startNode.x,
y: middleNode.y - startNode.y,
};
const startEndOffset = {x: endNode.x - startNode.x, y: endNode.y - startNode.y};
const startEndOffset = buildOffset(startNode, endNode);
const middleArea = getAreaFromPositionAndShape(middleNode, this.tokenShape);
const middleEndOffset = {x: endNode.x - middleNode.x, y: endNode.y - middleNode.y};
const middleEndOffset = buildOffset(middleNode, endNode);

// TODO Cache the measurement for use in the next loop to improve performance - this can possibly be done withing terrainCostForStep
const middleDistance = this.terrainCostForStep(startArea, startMiddleOffset);
Expand Down
38 changes: 38 additions & 0 deletions js/util.js
Original file line number Diff line number Diff line change
Expand Up @@ -161,3 +161,41 @@ export function getAreaFromPositionAndShape(position, shape) {
return {x, y};
});
}

export function buildOffset(startPos, endPos) {
const offset = {x: endPos.x - startPos.x, y: endPos.y - startPos.y};
if (canvas.grid.isHex) {
if (canvas.grid.grid.columnar) {
offset.adjustmentNeeded = (startPos.x - endPos.x) % 2 !== 0;
offset.originEven = startPos.x % 2 === 0;
} else {
offset.adjustmentNeeded = (startPos.y - endPos.y) % 2 !== 0;
offset.originEven = startPos.y % 2 === 0;
}
}
return offset;
}

export function applyOffset(origin, offset) {
const pos = {x: origin.x + offset.x, y: origin.y + offset.y};
if (canvas.grid.isHex && offset.adjustmentNeeded) {
if (canvas.grid.grid.columnar) {
if ((origin.x % 2 === 0) !== offset.originEven) {
if (offset.originEven === canvas.grid.grid.even) {
pos.y -= 1;
} else {
pos.y += 1;
}
}
} else {
if ((origin.y % 2 === 0) !== offset.originEven) {
if (offset.originEven === canvas.grid.grid.even) {
pos.x -= 1;
} else {
pos.x += 1;
}
}
}
}
return pos;
}

0 comments on commit ae5449e

Please sign in to comment.