foundryvtt / pf2e

A community contributed game system for Pathfinder Second Edition.
https://foundryvtt.com/packages/pf2e
Apache License 2.0
413 stars 345 forks source link

Fix for Treat wounds not handling Natural Medicine feat #752

Closed cswendrowski closed 2 years ago

cswendrowski commented 4 years ago

In GitLab by @JamzTheMan on Sep 3, 2020, 22:12

I don't believe we can submit PR's against compendium items? So here I submit my changes to Treat Wounds that will use Nature vs Medicine if actor has Natural Medicine feat.

let toChat = (content, rollString) => {
  let chatData = {
    user: game.user.id,
    content,
    speaker: ChatMessage.getSpeaker(),
  }
  ChatMessage.create(chatData, {})
  if (rollString) {
    let roll = new Roll(rollString).roll();
    chatData = {
      ...chatData,
      flavor: "Treat Wounds Healing",
      type: CONST.CHAT_MESSAGE_TYPES.ROLL,
      roll
    }
    ChatMessage.create(chatData, {})
  }

}

const handleCrits = (roll) => roll === 1 ? -1 : (roll === 20 ? 1 : 0);

let rollTreatWounds = (args) => {

  let { DC, bonus, skillValue, skillUsed, name } = args;
  const roll = new Roll(`d20`).roll().total;
  const crit = handleCrits(roll)

  let message = `${name} Treats Wounds using ${skillUsed} at a DC ${DC}... they roll a [[${roll}+${skillValue}]] and`;

  let success = 0;

  if (roll + skillValue >= DC + 10) {
    success = 2;
  } else if (roll + skillValue >= DC) {
    success = 1;
  } else if (roll + skillValue <= DC - 10) {
    // Fix for crit fail to match CRB 10 or less
    success = -1;
  }

  success += crit;

  if (success > 1) {
    toChat(`${message} critically succeed!`, `4d8+${bonus}`);
  } else if (success === 1) {
    toChat(`${message} succeed.`, `2d8+${bonus}`);
  } else if (success < 0) {
    toChat(`${message} critically fail! The target takes damage.`, '1d8');
  } else if (success === 0) {
    toChat(`${message} fail.`);
  }
}

let applyChanges = false;
new Dialog({
  title: `Treat Wounds`,
  content: `
    <div>Select a target DC, remember that you can't attempt a heal above your proficiency. Attempting to do so will downgrade the DC and amount healed to the highest you're capable of.<div>
    <hr/>
    <form>
      <div class="form-group">
        <label>Medicine DC: </label>
        <select id="dc-type" name="dc-type">
          <option value="trained">Trained DC 15</option>
          <option value="expert">Expert DC 20, +10 Healing</option>
          <option value="master">Master DC 30, +30 Healing</option>
          <option value="legendary">Legendary DC 40, +50 Healing</option>
        </select>
      </div>
      <div class="form-group">
        <label>Modifier: </label>
        <input id="modifier" name="modifier" type="number"/>
      </div>
      <br />
    </form>
    `,
  buttons: {
    yes: {
      icon: "<i class='fas fa-check'></i>",
      label: `Treat Wounds`,
      callback: () => applyChanges = true
    },
    no: {
      icon: "<i class='fas fa-times'></i>",
      label: `Cancel`
    },
  },
  default: "yes",
  close: html => {
    if (applyChanges) {
      for (let token of canvas.tokens.controlled) {
        const { name } = token;
        const { med } = token.actor.data.data.skills;
        const { nat } = token.actor.data.data.skills

        const feats = new Set(token.actor.data.items
          .filter(item => item.type === 'feat')
          .map(item => item.name))

        const hasNaturalMedicine = feats.has('Natural Medicine')
        console.log("hasNaturalMedicine: " + hasNaturalMedicine)

        var skillRank = med.rank;
        var skillValue = med.value;
        var skillUsed = "Medicine"

        if (hasNaturalMedicine) {
          skillRank = nat.rank;
          skillValue = nat.value;
          skillUsed = "Nature";
        }

        console.log(skillUsed + " skillValue: " + skillValue)

        let prof = html.find('[name="dc-type"]')[0].value || "trained";
        let mod = parseInt(html.find('[name="modifier"]')[0].value) || 0;
        if (prof === 'legendary') {
          if (skillRank >= 4) {
            return rollTreatWounds({ DC: 40 + mod, bonus: 50, skillValue, skillUsed, name });
          }
          prof = 'master';
        }
        if (prof === 'master') {
          if (skillRank >= 3) {
            return rollTreatWounds({ DC: 30 + mod, bonus: 30, skillValue, skillUsed, name });
          }
          prof = 'expert';
        }
        if (prof === 'expert') {
          if (skillRank >= 2) {
            return rollTreatWounds({ DC: 20 + mod, bonus: 10, skillValue, skillUsed, name });
          }
          prof = 'trained';
        }
        if (prof === 'trained') {
          if (skillRank >= 1) {
            return rollTreatWounds({ DC: 15 + mod, bonus: 0, skillValue, skillUsed, name });
          }
        }

        toChat(`${name} is not trained in ${skillUsed}, and doesn't know how to treat wounds!`);
        return;
      }
    }
  }
}).render(true);
cswendrowski commented 3 years ago

In GitLab by @TMun on Jan 13, 2021, 16:43

marked this issue as related to #994

cswendrowski commented 3 years ago

In GitLab by @stwlam on Feb 8, 2021, 24:51

Addressed in https://gitlab.com/hooking/foundry-vtt---pathfinder-2e/-/merge_requests/1984