mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-04-21 15:03:37 +02:00
147 lines
5.6 KiB
JavaScript
147 lines
5.6 KiB
JavaScript
export default class DhRegionLayer extends foundry.canvas.layers.RegionLayer {
|
|
static prepareSceneControls() {
|
|
const sc = foundry.applications.ui.SceneControls;
|
|
const { tools, ...rest } = super.prepareSceneControls();
|
|
|
|
return {
|
|
...rest,
|
|
tools: {
|
|
select: tools.select,
|
|
templateMode: tools.templateMode,
|
|
rectangle: tools.rectangle,
|
|
circle: tools.circle,
|
|
ellipse: tools.ellipse,
|
|
cone: tools.cone,
|
|
inFront: {
|
|
name: 'inFront',
|
|
order: 7,
|
|
title: 'CONTROLS.inFront',
|
|
icon: 'fa-solid fa-eye',
|
|
toolclip: {
|
|
src: 'toolclips/tools/measure-cone.webm',
|
|
heading: 'CONTROLS.inFront',
|
|
items: sc.buildToolclipItems(['create', 'move', 'edit', 'hide', 'delete', 'rotate'])
|
|
}
|
|
},
|
|
ring: { ...tools.ring, order: 8 },
|
|
line: { ...tools.line, order: 9 },
|
|
emanation: { ...tools.emanation, order: 10 },
|
|
polygon: { ...tools.polygon, order: 11 },
|
|
hole: { ...tools.hole, order: 12 },
|
|
snap: { ...tools.snap, order: 13 },
|
|
clear: { ...tools.clear, order: 14 }
|
|
}
|
|
};
|
|
}
|
|
|
|
/** @inheritDoc */
|
|
_isCreationToolActive() {
|
|
return this.active && (game.activeTool === 'inFront' || game.activeTool in foundry.data.BaseShapeData.TYPES);
|
|
}
|
|
|
|
_createDragShapeData(event) {
|
|
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 };
|
|
|
|
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;
|
|
}
|
|
|
|
static getTemplateShape({ type, angle, range, direction } = {}) {
|
|
const { line, rectangle, inFront, cone } = CONFIG.DH.GENERAL.templateTypes;
|
|
|
|
const usedAngle =
|
|
type === cone.id
|
|
? (angle ?? CONFIG.MeasuredTemplate.defaults.angle)
|
|
: type === inFront.id
|
|
? '180'
|
|
: undefined;
|
|
|
|
const { grid, distance } = CONFIG.Scene.documentClass.schema.fields.grid.fields;
|
|
const sceneGridSize = canvas.scene?.grid.size ?? grid.size.initial;
|
|
const sceneGridDistance = canvas.scene?.grid.distance ?? distance.getInitialValue();
|
|
const dimensionConstant = sceneGridSize / sceneGridDistance;
|
|
|
|
const rangeNumber = Number(range);
|
|
const settings = canvas.scene?.rangeSettings;
|
|
const baseDistance =
|
|
(!Number.isNaN(rangeNumber) ? rangeNumber : settings ? settings[range] : 0) * dimensionConstant;
|
|
|
|
const length = baseDistance;
|
|
const radius = length;
|
|
|
|
const shapeWidth = type === line.id ? 5 * dimensionConstant : type === rectangle.id ? length : undefined;
|
|
const shapeType = type === inFront.id ? cone.id : type;
|
|
|
|
const { width, height } = game.canvas.scene.dimensions;
|
|
return {
|
|
x: width / 2,
|
|
y: height / 2,
|
|
base: {
|
|
type: 'token',
|
|
x: 0,
|
|
y: 0,
|
|
width: 1,
|
|
height: 1,
|
|
shape: game.canvas.grid.isHexagonal ? CONST.TOKEN_SHAPES.ELLIPSE_1 : CONST.TOKEN_SHAPES.RECTANGLE_1
|
|
},
|
|
t: shapeType,
|
|
length: length,
|
|
width: shapeWidth,
|
|
height: length,
|
|
angle: usedAngle,
|
|
radius: radius,
|
|
direction: direction ?? 0,
|
|
type: shapeType
|
|
};
|
|
}
|
|
}
|