mirror of
https://github.com/Foundryborne/daggerheart.git
synced 2026-06-06 04:44:16 +02:00
[Feature] Full Rerolls (#1928)
Some checks are pending
Project CI / build (24.x) (push) Waiting to run
Some checks are pending
Project CI / build (24.x) (push) Waiting to run
* Initial * Removed damage dialogs * Fixed DamageReroll * Fixed d20 modifiers * Fixed * Fixed DiceSoNice multiple damageType reroll * Added triggerChatRollFx * Fixed dice.denomination being lost on damage reroll
This commit is contained in:
parent
ddf4747310
commit
f1a530f57f
23 changed files with 164 additions and 830 deletions
|
|
@ -1,4 +1,5 @@
|
|||
import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs';
|
||||
import { triggerChatRollFx } from '../helpers/utils.mjs';
|
||||
import DHRoll from './dhRoll.mjs';
|
||||
|
||||
export default class D20Roll extends DHRoll {
|
||||
|
|
@ -224,4 +225,15 @@ export default class D20Roll extends DHRoll {
|
|||
resetFormula() {
|
||||
return (this._formula = this.constructor.getFormula(this.terms));
|
||||
}
|
||||
|
||||
async reroll(options) {
|
||||
const result = await super.reroll(options);
|
||||
if (this instanceof game.system.api.dice.DualityRoll) return result;
|
||||
|
||||
if (options?.liveRoll) {
|
||||
await triggerChatRollFx([result]);
|
||||
}
|
||||
|
||||
return result;
|
||||
}
|
||||
}
|
||||
|
|
|
|||
|
|
@ -1,5 +1,5 @@
|
|||
import DamageDialog from '../applications/dialogs/damageDialog.mjs';
|
||||
import { parseRallyDice } from '../helpers/utils.mjs';
|
||||
import { parseRallyDice, triggerChatRollFx } from '../helpers/utils.mjs';
|
||||
import DHRoll from './dhRoll.mjs';
|
||||
|
||||
export default class DamageRoll extends DHRoll {
|
||||
|
|
@ -18,7 +18,12 @@ export default class DamageRoll extends DHRoll {
|
|||
if (config.evaluate !== false) for (const roll of config.roll) await roll.roll.evaluate();
|
||||
|
||||
roll._evaluated = true;
|
||||
const parts = config.roll.map(r => this.postEvaluate(r));
|
||||
|
||||
const parts = [];
|
||||
for (const roll of config.roll) {
|
||||
parts.push(this.postEvaluate(roll));
|
||||
roll.roll = JSON.stringify(roll.roll.toJSON());
|
||||
}
|
||||
|
||||
config.damage = this.unifyDamageRoll(parts);
|
||||
}
|
||||
|
|
@ -38,25 +43,24 @@ export default class DamageRoll extends DHRoll {
|
|||
const chatMessage = config.source?.message
|
||||
? ui.chat.collection.get(config.source.message)
|
||||
: getDocumentClass('ChatMessage').applyMode({}, config.rollMode ?? 'public');
|
||||
|
||||
const diceRolls = [];
|
||||
if (game.modules.get('dice-so-nice')?.active) {
|
||||
const pool = foundry.dice.terms.PoolTerm.fromRolls(
|
||||
Object.values(config.damage).flatMap(r => r.parts.map(p => p.roll))
|
||||
),
|
||||
diceRoll = Roll.fromTerms([pool]);
|
||||
await game.dice3d.showForRoll(
|
||||
diceRoll,
|
||||
game.user,
|
||||
true,
|
||||
chatMessage.whisper?.length > 0 ? chatMessage.whisper : null,
|
||||
chatMessage.blind
|
||||
);
|
||||
config.mute = true;
|
||||
const pool = foundry.dice.terms.PoolTerm.fromRolls(
|
||||
Object.values(config.damage).flatMap(r => r.parts.map(p => p.roll))
|
||||
);
|
||||
diceRolls.push(Roll.fromTerms([pool]));
|
||||
}
|
||||
|
||||
await triggerChatRollFx(diceRolls, {
|
||||
whisper: chatMessage.whisper?.length > 0 ? chatMessage.whisper : null,
|
||||
blind: chatMessage.blind
|
||||
});
|
||||
await super.buildPost(roll, config, message);
|
||||
|
||||
if (config.source?.message) {
|
||||
chatMessage.update({ 'system.damage': config.damage });
|
||||
|
||||
if (!game.modules.get('dice-so-nice')?.active) foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice });
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -319,9 +323,10 @@ export default class DamageRoll extends DHRoll {
|
|||
const newIndex = parsedDiceTerms[dice].results.length;
|
||||
await term.reroll(`/r1=${termResult.result}`);
|
||||
|
||||
const diceRolls = [];
|
||||
if (game.modules.get('dice-so-nice')?.active) {
|
||||
const newResult = parsedDiceTerms[dice].results[newIndex];
|
||||
const diceSoNiceRoll = {
|
||||
diceRolls.push({
|
||||
_evaluated: true,
|
||||
dice: [
|
||||
new foundry.dice.terms.Die({
|
||||
|
|
@ -332,11 +337,10 @@ export default class DamageRoll extends DHRoll {
|
|||
})
|
||||
],
|
||||
options: { appearance: {} }
|
||||
};
|
||||
|
||||
await game.dice3d.showForRoll(diceSoNiceRoll, game.user, true);
|
||||
});
|
||||
}
|
||||
|
||||
await triggerChatRollFx(diceRolls);
|
||||
await parsedRoll.evaluate();
|
||||
|
||||
const results = parsedRoll.dice[dice].results.map(result => ({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,5 @@
|
|||
import D20RollDialog from '../applications/dialogs/d20RollDialog.mjs';
|
||||
import { triggerChatRollFx } from '../helpers/utils.mjs';
|
||||
|
||||
export default class DHRoll extends Roll {
|
||||
baseTerms = [];
|
||||
|
|
@ -75,9 +76,7 @@ export default class DHRoll extends Roll {
|
|||
}
|
||||
|
||||
if (config.skips?.createMessage) {
|
||||
if (game.modules.get('dice-so-nice')?.active) {
|
||||
await game.dice3d.showForRoll(roll, game.user, true);
|
||||
}
|
||||
await triggerChatRollFx([roll]);
|
||||
} else if (!config.source?.message) {
|
||||
config.message = await this.toMessage(roll, config);
|
||||
}
|
||||
|
|
@ -85,6 +84,7 @@ export default class DHRoll extends Roll {
|
|||
|
||||
static postEvaluate(roll, config = {}) {
|
||||
return {
|
||||
...roll.options.roll,
|
||||
total: roll.total,
|
||||
formula: roll.formula,
|
||||
dice: roll.dice.map(d => ({
|
||||
|
|
|
|||
|
|
@ -1,4 +1,4 @@
|
|||
import { ResourceUpdateMap } from '../../data/action/baseAction.mjs';
|
||||
import { updateResourcesForDualityReroll } from '../helpers.mjs';
|
||||
|
||||
export default class DualityDie extends foundry.dice.terms.Die {
|
||||
constructor(options) {
|
||||
|
|
@ -12,24 +12,6 @@ export default class DualityDie extends foundry.dice.terms.Die {
|
|||
return roll.withHope ? 1 : roll.withFear ? -1 : 0;
|
||||
}
|
||||
|
||||
#updateResources(oldDuality, newDuality, actor) {
|
||||
const { hopeFear } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
|
||||
if (game.user.isGM ? !hopeFear.gm : !hopeFear.players) return;
|
||||
|
||||
const updates = [];
|
||||
const hope = (newDuality >= 0 ? 1 : 0) - (oldDuality >= 0 ? 1 : 0);
|
||||
const stress = (newDuality === 0 ? 1 : 0) - (oldDuality === 0 ? 1 : 0);
|
||||
const fear = (newDuality === -1 ? 1 : 0) - (oldDuality === -1 ? 1 : 0);
|
||||
|
||||
if (hope !== 0) updates.push({ key: 'hope', value: hope, total: -1 * hope, enabled: true });
|
||||
if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, total: stress, enabled: true });
|
||||
if (fear !== 0) updates.push({ key: 'fear', value: fear, total: -1 * fear, enabled: true });
|
||||
|
||||
const resourceUpdates = new ResourceUpdateMap(actor);
|
||||
resourceUpdates.addResources(updates);
|
||||
resourceUpdates.updateResources();
|
||||
}
|
||||
|
||||
async reroll(modifier, options) {
|
||||
const oldDuality = this.#getDualityState(options.liveRoll.roll);
|
||||
await super.reroll(modifier, options);
|
||||
|
|
@ -57,7 +39,7 @@ export default class DualityDie extends foundry.dice.terms.Die {
|
|||
if (options.liveRoll.isReaction) return;
|
||||
|
||||
const newDuality = this.#getDualityState(options.liveRoll.roll);
|
||||
this.#updateResources(oldDuality, newDuality, options.liveRoll.actor);
|
||||
updateResourcesForDualityReroll(oldDuality, newDuality, options.liveRoll.actor);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
|
|||
|
|
@ -1,6 +1,8 @@
|
|||
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 { updateResourcesForDualityReroll } from './helpers.mjs';
|
||||
|
||||
export default class DualityRoll extends D20Roll {
|
||||
_advantageNumber = 1;
|
||||
|
|
@ -130,13 +132,7 @@ export default class DualityRoll extends D20Roll {
|
|||
}
|
||||
|
||||
createBaseDice() {
|
||||
if (
|
||||
this.dice[0] instanceof game.system.api.dice.diceTypes.HopeDie &&
|
||||
this.dice[1] instanceof game.system.api.dice.diceTypes.FearDie
|
||||
) {
|
||||
this.terms = [this.terms[0], this.terms[1], this.terms[2]];
|
||||
return;
|
||||
}
|
||||
this.terms = [this.terms[0], this.terms[1], this.terms[2]];
|
||||
|
||||
this.terms[0] = new game.system.api.dice.diceTypes.HopeDie({
|
||||
faces: this.data.rules.dualityRoll?.defaultHopeDice ?? 12
|
||||
|
|
@ -388,4 +384,40 @@ export default class DualityRoll extends D20Roll {
|
|||
if (currentCombatant?.actorId == config.data.id) ui.combat.setCombatantSpotlight(currentCombatant.id);
|
||||
}
|
||||
}
|
||||
|
||||
async reroll(options) {
|
||||
const oldDuality = this.withHope ? 1 : this.withFear ? -1 : 0;
|
||||
const rerolled = DualityRoll.fromData((await super.reroll(options)).toJSON());
|
||||
|
||||
if (options?.liveRoll) {
|
||||
if (game.modules.get('dice-so-nice')?.active) {
|
||||
const diceAppearance = await getDiceSoNicePresets(
|
||||
rerolled,
|
||||
rerolled.dHope.denomination,
|
||||
rerolled.dFear.denomination
|
||||
);
|
||||
rerolled.dHope.options.appearance = diceAppearance.hope.appearance;
|
||||
rerolled.dFear.options.appearance = diceAppearance.fear.appearance;
|
||||
if (rerolled.dAdvantage) rerolled.dAdvantage.options.appearance = diceAppearance.advantage.appearance;
|
||||
if (rerolled.dDisadvantage)
|
||||
rerolled.dDisadvantage.options.appearance = diceAppearance.disadvantage.appearance;
|
||||
|
||||
await game.dice3d.showForRoll(rerolled, game.user, true);
|
||||
} else {
|
||||
foundry.audio.AudioHelper.play({ src: CONFIG.sounds.dice });
|
||||
}
|
||||
|
||||
if (this.options.actionType === 'reaction') return;
|
||||
|
||||
const newDuality = rerolled.withHope ? 1 : rerolled.withFear ? -1 : 0;
|
||||
const actor = await foundry.utils.fromUuid(this.options.source.actor);
|
||||
updateResourcesForDualityReroll(oldDuality, newDuality, actor);
|
||||
}
|
||||
|
||||
return rerolled;
|
||||
}
|
||||
|
||||
fromJSON(json) {
|
||||
return super.fromJSON(json);
|
||||
}
|
||||
}
|
||||
|
|
|
|||
17
module/dice/helpers.mjs
Normal file
17
module/dice/helpers.mjs
Normal file
|
|
@ -0,0 +1,17 @@
|
|||
export function updateResourcesForDualityReroll(oldDuality, newDuality, actor) {
|
||||
const { hopeFear } = game.settings.get(CONFIG.DH.id, CONFIG.DH.SETTINGS.gameSettings.Automation);
|
||||
if (game.user.isGM ? !hopeFear.gm : !hopeFear.players) return;
|
||||
|
||||
const updates = [];
|
||||
const hope = (newDuality >= 0 ? 1 : 0) - (oldDuality >= 0 ? 1 : 0);
|
||||
const stress = (newDuality === 0 ? 1 : 0) - (oldDuality === 0 ? 1 : 0);
|
||||
const fear = (newDuality === -1 ? 1 : 0) - (oldDuality === -1 ? 1 : 0);
|
||||
|
||||
if (hope !== 0) updates.push({ key: 'hope', value: hope, total: -1 * hope, enabled: true });
|
||||
if (stress !== 0) updates.push({ key: 'stress', value: -1 * stress, total: stress, enabled: true });
|
||||
if (fear !== 0) updates.push({ key: 'fear', value: fear, total: -1 * fear, enabled: true });
|
||||
|
||||
const resourceUpdates = new ResourceUpdateMap(actor);
|
||||
resourceUpdates.addResources(updates);
|
||||
resourceUpdates.updateResources();
|
||||
}
|
||||
Loading…
Add table
Add a link
Reference in a new issue