mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-03-07 14:36:13 +01:00
Fixed so that our templates make use of SceneRegions instead
This commit is contained in:
parent
57e51ee841
commit
0f57ad26c5
6 changed files with 69 additions and 115 deletions
|
|
@ -20,7 +20,6 @@ import {
|
||||||
} from './module/systemRegistration/_module.mjs';
|
} from './module/systemRegistration/_module.mjs';
|
||||||
import { placeables, DhTokenLayer } from './module/canvas/_module.mjs';
|
import { placeables, DhTokenLayer } from './module/canvas/_module.mjs';
|
||||||
import './node_modules/@yaireo/tagify/dist/tagify.css';
|
import './node_modules/@yaireo/tagify/dist/tagify.css';
|
||||||
import TemplateManager from './module/documents/templateManager.mjs';
|
|
||||||
import TokenManager from './module/documents/tokenManager.mjs';
|
import TokenManager from './module/documents/tokenManager.mjs';
|
||||||
|
|
||||||
CONFIG.DH = SYSTEM;
|
CONFIG.DH = SYSTEM;
|
||||||
|
|
@ -55,7 +54,7 @@ CONFIG.ChatMessage.documentClass = documents.DhChatMessage;
|
||||||
CONFIG.ChatMessage.template = 'systems/daggerheart/templates/ui/chat/chat-message.hbs';
|
CONFIG.ChatMessage.template = 'systems/daggerheart/templates/ui/chat/chat-message.hbs';
|
||||||
|
|
||||||
CONFIG.Canvas.rulerClass = placeables.DhRuler;
|
CONFIG.Canvas.rulerClass = placeables.DhRuler;
|
||||||
CONFIG.Canvas.layers.templates.layerClass = placeables.DhTemplateLayer;
|
CONFIG.Canvas.layers.regions.layerClass = placeables.DhRegionLayer;
|
||||||
CONFIG.Canvas.layers.tokens.layerClass = DhTokenLayer;
|
CONFIG.Canvas.layers.tokens.layerClass = DhTokenLayer;
|
||||||
|
|
||||||
CONFIG.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate;
|
CONFIG.MeasuredTemplate.objectClass = placeables.DhMeasuredTemplate;
|
||||||
|
|
@ -83,7 +82,6 @@ CONFIG.ui.resources = applications.ui.DhFearTracker;
|
||||||
CONFIG.ui.countdowns = applications.ui.DhCountdowns;
|
CONFIG.ui.countdowns = applications.ui.DhCountdowns;
|
||||||
CONFIG.ux.ContextMenu = applications.ux.DHContextMenu;
|
CONFIG.ux.ContextMenu = applications.ux.DHContextMenu;
|
||||||
CONFIG.ux.TooltipManager = documents.DhTooltipManager;
|
CONFIG.ux.TooltipManager = documents.DhTooltipManager;
|
||||||
CONFIG.ux.TemplateManager = new TemplateManager();
|
|
||||||
CONFIG.ux.TokenManager = new TokenManager();
|
CONFIG.ux.TokenManager = new TokenManager();
|
||||||
CONFIG.debug.triggers = false;
|
CONFIG.debug.triggers = false;
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
export { default as DhMeasuredTemplate } from './measuredTemplate.mjs';
|
export { default as DhMeasuredTemplate } from './measuredTemplate.mjs';
|
||||||
export { default as DhRuler } from './ruler.mjs';
|
export { default as DhRuler } from './ruler.mjs';
|
||||||
export { default as DhTemplateLayer } from './templateLayer.mjs';
|
export { default as DhRegionLayer } from './regionLayer.mjs';
|
||||||
export { default as DhTokenPlaceable } from './token.mjs';
|
export { default as DhTokenPlaceable } from './token.mjs';
|
||||||
export { default as DhTokenRuler } from './tokenRuler.mjs';
|
export { default as DhTokenRuler } from './tokenRuler.mjs';
|
||||||
|
|
|
||||||
48
module/canvas/placeables/regionLayer.mjs
Normal file
48
module/canvas/placeables/regionLayer.mjs
Normal file
|
|
@ -0,0 +1,48 @@
|
||||||
|
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 };
|
||||||
|
|
||||||
|
return super._createDragShapeData(event);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
@ -8,5 +8,4 @@ export { default as DhRollTable } from './rollTable.mjs';
|
||||||
export { default as DhScene } from './scene.mjs';
|
export { default as DhScene } from './scene.mjs';
|
||||||
export { default as DhToken } from './token.mjs';
|
export { default as DhToken } from './token.mjs';
|
||||||
export { default as DhTooltipManager } from './tooltipManager.mjs';
|
export { default as DhTooltipManager } from './tooltipManager.mjs';
|
||||||
export { default as DhTemplateManager } from './templateManager.mjs';
|
|
||||||
export { default as DhTokenManager } from './tokenManager.mjs';
|
export { default as DhTokenManager } from './tokenManager.mjs';
|
||||||
|
|
|
||||||
|
|
@ -1,105 +0,0 @@
|
||||||
/**
|
|
||||||
* A singleton class that handles preview templates.
|
|
||||||
*/
|
|
||||||
|
|
||||||
export default class DhTemplateManager {
|
|
||||||
#activePreview;
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Create a template preview, deactivating any existing ones.
|
|
||||||
* @param {object} data
|
|
||||||
*/
|
|
||||||
async createPreview(data) {
|
|
||||||
const template = await canvas.templates._createPreview(data, { renderSheet: false });
|
|
||||||
|
|
||||||
this.#activePreview = {
|
|
||||||
document: template.document,
|
|
||||||
object: template,
|
|
||||||
origin: { x: template.document.x, y: template.document.y }
|
|
||||||
};
|
|
||||||
|
|
||||||
this.#activePreview.events = {
|
|
||||||
contextmenu: this.#cancelTemplate.bind(this),
|
|
||||||
mousedown: this.#confirmTemplate.bind(this),
|
|
||||||
mousemove: this.#onDragMouseMove.bind(this),
|
|
||||||
wheel: this.#onMouseWheel.bind(this)
|
|
||||||
};
|
|
||||||
canvas.stage.on('mousemove', this.#activePreview.events.mousemove);
|
|
||||||
canvas.stage.on('mousedown', this.#activePreview.events.mousedown);
|
|
||||||
|
|
||||||
canvas.app.view.addEventListener('wheel', this.#activePreview.events.wheel, true);
|
|
||||||
canvas.app.view.addEventListener('contextmenu', this.#activePreview.events.contextmenu);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the movement of the temlate preview on mousedrag.
|
|
||||||
* @param {mousemove Event} event
|
|
||||||
*/
|
|
||||||
#onDragMouseMove(event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
const { moveTime, object } = this.#activePreview;
|
|
||||||
const update = {};
|
|
||||||
|
|
||||||
const now = Date.now();
|
|
||||||
if (now - (moveTime || 0) <= 16) return;
|
|
||||||
this.#activePreview.moveTime = now;
|
|
||||||
|
|
||||||
let cursor = event.getLocalPosition(canvas.templates);
|
|
||||||
|
|
||||||
Object.assign(update, canvas.grid.getCenterPoint(cursor));
|
|
||||||
|
|
||||||
object.document.updateSource(update);
|
|
||||||
object.renderFlags.set({ refresh: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Handles the rotation of the preview template on scrolling.
|
|
||||||
* @param {wheel Event} event
|
|
||||||
*/
|
|
||||||
#onMouseWheel(event) {
|
|
||||||
if (!this.#activePreview) {
|
|
||||||
return;
|
|
||||||
}
|
|
||||||
if (!event.shiftKey && !event.ctrlKey) return;
|
|
||||||
event.stopPropagation();
|
|
||||||
event.preventDefault();
|
|
||||||
const { moveTime, object } = this.#activePreview;
|
|
||||||
|
|
||||||
const now = Date.now();
|
|
||||||
if (now - (moveTime || 0) <= 16) return;
|
|
||||||
this.#activePreview.moveTime = now;
|
|
||||||
|
|
||||||
const multiplier = event.shiftKey ? 0.2 : 0.1;
|
|
||||||
|
|
||||||
object.document.updateSource({
|
|
||||||
direction: object.document.direction + event.deltaY * multiplier
|
|
||||||
});
|
|
||||||
object.renderFlags.set({ refresh: true });
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Cancels the preview template on right-click.
|
|
||||||
* @param {contextmenu Event} event
|
|
||||||
*/
|
|
||||||
#cancelTemplate(event) {
|
|
||||||
const { mousemove, mousedown, contextmenu, wheel } = this.#activePreview.events;
|
|
||||||
canvas.templates._onDragLeftCancel(event);
|
|
||||||
|
|
||||||
canvas.stage.off('mousemove', mousemove);
|
|
||||||
canvas.stage.off('mousedown', mousedown);
|
|
||||||
canvas.app.view.removeEventListener('contextmenu', contextmenu);
|
|
||||||
canvas.app.view.removeEventListener('wheel', wheel);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
|
||||||
* Creates a real MeasuredTemplate at the preview location and cancels the preview.
|
|
||||||
* @param {click Event} event
|
|
||||||
*/
|
|
||||||
#confirmTemplate(event) {
|
|
||||||
event.stopPropagation();
|
|
||||||
this.#cancelTemplate(event);
|
|
||||||
|
|
||||||
canvas.scene.createEmbeddedDocuments('MeasuredTemplate', [this.#activePreview.document.toObject()]);
|
|
||||||
this.#activePreview = undefined;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
@ -58,7 +58,7 @@ export const renderMeasuredTemplate = async event => {
|
||||||
|
|
||||||
const usedType = type === 'inFront' ? 'cone' : type === 'emanation' ? 'circle' : type;
|
const usedType = type === 'inFront' ? 'cone' : type === 'emanation' ? 'circle' : type;
|
||||||
const usedAngle =
|
const usedAngle =
|
||||||
type === CONST.MEASURED_TEMPLATE_TYPES.CONE
|
type === CONFIG.DH.GENERAL.templateTypes.CONE
|
||||||
? (angle ?? CONFIG.MeasuredTemplate.defaults.angle)
|
? (angle ?? CONFIG.MeasuredTemplate.defaults.angle)
|
||||||
: type === CONFIG.DH.GENERAL.templateTypes.INFRONT
|
: type === CONFIG.DH.GENERAL.templateTypes.INFRONT
|
||||||
? '180'
|
? '180'
|
||||||
|
|
@ -71,17 +71,31 @@ export const renderMeasuredTemplate = async event => {
|
||||||
];
|
];
|
||||||
}
|
}
|
||||||
const distance = type === CONFIG.DH.GENERAL.templateTypes.EMANATION ? baseDistance + 2.5 : baseDistance;
|
const distance = type === CONFIG.DH.GENERAL.templateTypes.EMANATION ? baseDistance + 2.5 : baseDistance;
|
||||||
|
const radius = (distance / game.scenes.active.grid.distance) * game.scenes.active.grid.size;
|
||||||
|
|
||||||
const { width, height } = game.canvas.scene.dimensions;
|
const { width, height } = game.canvas.scene.dimensions;
|
||||||
const data = {
|
const shapeData = {
|
||||||
x: width / 2,
|
x: width / 2,
|
||||||
y: height / 2,
|
y: height / 2,
|
||||||
t: usedType,
|
t: usedType,
|
||||||
distance: distance,
|
distance: distance,
|
||||||
width: type === CONST.MEASURED_TEMPLATE_TYPES.RAY ? 5 : undefined,
|
width: type === CONFIG.DH.GENERAL.templateTypes.RAY ? 5 : undefined,
|
||||||
angle: usedAngle,
|
angle: usedAngle,
|
||||||
direction: direction
|
radius: radius,
|
||||||
|
direction: direction,
|
||||||
|
type: usedType
|
||||||
};
|
};
|
||||||
|
|
||||||
CONFIG.ux.TemplateManager.createPreview(data);
|
await canvas.regions.placeRegion(
|
||||||
|
{
|
||||||
|
name: usedType.capitalize(),
|
||||||
|
shapes: [shapeData],
|
||||||
|
restriction: { enabled: false, type: 'move', priority: 0 },
|
||||||
|
behaviors: [],
|
||||||
|
displayMeasurements: true,
|
||||||
|
locked: false,
|
||||||
|
ownership: { default: CONST.DOCUMENT_OWNERSHIP_LEVELS.NONE }
|
||||||
|
},
|
||||||
|
{ create: true }
|
||||||
|
);
|
||||||
};
|
};
|
||||||
|
|
|
||||||
Loading…
Add table
Add a link
Reference in a new issue