|
|
- import { getSetting } from './settings.js';
- const rad = Math.PI * 2, baseRotation = Math.PI / 4;
- function repositionToken(token, rotation, offset, pos = 0) {
- const size = token.scene.dimensions.size, x = Math.sin(rotation * pos + baseRotation) * offset * token.document.width * size, y = Math.cos(rotation * pos + baseRotation) * offset * token.document.height * size;
- token.border.x = token.document.x - x;
- token.border.y = token.document.y - y;
- token.hitArea.x = -x;
- token.hitArea.y = -y;
- const gridOffset = size / 2;
- token.mesh.x = token.border.x + gridOffset * token.document.width;
- token.mesh.y = token.border.y + gridOffset * token.document.height;
- }
- let SNAPPED_TOKENS = [];
- function findGroup(token) {
- for (const group of SNAPPED_TOKENS) {
- for (const t of group) {
- if (token === t)
- return group;
- }
- }
- }
- function sameGroup(oldGroup, newGroup) {
- if (oldGroup.length !== newGroup.length)
- return false;
- for (const t of oldGroup) {
- if (!newGroup.includes(t))
- return false;
- }
- return true;
- }
- export function refreshAll(groups = SNAPPED_TOKENS) {
- for (const t of SNAPPED_TOKENS.flat()) {
- t.object?.refresh();
- }
- }
- function snapToken(token, options) {
- if (token.isAnimating)
- return;
- if (!getSetting('snapTokens')) {
- token.hitArea.x = 0;
- token.hitArea.y = 0;
- return;
- }
- const oldGroup = findGroup(token.document);
- const x = token.document.x, y = token.document.y, height = token.document.height, width = token.document.width;
- const ignoreDead = getSetting('ignoreDead');
- const tokens = token.scene.tokens.contents.filter((token) => !token.object?.destroyed &&
- token.object.x === x &&
- token.object.y === y &&
- token.height === height &&
- token.width === width &&
- !(ignoreDead && checkStatus(token, ['dead', 'dying', 'unconscious'])) &&
- token.object.visible);
- if (tokens.length < 2) {
- token.hitArea.x = 0;
- token.hitArea.y = 0;
- if (oldGroup) {
- if (oldGroup.length > 1) {
- const idx = oldGroup.indexOf(token.document);
- oldGroup.splice(idx, 1);
- refreshAll(oldGroup);
- }
- else {
- const idx = SNAPPED_TOKENS.indexOf(oldGroup);
- SNAPPED_TOKENS.splice(idx, 1);
- }
- }
- return;
- }
- if (oldGroup && !sameGroup(oldGroup, tokens)) {
- const idx = oldGroup.indexOf(token.document);
- oldGroup.splice(idx, 1);
- if (oldGroup.length)
- refreshAll(oldGroup);
- else {
- const idx = SNAPPED_TOKENS.indexOf(oldGroup);
- SNAPPED_TOKENS.splice(idx, 1);
- }
- }
- const newGroup = findGroup(tokens.find((t) => t !== token.document));
- if (newGroup) {
- const idx = SNAPPED_TOKENS.indexOf(newGroup);
- SNAPPED_TOKENS.splice(idx, 1);
- }
- SNAPPED_TOKENS.push(tokens);
- const angle = rad / tokens.length;
- const offset = getSetting('scatter');
- for (let i = 0; i < tokens.length; i++)
- repositionToken(tokens[i].object, angle, offset, i);
- }
- function checkStatus(token, status) {
- return status.some((s) => token.hasStatusEffect(s));
- }
- Hooks.on('refreshToken', snapToken);
- Hooks.on('canvasTearDown', () => (SNAPPED_TOKENS = []));
|