diff --git a/daggerheart.mjs b/daggerheart.mjs
index 7e744571..87208c3d 100644
--- a/daggerheart.mjs
+++ b/daggerheart.mjs
@@ -187,12 +187,14 @@ Hooks.on('renderHandlebarsApplication', (_, element) => {
Hooks.on('chatMessage', (_, message) => {
if (message.startsWith('/dr')) {
- const rollCommand = rollCommandToJSON(message.replace(/\/dr\s?/, ''));
- if (!rollCommand) {
+ const result = rollCommandToJSON(message.replace(/\/dr\s?/, ''));
+ if (!result) {
ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.dualityParsing'));
return false;
}
+ const { result: rollCommand, flavor } = result;
+
const reaction = rollCommand.reaction;
const traitValue = rollCommand.trait?.toLowerCase();
const advantage = rollCommand.advantage
diff --git a/module/enrichers/DualityRollEnricher.mjs b/module/enrichers/DualityRollEnricher.mjs
index 275adcf7..4a6fac23 100644
--- a/module/enrichers/DualityRollEnricher.mjs
+++ b/module/enrichers/DualityRollEnricher.mjs
@@ -2,19 +2,21 @@ import { abilities } from '../config/actorConfig.mjs';
import { getCommandTarget, rollCommandToJSON } from '../helpers/utils.mjs';
export default function DhDualityRollEnricher(match, _options) {
- const roll = rollCommandToJSON(match[1]);
+ const roll = rollCommandToJSON(match[1], match[0]);
if (!roll) return match[0];
- return getDualityMessage(roll);
+ return getDualityMessage(roll.result, roll.flavor);
}
-function getDualityMessage(roll) {
+function getDualityMessage(roll, flavor) {
const trait = roll.trait && abilities[roll.trait] ? game.i18n.localize(abilities[roll.trait].label) : null;
- const label = roll.trait
- ? game.i18n.format('DAGGERHEART.GENERAL.rollWith', { roll: trait })
- : roll.reaction
- ? game.i18n.localize('DAGGERHEART.GENERAL.reactionRoll')
- : game.i18n.localize('DAGGERHEART.GENERAL.duality');
+ const label =
+ flavor ??
+ (roll.trait
+ ? game.i18n.format('DAGGERHEART.GENERAL.rollWith', { roll: trait })
+ : roll.reaction
+ ? game.i18n.localize('DAGGERHEART.GENERAL.reactionRoll')
+ : game.i18n.localize('DAGGERHEART.GENERAL.duality'));
const dataLabel = trait
? game.i18n.localize(abilities[roll.trait].label)
@@ -48,7 +50,7 @@ function getDualityMessage(roll) {
>
${roll.reaction ? '' : ''}
${label}
- ${roll.difficulty || advantageLabel ? `(${[roll.difficulty, advantageLabel ? game.i18n.localize(`DAGGERHEART.GENERAL.${advantageLabel}.short`) : null].filter(x => x).join(' ')})` : ''}
+ ${!flavor && (roll.difficulty || advantageLabel) ? `(${[roll.difficulty, advantageLabel ? game.i18n.localize(`DAGGERHEART.GENERAL.${advantageLabel}.short`) : null].filter(x => x).join(' ')})` : ''}
`;
diff --git a/module/enrichers/_module.mjs b/module/enrichers/_module.mjs
index abfd8158..3b597dd5 100644
--- a/module/enrichers/_module.mjs
+++ b/module/enrichers/_module.mjs
@@ -7,19 +7,19 @@ export { DhDamageEnricher, DhDualityRollEnricher, DhEffectEnricher, DhTemplateEn
export const enricherConfig = [
{
- pattern: /^@Damage\[(.*)\]$/g,
+ pattern: /^@Damage\[(.*)\]({.*})?$/g,
enricher: DhDamageEnricher
},
{
- pattern: /\[\[\/dr\s?(.*?)\]\]/g,
+ pattern: /\[\[\/dr\s?(.*?)\]\]({.*})?/g,
enricher: DhDualityRollEnricher
},
{
- pattern: /^@Effect\[(.*)\]$/g,
+ pattern: /^@Effect\[(.*)\]({.*})?$/g,
enricher: DhEffectEnricher
},
{
- pattern: /^@Template\[(.*)\]$/g,
+ pattern: /^@Template\[(.*)\]({.*})?$/g,
enricher: DhTemplateEnricher
}
];
diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs
index ac9ac9e7..1119e91b 100644
--- a/module/helpers/utils.mjs
+++ b/module/helpers/utils.mjs
@@ -5,9 +5,12 @@ export const capitalize = string => {
return string.charAt(0).toUpperCase() + string.slice(1);
};
-export function rollCommandToJSON(text) {
+export function rollCommandToJSON(text, raw) {
if (!text) return {};
+ const flavorMatch = raw?.match(/{(.*)}$/);
+ const flavor = flavorMatch ? flavorMatch[1] : null;
+
// Match key="quoted string" OR key=unquotedValue
const PAIR_RE = /(\w+)=("(?:[^"\\]|\\.)*"|\S+)/g;
const result = {};
@@ -28,7 +31,7 @@ export function rollCommandToJSON(text) {
}
result[key] = value;
}
- return Object.keys(result).length > 0 ? result : null;
+ return Object.keys(result).length > 0 ? { result, flavor } : null;
}
export const getCommandTarget = (options = {}) => {