From 1a928e950c79f5870e0f0cd7bc5c82916ea023c2 Mon Sep 17 00:00:00 2001 From: WBHarry Date: Thu, 29 Jan 2026 18:46:39 +0100 Subject: [PATCH] Initial v14 fixes --- .../sheets-configs/activeEffectConfig.mjs | 34 ++++++++ .../sheets/api/application-mixin.mjs | 29 +------ module/applications/ui/countdowns.mjs | 11 +-- module/canvas/placeables/templateLayer.mjs | 2 +- module/config/generalConfig.mjs | 39 ++++++++- module/data/action/beastformAction.mjs | 80 ------------------- module/data/activeEffect/baseEffect.mjs | 35 +++++++- module/data/activeEffect/beastformEffect.mjs | 1 + module/data/fields/actionField.mjs | 14 +++- module/data/item/beastform.mjs | 29 +++---- module/data/item/subclass.mjs | 6 +- module/dice/damageRoll.mjs | 2 +- module/dice/dhRoll.mjs | 4 +- module/dice/dualityRoll.mjs | 4 +- module/documents/activeEffect.mjs | 20 +++-- module/helpers/utils.mjs | 7 +- system.json | 8 +- templates/sheets/activeEffect/change.hbs | 17 ++++ templates/sheets/activeEffect/changes.hbs | 35 +++----- 19 files changed, 197 insertions(+), 180 deletions(-) create mode 100644 templates/sheets/activeEffect/change.hbs diff --git a/module/applications/sheets-configs/activeEffectConfig.mjs b/module/applications/sheets-configs/activeEffectConfig.mjs index d7b1b536..aa6d9d54 100644 --- a/module/applications/sheets-configs/activeEffectConfig.mjs +++ b/module/applications/sheets-configs/activeEffectConfig.mjs @@ -33,6 +33,7 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac settings: { template: 'systems/daggerheart/templates/sheets/activeEffect/settings.hbs' }, changes: { template: 'systems/daggerheart/templates/sheets/activeEffect/changes.hbs', + templates: ['systems/daggerheart/templates/sheets/activeEffect/change.hbs'], scrollable: ['ol[data-changes]'] }, footer: { template: 'systems/daggerheart/templates/sheets/global/tabs/tab-form-footer.hbs' } @@ -121,8 +122,41 @@ export default class DhActiveEffectConfig extends foundry.applications.sheets.Ac })); } break; + case 'changes': + const fields = this.document.system.schema.fields.changes.element.fields; + partContext.changes = await Promise.all( + foundry.utils + .deepClone(context.source.changes) + .map((c, i) => this._prepareChangeContext(c, i, fields)) + ); + break; } return partContext; } + + _prepareChangeContext(change, index, 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.${index}.${fieldName}`; + return paths; + }, {}) + ); + return ( + game.system.api.documents.DhActiveEffect.CHANGE_TYPES[change.type].render?.( + change, + index, + defaultPriority + ) ?? + renderTemplate('systems/daggerheart/templates/sheets/activeEffect/change.hbs', { + change, + index, + defaultPriority, + fields + }) + ); + } } diff --git a/module/applications/sheets/api/application-mixin.mjs b/module/applications/sheets/api/application-mixin.mjs index 3c0444eb..ab6a352d 100644 --- a/module/applications/sheets/api/application-mixin.mjs +++ b/module/applications/sheets/api/application-mixin.mjs @@ -72,18 +72,6 @@ const typeSettingsMap = { */ export default function DHApplicationMixin(Base) { class DHSheetV2 extends HandlebarsApplicationMixin(Base) { - /** - * @param {DHSheetV2Configuration} [options={}] - */ - constructor(options = {}) { - super(options); - /** - * @type {foundry.applications.ux.DragDrop[]} - * @private - */ - this._dragDrop = this._createDragDropHandlers(); - } - #nonHeaderAttribution = ['environment', 'ancestry', 'community', 'domainCard']; /** @@ -177,7 +165,7 @@ export default function DHApplicationMixin(Base) { /**@inheritdoc */ _attachPartListeners(partId, htmlElement, options) { super._attachPartListeners(partId, htmlElement, options); - this._dragDrop.forEach(d => d.bind(htmlElement)); + // this._dragDrop.forEach(d => d.bind(htmlElement)); // Handle delta inputs for (const deltaInput of htmlElement.querySelectorAll('input[data-allow-delta]')) { @@ -350,21 +338,6 @@ export default function DHApplicationMixin(Base) { /* Drag and Drop */ /* -------------------------------------------- */ - /** - * Creates drag-drop handlers from the configured options. - * @returns {foundry.applications.ux.DragDrop[]} - * @private - */ - _createDragDropHandlers() { - return this.options.dragDrop.map(d => { - d.callbacks = { - dragstart: this._onDragStart.bind(this), - drop: this._onDrop.bind(this) - }; - return new foundry.applications.ux.DragDrop.implementation(d); - }); - } - /** * Handle dragStart event. * @param {DragEvent} event diff --git a/module/applications/ui/countdowns.mjs b/module/applications/ui/countdowns.mjs index 42920a4a..0f83a05f 100644 --- a/module/applications/ui/countdowns.mjs +++ b/module/applications/ui/countdowns.mjs @@ -52,10 +52,6 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application } }; - get element() { - return document.body.querySelector('.daggerheart.dh-style.countdowns'); - } - /**@inheritdoc */ async _renderFrame(options) { const frame = await super._renderFrame(options); @@ -68,6 +64,7 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application const header = frame.querySelector('.window-header'); header.querySelector('button[data-action="close"]').remove(); + header.querySelector('button[data-action="toggleControls"]').remove(); if (game.user.isGM) { const editTooltip = game.i18n.localize('DAGGERHEART.APPLICATIONS.CountdownEdit.editTitle'); @@ -278,10 +275,8 @@ export default class DhCountdowns extends HandlebarsApplicationMixin(Application return acc; }, {}) }; - await emitAsGM(GMUpdateEvent.UpdateCountdowns, - DhCountdowns.gmSetSetting.bind(settings), - settings, null, { - refreshType: RefreshType.Countdown + await emitAsGM(GMUpdateEvent.UpdateCountdowns, DhCountdowns.gmSetSetting.bind(settings), settings, null, { + refreshType: RefreshType.Countdown }); } diff --git a/module/canvas/placeables/templateLayer.mjs b/module/canvas/placeables/templateLayer.mjs index 551a06cc..55bd7eb2 100644 --- a/module/canvas/placeables/templateLayer.mjs +++ b/module/canvas/placeables/templateLayer.mjs @@ -6,7 +6,7 @@ export default class DhTemplateLayer extends foundry.canvas.layers.TemplateLayer order: 2, title: 'CONTROLS.GroupMeasure', icon: 'fa-solid fa-ruler-combined', - visible: game.user.can('TEMPLATE_CREATE'), + visible: game.user.can('REGION_CREATE'), onChange: (event, active) => { if (active) canvas.templates.activate(); }, diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index be1dfce1..677351cd 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -70,8 +70,12 @@ export const range = { } }; +/* circle|cone|rect|ray used to be CONST.MEASURED_TEMPLATE_TYPES. Hardcoded for now */ export const templateTypes = { - ...CONST.MEASURED_TEMPLATE_TYPES, + CIRCLE: 'circle', + CONE: 'cone', + RECTANGLE: 'rect', + RAY: 'ray', EMANATION: 'emanation', INFRONT: 'inFront' }; @@ -737,3 +741,36 @@ export const sceneRangeMeasurementSetting = { label: 'Custom' } }; + +export const activeEffectModes = { + custom: { + id: 'custom', + priority: 0, + label: 'EFFECT.CHANGES.TYPES.custom' + }, + multiply: { + id: 'multiply', + priority: 10, + label: 'EFFECT.CHANGES.TYPES.multiply' + }, + add: { + id: 'add', + priority: 20, + label: 'EFFECT.CHANGES.TYPES.add' + }, + downgrade: { + id: 'downgrade', + priority: 30, + label: 'EFFECT.CHANGES.TYPES.downgrade' + }, + upgrade: { + id: 'upgrade', + priority: 40, + label: 'EFFECT.CHANGES.TYPES.upgrade' + }, + override: { + id: 'override', + priority: 50, + label: 'EFFECT.CHANGES.TYPES.override' + } +}; diff --git a/module/data/action/beastformAction.mjs b/module/data/action/beastformAction.mjs index 657cfde2..8855b122 100644 --- a/module/data/action/beastformAction.mjs +++ b/module/data/action/beastformAction.mjs @@ -2,84 +2,4 @@ import DHBaseAction from './baseAction.mjs'; export default class DhBeastformAction extends DHBaseAction { static extraSchemas = [...super.extraSchemas, 'beastform']; - - /* async use(event, options) { - const beastformConfig = this.prepareBeastformConfig(); - - const abort = await this.handleActiveTransformations(); - if (abort) return; - - const calcCosts = game.system.api.fields.ActionFields.CostField.calcCosts.call(this, this.cost); - const hasCost = game.system.api.fields.ActionFields.CostField.hasCost.call(this, calcCosts); - if (!hasCost) { - ui.notifications.warn(game.i18n.localize('DAGGERHEART.UI.Notifications.insufficientResources')); - return; - } - - const { selected, evolved, hybrid } = await BeastformDialog.configure(beastformConfig, this.item); - if (!selected) return; - - const result = await super.use(event, options); - if (!result) return; - - await this.transform(selected, evolved, hybrid); - } - - prepareBeastformConfig(config) { - const settingsTiers = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.LevelTiers).tiers; - const actorLevel = this.actor.system.levelData.level.current; - const actorTier = - Object.values(settingsTiers).find( - tier => actorLevel >= tier.levels.start && actorLevel <= tier.levels.end - ) ?? 1; - - return { - tierLimit: this.beastform.tierAccess.exact ?? actorTier - }; - } - - async transform(selectedForm, evolvedData, hybridData) { - const formData = evolvedData?.form ? evolvedData.form.toObject() : selectedForm.toObject(); - const beastformEffect = formData.effects.find(x => x.type === 'beastform'); - if (!beastformEffect) { - ui.notifications.error('DAGGERHEART.UI.Notifications.beastformMissingEffect'); - return; - } - - if (evolvedData?.form) { - const evolvedForm = selectedForm.effects.find(x => x.type === 'beastform'); - if (!evolvedForm) { - ui.notifications.error('DAGGERHEART.UI.Notifications.beastformMissingEffect'); - return; - } - - beastformEffect.changes = [...beastformEffect.changes, ...evolvedForm.changes]; - formData.system.features = [...formData.system.features, ...selectedForm.system.features.map(x => x.uuid)]; - } - - if (selectedForm.system.beastformType === CONFIG.DH.ITEM.beastformTypes.hybrid.id) { - formData.system.advantageOn = Object.values(hybridData.advantages).reduce((advantages, formCategory) => { - Object.keys(formCategory).forEach(advantageKey => { - advantages[advantageKey] = formCategory[advantageKey]; - }); - return advantages; - }, {}); - formData.system.features = [ - ...formData.system.features, - ...Object.values(hybridData.features).flatMap(x => Object.keys(x)) - ]; - } - - this.actor.createEmbeddedDocuments('Item', [formData]); - } - - async handleActiveTransformations() { - const beastformEffects = this.actor.effects.filter(x => x.type === 'beastform'); - const existingEffects = beastformEffects.length > 0; - await this.actor.deleteEmbeddedDocuments( - 'ActiveEffect', - beastformEffects.map(x => x.id) - ); - return existingEffects; - } */ } diff --git a/module/data/activeEffect/baseEffect.mjs b/module/data/activeEffect/baseEffect.mjs index ea74531d..b8f2c65f 100644 --- a/module/data/activeEffect/baseEffect.mjs +++ b/module/data/activeEffect/baseEffect.mjs @@ -12,11 +12,27 @@ * "Anything that uses another data model value as its value": +1 - Effects that increase traits have to be calculated first at Base priority. (EX: Raise evasion by half your agility) */ -export default class BaseEffect extends foundry.abstract.TypeDataModel { +export default class BaseEffect extends foundry.data.ActiveEffectTypeDataModel { static defineSchema() { const fields = foundry.data.fields; 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() + }) + ), rangeDependence: new fields.SchemaField({ enabled: new fields.BooleanField({ required: true, @@ -45,6 +61,23 @@ export default class BaseEffect extends foundry.abstract.TypeDataModel { }; } + /** + * Validate that an {@link EffectChangeData#type} string is well-formed. + * @param {string} type The string to be validated + * @returns {true} + * @throws {Error} An error if the type string is malformed + */ + static #validateType(type) { + if (type.length < 3) throw new Error('must be at least three characters long'); + if (!/^custom\.-?\d+$/.test(type) && !type.split('.').every(s => /^[a-z0-9]+$/i.test(s))) { + throw new Error( + 'A change type must either be a sequence of dot-delimited, alpha-numeric substrings or of the form' + + ' "custom.{number}"' + ); + } + return true; + } + static getDefaultObject() { return { name: 'New Effect', diff --git a/module/data/activeEffect/beastformEffect.mjs b/module/data/activeEffect/beastformEffect.mjs index 65e36606..53430ba3 100644 --- a/module/data/activeEffect/beastformEffect.mjs +++ b/module/data/activeEffect/beastformEffect.mjs @@ -5,6 +5,7 @@ export default class BeastformEffect extends BaseEffect { static defineSchema() { const fields = foundry.data.fields; return { + ...super.defineSchema(), characterTokenData: new fields.SchemaField({ usesDynamicToken: new fields.BooleanField({ initial: false }), tokenImg: new fields.FilePathField({ diff --git a/module/data/fields/actionField.mjs b/module/data/fields/actionField.mjs index 0d71ab86..a6d0abbe 100644 --- a/module/data/fields/actionField.mjs +++ b/module/data/fields/actionField.mjs @@ -111,9 +111,17 @@ export class ActionField extends foundry.data.fields.ObjectField { * @param {object} sourceData Candidate source data of the root model. * @param {any} fieldData The value of this field within the source data. */ - migrateSource(sourceData, fieldData) { - const cls = this.getModel(fieldData); - if (cls) cls.migrateDataSafe(fieldData); + _migrate(sourceData, _fieldData) { + const source = sourceData ?? this.options.initial; + if (!source) return sourceData; + + const cls = this.getModel(source); + if (cls) { + cls.migrateDataSafe(source); + return source; + } + + return sourceData; } } diff --git a/module/data/item/beastform.mjs b/module/data/item/beastform.mjs index dd491169..9c8df9ea 100644 --- a/module/data/item/beastform.mjs +++ b/module/data/item/beastform.mjs @@ -101,12 +101,13 @@ export default class DHBeastform extends BaseDataItem { const effect = this.parent.effects.find(x => x.type === 'beastform'); if (!effect) return null; - const traitBonus = effect.changes.find(x => x.key === `system.traits.${this.mainTrait}.value`)?.value ?? 0; - const evasionBonus = effect.changes.find(x => x.key === 'system.evasion')?.value ?? 0; + const traitBonus = + effect.system.changes.find(x => x.key === `system.traits.${this.mainTrait}.value`)?.value ?? 0; + const evasionBonus = effect.system.changes.find(x => x.key === 'system.evasion')?.value ?? 0; - const damageDiceIndex = effect.changes.find(x => x.key === 'system.rules.attack.damage.diceIndex'); + const damageDiceIndex = effect.system.changes.find(x => x.key === 'system.rules.attack.damage.diceIndex'); const damageDice = damageDiceIndex ? Object.keys(CONFIG.DH.GENERAL.diceTypes)[damageDiceIndex.value] : null; - const damageBonus = effect.changes.find(x => x.key === 'system.rules.attack.damage.bonus')?.value ?? 0; + const damageBonus = effect.system.changes.find(x => x.key === 'system.rules.attack.damage.bonus')?.value ?? 0; return { trait: game.i18n.localize(CONFIG.DH.ACTOR.abilities[this.mainTrait].label), @@ -169,17 +170,17 @@ export default class DHBeastform extends BaseDataItem { const beastformEffect = this.parent.effects.find(x => x.type === 'beastform'); await beastformEffect.updateSource({ - changes: [ - ...beastformEffect.changes, - { - key: 'system.advantageSources', - mode: 2, - value: Object.values(this.advantageOn) - .map(x => x.value) - .join(', ') - } - ], system: { + changes: [ + ...beastformEffect.system.changes, + { + key: 'system.advantageSources', + mode: 2, + value: Object.values(this.advantageOn) + .map(x => x.value) + .join(', ') + } + ], characterTokenData: { usesDynamicToken: this.parent.parent.prototypeToken.ring.enabled, tokenImg: this.parent.parent.prototypeToken.texture.src, diff --git a/module/data/item/subclass.mjs b/module/data/item/subclass.mjs index 375588fb..33acb311 100644 --- a/module/data/item/subclass.mjs +++ b/module/data/item/subclass.mjs @@ -51,6 +51,9 @@ export default class DHSubclass extends BaseDataItem { } async _preCreate(data, options, user) { + const allowed = await super._preCreate(data, options, user); + if (allowed === false) return; + if (this.actor?.type === 'character') { const dataUuid = data.uuid ?? data._stats.compendiumSource ?? `Item.${data._id}`; if (this.actor.system.class.subclass) { @@ -85,8 +88,5 @@ export default class DHSubclass extends BaseDataItem { } } } - - const allowed = await super._preCreate(data, options, user); - if (allowed === false) return; } } diff --git a/module/dice/damageRoll.mjs b/module/dice/damageRoll.mjs index cd26eb21..e1acaf40 100644 --- a/module/dice/damageRoll.mjs +++ b/module/dice/damageRoll.mjs @@ -191,7 +191,7 @@ export default class DamageRoll extends DHRoll { if (config.data.parent.appliedEffects) { // Bardic Rally const rallyChoices = config.data?.parent?.appliedEffects.reduce((a, c) => { - const change = c.changes.find(ch => ch.key === 'system.bonuses.rally'); + const change = c.system.changes.find(ch => ch.key === 'system.bonuses.rally'); if (change) a.push({ value: c.id, label: change.value }); return a; }, []); diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index 1977c7ea..317536a0 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -249,12 +249,12 @@ export default class DHRoll extends Roll { const changeKeys = this.getActionChangeKeys(); return ( this.options.effects?.reduce((acc, effect) => { - if (effect.changes.some(x => changeKeys.some(key => x.key.includes(key)))) { + if (effect.system.changes.some(x => changeKeys.some(key => x.key.includes(key)))) { acc[effect.id] = { id: effect.id, name: effect.name, description: effect.description, - changes: effect.changes, + changes: effect.system.changes, origEffect: effect, selected: !effect.disabled }; diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index e65d0ff5..a19c7441 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -67,7 +67,7 @@ export default class DualityRoll extends D20Roll { setRallyChoices() { return this.data?.parent?.appliedEffects.reduce((a, c) => { - const change = c.changes.find(ch => ch.key === 'system.bonuses.rally'); + const change = c.system.changes.find(ch => ch.key === 'system.bonuses.rally'); if (change) a.push({ value: c.id, label: change.value }); return a; }, []); @@ -179,7 +179,7 @@ export default class DualityRoll extends D20Roll { static async buildConfigure(config = {}, message = {}) { config.dialog ??= {}; config.guaranteedCritical = config.data?.parent?.appliedEffects.reduce((a, c) => { - const change = c.changes.find(ch => ch.key === 'system.rules.roll.guaranteedCritical'); + const change = c.system.changes.find(ch => ch.key === 'system.rules.roll.guaranteedCritical'); if (change) a = true; return a; }, false); diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index 5e9b0c3b..330bd838 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -109,17 +109,25 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { /**@inheritdoc*/ static applyField(model, change, field) { - change.value = DhActiveEffect.getChangeValue(model, change, change.effect); + change.key = DhActiveEffect.getChangeKey(model, change, change.effect); super.applyField(model, change, field); } /** */ + static getChangeKey(model, change, effect) { + return DhActiveEffect.parseValue(change.key, model, change, effect); + } + static getChangeValue(model, change, effect) { - let value = change.value; - const isOriginTarget = value.toLowerCase().includes('origin.@'); + return DhActiveEffect.parseValue(change.value, model, change, effect); + } + + static parseValue(value, model, change, effect) { + let key = value; + const isOriginTarget = key.toLowerCase().includes('origin.@'); let parseModel = model; if (isOriginTarget && effect.origin) { - value = change.value.replaceAll(/origin\.@/gi, '@'); + key = change.key.replaceAll(/origin\.@/gi, '@'); try { const originEffect = foundry.utils.fromUuidSync(effect.origin); const doc = @@ -130,8 +138,8 @@ export default class DhActiveEffect extends foundry.documents.ActiveEffect { } catch (_) {} } - const evalValue = this.effectSafeEval(itemAbleRollParse(value, parseModel, effect.parent)); - return evalValue ?? value; + const evalValue = this.effectSafeEval(itemAbleRollParse(key, parseModel, effect.parent)); + return evalValue ?? key; } /** diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index c0dd45bd..bb9a0cfa 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -415,7 +415,12 @@ export async function createEmbeddedItemWithEffects(actor, baseData, update) { ...baseData, id: data.id, uuid: data.uuid, - effects: data.effects?.map(effect => effect.toObject()) + _uuid: data.uuid, + effects: data.effects?.map(effect => effect.toObject()), + _stats: { + ...data._stats, + compendiumSource: data.pack ? `Compendium.${data.pack}.Item.${data.id}` : null + } } ]); diff --git a/system.json b/system.json index 4a5eee0f..bd650096 100644 --- a/system.json +++ b/system.json @@ -2,11 +2,11 @@ "id": "daggerheart", "title": "Daggerheart", "description": "An unofficial implementation of the Daggerheart system", - "version": "1.6.1", + "version": "2.0.0", "compatibility": { - "minimum": "13.346", - "verified": "13.351", - "maximum": "13" + "minimum": "14.353", + "verified": "14.353", + "maximum": "14" }, "authors": [ { diff --git a/templates/sheets/activeEffect/change.hbs b/templates/sheets/activeEffect/change.hbs new file mode 100644 index 00000000..60cb0d85 --- /dev/null +++ b/templates/sheets/activeEffect/change.hbs @@ -0,0 +1,17 @@ +
  • +
    + {{formInput fields.key name=change.keyPath value=change.key}} +
    +
    + {{formInput fields.type name=change.typePath value=change.type localize=true}} +
    +
    + {{formInput fields.value name=change.valuePath value=change.value elementType="input"}} +
    +
    + {{formInput fields.priority name=change.priorityPath value=change.priority placeholder=defaultPriority}} +
    +
    + +
    +
  • diff --git a/templates/sheets/activeEffect/changes.hbs b/templates/sheets/activeEffect/changes.hbs index 75f49e4a..8604daf6 100644 --- a/templates/sheets/activeEffect/changes.hbs +++ b/templates/sheets/activeEffect/changes.hbs @@ -1,31 +1,16 @@
    -
    {{localize "EFFECT.ChangeKey"}}
    -
    {{localize "EFFECT.ChangeMode"}}
    -
    {{localize "EFFECT.ChangeValue"}}
    -
    {{localize "EFFECT.ChangePriority"}}
    -
    +
    {{localize "EFFECT.FIELDS.changes.element.key.label"}}
    +
    {{localize "EFFECT.FIELDS.changes.element.type.label"}}
    +
    {{localize "EFFECT.FIELDS.changes.element.value.label"}}
    +
    {{localize "EFFECT.FIELDS.changes.element.priority.label"}}
    +
    + +
      - {{#each source.changes as |change i|}} - {{#with ../fields.changes.element.fields as |changeFields|}} -
    1. -
      - -
      -
      - {{formInput changeFields.mode name=(concat "changes." i ".mode") value=change.mode choices=@root.modes}} -
      -
      - {{formInput changeFields.value name=(concat "changes." i ".value") value=change.value}} -
      -
      - {{formInput changeFields.priority name=(concat "changes." i ".priority") value=change.priority - placeholder=(lookup ../../priorities change.mode)}} -
      -
      -
    2. - {{/with}} + {{#each changes as |change|}} + {{{change}}} {{/each}}
    -
    \ No newline at end of file +