From a54f4e383119e62fbc1b2666e02421c9e429e02c Mon Sep 17 00:00:00 2001 From: WBHarry <89362246+WBHarry@users.noreply.github.com> Date: Sat, 26 Jul 2025 22:34:20 +0200 Subject: [PATCH] [Bug] Downtime Actions Fixes (#421) * . * Added a temp fix for a bug in action healing section * Corrected rules.attack.roll.trait * . --- lang/en.json | 7 ++++++ .../settings/homebrewSettings.mjs | 24 +++++++++++++++---- .../applications/sheets/items/beastform.mjs | 1 + module/config/generalConfig.mjs | 6 +++++ module/data/actor/character.mjs | 18 +++++++++++--- module/data/fields/actionField.mjs | 5 +++- module/data/item/weapon.mjs | 17 +++++++++++++ module/documents/activeEffect.mjs | 3 ++- 8 files changed, 71 insertions(+), 10 deletions(-) diff --git a/lang/en.json b/lang/en.json index 182c7419..5d434861 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1243,6 +1243,9 @@ "attack": { "damage": { "value": { "label": "Base Attack: Damage" } + }, + "roll": { + "trait": { "label": "Base Attack: Trait" } } } }, @@ -1593,6 +1596,10 @@ "hint": "test" } } + }, + "ResetSettings": { + "resetConfirmationTitle": "Reset Settings", + "resetConfirmationText": "Are you sure you want to reset the {settings}?" } }, "UI": { diff --git a/module/applications/settings/homebrewSettings.mjs b/module/applications/settings/homebrewSettings.mjs index 2aa2660e..1b73747c 100644 --- a/module/applications/settings/homebrewSettings.mjs +++ b/module/applications/settings/homebrewSettings.mjs @@ -136,10 +136,14 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli ...move, name: game.i18n.localize(move.name), description: game.i18n.localize(move.description), - actions: move.actions.map(action => ({ - ...action, - name: game.i18n.localize(action.name) - })) + actions: move.actions.reduce((acc, key) => { + const action = move.actions[key]; + acc[key] = { + ...action, + name: game.i18n.localize(action.name) + }; + return acc; + }, {}) }; return acc; @@ -165,8 +169,18 @@ export default class DhHomebrewSettings extends HandlebarsApplicationMixin(Appli } static async reset() { + const confirmed = await foundry.applications.api.DialogV2.confirm({ + window: { + title: game.i18n.format('DAGGERHEART.SETTINGS.ResetSettings.resetConfirmationTitle') + }, + content: game.i18n.format('DAGGERHEART.SETTINGS.ResetSettings.resetConfirmationText', { + settings: game.i18n.localize('DAGGERHEART.SETTINGS.Menu.homebrew.name') + }) + }); + if (!confirmed) return; + const resetSettings = new DhHomebrew(); - let localizedSettings = this.localizeObject(resetSettings); + let localizedSettings = this.localizeObject(resetSettings.toObject()); this.settings.updateSource(localizedSettings); this.render(); } diff --git a/module/applications/sheets/items/beastform.mjs b/module/applications/sheets/items/beastform.mjs index 1d6adcd3..1c4a4880 100644 --- a/module/applications/sheets/items/beastform.mjs +++ b/module/applications/sheets/items/beastform.mjs @@ -81,6 +81,7 @@ export default class BeastformSheet extends DHBaseItemSheet { case 'effects': context.effects.actives = context.effects.actives.map(effect => { const data = effect.toObject(); + data.uuid = effect.uuid; data.id = effect.id; if (effect.type === 'beastform') data.mandatory = true; diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index de33eade..fff7b613 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -141,6 +141,7 @@ export const defaultRestOptions = { actions: { tendToWounds: { type: 'healing', + systemPath: 'restMoves.shortRest.moves.tendToWounds.actions', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.tendToWounds.name'), img: 'icons/magic/life/cross-worn-green.webp', actionType: 'action', @@ -166,6 +167,7 @@ export const defaultRestOptions = { actions: { clearStress: { type: 'healing', + systemPath: 'restMoves.shortRest.moves.clearStress.actions', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.clearStress.name'), img: 'icons/magic/perception/eye-ringed-green.webp', actionType: 'action', @@ -191,6 +193,7 @@ export const defaultRestOptions = { actions: { repairArmor: { type: 'healing', + systemPath: 'restMoves.shortRest.moves.repairArmor.actions', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.shortRest.repairArmor.name'), img: 'icons/skills/trades/smithing-anvil-silver-red.webp', actionType: 'action', @@ -226,6 +229,7 @@ export const defaultRestOptions = { actions: { tendToWounds: { type: 'healing', + systemPath: 'restMoves.longRest.moves.tendToWounds.actions', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.tendToWounds.name'), img: 'icons/magic/life/cross-worn-green.webp', actionType: 'action', @@ -251,6 +255,7 @@ export const defaultRestOptions = { actions: { clearStress: { type: 'healing', + systemPath: 'restMoves.longRest.moves.clearStress.actions', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.clearStress.name'), img: 'icons/magic/perception/eye-ringed-green.webp', actionType: 'action', @@ -276,6 +281,7 @@ export const defaultRestOptions = { actions: { repairArmor: { type: 'healing', + systemPath: 'restMoves.longRest.moves.repairArmor.actions', name: game.i18n.localize('DAGGERHEART.APPLICATIONS.Downtime.longRest.repairArmor.name'), img: 'icons/skills/trades/smithing-anvil-silver-red.webp', actionType: 'action', diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 289b5dba..5cd63e84 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -204,7 +204,7 @@ export default class DhCharacter extends BaseDataActor { }) }) }), - maxLoadout : new fields.NumberField({ + maxLoadout: new fields.NumberField({ integer: true, initial: 0, label: 'DAGGERHEART.GENERAL.Bonuses.maxLoadout.label' @@ -249,6 +249,15 @@ export default class DhCharacter extends BaseDataActor { initial: '@profd4', label: 'DAGGERHEART.GENERAL.Rules.attack.damage.value.label' }) + }), + roll: new fields.SchemaField({ + trait: new fields.StringField({ + required: true, + choices: CONFIG.DH.ACTOR.abilities, + nullable: true, + initial: null, + label: 'DAGGERHEART.GENERAL.Rules.attack.roll.trait.label' + }) }) }), weapon: new fields.SchemaField({ @@ -329,13 +338,15 @@ export default class DhCharacter extends BaseDataActor { get loadoutSlot() { const loadoutCount = this.domainCards.loadout?.length ?? 0, - max = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxLoadout + this.bonuses.maxLoadout; + max = + game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Homebrew).maxLoadout + + this.bonuses.maxLoadout; return { current: loadoutCount, available: Math.max(max - loadoutCount, 0), max - } + }; } get armor() { @@ -535,6 +546,7 @@ export default class DhCharacter extends BaseDataActor { prepareDerivedData() { const baseHope = this.resources.hope.value + (this.companion?.system?.resources?.hope ?? 0); this.resources.hope.value = Math.min(baseHope, this.resources.hope.max); + this.attack.roll.trait = this.rules.attack.roll.trait ?? this.attack.roll.trait; } getRollData() { diff --git a/module/data/fields/actionField.mjs b/module/data/fields/actionField.mjs index 00197e53..287d53ee 100644 --- a/module/data/fields/actionField.mjs +++ b/module/data/fields/actionField.mjs @@ -215,7 +215,10 @@ export function ActionMixin(Base) { await this.parent.updateSource({ [path]: updates }, options); result = this.parent; } else { - result = await this.item.update({ [path]: updates }, options); + /* Fix me - For some reason updating the "healing" section in particular doesn't work without this */ + await this.item.update({ [path]: updates }, options); + await this.item.updateSource({ [path]: updates }, options); + result = this.item; } return this.inCollection diff --git a/module/data/item/weapon.mjs b/module/data/item/weapon.mjs index 71d1e08d..96c0eeba 100644 --- a/module/data/item/weapon.mjs +++ b/module/data/item/weapon.mjs @@ -63,6 +63,19 @@ export default class DHWeapon extends AttachableItem { ] } } + }), + rules: new fields.SchemaField({ + attack: new fields.SchemaField({ + roll: new fields.SchemaField({ + trait: new fields.StringField({ + required: true, + choices: CONFIG.DH.ACTOR.abilities, + nullable: true, + initial: null, + label: 'DAGGERHEART.GENERAL.Rules.attack.roll.trait.label' + }) + }) + }) }) }; } @@ -77,6 +90,10 @@ export default class DHWeapon extends AttachableItem { ); } + prepareDerivedData() { + this.attack.roll.trait = this.rules.attack.roll.trait ?? this.attack.roll.trait; + } + async _preUpdate(changes, options, user) { const allowed = await super._preUpdate(changes, options, user); if (allowed === false) return false; diff --git a/module/documents/activeEffect.mjs b/module/documents/activeEffect.mjs index 6c4545b1..3c45929b 100644 --- a/module/documents/activeEffect.mjs +++ b/module/documents/activeEffect.mjs @@ -55,7 +55,8 @@ export default class DhActiveEffect extends ActiveEffect { } static applyField(model, change, field) { - change.value = this.effectSafeEval(itemAbleRollParse(change.value, model, change.effect.parent)); + const evalValue = this.effectSafeEval(itemAbleRollParse(change.value, model, change.effect.parent)); + change.value = evalValue ?? change.value; super.applyField(model, change, field); }