From e37fc83c590db43920439eecf5e609d170661484 Mon Sep 17 00:00:00 2001 From: WBHarry Date: Sat, 12 Jul 2025 16:45:30 +0200 Subject: [PATCH] Actions can only use item resources from their parent item --- .../sheets-configs/action-config.mjs | 55 +++++-------------- module/applications/sheets/api/base-item.mjs | 24 +++++++- module/data/action/baseAction.mjs | 21 +++---- module/data/item/base.mjs | 23 ++++---- module/documents/actor.mjs | 3 +- .../sheets/global/partials/inventory-item.hbs | 4 +- .../global/partials/resource-section.hbs | 23 +++++--- 7 files changed, 79 insertions(+), 74 deletions(-) diff --git a/module/applications/sheets-configs/action-config.mjs b/module/applications/sheets-configs/action-config.mjs index cf02eb70..70a9f4d4 100644 --- a/module/applications/sheets-configs/action-config.mjs +++ b/module/applications/sheets-configs/action-config.mjs @@ -111,7 +111,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { context.hasBaseDamage = !!this.action.parent.attack; context.getRealIndex = this.getRealIndex.bind(this); context.getEffectDetails = this.getEffectDetails.bind(this); - context.costOptions = await this.getCostOptions(); + context.costOptions = this.getCostOptions(); context.disableOption = this.disableOption.bind(this); context.isNPC = this.action.actor && this.action.actor.type !== 'character'; context.hasRoll = this.action.hasRoll; @@ -130,42 +130,17 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { this.render(true); } - async getCostOptions() { - const worldItems = this.action.actor ? this.action.actor.items : game.items; - const compendiumItems = this.action.actor - ? [] - : Array.from(game.packs).flatMap(x => - x.index.map(x => ({ - id: x._id, - uuid: x.uuid, - name: x.name - })) - ); + getCostOptions() { + const options = foundry.utils.deepClone(CONFIG.DH.GENERAL.abilityCosts); + const resource = this.action.parent.resource; + if (resource) { + options[this.action.parent.parent.id] = { + label: this.action.parent.parent.name, + group: 'TYPES.Actor.character' + }; + } - const resourceOptions = [...worldItems, ...compendiumItems].reduce((acc, x) => { - if (['feature', 'domainCard'].includes(x.type) && x.system.resource?.max) { - acc.push({ - id: x.id, - uuid: x.uuid, - label: x.name, - group: 'TYPES.Actor.character' - }); - } - - return acc; - }, []); - - const abilityCosts = Object.values(CONFIG.DH.GENERAL.abilityCosts); - const sortedOptions = [...abilityCosts, ...resourceOptions].sort((a, b) => { - const groupSort = game.i18n.localize(a.group).localeCompare(game.i18n.localize(b.group)); - return groupSort ? groupSort : game.i18n.localize(a.label).localeCompare(game.i18n.localize(b.label)); - }); - - return sortedOptions.reduce((acc, x) => { - acc[x.uuid ?? x.id] = x; - - return acc; - }, {}); + return options; } disableOption(index, costOptions, choices) { @@ -185,15 +160,15 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { return this.action.item.effects.get(id); } - async _prepareSubmitData(_event, formData) { + _prepareSubmitData(_event, formData) { const submitData = foundry.utils.expandObject(formData.object); for (const keyPath of this.constructor.CLEAN_ARRAYS) { const data = foundry.utils.getProperty(submitData, keyPath); const dataValues = data ? Object.values(data) : []; if (keyPath === 'cost') { for (var value of dataValues) { - const item = await foundry.utils.fromUuid(value.key ?? ''); - value.keyIsUUID = Boolean(item); + const item = this.action.parent.parent.id === value.key; + value.keyIsID = Boolean(item); } } @@ -203,7 +178,7 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { } static async updateForm(event, _, formData) { - const submitData = await this._prepareSubmitData(event, formData), + const submitData = this._prepareSubmitData(event, formData), data = foundry.utils.mergeObject(this.action.toObject(), submitData), container = foundry.utils.getProperty(this.action.parent, this.action.systemPath); let newActions; diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs index d624acc6..f6688216 100644 --- a/module/applications/sheets/api/base-item.mjs +++ b/module/applications/sheets/api/base-item.mjs @@ -24,7 +24,9 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { removeAction: DHBaseItemSheet.#removeAction, addFeature: DHBaseItemSheet.#addFeature, editFeature: DHBaseItemSheet.#editFeature, - removeFeature: DHBaseItemSheet.#removeFeature + removeFeature: DHBaseItemSheet.#removeFeature, + addResource: DHBaseItemSheet.#addResource, + removeResource: DHBaseItemSheet.#removeResource }, dragDrop: [ { dragSelector: null, dropSelector: '.tab.features .drop-section' }, @@ -215,6 +217,26 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { }); } + /** + * Add a resource to the item. + * @type {ApplicationClickAction} + */ + static async #addResource() { + await this.document.update({ + 'system.resource': { value: 0 } + }); + } + + /** + * Remove the resource from the item. + * @type {ApplicationClickAction} + */ + static async #removeResource() { + await this.document.update({ + 'system.resource': null + }); + } + /* -------------------------------------------- */ /* Application Drag/Drop */ /* -------------------------------------------- */ diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 2516d28f..fdca2be2 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -41,7 +41,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { required: true, initial: 'hope' }), - keyIsUUID: new fields.BooleanField(), + keyIsID: new fields.BooleanField(), value: new fields.NumberField({ nullable: true, initial: 1 }), scalable: new fields.BooleanField({ initial: false }), step: new fields.NumberField({ nullable: true, initial: null }) @@ -337,12 +337,11 @@ export default class DHBaseAction extends foundry.abstract.DataModel { async consume(config) { const usefulResources = foundry.utils.deepClone(this.actor.system.resources); for (var cost of config.costs) { - if (cost.keyIsUUID) { - const item = await foundry.utils.fromUuid(cost.key); + if (cost.keyIsID) { usefulResources[cost.key] = { - value: item.system.resource.value, - target: item, - keyIsUUID: true + value: cost.value, + target: this.parent.parent, + keyIsID: true }; } } @@ -354,7 +353,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { key: c.key, value: (c.total ?? c.value) * (resource.hasOwnProperty('maxTotal') ? 1 : -1), target: resource.target, - keyIsUUID: resource.keyIsUUID + keyIsID: resource.keyIsID }; }); @@ -400,10 +399,9 @@ export default class DHBaseAction extends foundry.abstract.DataModel { const actorResources = this.actor.system.resources; const itemResources = {}; for (var itemResource of costs) { - if (itemResource.keyIsUUID) { - const item = await foundry.utils.fromUuid(itemResource.key); + if (itemResource.keyIsID) { itemResources[itemResource.key] = { - value: item?.system?.resource?.value ?? 0 + value: this.parent.resource.value ?? 0 }; } } @@ -414,6 +412,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { }; } + /* COST */ async hasCost(costs) { const realCosts = this.getRealCosts(costs), hasFearCost = realCosts.findIndex(c => c.key === 'fear'); @@ -436,7 +435,6 @@ export default class DHBaseAction extends foundry.abstract.DataModel { true ); } - /* COST */ /* USES */ calcUses(uses) { @@ -451,7 +449,6 @@ export default class DHBaseAction extends foundry.abstract.DataModel { if (!uses) return true; return (uses.hasOwnProperty('enabled') && !uses.enabled) || uses.value + 1 <= uses.max; } - /* USES */ /* TARGET */ isTargetFriendly(target) { diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 513cc08e..f73e7814 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -37,16 +37,19 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { if (this.metadata.hasDescription) schema.description = new fields.HTMLField({ required: true, nullable: true }); if (this.metadata.hasResource) { - schema.resource = new fields.SchemaField({ - value: new fields.NumberField({ integer: true, min: 0, nullable: true, initial: null }), - max: new fields.NumberField({ nullable: true, initial: null }), - icon: new fields.StringField(), - recovery: new fields.StringField({ - choices: CONFIG.DH.GENERAL.refreshTypes, - initial: null, - nullable: true - }) - }); + schema.resource = new fields.SchemaField( + { + value: new fields.NumberField({ integer: true, min: 0, initial: 0 }), + max: new fields.NumberField({ nullable: true, initial: null }), + icon: new fields.StringField(), + recovery: new fields.StringField({ + choices: CONFIG.DH.GENERAL.refreshTypes, + initial: null, + nullable: true + }) + }, + { nullable: true, initial: null } + ); } if (this.metadata.isQuantifiable) diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index be2ce5bd..9762fbbf 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -526,9 +526,8 @@ export default class DhpActor extends Actor { items: {} }; resources.forEach(r => { - if (r.keyIsUUID) { + if (r.keyIsID) { updates.items[r.key] = { - uuid: r.key, target: r.target, resources: { 'system.resource.value': r.target.system.resource.value + r.value diff --git a/templates/sheets/global/partials/inventory-item.hbs b/templates/sheets/global/partials/inventory-item.hbs index 39af0c51..6ad7885e 100644 --- a/templates/sheets/global/partials/inventory-item.hbs +++ b/templates/sheets/global/partials/inventory-item.hbs @@ -1,7 +1,7 @@
  • -
    +
    {{#if isCompanion}} {{item.name}} {{else}} @@ -123,7 +123,7 @@
    {{/if}}
    - {{#if (and (not isSidebar) item.system.resource.max)}} + {{#if (and (not isSidebar) item.system.resource)}}
    diff --git a/templates/sheets/global/partials/resource-section.hbs b/templates/sheets/global/partials/resource-section.hbs index 34d8b1e1..09a6fbd0 100644 --- a/templates/sheets/global/partials/resource-section.hbs +++ b/templates/sheets/global/partials/resource-section.hbs @@ -1,10 +1,19 @@
    - {{localize "DAGGERHEART.GENERAL.Resource.single"}} + + {{localize "DAGGERHEART.GENERAL.Resource.single"}} + {{#unless source.system.resource}} + + {{else}} + + {{/unless}} + -
    - {{formGroup systemFields.resource.fields.value value=source.system.resource.value localize=true}} - {{formGroup systemFields.resource.fields.max value=source.system.resource.max localize=true}} - {{formGroup systemFields.resource.fields.icon value=source.system.resource.icon localize=true placeholder="fa-solid fa-hashtag"}} - {{formGroup systemFields.resource.fields.recovery value=source.system.resource.recovery localize=true}} -
    + {{#if source.system.resource}} +
    + {{formGroup systemFields.resource.fields.value value=source.system.resource.value localize=true}} + {{formGroup systemFields.resource.fields.max value=source.system.resource.max localize=true}} + {{formGroup systemFields.resource.fields.icon value=source.system.resource.icon localize=true placeholder="fa-solid fa-hashtag"}} + {{formGroup systemFields.resource.fields.recovery value=source.system.resource.recovery localize=true}} +
    + {{/if}}
    \ No newline at end of file