diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index 6e2e665d..add3c9e1 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -165,7 +165,8 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli name: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.newDowntimeMove'), img: 'icons/magic/life/cross-worn-green.webp', description: '', - actions: [] + actions: [], + effects: [] } }); } else if (['armorFeatures', 'weaponFeatures'].includes(type)) { diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 115e6463..e843027b 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -114,9 +114,24 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel * Return Item the action is attached too. */ get item() { + if (!this.parent.parent && this.systemPath) + return foundry.utils.getProperty(this.parent, this.systemPath).get(this.id); + return this.parent.parent; } + get applyEffects() { + if (this.item.systemPath) { + const itemEffectIds = this.item.effects.map(x => x._id); + const movePathSplit = this.item.systemPath.split('.'); + movePathSplit.pop(); + const move = foundry.utils.getProperty(this.parent, movePathSplit.join('.')); + return new Collection(itemEffectIds.map(id => [id, move.effects.find(x => x.id === id)])); + } + + return this.item.effects; + } + /** * Return the first Actor parent found. */ @@ -125,7 +140,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel ? this.item : this.item?.parent instanceof DhpActor ? this.item.parent - : this.item?.actor; + : null; } static getRollType(parent) { diff --git a/module/data/fields/action/effectsField.mjs b/module/data/fields/action/effectsField.mjs index 2233a383..6afd470b 100644 --- a/module/data/fields/action/effectsField.mjs +++ b/module/data/fields/action/effectsField.mjs @@ -73,7 +73,7 @@ export default class EffectsField extends fields.ArrayField { }); effects.forEach(async e => { - const effect = this.item.effects.get(e._id); + const effect = (this.item.applyEffects ?? this.item.effects).get(e._id); if (!token.actor || !effect) return; await EffectsField.applyEffect(effect, token.actor); }); @@ -96,7 +96,7 @@ export default class EffectsField extends fields.ArrayField { content: await foundry.applications.handlebars.renderTemplate( 'systems/daggerheart/templates/ui/chat/effectSummary.hbs', { - effects: this.effects.map(e => this.item.effects.get(e._id)), + effects: this.effects.map(e => (this.item.applyEffects ?? this.item.effects).get(e._id)), targets: messageTargets } ) @@ -123,7 +123,7 @@ export default class EffectsField extends fields.ArrayField { // Otherwise, create a new effect on the target const effectData = foundry.utils.mergeObject({ - ...effect.toObject(), + ...(effect.toObject?.() ?? effect), disabled: false, transfer: false, origin: effect.uuid diff --git a/module/data/fields/actionField.mjs b/module/data/fields/actionField.mjs index 0d71ab86..9c006beb 100644 --- a/module/data/fields/actionField.mjs +++ b/module/data/fields/actionField.mjs @@ -152,6 +152,7 @@ export function ActionMixin(Base) { } get uuid() { + if (!(this.item instanceof game.system.api.documents.DHItem)) return null; return `${this.item.uuid}.${this.documentName}.${this.id}`; } diff --git a/module/data/settings/Homebrew.mjs b/module/data/settings/Homebrew.mjs index 0138713c..b8804fa7 100644 --- a/module/data/settings/Homebrew.mjs +++ b/module/data/settings/Homebrew.mjs @@ -12,6 +12,20 @@ const currencyField = (initial, label, icon) => icon: new foundry.data.fields.StringField({ required: true, nullable: false, blank: true, initial: icon }) }); +const restMoveField = () => + new foundry.data.fields.SchemaField({ + name: new foundry.data.fields.StringField({ required: true }), + icon: new foundry.data.fields.StringField({ required: true }), + img: new foundry.data.fields.FilePathField({ + initial: 'icons/magic/life/cross-worn-green.webp', + categories: ['IMAGE'], + base64: false + }), + description: new foundry.data.fields.HTMLField(), + actions: new ActionsField(), + effects: new foundry.data.fields.ArrayField(new foundry.data.fields.ObjectField()) + }); + export default class DhHomebrew extends foundry.abstract.DataModel { static defineSchema() { const fields = foundry.data.fields; @@ -105,37 +119,11 @@ export default class DhHomebrew extends foundry.abstract.DataModel { restMoves: new fields.SchemaField({ longRest: new fields.SchemaField({ nrChoices: new fields.NumberField({ required: true, integer: true, min: 1, initial: 2 }), - moves: new fields.TypedObjectField( - new fields.SchemaField({ - name: new fields.StringField({ required: true }), - icon: new fields.StringField({ required: true }), - img: new fields.FilePathField({ - initial: 'icons/magic/life/cross-worn-green.webp', - categories: ['IMAGE'], - base64: false - }), - description: new fields.HTMLField(), - actions: new ActionsField() - }), - { initial: defaultRestOptions.longRest() } - ) + moves: new fields.TypedObjectField(restMoveField(), { initial: defaultRestOptions.longRest() }) }), shortRest: new fields.SchemaField({ nrChoices: new fields.NumberField({ required: true, integer: true, min: 1, initial: 2 }), - moves: new fields.TypedObjectField( - new fields.SchemaField({ - name: new fields.StringField({ required: true }), - icon: new fields.StringField({ required: true }), - img: new fields.FilePathField({ - initial: 'icons/magic/life/cross-worn-green.webp', - categories: ['IMAGE'], - base64: false - }), - description: new fields.HTMLField(), - actions: new ActionsField() - }), - { initial: defaultRestOptions.shortRest() } - ) + moves: new fields.TypedObjectField(restMoveField(), { initial: defaultRestOptions.shortRest() }) }) }), domains: new fields.TypedObjectField(