#Yeah the main obstacle there is the "

1 messages · Page 1 of 1 (latest)

raven knoll
#

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.");
visual latch
#

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

raven knoll
#

the movement mode works great, it's that the token lands between grid squares:

cerulean fog
#

Does canvas.grid.getSnappedPoint() help here?

raven knoll
#

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

cerulean fog
#

You might be able to do a ternary for a center variable instead of raw and snapped.

raven knoll
#

I can mess with it...it's working anyway. Honestly not sure it's much better than just using token hud and dragging

cerulean fog
#

Maybe check the canvas grid mode.

cerulean fog
raven knoll