MCDM-Productions / mcdm-core

Common driver for MCDM-specific functionality introduced by their dnd5e supplements for FoundryVTT
Other
3 stars 2 forks source link

BH: Ferocity Gain #3

Closed trioderegion closed 2 years ago

trioderegion commented 2 years ago

Template macro:

const feroPath = 'system.resources.primary.value';

//find all owned Monstrous Companions
const comps = game.actors.filter( actor => actor.isOwner && !!actor.items.find(item => item.system.identifier == 'moncom'));

//find my possessed character's companion
const defaultCompId = character?.getFlag('mcdm-beastheart','ferolink')
const defaultCompName = game.actors.get(defaultCompId)?.name + " (Default)";

const companions = comps.reduce( (acc, actor) => acc += `<option value="${actor.id}">${actor.name}</option>`,defaultCompId ? `<option value="${defaultCompId}">${defaultCompName}</option>` : '');

let content = `
<form class="flexrow" style="margin-bottom:1em;">
  <div class="flexcol" style="align-items:center;">
    <label for="companion"><h3>Companion</h3></label>
    <select name="companion">${companions}</select>
  </div>
  <div class="flexcol" style="align-items:flex-end;">
    <label for="base"><h3>Base</h3></label>
    <h4 name="base" style="margin-top:auto;margin-bottom:auto;">1d4 + </h4>
  </div>
  <div class="flexcol" style="align-items:center;">
    <label for="nearby"><h3>Hostiles</h3></label>
    <input type="number" name="nearby" placeholder=0>
  </div>
</form>`;

let callback = (html) => {
  const companion = html.find('[name="companion"]').val();
  const nearby = html.find('[name="nearby"]').val();
  return {companion, nearby: Number(nearby)};
};

//prompt for companion and number of nearby enemies
let result = await Dialog.prompt({content, callback, title: 'Ferocity: Select Companion and Nearby Creatures', rejectClose: false, options:{width: '100%'}})

console.log(result)

if (result == undefined) return;

const {companion, nearby} = result;

const chosenCompanion = game.actors.get(companion);
const caregiver = game.actors.get(chosenCompanion.getFlag('mcdm-beastheart','ferolink'));
const currentFerocity = getProperty(caregiver, feroPath);

const feroRoll = await new Roll(`${currentFerocity}[current] + @scale.beastheart.ferogain + 1d4 + ${nearby}`).evaluate({async:true}, caregiver.getRollData() );
const total = feroRoll.total;

await feroRoll.toMessage({flavor: total >= 10 ? 'Ferocity Roll - Rampage Threat!' : 'Ferocity Roll', speaker: ChatMessage.getSpeaker({actor: chosenCompanion})});

await chosenCompanion.update({[feroPath]: total});

//Rampage check!
if(total>=10){
  const caregiver = game.actors.get(chosenCompanion.getFlag('mcdm-beastheart','ferolink'));
  const DC = 5 + total;

  content = `
<form class="flexrow" style="margin-bottom:1em;">
    <label for="action"><h3>Caregiver: ${caregiver.name}</h3></label>
    <select name="action">
      <option value="roll">Roll Animal Handling</option>
      <option value="pass">Force Pass</option>
      <option value="fail">Force Fail</option>
    </select>
</form>`;

  callback = (html) => {
    const action = html.find('[name="action"]').val();
    return action
  };

  result = await Dialog.prompt({content, callback, rejectClose: false, title: `DC ${DC} Rampage Check`})
  let checkPass = false;
  switch(result) {
    case 'roll':
      const d20roll = await caregiver.rollSkill('ani');
      checkPass = d20roll.total >= DC;
      break;
    case 'pass':
      checkPass = true;
      break;
    case 'fail':
      checkPass = false;
      break;
  }

  if(checkPass) {
    await ChatMessage.create({
      content: `${caregiver.name} keeps ${chosenCompanion.name}'s ferocity under control.`,
      speaker: ChatMessage.getSpeaker({actor: chosenCompanion}),
      flavor: `DC ${DC} Rampage Check`
    });
  } else {
    await ChatMessage.create({
      content: `${caregiver.name} is unable to control ${chosenCompanion.name}'s ferocity as they enter a rampage!`,
      speaker: ChatMessage.getSpeaker({actor: companion}),
      flavor: `DC ${DC} Rampage Check`
    });

    /* attempt to enable the pre-placed Rampage AE */

    // Do we have furious rampage?
    const furious = caregiver.items.getName('Furious Rampage');
    const aeLabel = !!furious ? 'Furious' : 'Rampaging';
    // Try to find the AE on the actor and enable it
    const effect = chosenCompanion.effects.find( e => e.label == aeLabel );
    if(effect) {
      await effect.update({disabled: false})
    } else {
      ui.notifications.warn(`Could not find expected AE "${aeLabel}" on "${chosenCompanion.name}" [${chosenCompanion.uuid}]`)
    }

  }
}