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:
Manuel Vögele
2022-10-15 16:00:38 +02:00
parent 01b9941c16
commit a9c15d779b
5 changed files with 110 additions and 127 deletions
+99 -92
View File
@@ -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