Basic rework to the roll data in messages

This commit is contained in:
WBHarry 2026-03-30 18:51:29 +02:00
parent e2b13d6717
commit 2664979823
15 changed files with 199 additions and 226 deletions

View file

@ -1,8 +1,6 @@
import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs';
import D20Roll from './d20Roll.mjs';
import { parseRallyDice, setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs';
import { getDiceSoNicePresets } from '../config/generalConfig.mjs';
import { ResourceUpdateMap } from '../data/action/baseAction.mjs';
export default class DualityRoll extends D20Roll {
_advantageFaces = 6;
@ -19,6 +17,22 @@ export default class DualityRoll extends D20Roll {
static DefaultDialog = D20RollDialog;
/**@inheritdoc */
static instantiateAST(ast) {
/* First two dice are always the DualityDice */
const nodes = CONFIG.Dice.parser.flattenTree(ast);
const dieNodes = nodes.filter(x => x.class === 'DiceTerm');
if (dieNodes.length > 1) {
dieNodes[0].class = 'DualityDie';
dieNodes[1].class = 'DualityDie';
}
return nodes.map(node => {
const cls = foundry.dice.terms[node.class] ?? foundry.dice.terms.RollTerm;
return cls.fromParseNode(node);
});
}
get title() {
return game.i18n.localize(
`DAGGERHEART.GENERAL.${this.options?.actionType === 'reaction' ? 'reactionRoll' : 'dualityRoll'}`
@ -65,6 +79,21 @@ export default class DualityRoll extends D20Roll {
this._advantageNumber = Number(value);
}
/* This isn't fullproof, but trying to cover parathetical situations is ridiculously complex */
get modifierTotal() {
let modifierTotal = 0;
for (let i = 0; i < this.terms.length; i++) {
if (
this.terms[i] instanceof foundry.dice.terms.NumericTerm &&
!!this.terms[i - 1] &&
this.terms[i - 1] instanceof foundry.dice.terms.OperatorTerm
)
modifierTotal += Number(`${this.terms[i - 1].operator}${this.terms[i].total}`);
}
return modifierTotal;
}
setRallyChoices() {
return this.data?.parent?.appliedEffects.reduce((a, c) => {
const change = c.system.changes.find(ch => ch.key === 'system.bonuses.rally');
@ -116,24 +145,20 @@ export default class DualityRoll extends D20Roll {
return [...(hooks ?? []), 'Duality'];
}
/** @inheritDoc */
static fromData(data) {
data.terms[0].class = foundry.dice.terms.Die.name;
data.terms[2].class = foundry.dice.terms.Die.name;
return super.fromData(data);
}
createBaseDice() {
if (this.dice[0] instanceof foundry.dice.terms.Die && this.dice[1] instanceof foundry.dice.terms.Die) {
if (
this.dice[0] instanceof game.system.api.dice.diceTypes.DualityDie &&
this.dice[1] instanceof game.system.api.dice.diceTypes.DualityDie
) {
this.terms = [this.terms[0], this.terms[1], this.terms[2]];
return;
}
this.terms[0] = new foundry.dice.terms.Die({
this.terms[0] = new game.system.api.dice.diceTypes.DualityDie({
faces: this.data.rules.dualityRoll?.defaultHopeDice ?? 12
});
this.terms[1] = new foundry.dice.terms.OperatorTerm({ operator: '+' });
this.terms[2] = new foundry.dice.terms.Die({
this.terms[2] = new game.system.api.dice.diceTypes.DualityDie({
faces: this.data.rules.dualityRoll?.defaultFearDice ?? 12
});
}
@ -371,63 +396,4 @@ export default class DualityRoll extends D20Roll {
if (currentCombatant?.actorId == config.data.id) ui.combat.setCombatantSpotlight(currentCombatant.id);
}
}
static async reroll(rollBase, dieIndex, diceType, updateResources = true) {
let parsedRoll = game.system.api.dice.DualityRoll.fromData({ ...rollBase, evaluated: false });
const term = parsedRoll.terms[dieIndex];
await term.reroll(`/r1=${term.total}`);
const result = await parsedRoll.evaluate();
if (game.modules.get('dice-so-nice')?.active) {
const diceSoNiceRoll = {
_evaluated: true,
dice: [
new foundry.dice.terms.Die({
...term,
faces: term._faces,
results: term.results.filter(x => !x.rerolled)
})
],
options: { appearance: {} }
};
const diceSoNicePresets = await getDiceSoNicePresets(`d${term._faces}`, `d${term._faces}`);
if (diceSoNicePresets[diceType]) {
diceSoNiceRoll.dice[0].options = diceSoNicePresets[diceType];
}
await game.dice3d.showForRoll(diceSoNiceRoll, game.user, true);
} else {
foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice });
}
const newRoll = game.system.api.dice.DualityRoll.postEvaluate(parsedRoll, {
targets: parsedRoll.options.targets ?? [],
roll: {
advantage: parsedRoll.options.roll.advantage?.type,
difficulty: parsedRoll.options.roll.difficulty ? Number(parsedRoll.options.roll.difficulty) : null
}
});
const extraIndex = newRoll.advantage ? 3 : 2;
newRoll.extra = newRoll.extra.slice(extraIndex);
const actor = parsedRoll.options.source.actor
? await foundry.utils.fromUuid(parsedRoll.options.source.actor)
: null;
const config = {
source: { actor: parsedRoll.options.source.actor ?? '' },
targets: parsedRoll.targets,
roll: newRoll,
rerolledRoll: parsedRoll.options.roll,
resourceUpdates: new ResourceUpdateMap(actor)
};
if (updateResources) {
await DualityRoll.addDualityResourceUpdates(config);
await config.resourceUpdates.updateResources();
}
return { newRoll, parsedRoll };
}
}