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

Sheet Coding Help

I have a game system with two things I'm trying to figure out how to add to the html. First, there's a stat called Snark, which is equal to one of two potential stats - a character's Wit or their Charm. Snark is the higher of the two, multiplied by 5. So far I have: name="attr_snark" value="[[ @{charm}*5, @{wit}*5}d1" But I don't think that's right, and it doesn't seem to be working in the sheet html. Second, I have a system where an Ability roll can be Boosted. If it's not Boosted, it rolls 1d6 + 1t[Item-Table] + 1d6, with the Item Table giving a specific result from the Item Table. If it is Boosted, it returns 1d6 + 1t[Boost-Table] + 1d6, giving a specific result from the Boost Table. This is what I have for the Speed ability: /roll ?{Basic/Boosted|Basic,1d6 + 1t[Item-Dice] + 1d6 + @{Speed}|Boosted,1d6 + 1t[Boost-Dice] + 1d6 + @{Speed}} This asks every time if the stat is Boosted or not, but I want to streamline this, so that on the sheet there is a checkbox, and if the box is checked, it rolls from the Boost table. I found a script so that the html can "recognise" that the Speed Boost checkbox is checked, but I'm not sure if I'm doing it correctly - as is, when the box is unchecked, it's returning a 0 value, and when its checked, its returning a 1 value... <script type="text/worker"> on('change:speedboost\_checkbox sheet:opened', (eventInfo) => { getAttrs(\['speedboost\_checkbox'\], (v) => { const output = {1t\[Item-Dice\]}; const speedboostState = parseInt(v.speedboost\_checkbox) || 0; output.boosted = speedboostState ? '1t\[Boost-Dice\]' : '1t\[Item-Dice\]'; setAttrs(output, {silent: true}); }); }); </script> If it helps, I have two macros called Basic-Check (/roll 1d6 + 1t[Item-Dice] + 1d6) and Ability-Boost (/roll 1d6 + 1t[Boost-Dice] + 1d6), so I can easily just get the sheet to roll from the Macros and add the corresponding ability (Like Strength or Speed), but I just need to know what I'm doing wrong to get it to recognise the Boosted/Unboosted state... Can anyone help with these two things? I'm still scratching the surface with Roll20 and html coding, so any help would be appreciated!
1792263981

Edited 1792264025
vÍnce
Pro
Sheet Author
Hi CRTScreem, See if this works for snark; <input name="attr_snark" value="[[ {@{charm}*5, @{wit}*5}}d1 ]]" /> Is your sheetworker not working as you expect or are you just wanting someone to check the work? Slightly updated, but your logic seems sound. (assumes attr_boosted is not "disabled". Otherwise the sheetworker cannot write to it) on('change:speedboost_checkbox sheet:opened', (eventInfo) => { getAttrs(['speedboost_checkbox'], (v) => { const output = {}; const speedboostState = parseInt(v.speedboost_checkbox) || 0; output.boosted = speedboostState ? '1t[Boost-Dice]' : '1t[Item-Dice]'; setAttrs(output, {silent: true}); }); });
I tried using your code for snark and it generated this, same as when I do it: and when I add in a Wit value, it just adds that value to the generated Snark, like this: I don't know where it's getting 51 from, because it's supposed to be 2x5... As for the checkbox code, this is what keeps being generated when the box is checked and unchecked - it recognises the different states, but it's not sending the request to roll from the tables, only replacing the value with a 0 (for unchecked) or 1 (for checked)
1792280124

Edited 1792280341
Could it be the command I'm giving it, to get it to roll the tables? At the moment it's /roll [[ 1d6 + @{speedboost} + 1d6 + @{Speed} ]] where speedboost is the name of the checkbox... I also tried it without the [[ ]] to the same result... Alternatively, is there a way I can create a roll template and add it in using startRoll? The Item-Dice and Boost-Dice are just 1d6 and 1d12, but with the 6 on the d6 replaced with an image, and the 12 and the 1 on the d12 replaced with the same image (Similar to the Marvel Multiverse RPG). 
1792292077

