mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-01-17 15:39:02 +01:00
Resource/Uses max as FormulaField
This commit is contained in:
parent
18aed3a9f0
commit
a15028594d
13 changed files with 86 additions and 48 deletions
|
|
@ -1381,6 +1381,7 @@
|
|||
"imagePath": "Image Path",
|
||||
"inactiveEffects": "Inactive Effects",
|
||||
"inventory": "Inventory",
|
||||
"itemResource": "Item Resource",
|
||||
"level": "Level",
|
||||
"levelUp": "Level Up",
|
||||
"loadout": "Loadout",
|
||||
|
|
|
|||
|
|
@ -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'
|
||||
};
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -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);
|
||||
|
|
|
|||
|
|
@ -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() {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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 {
|
||||
|
|
|
|||
|
|
@ -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;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -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,
|
||||
|
|
|
|||
|
|
@ -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(
|
||||
|
|
|
|||
|
|
@ -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
|
||||
|
|
|
|||
|
|
@ -26,26 +26,4 @@
|
|||
{{formField fields.advState label= "Advantage State" name="roll.advState" value=source.advState localize=true disabled=(not source.type)}}
|
||||
</div>
|
||||
{{/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")}}
|
||||
<div class="nest-inputs">
|
||||
{{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}}
|
||||
</div>
|
||||
{{else}}
|
||||
<div class="nest-inputs">
|
||||
{{#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}}
|
||||
</div>
|
||||
{{/if}}
|
||||
{{/if}} --}}
|
||||
</fieldset>
|
||||
|
|
@ -8,8 +8,8 @@
|
|||
<input name="uses.enabled" type="checkbox"{{#if uses.enabled}} checked{{/if}}>
|
||||
<label for="uses.enabled">Uses</label>
|
||||
</div>
|
||||
</div>
|
||||
<label class="modifier-label">{{uses.value}}/{{uses.max}}</label>
|
||||
</div>{{log @root}}
|
||||
<label class="modifier-label">{{uses.value}}/{{formulaValue uses.max @root.rollConfig.data}}</label>
|
||||
</li>
|
||||
{{/if}}
|
||||
{{#each costs as | cost index |}}
|
||||
|
|
|
|||
|
|
@ -2,7 +2,6 @@
|
|||
<h2 class="tooltip-title">{{item.name}}</h2>
|
||||
<img class="tooltip-image" src="{{item.img}}" />
|
||||
<div class="tooltip-description">{{{description}}}</div>
|
||||
|
||||
{{#if item.uses.max}}
|
||||
<h4 class="tooltip-sub-title">{{localize "DAGGERHEART.GENERAL.uses"}}</h4>
|
||||
<div class="tooltip-information-section triple spaced">
|
||||
|
|
@ -12,7 +11,7 @@
|
|||
</div>
|
||||
<div class="tooltip-information">
|
||||
<label>{{localize "DAGGERHEART.GENERAL.max"}}</label>
|
||||
<div>{{item.uses.max}}</div>
|
||||
<div>{{formulaValue item.uses.max item}}</div>
|
||||
</div>
|
||||
<div class="tooltip-information">
|
||||
<label>{{localize "DAGGERHEART.GENERAL.recovery"}}</label>
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue