From 363afb97a1e51eeb311cfa681220bd77c3d7f349 Mon Sep 17 00:00:00 2001 From: WBHarry Date: Mon, 7 Jul 2025 20:14:05 +0200 Subject: [PATCH] Added parsing of effect values from Item data model. Almost finished with itemConfig. --- lang/en.json | 8 +- .../dialogs/damageReductionDialog.mjs | 47 +- module/applications/sheets/items/weapon.mjs | 4 +- module/config/generalConfig.mjs | 4 +- module/config/itemConfig.mjs | 643 +++++++++++++++--- module/data/action/baseAction.mjs | 13 +- module/data/actor/character.mjs | 39 +- module/data/item/weapon.mjs | 56 +- module/documents/activeEffect.mjs | 6 +- 9 files changed, 679 insertions(+), 141 deletions(-) diff --git a/lang/en.json b/lang/en.json index a6fa661c..9752d8fd 100755 --- a/lang/en.json +++ b/lang/en.json @@ -482,10 +482,6 @@ "name": "Magic", "description": "You can't mark an Armor Slot to reduce physical damage." }, - "painful": { - "name": "Painful", - "description": "Each time you mark an Armor Slot, you must mark a Stress." - }, "physical": { "name": "Physical", "description": "You can't mark an Armor Slot to reduce magic damage." @@ -883,6 +879,10 @@ "name": "Scary", "description": "On a successful attack, the target must mark a Stress." }, + "selfCorrecting": { + "name": "Self Correcting", + "description": "When you roll a 1 on a damage die, it deals 6 damage instead." + }, "serrated": { "name": "Serrated", "description": "When you roll a 1 on a damage die, it deals 8 damage instead." diff --git a/module/applications/dialogs/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs index 8a67ef98..64da237f 100644 --- a/module/applications/dialogs/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -13,35 +13,41 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap const maxArmorMarks = Math.min( actor.system.armorScore - actor.system.armor.system.marks.value, - actor.system.rules.maxArmorMarked.total + actor.system.rules.damageReduction.maxArmorMarked.total ); const armor = [...Array(maxArmorMarks).keys()].reduce((acc, _) => { acc[foundry.utils.randomID()] = { selected: false }; return acc; }, {}); - const stress = [...Array(actor.system.rules.maxArmorMarked.stressExtra ?? 0).keys()].reduce((acc, _) => { - acc[foundry.utils.randomID()] = { selected: false }; - return acc; - }, {}); + const stress = [...Array(actor.system.rules.damageReduction.maxArmorMarked.stressExtra ?? 0).keys()].reduce( + (acc, _) => { + acc[foundry.utils.randomID()] = { selected: false }; + return acc; + }, + {} + ); this.marks = { armor, stress }; - this.availableStressReductions = Object.keys(actor.system.rules.stressDamageReduction).reduce((acc, key) => { - const dr = actor.system.rules.stressDamageReduction[key]; - if (dr.enabled) { - if (acc === null) acc = {}; + this.availableStressReductions = Object.keys(actor.system.rules.damageReduction.stressDamageReduction).reduce( + (acc, key) => { + const dr = actor.system.rules.damageReduction.stressDamageReduction[key]; + if (dr.enabled) { + if (acc === null) acc = {}; - const damage = damageKeyToNumber(key); - acc[damage] = { - cost: dr.cost, - selected: false, - from: getDamageLabel(damage), - to: getDamageLabel(damage - 1) - }; - } + const damage = damageKeyToNumber(key); + acc[damage] = { + cost: dr.cost, + selected: false, + from: getDamageLabel(damage), + to: getDamageLabel(damage - 1) + }; + } - return acc; - }, null); + return acc; + }, + null + ); } get title() { @@ -90,7 +96,8 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap context.armorScore = this.actor.system.armorScore; context.armorMarks = currentMarks; - context.basicMarksUsed = selectedArmorMarks.length === this.actor.system.rules.maxArmorMarked.total; + context.basicMarksUsed = + selectedArmorMarks.length === this.actor.system.rules.damageReduction.maxArmorMarked.total; const stressReductionStress = this.availableStressReductions ? stressReductions.reduce((acc, red) => acc + red.cost, 0) diff --git a/module/applications/sheets/items/weapon.mjs b/module/applications/sheets/items/weapon.mjs index fdce55fc..cadbfcd9 100644 --- a/module/applications/sheets/items/weapon.mjs +++ b/module/applications/sheets/items/weapon.mjs @@ -34,7 +34,7 @@ export default class WeaponSheet extends DHBaseItemSheet { switch (partId) { case 'settings': - context.features = this.document.system.features.map(x => x.value); + context.features = this.document.system.weaponFeatures.map(x => x.value); break; } @@ -46,6 +46,6 @@ export default class WeaponSheet extends DHBaseItemSheet { * @param {Array} selectedOptions - The currently selected tag objects. */ static async #onFeatureSelect(selectedOptions) { - await this.document.update({ 'system.features': selectedOptions.map(x => ({ value: x.value })) }); + await this.document.update({ 'system.weaponFeatures': selectedOptions.map(x => ({ value: x.value })) }); } } diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 1299dccb..1e06bd20 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -351,7 +351,7 @@ export const abilityCosts = { }, stress: { id: 'stress', - label: 'DAGGERHEART.CONFIG.HealingType.Stress.Name', + label: 'DAGGERHEART.CONFIG.HealingType.stress.name', group: 'TYPES.Actor.character' }, armor: { @@ -361,7 +361,7 @@ export const abilityCosts = { }, hp: { id: 'hp', - label: 'DAGGERHEART.CONFIG.HealingType.HitPoints.Name', + label: 'DAGGERHEART.CONFIG.HealingType.hitPoints.name', group: 'TYPES.Actor.character' }, prayer: { diff --git a/module/config/itemConfig.mjs b/module/config/itemConfig.mjs index 4cdd8125..32e3f9cd 100644 --- a/module/config/itemConfig.mjs +++ b/module/config/itemConfig.mjs @@ -1,16 +1,29 @@ export const armorFeatures = { burning: { label: 'DAGGERHEART.CONFIG.ArmorFeature.burning.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.burning.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.burning.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.burning.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.burning.description', + img: 'icons/magic/fire/flame-burning-embers-yellow.webp' + } + ] }, channeling: { label: 'DAGGERHEART.CONFIG.ArmorFeature.channeling.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.channeling.description', effects: [ { + name: 'DAGGERHEART.CONFIG.ArmorFeature.channeling.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.channeling.description', + img: 'icons/magic/symbols/rune-sigil-horned-blue.webp', changes: [ { - key: 'system.bonuses.spellcast', + key: 'system.bonuses.roll.spellcast', mode: 2, value: '1' } @@ -23,6 +36,9 @@ export const armorFeatures = { description: 'DAGGERHEART.CONFIG.ArmorFeature.difficult.description', effects: [ { + name: 'DAGGERHEART.CONFIG.ArmorFeature.difficult.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.difficult.description', + img: 'icons/magic/control/buff-flight-wings-red.webp', changes: [ { key: 'system.traits.agility.bonus', @@ -68,6 +84,9 @@ export const armorFeatures = { description: 'DAGGERHEART.CONFIG.ArmorFeature.flexible.description', effects: [ { + name: 'DAGGERHEART.CONFIG.ArmorFeature.flexible.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.flexible.description', + img: 'icons/magic/movement/abstract-ribbons-red-orange.webp', changes: [ { key: 'system.evasion.bonus', @@ -80,13 +99,30 @@ export const armorFeatures = { }, fortified: { label: 'DAGGERHEART.CONFIG.ArmorFeature.fortified.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.fortified.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.fortified.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.ArmorFeature.fortified.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.fortified.description', + img: 'icons/magic/defensive/shield-barrier-glowing-blue.webp', + changes: [ + { + key: 'system.rules.damageReduction.increasePerArmorMark', + mode: 3, + value: '2' + } + ] + } + ] }, gilded: { label: 'DAGGERHEART.CONFIG.ArmorFeature.gilded.name', description: 'DAGGERHEART.CONFIG.ArmorFeature.gilded.description', effects: [ { + name: 'DAGGERHEART.CONFIG.ArmorFeature.gilded.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.gilded.description', + img: 'icons/magic/control/control-influence-crown-gold.webp', changes: [ { key: 'system.traits.presence.bonus', @@ -102,6 +138,9 @@ export const armorFeatures = { description: 'DAGGERHEART.CONFIG.ArmorFeature.heavy.description', effects: [ { + name: 'DAGGERHEART.CONFIG.ArmorFeature.heavy.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.heavy.description', + img: 'icons/commodities/metal/ingot-worn-iron.webp', changes: [ { key: 'system.evasion.bonus', @@ -114,19 +153,60 @@ export const armorFeatures = { }, hopeful: { label: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.hopeful.description', + img: 'icons/magic/holy/barrier-shield-winged-blue.webp' + } + ] }, impenetrable: { label: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.impenetrable.description', + img: 'icons/magic/defensive/shield-barrier-flaming-pentagon-purple-orange.webp', + uses: { + max: 1, + recovery: 'shortRest', + value: 0 + }, + cost: [ + { + type: 'stress', + value: 1 + } + ] + } + ] }, magic: { label: 'DAGGERHEART.CONFIG.ArmorFeature.magic.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.magic.description' - }, - painful: { - label: 'DAGGERHEART.CONFIG.ArmorFeature.painful.name', - description: 'DAGGERHEART.CONFIG.ArmorFeature.painful.description' + description: 'DAGGERHEART.CONFIG.ArmorFeature.magic.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.ArmorFeature.magic.name', + description: 'DAGGERHEART.CONFIG.ArmorFeature.magic.description', + img: 'icons/magic/defensive/barrier-shield-dome-blue-purple.webp', + changes: [ + { + key: 'system.rules.damageReduction.magic', + mode: 3, + value: '1' + } + ] + } + ] }, physical: { label: 'DAGGERHEART.CONFIG.ArmorFeature.physical.name', @@ -196,7 +276,7 @@ export const weaponFeatures = { { key: 'system.bonuses.armorScore', mode: 2, - value: '@system.tier + 1' + value: 'ITEM.@system.tier + 1' } ] }, @@ -218,9 +298,9 @@ export const weaponFeatures = { { changes: [ { - key: 'system.bonuses.damage', + key: 'system.bonuses.damage.primaryWeapon.bonus', mode: 2, - value: 'system.levelData.levels.current' + value: '@system.levelData.levels.current' } ] } @@ -228,7 +308,25 @@ export const weaponFeatures = { }, bouncing: { label: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.bouncing.description', + img: 'icons/skills/movement/ball-spinning-blue.webp', + cost: [ + { + type: 'stress', + value: 1, + scalable: true, + step: 1 + } + ] + } + ] }, brave: { label: 'DAGGERHEART.CONFIG.WeaponFeature.brave.name', @@ -248,7 +346,7 @@ export const weaponFeatures = { { key: 'system.damageThresholds.severe', mode: 2, - value: '3' + value: 'ITEM.@system.tier' } ] } @@ -256,7 +354,17 @@ export const weaponFeatures = { }, brutal: { label: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.brutal.description', + img: 'icons/skills/melee/strike-dagger-blood-red.webp' + } + ] }, charged: { label: 'DAGGERHEART.CONFIG.WeaponFeature.charged.name', @@ -264,16 +372,31 @@ export const weaponFeatures = { actions: [ { type: 'effect', - name: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.name', - img: 'icons/skills/melee/shield-damaged-broken-brown.webp', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.charged.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.charged.description', + img: 'icons/magic/lightning/claws-unarmed-strike-teal.webp', cost: [ { type: 'stress', value: 1 } + ], + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.charged.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.charged.description', + img: 'icons/magic/lightning/claws-unarmed-strike-teal.webp', + changes: [ + { + key: 'system.proficiency.bonus', + mode: 2, + value: '1' + } + ] + } ] - // Should add an effect with path system.proficiency.bonus +1 } ] }, @@ -282,10 +405,12 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.name', - img: 'icons/skills/melee/shield-damaged-broken-brown.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.concussive.description', + img: 'icons/skills/melee/shield-block-bash-yellow.webp', cost: [ { type: 'hope', @@ -300,6 +425,9 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.cumbersome.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.cumbersome.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.cumbersome.description', + img: 'icons/commodities/metal/mail-plate-steel.webp', changes: [ { key: 'system.traits.finesse.bonus', @@ -312,27 +440,70 @@ export const weaponFeatures = { }, deadly: { label: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.deadly.description', + img: 'icons/skills/melee/strike-sword-dagger-runes-red.webp' + } + ] }, deflecting: { label: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.description' - // actions: [{ - // type: 'effect', - // name: 'DAGGERHEART.CONFIG.WeaponFeature.Deflecting.Name', - // img: 'icons/skills/melee/strike-flail-destructive-yellow.webp', - // actionType: 'reaction', - // cost: [{ - // type: 'armorSlot', // Needs armorSlot as type - // value: 1 - // }], - // }], + description: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.description', + img: 'icons/skills/melee/hand-grip-sword-strike-orange.webp', + cost: [ + { + type: 'armorStack', + value: 1 + } + ], + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.deflecting.description', + img: 'icons/skills/melee/hand-grip-sword-strike-orange.webp', + changes: [ + { + key: 'system.evasion.bonus', + mode: 2, + value: '@system.armorScore' + } + ] + } + ] + } + ] }, destructive: { label: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.description', + img: 'icons/skills/melee/strike-flail-spiked-pink.webp' + } + ], effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.destructive.description', + img: 'icons/skills/melee/strike-flail-spiked-pink.webp', changes: [ { key: 'system.traits.agility.bonus', @@ -348,10 +519,12 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.name', - img: 'icons/skills/melee/strike-flail-destructive-yellow.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.devastating.description', + img: 'icons/skills/melee/strike-flail-destructive-yellow.webp', cost: [ { type: 'stress', @@ -366,11 +539,19 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.doubleDuty.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.doubleDuty.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.doubleDuty.description', + img: 'icons/skills/melee/sword-shield-stylized-white.webp', changes: [ { key: 'system.bonuses.armorScore', mode: 2, value: '1' + }, + { + key: 'system.bonuses.damage.primaryWeapon.bonus', + mode: 2, + value: '1' } ] } @@ -378,28 +559,60 @@ export const weaponFeatures = { }, doubledup: { label: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.doubledUp.description', + img: 'icons/skills/melee/strike-slashes-orange.webp' + } + ] }, dueling: { label: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.dueling.description', + img: 'icons/skills/melee/weapons-crossed-swords-pink.webp' + } + ] }, eruptive: { label: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.description', + actions: [ + { + type: 'effect', // Should prompt a dc 14 reaction save on adversaries + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.eruptive.description', + img: 'icons/skills/melee/strike-hammer-destructive-blue.webp' + } + ] }, grappling: { label: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.name', - img: 'icons/magic/control/debuff-chains-ropes-net-white.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.grappling.description', + img: 'icons/magic/control/debuff-chains-ropes-net-white.webp', cost: [ { - type: 'stress', + type: 'hope', value: 1 } ] @@ -408,7 +621,32 @@ export const weaponFeatures = { }, greedy: { label: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.description', + img: 'icons/commodities/currency/coins-crown-stack-gold.webp', + // Should cost handfull of gold, + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.greedy.description', + img: 'icons/commodities/currency/coins-crown-stack-gold.webp', + changes: [ + { + key: 'system.proficiency.bonus', + mode: 2, + value: '1' + } + ] + } + ] + } + ] }, healing: { label: 'DAGGERHEART.CONFIG.WeaponFeature.healing.name', @@ -416,9 +654,10 @@ export const weaponFeatures = { actions: [ { type: 'healing', + actionType: 'action', + chatDisplay: true, name: 'DAGGERHEART.CONFIG.WeaponFeature.healing.name', img: 'icons/magic/life/cross-beam-green.webp', - actionType: 'action', healing: { type: 'health', value: { @@ -436,6 +675,9 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.heavy.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.heavy.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.heavy.description', + img: 'icons/commodities/metal/ingot-worn-iron.webp', changes: [ { key: 'system.evasion.bonus', @@ -448,37 +690,99 @@ export const weaponFeatures = { }, hooked: { label: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.hooked.description', + img: 'icons/skills/melee/strike-chain-whip-blue.webp' + } + ] }, hot: { label: 'DAGGERHEART.CONFIG.WeaponFeature.hot.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.hot.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.hot.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.hot.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.hot.description', + img: 'icons/magic/fire/dagger-rune-enchant-flame-red.webp' + } + ] }, invigorating: { label: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.invigorating.description', + img: 'icons/magic/life/heart-cross-green.webp' + } + ] }, lifestealing: { label: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.lifestealing.description', + img: 'icons/magic/unholy/hand-claw-fire-blue.webp' + } + ] }, lockedon: { label: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.lockedOn.description', + img: 'icons/skills/targeting/crosshair-arrowhead-blue.webp' + } + ] }, long: { label: 'DAGGERHEART.CONFIG.WeaponFeature.long.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.long.description' + // actions: [ + // { + // type: 'effect', + // actionType: 'action', + // chatDisplay: true, + // name: 'DAGGERHEART.CONFIG.WeaponFeature.long.name', + // description: 'DAGGERHEART.CONFIG.WeaponFeature.long.description', + // img: 'icons/skills/melee/strike-weapon-polearm-ice-blue.webp', + // } + // ] }, lucky: { label: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.name', - img: 'icons/magic/control/buff-luck-fortune-green.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.lucky.description', + img: 'icons/magic/control/buff-luck-fortune-green.webp', cost: [ { type: 'stress', @@ -493,11 +797,24 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.massive.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.massive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.massive.description', + img: '', changes: [ { key: 'system.evasion.bonus', mode: 2, value: '-1' + }, + { + key: 'system.bonuses.damage.primaryWeapon.extraDice', + mode: 2, + value: '1' + }, + { + key: 'system.rules.weapon.dropLowestDamageDice', + mode: 3, + value: '1' } ] } @@ -508,10 +825,12 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.painful.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.painful.name', - img: 'icons/skills/wounds/injury-face-impact-orange.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.painful.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.painful.description', + img: 'icons/skills/wounds/injury-face-impact-orange.webp', cost: [ { type: 'stress', @@ -524,17 +843,64 @@ export const weaponFeatures = { paired: { label: 'DAGGERHEART.CONFIG.WeaponFeature.paired.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.paired.description', - override: { - bonusDamage: 1 - } + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.paired.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.paired.description', + img: 'icons/skills/melee/strike-flail-spiked-red.webp' + } + ] }, parry: { label: 'DAGGERHEART.CONFIG.WeaponFeature.parry.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.parry.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.parry.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.parry.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.parry.description', + img: 'icons/skills/melee/shield-block-fire-orange.webp' + } + ] }, persuasive: { label: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.description', + img: 'icons/magic/control/hypnosis-mesmerism-eye.webp', + cost: [ + { + type: 'stress', + value: 1 + } + ], + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.persuasive.description', + img: 'icons/magic/control/hypnosis-mesmerism-eye.webp', + changes: [ + { + key: 'system.traits.presence.bonus', + mode: 2, + value: '2' + } + ] + } + ] + } + ] }, pompous: { label: 'DAGGERHEART.CONFIG.WeaponFeature.pompous.name', @@ -542,18 +908,50 @@ export const weaponFeatures = { }, powerful: { label: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.description', + img: 'icons/magic/control/buff-flight-wings-runes-red-yellow.webp', + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.powerful.description', + img: 'icons/magic/control/buff-flight-wings-runes-red-yellow.webp', + changes: [ + { + key: 'system.bonuses.damage.primaryWeapon.extraDice', + mode: 2, + value: '1' + }, + { + key: 'system.rules.weapon.dropLowestDamageDice', + mode: 3, + value: '1' + } + ] + } + ] + } + ] }, protective: { label: 'DAGGERHEART.CONFIG.WeaponFeature.protective.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.protective.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.protective.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.protective.description', + img: 'icons/skills/melee/shield-block-gray-orange.webp', changes: [ { key: 'system.bonuses.armorScore', mode: 2, - value: '@system.tier' + value: '1' } ] } @@ -564,10 +962,12 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.quick.description', actions: [ { - type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.quick.name', - img: 'icons/skills/movement/arrow-upward-yellow.webp', + type: 'effect', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.quick.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.quick.description', + img: 'icons/skills/movement/arrow-upward-yellow.webp', cost: [ { type: 'stress', @@ -582,9 +982,12 @@ export const weaponFeatures = { description: 'DAGGERHEART.CONFIG.WeaponFeature.reliable.description', effects: [ { + name: 'DAGGERHEART.CONFIG.WeaponFeature.reliable.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.reliable.description', + img: 'icons/skills/melee/strike-sword-slashing-red.webp', changes: [ { - key: 'system.bonuses.attack', + key: 'system.bonuses.roll.primaryWeapon.attack', mode: 2, value: 1 } @@ -594,7 +997,17 @@ export const weaponFeatures = { }, reloading: { label: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.reloading.description', + img: 'icons/weapons/ammunition/shot-round-blue.webp' + } + ] }, retractable: { label: 'DAGGERHEART.CONFIG.WeaponFeature.retractable.name', @@ -604,21 +1017,87 @@ export const weaponFeatures = { label: 'DAGGERHEART.CONFIG.WeaponFeature.returning.name', description: 'DAGGERHEART.CONFIG.WeaponFeature.returning.description' }, + selfCorrecting: { + label: 'DAGGERHEART.CONFIG.WeaponFeature.selfCorrecting.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.selfCorrecting.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.selfCorrecting.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.selfCorrecting.description', + img: 'icons/weapons/ammunition/arrow-broadhead-glowing-orange.webp', + changes: [ + { + key: 'system.rules.damage.flipMinDiceValue', + mode: 3, + value: 1 + } + ] + } + ] + }, scary: { label: 'DAGGERHEART.CONFIG.WeaponFeature.scary.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.scary.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.scary.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.scary.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.scary.description', + img: 'icons/magic/death/skull-energy-light-purple.webp' + } + ] }, serrated: { label: 'DAGGERHEART.CONFIG.WeaponFeature.serrated.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.serrated.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.serrated.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.serrated.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.serrated.description', + img: 'icons/weapons/ammunition/arrow-broadhead-glowing-orange.webp', + changes: [ + { + key: 'system.rules.damage.flipMinDiceValue', + mode: 3, + value: 1 + } + ] + } + ] }, sharpwing: { label: 'DAGGERHEART.CONFIG.WeaponFeature.sharpwing.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.sharpwing.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.sharpwing.description', + effects: [ + { + name: 'DAGGERHEART.CONFIG.WeaponFeature.sharpwing.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.sharpwing.description', + img: 'icons/weapons/swords/sword-winged-pink.webp', + changes: [ + { + key: 'system.bonuses.damage.primaryWeapon.bonus', + mode: 2, + value: '@system.traits.agility.total' + } + ] + } + ] }, sheltering: { label: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.description' + description: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.description', + actions: [ + { + type: 'effect', + actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.sheltering.description', + img: 'icons/skills/melee/shield-block-gray-yellow.webp' + } + ] }, startling: { label: 'DAGGERHEART.CONFIG.WeaponFeature.startling.name', @@ -626,9 +1105,11 @@ export const weaponFeatures = { actions: [ { type: 'resource', - name: 'DAGGERHEART.CONFIG.WeaponFeature.startling.name', - img: 'icons/magic/control/fear-fright-mask-orange.webp', actionType: 'action', + chatDisplay: true, + name: 'DAGGERHEART.CONFIG.WeaponFeature.startling.name', + description: 'DAGGERHEART.CONFIG.WeaponFeature.startling.description', + img: 'icons/magic/control/fear-fright-mask-orange.webp', cost: [ { type: 'stress', @@ -644,12 +1125,12 @@ export const weaponFeatures = { }, versatile: { label: 'DAGGERHEART.CONFIG.WeaponFeature.versatile.name', - description: 'DAGGERHEART.CONFIG.WeaponFeature.versatile.description', - versatile: { - characterTrait: '', - range: '', - damage: '' - } + description: 'DAGGERHEART.CONFIG.WeaponFeature.versatile.description' + // versatile: { + // characterTrait: '', + // range: '', + // damage: '' + // } } }; diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 55f08d9a..bd158159 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -290,7 +290,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { } prepareTarget() { - if(!this.target?.type) return []; + if (!this.target?.type) return []; let targets; if (this.target?.type === CONFIG.DH.ACTIONS.targetTypes.self.id) targets = this.constructor.formatTarget(this.actor.token ?? this.actor.prototypeToken); @@ -332,7 +332,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { const resources = config.costs .filter(c => c.enabled !== false) .map(c => { - return { type: c.type, value: (c.total ?? c.value) * -1 }; + return { type: c.type, value: c.total ?? c.value }; }); await this.actor.modifyResource(resources); @@ -384,8 +384,15 @@ export default class DHBaseAction extends foundry.abstract.DataModel { ) return false; } + + const resources = this.actor.system.resources; return realCosts.reduce( - (a, c) => a && this.actor.system.resources[c.type]?.value >= (c.total ?? c.value), + (a, c) => + a && + !( + resources[c.type]?.value + (c.total ?? c.value) > + (resources[c.type]?.maxTotal ?? resources[c.type]?.total) + ), true ); } diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 4ccda1cd..3989c7fc 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -106,6 +106,9 @@ export default class DhCharacter extends BaseDataActor { }), roll: new fields.SchemaField({ attack: new fields.NumberField({ integer: true, initial: 0 }), + primaryWeapon: new fields.SchemaField({ + attack: new fields.NumberField({ integer: true, initial: 0 }) + }), spellcast: new fields.NumberField({ integer: true, initial: 0 }), action: new fields.NumberField({ integer: true, initial: 0 }), hopeOrFear: new fields.NumberField({ integer: true, initial: 0 }) @@ -113,20 +116,29 @@ export default class DhCharacter extends BaseDataActor { damage: new fields.SchemaField({ all: new fields.NumberField({ integer: true, initial: 0 }), physical: new fields.NumberField({ integer: true, initial: 0 }), - magic: new fields.NumberField({ integer: true, initial: 0 }) + magic: new fields.NumberField({ integer: true, initial: 0 }), + primaryWeapon: new fields.SchemaField({ + bonus: new fields.NumberField({ integer: true }), + extraDice: new fields.NumberField({ integer: true }) + }) }) }), companion: new ForeignDocumentUUIDField({ type: 'Actor', nullable: true, initial: null }), rules: new fields.SchemaField({ - maxArmorMarked: new fields.SchemaField({ - value: new fields.NumberField({ required: true, integer: true, initial: 1 }), - bonus: new fields.NumberField({ required: true, integer: true, initial: 0 }), - stressExtra: new fields.NumberField({ required: true, integer: true, initial: 0 }) - }), - stressDamageReduction: new fields.SchemaField({ - severe: stressDamageReductionRule(), - major: stressDamageReductionRule(), - minor: stressDamageReductionRule() + damageReduction: new fields.SchemaField({ + maxArmorMarked: new fields.SchemaField({ + value: new fields.NumberField({ required: true, integer: true, initial: 1 }), + bonus: new fields.NumberField({ required: true, integer: true, initial: 0 }), + stressExtra: new fields.NumberField({ required: true, integer: true, initial: 0 }) + }), + stressDamageReduction: new fields.SchemaField({ + severe: stressDamageReductionRule(), + major: stressDamageReductionRule(), + minor: stressDamageReductionRule() + }), + increasePerArmorMark: new fields.NumberField({ integer: true, initial: 1 }), + magical: new fields.BooleanField({ initial: false }), + physical: new fields.BooleanField({ initial: false }) }), strangePatterns: new fields.NumberField({ integer: true, @@ -135,6 +147,10 @@ export default class DhCharacter extends BaseDataActor { nullable: true, initial: null }), + weapon: new fields.SchemaField({ + dropLowestDamageDice: new fields.BooleanField({ initial: false }), + flipMinDiceValue: new fields.BooleanField({ intial: false }) + }), runeWard: new fields.BooleanField({ initial: false }) }) }; @@ -372,7 +388,8 @@ export default class DhCharacter extends BaseDataActor { experience.total = experience.value + experience.bonus; } - this.rules.maxArmorMarked.total = this.rules.maxArmorMarked.value + this.rules.maxArmorMarked.bonus; + this.rules.damageReduction.maxArmorMarked.total = + this.rules.damageReduction.maxArmorMarked.value + this.rules.damageReduction.maxArmorMarked.bonus; this.armorScore = this.armor ? this.armor.system.baseScore + (this.bonuses.armorScore ?? 0) : 0; this.resources.hitPoints.maxTotal = (this.class.value?.system?.hitPoints ?? 0) + this.resources.hitPoints.bonus; diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index e6cfcbf0..0c0bab46 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -38,7 +38,7 @@ export default class DHWeapon extends BaseDataItem { initial: 'physical' }) }), - features: new fields.ArrayField( + weaponFeatures: new fields.ArrayField( new fields.SchemaField({ value: new fields.StringField({ required: true, @@ -57,18 +57,20 @@ export default class DHWeapon extends BaseDataItem { const allowed = await super._preUpdate(changes, options, user); if (allowed === false) return false; - if (changes.system?.features) { - const removed = this.features.filter(x => !changes.system.features.includes(x)); - const added = changes.system.features.filter(x => !this.features.includes(x)); + if (changes.system?.weaponFeatures) { + const removed = this.weaponFeatures.filter(x => !changes.system.weaponFeatures.includes(x)); + const added = changes.system.weaponFeatures.filter(x => !this.weaponFeatures.includes(x)); + const removedEffectsUpdate = []; + const removedActionsUpdate = []; for (let weaponFeature of removed) { - for (var effectId of weaponFeature.effectIds) { - await this.parent.effects.get(effectId).delete(); - } - - changes.system.actions = this.actions.filter(x => !weaponFeature.actionIds.includes(x._id)); + removedEffectsUpdate.push(...weaponFeature.effectIds); + removedActionsUpdate.push(...weaponFeature.actionIds); } + await this.parent.deleteEmbeddedDocuments('ActiveEffect', removedEffectsUpdate); + changes.system.actions = this.actions.filter(x => !removedActionsUpdate.includes(x._id)); + for (let weaponFeature of added) { const featureData = CONFIG.DH.ITEM.weaponFeatures[weaponFeature.value]; if (featureData.effects?.length > 0) { @@ -81,17 +83,37 @@ export default class DHWeapon extends BaseDataItem { ]); weaponFeature.effectIds = embeddedItems.map(x => x.id); } + + const newActions = []; if (featureData.actions?.length > 0) { - const newActions = featureData.actions.map(action => { - const cls = actionsTypes[action.type]; - return new cls( - { ...action, _id: foundry.utils.randomID(), name: game.i18n.localize(action.name) }, - { parent: this } + for (let action of featureData.actions) { + const embeddedEffects = await this.parent.createEmbeddedDocuments( + 'ActiveEffect', + (action.effects ?? []).map(effect => ({ + ...effect, + transfer: false, + name: game.i18n.localize(effect.name), + description: game.i18n.localize(effect.description) + })) ); - }); - changes.system.actions = [...this.actions, ...newActions]; - weaponFeature.actionIds = newActions.map(x => x._id); + const cls = actionsTypes[action.type]; + newActions.push( + new cls( + { + ...action, + _id: foundry.utils.randomID(), + name: game.i18n.localize(action.name), + description: game.i18n.localize(action.description), + effects: embeddedEffects.map(x => ({ _id: x.id })) + }, + { parent: this } + ) + ); + } } + + changes.system.actions = [...this.actions, ...newActions]; + weaponFeature.actionIds = newActions.map(x => x._id); } } } diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index 65610e7c..1abc2d17 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -25,7 +25,11 @@ export default class DhActiveEffect extends ActiveEffect { } static applyField(model, change, field) { - change.value = Roll.safeEval(Roll.replaceFormulaData(change.value, change.effect.parent)); + const isItemTarget = change.value.toLowerCase().startsWith('item.'); + change.value = isItemTarget ? change.value.slice(5) : change.value; + change.value = Roll.safeEval( + Roll.replaceFormulaData(change.value, isItemTarget ? change.effect.parent : model) + ); super.applyField(model, change, field); }