
Don't believe that is possible without using the api, assuming you wanted to see each individual roll.
If you just wanted the total roll (and limited to a single extra d6), you could easily make a rollable table and weight appropriately for the corresponding probabilities.
You would first have values 2-11, with normal 2d6 probabilities. There would be no roll of 12 in the table. Instead, there would be additional roll values 13-18, each with 1/6th the probability of rolling a 12. So probability of each of these would be [1/36]/6. Then, use a constant multiplier for all entries to get to whole number weights.
The final rollable table would be set up with the first two columns below:
Roll | Weight | Probability |
2 | 6 | 2.78% |
3 | 12 | 5.56% |
4 | 18 | 8.33% |
5 | 24 | 11.11% |
6 | 30 | 13.89% |
7 | 36 | 16.67% |
8 | 30 | 13.89% |
9 | 24 | 11.11% |
10 | 18 | 8.33% |
11 | 12 | 5.56% |
13 | 1 | 0.46% |
14 | 1 | 0.46% |
15 | 1 | 0.46% |
16 | 1 | 0.46% |
17 | 1 | 0.46% |
18 | 1 | 0.46% |
Yeah unfortunately. Was hoping there was a way to trick it into recognizing both numbers but alas. The way this mechanic works is just like regular exploding dice but it starts with two dice and both need to max roll, so it can expand beyond three if lucky. Oh well.
Got it. Here is a simple little one-off script that I think does what you are asking. Only explodes if the first two dice are maxed, then explodes normally for each max die rolled. Sums the total, with optional roll modifier. Outputs with default template, but you could play around with any other templates you have available.
Syntax:
!2dX <dieSize>
e.g. !2dX 6
or add optional roll modifier
!2dX <dieSize> <modifier>
e.g. !2dX 10 1
If you never have any mods you can just take those sections out of the code.
Example output, rolling some 2d2's and 2d6's with and without modifiers
Here's the script:
const dExplode = (() => { const version = '0.1.0'; const scriptName = '2dX'; const checkInstall = () => { log('-=> ' + scriptName + ' v' + version); }; const handleInput = (msg) => { let rolls = []; let rollMod = 0; let result; let displayRolls = ''; if (msg.type=="api" && msg.content.indexOf("!2dX") === 0 ) { try { who = getObj('player',msg.playerid).get('_displayname'); let args = msg.content.split(/\s+/); let dieType = parseInt(args[1]); if (args.length > 2) { rollMod = parseInt(args[2]); } //Initial rolls (2 dice of size dieType) rolls.push(randomInteger(dieType)); rolls.push(randomInteger(dieType)); displayRolls = `${rolls[0]}, ${rolls[1]}`; //check for double max rolls. Start exploding if (rolls[0] === dieType && rolls[1] === dieType) { let done = false; do { rolls.push(randomInteger(dieType)); displayRolls = displayRolls + `, ${rolls[rolls.length-1]}`; if (rolls[rolls.length-1] !== dieType) { done = true; } } while (done === false); } //calculate total roll result = rolls.reduce((a, b) => a + b, 0) + rollMod; //output displayRolls = '**' + displayRolls + '**'; //bold all the rolls //using default template let output = `&{template:default} {{name=2d${dieType}!}} {{Rolls=${displayRolls}}} {{Roll Mod=**${rollMod}**}} {{Result=[[${result}]]}}`; sendChat('', output); } catch(err) { sendChat('',`/w "${who}" `+ 'Error: ' + err.message); } }; }; const registerEventHandlers = () => { on('chat:message', handleInput); }; on('ready', () => { checkInstall(); registerEventHandlers(); }); })();
After chatting with Jack via PM, I added inline roll capability for the script input. Putting it here publicly in case anyone wants to use part of this as a template or starting point for their own custom die rolling scripts.
Examples
!2dX 6 [[1d4]]
!2dX 6 [[1d6 + @{Charname|AttributeName}]]
Updated script:
const dExplode = (() => { const version = '0.1.0'; const scriptName = '2dX'; const checkInstall = () => { log('-=> ' + scriptName + ' v' + version); }; function processInlinerolls(msg) { if(_.has(msg,'inlinerolls')){ return _.chain(msg.inlinerolls) .reduce(function(m,v,k){ var ti=_.reduce(v.results.rolls,function(m2,v2){ if(_.has(v2,'table')){ m2.push(_.reduce(v2.results,function(m3,v3){ m3.push(v3.tableItem.name); return m3; },[]).join(', ')); } return m2; },[]).join(', '); m['$[['+k+']]']= (ti.length && ti) || v.results.total || 0; return m; },{}) .reduce(function(m,v,k){ return m.replace(k,v); },msg.content) .value(); } else { return msg.content; } } const handleInput = (msg) => { let rolls = []; let rollMod = 0; let result; let displayRolls = ''; if (msg.type=="api" && msg.content.indexOf("!2dX") === 0 ) { try { who = getObj('player',msg.playerid).get('_displayname'); //Check for inline rolls in script input let inlineContent = processInlinerolls(msg); let args = inlineContent.split(/\s+/); let dieType = parseInt(args[1]); if (args.length > 2) { rollMod = parseInt(args[2]); } //Initial rolls (2 dice of size dieType) rolls.push(randomInteger(dieType)); rolls.push(randomInteger(dieType)); displayRolls = `${rolls[0]}, ${rolls[1]}`; //check for double max rolls. Start exploding if (rolls[0] === dieType && rolls[1] === dieType) { let done = false; do { rolls.push(randomInteger(dieType)); displayRolls = displayRolls + `, ${rolls[rolls.length-1]}`; if (rolls[rolls.length-1] !== dieType) { done = true; } } while (done === false); } //calculate total roll result = rolls.reduce((a, b) => a + b, 0) + rollMod; //output displayRolls = '**' + displayRolls + '**'; //bold all the rolls //using default template let output = `&{template:default} {{name=2d${dieType}!}} {{Rolls=${displayRolls}}} {{Roll Mod=**${rollMod}**}} {{Result=[[${result}]]}}`; sendChat('', output); } catch(err) { sendChat('',`/w "${who}" `+ 'Error: ' + err.message); } }; }; const registerEventHandlers = () => { on('chat:message', handleInput); }; on('ready', () => { checkInstall(); registerEventHandlers(); }); })();