Merge branch 'main' into fix/1601-Template-Enrichment

This commit is contained in:
WBHarry 2026-02-01 00:49:38 +01:00
commit 6baac9f605
8 changed files with 58 additions and 44 deletions

View file

@ -165,7 +165,8 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli
name: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.newDowntimeMove'), name: game.i18n.localize('DAGGERHEART.SETTINGS.Homebrew.newDowntimeMove'),
img: 'icons/magic/life/cross-worn-green.webp', img: 'icons/magic/life/cross-worn-green.webp',
description: '', description: '',
actions: [] actions: [],
effects: []
} }
}); });
} else if (['armorFeatures', 'weaponFeatures'].includes(type)) { } else if (['armorFeatures', 'weaponFeatures'].includes(type)) {

View file

@ -252,7 +252,8 @@ export const defaultRestOptions = {
] ]
} }
} }
} },
effects: []
}, },
clearStress: { clearStress: {
id: 'clearStress', id: 'clearStress',
@ -285,7 +286,8 @@ export const defaultRestOptions = {
] ]
} }
} }
} },
effects: []
}, },
repairArmor: { repairArmor: {
id: 'repairArmor', id: 'repairArmor',
@ -318,7 +320,8 @@ export const defaultRestOptions = {
] ]
} }
} }
} },
effects: []
}, },
prepare: { prepare: {
id: 'prepare', id: 'prepare',
@ -326,7 +329,8 @@ export const defaultRestOptions = {
icon: 'fa-solid fa-dumbbell', icon: 'fa-solid fa-dumbbell',
img: 'icons/skills/trades/academics-merchant-scribe.webp', img: 'icons/skills/trades/academics-merchant-scribe.webp',
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.prepare.description'), description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.prepare.description'),
actions: {} actions: {},
effects: []
} }
}), }),
longRest: () => ({ longRest: () => ({
@ -361,7 +365,8 @@ export const defaultRestOptions = {
] ]
} }
} }
} },
effects: []
}, },
clearStress: { clearStress: {
id: 'clearStress', id: 'clearStress',
@ -394,7 +399,8 @@ export const defaultRestOptions = {
] ]
} }
} }
} },
effects: []
}, },
repairArmor: { repairArmor: {
id: 'repairArmor', id: 'repairArmor',
@ -427,7 +433,8 @@ export const defaultRestOptions = {
] ]
} }
} }
} },
effects: []
}, },
prepare: { prepare: {
id: 'prepare', id: 'prepare',
@ -435,7 +442,8 @@ export const defaultRestOptions = {
icon: 'fa-solid fa-dumbbell', icon: 'fa-solid fa-dumbbell',
img: 'icons/skills/trades/academics-merchant-scribe.webp', img: 'icons/skills/trades/academics-merchant-scribe.webp',
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.prepare.description'), description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.prepare.description'),
actions: {} actions: {},
effects: []
}, },
workOnAProject: { workOnAProject: {
id: 'workOnAProject', id: 'workOnAProject',
@ -443,7 +451,8 @@ export const defaultRestOptions = {
icon: 'fa-solid fa-diagram-project', icon: 'fa-solid fa-diagram-project',
img: 'icons/skills/social/thumbsup-approval-like.webp', img: 'icons/skills/social/thumbsup-approval-like.webp',
description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.workOnAProject.description'), description: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.workOnAProject.description'),
actions: {} actions: {},
effects: []
} }
}) })
}; };

View file

@ -114,9 +114,24 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
* Return Item the action is attached too. * Return Item the action is attached too.
*/ */
get item() { get item() {
if (!this.parent.parent && this.systemPath)
return foundry.utils.getProperty(this.parent, this.systemPath).get(this.id);
return this.parent.parent; 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. * Return the first Actor parent found.
*/ */
@ -125,7 +140,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel
? this.item ? this.item
: this.item?.parent instanceof DhpActor : this.item?.parent instanceof DhpActor
? this.item.parent ? this.item.parent
: this.item?.actor; : null;
} }
static getRollType(parent) { static getRollType(parent) {

View file

@ -73,7 +73,7 @@ export default class EffectsField extends fields.ArrayField {
}); });
effects.forEach(async e => { 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; if (!token.actor || !effect) return;
await EffectsField.applyEffect(effect, token.actor); await EffectsField.applyEffect(effect, token.actor);
}); });
@ -96,7 +96,7 @@ export default class EffectsField extends fields.ArrayField {
content: await foundry.applications.handlebars.renderTemplate( content: await foundry.applications.handlebars.renderTemplate(
'systems/daggerheart/templates/ui/chat/effectSummary.hbs', '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 targets: messageTargets
} }
) )
@ -123,7 +123,7 @@ export default class EffectsField extends fields.ArrayField {
// Otherwise, create a new effect on the target // Otherwise, create a new effect on the target
const effectData = foundry.utils.mergeObject({ const effectData = foundry.utils.mergeObject({
...effect.toObject(), ...(effect.toObject?.() ?? effect),
disabled: false, disabled: false,
transfer: false, transfer: false,
origin: effect.uuid origin: effect.uuid

View file

@ -152,6 +152,7 @@ export function ActionMixin(Base) {
} }
get uuid() { get uuid() {
if (!(this.item instanceof game.system.api.documents.DHItem)) return null;
return `${this.item.uuid}.${this.documentName}.${this.id}`; return `${this.item.uuid}.${this.documentName}.${this.id}`;
} }

View file

@ -12,6 +12,20 @@ const currencyField = (initial, label, icon) =>
icon: new foundry.data.fields.StringField({ required: true, nullable: false, blank: true, initial: 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 { export default class DhHomebrew extends foundry.abstract.DataModel {
static defineSchema() { static defineSchema() {
const fields = foundry.data.fields; const fields = foundry.data.fields;
@ -105,37 +119,11 @@ export default class DhHomebrew extends foundry.abstract.DataModel {
restMoves: new fields.SchemaField({ restMoves: new fields.SchemaField({
longRest: new fields.SchemaField({ longRest: new fields.SchemaField({
nrChoices: new fields.NumberField({ required: true, integer: true, min: 1, initial: 2 }), nrChoices: new fields.NumberField({ required: true, integer: true, min: 1, initial: 2 }),
moves: new fields.TypedObjectField( moves: new fields.TypedObjectField(restMoveField(), { initial: defaultRestOptions.longRest() })
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() }
)
}), }),
shortRest: new fields.SchemaField({ shortRest: new fields.SchemaField({
nrChoices: new fields.NumberField({ required: true, integer: true, min: 1, initial: 2 }), nrChoices: new fields.NumberField({ required: true, integer: true, min: 1, initial: 2 }),
moves: new fields.TypedObjectField( moves: new fields.TypedObjectField(restMoveField(), { initial: defaultRestOptions.shortRest() })
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() }
)
}) })
}), }),
domains: new fields.TypedObjectField( domains: new fields.TypedObjectField(

View file

@ -269,7 +269,7 @@ export default class DHToken extends CONFIG.Token.documentClass {
// Hexagon symmetry // Hexagon symmetry
if (columns) { if (columns) {
const rowData = BaseToken.#getHexagonalShape(height, width, shape, false); const rowData = DHToken.#getHexagonalShape(height, width, shape, false);
if (!rowData) return null; if (!rowData) return null;
// Transpose the offsets/points of the shape in row orientation // Transpose the offsets/points of the shape in row orientation

View file

@ -2,7 +2,7 @@
"id": "daggerheart", "id": "daggerheart",
"title": "Daggerheart", "title": "Daggerheart",
"description": "An unofficial implementation of the Daggerheart system", "description": "An unofficial implementation of the Daggerheart system",
"version": "1.6.1", "version": "1.6.2",
"compatibility": { "compatibility": {
"minimum": "13.346", "minimum": "13.346",
"verified": "13.351", "verified": "13.351",