v10 compat: Make Drag Ruler play nice with Foundry v10's hex grid and the new hex-size-support module
This commit is contained in:
+99
-92
@@ -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
|
||||
|
||||
Reference in New Issue
Block a user