From fae05c24a8bbd1f8d921f596e8a438b5708b5e30 Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Thu, 23 Apr 2026 00:22:08 +0200 Subject: [PATCH 1/2] 1794 - Include Item Damage (#1827) * Went ahead and made IncludeItemDamage work again, smashing the formulas together * . * Lint fix --- lang/en.json | 5 +- .../dialogs/actionSelectionDialog.mjs | 4 +- .../sheets-configs/action-base-config.mjs | 4 +- module/data/action/attackAction.mjs | 28 ++++---- templates/actionTypes/damage.hbs | 66 +++++++++---------- 5 files changed, 52 insertions(+), 55 deletions(-) diff --git a/lang/en.json b/lang/en.json index 2efd6d7b..99a75f83 100755 --- a/lang/en.json +++ b/lang/en.json @@ -119,8 +119,7 @@ "deleteTriggerContent": "Are you sure you want to delete the {trigger} trigger?", "advantageState": "Advantage State", "damageOnSave": "Damage on Save", - "useDefaultItemValues": "Use default Item values", - "itemDamageIsUsed": "Item Damage Is Used" + "useDefaultItemValues": "Use default Item values" }, "RollField": { "diceRolling": { @@ -135,7 +134,7 @@ "attackModifier": "Attack Modifier", "attackName": "Attack Name", "criticalThreshold": "Critical Threshold", - "includeBase": { "label": "Use Item Damage" }, + "includeBase": { "label": "Include Item Damage" }, "groupAttack": { "label": "Group Attack" }, "multiplier": "Multiplier", "saveHint": "Set a default Trait to enable Reaction Roll. It can be changed later in Reaction Roll Dialog.", diff --git a/module/applications/dialogs/actionSelectionDialog.mjs b/module/applications/dialogs/actionSelectionDialog.mjs index 995c4894..6123c970 100644 --- a/module/applications/dialogs/actionSelectionDialog.mjs +++ b/module/applications/dialogs/actionSelectionDialog.mjs @@ -72,8 +72,8 @@ export default class ActionSelectionDialog extends HandlebarsApplicationMixin(Ap static async #onChooseAction(event, button) { const { actionId } = button.dataset; - this.action = this.item.system.actionsList.find(a => a._id === actionId); - Object.defineProperty(this.event, 'shiftKey', { + this.#action = this.item.system.actionsList.find(a => a._id === actionId); + Object.defineProperty(this.#event, 'shiftKey', { get() { return event.shiftKey; } diff --git a/module/applications/sheets-configs/action-base-config.mjs b/module/applications/sheets-configs/action-base-config.mjs index a94abb26..7406b084 100644 --- a/module/applications/sheets-configs/action-base-config.mjs +++ b/module/applications/sheets-configs/action-base-config.mjs @@ -156,7 +156,7 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) context.openSection = this.openSection; context.tabs = this._getTabs(this.constructor.TABS); context.config = CONFIG.DH; - if (this.action.hasDamage) { + if (this.action.damage) { context.allDamageTypesUsed = !getUnusedDamageTypes(this.action.damage.parts).length; if (this.action.damage.hasOwnProperty('includeBase') && this.action.type === 'attack') @@ -302,7 +302,7 @@ export default class DHActionBaseConfig extends DaggerheartSheet(ApplicationV2) static addDamage(_event) { if (!this.action.damage.parts) return; - const choices = getUnusedDamageTypes(this.action.damage.parts); + const choices = getUnusedDamageTypes(this.action._source.damage.parts); const content = new foundry.data.fields.StringField({ label: game.i18n.localize('Damage Type'), choices, diff --git a/module/data/action/attackAction.mjs b/module/data/action/attackAction.mjs index 15cc1696..c4d07c25 100644 --- a/module/data/action/attackAction.mjs +++ b/module/data/action/attackAction.mjs @@ -1,4 +1,3 @@ -import { DHDamageData } from '../fields/action/damageField.mjs'; import DHDamageAction from './damageAction.mjs'; export default class DHAttackAction extends DHDamageAction { @@ -12,8 +11,19 @@ export default class DHAttackAction extends DHDamageAction { super.prepareData(); if (!!this.item?.system?.attack) { if (this.damage.includeBase) { - const baseDamage = this.getParentDamage(); - this.damage.parts.hitPoints = new DHDamageData(baseDamage); + const baseDamage = this.getParentHitPointDamage(); + if (baseDamage) { + if (!this.damage.parts.hitPoints) { + this.damage.parts.hitPoints = baseDamage; + } else { + for (const type of baseDamage.type) this.damage.parts.hitPoints.type.add(type); + + this.damage.parts.hitPoints.value.custom = { + enabled: true, + formula: `${baseDamage.value.getFormula()} + ${this.damage.parts.hitPoints.value.getFormula()}` + }; + } + } } if (this.roll.useDefault) { this.roll.trait = this.item.system.attack.roll.trait; @@ -22,16 +32,8 @@ export default class DHAttackAction extends DHDamageAction { } } - getParentDamage() { - return { - value: { - multiplier: 'prof', - dice: this.item?.system?.attack.damage.parts.hitPoints.value.dice, - bonus: this.item?.system?.attack.damage.parts.hitPoints.value.bonus ?? 0 - }, - type: this.item?.system?.attack.damage.parts.hitPoints.type, - base: true - }; + getParentHitPointDamage() { + return this.item?.system?.attack.damage.parts.hitPoints; } get damageFormula() { diff --git a/templates/actionTypes/damage.hbs b/templates/actionTypes/damage.hbs index 454d0413..03300840 100644 --- a/templates/actionTypes/damage.hbs +++ b/templates/actionTypes/damage.hbs @@ -31,44 +31,40 @@ {{/unless}} - {{#unless (and @root.source.damage.includeBase (eq key 'hitPoints'))}} - {{#if (and (not @root.isNPC) @root.hasRoll (not dmg.base))}} - {{formField ../fields.resultBased value=dmg.resultBased name=(concat "damage.parts." dmg.applyTo ".resultBased") localize=true classes="checkbox"}} - {{/if}} - {{#if (and (not @root.isNPC) @root.hasRoll (not dmg.base) dmg.resultBased)}} -
-
- {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.hope")}} - {{> formula fields=../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" key=dmg.applyTo path=../path}} -
-
- {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.fear")}} - {{> formula fields=../fields.valueAlt.fields type=../fields.type dmg=dmg source=dmg.valueAlt target="valueAlt" key=dmg.applyTo path=../path}} -
-
- {{else}} - {{> formula fields=../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" key=dmg.applyTo path=../path}} - {{/if}} - - {{#if (and (eq dmg.applyTo 'hitPoints') (ne @root.source.type 'healing'))}} - {{formField ../fields.type value=dmg.type name=(concat ../path "damage.parts." dmg.applyTo ".type") localize=true}} - {{/if}} - - {{#if ../horde}} + {{#if (and (not @root.isNPC) @root.hasRoll (not dmg.base))}} + {{formField ../fields.resultBased value=dmg.resultBased name=(concat "damage.parts." dmg.applyTo ".resultBased") localize=true classes="checkbox"}} + {{/if}} + {{#if (and (not @root.isNPC) @root.hasRoll (not dmg.base) dmg.resultBased)}} +
- {{localize "DAGGERHEART.ACTORS.Adversary.hordeDamage"}} -
- - {{formField ../fields.valueAlt.fields.flatMultiplier value=dmg.valueAlt.flatMultiplier name=(concat ../path "damage.parts." dmg.applyTo ".valueAlt.flatMultiplier") label="DAGGERHEART.ACTIONS.Settings.multiplier" classes="inline-child" localize=true }} - {{formField ../fields.valueAlt.fields.dice value=dmg.valueAlt.dice name=(concat ../path "damage.parts." dmg.applyTo ".valueAlt.dice") classes="inline-child" localize=true}} - {{formField ../fields.valueAlt.fields.bonus value=dmg.valueAlt.bonus name=(concat ../path "damage.parts." dmg.applyTo ".valueAlt.bonus") localize=true classes="inline-child"}} -
+ {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.hope")}} + {{> formula fields=../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" key=dmg.applyTo path=../path}}
- {{/if}} - +
+ {{localize "DAGGERHEART.GENERAL.withThing" thing=(localize "DAGGERHEART.GENERAL.fear")}} + {{> formula fields=../fields.valueAlt.fields type=../fields.type dmg=dmg source=dmg.valueAlt target="valueAlt" key=dmg.applyTo path=../path}} +
+
{{else}} - {{localize "DAGGERHEART.ACTIONS.Config.itemDamageIsUsed"}} - {{/unless}} + {{> formula fields=../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" key=dmg.applyTo path=../path}} + {{/if}} + + {{#if (and (eq dmg.applyTo 'hitPoints') (ne @root.source.type 'healing'))}} + {{formField ../fields.type value=dmg.type name=(concat ../path "damage.parts." dmg.applyTo ".type") localize=true}} + {{/if}} + + {{#if ../horde}} +
+ {{localize "DAGGERHEART.ACTORS.Adversary.hordeDamage"}} +
+ + {{formField ../fields.valueAlt.fields.flatMultiplier value=dmg.valueAlt.flatMultiplier name=(concat ../path "damage.parts." dmg.applyTo ".valueAlt.flatMultiplier") label="DAGGERHEART.ACTIONS.Settings.multiplier" classes="inline-child" localize=true }} + {{formField ../fields.valueAlt.fields.dice value=dmg.valueAlt.dice name=(concat ../path "damage.parts." dmg.applyTo ".valueAlt.dice") classes="inline-child" localize=true}} + {{formField ../fields.valueAlt.fields.bonus value=dmg.valueAlt.bonus name=(concat ../path "damage.parts." dmg.applyTo ".valueAlt.bonus") localize=true classes="inline-child"}} +
+
+ {{/if}} + {{/each}} From 276aee4747005a83fc3909fc08dc8036ac05e9ef Mon Sep 17 00:00:00 2001 From: WBHarry Date: Thu, 23 Apr 2026 00:38:55 +0200 Subject: [PATCH 2/2] Corrected fireball to be two different actions, one for the casting and one for the explosion --- ...inCard_Book_of_Norai_WtwSWXTRZa7QVvmo.json | 128 +++++++++++++----- 1 file changed, 96 insertions(+), 32 deletions(-) diff --git a/src/packs/domains/domainCard_Book_of_Norai_WtwSWXTRZa7QVvmo.json b/src/packs/domains/domainCard_Book_of_Norai_WtwSWXTRZa7QVvmo.json index f32f380a..78028bab 100644 --- a/src/packs/domains/domainCard_Book_of_Norai_WtwSWXTRZa7QVvmo.json +++ b/src/packs/domains/domainCard_Book_of_Norai_WtwSWXTRZa7QVvmo.json @@ -91,7 +91,7 @@ "type": "attack", "_id": "GI2VkIcGDOjFRxpT", "systemPath": "actions", - "description": "

Make a Spellcast Roll against a target within Very Far range. On a success, hurl a sphere of fire toward them that explodes on impact. The target and all creatures within Very Close range of them must make a Reaction Roll (13). Targets who fail take d20+5 magic damage using your Proficiency. Targets who succeed take half damage.

@Template[type:emanation|range:vc]

", + "description": "

Make a Spellcast Roll against a target within Very Far range. On a success, hurl a sphere of fire toward them that explodes on impact.

", "chatDisplay": true, "actionType": "action", "cost": [], @@ -101,34 +101,7 @@ "recovery": null }, "damage": { - "parts": { - "hitPoints": { - "resultBased": false, - "value": { - "custom": { - "enabled": false - }, - "multiplier": "prof", - "dice": "d20", - "bonus": 5, - "flatMultiplier": 1 - }, - "applyTo": "hitPoints", - "type": [ - "magical" - ], - "base": false, - "valueAlt": { - "multiplier": "prof", - "flatMultiplier": 1, - "dice": "d6", - "bonus": null, - "custom": { - "enabled": false - } - } - } - }, + "parts": {}, "includeBase": false }, "target": { @@ -151,14 +124,105 @@ }, "useDefault": false }, + "save": { + "trait": null, + "difficulty": 13, + "damageMod": "half" + }, + "name": "Fireball - Cast", + "img": "icons/magic/fire/explosion-fireball-large-red-orange.webp", + "range": "veryFar" + }, + "HJ749c2a8WTjkSHY": { + "type": "attack", + "_id": "HJ749c2a8WTjkSHY", + "systemPath": "actions", + "baseAction": false, + "description": "

The target and all creatures within Very Close range of them must make a Reaction Roll (13). Targets who fail take d20+5 magic damage using your Proficiency. Targets who succeed take half damage.

", + "chatDisplay": true, + "originItem": { + "type": "itemCollection" + }, + "actionType": "action", + "triggers": [], + "areas": [ + { + "name": "Fireball", + "type": "placed", + "shape": "emanation", + "size": "veryClose", + "effects": [] + } + ], + "cost": [], + "uses": { + "value": null, + "max": "", + "recovery": null, + "consumeOnSuccess": false + }, + "damage": { + "parts": { + "hitPoints": { + "applyTo": "hitPoints", + "resultBased": false, + "value": { + "multiplier": "prof", + "flatMultiplier": 1, + "dice": "d20", + "bonus": 5, + "custom": { + "enabled": false, + "formula": "" + } + }, + "valueAlt": { + "multiplier": "flat", + "flatMultiplier": 1, + "dice": "d6", + "bonus": null, + "custom": { + "enabled": false, + "formula": "" + } + }, + "base": false, + "type": [ + "magical" + ] + } + }, + "includeBase": false, + "direct": false + }, + "target": { + "type": "any", + "amount": null + }, + "effects": [], + "roll": { + "type": null, + "trait": null, + "difficulty": null, + "bonus": null, + "advState": "neutral", + "diceRolling": { + "multiplier": "prof", + "flatMultiplier": 1, + "dice": "d6", + "compare": null, + "treshold": null + }, + "useDefault": false + }, "save": { "trait": "agility", "difficulty": 13, "damageMod": "half" }, - "name": "Fireball", - "img": "icons/magic/fire/explosion-fireball-large-red-orange.webp", - "range": "veryFar" + "name": "Fireball - Explosion", + "range": "", + "img": "icons/magic/fire/explosion-fireball-large-red-orange.webp" } }, "attribution": {