diff --git a/src/compatibility.js b/src/compatibility.js index 64b1174..2307519 100644 --- a/src/compatibility.js +++ b/src/compatibility.js @@ -2,11 +2,6 @@ import {buildCostFunction} from "./api.js"; import {settingsKey} from "./settings.js"; import {highlightTokenShape} from "./util.js"; -export function getHexSizeSupportTokenGridCenter(token) { - const tokenCenterOffset = CONFIG.hexSizeSupport.getCenterOffset(token); - return {x: token.x + tokenCenterOffset.x, y: token.y + tokenCenterOffset.y}; -} - export function highlightMeasurementTerrainRuler( ray, startDistance, diff --git a/src/hex_support.js b/src/hex_support.js index 011e39c..33451d1 100644 --- a/src/hex_support.js +++ b/src/hex_support.js @@ -10,7 +10,7 @@ */ export function findVertexSnapPoint(x, y, altOrientationFlag) { const grid = canvas.grid.grid; - if (grid.columns) { + if (grid.columnar) { return findSnapPointCols(x, y, grid.h, grid.w, altOrientationFlag); } else { return findSnapPointRows(x, y, grid.h, grid.w, altOrientationFlag); @@ -59,11 +59,11 @@ function findSnapPointCols(x, y, h, w, alt) { yOffset = -0.5; } - let xOffset1 = 0.25; - let xOffset2 = 1.0; + let xOffset1 = 0.75; + let xOffset2 = 0.0; if (alt) { - xOffset1 = 0.75; - xOffset2 = 0.0; + xOffset1 = 0.25; + xOffset2 = 1.0; } let row1 = calculateSnapPointsCols(x, y, h, w, xOffset1, 0.5 + yOffset); diff --git a/src/main.js b/src/main.js index 3f001f6..f3d23d1 100644 --- a/src/main.js +++ b/src/main.js @@ -8,7 +8,7 @@ import { registerModule, registerSystem, } from "./api.js"; -import {checkDependencies, getHexSizeSupportTokenGridCenter} from "./compatibility.js"; +import {checkDependencies} from "./compatibility.js"; import {moveEntities, onMouseMove} from "./foundry_imports.js"; import {disableSnap, registerKeybindings} from "./keybindings.js"; import {libWrapper} from "./libwrapper_shim.js"; @@ -18,7 +18,7 @@ import {extendRuler} from "./ruler.js"; import {registerSettings, RightClickAction, settingsKey} from "./settings.js"; import {recalculate} from "./socket.js"; import {SpeedProvider} from "./speed_provider.js"; -import {setSnapParameterOnOptions} from "./util.js"; +import {getEntityCenter, setSnapParameterOnOptions} from "./util.js"; CONFIG.debug.dragRuler = false; export let debugGraphics = undefined; @@ -136,15 +136,7 @@ function onEntityLeftDragStart(wrapped, event) { const isToken = this instanceof Token; const ruler = canvas.controls.ruler; ruler.draggedEntity = this; - let entityCenter; - if ( - isToken && - canvas.grid.isHex && - game.modules.get("hex-size-support")?.active && - CONFIG.hexSizeSupport.getAltSnappingFlag(this) - ) - entityCenter = getHexSizeSupportTokenGridCenter(this); - else entityCenter = this.center; + const entityCenter = getEntityCenter(this); ruler.rulerOffset = { x: entityCenter.x - event.data.origin.x, y: entityCenter.y - event.data.origin.y, diff --git a/src/ruler.js b/src/ruler.js index 1ae7f93..e6b90a1 100644 --- a/src/ruler.js +++ b/src/ruler.js @@ -3,11 +3,7 @@ import { getColorForDistanceAndToken, getRangesFromSpeedProvider, } from "./api.js"; -import { - getHexSizeSupportTokenGridCenter, - highlightMeasurementTerrainRuler, - measureDistances, -} from "./compatibility.js"; +import {highlightMeasurementTerrainRuler, measureDistances} from "./compatibility.js"; import {getGridPositionFromPixelsObj, getPixelsFromGridPositionObj} from "./foundry_fixes.js"; import {cancelScheduledMeasurement, highlightMeasurementNative} from "./foundry_imports.js"; import {disableSnap} from "./keybindings.js"; @@ -17,6 +13,7 @@ import { applyTokenSizeOffset, getSnapPointForEntity, getSnapPointForTokenObj, + getEntityCenter, getTokenShape, isPathfindingEnabled, } from "./util.js"; @@ -482,15 +479,7 @@ export function extendRuler() { const ruler = canvas.controls.ruler; ruler.clear(); ruler._state = Ruler.STATES.STARTING; - let entityCenter; - if ( - isToken && - canvas.grid.isHex && - game.modules.get("hex-size-support")?.active && - CONFIG.hexSizeSupport.getAltSnappingFlag(entity) - ) - entityCenter = getHexSizeSupportTokenGridCenter(entity); - else entityCenter = entity.center; + const entityCenter = getEntityCenter(this.draggedEntity); if (isToken && game.settings.get(settingsKey, "enableMovementHistory")) ruler.dragRulerAddWaypointHistory(getMovementHistory(entity)); ruler.dragRulerAddWaypoint(entityCenter, {snap: false}); diff --git a/src/util.js b/src/util.js index a2d53f4..eb0d88a 100644 --- a/src/util.js +++ b/src/util.js @@ -27,83 +27,99 @@ export function sum(arr) { return arr.reduce((a, b) => a + b, 0); } -export function buildSnapPointTokenData(token) { - const tokenData = { - width: token.document.width, - height: token.document.height, - }; - - if (isModuleActive("hex-size-support")) { - tokenData.hexSizeSupport = {}; - tokenData.hexSizeSupport.altSnappingFlag = CONFIG.hexSizeSupport.getAltSnappingFlag(token); - tokenData.hexSizeSupport.altOrientationFlag = - CONFIG.hexSizeSupport.getAltOrientationFlag(token); - tokenData.hexSizeSupport.borderSize = token.document.getFlag("hex-size-support", "borderSize"); +export function getHexTokenSize(token) { + const size = token.document.width; + if (token.document.height !== size) { + return 1; } - - return tokenData; + return size; } -export function getSnapPointForToken(x, y, token) { - return getSnapPointForTokenData(x, y, buildSnapPointTokenData(token)); +export function getEntityCenter(token) { + if (token instanceof Token && canvas.grid.isHex) { + const center = token.center; + const size = getHexTokenSize(token); + if (size % 2 === 0) { + let offset; + if (canvas.grid.grid.columnar) { + offset = canvas.grid.grid.w - canvas.grid.grid.h; + } else { + offset = canvas.grid.grid.h - canvas.grid.grid.w; + } + if (getAltOrientationFlagForToken(token, size)) { + offset *= -1; + } + if (canvas.grid.grid.columnar) { + center.x -= offset; + return center; + } else { + center.y -= offset; + return center; + } + } + } + return token.center; } -export function getSnapPointForTokenDataObj(pos, tokenData) { - return getSnapPointForTokenData(pos.x, pos.y, tokenData); +export function getAltOrientationFlagForToken(token, size) { + const hexSizeSupport = game.modules.get("hex-size-support").api; + if (hexSizeSupport) { + return hexSizeSupport.isAltOrientation(token); + } + // In native foundry, tokens of size 2 are oriented like the "alt orientation" from hex-size-support + // Tokens of size 4 are oriented like alt orientation wasn't set + return size === 2; } // A copy of this function lives in the librouting module -function getSnapPointForTokenData(x, y, tokenData) { +export function getSnapPointForToken(x, y, token) { if (canvas.grid.type === CONST.GRID_TYPES.GRIDLESS) { - return new PIXI.Point(x, y); + return {x, y}; } + if (canvas.grid.isHex) { - if (tokenData.hexSizeSupport?.altSnappingFlag) { - if (tokenData.hexSizeSupport.borderSize % 2 === 0) { - const snapPoint = findVertexSnapPoint(x, y, tokenData.hexSizeSupport.altOrientationFlag); - return new PIXI.Point(snapPoint.x, snapPoint.y); - } else { - return new PIXI.Point(...canvas.grid.getCenter(x, y)); - } - } else { - return new PIXI.Point(...canvas.grid.getCenter(x, y)); + const size = getHexTokenSize(token); + if (size % 2 === 0) { + return findVertexSnapPoint(x, y, getAltOrientationFlagForToken(token, size)); } + const [snapX, snapY] = canvas.grid.getCenter(x, y); + return {x: snapX, y: snapY}; } const [topLeftX, topLeftY] = canvas.grid.getTopLeft(x, y); let cellX, cellY; - if (tokenData.width % 2 === 0) cellX = x - canvas.grid.h / 2; + if (token.width % 2 === 0) cellX = x - canvas.grid.h / 2; else cellX = x; - if (tokenData.height % 2 === 0) cellY = y - canvas.grid.h / 2; + if (token.height % 2 === 0) cellY = y - canvas.grid.h / 2; else cellY = y; const [centerX, centerY] = canvas.grid.getCenter(cellX, cellY); let snapX, snapY; // Tiny tokens can snap to the cells corners - if (tokenData.width <= 0.5) { + if (token.width <= 0.5) { const offsetX = x - topLeftX; const subGridWidth = Math.floor(canvas.grid.w / 2); const subGridPosX = Math.floor(offsetX / subGridWidth); snapX = topLeftX + (subGridPosX + 0.5) * subGridWidth; } // Tokens with odd multipliers (1x1, 3x3, ...) and tokens smaller than 1x1 but bigger than 0.5x0.5 snap to the center of the grid cell - else if (Math.round(tokenData.width) % 2 === 1 || tokenData.width < 1) { + else if (Math.round(token.width) % 2 === 1 || token.width < 1) { snapX = centerX; } // All remaining tokens (those with even or fractional multipliers on square grids) snap to the intersection points of the grid else { snapX = centerX + canvas.grid.w / 2; } - if (tokenData.height <= 0.5) { + if (token.height <= 0.5) { const offsetY = y - topLeftY; const subGridHeight = Math.floor(canvas.grid.h / 2); const subGridPosY = Math.floor(offsetY / subGridHeight); snapY = topLeftY + (subGridPosY + 0.5) * subGridHeight; - } else if (Math.round(tokenData.height) % 2 === 1 || tokenData.height < 1) { + } else if (Math.round(token.height) % 2 === 1 || token.height < 1) { snapY = centerY; } else { snapY = centerY + canvas.grid.h / 2; } - return new PIXI.Point(snapX, snapY); + return {x: snapX, y: snapY}; } export function getSnapPointForTokenObj(pos, token) { @@ -141,7 +157,7 @@ export function getAreaFromPositionAndShape(position, shape) { let shiftedRow; if (canvas.grid.grid.options.even) shiftedRow = 1; else shiftedRow = 0; - if (canvas.grid.grid.options.columns) { + if (canvas.grid.grid.columnar) { if (space.x % 2 !== 0 && position.x % 2 !== shiftedRow) { y += 1; } @@ -156,66 +172,59 @@ export function getAreaFromPositionAndShape(position, shape) { } export function getTokenShape(token) { - return getTokenShapeForTokenData(buildSnapPointTokenData(token), token.scene); -} - -export function getTokenShapeForTokenData(tokenData, scene = canvas.scene) { + let scene = canvas.scene; if (scene.grid.type === CONST.GRID_TYPES.GRIDLESS) { return [{x: 0, y: 0}]; } else if (scene.grid.type === CONST.GRID_TYPES.SQUARE) { - const topOffset = -Math.floor(tokenData.height / 2); - const leftOffset = -Math.floor(tokenData.width / 2); + const topOffset = -Math.floor(token.height / 2); + const leftOffset = -Math.floor(token.width / 2); const shape = []; - for (let y = 0; y < tokenData.height; y++) { - for (let x = 0; x < tokenData.width; x++) { + for (let y = 0; y < token.height; y++) { + for (let x = 0; x < token.width; x++) { shape.push({x: x + leftOffset, y: y + topOffset}); } } return shape; } else { // Hex grids - if (game.modules.get("hex-size-support")?.active && tokenData.hexSizeSupport.altSnappingFlag) { - const borderSize = tokenData.hexSizeSupport.borderSize; - let shape = [{x: 0, y: 0}]; - if (borderSize >= 2) - shape = shape.concat([ - {x: 0, y: -1}, - {x: -1, y: -1}, - ]); - if (borderSize >= 3) - shape = shape.concat([ - {x: 0, y: 1}, - {x: -1, y: 1}, - {x: -1, y: 0}, - {x: 1, y: 0}, - ]); - if (borderSize >= 4) - shape = shape.concat([ - {x: -2, y: -1}, - {x: 1, y: -1}, - {x: -1, y: -2}, - {x: 0, y: -2}, - {x: 1, y: -2}, - ]); + const size = getHexTokenSize(token); + let shape = [{x: 0, y: 0}]; + if (size >= 2) + shape = shape.concat([ + {x: 0, y: -1}, + {x: -1, y: -1}, + ]); + if (size >= 3) + shape = shape.concat([ + {x: 0, y: 1}, + {x: -1, y: 1}, + {x: -1, y: 0}, + {x: 1, y: 0}, + ]); + if (size >= 4) + shape = shape.concat([ + {x: -2, y: -1}, + {x: 1, y: -1}, + {x: -1, y: -2}, + {x: 0, y: -2}, + {x: 1, y: -2}, + ]); - if (Boolean(tokenData.hexSizeSupport.altOrientationFlag) !== canvas.grid.grid.options.columns) - shape.forEach(space => (space.y *= -1)); - if (canvas.grid.grid.options.columns) - shape = shape.map(space => { - return {x: space.y, y: space.x}; - }); - return shape; - } else { - return [{x: 0, y: 0}]; + if (getAltOrientationFlagForToken(token, size)) { + shape.forEach(space => (space.y *= -1)); } + if (canvas.grid.grid.columnar) + shape = shape.map(space => { + return {x: space.y, y: space.x}; + }); + return shape; } } export function getTokenSize(token) { let w, h; - const hexSizeSupportBorderSize = token.document.flags["hex-size-support"]?.borderSize; - if (hexSizeSupportBorderSize > 0) { - w = h = hexSizeSupportBorderSize; + if (canvas.grid.isHex) { + w = h = getHexTokenSize(token); } else { w = token.document.width; h = token.document.height; @@ -233,18 +242,16 @@ export function applyTokenSizeOffset(waypoints, token) { const tokenSize = getTokenSize(token); const waypointOffset = {x: 0, y: 0}; if (canvas.grid.isHex) { - if (game.modules.get("hex-size-support")?.active) { - const isAltOrientation = CONFIG.hexSizeSupport.getAltOrientationFlag(token); - if (canvas.grid.grid.options.columns) { - if (tokenSize.w % 2 === 0) { - waypointOffset.x = canvas.grid.w / 2; - if (!isAltOrientation) waypointOffset.x *= -1; - } - } else { - if (tokenSize.h % 2 === 0) { - waypointOffset.y = canvas.grid.h / 2; - if (isAltOrientation) waypointOffset.y *= -1; - } + const isAltOrientation = getAltOrientationFlagForToken(token, getHexTokenSize(token)); + if (canvas.grid.grid.columnar) { + if (tokenSize.w % 2 === 0) { + waypointOffset.x = canvas.grid.w / 2; + if (isAltOrientation) waypointOffset.x *= -1; + } + } else { + if (tokenSize.h % 2 === 0) { + waypointOffset.y = canvas.grid.h / 2; + if (isAltOrientation) waypointOffset.y *= -1; } } // If hex size support isn't active leave the waypoints like they are