Roll fixes

This commit is contained in:
WBHarry 2025-06-13 10:51:43 +02:00
parent dba49a9bfb
commit 564dcf8932
13 changed files with 121 additions and 286 deletions

View file

@ -141,14 +141,14 @@ const renderDualityButton = async event => {
const config = {
event: event,
title: button.dataset.label,
title: button.dataset.title,
roll: {
modifier: traitValue ? target.system.traits[traitValue].value : null,
label: button.dataset.label,
type: button.dataset.actionType ?? null // Need check
},
chatMessage: {
template: 'systems/daggerheart/templates/chat/attack-roll.hbs'
template: 'systems/daggerheart/templates/chat/duality-roll.hbs'
}
};
await target.diceRoll(config);
@ -220,6 +220,7 @@ Hooks.on('chatMessage', (_, message) => {
}
const traitValue = rollCommand.trait?.toLowerCase();
const advantageState = rollCommand.advantage ? true : rollCommand.disadvantage ? false : null;
// Target not required if an attribute is not used.
const target = traitValue ? getCommandTarget() : undefined;
@ -239,15 +240,11 @@ Hooks.on('chatMessage', (_, message) => {
: game.i18n.localize('DAGGERHEART.General.Duality');
const hopeAndFearRoll = `1${rollCommand.hope ?? 'd12'}+1${rollCommand.fear ?? 'd12'}`;
const advantageRoll = `${rollCommand.advantage && !rollCommand.disadvantage ? '+d6' : rollCommand.disadvantage && !rollCommand.advantage ? '-d6' : ''}`;
const advantageRoll = `${advantageState === true ? '+d6' : advantageState === false ? '-d6' : ''}`;
const attributeRoll = `${trait?.value ? `${trait.value > 0 ? `+${trait.value}` : `${trait.value}`}` : ''}`;
const roll = await Roll.create(`${hopeAndFearRoll}${advantageRoll}${attributeRoll}`).evaluate();
setDiceSoNiceForDualityRoll(
roll,
rollCommand.advantage && !rollCommand.disadvantage,
rollCommand.disadvantage && !rollCommand.advantage
);
setDiceSoNiceForDualityRoll(roll, advantageState);
resolve({
roll,
@ -268,14 +265,8 @@ Hooks.on('chatMessage', (_, message) => {
modifiers: trait ? [trait] : [],
hope: { dice: rollCommand.hope ?? 'd12', value: roll.dice[0].total },
fear: { dice: rollCommand.fear ?? 'd12', value: roll.dice[1].total },
advantage:
rollCommand.advantage && !rollCommand.disadvantage
? { dice: 'd6', value: roll.dice[2].total }
: undefined,
disadvantage:
rollCommand.disadvantage && !rollCommand.advantage
? { dice: 'd6', value: roll.dice[2].total }
: undefined
advantage: advantageState !== null ? { dice: 'd6', value: roll.dice[2].total } : undefined,
advantageState
});
const msgData = {

View file

@ -3,12 +3,7 @@ import DHDualityRoll from '../data/chat-message/dualityRoll.mjs';
export default class DhpChatMessage extends foundry.documents.ChatMessage {
async renderHTML() {
if (
this.type === 'dualityRoll' ||
this.type === 'adversaryRoll' ||
this.type === 'damageRoll' ||
this.type === 'abilityUse'
) {
if (this.type === 'dualityRoll' || this.type === 'adversaryRoll') {
this.content = await foundry.applications.handlebars.renderTemplate(this.content, this.system);
}

View file

@ -16,7 +16,6 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
hope: ['d12'],
fear: ['d12'],
advantage: null,
// disadvantage: null,
hopeResource: hopeResource
};
}
@ -32,8 +31,6 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
actions: {
updateIsAdvantage: this.updateIsAdvantage,
selectExperience: this.selectExperience,
// setAdvantage: this.setAdvantage,
// setDisadvantage: this.setDisadvantage,
finish: this.finish
},
form: {
@ -62,7 +59,6 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
context.hope = this.data.hope;
context.fear = this.data.fear;
context.advantage = this.data.advantage;
// context.disadvantage = this.data.disadvantage;
context.experiences = Object.keys(this.experiences).map(id => ({ id, ...this.experiences[id] }));
context.hopeResource = this.data.hopeResource + 1;
@ -92,20 +88,6 @@ export default class RollSelectionDialog extends HandlebarsApplicationMixin(Appl
this.render();
}
/* static setAdvantage() {
this.data.advantage = this.data.advantage ? null : 'd6';
this.data.disadvantage = null;
this.render(true);
}
static setDisadvantage() {
this.data.advantage = null;
this.data.disadvantage = this.data.disadvantage ? null : 'd6';
this.render(true);
} */
static async finish() {
const { diceOptions, ...rest } = this.data;

View file

@ -1,4 +1,5 @@
import { DHActionDiceData, DHDamageData, DHDamageField } from "./actionDice.mjs";
import { abilities } from '../../config/actorConfig.mjs';
import { DHActionDiceData, DHDamageData, DHDamageField } from './actionDice.mjs';
export default class DHAction extends foundry.abstract.DataModel {
static defineSchema() {
@ -56,25 +57,39 @@ export class DHBaseAction extends foundry.abstract.DataModel {
_id: new fields.DocumentIdField(),
type: new fields.StringField({ initial: undefined, readonly: true, required: true }),
name: new fields.StringField({ initial: undefined }),
img: new fields.FilePathField({ initial: undefined, categories: ["IMAGE"], base64: false }),
img: new fields.FilePathField({ initial: undefined, categories: ['IMAGE'], base64: false }),
actionType: new fields.StringField({ choices: SYSTEM.ITEM.actionTypes, initial: 'action', nullable: true }),
cost: new fields.ArrayField(
new fields.SchemaField({
type: new fields.StringField({ choices: SYSTEM.GENERAL.abilityCosts, nullable: false, required: true, initial: 'hope' }),
type: new fields.StringField({
choices: SYSTEM.GENERAL.abilityCosts,
nullable: false,
required: true,
initial: 'hope'
}),
value: new fields.NumberField({ nullable: true, initial: 1 }),
scalable: new fields.BooleanField({ initial: false }),
step: new fields.NumberField({ nullable: true, initial: null }),
step: new fields.NumberField({ nullable: true, initial: null })
})
),
uses: new fields.SchemaField({
value: new fields.NumberField({ nullable: true, initial: null }),
max: new fields.NumberField({ nullable: true, initial: null }),
recovery: new fields.StringField({ choices: SYSTEM.GENERAL.refreshTypes, initial: null, nullable: true })
recovery: new fields.StringField({
choices: SYSTEM.GENERAL.refreshTypes,
initial: null,
nullable: true
})
}),
range: new fields.StringField({ choices: SYSTEM.GENERAL.range, required: true, blank: false, initial: "self" })
}
range: new fields.StringField({
choices: SYSTEM.GENERAL.range,
required: true,
blank: false,
initial: 'self'
})
};
}
prepareData() {}
get index() {
@ -100,25 +115,27 @@ export class DHBaseAction extends foundry.abstract.DataModel {
static getSourceConfig(parent) {
const updateSource = {};
updateSource.img ??= parent?.img ?? parent?.system?.img;
if(parent?.system?.trait) {
if (parent?.system?.trait) {
updateSource['roll'] = {
type: this.getRollType(),
trait: parent.system.trait
};
}
if(parent?.system?.range) {
if (parent?.system?.range) {
updateSource['range'] = parent?.system?.range;
}
return updateSource;
}
async use(event) {
if(this.roll.type && this.roll.trait) {
if (this.roll.type && this.roll.trait) {
const modifierValue = this.actor.system.traits[this.roll.trait].value;
const config = {
event: event,
title: this.item.name,
roll: {
modifier: this.actor.system.traits[this.roll.trait].value,
modifier: modifierValue,
label: game.i18n.localize(abilities[this.roll.trait].label),
type: this.actionType,
difficulty: this.roll?.difficulty
},
@ -126,14 +143,14 @@ export class DHBaseAction extends foundry.abstract.DataModel {
template: this.chatTemplate
}
};
if(this.target?.type) config.checkTarget = true;
if(this.damage.parts.length) {
if (this.target?.type) config.checkTarget = true;
if (this.damage.parts.length) {
config.damage = {
value: this.damage.parts.map(p => p.getFormula(this.actor)).join(' + '),
type: this.damage.parts[0].type
};
}
if(this.effects.length) {
if (this.effects.length) {
// Apply Active Effects. In Chat Message ?
}
return this.actor.diceRoll(config);
@ -143,7 +160,7 @@ export class DHBaseAction extends foundry.abstract.DataModel {
const extraDefineSchema = (field, option) => {
return {
[field] : {
[field]: {
// damage: new fields.SchemaField({
// parts: new fields.ArrayField(new fields.EmbeddedDataField(DHDamageData))
// }),
@ -154,16 +171,19 @@ const extraDefineSchema = (field, option) => {
difficulty: new fields.NumberField({ nullable: true, initial: null, integer: true, min: 0 })
}),
target: new fields.SchemaField({
type: new fields.StringField({ choices: SYSTEM.ACTIONS.targetTypes, initial: SYSTEM.ACTIONS.targetTypes.other.id })
type: new fields.StringField({
choices: SYSTEM.ACTIONS.targetTypes,
initial: SYSTEM.ACTIONS.targetTypes.other.id
})
}),
effects: new fields.ArrayField( // ActiveEffect
new fields.SchemaField({
'_id': new fields.DocumentIdField()
_id: new fields.DocumentIdField()
})
)
}[field]
};
}
};
export class DHAttackAction extends DHBaseAction {
static defineSchema() {
@ -173,7 +193,7 @@ export class DHAttackAction extends DHBaseAction {
...extraDefineSchema('roll'),
...extraDefineSchema('target'),
...extraDefineSchema('effects')
}
};
}
static getRollType() {
@ -182,7 +202,7 @@ export class DHAttackAction extends DHBaseAction {
prepareData() {
super.prepareData();
if ( this.damage.includeBase && !!this.item?.system?.damage ) {
if (this.damage.includeBase && !!this.item?.system?.damage) {
const baseDamage = this.getParentDamage();
this.damage.parts.unshift(new DHDamageData(baseDamage));
}
@ -212,7 +232,7 @@ export class DHSpellCastAction extends DHBaseAction {
...extraDefineSchema('roll'),
...extraDefineSchema('target'),
...extraDefineSchema('effects')
}
};
}
static getRollType() {
@ -227,12 +247,12 @@ export class DHDamageAction extends DHBaseAction {
...extraDefineSchema('damage', false),
...extraDefineSchema('target'),
...extraDefineSchema('effects')
}
};
}
async use(event) {
const formula = this.damage.parts.map(p => p.getFormula(this.actor)).join(' + ');
if(!formula || formula == '') return;
if (!formula || formula == '') return;
let roll = { formula: formula, total: formula };
if (isNaN(formula)) {
@ -261,17 +281,23 @@ export class DHHealingAction extends DHBaseAction {
return {
...super.defineSchema(),
healing: new fields.SchemaField({
type: new fields.StringField({ choices: SYSTEM.GENERAL.healingTypes, required: true, blank: false, initial: SYSTEM.GENERAL.healingTypes.health.id, label: "Healing" }),
type: new fields.StringField({
choices: SYSTEM.GENERAL.healingTypes,
required: true,
blank: false,
initial: SYSTEM.GENERAL.healingTypes.health.id,
label: 'Healing'
}),
value: new fields.EmbeddedDataField(DHActionDiceData)
}),
...extraDefineSchema('target'),
...extraDefineSchema('effects')
}
};
}
async use(event) {
const formula = this.healing.value.getFormula(this.actor);
if(!formula || formula == '') return;
if (!formula || formula == '') return;
// const roll = await super.use(event);
let roll = { formula: formula, total: formula };
@ -308,10 +334,10 @@ export class DHResourceAction extends DHBaseAction {
...extraDefineSchema('target'),
...extraDefineSchema('effects'),
resource: new fields.SchemaField({
type: new fields.StringField({ choices: [], initial: "", label: "Resource" }),
value: new fields.NumberField({ initial: 0, label: "Value" })
type: new fields.StringField({ choices: [], initial: '', label: 'Resource' }),
value: new fields.NumberField({ initial: 0, label: 'Value' })
})
}
};
}
}
@ -319,8 +345,8 @@ export class DHSummonAction extends DHBaseAction {
static defineSchema() {
return {
...super.defineSchema(),
documentUUID: new fields.StringField({ blank: true, initial: "", placeholder:'Enter a Creature UUID' })
}
documentUUID: new fields.StringField({ blank: true, initial: '', placeholder: 'Enter a Creature UUID' })
};
}
}
@ -329,7 +355,7 @@ export class DHEffectAction extends DHBaseAction {
return {
...super.defineSchema(),
...extraDefineSchema('effects')
}
};
}
}
@ -337,19 +363,18 @@ export class DHMacroAction extends DHBaseAction {
static defineSchema() {
return {
...super.defineSchema(),
documentUUID: new fields.StringField({ blank: true, initial: "", placeholder:'Enter a macro UUID' })
}
documentUUID: new fields.StringField({ blank: true, initial: '', placeholder: 'Enter a macro UUID' })
};
}
async use(event) {
const fixUUID = !this.documentUUID.includes('Macro.') ? `Macro.${this.documentUUID}` : this.documentUUID,
macro = await fromUuid(fixUUID);
try {
if(!macro) throw new Error(`No macro found for the UUID: ${this.documentUUID}.`);
if (!macro) throw new Error(`No macro found for the UUID: ${this.documentUUID}.`);
macro.execute();
} catch (error) {
ui.notifications.error(error);
}
}
}

View file

@ -9,7 +9,13 @@ export default class DHDamageRoll extends foundry.abstract.TypeDataModel {
total: new fields.NumberField({ required: true, integer: true }),
type: new fields.StringField({ choices: Object.keys(SYSTEM.GENERAL.damageTypes), integer: false })
}),
dice: new fields.ArrayField(new fields.EmbeddedDataField(DhpDamageDice)),
dice: new fields.ArrayField(
new fields.SchemaField({
type: new fields.StringField({ required: true }),
rolls: new fields.ArrayField(new fields.NumberField({ required: true, integer: true })),
total: new fields.NumberField({ integer: true })
})
),
modifiers: new fields.ArrayField(
new fields.SchemaField({
value: new fields.NumberField({ required: true, integer: true }),
@ -26,18 +32,3 @@ export default class DHDamageRoll extends foundry.abstract.TypeDataModel {
};
}
}
class DhpDamageDice extends foundry.abstract.DataModel {
static defineSchema() {
const fields = foundry.data.fields;
return {
type: new fields.StringField({ required: true }),
rolls: new fields.ArrayField(new fields.NumberField({ required: true, integer: true }))
};
}
get rollTotal() {
return this.rolls.reduce((acc, roll) => acc + roll, 0);
}
}

View file

@ -28,10 +28,8 @@ export default class DHDualityRoll extends foundry.abstract.TypeDataModel {
),
hope: diceField(),
fear: diceField(),
advantageState: new fields.NumberField({ integer: true }),
advantageState: new fields.BooleanField({ nullable: true, initial: null }),
advantage: diceField(),
// advantage: diceField(),
// disadvantage: diceField(),
targets: new fields.ArrayField(
new fields.SchemaField({
id: new fields.StringField({}),
@ -66,16 +64,6 @@ export default class DHDualityRoll extends foundry.abstract.TypeDataModel {
};
}
get total() {
// const advantage = this.advantage.value
// ? this.advantage.value
// : this.disadvantage.value
// ? -this.disadvantage.value
// : 0;
// return this.diceTotal + advantage + this.modifierTotal.value;
return this.roll.total;
}
get diceTotal() {
return this.hope.value + this.fear.value;
}
@ -115,7 +103,7 @@ export default class DHDualityRoll extends foundry.abstract.TypeDataModel {
}
prepareDerivedData() {
const total = this.total;
const total = this.roll.total;
this.hope.discarded = this.hope.value < this.fear.value;
this.fear.discarded = this.fear.value < this.hope.value;

View file

@ -165,8 +165,6 @@ export default class DhpActor extends Actor {
});
rollConfig = await dialogClosed;
// advantageDice = result.advantage;
// disadvantageDice = result.disadvantage;
advantage = rollConfig.advantage;
hopeDice = rollConfig.hope;
fearDice = rollConfig.fear;
@ -199,7 +197,7 @@ export default class DhpActor extends Actor {
const roll = await Roll.create(formula).evaluate();
if (this.type === 'character') {
setDiceSoNiceForDualityRoll(roll, advantageDice, disadvantageDice);
setDiceSoNiceForDualityRoll(roll, advantage);
hope = roll.dice[0].results[0].result;
fear = roll.dice[1].results[0].result;
if (
@ -249,8 +247,6 @@ export default class DhpActor extends Actor {
configRoll.hope = { dice: hopeDice, value: hope };
configRoll.fear = { dice: fearDice, value: fear };
configRoll.advantage = { dice: advantageDice, value: roll.dice[2]?.results[0].result ?? null };
/* advantage: { dice: advantageDice, value: advantage },
disadvantage: { dice: disadvantageDice, value: disadvantage } */
}
if (damage) configRoll.damage = damage;
if (targets) configRoll.targets = targets;
@ -283,151 +279,6 @@ export default class DhpActor extends Actor {
: [];
}
// Delete when new roll logic test done
/* async diceRollOld(modifier, shiftKey) {
if (this.type === 'character') {
return await this.dualityRoll(modifier, shiftKey);
} else {
return await this.npcRoll(modifier, shiftKey);
}
}
async npcRoll(modifier, shiftKey) {
let advantage = null;
const modifiers = [
{
value: Number.parseInt(modifier.value),
label: modifier.value >= 0 ? `+${modifier.value}` : `-${modifier.value}`,
title: modifier.title
}
];
if (!shiftKey) {
const dialogClosed = new Promise((resolve, _) => {
new NpcRollSelectionDialog(this.system.experiences, resolve).render(true);
});
const result = await dialogClosed;
advantage = result.advantage;
result.experiences.forEach(x =>
modifiers.push({
value: x.value,
label: x.value >= 0 ? `+${x.value}` : `-${x.value}`,
title: x.description
})
);
}
const roll = Roll.create(
`${advantage === true || advantage === false ? 2 : 1}d20${advantage === true ? 'kh' : advantage === false ? 'kl' : ''} ${modifiers.map(x => `+ ${x.value}`).join(' ')}`
);
let rollResult = await roll.evaluate();
const dice = [];
for (var i = 0; i < rollResult.terms.length; i++) {
const term = rollResult.terms[i];
if (term.faces) {
dice.push({ type: `d${term.faces}`, rolls: term.results.map(x => ({ value: x.result })) });
}
}
// There is Only ever one dice term here
return { roll, dice: dice[0], modifiers, advantageState: advantage === true ? 1 : advantage === false ? 2 : 0 };
}
async dualityRoll(modifier, shiftKey) {
let hopeDice = 'd12',
fearDice = 'd12',
advantageDice = null,
disadvantageDice = null;
const modifiers =
modifier.value !== null
? [
{
value: modifier.value ? Number.parseInt(modifier.value) : 0,
label:
modifier.value >= 0
? `${modifier.title} +${modifier.value}`
: `${modifier.title} ${modifier.value}`,
title: modifier.title
}
]
: [];
if (!shiftKey) {
const dialogClosed = new Promise((resolve, _) => {
new RollSelectionDialog(this.system.experiences, this.system.resources.hope.value, resolve).render(
true
);
});
const result = await dialogClosed;
(hopeDice = result.hope),
(fearDice = result.fear),
(advantageDice = result.advantage),
(disadvantageDice = result.disadvantage);
result.experiences.forEach(x =>
modifiers.push({
value: x.value,
label: x.value >= 0 ? `+${x.value}` : `-${x.value}`,
title: x.description
})
);
const automateHope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope);
if (automateHope && result.hopeUsed) {
await this.update({
'system.resources.hope.value': this.system.resources.hope.value - result.hopeUsed
});
}
}
const roll = new Roll(
`1${hopeDice} + 1${fearDice}${advantageDice ? ` + 1${advantageDice}` : disadvantageDice ? ` - 1${disadvantageDice}` : ''} ${modifiers.map(x => `+ ${x.value}`).join(' ')}`
);
let rollResult = await roll.evaluate();
setDiceSoNiceForDualityRoll(rollResult, advantageDice, disadvantageDice);
const hope = rollResult.dice[0].results[0].result;
const fear = rollResult.dice[1].results[0].result;
const advantage = advantageDice ? rollResult.dice[2].results[0].result : null;
const disadvantage = disadvantageDice ? rollResult.dice[2].results[0].result : null;
if (disadvantage) {
rollResult = { ...rollResult, total: rollResult.total - Math.max(hope, disadvantage) };
}
if (advantage) {
rollResult = { ...rollResult, total: 'Select Hope Die' };
}
const automateHope = await game.settings.get(SYSTEM.id, SYSTEM.SETTINGS.gameSettings.Automation.Hope);
if (automateHope && hope > fear) {
await this.update({
'system.resources.hope.value': Math.min(
this.system.resources.hope.value + 1,
this.system.resources.hope.max
)
});
}
if (automateHope && hope === fear) {
await this.update({
'system.resources': {
'hope.value': Math.min(this.system.resources.hope.value + 1, this.system.resources.hope.max),
'stress.value': Math.max(this.system.resources.stress.value - 1, 0)
}
});
}
return {
roll,
rollResult,
hope: { dice: hopeDice, value: hope },
fear: { dice: fearDice, value: fear },
advantage: { dice: advantageDice, value: advantage },
disadvantage: { dice: disadvantageDice, value: disadvantage },
modifiers: modifiers
};
} */
async damageRoll(title, damage, targets, shiftKey) {
let rollString = damage.value;
let bonusDamage = damage.bonusDamage?.filter(x => x.initiallySelected) ?? [];
@ -455,7 +306,11 @@ export default class DhpActor extends Actor {
for (var i = 0; i < rollResult.terms.length; i++) {
const term = rollResult.terms[i];
if (term.faces) {
dice.push({ type: `d${term.faces}`, rolls: term.results.map(x => x.result) });
dice.push({
type: `d${term.faces}`,
rolls: term.results.map(x => x.result),
total: term.results.reduce((acc, x) => acc + x.result, 0)
});
} else if (term.operator) {
} else if (term.number) {
const operator = i === 0 ? '' : rollResult.terms[i - 1].operator;

View file

@ -15,12 +15,17 @@ export function getDualityMessage(roll) {
check: game.i18n.localize(abilities[roll.trait].label)
})
: null;
const label = traitLabel ?? game.i18n.localize('DAGGERHEART.General.Duality');
const dataLabel = traitLabel
? game.i18n.localize(abilities[roll.trait].label)
: game.i18n.localize('DAGGERHEART.General.Duality');
const dualityElement = document.createElement('span');
dualityElement.innerHTML = `
<button class="duality-roll-button"
data-label="${label}"
data-title="${label}"
data-label="${dataLabel}"
data-hope="${roll.hope ?? 'd12'}"
data-fear="${roll.fear ?? 'd12'}"
${roll.trait && abilities[roll.trait] ? `data-trait="${roll.trait}"` : ''}

View file

@ -122,14 +122,14 @@ export const getCommandTarget = () => {
return target;
};
export const setDiceSoNiceForDualityRoll = (rollResult, advantage, disadvantage) => {
export const setDiceSoNiceForDualityRoll = (rollResult, advantageState) => {
const diceSoNicePresets = getDiceSoNicePresets();
rollResult.dice[0].options.appearance = diceSoNicePresets.hope;
rollResult.dice[1].options.appearance = diceSoNicePresets.fear;
if(rollResult.dice[2]) {
if (advantage) {
if (rollResult.dice[2]) {
if (advantageState === true) {
rollResult.dice[2].options.appearance = diceSoNicePresets.advantage;
} else if (disadvantage) {
} else if (advantageState === false) {
rollResult.dice[2].options.appearance = diceSoNicePresets.disadvantage;
}
}
@ -227,8 +227,11 @@ export const getDeleteKeys = (property, innerProperty, innerPropertyDefaultValue
// Fix on Foundry native formula replacement for DH
const nativeReplaceFormulaData = Roll.replaceFormulaData;
Roll.replaceFormulaData = function(formula, data, {missing, warn=false}={}) {
const terms = [{term: 'prof', default: 1}, {term: 'cast', default: 1}];
formula = terms.reduce((a,c) => a.replaceAll(`@${c.term}`, data[c.term] ?? c.default), formula);
return nativeReplaceFormulaData(formula, data, {missing, warn});
}
Roll.replaceFormulaData = function (formula, data, { missing, warn = false } = {}) {
const terms = [
{ term: 'prof', default: 1 },
{ term: 'cast', default: 1 }
];
formula = terms.reduce((a, c) => a.replaceAll(`@${c.term}`, data[c.term] ?? c.default), formula);
return nativeReplaceFormulaData(formula, data, { missing, warn });
};

View file

@ -10,12 +10,12 @@
{{label}}
</div>
{{/each}}
{{#if (eq advantageState 1)}}
{{#if advantageState}}
<div class="duality-modifier">
{{localize "DAGGERHEART.General.Advantage.Full"}}
</div>
{{/if}}
{{#if (eq advantageState 2)}}
{{#if (eq advantageState false)}}
<div class="duality-modifier">
{{localize "DAGGERHEART.General.Disadvantage.Full"}}
</div>
@ -41,7 +41,7 @@
<div class="dice-value">{{fear.value}}</div>
</div>
</div>
{{#if (eq advantageState 1)}}
{{#if advantageState}}
<div class="advantage-container advantage">
<div class="dice-wrapper">
<img class="dice" src="../icons/svg/d6-grey.svg"/>
@ -49,7 +49,7 @@
</div>
</div>
{{/if}}
{{#if (eq advantageState 2)}}
{{#if (eq advantageState false)}}
<div class="advantage-container disadvantage">
<div class="dice-wrapper">
<img class="dice" src="../icons/svg/d6-grey.svg"/>
@ -61,7 +61,7 @@
</div>
{{#if (not damage.value)}}
<div class="duality-result">
<div>{{total}} {{#if (eq dualityResult 1)}}With Hope{{else}}{{#if (eq dualityResult 2)}}With Fear{{else}}Critical Success{{/if}}{{/if}}</div>
<div>{{roll.total}} {{#if (eq dualityResult 1)}}With Hope{{else}}{{#if (eq dualityResult 2)}}With Fear{{else}}Critical Success{{/if}}{{/if}}</div>
</div>
{{/if}}
</div>
@ -80,9 +80,9 @@
{{/if}}
{{#if damage.value}}
<div class="duality-actions">
<button class="duality-action" data-value="{{total}}" data-damage="{{damage.value}}" data-damage-type="{{damage.type}}" {{#if damage.disabled}}disabled{{/if}}><span>Roll Damage</span></button>
<button class="duality-action" data-value="{{roll.total}}" data-damage="{{damage.value}}" data-damage-type="{{damage.type}}" {{#if damage.disabled}}disabled{{/if}}><span>Roll Damage</span></button>
<div class="duality-result">
<div>{{total}} {{#if (eq dualityResult 1)}}With Hope{{else}}{{#if (eq dualityResult 2)}}With Fear{{else}}Critical Success{{/if}}{{/if}}</div>
<div>{{roll.total}} {{#if (eq dualityResult 1)}}With Hope{{else}}{{#if (eq dualityResult 2)}}With Fear{{else}}Critical Success{{/if}}{{/if}}</div>
</div>
</div>
{{/if}}
@ -148,7 +148,7 @@
<div class="dice-total duality {{#if fear.discarded}}hope{{else}}{{#if hope.discarded}}fear{{else}}critical{{/if}}{{/if}}">
<div class="dice-total-label">{{totalLabel}}</div>
<div class="dice-total-value">
{{total}}
{{roll.total}}
</div>
</div>
{{#if (gt targets.length 0)}}
@ -164,7 +164,7 @@
</div>
{{/if}}
<div class="dice-actions">
<button class="duality-action" data-value="{{total}}" data-damage="{{damage.value}}" data-damage-type="{{damage.type}}" {{#if damage.disabled}}disabled{{/if}}><span>{{localize "DAGGERHEART.Chat.AttackRoll.RollDamage"}}</span></button>
<button class="duality-action" data-value="{{roll.total}}" data-damage="{{damage.value}}" data-damage-type="{{damage.type}}" {{#if damage.disabled}}disabled{{/if}}><span>{{localize "DAGGERHEART.Chat.AttackRoll.RollDamage"}}</span></button>
</div>
</div>
</div>

View file

@ -11,7 +11,7 @@
<header class="part-header flexrow">
<span class="part-formula">{{rolls.length}}{{type}}</span>
<span class="part-total">{{rollTotal}}</span>
<span class="part-total">{{this.total}}</span>
</header>
<ol class="dice-rolls">
{{#each rolls}}
@ -23,7 +23,7 @@
</section>
</div>
</div>
<div class="dice-total">{{total}}</div>
<div class="dice-total">{{damage.total}}</div>
<div class="dice-actions">
<button class="damage-button" data-target-hit="true" {{#if (eq targets.length 0)}}disabled{{/if}}>{{localize "DAGGERHEART.Chat.DamageRoll.DealDamageToTargets"}}</button>
<button class="damage-button">{{localize "DAGGERHEART.Chat.DamageRoll.DealDamage"}}</button>

View file

@ -10,12 +10,12 @@
{{label}}
</div>
{{/each}}
{{#if (eq advantageState 1)}}
{{#if advantageState}}
<div class="duality-modifier">
{{localize "DAGGERHEART.General.Advantage.Full"}}
</div>
{{/if}}
{{#if (eq advantageState 2)}}
{{#if (eq advantageState false)}}
<div class="duality-modifier">
{{localize "DAGGERHEART.General.Disadvantage.Full"}}
</div>
@ -41,7 +41,7 @@
<div class="dice-value">{{fear.value}}</div>
</div>
</div>
{{#if (eq advantageState 1)}}
{{#if advantageState}}
<div class="advantage-container advantage">
<div class="dice-wrapper">
<img class="dice" src="../icons/svg/d6-grey.svg"/>
@ -49,7 +49,7 @@
</div>
</div>
{{/if}}
{{#if (eq advantageState 2)}}
{{#if (eq advantageState false)}}
<div class="advantage-container disadvantage">
<div class="dice-wrapper">
<img class="dice" src="../icons/svg/d6-grey.svg"/>
@ -61,7 +61,7 @@
</div>
{{#if (not damage.value)}}
<div class="duality-result">
<div>{{total}} {{#if (eq dualityResult 1)}}With Hope{{else}}{{#if (eq dualityResult 2)}}With Fear{{else}}Critical Success{{/if}}{{/if}}</div>
<div>{{roll.total}} {{#if (eq dualityResult 1)}}With Hope{{else}}{{#if (eq dualityResult 2)}}With Fear{{else}}Critical Success{{/if}}{{/if}}</div>
</div>
{{/if}}
</div>
@ -135,7 +135,7 @@
<div class="dice-total duality {{#if fear.discarded}}hope{{else}}{{#if hope.discarded}}fear{{else}}critical{{/if}}{{/if}}">
<div class="dice-total-label">{{totalLabel}}</div>
<div class="dice-total-value">
{{total}}
{{roll.total}}
</div>
</div>
</div>

View file

@ -13,7 +13,7 @@
</div>
<div class="flexrow">
<button class="disadvantage flex1 {{#if this.advantage}}selected{{/if}}" data-action="updateIsAdvantage" data-advantage="true">{{localize "DAGGERHEART.General.Advantage.Full"}}</button>
<button class="disadvantage flex1 {{#if this.disadvantage}}selected{{/if}}" data-action="updateIsAdvantage">{{localize "DAGGERHEART.General.Disadvantage.Full"}}</button>
<button class="disadvantage flex1 {{#if (eq this.advantage false)}}selected{{/if}}" data-action="updateIsAdvantage">{{localize "DAGGERHEART.General.Disadvantage.Full"}}</button>
</div>
{{#if (not this.isNpc)}}
<div class="form-group">