From c3d0495d0ca7868f22475d04e7d5498f168d887c Mon Sep 17 00:00:00 2001 From: Veilza Date: Tue, 27 Feb 2024 22:45:09 -0600 Subject: [PATCH] Willpower reroll update --- css/parts/chat.css | 15 ++++--- module/main.js | 5 ++- module/scripts/rolls/roll-message.js | 7 +++ module/scripts/system-rolls.js | 65 +++++++++++++++------------ module/scripts/willpower-reroll.js | 66 +++++++++++++++++++++++++--- templates/chat/roll-message.hbs | 4 +- 6 files changed, 120 insertions(+), 42 deletions(-) diff --git a/css/parts/chat.css b/css/parts/chat.css index 9dd55464..e9659b86 100644 --- a/css/parts/chat.css +++ b/css/parts/chat.css @@ -109,12 +109,6 @@ border-color: black; } -.roll-img.hunger-dice.rerolled { - background: #7b7b7b80; - border-color: #d3d3d3; - filter: invert(1); -} - .roll-img.desperation-dice { background: black; border-color: #cc6d28; @@ -128,4 +122,13 @@ .roll-img.rage-dice { background: #9b0b00; border-color: #330300; +} + +.roll-img.rerolled { + background: #7b7b7b80; +} + +.roll-img.hunger-dice.rerolled, .roll-img.rage-dice.rerolled { + border-color: #d3d3d3; + filter: invert(1); } \ No newline at end of file diff --git a/module/main.js b/module/main.js index 523f195c..c9cc88ac 100644 --- a/module/main.js +++ b/module/main.js @@ -155,8 +155,11 @@ Hooks.on('getChatLogEntryContext', (html, options) => { // Only show this context menu if there are re-rollable dice in the message const rerollableDice = li.find('.rerollable').length + // Only show this context menu if there's not any already rerolled dice in the message + const rerolledDice = li.find('.rerolled').length + // All must be true to show the reroll dialog - return (game.user.isGM || message.isAuthor) && (rerollableDice > 0) + return (game.user.isGM || message.isAuthor) && (rerollableDice > 0) && (rerolledDice === 0) }, callback: li => willpowerReroll(li) }) diff --git a/module/scripts/rolls/roll-message.js b/module/scripts/rolls/roll-message.js index 7dba6296..b84456db 100644 --- a/module/scripts/rolls/roll-message.js +++ b/module/scripts/rolls/roll-message.js @@ -64,6 +64,9 @@ export async function generateRollMessage ({ let dieResult, dieImg, dieAltText const dieClasses = ['roll-img', 'rerollable'] + // Mark any die that were rerolled / not used + if (die.discarded) dieClasses.push(['rerolled']) + // Basic die results if (die.result === 10) dieResult = 'critical' // Critical successes else if (die.result < 10 && die.result > 5) dieResult = 'success' // Successes @@ -103,6 +106,8 @@ export async function generateRollMessage ({ // Increase the number of criticals collected across the dice if (dieResult === 'critical') criticals++ + + die.index = index }) // Add in critical data as its own property @@ -179,6 +184,8 @@ export async function generateRollMessage ({ // Increase the number of criticals collected across the dice if (dieResult === 'critical') criticals++ if (dieResult === 'criticalFailure' || dieResult === 'bestial' || dieResult === 'brutal') critFails++ + + die.index = index }) // Add in critical data as its own properties diff --git a/module/scripts/system-rolls.js b/module/scripts/system-rolls.js index bdd60865..2f6d1b1b 100644 --- a/module/scripts/system-rolls.js +++ b/module/scripts/system-rolls.js @@ -30,6 +30,7 @@ class WOD5eDice { * @param rerollHunger (Optional, default false) Whether to reroll failed hunger dice * @param selectors (Optional, default []) Any selectors to use when compiling situational modifiers * @param macro (Optional, default '') A macro to run after the roll has been made + * @param disableMessageOutput (optional, default false) Whether to display the message output of a roll * */ static async Roll ({ @@ -50,7 +51,8 @@ class WOD5eDice { rollMode = game.settings.get('core', 'rollMode'), rerollHunger = false, selectors = [], - macro = '' + macro = '', + disableMessageOutput = false }) { // Define the actor's gamesystem, defaulting to 'mortal' if it's not in the systems list const system = WOD5E.Systems.getList().find(obj => actor.system.gamesystem in obj) ? actor.system.gamesystem : 'mortal' @@ -73,31 +75,6 @@ class WOD5eDice { rerollHunger }) - // Send the roll to chat - const roll = await new Roll(rollFormula, data).roll({ - async: true - }) - - // Handle failures for werewolves and vampires - if (roll.terms[2]) await handleFailure(system, roll.terms[2].results) - - // Handle willpower damage - if (willpowerDamage > 0 && game.settings.get('vtm5e', 'automatedWillpower')) _damageWillpower(actor, willpowerDamage) - - // Send the results of the roll back to any functions that need it - if (callback) callback(roll) - - // Run any macros that need to be ran - if (macro && game.macros.get(macro)) { - game.macros.get(macro).execute({ - actor, - token: actor.token ?? actor.getActiveTokens[0] - }) - } - - // The below isn't needed if there's no dice being rolled - if (parseInt(inputBasicDice) === 0 && parseInt(inputAdvancedDice) === 0) return roll - // Determine any active modifiers const activeModifiers = [] if ($form) { @@ -146,6 +123,34 @@ class WOD5eDice { } } + // Send the roll to chat + const roll = await new Roll(rollFormula, data).roll({ + async: true + }) + + // Handle failures for werewolves and vampires + if (roll.terms[2]) await handleFailure(system, roll.terms[2].results) + + // Handle willpower damage + if (willpowerDamage > 0 && game.settings.get('vtm5e', 'automatedWillpower')) _damageWillpower(actor, willpowerDamage) + + // Send the results of the roll back to any functions that need it + if (callback) callback(roll) + + // Run any macros that need to be ran + if (macro && game.macros.get(macro)) { + game.macros.get(macro).execute({ + actor, + token: actor.token ?? actor.getActiveTokens[0] + }) + } + + // The below isn't needed if there's no dice being rolled + if (parseInt(inputBasicDice) === 0 && parseInt(inputAdvancedDice) === 0) return roll + + // The below isn't needed if disableMessageOutput is set to true + if (disableMessageOutput) return roll + // Construct the proper message content from the generateRollMessage function const content = await generateRollMessage({ system, @@ -161,7 +166,13 @@ class WOD5eDice { // Post the message to the chat roll.toMessage({ speaker: ChatMessage.getSpeaker({ actor }), - content + content, + flags: { + system, + title, + flavor, + activeModifiers + } }, { rollMode: $form ? $form.find('[name=rollMode]').val() : rollMode diff --git a/module/scripts/willpower-reroll.js b/module/scripts/willpower-reroll.js index f734fb67..1a5f1c6d 100644 --- a/module/scripts/willpower-reroll.js +++ b/module/scripts/willpower-reroll.js @@ -2,6 +2,7 @@ // Import modules import { WOD5eDice } from './system-rolls.js' +import { generateRollMessage } from './rolls/roll-message.js' /** * Initalise willpower rerolls and its functions @@ -84,8 +85,8 @@ export const willpowerReroll = async (roll) => { // For now this works well enough as "roll three new dice" async function rerollDie (roll) { // Variables - const diceSelected = $('.willpower-reroll .selected').length - const rageDiceSelected = $('.willpower-reroll .selected .rage-dice').length + const diceSelected = $('.willpower-reroll .selected') + const rageDiceSelected = $('.willpower-reroll .selected .rage-dice') const selectors = ['willpower', 'willpower-reroll'] // Get the actor associated with the message @@ -95,15 +96,68 @@ export const willpowerReroll = async (roll) => { const actor = game.actors.get(message.speaker.actor) // If there is at least 1 die selected and aren't any more than 3 die selected, reroll the total number of die and generate a new message. - if ((diceSelected > 0) && (diceSelected < 4)) { + if ((diceSelected.length > 0) && (diceSelected.length < 4)) { WOD5eDice.Roll({ - basicDice: diceSelected - rageDiceSelected, - advancedDice: rageDiceSelected, + basicDice: diceSelected.length - rageDiceSelected.length, + advancedDice: rageDiceSelected.length, title: game.i18n.localize('WOD5E.Chat.WillpowerReroll'), actor, willpowerDamage: 1, quickRoll: true, - selectors + selectors, + disableMessageOutput: true, + callback: async (reroll) => { + let messageRolls = message.rolls + + diceSelected.each(function (index) { + const dieHTML = diceSelected.eq(index) + const imgElement = dieHTML.find('img') + + if (!imgElement.length) { + console.error('Image element not found in dieHTML:', dieHTML) + return // Skip this iteration if image element is not found + } + + const dieIndex = imgElement.data('index') + + if (imgElement.hasClass('rage-dice')) { + const die = messageRolls[0].terms[2].results.find(die => die.index === dieIndex) + + if (die) { + die.discarded = true + } else { + console.error('Die not found in rage diceset:', dieIndex) + } + } else { + const die = messageRolls[0].terms[0].results.find(die => die.index === dieIndex) + + if (die) { + die.discarded = true + } else { + console.error('Die not found in base diceset:', dieIndex) + } + } + }) + + // Merge "results" arrays + messageRolls[0].terms[0].results = messageRolls[0].terms[0].results.concat(reroll.terms[0].results) + messageRolls[0].terms[2].results = messageRolls[0].terms[2].results.concat(reroll.terms[2].results) + + // Update the "content" field + const newContent = await generateRollMessage({ + system: message.flags.system, + roll: messageRolls[0], + data: message.flags.data, + title: message.flags.title, + flavor: message.flags.flavor, + activeModifiers: message.flags.activeModifiers + }) + + message.update({ + content: newContent, + rolls: messageRolls + }) + } }) } } diff --git a/templates/chat/roll-message.hbs b/templates/chat/roll-message.hbs index 92d0fffa..64b0cada 100644 --- a/templates/chat/roll-message.hbs +++ b/templates/chat/roll-message.hbs @@ -9,10 +9,10 @@
{{#each basicDice.results as |die key|}} - {{die.altText}} + {{die.altText}} {{/each}} {{#each advancedDice.results as |die key|}} - {{die.altText}} + {{die.altText}} {{/each}} {{#if flavor}}