diff --git a/src/module/helpers.js b/src/module/helpers.js index 589844c..6f06a75 100644 --- a/src/module/helpers.js +++ b/src/module/helpers.js @@ -1,4 +1,6 @@ import { moduleHelpers } from './globals.js'; +import { templates } from './preloadTemplates.js'; +import { log } from './globals.js'; export async function requestFearRollFromTokens(tokens, options = {}) { // tokens: list of tokens to request the roll from @@ -48,7 +50,113 @@ export function firstGM() { return game.users?.find((u) => u.isGM && u.active); } +export function helpersRenderChatMessage(message, html, data) { + const messageId = message._id; + const requestContentDiv = html.querySelector('.mb-requestroll'); + if (!requestContentDiv) { + return; + } + const rollType = requestContentDiv.dataset?.rollType; + const rollDesc = requestContentDiv.dataset?.rollDesc; + const targetNumber = requestContentDiv.dataset?.rollTargetNumber; + const flavour = requestContentDiv.dataset?.rollFlavour; + const title = requestContentDiv.dataset?.rollTitle; + const mods = JSON.parse(requestContentDiv.dataset?.rollMods ?? '[]'); + const rows = requestContentDiv.querySelectorAll('.mb-rollrequest-results tr'); + for (const row of rows) { + const resolved = row.dataset?.resolved === 'true'; + const value = row.dataset?.value ?? 'None'; + const tokenUuid = row.dataset?.tokenUuid; + const rowMods = JSON.parse(row.dataset?.tokenAdditonalMods ?? '[]'); + const token = foundry.utils.fromUuidSync(tokenUuid); + const actor = token?.actor; + const iconSpan = row.querySelector('.mb-roll-result-icon'); + const valueSpan = row.querySelector('.mb-roll-result'); + const buttonSpan = row.querySelector('.mb-roll-button'); + if (resolved) { + buttonSpan.remove(); + } else { + iconSpan.remove(); + valueSpan.remove(); + buttonSpan.addEventListener('click', async () => { + const options = { + title: `${title} - ${token.name}`, + isMbRequestedRoll: true, + mbRequestMessageId: messageId, + targetNumber, + flavour, + additionalMods: [...mods, ...rowMods], + }; + let rollFunc = 'rollAttribute'; + let rollId = rollDesc.toLowerCase(); + if (rollType === 'skill') { + rollFunc = 'rollSkill'; + rollId = actor.items + .filter((i) => i.type === 'skill') + .find( + (i) => i.system.swid === rollDesc.toLowerCase() || i.name.toLowerCase() === rollDesc.toLowerCase(), + )?.id; + } + const result = await actor[rollFunc](rollId, options); + }); + } + } +} + +export function helpersRenderChatLog(app, html, data) { + // log('RENDER CHAT LOG', app, html, data); +} + export async function requestRollFromTokens(tokens, rollType, rollDesc, options = {}) { + // tokens: list of tokens to request a roll from + // rollType: 'attribute' or 'skill + // rollDesc: name of attribute or skill + // options: + // title: title for the roll dialog. Will have "- {{ token name }}" + // appended + // flavour: flavor text for the roll card. Defaults to title + // targetNumber: defaults to 4 + // mods: list of modifiers {label: "", value: 0, ignore: false} + // modCallback: callback function that takes a token and returns a list of + // modifiers in the same format as modifiers, above + const requestingUser = game.user; + const title = options?.title || `${requestingUser.name} requests a ${rollDesc} roll`; + const flavour = options?.flavour || options?.flavor || title; + const targetNumber = options?.targetNumber || 4; + const tokenData = []; + for (const token of tokens) { + const additionalMods = []; + if ('modCallback' in options) { + const tokenMods = await options.modCallback(token); + for (const tm of tokenMods) { + additionalMods.push(tm); + } + } + tokenData.push({ + name: token.name, + id: token.id, + uuid: token.document.uuid, + additionalMods: JSON.stringify(additionalMods), + }); + } + const rollData = { + type: rollType, + desc: rollDesc, + title, + flavour, + targetNumber, + mods: JSON.stringify(options.mods ? options.mods : []), + }; + const template = templates['rollRequest/chatcard.html']; + const chatData = { + user: game.user._id, + flavor: flavour, + content: await foundry.applications.handlebars.renderTemplate(template, { roll: rollData, tokens: tokenData }), + }; + return ChatMessage.create(chatData); +} + +export async function oldRequestRollFromTokens(tokens, rollType, rollDesc, options = {}) { // tokens: list of tokens to request a roll from // rollType: 'attribute' or 'skill // rollDesc: name of attribute or skill diff --git a/src/module/preloadTemplates.js b/src/module/preloadTemplates.js index 9f60aab..0094328 100644 --- a/src/module/preloadTemplates.js +++ b/src/module/preloadTemplates.js @@ -1,4 +1,4 @@ -const _templatePaths = ['dialogHeader.html', 'powerDialog.html', 'summonCosts.html']; +const _templatePaths = ['dialogHeader.html', 'powerDialog.html', 'summonCosts.html', 'rollRequest/chatcard.html']; export async function preloadTemplates() { return loadTemplates(_templatePaths.map((f) => `modules/swade-mb-helpers/templates/${f}`)); diff --git a/src/module/swade-mb-helpers.js b/src/module/swade-mb-helpers.js index b25070f..161b5f2 100644 --- a/src/module/swade-mb-helpers.js +++ b/src/module/swade-mb-helpers.js @@ -13,6 +13,8 @@ import { requestTokenRoll, SwadeVAEbuttons, updateOwnedToken, + helpersRenderChatMessage, + helpersRenderChatLog, } from './helpers.js'; import { preAttackRollModifiers, preDamageRollModifiers, preTraitRollModifiers } from './rollHelpers.js'; import { log, moduleHelpers } from './globals.js'; @@ -51,6 +53,8 @@ function _checkModule(name) { } Hooks.on('preCreateItem', embeddedHelperHook); +Hooks.on('renderChatMessageHTML', helpersRenderChatMessage); +Hooks.on('renderChatLogHTML', helpersRenderChatLog); Hooks.on('swadePreRollAttribute', preTraitRollModifiers); Hooks.on('swadePreRollSkill', preTraitRollModifiers); Hooks.on('swadeCalculateDefaultAttackMods', preAttackRollModifiers); diff --git a/src/templates/rollRequest/chatcard.html b/src/templates/rollRequest/chatcard.html new file mode 100644 index 0000000..736cfb7 --- /dev/null +++ b/src/templates/rollRequest/chatcard.html @@ -0,0 +1,22 @@ +
+
+

Click the button to make your roll.

+
+
+ + {{#each tokens}} + + + +
{{name}} + + ? + NA + + {{/each}} +
+
+