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

[Sheet worker] [DCC] Help with grabbing the highest value in a repeating section using a sheet worker

Hi, I'm using the Dungeon Crawl Classics character sheet, but I have created my own fork of it, as there is some functionality that I wanted to add. One thing I want to do, but really don't understand how, is how to create a sheet worker script to programmatically choose the highest 'fumble die' in a repeating section of armor, with an arbitrary number of entries? The 'fumble die' is an n-sided die that's rolled when the character fumbles his attack, and the size/number of sides on the die is worse with heavier armor.  It starts as a 'd4' for unarmored characters (and should default to this when there are no armor entries in the repeating_armor section), and goes up to 'd16' for plate-armored characters; shields are a 'd8'. I'm a noob in programming; sorting routines (which I think this needs, but I'm probably wrong) are not something I have a grasp on, especially when the number of entries is arbitrary. The attribute that needs to be changed automatically is called 'armorFumbleDie'.  The repeating section is 'repeating_armor', the relevant entries in the repeating section are 'armorFumbleDie', and it should only be looking at repeating entries with the 'armorActive' checkbox checked (i.e. don't grab info from armor the character isn't wearing). I guess it would need to be updated anytime an entry was added or removed from the repeating_armor section, or when any 'armorFumbleDie' entries were changed in that section, or when any 'armorActive' checkbox is changed. Can anyone help with this?
1532882039
GiGs
Pro
Sheet Author
API Scripter
There'll be a more elegant way to do it, but this should work: // This assumes the checkbox armorActive has a value=1, and armorFumbleDie has a value of d4, d6, d8, etc. on ( "change:repeating_armor:armorFumbleDie change:repeating_armor:armorActive remove:repeating_armor" , function () {      getSectionIDs ( "repeating_armor" , function ( IDarray ) {          var fieldNames = [];          let fumble = 0 ; for ( var i = 0 ; i < IDarray . length ; i ++) {              fieldNames . push ( "repeating_armor_" + IDarray [ i ] + "_armorFumbleDie" );              fieldNames . push ( "repeating_armor_" + IDarray [ i ] + "_armorActive" );         } getAttrs ( fieldNames , function ( values ) {              for ( var i = 0 ; i < IDarray . length ; i ++) {                  if ( parseInt ( values [ "repeating_armor_" + IDarray [ i ] + "armorActive" ])|| 0 === 1 ) { fumble = Math . max ( fumble , parseInt ( values [ "repeating_armor_" + IDarray [ i ] + "armorActive" ]). replace ( "d" , "" ) || 0 ); } } fumble = "d" + fumble ;              setAttrs ({ "armorFumbleDie" : fumble }); });     }); }); Possible downside: what happens if no armour is worn? This can give d0 as a result.
It doesn't seem to work.  It didn't seem to be doing anything at all at first.  I changed "let fumble = 0;" to "let fumble = 4;" so that the minimum fumble die was a d4, and this verifies that the events fire (when I make a relevant change, armorFumbleDie is set back to a d4). I put "console.log("Fumble die=" + fumble);" after your " fumble = "d" + fumble ;" line, and this confirmed it.  It never changes to anything but a d4.  Not sure why though. I tried a few things, but it did not change the result.
Forgot...thanks for the help.  :-)
1532891844

Edited 1532892413
GiGs
Pro
Sheet Author
API Scripter
oh! I forgot the change line should be all lower case: change this line on ( "change:repeating_armor:armorFumbleDie change:repeating_armor:armorActive remove:repeating_armor" , function () { to this on ( "change:repeating_armor:armorfumbledie change:repeating_armor:armoractive remove:repeating_armor" , function () { Important: only change the case on that first line; leave the others as listed. If that doesnt work, post your html and css files on pastebin, and I'll be able to test it. I may have messed up the syntax in a way its not easy for me to spot without testing it.
I'll send you a PM invitation to my game; the HTML exceeds pastebin's allowance for non-pro accounts.
1532897289
GiGs
Pro
Sheet Author
API Scripter
The game invite wont help much, I need to be able to copy the html into a custom game. Could you copy out the html for just the repeating section, then?
1532897895
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Use a GitHub gist. No real limit there.
1532902518

Edited 1532902740
GiGs
Pro
Sheet Author
API Scripter
Here's the fixed version of the script, with a few console.log entries so you can see it working. IMPORTANT:  you need to add the value="1" to the html for the armorActive checkboxes. Find the lines  <input type="checkbox" name="attr_armorActive"/> and change them to <input type="checkbox" name="attr_armorActive" value="1"/> I think there are two. Here's the script. on("change:repeating_armor:armorfumbledie change:repeating_armor:armoractive remove:repeating_armor", function () { console.log("============================="); getSectionIDs("repeating_armor", function(IDarray) { var fieldNames = []; let fumble = 0; for (var i=0; i < IDarray.length; i++) { fieldNames.push("repeating_armor_" + IDarray[i] + "_armorFumbleDie"); fieldNames.push("repeating_armor_" + IDarray[i] + "_armorActive"); } console.log("ID Array 0:" + IDarray[0]); console.log("FieldNames 0:" + fieldNames[0]); console.log("FieldNames 1:" + fieldNames[1]); getAttrs(fieldNames, function(values) { for (var i=0; i < IDarray.length; i++) { console.log("Armour Active: " + values["repeating_armor_" + IDarray[i] + "_armorActive"]); if(parseInt(values["repeating_armor_" + IDarray[i] + "_armorActive"])||0 === 1) { fumble = Math.max(fumble, parseInt(values["repeating_armor_" + IDarray[i] + "_armorFumbleDie"].replace("d",""))||0); console.log("Fumble = " + fumble); } } if(parseInt(fumble)||0 !== 0 ) fumble = "d" + fumble; console.log("Fumble die=" + fumble); setAttrs({ "armorFumbleDie": fumble }); }); }); }); Also I noticed that one of the armorFumbleDie selects allows for a fumbleDie of 0, so I accounted for that. PS: in the text file you sent me, there were a bunch of extra spaces here and there that had crept into the code, and affected other scripts. For instance, the setAttrs section was like this:             fumble = "d " + fumble; console.log("Fumble die=" + fumble); setAttrs({ " armorFumbleDie ": fumble }); Notice the extra spaces inside the quotes that shouldnt be there? I hope this was just a glitch that crept in due to the copy and paste to text, but if those extra spaces are in the original, you will need to go through all the other scripts in the character sheet and remove them: they were everywhere in my copy.
Seems to work perfectly!  Thanks soooo much! Those extra spaces must have been from the copy/paste--they aren't in mine either.  I pasted and saved into Notepad++; is this a known issue? I've not noticed it before.
1532915564
GiGs
Pro
Sheet Author
API Scripter
You're welcome! I've never seen that spaces issue before either, no idea how it happened.