Daggerheart-fvtt/module/documents/action.mjs

110 lines
3.4 KiB
JavaScript

/**
* Base Action Class
*/
export class Action {
/**
* Roll an action
* @param {any} action The actual action object
* @param {string} actionId The key id of the action
*/
static async rollAction(action, actionId) {
const drives = await this._prepareActionRoll(actionId);
if (drives == null) return; // dialog canceled
const diceCount = action.value + drives;
let r;
if (diceCount == 0) {
// no action rating, roll two dice and keep lower result
const normalDice = new Die({
number: 2,
faces: 6,
modifiers: ['kl'],
});
r = Roll.fromTerms([normalDice]);
} else if (action.gilded) {
// gilded action, replace one die with a gilded die
const normalDice = new Die({
number: diceCount - 1,
faces: 6,
modifiers: ['kh'],
});
const plus = new OperatorTerm({ operator: '+' });
const gildedDice = new Die({
number: 1,
faces: 6,
options: { flavor: 'gilded' },
modifiers: ['kh'],
});
r = Roll.fromTerms([normalDice, plus, gildedDice]);
} else {
// normal roll
const normalDice = new Die({ number: diceCount, faces: 6 });
r = Roll.fromTerms([normalDice]);
}
await r.evaluate();
// construct chat message
const speaker = ChatMessage.getSpeaker({ actor: this.actor });
const rollMode = game.settings.get('core', 'rollMode');
const label = `[action] ${actionId}`;
const content = await renderTemplate('systems/candelafvtt/templates/chat/roll.hbs', r);
const msg = {
content: content,
speaker: speaker,
rollMode: rollMode,
flavor: label,
type: CONST.CHAT_MESSAGE_TYPES.ROLL,
rolls: [r],
};
AudioHelper.play({ src: 'sounds/dice.wav', volume: 0.8, autoplay: true, loop: false }, true);
// post to chat
CONFIG.ChatMessage.documentClass.create(msg, {});
return r;
}
/**
* Prepare a roll by getting necessary information via user dialog
* @param {string} actionId The key id of the action
* @private
*/
static async _prepareActionRoll(actionId) {
let title = actionId;
let content = await renderTemplate('systems/candelafvtt/templates/chat/roll-dialog.hbs');
let options = {};
return new Promise(resolve => {
new Dialog(
{
title,
content,
buttons: {
roll: {
label: game.i18n.localize('CANDELAFVTT.roll'),
callback: html => resolve(this._onRollDialogSubmit(html)),
},
},
default: 'roll',
close: () => resolve(null),
},
options
).render(true);
});
}
/**
* Read the drives from the submitted form
* @param {html} html The submitted html containing the form
* @private
*/
static async _onRollDialogSubmit(html) {
const form = html[0].querySelector('form');
const drives = parseInt(form.drives.value);
return drives;
}
}