Compare commits
8 Commits
| Author | SHA1 | Date | |
|---|---|---|---|
| 9d5dccb504 | |||
| a252da620a | |||
| 41c8979925 | |||
| 39f9204fa7 | |||
| 10633e4e2a | |||
| f3e1492edd | |||
| 7ac1c828b6 | |||
| 1972498b05 |
@@ -0,0 +1 @@
|
|||||||
|
foundry-*.js
|
||||||
@@ -1,3 +1,19 @@
|
|||||||
|
## 1.11.2
|
||||||
|
### Bugfixes
|
||||||
|
- Fixed a memory leak that could cause the rule to slow down after using the pathfinding functionality for a while
|
||||||
|
|
||||||
|
### Misc
|
||||||
|
- GMs are now always allowed to use the pathfinding tool. The setting now only prevents players from using it.
|
||||||
|
|
||||||
|
### Compatibility
|
||||||
|
- Drag Ruler's generic speed provider is now aware of good defaults for Dungeonslayers 4
|
||||||
|
|
||||||
|
|
||||||
|
## 1.11.1
|
||||||
|
### Bugfixes
|
||||||
|
- Fixed a bug that would cause the pathfinding algorithm to make tokens of size 2 and 4 to take an unnecessary step
|
||||||
|
|
||||||
|
|
||||||
## 1.11.0
|
## 1.11.0
|
||||||
### New features
|
### New features
|
||||||
- Drag Ruler now supports pathfinding. Pressing the assigned button will automatically calculate the shortest route to the point you're dragging your token to and add the necessary waypoints to the ruler.
|
- Drag Ruler now supports pathfinding. Pressing the assigned button will automatically calculate the shortest route to the point you're dragging your token to and add the necessary waypoints to the ruler.
|
||||||
|
|||||||
+2
-2
@@ -48,8 +48,8 @@
|
|||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"allowPathfinding": {
|
"allowPathfinding": {
|
||||||
"name": "Wegfindung aktivieren",
|
"name": "Wegfindung für Spieler erlauben",
|
||||||
"hint": "Aktiviert Drag Ruler's Wegfindungsfunktion. Bitte beachte, dass die Wegfindung Wege durch unerkundeten Nebel des Kriegs und Ätherische Wände berechnen kann. Dies kann deinen Spielern Geheimnisse lüften, von denen sie noch nicht erfahren sollten."
|
"hint": "Erlaubt es Spielern die Wegfindungs zu benutzen. Bitte beachte, dass die Wegfindung Wege durch unerkundeten Nebel des Kriegs und Ätherische Wände berechnen kann. Dies kann deinen Spielern Geheimnisse lüften, von denen sie noch nicht erfahren sollten."
|
||||||
},
|
},
|
||||||
"alwaysShowSpeedForPCs": {
|
"alwaysShowSpeedForPCs": {
|
||||||
"name": "Geschwindigkeit von Spielercharakteren für jeden anzeigen",
|
"name": "Geschwindigkeit von Spielercharakteren für jeden anzeigen",
|
||||||
|
|||||||
+2
-2
@@ -48,8 +48,8 @@
|
|||||||
},
|
},
|
||||||
"settings": {
|
"settings": {
|
||||||
"allowPathfinding": {
|
"allowPathfinding": {
|
||||||
"name": "Enable pathfinding feature",
|
"name": "Allow pathfinding for players",
|
||||||
"hint": "Enables Drag Ruler's pathfinding functionality in this world. Be aware that pathfinding can route through unexplored fog of war and Ethereal Walls, which might reveal secrets to your players ahead of time."
|
"hint": "Allows players to use Drag Ruler's pathfinding functionality in this world. Be aware that pathfinding can route through unexplored fog of war and Ethereal Walls, which might reveal secrets to your players ahead of time."
|
||||||
},
|
},
|
||||||
"alwaysShowSpeedForPCs": {
|
"alwaysShowSpeedForPCs": {
|
||||||
"name": "Show PC speed to everyone",
|
"name": "Show PC speed to everyone",
|
||||||
|
|||||||
+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.11.0",
|
"version": "1.11.2",
|
||||||
"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/archive/v1.11.0.zip",
|
"download": "https://github.com/manuelVo/foundryvtt-drag-ruler/archive/v1.11.2.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",
|
||||||
|
|||||||
@@ -1,12 +1,12 @@
|
|||||||
import {highlightMeasurementTerrainRuler, measureDistances} from "./compatibility.js";
|
import {highlightMeasurementTerrainRuler, measureDistances} from "./compatibility.js";
|
||||||
import {getCenterFromGridPositionObj, getGridPositionFromPixels, getGridPositionFromPixelsObj} from "./foundry_fixes.js";
|
import {getGridPositionFromPixels, getGridPositionFromPixelsObj, getPixelsFromGridPositionObj} from "./foundry_fixes.js";
|
||||||
import {Line} from "./geometry.js";
|
import {Line} from "./geometry.js";
|
||||||
import {disableSnap, moveWithoutAnimation} from "./keybindings.js";
|
import {disableSnap, moveWithoutAnimation} from "./keybindings.js";
|
||||||
import {trackRays} from "./movement_tracking.js"
|
import {trackRays} from "./movement_tracking.js"
|
||||||
import {findPath, isPathfindingEnabled} from "./pathfinding.js";
|
import {findPath, isPathfindingEnabled} from "./pathfinding.js";
|
||||||
import {settingsKey} from "./settings.js";
|
import {settingsKey} from "./settings.js";
|
||||||
import {recalculate} from "./socket.js";
|
import {recalculate} from "./socket.js";
|
||||||
import {applyTokenSizeOffset, enumeratedZip, getSnapPointForEntity, getSnapPointForToken, getTokenShape, highlightTokenShape, sum} from "./util.js";
|
import {applyTokenSizeOffset, enumeratedZip, getSnapPointForEntity, getSnapPointForToken, getSnapPointForTokenObj, getTokenShape, highlightTokenShape, sum} from "./util.js";
|
||||||
|
|
||||||
// This is a modified version of Ruler.moveToken from foundry 0.7.9
|
// This is a modified version of Ruler.moveToken from foundry 0.7.9
|
||||||
export async function moveEntities(draggedEntity, selectedEntities) {
|
export async function moveEntities(draggedEntity, selectedEntities) {
|
||||||
@@ -169,9 +169,11 @@ export function measure(destination, options={}) {
|
|||||||
this.dragRulerRemovePathfindingWaypoints();
|
this.dragRulerRemovePathfindingWaypoints();
|
||||||
|
|
||||||
if (isToken && isPathfindingEnabled()) {
|
if (isToken && isPathfindingEnabled()) {
|
||||||
let path = findPath(getGridPositionFromPixelsObj(this.waypoints[this.waypoints.length - 1]), getGridPositionFromPixelsObj(destination), this.waypoints);
|
const from = getGridPositionFromPixelsObj(this.waypoints[this.waypoints.length - 1]);
|
||||||
|
const to = getGridPositionFromPixelsObj(destination);
|
||||||
|
let path = findPath(from, to, this.draggedEntity, this.waypoints);
|
||||||
if (path) {
|
if (path) {
|
||||||
path = path.map(point => getCenterFromGridPositionObj(point))
|
path = path.map(point => getSnapPointForTokenObj(getPixelsFromGridPositionObj(point), this.draggedEntity));
|
||||||
|
|
||||||
// If the token is snapped to the grid, the first point of the path is already handled by the ruler
|
// If the token is snapped to the grid, the first point of the path is already handled by the ruler
|
||||||
if (path[0].x === this.waypoints[this.waypoints.length - 1].x && path[0].y === this.waypoints[this.waypoints.length - 1].y)
|
if (path[0].x === this.waypoints[this.waypoints.length - 1].x && path[0].y === this.waypoints[this.waypoints.length - 1].y)
|
||||||
|
|||||||
+1
-2
@@ -52,16 +52,15 @@ export function registerKeybindings() {
|
|||||||
precedence: -1,
|
precedence: -1,
|
||||||
});
|
});
|
||||||
|
|
||||||
if (game.settings.get(settingsKey, "allowPathfinding")) {
|
|
||||||
game.keybindings.register(settingsKey, "togglePathfinding", {
|
game.keybindings.register(settingsKey, "togglePathfinding", {
|
||||||
name: "drag-ruler.keybindings.togglePathfinding.name",
|
name: "drag-ruler.keybindings.togglePathfinding.name",
|
||||||
hint: "drag-ruler.keybindings.togglePathfinding.hint",
|
hint: "drag-ruler.keybindings.togglePathfinding.hint",
|
||||||
onDown: handleTogglePathfinding,
|
onDown: handleTogglePathfinding,
|
||||||
onUp: handleTogglePathfinding,
|
onUp: handleTogglePathfinding,
|
||||||
precedence: -1,
|
precedence: -1,
|
||||||
|
restricted: !game.settings.get(settingsKey, "allowPathfinding"),
|
||||||
});
|
});
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
function handleDeleteWaypoint() {
|
function handleDeleteWaypoint() {
|
||||||
const ruler = canvas.controls.ruler;
|
const ruler = canvas.controls.ruler;
|
||||||
|
|||||||
+22
-16
@@ -1,8 +1,8 @@
|
|||||||
import {getCenterFromGridPositionObj, getGridPositionFromPixelsObj} from "./foundry_fixes.js";
|
import {getGridPositionFromPixelsObj, getPixelsFromGridPositionObj} from "./foundry_fixes.js";
|
||||||
import {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 {iterPairs} from "./util.js";
|
import {getSnapPointForTokenObj, iterPairs} from "./util.js";
|
||||||
|
|
||||||
let cachedNodes = undefined;
|
let cachedNodes = undefined;
|
||||||
let use5105 = false;
|
let use5105 = false;
|
||||||
@@ -10,21 +10,21 @@ let use5105 = false;
|
|||||||
export function isPathfindingEnabled() {
|
export function isPathfindingEnabled() {
|
||||||
if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS)
|
if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS)
|
||||||
return false;
|
return false;
|
||||||
if (!game.settings.get(settingsKey, "allowPathfinding"))
|
if (!game.user.isGM && !game.settings.get(settingsKey, "allowPathfinding"))
|
||||||
return false;
|
return false;
|
||||||
return game.settings.get(settingsKey, "autoPathfinding") != togglePathfinding;
|
return game.settings.get(settingsKey, "autoPathfinding") != togglePathfinding;
|
||||||
}
|
}
|
||||||
|
|
||||||
export function findPath(from, to, previousWaypoints) {
|
export function findPath(from, to, token, previousWaypoints) {
|
||||||
const lastNode = calculatePath(from, to, previousWaypoints);
|
const lastNode = calculatePath(from, to, token, previousWaypoints);
|
||||||
if (!lastNode)
|
if (!lastNode)
|
||||||
return null;
|
return null;
|
||||||
paintPathfindingDebug(lastNode);
|
paintPathfindingDebug(lastNode, token);
|
||||||
const path = [];
|
const path = [];
|
||||||
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 && !canvas.walls.checkCollision(new Ray(getCenterFromGridPositionObj(currentNode.node), getCenterFromGridPositionObj(path[path.length - 2]))))
|
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
|
||||||
@@ -38,7 +38,7 @@ export function wipePathfindingCache() {
|
|||||||
cachedNodes = undefined;
|
cachedNodes = undefined;
|
||||||
}
|
}
|
||||||
|
|
||||||
function getNode(pos, 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)
|
||||||
cachedNodes = new Array(2);
|
cachedNodes = new Array(2);
|
||||||
@@ -57,12 +57,12 @@ function getNode(pos, initialize=true) {
|
|||||||
if (neighborPos.x < 0 || neighborPos.y < 0)
|
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 (!canvas.walls.checkCollision(new Ray(getCenterFromGridPositionObj(pos), getCenterFromGridPositionObj(neighborPos)))) {
|
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)
|
||||||
targetLayer = 1 - targetLayer;
|
targetLayer = 1 - targetLayer;
|
||||||
const neighbor = getNode({...neighborPos, layer: targetLayer}, false);
|
const neighbor = getNode({...neighborPos, layer: targetLayer}, token, false);
|
||||||
|
|
||||||
// TODO We currently assume a cost of one or two for all transitions. Change this for difficult terrain support
|
// TODO We currently assume a cost of one or two for all transitions. Change this for difficult terrain support
|
||||||
let edgeCost = 1;
|
let edgeCost = 1;
|
||||||
@@ -77,17 +77,17 @@ function getNode(pos, initialize=true) {
|
|||||||
return node;
|
return node;
|
||||||
}
|
}
|
||||||
|
|
||||||
function calculatePath(from, to, previousWaypoints) {
|
function calculatePath(from, to, token, previousWaypoints) {
|
||||||
if (game.system.id === "pf2e")
|
if (game.system.id === "pf2e")
|
||||||
use5105 = true;
|
use5105 = true;
|
||||||
if (canvas.grid.diagonalRule === "5105")
|
if (canvas.grid.diagonalRule === "5105")
|
||||||
use5105 = true;
|
use5105 = true;
|
||||||
let startLayer = 0;
|
let startLayer = 0;
|
||||||
if (use5105) {
|
if (use5105 && canvas.grid.type === CONST.GRID_TYPES.SQUARE) {
|
||||||
previousWaypoints = previousWaypoints.map(w => getGridPositionFromPixelsObj(w));
|
previousWaypoints = previousWaypoints.map(w => getGridPositionFromPixelsObj(w));
|
||||||
startLayer = calcNoDiagonals(previousWaypoints) % 2;
|
startLayer = calcNoDiagonals(previousWaypoints) % 2;
|
||||||
}
|
}
|
||||||
const nextNodes = [{node: getNode({...to, layer: startLayer}), cost: 0, estimated: estimateCost(to, from), previous: null}];
|
const nextNodes = [{node: getNode({...to, layer: startLayer}, token), cost: 0, estimated: estimateCost(to, from), previous: null}];
|
||||||
const previousNodes = new Set();
|
const previousNodes = new Set();
|
||||||
while (nextNodes.length > 0) {
|
while (nextNodes.length > 0) {
|
||||||
// Sort by estimated cost, high to low
|
// Sort by estimated cost, high to low
|
||||||
@@ -99,7 +99,7 @@ function calculatePath(from, to, previousWaypoints) {
|
|||||||
return currentNode;
|
return currentNode;
|
||||||
previousNodes.add(currentNode.node);
|
previousNodes.add(currentNode.node);
|
||||||
for (const edge of currentNode.node.edges) {
|
for (const edge of currentNode.node.edges) {
|
||||||
const neighborNode = getNode(edge.target);
|
const neighborNode = getNode(edge.target, token);
|
||||||
if (previousNodes.has(neighborNode))
|
if (previousNodes.has(neighborNode))
|
||||||
continue;
|
continue;
|
||||||
const neighbor = {node: neighborNode, cost: currentNode.cost + edge.cost, estimated: currentNode.cost + edge.cost + estimateCost(neighborNode, from), previous: currentNode};
|
const neighbor = {node: neighborNode, cost: currentNode.cost + edge.cost, estimated: currentNode.cost + edge.cost + estimateCost(neighborNode, from), previous: currentNode};
|
||||||
@@ -129,7 +129,13 @@ function estimateCost(pos, target) {
|
|||||||
return Math.max(Math.abs(pos.x - target.x), Math.abs(pos.y - target.y));
|
return Math.max(Math.abs(pos.x - target.x), Math.abs(pos.y - target.y));
|
||||||
}
|
}
|
||||||
|
|
||||||
function paintPathfindingDebug(lastNode) {
|
function stepCollidesWithWall(from, to, token) {
|
||||||
|
const stepStart = getSnapPointForTokenObj(getPixelsFromGridPositionObj(from), token);
|
||||||
|
const stepEnd = getSnapPointForTokenObj(getPixelsFromGridPositionObj(to), token);
|
||||||
|
return canvas.walls.checkCollision(new Ray(stepStart, stepEnd));
|
||||||
|
}
|
||||||
|
|
||||||
|
function paintPathfindingDebug(lastNode, token) {
|
||||||
if (!CONFIG.debug.dragRuler)
|
if (!CONFIG.debug.dragRuler)
|
||||||
return;
|
return;
|
||||||
|
|
||||||
@@ -137,7 +143,7 @@ function paintPathfindingDebug(lastNode) {
|
|||||||
let currentNode = lastNode;
|
let currentNode = lastNode;
|
||||||
while (currentNode) {
|
while (currentNode) {
|
||||||
let text = new PIXI.Text(currentNode.cost.toFixed(0));
|
let text = new PIXI.Text(currentNode.cost.toFixed(0));
|
||||||
let pixels = getCenterFromGridPositionObj(currentNode.node);
|
let pixels = getSnapPointForTokenObj(getPixelsFromGridPositionObj(currentNode.node), token);
|
||||||
text.anchor.set(0.5, 1.0);
|
text.anchor.set(0.5, 1.0);
|
||||||
text.x = pixels.x;
|
text.x = pixels.x;
|
||||||
text.y = pixels.y;
|
text.y = pixels.y;
|
||||||
|
|||||||
+1
-1
@@ -116,7 +116,7 @@ export function extendRuler() {
|
|||||||
}
|
}
|
||||||
|
|
||||||
dragRulerRemovePathfindingWaypoints() {
|
dragRulerRemovePathfindingWaypoints() {
|
||||||
this.waypoints.filter(waypoint => waypoint.isPathfinding).forEach(_ => this.labels.removeChild(this.labels.children.pop()));
|
this.waypoints.filter(waypoint => waypoint.isPathfinding).forEach(_ => this.labels.removeChild(this.labels.children[this.labels.children.length - 1]).destroy());
|
||||||
this.waypoints = this.waypoints.filter(waypoint => !waypoint.isPathfinding);
|
this.waypoints = this.waypoints.filter(waypoint => !waypoint.isPathfinding);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+2
-1
@@ -1,5 +1,6 @@
|
|||||||
import {availableSpeedProviders, currentSpeedProvider, getDefaultSpeedProvider, updateSpeedProvider} from "./api.js";
|
import {availableSpeedProviders, currentSpeedProvider, getDefaultSpeedProvider, updateSpeedProvider} from "./api.js";
|
||||||
import {SpeedProvider} from "./speed_provider.js"
|
import {SpeedProvider} from "./speed_provider.js"
|
||||||
|
import { early_isGM } from "./util.js";
|
||||||
|
|
||||||
export const settingsKey = "drag-ruler";
|
export const settingsKey = "drag-ruler";
|
||||||
|
|
||||||
@@ -96,7 +97,7 @@ export function registerSettings() {
|
|||||||
name: "drag-ruler.settings.autoPathfinding.name",
|
name: "drag-ruler.settings.autoPathfinding.name",
|
||||||
hint: "drag-ruler.settings.autoPathfinding.hint",
|
hint: "drag-ruler.settings.autoPathfinding.hint",
|
||||||
scpoe: "client",
|
scpoe: "client",
|
||||||
config: true,
|
config: early_isGM(),
|
||||||
type: Boolean,
|
type: Boolean,
|
||||||
defualt: false,
|
defualt: false,
|
||||||
});
|
});
|
||||||
|
|||||||
@@ -17,6 +17,8 @@ export function getDefaultSpeedAttribute() {
|
|||||||
return "actor.data.data.movement.walk.value";
|
return "actor.data.data.movement.walk.value";
|
||||||
case "swade":
|
case "swade":
|
||||||
return "actor.data.data.stats.speed.adjusted";
|
return "actor.data.data.stats.speed.adjusted";
|
||||||
|
case "ds4":
|
||||||
|
return "actor.data.data.combatValues.movement.total";
|
||||||
}
|
}
|
||||||
return ""
|
return ""
|
||||||
}
|
}
|
||||||
@@ -32,6 +34,7 @@ export function getDefaultDashMultiplier() {
|
|||||||
case "D35E":
|
case "D35E":
|
||||||
case "sfrpg":
|
case "sfrpg":
|
||||||
case "shadowrun5e":
|
case "shadowrun5e":
|
||||||
|
case "ds4":
|
||||||
return 2
|
return 2
|
||||||
case "CoC7":
|
case "CoC7":
|
||||||
return 5;
|
return 5;
|
||||||
|
|||||||
+11
@@ -86,6 +86,10 @@ export function getSnapPointForToken(x, y, token) {
|
|||||||
return new PIXI.Point(snapX, snapY);
|
return new PIXI.Point(snapX, snapY);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
export function getSnapPointForTokenObj(pos, token) {
|
||||||
|
return getSnapPointForToken(pos.x, pos.y, token);
|
||||||
|
}
|
||||||
|
|
||||||
export function getSnapPointForMeasuredTemplate(x, y) {
|
export function getSnapPointForMeasuredTemplate(x, y) {
|
||||||
if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS) {
|
if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS) {
|
||||||
return new PIXI.Point(x, y);
|
return new PIXI.Point(x, y);
|
||||||
@@ -268,3 +272,10 @@ export function getMeasurePosition() {
|
|||||||
const measurePosition = {x: mousePosition.x + rulerOffset.x, y: mousePosition.y + rulerOffset.y};
|
const measurePosition = {x: mousePosition.x + rulerOffset.x, y: mousePosition.y + rulerOffset.y};
|
||||||
return measurePosition;
|
return measurePosition;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// isGM function for use during loading when game.user isn't available yet
|
||||||
|
export function early_isGM() {
|
||||||
|
const level = game.data.users.find(u => u._id == game.data.userId).role;
|
||||||
|
const gmLevel = CONST.USER_ROLES.ASSISTANT;
|
||||||
|
return level >= gmLevel;
|
||||||
|
}
|
||||||
|
|||||||
Reference in New Issue
Block a user