diff --git a/module/dice.js b/module/dice.js deleted file mode 100644 index 8f2d4e46..00000000 --- a/module/dice.js +++ /dev/null @@ -1,251 +0,0 @@ -export class Dice5e { - - /** - * A standardized helper function for managing core 5e "d20 rolls" - * - * Holding SHIFT, ALT, or CTRL when the attack is rolled will "fast-forward". - * This chooses the default options of a normal attack with no bonus, Advantage, or Disadvantage respectively - * - * @param {Array} parts The dice roll component parts, excluding the initial d20 - * @param {Object} data Actor or item data against which to parse the roll - * @param {Event|object} event The triggering event which initiated the roll - * @param {string} rollMode A specific roll mode to apply as the default for the resulting roll - * @param {string|null} template The HTML template used to render the roll dialog - * @param {string|null} title The dice roll UI window title - * @param {Object} speaker The ChatMessage speaker to pass when creating the chat - * @param {string|null} flavor Flavor text to use in the posted chat message - * @param {Boolean} fastForward Allow fast-forward advantage selection - * @param {Function} onClose Callback for actions to take when the dialog form is closed - * @param {Object} dialogOptions Modal dialog options - * @param {boolean} advantage Apply advantage to the roll (unless otherwise specified) - * @param {boolean} disadvantage Apply disadvantage to the roll (unless otherwise specified) - * @param {number} critical The value of d20 result which represents a critical success - * @param {number} fumble The value of d20 result which represents a critical failure - * @param {number} targetValue Assign a target value against which the result of this roll should be compared - * @param {boolean} elvenAccuracy Allow Elven Accuracy to modify this roll? - * @param {boolean} halflingLucky Allow Halfling Luck to modify this roll? - * - * @return {Promise} A Promise which resolves once the roll workflow has completed - */ - static async d20Roll({parts=[], data={}, event={}, rollMode=null, template=null, title=null, speaker=null, - flavor=null, fastForward=null, onClose, dialogOptions, - advantage=null, disadvantage=null, critical=20, fumble=1, targetValue=null, - elvenAccuracy=false, halflingLucky=false}={}) { - - // Handle input arguments - flavor = flavor || title; - speaker = speaker || ChatMessage.getSpeaker(); - parts = parts.concat(["@bonus"]); - rollMode = rollMode || game.settings.get("core", "rollMode"); - let rolled = false; - - // Define inner roll function - const _roll = function(parts, adv, form=null) { - - // Determine the d20 roll and modifiers - let nd = 1; - let mods = halflingLucky ? "r=1" : ""; - - // Handle advantage - if ( adv === 1 ) { - nd = elvenAccuracy ? 3 : 2; - flavor += ` (${game.i18n.localize("SW5E.Advantage")})`; - mods += "kh"; - } - - // Handle disadvantage - else if ( adv === -1 ) { - nd = 2; - flavor += ` (${game.i18n.localize("SW5E.Disadvantage")})`; - mods += "kl"; - } - - // Include the d20 roll - parts.unshift(`${nd}d20${mods}`); - - // Optionally include a situational bonus - if ( form !== null ) data['bonus'] = form.bonus.value; - if ( !data["bonus"] ) parts.pop(); - - // Optionally include an ability score selection (used for tool checks) - const ability = form ? form.ability : null; - if ( ability && ability.value ) { - data.ability = ability.value; - const abl = data.abilities[data.ability]; - if ( abl ) { - data.mod = abl.mod; - flavor += ` (${CONFIG.SW5E.abilities[data.ability]})`; - } - } - - // Execute the roll and flag critical thresholds on the d20 - let roll = new Roll(parts.join(" + "), data).roll(); - const d20 = roll.parts[0]; - d20.options.critical = critical; - d20.options.fumble = fumble; - if ( targetValue ) d20.options.target = targetValue; - - // Convert the roll to a chat message and return the roll - rollMode = form ? form.rollMode.value : rollMode; - roll.toMessage({ - speaker: speaker, - flavor: flavor - }, { rollMode }); - rolled = true; - return roll; - }; - - // Determine whether the roll can be fast-forward - if ( fastForward === null ) { - fastForward = event && (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey); - } - - // Optionally allow fast-forwarding to specify advantage or disadvantage - if ( fastForward ) { - if ( advantage || event.altKey ) return _roll(parts, 1); - else if ( disadvantage || event.ctrlKey || event.metaKey ) return _roll(parts, -1); - else return _roll(parts, 0); - } - - // Render modal dialog - template = template || "systems/sw5e/templates/chat/roll-dialog.html"; - let dialogData = { - formula: parts.join(" + "), - data: data, - rollMode: rollMode, - rollModes: CONFIG.rollModes, - config: CONFIG.SW5E - }; - const html = await renderTemplate(template, dialogData); - - // Create the Dialog window - let roll; - return new Promise(resolve => { - new Dialog({ - title: title, - content: html, - buttons: { - advantage: { - label: game.i18n.localize("SW5E.Advantage"), - callback: html => roll = _roll(parts, 1, html[0].children[0]) - }, - normal: { - label: game.i18n.localize("SW5E.Normal"), - callback: html => roll = _roll(parts, 0, html[0].children[0]) - }, - disadvantage: { - label: game.i18n.localize("SW5E.Disadvantage"), - callback: html => roll = _roll(parts, -1, html[0].children[0]) - } - }, - default: "normal", - close: html => { - if (onClose) onClose(html, parts, data); - resolve(rolled ? roll : false) - } - }, dialogOptions).render(true); - }) - } - - /* -------------------------------------------- */ - - /** - * A standardized helper function for managing core 5e "d20 rolls" - * - * Holding SHIFT, ALT, or CTRL when the attack is rolled will "fast-forward". - * This chooses the default options of a normal attack with no bonus, Critical, or no bonus respectively - * - * @param {Array} parts The dice roll component parts, excluding the initial d20 - * @param {Actor} actor The Actor making the damage roll - * @param {Object} data Actor or item data against which to parse the roll - * @param {Event|object}[event The triggering event which initiated the roll - * @param {string} rollMode A specific roll mode to apply as the default for the resulting roll - * @param {String} template The HTML template used to render the roll dialog - * @param {String} title The dice roll UI window title - * @param {Object} speaker The ChatMessage speaker to pass when creating the chat - * @param {string} flavor Flavor text to use in the posted chat message - * @param {boolean} allowCritical Allow the opportunity for a critical hit to be rolled - * @param {Boolean} critical Flag this roll as a critical hit for the purposes of fast-forward rolls - * @param {Boolean} fastForward Allow fast-forward advantage selection - * @param {Function} onClose Callback for actions to take when the dialog form is closed - * @param {Object} dialogOptions Modal dialog options - * - * @return {Promise} A Promise which resolves once the roll workflow has completed - */ - static async damageRoll({parts, actor, data, event={}, rollMode=null, template, title, speaker, flavor, - allowCritical=true, critical=false, fastForward=null, onClose, dialogOptions}) { - - // Handle input arguments - flavor = flavor || title; - speaker = speaker || ChatMessage.getSpeaker(); - rollMode = game.settings.get("core", "rollMode"); - let rolled = false; - - // Define inner roll function - const _roll = function(parts, crit, form) { - data['bonus'] = form ? form.bonus.value : 0; - let roll = new Roll(parts.join("+"), data); - - // Modify the damage formula for critical hits - if ( crit === true ) { - let add = (actor && actor.getFlag("sw5e", "savageAttacks")) ? 1 : 0; - let mult = 2; - roll.alter(add, mult); - flavor = `${flavor} (${game.i18n.localize("SW5E.Critical")})`; - } - - // Convert the roll to a chat message - rollMode = form ? form.rollMode.value : rollMode; - roll.toMessage({ - speaker: speaker, - flavor: flavor - }, { rollMode }); - rolled = true; - return roll; - }; - - // Determine whether the roll can be fast-forward - if ( fastForward === null ) { - fastForward = event && (event.shiftKey || event.altKey || event.ctrlKey || event.metaKey); - } - - // Modify the roll and handle fast-forwarding - if ( fastForward ) return _roll(parts, critical || event.altKey); - else parts = parts.concat(["@bonus"]); - - // Render modal dialog - template = template || "systems/sw5e/templates/chat/roll-dialog.html"; - let dialogData = { - formula: parts.join(" + "), - data: data, - rollMode: rollMode, - rollModes: CONFIG.rollModes - }; - const html = await renderTemplate(template, dialogData); - - // Create the Dialog window - let roll; - return new Promise(resolve => { - new Dialog({ - title: title, - content: html, - buttons: { - critical: { - condition: allowCritical, - label: game.i18n.localize("SW5E.CriticalHit"), - callback: html => roll = _roll(parts, true, html[0].children[0]) - }, - normal: { - label: game.i18n.localize(allowCritical ? "SW5E.Normal" : "SW5E.Roll"), - callback: html => roll = _roll(parts, false, html[0].children[0]) - }, - }, - default: "normal", - close: html => { - if (onClose) onClose(html, parts, data); - resolve(rolled ? roll : false); - } - }, dialogOptions).render(true); - }); - } -}