123 lines
4.5 KiB
JavaScript

import { module } from './globals.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 = game.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 = 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 promises = []
for (const token of tokens) {
const owner = warpgate.util.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(module.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: [...ChatMessage.getWhisperRecipients('GM'), requestingUser],
content: `<p>Results of ${rollDesc[0].toUpperCase()}${rollDesc.slice(1)} roll${contentExtra}:</p>
<table><thead><tr><th>Token</th><th>Roll</th><th>Result</th></tr></thead><tbody>`,
rolls: []
}
for (const result of results) {
const token = game.scenes.get(result.sceneId).tokens.get(result.tokenId)
const roll = (
result.result instanceof CONFIG.Dice.SwadeRoll
? result.result
: 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 += ('<tr>' +
`<th>${token.name}</th>` +
`<td>${roll ? roll.total : '<i>Canceled</i>'}</td>` +
`<td>${textResult}</td>` +
'</tr>')
if (roll) {
messageData.rolls.unshift(roll)
}
}
messageData.content += '</tbody></table>'
ChatMessage.create(messageData, {})
return results
}
export async function requestTokenRoll (
sceneId, tokenId, rollType, rollDesc, options
) {
const scene = game.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 }
}