Initial difficult terrain support
This commit is contained in:
@@ -2,7 +2,7 @@ import {measureDistances} from "./compatibility.js";
|
|||||||
import {getMovementHistory} from "./movement_tracking.js";
|
import {getMovementHistory} from "./movement_tracking.js";
|
||||||
import {GenericSpeedProvider, SpeedProvider} from "./speed_provider.js"
|
import {GenericSpeedProvider, SpeedProvider} from "./speed_provider.js"
|
||||||
import {settingsKey} from "./settings.js"
|
import {settingsKey} from "./settings.js"
|
||||||
import {getTokenShape} from "./util.js";
|
import {getAreaFromPositionAndShape, getTokenShape} from "./util.js";
|
||||||
|
|
||||||
export const availableSpeedProviders = {}
|
export const availableSpeedProviders = {}
|
||||||
export let currentSpeedProvider = undefined
|
export let currentSpeedProvider = undefined
|
||||||
@@ -140,6 +140,10 @@ export function getMovedDistanceFromToken(token) {
|
|||||||
return distances.reduce((acc, val) => acc + val, 0);
|
return distances.reduce((acc, val) => acc + val, 0);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function buildCostFunction(token, shape) {
|
||||||
|
return (x, y, costOptions={}) => getCostFromSpeedProvider(token, getAreaFromPositionAndShape({x, y}, shape), costOptions);
|
||||||
|
}
|
||||||
|
|
||||||
export function registerModule(moduleId, speedProvider) {
|
export function registerModule(moduleId, speedProvider) {
|
||||||
// Check if a module with the given id exists and is currently enabled
|
// Check if a module with the given id exists and is currently enabled
|
||||||
const module = game.modules.get(moduleId)
|
const module = game.modules.get(moduleId)
|
||||||
|
|||||||
+3
-3
@@ -1,6 +1,6 @@
|
|||||||
import {getCostFromSpeedProvider} from "./api.js";
|
import {buildCostFunction} from "./api.js";
|
||||||
import {settingsKey} from "./settings.js";
|
import {settingsKey} from "./settings.js";
|
||||||
import {getAreaFromPositionAndShape, highlightTokenShape} from "./util.js";
|
import {highlightTokenShape} from "./util.js";
|
||||||
|
|
||||||
export function getHexSizeSupportTokenGridCenter(token) {
|
export function getHexSizeSupportTokenGridCenter(token) {
|
||||||
const tokenCenterOffset = CONFIG.hexSizeSupport.getCenterOffset(token)
|
const tokenCenterOffset = CONFIG.hexSizeSupport.getCenterOffset(token)
|
||||||
@@ -27,7 +27,7 @@ export function measureDistances(segments, entity, shape, options={}) {
|
|||||||
const newSegments = segments.slice(firstNewSegmentIndex);
|
const newSegments = segments.slice(firstNewSegmentIndex);
|
||||||
const distances = previousSegments.map(segment => segment.ray.dragRulerVisitedSpaces[segment.ray.dragRulerVisitedSpaces.length - 1].distance);
|
const distances = previousSegments.map(segment => segment.ray.dragRulerVisitedSpaces[segment.ray.dragRulerVisitedSpaces.length - 1].distance);
|
||||||
previousSegments.forEach(segment => segment.ray.terrainRulerVisitedSpaces = duplicate(segment.ray.dragRulerVisitedSpaces));
|
previousSegments.forEach(segment => segment.ray.terrainRulerVisitedSpaces = duplicate(segment.ray.dragRulerVisitedSpaces));
|
||||||
opts.costFunction = (x, y, costOptions={}) => { return getCostFromSpeedProvider(entity, getAreaFromPositionAndShape({x, y}, shape), costOptions); }
|
opts.costFunction = buildCostFunction(entity, shape);
|
||||||
if (previousSegments.length > 0)
|
if (previousSegments.length > 0)
|
||||||
opts.terrainRulerInitialState = previousSegments[previousSegments.length - 1].ray.dragRulerFinalState;
|
opts.terrainRulerInitialState = previousSegments[previousSegments.length - 1].ray.dragRulerFinalState;
|
||||||
return distances.concat(terrainRuler.measureDistances(newSegments, opts));
|
return distances.concat(terrainRuler.measureDistances(newSegments, opts));
|
||||||
|
|||||||
+18
-6
@@ -1,4 +1,4 @@
|
|||||||
import {getGridPositionFromPixelsObj, getPixelsFromGridPositionObj} from "./foundry_fixes.js";
|
import {getCenterFromGridPositionObj, getGridPositionFromPixelsObj, getPixelsFromGridPositionObj} from "./foundry_fixes.js";
|
||||||
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";
|
||||||
@@ -6,6 +6,8 @@ import {getSnapPointForTokenObj, 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 { measure } from "./foundry_imports.js";
|
||||||
|
|
||||||
let cachedNodes = undefined;
|
let cachedNodes = undefined;
|
||||||
let cacheElevation;
|
let cacheElevation;
|
||||||
@@ -74,12 +76,22 @@ function getNode(pos, token, initialize=true) {
|
|||||||
|
|
||||||
// TODO Work with pixels instead of grid locations
|
// TODO Work with pixels instead of grid locations
|
||||||
if (!stepCollidesWithWall(neighborPos, pos, token)) {
|
if (!stepCollidesWithWall(neighborPos, pos, token)) {
|
||||||
const isDiagonal = node.x !== neighborPos.x && node.y !== neighborPos.y && canvas.grid.type === CONST.GRID_TYPES.SQUARE;
|
let edgeCost;
|
||||||
const neighbor = getNode(neighborPos, token, false);
|
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 measuredDistance = terrainRuler.measureDistances([{ray}], {costFunction: buildCostFunction(token, [{x: 0, y: 0}])})[0];
|
||||||
|
edgeCost = Math.round(measuredDistance / canvas.dimensions.distance);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
const isDiagonal = node.x !== neighborPos.x && node.y !== neighborPos.y && canvas.grid.type === CONST.GRID_TYPES.SQUARE;
|
||||||
|
|
||||||
// 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)
|
// 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)
|
||||||
// TODO Account for difficult terrain
|
// TODO Account for difficult terrain
|
||||||
let edgeCost = isDiagonal ? (use5105 ? 1.5 : 1.0001) : 1;
|
edgeCost = isDiagonal ? (use5105 ? 1.5 : 1.0001) : 1;
|
||||||
|
}
|
||||||
|
const neighbor = getNode(neighborPos, token, false);
|
||||||
node.edges.push({target: neighbor, cost: edgeCost});
|
node.edges.push({target: neighbor, cost: edgeCost});
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user