From f3859829878545f7793c2bd2257af23cc979f5af Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Sun, 21 Jun 2026 23:04:28 +0200 Subject: [PATCH 1/6] [Fix] Action Uses Not Spent (#2029) --- module/applications/dialogs/d20RollDialog.mjs | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs index e9140b56..048797d8 100644 --- a/module/applications/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -160,7 +160,7 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio } if (rest.hasOwnProperty('trait')) { this.config.roll.trait = rest.trait; - if (!this.config.source.item) + if (!this.config.source.item && this.config.roll.trait) this.config.title = game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { ability: game.i18n.localize(abilities[this.config.roll.trait]?.label) }); @@ -225,7 +225,6 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio } static async submitRoll(event) { - event.preventDefault(); await this.close({ submitted: true }); } From 0d59e37a806d71b7daa6faef7229d942709abf01 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Sun, 21 Jun 2026 23:35:38 +0200 Subject: [PATCH 2/6] [Fix] Trigger Error Info (#2030) * Made trigger errors more informative * . --- lang/en.json | 2 +- module/data/registeredTriggers.mjs | 7 +++++-- 2 files changed, 6 insertions(+), 3 deletions(-) diff --git a/lang/en.json b/lang/en.json index 5bab0e64..a4a5edf0 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1451,7 +1451,7 @@ }, "triggerType": "Trigger Type", "triggeringActorType": "Triggering Actor Type", - "triggerError": "{trigger} trigger failed for {actor}. It's probably configured wrong." + "triggerError": "{trigger} trigger on {item}({itemUuid}) failed for {actor}. It's probably configured wrong." }, "WeaponFeature": { "barrier": { diff --git a/module/data/registeredTriggers.mjs b/module/data/registeredTriggers.mjs index 0b637930..64e7f93e 100644 --- a/module/data/registeredTriggers.mjs +++ b/module/data/registeredTriggers.mjs @@ -150,11 +150,14 @@ export default class RegisteredTriggers extends Map { const result = await command(...args); if (result?.updates?.length) updates.push(...result.updates); } catch { + const item = await foundry.utils.fromUuid(itemUuid); const triggerName = game.i18n.localize(triggerData.label); - ui.notifications.error( + console.error( game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerError', { trigger: triggerName, - actor: currentActor?.name + actor: currentActor?.name, + item: item?.name ?? '', + itemUuid: item?.uuid ?? '' }) ); } From cc16a726bffb9bb4bd0a9f12f1d8e68b76bdc556 Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Sun, 21 Jun 2026 17:53:41 -0400 Subject: [PATCH 3/6] [Feature] In setting sheets, split by feature type and include descriptions (#2026) --- .../sheets-configs/adversary-settings.mjs | 25 +++++----- .../sheets-configs/environment-settings.mjs | 22 +++++--- .../sheets-configs/npc-settings.mjs | 19 ++++--- .../applications/sheets/api/actor-setting.mjs | 7 ++- .../sheets/api/application-mixin.mjs | 9 ++-- .../adversary-settings/features.hbs | 50 ++++++++++--------- .../environment-settings/features.hbs | 47 +++++++++-------- .../sheets-settings/npc-settings/features.hbs | 50 ++++++++++--------- .../global/partials/inventory-item-V2.hbs | 24 ++++----- 9 files changed, 143 insertions(+), 110 deletions(-) diff --git a/module/applications/sheets-configs/adversary-settings.mjs b/module/applications/sheets-configs/adversary-settings.mjs index 583f37b7..ff3f3039 100644 --- a/module/applications/sheets-configs/adversary-settings.mjs +++ b/module/applications/sheets-configs/adversary-settings.mjs @@ -10,11 +10,7 @@ export default class DHAdversarySettings extends DHBaseActorSettings { actions: { addExperience: DHAdversarySettings.#addExperience, removeExperience: DHAdversarySettings.#removeExperience - }, - dragDrop: [ - { dragSelector: null, dropSelector: '.tab.features' }, - { dragSelector: '.feature-item', dropSelector: null } - ] + } }; /**@override */ @@ -38,7 +34,8 @@ export default class DHAdversarySettings extends DHBaseActorSettings { }, features: { id: 'features', - template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/features.hbs' + template: 'systems/daggerheart/templates/sheets-settings/adversary-settings/features.hbs', + scrollable: [''] } }; @@ -54,12 +51,16 @@ export default class DHAdversarySettings extends DHBaseActorSettings { async _prepareContext(options) { const context = await super._prepareContext(options); - const featureForms = Object.keys(CONFIG.DH.ITEM.featureForm); - context.features = context.document.system.features.sort((a, b) => - a.system.featureForm !== b.system.featureForm - ? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm) - : a.sort - b.sort - ); + // Get feature groups. Uncategorized go to actions + const featureFormsTypes = ['passive', 'action', 'reaction']; + const features = this.document.system.features.sort((a, b) => a.sort - b.sort); + const featureGroups = featureFormsTypes.map(t => ({ + featureForm: t, + label: _loc(CONFIG.DH.ITEM.featureForm[t]), + features: features.filter(f => f.system.featureForm === t) + })); + featureGroups[1].features.push(...features.filter(f => !featureFormsTypes.includes(f.system.featureForm))); + context.featureGroups = featureGroups; return context; } diff --git a/module/applications/sheets-configs/environment-settings.mjs b/module/applications/sheets-configs/environment-settings.mjs index d6744eb8..954d6381 100644 --- a/module/applications/sheets-configs/environment-settings.mjs +++ b/module/applications/sheets-configs/environment-settings.mjs @@ -32,11 +32,13 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings { }, features: { id: 'features', - template: 'systems/daggerheart/templates/sheets-settings/environment-settings/features.hbs' + template: 'systems/daggerheart/templates/sheets-settings/environment-settings/features.hbs', + scrollable: [''] }, adversaries: { id: 'adversaries', - template: 'systems/daggerheart/templates/sheets-settings/environment-settings/adversaries.hbs' + template: 'systems/daggerheart/templates/sheets-settings/environment-settings/adversaries.hbs', + scrollable: [''] } }; @@ -52,12 +54,16 @@ export default class DHEnvironmentSettings extends DHBaseActorSettings { async _prepareContext(options) { const context = await super._prepareContext(options); - const featureForms = ['passive', 'action', 'reaction']; - context.features = context.document.system.features.sort((a, b) => - a.system.featureForm !== b.system.featureForm - ? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm) - : a.sort - b.sort - ); + // Get feature groups. Uncategorized go to actions + const featureFormsTypes = ['passive', 'action', 'reaction']; + const features = this.document.system.features.sort((a, b) => a.sort - b.sort); + const featureGroups = featureFormsTypes.map(t => ({ + featureForm: t, + label: _loc(CONFIG.DH.ITEM.featureForm[t]), + features: features.filter(f => f.system.featureForm === t) + })); + featureGroups[1].features.push(...features.filter(f => !featureFormsTypes.includes(f.system.featureForm))); + context.featureGroups = featureGroups; return context; } diff --git a/module/applications/sheets-configs/npc-settings.mjs b/module/applications/sheets-configs/npc-settings.mjs index d2132a91..33cbc270 100644 --- a/module/applications/sheets-configs/npc-settings.mjs +++ b/module/applications/sheets-configs/npc-settings.mjs @@ -27,7 +27,8 @@ export default class DHNPCSettings extends DHBaseActorSettings { }, features: { id: 'features', - template: 'systems/daggerheart/templates/sheets-settings/npc-settings/features.hbs' + template: 'systems/daggerheart/templates/sheets-settings/npc-settings/features.hbs', + scrollable: [''] } }; @@ -43,12 +44,16 @@ export default class DHNPCSettings extends DHBaseActorSettings { async _prepareContext(options) { const context = await super._prepareContext(options); - const featureForms = ['passive', 'action', 'reaction']; - context.features = context.document.system.features.sort((a, b) => - a.system.featureForm !== b.system.featureForm - ? featureForms.indexOf(a.system.featureForm) - featureForms.indexOf(b.system.featureForm) - : a.sort - b.sort - ); + // Get feature groups. Uncategorized go to actions + const featureFormsTypes = ['passive', 'action', 'reaction']; + const features = this.document.system.features.sort((a, b) => a.sort - b.sort); + const featureGroups = featureFormsTypes.map(t => ({ + featureForm: t, + label: _loc(CONFIG.DH.ITEM.featureForm[t]), + features: features.filter(f => f.system.featureForm === t) + })); + featureGroups[1].features.push(...features.filter(f => !featureFormsTypes.includes(f.system.featureForm))); + context.featureGroups = featureGroups; return context; } diff --git a/module/applications/sheets/api/actor-setting.mjs b/module/applications/sheets/api/actor-setting.mjs index 65497cec..fa434034 100644 --- a/module/applications/sheets/api/actor-setting.mjs +++ b/module/applications/sheets/api/actor-setting.mjs @@ -25,7 +25,7 @@ export default class DHBaseActorSettings extends DHApplicationMixin(ActorSheetV2 }, dragDrop: [ { dragSelector: null, dropSelector: '.tab.features' }, - { dragSelector: '.feature-item', dropSelector: null } + { dragSelector: '.feature-item, .inventory-item[data-type="feature"]', dropSelector: null } ] }; @@ -77,7 +77,7 @@ export default class DHBaseActorSettings extends DHApplicationMixin(ActorSheetV2 } async _onDragStart(event) { - const featureItemEl = event.currentTarget.closest('.feature-item'); + const featureItemEl = event.currentTarget.closest('.feature-item, .inventory-item[data-type="feature"]'); const feature = this.actor.items.get(featureItemEl?.dataset.itemId); if (feature && event.target.closest('.tab.features')) { const featureData = { ...feature.toDragData(), fromInternal: true }; @@ -100,4 +100,7 @@ export default class DHBaseActorSettings extends DHApplicationMixin(ActorSheetV2 await this.actor.createEmbeddedDocuments('Item', [itemData]); } } + + /** Setting sheets do not auto extend */ + async _autoExpandDescriptions() {} } diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index f3d612e9..d89237df 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -4,6 +4,7 @@ import { getDocFromElement, getDocFromElementSync, tagifyElement } from '../../. const typeSettingsMap = { character: 'extendCharacterDescriptions', adversary: 'extendAdversaryDescriptions', + npc: 'extendAdversaryDescriptions', environment: 'extendEnvironmentDescriptions', ancestry: 'extendItemDescriptions', community: 'extendItemDescriptions', @@ -262,7 +263,7 @@ export default function DHApplicationMixin(Base) { if (!!this.options.contextMenus.length) this._createContextMenus(); - this.#autoExtendDescriptions(context); + this._autoExpandDescriptions(context); } /** @inheritDoc */ @@ -630,8 +631,9 @@ export default function DHApplicationMixin(Base) { /** * Extend inventory description when enabled in settings. * @returns {Promise} + * @protected */ - async #autoExtendDescriptions(context) { + async _autoExpandDescriptions(context) { const inventoryItems = this.element.querySelectorAll('.inventory-item[data-item-uuid]'); for (const el of inventoryItems) { // Get the doc uuid from the element @@ -734,7 +736,7 @@ export default function DHApplicationMixin(Base) { * @type {ApplicationClickAction} */ static async #onCreateDoc(event, target) { - const { documentClass, type, inVault, disabled } = target.dataset; + const { documentClass, type, inVault, disabled, featureForm } = target.dataset; const parentIsItem = this.document.documentName === 'Item'; const featureOnCharacter = this.document.parent?.type === 'character' && type === 'feature'; const parent = featureOnCharacter @@ -752,6 +754,7 @@ export default function DHApplicationMixin(Base) { identifier: this.document.system.isMulticlass ? 'multiclass' : null }; } + if (featureForm) systemData.featureForm = featureForm; const cls = type === 'action' ? game.system.api.models.actions.actionsTypes.base : getDocumentClass(documentClass); diff --git a/templates/sheets-settings/adversary-settings/features.hbs b/templates/sheets-settings/adversary-settings/features.hbs index 3e0ed654..1cab8cfe 100644 --- a/templates/sheets-settings/adversary-settings/features.hbs +++ b/templates/sheets-settings/adversary-settings/features.hbs @@ -3,27 +3,31 @@ data-tab='{{tabs.features.id}}' data-group='{{tabs.features.group}}' > - -
- {{localize tabs.features.label}} -
    - {{#each @root.features as |feature|}} -
  • - -
    - {{feature.name}} -
    -
    - - -
    -
  • - {{/each}} -
-
- {{localize "DAGGERHEART.GENERAL.dropFeaturesHere"}} -
-
+ {{#each featureGroups as |group|}} +
+ + {{group.label}} + + + + +
    + {{#each group.features as |feature|}} + {{> 'daggerheart.inventory-item' + item=feature + type='feature' + actorType=@root.document.type + hideTags=true + hideContextMenu=true + hideResources=true + showActions=false + hideTooltip=true + }} + {{/each}} +
+
+ {{/each}} +
+ {{localize "DAGGERHEART.GENERAL.dropFeaturesHere"}} +
\ No newline at end of file diff --git a/templates/sheets-settings/environment-settings/features.hbs b/templates/sheets-settings/environment-settings/features.hbs index ecda0e6b..1cab8cfe 100644 --- a/templates/sheets-settings/environment-settings/features.hbs +++ b/templates/sheets-settings/environment-settings/features.hbs @@ -3,24 +3,31 @@ data-tab='{{tabs.features.id}}' data-group='{{tabs.features.group}}' > - -
- {{localize tabs.features.label}} -
    - {{#each @root.features as |feature|}} -
  • - -
    - {{feature.name}} -
    -
    - - -
    -
  • - {{/each}} -
-
+ {{#each featureGroups as |group|}} +
+ + {{group.label}} + + + + +
    + {{#each group.features as |feature|}} + {{> 'daggerheart.inventory-item' + item=feature + type='feature' + actorType=@root.document.type + hideTags=true + hideContextMenu=true + hideResources=true + showActions=false + hideTooltip=true + }} + {{/each}} +
+
+ {{/each}} +
+ {{localize "DAGGERHEART.GENERAL.dropFeaturesHere"}} +
\ No newline at end of file diff --git a/templates/sheets-settings/npc-settings/features.hbs b/templates/sheets-settings/npc-settings/features.hbs index 3e0ed654..1cab8cfe 100644 --- a/templates/sheets-settings/npc-settings/features.hbs +++ b/templates/sheets-settings/npc-settings/features.hbs @@ -3,27 +3,31 @@ data-tab='{{tabs.features.id}}' data-group='{{tabs.features.group}}' > - -
- {{localize tabs.features.label}} -
    - {{#each @root.features as |feature|}} -
  • - -
    - {{feature.name}} -
    -
    - - -
    -
  • - {{/each}} -
-
- {{localize "DAGGERHEART.GENERAL.dropFeaturesHere"}} -
-
+ {{#each featureGroups as |group|}} +
+ + {{group.label}} + + + + +
    + {{#each group.features as |feature|}} + {{> 'daggerheart.inventory-item' + item=feature + type='feature' + actorType=@root.document.type + hideTags=true + hideContextMenu=true + hideResources=true + showActions=false + hideTooltip=true + }} + {{/each}} +
+
+ {{/each}} +
+ {{localize "DAGGERHEART.GENERAL.dropFeaturesHere"}} +
\ No newline at end of file diff --git a/templates/sheets/global/partials/inventory-item-V2.hbs b/templates/sheets/global/partials/inventory-item-V2.hbs index 523e9304..f7d22a30 100644 --- a/templates/sheets/global/partials/inventory-item-V2.hbs +++ b/templates/sheets/global/partials/inventory-item-V2.hbs @@ -27,17 +27,17 @@ Parameters: >
{{!-- Image --}} -
- - {{#if item.usable}} - {{#if @root.isNPC}} - d20 - {{else}} - 2d12 +
+ + {{#if (and item.usable (ne showActions false))}} + {{#if @root.isNPC}} + d20 + {{else}} + 2d12 + {{/if}} {{/if}} - {{/if}}
{{!-- Name & Tags --}} @@ -46,10 +46,10 @@ Parameters: {{localize item.name}} {{#unless (or noExtensible (not item.system.description))}}{{/unless}} {{!-- Tags Start --}} - {{#if (not ../hideTags)}} + {{#if (not hideTags)}} {{#> "systems/daggerheart/templates/sheets/global/partials/item-tags.hbs" item}} {{#if (eq ../type 'feature')}} - {{#if (and system.featureForm (or (eq @root.document.type "adversary") (eq @root.document.type "environment")))}} + {{#if (and system.featureForm (ne @root.document.type "character"))}}
{{localize (concat "DAGGERHEART.CONFIG.FeatureForm." system.featureForm)}}
From 149249199843ccada03ec7857894230f1c97e202 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Mon, 22 Jun 2026 00:14:40 +0200 Subject: [PATCH 4/6] [Fix] Reroll Countdown Automation (#2031) * Fixed so that automated countdowns reverse progress from Fear when rerolling dice if the duality result changes * . * Removed overprep * Apply suggestion from @CarlosFdez --------- Co-authored-by: Carlos Fernandez --- module/applications/ui/countdowns.mjs | 14 +++++++------ module/dice/helpers.mjs | 29 ++++++++++++++++++--------- 2 files changed, 27 insertions(+), 16 deletions(-) diff --git a/module/applications/ui/countdowns.mjs b/module/applications/ui/countdowns.mjs index d559582f..5cf79100 100644 --- a/module/applications/ui/countdowns.mjs +++ b/module/applications/ui/countdowns.mjs @@ -342,29 +342,31 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application * Sends updates of the countdowns to the GM player. Since this is asynchronous, be sure to * update all the countdowns at the same time. * - * @param {...any} progressTypes Countdowns to be updated + * @param {...(string | { type: string; undo?: boolean })} progressTypes Countdowns to be updated */ static async updateCountdowns(...progressTypes) { + progressTypes = progressTypes.map(p => typeof p === 'string' ? { type: p } : p); const { countdownAutomation } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); if (!countdownAutomation) return; const countdownSetting = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Countdowns); const updatedCountdowns = Object.keys(countdownSetting.countdowns).reduce((acc, key) => { const countdown = countdownSetting.countdowns[key]; - if (progressTypes.indexOf(countdown.progress.type) !== -1 && countdown.progress.current > 0) { - acc.push(key); + const progressData = progressTypes.find(x => x.type === countdown.progress.type); + if (progressData && countdown.progress.current > 0) { + acc[key] = { value: progressData.undo ? 1 : -1 }; } return acc; - }, []); + }, {}); const countdownData = countdownSetting.toObject(); const settings = { ...countdownData, countdowns: Object.keys(countdownData.countdowns).reduce((acc, key) => { const countdown = foundry.utils.deepClone(countdownData.countdowns[key]); - if (updatedCountdowns.includes(key)) { - countdown.progress.current -= 1; + if (updatedCountdowns[key]) { + countdown.progress.current += updatedCountdowns[key].value; } acc[key] = countdown; diff --git a/module/dice/helpers.mjs b/module/dice/helpers.mjs index 5f8a7bbb..d03970d0 100644 --- a/module/dice/helpers.mjs +++ b/module/dice/helpers.mjs @@ -1,19 +1,28 @@ import { ResourceUpdateMap } from '../data/action/baseAction.mjs'; export function updateResourcesForDualityReroll(oldDuality, newDuality, actor) { - const { hopeFear } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); - if (game.user.isGM ? !hopeFear.gm : !hopeFear.players) return; - - const updates = []; const hope = (newDuality >= 0 ? 1 : 0) - (oldDuality >= 0 ? 1 : 0); const stress = (newDuality === 0 ? 1 : 0) - (oldDuality === 0 ? 1 : 0); const fear = (newDuality === -1 ? 1 : 0) - (oldDuality === -1 ? 1 : 0); - if (hope !== 0) updates.push({ key: 'hope', value: hope, enabled: true }); - if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, enabled: true }); - if (fear !== 0) updates.push({ key: 'fear', value: fear, enabled: true }); + const { hopeFear, countdownAutomation } = + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation); - const resourceUpdates = new ResourceUpdateMap(actor); - resourceUpdates.addResources(updates); - resourceUpdates.updateResources(); + if (game.user.isGM ? hopeFear.gm : hopeFear.players) { + const updates = []; + if (hope !== 0) updates.push({ key: 'hope', value: hope, enabled: true }); + if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, enabled: true }); + if (fear !== 0) updates.push({ key: 'fear', value: fear, enabled: true }) + + const resourceUpdates = new ResourceUpdateMap(actor); + resourceUpdates.addResources(updates); + resourceUpdates.updateResources(); + } + + if (countdownAutomation && fear !== 0) { + game.system.api.applications.ui.DhCountdowns.updateCountdowns({ + type: CONFIG.DH.GENERAL.countdownProgressionTypes.fear.id, + undo: fear === 1 ? false : true + }); + } } From 8e930259474f631d4923b37d45dade63070e6adb Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Mon, 22 Jun 2026 00:24:33 +0200 Subject: [PATCH 5/6] [Fix] Weapon Spellcasting Active Effects (#2032) * . * . * Apply suggestion from @CarlosFdez --------- Co-authored-by: Carlos Fernandez --- .../sheets/api/application-mixin.mjs | 2 +- module/applications/sheets/api/base-actor.mjs | 2 +- module/data/action/baseAction.mjs | 39 +++++++++++++------ module/documents/actor.mjs | 2 +- module/documents/chatMessage.mjs | 2 +- 5 files changed, 32 insertions(+), 15 deletions(-) diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index d89237df..98f38f03 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -518,7 +518,7 @@ export default function DHApplicationMixin(Base) { const doc = await getDocFromElement(target), action = doc?.system?.attack ?? doc; const config = action.prepareConfig(event); - config.effects = await game.system.api.data.actions.actionsTypes.base.getEffects( + config.effects = await game.system.api.data.actions.actionsTypes.base.getActionRelevantEffects( this.document, doc ); diff --git a/module/applications/sheets/api/base-actor.mjs b/module/applications/sheets/api/base-actor.mjs index e65745c0..007b641b 100644 --- a/module/applications/sheets/api/base-actor.mjs +++ b/module/applications/sheets/api/base-actor.mjs @@ -212,7 +212,7 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { const doc = await getDocFromElement(target), action = doc?.system?.attack ?? doc; const config = action.prepareConfig(event); - config.effects = await game.system.api.data.actions.actionsTypes.base.getEffects( + config.effects = await game.system.api.data.actions.actionsTypes.base.getActionRelevantEffects( this.document, doc ); diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index ea4361b9..f568436e 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -228,7 +228,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel let config = this.prepareConfig(event, configOptions); if (!config) return; - config.effects = await game.system.api.data.actions.actionsTypes.base.getEffects(this.actor, this.item); + config.effects = + await game.system.api.data.actions.actionsTypes.base.getActionRelevantEffects(this.actor, this.item); if (Hooks.call(`${CONFIG.DH.id}.preUseAction`, this, config) === false) return; @@ -333,27 +334,43 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel } /** - * Get the all potentially applicable effects on the actor + * Get the all potentially applicable effects on the actor for the action's RollDialog * @param {DHActor} actor The actor performing the action * @param {DHItem|DhActor} effectParent The parent of the effect * @returns {DhActiveEffect[]} */ - static async getEffects(actor, effectParent) { + static async getActionRelevantEffects(actor, effectParent) { if (!actor) return []; - return Array.from(await actor.allApplicableEffects({ noTransferArmor: true, noSelfArmor: true })).filter( - effect => { - /* Effects on weapons only ever apply for the weapon itself */ + // Changes on weapon effects are not typically only applicable to show in the roll dialog for the weapon itself + // The exemptions to this rule are listed below + const weaponTransferredEffectKeys = [ + 'system.bonuses.roll.spellcast.bonus' + ]; + + return Array.from(await actor.allApplicableEffects({ noTransferArmor: true, noSelfArmor: true })).reduce( + (acc, effect) => { + const effectData = effect.toObject(); + /* Effects on weapons only ever apply for the weapon itself, with a few defined exceptions */ 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; + if (effectParent?.type !== 'weapon' || effectParent?.system.secondary) { + effectData.system.changes = + effectData.system.changes.filter(x => weaponTransferredEffectKeys.includes(x.key)); + } + } else if (effectParent?.id !== effect.parent.id) { + effectData.system.changes = + effectData.system.changes.filter(x => weaponTransferredEffectKeys.includes(x.key)); + } } - return !effect.isSuppressed; - } - ); + if (!effect.isSuppressed) { + acc.push(effectData); + } + + return acc; + }, []); } /** diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 1642ed30..8ef64f65 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -549,7 +549,7 @@ export default class DhpActor extends Actor { headerTitle: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { ability: abilityLabel }), - effects: await game.system.api.data.actions.actionsTypes.base.getEffects(this), + effects: await game.system.api.data.actions.actionsTypes.base.getActionRelevantEffects(this), roll: { trait: trait, type: 'trait' diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index 480f8c69..b555dfca 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -167,7 +167,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { if (this.system.action) { const actor = await foundry.utils.fromUuid(config.source.actor); const item = actor?.items.get(config.source.item) ?? null; - config.effects = await game.system.api.data.actions.actionsTypes.base.getEffects(actor, item); + config.effects = await game.system.api.data.actions.actionsTypes.base.getActionRelevantEffects(actor, item); await this.system.action.workflow.get('damage')?.execute(config, this._id, true); } } From 329d820aab0ce538ab4c1696afa27b1e4c827ad4 Mon Sep 17 00:00:00 2001 From: WBHarry Date: Mon, 22 Jun 2026 00:26:24 +0200 Subject: [PATCH 6/6] Raised version --- system.json | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) diff --git a/system.json b/system.json index f5e13a62..08693074 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "daggerheart", "title": "Daggerheart", "description": "An unofficial implementation of the Daggerheart system", - "version": "2.3.4", + "version": "2.4.0", "compatibility": { "minimum": "14.364", "verified": "14.364", @@ -10,7 +10,7 @@ }, "url": "https://github.com/Foundryborne/daggerheart", "manifest": "https://raw.githubusercontent.com/Foundryborne/daggerheart/v14/system.json", - "download": "https://github.com/Foundryborne/daggerheart/releases/download/2.3.4/system.zip", + "download": "https://github.com/Foundryborne/daggerheart/releases/download/2.4.0/system.zip", "authors": [ { "name": "WBHarry"