From 7cbbb3168e7cb7a48a63855423570e7fbeafda5f Mon Sep 17 00:00:00 2001 From: Dapoulp <74197441+Dapoulp@users.noreply.github.com> Date: Sat, 19 Jul 2025 15:48:50 +0200 Subject: [PATCH 1/4] Feature/336 damage targeted resources (#376) * Unify healing & damage * create DHResourceData * Damages parts roll * h * ChatMessage & takeDamage updates * Adapt healing * No, there was not a console.log ! --- lang/en.json | 8 ++ module/applications/dialogs/damageDialog.mjs | 6 +- .../dialogs/damageReductionDialog.mjs | 6 +- module/applications/ui/chatLog.mjs | 30 ++++-- module/config/generalConfig.mjs | 5 + module/data/action/actionDice.mjs | 37 +++++-- module/data/action/baseAction.mjs | 24 ++--- module/data/action/damageAction.mjs | 39 ++++--- module/data/action/healingAction.mjs | 22 ++-- module/data/actor/character.mjs | 5 +- module/dice/d20Roll.mjs | 19 ++-- module/dice/damageRoll.mjs | 101 +++++++++++++++--- module/dice/dhRoll.mjs | 28 ++--- module/dice/dualityRoll.mjs | 14 +-- module/documents/actor.mjs | 78 ++++++++------ module/documents/token.mjs | 2 +- module/helpers/utils.mjs | 12 +++ styles/less/global/dialog.less | 11 ++ styles/less/global/elements.less | 2 +- styles/less/ui/chat/chat.less | 5 + templates/actionTypes/damage.hbs | 14 ++- templates/actionTypes/healing.hbs | 64 ++++++----- .../dialogs/dice-roll/damageSelection.hbs | 24 ++++- templates/ui/chat/healing-roll.hbs | 42 ++++---- templates/ui/chat/parts/damage-chat.hbs | 49 +++++---- 25 files changed, 415 insertions(+), 232 deletions(-) diff --git a/lang/en.json b/lang/en.json index 4e9a9b11..9f929c77 100755 --- a/lang/en.json +++ b/lang/en.json @@ -35,6 +35,9 @@ "Settings": { "resultBased": { "label": "Formula based on Hope/Fear result." + }, + "applyTo": { + "label": "Targeted Resource" } }, "TYPES": { @@ -662,6 +665,10 @@ "armorStack": { "name": "Armor Stack", "abbreviation": "AS" + }, + "fear": { + "name": "Fear", + "abbreviation": "FR" } }, "ItemResourceType": { @@ -1252,6 +1259,7 @@ }, "fear": "Fear", "features": "Features", + "healing": "Healing", "hitPoints": { "single": "Hit Point", "plural": "Hit Points", diff --git a/module/applications/dialogs/damageDialog.mjs b/module/applications/dialogs/damageDialog.mjs index 70dcace8..1b61b96d 100644 --- a/module/applications/dialogs/damageDialog.mjs +++ b/module/applications/dialogs/damageDialog.mjs @@ -43,10 +43,11 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application async _prepareContext(_options) { const context = await super._prepareContext(_options); + context.config = CONFIG.DH; context.title = this.config.title ? this.config.title : game.i18n.localize('DAGGERHEART.EFFECTS.ApplyLocations.damageRoll.name'); - context.extraFormula = this.config.extraFormula; + // context.extraFormula = this.config.extraFormula; context.formula = this.roll.constructFormula(this.config); context.directDamage = this.config.directDamage; context.selectedRollMode = this.config.selectedRollMode; @@ -55,13 +56,12 @@ export default class DamageDialog extends HandlebarsApplicationMixin(Application label, icon })); - return context; } static updateRollConfiguration(_event, _, formData) { const { ...rest } = foundry.utils.expandObject(formData.object); - this.config.extraFormula = rest.extraFormula; + foundry.utils.mergeObject(this.config.roll, rest.roll) this.config.selectedRollMode = rest.selectedRollMode; this.render(); diff --git a/module/applications/dialogs/damageReductionDialog.mjs b/module/applications/dialogs/damageReductionDialog.mjs index 984106d7..658cef96 100644 --- a/module/applications/dialogs/damageReductionDialog.mjs +++ b/module/applications/dialogs/damageReductionDialog.mjs @@ -10,12 +10,12 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap this.reject = reject; this.actor = actor; this.damage = damage; - + const canApplyArmor = damageType.every(t => actor.system.armorApplicableDamageTypes[t] === true); const maxArmorMarks = canApplyArmor ? Math.min( actor.system.armorScore - actor.system.armor.system.marks.value, - actor.system.rules.damageReduction.maxArmorMarked.total + actor.system.rules.damageReduction.maxArmorMarked.value ) : 0; @@ -100,7 +100,7 @@ export default class DamageReductionDialog extends HandlebarsApplicationMixin(Ap context.armorScore = this.actor.system.armorScore; context.armorMarks = currentMarks; context.basicMarksUsed = - selectedArmorMarks.length === this.actor.system.rules.damageReduction.maxArmorMarked.total; + selectedArmorMarks.length === this.actor.system.rules.damageReduction.maxArmorMarked.value; const stressReductionStress = this.availableStressReductions ? stressReductions.reduce((acc, red) => acc + red.cost, 0) diff --git a/module/applications/ui/chatLog.mjs b/module/applications/ui/chatLog.mjs index 4570b076..29a0f46e 100644 --- a/module/applications/ui/chatLog.mjs +++ b/module/applications/ui/chatLog.mjs @@ -187,7 +187,6 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.attackTargetDoesNotExist')); return; } - game.canvas.pan(token); }; @@ -207,15 +206,24 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo if (!confirm) return; } } - + if (targets.length === 0) - ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected')); - for (let target of targets) { - let damage = message.system.roll.total; - if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true) - damage = Math.ceil(damage * (CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1)); + return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected')); - target.actor.takeDamage(damage, message.system.damage.damageType); + for (let target of targets) { + let damages = message.system.damage; + if (message.system.onSave && message.system.targets.find(t => t.id === target.id)?.saved?.success === true) { + const mod = CONFIG.DH.ACTIONS.damageOnSave[message.system.onSave]?.mod ?? 1; + Object.entries(damages).forEach((k,v) => { + let newTotal = 0; + v.forEach(part => { + v.total = Math.ceil(v.total * mod); + newTotal += v.total; + }) + }) + } + + target.actor.takeDamage(damages.roll); } }; @@ -224,10 +232,10 @@ export default class DhpChatLog extends foundry.applications.sidebar.tabs.ChatLo const targets = Array.from(game.user.targets); if (targets.length === 0) - ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected')); - + return ui.notifications.info(game.i18n.localize('DAGGERHEART.UI.Notifications.noTargetsSelected')); + for (var target of targets) { - target.actor.takeHealing([{ value: message.system.roll.total, type: message.system.roll.type }]); + target.actor.takeHealing(message.system.roll); } }; diff --git a/module/config/generalConfig.mjs b/module/config/generalConfig.mjs index 632e5448..efe8a016 100644 --- a/module/config/generalConfig.mjs +++ b/module/config/generalConfig.mjs @@ -89,6 +89,11 @@ export const healingTypes = { id: 'armorStack', label: 'DAGGERHEART.CONFIG.HealingType.armorStack.name', abbreviation: 'DAGGERHEART.CONFIG.HealingType.armorStack.abbreviation' + }, + fear: { + id: 'fear', + label: 'DAGGERHEART.CONFIG.HealingType.fear.name', + abbreviation: 'DAGGERHEART.CONFIG.HealingType.fear.abbreviation' } }; diff --git a/module/data/action/actionDice.mjs b/module/data/action/actionDice.mjs index d71b390a..c3c28247 100644 --- a/module/data/action/actionDice.mjs +++ b/module/data/action/actionDice.mjs @@ -93,10 +93,32 @@ export class DHDamageField extends fields.SchemaField { } } -export class DHDamageData extends foundry.abstract.DataModel { +export class DHResourceData extends foundry.abstract.DataModel { /** @override */ static defineSchema() { return { + applyTo: new fields.StringField({ + choices: CONFIG.DH.GENERAL.healingTypes, + required: true, + blank: false, + initial: CONFIG.DH.GENERAL.healingTypes.hitPoints.id, + label: 'DAGGERHEART.ACTIONS.Settings.applyTo.label' + }), + resultBased: new fields.BooleanField({ + initial: false, + label: 'DAGGERHEART.ACTIONS.Settings.resultBased.label' + }), + value: new fields.EmbeddedDataField(DHActionDiceData), + valueAlt: new fields.EmbeddedDataField(DHActionDiceData) + } + } +} + +export class DHDamageData extends DHResourceData { + /** @override */ + static defineSchema() { + return { + ...super.defineSchema(), base: new fields.BooleanField({ initial: false, readonly: true, label: 'Base' }), type: new fields.SetField( new fields.StringField({ @@ -106,16 +128,9 @@ export class DHDamageData extends foundry.abstract.DataModel { required: true }), { - label: 'Type', - initial: 'physical' + label: 'Type' } - ), - resultBased: new fields.BooleanField({ - initial: false, - label: 'DAGGERHEART.ACTIONS.Settings.resultBased.label' - }), - value: new fields.EmbeddedDataField(DHActionDiceData), - valueAlt: new fields.EmbeddedDataField(DHActionDiceData) - }; + ) + } } } diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index a46b0a85..f0176d78 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -1,4 +1,4 @@ -import { DHActionDiceData, DHActionRollData, DHDamageField } from './actionDice.mjs'; +import { DHActionDiceData, DHActionRollData, DHDamageData, DHDamageField, DHResourceData } from './actionDice.mjs'; import DhpActor from '../../documents/actor.mjs'; import D20RollDialog from '../../applications/dialogs/d20RollDialog.mjs'; @@ -96,21 +96,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { onSave: new fields.BooleanField({ initial: false }) }) ), - healing: new fields.SchemaField({ - type: new fields.StringField({ - choices: CONFIG.DH.GENERAL.healingTypes, - required: true, - blank: false, - initial: CONFIG.DH.GENERAL.healingTypes.hitPoints.id, - label: 'Healing' - }), - resultBased: new fields.BooleanField({ - initial: false, - label: 'DAGGERHEART.ACTIONS.Settings.resultBased.label' - }), - value: new fields.EmbeddedDataField(DHActionDiceData), - valueAlt: new fields.EmbeddedDataField(DHActionDiceData) - }), + healing: new fields.EmbeddedDataField(DHResourceData), beastform: new fields.SchemaField({ tierAccess: new fields.SchemaField({ exact: new fields.NumberField({ integer: true, nullable: true, initial: null }) @@ -156,7 +142,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { static getSourceConfig(parent) { const updateSource = {}; updateSource.img ??= parent?.img ?? parent?.system?.img; - if (parent?.type === 'weapon') { + if (parent?.type === 'weapon' && this === game.system.api.models.actions.actionsTypes.attack) { updateSource['damage'] = { includeBase: true }; updateSource['range'] = parent?.system?.attack?.range; updateSource['roll'] = { @@ -177,6 +163,7 @@ export default class DHBaseAction extends foundry.abstract.DataModel { } getRollData(data = {}) { + if(!this.actor) return null; const actorData = this.actor.getRollData(false); // Add Roll results to RollDatas @@ -191,6 +178,8 @@ export default class DHBaseAction extends foundry.abstract.DataModel { } async use(event, ...args) { + if(!this.actor) throw new Error("An Action can't be used outside of an Actor context."); + const isFastForward = event.shiftKey || (!this.hasRoll && !this.hasSave); // Prepare base Config const initConfig = this.initActionConfig(event); @@ -227,7 +216,6 @@ export default class DHBaseAction extends foundry.abstract.DataModel { if (Hooks.call(`${CONFIG.DH.id}.preUseAction`, this, config) === false) return; // Display configuration window if necessary - // if (config.dialog?.configure && this.requireConfigurationDialog(config)) { if (this.requireConfigurationDialog(config)) { config = await D20RollDialog.configure(null, config); if (!config) return; diff --git a/module/data/action/damageAction.mjs b/module/data/action/damageAction.mjs index ccd996f7..13461d30 100644 --- a/module/data/action/damageAction.mjs +++ b/module/data/action/damageAction.mjs @@ -1,3 +1,4 @@ +import { setsEqual } from '../../helpers/utils.mjs'; import DHBaseAction from './baseAction.mjs'; export default class DHDamageAction extends DHBaseAction { @@ -18,28 +19,40 @@ export default class DHDamageAction extends DHBaseAction { return formulaValue; } + formatFormulas(formulas, systemData) { + const formattedFormulas = []; + formulas.forEach(formula => { + if (isNaN(formula.formula)) formula.formula = Roll.replaceFormulaData(formula.formula, this.getRollData(systemData)); + const same = formattedFormulas.find(f => setsEqual(f.damageTypes, formula.damageTypes) && f.applyTo === formula.applyTo); + if(same) + same.formula += ` + ${formula.formula}`; + else + formattedFormulas.push(formula); + }) + return formattedFormulas; + } + async rollDamage(event, data) { const systemData = data.system ?? data; - let formula = this.damage.parts.map(p => this.getFormulaValue(p, data).getFormula(this.actor)).join(' + '), - damageTypes = [...new Set(this.damage.parts.reduce((a, c) => a.concat([...c.type]), []))]; + + let formulas = this.damage.parts.map(p => ({ + formula: this.getFormulaValue(p, data).getFormula(this.actor), + damageTypes: p.applyTo === 'hitPoints' && !p.type.size ? new Set(['physical']) : p.type, + applyTo: p.applyTo + })); - damageTypes = !damageTypes.length ? ['physical'] : damageTypes; + if(!formulas.length) return; - if (!formula || formula == '') return; - let roll = { formula: formula, total: formula }, - bonusDamage = []; - - if (isNaN(formula)) formula = Roll.replaceFormulaData(formula, this.getRollData(systemData)); + formulas = this.formatFormulas(formulas, systemData); const config = { title: game.i18n.format('DAGGERHEART.UI.Chat.damageRoll.title', { damage: this.name }), - roll: { formula }, + roll: formulas, targets: systemData.targets.filter(t => t.hit) ?? data.targets, hasSave: this.hasSave, isCritical: systemData.roll?.isCritical ?? false, source: systemData.source, data: this.getRollData(), - damageTypes, event }; if (this.hasSave) config.onSave = this.save.damageMod; @@ -50,10 +63,6 @@ export default class DHDamageAction extends DHBaseAction { config.directDamage = true; } - roll = CONFIG.Dice.daggerheart.DamageRoll.build(config); + return CONFIG.Dice.daggerheart.DamageRoll.build(config); } - - // get modifiers() { - // return []; - // } } diff --git a/module/data/action/healingAction.mjs b/module/data/action/healingAction.mjs index 4c1366a1..e0a74f27 100644 --- a/module/data/action/healingAction.mjs +++ b/module/data/action/healingAction.mjs @@ -15,25 +15,25 @@ export default class DHHealingAction extends DHBaseAction { } async rollHealing(event, data) { - let formulaValue = this.getFormulaValue(data), - formula = formulaValue.getFormula(this.actor); - - if (!formula || formula == '') return; - let roll = { formula: formula, total: formula }, - bonusDamage = []; - + const systemData = data.system ?? data; + let formulas = [{ + formula: this.getFormulaValue(data).getFormula(this.actor), + applyTo: this.healing.applyTo + }]; + const config = { title: game.i18n.format('DAGGERHEART.UI.Chat.healingRoll.title', { - healing: game.i18n.localize(CONFIG.DH.GENERAL.healingTypes[this.healing.type].label) + healing: game.i18n.localize(CONFIG.DH.GENERAL.healingTypes[this.healing.applyTo].label) }), - roll: { formula }, + roll: formulas, targets: (data.system?.targets ?? data.targets).filter(t => t.hit), messageType: 'healing', - type: this.healing.type, + source: systemData.source, + data: this.getRollData(), event }; - roll = CONFIG.Dice.daggerheart.DamageRoll.build(config); + return CONFIG.Dice.daggerheart.DamageRoll.build(config); } get chatTemplate() { diff --git a/module/data/actor/character.mjs b/module/data/actor/character.mjs index c15d2221..292eedb7 100644 --- a/module/data/actor/character.mjs +++ b/module/data/actor/character.mjs @@ -170,11 +170,10 @@ export default class DhCharacter extends BaseDataActor { rules: new fields.SchemaField({ damageReduction: new fields.SchemaField({ maxArmorMarked: new fields.SchemaField({ - value: new fields.NumberField({ required: true, integer: true, initial: 1 }), - bonus: new fields.NumberField({ + value: new fields.NumberField({ required: true, integer: true, - initial: 0, + initial: 1, label: 'DAGGERHEART.GENERAL.Rules.damageReduction.maxArmorMarkedBonus' }), stressExtra: new fields.NumberField({ diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index 58d45f95..09dd716e 100644 --- a/module/dice/d20Roll.mjs +++ b/module/dice/d20Roll.mjs @@ -140,28 +140,22 @@ export default class D20Roll extends DHRoll { return modifiers; } - static async buildEvaluate(roll, config = {}, message = {}) { - if (config.evaluate !== false) await roll.evaluate(); - - this.postEvaluate(roll, config); - } - static postEvaluate(roll, config = {}) { - super.postEvaluate(roll, config); + const data = super.postEvaluate(roll, config); if (config.targets?.length) { config.targets.forEach(target => { const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion; target.hit = this.isCritical || roll.total >= difficulty; }); } else if (config.roll.difficulty) - config.roll.success = roll.isCritical || roll.total >= config.roll.difficulty; - config.roll.advantage = { + data.success = roll.isCritical || roll.total >= config.roll.difficulty; + data.advantage = { type: config.roll.advantage, dice: roll.dAdvantage?.denomination, value: roll.dAdvantage?.total }; - config.roll.isCritical = roll.isCritical; - config.roll.extra = roll.dice + data.isCritical = roll.isCritical; + data.extra = roll.dice .filter(d => !roll.baseTerms.includes(d)) .map(d => { return { @@ -169,7 +163,8 @@ export default class D20Roll extends DHRoll { value: d.total }; }); - config.roll.modifierTotal = this.calculateTotalModifiers(roll); + data.modifierTotal = this.calculateTotalModifiers(roll); + return data; } resetFormula() { diff --git a/module/dice/damageRoll.mjs b/module/dice/damageRoll.mjs index bfbfc7d5..aa1c4c86 100644 --- a/module/dice/damageRoll.mjs +++ b/module/dice/damageRoll.mjs @@ -10,10 +10,24 @@ export default class DamageRoll extends DHRoll { static DefaultDialog = DamageDialog; - static async postEvaluate(roll, config = {}) { - super.postEvaluate(roll, config); - config.roll.type = config.type; - config.roll.modifierTotal = this.calculateTotalModifiers(roll); + static async buildEvaluate(roll, config = {}, message = {}) { + if ( config.evaluate !== false ) { + for ( const roll of config.roll ) await roll.roll.evaluate(); + } + roll._evaluated = true; + const parts = config.roll.map(r => this.postEvaluate(r)); + config.roll = this.unifyDamageRoll(parts); + } + + static postEvaluate(roll, config = {}) { + return { + ...roll, + ...super.postEvaluate(roll.roll, config), + damageTypes: [...(roll.damageTypes ?? [])], + roll: roll.roll, + type: config.type, + modifierTotal: this.calculateTotalModifiers(roll.roll) + } } static async buildPost(roll, config, message) { @@ -24,12 +38,50 @@ export default class DamageRoll extends DHRoll { } } - applyBaseBonus() { + static unifyDamageRoll(rolls) { + const unified = {}; + rolls.forEach(r => { + const resource = unified[r.applyTo] ?? { formula: '', total: 0, parts: [] }; + resource.formula += `${resource.formula !== '' ? ' + ' : ''}${r.formula}`; + resource.total += r.total; + resource.parts.push(r); + unified[r.applyTo] = resource; + }) + return unified; + } + + static formatGlobal(rolls) { + let formula, total; + const applyTo = new Set(rolls.flatMap(r => r.applyTo)); + if(applyTo.size > 1) { + const data = {}; + rolls.forEach(r => { + if(data[r.applyTo]) { + data[r.applyTo].formula += ` + ${r.formula}` ; + data[r.applyTo].total += r.total ; + } else { + data[r.applyTo] = { + formula: r.formula, + total: r.total + } + } + }); + formula = Object.entries(data).reduce((a, [k,v]) => a + ` ${k}: ${v.formula}`, ''); + total = Object.entries(data).reduce((a, [k,v]) => a + ` ${k}: ${v.total}`, ''); + } else { + formula = rolls.map(r => r.formula).join(' + '); + total = rolls.reduce((a,c) => a + c.total, 0) + } + return {formula, total} + } + + applyBaseBonus(part) { const modifiers = [], - type = this.options.messageType ?? 'damage'; + type = this.options.messageType ?? 'damage', + options = part ?? this.options; modifiers.push(...this.getBonus(`${type}`, `${type.capitalize()} Bonus`)); - this.options.damageTypes?.forEach(t => { + options.damageTypes?.forEach(t => { modifiers.push(...this.getBonus(`${type}.${t}`, `${t.capitalize()} ${type.capitalize()} Bonus`)); }); const weapons = ['primaryWeapon', 'secondaryWeapon']; @@ -42,13 +94,36 @@ export default class DamageRoll extends DHRoll { } constructFormula(config) { - super.constructFormula(config); + this.options.roll.forEach( part => { + part.roll = new Roll(part.formula); + this.constructFormulaPart(config, part) + }) + return this.options.roll; + } - if (config.isCritical) { - const tmpRoll = new Roll(this._formula)._evaluateSync({ maximize: true }), - criticalBonus = tmpRoll.total - this.constructor.calculateTotalModifiers(tmpRoll); - this.terms.push(...this.formatModifier(criticalBonus)); + constructFormulaPart(config, part) { + part.roll.terms = Roll.parse(part.roll.formula, config.data); + + if(part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) { + part.modifiers = this.applyBaseBonus(part); + this.addModifiers(part); + part.modifiers?.forEach(m => { + part.roll.terms.push(...this.formatModifier(m.value)); + }); } - return (this._formula = this.constructor.getFormula(this.terms)); + + if (part.extraFormula) { + part.roll.terms.push( + new foundry.dice.terms.OperatorTerm({ operator: '+' }), + ...this.constructor.parse(part.extraFormula, this.options.data) + ); + } + + if (config.isCritical && part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) { + const tmpRoll = Roll.fromTerms(part.roll.terms)._evaluateSync({ maximize: true }), + criticalBonus = tmpRoll.total - this.constructor.calculateTotalModifiers(tmpRoll); + part.roll.terms.push(...this.formatModifier(criticalBonus)); + } + return (part.roll._formula = this.constructor.getFormula(part.roll.terms)); } } diff --git a/module/dice/dhRoll.mjs b/module/dice/dhRoll.mjs index 33de251b..cb1007e3 100644 --- a/module/dice/dhRoll.mjs +++ b/module/dice/dhRoll.mjs @@ -47,7 +47,7 @@ export default class DHRoll extends Roll { static async buildEvaluate(roll, config = {}, message = {}) { if (config.evaluate !== false) await roll.evaluate(); - this.postEvaluate(roll, config); + config.roll = this.postEvaluate(roll, config); } static async buildPost(roll, config, message) { @@ -57,25 +57,26 @@ export default class DHRoll extends Roll { // Create Chat Message if (config.source?.message) { + if(Object.values(config.roll)?.length) { + const pool = foundry.dice.terms.PoolTerm.fromRolls(Object.values(config.roll).flatMap(r => r.parts.map(p => p.roll))); + roll = Roll.fromTerms([pool]); + } if (game.modules.get('dice-so-nice')?.active) await game.dice3d.showForRoll(roll, game.user, true); - } else { + } else config.message = await this.toMessage(roll, config); - } } static postEvaluate(roll, config = {}) { - if (!config.roll) config.roll = {}; - config.roll.total = roll.total; - config.roll.formula = roll.formula; - config.roll.dice = []; - roll.dice.forEach(d => { - config.roll.dice.push({ + return { + total: roll.total, + formula: roll.formula, + dice: roll.dice.map(d => ({ dice: d.denomination, total: d.total, formula: d.formula, results: d.results - }); - }); + })) + } } static async toMessage(roll, config) { @@ -118,8 +119,9 @@ export default class DHRoll extends Roll { return []; } - addModifiers() { - this.options.roll.modifiers?.forEach(m => { + addModifiers(roll) { + roll = roll ?? this.options.roll; + roll.modifiers?.forEach(m => { this.terms.push(...this.formatModifier(m.value)); }); } diff --git a/module/dice/dualityRoll.mjs b/module/dice/dualityRoll.mjs index 5fd71e6c..e36d2427 100644 --- a/module/dice/dualityRoll.mjs +++ b/module/dice/dualityRoll.mjs @@ -161,21 +161,21 @@ export default class DualityRoll extends D20Roll { } static postEvaluate(roll, config = {}) { - super.postEvaluate(roll, config); + const data = super.postEvaluate(roll, config); - config.roll.hope = { + data.hope = { dice: roll.dHope.denomination, value: roll.dHope.total }; - config.roll.fear = { + data.fear = { dice: roll.dFear.denomination, value: roll.dFear.total }; - config.roll.rally = { + data.rally = { dice: roll.dRally?.denomination, value: roll.dRally?.total }; - config.roll.result = { + data.result = { duality: roll.withHope ? 1 : roll.withFear ? -1 : 0, total: roll.dHope.total + roll.dFear.total, label: roll.totalLabel @@ -184,6 +184,8 @@ export default class DualityRoll extends D20Roll { if(roll._rallyIndex && roll.data?.parent) roll.data.parent.deleteEmbeddedDocuments('ActiveEffect', [roll._rallyIndex]); - setDiceSoNiceForDualityRoll(roll, config.roll.advantage.type); + setDiceSoNiceForDualityRoll(roll, data.advantage.type); + + return data; } } diff --git a/module/documents/actor.mjs b/module/documents/actor.mjs index 73a8a3db..e6ae781a 100644 --- a/module/documents/actor.mjs +++ b/module/documents/actor.mjs @@ -391,59 +391,70 @@ export default class DhpActor extends Actor { return canUseArmor || canUseStress; } - async takeDamage(baseDamage, type) { - if (Hooks.call(`${CONFIG.DH.id}.preTakeDamage`, this, baseDamage, type) === false) return null; + async takeDamage(damages) { + if (Hooks.call(`${CONFIG.DH.id}.preTakeDamage`, this, damages) === false) return null; if (this.type === 'companion') { await this.modifyResource([{ value: 1, key: 'stress' }]); return; } - type = !Array.isArray(type) ? [type] : type; + const updates = []; - const hpDamage = this.calculateDamage(baseDamage, type); + Object.entries(damages).forEach(([key, damage]) => { + damage.parts.forEach(part => { + if(part.applyTo === CONFIG.DH.GENERAL.healingTypes.hitPoints.id) + part.total = this.calculateDamage(part.total, part.damageTypes); + const update = updates.find(u => u.key === key); + if(update) { + update.value += part.total; + update.damageTypes.add(...new Set(part.damageTypes)); + } else updates.push({ value: part.total, key, damageTypes: new Set(part.damageTypes) }) + }) + }); - if (!hpDamage) return; + if (Hooks.call(`${CONFIG.DH.id}.postCalculateDamage`, this, damages) === false) return null; - const updates = [{ value: hpDamage, type: 'hitPoints' }]; + if(!updates.length) return; - if (this.type === 'character' && this.system.armor && this.#canReduceDamage(hpDamage, type)) { - const armorStackResult = await this.owner.query('armorStack', { - actorId: this.uuid, - damage: hpDamage, - type: type - }); - if (armorStackResult) { - const { modifiedDamage, armorSpent, stressSpent } = armorStackResult; - updates.find(u => u.type === 'hitPoints').value = modifiedDamage; - updates.push( - ...(armorSpent ? [{ value: armorSpent, key: 'armorStack' }] : []), - ...(stressSpent ? [{ value: stressSpent, key: 'stress' }] : []) - ); + const hpDamage = updates.find(u => u.key === CONFIG.DH.GENERAL.healingTypes.hitPoints.id); + if(hpDamage) { + hpDamage.value = this.convertDamageToThreshold(hpDamage.value); + if (this.type === 'character' && this.system.armor && this.#canReduceDamage(hpDamage.value, hpDamage.damageTypes)) { + const armorStackResult = await this.owner.query('armorStack', { + actorId: this.uuid, + damage: hpDamage.value, + type: [...hpDamage.damageTypes] + }); + if (armorStackResult) { + const { modifiedDamage, armorSpent, stressSpent } = armorStackResult; + updates.find(u => u.key === 'hitPoints').value = modifiedDamage; + updates.push( + ...(armorSpent ? [{ value: armorSpent, key: 'armorStack' }] : []), + ...(stressSpent ? [{ value: stressSpent, key: 'stress' }] : []) + ); + } } } - + + updates.forEach( u => + u.value = u.key === 'fear' || this.system?.resources?.[u.key]?.isReversed === false ? u.value * -1 : u.value + ); + await this.modifyResource(updates); - if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, damage, type) === false) return null; + if (Hooks.call(`${CONFIG.DH.id}.postTakeDamage`, this, damages) === false) return null; } calculateDamage(baseDamage, type) { - if (Hooks.call(`${CONFIG.DH.id}.preCalculateDamage`, this, baseDamage, type) === false) return null; - /* if(this.system.resistance[type]?.immunity) return 0; - if(this.system.resistance[type]?.resistance) baseDamage = Math.ceil(baseDamage / 2); */ if (this.canResist(type, 'immunity')) return 0; if (this.canResist(type, 'resistance')) baseDamage = Math.ceil(baseDamage / 2); - // const flatReduction = this.system.resistance[type].reduction; const flatReduction = this.getDamageTypeReduction(type); const damage = Math.max(baseDamage - (flatReduction ?? 0), 0); - const hpDamage = this.convertDamageToThreshold(damage); - if (Hooks.call(`${CONFIG.DH.id}.postCalculateDamage`, this, baseDamage, type) === false) return null; - - return hpDamage; + return damage; } canResist(type, resistance) { @@ -461,8 +472,13 @@ export default class DhpActor extends Actor { } async takeHealing(resources) { - resources.forEach(r => (r.value *= -1)); - await this.modifyResource(resources); + const updates = Object.entries(resources).map(([key, value]) => ( + { + key: key, + value: !(key === 'fear' || this.system?.resources?.[key]?.isReversed === false) ? value.total * -1 : value.total + } + )) + await this.modifyResource(updates); } async modifyResource(resources) { diff --git a/module/documents/token.mjs b/module/documents/token.mjs index 89305128..f48af563 100644 --- a/module/documents/token.mjs +++ b/module/documents/token.mjs @@ -16,7 +16,7 @@ export default class DHToken extends TokenDocument { }); bars.sort((a, b) => a.label.compare(b.label)); - const invalidAttributes = ['gold', 'levelData', 'actions', 'rules.damageReduction.maxArmorMarked.value']; + const invalidAttributes = ['gold', 'levelData', 'actions']; const values = attributes.value.reduce((acc, v) => { const a = v.join('.'); if (invalidAttributes.some(x => a.startsWith(x))) return acc; diff --git a/module/helpers/utils.mjs b/module/helpers/utils.mjs index 336ecf5b..91671e36 100644 --- a/module/helpers/utils.mjs +++ b/module/helpers/utils.mjs @@ -311,3 +311,15 @@ export const itemAbleRollParse = (value, actor, item) => { return ''; } }; + +export const arraysEqual = (a, b) => + a.length === b.length && + [...new Set([...a, ...b])].every( + v => a.filter(e => e === v).length === b.filter(e => e === v).length + ); + +export const setsEqual = (a, b) => + a.size === b.size && + [...a].every( + value => b.has(value) + ); \ No newline at end of file diff --git a/styles/less/global/dialog.less b/styles/less/global/dialog.less index 11a4eee9..8c86e825 100644 --- a/styles/less/global/dialog.less +++ b/styles/less/global/dialog.less @@ -56,4 +56,15 @@ color: light-dark(@dark, @beige); } + + .damage-formula { + display: flex; + justify-content: space-between; + .damage-details { + font-style: italic; + display: flex; + align-items: center; + gap: 5px; + } + } } diff --git a/styles/less/global/elements.less b/styles/less/global/elements.less index 9d38e386..b9509b38 100755 --- a/styles/less/global/elements.less +++ b/styles/less/global/elements.less @@ -109,7 +109,7 @@ height: 34px; .tags { justify-content: flex-start; - margin: 5px; + margin: 4px; height: inherit; .tag { padding: 0.3rem 0.5rem; diff --git a/styles/less/ui/chat/chat.less b/styles/less/ui/chat/chat.less index 12e8ba0c..6b5db1b9 100644 --- a/styles/less/ui/chat/chat.less +++ b/styles/less/ui/chat/chat.less @@ -164,6 +164,11 @@ } } } + + .damage-resource { + font-weight: 600; + margin-top: 5px; + } } .dice-total { diff --git a/templates/actionTypes/damage.hbs b/templates/actionTypes/damage.hbs index 3c125bd7..bfbbc592 100644 --- a/templates/actionTypes/damage.hbs +++ b/templates/actionTypes/damage.hbs @@ -22,7 +22,12 @@ {{formField ../fields.value.fields.bonus value=dmg.value.bonus name=(concat ../path "damage.parts." index ".value.bonus") localize=true classes="inline-child"}} {{/if}} - {{formField ../fields.type value=dmg.type name=(concat ../path "damage.parts." index ".type") localize=true}} +
+ {{formField ../fields.applyTo value=dmg.applyTo name=(concat ../path "damage.parts." realIndex ".applyTo") localize=true}} + {{#if (eq dmg.applyTo 'hitPoints')}} + {{formField ../fields.type value=dmg.type name=(concat ../path "damage.parts." index ".type") localize=true}} + {{/if}} +
{{#if ../horde}}
{{localize "DAGGERHEART.ACTORS.Adversary.hordeDamage"}} @@ -56,7 +61,12 @@ {{> formula fields=../../fields.value.fields type=../fields.type dmg=dmg source=dmg.value target="value" realIndex=realIndex}}
{{/if}} - {{formField ../../fields.type value=dmg.type name=(concat "damage.parts." realIndex ".type") localize=true}} +
+ {{formField ../../fields.applyTo value=dmg.applyTo name=(concat "damage.parts." realIndex ".applyTo") localize=true}} + {{#if (eq dmg.applyTo 'hitPoints')}} + {{formField ../../fields.type value=dmg.type name=(concat "damage.parts." realIndex ".type") localize=true}} + {{/if}} +
{{#unless dmg.base}}
{{/unless}} diff --git a/templates/actionTypes/healing.hbs b/templates/actionTypes/healing.hbs index 5bf46f7a..4b095174 100644 --- a/templates/actionTypes/healing.hbs +++ b/templates/actionTypes/healing.hbs @@ -1,43 +1,41 @@ -
- -
Healing
+
+ + {{localize "DAGGERHEART.GENERAL.healing"}} -
-
- {{formField fields.type value=source.type name="healing.type" localize=true}} - {{#if (and (not @root.isNPC) @root.hasRoll)}} - {{formField fields.resultBased value=source.resultBased name="healing.resultBased" localize=true}} - {{/if}} - {{#if (and (not @root.isNPC) @root.hasRoll source.resultBased)}} -
- -
With Hope
-
- {{> formula fields=fields.value.fields source=source.value target="value"}} -
-
- -
With Fear
-
- {{> formula fields=fields.valueAlt.fields source=source.valueAlt target="valueAlt"}} -
- {{else}} + {{#if (and (not @root.isNPC) @root.hasRoll)}} + {{formField fields.resultBased value=source.resultBased name="healing.resultBased" localize=true classes="checkbox"}} + {{/if}} + {{#if (and (not @root.isNPC) @root.hasRoll source.resultBased)}} +
+
+ +
With Hope
+
{{> formula fields=fields.value.fields source=source.value target="value"}} - {{/if}} -
-
+
+
+ +
With Fear
+
+ {{> formula fields=fields.valueAlt.fields source=source.valueAlt target="valueAlt"}} +
+
+ {{else}} + {{> formula fields=fields.value.fields source=source.value target="value"}} + {{/if}} + {{formField fields.applyTo value=source.type name="healing.applyTo" localize=true}}
{{#*inline "formula"}} -
- {{formField fields.custom.fields.enabled value=source.custom.enabled name=(concat "healing." target ".custom.enabled")}} - {{#if source.custom.enabled}} - {{formField fields.custom.fields.formula value=source.custom.formula name=(concat "healing." target ".custom.formula") localize=true}} - {{else}} + {{formField fields.custom.fields.enabled value=source.custom.enabled name=(concat "healing." target ".custom.enabled") classes="checkbox"}} + {{#if source.custom.enabled}} + {{formField fields.custom.fields.formula value=source.custom.formula name=(concat "healing." target ".custom.formula") localize=true}} + {{else}} +
{{formField fields.multiplier value=source.multiplier name=(concat "healing." target ".multiplier") localize=true}} {{formField fields.dice value=source.dice name=(concat "healing." target ".dice")}} {{formField fields.bonus value=source.bonus name=(concat "healing." target ".bonus") localize=true}} - {{/if}} -
+
+ {{/if}} {{/inline}} \ No newline at end of file diff --git a/templates/dialogs/dice-roll/damageSelection.hbs b/templates/dialogs/dice-roll/damageSelection.hbs index bd97cfdf..3e47cf68 100644 --- a/templates/dialogs/dice-roll/damageSelection.hbs +++ b/templates/dialogs/dice-roll/damageSelection.hbs @@ -2,10 +2,26 @@

{{title}}

- Formula: {{@root.formula}} -
- -
+ {{#each @root.formula}} +
+ Formula: {{roll.formula}} + + {{#with (lookup @root.config.GENERAL.healingTypes applyTo)}} + {{localize label}} + {{/with}} + {{#if damageTypes}} + {{#each damageTypes as | type | }} + {{#with (lookup @root.config.GENERAL.damageTypes type)}} + + {{/with}} + {{/each}} + {{/if}} + +
+
+ +
+ {{/each}}
{{#if directDamage}} - - - + {{#each document.system.potentialAdversaries as |category categoryId|}} +
+ {{category.label}} +
+ + + + +
+
+ {{#each category.adversaries as |adversary|}} +
+ {{> 'daggerheart.inventory-item' + item=adversary + type='adversary' + isActor=true + categoryAdversary=categoryId + }}
-
- {{#each category.adversaries as |adversary|}} -
- {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=adversary type='adversary' isActor=true categoryAdversary=@../key}} -
- {{/each}} -
-
- Drop Actors here -
-
+ {{/each}} +
+
+ Drop Actors here +
+
{{/each}} \ No newline at end of file diff --git a/templates/sheets-settings/environment-settings/features.hbs b/templates/sheets-settings/environment-settings/features.hbs index f232dae9..aab68309 100644 --- a/templates/sheets-settings/environment-settings/features.hbs +++ b/templates/sheets-settings/environment-settings/features.hbs @@ -16,8 +16,8 @@ {{feature.name}}
- - + +
{{/each}} diff --git a/templates/sheets/actors/adversary/effects.hbs b/templates/sheets/actors/adversary/effects.hbs index 3d378802..325610e6 100644 --- a/templates/sheets/actors/adversary/effects.hbs +++ b/templates/sheets/actors/adversary/effects.hbs @@ -1,8 +1,20 @@ -
- {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.activeEffects') type='effect'}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.inactiveEffects') type='effect'}} +
+ {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.activeEffects' + type='effect' + isGlassy=true + collection=effects.actives + canCreate=true + hideResources=true + }} + + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.inactiveEffects' + type='effect' + isGlassy=true + collection=effects.inactives + canCreate=true + hideResources=true + }}
\ No newline at end of file diff --git a/templates/sheets/actors/adversary/features.hbs b/templates/sheets/actors/adversary/features.hbs index 1a8d918e..e5a304ef 100644 --- a/templates/sheets/actors/adversary/features.hbs +++ b/templates/sheets/actors/adversary/features.hbs @@ -1,9 +1,13 @@ -
+
- {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize tabs.features.label) type='feature' values=document.system.features hideControls=true}} + {{> 'daggerheart.inventory-items' + title=tabs.features.label + type='feature' + collection=document.system.features + hideControls=true + canCreate=true + showActions=true + }}
\ No newline at end of file diff --git a/templates/sheets/actors/adversary/header.hbs b/templates/sheets/actors/adversary/header.hbs index 28c0d002..fd6389aa 100644 --- a/templates/sheets/actors/adversary/header.hbs +++ b/templates/sheets/actors/adversary/header.hbs @@ -27,7 +27,7 @@
- {{{source.system.description}}} + {{{description}}}
{{localize 'DAGGERHEART.ACTORS.Adversary.FIELDS.motivesAndTactics.label'}}: {{{source.system.motivesAndTactics}}} diff --git a/templates/sheets/actors/adversary/notes.hbs b/templates/sheets/actors/adversary/notes.hbs index effa7240..a2378516 100644 --- a/templates/sheets/actors/adversary/notes.hbs +++ b/templates/sheets/actors/adversary/notes.hbs @@ -5,6 +5,6 @@ >
{{localize tabs.notes.label}} - {{formInput systemFields.notes value=document.system.notes enriched=document.system.notes localize=true toggled=true}} + {{formInput notes.field value=notes.value enriched=notes.enriched toggled=true}}
\ No newline at end of file diff --git a/templates/sheets/actors/adversary/sidebar.hbs b/templates/sheets/actors/adversary/sidebar.hbs index 5384504e..8eb4dcb0 100644 --- a/templates/sheets/actors/adversary/sidebar.hbs +++ b/templates/sheets/actors/adversary/sidebar.hbs @@ -1,111 +1,118 @@ \ No newline at end of file diff --git a/templates/sheets/actors/character/biography.hbs b/templates/sheets/actors/character/biography.hbs index 34313def..6913f279 100644 --- a/templates/sheets/actors/character/biography.hbs +++ b/templates/sheets/actors/character/biography.hbs @@ -26,11 +26,11 @@
{{localize 'DAGGERHEART.ACTORS.Character.story.backgroundTitle'}} - {{formInput systemFields.biography.fields.background value=source.system.biography.background enriched=source.system.biography.background localize=true toggled=true}} + {{formInput background.field value=background.value enriched=background.enriched toggled=true}}
{{localize 'DAGGERHEART.ACTORS.Character.story.connectionsTitle'}} - {{formInput systemFields.biography.fields.connections value=source.system.biography.connections enriched=source.system.biography.connections localize=true toggled=true}} + {{formInput connections.field value=connections.value enriched=connections.enriched toggled=true}}
\ No newline at end of file diff --git a/templates/sheets/actors/character/effects.hbs b/templates/sheets/actors/character/effects.hbs index 3d378802..4c4fca27 100644 --- a/templates/sheets/actors/character/effects.hbs +++ b/templates/sheets/actors/character/effects.hbs @@ -1,8 +1,21 @@ -
- {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.activeEffects') type='effect'}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.inactiveEffects') type='effect'}} +
+ + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.activeEffects' + type='effect' + isGlassy=true + collection=effects.actives + canCreate=true + hideResources=true + }} + + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.inactiveEffects' + type='effect' + isGlassy=true + collection=effects.inactives + canCreate=true + hideResources=true + }}
\ No newline at end of file diff --git a/templates/sheets/actors/character/features.hbs b/templates/sheets/actors/character/features.hbs index 7fab5263..acabd37e 100644 --- a/templates/sheets/actors/character/features.hbs +++ b/templates/sheets/actors/character/features.hbs @@ -1,13 +1,25 @@ -
+
- {{#each document.system.sheetLists}} - {{#if this.values}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=this.title values=this.values}} - {{/if}} + {{#each document.system.sheetLists as |category|}} + {{#if (eq category.type 'feature' )}} + {{> 'daggerheart.inventory-items' + title=category.title + type='feature' + collection=category.values + canCreate=true + showActions=true + }} + {{else if category.values}} + {{> 'daggerheart.inventory-items' + title=category.title + type='feature' + collection=category.values + canCreate=false + showActions=true + }} + + {{/if}} {{/each}}
\ No newline at end of file diff --git a/templates/sheets/actors/character/header.hbs b/templates/sheets/actors/character/header.hbs index 18e791d1..9e930fd6 100644 --- a/templates/sheets/actors/character/header.hbs +++ b/templates/sheets/actors/character/header.hbs @@ -29,25 +29,25 @@
{{#if document.system.class.value}} - {{document.system.class.value.name}} + {{document.system.class.value.name}} {{else}} {{localize 'TYPES.Item.class'}} {{/if}} {{#if document.system.class.subclass}} - {{document.system.class.subclass.name}} + {{document.system.class.subclass.name}} {{else}} {{localize 'TYPES.Item.subclass'}} {{/if}} {{#if document.system.community}} - {{document.system.community.name}} + {{document.system.community.name}} {{else}} {{localize 'TYPES.Item.community'}} {{/if}} {{#if document.system.ancestry}} - {{document.system.ancestry.name}} + {{document.system.ancestry.name}} {{else}} {{localize 'TYPES.Item.ancestry'}} {{/if}} @@ -56,13 +56,13 @@ {{#if document.system.multiclass.value}}
{{#if document.system.multiclass.value}} - {{document.system.multiclass.value.name}} + {{document.system.multiclass.value.name}} {{else}} {{localize 'DAGGERHEART.GENERAL.multiclass'}} {{/if}} {{#if document.system.multiclass.subclass}} - {{document.system.multiclass.subclass.name}} + {{document.system.multiclass.subclass.name}} {{else}} {{localize 'TYPES.Item.subclass'}} {{/if}} diff --git a/templates/sheets/actors/character/inventory.hbs b/templates/sheets/actors/character/inventory.hbs index be8bb251..9610d8e2 100644 --- a/templates/sheets/actors/character/inventory.hbs +++ b/templates/sheets/actors/character/inventory.hbs @@ -1,8 +1,5 @@ -
+
\ No newline at end of file diff --git a/templates/sheets/actors/character/loadout.hbs b/templates/sheets/actors/character/loadout.hbs index 5a1d675e..0319d56f 100644 --- a/templates/sheets/actors/character/loadout.hbs +++ b/templates/sheets/actors/character/loadout.hbs @@ -10,28 +10,33 @@ -
- {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' - title=(localize 'DAGGERHEART.GENERAL.Tabs.loadout') + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.Tabs.loadout' type='domainCard' isGlassy=true - cardView=(ifThen listView "list" "card")}} - - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' - title=(localize 'DAGGERHEART.GENERAL.Tabs.vault') + cardView=cardView + collection=document.system.domainCards.loadout + canCreate=true + }} + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.Tabs.vault' type='domainCard' - isVault=true isGlassy=true - cardView=(ifThen listView "list" "card")}} + cardView=cardView + collection=document.system.domainCards.vault + canCreate=true + inVault=true + }}
\ No newline at end of file diff --git a/templates/sheets/actors/character/sidebar.hbs b/templates/sheets/actors/character/sidebar.hbs index 51816443..553ba246 100644 --- a/templates/sheets/actors/character/sidebar.hbs +++ b/templates/sheets/actors/character/sidebar.hbs @@ -1,14 +1,16 @@
\ No newline at end of file diff --git a/templates/sheets/actors/companion/effects.hbs b/templates/sheets/actors/companion/effects.hbs index 3d378802..325610e6 100644 --- a/templates/sheets/actors/companion/effects.hbs +++ b/templates/sheets/actors/companion/effects.hbs @@ -1,8 +1,20 @@ -
- {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.activeEffects') type='effect'}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize 'DAGGERHEART.GENERAL.inactiveEffects') type='effect'}} +
+ {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.activeEffects' + type='effect' + isGlassy=true + collection=effects.actives + canCreate=true + hideResources=true + }} + + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.inactiveEffects' + type='effect' + isGlassy=true + collection=effects.inactives + canCreate=true + hideResources=true + }}
\ No newline at end of file diff --git a/templates/sheets/actors/environment/features.hbs b/templates/sheets/actors/environment/features.hbs index 6697e42c..d7f10d56 100644 --- a/templates/sheets/actors/environment/features.hbs +++ b/templates/sheets/actors/environment/features.hbs @@ -4,6 +4,13 @@ data-group='{{tabs.features.group}}' >
- {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=(localize tabs.features.label) type='feature' values=document.system.features hideControls=true }} + {{> 'daggerheart.inventory-items' + title=tabs.features.label + type='feature' + collection=document.system.features + hideControls=true + canCreate=true + showActions=true + }}
\ No newline at end of file diff --git a/templates/sheets/actors/environment/header.hbs b/templates/sheets/actors/environment/header.hbs index e9921bae..fff55144 100644 --- a/templates/sheets/actors/environment/header.hbs +++ b/templates/sheets/actors/environment/header.hbs @@ -34,7 +34,7 @@
- {{{source.system.description}}} + {{{description}}}
{{localize 'DAGGERHEART.ACTORS.Environment.FIELDS.impulses.label'}}: {{{source.system.impulses}}} diff --git a/templates/sheets/actors/environment/notes.hbs b/templates/sheets/actors/environment/notes.hbs index effa7240..663a484a 100644 --- a/templates/sheets/actors/environment/notes.hbs +++ b/templates/sheets/actors/environment/notes.hbs @@ -5,6 +5,6 @@ >
{{localize tabs.notes.label}} - {{formInput systemFields.notes value=document.system.notes enriched=document.system.notes localize=true toggled=true}} + {{formInput notes.field value=notes.value enriched=notes.value toggled=true}}
\ No newline at end of file diff --git a/templates/sheets/actors/environment/potentialAdversaries.hbs b/templates/sheets/actors/environment/potentialAdversaries.hbs index f39a1adf..cc246312 100644 --- a/templates/sheets/actors/environment/potentialAdversaries.hbs +++ b/templates/sheets/actors/environment/potentialAdversaries.hbs @@ -4,8 +4,17 @@ data-group='{{tabs.potentialAdversaries.group}}' >
- {{#each document.system.potentialAdversaries}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-fieldset-items.hbs' title=this.label type='adversary' isGlassy=true adversaries=this.adversaries}} + {{#each document.system.potentialAdversaries as |category categoryId|}} + {{> 'daggerheart.inventory-items' + title=category.label + type='adversary' + isGlassy=true + isActor=true + categoryAdversary=categoryId + hideControls=true + collection=category.adversaries + hideResources=true + }} {{/each}}
\ No newline at end of file diff --git a/templates/sheets/global/partials/domain-card-item.hbs b/templates/sheets/global/partials/domain-card-item.hbs index 0ff7e8f5..37d6a0e2 100644 --- a/templates/sheets/global/partials/domain-card-item.hbs +++ b/templates/sheets/global/partials/domain-card-item.hbs @@ -1,34 +1,22 @@ -
  • +
  • -
  • +
  • {{feature.name}}

    {{#unless hideContrals}} - + {{/unless}}
  • \ No newline at end of file diff --git a/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs b/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs new file mode 100644 index 00000000..aa58aad8 --- /dev/null +++ b/templates/sheets/global/partials/inventory-fieldset-items-V2.hbs @@ -0,0 +1,70 @@ +{{!-- +Inventory/Domain Card Section + +{{> 'daggerheart.inventory-items' }} + +Parameters: +- title {string} : Localization key used for the legend. +- collection {array} : Array of items to render. +- type {string} : The type of items in the list: +- isGlassy {boolean} : If true, applies the 'glassy' class to the fieldset. +- cardView {boolean} : If true and type is 'domainCard', renders using domain card layout. +- isActor {boolean} : Passed through to inventory-item partials. +- canCreate {boolean} : If true, show createDoc anchor on legend +- inVault {boolean} : If true, the domainCard is created with inVault=true +- disabled {boolean}: If true, the ActiveEffect is created with disabled=true; +- categoryAdversary {string} : Category adversary id. +- showLabels {boolean} : If true, show label-tags else show simple tags. +- hideTooltip {boolean} : If true, disables the tooltip on the item image. +- hideControls {boolean} : If true, hides the controls inside inventory-item partials. +- hideDescription {boolean} : If true, hides the item's description. +- hideResources {boolean} : If true, hides the item's resources. +- showActions {boolean} : If true show feature's actions. +--}} + +
    + + {{localize title}} + {{#if canCreate}} + + + + {{/if }} + + {{#if (and cardView (eq type 'domainCard'))}} +
      + {{#each collection as |item|}} + + {{> 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs' + item=item + type='domainCard' + }} + + {{/each}} +
    + {{else}} +
      + {{#each collection as |item|}} + + {{> 'daggerheart.inventory-item' + item=item + type=../type + hideControls=../hideControls + isActor=../isActor + categoryAdversary=../categoryAdversary + hideTooltip=../hideTooltip + showLabels=../showLabels + isAction=../isAction + hideResources=../hideResources + showActions=../showActions + }} + + {{/each}} +
    + {{/if}} +
    \ No newline at end of file diff --git a/templates/sheets/global/partials/inventory-fieldset-items.hbs b/templates/sheets/global/partials/inventory-fieldset-items.hbs deleted file mode 100644 index 65c52736..00000000 --- a/templates/sheets/global/partials/inventory-fieldset-items.hbs +++ /dev/null @@ -1,44 +0,0 @@ -
    - {{title}} -
      - {{#unless (eq cardView 'card') }} - {{#if (or (eq type 'domainCard') (eq type 'armor') (eq type 'consumable') (eq type 'miscellaneous') (eq type 'weapon'))}} - {{#each document.items as |item|}} - {{#if (eq item.type ../type)}} - {{#unless (and (eq ../type 'domainCard') (or (and item.system.inVault (not ../isVault)) (and (not item.system.inVault) ../isVault)))}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=item type=../type}} - {{/unless}} - {{/if}} - {{/each}} - {{else}} - {{#if (eq type 'effect')}} - {{#each document.effects as |effect|}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=effect type=../type}} - {{/each}} - {{else}} - {{#each values}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=this type=../type hideControls=../hideControls featureType=true }} - {{/each}} - - {{#each adversaries as |adversary|}} - {{> 'systems/daggerheart/templates/sheets/global/partials/inventory-item.hbs' item=adversary type='adversary' hideControls=true isActor=true categoryAdversary=@../key}} - {{/each}} - {{/if}} - {{/if}} - {{/unless}} - -
    - {{#if (and (eq cardView 'card') (eq type 'domainCard'))}} -
      - {{#if isVault}} - {{#each document.system.domainCards.vault as |card|}} - {{> 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs' item=card type=../type}} - {{/each}} - {{else}} - {{#each document.system.domainCards.loadout as |card|}} - {{> 'systems/daggerheart/templates/sheets/global/partials/domain-card-item.hbs' item=card type=../type}} - {{/each}} - {{/if}} -
    - {{/if}} -
    \ No newline at end of file diff --git a/templates/sheets/global/partials/inventory-item-V2.hbs b/templates/sheets/global/partials/inventory-item-V2.hbs new file mode 100644 index 00000000..5329e7b5 --- /dev/null +++ b/templates/sheets/global/partials/inventory-item-V2.hbs @@ -0,0 +1,239 @@ +{{!-- +{{> 'daggerheart.inventory-item' }} + +Parameters: +- type {string} : The type of items in the list +- isActor {boolean} : Passed through to inventory-item partials. +- categoryAdversary {string} : Category adversary id. +- noExtensible {boolean} : If true, the inventory-item-content would be collapsable/extendible else it always be showed +- hideLabels {boolean} : If true, hide label-tags else show label-tags. +- hideTags {boolean} : If true, hide simple-tags else show simple-tags. +- hideTooltip {boolean} : If true, disables the tooltip on the item image. +- hideControls {boolean} : If true, hides the controls inside inventory-item partials. +- hideDescription {boolean} : If true, hides the item's description. +- hideResources {boolean} : If true, hides the item's resources. +- showActions {boolean} : If true show feature's actions. +--}} + +
  • +
    + {{!-- Image --}} +
    + + d20 +
    + + {{!-- Name & Tags --}} +
    + + {{!-- Item Name --}} +
    {{item.name}}
    + + {{!-- Weapon Block Start --}} + {{#if (eq type 'weapon')}} + {{#if (not hideTags)}} +
    +
    + {{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.name')}} +
    +
    + {{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.name')}} +
    +
    + {{item.system.attack.damage.parts.0.value.dice}} + {{#if item.system.attack.damage.parts.0.value.bonus}} + + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} + ( + {{#each item.system.attack.damage.parts.0.type as |type|}} + + {{localize (concat 'DAGGERHEART.CONFIG.DamageType.' type '.abbreviation')}} + {{#unless @last}}|{{/unless}} + {{/each}} + ) + +
    +
    + {{localize (concat 'DAGGERHEART.CONFIG.Burden.' item.system.burden)}} +
    +
    + {{else if (not hideLabels)}} +
    +
    + {{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.short')}} + {{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.short')}} + - + {{item.system.attack.damage.parts.0.value.dice}} + {{#if item.system.attack.damage.parts.0.value.bonus}} + + {{item.system.attack.damage.parts.0.value.bonus}} + {{/if}} + {{#with (lookup @root.config.GENERAL.damageTypes item.system.attack.damage.parts.0.type)}} + {{#each icon}}{{/each}} + {{/with}} +
    +
    + {{/if}} + {{/if}} + {{!-- Weapon Block End --}} + + {{!-- Armor Block Start --}} + {{#if (eq type 'armor')}} + {{#if (not hideTags)}} +
    +
    {{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: {{item.system.baseScore}}
    +
    + {{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.base"}}: + {{item.system.baseThresholds.major}} / {{item.system.baseThresholds.severe}} +
    +
    + {{else if (not hideLabels)}} +
    +
    + {{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: {{item.system.baseScore}} +
    +
    + {{/if}} + {{/if}} + {{!-- Armor Block End --}} + + {{!-- Domain Card Block Start --}} + {{#if (eq type 'domainCard')}} + {{#if (not hideTags)}} +
    +
    {{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}}
    +
    {{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}}
    +
    + {{localize "DAGGERHEART.ITEMS.DomainCard.recallCost"}}: + {{item.system.recallCost}} +
    +
    + {{else if (not hideLabels)}} +
    +
    + {{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}} - + {{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}} - + {{item.system.recallCost}} + +
    +
    + {{/if}} + {{/if}} + {{!-- Domain Card Block End --}} + + {{!-- Effect Block Start --}} + {{#if (eq type 'effect')}} + {{#if (not hideTags)}} +
    +
    + {{localize item.parent.system.metadata.label}}: {{item.parent.name}} +
    +
    + {{#if item.duration.duration}} + {{localize 'DAGGERHEART.EFFECTS.Duration.temporary'}} + {{else}} + {{localize 'DAGGERHEART.EFFECTS.Duration.passive'}} + {{/if}} +
    + {{#each item.statuses as |status|}} +
    {{localize (concat 'DAGGERHEART.CONFIG.Condition.' status '.name')}}
    + {{/each}} +
    + {{else if (not hideLabels)}} + {{!-- Empty --}} + {{/if}} + {{/if}} + {{!-- Effect Block End --}} + + {{!-- Action Block Start --}} + {{#if (eq type 'action')}} + {{#if (not hideTags)}} +
    +
    {{localize (concat 'DAGGERHEART.ACTIONS.TYPES.' item.type '.name')}}
    +
    {{localize (concat 'DAGGERHEART.CONFIG.ActionType.' item.actionType)}}
    +
    + {{else if (not hideLabels)}} + {{!-- Empty --}} + {{/if}} + {{/if}} + {{!-- Action Block End --}} +
    + + {{!-- Simple Resource --}} + {{#if (and (not hideResources) (eq item.system.resource.type 'simple'))}} + {{> "systems/daggerheart/templates/sheets/global/partials/item-resource.hbs"}} + {{/if}} + {{#if (and (not hideResources) item.system.quantity)}} +
    + +
    + {{/if}} + + {{!-- Controls --}} + {{#unless hideControls}} +
    + {{#if isActor}} + + + + {{#if (eq type 'adversary')}} + + + + {{/if}} + {{else}} + {{#if (eq type 'weapon')}} + + + + {{else if (eq type 'armor')}} + + + + {{else if (eq type 'domainCard')}} + + + + {{else if (eq type 'effect')}} + + + + {{/if}} + {{#if (hasProperty item "toChat")}} + + + + {{/if}} + + + + {{/if}} +
    + {{/unless}} +
    +
    + {{!-- Description --}} + {{#unless hideDescription}} +
    + {{/unless}} + {{!-- Dice Resource --}} + {{#if (and (not hideResources) (eq item.system.resource.type 'diceValue'))}} + {{> "systems/daggerheart/templates/sheets/global/partials/item-resource.hbs"}} + {{/if}} + {{!-- Actions Buttons --}} + {{#if (and showActions (eq item.type 'feature'))}} +
    + {{#each item.system.actions as | action |}} + + {{/each}} +
    + {{/if}} +
    +
  • \ No newline at end of file diff --git a/templates/sheets/global/partials/inventory-item.hbs b/templates/sheets/global/partials/inventory-item.hbs deleted file mode 100644 index a6373c08..00000000 --- a/templates/sheets/global/partials/inventory-item.hbs +++ /dev/null @@ -1,197 +0,0 @@ -
  • - -
    -
    - {{#if isCompanion}} - {{item.name}} - {{else}} -
    {{item.name}}
    - {{/if}} - {{#if (eq type 'weapon')}} -
    - {{#if isSidebar}} -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.short')}} - {{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.short')}} - - - {{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} - {{#each item.system.attack.damage.parts.0.type as | type | }} - {{#with (lookup @root.config.GENERAL.damageTypes type)}} - - {{/with}} - {{/each}} -
    -
    - {{else}} -
    - {{localize (concat 'DAGGERHEART.CONFIG.Traits.' item.system.attack.roll.trait '.name')}} -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.Range.' item.system.attack.range '.name')}} -
    -
    - {{item.system.attack.damage.parts.0.value.dice}}{{#if item.system.attack.damage.parts.0.value.bonus}} + {{item.system.attack.damage.parts.0.value.bonus}}{{/if}} - ( - {{#each item.system.attack.damage.parts.0.type}} - {{localize (concat 'DAGGERHEART.CONFIG.DamageType.' this '.abbreviation')}} - {{/each}} - ) -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.Burden.' item.system.burden)}} -
    - {{/if}} -
    - {{/if}} - {{#if (eq type 'armor')}} - {{#if isSidebar}} -
    -
    - {{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: - {{item.system.baseScore}} -
    -
    - {{else}} -
    -
    - {{localize "DAGGERHEART.ITEMS.Armor.baseScore"}}: - {{item.system.baseScore}} -
    -
    - {{localize "DAGGERHEART.ITEMS.Armor.baseThresholds.base"}}: - {{item.system.baseThresholds.major}} - / - {{item.system.baseThresholds.severe}} -
    -
    - {{/if}} - {{/if}} - {{#if (eq type 'domainCard')}} - {{#if isSidebar}} -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}} - - - {{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}} - - - {{item.system.recallCost}} - -
    -
    - {{else}} -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.DomainCardTypes.' item.system.type)}} -
    -
    - {{localize (concat 'DAGGERHEART.GENERAL.Domain.' item.system.domain '.label')}} -
    -
    - {{localize "DAGGERHEART.ITEMS.DomainCard.recallCost"}}: - {{item.system.recallCost}} -
    -
    - {{/if}} - {{/if}} - {{#if (eq type 'effect')}} -
    -
    - {{localize (concat 'TYPES.Item.' item.parent.type)}} - : - {{item.parent.name}} -
    -
    - {{#if item.duration.duration}} - {{localize 'DAGGERHEART.EFFECTS.Duration.temporary'}} - {{else}} - {{localize 'DAGGERHEART.EFFECTS.Duration.passive'}} - {{/if}} -
    - {{#each item.statuses as |status|}} -
    - {{localize (concat 'DAGGERHEART.CONFIG.Condition.' status '.name')}} -
    - {{/each}} -
    - {{/if}} - {{#if (eq type 'action')}} -
    -
    - {{localize (concat 'DAGGERHEART.ACTIONS.TYPES.' item.type '.name')}} -
    -
    - {{localize (concat 'DAGGERHEART.CONFIG.ActionType.' item.actionType)}} -
    -
    - {{/if}} -
    - {{#if (and (not isSidebar) (eq item.system.resource.type 'simple'))}} - {{> "systems/daggerheart/templates/sheets/global/partials/item-resource.hbs"}} - {{/if}} - {{#if (and (not isSidebar) item.system.quantity)}} -
    - -
    - {{/if}} -
    - {{#unless hideControls}} - {{#if isActor}} -
    - {{#if (eq type 'actor')}} - - - - {{/if}} - {{#if (eq type 'adversary')}} - - - - - - - {{/if}} -
    - {{else}} -
    - {{#if (eq type 'weapon')}} - - - - {{/if}} - {{#if (eq type 'armor')}} - - - - {{/if}} - {{#if (eq type 'domainCard')}} - {{#unless item.system.inVault}} - - - - {{else}} - - - - {{/unless}} - - {{/if}} - - -
    - {{/if}} - {{else}} - - {{/unless}} -
    {{#unless isSidebar}}{{{item.system.description}}}{{/unless}}
    - {{#if (and (not isSidebar) (eq item.system.resource.type 'diceValue'))}} - {{> "systems/daggerheart/templates/sheets/global/partials/item-resource.hbs"}} - {{/if}} - {{#if featureType}} -
    - {{#each item.system.actions as | action |}} - - {{/each}} -
    - {{/if}} -
  • \ No newline at end of file diff --git a/templates/sheets/global/tabs/tab-actions.hbs b/templates/sheets/global/tabs/tab-actions.hbs index ed71c45f..584cf782 100644 --- a/templates/sheets/global/tabs/tab-actions.hbs +++ b/templates/sheets/global/tabs/tab-actions.hbs @@ -3,22 +3,11 @@ data-tab='{{tabs.actions.id}}' data-group='{{tabs.actions.group}}' > -
    - {{localize "DAGGERHEART.GENERAL.Action.plural"}} -
    - {{#each document.system.actions as |action index|}} -
    - - {{action.name}} -
    - -
    -
    - {{/each}} -
    -
    + +{{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.Action.plural' + collection=document.system.actions + type='action' + canCreate=true +}} \ No newline at end of file diff --git a/templates/sheets/global/tabs/tab-effects.hbs b/templates/sheets/global/tabs/tab-effects.hbs index a75f1b0b..c89c6ff4 100644 --- a/templates/sheets/global/tabs/tab-effects.hbs +++ b/templates/sheets/global/tabs/tab-effects.hbs @@ -1,26 +1,21 @@ -
    -
    - - {{localize "DAGGERHEART.GENERAL.Effect.plural"}} - - - - -
    - {{#each document.effects as |effect|}} -
    - - {{effect.name}} -
    - - -
    -
    - {{/each}} -
    -
    +
    + + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.activeEffects' + type='effect' + isGlassy=true + collection=effects.actives + canCreate=true + hideResources=true + }} + + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.inactiveEffects' + type='effect' + isGlassy=true + collection=effects.inactives + canCreate=true + hideResources=true + }}
    \ No newline at end of file diff --git a/templates/sheets/global/tabs/tab-feature-section.hbs b/templates/sheets/global/tabs/tab-feature-section.hbs deleted file mode 100644 index ca6af184..00000000 --- a/templates/sheets/global/tabs/tab-feature-section.hbs +++ /dev/null @@ -1,14 +0,0 @@ -
    -
    - {{localize "DAGGERHEART.GENERAL.Tabs.features"}} -
    - {{#each source.system.abilities as |feature key|}} - {{> 'systems/daggerheart/templates/sheets/global/partials/feature-section-item.hbs' feature=feature}} - {{/each}} -
    -
    -
    \ No newline at end of file diff --git a/templates/sheets/global/tabs/tab-features.hbs b/templates/sheets/global/tabs/tab-features.hbs index eced83d7..b70b33d3 100644 --- a/templates/sheets/global/tabs/tab-features.hbs +++ b/templates/sheets/global/tabs/tab-features.hbs @@ -1,23 +1,11 @@ -
    -
    - {{localize "DAGGERHEART.GENERAL.features"}} -
    - {{#each document.system.features as |feature|}} -
    - - {{feature.name}} -
    - -
    -
    - {{/each}} -
    -
    +
    + {{> 'daggerheart.inventory-items' + title='DAGGERHEART.GENERAL.features' + type='feature' + isGlassy=true + collection=document.system.features + canCreate=(or document.parent isGM) + showActions=false + }}
    \ No newline at end of file diff --git a/templates/sheets/items/class/settings.hbs b/templates/sheets/items/class/settings.hbs index b110bf4c..756687b4 100644 --- a/templates/sheets/items/class/settings.hbs +++ b/templates/sheets/items/class/settings.hbs @@ -38,7 +38,7 @@ {{localize "DAGGERHEART.ITEMS.Class.guide.suggestedPrimaryWeaponTitle"}}
    {{#if document.system.characterGuide.suggestedPrimaryWeapon}} -
    +
    {{document.system.characterGuide.suggestedPrimaryWeapon.name}}
    @@ -53,7 +53,7 @@ {{localize "DAGGERHEART.ITEMS.Class.guide.suggestedSecondaryWeaponTitle"}}
    {{#if document.system.characterGuide.suggestedSecondaryWeapon}} -
    +
    {{document.system.characterGuide.suggestedSecondaryWeapon.name}}
    @@ -68,7 +68,7 @@ {{localize "DAGGERHEART.ITEMS.Class.guide.suggestedArmorTitle"}}
    {{#if document.system.characterGuide.suggestedArmor}} -
    +
    {{document.system.characterGuide.suggestedArmor.name}}
    @@ -86,7 +86,7 @@ {{localize "DAGGERHEART.GENERAL.take"}}
    {{#each source.system.inventory.take}} -
    +
    {{this.name}}
    @@ -101,7 +101,7 @@ {{localize "DAGGERHEART.ITEMS.Class.guide.inventory.thenChoose"}}
    {{#each source.system.inventory.choiceA}} -
    +
    {{this.name}}
    @@ -116,7 +116,7 @@ {{localize "DAGGERHEART.ITEMS.Class.guide.inventory.andEither"}}
    {{#each source.system.inventory.choiceB}} -
    +
    {{this.name}}