Edited 1792292761
vÍnce
Pro
Sheet Author
Sorry, I didn't know how you were using the value of snark.   [[ {@{charm}*5, @{wit}*5} }d1 ]] will only work as part of a roll.  You can use a sheetworker to handle the same logic though.   example; on('change:charm change:wit', (eventInfo) => { getAttrs(['charm', 'wit'], (v) => { const output = {}; const charm = parseInt(v.charm) || 0; const wit = parseInt(v.wit) || 0; const bestSnark = Math.max(charm * 5, wit * 5); output.snark = bestSnark; setAttrs(output, {silent: true}); }); }); In the original worker you were setting the value of "boosted"... but is it actually supposed to be "speedboost"?   If so, change worker I posted from; output.boosted = speedboostState ? '1t[Boost-Dice]' : '1t[Item-Dice]'; to  output.speedboost = speedboostState ? '1t[Boost-Dice]' : '1t[Item-Dice]'; Then your roll would actually resolve to (assuming speed is 5 like your image) /roll [[ 1d6 + 1t[Boost-Dice] + 1d6 + 5 ]] if speedboost_checkbox is checked or  /roll [[ 1d6 + 1t[Item-Dice] + 1d6 + 5 ]] if speedboost_checkbox is unchecked note: You do not need to include the checkbox attr in your roll since it's only the sheetworker that is using that to determine which roll table to include. btw you don't have to include the "/roll" in this macro unless you want to see extra roll info in chat.  Inline roll will just show the result (hover to see details)
1792293357

Edited 1792295795
Perfect, I'll give those both a try and see!  Where do I insert the sheetworker for Snark, and what do I place as the default value for snark as an attribute? (Sorry I'm very new to this) Edit: I was able to get the Charm/Wit function working, and the Speed roll works now - but it only works on the first try with the unchecked box. If I check the box, it goes back to just marking it as 1, and I uncheck the box, it reverts back to 0 rather than reverting back to the working roll... Is there something that's resetting the code when the box is checked the first time?
1792295617
vÍnce
Pro
Sheet Author
CRTScream said: Alternatively, is there a way I can create a roll template and add it in using startRoll? The Item-Dice and Boost-Dice are just 1d6 and 1d12, but with the 6 on the d6 replaced with an image, and the 12 and the 1 on the d12 replaced with the same image (Similar to the Marvel Multiverse RPG).&nbsp; Yes, but...&nbsp; there's some work involved; Create a roll template using HTML and CSS.&nbsp; Something that fits the style/theme of your sheet. Define properties {{keys}} as-needed that can be triggered from macro rolls. {{title}}, {{name}}, {{roll}}, etc. Create an Action roll button that triggers a sheetworker.&nbsp; This is how you will initiate CRP Create the roll that will be sent to chat (this is what will call the roll template and initiate any rolls). Use startRoll() and grab the roll(s) results. Use logic to write to the roll template using " computed:: X" and/or set any attribute values. finishRoll() send the results to chat. The roll template can hide/show whatever you want using the computed values and normal roll template logic . (ie display the same image for 1 and 12). I highly recommend GiGs site:&nbsp; <a href="https://cybersphere.me/guide-to-custom-roll-parsing/" rel="nofollow">https://cybersphere.me/guide-to-custom-roll-parsing/</a>
1792296285

