Skip to content

Commit

Permalink
Merge pull request #3249 from foundryvtt/damage/negate-healing
Browse files Browse the repository at this point in the history
[#3248] Invert healing automatically in `calculateDamage`
  • Loading branch information
arbron authored Mar 18, 2024
2 parents d4427d8 + 9b3ecfb commit 49468fc
Show file tree
Hide file tree
Showing 2 changed files with 18 additions and 7 deletions.
23 changes: 17 additions & 6 deletions module/documents/actor/actor.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -858,15 +858,17 @@ export default class Actor5e extends SystemDocumentMixin(Actor) {
* Options for damage application.
*
* @typedef {object} DamageApplicationOptions
* @property {number} [multiplier=1] Amount by which to multiply all damage.
* @property {object|boolean} [ignore] Set to `true` to ignore all damage modifiers. If set to an object, then
* values can either be `true` to indicate that the all modifications of that
* type should be ignored, or a set of specific damage types for which it should
* be ignored.
* @property {number} [multiplier=1] Amount by which to multiply all damage.
* @property {boolean} [invertHealing=true] Automatically invert healing types to it heals, rather than damages.
* @property {object|boolean} [ignore] Set to `true` to ignore all damage modifiers. If set to an object, then
* values can either be `true` to indicate that the all modifications of
* that type should be ignored, or a set of specific damage types for which
* it should be ignored.
* @property {boolean|Set<string>} [ignore.immunity] Should this actor's damage immunity be ignored?
* @property {boolean|Set<string>} [ignore.resistance] Should this actor's damage resistance be ignored?
* @property {boolean|Set<string>} [ignore.vulnerability] Should this actor's damage vulnerability be ignored?
* @property {boolean|Set<string>} [ignore.modification] Should this actor's damage modification be ignored?
* @property {"damage"|"healing"} [only] Apply only damage or healing parts. Untyped rolls will always be applied.
*/

/**
Expand Down Expand Up @@ -981,11 +983,17 @@ export default class Actor5e extends SystemDocumentMixin(Actor) {
return !config.bypasses?.intersection(properties)?.size;
};

const skipped = type => {
if ( only === "damage" ) return type in CONFIG.DND5E.healingTypes;
if ( only === "healing" ) return type in CONFIG.DND5E.damageTypes;
return true;
};

const rollData = this.getRollData({deterministic: true});

damages.forEach(d => {
// Skip damage types with immunity
if ( !ignore("immunity", d.type) && hasEffect("di", d.type, d.properties) ) {
if ( skipped(d.type) || (!ignore("immunity", d.type) && hasEffect("di", d.type, d.properties)) ) {
d.value = 0;
return;
}
Expand All @@ -1005,6 +1013,9 @@ export default class Actor5e extends SystemDocumentMixin(Actor) {
// Apply type-specific damage vulnerability
if ( !ignore("vulnerability", d.type) && hasEffect("dv", d.type, d.properties) ) damageMultiplier *= 2;

// Negate healing types
if ( (options.invertHealing !== false) && (d.type === "healing") ) damageMultiplier *= -1;

d.value = d.value * damageMultiplier;
});

Expand Down
2 changes: 1 addition & 1 deletion module/documents/chat-message.mjs
Original file line number Diff line number Diff line change
Expand Up @@ -463,7 +463,7 @@ export default class ChatMessage5e extends ChatMessage {
properties: new Set(roll.options.properties ?? [])
}));
return Promise.all(canvas.tokens.controlled.map(t => {
return t.actor?.applyDamage(damages, { multiplier, ignore: true });
return t.actor?.applyDamage(damages, { multiplier, invertHealing: false, ignore: true });
}));
}

Expand Down

0 comments on commit 49468fc

Please sign in to comment.