fix dr command roll bug (#241)

* swap to use the DualityRoll not base roll

* update command to use new dice roll.

* reinstate DhpActor in action (which causes circular reference)

* fix additional dr options
This commit is contained in:
IrkTheImp 2025-07-02 17:02:20 -05:00 committed by GitHub
parent a79b7189b6
commit 9fb9a4af55
No known key found for this signature in database
GPG key ID: B5690EEEBB952194
5 changed files with 96 additions and 83 deletions

View file

@ -213,46 +213,27 @@ Hooks.on('chatMessage', (_, message) => {
}) })
: game.i18n.localize('DAGGERHEART.General.Duality'); : game.i18n.localize('DAGGERHEART.General.Duality');
const hopeAndFearRoll = `1${rollCommand.hope ?? 'd12'}+1${rollCommand.fear ?? 'd12'}`; const config = {
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, advantageState);
resolve({
roll,
trait: trait
? {
value: trait.value,
label: `${game.i18n.localize(abilities[traitValue].label)} ${trait.value >= 0 ? `+` : ``}${trait.value}`
}
: undefined,
title
});
}).then(async ({ roll, trait, title }) => {
const cls = getDocumentClass('ChatMessage');
const systemData = new DHDualityRoll({
title: title, title: title,
origin: target?.id, roll: {
roll: roll, trait: traitValue
modifiers: trait ? [trait] : [], },
hope: { dice: rollCommand.hope ?? 'd12', value: roll.dice[0].total }, data: {
fear: { dice: rollCommand.fear ?? 'd12', value: roll.dice[1].total }, traits: {
advantage: advantageState !== null ? { dice: 'd6', value: roll.dice[2].total } : undefined, [traitValue]: trait
advantageState }
}); },
source: target,
const msgData = { hasSave: false,
type: 'dualityRoll', dialog: { configure: false },
sound: CONFIG.sounds.dice, evaluate: true,
system: systemData, advantage: rollCommand.advantage == true,
user: game.user.id, disadvantage: rollCommand.disadvantage == true
content: 'systems/daggerheart/templates/chat/duality-roll.hbs',
rolls: [roll]
}; };
cls.create(msgData); await CONFIG.Dice.daggerheart['DualityRoll'].build(config);
resolve();
}); });
} }

View file

