#Yeah the main obstacle there is the "
1 messages · Page 1 of 1 (latest)
Got it sorta working, but it doesn't go to the center of a grid square on gridded maps:
// Ensure a token is selected
if (!token) {
ui.notifications.warn("Please select a token first.");
return;
}
// Store original movementAction
const origMovement = token.document.movementAction;
// Switch to 'blink' movement mode
await token.document.update({ movementAction: 'blink' });
// Inform the user
ui.notifications.info("Click a location on the canvas to blink the token.");
// Wait for a canvas click and get destination
const destination = await new Promise((resolve) => {
const handler = async (event) => {
// Remove the handler after click
canvas.stage.off('mousedown', handler);
// Translate screen coords to world coords
const { x, y } = event.data.getLocalPosition(canvas.app.stage);
resolve({ x, y });
};
canvas.stage.on('mousedown', handler);
});
// Move the token using blink movement
await token.document.update({ x: destination.x, y: destination.y });
// Optional delay to ensure visual effect completes
await new Promise(resolve => setTimeout(resolve, 500));
// Restore original movement mode
await token.document.update({ movementAction: origMovement });
ui.notifications.info("Token blinked and movement restored.");
Well when moving a token via an update like that, I believe it automatically uses blink or teleport as the movement action, so approaching it from that perspective means you don't need to do the movement change at all
the movement mode works great, it's that the token lands between grid squares:
Does canvas.grid.getSnappedPoint() help here?
investigating the API now
this works but seems hacky to make an allowance for square grids and no grids separately:
// Ensure a token is selected
if (!token) {
ui.notifications.warn("Please select a token first.");
return;
}
ui.notifications.info("Click a location on the canvas to blink the token.");
// Wait for a click and compute destination
const destination = await new Promise((resolve) => {
const handler = (event) => {
canvas.stage.off('mousedown', handler);
const raw = event.data.getLocalPosition(canvas.app.stage);
// Try to snap to top-left of nearest grid square
const snapped = canvas.grid.getSnappedPoint(
{ x: raw.x, y: raw.y },
{ mode: "top-left" }
);
let x, y;
if (snapped && Number.isFinite(snapped.x) && Number.isFinite(snapped.y)) {
// Move to center of the snapped grid square
const center = canvas.grid.getTopLeftPoint(snapped, { center: true });
x = center.x;
y = center.y;
} else {
// Fallback to center of raw point
const center = canvas.grid.getTopLeftPoint(raw, { center: true });
x = center.x;
y = center.y;
}
resolve({ x, y });
};
canvas.stage.on('mousedown', handler);
});
// Move token with blink effect
await token.document.update(
{ x: destination.x, y: destination.y },
{ movementMode: 'blink' }
);
ui.notifications.info("Token blinked to grid center.");
found an error on gridless, but got that fixed up now to
You might be able to do a ternary for a center variable instead of raw and snapped.
I can mess with it...it's working anyway. Honestly not sure it's much better than just using token hud and dragging
Maybe check the canvas grid mode.
Yeah, only in the sense that it could make for a convenient action on the teleport power
this saved a few lines for sure