Edited 1792296561
vÍnce
Pro
Sheet Author
CRTScream said: Perfect, I'll give those both a try and see!&nbsp; Where do I insert the sheetworker for Snark, and what do I place as the default value for snark as an attribute? (Sorry I'm very new to this) Sheetworkers should be placed within script tags(I've always included them after the sheet's HTML); all sheet HTML first&nbsp; &lt;script type="text/worker"&gt;&nbsp; &nbsp; // all JS goes here &lt;/script&gt; I assume you already have snark in the HTML.&nbsp; You could simply assign a value="0" or whatever...&nbsp; Snark's value will get updated as soon as wit or charm is changed.&nbsp; If you need to always have snark default to the higher of wit*5 or charm*5, you could add sheet:opened &nbsp;to the snark sheetworker to ensure snark is always the correct value.&nbsp;&nbsp; It looks like your image has 2 fields for snark though...?&nbsp; What is that exactly?&nbsp; Is it supposed to show wit*5 and charm*5?
Got it! The two fields are the character's total Snark, and the character's current Snark (it's a resource they can use). I was able to get that adjustment working,&nbsp;and the Speed roll works now - but it only works on the first try with the unchecked box. If I check the box, it goes back to just marking it as 1, and I uncheck the box, it reverts back to 0 rather than reverting back to the working roll... Is there something that's resetting the code when the box is checked the first time?
1792297013

Edited 1792297151
vÍnce
Pro
Sheet Author
Please post the HTML for the checkbox. and the current version of the speed boost sheetworker.&nbsp; (use the forums code format tool to help keep it neat)
1792297200

Edited 1792297319
&lt;input name="attr_speedboost" data-sm-id="21" type="checkbox" value="1" class="sm-prop sm-checkbox" style="left: 210px; top: 209px; width: 31px; height: 23px;"&gt; and &lt;script type="text/worker"&gt; on('change:speedboost_checkbox sheet:opened', (eventInfo) =&gt; { getAttrs(['speedboost_checkbox'], (v) =&gt; { const output = {}; const speedboostState = parseInt(v.speedboost_checkbox) || 0; output.speedboost = speedboostState ? '1t[Boost-Dice]' : '1t[Item-Dice]'; setAttrs(output, {silent: true}); }); }); &lt;/script&gt;
1792299101

Edited 1792299730
vÍnce
Pro
Sheet Author
The worker is writing to attr_speedboost ( a checkbox )... only the "on" state is storing the sheetworker's value.&nbsp; When unchecked the value is always "0". Re-name the checkbox to "attr_speedboost_checkbox" in order for the sheetworker to detect the on/off state as intended.&nbsp; Create a new input for attr_speedboost (that is not a checkbox) to hold the sheetworker value and that's sent with the roll. example; &lt;input type="checkbox" name="attr_speedboost_checkbox" value="1" data-sm-id="21" class="sm-prop sm-checkbox" style="left:210px; top:209px; width:31px; height:23px;"&gt; &lt;input type="hidden" name="attr_speedboost" value="0" /&gt;
That got it working!&nbsp; I just have one more request, if you would be so kind: A character's Hit Difficulty is determined in one of two ways: If any of their abilities are Boosted, their Hit Difficulty is 12 + their Power (I've calculated this as 12 + @{power} If none of their abilities are Boosted, their Hit Difficulty is 10.&nbsp; So I need it to see if any boxes are unchecked, and if so, then hitdifficulty = 10, and if any of them are checked, hitdifficulty = 12 + @{power} Is there a sheetworker I can make for this?
1792303161
vÍnce
Pro
Sheet Author
Without knowing the exact attr names... (modify accordingly)&nbsp; something like this should work; on( 'change:speed_boost_checkbox change:power_boost_checkbox change:soar_boost_checkbox change:charm_boost_checkbox change:wit_boost_checkbox change:intellect_boost_checkbox', (eventInfo) =&gt; { getAttrs(['speed_boost_checkbox', 'power_boost_checkbox', 'soar_boost_checkbox', 'charm_boost_checkbox', 'wit_boost_checkbox', 'intellect_boost_checkbox', 'power'], (v) =&gt; { const output = {}; const speedBoost = parseInt(v.speed_boost_checkbox) || 10; const powerBoost = parseInt(v.power_boost_checkbox) || 10; const soarBoost = parseInt(v.soar_boost_checkbox) || 10; const charmBoost = parseInt(v.charm_boost_checkbox) || 10; const witBoost = parseInt(v.wit_boost_checkbox) || 10; const intellectBoost = parseInt(v.intellect_boost_checkbox) || 10; const power = parseInt(v.power) || 10; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// if any of the ability checkboxes are checked isBoosted total will be greater than 0. const isBoosted = speedBoost + powerBoost + soarBoost + charmBoost + witBoost + intellectBoost &gt; 0 ? 1 : 0; output.hitdifficulty = isBoosted ? 12 + power : 10; setAttrs(output, {silent: true}); }); }, );
Thank you! This doesn't seem to work - the attributes are called, for example speed with the checkbox being called, for example speedboost_checkbox I adjusted the attr names in your example to be&nbsp; on( 'change:speedboost_checkbox change:powerboost_checkbox change:soarboost_checkbox change:charmboost_checkbox change:witboost_checkbox change:intellectboost_checkbox', (eventInfo) =&gt; { getAttrs(['speedboost_checkbox', 'powerboost_checkbox', 'soarboost_checkbox', 'charmboost_checkbox', 'witboost_checkbox', 'intellectboost_checkbox', 'power'], (v) =&gt; { const output = {}; const speedBoost = parseInt(v.speedboost_checkbox) || 10; const powerBoost = parseInt(v.powerboost_checkbox) || 10; const soarBoost = parseInt(v.soarboost_checkbox) || 10; const charmBoost = parseInt(v.charmboost_checkbox) || 10; const witBoost = parseInt(v.witboost_checkbox) || 10; const intellectBoost = parseInt(v.intellectboost_checkbox) || 10; const power = parseInt(v.power) || 10; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;// if any of the ability checkboxes are checked isBoosted total will be greater than 0. const isBoosted = speedBoost + powerBoost + soarBoost + charmBoost + witBoost + intellectBoost &gt; 0 ? 1 : 0; output.hitdifficulty = isBoosted ? 12 + power : 10; setAttrs(output, {silent: true}); }); }, ); What am I missing?
1792306857

Edited 1792361755
vÍnce
Pro
Sheet Author
What isn't working?&nbsp; hitdifficulty doesn't change?&nbsp;&nbsp; Some things to check;&nbsp; 1. all the checkboxes have a value="1" 2. hitdifficulty is not disabled (use readonly if you do not want it editable) 3. the attrs names are correct (casing matters) 4. add log(s) to the script to see what's going on when the script runs. example (added some logs to your code above.&nbsp;&nbsp;ctrl+shift+i to open the browser's console window, clear it, then watch what is logged when you check/uncheck the boost boxes) on( 'change:speedboost_checkbox change:powerboost_checkbox change:soarboost_checkbox change:charmboost_checkbox change:witboost_checkbox change:intellectboost_checkbox', (eventInfo) =&gt; { getAttrs(['speedboost_checkbox', 'powerboost_checkbox', 'soarboost_checkbox', 'charmboost_checkbox', 'witboost_checkbox', 'intellectboost_checkbox', 'power'], (v) =&gt; { console.log(`Change detected: ${eventInfo.sourceAttribute}`); const output = {}; const speedBoost = parseInt(v.speedboost_checkbox) || 0; const powerBoost = parseInt(v.powerboost_checkbox) || 0; const soarBoost = parseInt(v.soarboost_checkbox) || 0; const charmBoost = parseInt(v.charmboost_checkbox) || 0; const witBoost = parseInt(v.witboost_checkbox) || 0; const intellectBoost = parseInt(v.intellectboost_checkbox) || 0; const power = parseInt(v.power) || 10; // if any of the ability checkboxes are checked isBoosted total will be greater than 0. const isBoosted = speedBoost + powerBoost + soarBoost + charmBoost + witBoost + intellectBoost &gt; 0 ? 1 : 0; console.log( `isBoosted:${isBoosted} speedBoost:${speedBoost} powerBoost:${powerBoost} soarBoost:${soarBoost} charmBoost:${charmBoost} witBoost:${witBoost} intellectBoost:${intellectBoost} power:${power}`, ); output.hitdifficulty = isBoosted ? 12 + power : 10; setAttrs(output, {silent: true}); }); }, ); logs can be VERY useful at determining what is and isn't working.&nbsp; EDIT/UPDATE code; changed the fallback from "|| 10;" to&nbsp; "|| 0;"
Right! Yes, sorry, it's very late here 😅 yeah, the hit difficulty isn't changing whether the checkboxes are ticked or not, it's still just equalling 12 + power, or showing as 12 when power isn't filled in. I'm pretty sure each of those things are correct, the only thing it might be is the values not being set to 1, but I'll try putting in the log and see what comes up Thank you for all your help so far, I really appreciate it! I'm just scratching the surface of coding myself, so having someone to talk to really helps
1792307851
vÍnce
Pro
Sheet Author
No worries.&nbsp; Past midnight for me. lol&nbsp; Check those logs.&nbsp; copy and paste the results of what we are logging in the script and it should help figure out the issue.
1792309590

Edited 1792310149
It came back with this ReferenceError: on is not defined Edit: I was able to correct it as a line error, but then it came back with this Uncaught SyntaxError: expected expression, got '&lt;' debugger eval code :1:1
1792339905
vÍnce
Pro
Sheet Author
Are all of your sheet workers inside a &lt;script&gt; tag?&nbsp; You might need to share (here or DM me) a link to your code.
I've got it linked here: <a href="https://htmlto.link/oatx6stt" rel="nofollow">https://htmlto.link/oatx6stt</a> They all seem to be inside scripts, and I made sure hitdifficulty was not disabled, (marked it disabled="false"), made sure the values were all 1, and the attrs names are correct...
1792347044

Edited 1792348387
vÍnce
Pro
Sheet Author
CRTScream said: I've got it linked here: <a href="https://htmlto.link/oatx6stt" rel="nofollow">https://htmlto.link/oatx6stt</a> They all seem to be inside scripts, and I made sure hitdifficulty was not disabled, (marked it disabled="false"), made sure the values were all 1, and the attrs names are correct... Do you have a link to the actual html, css (not a rendered page)?&nbsp; Maybe gist, pastebin, etc. Roll20 has many unique rules/restrictions when it comes to creating sheets. ;-( also. do not add disabled="false". Just leave disabled off the input) also, also: put all of your sheetworker inside a single &lt;script type="text/worker"&gt; ALL JS HERE &lt;/script&gt; The sheetworkers appear to be working for me, albeit a very basic/striped down set of code for testing. (toggling speed_boost) The logs look as expected.&nbsp; I'm sure it's just some syntax issues your code.&nbsp; Place your JS within a single script tag for starters. ;-)
I've tried a few variations, but when I remove the disabled condition and have no {power} value, then it defaults to 22... the normal value should be @{power}+12, and it does give that, even when the boxes aren't ticked...&nbsp; here's the link to the pastebin for the html <a href="https://pastebin.com/cRpQ1wW8" rel="nofollow">https://pastebin.com/cRpQ1wW8</a> I'm really lost here :') Also, do you mean get rid of all the intermediary&nbsp; &lt;/script&gt; and &lt;script type="text/worker"&gt; lines? or just rename that last script tag to&nbsp; &lt;script type="text/worker"&gt; ?
1792356969
vÍnce
Pro
Sheet Author
Place all of your js/sheetworker code inside of one &lt;script type="text/worker"&gt;&lt;/script&gt;
1792361631

Edited 1792362692
vÍnce
Pro
Sheet Author
I had a look at the code.(thank you for posting.&nbsp; css also helps btw... because your sheet is a "fields overlay" of the background image, nothing aligns properly with the background's labels.&nbsp; Just makes it much more difficult to know what each field/attr actually is.)&nbsp;&nbsp; I made some changes to combine the sheetworkers.&nbsp; Corrected my error with the fallback values of "|| 10;",&nbsp; Should have been&nbsp; "|| 0;".&nbsp; Placed all JS under one script tag.&nbsp; Made some formatting/housekeeping in the html.&nbsp; Being consistent with your code and formatting helps troubleshoot issues that come up.&nbsp; Replaced all disabled with readonly.&nbsp; Sheetworkers cannot write to disabled attrs.&nbsp; Assigned value="0" to some of the attrs.&nbsp; Always good practice to assign a default value. See if this helps; <a href="https://gist.github.com/vince-roll20/03c895c3dea21bb1cc88e9612c86ba56" rel="nofollow">https://gist.github.com/vince-roll20/03c895c3dea21bb1cc88e9612c86ba56</a>
Thank you so much for your help!&nbsp; I'll be honest, I'm so new to coding I was using SheetMagic to insert all the calculations, and listing them as dice references - so Movement, which is a character's speed times 5, I was inputting as @{speed}*5.&nbsp; I tried your corrected version, and Snark and Hit Difficulty both calculated as they should, but the other values weren't working... so, using the codes you showed me as a template, I was able to make the other stats (Movement, Strength, Air, and Control) correct! Not only did you help me get it working, you helped me learn how to&nbsp; actually&nbsp; code some html XD For interest's sake (and to help the sheet be understandable) New html: <a href="https://pastebin.com/cRpQ1wW8" rel="nofollow">https://pastebin.com/cRpQ1wW8</a> Sheet CSS (also taken from SheetMagic):&nbsp; <a href="https://pastebin.com/RwQujw3L" rel="nofollow">https://pastebin.com/RwQujw3L</a> Thank you so much again for your help! I feel confident I can actually play this now XD
1792416604
vÍnce
Pro
Sheet Author
Glad to help.&nbsp; Coding sheets for Roll20 can be frustrating, fun, and addictive.&nbsp; Enjoy the journey.
Thank you!&nbsp; I guess I do have one last question actually - I have an image placeholder in the CSS, and I was wondering if there's a html code that allows you to place your token image on the sheet itself? It doesn't have to replace the one that's there, but just a box that allows an image to be uploaded, or even a box that will refer to what the character's avatar/token already is (if there's one that will update the token to what is on the sheet, even better). Do you know what the code would be for this, be chance?
I found a code, but I'm not sure how to get it working, since it's just linking to the image url and not showing the image itself... but I have this, in the &lt;div&gt;&nbsp;&lt;input type="image" img name="attr_character_avatar" style="left: 120px; top: 175px; width: 250px; height: 250px;"&gt; &lt;/div&gt;&nbsp; and then the following under the sheetworker&nbsp; &nbsp; on( &nbsp; "sheet:opened, function() { &nbsp; getAttrs([character_avatar"], function(values) { &nbsp; &nbsp; let theAvatarURL=values.character_avatar; &nbsp; &nbsp; getAttrs({ &nbsp; &nbsp; &nbsp; &nbsp; character_avatar:theAvatarURL &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; }); }); What's wrong with this that it isn't just showing the image itself?
1792469703
vÍnce
Pro
Sheet Author
You could just use the img element by itself if you simply want to use the character's avatar.&nbsp; No need for a sheetworker. example;&nbsp; &lt;div&gt;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &lt;img name="attr_character_avatar" style="left: 120px; top: 175px; width: 250px; height: 250px; object-fit: contain;"&gt; &lt;/div&gt; I've added object-fit: contain; to force the character's avatar image to better fit within your defined height and width and maintain it's aspect ratio.