From 6e5d7fb34c85ff77449e60f39343126d0a49289c Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Wed, 21 Jan 2026 02:52:42 +0100 Subject: [PATCH 1/6] Fixed so that saving throw damage mitigation works again (#1555) --- module/data/action/baseAction.mjs | 1 + module/documents/actor.mjs | 2 +- module/documents/chatMessage.mjs | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index b5f95aff..c403d4a9 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -241,6 +241,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel hasHealing: this.hasHealing, hasEffect: this.hasEffect, hasSave: this.hasSave, + onSave: this.save?.damageMod, isDirect: !!this.damage?.direct, selectedRollMode: game.settings.get('core', 'rollMode'), data: this.getRollData(), diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 27c310ae..6d943c54 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -607,7 +607,7 @@ export default class DhpActor extends Actor { if (!updates.length) return; const hpDamage = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id); - if (hpDamage) { + if (hpDamage?.value) { hpDamage.value = this.convertDamageToThreshold(hpDamage.value); if ( this.type === 'character' && diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index 2f23cc1a..4c6b0b93 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -179,7 +179,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { config = foundry.utils.deepClone(this.system); config.event = event; - if (this.system.onSave) { + if (config.hasSave) { const pendingingSaves = targets.filter(t => t.saved.success === null); if (pendingingSaves.length) { const confirm = await foundry.applications.api.DialogV2.confirm({ From f659d08d58c236256f9d8d9ae48005e80594b7ff Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Wed, 21 Jan 2026 02:53:07 +0100 Subject: [PATCH 2/6] . (#1563) --- module/applications/ui/combatTracker.mjs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/module/applications/ui/combatTracker.mjs b/module/applications/ui/combatTracker.mjs index 288ba8ad..fc47f085 100644 --- a/module/applications/ui/combatTracker.mjs +++ b/module/applications/ui/combatTracker.mjs @@ -42,8 +42,8 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C this.combats .find(x => x.active) ?.system?.extendedBattleToggles?.reduce((acc, toggle) => (acc ?? 0) + toggle.category, null) ?? null; - const maxBP = CONFIG.DH.ENCOUNTER.BaseBPPerEncounter(context.characters.length) + modifierBP; - const currentBP = AdversaryBPPerEncounter(context.adversaries, context.characters); + const maxBP = CONFIG.DH.ENCOUNTER.BaseBPPerEncounter(context.allCharacters.length) + modifierBP; + const currentBP = AdversaryBPPerEncounter(context.adversaries, context.allCharacters); Object.assign(context, { fear: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Resources.Fear), @@ -73,9 +73,8 @@ export default class DhCombatTracker extends foundry.applications.sidebar.tabs.C Object.assign(context, { actionTokens: game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.variantRules).actionTokens, adversaries, - characters: characters - ?.filter(x => !x.isNPC) - .filter(x => !spotlightQueueEnabled || x.system.spotlight.requestOrderIndex == 0), + allCharacters: characters, + characters: characters.filter(x => !spotlightQueueEnabled || x.system.spotlight.requestOrderIndex == 0), spotlightRequests }); } From 38fb00bd1058c24af88475157ade74996f0ddfef Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Wed, 21 Jan 2026 13:47:03 +0100 Subject: [PATCH 3/6] Fixed DowntimeMoves and ItemFeatures reset functions (#1568) --- lang/en.json | 1 + .../settings/homebrewSettings.mjs | 32 +++++++++++++++++-- .../settings/homebrew-settings/downtime.hbs | 4 +-- .../homebrew-settings/itemFeatures.hbs | 4 +-- 4 files changed, 34 insertions(+), 7 deletions(-) diff --git a/lang/en.json b/lang/en.json index 8e64ab7d..18048d9d 100755 --- a/lang/en.json +++ b/lang/en.json @@ -2506,6 +2506,7 @@ "itemFeatures": "Item Features", "nrChoices": "# Moves Per Rest", "resetMovesTitle": "Reset {type} Downtime Moves", + "resetItemFeaturesTitle": "Reset {type}", "resetMovesText": "Are you sure you want to reset?", "FIELDS": { "maxFear": { "label": "Max Fear" }, diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index 3c4486c1..6e2e665d 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -36,7 +36,8 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli addItem: this.addItem, editItem: this.editItem, removeItem: this.removeItem, - resetMoves: this.resetMoves, + resetDowntimeMoves: this.resetDowntimeMoves, + resetItemFeatures: this.resetItemFeatures, addDomain: this.addDomain, toggleSelectedDomain: this.toggleSelectedDomain, deleteDomain: this.deleteDomain, @@ -232,7 +233,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli this.render(); } - static async resetMoves(_, target) { + static async resetDowntimeMoves(_, target) { const confirmed = await foundry.applications.api.DialogV2.confirm({ window: { title: game.i18n.format('DAGGERHEART.SETTINGS.Homebrew.resetMovesTitle', { @@ -266,7 +267,7 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli ...move, name: game.i18n.localize(move.name), description: game.i18n.localize(move.description), - actions: move.actions.reduce((acc, key) => { + actions: Object.keys(move.actions).reduce((acc, key) => { const action = move.actions[key]; acc[key] = { ...action, @@ -293,6 +294,31 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli this.render(); } + static async resetItemFeatures(_, target) { + const confirmed = await foundry.applications.api.DialogV2.confirm({ + window: { + title: game.i18n.format('DAGGERHEART.SETTINGS.Homebrew.resetItemFeaturesTitle', { + type: game.i18n.localize(`DAGGERHEART.GENERAL.${target.dataset.type}`) + }) + }, + content: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.resetMovesText') + }); + + if (!confirmed) return; + + await this.settings.updateSource({ + [`itemFeatures.${target.dataset.type}`]: Object.keys( + this.settings.itemFeatures[target.dataset.type] + ).reduce((acc, key) => { + acc[`-=${key}`] = null; + + return acc; + }, {}) + }); + + this.render(); + } + static async addDomain(event) { event.preventDefault(); const content = new foundry.data.fields.StringField({ diff --git a/templates/settings/homebrew-settings/downtime.hbs b/templates/settings/homebrew-settings/downtime.hbs index 8612f3d5..25f4c95d 100644 --- a/templates/settings/homebrew-settings/downtime.hbs +++ b/templates/settings/homebrew-settings/downtime.hbs @@ -10,7 +10,7 @@ {{localize "DAGGERHEART.APPLICATIONS.Downtime.longRest.title"}} - +
@@ -31,7 +31,7 @@ {{localize "DAGGERHEART.APPLICATIONS.Downtime.shortRest.title"}} - +
diff --git a/templates/settings/homebrew-settings/itemFeatures.hbs b/templates/settings/homebrew-settings/itemFeatures.hbs index 22c23af6..df3419fa 100644 --- a/templates/settings/homebrew-settings/itemFeatures.hbs +++ b/templates/settings/homebrew-settings/itemFeatures.hbs @@ -8,7 +8,7 @@ {{localize "DAGGERHEART.GENERAL.weaponFeatures"}} - +
@@ -22,7 +22,7 @@ {{localize "DAGGERHEART.GENERAL.armorFeatures"}} - +
From 1f7d4d6f1e864fe1fd38aa59601a52f0e28c6553 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Thu, 22 Jan 2026 16:52:22 +0100 Subject: [PATCH 4/6] Fixed an error where a player having their token initially selected caused an error in effectsDisplay.mjs (#1569) --- module/applications/ui/effectsDisplay.mjs | 2 ++ 1 file changed, 2 insertions(+) diff --git a/module/applications/ui/effectsDisplay.mjs b/module/applications/ui/effectsDisplay.mjs index 0875e783..8c0c939c 100644 --- a/module/applications/ui/effectsDisplay.mjs +++ b/module/applications/ui/effectsDisplay.mjs @@ -76,6 +76,8 @@ export default class DhEffectsDisplay extends HandlebarsApplicationMixin(Applica }; toggleHidden(token, focused) { + if (!this.element) return; + const effects = DhEffectsDisplay.getTokenEffects(focused ? token : null); this.element.hidden = effects.length === 0; From fa3b3fa0a81401ce6e8022582d7bb096004d4806 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Thu, 22 Jan 2026 23:21:42 +0100 Subject: [PATCH 5/6] [Fix] Damage Rerolls (#1566) * Fixed so that damage rerolls work again * Set default data for a roll instead and fix title (#1570) * Set default data for a roll instead and fix title * Ensure same options object is used --------- Co-authored-by: Carlos Fernandez --- lang/en.json | 1 + module/dice/dhRoll.mjs | 2 +- system.json | 2 +- 3 files changed, 3 insertions(+), 2 deletions(-) diff --git a/lang/en.json b/lang/en.json index 18048d9d..33f8c514 100755 --- a/lang/en.json +++ b/lang/en.json @@ -607,6 +607,7 @@ }, "RerollDialog": { "title": "Reroll", + "damageTitle": "Reroll Damage", "deselectDiceNotification": "Deselect one of the selected dice first", "acceptCurrentRolls": "Accept Current Rolls" }, diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index a5ac5091..1977c7ea 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -3,7 +3,7 @@ import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs'; export default class DHRoll extends Roll { baseTerms = []; constructor(formula, data = {}, options = {}) { - super(formula, data, options); + super(formula, data, foundry.utils.mergeObject(options, { roll: [] }, { overwrite: false })); options.bonusEffects = this.bonusEffectBuilder(); if (!this.data || !Object.keys(this.data).length) this.data = options.data; } diff --git a/system.json b/system.json index 2c68f785..6521c6d6 100644 --- a/system.json +++ b/system.json @@ -2,7 +2,7 @@ "id": "daggerheart", "title": "Daggerheart", "description": "An unofficial implementation of the Daggerheart system", - "version": "1.5.4", + "version": "1.5.5", "compatibility": { "minimum": "13.346", "verified": "13.351", From 21ef288283bef655918412b25fe4bf692e1e97d1 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Fri, 23 Jan 2026 11:51:14 +0100 Subject: [PATCH 6/6] Fixed when users drag in compendium environments to the sceneEnvironments (#1573) --- .../applications/scene/sceneConfigSettings.mjs | 13 ++++++++++++- module/systemRegistration/migrations.mjs | 16 ++++++++++++++++ 2 files changed, 28 insertions(+), 1 deletion(-) diff --git a/module/applications/scene/sceneConfigSettings.mjs b/module/applications/scene/sceneConfigSettings.mjs index 8a58db5c..98e18f09 100644 --- a/module/applications/scene/sceneConfigSettings.mjs +++ b/module/applications/scene/sceneConfigSettings.mjs @@ -65,8 +65,15 @@ export default class DhSceneConfigSettings extends foundry.applications.sheets.S const data = foundry.applications.ux.TextEditor.implementation.getDragEventData(event); const item = await foundry.utils.fromUuid(data.uuid); if (item instanceof game.system.api.documents.DhpActor && item.type === 'environment') { + let sceneUuid = data.uuid; + if (item.pack) { + const inWorldActor = await game.system.api.documents.DhpActor.create([item.toObject()]); + if (!inWorldActor.length) return; + sceneUuid = inWorldActor[0].uuid; + } + await this.daggerheartFlag.updateSource({ - sceneEnvironments: [...this.daggerheartFlag.sceneEnvironments, data.uuid] + sceneEnvironments: [...this.daggerheartFlag.sceneEnvironments, sceneUuid] }); this.render({ internalRefresh: true }); } @@ -97,6 +104,10 @@ export default class DhSceneConfigSettings extends foundry.applications.sheets.S /** @override */ async _processSubmitData(event, form, submitData, options) { submitData.flags.daggerheart = this.daggerheartFlag.toObject(); + submitData.flags.daggerheart.sceneEnvironments = submitData.flags.daggerheart.sceneEnvironments.filter(x => + foundry.utils.fromUuidSync(x) + ); + for (const key of Object.keys(this.document._source.flags.daggerheart?.sceneEnvironments ?? {})) { if (!submitData.flags.daggerheart.sceneEnvironments[key]) { submitData.flags.daggerheart.sceneEnvironments[`-=${key}`] = null; diff --git a/module/systemRegistration/migrations.mjs b/module/systemRegistration/migrations.mjs index b3116459..086647bf 100644 --- a/module/systemRegistration/migrations.mjs +++ b/module/systemRegistration/migrations.mjs @@ -210,6 +210,22 @@ export async function runMigrations() { lastMigrationVersion = '1.2.7'; } + + if (foundry.utils.isNewerVersion('1.5.5', lastMigrationVersion)) { + for (const scene of game.scenes) { + if (!scene.flags.daggerheart) continue; + const systemData = new game.system.api.data.scenes.DHScene(scene.flags.daggerheart); + const sceneEnvironments = systemData.sceneEnvironments; + + const newEnvironments = sceneEnvironments.filter(x => !x?.pack); + if (newEnvironments.length !== sceneEnvironments.length) + await scene.update({ 'flags.daggerheart.sceneEnvironments': newEnvironments }); + } + + ui.nav.render(true); + + lastMigrationVersion = '1.5.5'; + } //#endregion await game.settings.set(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LastMigrationVersion, lastMigrationVersion);