158 lines
4.6 KiB
JavaScript
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);
|
|
}
|
|
}
|