From 5757db3f490e3449e76e29572ad828866e97dc5b Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Sat, 2 Aug 2025 23:35:45 +0200 Subject: [PATCH] ActiveEffect values can now specify ORIGIN. to grab the value from the origin (#534) --- module/data/action/baseAction.mjs | 39 +++++++++++++++---------------- module/documents/activeEffect.mjs | 12 +++++++++- module/documents/chatMessage.mjs | 14 +++++++++-- 3 files changed, 42 insertions(+), 23 deletions(-) diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 337cdb2a..7dce4f06 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -139,14 +139,14 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel config = await this.actor.diceRoll(config); if (!config) return; } - + if (this.doFollowUp()) { if (this.rollDamage && this.damage.parts.length) await this.rollDamage(event, config); else if (this.trigger) await this.trigger(event, config); - else if(this.hasSave || this.hasEffect) { + else if (this.hasSave || this.hasEffect) { const roll = new Roll(''); roll._evaluated = true; - if(this.hasTarget) config.targetSelection = config.targets.length > 0; + if (this.hasTarget) config.targetSelection = config.targets.length > 0; await CONFIG.Dice.daggerheart.DHRoll.toMessage(roll, config); } } @@ -199,9 +199,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel formula: this.roll.getFormula(), advantage: CONFIG.DH.ACTIONS.advantageState[this.roll.advState].value }; - if (this.roll?.type === 'diceSet' - || !this.hasRoll - ) roll.lite = true; + if (this.roll?.type === 'diceSet' || !this.hasRoll) roll.lite = true; return roll; } @@ -284,8 +282,9 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel } async applyEffect(effect, actor) { + const origin = effect.parent?.parent ? effect.parent.parent.uuid : effect.parent.uuid; // Enable an existing effect on the target if it originated from this effect - const existingEffect = actor.effects.find(e => e.origin === origin.uuid); + const existingEffect = actor.effects.find(e => e.origin === origin); if (existingEffect) { return existingEffect.update( foundry.utils.mergeObject({ @@ -300,7 +299,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel ...effect.toObject(), disabled: false, transfer: false, - origin: origin.uuid + origin: origin }); await ActiveEffect.implementation.create(effectData, { parent: actor }); } @@ -312,8 +311,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel const title = actor.isNPC ? game.i18n.localize('DAGGERHEART.GENERAL.reactionRoll') : game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { - ability: game.i18n.localize(abilities[this.save.trait]?.label) - }); + ability: game.i18n.localize(abilities[this.save.trait]?.label) + }); return actor.diceRoll({ event, title, @@ -329,7 +328,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel } updateSaveMessage(result, message, targetId) { - if(!result) return; + if (!result) return; const updateMsg = this.updateChatMessage.bind(this, message, targetId, { result: result.roll.total, success: result.roll.success @@ -352,16 +351,16 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel async updateChatMessage(message, targetId, changes, chain = true) { setTimeout(async () => { const chatMessage = ui.chat.collection.get(message._id), - msgTarget = chatMessage.system.targets.find(mt => mt.id === targetId) ?? chatMessage.system.oldTargets.find(mt => mt.id === targetId); + msgTarget = + chatMessage.system.targets.find(mt => mt.id === targetId) ?? + chatMessage.system.oldTargets.find(mt => mt.id === targetId); msgTarget.saved = changes; - await chatMessage.update( - { - system: { - targets: chatMessage.system.targets, - oldTargets: chatMessage.system.oldTargets - } - } - ); + await chatMessage.update({ + system: { + targets: chatMessage.system.targets, + oldTargets: chatMessage.system.oldTargets + } + }); }, 100); if (chain) { if (message.system.source.message) diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index 9eec2ffa..e0376d7e 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -70,7 +70,17 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { /**@inheritdoc*/ static applyField(model, change, field) { - const evalValue = this.effectSafeEval(itemAbleRollParse(change.value, model, change.effect.parent)); + const isOriginTarget = change.value.toLowerCase().includes('origin.@'); + let parseModel = model; + if (isOriginTarget && change.effect.origin) { + change.value = change.value.replaceAll(/origin\.@/gi, '@'); + try { + const doc = foundry.utils.fromUuidSync(change.effect.origin); + if (doc) parseModel = doc; + } catch (_) {} + } + + const evalValue = this.effectSafeEval(itemAbleRollParse(change.value, parseModel, change.effect.parent)); change.value = evalValue ?? change.value; super.applyField(model, change, field); } diff --git a/module/documents/chatMessage.mjs b/module/documents/chatMessage.mjs index 0fdc2a5f..6acb0372 100644 --- a/module/documents/chatMessage.mjs +++ b/module/documents/chatMessage.mjs @@ -69,7 +69,6 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { getTargetList() { const targets = this.system.hitTargets; return targets.map(target => game.canvas.tokens.documentCollection.find(t => t.actor.uuid === target.actorId)); - } async onDamage(event) { @@ -77,7 +76,7 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { const targets = this.getTargetList(); if (this.system.onSave) { - const pendingingSaves = this.system.hitTargets.filter(t => t.saved.success === null); + const pendingingSaves = this.system.hitTargets.filter(t => t.saved.success === null); if (pendingingSaves.length) { const confirm = await foundry.applications.api.DialogV2.confirm({ window: { title: 'Pending Reaction Rolls found' }, @@ -112,6 +111,17 @@ export default class DhpChatMessage extends foundry.documents.ChatMessage { } } + getAction(actor, itemId, actionId) { + const item = actor.items.get(itemId), + action = + actor.system.attack?._id === actionId + ? actor.system.attack + : item.system.attack?._id === actionId + ? item.system.attack + : item?.system?.actions?.get(actionId); + return action; + } + async onApplyEffect(event) { event.stopPropagation(); const actor = await foundry.utils.fromUuid(this.system.source.actor);