From b8786d981e2cbe90930456be73d5ace3918ceef6 Mon Sep 17 00:00:00 2001 From: WBHarry Date: Fri, 25 Jul 2025 18:22:56 +0200 Subject: [PATCH] Fixed downtime config again --- module/applications/dialogs/downtime.mjs | 8 +- .../settings/homebrewSettings.mjs | 3 +- .../sheets-configs/action-config.mjs | 2 + .../sheets-configs/downtimeConfig.mjs | 27 +++--- module/config/generalConfig.mjs | 84 +++++++++++++++---- module/data/fields/actionField.mjs | 16 +++- module/data/settings/Homebrew.mjs | 6 +- .../settings/downtime-config/actions.hbs | 4 +- 8 files changed, 105 insertions(+), 45 deletions(-) diff --git a/module/applications/dialogs/downtime.mjs b/module/applications/dialogs/downtime.mjs index 163af03e..d0da7d72 100644 --- a/module/applications/dialogs/downtime.mjs +++ b/module/applications/dialogs/downtime.mjs @@ -64,8 +64,8 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV context.selectedActivity = this.selectedActivity; context.moveData = this.moveData; - const shortRestMovesSelected = this.#nrSelectedMoves('shortRest'); - const longRestMovesSelected = this.#nrSelectedMoves('longRest'); + const shortRestMovesSelected = this.nrSelectedMoves('shortRest'); + const longRestMovesSelected = this.nrSelectedMoves('longRest'); context.nrChoices = { ...this.nrChoices, shortRest: { @@ -89,7 +89,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV static selectMove(_, target) { const { category, move } = target.dataset; - const nrSelected = this.#nrSelectedMoves(category); + const nrSelected = this.nrSelectedMoves(category); if (nrSelected + this.nrChoices[category].taken >= this.nrChoices[category].max) { ui.notifications.error(game.i18n.localize('DAGGERHEART.UI.Notifications.noMoreMoves')); @@ -176,7 +176,7 @@ export default class DhpDowntime extends HandlebarsApplicationMixin(ApplicationV this.render(); } - #nrSelectedMoves(category) { + nrSelectedMoves(category) { return Object.values(this.moveData[category].moves).reduce((acc, x) => acc + (x.selected ?? 0), 0); } } diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index 06992f6e..2aa2660e 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -71,9 +71,10 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli static async editItem(_, target) { const move = this.settings.restMoves[target.dataset.type].moves[target.dataset.id]; + const path = `restMoves.${target.dataset.type}.moves.${target.dataset.id}`; const editedMove = await game.system.api.applications.sheetConfigs.DowntimeConfig.configure( move, - target.dataset.id, + path, this.settings ); if (!editedMove) return; diff --git a/module/applications/sheets-configs/action-config.mjs b/module/applications/sheets-configs/action-config.mjs index 7e154671..85483287 100644 --- a/module/applications/sheets-configs/action-config.mjs +++ b/module/applications/sheets-configs/action-config.mjs @@ -172,6 +172,8 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { const submitData = this._prepareSubmitData(event, formData), data = foundry.utils.mergeObject(this.action.toObject(), submitData); this.action = await this.action.update(data); + + this.sheetUpdate?.(this.action); this.render(); } diff --git a/module/applications/sheets-configs/downtimeConfig.mjs b/module/applications/sheets-configs/downtimeConfig.mjs index 00b6a993..5477c9f6 100644 --- a/module/applications/sheets-configs/downtimeConfig.mjs +++ b/module/applications/sheets-configs/downtimeConfig.mjs @@ -4,12 +4,13 @@ import DHActionConfig from './action-config.mjs'; const { HandlebarsApplicationMixin, ApplicationV2 } = foundry.applications.api; export default class DhSettingsActionView extends HandlebarsApplicationMixin(ApplicationV2) { - constructor(move, moveId, settings, options) { + constructor(move, movePath, settings, options) { super(options); this.move = move; - this.actionsPath = `restMoves.shortRest.moves.${moveId}.actions`; + this.movePath = movePath; + this.actionsPath = `${movePath}.actions`; this.settings = settings; } @@ -111,7 +112,6 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App const cls = actionsTypes[actionType] ?? actionsTypes.attack, action = new cls( { - _id: foundry.utils.randomID(), type: actionType, name: game.i18n.localize(CONFIG.DH.ACTIONS.actionTypes[actionType].name), img: 'icons/magic/life/cross-worn-green.webp', @@ -123,26 +123,25 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App } ); - this.move.actions.push(action); - await this.settings.updateSource({ [this.actionsPath]: this.move.actions }); + await this.settings.updateSource({ [`${this.actionsPath}.${action.id}`]: action }); + this.move = foundry.utils.getProperty(this.settings, this.movePath); this.render(); } static async editItem(_, target) { - const editIndex = Number(target.dataset.id); - const action = this.move.actions.find((_, index) => index === editIndex); + const actionId = target.dataset.id; + const action = this.move.actions.get(actionId); await new DHActionConfig(action, async updatedMove => { - this.move.actions[editIndex] = updatedMove; - await this.settings.updateSource({ [this.actionsPath]: this.move.actions }); + await this.settings.updateSource({ [`${this.actionsPath}.${actionId}`]: updatedMove }); + this.move = foundry.utils.getProperty(this.settings, this.movePath); this.render(); }).render(true); } static async removeItem(_, target) { - this.move.actions = this.move.actions.filter((_, index) => index !== Number(target.dataset.id)); - await this.settings.updateSource({ [this.actionsPath]: this.move.actions }); - + await this.settings.updateSource({ [`${this.actionsPath}.-=${target.dataset.id}`]: null }); + this.move = foundry.utils.getProperty(this.settings, this.movePath); this.render(); } @@ -153,9 +152,9 @@ export default class DhSettingsActionView extends HandlebarsApplicationMixin(App if (!options.submitted) this.move = null; } - static async configure(move, moveId, settings, options = {}) { + static async configure(move, movePath, settings, options = {}) { return new Promise(resolve => { - const app = new this(move, moveId, settings, options); + const app = new this(move, movePath, settings, options); app.addEventListener('close', () => resolve(app.move), { once: true }); app.render({ force: true }); }); diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index ec190ef2..0aacda68 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -138,9 +138,8 @@ export const defaultRestOptions = { icon: 'fa-solid fa-bandage', img: 'icons/magic/life/cross-worn-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.tendToWounds.description'), - actions: [ - { - _id: foundry.utils.randomID(), + actions: { + tendToWounds: { systemPath: 'restMoves.shortRest.moves.tendToWounds.actions', type: 'healing', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.tendToWounds.name'), @@ -156,7 +155,7 @@ export const defaultRestOptions = { } } } - ] + } }, clearStress: { id: 'clearStress', @@ -164,9 +163,8 @@ export const defaultRestOptions = { icon: 'fa-regular fa-face-surprise', img: 'icons/magic/perception/eye-ringed-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.clearStress.description'), - actions: [ - { - _id: foundry.utils.randomID(), + actions: { + clearStress: { systemPath: 'restMoves.shortRest.moves.tendToWounds.actions', type: 'healing', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.clearStress.name'), @@ -182,7 +180,7 @@ export const defaultRestOptions = { } } } - ] + } }, repairArmor: { id: 'repairArmor', @@ -190,9 +188,8 @@ export const defaultRestOptions = { icon: 'fa-solid fa-hammer', img: 'icons/skills/trades/smithing-anvil-silver-red.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.description'), - actions: [ - { - _id: foundry.utils.randomID(), + actions: { + repairArmor: { systemPath: 'restMoves.shortRest.moves.tendToWounds.actions', type: 'healing', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.name'), @@ -208,7 +205,7 @@ export const defaultRestOptions = { } } } - ] + } }, prepare: { id: 'prepare', @@ -216,7 +213,7 @@ export const defaultRestOptions = { icon: 'fa-solid fa-dumbbell', img: 'icons/skills/trades/academics-merchant-scribe.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.prepare.description'), - actions: [] + actions: {} } }), longRest: () => ({ @@ -226,7 +223,24 @@ export const defaultRestOptions = { icon: 'fa-solid fa-bandage', img: 'icons/magic/life/cross-worn-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.tendToWounds.description'), - actions: [] + actions: { + tendToWounds: { + systemPath: 'restMoves.longRest.moves.tendToWounds.actions', + type: 'healing', + name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.tendToWounds.name'), + img: 'icons/magic/life/cross-worn-green.webp', + actionType: 'action', + healing: { + applyTo: healingTypes.hitPoints.id, + value: { + custom: { + enabled: true, + formula: '@system.resources.hitPoints.max' + } + } + } + } + } }, clearStress: { id: 'clearStress', @@ -234,7 +248,24 @@ export const defaultRestOptions = { icon: 'fa-regular fa-face-surprise', img: 'icons/magic/perception/eye-ringed-green.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.clearStress.description'), - actions: [] + actions: { + clearStress: { + systemPath: 'restMoves.longRest.moves.tendToWounds.actions', + type: 'healing', + name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.clearStress.name'), + img: 'icons/magic/perception/eye-ringed-green.webp', + actionType: 'action', + healing: { + applyTo: healingTypes.stress.id, + value: { + custom: { + enabled: true, + formula: '@system.resources.stress.max' + } + } + } + } + } }, repairArmor: { id: 'repairArmor', @@ -242,7 +273,24 @@ export const defaultRestOptions = { icon: 'fa-solid fa-hammer', img: 'icons/skills/trades/smithing-anvil-silver-red.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.repairArmor.description'), - actions: [] + actions: { + repairArmor: { + systemPath: 'restMoves.longRest.moves.tendToWounds.actions', + type: 'healing', + name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.repairArmor.name'), + img: 'icons/skills/trades/smithing-anvil-silver-red.webp', + actionType: 'action', + healing: { + applyTo: healingTypes.armorStack.id, + value: { + custom: { + enabled: true, + formula: '@system.armorScore' + } + } + } + } + } }, prepare: { id: 'prepare', @@ -250,7 +298,7 @@ export const defaultRestOptions = { icon: 'fa-solid fa-dumbbell', img: 'icons/skills/trades/academics-merchant-scribe.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.prepare.description'), - actions: [] + actions: {} }, workOnAProject: { id: 'workOnAProject', @@ -258,7 +306,7 @@ export const defaultRestOptions = { icon: 'fa-solid fa-diagram-project', img: 'icons/skills/social/thumbsup-approval-like.webp', description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.workOnAProject.description'), - actions: [] + actions: {} } }) }; diff --git a/module/data/fields/actionField.mjs b/module/data/fields/actionField.mjs index 1a297ce5..db6858d0 100644 --- a/module/data/fields/actionField.mjs +++ b/module/data/fields/actionField.mjs @@ -202,11 +202,21 @@ export function ActionMixin(Base) { } async update(updates, options = {}) { - const path = this.inCollection ? `system.${this.systemPath}.${this.id}` : `system.${this.systemPath}`, + const isSetting = !this.parent.parent; + const basePath = isSetting ? this.systemPath : `system.${this.systemPath}`; + + const path = this.inCollection ? `${basePath}.${this.id}` : basePath; + + let result = null; + if (isSetting) { + await this.parent.updateSource({ [path]: updates }, options); + result = this.parent; + } else { result = await this.item.update({ [path]: updates }, options); + } return this.inCollection - ? foundry.utils.getProperty(result, `system.${this.systemPath}`).get(this.id) - : foundry.utils.getProperty(result, `system.${this.systemPath}`); + ? foundry.utils.getProperty(result, basePath).get(this.id) + : foundry.utils.getProperty(result, basePath); } delete() { diff --git a/module/data/settings/Homebrew.mjs b/module/data/settings/Homebrew.mjs index 35843a90..5619898e 100644 --- a/module/data/settings/Homebrew.mjs +++ b/module/data/settings/Homebrew.mjs @@ -1,5 +1,5 @@ import { defaultRestOptions } from '../../config/generalConfig.mjs'; -import ActionField from '../fields/actionField.mjs'; +import { ActionsField } from '../fields/actionField.mjs'; export default class DhHomebrew extends foundry.abstract.DataModel { static LOCALIZATION_PREFIXES = ['DAGGERHEART.SETTINGS.Homebrew']; // Doesn't work for some reason @@ -62,7 +62,7 @@ export default class DhHomebrew extends foundry.abstract.DataModel { base64: false }), description: new fields.HTMLField(), - actions: new fields.ArrayField(new ActionField()) + actions: new ActionsField() }), { initial: defaultRestOptions.longRest() } ) @@ -79,7 +79,7 @@ export default class DhHomebrew extends foundry.abstract.DataModel { base64: false }), description: new fields.HTMLField(), - actions: new fields.ArrayField(new ActionField()) + actions: new ActionsField() }), { initial: defaultRestOptions.shortRest() } ) diff --git a/templates/settings/downtime-config/actions.hbs b/templates/settings/downtime-config/actions.hbs index 56d15ca2..d197f983 100644 --- a/templates/settings/downtime-config/actions.hbs +++ b/templates/settings/downtime-config/actions.hbs @@ -7,8 +7,8 @@ {{localize "DAGGERHEART.GENERAL.Action.plural"}}
- {{#each move.actions as |action index|}} - {{> "systems/daggerheart/templates/settings/components/settings-item-line.hbs" id=index }} + {{#each move.actions as |action|}} + {{> "systems/daggerheart/templates/settings/components/settings-item-line.hbs" id=action.id }} {{/each}}