diff --git a/daggerheart.mjs b/daggerheart.mjs index c4cf1c94..c5c685cd 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -9,13 +9,15 @@ import { registerDHSettings } from './module/applications/settings.mjs'; import DhpChatLog from './module/ui/chatLog.mjs'; import DhpRuler from './module/ui/ruler.mjs'; import DhpTokenRuler from './module/ui/tokenRuler.mjs'; -import { dualityRollEnricher } from './module/enrichers/DualityRollEnricher.mjs'; +import { DhDualityRollEnricher, DhTemplateEnricher } from './module/enrichers/_module.mjs'; import { getCommandTarget, rollCommandToJSON, setDiceSoNiceForDualityRoll } from './module/helpers/utils.mjs'; import { abilities } from './module/config/actorConfig.mjs'; import Resources from './module/applications/resources.mjs'; import DHDualityRoll from './module/data/chat-message/dualityRoll.mjs'; import { DualityRollColor } from './module/data/settings/Appearance.mjs'; import { DhMeasuredTemplate } from './module/placeables/_module.mjs'; +import { renderDualityButton } from './module/enrichers/DualityRollEnricher.mjs'; +import { renderMeasuredTemplate } from './module/enrichers/TemplateEnricher.mjs'; globalThis.SYSTEM = SYSTEM; @@ -28,10 +30,18 @@ Hooks.once('init', () => { documents }; - CONFIG.TextEditor.enrichers.push({ - pattern: /\[\[\/dr\s?(.*?)\]\]/g, - enricher: dualityRollEnricher - }); + CONFIG.TextEditor.enrichers.push( + ...[ + { + pattern: /\[\[\/dr\s?(.*?)\]\]/g, + enricher: DhDualityRollEnricher + }, + { + pattern: /^@Template\[(.*)\]$/g, + enricher: DhTemplateEnricher + } + ] + ); CONFIG.statusEffects = Object.values(SYSTEM.GENERAL.conditions).map(x => ({ ...x, @@ -144,43 +154,34 @@ Hooks.on(socketEvent.GMUpdate, async (action, uuid, update) => { } }); -const renderDualityButton = async event => { - const button = event.currentTarget, - traitValue = button.dataset.trait?.toLowerCase(), - target = getCommandTarget(); - if (!target) return; - - const config = { - event: event, - title: button.dataset.title, - roll: { - modifier: traitValue ? target.system.traits[traitValue].value : null, - label: button.dataset.label, - type: button.dataset.actionType ?? null // Need check - }, - chatMessage: { - template: 'systems/daggerheart/templates/chat/duality-roll.hbs' - } - }; - await target.diceRoll(config); -}; - Hooks.on('renderChatMessageHTML', (_, element) => { element .querySelectorAll('.duality-roll-button') .forEach(element => element.addEventListener('click', renderDualityButton)); + + element + .querySelectorAll('.measured-template-button') + .forEach(element => element.addEventListener('click', renderMeasuredTemplate)); }); Hooks.on('renderJournalEntryPageProseMirrorSheet', (_, element) => { element .querySelectorAll('.duality-roll-button') .forEach(element => element.addEventListener('click', renderDualityButton)); + + element + .querySelectorAll('.measured-template-button') + .forEach(element => element.addEventListener('click', renderMeasuredTemplate)); }); Hooks.on('renderHandlebarsApplication', (_, element) => { element .querySelectorAll('.duality-roll-button') .forEach(element => element.addEventListener('click', renderDualityButton)); + + element + .querySelectorAll('.measured-template-button') + .forEach(element => element.addEventListener('click', renderMeasuredTemplate)); }); Hooks.on('chatMessage', (_, message) => { diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 76fd12a0..2b0e11b9 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -1,35 +1,42 @@ export const range = { self: { + id: 'self', + short: 's', label: 'DAGGERHEART.Range.self.name', description: 'DAGGERHEART.Range.self.description', distance: 0 }, melee: { id: 'melee', + short: 'm', label: 'DAGGERHEART.Range.melee.name', description: 'DAGGERHEART.Range.melee.description', distance: 1 }, veryClose: { id: 'veryClose', + short: 'vc', label: 'DAGGERHEART.Range.veryClose.name', description: 'DAGGERHEART.Range.veryClose.description', distance: 3 }, close: { id: 'close', + short: 'c', label: 'DAGGERHEART.Range.close.name', description: 'DAGGERHEART.Range.close.description', distance: 10 }, far: { id: 'far', + short: 'f', label: 'DAGGERHEART.Range.far.name', description: 'DAGGERHEART.Range.far.description', distance: 20 }, veryFar: { id: 'veryFar', + short: 'vf', label: 'DAGGERHEART.Range.veryFar.name', description: 'DAGGERHEART.Range.veryFar.description', distance: 30 diff --git a/module/enrichers/DualityRollEnricher.mjs b/module/enrichers/DualityRollEnricher.mjs index 01fbe1af..61884acc 100644 --- a/module/enrichers/DualityRollEnricher.mjs +++ b/module/enrichers/DualityRollEnricher.mjs @@ -1,7 +1,7 @@ import { abilities } from '../config/actorConfig.mjs'; -import { rollCommandToJSON } from '../helpers/utils.mjs'; +import { getCommandTarget, rollCommandToJSON } from '../helpers/utils.mjs'; -export function dualityRollEnricher(match, _options) { +export default function DhDualityRollEnricher(match, _options) { const roll = rollCommandToJSON(match[1]); if (!roll) return match[0]; @@ -39,3 +39,24 @@ export function getDualityMessage(roll) { return dualityElement; } + +export const renderDualityButton = async event => { + const button = event.currentTarget, + traitValue = button.dataset.trait?.toLowerCase(), + target = getCommandTarget(); + if (!target) return; + + const config = { + event: event, + title: button.dataset.title, + roll: { + modifier: traitValue ? target.system.traits[traitValue].value : null, + label: button.dataset.label, + type: button.dataset.actionType ?? null // Need check + }, + chatMessage: { + template: 'systems/daggerheart/templates/chat/duality-roll.hbs' + } + }; + await target.diceRoll(config); +}; diff --git a/module/enrichers/TemplateEnricher.mjs b/module/enrichers/TemplateEnricher.mjs new file mode 100644 index 00000000..50b27068 --- /dev/null +++ b/module/enrichers/TemplateEnricher.mjs @@ -0,0 +1,60 @@ +import { range as configRange } from '../config/generalConfig.mjs'; + +export default function DhTemplateEnricher(match, _options) { + const parts = match[1].split('|').map(x => x.trim()); + + let type = null, + range = null; + + parts.forEach(part => { + const split = part.split(':').map(x => x.toLowerCase().trim()); + if (split.length === 2) { + switch (split[0]) { + case 'type': + const matchedType = Object.values(CONST.MEASURED_TEMPLATE_TYPES).find( + x => x.toLowerCase() === split[1] + ); + type = matchedType; + break; + case 'range': + const matchedRange = Object.values(configRange).find( + x => x.id.toLowerCase() === split[1] || x.short === split[1] + ); + range = matchedRange?.id; + break; + } + } + }); + + if (!type || !range) return match[0]; + + const templateElement = document.createElement('span'); + templateElement.innerHTML = ` + + `; + + return templateElement; +} + +export const renderMeasuredTemplate = async event => { + const button = event.currentTarget, + type = button.dataset.type, + range = button.dataset.range; + + if (!type || !range || !game.canvas.scene) return; + + const distance = game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.RangeMeasurement)[range]; + const { width, height } = game.canvas.scene.dimensions; + canvas.scene.createEmbeddedDocuments('MeasuredTemplate', [ + { + x: width / 2, + y: height / 2, + t: type, + distance: distance, + width: type === CONST.MEASURED_TEMPLATE_TYPES.RAY ? 5 : undefined, + angle: type === CONST.MEASURED_TEMPLATE_TYPES.CONE ? CONFIG.MeasuredTemplate.defaults.angle : undefined + } + ]); +}; diff --git a/module/enrichers/_module.mjs b/module/enrichers/_module.mjs new file mode 100644 index 00000000..4ba1bdb6 --- /dev/null +++ b/module/enrichers/_module.mjs @@ -0,0 +1,4 @@ +import DhDualityRollEnricher from './DualityRollEnricher.mjs'; +import DhTemplateEnricher from './TemplateEnricher.mjs'; + +export { DhDualityRollEnricher, DhTemplateEnricher };