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

Variable die size

I'm trying to create my first sheet so please bear with me. The system assigns a value to i.e. attr_strength of "A", "B", "C", or "D". The die rolled to check for success depends on the value of attr_strength: If attr_strength = "A" the die is 1d12 If attr_strength = "B" the die is 1d10 If attr_strength = "C" the die is 1d8 If attr_strength = "D" the die is 1d6 How can I make the die size depend on a variable?
1607771217
mrianmerry
Pro
Sheet Author
I had a similar desire with the PTA v3 sheet, and ended up settling on making the attributes a numerical value, with a display that varied based on that (thank you, sheet workers!) , and then using that in a roll template for output. So you'd have something like this: <input name="attr_strength" type="hidden" value="1" /> <button name="roll_strength_check" type="roll" value="&{{template:check-output}} {{attribute-level=@{strength}}}">Strength:</button> <select name="attr_strength_display"> <option value="a" selected>A</option> <option value="b">B</option> ... </select> ...... on("change:strength_display, function(event) { const str = event.newValue; var strength = 1; // doesn't hurt to keep the default value as a fallback, for whatever reason if (str === "b") strength = 2; else if (str === "c") strength = 3; else ... setAttrs({ strength: strength }); }); ...... <rolltemplate class="sheet-rolltemplate-check-output"> <!-- the rest of your roll template goes somewhere in this bit of course --> <tr class="rt-dice-output"> <td class="rt-output-label">Check:</td>     <!-- Here's the tricky bit, detailed in the link after this code block -->     {{#rollTotal() attribute-level 1}}     <td class="rt-output-value"> [[1d12]] </td>     {{/rollTotal() attribute-level 1}}     {{#rollTotal() attribute-level 2}}      <td class="rt-output-value"> [[1d10]] </td>     {{/rollTotal() attribute-level 2}}     {{#rollTotal() attribute-level 3}}      <td class="rt-output-value"> [[1d8]] </td>     {{/rollTotal() attribute-level 3}} </tr> </rolltemplate> While typing this, I had the idea of using the sheet worker to simply directly set the "attr_strength" value to the dice value you want to use; this is definitely a simpler approach and doesn't require you to make a roll template for displaying the output of whatever check you wanna do (although you should! they look so much nicer)  but it does come with the down-side of having the dice roll directly editable by users via the "Attributes & Abilities"  tab, where any enterprising cheat would find it harder to do so with the dice rolls embedded in the roll template HTML.
1607776732

Edited 1607776755
Thanks alot! Ian said: using the sheet worker to simply directly set the "attr_strength" value to the dice value you want to use Do you have time to show me how the "attr_strength" value (i.e. "10") could control the dice value? Would this work?: <button type='roll' name='roll_strengthtest' value='&{template:default} {{name=@{character_name}}} {{result=[[1d@{attr_strength}]]}}'></button>
The following works: <input name="attr_strengthdie" type="hidden" value="8"> <button type='roll' name='roll_strength' value='&{template:default} {{name=@{character_name}}} {{result=[[1d@{strengthdie}]]}}'></button> Now I'm struggling to change the value of attr_strengthdie when the value of attr_strength is changed. This sheetworker doesn't seem to do what I want it to do:     on("change:strength sheet:opened", function() {          getAttrs(["strength"], function(values) {                 let str = values.strength;             if (values.strength === "A") {                 let strdie = 12;             }             setAttrs({                                                 strengthdie: strdie;             });         });     });});
1607782541
mrianmerry
Pro
Sheet Author
Ahh, that's a common coding issue. Your "strdie" variable is out of scope for the "setAttrs" call. Try this: on("change:strength sheet:opened", function() { getAttrs(["strength"], function(values) {     const str = values.strength;     var strDie = 10; // Use your default value here - whatever the die would be when a character is first created     if (str === "A") strDie = 12;     setAttrs({ strengthdie: strDie }); }); }); The differences are that my "strDie" variable is declared before  the if check, so it's available for the "setAttrs" call to use it after  the if check has closed. (Feel free to not use a default value; you can totally just leave it empty if you need to! As below: ) var strDie = ""; if (str === "A") strDie = 12; setAttrs({ strengthdie: strDie });
Once again: thanks alot! This is what finally worked as I wanted it too: <label>STRENGTH</label><input type="text" name='attr_strength' class='sheet-short' value ='C'> <button type='roll' name='roll_strength' value='&{template:default} {{name=@{character_name}}} {{result=[[1d@{strengthdie}]]}}'></button> <script type="text/worker">     on("change:strength sheet:opened", function() {          getAttrs(["strength"], function(values) {                 const str = values.strength;             var strdie = 10;             if (str == "A") strdie = 12;             if (str == "B") strdie = 10;             if (str == "C") strdie = 8;             if (str == "D") strdie = 6;             setAttrs({strengthdie: strdie});         });     }); </script>
1607822845

Edited 1607822940
Oosh
Sheet Author
API Scripter
This won't do anything your code doesn't already do, but ternary operators can save you a bunch of space when you've got a heap of variables to set conditionally. It doesn't make much difference in this case, but it's something to keep in mind if you've got a whole bunch of IFs with single statements after them (I also got rid of 'B' since it's the same as your default value): <script type="text/worker"> on("change:strength sheet:opened", function() { getAttrs(["strength"], function(values) { const str = values.strength; let strdie = (str == 'A') ? 12 : (str == 'C') ? 8 : (str == 'D') ? 6 : 10; setAttrs({strengthdie: strdie}); }); }); </script> There's some flexibility in the placement of parentheses, but this is the way I find it most logical to read: the part in (parentheses) is your logic condition, followed by a question mark. The first value after the ? is "if truthy", the second value is "if falsy". In this case, they're chained together, with the final value of "10" being landed on if each condition returns falsy. A non-chained ternary is easier to read: let x = (y !== 0) ? 'y is non-zero' : 'y is zero' Again, this doesn't do anything an IF statement can't do, but it will save you a bunch of typing & tabbing in the right places. Also, if your players are inputting the strength value manually, it might be worth considering this: let str = values.strength.toLowerCase(); let strdie = (str === 'a') ? 12 : (str === 'c') ? 8 : (str === 'd') ? 6 : 10; to handle people who don't like using their shift key.