From f37af823606d0a5218557bc2f9e36736749ad744 Mon Sep 17 00:00:00 2001 From: TheLastScrub <67403321+TheLastScrub@users.noreply.github.com> Date: Sun, 23 Jun 2024 18:08:21 -0700 Subject: [PATCH] Include Options for uncommon and rare rolls in Roll Dialogue (GitHub #124) --- module/roll/roll.js | 101 ++++++++++++++++++++++++++++++++++++++++---- 1 file changed, 93 insertions(+), 8 deletions(-) diff --git a/module/roll/roll.js b/module/roll/roll.js index 9d6df3a..09542b3 100644 --- a/module/roll/roll.js +++ b/module/roll/roll.js @@ -177,6 +177,54 @@ export class DGPercentileRoll extends DGRoll { } }, }, + roll40Negative: { + label: "-40", + callback: (html) => { + try { + const rollMode = html.find("[name='rollMode']").val(); + const targetModifier = -40; + resolve({ targetModifier, rollMode }); + } catch (ex) { + reject(console.log(ex)); + } + }, + }, + roll20Negative: { + label: "-20", + callback: (html) => { + try { + const rollMode = html.find("[name='rollMode']").val(); + const targetModifier = -20; + resolve({ targetModifier, rollMode }); + } catch (ex) { + reject(console.log(ex)); + } + }, + }, + roll20Positive: { + label: "+20", + callback: (html) => { + try { + const rollMode = html.find("[name='rollMode']").val(); + const targetModifier = 20; + resolve({ targetModifier, rollMode }); + } catch (ex) { + reject(console.log(ex)); + } + }, + }, + roll40Positive: { + label: "+40", + callback: (html) => { + try { + const rollMode = html.find("[name='rollMode']").val(); + const targetModifier = 40; + resolve({ targetModifier, rollMode }); + } catch (ex) { + reject(console.log(ex)); + } + }, + }, }, }).render(true); }); @@ -206,9 +254,7 @@ export class DGPercentileRoll extends DGRoll { let label = `${game.i18n.localize("DG.Roll.Rolling")} ${ this.localizedKey - } ${game.i18n.localize("DG.Roll.Target")} ${ - this.target + this.modifier - }`; + } ${game.i18n.localize("DG.Roll.Target")} ${this.effectiveTarget}%`; // "Inhuman" stat being rolled. See function for details. if (this.isInhuman) { label = `${game.i18n.localize("DG.Roll.Rolling")} ${ @@ -216,11 +262,13 @@ export class DGPercentileRoll extends DGRoll { } [${game.i18n .localize("DG.Roll.Inhuman") .toUpperCase()}] ${game.i18n.localize("DG.Roll.Target")} ${ - this.target + this.modifier + this.effectiveTarget }`; } if (this.modifier) { - label += ` (${DGUtils.formatStringWithLeadingPlus(this.modifier)}%)`; + label += ` (${this.target}${DGUtils.formatStringWithLeadingPlus( + this.modifier, + )}%)`; } let resultString = ""; @@ -315,7 +363,12 @@ export class DGPercentileRoll extends DGRoll { * @returns {Boolean} */ get isInhuman() { - if (this.target + this.modifier > 99 && this.type === "stat") { + /* + Changing this to only consider the base x5 stat target for whether something is 'inhuman' + beecause I do not think the intent was an Agent with a high strength getting a +40% bonus to be considered 'inhuman' + and therefore benefit from the increased crit threshold, although could be wrong about this. + */ + if (this.target > 99 && this.type === "stat") { return true; } return false; @@ -342,7 +395,7 @@ export class DGPercentileRoll extends DGRoll { // If inhuman and the roll is below the regular (non-x5) value of the stat, it is a critical. // E.g. a CON of 25, a d100 roll of 21 would be a critical. - if (this.isInhuman && this.total <= (this.target + this.modifier) / 5) { + if (this.isInhuman && this.total <= this.target / 5) { isCritical = true; } @@ -363,7 +416,39 @@ export class DGPercentileRoll extends DGRoll { // A roll of 100 always (critically) fails, even for inhuman rolls. if (this.total === 100) return false; - return this.total <= this.target + this.modifier; + return this.total <= this.effectiveTarget; + } + + /** + * Actual target for the roll accounting for modifier if present. + * Floored to 1 if a negative modifier would bring it below 1. + * + * @returns {null|integer} + */ + get effectiveTarget() { + let target = 1; + + if (!this.target || Number.isNaN(this.target)) { + return null; + } + + target = parseInt(this.target); + + if (this.modifier && !Number.isNaN(this.modifier)) { + const modifier = parseInt(this.modifier); + + target += modifier; + + // per agent's handbook (pg.43), a negative modifier can't lower a target below 1% + target = Math.max(target, 1); + } + + // an 'inhuman' stat test can exceed 99% as a target, but skill tests otherwise cannot (agents handbook pg.43) + if (!this.isInhuman) { + target = Math.min(target, 99); + } + + return target; } }