110 lines
3.4 KiB
JavaScript
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;
|
||
|
}
|
||
|
}
|