diff --git a/lang/en.json b/lang/en.json index 40317f8c..0d338238 100755 --- a/lang/en.json +++ b/lang/en.json @@ -1381,6 +1381,7 @@ "imagePath": "Image Path", "inactiveEffects": "Inactive Effects", "inventory": "Inventory", + "itemResource": "Item Resource", "level": "Level", "levelUp": "Level Up", "loadout": "Loadout", diff --git a/module/applications/sheets-configs/action-config.mjs b/module/applications/sheets-configs/action-config.mjs index a569e66f..92176861 100644 --- a/module/applications/sheets-configs/action-config.mjs +++ b/module/applications/sheets-configs/action-config.mjs @@ -133,8 +133,8 @@ export default class DHActionConfig extends DaggerheartSheet(ApplicationV2) { const resource = this.action.parent.resource; if (resource) { options[this.action.parent.parent.id] = { - label: this.action.parent.parent.name, - group: 'TYPES.Actor.character' + label: "DAGGERHEART.GENERAL.itemResource", + group: 'Global' }; } diff --git a/module/applications/sheets/actors/character.mjs b/module/applications/sheets/actors/character.mjs index d9098f9b..6bbef5b0 100644 --- a/module/applications/sheets/actors/character.mjs +++ b/module/applications/sheets/actors/character.mjs @@ -260,7 +260,7 @@ export default class CharacterSheet extends DHBaseActorSheet { icon: 'fa-solid fa-arrow-up', condition: target => { const doc = getDocFromElementSync(target); - return doc && system.inVault; + return doc && doc.system.inVault; }, callback: async target => { const doc = await getDocFromElement(target); diff --git a/module/data/action/baseAction.mjs b/module/data/action/baseAction.mjs index 8f0e0682..a21b162b 100644 --- a/module/data/action/baseAction.mjs +++ b/module/data/action/baseAction.mjs @@ -185,13 +185,11 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel prepareRoll() { const roll = { - modifiers: this.modifiers, - trait: this.roll?.trait, + baseModifiers: this.roll.getModifier(), label: 'Attack', type: this.actionType, difficulty: this.roll?.difficulty, formula: this.roll.getFormula(), - bonus: this.roll.bonus, advantage: CONFIG.DH.ACTIONS.advantageState[this.roll.advState].value }; if (this.roll?.type === 'diceSet') roll.lite = true; @@ -237,7 +235,7 @@ export default class DHBaseAction extends ActionMixin(foundry.abstract.DataModel /* ROLL */ get hasRoll() { - return !!this.roll?.type || !!this.roll?.bonus; + return !!this.roll?.type; } get modifiers() { diff --git a/module/data/fields/action/costField.mjs b/module/data/fields/action/costField.mjs index f5e1999c..79ecd51f 100644 --- a/module/data/fields/action/costField.mjs +++ b/module/data/fields/action/costField.mjs @@ -51,9 +51,11 @@ export default class CostField extends fields.ArrayField { const resources = CostField.getResources.call(this, realCosts); return realCosts.reduce( (a, c) => - a && resources[c.key].isReversed - ? resources[c.key].value + (c.total ?? c.value) <= resources[c.key].max - : resources[c.key]?.value >= (c.total ?? c.value), + !resources[c.key] + ? a + : a && resources[c.key].isReversed + ? resources[c.key].value + (c.total ?? c.value) <= resources[c.key].max + : resources[c.key]?.value >= (c.total ?? c.value), true ); } @@ -61,10 +63,12 @@ export default class CostField extends fields.ArrayField { static getResources(costs) { const actorResources = this.actor.system.resources; const itemResources = {}; - for (var itemResource of costs) { + for (let itemResource of costs) { if (itemResource.keyIsID) { itemResources[itemResource.key] = { - value: this.parent.resource.value ?? 0 + value: this.parent.resource.value ?? 0, + max: CostField.formatMax.call(this, this.parent?.resource?.max), + isReversed: true }; } } @@ -79,4 +83,13 @@ export default class CostField extends fields.ArrayField { const realCosts = costs?.length ? costs.filter(c => c.enabled) : []; return realCosts; } + + static formatMax(max) { + max ??= 0; + if(isNaN(max)) { + const roll = Roll.replaceFormulaData(max, this.getRollData()); + max = roll.total; + } + return max; + } } diff --git a/module/data/fields/action/rollField.mjs b/module/data/fields/action/rollField.mjs index 511e0660..35f77ffe 100644 --- a/module/data/fields/action/rollField.mjs +++ b/module/data/fields/action/rollField.mjs @@ -66,6 +66,43 @@ export class DHActionRollData extends foundry.abstract.DataModel { } return formula; } + + getModifier() { + const modifiers = []; + if(!this.parent?.actor) return modifiers; + switch (this.parent.actor.type) { + case 'character': + const trait = this.useDefault || !this.trait ? this.parent.item.system.attack.roll.trait : this.trait; + if(this.type === CONFIG.DH.GENERAL.rollTypes.attack.id || this.type === CONFIG.DH.GENERAL.rollTypes.trait.id) + modifiers.push( + { + label: `DAGGERHEART.CONFIG.Traits.${trait}.name`, + value: this.parent.actor.system.traits[trait].value + } + ) + else if(this.type === CONFIG.DH.GENERAL.rollTypes.spellcast.id) + modifiers.push( + { + label: `DAGGERHEART.CONFIG.RollTypes.spellcast.name`, + value: this.parent.actor.system.spellcastModifier + } + ) + break; + case 'companion': + case 'adversary': + if(this.type === CONFIG.DH.GENERAL.rollTypes.attack.id) + modifiers.push( + { + label: 'Bonus to Hit', + value: this.bonus ?? this.parent.actor.system.attack.roll.bonus + } + ) + break; + default: + break; + } + return modifiers; + } } export default class RollField extends fields.EmbeddedDataField { diff --git a/module/data/fields/action/usesField.mjs b/module/data/fields/action/usesField.mjs index df6c5d0c..177904a1 100644 --- a/module/data/fields/action/usesField.mjs +++ b/module/data/fields/action/usesField.mjs @@ -1,10 +1,12 @@ +import FormulaField from "../formulaField.mjs"; + const fields = foundry.data.fields; export default class UsesField extends fields.SchemaField { constructor(options = {}, context = {}) { const usesFields = { value: new fields.NumberField({ nullable: true, initial: null }), - max: new fields.NumberField({ nullable: true, initial: null }), + max: new FormulaField({ nullable: true, initial: null, deterministic: true }), recovery: new fields.StringField({ choices: CONFIG.DH.GENERAL.refreshTypes, initial: null, @@ -33,6 +35,11 @@ export default class UsesField extends fields.SchemaField { static hasUses(uses) { if (!uses) return true; - return (uses.hasOwnProperty('enabled') && !uses.enabled) || uses.value + 1 <= uses.max; + let max = uses.max ?? 0; + if(isNaN(max)) { + const roll = new Roll(Roll.replaceFormulaData(uses.max, this.getRollData())).evaluateSync(); + max = roll.total; + } + return (uses.hasOwnProperty('enabled') && !uses.enabled) || uses.value + 1 <= max; } } diff --git a/module/data/item/base.mjs b/module/data/item/base.mjs index 5b95a810..87267c39 100644 --- a/module/data/item/base.mjs +++ b/module/data/item/base.mjs @@ -10,6 +10,7 @@ import { addLinkedItemsDiff, updateLinkedItemApps } from '../../helpers/utils.mjs'; import { ActionsField } from '../fields/actionField.mjs'; +import FormulaField from '../fields/formulaField.mjs'; const fields = foundry.data.fields; @@ -48,7 +49,7 @@ export default class BaseDataItem extends foundry.abstract.TypeDataModel { initial: CONFIG.DH.ITEM.itemResourceTypes.simple }), value: new fields.NumberField({ integer: true, min: 0, initial: 0 }), - max: new fields.StringField({ nullable: true, initial: null }), + max: new FormulaField({ nullable: true, initial: null, deterministic: true }), icon: new fields.StringField(), recovery: new fields.StringField({ choices: CONFIG.DH.GENERAL.refreshTypes, diff --git a/module/dice/d20Roll.mjs b/module/dice/d20Roll.mjs index ce400110..701616f1 100644 --- a/module/dice/d20Roll.mjs +++ b/module/dice/d20Roll.mjs @@ -124,13 +124,7 @@ export default class D20Roll extends DHRoll { } applyBaseBonus() { - const modifiers = []; - - if (this.options.roll.bonus) - modifiers.push({ - label: 'Bonus to Hit', - value: this.options.roll.bonus - }); + const modifiers = foundry.utils.deepClone(this.options.roll.baseModifiers) ?? []; modifiers.push(...this.getBonus(`roll.${this.options.type}`, `${this.options.type?.capitalize()} Bonus`)); modifiers.push( diff --git a/module/helpers/handlebarsHelper.mjs b/module/helpers/handlebarsHelper.mjs index 751b2c38..790d291c 100644 --- a/module/helpers/handlebarsHelper.mjs +++ b/module/helpers/handlebarsHelper.mjs @@ -7,6 +7,7 @@ export default class RegisterHandlebarsHelpers { includes: this.includes, times: this.times, damageFormula: this.damageFormula, + formulaValue: this.formulaValue, damageSymbols: this.damageSymbols, rollParsed: this.rollParsed, hasProperty: foundry.utils.hasProperty, @@ -39,6 +40,15 @@ export default class RegisterHandlebarsHelpers { return instances.join(traitTotal > 0 ? ' + ' : ' - '); } + static formulaValue(formula, item) { + if(isNaN(formula)) { + const data = item.getRollData.bind(item)(), + roll = new Roll(Roll.replaceFormulaData(formula, data)).evaluateSync(); + formula = roll.total; + } + return formula; + } + static damageSymbols(damageParts) { const symbols = [...new Set(damageParts.reduce((a, c) => a.concat([...c.type]), []))].map( p => CONFIG.DH.GENERAL.damageTypes[p].icon diff --git a/templates/actionTypes/roll.hbs b/templates/actionTypes/roll.hbs index 2d78033a..3e25b9c8 100644 --- a/templates/actionTypes/roll.hbs +++ b/templates/actionTypes/roll.hbs @@ -26,26 +26,4 @@ {{formField fields.advState label= "Advantage State" name="roll.advState" value=source.advState localize=true disabled=(not source.type)}} {{/if}} - - {{!-- {{#if @root.isNPC}} - {{formField fields.bonus label="Bonus" name="roll.bonus" value=source.bonus}} - {{formField fields.advState label= "Advantage State" name="roll.advState" value=source.advState localize=true}} - {{else}} - {{formField fields.type label="Type" name="roll.type" value=source.type localize=true}} - {{#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" 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}} -
- {{#unless (eq source.type 'spellcast')}}{{formField fields.trait label="Trait" name="roll.trait" value=source.trait localize=true disabled=(not source.type)}}{{/unless}} - {{formField fields.difficulty label="Difficulty" name="roll.difficulty" value=source.difficulty disabled=(not source.type)}} - {{formField fields.advState label= "Advantage State" name="roll.advState" value=source.advState localize=true}} -
- {{/if}} - {{/if}} --}} \ No newline at end of file diff --git a/templates/dialogs/dice-roll/costSelection.hbs b/templates/dialogs/dice-roll/costSelection.hbs index d376c749..d9643fc2 100644 --- a/templates/dialogs/dice-roll/costSelection.hbs +++ b/templates/dialogs/dice-roll/costSelection.hbs @@ -8,8 +8,8 @@ - - + {{log @root}} + {{/if}} {{#each costs as | cost index |}} diff --git a/templates/ui/tooltip/action.hbs b/templates/ui/tooltip/action.hbs index 59e0be70..20929bf3 100644 --- a/templates/ui/tooltip/action.hbs +++ b/templates/ui/tooltip/action.hbs @@ -2,7 +2,6 @@

{{item.name}}

{{{description}}}
- {{#if item.uses.max}}

{{localize "DAGGERHEART.GENERAL.uses"}}

@@ -12,7 +11,7 @@
-
{{item.uses.max}}
+
{{formulaValue item.uses.max item}}