Forum

Midi QoL / DAE – He...
 
Notifications
Clear all

Question Midi QoL / DAE – Hex Automation

   RSS

1
Topic starter

I would like to set up automation for the 5E hex spell, including bonus damage and disadvantage on a chosen ability's checks. Has anyone set this up before? Any suggestions are appreciated.

1 Answer
1

You're well into the territory where you're going to need a macro here.  Probably two macros (or one macro with two if statements to check how it's being called).

I'm going to sketch out an approach here - this probably isn't the only way to do it, but it *should* work.  Not testing this, this is off the cuff for now.

Firstly, I'm assuming you have MidiQoL, DAE, and Item Macro installed.  Item Macro isn't essential here, but it's handy to glue the macro to the item you're working with (if you're not using it, then just make this as a macro in the macro folder, and wherever something is set to ItemMacro, it should be set to that macro name).

We're going to need both an OnUseMacro and a DamageBonusMacro on the player, here, and an effect on the target.

The rough idea is:

1) Apply a condition to the target (DAE non-transfer effect), which gives it disadvantage on an ability check chosen by the player (onUseMacro to change what ability check that condition gives disadvantage to)
2) Apply a DamageBonusMacro to the player (DAE Transfer Effect), which checks for the effect from 1), and deals an extra d6 damage to the target if it's there (and the ability which triggered the DBM has an attack roll).

Cursing a new creature can be handled by recasting the spell, no need for special support there.

Setting up the item, we want OnUseMacro to be ItemMacro, and then we want two Active Effects.

The first should be a non-transfer effect (i.e. with "transfer effect to actor on equip" unselected), called Hex, which has flags.midi-qol.disadvantage.ability.check.str CUSTOM 1 (we'll change this to the right ability later).

The second should be a transfer effect, call it Hex2 (since we want a different name, so we don't deal extra damage to ourselves), with DamageBonusMacro CUSTOM ItemMacro

The Item Macro for the item wants to be of the form:

if(args[0].tag === OnUse){
  //do the stuff we need in an OnUseMacro
}

if(args[0].tag === DamageBonus){
  //do the stuff we need in a DamageBonusMacro
}

For 1) (the OnUseMacro to select the ability), let's take some inspiration from Kandashi's implementation of Absorb Elements: https://github.com/kandashi/Macros/blob/master/Spell%20Macros/1st%20Level/Absorb%20Elements.js

First we need to define the target, and the target's actor.  Do this before the if statements above, since we'll need the same variables for both

let target = canvas.tokens.get(args[0].targets[0]._id) //we can assume there's only one target
let tactor = target?.actor //we can assume there is a target

if(!tactor) return; //if we haven't found a target actor, we should back out to avoid error spam

Then we need to provide a dialog for the user to choose which stat to curse.  All this goes within the OnUse if block:

new Dialog({
        title: 'Choose a damage type',
        content: `
          <form class="flexcol">
            <div class="form-group">
              <select id="stat">
                <option value="str">Strength</option>
                <option value="dex">Dexterity</option>
                <option value="con">Constitution</option>
                <option value="int">Intelligence</option>
                <option value="wis">Wisdom</option>
                <option value="cha">Charisma</option>
              </select>
            </div>
          </form>
        `,
        buttons: {
            yes: {
                icon: '<i class="fas fa-bolt"></i>',
                label: 'Select',
                callback: async (html) => {
                    let stat = html.find('#stat').val();
                    let effect =  tactor.effects.find(i => i.data.label === "Hex");
                    let changes = effect.data.changes;
                    changes[0].key = `flags.midi-qol.disadvantage.ability.check.${stat}`;
                    await effect.update({changes});
                },
            },
        }
    }).render(true);

What this does is to present the user with a dropdown to choose a stat, and then automatically changes the stat affected by the DAE to the appropriate stat (this is going to have to be adjusted to run the actual update as a GM, while keeping the bulk of the macro running playerside - this can either be done by doing "await macro.execute(game.macros.getName("Update Effect"), changes)", to call a "run as GM macro" (made using Furnace) called Update Effect which just contains "return await effect.update({args[0]})" , or by using Bad Ideas Toolkit, and replacing "await effect.update({changes})" with "await badIdeas.entityUpdate(effect, {changes})" ).

Dealing an extra 1d6 on hit is done within the DamageBonusMacro.  THe approach sketched out below doesn't account for having more than one warlock who casts Hex (since it doesn't check *who* cast Hex on the target, just that it's there),

if (!args[0].attackRoll) return; //you only get the bonus damage on attacks
if (!tactor.effects.find(i => i.data.label === "Hex")) return; //check if the Hex effect is present, return if not there.
return {damageRoll: `1d6[necrotic]`, flavor: "Hex Damage"}; //deal an extra 1d6 of damage if we didn't cancel out earlier

I'm going to put that all together in the next post, because it turns out copy/pasting from clode blocks within a post is hard.

 

let target = canvas.tokens.get(args[0]?.targets[0]?._id) //we can assume there's only one target
let tactor = target?.actor //we can assume there is a target

if(!tactor) return; //if we haven't found a target actor, we should back out to avoid error spam

if(args[0].tag === OnUse){
  new Dialog({
        title: 'Choose a damage type',
        content: `
          <form class="flexcol">
            <div class="form-group">
              <select id="stat">
                <option value="str">Strength</option>
                <option value="dex">Dexterity</option>
                <option value="con">Constitution</option>
                <option value="int">Intelligence</option>
                <option value="wis">Wisdom</option>
                <option value="cha">Charisma</option>
              </select>
            </div>
          </form>
        `,
        buttons: {
            yes: {
                icon: '<i class="fas fa-bolt"></i>',
                label: 'Select',
                callback: async (html) => {
                    let stat = html.find('#stat').val();
                    let effect =  tactor.effects.find(i => i.data.label === "Hex");
                    let changes = effect.data.changes;
                    changes[0].key = `flags.midi-qol.disadvantage.ability.check.${stat}`;
                    await effect.update({changes});
                },
            },
        }
    }).render(true);
}

if(args[0].tag === DamageBonus){
 if (!args[0].attackRoll) return; //you only get the bonus damage on attacks
  if (!tactor.effects.find(i => i.data.label === "Hex")) return; //check if the Hex effect is present, return if not there.
  return {damageRoll: `1d6[necrotic]`, flavor: "Hex Damage"}; //deal an extra 1d6 of damage if we didn't cancel out earlier
}

Love this implementation but I'm apparently too dumb to get it working.  The macro provided keeps telling me args is undefined.  Has syntax changed in 0.8.6?

Share: