From 73ca6dc36452979646d0c9aa56f9a25c47daa514 Mon Sep 17 00:00:00 2001 From: Stefan Zermatten Date: Sat, 5 Mar 2022 18:40:18 +0200 Subject: [PATCH] Damage multipliers are now applied to damage dealt --- .../applyPropertyByType/applyDamage.js | 62 ++++++++++++++++++- .../viewers/shared/PropertyField.vue | 3 +- 2 files changed, 63 insertions(+), 2 deletions(-) diff --git a/app/imports/api/engine/actions/applyPropertyByType/applyDamage.js b/app/imports/api/engine/actions/applyPropertyByType/applyDamage.js index 5e2153fc..acf42475 100644 --- a/app/imports/api/engine/actions/applyPropertyByType/applyDamage.js +++ b/app/imports/api/engine/actions/applyPropertyByType/applyDamage.js @@ -1,3 +1,4 @@ +import { some, intersection, difference } from 'lodash'; import applyProperty from '../applyProperty.js'; import { dealDamageWork } from '/imports/api/creature/creatureProperties/methods/dealDamage.js'; import {insertCreatureLog} from '/imports/api/creature/log/CreatureLogs.js'; @@ -62,13 +63,16 @@ export default function applyDamage(node, { prop.amount.value = toString(reduced); } - const damage = +reduced.value; + let damage = +reduced.value; // If we didn't end up with a constant of finite amount, give up if (reduced?.parseType !== 'constant' && !isFinite(reduced.value)){ return applyChildren(); } + // Round the damage to a whole number + damage = Math.floor(damage); + // Memoise the damage suffix for the log let suffix = (criticalHit ? ' critical ' : ' ') + prop.damageType + @@ -78,6 +82,14 @@ export default function applyDamage(node, { // Iterate through all the targets damageTargets.forEach(target => { + // Apply weaknesses/resistances/immunities + damage = applyDamageMultipliers({ + target, + damage, + damageProp: prop, + logValue + }); + // Deal the damage to the target let damageDealt = dealDamageWork({ creature: target, @@ -114,3 +126,51 @@ export default function applyDamage(node, { }); return applyChildren(); } + +function applyDamageMultipliers({target, damage, damageProp, logValue}){ + const damageType = damageProp?.damageType; + if (!damageType) return; + + const multiplier = target?.variables?.[damageType]; + if (!multiplier) return; + + const damageTypeText = damageType == 'healing' ? 'healing': `${damageType} damage`; + + if ( + multiplier.immunity && + some(multiplier.immunities, multiplierAppliesTo(damageProp)) + ){ + logValue.push(`Immune to ${damageTypeText}`); + return 0; + } else { + if ( + multiplier.resistance && + some(multiplier.resistances, multiplierAppliesTo(damageProp)) + ){ + logValue.push(`Resistant to ${damageTypeText}`); + damage = Math.floor(damage / 2); + } + if ( + multiplier.vulnerability && + some(multiplier.vulnerabilities, multiplierAppliesTo(damageProp)) + ){ + logValue.push(`Vulnerable to ${damageTypeText}`); + damage = Math.floor(damage * 2); + } + return damage; + } +} + +function multiplierAppliesTo(damageProp){ + return multiplier => { + const hasRequiredTags = difference( + multiplier.includeTags, damageProp.tags + ).length === 0; + + const hasNoExcludedTags = intersection( + multiplier.excludeTags, damageProp.tags + ).length === 0; + + return hasRequiredTags && hasNoExcludedTags; + } +} diff --git a/app/imports/ui/properties/viewers/shared/PropertyField.vue b/app/imports/ui/properties/viewers/shared/PropertyField.vue index 4ec09bba..fa48a003 100644 --- a/app/imports/ui/properties/viewers/shared/PropertyField.vue +++ b/app/imports/ui/properties/viewers/shared/PropertyField.vue @@ -19,7 +19,7 @@ {{ name }}