From 318d00b47d9173f52adf749aeeb83664f6bafd92 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Mon, 1 Jun 2026 10:24:44 +0200 Subject: [PATCH 01/21] Add NPC Improvements --- module/applications/sheets/actors/party.mjs | 15 +------ styles/less/sheets/actors/npc/header.less | 2 +- templates/sheets/actors/npc/header.hbs | 10 +++-- .../sheets/actors/party/party-members.hbs | 42 ++++++++++--------- 4 files changed, 31 insertions(+), 38 deletions(-) diff --git a/module/applications/sheets/actors/party.mjs b/module/applications/sheets/actors/party.mjs index cec1e1f0..927a8810 100644 --- a/module/applications/sheets/actors/party.mjs +++ b/module/applications/sheets/actors/party.mjs @@ -47,11 +47,6 @@ export default class Party extends DHBaseActorSheet { template: 'systems/daggerheart/templates/sheets/actors/party/party-members.hbs', scrollable: [''] }, - /* NOT YET IMPLEMENTED */ - // projects: { - // template: 'systems/daggerheart/templates/sheets/actors/party/projects.hbs', - // scrollable: [''] - // }, inventory: { template: 'systems/daggerheart/templates/sheets/actors/party/inventory.hbs', scrollable: ['.tab.inventory .items-section'] @@ -62,19 +57,13 @@ export default class Party extends DHBaseActorSheet { /** @inheritdoc */ static TABS = { primary: { - tabs: [ - { id: 'partyMembers' }, - /* NOT YET IMPLEMENTED */ - // { id: 'projects' }, - { id: 'inventory' }, - { id: 'notes' } - ], + tabs: [{ id: 'partyMembers' }, { id: 'inventory' }, { id: 'notes' }], initial: 'partyMembers', labelPrefix: 'DAGGERHEART.GENERAL.Tabs' } }; - static ALLOWED_ACTOR_TYPES = ['character', 'companion', 'adversary']; + static ALLOWED_ACTOR_TYPES = ['character', 'companion', 'adversary', 'npc']; static DICE_ROLL_ACTOR_TYPES = ['character']; async _onRender(context, options) { diff --git a/styles/less/sheets/actors/npc/header.less b/styles/less/sheets/actors/npc/header.less index d49d763c..086a254c 100644 --- a/styles/less/sheets/actors/npc/header.less +++ b/styles/less/sheets/actors/npc/header.less @@ -5,7 +5,7 @@ .portrait { cursor: pointer; - width: 275px; + max-width: 275px; img { height: 275px; diff --git a/templates/sheets/actors/npc/header.hbs b/templates/sheets/actors/npc/header.hbs index 8dc345dc..fce300da 100644 --- a/templates/sheets/actors/npc/header.hbs +++ b/templates/sheets/actors/npc/header.hbs @@ -31,10 +31,12 @@ {{{description}}} -
${game.i18n.localize('DAGGERHEART.APPLICATIONS.PendingReactionsDialog.unfinishedRolls')}
${game.i18n.localize('DAGGERHEART.APPLICATIONS.PendingReactionsDialog.confirmation')}
${game.i18n.localize('DAGGERHEART.APPLICATIONS.PendingReactionsDialog.warning')}
` + content: ` +${game.i18n.localize('DAGGERHEART.APPLICATIONS.PendingReactionsDialog.unfinishedRolls')}
+${game.i18n.localize('DAGGERHEART.APPLICATIONS.PendingReactionsDialog.warning')}
+${game.i18n.localize('DAGGERHEART.APPLICATIONS.PendingReactionsDialog.confirmation')}
+ ` }); if (!confirm) return; } @@ -247,8 +251,24 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { const targets = this.filterPermTargets(this.system.hitTargets), config = foundry.utils.deepClone(this.system); config.event = event; + if (targets.length === 0) - ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelectedOrPerm')); + return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelectedOrPerm')); + else if (config.hasSave) { + const pendingingSaves = targets.filter(t => t.saved.success === null); + if (pendingingSaves.length) { + const confirm = await foundry.applications.api.DialogV2.confirm({ + window: { title: game.i18n.localize('DAGGERHEART.APPLICATIONS.PendingReactionsDialog.title') }, + content: ` +${game.i18n.localize('DAGGERHEART.APPLICATIONS.PendingReactionsDialog.unfinishedRolls')}
+${game.i18n.localize('DAGGERHEART.APPLICATIONS.PendingReactionsDialog.warning')}
+${game.i18n.localize('DAGGERHEART.APPLICATIONS.PendingReactionsDialog.confirmation')}
+ ` + }); + if (!confirm) return; + } + } + this.consumeOnSuccess(); this.system.action?.workflow.get('effects')?.execute(config, targets, true); } From 3c36c5747d477a831d6b0d5a653a414073f6f39c Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Mon, 1 Jun 2026 22:02:42 +0200 Subject: [PATCH 08/21] [Fix] Base Attack Context Menu (#1961) * Fixed Adversary standard attack context menu * Fixed Character base attack context menu * Fixed Companion base attack context menu --- .../applications/sheets/actors/adversary.mjs | 10 +++++ .../applications/sheets/actors/character.mjs | 8 ++++ .../applications/sheets/actors/companion.mjs | 12 +++++- module/applications/sheets/api/base-actor.mjs | 37 +++++++++++++++++++ module/data/action/attackAction.mjs | 7 +++- 5 files changed, 72 insertions(+), 2 deletions(-) diff --git a/module/applications/sheets/actors/adversary.mjs b/module/applications/sheets/actors/adversary.mjs index 04be3efb..06dd4a0f 100644 --- a/module/applications/sheets/actors/adversary.mjs +++ b/module/applications/sheets/actors/adversary.mjs @@ -31,6 +31,16 @@ export default class AdversarySheet extends DHBaseActorSheet { dragSelector: '[data-item-id][draggable="true"], [data-item-id] [draggable="true"]', dropSelector: null } + ], + contextMenus: [ + { + handler: DHBaseActorSheet.getBaseAttackContextOptions, + selector: '[data-item-uuid][data-type="attack"]', + options: { + parentClassHooks: false, + fixed: true + } + } ] }; diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 19b82712..e4d0e6d9 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -65,6 +65,14 @@ export default class CharacterSheet extends DHBaseActorSheet { fixed: true } }, + { + handler: DHBaseActorSheet.getBaseAttackContextOptions, + selector: '[data-item-uuid][data-type="attack"]', + options: { + parentClassHooks: false, + fixed: true + } + }, { handler: CharacterSheet.#getDomainCardContextOptions, selector: '[data-item-uuid][data-type="domainCard"]', diff --git a/module/applications/sheets/actors/companion.mjs b/module/applications/sheets/actors/companion.mjs index b30b9c07..a01b4a64 100644 --- a/module/applications/sheets/actors/companion.mjs +++ b/module/applications/sheets/actors/companion.mjs @@ -11,7 +11,17 @@ export default class DhCompanionSheet extends DHBaseActorSheet { toggleStress: DhCompanionSheet.#toggleStress, actionRoll: DhCompanionSheet.#actionRoll, levelManagement: DhCompanionSheet.#levelManagement - } + }, + contextMenus: [ + { + handler: DHBaseActorSheet.getBaseAttackContextOptions, + selector: '[data-item-uuid][data-type="attack"]', + options: { + parentClassHooks: false, + fixed: true + } + } + ] }; static PARTS = { diff --git a/module/applications/sheets/api/base-actor.mjs b/module/applications/sheets/api/base-actor.mjs index 5cd0f6a5..7b820822 100644 --- a/module/applications/sheets/api/base-actor.mjs +++ b/module/applications/sheets/api/base-actor.mjs @@ -189,6 +189,43 @@ export default class DHBaseActorSheet extends DHApplicationMixin(ActorSheetV2) { return this._getContextMenuCommonOptions.call(this, { usable: true, toChat: true }); } + /** + * Get the set of ContextMenu options for the base attack. + * @returns {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} - The Array of context options passed to the ContextMenu instance + * @this {CharacterSheet} + * @protected + */ + static getBaseAttackContextOptions() { + /**@type {import('@client/applications/ux/context-menu.mjs').ContextMenuEntry[]} */ + return [ + { + label: 'DAGGERHEART.CONFIG.RollTypes.attack.name', + icon: 'fa-solid fa-burst', + onClick: async (event, target) => (await getDocFromElement(target)).use(event) + }, + { + label: 'DAGGERHEART.GENERAL.damage', + icon: 'fa-solid fa-explosion', + onClick: async (event, target) => { + 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( + this.document, + doc + ); + config.hasRoll = false; + return action && action.workflow.get('damage').execute(config, null, true); + } + }, + { + label: 'DAGGERHEART.APPLICATIONS.ContextMenu.sendToChat', + icon: 'fa-solid fa-message', + onClick: async (_, target) => (await getDocFromElement(target)).toChat(this.document.uuid) + } + ]; + } + /* -------------------------------------------- */ /* Application Listener Actions */ /* -------------------------------------------- */ diff --git a/module/data/action/attackAction.mjs b/module/data/action/attackAction.mjs index c4d07c25..1f7e1c92 100644 --- a/module/data/action/attackAction.mjs +++ b/module/data/action/attackAction.mjs @@ -75,7 +75,12 @@ export default class DHAttackAction extends DHDamageAction { const useAltDamage = this.actor?.effects?.find(x => x.type === 'horde')?.active; for (const { value, valueAlt, type } of damage.parts) { const usedValue = useAltDamage ? valueAlt : value; - const str = Roll.replaceFormulaData(usedValue.getFormula(), this.actor?.getRollData() ?? {}); + const damageString = Roll.replaceFormulaData(usedValue.getFormula(), this.actor?.getRollData() ?? {}); + const str = damageString + ? damageString + : game.i18n.format('DAGGERHEART.GENERAL.missingX', { + x: game.i18n.localize('DAGGERHEART.GENERAL.damage') + }); const icons = Array.from(type) .map(t => CONFIG.DH.GENERAL.damageTypes[t]?.icon) From d98a7c951e5363ce1980b1540767bad923385e64 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Mon, 1 Jun 2026 22:20:06 +0200 Subject: [PATCH 09/21] [Fix] Tooltip Color Scope (#1964) * Added DH style to tooltips * Setting dh-style for ResourceManagementTooltip and ArmorManagementTooltip --- module/applications/sheets/actors/character.mjs | 4 ++-- module/documents/tooltipManager.mjs | 1 - 2 files changed, 2 insertions(+), 3 deletions(-) diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index e4d0e6d9..5d0e7144 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -1053,7 +1053,7 @@ export default class CharacterSheet extends DHBaseActorSheet { game.tooltip.activate(target, { html, locked: true, - cssClass: 'bordered-tooltip', + cssClass: 'bordered-tooltip dh-style', direction: 'DOWN' }); @@ -1149,7 +1149,7 @@ export default class CharacterSheet extends DHBaseActorSheet { game.tooltip.activate(target, { html, locked: true, - cssClass: 'bordered-tooltip', + cssClass: 'bordered-tooltip dh-style', direction: 'DOWN', noOffset: true }); diff --git a/module/documents/tooltipManager.mjs b/module/documents/tooltipManager.mjs index 18c03169..3e3f4a16 100644 --- a/module/documents/tooltipManager.mjs +++ b/module/documents/tooltipManager.mjs @@ -3,7 +3,6 @@ import { AdversaryBPPerEncounter, BaseBPPerEncounter } from '../config/encounter export default class DhTooltipManager extends foundry.helpers.interaction.TooltipManager { #wide = false; #bordered = false; - #active = false; async activate(element, options = {}) { const { TextEditor } = foundry.applications.ux; From 5dbcd9448064f97d202abb541cd5b4c5072fe544 Mon Sep 17 00:00:00 2001 From: WBHarry