From a9d0167ebe96ac430a1c70ef72311017b55729a9 Mon Sep 17 00:00:00 2001 From: cosmo Date: Mon, 13 Apr 2026 22:03:05 +0200 Subject: [PATCH 1/3] bump module version to 1.1.0 and update compatibility requirements --- module.json | 8 ++++---- 1 file changed, 4 insertions(+), 4 deletions(-) diff --git a/module.json b/module.json index 36c4bc2..301fa6e 100644 --- a/module.json +++ b/module.json @@ -4,11 +4,11 @@ "description": "Adds a browser to easily find and copy Active Effect data paths in Daggerheart.", "url": "https://git.geeks.gay/cosmo/dh-path-browser", "manifest": "https://git.geeks.gay/cosmo/dh-path-browser/raw/branch/main/module.json", - "download": "https://git.geeks.gay/cosmo/dh-path-browser/releases/download/1.0.0/dh-path-browser.zip", - "version": "1.0.0", + "download": "https://git.geeks.gay/cosmo/dh-path-browser/releases/download/1.1.0/dh-path-browser.zip", + "version": "1.1.0", "compatibility": { "minimum": "13", - "verified": "13" + "verified": "14" }, "authors": [ { @@ -31,7 +31,7 @@ "id": "daggerheart", "type": "system", "compatibility": { - "minimum": "1.9.4" + "minimum": "1.9.9" } } ] From 8c4be1594e599e317334b3c34ee2716ccf791d97 Mon Sep 17 00:00:00 2001 From: cosmo Date: Mon, 13 Apr 2026 22:19:50 +0200 Subject: [PATCH 2/3] add item support and dynamic translation handling to path browser choices --- scripts/app.mjs | 91 +++++++++++++++++++++++++++++++------------------ 1 file changed, 58 insertions(+), 33 deletions(-) diff --git a/scripts/app.mjs b/scripts/app.mjs index c08fba7..96515ee 100644 --- a/scripts/app.mjs +++ b/scripts/app.mjs @@ -97,61 +97,86 @@ export class DhPathBrowserApp extends HandlebarsApplicationMixin(ApplicationV2) static getChangeChoices() { const ignoredActorKeys = ['config', 'DhEnvironment', 'DhParty']; - const getAllLeaves = (root, group, parentPath = '') => { + const getTranslations = (model, path) => { + if (path === 'resources.hope.max') + return { + label: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.FIELDS.maxHope.label'), + hint: '' + }; + + // Armor overrides + if (path.endsWith('armor.max')) return { label: game.i18n.localize('DAGGERHEART.ArmorScoreMax'), hint: '' }; + if (path.endsWith('armor.current')) return { label: game.i18n.localize('DAGGERHEART.ArmorScoreCurrent'), hint: '' }; + + const field = model.schema.getField(path); + return { + label: field ? game.i18n.localize(field.label) : path, + hint: field ? game.i18n.localize(field.hint) : '' + }; + }; + + const getAllLeaves = (model, root, group, parentPath = '') => { + if (!root) return []; const leaves = []; const rootKey = `${parentPath ? `${parentPath}.` : ''}${root.name}`; - for (const field of Object.values(root.fields)) { - if (field instanceof foundry.data.fields.SchemaField) - leaves.push(...getAllLeaves(field, group, rootKey)); - else + + const fields = root.fields || root; + + for (const [name, field] of Object.entries(fields)) { + const currentPath = `${rootKey}.${name}`; + if (field instanceof foundry.data.fields.SchemaField) { + leaves.push(...getAllLeaves(model, field, group, rootKey)); + } else { + const trans = getTranslations(model, currentPath); leaves.push({ - value: `${rootKey}.${field.name}`, - label: game.i18n.localize(field.label), - hint: game.i18n.localize(field.hint), + value: currentPath, + label: trans.label || name, + hint: trans.hint || '', group }); + } } return leaves; }; - return Object.keys(game.system.api.models.actors).reduce((acc, key) => { - if (ignoredActorKeys.includes(key)) return acc; + const choices = []; + + // Process Actors + for (const [key, model] of Object.entries(game.system.api.models.actors)) { + if (ignoredActorKeys.includes(key)) continue; - const model = game.system.api.models.actors[key]; const group = game.i18n.localize(model.metadata.label); const attributes = CONFIG.Token.documentClass.getTrackedAttributes(model.metadata.type); - const getTranslations = path => { - if (path === 'resources.hope.max') - return { - label: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.FIELDS.maxHope.label'), - hint: '' - }; - - const field = model.schema.getField(path); - return { - label: field ? game.i18n.localize(field.label) : path, - hint: field ? game.i18n.localize(field.hint) : '' - }; - }; - const bars = attributes.bar.flatMap(x => { const baseJoined = x.join('.'); return [ - { value: `${baseJoined}.max`, ...getTranslations(`${baseJoined}.max`), group }, - { value: `${baseJoined}.value`, ...getTranslations(`${baseJoined}.value`), group } + { value: `${baseJoined}.max`, ...getTranslations(model, `${baseJoined}.max`), group }, + { value: `${baseJoined}.value`, ...getTranslations(model, `${baseJoined}.value`), group } ]; }); const values = attributes.value.flatMap(x => { const joined = x.join('.'); - return { value: joined, ...getTranslations(joined), group }; + return { value: joined, ...getTranslations(model, joined), group }; }); - const bonuses = getAllLeaves(model.schema.fields.bonuses, group); - const rules = getAllLeaves(model.schema.fields.rules, group); + const bonuses = getAllLeaves(model, model.schema.fields.bonuses, group); + const rules = getAllLeaves(model, model.schema.fields.rules, group); + const armor = getAllLeaves(model, model.schema.fields.armor, group); - acc.push(...bars, ...values, ...rules, ...bonuses); - return acc; - }, []); + choices.push(...bars, ...values, ...rules, ...bonuses, ...armor); + } + + // Process Items + for (const [key, model] of Object.entries(game.system.api.models.items)) { + const group = `${game.i18n.localize('DOCUMENT.Item')} (${game.i18n.localize(model.metadata.label)})`; + + const bonuses = getAllLeaves(model, model.schema.fields.bonuses, group); + const armor = getAllLeaves(model, model.schema.fields.armor, group); + + choices.push(...bonuses, ...armor); + } + + return choices; } } From 264b83bc88a67bc38bbf40c81757ce1f17b1b936 Mon Sep 17 00:00:00 2001 From: cosmo Date: Mon, 13 Apr 2026 22:23:20 +0200 Subject: [PATCH 3/3] add metadata validation for actor and item processing --- module.json | 4 ++-- scripts/app.mjs | 3 ++- 2 files changed, 4 insertions(+), 3 deletions(-) diff --git a/module.json b/module.json index 301fa6e..d4a468a 100644 --- a/module.json +++ b/module.json @@ -4,8 +4,8 @@ "description": "Adds a browser to easily find and copy Active Effect data paths in Daggerheart.", "url": "https://git.geeks.gay/cosmo/dh-path-browser", "manifest": "https://git.geeks.gay/cosmo/dh-path-browser/raw/branch/main/module.json", - "download": "https://git.geeks.gay/cosmo/dh-path-browser/releases/download/1.1.0/dh-path-browser.zip", - "version": "1.1.0", + "download": "https://git.geeks.gay/cosmo/dh-path-browser/releases/download/1.1.1/dh-path-browser.zip", + "version": "1.1.1", "compatibility": { "minimum": "13", "verified": "14" diff --git a/scripts/app.mjs b/scripts/app.mjs index 96515ee..f1453aa 100644 --- a/scripts/app.mjs +++ b/scripts/app.mjs @@ -143,7 +143,7 @@ export class DhPathBrowserApp extends HandlebarsApplicationMixin(ApplicationV2) // Process Actors for (const [key, model] of Object.entries(game.system.api.models.actors)) { - if (ignoredActorKeys.includes(key)) continue; + if (ignoredActorKeys.includes(key) || !model?.metadata) continue; const group = game.i18n.localize(model.metadata.label); const attributes = CONFIG.Token.documentClass.getTrackedAttributes(model.metadata.type); @@ -169,6 +169,7 @@ export class DhPathBrowserApp extends HandlebarsApplicationMixin(ApplicationV2) // Process Items for (const [key, model] of Object.entries(game.system.api.models.items)) { + if (!model?.metadata) continue; const group = `${game.i18n.localize('DOCUMENT.Item')} (${game.i18n.localize(model.metadata.label)})`; const bonuses = getAllLeaves(model, model.schema.fields.bonuses, group);