diff --git a/module/applications/sheets/api/base-actor.mjs b/module/applications/sheets/api/base-actor.mjs index e619daad..2fb3f68a 100644 --- a/module/applications/sheets/api/base-actor.mjs +++ b/module/applications/sheets/api/base-actor.mjs @@ -160,7 +160,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { inactives: [] }; - for (const effect of this.actor.allApplicableEffects({ noArmor: true })) { + for (const effect of this.actor.allApplicableEffects({ noTransferArmor: true })) { const list = effect.active ? context.effects.actives : context.effects.inactives; list.push(effect); } diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index f6ffe75f..23d30cb2 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -295,17 +295,19 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel static async getEffects(actor, effectParent) { if (!actor) return []; - return Array.from(await actor.allApplicableEffects()).filter(effect => { - /* Effects on weapons only ever apply for the weapon itself */ - if (effect.parent.type === 'weapon') { - /* Unless they're secondary - then they apply only to other primary weapons */ - if (effect.parent.system.secondary) { - if (effectParent?.type !== 'weapon' || effectParent?.system.secondary) return false; - } else if (effectParent?.id !== effect.parent.id) return false; - } + return Array.from(await actor.allApplicableEffects({ noTransferArmor: true, noSelfArmor: true })).filter( + effect => { + /* Effects on weapons only ever apply for the weapon itself */ + if (effect.parent.type === 'weapon') { + /* Unless they're secondary - then they apply only to other primary weapons */ + if (effect.parent.system.secondary) { + if (effectParent?.type !== 'weapon' || effectParent?.system.secondary) return false; + } else if (effectParent?.id !== effect.parent.id) return false; + } - return !effect.isSuppressed; - }); + return !effect.isSuppressed; + } + ); } /** diff --git a/module/data/activeEffect/armorEffect.mjs b/module/data/activeEffect/armorEffect.mjs index f52f5efc..597cdf27 100644 --- a/module/data/activeEffect/armorEffect.mjs +++ b/module/data/activeEffect/armorEffect.mjs @@ -1,3 +1,5 @@ +import { getScrollTextData } from '../../helpers/utils.mjs'; + /** * ArmorEffects are ActiveEffects that have a static changes field of length 1. It includes current and maximum armor. * When applied to a character, it adds to their currently marked and maximum armor. @@ -185,6 +187,19 @@ export default class ArmorEffect extends foundry.data.ActiveEffectTypeDataModel ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.cannotAlterArmorEffectType')); return false; } + + if (changes.system.changes[0].value !== this.armorChange.value && this.parent.actor?.type === 'character') { + const increased = changes.system.changes[0].value > this.armorChange.value; + const value = -1 * (this.armorChange.value - changes.system.changes[0].value); + options.scrollingTextData = [getScrollTextData(increased, value, 'armor')]; + } } } + + _onUpdate(changes, options, userId) { + super._onUpdate(changes, options, userId); + + if (options.scrollingTextData && this.parent.actor?.type === 'character') + this.parent.actor.queueScrollText(options.scrollingTextData); + } } diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs index 3b4de08d..14bc4fe8 100644 --- a/module/data/actor/base.mjs +++ b/module/data/actor/base.mjs @@ -1,6 +1,6 @@ import DHBaseActorSettings from '../../applications/sheets/api/actor-setting.mjs'; import DHItem from '../../documents/item.mjs'; -import { getScrollTextData } from '../../helpers/utils.mjs'; +import { getResourceScrollTextData } from '../../helpers/utils.mjs'; const fields = foundry.data.fields; @@ -211,7 +211,7 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel { const textData = Object.keys(changes.system.resources).reduce((acc, key) => { const resource = changes.system.resources[key]; if (resource.value !== undefined && resource.value !== this.resources[key].value) { - acc.push(getScrollTextData(this.resources, resource, key)); + acc.push(getResourceScrollTextData(this.resources, resource, key)); } return acc; diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 447da3bf..334b0c5e 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -8,7 +8,7 @@ * @property {boolean} isInventoryItem- Indicates whether items of this type is a Inventory Item */ -import { addLinkedItemsDiff, getScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs'; +import { addLinkedItemsDiff, getResourceScrollTextData, updateLinkedItemApps } from '../../helpers/utils.mjs'; import { ActionsField } from '../fields/actionField.mjs'; import FormulaField from '../fields/formulaField.mjs'; @@ -224,7 +224,11 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { const armorChanged = changed.system?.marks?.value !== undefined && changed.system.marks.value !== this.marks.value; if (armorChanged && autoSettings.resourceScrollTexts && this.parent.parent?.type === 'character') { - const armorData = getScrollTextData(this.parent.parent.system.resources, changed.system.marks, 'armor'); + const armorData = getResourceScrollTextData( + this.parent.parent.system.resources, + changed.system.marks, + 'armor' + ); options.scrollingTextData = [armorData]; } diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 2eafc70f..da399df5 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -573,8 +573,7 @@ export default class DhpActor extends Actor { const availableStress = this.system.resources.stress.max - this.system.resources.stress.value; const canUseArmor = - this.system.armor && - this.system.armor.system.marks.value < this.system.armorScore && + this.system.armorScore.value < this.system.armorScore.max && type.every(t => this.system.armorApplicableDamageTypes[t] === true); const canUseStress = Object.keys(stressDamageReduction).reduce((acc, x) => { const rule = stressDamageReduction[x]; @@ -614,12 +613,7 @@ export default class DhpActor extends Actor { const hpDamage = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id); if (hpDamage?.value) { hpDamage.value = this.convertDamageToThreshold(hpDamage.value); - if ( - this.type === 'character' && - !isDirect && - this.system.armor && - this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes) - ) { + if (this.type === 'character' && !isDirect && this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes)) { const armorSlotResult = await this.owner.query( 'armorSlot', { @@ -989,13 +983,13 @@ export default class DhpActor extends Actor { } /**@inheritdoc */ - *allApplicableEffects({ noArmor } = {}) { + *allApplicableEffects({ noSelfArmor, noTransferArmor } = {}) { for (const effect of this.effects) { - yield effect; + if (!noSelfArmor || effect.type !== 'armor') yield effect; } for (const item of this.items) { for (const effect of item.effects) { - if (effect.transfer && (!noArmor || effect.type !== 'armor')) yield effect; + if (effect.transfer && (!noTransferArmor || effect.type !== 'armor')) yield effect; } } } diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 980349ba..18f7dfd7 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -378,14 +378,18 @@ export const arraysEqual = (a, b) => export const setsEqual = (a, b) => a.size === b.size && [...a].every(value => b.has(value)); -export function getScrollTextData(resources, resource, key) { - const { reversed, label } = CONFIG.DH.ACTOR.scrollingTextResource[key]; - const { BOTTOM, TOP } = CONST.TEXT_ANCHOR_POINTS; +export function getResourceScrollTextData(resources, resource, key) { const increased = resources[key].value < resource.value; const value = -1 * (resources[key].value - resource.value); - const text = `${game.i18n.localize(label)} ${value.signedString()}`; + return getScrollTextData(increased, value, key); +} +export function getScrollTextData(increased, value, key) { + const { reversed, label } = CONFIG.DH.ACTOR.scrollingTextResource[key]; + const { BOTTOM, TOP } = CONST.TEXT_ANCHOR_POINTS; + + const text = `${game.i18n.localize(label)} ${value.signedString()}`; const stroke = increased ? (reversed ? 0xffffff : 0x000000) : reversed ? 0x000000 : 0xffffff; const fill = increased ? (reversed ? 0x0032b1 : 0xffe760) : reversed ? 0xffe760 : 0x0032b1; const direction = increased ? (reversed ? BOTTOM : TOP) : reversed ? TOP : BOTTOM;