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

Switch/Case Function use in Character Sheet

Hi all, I am having difficulty finding any information on if/how to code a case statement function in a character sheet I have a process where I have a button push to roll a 1-100 value. which has an input value from 1-10, based on that input (case 1; case 2; etc) it will set a value to a variable which will then be subtracted from the 1-100 roll to give the end result. Any help with this would be appreciated
1643790518
GiGs
Pro
Sheet Author
API Scripter
Can you describe that in more detail. It's unclear whether you want to do something in the print to chat, or to make a change on the character sheet. If it's a roll to chat, look at the wiki for reollTemplates, and the logic helper functions.
1643823571
John D.
Pro
Sheet Author
There may be other ways to handle this, but the way I accomplish dynamic roll outputs is by doing all the calculations and variable setting upfront and express them as roll template variables.  Then, as GiGs suggested, use the roll template helper functions against the dice output to determine which roll template variables to use in the chat message.  To that end, don't get hung up on using switch/case but consider where you want to end up and work it back from there. As an example, in my sheet I don't roll for damage but determine damage as a percentage of the max based on the dice roll.  All of that is calculated upfront and embedded in the dice roll value when a character "arms" the weapon.  In the example below, assume that we're using 1d20 "to hit". JS: const damage = parseInt(value[`repeating_weapon_${rowID}_damage`]); const dam1 = Math.round(damage*0.05); const dam2 = Math.round(damage*0.1); const dam3 = Math.round(damage*0.15); ... const dam19 = Math.round(damage*0.95); const dam20 = damage; const rollButtonValue = `&{template:attack} {{roll=1d20}} {{dam1=${dam1}}} {{dam2=${dam2}}} {{dam3=${dam3}}} ... {{dam20=${dam20}}}`; Roll Template: {{#rollTotal() roll 1}} <div>{{dam1}}</div> {{/rollTotal() roll 1}} {{#rollTotal() roll 2}} <div>{{dam2}}</div> {{/rollTotal() roll 2}} {{#rollTotal() roll 3}} <div>{{dam3}}</div> ... {{/rollTotal() roll 19}} {{#rollTotal() roll 20}} <div>{{dam20}}</div> {{/rollTotal() roll 20}} This method can work for anything you want to use in any particular roll.  The thing to bear in mind is that once a player clicks that roll button, you are very limited in what you can do.  Therefore, address everything you can prior to the roll button event and express all the possibilities as roll template variables that show/hide based on the dice roll.
GiGs said: Can you describe that in more detail. It's unclear whether you want to do something in the print to chat, or to make a change on the character sheet. If it's a roll to chat, look at the wiki for reollTemplates, and the logic helper functions. Thank you Gigs. the process will be thus: push a button on the character sheet to roll a d100. this will initiate asking for input from the player for a value between 1 and 10 The input value will then look at a "table" (I say table but really it will be a Case statement) based on the input value (of 1-10) the Case statement will return a value assigned to a variable. that variable will then be subtracted from the d100 roll. the result will then appear in the chat. I need help with the coding as I can't find any examples that do anything like this in a character sheet.  Though I would also be happy to move this to a Macro instead of trying to place it in the character sheet itself. What I propose above is a simplistic version of what I am trying to accomplish. Any help would be appreciated. NO This is not for DnD or 5th edition or pathfinder
1643849705
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Ah, what you want is custom roll parsing . There are several sheets around using CRP to do similar tasks to what you are looking for. Assuming I've correctly understood what you're looking for, you'll want something like this: <button type="action" name="act_roll">Roll the d100</button><!-- you can replace the "roll" part of the name with whatever you please. I recommend using dashes in place of spaces (kebob-case) for action buttons.--> <script type="text/worker"> const extractQueryResult = async function(query){ let queryRoll = await startRoll(`!{{query=[[0[response=?{${query}}]]]}}`); finishRoll(queryRoll.rollId); return queryRoll.results.query.expression.replace(/^.+?response=|\]$/g,''); }; const initiateRoll = async function(event){//Async tag here to allow us to await the various rolls that we're going to do. let queryResult = await extractQueryResult('Which mod|1|2|3|4|5|6|7|8|9|10');//Await the asynchronous startRoll const resultSwitchArray = [0,2,6,10,12,16,20,24,30,40,60];//Used an array in place of the switch cause it's a bit more performant. Can easily replace this with your switch statement if you need more complex figuring. let mod = resultSwitchArray[queryResult]; let output = `&{template:default} {{name=Demo Output}} {{d100=[[d100 - ${mod}[Mod]]]}}` let finalRoll = await startRoll(output); finishRoll(finalRoll.rollId); }; on('clicked:roll',initiateRoll); </script>
Scott C. said: Ah, what you want is custom roll parsing . There are several sheets around using CRP to do similar tasks to what you are looking for. Assuming I've correctly understood what you're looking for, you'll want something like this: <button type="action" name="act_roll">Roll the d100</button><!-- you can replace the "roll" part of the name with whatever you please. I recommend using dashes in place of spaces (kebob-case) for action buttons.--> <script type="text/worker"> const extractQueryResult = async function(query){ let queryRoll = await startRoll(`!{{query=[[0[response=?{${query}}]]]}}`); finishRoll(queryRoll.rollId); return queryRoll.results.query.expression.replace(/^.+?response=|\]$/g,''); }; const initiateRoll = async function(event){//Async tag here to allow us to await the various rolls that we're going to do. let queryResult = await extractQueryResult('Which mod|1|2|3|4|5|6|7|8|9|10');//Await the asynchronous startRoll const resultSwitchArray = [0,2,6,10,12,16,20,24,30,40,60];//Used an array in place of the switch cause it's a bit more performant. Can easily replace this with your switch statement if you need more complex figuring. let mod = resultSwitchArray[queryResult]; let output = `&{template:default} {{name=Demo Output}} {{d100=[[d100 - ${mod}[Mod]]]}}` let finalRoll = await startRoll(output); finishRoll(finalRoll.rollId); }; on('clicked:roll',initiateRoll); </script> oooooooooooo yes, actually an array is what I was looking for, but was not sure they were available to code in, as I am actually looking to create a 2 dimensional array. thanks, I'll review this Your kindness and consideration is welcome! Carl
Hi Scott, I am discovering that I just don't have the right language skills to modify this code to meet my actual needs.  Thought I could convert this to a 2 dimensional array and add another input but failed horribly in that attempt.  If you have the time (and/or inclination) to help out and update my modification to your code I would appreciate it. <script type="text/worker">   const extractQueryResult = async function(query){     let queryRoll = await startRoll(`!{{query=[[0[response=?{${query}}]]]}}`);     finishRoll(queryRoll.rollId);     return queryRoll.results.query.expression.replace(/^.+?response=|\]$/g,'');   };   const initiateRoll = async function(event){//Async tag here to allow us to await the various rolls that we're going to do.     let queryResult = await extractQueryResult('Which mod|1|2|3|4|5|6|7|8|9|10');//Await the asynchronous startRoll const resultSwitchArray =[ [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30], [1,50,55,60,65,70,73,76,79,82,85,87,89,91,93,95,96,97,98,99,100,101,102,103,104,105,106,107,108,109,110], [2,45,50,55,60,65,68,71,74,77,80,82,84,86,88,90,91,92,93,94,95,96,97,98,99,100,101,102,103,104,105], [3,40,45,50,55,60,63,66,69,72,75,77,79,81,83,85,86,87,88,89,90,91,92,93,94,95,96,97,98,99,100], [4,35,40,45,50,55,58,61,64,67,70,72,74,76,78,80,81,82,83,84,85,86,87,88,89,90,91,92,93,94,95], [5,30,35,40,45,50,53,56,59,62,65,67,69,71,73,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90], [6,27,32,37,42,47,50,53,56,59,62,64,66,68,70,72,73,74,75,76,77,78,79,80,81,82,83,84,85,86,87], [7,24,29,34,39,44,47,50,53,56,59,61,63,65,67,69,70,71,72,73,74,75,76,77,78,79,80,81,82,83,84], [8,21,26,31,36,41,44,47,50,53,56,58,60,62,64,66,67,68,69,70,71,72,73,74,75,76,77,78,79,80,81], [9,18,23,28,33,38,41,44,47,50,53,55,57,59,61,63,64,65,66,67,68,69,70,71,72,73,74,75,76,77,78], [10,15,20,25,30,35,38,41,44,47,50,52,54,56,58,60,61,62,63,64,65,66,67,68,69,70,71,72,73,74,75], [11,13,18,23,28,33,36,39,42,45,48,50,52,54,56,58,59,60,61,62,63,64,65,66,67,68,69,70,71,72,73], [12,11,16,21,26,31,34,37,40,43,46,48,50,52,54,56,57,58,59,60,61,62,63,64,65,66,67,68,69,70,71], [13,9,14,19,24,29,32,35,38,41,44,46,48,50,52,54,55,56,57,58,59,60,61,62,63,64,65,66,67,68,69], [14,7,12,17,22,27,30,33,36,39,42,44,46,48,50,52,53,54,55,56,57,58,59,60,61,62,63,64,65,66,67], [15,5,10,15,20,25,28,31,34,37,40,42,44,46,48,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64,65], [16,4,9,14,19,24,27,30,33,36,39,41,43,45,47,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63,64], [17,3,8,13,18,23,26,29,32,35,38,40,42,44,46,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62,63], [18,2,7,12,17,22,25,28,31,34,37,39,41,43,45,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61,62], [19,1,6,11,16,21,24,27,30,33,36,38,40,42,44,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60,61], [20,0,5,10,15,20,23,26,29,32,35,37,39,41,43,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59,60], [21,-1,4,9,14,19,22,25,28,31,34,36,38,40,42,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58,59], [22,-2,3,8,13,18,21,24,27,30,33,35,37,39,41,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57,58], [23,-3,2,7,12,17,20,23,26,29,32,34,36,38,40,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56,57], [24,-4,1,6,11,16,19,22,25,28,31,33,35,37,39,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55,56], [25,-5,0,5,10,15,18,21,24,27,30,32,34,36,38,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54,55], [26,-6,-1,4,9,14,17,20,23,26,29,31,33,35,37,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53,54], [27,-7,-2,3,8,13,16,19,22,25,28,30,32,34,36,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52,53], [28,-8,-3,2,7,12,15,18,21,24,27,29,31,33,35,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51,52], [29,-9,-4,1,6,11,14,17,20,23,26,28,30,32,34,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50,51], [30,-10,-5,0,5,10,13,16,19,22,25,27,29,31,33,35,36,37,38,39,40,41,42,43,44,45,46,47,48,49,50], ];      let mod = resultSwitchArray[queryResult,0]; //The two inputs should be AttackLevel and DefenseLevel. Column 0 is the AttackLevel 0-30; Row 0 is the DefenseLevel 0-30. So if the Attacker is Level 10 and the Defender Level 5 the result should be 35     let output = `&{template:default} {{name=Demo Output}} {{d100=[[d100 - ${mod}[Mod]]]}}`     let finalRoll = await startRoll(output);     finishRoll(finalRoll.rollId);   };   on('clicked:roll',initiateRoll); </script> Scott C. said: Ah, what you want is custom roll parsing . There are several sheets around using CRP to do similar tasks to what you are looking for. Assuming I've correctly understood what you're looking for, you'll want something like this: <button type="action" name="act_roll">Roll the d100</button><!-- you can replace the "roll" part of the name with whatever you please. I recommend using dashes in place of spaces (kebob-case) for action buttons.--> <script type="text/worker"> const extractQueryResult = async function(query){ let queryRoll = await startRoll(`!{{query=[[0[response=?{${query}}]]]}}`); finishRoll(queryRoll.rollId); return queryRoll.results.query.expression.replace(/^.+?response=|\]$/g,''); }; const initiateRoll = async function(event){//Async tag here to allow us to await the various rolls that we're going to do. let queryResult = await extractQueryResult('Which mod|1|2|3|4|5|6|7|8|9|10');//Await the asynchronous startRoll const resultSwitchArray = [0,2,6,10,12,16,20,24,30,40,60];//Used an array in place of the switch cause it's a bit more performant. Can easily replace this with your switch statement if you need more complex figuring. let mod = resultSwitchArray[queryResult]; let output = `&{template:default} {{name=Demo Output}} {{d100=[[d100 - ${mod}[Mod]]]}}` let finalRoll = await startRoll(output); finishRoll(finalRoll.rollId); }; on('clicked:roll',initiateRoll); </script>
1647202679
GiGs
Pro
Sheet Author
API Scripter
This is likely your problem: let mod = resultSwitchArray[queryResult,0] That should probably be let mod = resultSwitchArray[queryResult][0] In javascript, array[0] gets the full variable at that index. If that variable is another array, you have to array[0] again to get the index out of it. That's essentially what chaining the [0]'s together does. So resultSwitch[0] gives [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30] and then [0] again gives the 0 index, which is 0. Doing resultSwitch[5][3] would first do resultSwitch[5], giving [5,30,35,40,45,50,53,56,59,62,65,67,69,71,73,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90] then you'd do that_result[3], giving a result of 40.
Thanks Gigs,  now I just need help getting another input value so that instead of 0, it is queryResult2 GiGs said: This is likely your problem: let mod = resultSwitchArray[queryResult,0] That should probably be let mod = resultSwitchArray[queryResult][0] In javascript, array[0] gets the full variable at that index. If that variable is another array, you have to array[0] again to get the index out of it. That's essentially what chaining the [0]'s together does. So resultSwitch[0] gives [0,1,2,3,4,5,6,7,8,9,10,11,12,13,14,15,16,17,18,19,20,21,22,23,24,25,26,27,28,29,30] and then [0] again gives the 0 index, which is 0. Doing resultSwitch[5][3] would first do resultSwitch[5], giving [5,30,35,40,45,50,53,56,59,62,65,67,69,71,73,75,76,77,78,79,80,81,82,83,84,85,86,87,88,89,90] then you'd do that_result[3], giving a result of 40.
Hi again Gigs, got it working, thank you for all your help and input. How is it that the <script> knows to run on the button push?  I can't see anything linking the button to the code in the script. I am inserting this code into my created character sheet code
1647226882
GiGs
Pro
Sheet Author
API Scripter
The code we have access to isnt the full code that roll20 runs. Each sheet worker has an event line, where you put something like on('clicked:act_roll', - roughly speak, the event tells roll20 to "Watch the action button named roll, and when it is clicked run this worker." There are other special functions, like getAttrs(['strength', 'dexterity'], function(values) { - this tells roll20 to "look at the character sheet, find the attributes named strength and dextity, and store them and their scores in an object variable called values. startRoll, finishRoll, setAttrs, and getSectionIDs also have code that isn't accessible to us, but operate behind the scenes to perform actions that are vital to running sheet workers.
Thanks GiGs, I am familiar with preset keywords and functions.  Still trying to teach myself java script (never used it before) as well as the specifics of roll20 coding. Thank you for all your help with this! C ?:>