import { shim } from './shim.js' export async function requestFearRollFromTokens (tokens, options = {}) { // tokens: list of tokens to request the roll from // options: // title: tile for the roll dialog. Will have "- {{ token name }}" appended // flavour: flavor text for the roll card. Defaults to title // fear: value of the fear modifier. Defaults to 0. Positive number. const requestingUser = shim.user const title = options?.title || `${requestingUser.name} requests a Fear check` const flavour = options?.flavour || options?.flavor || title const fear = options.fear || 0 const rollOpts = { title, flavour, mods: [ { label: 'Fear Penalty', value: Math.abs(fear) * -1, ignore: false } ] } return requestRollFromTokens(tokens, 'attribute', 'spirit', rollOpts) } 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 = shim.user const title = options?.title || `${requestingUser.name} requests a ${rollDesc} roll` const flavour = options?.flavour || options?.flavor || title const targetNumber = options?.targetNumber || 4 const promises = [] for (const token of tokens) { const owner = shim.warpgateUtil.firstOwner(token.document) const rollOpts = { title: `${title} - ${token.name}`, targetNumber, flavour } const additionalMods = [] if ('mods' in options) { for (const mod of options.mods) { additionalMods.push(mod) } } if ('modCallback' in options) { const tokenMods = await options.modCallback(token) for (const tm of tokenMods) { additionalMods.push(tm) } } if (additionalMods.length > 0) { rollOpts.additionalMods = additionalMods } promises.push(shim.socket.executeAsUser(requestTokenRoll, owner.id, token.scene.id, token.id, rollType, rollDesc, rollOpts)) } const results = (await Promise.allSettled(promises)).map(r => r.value) const contentExtra = targetNumber === 4 ? '' : ` vs TN: ${targetNumber}` const messageData = { flavor: flavour, speaker: { alias: 'Requested Roll Results' }, whisper: [...shim.ChatMessage.getWhisperRecipients('GM'), requestingUser], content: `

Results of ${rollDesc[0].toUpperCase()}${rollDesc.slice(1)} roll${contentExtra}:

`, rolls: [] } for (const result of results) { const token = shim.game.scenes.get(result.sceneId).tokens.get(result.tokenId) const roll = ( result.result instanceof shim.CONFIG.Dice.SwadeRoll ? result.result : shim.CONFIG.Dice[result.result.class].fromData(result.result) ) roll.targetNumber = targetNumber let textResult = '' if (roll.successes === -1) { textResult = 'CRITICAL FAILURE' } else if (roll.successes === 0) { textResult = 'failed' } else if (roll.successes === 1) { textResult = 'success' } else { textResult = `success and ${roll.successes - 1} raise${roll.successes > 2 ? 's' : ''}` } messageData.content += ('' + `` + `` + `` + '') if (roll) { messageData.rolls.unshift(roll) } } messageData.content += '
TokenRollResult
${token.name}${roll ? roll.total : 'Canceled'}${textResult}
' shim.ChatMessage.create(messageData, {}) return results } export async function requestTokenRoll ( sceneId, tokenId, rollType, rollDesc, options ) { const scene = shim.scenes.get(sceneId) const token = scene.tokens.get(tokenId) let rollFunc = 'rollAttribute' let rollId = rollDesc.toLowerCase() if (rollType === 'skill') { rollFunc = 'rollSkill' rollId = token.actor.items.filter(i => i.type === 'skill').find(i => ( i.system.swid === rollDesc.toLowerCase() || i.name.toLowerCase() === rollDesc.toLowerCase()))?.id } const result = await token.actor[rollFunc](rollId, options) return { sceneId, tokenId, result } }