From 86eeba06483a811b783dbeb852b69f0b379dd553 Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Sat, 4 Oct 2025 07:10:39 -0400 Subject: [PATCH] Implement @Lookup enricher (#1196) --- module/documents/actor.mjs | 1 + module/enrichers/DamageEnricher.mjs | 29 ++------------ module/enrichers/LookupEnricher.mjs | 8 ++++ module/enrichers/TemplateEnricher.mjs | 55 ++++++--------------------- module/enrichers/_module.mjs | 5 +++ module/enrichers/parser.mjs | 20 ++++++++++ 6 files changed, 50 insertions(+), 68 deletions(-) create mode 100644 module/enrichers/LookupEnricher.mjs create mode 100644 module/enrichers/parser.mjs diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 79e71549..3601e09d 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -501,6 +501,7 @@ export default class DhpActor extends Actor { /**@inheritdoc */ getRollData() { const rollData = super.getRollData(); + rollData.name = this.name; rollData.system = this.system.getRollData(); rollData.prof = this.system.proficiency ?? 1; rollData.cast = this.system.spellcastModifier ?? 1; diff --git a/module/enrichers/DamageEnricher.mjs b/module/enrichers/DamageEnricher.mjs index a52c4b31..e3f9c42a 100644 --- a/module/enrichers/DamageEnricher.mjs +++ b/module/enrichers/DamageEnricher.mjs @@ -1,29 +1,8 @@ +import { parseInlineParams } from './parser.mjs'; + export default function DhDamageEnricher(match, _options) { - const parts = match[1].split('|').map(x => x.trim()); - - let value = null, - type = null, - inline = false; - - parts.forEach(part => { - const split = part.split(':').map(x => x.toLowerCase().trim()); - if (split.length === 2) { - switch (split[0]) { - case 'value': - value = split[1]; - break; - case 'type': - type = split[1]; - break; - case 'inline': - inline = true; - break; - } - } - }); - - if (!value || !value) return match[0]; - + const { value, type, inline } = parseInlineParams(match[1]); + if (!value || !type) return match[0]; return getDamageMessage(value, type, inline, match[0]); } diff --git a/module/enrichers/LookupEnricher.mjs b/module/enrichers/LookupEnricher.mjs new file mode 100644 index 00000000..7836311e --- /dev/null +++ b/module/enrichers/LookupEnricher.mjs @@ -0,0 +1,8 @@ +import { parseInlineParams } from './parser.mjs'; + +export default function DhLookupEnricher(match, { rollData }) { + const results = parseInlineParams(match[1], { first: 'formula'}); + const element = document.createElement('span'); + element.textContent = Roll.replaceFormulaData(String(results.formula), rollData); + return element; +} diff --git a/module/enrichers/TemplateEnricher.mjs b/module/enrichers/TemplateEnricher.mjs index 15936b29..f1e9298d 100644 --- a/module/enrichers/TemplateEnricher.mjs +++ b/module/enrichers/TemplateEnricher.mjs @@ -1,49 +1,18 @@ +import { parseInlineParams } from './parser.mjs'; + export default function DhTemplateEnricher(match, _options) { - const parts = match[1].split('|').map(x => x.trim()); - - let type = null, - range = null, - angle = CONFIG.MeasuredTemplate.defaults.angle, - direction = 0, - inline = false; - - 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(CONFIG.DH.GENERAL.templateTypes).find( - x => x.toLowerCase() === split[1] - ); - type = matchedType; - break; - case 'range': - if (Number.isNaN(Number(split[1]))) { - const matchedRange = Object.values(CONFIG.DH.GENERAL.templateRanges).find( - x => x.id.toLowerCase() === split[1] || x.short === split[1] - ); - range = matchedRange?.id; - } else { - range = split[1]; - } - break; - case 'inline': - inline = true; - break; - case 'angle': - angle = split[1]; - break; - case 'direction': - direction = split[1]; - break; - } - } - }); - - if (!type || !range) return match[0]; + const params = parseInlineParams(match[1]); + const { type, angle = CONFIG.MeasuredTemplate.defaults.angle, inline = false } = params; + const direction = Number(params.direction) || 0; + const range = + params.range && Number.isNaN(params.range) + ? Object.values(CONFIG.DH.GENERAL.templateRanges).find( + x => x.id.toLowerCase() === split[1] || x.short === split[1] + )?.id + : params.range; + if (!(type in CONFIG.MeasuredTemplate.types) || !range) return match[0]; const label = game.i18n.localize(`DAGGERHEART.CONFIG.TemplateTypes.${type}`); - const rangeDisplay = Number.isNaN(Number(range)) ? game.i18n.localize(`DAGGERHEART.CONFIG.Range.${range}.name`) : range; let angleDisplay = ''; diff --git a/module/enrichers/_module.mjs b/module/enrichers/_module.mjs index deec4250..794756f4 100644 --- a/module/enrichers/_module.mjs +++ b/module/enrichers/_module.mjs @@ -2,6 +2,7 @@ import { default as DhDamageEnricher, renderDamageButton } from './DamageEnriche import { default as DhDualityRollEnricher, renderDualityButton } from './DualityRollEnricher.mjs'; import { default as DhEffectEnricher } from './EffectEnricher.mjs'; import { default as DhTemplateEnricher, renderMeasuredTemplate } from './TemplateEnricher.mjs'; +import { default as DhLookupEnricher } from './LookupEnricher.mjs'; export { DhDamageEnricher, DhDualityRollEnricher, DhEffectEnricher, DhTemplateEnricher }; @@ -21,6 +22,10 @@ export const enricherConfig = [ { pattern: /@Template\[(.*)\]({.*})?/g, enricher: DhTemplateEnricher + }, + { + pattern: /@Lookup\[(.*)\]({.*})?/g, + enricher: DhLookupEnricher } ]; diff --git a/module/enrichers/parser.mjs b/module/enrichers/parser.mjs new file mode 100644 index 00000000..9fcc4af1 --- /dev/null +++ b/module/enrichers/parser.mjs @@ -0,0 +1,20 @@ +/** + * @param {string} paramString The parameter inside the brackets of something like @Template[] to parse + * @param {Object} options + * @param {string} options.first If set, the first parameter is treated as a value with this as its key + * @returns {Record | null} + */ +export function parseInlineParams(paramString, { first } = {}) { + const parts = paramString.split('|').map(x => x.trim()); + const params = {}; + for (const [idx, param] of parts.entries()) { + if (first && idx === 0) { + params[first] = param; + } else { + const parts = param.split(':'); + params[parts[0]] = parts.length > 1 ? parts[1] : true; + } + } + + return params; +}