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

Rolling x number of dice OR until y is rolled

I'm trying to figure out a macro or something that will allow me to roll a certain number of dice (to be inputted prior to the roll) and then stop rolling. Alternatively, if any of the dice rolled are equal to or below a certain value, then it will also stop rolling. Basically something like… Roll 10d100. If a dice rolled is equal to or less than 50, stop rolling dice. Any idea how this could be done?
1554815852
keithcurtis
Forum Champion
Marketplace Creator
API Scripter
Maybe one of the dice gurus can come up with a method, but in general dice macros don't allow for conditional logic. It's probably possible with an API script like Power Cards or with a Roll Template defined within the character sheet, and definitely possible with a dedicated API script.
1554818676
GiGs
Pro
Sheet Author
API Scripter
As Keith says, this is only possible for Pro users, using an API script or rolltemplate in a custom character sheet.
1554818783
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
All dice in a message are rolled simultaneously, so in the Roll20 roller there's no such thing as an order to the die roll. What's the game rule you are trying to handle? That might help explore the options.
It's not so much a game rule as it is a way of shortening the amount of time spent rolling in game/making things look a bit neater. We are using a homebrew system based on the Call of Cthulhu system where you roll a d100 and attempt to get equal to or lower than your skill value. In some cases you can only attempt a skill once a day, so sometimes we may spend a few days trying to succeed in it. Being able to roll up to 10 dice for example (10 days) but have the dice stop rolling automatically when one of the dice is equal to or below your skill value would mean not having to wonder how long you want to do it for, only what the maximum number of days would be. It also makes things look and feel a lot smoother than having to do it manually. Funny you should mention API Scripts and custom character sheets – our GM is a pro subscriber and I was too up until recently (cancelled the subscription as I no longer had a need for it). I had helped create a basic, custom character sheet with a roll template included, but I don't have any experience with JavaScript/API scripts. So we would be able to implement the script into the campaign if someone could supply the code for us. To reiterate what we need: Player decides maximum number of dice to be rolled. Begin rolling said dice. As soon as one of the dice rolled is equal to a (determined at the start) number or less than that number, stop rolling. [Optional] Display the total number of dice that were rolled at the end ("Total dice rolled: 5").
1555077630
The Aaron
Roll20 Production Team
API Scripter
Ok. Format is: !x ROLLS TARGET SIZE --DESCRIPTION Where: ROLLS - The number of times to try rolling. Defaults to 10 if omitted. TARGET - The number to attempt to be equal to or less than. Defaults to 50 if omitted. SIZE - The die size to roll on each attempt. Defaults to 100 if omitted. DESCRIPTION -- A text description to be displayed with the roll.  Not shown if omitted. Inline rolls are expanded, in case you calculate the number of rolls or the target based on attributes or adjudication. Examples: !x !x --A basic attempt !x 5 10 --Something hard !x 10 7 10 --Using d10s Let me know if you want any styling changes.  Cheers! Code: on('ready',()=>{ on('chat:message',(msg) => { let args; let cmds; let who; if('api' === msg.type) { if(msg.content.match(/^!x\b/) ){ who=(getObj('player',msg.playerid)||{get:()=>'API'}).get('_displayname'); if(_.has(msg,'inlinerolls')){ msg.content = _.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(); } args = msg.content.split(/\s+--/); cmds=args.shift().split(/\s+/).slice(1); let rolls = parseInt(cmds[0]); let target = parseInt(cmds[1]); let size = parseInt(cmds[2]); rolls = (!isNaN(rolls) ? rolls : 10); target = (!isNaN(target) ? target : 50); size = (!isNaN(size) ? size : 100); let tries = 0; let attempts = []; if(rolls>0){ do { attempts.push(randomInteger(size)); } while( (++tries < rolls) && (attempts[attempts.length-1]>target)); } let success = (rolls && !(attempts[attempts.length-1]>target)); let fmtSuccess=''; if(success){ fmtSuccess = `<span style="color: #090;font-weight:bold;">Success!</span> <code>${attempts[attempts.length-1]}</code> <b><=</b> <code>${target}</code> after <code>${attempts.length}</code> attempts. (<code>d${size}</code>)`; } else { fmtSuccess = `<span style="color: #c43c35;font-weight:bold;">Failure!</span> <code>${attempts.length}</code> rolls without being <b><=</b> <code>${target}</code> attempts. (<code>d${size}</code>)`; } let fmtRolls=attempts.map(r=>`<div style="display:inline-block; font-size: .8em; line-height: .8em; padding: .1em; margin: .1em; border: 1px solid #999; border-radius: .1em; background-color: #ccc; font-weight:bold;">${r}</div>`).join(''); let fmtDesc = (args.length && args[0].length) ? `<div>${args[0]}</div>` : ''; sendChat('',`<div style="padding:1px 3px;border: 1px solid #8B4513;background: #eeffee; color: #8B4513; font-size: 80%;"><div style="background-color: #ffeeee;"><b>${who}</b>: ${fmtSuccess}</div><div>${fmtRolls}</div>${fmtDesc}</div>`); } } }); });
1555080357

Edited 1555080506
Wow. That was quick. Works really really well. Thank you. I even renewed my subscription so that I don't need to bother my GM with making any modifications (I'll do it in my test game and then just transfer the code over to him). I figured out how to stylise it myself so there's no need to bother you with any of that. Just a few things that I can foresee us wanting: Have another code where, instead of manually typing in the values, you get pop-up boxes asking you to input the values (like with regular query macros). Some of the players aren't as computer savvy and may struggle with the syntax, so this can be an alternative. I can turn the chat command into a macro that they can just click, then have the pop-up boxes appear where they can input their values. Would that be possible? Another thing that may be nifty to have is an added Fumble calculation as well. Fumbles are a bit trickier to calculate mathematically (not really, but still). It would be something like this: Determine dice etc to be rolled. Determine value. Begin rolling. If any of the dice rolled are equal to 90+(skill value inputted/10, rounded down) or above, stop rolling dice (this is a fumble). If the player has a skill value between 1-9, a fumble is 90+. A skill value of 57 would mean that a player fumbles if they roll a 95+. If they have a skill value of 90-98, then a fumble is 99+. If they have a skill value of 99+, then a fumble is only ever 100. Probably getting a little too fancy now, but if the maximum number of dice to be rolled hasn't been reached after a fumble, a pop-up box asking the player if they would like to continue rolling the remaining dice would also be pretty nifty. If that's getting a little too technical then don't worry about it. Thanks a bunch for the code. Going to play around with it now.
1555081694
The Aaron
Roll20 Production Team
API Scripter
Passing Roll Queries will work: !x ?{Rolls|10} ?{Target|50} Adding in the skill value as a 4th positional input after the die size (or a 3rd before it) would be trivial, as would setting up the check for fumble, probably about 5 more lines of code.   One thing the API can't do is pop up a query to the player.  However, it could stop at that point and print a current state, then provide a button to the player to continue or finalize or some such.  Look at my Mutant Year Zero script and its push mechanics for an example.
Saw your mutant year zero push mechanic. It looks good. I think something like that would work well. Roll 10 dice, succeed/fumble after 3, get a button which allows you to roll the other 7 the same way.