From 0808f17ee34de2047f9fadf6ac695083d182d4d9 Mon Sep 17 00:00:00 2001 From: Nils Date: Thu, 11 Jul 2024 02:47:20 +0200 Subject: [PATCH] Update foundry for v12 --- module.json | 2 +- src/compatibility.js | 4 ++-- src/foundry_imports.js | 6 +++++- src/ruler.js | 42 ++++++++++++++++++++++++++++++------------ src/settings.js | 2 +- src/speed_provider.js | 2 +- src/util.js | 16 +++++++++++----- 7 files changed, 51 insertions(+), 23 deletions(-) diff --git a/module.json b/module.json index 2874e3c..98d3445 100644 --- a/module.json +++ b/module.json @@ -5,7 +5,7 @@ "version": "1.13.8", "compatibility": { "minimum": "11", - "verified": "11" + "verified": "12" }, "authors": [ { diff --git a/src/compatibility.js b/src/compatibility.js index f542ed8..cc58f56 100644 --- a/src/compatibility.js +++ b/src/compatibility.js @@ -15,7 +15,7 @@ export function highlightMeasurementTerrainRuler( } export function measureDistances(segments, entity, shape, options = {}) { - const opts = duplicate(options); + const opts = foundry.utils.duplicate(options); if (canvas.grid.diagonalRule === "EUCL") { opts.ignoreGrid = true; opts.gridSpaces = false; @@ -31,7 +31,7 @@ export function measureDistances(segments, entity, shape, options = {}) { ); previousSegments.forEach( segment => - (segment.ray.terrainRulerVisitedSpaces = duplicate(segment.ray.dragRulerVisitedSpaces)), + (segment.ray.terrainRulerVisitedSpaces = foundry.utils.duplicate(segment.ray.dragRulerVisitedSpaces)), ); opts.costFunction = buildCostFunction(entity, shape); if (previousSegments.length > 0) diff --git a/src/foundry_imports.js b/src/foundry_imports.js index f889073..568fd52 100644 --- a/src/foundry_imports.js +++ b/src/foundry_imports.js @@ -36,6 +36,7 @@ export async function moveEntities(draggedEntity, selectedEntities) { }); if (hasCollision) { ui.notifications.error(game.i18n.localize("RULER.MovementCollision")); + this._state = Ruler.STATES.MEASURING; this._endMeasurement(); return true; } @@ -47,7 +48,10 @@ export async function moveEntities(draggedEntity, selectedEntities) { await animateEntities.call(this, selectedEntities, draggedEntity, rays, wasPaused); // Once all animations are complete we can clear the ruler - if (this.draggedEntity?.id === draggedEntity.id) this._endMeasurement(); + if (this.draggedEntity?.id === draggedEntity.id) { + this._state = Ruler.STATES.MEASURING; + this._endMeasurement(); + } } // This is a modified version code extracted from Ruler.moveToken from foundry 0.7.9 diff --git a/src/ruler.js b/src/ruler.js index 02a417c..02dd94c 100644 --- a/src/ruler.js +++ b/src/ruler.js @@ -41,14 +41,14 @@ export function extendRuler() { if (!this.isDragRuler) return await super.moveToken(event); } - toJSON() { - const json = super.toJSON(); + _getMeasurementData() { + const json = typeof super._getMeasurementData === 'function' ? super._getMeasurementData() : super.toJSON(); if (this.draggedEntity) { const isToken = this.draggedEntity instanceof Token; json.draggedEntityIsToken = isToken; json.draggedEntity = this.draggedEntity.id; json.waypoints = json.waypoints.map(old => { - let w = duplicate(old); + let w = foundry.utils.duplicate(old); w.isPathfinding = undefined; return w; }); @@ -56,7 +56,13 @@ export function extendRuler() { return json; } + /** @deprecated since V12 */ + toJSON() { + return this._getMeasurementData(); + } + update(data) { + if ( !data || (data.state === Ruler.STATES.INACTIVE) ) return this.clear(); // Don't show a GMs drag ruler to non GM players if ( data.draggedEntity && @@ -105,7 +111,10 @@ export function extendRuler() { // Compute the measurement destination, segments, and distance const d = this._getMeasurementDestination(destination); - if (d.x === this.destination.x && d.y === this.destination.y) return; + if ( this.destination && (d.x === this.destination.x) && (d.y === this.destination.y)) { + this.performPostPathfindingActions(options); + return; + } this.destination = d; // TODO Check if we can reuse the old path @@ -206,6 +215,7 @@ export function extendRuler() { } } } + this.dragRulerSendState(); return this.segments; } @@ -227,7 +237,7 @@ export function extendRuler() { const waypoints = this.draggedEntity instanceof Token ? applyTokenSizeOffset(unsnappedWaypoints, this.draggedEntity) - : duplicate(unsnappedWaypoints); + : foundry.utils.duplicate(unsnappedWaypoints); const unsnappedSegments = []; const segments = []; for (const [i, p1] of waypoints.entries()) { @@ -252,6 +262,9 @@ export function extendRuler() { unsnappedSegments.push({ray: unsnappedRay, label}); } this.dragRulerUnsnappedSegments = unsnappedSegments; + if ( this.labels.children.length > segments.length ) { + this.labels.removeChildren(segments.length).forEach(c => c.destroy()); + } return segments; } else { return super._getMeasurementSegments(); @@ -269,14 +282,16 @@ export function extendRuler() { enableTerrainRuler: this.dragRulerEnableTerrainRuler, }; const distances = measureDistances(this.segments, this.draggedEntity, shape, options); - let totalDistance = 0; + this.totalDistance = 0; for (const [i, d] of distances.entries()) { let s = this.segments[i]; - s.startDistance = totalDistance; - totalDistance += d; + s.startDistance = this.totalDistance; + this.totalDistance += d; s.last = i === this.segments.length - 1; s.distance = d; - s.text = this._getSegmentLabel(s, totalDistance); + // V11 and lower use totalDistance as a second arg + // V12 ignores the 2nd argument and uses this.totalDistance + s.text = this._getSegmentLabel(s, this.totalDistance); } for (const [i, segment] of this.segments.entries()) { @@ -383,7 +398,7 @@ export function extendRuler() { {x: mousePosition.x + rulerOffset.x, y: mousePosition.y + rulerOffset.y}, options, ); - game.user.broadcastActivity({ruler: this}); + this.performPostPathfindingActions(options); } else { this.dragRulerAbortDrag(event); } @@ -428,7 +443,7 @@ export function extendRuler() { this.dragRulerAddWaypoint(waypoint, {snap: false}); } this.measure(this.destination); - game.user.broadcastActivity({ruler: this}); + this.dragRulerSendState(); } static dragRulerGetRaysFromWaypoints(waypoints, destination) { @@ -485,8 +500,11 @@ export function extendRuler() { } dragRulerSendState() { + if (this.user !== game.user) { + return; + } game.user.broadcastActivity({ - ruler: this.toJSON(), + ruler: this._getMeasurementData(), }); } } diff --git a/src/settings.js b/src/settings.js index 160b06e..2cda541 100644 --- a/src/settings.js +++ b/src/settings.js @@ -298,7 +298,7 @@ function enumerateProviderSettings(provider) { for (const setting of provider.settings) { try { if (setting.scope === "world" && !game.user.isGM) continue; - const s = duplicate(setting); + const s = foundry.utils.duplicate(setting); s.id = `${provider.id}.setting.${s.id}`; s.name = game.i18n.localize(s.name); s.hint = game.i18n.localize(s.hint); diff --git a/src/speed_provider.js b/src/speed_provider.js index e2b41d7..020a86f 100644 --- a/src/speed_provider.js +++ b/src/speed_provider.js @@ -115,7 +115,7 @@ export class GenericSpeedProvider extends SpeedProvider { getRanges(token) { const speedAttribute = this.getSetting("speedAttribute"); if (!speedAttribute) return []; - const tokenSpeed = parseFloat(getProperty(token, speedAttribute)); + const tokenSpeed = parseFloat(foundry.utils.getProperty(token, speedAttribute)); if (tokenSpeed === undefined) { console.warn( `Drag Ruler (Generic Speed Provider) | The configured token speed attribute "${speedAttribute}" didn't return a speed value. To use colors based on drag distance set the setting to the correct value (or clear the box to disable this feature).`, diff --git a/src/util.js b/src/util.js index efbec63..f246437 100644 --- a/src/util.js +++ b/src/util.js @@ -37,7 +37,7 @@ export function getHexTokenSize(token) { } export function getEntityCenter(token) { - if (token instanceof Token && canvas.grid.isHex) { + if (token instanceof Token && isCanvasHex()) { const center = token.center; const size = getHexTokenSize(token); if (size % 2 === 0) { @@ -79,7 +79,7 @@ export function getSnapPointForToken(x, y, token) { return {x, y}; } - if (canvas.grid.isHex) { + if (isCanvasHex()) { const size = getHexTokenSize(token); if (size % 2 === 0) { return findVertexSnapPoint(x, y, getAltOrientationFlagForToken(token, size)); @@ -155,7 +155,7 @@ export function getAreaFromPositionAndShape(position, shape) { return shape.map(space => { let x = position.x + space.x; let y = position.y + space.y; - if (canvas.grid.isHex) { + if (isCanvasHex()) { let shiftedRow; if (canvas.grid.grid.options.even) shiftedRow = 1; else shiftedRow = 0; @@ -236,7 +236,7 @@ export function getTokenShape(token) { export function getTokenSize(token) { let w, h; - if (canvas.grid.isHex) { + if (isCanvasHex()) { w = h = getHexTokenSize(token); } else { w = token.document.width; @@ -254,7 +254,7 @@ export function applyTokenSizeOffset(waypoints, token) { const tokenSize = getTokenSize(token); const waypointOffset = {x: 0, y: 0}; - if (canvas.grid.isHex) { + if (isCanvasHex()) { const isAltOrientation = getAltOrientationFlagForToken(token, getHexTokenSize(token)); if (canvas.grid.grid.columnar) { if (tokenSize.w % 2 === 0) { @@ -324,3 +324,9 @@ export function isPathfindingEnabled() { if (moveWithoutAnimation) return false; return game.settings.get(settingsKey, "autoPathfinding") != togglePathfinding; } + +function isCanvasHex() { + // isHexagonal is introduced in V12 (undefined in V11) + // isHex is deprecated since V12 + return canvas.grid.isHexagonal ?? canvas.grid.isHex +} \ No newline at end of file