Refactor resource settings to not be a method (#1723)

This commit is contained in:
Carlos Fernandez 2026-03-10 20:37:11 -04:00 committed by GitHub
parent f72fb3cf31
commit f298b2160a
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
7 changed files with 82 additions and 66 deletions

View file

@ -233,6 +233,11 @@ Hooks.once('init', () => {
return handlebarsRegistration(); return handlebarsRegistration();
}); });
Hooks.on('i18nInit', () => {
// Setup homebrew resources
game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).refreshConfig();
});
Hooks.on('setup', () => { Hooks.on('setup', () => {
CONFIG.statusEffects = [ CONFIG.statusEffects = [
...CONFIG.statusEffects.filter(x => !['dead', 'unconscious'].includes(x.id)), ...CONFIG.statusEffects.filter(x => !['dead', 'unconscious'].includes(x.id)),

View file

@ -245,8 +245,8 @@ export default class CharacterSheet extends DHBaseActorSheet {
} }
async _prepareHeaderContext(context, _options) { async _prepareHeaderContext(context, _options) {
context.hasExtraResources = Object.keys(CONFIG.DH.RESOURCE.allCharacterResources()).some( context.hasExtraResources = Object.keys(CONFIG.DH.RESOURCE.character.all).some(
key => !CONFIG.DH.RESOURCE.characterBaseResources[key] key => !CONFIG.DH.RESOURCE.character.base[key]
); );
} }
@ -960,8 +960,8 @@ export default class CharacterSheet extends DHBaseActorSheet {
return; return;
} }
const extraResources = Object.values(CONFIG.DH.RESOURCE.allCharacterResources()).reduce((acc, resource) => { const extraResources = Object.values(CONFIG.DH.RESOURCE.character.all).reduce((acc, resource) => {
if (CONFIG.DH.RESOURCE.characterBaseResources[resource.id]) return acc; if (CONFIG.DH.RESOURCE.character.base[resource.id]) return acc;
const resourceData = this.document.system.resources[resource.id]; const resourceData = this.document.system.resources[resource.id];
acc[resource.id] = { acc[resource.id] = {

View file

@ -1,5 +1,3 @@
import { allAdversaryResources, allCharacterResources, allCompanionResources } from './resourceConfig.mjs';
export const abilities = { export const abilities = {
agility: { agility: {
id: 'agility', id: 'agility',

View file

@ -11,7 +11,7 @@
* } * }
*/ */
export const characterBaseResources = { const characterBaseResources = Object.freeze({
hitPoints: { hitPoints: {
id: 'hitPoints', id: 'hitPoints',
initial: 0, initial: 0,
@ -34,25 +34,9 @@ export const characterBaseResources = {
reverse: false, reverse: false,
label: 'DAGGERHEART.GENERAL.hope' label: 'DAGGERHEART.GENERAL.hope'
} }
}; });
export const characterResources = { const adversaryBaseResources = Object.freeze({
...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 = {
hitPoints: { hitPoints: {
id: 'hitPoints', id: 'hitPoints',
initial: 0, initial: 0,
@ -68,15 +52,9 @@ export const adversaryBaseResources = {
reverse: true, reverse: true,
label: 'DAGGERHEART.GENERAL.stress' label: 'DAGGERHEART.GENERAL.stress'
} }
}; });
export const adversaryResources = { const companionBaseResources = Object.freeze({
...adversaryBaseResources
};
export const allAdversaryResources = () => adversaryResources;
export const companionBaseResources = {
stress: { stress: {
id: 'stress', id: 'stress',
initial: 0, initial: 0,
@ -91,10 +69,19 @@ export const companionBaseResources = {
reverse: false, reverse: false,
label: 'DAGGERHEART.GENERAL.hope' label: 'DAGGERHEART.GENERAL.hope'
} }
});
export const character = {
base: characterBaseResources,
all: { ...characterBaseResources },
}; };
export const companionResources = { export const adversary = {
...companionBaseResources base: adversaryBaseResources,
all: { ...adversaryBaseResources },
}; };
export const allCompanionResources = () => companionResources; export const companion = {
base: companionBaseResources,
all: { ...companionBaseResources },
};

View file

@ -9,7 +9,7 @@ export default class DhCreature extends BaseDataActor {
return { return {
...super.defineSchema(), ...super.defineSchema(),
resources: new fields.SchemaField({ 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) => { (acc, resource) => {
if (resource.max !== undefined) { if (resource.max !== undefined) {
acc[resource.id] = resourceField( acc[resource.id] = resourceField(
@ -58,7 +58,7 @@ export default class DhCreature extends BaseDataActor {
prepareDerivedData() { prepareDerivedData() {
super.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) { if (resources) {
for (const [key, value] of Object.entries(this.resources)) { for (const [key, value] of Object.entries(this.resources)) {
value.label = resources[key]?.label; value.label = resources[key]?.label;

View file

@ -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 */ /** @inheritDoc */
_initializeSource(source, options = {}) { _initializeSource(source, options = {}) {
source = super._initializeSource(source, options); source = super._initializeSource(source, options);
@ -195,6 +201,53 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
} }
return source; 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 { export class Resource extends foundry.abstract.DataModel {

View file

@ -43,12 +43,7 @@ const registerMenuSettings = () => {
config: false, config: false,
type: DhHomebrew, type: DhHomebrew,
onChange: value => { onChange: value => {
if (value.maxFear) { value.handleChange();
if (ui.resources) ui.resources.render({ force: true });
}
// Some homebrew settings may change sheets in various ways, so trigger a re-render
resetActors();
} }
}); });
@ -149,25 +144,3 @@ const registerNonConfigSettings = () => {
type: CompendiumBrowserSettings 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();
}
}