Following up on some stale threads as I was bored this morning and I threw together a quick and dirty script. I know this is a Pro only solution, but just in case you were on the fence ;) Meanwhile, hopefully Ziechael can come through with that free solution! Example syntax !xdn 5d6 //base roll, no target supplied
!xdn 5d6 6 //target supplied
A few output examples (EDIT - just noticed this pic is out of date. The trailing commas in the rolls section won't appear in the output) EDIT 2 -- GiGs pointed out a couple of oversights with the error handling that could have potentially cause problems. I've edited the code below to reflect those issues. Thanks, GiGs! on('ready',function()
{
on('chat:message',function(msg){
if(msg.type=='api' && msg.content.indexOf('!xdn')==0) {
let who;
try {
const scriptName = 'xdn';
let target, vals, numRolls, dieSize, i;
let displayRolls = '';
let successes = 0;
let rolls = [];
let results = [];
who = getObj('player',msg.playerid).get('_displayname');
let args = msg.content.toLowerCase().split(/\s+/);
if (args.length > 1) {
//parse arguments, with some error checking
if (args[1].match(/d/)) {
vals = args[1].split('d')
numRolls = parseInt(vals[0]);
if (isNaN(numRolls)) {
sendChat(scriptName, `/w "${who}" `+ 'Error. Invalid number of rolls \"' + numRolls + '\"');
return;
}
numRolls = Math.min(numRolls, 6); //max of 6 dice
dieSize = parseInt(vals[1]);
if (isNaN(dieSize)) {
sendChat(scriptName, `/w "${who}" `+ 'Error. Invalid die size \"' + dieSize + '\"');
return;
}
} else {
sendChat(scriptName, `/w "${who}" `+ 'Error. Expected \"d\", e.g. 3d6.');
return;
}
//optional target number from user
if (args.length > 2) {
target = parseInt(args[2]);
if (isNaN(target)) {
sendChat(scriptName, `/w "${who}" `+ 'Error. Invalid target number \"' + target + '\"');
return;
}
}
//roll the dice
for (i = 0; i < numRolls; i++) {
rolls.push(randomInteger(dieSize));
}
//sort the rolls before determining results, for display later
rolls.sort((a,b)=>a-b);
//determine successes (even numbers, PLUS odd numbers greater than target, if supplied)
for (i = 0; i < numRolls; i++) {
//even rolls. pass
if (rolls[i] % 2 === 0) {
results.push(1);
successes += 1;
} else {
//odd rolls
if (target) {
//check if target number specified
if (rolls[i] > target) {
//odd roll, greater than target. pass
results.push(1);
successes += 1;
} else {
//odd roll, less than target. fail
results.push(0);
}
} else {
//odd roll, no target number. fail
results.push(0);
}
}
}
//create output
displayRolls = rolls.map((r, idx) => {
if (results[idx]) {
return '[[' + r + ']]';
} else {
return r;
}
}).join(',');
if (target === undefined) {
target = 'N/A';
} else {
target = '[[' + target + ']]';
}
let subtitle = args.slice(1).join(' ');
let output = `&{template:default} {{name=Check Results (${subtitle})}} {{Rolls=${displayRolls}}} {{Target Num=${target}}} {{Successes=[[${successes}]]}}`;
sendChat(scriptName, `/w "${who}" `+ output);
} else {
sendChat(scriptName, `/w "${who}" `+ 'Error. Wrong number of arguments. Format is XdN <target num>.');
}
}
catch(err) {
sendChat('',`/w "${who}" `+ 'Error: ' + err.message);
}
}
});
});