@ -1,6 +1,10 @@
export default class DhpChatMessage extends foundry.documents.ChatMessage { export default class DhpChatMessage extends foundry.documents.ChatMessage {
async renderHTML() { async renderHTML() {
if(this.system.messageTemplate) this.content = await foundry.applications.handlebars.renderTemplate(this.system.messageTemplate, this.system); if (this.system.messageTemplate)
this.content = await foundry.applications.handlebars.renderTemplate(
this.system.messageTemplate,
this.system
);
/* We can change to fully implementing the renderHTML function if needed, instead of augmenting it. */ /* We can change to fully implementing the renderHTML function if needed, instead of augmenting it. */
const html = await super.renderHTML(); const html = await super.renderHTML();

View file

@ -1,6 +1,7 @@
import DHDamageRoll from '../data/chat-message/damageRoll.mjs'; import DHDamageRoll from '../data/chat-message/damageRoll.mjs';
import D20RollDialog from '../dialogs/d20RollDialog.mjs'; import D20RollDialog from '../dialogs/d20RollDialog.mjs';
import DamageDialog from '../dialogs/damageDialog.mjs'; import DamageDialog from '../dialogs/damageDialog.mjs';
import { setDiceSoNiceForDualityRoll } from '../helpers/utils.mjs';
/* /*
- Damage & other resources roll - Damage & other resources roll
@ -38,7 +39,7 @@ export class DHRoll extends Roll {
if (config.dialog.configure !== false) { if (config.dialog.configure !== false) {
// Open Roll Dialog // Open Roll Dialog
const DialogClass = config.dialog?.class ?? this.DefaultDialog; const DialogClass = config.dialog?.class ?? this.DefaultDialog;
console.log(roll, config) console.log(roll, config);
const configDialog = await DialogClass.configure(roll, config, message); const configDialog = await DialogClass.configure(roll, config, message);
if (!configDialog) return; if (!configDialog) return;
} }
@ -96,7 +97,8 @@ export class DHRoll extends Roll {
} }
static applyKeybindings(config) { static applyKeybindings(config) {
config.dialog.configure ??= !(config.event.shiftKey || config.event.altKey || config.event.ctrlKey); if (config.event)
config.dialog.configure ??= !(config.event.shiftKey || config.event.altKey || config.event.ctrlKey);
} }
formatModifier(modifier) { formatModifier(modifier) {
@ -108,7 +110,7 @@ export class DHRoll extends Roll {
} }
getFaces(faces) { getFaces(faces) {
return Number((faces.startsWith('d') ? faces.replace('d', '') : faces)); return Number(faces.startsWith('d') ? faces.replace('d', '') : faces);
} }
constructFormula(config) { constructFormula(config) {
@ -131,7 +133,6 @@ export class DualityDie extends foundry.dice.terms.Die {
} }
export class D20Roll extends DHRoll { export class D20Roll extends DHRoll {
constructor(formula, data = {}, options = {}) { constructor(formula, data = {}, options = {}) {
super(formula, data, options); super(formula, data, options);
this.constructFormula(); this.constructFormula();
@ -177,18 +178,27 @@ export class D20Roll extends DHRoll {
} }
static applyKeybindings(config) { static applyKeybindings(config) {
const keys = { let keys = {
normal: config.event.shiftKey || config.event.altKey || config.event.ctrlKey, normal: true,
advantage: config.event.altKey, advantage: false,
disadvantage: config.event.ctrlKey disadvantage: false
}; };
if (config.event) {
keys = {
normal: config.event.shiftKey || config.event.altKey || config.event.ctrlKey,
advantage: config.event.altKey,
disadvantage: config.event.ctrlKey
};
}
// Should the roll configuration dialog be displayed? // Should the roll configuration dialog be displayed?
config.dialog.configure ??= !Object.values(keys).some(k => k); config.dialog.configure ??= !Object.values(keys).some(k => k);
// Determine advantage mode // Determine advantage mode
const advantage = config.roll.advantage === this.ADV_MODE.ADVANTAGE || keys.advantage; const advantage = config.roll.advantage === this.ADV_MODE.ADVANTAGE || keys.advantage || config.advantage;
const disadvantage = config.roll.advantage === this.ADV_MODE.DISADVANTAGE || keys.disadvantage; const disadvantage =
config.roll.advantage === this.ADV_MODE.DISADVANTAGE || keys.disadvantage || config.disadvantage;
if (advantage && !disadvantage) config.roll.advantage = this.ADV_MODE.ADVANTAGE; if (advantage && !disadvantage) config.roll.advantage = this.ADV_MODE.ADVANTAGE;
else if (!advantage && disadvantage) config.roll.advantage = this.ADV_MODE.DISADVANTAGE; else if (!advantage && disadvantage) config.roll.advantage = this.ADV_MODE.DISADVANTAGE;
else config.roll.advantage = this.ADV_MODE.NORMAL; else config.roll.advantage = this.ADV_MODE.NORMAL;
@ -247,14 +257,24 @@ export class D20Roll extends DHRoll {
applyBaseBonus() { applyBaseBonus() {
this.options.roll.modifiers = []; this.options.roll.modifiers = [];
if(!this.options.roll.bonus) return; if (!this.options.roll.bonus) return;
this.options.roll.modifiers.push( this.options.roll.modifiers.push({
{ label: 'Bonus to Hit',
label: 'Bonus to Hit', value: this.options.roll.bonus
value: this.options.roll.bonus // value: Roll.replaceFormulaData('@attackBonus', this.data)
// value: Roll.replaceFormulaData('@attackBonus', this.data) });
} }
);
static async buildEvaluate(roll, config = {}, message = {}) {
if (config.evaluate !== false) await roll.evaluate();
const advantageState =
config.roll.advantage == this.ADV_MODE.ADVANTAGE
? true
: config.roll.advantage == this.ADV_MODE.DISADVANTAGE
? false
: null;
setDiceSoNiceForDualityRoll(roll, advantageState);
this.postEvaluate(roll, config);
} }
static postEvaluate(roll, config = {}) { static postEvaluate(roll, config = {}) {
@ -264,21 +284,29 @@ export class D20Roll extends DHRoll {
const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion; const difficulty = config.roll.difficulty ?? target.difficulty ?? target.evasion;
target.hit = this.isCritical || roll.total >= difficulty; target.hit = this.isCritical || roll.total >= difficulty;
}); });
} else if (config.roll.difficulty) config.roll.success = roll.isCritical || roll.total >= config.roll.difficulty; } else if (config.roll.difficulty)
config.roll.success = roll.isCritical || roll.total >= config.roll.difficulty;
config.roll.advantage = { config.roll.advantage = {
type: config.roll.advantage, type: config.roll.advantage,
dice: roll.dAdvantage?.denomination, dice: roll.dAdvantage?.denomination,
value: roll.dAdvantage?.total value: roll.dAdvantage?.total
}; };
config.roll.extra = roll.dice.filter(d => !roll.baseTerms.includes(d)).map(d => { config.roll.extra = roll.dice
return { .filter(d => !roll.baseTerms.includes(d))
dice: d.denomination, .map(d => {
value: d.total return {
} dice: d.denomination,
}) value: d.total
};
});
config.roll.modifierTotal = 0; config.roll.modifierTotal = 0;
for(let i = 0; i < roll.terms.length; i++) { for (let i = 0; i < roll.terms.length; i++) {
if(roll.terms[i] instanceof foundry.dice.terms.NumericTerm && !!roll.terms[i-1] && roll.terms[i-1] instanceof foundry.dice.terms.OperatorTerm) config.roll.modifierTotal += Number(`${roll.terms[i-1].operator}${roll.terms[i].total}`); if (
roll.terms[i] instanceof foundry.dice.terms.NumericTerm &&
!!roll.terms[i - 1] &&
roll.terms[i - 1] instanceof foundry.dice.terms.OperatorTerm
)
config.roll.modifierTotal += Number(`${roll.terms[i - 1].operator}${roll.terms[i].total}`);
} }
} }
@ -365,12 +393,13 @@ export class DualityRoll extends D20Roll {
return game.i18n.localize(label); return game.i18n.localize(label);
} }
updateFormula() { updateFormula() {}
}
createBaseDice() { createBaseDice() {
if (this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie && this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie) { if (
this.dice[0] instanceof CONFIG.Dice.daggerheart.DualityDie &&
this.dice[1] instanceof CONFIG.Dice.daggerheart.DualityDie
) {
this.terms = [this.terms[0], this.terms[1], this.terms[2]]; this.terms = [this.terms[0], this.terms[1], this.terms[2]];
return; return;
} }
@ -383,7 +412,8 @@ export class DualityRoll extends D20Roll {
const dieFaces = this.advantageFaces, const dieFaces = this.advantageFaces,
bardRallyFaces = this.hasBarRally, bardRallyFaces = this.hasBarRally,
advDie = new foundry.dice.terms.Die({ faces: dieFaces }); advDie = new foundry.dice.terms.Die({ faces: dieFaces });
if (this.hasAdvantage || this.hasDisadvantage || bardRallyFaces) this.terms.push(new foundry.dice.terms.OperatorTerm({ operator: this.hasDisadvantage ? '-' : '+' })); if (this.hasAdvantage || this.hasDisadvantage || bardRallyFaces)
this.terms.push(new foundry.dice.terms.OperatorTerm({ operator: this.hasDisadvantage ? '-' : '+' }));
if (bardRallyFaces) { if (bardRallyFaces) {
const rallyDie = new foundry.dice.terms.Die({ faces: bardRallyFaces }); const rallyDie = new foundry.dice.terms.Die({ faces: bardRallyFaces });
if (this.hasAdvantage) { if (this.hasAdvantage) {
@ -401,13 +431,11 @@ export class DualityRoll extends D20Roll {
applyBaseBonus() { applyBaseBonus() {
this.options.roll.modifiers = []; this.options.roll.modifiers = [];
if(!this.options.roll.trait) return; if (!this.options.roll.trait) return;
this.options.roll.modifiers.push( this.options.roll.modifiers.push({
{ label: `DAGGERHEART.Abilities.${this.options.roll.trait}.name`,
label: `DAGGERHEART.Abilities.${this.options.roll.trait}.name`, value: Roll.replaceFormulaData(`@traits.${this.options.roll.trait}.total`, this.data)
value: Roll.replaceFormulaData(`@traits.${this.options.roll.trait}.total`, this.data) });
}
);
} }
static postEvaluate(roll, config = {}) { static postEvaluate(roll, config = {}) {

View file

@ -124,13 +124,13 @@ export const getCommandTarget = () => {
export const setDiceSoNiceForDualityRoll = (rollResult, advantageState) => { export const setDiceSoNiceForDualityRoll = (rollResult, advantageState) => {
const diceSoNicePresets = getDiceSoNicePresets(); const diceSoNicePresets = getDiceSoNicePresets();
rollResult.dice[0].options.appearance = diceSoNicePresets.hope; rollResult.dice[0].options = { appearance: diceSoNicePresets.hope };
rollResult.dice[1].options.appearance = diceSoNicePresets.fear; rollResult.dice[1].options = { appearance: diceSoNicePresets.fear }; //diceSoNicePresets.fear;
if (rollResult.dice[2]) { if (rollResult.dice[2]) {
if (advantageState === true) { if (advantageState === true) {
rollResult.dice[2].options.appearance = diceSoNicePresets.advantage; rollResult.dice[2].options = { appearance: diceSoNicePresets.advantage };
} else if (advantageState === false) { } else if (advantageState === false) {
rollResult.dice[2].options.appearance = diceSoNicePresets.disadvantage; rollResult.dice[2].options = { appearance: diceSoNicePresets.disadvantage };
} }
} }
}; };

View file

@ -123,7 +123,7 @@
<div class="dice-result"> <div class="dice-result">
<div class="dice-tooltip"> <div class="dice-tooltip">
<div class="wrapper"> <div class="wrapper">
{{> 'systems/daggerheart/templates/chat/parts/damage-chat.hbs' damage=damage noTitle=true}} {{!-- {{> 'systems/daggerheart/templates/chat/parts/damage-chat.hbs' damage=damage noTitle=true}} --}}
</div> </div>
</div> </div>
</div> </div>