diff --git a/daggerheart.mjs b/daggerheart.mjs index 3abcd210..4e88c148 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -78,7 +78,6 @@ CONFIG.ux.ContextMenu = applications.ux.DHContextMenu; CONFIG.ux.TooltipManager = documents.DhTooltipManager; CONFIG.ux.TemplateManager = new TemplateManager(); CONFIG.ux.TokenManager = new TokenManager(); -CONFIG.debug.triggers = false; Hooks.once('init', () => { game.system.api = { @@ -90,7 +89,7 @@ Hooks.once('init', () => { fields }; - game.system.registeredTriggers = new game.system.api.data.RegisteredTriggers(); + game.system.registeredTriggers = new RegisteredTriggers(); const { DocumentSheetConfig } = foundry.applications.apps; DocumentSheetConfig.unregisterSheet(TokenDocument, 'core', foundry.applications.sheets.TokenConfig); @@ -390,12 +389,49 @@ Hooks.on('refreshToken', (_, options) => { Hooks.on('renderCompendiumDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html)); Hooks.on('renderDocumentDirectory', (app, html) => applications.ui.ItemBrowser.injectSidebarButton(html)); -/* Non actor-linked Actors should unregister the triggers of their tokens if a scene's token layer is torn down */ -Hooks.on('canvasTearDown', canvas => { - game.system.registeredTriggers.unregisterSceneTriggers(canvas.scene); -}); +class RegisteredTriggers extends Map { + constructor() { + super(); + } -/* Non actor-linked Actors should register the triggers of their tokens on a readied scene */ -Hooks.on('canvasReady', canas => { - game.system.registeredTriggers.registerSceneTriggers(canvas.scene); -}); + async registerTriggers(trigger, actor, triggeringActorType, uuid, commands) { + const existingTrigger = this.get(trigger); + if (!existingTrigger) this.set(trigger, new Map()); + + this.get(trigger).set(uuid, { actor, triggeringActorType, commands }); + } + + async runTrigger(trigger, currentActor, ...args) { + const updates = []; + const triggerSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).triggers; + if (!triggerSettings.enabled) return updates; + + const dualityTrigger = this.get(trigger); + if (dualityTrigger) { + for (let { actor, triggeringActorType, commands } of dualityTrigger.values()) { + const triggerData = CONFIG.DH.TRIGGER.triggers[trigger]; + if (triggerData.usesActor && triggeringActorType !== 'any') { + if (triggeringActorType === 'self' && currentActor?.uuid !== actor) continue; + else if (triggeringActorType === 'other' && currentActor?.uuid === actor) continue; + } + + for (let command of commands) { + try { + const result = await command(...args); + if (result?.updates?.length) updates.push(...result.updates); + } catch (_) { + const triggerName = game.i18n.localize(triggerData.label); + ui.notifications.error( + game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerError', { + trigger: triggerName, + actor: currentActor?.name + }) + ); + } + } + } + } + + return updates; + } +} diff --git a/lang/en.json b/lang/en.json index 8e64ab7d..1157c7b9 100755 --- a/lang/en.json +++ b/lang/en.json @@ -2710,9 +2710,6 @@ "rerollDamage": "Reroll Damage", "assignTagRoll": "Assign as Tag Roll" }, - "ConsoleLogs": { - "triggerRun": "DH TRIGGER | Item '{item}' on actor '{actor}' ran a '{trigger}' trigger." - }, "Countdowns": { "title": "Countdowns", "toggleIconMode": "Toggle Icon Only", diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index e11fee05..dd5f35fc 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -712,7 +712,7 @@ export default class CharacterSheet extends DHBaseActorSheet { headerTitle: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { ability: abilityLabel }), - effects: await game.system.api.data.actions.actionsTypes.base.getEffects(this.document), + effects: Array.from(await this.document.allApplicableEffects()), roll: { trait: button.dataset.attribute, type: 'trait' diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index b590de86..7276316f 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -505,10 +505,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( - this.document, - doc - ); + config.effects = Array.from(await this.document.allApplicableEffects()); config.hasRoll = false; return action && action.workflow.get('damage').execute(config, null, true); } diff --git a/module/data/_module.mjs b/module/data/_module.mjs index 7ad20808..0a476ee9 100644 --- a/module/data/_module.mjs +++ b/module/data/_module.mjs @@ -1,7 +1,6 @@ export { default as DhCombat } from './combat.mjs'; export { default as DhCombatant } from './combatant.mjs'; export { default as DhTagTeamRoll } from './tagTeamRoll.mjs'; -export { default as RegisteredTriggers } from './registeredTriggers.mjs'; export * as countdowns from './countdowns.mjs'; export * as actions from './action/_module.mjs'; diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index b5f95aff..dac4cf68 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -198,7 +198,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel let config = this.prepareConfig(event); if (!config) return; - config.effects = await game.system.api.data.actions.actionsTypes.base.getEffects(this.actor, this.item); + await this.addEffects(config); if (Hooks.call(`${CONFIG.DH.id}.preUseAction`, this, config) === false) return; @@ -266,26 +266,14 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel return config; } - /** - * Get the all potentially applicable effects on the actor - * @param {DHActor} actor The actor performing the action - * @param {DHItem|DhActor} effectParent The parent of the effect - * @returns {DhActiveEffect[]} - */ - static async getEffects(actor, effectParent) { - if (!actor) return []; + /** */ + async addEffects(config) { + let effects = []; + if (this.actor) { + effects = Array.from(await this.actor.allApplicableEffects()); + } - return Array.from(await actor.allApplicableEffects()).filter(effect => { - /* Effects on weapons only ever apply for the weapon itself */ - 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; - } - - return !effect.isSuppressed; - }); + config.effects = effects; } /** diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 0c9fdabe..415fc8d4 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -164,7 +164,26 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { prepareBaseData() { super.prepareBaseData(); - game.system.registeredTriggers.registerItemTriggers(this.parent); + + for (const action of this.actions ?? []) { + if (!action.actor) continue; + + const actionsToRegister = []; + for (let i = 0; i < action.triggers.length; i++) { + const trigger = action.triggers[i]; + const { args } = CONFIG.DH.TRIGGER.triggers[trigger.trigger]; + const fn = new foundry.utils.AsyncFunction(...args, `{${trigger.command}\n}`); + actionsToRegister.push(fn.bind(action)); + if (i === action.triggers.length - 1) + game.system.registeredTriggers.registerTriggers( + trigger.trigger, + action.actor?.uuid, + trigger.triggeringActorType, + this.parent.uuid, + actionsToRegister + ); + } + } } async _preCreate(data, options, user) { @@ -227,28 +246,6 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { const armorData = getScrollTextData(this.parent.parent.system.resources, changed.system.marks, 'armor'); options.scrollingTextData = [armorData]; } - - if (changed.system?.actions) { - const triggersToRemove = Object.keys(changed.system.actions).reduce((acc, key) => { - if (!changed.system.actions[key]) { - const strippedKey = key.replace('-=', ''); - acc.push(...this.actions.get(strippedKey).triggers.map(x => x.trigger)); - } - - return acc; - }, []); - - game.system.registeredTriggers.unregisterTriggers(triggersToRemove, this.parent.uuid); - - if (!(this.parent.parent.token instanceof game.system.api.documents.DhToken)) { - for (const token of this.parent.parent.getActiveTokens()) { - game.system.registeredTriggers.unregisterTriggers( - triggersToRemove, - `${token.document.uuid}.${this.parent.uuid}` - ); - } - } - } } _onUpdate(changed, options, userId) { diff --git a/module/data/registeredTriggers.mjs b/module/data/registeredTriggers.mjs deleted file mode 100644 index fe962c5e..00000000 --- a/module/data/registeredTriggers.mjs +++ /dev/null @@ -1,154 +0,0 @@ -export default class RegisteredTriggers extends Map { - constructor() { - super(); - } - - registerTriggers(triggers, actor, uuid) { - for (const triggerKey of Object.keys(CONFIG.DH.TRIGGER.triggers)) { - const match = triggers[triggerKey]; - const existingTrigger = this.get(triggerKey); - - if (!match) { - if (existingTrigger?.get(uuid)) this.get(triggerKey).delete(uuid); - } else { - const { trigger, triggeringActorType, commands } = match; - - if (!existingTrigger) this.set(trigger, new Map()); - this.get(trigger).set(uuid, { actor, triggeringActorType, commands }); - } - } - } - - registerItemTriggers(item, registerOverride) { - for (const action of item.system.actions ?? []) { - if (!action.actor) continue; - - /* Non actor-linked should only prep synthetic actors so they're not registering triggers unless they're on the canvas */ - if ( - !registerOverride && - !action.actor.prototypeToken.actorLink && - (!(action.actor.parent instanceof game.system.api.documents.DhToken) || !action.actor.parent?.uuid) - ) - continue; - - const triggers = {}; - for (const trigger of action.triggers) { - const { args } = CONFIG.DH.TRIGGER.triggers[trigger.trigger]; - const fn = new foundry.utils.AsyncFunction(...args, `{${trigger.command}\n}`); - - if (!triggers[trigger.trigger]) - triggers[trigger.trigger] = { - trigger: trigger.trigger, - triggeringActorType: trigger.triggeringActorType, - commands: [] - }; - triggers[trigger.trigger].commands.push(fn.bind(action)); - } - - this.registerTriggers(triggers, action.actor?.uuid, item.uuid); - } - } - - unregisterTriggers(triggerKeys, uuid) { - for (const triggerKey of triggerKeys) { - const existingTrigger = this.get(triggerKey); - if (!existingTrigger) return; - - existingTrigger.delete(uuid); - } - } - - unregisterItemTriggers(items) { - for (const item of items) { - if (!item.system.actions.size) continue; - - const triggers = (item.system.actions ?? []).reduce((acc, action) => { - acc.push(...action.triggers.map(x => x.trigger)); - return acc; - }, []); - - this.unregisterTriggers(triggers, item.uuid); - } - } - - unregisterSceneTriggers(scene) { - for (const triggerKey of Object.keys(CONFIG.DH.TRIGGER.triggers)) { - const existingTrigger = this.get(triggerKey); - if (!existingTrigger) continue; - const filtered = new Map(); - for (const [uuid, data] of existingTrigger.entries()) { - if (!uuid.startsWith(scene.uuid)) filtered.set(uuid, data); - } - this.set(triggerKey, filtered); - } - } - - registerSceneTriggers(scene) { - /* TODO: Finish sceneEnvironment registration and unreg */ - // const systemData = new game.system.api.data.scenes.DHScene(scene.flags.daggerheart); - // for (const environment of systemData.sceneEnvironments) { - // for (const feature of environment.system.features) { - // if(feature) this.registerItemTriggers(feature, true); - // } - // } - - for (const actor of scene.tokens.filter(x => x.actor).map(x => x.actor)) { - if (actor.prototypeToken.actorLink) continue; - - for (const item of actor.items) { - this.registerItemTriggers(item); - } - } - } - - async runTrigger(trigger, currentActor, ...args) { - const updates = []; - const triggerSettings = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation).triggers; - if (!triggerSettings.enabled) return updates; - - const dualityTrigger = this.get(trigger); - if (dualityTrigger) { - const tokenBoundActors = ['adversary', 'environment']; - const triggerActors = ['character', ...tokenBoundActors]; - for (let [itemUuid, { actor: actorUuid, triggeringActorType, commands }] of dualityTrigger.entries()) { - const actor = await foundry.utils.fromUuid(actorUuid); - if (!actor || !triggerActors.includes(actor.type)) continue; - if (tokenBoundActors.includes(actor.type) && !actor.getActiveTokens().length) continue; - - const triggerData = CONFIG.DH.TRIGGER.triggers[trigger]; - if (triggerData.usesActor && triggeringActorType !== 'any') { - if (triggeringActorType === 'self' && currentActor?.uuid !== actorUuid) continue; - else if (triggeringActorType === 'other' && currentActor?.uuid === actorUuid) continue; - } - - for (const command of commands) { - try { - if (CONFIG.debug.triggers) { - const item = await foundry.utils.fromUuid(itemUuid); - console.log( - game.i18n.format('DAGGERHEART.UI.ConsoleLogs.triggerRun', { - actor: actor.name ?? '', - item: item?.name ?? '', - trigger: game.i18n.localize(triggerData.label) - }) - ); - } - - const result = await command(...args); - if (result?.updates?.length) updates.push(...result.updates); - } catch (_) { - const triggerName = game.i18n.localize(triggerData.label); - ui.notifications.error( - game.i18n.format('DAGGERHEART.CONFIG.Triggers.triggerError', { - trigger: triggerName, - actor: currentActor?.name - }) - ); - } - } - } - } - - return updates; - } -} diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 27c310ae..1a4153ad 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -104,16 +104,6 @@ export default class DhpActor extends Actor { } } - async _preDelete() { - if (this.prototypeToken.actorLink) { - game.system.registeredTriggers.unregisterItemTriggers(this.items); - } else { - for (const token of this.getActiveTokens()) { - game.system.registeredTriggers.unregisterItemTriggers(token.actor.items); - } - } - } - _onDelete(options, userId) { super._onDelete(options, userId); for (const party of this.parties) { diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index 2f23cc1a..d85bcb45 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -158,9 +158,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { const config = foundry.utils.deepClone(this.system); config.event = event; 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); + await this.system.action.addEffects(config); await this.system.action.workflow.get('damage')?.execute(config, this._id, true); } @@ -194,16 +192,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelectedOrPerm')); this.consumeOnSuccess(); - if (this.system.action) this.system.action.workflow.get('applyDamage')?.execute(config, targets, true); - else { - for (const target of targets) { - const actor = await foundry.utils.fromUuid(target.actorId); - if (!actor) continue; - - if (this.system.hasHealing) actor.takeHealing(this.system.damage); - else actor.takeDamage(this.system.damage); - } - } + this.system.action?.workflow.get('applyDamage')?.execute(config, targets, true); } async onRollSave(event) { diff --git a/module/documents/item.mjs b/module/documents/item.mjs index 0a163dab..7607658c 100644 --- a/module/documents/item.mjs +++ b/module/documents/item.mjs @@ -208,23 +208,4 @@ export default class DHItem extends foundry.documents.Item { cls.create(msg); } - - deleteTriggers() { - const actions = Array.from(this.system.actions ?? []); - if (!actions.length) return; - - const triggerKeys = actions.flatMap(action => action.triggers.map(x => x.trigger)); - - game.system.registeredTriggers.unregisterTriggers(triggerKeys, this.uuid); - - if (!(this.actor.parent instanceof game.system.api.documents.DhToken)) { - for (const token of this.actor.getActiveTokens()) { - game.system.registeredTriggers.unregisterTriggers(triggerKeys, `${token.document.uuid}.${this.uuid}`); - } - } - } - - async _preDelete() { - this.deleteTriggers(); - } } diff --git a/module/documents/token.mjs b/module/documents/token.mjs index 317f3acf..4ac29264 100644 --- a/module/documents/token.mjs +++ b/module/documents/token.mjs @@ -536,10 +536,4 @@ export default class DHToken extends CONFIG.Token.documentClass { }; } //#endregion - - async _preDelete() { - if (this.actor && !this.actor.prototypeToken?.actorLink) { - game.system.registeredTriggers.unregisterItemTriggers(this.actor.items); - } - } } diff --git a/src/packs/items/weapons/weapon_Advanced_Greatstaff_4UzxqfkwF8gDSdu7.json b/src/packs/items/weapons/weapon_Advanced_Greatstaff_4UzxqfkwF8gDSdu7.json index c66354c2..6ce54823 100644 --- a/src/packs/items/weapons/weapon_Advanced_Greatstaff_4UzxqfkwF8gDSdu7.json +++ b/src/packs/items/weapons/weapon_Advanced_Greatstaff_4UzxqfkwF8gDSdu7.json @@ -113,7 +113,18 @@ "name": "Powerful", "description": "On a successful attack, roll an additional damage die and discard the lowest result.", "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "changes": [], + "changes": [ + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" + } + ], "_id": "sGVVxSM68Fmr1sSM", "type": "base", "system": {}, diff --git a/src/packs/items/weapons/weapon_Advanced_Greatsword_MAC6YWTo4lzSotQc.json b/src/packs/items/weapons/weapon_Advanced_Greatsword_MAC6YWTo4lzSotQc.json index 71226630..fe3fff0e 100644 --- a/src/packs/items/weapons/weapon_Advanced_Greatsword_MAC6YWTo4lzSotQc.json +++ b/src/packs/items/weapons/weapon_Advanced_Greatsword_MAC6YWTo4lzSotQc.json @@ -118,6 +118,16 @@ "key": "system.evasion", "mode": 2, "value": "-1" + }, + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" } ], "_id": "E0PjC15OP55vIype", diff --git a/src/packs/items/weapons/weapon_Double_Flail_xm1yU7k58fMgXxRR.json b/src/packs/items/weapons/weapon_Double_Flail_xm1yU7k58fMgXxRR.json index a118b399..2e00f9c1 100644 --- a/src/packs/items/weapons/weapon_Double_Flail_xm1yU7k58fMgXxRR.json +++ b/src/packs/items/weapons/weapon_Double_Flail_xm1yU7k58fMgXxRR.json @@ -113,7 +113,18 @@ "name": "Powerful", "description": "On a successful attack, roll an additional damage die and discard the lowest result.", "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "changes": [], + "changes": [ + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" + } + ], "_id": "DCie5eR1dZH2Qvln", "type": "base", "system": {}, diff --git a/src/packs/items/weapons/weapon_Elder_Bow_JdWcn9W1edhAEInL.json b/src/packs/items/weapons/weapon_Elder_Bow_JdWcn9W1edhAEInL.json index 35659402..b6437781 100644 --- a/src/packs/items/weapons/weapon_Elder_Bow_JdWcn9W1edhAEInL.json +++ b/src/packs/items/weapons/weapon_Elder_Bow_JdWcn9W1edhAEInL.json @@ -113,7 +113,18 @@ "name": "Powerful", "description": "On a successful attack, roll an additional damage die and discard the lowest result.", "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "changes": [], + "changes": [ + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" + } + ], "_id": "sZ1XotFlGdkPPDG4", "type": "base", "system": {}, diff --git a/src/packs/items/weapons/weapon_Floating_Bladeshards_3vti3xfo0wJND7ew.json b/src/packs/items/weapons/weapon_Floating_Bladeshards_3vti3xfo0wJND7ew.json index 232f26e9..fa7b7d45 100644 --- a/src/packs/items/weapons/weapon_Floating_Bladeshards_3vti3xfo0wJND7ew.json +++ b/src/packs/items/weapons/weapon_Floating_Bladeshards_3vti3xfo0wJND7ew.json @@ -113,7 +113,18 @@ "name": "Powerful", "description": "On a successful attack, roll an additional damage die and discard the lowest result.", "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "changes": [], + "changes": [ + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" + } + ], "_id": "T831j6kZiMnpMNmv", "type": "base", "system": {}, diff --git a/src/packs/items/weapons/weapon_Gilded_Falchion_VwcOgqnzjf9LBj2S.json b/src/packs/items/weapons/weapon_Gilded_Falchion_VwcOgqnzjf9LBj2S.json index ee8afebc..551dcf56 100644 --- a/src/packs/items/weapons/weapon_Gilded_Falchion_VwcOgqnzjf9LBj2S.json +++ b/src/packs/items/weapons/weapon_Gilded_Falchion_VwcOgqnzjf9LBj2S.json @@ -113,7 +113,18 @@ "name": "Powerful", "description": "On a successful attack, roll an additional damage die and discard the lowest result.", "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "changes": [], + "changes": [ + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" + } + ], "_id": "ir4iKLIQ4CH1Qckn", "type": "base", "system": {}, diff --git a/src/packs/items/weapons/weapon_Greatbow_MXBpbqQsZFln4rZk.json b/src/packs/items/weapons/weapon_Greatbow_MXBpbqQsZFln4rZk.json index f56e77c7..f97e5432 100644 --- a/src/packs/items/weapons/weapon_Greatbow_MXBpbqQsZFln4rZk.json +++ b/src/packs/items/weapons/weapon_Greatbow_MXBpbqQsZFln4rZk.json @@ -113,7 +113,18 @@ "name": "Powerful", "description": "On a successful attack, roll an additional damage die and discard the lowest result.", "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "changes": [], + "changes": [ + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" + } + ], "_id": "K4VgrDjVj1U1m9Ie", "type": "base", "system": {}, diff --git a/src/packs/items/weapons/weapon_Greatstaff_Yk8pTEmyLLi4095S.json b/src/packs/items/weapons/weapon_Greatstaff_Yk8pTEmyLLi4095S.json index 66c12e5e..0fbfc2b4 100644 --- a/src/packs/items/weapons/weapon_Greatstaff_Yk8pTEmyLLi4095S.json +++ b/src/packs/items/weapons/weapon_Greatstaff_Yk8pTEmyLLi4095S.json @@ -113,7 +113,18 @@ "name": "Powerful", "description": "On a successful attack, roll an additional damage die and discard the lowest result.", "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "changes": [], + "changes": [ + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" + } + ], "_id": "904orawScurM9GjG", "type": "base", "system": {}, diff --git a/src/packs/items/weapons/weapon_Greatsword_70ysaFJDREwTgvZa.json b/src/packs/items/weapons/weapon_Greatsword_70ysaFJDREwTgvZa.json index f60e438d..4707e397 100644 --- a/src/packs/items/weapons/weapon_Greatsword_70ysaFJDREwTgvZa.json +++ b/src/packs/items/weapons/weapon_Greatsword_70ysaFJDREwTgvZa.json @@ -118,6 +118,16 @@ "key": "system.evasion", "mode": 2, "value": "-1" + }, + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" } ], "_id": "cffkpiwGpEGhjiUC", diff --git a/src/packs/items/weapons/weapon_Improved_Greatstaff_LCuTrYXi4lhg6LqW.json b/src/packs/items/weapons/weapon_Improved_Greatstaff_LCuTrYXi4lhg6LqW.json index cf1bdf63..5faa0b0e 100644 --- a/src/packs/items/weapons/weapon_Improved_Greatstaff_LCuTrYXi4lhg6LqW.json +++ b/src/packs/items/weapons/weapon_Improved_Greatstaff_LCuTrYXi4lhg6LqW.json @@ -113,7 +113,18 @@ "name": "Powerful", "description": "On a successful attack, roll an additional damage die and discard the lowest result.", "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "changes": [], + "changes": [ + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" + } + ], "_id": "hnayB09P25ZW3gVY", "type": "base", "system": {}, diff --git a/src/packs/items/weapons/weapon_Improved_Greatsword_FPX4ouDrxXiQ5MDf.json b/src/packs/items/weapons/weapon_Improved_Greatsword_FPX4ouDrxXiQ5MDf.json index f71e5ea6..f8407b13 100644 --- a/src/packs/items/weapons/weapon_Improved_Greatsword_FPX4ouDrxXiQ5MDf.json +++ b/src/packs/items/weapons/weapon_Improved_Greatsword_FPX4ouDrxXiQ5MDf.json @@ -118,6 +118,16 @@ "key": "system.evasion", "mode": 2, "value": "-1" + }, + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" } ], "_id": "2nl35v8sPAudiOIb", diff --git a/src/packs/items/weapons/weapon_Legendary_Greatstaff_jDtvEabkHY1GFgfc.json b/src/packs/items/weapons/weapon_Legendary_Greatstaff_jDtvEabkHY1GFgfc.json index a5ea82f9..0d317f0d 100644 --- a/src/packs/items/weapons/weapon_Legendary_Greatstaff_jDtvEabkHY1GFgfc.json +++ b/src/packs/items/weapons/weapon_Legendary_Greatstaff_jDtvEabkHY1GFgfc.json @@ -113,7 +113,18 @@ "name": "Powerful", "description": "On a successful attack, roll an additional damage die and discard the lowest result.", "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "changes": [], + "changes": [ + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" + } + ], "_id": "OV1Ly7vX4owBUgLQ", "type": "base", "system": {}, diff --git a/src/packs/items/weapons/weapon_Legendary_Greatsword_zMZ46F9VR7zdTxb9.json b/src/packs/items/weapons/weapon_Legendary_Greatsword_zMZ46F9VR7zdTxb9.json index 840e7ec7..fb7a2ed3 100644 --- a/src/packs/items/weapons/weapon_Legendary_Greatsword_zMZ46F9VR7zdTxb9.json +++ b/src/packs/items/weapons/weapon_Legendary_Greatsword_zMZ46F9VR7zdTxb9.json @@ -118,6 +118,16 @@ "key": "system.evasion", "mode": 2, "value": "-1" + }, + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" } ], "_id": "oRCiXSElN5xufUfn", diff --git a/src/packs/items/weapons/weapon_Mage_Orb_XKBmBUEoGLdLcuqQ.json b/src/packs/items/weapons/weapon_Mage_Orb_XKBmBUEoGLdLcuqQ.json index 3b5983f5..8d3fd741 100644 --- a/src/packs/items/weapons/weapon_Mage_Orb_XKBmBUEoGLdLcuqQ.json +++ b/src/packs/items/weapons/weapon_Mage_Orb_XKBmBUEoGLdLcuqQ.json @@ -113,7 +113,18 @@ "name": "Powerful", "description": "On a successful attack, roll an additional damage die and discard the lowest result.", "img": "icons/magic/control/buff-flight-wings-runes-red-yellow.webp", - "changes": [], + "changes": [ + { + "key": "system.bonuses.damage.primaryWeapon.extraDice", + "mode": 2, + "value": "1" + }, + { + "key": "system.rules.weapon.dropLowestDamageDice", + "mode": 5, + "value": "1" + } + ], "_id": "2J6vzNUel78JFypp", "type": "base", "system": {}, diff --git a/system.json b/system.json index 50a9c83b..50b4cd2d 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.2", + "version": "1.5.1", "compatibility": { "minimum": "13.346", "verified": "13.351",