Checks V2 by Example - League-of-Fabulous-Developers/FoundryVTT-Fabula-Ultima GitHub Wiki
The following is a script macro to automate the Darkblade skill "Shadow Strike" with comments to explain what is being done and why. The macro should be executed by the player of the Darkblade.
// This is just a check to prevent the Hooks from being registered multiple times. We'll set "initialized" to "true" once all Hooks are registered.
if (!this.initialized) {
// Registering the prepareCheck Hook. We need to know if Shadow Strike is used before the check is rolled.
Hooks.on('projectfu.prepareCheck', (check, actor, item, registerCallback) => {
// We are only interested in accuracy checks.
if (check.type === 'accuracy') {
// Hooks are synchronous, so we need to register an asynchronous callback for our user interaction.
registerCallback(async (check) => {
// Ask the user if they want to use Shadow Strike
const use = await Dialog.confirm({
title: 'Use Shadow Strike?',
});
if (use) {
// Shadow Strike adds 1 MIG dice of damage to the roll, which we do here. "[black]" in the roll formula is the name of a Dice So Nice color preset to distinguish the Shadow Strike dice from the normal check dice.
const damageRoll = await new Roll(`1d${actor.system.attributes.mig.current}[black]`).roll();
// Saving our data in the "check.additionalData" object for later reference.
check.additionalData.shadowstrike = {
damage: damageRoll.total,
roll: damageRoll,
};
// We're using the CheckConfiguration utility to adjust the damage data.
// First we add a damage bonus with the label "Shadow Strike" and the value of our roll.
// Then we change the damage type to "dark".
game.projectfu.CheckConfiguration.configure(check)
.addDamageBonus('Shadow Strike', damageRoll.total)
.modifyDamage(damage => {
if (damage) damage.type = 'dark';
return damage;
});
}
});
}
});
// Registering the processCheck Hook.
Hooks.on('projectfu.processCheck', (check, actor, item) => {
// We're only interested in checks that made use of Shadow Strike and thus contain the data we need.
const shadowstrike = check.additionalData.shadowstrike;
if (shadowstrike) {
// Add our Shadow Strike roll to the check result so it can get picked up by Dice So Nice
check.additionalRolls.push(shadowstrike.roll);
delete shadowstrike.roll;
}
});
// Registering the renderCheck Hook.
Hooks.on('projectfu.renderCheck', (sections, check, actor, item) => {
// Again we're only interested in checks that made use of Shadow Strike and thus contain the data we need.
const shadowstrike = check.additionalData.shadowstrike;
if (shadowstrike) {
// Enrich some static HTML for the inline damage Shadow Strike deals to the user and then transform it into a "CheckSection". The order is lower than the default order for the check roll so that our section shows up before all the to hit and damage numbers.
sections.push(TextEditor.enrichHTML(`<div class="chat-desc"><p><b>Shadow Strike</b></p><p>You lost @LOSS[${shadowstrike.damage} hp] to activate the ability.</p></div>`).then(v => ({
content: v,
order: -1050,
})));
}
});
// Set "initialized" to true to prevent the Hooks from being registered multiple times and show a success message.
this.initialized = true;
ui.notifications.info('Shadow Strike automation activated!');
} else {
// Already initialized. Show a message saying as much.
ui.notifications.info('Shadow Strike automation already active!');
}