From e55809f98823ef24d2d8dbfa4b4f468ba0d9a758 Mon Sep 17 00:00:00 2001 From: WBHarry Date: Sun, 27 Jul 2025 13:06:26 +0200 Subject: [PATCH] Various fixes --- daggerheart.mjs | 4 +- lang/en.json | 77 +++++++++++++------ module/applications/sheets/api/base-item.mjs | 20 +++-- module/applications/ui/chatLog.mjs | 4 +- module/config/actionConfig.mjs | 2 +- module/data/action/baseAction.mjs | 6 +- module/data/actor/base.mjs | 33 ++++++-- module/data/actor/character.mjs | 4 +- module/data/fields/action/rollField.mjs | 37 ++++++--- module/data/item/armor.mjs | 1 - module/data/item/beastform.mjs | 16 ++-- module/enrichers/DualityRollEnricher.mjs | 8 +- module/helpers/utils.mjs | 4 +- templates/actionTypes/roll.hbs | 6 +- .../partials/inventory-fieldset-items-V2.hbs | 2 +- templates/ui/chat/duality-roll.hbs | 2 +- 16 files changed, 152 insertions(+), 74 deletions(-) diff --git a/daggerheart.mjs b/daggerheart.mjs index 387c1a74..8964184c 100644 --- a/daggerheart.mjs +++ b/daggerheart.mjs @@ -196,9 +196,9 @@ Hooks.on('chatMessage', (_, message) => { const traitValue = rollCommand.trait?.toLowerCase(); const advantage = rollCommand.advantage - ? CONFIG.DH.ACTIONS.advandtageState.advantage.value + ? CONFIG.DH.ACTIONS.advantageState.advantage.value : rollCommand.disadvantage - ? CONFIG.DH.ACTIONS.advandtageState.disadvantage.value + ? CONFIG.DH.ACTIONS.advantageState.disadvantage.value : undefined; const difficulty = rollCommand.difficulty; diff --git a/lang/en.json b/lang/en.json index d5a08fff..a5c9132a 100755 --- a/lang/en.json +++ b/lang/en.json @@ -28,26 +28,6 @@ }, "DAGGERHEART": { "ACTIONS": { - "Config": { - "beastform": { - "exact": "Beastform Max Tier", - "exactHint": "The Character's Tier is used if empty", - "label": "Beastform" - }, - "displayInChat": "Display in chat" - }, - "Settings": { - "attackBonus": "Attack Bonus", - "attackName": "Attack Name", - "includeBase": { "label": "Include Item Damage" }, - "multiplier": "Multiplier", - "resultBased": { - "label": "Formula based on Hope/Fear result." - }, - "applyTo": { - "label": "Targeted Resource" - } - }, "TYPES": { "attack": { "name": "Attack", @@ -77,6 +57,35 @@ "name": "Summon", "tooltip": "Create tokens in the scene." } + }, + "Config": { + "beastform": { + "exact": "Beastform Max Tier", + "exactHint": "The Character's Tier is used if empty", + "label": "Beastform" + }, + "displayInChat": "Display in chat" + }, + "RollField": { + "diceRolling": { + "compare": "Should be", + "dice": "Dice Type", + "flatMultiplier": "Flat Multiplier", + "multiplier": "Dice Number", + "threshold": "Threshold" + } + }, + "Settings": { + "attackBonus": "Attack Bonus", + "attackName": "Attack Name", + "includeBase": { "label": "Include Item Damage" }, + "multiplier": "Multiplier", + "resultBased": { + "label": "Formula based on Hope/Fear result." + }, + "applyTo": { + "label": "Targeted Resource" + } } }, "ACTORS": { @@ -1107,10 +1116,30 @@ }, "DamageResistance": { "none": "None", - "resistance": "Resistance", - "immunity": "Immunity", - "physicalReduction": "Physical Damage Reduction", - "magicalReduction": "Magical Damage Reduction" + "physicalResistance": { + "label": "Damage Resistance: Physical", + "hint": "Physical Damage is halved if this is set to 1" + }, + "magicalResistance": { + "label": "Damage Resistance: Magical", + "hint": "Magical Damage is halved if this is set to 1" + }, + "physicalImmunity": { + "label": "Damage Immunity: Physical", + "hint": "Immune to Physical Damage if this is set to 1" + }, + "magicalImmunity": { + "label": "Damage Immunity: Magical", + "hint": "Immune to Magical Damage if this is set to 1" + }, + "physicalReduction": { + "label": "Damage Reduction: Physical", + "hint": "Physical Damage is reduced by the amount set here" + }, + "magicalReduction": { + "label": "Damage Reduction: Magical", + "hint": "Magical Damage is reduced by the amount set here" + } }, "DamageThresholds": { "title": "Damage Thresholds", diff --git a/module/applications/sheets/api/base-item.mjs b/module/applications/sheets/api/base-item.mjs index 22f7c880..ed63956b 100644 --- a/module/applications/sheets/api/base-item.mjs +++ b/module/applications/sheets/api/base-item.mjs @@ -249,12 +249,20 @@ export default class DHBaseItemSheet extends DHApplicationMixin(ItemSheetV2) { const target = event.target.closest('fieldset.drop-section'); const item = await fromUuid(data.uuid); if (item?.type === 'feature') { - await this.document.update({ - 'system.features': [...this.document.system.features, { type: target.dataset.type, item }].map(x => ({ - ...x, - item: x.item?.uuid - })) - }); + if (target.dataset.type) { + await this.document.update({ + 'system.features': [...this.document.system.features, { type: target.dataset.type, item }].map( + x => ({ + ...x, + item: x.item?.uuid + }) + ) + }); + } else { + await this.document.update({ + 'system.features': [...this.document.system.features, item].map(x => x.uuid) + }); + } } } } diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 2547a47c..8af11249 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -66,8 +66,8 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo super.close(options); } - async getActor(id) { - return await fromUuid(id); + async getActor(uuid) { + return await foundry.utils.fromUuid(uuid); } getAction(actor, itemId, actionId) { diff --git a/module/config/actionConfig.mjs b/module/config/actionConfig.mjs index f6fa41f6..1f1ebf8b 100644 --- a/module/config/actionConfig.mjs +++ b/module/config/actionConfig.mjs @@ -108,7 +108,7 @@ export const diceCompare = { } }; -export const advandtageState = { +export const advantageState = { disadvantage: { label: 'DAGGERHEART.GENERAL.Disadvantage.full', value: -1 diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 779e5268..add9f77d 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -164,7 +164,8 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel title: this.item.name, source: { item: this.item._id, - action: this._id + action: this._id, + actor: this.actor.uuid }, dialog: {}, type: this.type, @@ -191,7 +192,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel difficulty: this.roll?.difficulty, formula: this.roll.getFormula(), bonus: this.roll.bonus, - advantage: CONFIG.DH.ACTIONS.advandtageState[this.roll.advState].value + advantage: CONFIG.DH.ACTIONS.advantageState[this.roll.advState].value }; if (this.roll?.type === 'diceSet') roll.lite = true; @@ -256,6 +257,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel /* EFFECTS */ async applyEffects(event, data, targets) { targets ??= data.system.targets; + const force = true; /* Where should this come from? */ if (!this.effects?.length || !targets.length) return; let effects = this.effects; targets.forEach(async token => { diff --git a/module/data/actor/base.mjs b/module/data/actor/base.mjs index 19de7b06..1f4060b0 100644 --- a/module/data/actor/base.mjs +++ b/module/data/actor/base.mjs @@ -1,10 +1,23 @@ import DHBaseActorSettings from '../../applications/sheets/api/actor-setting.mjs'; -const resistanceField = reductionLabel => +const resistanceField = (resistanceLabel, immunityLabel, reductionLabel) => new foundry.data.fields.SchemaField({ - resistance: new foundry.data.fields.BooleanField({ initial: false }), - immunity: new foundry.data.fields.BooleanField({ initial: false }), - reduction: new foundry.data.fields.NumberField({ integer: true, initial: 0, label: reductionLabel }) + resistance: new foundry.data.fields.BooleanField({ + initial: false, + label: `${resistanceLabel}.label`, + hint: `${resistanceLabel}.hint` + }), + immunity: new foundry.data.fields.BooleanField({ + initial: false, + label: `${immunityLabel}.label`, + hint: `${immunityLabel}.hint` + }), + reduction: new foundry.data.fields.NumberField({ + integer: true, + initial: 0, + label: `${reductionLabel}.label`, + hint: `${reductionLabel}.hint` + }) }); /** @@ -40,8 +53,16 @@ export default class BaseDataActor extends foundry.abstract.TypeDataModel { if (this.metadata.isNPC) schema.description = new fields.HTMLField({ required: true, nullable: true }); if (this.metadata.hasResistances) schema.resistance = new fields.SchemaField({ - physical: resistanceField('DAGGERHEART.GENERAL.DamageResistance.physicalReduction'), - magical: resistanceField('DAGGERHEART.GENERAL.DamageResistance.magicalReduction') + physical: resistanceField( + 'DAGGERHEART.GENERAL.DamageResistance.physicalResistance', + 'DAGGERHEART.GENERAL.DamageResistance.physicalImmunity', + 'DAGGERHEART.GENERAL.DamageResistance.physicalReduction' + ), + magical: resistanceField( + 'DAGGERHEART.GENERAL.DamageResistance.magicalResistance', + 'DAGGERHEART.GENERAL.DamageResistance.magicalImmunity', + 'DAGGERHEART.GENERAL.DamageResistance.magicalReduction' + ) }); return schema; } diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index 5cd63e84..61511241 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -45,12 +45,12 @@ export default class DhCharacter extends BaseDataActor { severe: new fields.NumberField({ integer: true, initial: 0, - label: 'DAGGERHEART.GENERAL.DamageThresholds.majorThreshold' + label: 'DAGGERHEART.GENERAL.DamageThresholds.severeThreshold' }), major: new fields.NumberField({ integer: true, initial: 0, - label: 'DAGGERHEART.GENERAL.DamageThresholds.severeThreshold' + label: 'DAGGERHEART.GENERAL.DamageThresholds.majorThreshold' }) }), experiences: new fields.TypedObjectField( diff --git a/module/data/fields/action/rollField.mjs b/module/data/fields/action/rollField.mjs index 0686f71f..b01db06b 100644 --- a/module/data/fields/action/rollField.mjs +++ b/module/data/fields/action/rollField.mjs @@ -8,25 +8,38 @@ export class DHActionRollData extends foundry.abstract.DataModel { trait: new fields.StringField({ nullable: true, initial: null, choices: CONFIG.DH.ACTOR.abilities }), difficulty: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 }), bonus: new fields.NumberField({ nullable: true, initial: null, integer: true }), - advState: new fields.StringField({ choices: CONFIG.DH.ACTIONS.advandtageState, initial: 'neutral' }), + advState: new fields.StringField({ + choices: CONFIG.DH.ACTIONS.advantageState, + initial: CONFIG.DH.ACTIONS.advantageState.neutral.label + }), diceRolling: new fields.SchemaField({ multiplier: new fields.StringField({ choices: CONFIG.DH.GENERAL.diceSetNumbers, - initial: 'prof', - label: 'Dice Number' + initial: CONFIG.DH.GENERAL.diceSetNumbers.prof, + label: 'DAGGERHEART.ACTIONS.RollField.diceRolling.multiplier' + }), + flatMultiplier: new fields.NumberField({ + nullable: true, + initial: 1, + label: 'DAGGERHEART.ACTIONS.RollField.diceRolling.flatMultiplier' }), - flatMultiplier: new fields.NumberField({ nullable: true, initial: 1, label: 'Flat Multiplier' }), dice: new fields.StringField({ choices: CONFIG.DH.GENERAL.diceTypes, - initial: 'd6', - label: 'Dice Type' + initial: CONFIG.DH.GENERAL.diceTypes.d6, + label: 'DAGGERHEART.ACTIONS.RollField.diceRolling.dice' }), compare: new fields.StringField({ choices: CONFIG.DH.ACTIONS.diceCompare, - initial: 'above', - label: 'Should be' + nullable: true, + initial: null, + label: 'DAGGERHEART.ACTIONS.RollField.diceRolling.compare' }), - treshold: new fields.NumberField({ initial: 1, integer: true, min: 1, label: 'Treshold' }) + treshold: new fields.NumberField({ + integer: true, + nullable: true, + initial: null, + label: 'DAGGERHEART.ACTIONS.RollField.diceRolling.threshold' + }) }), useDefault: new fields.BooleanField({ initial: false }) }; @@ -41,7 +54,11 @@ export class DHActionRollData extends foundry.abstract.DataModel { this.diceRolling.multiplier === 'flat' ? this.diceRolling.flatMultiplier : `@${this.diceRolling.multiplier}`; - formula = `${multiplier}${this.diceRolling.dice}cs${CONFIG.DH.ACTIONS.diceCompare[this.diceRolling.compare].operator}${this.diceRolling.treshold}`; + if (this.diceRolling.compare && this.diceRolling.threshold) { + formula = `${multiplier}${this.diceRolling.dice}cs${CONFIG.DH.ACTIONS.diceCompare[this.diceRolling.compare].operator}${this.diceRolling.treshold}`; + } else { + formula = `${multiplier}${this.diceRolling.dice}`; + } break; default: formula = ''; diff --git a/module/data/item/armor.mjs b/module/data/item/armor.mjs index 2639ae1e..64a6e9c0 100644 --- a/module/data/item/armor.mjs +++ b/module/data/item/armor.mjs @@ -1,5 +1,4 @@ import AttachableItem from './attachableItem.mjs'; -import { ActionsField } from '../fields/actionField.mjs'; import { armorFeatures } from '../../config/itemConfig.mjs'; export default class DHArmor extends AttachableItem { diff --git a/module/data/item/beastform.mjs b/module/data/item/beastform.mjs index 0dca8883..478beac6 100644 --- a/module/data/item/beastform.mjs +++ b/module/data/item/beastform.mjs @@ -152,12 +152,14 @@ export default class DHBeastform extends BaseDataItem { _onCreate(_data, _options, userId) { if (userId !== game.user.id) return; - this.parent.createEmbeddedDocuments('ActiveEffect', [ - { - type: 'beastform', - name: game.i18n.localize('DAGGERHEART.ITEMS.Beastform.beastformEffect'), - img: 'icons/creatures/abilities/paw-print-pair-purple.webp' - } - ]); + if (!this.parent.effects.find(x => x.type === 'beastform')) { + this.parent.createEmbeddedDocuments('ActiveEffect', [ + { + type: 'beastform', + name: game.i18n.localize('DAGGERHEART.ITEMS.Beastform.beastformEffect'), + img: 'icons/creatures/abilities/paw-print-pair-purple.webp' + } + ]); + } } } diff --git a/module/enrichers/DualityRollEnricher.mjs b/module/enrichers/DualityRollEnricher.mjs index 70f376e7..690262ce 100644 --- a/module/enrichers/DualityRollEnricher.mjs +++ b/module/enrichers/DualityRollEnricher.mjs @@ -22,14 +22,14 @@ function getDualityMessage(roll) { : game.i18n.localize('DAGGERHEART.GENERAL.duality'); const advantage = roll.advantage - ? CONFIG.DH.ACTIONS.advandtageState.advantage.value + ? CONFIG.DH.ACTIONS.advantageState.advantage.value : roll.disadvantage - ? CONFIG.DH.ACTIONS.advandtageState.disadvantage.value + ? CONFIG.DH.ACTIONS.advantageState.disadvantage.value : undefined; const advantageLabel = - advantage === CONFIG.DH.ACTIONS.advandtageState.advantage.value + advantage === CONFIG.DH.ACTIONS.advantageState.advantage.value ? 'Advantage' - : advantage === CONFIG.DH.ACTIONS.advandtageState.disadvantage.value + : advantage === CONFIG.DH.ACTIONS.advantageState.disadvantage.value ? 'Disadvantage' : undefined; diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index e2f30130..93568894 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -271,14 +271,14 @@ export function addLinkedItemsDiff(changedItems, currentItems, options) { newItems .difference(prevItems) .map(item => item?.item ?? item) - .filter(x => (typeof x === 'object' ? x.item : x)) + .filter(x => (typeof x === 'object' ? x?.item : x)) ); options.toUnlink = Array.from( prevItems .difference(newItems) .map(item => item?.item?.uuid ?? item?.uuid ?? item) - .filter(x => (typeof x === 'object' ? x.item : x)) + .filter(x => (typeof x === 'object' ? x?.item : x)) ); } } diff --git a/templates/actionTypes/roll.hbs b/templates/actionTypes/roll.hbs index 874d09f2..2d2dab3c 100644 --- a/templates/actionTypes/roll.hbs +++ b/templates/actionTypes/roll.hbs @@ -11,9 +11,9 @@ {{#if (eq source.type "diceSet")}}
{{formField fields.diceRolling.fields.multiplier name="roll.diceRolling.multiplier" value=source.diceRolling.multiplier localize=true}} - {{#if (eq source.diceRolling.multiplier 'flat')}}{{formField fields.diceRolling.fields.flatMultiplier value=source.diceRolling.flatMultiplier name="roll.diceRolling.flatMultiplier" }}{{/if}} - {{formField fields.diceRolling.fields.dice name="roll.diceRolling.dice" value=source.diceRolling.dice}} - {{formField fields.diceRolling.fields.compare name="roll.diceRolling.compare" value=source.diceRolling.compare localize=true}} + {{#if (eq source.diceRolling.multiplier 'flat')}}{{formField fields.diceRolling.fields.flatMultiplier value=source.diceRolling.flatMultiplier name="roll.diceRolling.flatMultiplier" localize=true }}{{/if}} + {{formField fields.diceRolling.fields.dice name="roll.diceRolling.dice" value=source.diceRolling.dice localize=true}} + {{formField fields.diceRolling.fields.compare name="roll.diceRolling.compare" value=source.diceRolling.compare localize=true blank=""}} {{formField fields.diceRolling.fields.treshold name="roll.diceRolling.treshold" value=source.diceRolling.treshold localize=true}}
{{else}} diff --git a/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs b/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs index aa58aad8..29b008bb 100644 --- a/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs +++ b/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs @@ -22,7 +22,7 @@ Parameters: - showActions {boolean} : If true show feature's actions. --}} -
+
{{localize title}} {{#if canCreate}} diff --git a/templates/ui/chat/duality-roll.hbs b/templates/ui/chat/duality-roll.hbs index 7ca039ab..79d906a4 100644 --- a/templates/ui/chat/duality-roll.hbs +++ b/templates/ui/chat/duality-roll.hbs @@ -189,7 +189,7 @@ {{/if}} {{/if}} {{#if hasEffect}} - + {{/if}}
{{roll.total}}