[V14] Emanation AutoSizing (#1686)

* Added so that emanation templates auto size their base to any token at the spot its placed

* Correct option useage

* Also snap emanations when done from scene controls

---------

Co-authored-by: Carlos Fernandez <cfern1990@gmail.com>
This commit is contained in:
WBHarry 2026-03-09 11:30:03 +01:00 committed by GitHub
parent 5a4bbc91f5
commit fcadf119b7
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
2 changed files with 48 additions and 117 deletions

View file

@ -43,6 +43,53 @@ export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer {
const hole = ui.controls.controls[this.options.name].tools.hole?.active ?? false;
if (game.activeTool === 'inFront') return { type: 'cone', x: 0, y: 0, radius: 0, angle: 180, hole };
return super._createDragShapeData(event);
const shape = super._createDragShapeData(event);
const token = shape?.type === 'emanation' && shape.base?.type === 'token' ? this.#findTokenInBounds(event.interactionData.origin) : null;
if (token) {
shape.base.width = token.width;
shape.base.height = token.height;
event.interactionData.origin = token.getCenterPoint();
}
return shape;
}
async placeRegion(data, options = {}) {
const preConfirm = ({ _event, document, _create, _options }) => {
const shape = document.shapes[0];
const isEmanation = shape.type === 'emanation';
if (isEmanation) {
const token = this.#findTokenInBounds(shape.base.origin);
if (!token) return options.preConfirm?.() ?? true;
const shapeData = shape.toObject();
document.updateSource({
shapes: [
{
...shapeData,
base: {
...shapeData.base,
height: token.height,
width: token.width,
x: token.x,
y: token.y
}
}
]
});
}
return options?.preConfirm?.() ?? true;
};
super.placeRegion(data, { ...options, preConfirm });
}
/** Searches for token at origin point, returning null if there are no tokens or multiple overlapping tokens */
#findTokenInBounds(origin) {
const { x, y } = origin;
const gridSize = canvas.grid.size;
const inBounds = canvas.scene.tokens.filter(t => {
return x.between(t.x, t.x + t.width * gridSize) && y.between(t.y, t.y + t.height * gridSize);
});
return inBounds.length === 1 ? inBounds[0] : null;
}
}