Sure thing! HTML <button type="action" name="act_roll">Roll!</button> This just creates the button that is going to trigger our javascript sheetworker. It works pretty similarly to a classic roll button, just without the value key. For the javascript, I'm going to put the walkthrough as comments in the code. JS // listen for the roll button being clicked (you'd likely have more than one button, and genericize some of this to work with all of them
on('clicked:roll',() => {
// Get the current values of the attributes we care about, just might and athletics for this demonstration
getAttrs(['might','athletics'],async (attributes) => {
// Ensure that the values contained in our attributes object are numerical. e.g. turn the string "1" into the number 1.
attributes.might = +attributes.might;
attributes.athletics = +attributes.athletics;
// Make an array of length equal to the value of might. This is really just a native implementation
// of the _.range function from the underscore library
let rollArray = [...Array(attributes.might).keys()]
// iterate over that array to create a dice expression for each point in might
.reduce((str,k) => {
// the dice expression is going to be d6 + the value of athletics. I didn't know what dice were supposed to be used, so just used d6 for demo.
str.push(`d6+${attributes.athletics}`);
// because we are in a reduce, we need to return the accumulator. This is just boilerplatey js stuff
return str;
},[])
// we take the array of roll expressions (e.g. for a might of 2 and atheltics of 1; ["d6+1","d6+1"]), and combine it into a comma separated string.
.join(',');
// The reason for the comma separated string is that we then insert this into a grouped success roll. This will roll each die, and total the number
// of successes. Note that r20's dice expression is weird, and ">" in a dice expression actually means >=, so this would be a success on anything
// greater than 6.
// We assemble the full roll string. This roll string is extremely barebones for the demo, but would be equivalent to whatever you are currently
// using in your roll button's value property.
const rollString = `&{template:default} {{roll=[[{${rollArray}}>7]]}}`
// send the message to chat. We wait for the result so that we can tell roll20 to finish the roll
const roll = await startRoll(rollString);
// Finish the roll. We could have also done manipulation of the display values for any rolls in our message. See the wiki on startRoll for more info.
finishRoll(roll.rollId);
})
}) And then, in case it isn't clear, all that JS would go inside a script tag in your sheet's html: <script type="text/worker">
// the js code above, along with any other js you are using goes here
</script>