Files
Foundry-VTT-Docker/resources/app/client/pixi/layers/placeables/templates.js
2025-01-04 00:34:03 +01:00

158 lines
4.6 KiB
JavaScript

/**
* This Canvas Layer provides a container for MeasuredTemplate objects.
* @category - Canvas
*/
class TemplateLayer extends PlaceablesLayer {
/** @inheritdoc */
static get layerOptions() {
return foundry.utils.mergeObject(super.layerOptions, {
name: "templates",
rotatableObjects: true,
zIndex: 400
});
}
/** @inheritdoc */
static documentName = "MeasuredTemplate";
/* -------------------------------------------- */
/** @inheritdoc */
get hookName() {
return TemplateLayer.name;
}
/* -------------------------------------------- */
/* Methods */
/* -------------------------------------------- */
/** @inheritDoc */
_deactivate() {
super._deactivate();
this.objects.visible = true;
}
/* -------------------------------------------- */
/** @inheritDoc */
async _draw(options) {
await super._draw(options);
this.objects.visible = true;
}
/* -------------------------------------------- */
/**
* Register game settings used by the TemplatesLayer
*/
static registerSettings() {
game.settings.register("core", "gridTemplates", {
name: "TEMPLATE.GridTemplatesSetting",
hint: "TEMPLATE.GridTemplatesSettingHint",
scope: "world",
config: true,
type: new foundry.data.fields.BooleanField({initial: false}),
onChange: () => {
if ( canvas.ready ) canvas.templates.draw();
}
});
game.settings.register("core", "coneTemplateType", {
name: "TEMPLATE.ConeTypeSetting",
hint: "TEMPLATE.ConeTypeSettingHint",
scope: "world",
config: true,
type: new foundry.data.fields.StringField({required: true, blank: false, initial: "round", choices: {
round: "TEMPLATE.ConeTypeRound",
flat: "TEMPLATE.ConeTypeFlat"
}}),
onChange: () => {
if ( canvas.ready ) canvas.templates.draw();
}
});
}
/* -------------------------------------------- */
/* Event Listeners and Handlers */
/* -------------------------------------------- */
/** @inheritdoc */
_onDragLeftStart(event) {
super._onDragLeftStart(event);
const interaction = event.interactionData;
// Snap the origin to the grid
if ( !event.shiftKey ) interaction.origin = this.getSnappedPoint(interaction.origin);
// Create a pending MeasuredTemplateDocument
const tool = game.activeTool;
const previewData = {
user: game.user.id,
t: tool,
x: interaction.origin.x,
y: interaction.origin.y,
sort: Math.max(this.getMaxSort() + 1, 0),
distance: 1,
direction: 0,
fillColor: game.user.color || "#FF0000",
hidden: event.altKey
};
const defaults = CONFIG.MeasuredTemplate.defaults;
if ( tool === "cone") previewData.angle = defaults.angle;
else if ( tool === "ray" ) previewData.width = (defaults.width * canvas.dimensions.distance);
const cls = getDocumentClass("MeasuredTemplate");
const doc = new cls(previewData, {parent: canvas.scene});
// Create a preview MeasuredTemplate object
const template = new this.constructor.placeableClass(doc);
interaction.preview = this.preview.addChild(template);
template.draw();
}
/* -------------------------------------------- */
/** @inheritdoc */
_onDragLeftMove(event) {
const interaction = event.interactionData;
// Snap the destination to the grid
if ( !event.shiftKey ) interaction.destination = this.getSnappedPoint(interaction.destination);
// Compute the ray
const {origin, destination, preview} = interaction;
const ray = new Ray(origin, destination);
let distance;
// Grid type
if ( game.settings.get("core", "gridTemplates") ) {
distance = canvas.grid.measurePath([origin, destination]).distance;
}
// Euclidean type
else {
const ratio = (canvas.dimensions.size / canvas.dimensions.distance);
distance = ray.distance / ratio;
}
// Update the preview object
preview.document.direction = Math.normalizeDegrees(Math.toDegrees(ray.angle));
preview.document.distance = distance;
preview.renderFlags.set({refreshShape: true});
}
/* -------------------------------------------- */
/** @inheritdoc */
_onMouseWheel(event) {
// Determine whether we have a hovered template?
const template = this.hover;
if ( !template || template.isPreview ) return;
// Determine the incremental angle of rotation from event data
const snap = event.shiftKey ? 15 : 5;
const delta = snap * Math.sign(event.delta);
return template.rotate(template.document.direction + delta, snap);
}
}