From b671928ade26212653d44c635f79d6f1235bbad3 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Manuel=20V=C3=B6gele?= Date: Mon, 8 Feb 2021 14:41:39 +0100 Subject: [PATCH] Disable grid snapping while pressing shift (fixes #9) --- src/foundry_imports.js | 28 +++++++++++++++++----------- src/main.js | 26 +++++++++++++++++++------- 2 files changed, 36 insertions(+), 18 deletions(-) diff --git a/src/foundry_imports.js b/src/foundry_imports.js index 422c0f4..7347fa2 100644 --- a/src/foundry_imports.js +++ b/src/foundry_imports.js @@ -1,12 +1,11 @@ // This is a modified version of Ruler.moveToken from foundry 0.7.9 -export async function moveTokens(selectedTokens) { +export async function moveTokens(draggedToken, selectedTokens) { let wasPaused = game.paused; if (wasPaused && !game.user.isGM) { ui.notifications.warn(game.i18n.localize("GAME.PausedWarning")); return false; } if (!this.visible || !this.destination) return false; - const draggedToken = this._getMovementToken(); if (!draggedToken) return; // Get the movement rays and check collision along each Ray @@ -44,22 +43,21 @@ async function animateToken(token, rays, tokenOffset, wasPaused) { // Determine offset relative to the Token top-left. // This is important so we can position the token relative to the ruler origin for non-1x1 tokens. - origin = canvas.grid.getTopLeft(this.waypoints[0].x + tokenOffset.x, this.waypoints[0].y + tokenOffset.y); + const origin = [this.waypoints[0].x + tokenOffset.x, this.waypoints[0].y + tokenOffset.y] let dx, dy if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS) { dx = token.data.x - origin[0] dy = token.data.y - origin[1] } else { - const s2 = canvas.dimensions.size / 2; - dx = Math.round((token.data.x - origin[0]) / s2) * s2; - dy = Math.round((token.data.y - origin[1]) / s2) * s2; + dx = token.data.x - origin[0] + dy = token.data.y - origin[1] } token._noAnimate = true; for (let r of offsetRays) { if (!wasPaused && game.paused) break; - const dest = canvas.grid.getTopLeft(r.B.x, r.B.y); + const dest = [r.B.x, r.B.y]; const path = new Ray({ x: token.x, y: token.y }, { x: dest[0] + dx, y: dest[1] + dy }); await token.update(path.B); await token.animateMovement(path); @@ -90,36 +88,44 @@ export function onMouseMove(event) { // Draw measurement updates if (Date.now() - mt > 50) { - this.measure(destination, { gridSpaces: !originalEvent.shiftKey }); + this.measure(destination, {snap: !originalEvent.shiftKey}); event._measureTime = Date.now(); this._state = Ruler.STATES.MEASURING; } } // This is a modified version of Ruler.measure form foundry 0.7.9 -export function measure(destination, {gridSpaces=true} = {}) { +export function measure(destination, {gridSpaces=true, snap=false} = {}) { if (this.isDragRuler && !this.draggedToken.isVisible) return [] - destination = new PIXI.Point(...canvas.grid.getCenter(destination.x, destination.y)); + + if (snap) + destination = new PIXI.Point(...canvas.grid.getCenter(destination.x, destination.y)); const waypoints = this.waypoints.concat([destination]); + const centeredWaypoints = waypoints.map(w => new PIXI.Point(...canvas.grid.getCenter(w.x, w.y))) const r = this.ruler; this.destination = destination; // Iterate over waypoints and construct segment rays const segments = []; + const centeredSegments = [] for (let [i, dest] of waypoints.slice(1).entries()) { + const centeredDest = centeredWaypoints[i + 1] const origin = waypoints[i]; + const centeredOrigin = centeredWaypoints[i] const label = this.labels.children[i]; const ray = new Ray(origin, dest); + const centeredRay = new Ray(centeredOrigin, centeredDest) if (ray.distance < 10) { if (label) label.visible = false; continue; } segments.push({ ray, label }); + centeredSegments.push({ray: centeredRay, label}) } // Compute measured distance - const distances = canvas.grid.measureDistances(segments, { gridSpaces }); + const distances = canvas.grid.measureDistances(centeredSegments, { gridSpaces }); let totalDistance = 0; for (let [i, d] of distances.entries()) { let s = segments[i]; diff --git a/src/main.js b/src/main.js index 880f0a4..4075e1f 100644 --- a/src/main.js +++ b/src/main.js @@ -102,11 +102,11 @@ function hookRulerFunctions() { function onTokenLeftDragStart(event) { canvas.controls.ruler.draggedToken = this - const tokenCenter = {x: this.x + canvas.grid.size / 2, y: this.y + canvas.grid.size / 2} + const tokenCenter = {x: this.x + canvas.grid.grid.w / 2, y: this.y + canvas.grid.grid.h / 2} canvas.controls.ruler.clear(); canvas.controls.ruler._state = Ruler.STATES.STARTING; canvas.controls.ruler.rulerOffset = {x: tokenCenter.x - event.data.origin.x, y: tokenCenter.y - event.data.origin.y} - canvas.controls.ruler._addWaypoint(tokenCenter); + addWaypoint.call(canvas.controls.ruler, tokenCenter, false); } function onTokenLeftDragMove(event) { @@ -117,9 +117,9 @@ function onTokenLeftDragMove(event) { function onTokenDragLeftDrop(event) { if (!canvas.controls.ruler.isDragRuler) return false - canvas.controls.ruler.draggedToken = null const selectedTokens = canvas.tokens.placeables.filter(token => token._controlled) - moveTokens.call(canvas.controls.ruler, selectedTokens) + moveTokens.call(canvas.controls.ruler, canvas.controls.ruler.draggedToken, selectedTokens) + canvas.controls.ruler.draggedToken = null return true } @@ -135,7 +135,8 @@ function onTokenDragLeftCancel(event) { } else { event.preventDefault() - canvas.controls.ruler._addWaypoint(canvas.controls.ruler.destination) + const snap = !event.shiftKey + addWaypoint.call(canvas.controls.ruler, canvas.controls.ruler.destination, snap) } } return true @@ -145,13 +146,24 @@ function onRulerMoveToken(event) { // This function is invoked by left clicking if (!this.isDragRuler) return false - if (!game.settings.get(settingsKey, "swapSpacebarRightClick")) - this._addWaypoint(this.destination) + if (!game.settings.get(settingsKey, "swapSpacebarRightClick")) { + const snap = !event.shiftKey + addWaypoint.call(this, this.destination, snap) + } else deleteWaypoint() return true } +function addWaypoint(point, snap=true) { + if (snap) + point = canvas.grid.getCenter(point.x, point.y); + else + point = [point.x, point.y] + this.waypoints.push(new PIXI.Point(point[0], point[1])); + this.labels.addChild(new PreciseText("", CONFIG.canvasTextStyle)); +} + function deleteWaypoint() { if (canvas.controls.ruler.waypoints.length > 1) { const mousePosition = canvas.app.renderer.plugins.interaction.mouse.getLocalPosition(canvas.tokens)