diff --git a/module/applications/dialogs/d20RollDialog.mjs b/module/applications/dialogs/d20RollDialog.mjs index 4b8749a3..a06708e6 100644 --- a/module/applications/dialogs/d20RollDialog.mjs +++ b/module/applications/dialogs/d20RollDialog.mjs @@ -45,6 +45,10 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio return this.config.title; } + get actor() { + return this.config?.data?.parent; + } + /** @override */ static PARTS = { header: { @@ -69,9 +73,10 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio icon })); + this.config.costs ??= []; if (this.config.costs?.length) { const updatedCosts = game.system.api.fields.ActionFields.CostField.calcCosts.call( - this.action, + this.action ?? { actor: this.actor }, this.config.costs ); context.costs = updatedCosts.map(x => ({ @@ -80,7 +85,10 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio ? this.action.parent.parent.name : game.i18n.localize(CONFIG.DH.GENERAL.abilityCosts[x.key].label) })); - context.canRoll = game.system.api.fields.ActionFields.CostField.hasCost.call(this.action, updatedCosts); + context.canRoll = game.system.api.fields.ActionFields.CostField.hasCost.call( + this.action ?? { actor: this.actor }, + updatedCosts + ); this.config.data.scale = this.config.costs[0].total; } if (this.config.uses?.max) { @@ -143,6 +151,12 @@ export default class D20RollDialog extends HandlebarsApplicationMixin(Applicatio this.config.experiences.indexOf(button.dataset.key) > -1 ? this.config.experiences.filter(x => x !== button.dataset.key) : [...this.config.experiences, button.dataset.key]; + if(this.config?.data?.parent?.type === 'character' || this.config?.data?.parent?.type === 'companion') { + this.config.costs = + this.config.costs.indexOf(this.config.costs.find(c => c.extKey === button.dataset.key)) > -1 + ? this.config.costs.filter(x => x.extKey !== button.dataset.key) + : [...this.config.costs, { extKey: button.dataset.key, key: 'hope', value: 1, name: this.config.data?.experiences?.[button.dataset.key]?.name }]; + } this.render(); } diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 55662f90..e93de7ed 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -631,13 +631,34 @@ export default class CharacterSheet extends DHBaseActorSheet { }, hasRoll: true }; - this.document.diceRoll({ + const result = await this.document.diceRoll({ ...config, headerTitle: `${game.i18n.localize('DAGGERHEART.GENERAL.dualityRoll')}: ${this.actor.name}`, title: game.i18n.format('DAGGERHEART.UI.Chat.dualityRoll.abilityCheckTitle', { ability: abilityLabel }) }); + + setTimeout(() => { + this.consumeResource(result?.costs); + }, 50); + } + + async consumeResource(costs) { + if(!costs?.length) return; + const usefulResources = foundry.utils.deepClone(this.actor.system.resources); + const resources = game.system.api.fields.ActionFields.CostField.getRealCosts(costs) + .map(c => { + const resource = usefulResources[c.key]; + return { + key: c.key, + value: (c.total ?? c.value) * (resource.isReversed ? 1 : -1), + target: resource.target, + keyIsID: resource.keyIsID + }; + }); + + await this.actor.modifyResource(resources); } //TODO: redo toggleEquipItem method diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 516419b9..954e5328 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -221,12 +221,11 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel } } - const resources = config.costs + const resources = game.system.api.fields.ActionFields.CostField.getRealCosts(config.costs) .filter( c => - c.enabled !== false && - ((!successCost && (!c.consumeOnSuccess || config.roll?.success)) || - (successCost && c.consumeOnSuccess)) + (!successCost && (!c.consumeOnSuccess || config.roll?.success)) || + (successCost && c.consumeOnSuccess) ) .map(c => { const resource = usefulResources[c.key]; @@ -238,7 +237,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel }; }); - await this.actor.modifyResource(resources); + await (this.actor.system.partner ?? this.actor).modifyResource(resources); if ( config.uses?.enabled && ((!successCost && (!config.uses?.consumeOnSuccess || config.roll?.success)) || diff --git a/module/data/fields/action/costField.mjs b/module/data/fields/action/costField.mjs index b9495e8b..4972a9a0 100644 --- a/module/data/fields/action/costField.mjs +++ b/module/data/fields/action/costField.mjs @@ -47,6 +47,7 @@ export default class CostField extends fields.ArrayField { static hasCost(costs) { const realCosts = CostField.getRealCosts.call(this, costs), hasFearCost = realCosts.findIndex(c => c.key === 'fear'); + if (hasFearCost > -1) { const fearCost = realCosts.splice(hasFearCost, 1)[0]; if ( @@ -70,7 +71,8 @@ export default class CostField extends fields.ArrayField { } static getResources(costs) { - const actorResources = this.actor.system.resources; + const actorResources = foundry.utils.deepClone(this.actor.system.resources); + if(this.actor.system.partner) actorResources.hope = foundry.utils.deepClone(this.actor.system.partner.system.resources.hope); const itemResources = {}; for (let itemResource of costs) { if (itemResource.keyIsID) { @@ -89,7 +91,13 @@ export default class CostField extends fields.ArrayField { static getRealCosts(costs) { const realCosts = costs?.length ? costs.filter(c => c.enabled) : []; - return realCosts; + let mergedCosts = []; + realCosts.forEach(c => { + const getCost = Object.values(mergedCosts).find(gc => gc.key === c.key); + if(getCost) getCost.total += c.total; + else mergedCosts.push(c); + }); + return mergedCosts; } static formatMax(max) { diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index 710a2728..889b24b3 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -236,7 +236,9 @@ export const registerRollDiceHooks = () => { if (updates.length) { const target = actor.system.partner ?? actor; if (!['dead', 'unconcious'].some(x => actor.statuses.has(x))) { - target.modifyResource(updates); + setTimeout(() => { + target.modifyResource(updates); + }, 50); } } diff --git a/templates/dialogs/dice-roll/costSelection.hbs b/templates/dialogs/dice-roll/costSelection.hbs index 84bc3399..775e681c 100644 --- a/templates/dialogs/dice-roll/costSelection.hbs +++ b/templates/dialogs/dice-roll/costSelection.hbs @@ -17,7 +17,11 @@