From ef4c52c6feb3b918ec96760f633946ba90d3f2a0 Mon Sep 17 00:00:00 2001 From: Carlos Fernandez Date: Tue, 10 Mar 2026 20:17:00 -0400 Subject: [PATCH] Refactor resource settings to not be a method --- daggerheart.mjs | 5 ++ .../applications/sheets/actors/character.mjs | 8 +-- module/config/actorConfig.mjs | 2 - module/config/resourceConfig.mjs | 47 ++++++---------- module/data/actor/creature.mjs | 4 +- module/data/settings/Homebrew.mjs | 53 +++++++++++++++++++ module/systemRegistration/settings.mjs | 29 +--------- 7 files changed, 82 insertions(+), 66 deletions(-) diff --git a/daggerheart.mjs b/daggerheart.mjs index 05b57ac9..5960c6b1 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -233,6 +233,11 @@ Hooks.once('init', () => { return handlebarsRegistration(); }); +Hooks.on('i18nInit', () => { + // Setup homebrew resources + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).refreshConfig(); +}); + Hooks.on('setup', () => { CONFIG.statusEffects = [ ...CONFIG.statusEffects.filter(x => !['dead', 'unconscious'].includes(x.id)), diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index 537a8713..14dd1ae7 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -245,8 +245,8 @@ export default class CharacterSheet extends DHBaseActorSheet { } async _prepareHeaderContext(context, _options) { - context.hasExtraResources = Object.keys(CONFIG.DH.RESOURCE.allCharacterResources()).some( - key => !CONFIG.DH.RESOURCE.characterBaseResources[key] + context.hasExtraResources = Object.keys(CONFIG.DH.RESOURCE.character.all).some( + key => !CONFIG.DH.RESOURCE.character.base[key] ); } @@ -960,8 +960,8 @@ export default class CharacterSheet extends DHBaseActorSheet { return; } - const extraResources = Object.values(CONFIG.DH.RESOURCE.allCharacterResources()).reduce((acc, resource) => { - if (CONFIG.DH.RESOURCE.characterBaseResources[resource.id]) return acc; + const extraResources = Object.values(CONFIG.DH.RESOURCE.character.all).reduce((acc, resource) => { + if (CONFIG.DH.RESOURCE.character.base[resource.id]) return acc; const resourceData = this.document.system.resources[resource.id]; acc[resource.id] = { diff --git a/module/config/actorConfig.mjs b/module/config/actorConfig.mjs index 43795a0b..aa7c3cf7 100644 --- a/module/config/actorConfig.mjs +++ b/module/config/actorConfig.mjs @@ -1,5 +1,3 @@ -import { allAdversaryResources, allCharacterResources, allCompanionResources } from './resourceConfig.mjs'; - export const abilities = { agility: { id: 'agility', diff --git a/module/config/resourceConfig.mjs b/module/config/resourceConfig.mjs index 1f594b39..1c24213a 100644 --- a/module/config/resourceConfig.mjs +++ b/module/config/resourceConfig.mjs @@ -11,7 +11,7 @@ * } */ -export const characterBaseResources = { +const characterBaseResources = Object.freeze({ hitPoints: { id: 'hitPoints', initial: 0, @@ -34,25 +34,9 @@ export const characterBaseResources = { reverse: false, label: 'DAGGERHEART.GENERAL.hope' } -}; +}); -export const characterResources = { - ...characterBaseResources -}; - -export const allCharacterResources = () => { - const resources = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).resources.character - .resources; - return { - ...Object.keys(resources).reduce((acc, key) => { - acc[key] = { ...resources[key].toObject(), id: key }; - return acc; - }, {}), - ...characterResources - }; -}; - -export const adversaryBaseResources = { +const adversaryBaseResources = Object.freeze({ hitPoints: { id: 'hitPoints', initial: 0, @@ -68,15 +52,9 @@ export const adversaryBaseResources = { reverse: true, label: 'DAGGERHEART.GENERAL.stress' } -}; +}); -export const adversaryResources = { - ...adversaryBaseResources -}; - -export const allAdversaryResources = () => adversaryResources; - -export const companionBaseResources = { +const companionBaseResources = Object.freeze({ stress: { id: 'stress', initial: 0, @@ -91,10 +69,19 @@ export const companionBaseResources = { reverse: false, label: 'DAGGERHEART.GENERAL.hope' } +}); + +export const character = { + base: characterBaseResources, + all: { ...characterBaseResources }, }; -export const companionResources = { - ...companionBaseResources +export const adversary = { + base: adversaryBaseResources, + all: { ...adversaryBaseResources }, }; -export const allCompanionResources = () => companionResources; +export const companion = { + base: companionBaseResources, + all: { ...companionBaseResources }, +}; diff --git a/module/data/actor/creature.mjs b/module/data/actor/creature.mjs index e12c645d..438c88be 100644 --- a/module/data/actor/creature.mjs +++ b/module/data/actor/creature.mjs @@ -9,7 +9,7 @@ export default class DhCreature extends BaseDataActor { return { ...super.defineSchema(), resources: new fields.SchemaField({ - ...Object.values(CONFIG.DH.RESOURCE[`all${this.metadata.type.capitalize()}Resources`]()).reduce( + ...Object.values(CONFIG.DH.RESOURCE[this.metadata.type].all).reduce( (acc, resource) => { if (resource.max !== undefined) { acc[resource.id] = resourceField( @@ -58,7 +58,7 @@ export default class DhCreature extends BaseDataActor { prepareDerivedData() { super.prepareDerivedData(); - const resources = CONFIG.DH.RESOURCE[`all${this.parent.type.capitalize()}Resources`](); + const resources = CONFIG.DH.RESOURCE[this.metadata.type].all; if (resources) { for (const [key, value] of Object.entries(this.resources)) { value.label = resources[key]?.label; diff --git a/module/data/settings/Homebrew.mjs b/module/data/settings/Homebrew.mjs index c525cabd..13694932 100644 --- a/module/data/settings/Homebrew.mjs +++ b/module/data/settings/Homebrew.mjs @@ -186,6 +186,12 @@ export default class DhHomebrew extends foundry.abstract.DataModel { }; } + /** + * Backed up configured resources stored to prevent overwriting module settings. + * As of V13, setting objects are not preserved between reprepares. + */ + static originalResources = null; + /** @inheritDoc */ _initializeSource(source, options = {}) { source = super._initializeSource(source, options); @@ -195,6 +201,53 @@ export default class DhHomebrew extends foundry.abstract.DataModel { } return source; } + + /** Invoked by the setting when data changes */ + handleChange() { + if (this.maxFear) { + if (ui.resources) ui.resources.render({ force: true }); + } + + this.refreshConfig(); + this.#resetActors(); + } + + /** Update config values based on homebrew data */ + refreshConfig() { + DhHomebrew.originalResources ??= foundry.utils.duplicate(CONFIG.DH.RESOURCE); + for (const [actorType, actorData] of Object.entries(this.resources)) { + for (const [resourceKey, resourceData] of Object.entries(actorData.resources)) { + if (resourceKey in DhHomebrew.originalResources[actorType].all) { + continue; + } + CONFIG.DH.RESOURCE[actorType].all[resourceKey] = resourceData.toObject(); + CONFIG.DH.RESOURCE[actorType].all[resourceKey].id = resourceKey; + } + } + } + + /** + * Triggers a reset and non-forced re-render on all given actors (if given) + * or all world actors and actors in all scenes to show immediate results for a changed setting. + */ + #resetActors() { + const actors = new Set( + [ + game.actors.contents, + game.scenes.contents.flatMap(s => s.tokens.contents).flatMap(t => t.actor ?? []) + ].flat() + ); + for (const actor of actors) { + for (const app of Object.values(actor.apps)) { + for (const element of app.element?.querySelectorAll('prose-mirror.active')) { + element.open = false; // This triggers a save + } + } + + actor.reset(); + actor.render(); + } + } } export class Resource extends foundry.abstract.DataModel { diff --git a/module/systemRegistration/settings.mjs b/module/systemRegistration/settings.mjs index c4acf7ed..7b74b7db 100644 --- a/module/systemRegistration/settings.mjs +++ b/module/systemRegistration/settings.mjs @@ -43,12 +43,7 @@ const registerMenuSettings = () => { config: false, type: DhHomebrew, onChange: value => { - if (value.maxFear) { - if (ui.resources) ui.resources.render({ force: true }); - } - - // Some homebrew settings may change sheets in various ways, so trigger a re-render - resetActors(); + value.handleChange(); } }); @@ -149,25 +144,3 @@ const registerNonConfigSettings = () => { type: CompendiumBrowserSettings }); }; - -/** - * Triggers a reset and non-forced re-render on all given actors (if given) - * or all world actors and actors in all scenes to show immediate results for a changed setting. - */ -function resetActors(actors) { - actors ??= [ - game.actors.contents, - game.scenes.contents.flatMap(s => s.tokens.contents).flatMap(t => t.actor ?? []) - ].flat(); - actors = new Set(actors); - for (const actor of actors) { - for (const app of Object.values(actor.apps)) { - for (const element of app.element?.querySelectorAll('prose-mirror.active')) { - element.open = false; // This triggers a save - } - } - - actor.reset(); - actor.render(); - } -}