Refactor ArmorChange schema and fix some bugs

This commit is contained in:
Carlos Fernandez 2026-03-21 02:42:43 -04:00
parent 6193153596
commit 251baba5b3
60 changed files with 128 additions and 317 deletions

View file

@ -190,23 +190,14 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
}));
break;
case 'changes':
const fields = this.document.system.schema.fields.changes.element.fields;
const singleTypes = ['armor'];
const { base, ...typedChanges } = context.source.changes.reduce((acc, change, index) => {
const type = CONFIG.DH.GENERAL.baseActiveEffectModes[change.type] ? 'base' : change.type;
if (singleTypes.includes(type)) {
acc[type] = { ...change, index };
} else {
if (!acc[type]) acc[type] = [];
acc[type].push({ ...change, index });
const typedChanges = context.source.changes.reduce((acc, change, index) => {
if (singleTypes.includes(change.type)) {
acc[change.type] = { ...change, index };
}
return acc;
}, {});
partContext.changes = await Promise.all(
foundry.utils.deepClone(base ?? []).map(c => this._prepareChangeContext(c, fields))
);
partContext.changes = partContext.changes.filter(c => !!c);
partContext.typedChanges = typedChanges;
break;
}
@ -238,29 +229,38 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac
return this.submit({ updateData: { system: { changes } } });
}
_prepareChangeContext(change, fields) {
/** @inheritdoc */
_renderChange(context) {
const { change, index, defaultPriority } = context;
if (!(change.type in CONFIG.DH.GENERAL.baseActiveEffectModes)) return null;
const changeTypesSchema = this.document.system.schema.fields.changes.element.types;
const fields = context.fields ?? (changeTypesSchema[change.type] ?? changeTypesSchema.add).fields;
if (typeof change.value !== 'string') change.value = JSON.stringify(change.value);
const defaultPriority = game.system.api.documents.DhActiveEffect.CHANGE_TYPES[change.type]?.defaultPriority;
Object.assign(
change,
['key', 'type', 'value', 'priority'].reduce((paths, fieldName) => {
paths[`${fieldName}Path`] = `system.changes.${change.index}.${fieldName}`;
paths[`${fieldName}Path`] = `system.changes.${index}.${fieldName}`;
return paths;
}, {})
);
return (
game.system.api.documents.DhActiveEffect.CHANGE_TYPES[change.type].render?.(
change,
change.index,
index,
defaultPriority
) ??
foundry.applications.handlebars.renderTemplate(
'systems/daggerheart/templates/sheets/activeEffect/change.hbs',
{
change,
index: change.index,
index,
defaultPriority,
fields
fields,
types: Object.keys(CONFIG.DH.GENERAL.baseActiveEffectModes).reduce((r, key) => {
r[key] = CONFIG.DH.GENERAL.baseActiveEffectModes[key].label;
return r;
}, {})
}
)
);

View file

@ -18,23 +18,34 @@ export default class BaseEffect extends foundry.data.ActiveEffectTypeDataModel {
static defineSchema() {
const fields = foundry.data.fields;
const baseChanges = Object.keys(CONFIG.DH.GENERAL.baseActiveEffectModes).reduce((r, type) => {
r[type] = new fields.SchemaField({
key: new fields.StringField({ required: true }),
type: new fields.StringField({
required: true,
choices: [type],
initial: type,
validate: BaseEffect.#validateType
}),
value: new fields.AnyField({
required: true,
nullable: true,
serializable: true,
initial: ''
}),
phase: new fields.StringField({ required: true, blank: false, initial: 'initial' }),
priority: new fields.NumberField()
});
return r;
}, {});
return {
...super.defineSchema(),
changes: new fields.ArrayField(
new fields.SchemaField({
key: new fields.StringField({ required: true }),
type: new fields.StringField({
required: true,
blank: false,
choices: CONFIG.DH.GENERAL.activeEffectModes,
initial: CONFIG.DH.GENERAL.activeEffectModes.add.id,
validate: BaseEffect.#validateType
}),
value: new fields.AnyField({ required: true, nullable: true, serializable: true, initial: '' }),
phase: new fields.StringField({ required: true, blank: false, initial: 'initial' }),
priority: new fields.NumberField(),
typeData: new fields.TypedSchemaField(changeTypes, { nullable: true, initial: null })
})
new fields.TypedSchemaField(
{ ...changeTypes, ...baseChanges },
{ initial: baseChanges.add.getInitialValue() }
)
),
duration: new fields.SchemaField({
type: new fields.StringField({
@ -97,7 +108,7 @@ export default class BaseEffect extends foundry.data.ActiveEffectTypeDataModel {
const armorChange = this.armorChange;
if (!armorChange) return null;
return armorChange.typeData.getArmorData(armorChange);
return armorChange.getArmorData(armorChange);
}
static getDefaultObject() {

View file

@ -2,42 +2,35 @@ import { itemAbleRollParse } from '../../../helpers/utils.mjs';
const fields = foundry.data.fields;
export default class Armor extends foundry.abstract.DataModel {
export default class ArmorChange extends foundry.abstract.DataModel {
static defineSchema() {
return {
type: new fields.StringField({ required: true, initial: 'armor', blank: false }),
max: new fields.StringField({
required: true,
nullable: false,
initial: '1',
label: 'DAGGERHEART.GENERAL.max'
priority: new fields.NumberField(),
phase: new fields.StringField({ required: true, blank: false, initial: 'initial' }),
value: new fields.SchemaField({
max: new fields.StringField({
required: true,
nullable: false,
initial: '1',
label: 'DAGGERHEART.GENERAL.max'
}),
interaction: new fields.StringField({
required: true,
choices: CONFIG.DH.GENERAL.activeEffectArmorInteraction,
initial: CONFIG.DH.GENERAL.activeEffectArmorInteraction.none.id,
label: 'DAGGERHEART.EFFECTS.ChangeTypes.armor.FIELDS.interaction.label',
hint: 'DAGGERHEART.EFFECTS.ChangeTypes.armor.FIELDS.interaction.hint'
})
}),
armorInteraction: new fields.StringField({
required: true,
choices: CONFIG.DH.GENERAL.activeEffectArmorInteraction,
initial: CONFIG.DH.GENERAL.activeEffectArmorInteraction.none.id,
label: 'DAGGERHEART.EFFECTS.ChangeTypes.armor.FIELDS.armorInteraction.label',
hint: 'DAGGERHEART.EFFECTS.ChangeTypes.armor.FIELDS.armorInteraction.hint'
})
};
}
static changeEffect = {
label: 'Armor',
defaultPriortiy: 20,
defaultPriority: 20,
handler: (actor, change, _options, _field, replacementData) => {
const parsedMax = itemAbleRollParse(change.typeData.max, actor, change.effect.parent);
game.system.api.documents.DhActiveEffect.applyChange(
actor,
{
...change,
key: 'system.armorScore.value',
type: CONFIG.DH.GENERAL.activeEffectModes.add.id,
value: change.value
},
replacementData
);
const parsedMax = itemAbleRollParse(change.value.max, actor, change.effect.parent);
game.system.api.documents.DhActiveEffect.applyChange(
actor,
{
@ -54,7 +47,7 @@ export default class Armor extends foundry.abstract.DataModel {
};
get isSuppressed() {
switch (this.armorInteraction) {
switch (this.value.interaction) {
case CONFIG.DH.GENERAL.activeEffectArmorInteraction.active.id:
return !this.parent.parent?.actor.system.armor;
case CONFIG.DH.GENERAL.activeEffectArmorInteraction.inactive.id:
@ -68,9 +61,7 @@ export default class Armor extends foundry.abstract.DataModel {
return {
key: 'Armor',
type: CONFIG.DH.GENERAL.activeEffectModes.armor.id,
value: 0,
typeData: {
type: 'armor',
value: {
max: 0,
locked
},
@ -84,7 +75,7 @@ export default class Armor extends foundry.abstract.DataModel {
name: game.i18n.localize('DAGGERHEART.EFFECTS.ChangeTypes.armor.newArmorEffect'),
img: 'icons/equipment/chest/breastplate-helmet-metal.webp',
system: {
changes: [Armor.getInitialValue(true)]
changes: [ArmorChange.getInitialValue(true)]
}
};
}

View file

@ -1,5 +1,5 @@
import { itemAbleRollParse } from '../helpers/utils.mjs';
import { RefreshType, socketEvent } from '../systemRegistration/socket.mjs';
import { RefreshType } from '../systemRegistration/socket.mjs';
export default class DhActiveEffect extends foundry.documents.ActiveEffect {
/* -------------------------------------------- */
@ -155,11 +155,6 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
/* Methods */
/* -------------------------------------------- */
/**@inheritdoc */
static applyChange(actor, change, options) {
super.applyChange(actor, change, options);
}
/**@inheritdoc*/
static applyChangeField(model, change, field) {
change.value = Number.isNumeric(change.value)
@ -168,7 +163,7 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect {
super.applyChangeField(model, change, field);
}
_applyChangeUnguided(actor, change, changes, options) {
static _applyChangeUnguided(actor, change, changes, options) {
change.value = DhActiveEffect.getChangeValue(actor, change, change.effect);
super._applyChangeUnguided(actor, change, changes, options);
}