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 .
×

Testing Succes against a range of results with multiple succes targets

I've created a TTRPG system where the player can roll up to 6 dice of a range from D2 - D12.  The dice are considered a 'Succes' if they are 'Even' so I've been using the following macro /roll {?{Number of Dice}d10s%2}=0 The problem is when using a tool/weapon they player can 'overroll' and use their 'Attribute' dice value instead of the tool/weapon damage dice, in this instance any roll above the damage dice would be a success so  /roll {?{Number of Dice}d10s}>?{Item Damage Dice} but also any Even number below Item Damage Dice would be a succes, is there anyway I can check for both on the sme roll without going into API? Bonus : Also any way of highlighting the success dice like with crits? Examples of Rolls: Attacking with a D6 weapon with a 'Power' of D10 and 3 levels of 'Training' = 4D10 (3, 4, 8,9) so the 4, 8, and 9 are all successes
1599118611
GiGs
Pro
Sheet Author
API Scripter
I cant think of a way to do this. Maybe Ziechael or Oosh will have an idea.
1599128430

Edited 1599128579
Oosh
Sheet Author
API Scripter
Had a crack at it yesterday, had a half-written post, then rage-quit. Sorry :) I was actually surprised the modulo even works in that code... it prints out to chat like it isn't working, but... it seems to give the right results? But yeah... either impossible or needs a massive flash of genius. You can get the even and greater-than conditions both working, but you'll get double-dipping (e.g. if your target number is 6, an 8 will give 2 successes, one for even and one for over 6). /me deftly passes the ball backwards to Ziechael edit - just to be clear, you can use some rule edits or rollable tables  to achieve the same probabilities with some tinkering... but I'm going to assume that isn't what you want.
1599133472
David M.
Pro
API Scripter
Yeah, this seems like it is going to be stymied by the inability to perform operations on re-used dice rolls. Pretty trivial with an api script, but I don't see how to get around it without one :/
1599136504
Ziechael
Forum Champion
Sheet Author
API Scripter
Smells like an API script to me but I've never let that stop me before, if the people already posting are stumped then I wouldn't hold out much hope for a vanilla solution... But, when I get a moment (not around my computer much the next few days sorry) I'll definitely see if I can hack something together that fits the bill ;)
1599485669

Edited 1599493163
David M.
Pro
API Scripter
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); } } }); });
1599495897
Ziechael
Forum Champion
Sheet Author
API Scripter
Oosh said: /me deftly passes the ball backwards to Ziechael /me screams in frustration and punts the ball out of the stadium in a fit of rage Back in the virtual office and thought I'd take a look at this... now I have a headache and I've failed to come up with anything even remotely approximating what you want... sorry. Seems like it might be an API solution, a manual one or nothing. Now, if you'll excuse me, I need to go tell my kids that their father is a failure who will never amount to anything.
1599532996
Oosh
Sheet Author
API Scripter
Nice, David. Ziechael said: Now, if you'll excuse me, I need to go tell my kids that their father is a failure who will never amount to anything. This is why I don't have children. Then again, they'd probably have figured it out themselves pretty quickly.
That's point I got to then posted in here 😅 could whack it out in c# in 10 mins but don't have the skill/ time to build roll20 from the ground up as well Haha Oosh said: Had a crack at it yesterday, had a half-written post, then rage-quit. Sorry :)
Thank you all for your time and effort, might have to take the plunge, interactive character sheets would super helpful for my test subjects to grok the game as well so might be a worthy investment.