Compare commits
65 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 7afb1e11de | |||
| 61c48dff5e | |||
| 3c9a86647e | |||
| c928f46f7c | |||
| 09e8ca79b3 | |||
| 833aced2be | |||
| 17d8db6c34 | |||
| 466e5a36d1 | |||
| 8e29cf186b | |||
| dd9a7ecf68 | |||
| 2bf52e62dd | |||
| c11899fb17 | |||
| e2afe05e4e | |||
| 8eb29a4dce | |||
| db7dd1c1c9 | |||
| 0ccfc6ef2f | |||
| f5b0e145ac | |||
| 78b1e8cc4e | |||
| 4d6543174a | |||
| b55af992ec | |||
| 0f288b65d9 | |||
| 9253f3decd | |||
| 188f6c15bf | |||
| 6273f7f8a7 | |||
| 6ce076fa43 | |||
| 1f434b3f6b | |||
| 1e14ff24b0 | |||
| cd61aa948e | |||
| 8817775201 | |||
| 673fa42a20 | |||
| 1ee406a047 | |||
| 08f41ed2ff | |||
| dc85609a75 | |||
| 472b373f13 | |||
| 57ed4d2cc5 | |||
| 81acdc3e63 | |||
| 64bce387d1 | |||
| 6a5c96e425 | |||
| 43c05745c8 | |||
| efc3eb871c | |||
| 8f134a49ba | |||
| e2c7fd992b | |||
| 2e06a2440c | |||
| 1c27f1a4a8 | |||
| 5e96be458e | |||
| b56d4fd14d | |||
| b822ada782 | |||
| b610a00f0f | |||
| fe3efd7fe4 | |||
| 5f971862e8 | |||
| b8c29de841 | |||
| a5b40382d7 | |||
| ce9bea14fc | |||
| a404353d38 | |||
| a132ac2bf3 | |||
| e3a785d8fe | |||
| 6e0571c565 | |||
| 4c006d34c9 | |||
| 9140ef3acf | |||
| 7e19fb95b0 | |||
| c9696f8725 | |||
| 54cebc3192 | |||
| 310014bb8a | |||
| d53399fa1e | |||
| 369159e6bb |
+1
-2
@@ -1,4 +1,3 @@
|
|||||||
/foundry*.js
|
foundry-*.js
|
||||||
artifact/
|
artifact/
|
||||||
wasm/
|
wasm/
|
||||||
*.lock
|
|
||||||
|
|||||||
@@ -1,30 +1,3 @@
|
|||||||
## 1.12.3
|
|
||||||
### Bugfixes
|
|
||||||
- Fixed a bug that could cause foundry to freeze indefinitely when trying to pathfind to an unreachalbe location (thanks to JDCalvert)
|
|
||||||
- Fixed a bug that caused the pathfinder to route through one-directional walls from the wrong direction (thanks to JDCalvert)
|
|
||||||
- Fixed a bug that could cause Drag Ruler to write errors into the JS console during regular usage
|
|
||||||
|
|
||||||
### Compatibility
|
|
||||||
- Drag Ruler's generic speed provider is now aware of good defaults for DnD 4th Edition
|
|
||||||
- Drag Ruler's pathfinder should now be compatible with the Wall Height and Levels modules (thanks to JDCalvert)
|
|
||||||
|
|
||||||
|
|
||||||
## 1.12.2
|
|
||||||
### Bugfixes
|
|
||||||
- Fixed a bug where the pathfinder on gridless scenes sometimes wasn't able to find a way around corners with specific angles
|
|
||||||
- Pathfinding will now be disabled when the hotkey to move tokens without animation is being pressed, to allow GMs to move their tokens through walls
|
|
||||||
|
|
||||||
|
|
||||||
## 1.12.1
|
|
||||||
### Hotfix
|
|
||||||
- Version 1.12.0 was incorrectly packaged, which caused it to fail to load
|
|
||||||
|
|
||||||
|
|
||||||
## 1.12.0
|
|
||||||
### New features
|
|
||||||
- Pathfinding is now supported on gridless scenes
|
|
||||||
|
|
||||||
|
|
||||||
## 1.11.5
|
## 1.11.5
|
||||||
### Bugfixes
|
### Bugfixes
|
||||||
- Fixed a bug that was causing Drag Ruler to spam useless warnings into the console (this was a regression introduced in 1.11.4)
|
- Fixed a bug that was causing Drag Ruler to spam useless warnings into the console (this was a regression introduced in 1.11.4)
|
||||||
|
|||||||
+1
-1
@@ -11,7 +11,7 @@ wasm_pack = Path("~/.cargo/bin/wasm-pack").expanduser()
|
|||||||
root_files = ["module.json", "README.md", "CHANGELOG.md", "LICENSE"]
|
root_files = ["module.json", "README.md", "CHANGELOG.md", "LICENSE"]
|
||||||
wasm_files = ["gridless_pathfinding_bg.wasm", "gridless_pathfinding.js"]
|
wasm_files = ["gridless_pathfinding_bg.wasm", "gridless_pathfinding.js"]
|
||||||
output_dir = Path("artifact")
|
output_dir = Path("artifact")
|
||||||
copy_everything_directories = ["js", "lang", "templates"]
|
copy_everything_directories = ["js", "lang", "templates", "wasm/snippets"]
|
||||||
wasm_dir = Path("wasm")
|
wasm_dir = Path("wasm")
|
||||||
root_dir = Path(".")
|
root_dir = Path(".")
|
||||||
rust_dir = Path("rust")
|
rust_dir = Path("rust")
|
||||||
|
|||||||
@@ -113,16 +113,6 @@ function handleDisableSnap(event) {
|
|||||||
|
|
||||||
function handleMoveWithoutAnimation(event) {
|
function handleMoveWithoutAnimation(event) {
|
||||||
moveWithoutAnimation = !event.up;
|
moveWithoutAnimation = !event.up;
|
||||||
|
|
||||||
const ruler = canvas.controls.ruler;
|
|
||||||
if (!ruler?.isDragRuler)
|
|
||||||
return false;
|
|
||||||
if (ruler._state !== Ruler.STATES.MEASURING)
|
|
||||||
return false;
|
|
||||||
|
|
||||||
ruler.measure(getMeasurePosition(), {snap: !disableSnap});
|
|
||||||
ruler.dragRulerSendState();
|
|
||||||
return false;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
function handleTogglePathfinding(event) {
|
function handleTogglePathfinding(event) {
|
||||||
|
|||||||
+2
-5
@@ -7,7 +7,7 @@ import {disableSnap, registerKeybindings} from "./keybindings.js";
|
|||||||
import {libWrapper} from "./libwrapper_shim.js";
|
import {libWrapper} from "./libwrapper_shim.js";
|
||||||
import {performMigrations} from "./migration.js"
|
import {performMigrations} from "./migration.js"
|
||||||
import {removeLastHistoryEntryIfAt, resetMovementHistory} from "./movement_tracking.js";
|
import {removeLastHistoryEntryIfAt, resetMovementHistory} from "./movement_tracking.js";
|
||||||
import {wipePathfindingCache, initializePathfinding} from "./pathfinding.js";
|
import {wipePathfindingCache} from "./pathfinding.js";
|
||||||
import {extendRuler} from "./ruler.js";
|
import {extendRuler} from "./ruler.js";
|
||||||
import {registerSettings, RightClickAction, settingsKey} from "./settings.js"
|
import {registerSettings, RightClickAction, settingsKey} from "./settings.js"
|
||||||
import {recalculate} from "./socket.js";
|
import {recalculate} from "./socket.js";
|
||||||
@@ -21,10 +21,7 @@ export let debugGraphics = undefined;
|
|||||||
|
|
||||||
initGridlessPathfinding().then(() => {
|
initGridlessPathfinding().then(() => {
|
||||||
Hooks.on("canvasInit", wipePathfindingCache);
|
Hooks.on("canvasInit", wipePathfindingCache);
|
||||||
Hooks.on("canvasReady", () => {
|
Hooks.on("canvasReady", wipePathfindingCache);
|
||||||
wipePathfindingCache();
|
|
||||||
initializePathfinding();
|
|
||||||
});
|
|
||||||
Hooks.on("createWall", wipePathfindingCache);
|
Hooks.on("createWall", wipePathfindingCache);
|
||||||
Hooks.on("updateWall", wipePathfindingCache);
|
Hooks.on("updateWall", wipePathfindingCache);
|
||||||
Hooks.on("deleteWall", wipePathfindingCache);
|
Hooks.on("deleteWall", wipePathfindingCache);
|
||||||
|
|||||||
+15
-42
@@ -1,5 +1,5 @@
|
|||||||
import {getGridPositionFromPixelsObj, getPixelsFromGridPositionObj} from "./foundry_fixes.js";
|
import {getGridPositionFromPixelsObj, getPixelsFromGridPositionObj} from "./foundry_fixes.js";
|
||||||
import {moveWithoutAnimation, togglePathfinding} from "./keybindings.js";
|
import {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, iterPairs} from "./util.js";
|
||||||
@@ -7,29 +7,23 @@ import {getSnapPointForTokenObj, iterPairs} from "./util.js";
|
|||||||
import * as GridlessPathfinding from "../wasm/gridless_pathfinding.js"
|
import * as GridlessPathfinding from "../wasm/gridless_pathfinding.js"
|
||||||
|
|
||||||
let cachedNodes = undefined;
|
let cachedNodes = undefined;
|
||||||
let cacheElevation;
|
|
||||||
let use5105 = false;
|
let use5105 = false;
|
||||||
let gridlessPathfinders = new Map();
|
let gridlessPathfinders = new Map();
|
||||||
let gridWidth, gridHeight;
|
|
||||||
|
|
||||||
export function isPathfindingEnabled() {
|
export function isPathfindingEnabled() {
|
||||||
if (this.user !== game.user)
|
if (this.user !== game.user)
|
||||||
return false;
|
return false;
|
||||||
if (!game.user.isGM && !game.settings.get(settingsKey, "allowPathfinding"))
|
if (!game.user.isGM && !game.settings.get(settingsKey, "allowPathfinding"))
|
||||||
return false;
|
return false;
|
||||||
if (moveWithoutAnimation)
|
|
||||||
return false;
|
|
||||||
return game.settings.get(settingsKey, "autoPathfinding") != togglePathfinding;
|
return game.settings.get(settingsKey, "autoPathfinding") != togglePathfinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function findPath(from, to, token, previousWaypoints) {
|
export function findPath(from, to, token, previousWaypoints) {
|
||||||
checkCacheValid(token);
|
|
||||||
|
|
||||||
if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS) {
|
if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS) {
|
||||||
let tokenSize = Math.max(token.data.width, token.data.height) * canvas.dimensions.size;
|
let tokenSize = Math.max(token.data.width, token.data.height) * canvas.dimensions.size;
|
||||||
let pathfinder = gridlessPathfinders.get(tokenSize);
|
let pathfinder = gridlessPathfinders.get(tokenSize);
|
||||||
if (!pathfinder) {
|
if (!pathfinder) {
|
||||||
pathfinder = GridlessPathfinding.initialize(canvas.walls.placeables, tokenSize, token.data.elevation, Boolean(game.modules.get("levels")?.active));
|
pathfinder = GridlessPathfinding.initialize(canvas.walls.placeables, tokenSize);
|
||||||
gridlessPathfinders.set(tokenSize, pathfinder);
|
gridlessPathfinders.set(tokenSize, pathfinder);
|
||||||
}
|
}
|
||||||
paintGridlessPathfindingDebug(pathfinder);
|
paintGridlessPathfindingDebug(pathfinder);
|
||||||
@@ -44,7 +38,7 @@ export function findPath(from, to, token, previousWaypoints) {
|
|||||||
let currentNode = lastNode;
|
let currentNode = lastNode;
|
||||||
while (currentNode) {
|
while (currentNode) {
|
||||||
// TODO Check if the distance doesn't change
|
// TODO Check if the distance doesn't change
|
||||||
if (path.length >= 2 && !stepCollidesWithWall(path[path.length - 2], currentNode.node, token))
|
if (path.length >= 2 && !stepCollidesWithWall(currentNode.node, path[path.length - 2], token))
|
||||||
// Replace last waypoint if the current waypoint leads to a valid path
|
// Replace last waypoint if the current waypoint leads to a valid path
|
||||||
path[path.length - 1] = {x: currentNode.node.x, y: currentNode.node.y};
|
path[path.length - 1] = {x: currentNode.node.x, y: currentNode.node.y};
|
||||||
else
|
else
|
||||||
@@ -55,6 +49,16 @@ export function findPath(from, to, token, previousWaypoints) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function wipePathfindingCache() {
|
||||||
|
cachedNodes = undefined;
|
||||||
|
for (const pathfinder of gridlessPathfinders.values()) {
|
||||||
|
GridlessPathfinding.free(pathfinder);
|
||||||
|
}
|
||||||
|
gridlessPathfinders.clear();
|
||||||
|
if (debugGraphics)
|
||||||
|
debugGraphics.removeChildren().forEach(c => c.destroy());
|
||||||
|
}
|
||||||
|
|
||||||
function getNode(pos, token, initialize=true) {
|
function getNode(pos, token, initialize=true) {
|
||||||
pos = {layer: 0, ...pos}; // Copy pos and set pos.layer to the default value if it's unset
|
pos = {layer: 0, ...pos}; // Copy pos and set pos.layer to the default value if it's unset
|
||||||
if (!cachedNodes)
|
if (!cachedNodes)
|
||||||
@@ -71,12 +75,10 @@ function getNode(pos, token, initialize=true) {
|
|||||||
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};})) {
|
||||||
if (neighborPos.x < 0 || neighborPos.y < 0 || neighborPos.x > gridWidth || neighborPos.y > gridHeight) {
|
if (neighborPos.x < 0 || neighborPos.y < 0)
|
||||||
continue;
|
continue;
|
||||||
}
|
|
||||||
|
|
||||||
// TODO Work with pixels instead of grid locations
|
// TODO Work with pixels instead of grid locations
|
||||||
if (!stepCollidesWithWall(neighborPos, pos, token)) {
|
if (!stepCollidesWithWall(pos, neighborPos, token)) {
|
||||||
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 targetLayer = pos.layer;
|
let targetLayer = pos.layer;
|
||||||
if (use5105 && isDiagonal)
|
if (use5105 && isDiagonal)
|
||||||
@@ -154,35 +156,6 @@ function stepCollidesWithWall(from, to, token) {
|
|||||||
return canvas.walls.checkCollision(new Ray(stepStart, stepEnd));
|
return canvas.walls.checkCollision(new Ray(stepStart, stepEnd));
|
||||||
}
|
}
|
||||||
|
|
||||||
export function wipePathfindingCache() {
|
|
||||||
cachedNodes = undefined;
|
|
||||||
for (const pathfinder of gridlessPathfinders.values()) {
|
|
||||||
GridlessPathfinding.free(pathfinder);
|
|
||||||
}
|
|
||||||
gridlessPathfinders.clear();
|
|
||||||
if (debugGraphics)
|
|
||||||
debugGraphics.removeChildren().forEach(c => c.destroy());
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Check if the current cache is still suitable for the path we're about to find. If not, clear the cache
|
|
||||||
*/
|
|
||||||
function checkCacheValid(token) {
|
|
||||||
// If levels is enabled, the cache is invalid if it was made for a
|
|
||||||
if (game.modules.get("levels")?.active) {
|
|
||||||
const tokenElevation = token.data.elevation;
|
|
||||||
if (tokenElevation !== cacheElevation) {
|
|
||||||
cacheElevation = tokenElevation;
|
|
||||||
wipePathfindingCache();
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
export function initializePathfinding() {
|
|
||||||
gridWidth = Math.ceil(canvas.dimensions.width / canvas.grid.w);
|
|
||||||
gridHeight = Math.ceil(canvas.dimensions.height / canvas.grid.h);
|
|
||||||
}
|
|
||||||
|
|
||||||
function paintGriddedPathfindingDebug(lastNode, token) {
|
function paintGriddedPathfindingDebug(lastNode, token) {
|
||||||
if (!CONFIG.debug.dragRuler)
|
if (!CONFIG.debug.dragRuler)
|
||||||
return;
|
return;
|
||||||
|
|||||||
+1
-5
@@ -10,10 +10,6 @@ export const RightClickAction = Object.freeze({
|
|||||||
ABORT_DRAG:2,
|
ABORT_DRAG:2,
|
||||||
});
|
});
|
||||||
|
|
||||||
function delayedReload() {
|
|
||||||
window.setTimeout(() => location.reload(), 500);
|
|
||||||
}
|
|
||||||
|
|
||||||
export function registerSettings() {
|
export function registerSettings() {
|
||||||
game.settings.register(settingsKey, "dataVersion", {
|
game.settings.register(settingsKey, "dataVersion", {
|
||||||
scope: "world",
|
scope: "world",
|
||||||
@@ -94,7 +90,7 @@ export function registerSettings() {
|
|||||||
config: true,
|
config: true,
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
default: false,
|
default: false,
|
||||||
onChange: delayedReload,
|
onChange: () => location.reload(),
|
||||||
});
|
});
|
||||||
|
|
||||||
game.settings.register(settingsKey, "autoPathfinding", {
|
game.settings.register(settingsKey, "autoPathfinding", {
|
||||||
|
|||||||
+1
-3
@@ -39,7 +39,5 @@ export function recalculate(tokens) {
|
|||||||
}
|
}
|
||||||
|
|
||||||
function _socketRecalculate(tokenIds) {
|
function _socketRecalculate(tokenIds) {
|
||||||
const ruler = canvas.controls.ruler;
|
return canvas.controls.ruler.dragRulerRecalculate(tokenIds);
|
||||||
if (ruler.isDragRuler)
|
|
||||||
ruler.dragRulerRecalculate(tokenIds);
|
|
||||||
}
|
}
|
||||||
|
|||||||
+5
-8
@@ -4,15 +4,13 @@ export function getDefaultSpeedAttribute() {
|
|||||||
return "actor.data.data.attribs.mov.value";
|
return "actor.data.data.attribs.mov.value";
|
||||||
case "dcc":
|
case "dcc":
|
||||||
return "actor.data.data.attributes.speed.value";
|
return "actor.data.data.attributes.speed.value";
|
||||||
case "dnd4e":
|
|
||||||
return "actor.data.data.movement.walk.value";
|
|
||||||
case "dnd5e":
|
case "dnd5e":
|
||||||
return "actor.data.data.attributes.movement.walk";
|
return "actor.data.data.attributes.movement.walk"
|
||||||
case "lancer":
|
case "lancer":
|
||||||
return "actor.data.data.derived.speed";
|
return "actor.data.data.derived.speed"
|
||||||
case "pf1":
|
case "pf1":
|
||||||
case "D35E":
|
case "D35E":
|
||||||
return "actor.data.data.attributes.speed.land.total";
|
return "actor.data.data.attributes.speed.land.total"
|
||||||
case "sfrpg":
|
case "sfrpg":
|
||||||
return "actor.data.data.attributes.speed.value";
|
return "actor.data.data.attributes.speed.value";
|
||||||
case "shadowrun5e":
|
case "shadowrun5e":
|
||||||
@@ -30,7 +28,6 @@ export function getDefaultDashMultiplier() {
|
|||||||
case "swade":
|
case "swade":
|
||||||
return 0
|
return 0
|
||||||
case "dcc":
|
case "dcc":
|
||||||
case "dnd4e":
|
|
||||||
case "dnd5e":
|
case "dnd5e":
|
||||||
case "lancer":
|
case "lancer":
|
||||||
case "pf1":
|
case "pf1":
|
||||||
@@ -38,9 +35,9 @@ export function getDefaultDashMultiplier() {
|
|||||||
case "sfrpg":
|
case "sfrpg":
|
||||||
case "shadowrun5e":
|
case "shadowrun5e":
|
||||||
case "ds4":
|
case "ds4":
|
||||||
return 2;
|
return 2
|
||||||
case "CoC7":
|
case "CoC7":
|
||||||
return 5;
|
return 5;
|
||||||
}
|
}
|
||||||
return 0;
|
return 0
|
||||||
}
|
}
|
||||||
|
|||||||
+2
-2
@@ -2,7 +2,7 @@
|
|||||||
"name": "drag-ruler",
|
"name": "drag-ruler",
|
||||||
"title": "Drag Ruler",
|
"title": "Drag Ruler",
|
||||||
"description": "When dragging a token displays a ruler showing how far you've moved that token.",
|
"description": "When dragging a token displays a ruler showing how far you've moved that token.",
|
||||||
"version": "1.12.3",
|
"version": "1.11.5",
|
||||||
"minimumCoreVersion" : "9.245",
|
"minimumCoreVersion" : "9.245",
|
||||||
"compatibleCoreVersion" : "9",
|
"compatibleCoreVersion" : "9",
|
||||||
"authors": [
|
"authors": [
|
||||||
@@ -65,7 +65,7 @@
|
|||||||
],
|
],
|
||||||
"socket": true,
|
"socket": true,
|
||||||
"url": "https://github.com/manuelVo/foundryvtt-drag-ruler",
|
"url": "https://github.com/manuelVo/foundryvtt-drag-ruler",
|
||||||
"download": "https://github.com/manuelVo/foundryvtt-drag-ruler/releases/download/v1.12.3/drag-ruler-1.12.3.zip",
|
"download": "https://github.com/manuelVo/foundryvtt-drag-ruler/archive/v1.11.5.zip",
|
||||||
"manifest": "https://raw.githubusercontent.com/manuelVo/foundryvtt-drag-ruler/master/module.json",
|
"manifest": "https://raw.githubusercontent.com/manuelVo/foundryvtt-drag-ruler/master/module.json",
|
||||||
"readme": "https://github.com/manuelVo/foundryvtt-drag-ruler/blob/master/README.md",
|
"readme": "https://github.com/manuelVo/foundryvtt-drag-ruler/blob/master/README.md",
|
||||||
"changelog": "https://github.com/manuelVo/foundryvtt-drag-ruler/blob/master/CHANGELOG.md",
|
"changelog": "https://github.com/manuelVo/foundryvtt-drag-ruler/blob/master/CHANGELOG.md",
|
||||||
|
|||||||
Generated
+1
-1
@@ -26,7 +26,7 @@ dependencies = [
|
|||||||
|
|
||||||
[[package]]
|
[[package]]
|
||||||
name = "gridless-pathfinding"
|
name = "gridless-pathfinding"
|
||||||
version = "1.12.3"
|
version = "0.1.0"
|
||||||
dependencies = [
|
dependencies = [
|
||||||
"console_error_panic_hook",
|
"console_error_panic_hook",
|
||||||
"js-sys",
|
"js-sys",
|
||||||
|
|||||||
+1
-1
@@ -1,6 +1,6 @@
|
|||||||
[package]
|
[package]
|
||||||
name = "gridless-pathfinding"
|
name = "gridless-pathfinding"
|
||||||
version = "1.12.3"
|
version = "0.1.0"
|
||||||
edition = "2021"
|
edition = "2021"
|
||||||
|
|
||||||
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
# See more keys and their definitions at https://doc.rust-lang.org/cargo/reference/manifest.html
|
||||||
|
|||||||
+4
-60
@@ -23,8 +23,6 @@ extern "C" {
|
|||||||
extern "C" {
|
extern "C" {
|
||||||
pub type JsWall;
|
pub type JsWall;
|
||||||
pub type JsWallData;
|
pub type JsWallData;
|
||||||
pub type JsWallFlags;
|
|
||||||
pub type JsWallHeight;
|
|
||||||
|
|
||||||
#[wasm_bindgen(method, getter)]
|
#[wasm_bindgen(method, getter)]
|
||||||
fn data(this: &JsWall) -> JsWallData;
|
fn data(this: &JsWall) -> JsWallData;
|
||||||
@@ -40,18 +38,6 @@ extern "C" {
|
|||||||
|
|
||||||
#[wasm_bindgen(method, getter, js_name = "move")]
|
#[wasm_bindgen(method, getter, js_name = "move")]
|
||||||
fn move_type(this: &JsWallData) -> WallSenseType;
|
fn move_type(this: &JsWallData) -> WallSenseType;
|
||||||
|
|
||||||
#[wasm_bindgen(method, getter)]
|
|
||||||
fn flags(this: &JsWallData) -> JsWallFlags;
|
|
||||||
|
|
||||||
#[wasm_bindgen(method, getter, js_name = "wallHeight")]
|
|
||||||
fn wall_height(this: &JsWallFlags) -> Option<JsWallHeight>;
|
|
||||||
|
|
||||||
#[wasm_bindgen(method, getter, js_name = "wallHeightTop")]
|
|
||||||
fn top(this: &JsWallHeight) -> Option<f64>;
|
|
||||||
|
|
||||||
#[wasm_bindgen(method, getter, js_name = "wallHeightBottom")]
|
|
||||||
fn bottom(this: &JsWallHeight) -> Option<f64>;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
@@ -134,38 +120,6 @@ impl TryFrom<usize> for WallSenseType {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[derive(Debug, Copy, Clone)]
|
|
||||||
pub struct WallHeight {
|
|
||||||
pub top: f64,
|
|
||||||
pub bottom: f64,
|
|
||||||
}
|
|
||||||
|
|
||||||
impl Default for WallHeight {
|
|
||||||
fn default() -> Self {
|
|
||||||
Self {
|
|
||||||
top: f64::INFINITY,
|
|
||||||
bottom: f64::NEG_INFINITY,
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl From<Option<JsWallHeight>> for WallHeight {
|
|
||||||
fn from(height: Option<JsWallHeight>) -> Self {
|
|
||||||
let height = height
|
|
||||||
.map(|height| (height.top(), height.bottom()))
|
|
||||||
.unwrap_or((None, None));
|
|
||||||
let top = height.0.unwrap_or(WallHeight::default().top);
|
|
||||||
let bottom = height.1.unwrap_or(WallHeight::default().bottom);
|
|
||||||
Self { top, bottom }
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
impl WallHeight {
|
|
||||||
pub fn contains(&self, height: f64) -> bool {
|
|
||||||
self.top >= height && self.bottom <= height
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
#[derive(Debug, Clone, Copy)]
|
#[derive(Debug, Clone, Copy)]
|
||||||
pub struct Wall {
|
pub struct Wall {
|
||||||
pub p1: Point,
|
pub p1: Point,
|
||||||
@@ -173,7 +127,6 @@ pub struct Wall {
|
|||||||
pub door_type: DoorType,
|
pub door_type: DoorType,
|
||||||
pub door_state: DoorState,
|
pub door_state: DoorState,
|
||||||
pub move_type: WallSenseType,
|
pub move_type: WallSenseType,
|
||||||
pub height: WallHeight,
|
|
||||||
}
|
}
|
||||||
|
|
||||||
impl Wall {
|
impl Wall {
|
||||||
@@ -183,7 +136,6 @@ impl Wall {
|
|||||||
door_type: DoorType,
|
door_type: DoorType,
|
||||||
door_state: DoorState,
|
door_state: DoorState,
|
||||||
move_type: WallSenseType,
|
move_type: WallSenseType,
|
||||||
height: WallHeight,
|
|
||||||
) -> Self {
|
) -> Self {
|
||||||
Self {
|
Self {
|
||||||
p1,
|
p1,
|
||||||
@@ -191,7 +143,6 @@ impl Wall {
|
|||||||
door_type,
|
door_type,
|
||||||
door_state,
|
door_state,
|
||||||
move_type,
|
move_type,
|
||||||
height,
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -205,36 +156,29 @@ impl Wall {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Wall {
|
impl Wall {
|
||||||
fn from_js(wall: &JsWall, enable_height: bool) -> Self {
|
fn from_js(wall: &JsWall) -> Self {
|
||||||
let data = wall.data();
|
let data = wall.data();
|
||||||
let mut c = data.c();
|
let mut c = data.c();
|
||||||
c.iter_mut().for_each(|val| *val = val.round());
|
c.iter_mut().for_each(|val| *val = val.round());
|
||||||
let height = if enable_height {
|
|
||||||
data.flags().wall_height().into()
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
WallHeight::default()
|
|
||||||
};
|
|
||||||
Self::new(
|
Self::new(
|
||||||
Point::new(c[0], c[1]),
|
Point::new(c[0], c[1]),
|
||||||
Point::new(c[2], c[3]),
|
Point::new(c[2], c[3]),
|
||||||
data.door_type(),
|
data.door_type(),
|
||||||
data.door_state(),
|
data.door_state(),
|
||||||
data.move_type(),
|
data.move_type(),
|
||||||
height,
|
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
#[wasm_bindgen]
|
#[wasm_bindgen]
|
||||||
pub fn initialize(js_walls: Vec<JsValue>, token_size: f64, token_elevation: f64, enable_height: bool) -> Pathfinder {
|
pub fn initialize(js_walls: Vec<JsValue>, token_size: f64) -> Pathfinder {
|
||||||
let mut walls = Vec::with_capacity(js_walls.len());
|
let mut walls = Vec::with_capacity(js_walls.len());
|
||||||
for wall in js_walls {
|
for wall in js_walls {
|
||||||
let wall = JsWall::from(wall);
|
let wall = JsWall::from(wall);
|
||||||
walls.push(Wall::from_js(&wall, enable_height));
|
walls.push(Wall::from_js(&wall));
|
||||||
}
|
}
|
||||||
Pathfinder::initialize(walls, token_size, token_elevation)
|
Pathfinder::initialize(walls, token_size)
|
||||||
}
|
}
|
||||||
|
|
||||||
#[allow(dead_code)]
|
#[allow(dead_code)]
|
||||||
|
|||||||
+22
-18
@@ -148,7 +148,7 @@ pub struct Pathfinder {
|
|||||||
}
|
}
|
||||||
|
|
||||||
impl Pathfinder {
|
impl Pathfinder {
|
||||||
pub fn initialize<I>(walls: I, token_size: f64, token_elevation: f64) -> Self
|
pub fn initialize<I>(walls: I, token_size: f64) -> Self
|
||||||
where
|
where
|
||||||
I: IntoIterator<Item = Wall>,
|
I: IntoIterator<Item = Wall>,
|
||||||
{
|
{
|
||||||
@@ -162,9 +162,6 @@ impl Pathfinder {
|
|||||||
if wall.is_door() && wall.is_open() {
|
if wall.is_door() && wall.is_open() {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
if !wall.height.contains(token_elevation) {
|
|
||||||
continue;
|
|
||||||
}
|
|
||||||
let x_diff = wall.p2.x - wall.p1.x;
|
let x_diff = wall.p2.x - wall.p1.x;
|
||||||
let y_diff = wall.p2.y - wall.p1.y;
|
let y_diff = wall.p2.y - wall.p1.y;
|
||||||
let p1_angle = y_diff.atan2(x_diff).rem_euclid(2.0 * PI);
|
let p1_angle = y_diff.atan2(x_diff).rem_euclid(2.0 * PI);
|
||||||
@@ -191,13 +188,18 @@ impl Pathfinder {
|
|||||||
if angle_diff <= PI {
|
if angle_diff <= PI {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let angle_between = angle_diff / 2.0 + angle1;
|
{
|
||||||
nodes.push(calc_pathfinding_node(
|
let angle_between = angle_diff / 2.0 + angle1;
|
||||||
point,
|
let pathfinding_node = calc_pathfinding_node(
|
||||||
angle_between,
|
point,
|
||||||
distance_from_walls,
|
angle_between,
|
||||||
&mut line_segments,
|
distance_from_walls,
|
||||||
));
|
&mut line_segments,
|
||||||
|
);
|
||||||
|
if angle_diff > 1.5 * PI {
|
||||||
|
nodes.push(pathfinding_node);
|
||||||
|
}
|
||||||
|
}
|
||||||
nodes.push(calc_pathfinding_node(
|
nodes.push(calc_pathfinding_node(
|
||||||
point,
|
point,
|
||||||
angle1 + 0.5 * PI,
|
angle1 + 0.5 * PI,
|
||||||
@@ -217,13 +219,15 @@ impl Pathfinder {
|
|||||||
if angle_diff <= PI {
|
if angle_diff <= PI {
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
let angle_between = angle_diff / 2.0 + angle1;
|
if angle_diff > 1.5 * PI {
|
||||||
nodes.push(calc_pathfinding_node(
|
let angle_between = angle_diff / 2.0 + angle1;
|
||||||
point,
|
nodes.push(calc_pathfinding_node(
|
||||||
angle_between,
|
point,
|
||||||
distance_from_walls,
|
angle_between,
|
||||||
&mut line_segments,
|
distance_from_walls,
|
||||||
));
|
&mut line_segments,
|
||||||
|
));
|
||||||
|
}
|
||||||
nodes.push(calc_pathfinding_node(
|
nodes.push(calc_pathfinding_node(
|
||||||
point,
|
point,
|
||||||
angle1 + 0.5 * PI,
|
angle1 + 0.5 * PI,
|
||||||
|
|||||||
Reference in New Issue
Block a user