Roll20 uses cookies to improve your experience on our site. Cookies enable you to enjoy certain features, social sharing functionality, and tailor message and display ads to your interests on our site and others. They also help us understand how our site is being used. By continuing to use our site, you consent to our use of cookies. Update your cookie preferences .
×
Create a free account

Exploding Dice but conditional

December 13 (4 years ago)
Jack M.
Sheet Author
Is there any way to set up the exploding dice function only when multiple max rolls are made? For instance, if I rolled 2d6 and both were 6, it would roll a 3rd die. As it works now, if either die gets a 6 it rolls again which isn't what I need.
December 13 (4 years ago)

Edited December 13 (4 years ago)
David M.
Pro
API Scripter

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%
You would then roll from the table using standard [[ 1t[TableName] ]] syntax.
December 13 (4 years ago)
Jack M.
Sheet Author

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.

December 14 (4 years ago)
David M.
Pro
API Scripter

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();
    });
})();

December 15 (4 years ago)

Edited December 15 (4 years ago)
David M.
Pro
API Scripter

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();
    });
})();