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

[Help] Manipulating values inside of repeating sections

I am starting to break into manipulating repeating sections, and I think I've got most of it down, I just can seem to get it to pass the calculations to the sheet.  I've examined a number of examples from the forums and many of them seem to lack the normal onChange or any other form of event handling, which leaves me wondering if that was assumed in those examples and left out because because it was... ahem.. assumed.  and if so what form would would that take for this code. var repeatingWeaponCalc = function () {     console.log("============ Start of Weapons Calculations ");     getSectionIDs("repeating_weapon", function (ids) {         _.each(ids,function(id) { // [[@{wepEnh}[Enh]+@{damage-mod}[Misc]+[[floor(@{damage-ability}*@{damage_ability_mult})]][Mod] ]]             getAttrs(["DMG-mod", "repeating_weapon_"+id+"_wepEnh", "repeating_weapon_"+id+"_damage-mod", "repeating_weapon_"+id+"_damage-ability", "repeating_weapon_"+id+"_damage_ability_mult"], function (v) { var wepEnh = v["repeating_weapon_"+id+"_wepEnh"]; var wepDmgMisc = parseInt(v["repeating_weapon_"+id+"_damage-mod"],10); var wepDmgAbilSrc = parseInt(v["repeating_weapon_"+id+"_damage_ability"],10); // Is a selection box...  grrr this is gonna be tricky var wepDmgAbilMulti = parseFloat(v["repeating_weapon_"+id+"_damage_ability_mult"],10); var wepAbilDam = 0; // RESERVED for the TOTALED value for ability damage * multiplier. var buff_DMG_Mod = parseFloat(v["DMG-mod"],10);                                  });         });         /* now inside the callback, occurring after everything is built, execute. */         var finalDamage = wepEnh + wepDmgMisc + buff_DMG_Mod;         console.log("======= Final Damage: "+finalDamage);         setAttrs({             "repeating_weapon_"+id+"_total-damage": finalDamage         });     }); }; There is also the matter of an unexpected token "+" error for the bolded line.  It doesn't seem to like how I am trying to set the repeating attribute for some reason.  Any thoughts as to what I'm doing wrong.
1511505648

Edited 1511514193
Jakob
Sheet Author
API Scripter
1. Yes, you need event handling. on("change:repeating_weapon", ...)  will do it. There's a performance matter here in that you could speed up things by only changing one row at a time when necessary, but that will make things more complicated. 2. You are aware (or so I believe by your comment) that you need to move the code for setting attributes inside the callback for it to work in this form? 3. Here's your main problem: you cannot use an object literal for this, since computed values as keys are not allowed inside object literals.  Use this instead: const attrs = {}; attrs["repeating_weapon_"+id+"_total-damage"] = finalDamage; setAttrs(attrs); That's the source of your syntax error. EDIT: okay,  turns out I'm wrong and you can use computed keys with this ES6 syntax: setAttrs({ ["repeating_weapon_"+id+"_total-damage"]: finalDamage }); This last option is probably preferable to my first suggested replacement.
1511529656

Edited 1511550475
Toby
Pro
Okay, well this is what I have now... all of the errors go away but the field within the repeating section still remains unfilled, and the console log never is sent to the output. var repeatingWeaponCalc = function () { console.log("============ Start of Weapons Calculations "); getSectionIDs("repeating_weapon", function (ids) { on('change:repeating_weapon:wepEnh change:repeating_weapon:damage-mod change:repeating_weapon:damage_ability change:repeating_weapon:damage_ability_mult change:buff_DMG_Mod', function() { _.each(ids,function(id) { // [[@{wepEnh}[Enh]+@{damage-mod}[Misc]+[[floor(@{damage-ability}*@{damage_ability_mult})]][Mod] ]] getAttrs(["DMG-mod", "repeating_weapon_"+id+"_wepEnh", "repeating_weapon_"+id+"_damage-mod", "repeating_weapon_"+id+"_damage-ability", "repeating_weapon_"+id+"_damage_ability_mult"], function (v) { var wepEnh = v["repeating_weapon_"+id+"_wepEnh"]; var wepDmgMisc = parseInt(v["repeating_weapon_"+id+"_damage-mod"],10); var wepDmgAbilSrc = parseInt(v["repeating_weapon_"+id+"_damage_ability"],10); // Is a selection box...  grrr this is gonna be tricky var wepDmgAbilMulti = parseFloat(v["repeating_weapon_"+id+"_damage_ability_mult"],10); var wepAbilDam = 0; // RESERVED for the TOTALED value for ability damage * multiplier. var buff_DMG_Mod = parseFloat(v["DMG-mod"],10); }); }); /* now inside the callback, occurring after everything is built, execute. */ var finalDamage = wepEnh + wepDmgMisc + buff_DMG_Mod;  // Incomplete equation needs case/if else statement to check ability score and atk type(melee,melee2,ranged,cmb,cmb2, etc) console.log("======= Final Damage: "+finalDamage); setAttrs({ ["repeating_weapon_"+id+"_total-damage"]: finalDamage }); });  // onChange eventhandler }); // getSectionIDs }; You said, I needed the callback,  I thought I had everything set and proper inside the callback, did I not manage do do that?  Or did I not place the event handler in the correct location? Edit:  Yeah, Perhaps I wasn't handing the Callback properly as it kept giving me undefined variable errors.  I've I have new code that no longer give undefined variable errors but they still silently fail. var weaponCalc = function () { on('change:repeating_weapon change:buff_DMG_Mod', function() { console.log("============ Start of Weapons Calculations "); var wepDamFinArray = []; getSectionIDs("repeating_weapon", function (ids) { _.each(ids,function(id) { getAttrs(["DMG-mod", "repeating_weapon_"+id+"_enhance", "repeating_weapon_"+id+"_damage", "repeating_weapon_"+id+"_damage-ability", "repeating_weapon_"+id+"_damage_ability_mult"], function (v) { var wepEnh = v["repeating_weapon_"+id+"_enhance"]; var wepDmgMisc = parseInt(v["repeating_weapon_"+id+"_damage"],10); var wepDmgAbilSrc = parseInt(v["repeating_weapon_"+id+"_damage_ability"],10); // Is a selection box...  grrr this is gonna be tricky var wepDmgAbilMulti = parseFloat(v["repeating_weapon_"+id+"_damage_ability_mult"],10); var wepAbilDam = 0; // RESERVED for the TOTALED value for ability damage * multiplier. var buff_DMG_Mod = parseFloat(v["DMG-mod"],10); var Damage = wepEnh + wepDmgMisc + buff_DMG_Mod;  // Incomplete equation needs case/if else statement to check ability score and atk type(melee,melee2,ranged,cmb,cmb2, etc) wepDamFinArray.Push(Damage); console.log("======= Pre-Callback: "+Damage); }); }); // now inside the callback, occurring after everything is built, execute.  var finalDamage = _.reduce(wepDamFinArray, function(m,a){return m+a;}, 0); console.log("======= Post-Callback Final Damage: "+finalDamage); setAttrs({ ["repeating_weapon_"+id+"_total-damage"]: finalDamage, }); }); // getSectionIDs });  // onChange eventhandler }; So.. needlessly complicated for basic math.  I hate Async code... -chuckle-
1511565727
Jakob
Sheet Author
API Scripter
Okay, this is all wrong. First off, you're just defining a function here. This will do exactly nothing until you run the function, of course, but just get rid of the container function weaponCalc (so just get rid of the first and last line) and it should at least do something. And then, the way you're setting the values is pretty nonsensical, and I don't even know what you want to do here. Isn't the final damage something you want to set per row? Because you're certainly trying to write into a specific row. If this is what you want to do, you should write the  setAttrs({ ["repeating_weapon_"+id+"_total-damage"]: finalDamage, }); into the getAttrs callback.  Of course, you need a sensible value for finalDamage here, and I don't know what it is supposed to be or why it should depend on all the other rows. If this is not what you want to do, I have no idea what you want to do instead, and I cannot guess it from your code. Anyway, it will not not do anything useful right now, among other things because id is undefined in the place you are calling it, and because wepDamFinArray will be empty at the time it is called. Also, I have a sneaking suspicion you don't know how callbacks work (sorry for being so blunt) ... that position in the code where you say "now inside the callback, occurring after everything is built, execute..." is a) outside the (inner) callbacks, b) will execute before  any of the stuff inside the getAttrs callbacks has executed.
1511568114

Edited 1511568548
Toby
Pro
No, I honestly dont know how callbacks work (no need to apologize).  I learn code by finding examples ripping them apart and using them myself for practical purposes.  Online tutorials, w3c, javascript.org skillsollogy tutorials have never been very helpful.  And classroom lessons only marginally more helpful (mostly because there was a instructor I could pester).  Ideally, fully formed code, well commented without too much weird stuff (like underscore or import/export spaghetti).  And I can progress, learning a little bit of new code or little bit of new syntax as I come across it. The above code--I coped and reworked from an example of an inventory script, and then started to slowly work away at it until I got to this point. So, anyways the DMG field is set to READONLY and is the total-damage for each row, or rather the total bonus damage associate with each weapon attack.  Its added from multiple sources including from weapon multipliers, ability mods, conditionals and Buffs, it changes based on if the attack is a melee or ranged from the ATTACK TYPE field.  I'm not even worrying about that code right now, once I get the output working I can worry about getting logic code working, as I suspect that will be easier. I just need the framework as to how this is to function, then from there I think I can replicate it for any other readonly fields.  The only other issues I foresee is when I try to bring in the SWUtil code to parse fields.  But, I'll cross that bridge when I come to it. on('change:repeating_weapon change:DMG-mod', function() { console.log("============ Start of Weapons Calculations "); var wepDamFinArray = []; getSectionIDs("repeating_weapon", function (ids) { _.each(ids,function(id) { getAttrs(["DMG-mod", "repeating_weapon_"+id+"_enhance", "repeating_weapon_"+id+"_damage", "repeating_weapon_"+id+"_damage-ability", "repeating_weapon_"+id+"_damage_ability_mult"], function (v) { var wepEnh = v["repeating_weapon_"+id+"_enhance"]; var wepDmgMisc = parseInt(v["repeating_weapon_"+id+"_damage"],10); //var wepDmgAbilSrc = parseInt(v["repeating_weapon_"+id+"_damage_ability"],10); // Is a selection box...  grrr this is gonna be tricky //var wepDmgAbilMulti = parseFloat(v["repeating_weapon_"+id+"_damage_ability_mult"],10); var wepAbilDam = 0; // RESERVED for the TOTALED value for ability damage * multiplier. var buff_DMG_Mod = parseFloat(v["DMG-mod"],10); var Damage = wepEnh + wepDmgMisc + buff_DMG_Mod;  // Incomplete equation needs case/if else statement to check ability score and atk type(melee,melee2,ranged,cmb,cmb2, etc) wepDamFinArray.Push(Damage); console.log("======= Pre-Callback: "+Damage); }); }); // now inside the callback, occurring after everything is built, execute.  var finalDamage = _.reduce(wepDamFinArray, function(m,a){return m+a;}, 0); console.log("======= Post-Callback Final Damage: "+finalDamage); setAttrs({ ["repeating_weapon_"+id+"_total-damage"]: finalDamage, }); }); // getSectionIDs });  // onChange eventhandler
1511582576

Edited 1511624255
GiGs
Pro
Sheet Author
API Scripter
Quick Question: which field in the screenshot is the above code trying to fill? It sounds like your code is only referring other fields within the same row, and if so, you dont need to use getSectionIDs, and your code will be much simpler. I cant tell exactly what you're calculating here, so can't give a proper answer, but the code would probably look something like the sample below.  The key thing to recognise is that if my guess is right about what you are doing, you can completely skip using ids. on("change:repeating_weapon:enhance change:repeating_weapon:damage-ability change:repeating_weapon:damage_ability_mod", function() { // notice in the above row, you replace the "_id_" section with a colon. // add a change statement for every stat that the final damage value is dependent on.     getAttrs(["STR","repeating_Weapon_enhance","repeating_Weapon_damage-ability", "repeating_Weapon_damage_ability_mult"], function(v) { // in getAttrs,enter the names in a different format - you replace the "_id_" with a single underscore. // include every stat you will need in the final damage calculation.         var enhance  = parseInt(v.repeating_Weapon_enhance)||0;         var damageAbility  = parseInt(v.repeating_Weapon_damage-ability)||0; // create a variable for every stat you are manipulating. // now you can manipulate the stats you have called and calculate final damage. // enter you code for that here, and then set the value with the following code.        setAttrs({                     "repeating_Weapon_total-damage": finalDamage                 });     }); });
Well, eventually, all of the grayed out fields, but until I figure this out I'm only working with the DAMAGE (Dmg).  If that would work, I would be tickled pink.  I do have some work to do later on with adding up weight, to calculate encumbrance and carry values.  But, I can worry about that later, its not nearly as important as damage/atk rolls.
1511609577
Finderski
Pro
Sheet Author
Compendium Curator
I think the real question GG is asking, though, a change in one row doesn't mean you need to re-calculate every row in the repeating section, correct?&nbsp; Because if you only need to worry about a single row, GG's code is the correct way to go.&nbsp; The only time you need to get all the section IDs if if you need to do something in all the different rows.&nbsp;&nbsp; As for the doing the weights and stuff...I'd recommend including TAS (<a href="https://github.com/shdwjk/TheAaronSheet/blob/master/TheAaronSheet.js" rel="nofollow">https://github.com/shdwjk/TheAaronSheet/blob/master/TheAaronSheet.js</a>) in your sheet's code—it has functions for summing things (like weight) already and it's a very simple call.
1511631156
Jakob
Sheet Author
API Scripter
Looks like he wants to include the global attribute DMG-mod in the calculation, so he needs the global version as well. However, you can take it apart and make a version that works for both all sections at once and one section at a time, depending on the situation. Something like this: const calcWeaponDamage = function (prefix) { const sourceAttrs = [ "DMG-mod", prefix+"_enhance", prefix+"_damage", prefix+"_damage-ability", prefix+"_damage_ability_mult", ]; getAttrs(sourceAttrs, function (v) { var wepEnh = parseInt(v[prefix+"_enhance"],10) || 0; var wepDmgMisc = parseInt(v[prefix+"_damage"],10) || 0; var buff_DMG_Mod = parseFloat(v["DMG-mod"],10) || 0; var Damage = wepEnh + wepDmgMisc + buff_DMG_Mod; setAttrs({ [prefix+"_total-damage"]: Damage, }); }); }; on('change:DMG-mod', function () { getSectionIDs('repeating_weapon', function (ids) { ids.forEach(id =&gt; calcWeaponDamage('repeating_weapon_'+id)); }); }); on('change:repeating_weapon', function () { calcWeaponDamage('repeating_weapon'); }); The idea is that prefix is "repeating_weapon" if the event is triggered from within a section, and it is "repeating_weapon"+id if we want to run the function from outside a repeating_weapon event.
1511640809

Edited 1511644486
Toby
Pro
Well, yes, but there are four possible external attributes.. DMG_Mod (for melee), DMG2_Mod (for alt melee), DMG_ranged_Mod (for ranged), and DMG_ranged2_Mod (for ranged2).&nbsp; And, its only added to the damage if the the correct.&nbsp; Attack Type is seleceted, the attack type value is already being used to hold the value for the attack rolls. So thats where the logic goes, I didn't speak of that because I've long since learned how to do that logic, assuming I can just plug that into this code and that it will work with the array style of sourceAttrs .&nbsp; I've never tried using that to set stuff.
1511658947

Edited 1511661456
Toby
Pro
Well, I have something that works, I have learned a lot from this... const calcWeaponDamage = function (prefix) { const sourceAttrs = [ "DMG-mod", "DMG2-mod", "DMG_ranged-mod", "DMG_ranged2-mod", 'PwrAtkDam', "APP-mod", "STR-mod", "DEX-mod", "CON-mod", "INT-mod", "WIS-mod", "CHA-mod", prefix+"_enhance", prefix+"_attack-type", prefix+"_damage", prefix+"_damage-ability", prefix+"_damage_ability_mult", prefix+"_damage-ability-max", prefix+"_masterwork", ]; getAttrs(sourceAttrs, function (v) { var atkType = v[prefix+"_attack-type"]; // Compare var damAbil = v[prefix+"_damage-ability"]; // Compare var attackType = " ", buff_DMG_mod = 0, damageAbil = " ", damAbilMod = 0; // Unset variables, yet. if (atkType === "0") {attackType="None", buff_DMG_mod=0;} if (atkType === "@{attk-melee}") {attackType="Melee", buff_DMG_mod=parseFloat(v["DMG-mod"],10) || 0;} if (atkType === "@{attk-melee2}") {attackType="Melee2", buff_DMG_mod=parseFloat(v["DMG2-mod"],10) || 0;} if (atkType === "@{attk-ranged}") {attackType="Ranged", buff_DMG_mod=parseFloat(v["DMG_ranged-mod"],10) || 0;} //if (atkType === "@{attk-ranged2}"){attackType="Ranged2", buff_DMG_mod=parseFloat(v["DMG_ranged2-mod"],10) || 0;}&nbsp; NOT USED, Yet. if (atkType === "@{attk-CMB}") {attackType="CMB";} if (atkType === "@{attk-CMB2}") {attackType="CMB2";} console.log("Attack Type: " +attackType+ " || Bonus Damage:" +buff_DMG_mod+ ".");&nbsp; &nbsp;// DOES NOT SHOW the propper damage?? if (damAbil === "0") {attackType="None";damAbilMod=0} if (damAbil === "@{APP-mod}") {damageAbil="APP Mod";damAbilMod=parseInt(v["APP-mod"]);}&nbsp; // Appearance Score, kinda like comelyness from AD&D, Houserule. if (damAbil === "@{STR-mod}") {damageAbil="STR Mod";damAbilMod=parseInt(v["STR-mod"]);} if (damAbil === "@{DEX-mod}") {damageAbil="DEX Mod";damAbilMod=parseInt(v["DEX-mod"]);} if (damAbil === "@{CON-mod}") {damageAbil="CON Mod";damAbilMod=parseInt(v["CON-mod"]);} if (damAbil === "@{INT-mod}") {damageAbil="INT Mod";damAbilMod=parseInt(v["INT-mod"]);} if (damAbil === "@{WIS-mod}") {damageAbil="WIS Mod";damAbilMod=parseInt(v["WIS-mod"]);} if (damAbil === "@{CHA-mod}") {damageAbil="CHA Mod";damAbilMod=parseInt(v["CHA-mod"]);} console.log("Damage Ability: " +damageAbil+ "+" +damAbilMod+ ".");&nbsp; // Does not show the proper ability modifier??&nbsp; Same problem as above console log? var wepEnh = parseInt(v[prefix+"_enhance"],10) || 0; var wepDmgMisc = parseInt(v[prefix+"_damage"],10) || 0; var abilDam = Math.max(damAbilMod * parseFloat(v[prefix+"_damage_ability_mult"]), parseInt(v[prefix+"_damage-ability-max"])); // I've never really understood abilty max... but okay.. var PwrAtk = parseInt(v["PwrAtkDam"])||0 * Math.max(parseFloat(v[prefix+"_damage_ability_mult"]),2);&nbsp; // Set Power Attack Based Abil Multiplier, with a maximum of x2 var Damage = wepEnh + wepDmgMisc + abilDam + PwrAtk + buff_DMG_mod; console.log("Damage Calculation: "+Damage+"= Enh:"+wepEnh+"+Mod"+wepDmgMisc+"+Abil"+abilDam+"+PwrAtk"+PwrAtk+"+Buffs"+buff_DMG_mod); /* From SWUtil.js || Parses an text or input field with @{xxx} or [[ xx ]] arithmatic into readable fields for SheetWorkers */ /* I have quickly learned to love SWUtils, I just wish there was more examples of how they work... */ evaluateAndSetNumber("repeating_weapon_attack","repeating_weapon_attack-mod"); evaluateAndSetNumber("repeating_weapon_crit_confirm","repeating_weapon_crit_conf_mod"); evaluateAndSetNumber("repeating_weapon_damage","repeating_weapon_damage-mod"); setAttrs({ [prefix+"_wepEnh"]: Math.max(parseInt(v["repeating_weapon_enhance"]),parseInt(v["repeating_weapon_masterwork"])), [prefix+"_total-damage"]: Damage, }); }); }; on('change:DMG-mod', function () { getSectionIDs('repeating_weapon', function (ids) { ids.forEach(id =&gt; calcWeaponDamage('repeating_weapon_'+id)); }); }); on('change:repeating_weapon', function () { calcWeaponDamage('repeating_weapon'); }); the&nbsp;const calcWeaponDamage = function (prefix) {....} in particular is different, I can see how that would be quite versatile and useful for separating different types of attributes that you wish to include. I'm not sure what the bottom two onChange() functions are actually doing, at least not specifically, the first appears to be looping through each repeating section row, but looping and doing what?&nbsp; That I cant see..&nbsp; And the second, maybe is setting the acceptable prefix? There are a few errors that are being throwing when this functions, specifically when the Buffs repeating section buffs are being enabled/disabled, I get a NaN in the console log that vanishes instantly, but it affects nothing, and doesn't seem to be causing issues with rolls or anything. And a more serious error that I have noticed just as I am writing this, that if I try and delete a row, it wont let me unless I click minimize/maximize all rows and thereby lock everything from moving around.&nbsp; Its hard to explain without alot of screenshots.&nbsp; It also seems to be releated to the NaN error. firebase.2.4.0.js:45 FIREBASE WARNING: Exception was thrown by user callback. Error: Firebase.update failed: First argument contains NaN in property 'stg-campaign-41092-XKZkxz5JZEsxvCFXxCI4Fg.char-attribs.char.-KQqjW1XrGfKWm2SWlPo.-KzprFQm2UXpt_1V6Odf.current' &nbsp; &nbsp; at hg (<a href="https://app.roll20dev.net/assets/firebase.2.4.0.js:123:203" rel="nofollow">https://app.roll20dev.net/assets/firebase.2.4.0.js:123:203</a>) &nbsp; &nbsp; at <a href="https://app.roll20dev.net/assets/firebase.2.4.0.j" rel="nofollow">https://app.roll20dev.net/assets/firebase.2.4.0.j</a>... &nbsp; &nbsp; at Fb (<a href="https://app.roll20dev.net/assets/firebase.2.4.0.js:28:656" rel="nofollow">https://app.roll20dev.net/assets/firebase.2.4.0.js:28:656</a>) &nbsp; &nbsp; at jg (<a href="https://app.roll20dev.net/assets/firebase.2.4.0.js:126:134" rel="nofollow">https://app.roll20dev.net/assets/firebase.2.4.0.js:126:134</a>) &nbsp; &nbsp; at X.update (<a href="https://app.roll20dev.net/assets/firebase.2.4.0.js:258:369" rel="nofollow">https://app.roll20dev.net/assets/firebase.2.4.0.js:258:369</a>) &nbsp; &nbsp; at <a href="https://app.roll20dev.net/assets/firebase.2.4.0.j" rel="nofollow">https://app.roll20dev.net/assets/firebase.2.4.0.j</a>... &nbsp; &nbsp; at c (<a href="https://app.roll20dev.net/assets/firebase.2.4.0.js:240:58" rel="nofollow">https://app.roll20dev.net/assets/firebase.2.4.0.js:240:58</a>) &nbsp; &nbsp; at <a href="https://app.roll20dev.net/assets/firebase.2.4.0.j" rel="nofollow">https://app.roll20dev.net/assets/firebase.2.4.0.j</a>... &nbsp; &nbsp; at gc (<a href="https://app.roll20dev.net/assets/firebase.2.4.0.js:52:165" rel="nofollow">https://app.roll20dev.net/assets/firebase.2.4.0.js:52:165</a>) &nbsp; &nbsp; at cc (<a href="https://app.roll20dev.net/assets/firebase.2.4.0.js:30:216" rel="nofollow">https://app.roll20dev.net/assets/firebase.2.4.0.js:30:216</a>)&nbsp; S @ firebase.2.4.0.js:45 (anonymous) @ firebase.2.4.0.js:52 setTimeout (async) gc @ firebase.2.4.0.js:52 cc @ firebase.2.4.0.js:30 bc @ firebase.2.4.0.js:29 Qi @ firebase.2.4.0.js:224 h.Ib @ firebase.2.4.0.js:238 h.Og @ firebase.2.4.0.js:240 Backbone.sync @ app.js?1509374274:3 save @ base.js?1507671575:1 syncedSave @ app.js?1509374274:40 (anonymous) @ app.js?1509374274:47 k.each.k.forEach @ base.js?1507671575:1 h.(anonymous function) @ base.js?1507671575:1 (anonymous) @ app.js?1509374274:47 firebase.2.4.0.js:123 Uncaught Error: Firebase.update failed: First argument contains NaN in property 'stg-campaign-41092-XKZkxz5JZEsxvCFXxCI4Fg.char-attribs.char.-KQqjW1XrGfKWm2SWlPo.-KzprFQm2UXpt_1V6Odf.current' &nbsp; &nbsp; at hg (firebase.2.4.0.js:123) &nbsp; &nbsp; at firebase.2.4.0.js:126 &nbsp; &nbsp; at Fb (firebase.2.4.0.js:28) &nbsp; &nbsp; at jg (firebase.2.4.0.js:126) &nbsp; &nbsp; at X.update (firebase.2.4.0.js:258) &nbsp; &nbsp; at app.js?1509374274:3 &nbsp; &nbsp; at c (firebase.2.4.0.js:240) &nbsp; &nbsp; at firebase.2.4.0.js:201 &nbsp; &nbsp; at gc (firebase.2.4.0.js:52) &nbsp; &nbsp; at cc (firebase.2.4.0.js:30) Anyways, I intend to keep fiddling, but I wanted to thank you for all your assistance.
1511662507
GiGs
Pro
Sheet Author
API Scripter
It sounds like you are a bit unclear on what the on:change events actually are for. They are needed to launch the function att he top of the code. They are like sensors that watch specific attributes on your sheet, and when those attributes change, they detect that and perform the code inside the change function. In this case, the first on-change event watches your DMG-Mod attribute. When that attribute changes, the change event code loops through each row of your repeating section, and sends the id of the row to the function at the top of the code. The second on-change is triggered when something in a row changes, and updates only that row, so it doesnt need the id. You can change the first&nbsp;on-change trigger to capture changes to more attributes, like this: on('change:DMG-mod change:DMG2-mod change:DMG_ranged-mod change:DMG_ranged2-mod change:PwrAtkDam change:APP-mod change:STR-mod change:DEX-mod change:CON-mod change:INT-mod change:WIS-mod change:CHA-mod', function () { getSectionIDs('repeating_weapon', function (ids) { ids.forEach(id =&gt; calcWeaponDamage('repeating_weapon_'+id)); }); }); That way whenever any of those stats change, the weapon rows will be updated. For error checking, I would put a console.log statement after every var statement, to check the variable is being set properly, and see what it is being set to.&nbsp; I'd also delete everything from "var attack type" up to and including the set attr fucntion, make sure that works, then add the rest of your code one line at a time, test it, and so on. That's the easiest way to find out where your error lies. So start with something like this: &nbsp;const calcWeaponDamage = function (prefix) { const sourceAttrs = [ "DMG-mod", "DMG2-mod", "DMG_ranged-mod", "DMG_ranged2-mod", 'PwrAtkDam', "APP-mod", "STR-mod", "DEX-mod", "CON-mod", "INT-mod", "WIS-mod", "CHA-mod", prefix+"_enhance", prefix+"_attack-type", prefix+"_damage", prefix+"_damage-ability", prefix+"_damage_ability_mult", prefix+"_damage-ability-max", prefix+"_masterwork", ]; getAttrs(sourceAttrs, function (v) { var atkType = v[prefix+"_attack-type"]; // Compare console.log("AtkType = " + atkType); var damAbil = v[prefix+"_damage-ability"]; // Compare console.log("damAbil = " + damAbil); var attackType = " ", buff_DMG_mod = 0, damageAbil = " ", damAbilMod = 0; // Unset variables, yet. }); }; on('change:DMG-mod', function () { getSectionIDs('repeating_weapon', function (ids) { ids.forEach(id =&gt; calcWeaponDamage('repeating_weapon_'+id)); }); }); on('change:repeating_weapon', function () { calcWeaponDamage('repeating_weapon'); }); It's laborious, but it works.
1511663616

Edited 1511663682
Toby
Pro
Ah, yes..&nbsp; thanks for pointing that out about the ability scores, I already caught the power attack.. I have a totaled field called ability_total &nbsp;or something similar that I use when I need to check for any of my ability scores.&nbsp; If any one of them changes it automatically changes that.&nbsp; Maybe I should do the same for the damages, although, perhaps not I want the attack rolls to run very quickly. As for that method of checking, yeah.. I could do that.. I'm not looking forward to trying to figure out whats going on, I wish the console log gave more information.&nbsp; You'd need a degree in rocket science to understand that "uncaught firebase" jibberish its spouting. Now, from what I can see, there is something wrong with how attributes are being updated from outside the repeating sections, because it only flashes that that error when I change things OUTSIDE the repeating section OR I try and delete a row. That being said, I have narrowed it down.&nbsp; It seems to be something funky with my ability scores, they are being totaled in with the multiplier and the max ability score... formula.. var abilDam = Math.max(damAbilMod * parseFloat(v[prefix+"_damage_ability_mult"]), parseInt(v[prefix+"_damage-ability-max"])); // I've never really understood abilty max... but okay.. Or least thats what I suspect, as I am very often getting a NaN in my own console.log for my damage totals, and its always with the ability score, the tricky thing is, its never there for more than an instant.&nbsp; Its as if its being unset by something else and then reset a moment later.&nbsp; Which, is really weird..
1511664333
GiGs
Pro
Sheet Author
API Scripter
Have you fixed this bit that occurs earlier in the code? console.log("Damage Ability: " +damageAbil+ "+" +damAbilMod+ ".");&nbsp; // Does not show the proper ability modifier??&nbsp; Same problem as above console log? Minor recommendation, you could add else statements to your if chains, like so: if (atkType === "0") {attackType="None", buff_DMG_mod=0;} else if (atkType === "@{attk-melee}") {attackType="Melee", buff_DMG_mod=parseFloat(v["DMG-mod"],10) || 0;} else if (atkType === "@{attk-melee2}") {attackType="Melee2", buff_DMG_mod=parseFloat(v["DMG2-mod"],10) || 0;} so that roll20 only processes the if statements it needs to, and skips over the rest once it finds a match.
1511667171

Edited 1511667226
Toby
Pro
Yes.&nbsp; I fixed that earlier bit of code, or rather it fixed it self, and added in the if..else statements. Now, I step by step removed one part of the code after another as you suggested.&nbsp; Nothing worked until I removed the entire&nbsp; getAttrs(sourceAttrs, function (v) {...}; All of it...&nbsp; and then the issue vanished..&nbsp; Yeah, well that's not so helpful..&nbsp; Also, as I worked I added comments to each variable, I saw nothing that I did not expect.
1511674769
GiGs
Pro
Sheet Author
API Scripter
Which issue vanished? It's hard to know what's happening, because your comments in the code refer to some variables not being set properly, but the problems you describe are extra problems on top of that, and we have no idea which issues you are working on. I dont know if its relevant, but i notice you reference a stat prefix+"_damage-ability-max a couple of times. Is this an actual attribute, or is it an attempt to access the max value of prefix+"_damage-ability? If you're trying to access the max value of an attribute, it should be&nbsp; _damage-ability_max . An underscore instead of a dash. If you change values just within a single row, and not changing values outside the row, work properly? Also, it might be worth showing your repeating section code from the html part of your character sheet.
The NaN issues vanish when I removed the getAttrs() and everything within.&nbsp; I have set all kinda of console.logs() to try and find what isnt being set, and nothing is showing up.&nbsp; Absolutely nothing. the prefix+"_damage-ability-max &nbsp;refers to an actual attribute, an attribute that maxes out the ability score multiplier (I've never seen it used in pathfinder but I suppose it could be useful so I included it). If I only manipulate the values within the row itself, yes.&nbsp; Everything works as intended EXCEPT when I try and delete the a row, the row is successfully removed but a new one and blank one is instantly added in its place.&nbsp; Unless I lock the row's position using the minimize and lock CSS stuff.&nbsp; When I do that the row vanishes and is successfully removed. const calcWeaponDamage = function (prefix) { const sourceAttrs = [ "DMG-mod", "DMG2-mod", "DMG_ranged-mod", "DMG_ranged2-mod", 'PwrAtkDam', "APP-mod", "STR-mod", "DEX-mod", "CON-mod", "INT-mod", "WIS-mod", "CHA-mod", prefix+"_enhance", prefix+"_attack-type", prefix+"_damage", prefix+"_damage-ability", prefix+"_damage_ability_mult", prefix+"_damage-ability-max", prefix+"_masterwork", ]; getAttrs(sourceAttrs, function (v) { var atkType = v[prefix+"_attack-type"]; // Compare console.log(prefix+"_attack-type" +atkType+ "."); var damAbil = v[prefix+"_damage-ability"]; // Compare console.log(prefix+"_damage-ability" +damAbil+ "."); var attackType = " ", buff_DMG_mod = 0, damageAbil = " ", damAbilMod = 0; // Unset variables, yet. console.log("buff_DMG_mod PRE: " +buff_DMG_mod+ "."); console.log("damAbilMod PRE: " +damAbilMod+ "."); if (atkType === "0") {attackType="None", buff_DMG_mod=0;} else if (atkType === "@{attk-melee}") {attackType="Melee", buff_DMG_mod=parseFloat(v["DMG-mod"],10) || 0;} else if (atkType === "@{attk-melee2}") {attackType="Melee2", buff_DMG_mod=parseFloat(v["DMG2-mod"],10) || 0;} else if (atkType === "@{attk-ranged}") {attackType="Ranged", buff_DMG_mod=parseFloat(v["DMG_ranged-mod"],10) || 0;} //else if (atkType === "@{attk-ranged2}"){attackType="Ranged2", buff_DMG_mod=parseFloat(v["DMG_ranged2-mod"],10) || 0;}&nbsp; NOT USED, Yet. else if (atkType === "@{attk-CMB}") {attackType="CMB";} else if (atkType === "@{attk-CMB2}") {attackType="CMB2";} console.log("Attack Type: " +attackType+ " || Bonus Damage:" +buff_DMG_mod+ ".");&nbsp; &nbsp;// DOES NOT SHOW the propper damage?? if (damAbil === "0") {attackType="None";damAbilMod=0} else if (damAbil === "@{APP-mod}") {damageAbil="APP Mod";damAbilMod=parseInt(v["APP-mod"])||0;}&nbsp; // Appearance Score, kinda like comelyness from AD&D, Houserule. else if (damAbil === "@{STR-mod}") {damageAbil="STR Mod";damAbilMod=parseInt(v["STR-mod"])||0;} else if (damAbil === "@{DEX-mod}") {damageAbil="DEX Mod";damAbilMod=parseInt(v["DEX-mod"])||0;} else if (damAbil === "@{CON-mod}") {damageAbil="CON Mod";damAbilMod=parseInt(v["CON-mod"])||0;} else if (damAbil === "@{INT-mod}") {damageAbil="INT Mod";damAbilMod=parseInt(v["INT-mod"])||0;} else if (damAbil === "@{WIS-mod}") {damageAbil="WIS Mod";damAbilMod=parseInt(v["WIS-mod"])||0;} else if (damAbil === "@{CHA-mod}") {damageAbil="CHA Mod";damAbilMod=parseInt(v["CHA-mod"])||0;} console.log("Damage Ability: " +damageAbil+ "+" +damAbilMod+ ".");&nbsp; // Does not show the proper ability modifier??&nbsp; Same problem as above console log? var wepEnh = parseInt(v[prefix+"_enhance"],10) || 0; console.log("wepEnh: " +wepEnh+ "."); var wepDmgMisc = parseInt(v[prefix+"_damage"],10) || 0; console.log("wepDmgMisc: " +wepDmgMisc+ "."); var abilDam = Math.max(damAbilMod * parseFloat(v[prefix+"_damage_ability_mult"]), parseInt(v[prefix+"_damage-ability-max"])); // I've never really understood abilty max... but okay.. console.log("abilDam: " +abilDam+ "."); var PwrAtk = parseInt(v["PwrAtkDam"])||0 * Math.max(parseFloat(v[prefix+"_damage_ability_mult"]),2);&nbsp; // Set Power Attack Based Abil Multiplier, with a maximum of x2 var Damage = wepEnh + wepDmgMisc + damAbilMod + PwrAtk + buff_DMG_mod; console.log("Damage Calculation: "+Damage+"= Enh: "+wepEnh+"+Mod: "+wepDmgMisc+"+Abil: "+abilDam+"PwrAtk: "+PwrAtk+"+Buffs: "+buff_DMG_mod); /* From SWUtil.js || Parses an text or input field with @{xxx} or [[ xx ]] arithmatic into readable fields for SheetWorkers */ /* I have quickly learned to love SWUtils, I just wish there was more examples of how they work... */ evaluateAndSetNumber("repeating_weapon_attack","repeating_weapon_attack-mod"); evaluateAndSetNumber("repeating_weapon_crit_confirm","repeating_weapon_crit_conf_mod"); evaluateAndSetNumber("repeating_weapon_damage","repeating_weapon_damage-mod"); setAttrs({ [prefix+"_wepEnh"]: Math.max(parseInt(v["repeating_weapon_enhance"]),parseInt(v["repeating_weapon_masterwork"])), [prefix+"_total-damage"]: Damage, }); }); }; on('change:APP-mod change:STR-mod change:DEX-mod change:CON-mod change:INT-mod change:WIS-mod change:CHA-mod change:DMG-mod change:DMG2-mod change:DMG_ranged-mod change:DMG_ranged2-mod change:toggle-PwrAtk', function () { getSectionIDs('repeating_weapon', function (ids) { ids.forEach(id =&gt; calcWeaponDamage('repeating_weapon_'+id)); }); }); on('change:repeating_weapon', function () { calcWeaponDamage('repeating_weapon'); }); Repeating Section HTML: &lt;fieldset class="repeating_weapon"&gt; &lt;input type="hidden" name="attr_wep-damage" title="wep-damage" value="[[@{damage-dice-num}d@{damage-die}+@{total-damage}]]"&gt; &lt;input type="hidden" name="attr_wepEnh" title="@{wepEnh}" readonly="readonly"&gt; &lt;input type="hidden" name="attr_wReach" title="@{wReach}" value="**Reach:** @{range} ft."&gt; &lt;input type="hidden" name="attr_wRange" title="@{wRange}" value="**Range:** @{range} ft."&gt; &lt;span class="sheet-error"&gt;&lt;span class="sheet-pictos"&gt;!&lt;/span&gt;&lt;span data-i18n="error-msg1"&gt;Error! You must delete this row before editing any items in this section.&lt;/span&gt;&lt;/span&gt; &lt;div class="sheet-nontable-repeating"&gt; &lt;input type="checkbox" class="sheet-counted sheet-sect-show" data-i18n-title="minimize-cmd" title="Minimize Row" name="attr_row-show" value="1" checked="checked" /&gt;&lt;span&gt;&lt;/span&gt; &lt;span class="sheet-repeating-rollbutton"&gt;&lt;button type="roll" name="attr_roll" title="%{selected|repeating_weapon_$X_roll}" value="@{macro-text}"&gt;&lt;/button&gt;&lt;/span&gt; &lt;span style="display:none;" class="sheet-repeating-rollbutton"&gt;&lt;button type="roll" name="attr_attack-npc-roll" title="%{selected|repeating_weapon_$X_attack-npc-roll}" value="@{NPC-macro-text}"&gt;&lt;/button&gt;&lt;/span&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers sheet-sect"&gt;&lt;input type="number" name="attr_enhance" title="@{repeating_weapon_$X_enhance}" value="0"&nbsp; /&gt;&lt;span data-i18n="enhancement-abbrv"&gt;Enh&lt;/span&gt;&lt;/label&gt; &lt;label class="sheet-small-label2 sheet-sect" style="width:2.125em;" &gt;&lt;input type="checkbox" name="attr_masterwork" title="@{repeating_weapon_$X_masterwork}" value="1" class="sheet-noshow" /&gt;&lt;span data-i18n="masterwork-abbrv"&gt;Mwk&lt;/span&gt;&lt;/label&gt; &lt;label class="sheet-small-label2 sheet-entry-25p-shrink"&gt;&lt;input type="text" name="attr_name" title="@{repeating_weapon_$X_name}" placeholder="Name" data-i18n-placeholder="name"/&gt;&lt;span data-i18n="name"&gt;Name&lt;/span&gt;&lt;/label&gt; &lt;div class="sheet-linked-fields sheet-sect"&gt; &lt;label class="sheet-small-label2 sheet-entry-short sheet-macro-text-inline" &gt;&lt;input type="text" name="attr_attack" title="@{repeating_weapon_$X_attack}" placeholder="# or Macro" value="0" data-i18n-placeholder="equation-macro-place" class="sheet-macro-text"/&gt;&lt;span data-i18n="attack-modifiers-abbrv"&gt;Attack Mods&lt;/span&gt;&lt;/label&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers" &gt;&lt;input type="number" name="attr_attack-mod" title="@{repeating_weapon_$X_attack-mod}" value="@{attack}" class="sheet-calc" readonly /&gt;&lt;span data-i18n="value-abbrv"&gt;val&lt;/span&gt;&lt;/label&gt; &lt;/div&gt; &lt;span class="sheet-divider-db sheet-sect"&gt;+&lt;/span&gt; &lt;label class="sheet-small-label2 sheet-entry-short"&gt; &lt;select class="sheet-select-small" title="@{repeating_weapon_$X_attack-type}" name="attr_attack-type"&gt; &lt;option value="0" data-i18n="none-default" selected&gt;&#8226;None&lt;/option&gt; &lt;option value="@{attk-melee}" data-i18n="melee"&gt;Melee&lt;/option&gt; &lt;option value="@{attk-melee2}" data-i18n="melee2"&gt;Melee2&lt;/option&gt; &lt;option value="@{attk-ranged}" data-i18n="ranged"&gt;Ranged&lt;/option&gt; &lt;!-- &lt;option value="@{attk-ranged2}" data-i18n="ranged2"&gt;Ranged2&lt;/option&gt; --&gt; &lt;option value="@{attk-CMB}" data-i18n="combat-maneuver-bonus-abbrv"&gt;CMB&lt;/option&gt; &lt;option value="@{attk-CMB2}" data-i18n="combat-maneuver-bonus-abbrv2"&gt;CMB2&lt;/option&gt; &lt;/select&gt; &lt;span data-i18n="attack-type"&gt;Attack Type&lt;/span&gt; &lt;/label&gt; &lt;span class="sheet-divider-db sheet-sect" style="margin-left:-5px"&gt;=&lt;/span&gt;&lt;!-- [[ [[{@{enhance}, @{masterwork}}kh1]][Enh] ]] + @{attack} + @{attack-type} || Final: [[ [[{@{enhance}, @{masterwork}}kh1]][Enh] + [[@{attack-mod}]][Mod] + [[@{attack-type}]][Type] ]] --&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers sheet-space-right-collapse"&gt;&lt;input type="number" name="attr_total-attack" title="@{repeating_weapon_$X_total-attack}" value="(@{wepEnh}+ @{attack-mod} + [[@{attack-type}}]])" class="sheet-calc" disabled /&gt;&lt;span data-i18n="attack"&gt;Attack&lt;/span&gt;&lt;/label&gt; &lt;label class="sheet-small-label2 sheet-entry-small sheet-sect"&gt; &lt;select class="sheet-select-small" name="attr_vs"&gt; &lt;option value="ac" data-i18n="armor-class-abbrv-default" selected&gt;&#8226;AC&lt;/option&gt; &lt;option value="touch" data-i18n="touch"&gt;Touch&lt;/option&gt; &lt;option value="ff" data-i18n="flat-footed-armor-class-abbrv"&gt;FF&lt;/option&gt; &lt;option value="fft" data-i18n="flat-footed-touch-abbrv"&gt;FF Touch&lt;/option&gt; &lt;option value="cmd" data-i18n="combat-maneuver-defense-abbrv"&gt;CMD&lt;/option&gt; &lt;option value="cmb" data-i18n="opposed-combat-maneuver-bonus-abbrv"&gt;Opposed CMB&lt;/option&gt; &lt;option value="other" data-i18n="other"&gt;Other&lt;/option&gt; &lt;/select&gt; &lt;span data-i18n="versus-abbrv"&gt;Vs.&lt;/span&gt; &lt;/label&gt; &lt;div class="sheet-linked-fields"&gt; &lt;span class="sheet-divider-db-lg sheet-sect" style="width:1em;" style="padding-bottom:10px;"&gt;1-&lt;/span&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers sheet-sect"&gt;&lt;input type="number" name="attr_fail-target" title="@{repeating_weapon_$X_fail-target}" value="1" min="0" max="20" /&gt;&lt;span data-i18n="fail-abbrv"&gt;Fail&lt;/span&gt;&lt;/label&gt; &lt;/div&gt; &lt;div class="sheet-linked-fields"&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers"&gt;&lt;input type="number" name="attr_crit-target" title="@{repeating_weapon_$X_crit-target}" value="20" min="0" max="20" /&gt;&lt;span data-i18n="critical-abbrv"&gt;Crit&lt;/span&gt;&lt;/label&gt; &lt;span class="sheet-divider-db-lg" style="width:1em;" style="padding-bottom:10px;"&gt;/x&lt;/span&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers"&gt;&lt;input type="number" name="attr_crit-multiplier" title="@{repeating_weapon_$X_crit-multiplier}" value="2" min="0" /&gt;&lt;span data-i18n="multiplier-abbrv"&gt;Mult&lt;/span&gt;&lt;/label&gt; &lt;/div&gt; &lt;div class="sheet-linked-fields"&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers sheet-sect" &gt;&lt;input type="number" name="attr_crit_confirm" title="@{repeating_weapon_$X_crit_confirm}" value="0" /&gt;&lt;span data-i18n-title="custom-crit-confirmation-bonus" title="Custom critical confirmation bonus for this attack" data-i18n="confirm-critical-bonus-abbrv"&gt;+Conf&lt;/span&gt;&lt;/label&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers sheet-space-right-collapse"&gt;&lt;input type="number" name="attr_crit_conf_mod" title="@{repeating_weapon_$X_crit_conf_mod}" value="@{crit_confirm}" class="sheet-calc" readonly /&gt;&lt;span data-i18n="confirm-critical-bonus-abbrv"&gt;+Conf&lt;/span&gt;&lt;/label&gt; &lt;/div&gt; &lt;div class="sheet-linked-fields"&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers"&gt;&lt;input type="number" name="attr_damage-dice-num" title="@{repeating_weapon_$X_damage-dice-num}" value="0" min="0" /&gt;&lt;span data-i18n="dice"&gt;Dice&lt;/span&gt;&lt;/label&gt; &lt;span class="sheet-divider-db-lg" style="padding-bottom: 10px;margin-right:-.125em;" data-i18n="dice-abbrv"&gt;d&lt;/span&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers"&gt;&lt;input type="number" name="attr_damage-die" title="@{repeating_weapon_$X_damage-die}" value="0" min="0" /&gt;&lt;span data-i18n="die"&gt;Die&lt;/span&gt;&lt;/label&gt; &lt;/div&gt; &lt;span class="sheet-divider-db sheet-sect"&gt;+&lt;/span&gt; &lt;div class="sheet-linked-fields sheet-sect"&gt; &lt;label class="sheet-small-label2 sheet-entry-short sheet-macro-text-inline"&gt;&lt;input type="text" name="attr_damage" title="@{repeating_weapon_$X_damage}" placeholder="# or Macro" value="0" data-i18n-placeholder="equation-macro-place" class="sheet-macro-text"/&gt;&lt;span data-i18n="damage-modifier-abbrv"&gt;Dmg Mods&lt;/span&gt;&lt;/label&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers"&gt;&lt;input type="number" name="attr_damage-mod" title="@{repeating_weapon_$X_damage-mod}" value="@{damage}" class="sheet-calc" readonly /&gt;&lt;span data-i18n="value-abbrv"&gt;val&lt;/span&gt;&lt;/label&gt; &lt;/div&gt; &lt;span class="sheet-divider-db"&gt;+&lt;/span&gt; &lt;span class="sheet-divider-db sheet-sect"&gt;(&lt;/span&gt; &lt;label class="sheet-small-label2 sheet-entry-small sheet-sect" style="margin-left: -5px;margin-right:-6px;"&gt; &lt;select class="sheet-select-small" title="@{repeating_weapon_$X_damage-ability}" name="attr_damage-ability"&gt; &lt;option value="0" data-i18n="none-default" selected&gt;&#8226;None&lt;/option&gt; &lt;option value="@{APP-mod}" data-i18n="appearence-abbrv"&gt;APP&lt;/option&gt; &lt;option value="@{STR-mod}" data-i18n="strength-abbrv"&gt;STR&lt;/option&gt; &lt;option value="@{DEX-mod}" data-i18n="dexterity-abbrv"&gt;DEX&lt;/option&gt; &lt;option value="@{CON-mod}" data-i18n="constitution-abbrv"&gt;CON&lt;/option&gt; &lt;option value="@{INT-mod}" data-i18n="intelligence-abbrv"&gt;INT&lt;/option&gt; &lt;option value="@{WIS-mod}" data-i18n="wisdom-abbrv"&gt;WIS&lt;/option&gt; &lt;option value="@{CHA-mod}" data-i18n="charisma-abbrv"&gt;CHA&lt;/option&gt; &lt;/select&gt; &lt;span style="margin-left:-.75em;" data-i18n="damage-ability"&gt;Dmg Ability&lt;/span&gt; &lt;/label&gt; &lt;span class="sheet-divider-db-lg sheet-sect"&gt;*&lt;/span&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers sheet-sect" style="margin-left:-6px;"&gt;&lt;input type="number" step=".5" name="attr_damage_ability_mult" title="@{repeating_weapon_$X_damage_ability_mult}" value="1" &gt;&lt;span data-i18n="multiplier-abbrv" data-i18n-title="damage-multiplier-title" title="Damage ability modifier: .5, 1.5, 2, etc, can leave blank to represent 1." &gt;Mult&lt;/span&gt;&lt;/label&gt; &lt;span class="sheet-divider-db sheet-sect"&gt;)&lt;/span&gt; &lt;span class="sheet-divider-db sheet-sect"&gt;(&lt;/span&gt; &lt;label class="sheet-small-label2 sheet-sect" style="width:1.75em;margin-left:-5px;margin-right:-5px;"&gt;&lt;input style="min-width:.5em;" type="text" name="attr_damage-ability-max" title="@{repeating_weapon_$X_damage-ability-max}" value="1" placeholder="NA" data-i18n-placeholder="not-applicable"/&gt; &lt;span data-i18n-title="maximum-damage-ability-title" title="Maximum damage ability applied (for strength score, etc.)" data-i18n="maximum-abbrv"&gt;Max&lt;/span&gt;&lt;/label&gt; &lt;span class="sheet-divider-db sheet-sect"&gt;)&lt;/span&gt; &lt;span class="sheet-divider-db sheet-sect"&gt;=&lt;/span&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers sheet-space-right-collapse"&gt;&lt;input type="number" name="attr_total-damage" title="@{repeating_weapon_$X_total-damage}" value="[[@{wepEnh}[Enh]+@{damage-mod}[Misc]+[[floor(@{damage-ability}*@{damage_ability_mult})]][Mod]+ ]]" class="sheet-calc" readonly /&gt;&lt;span data-i18n="damage-abbrv"&gt;Dmg&lt;/span&gt;&lt;/label&gt; &lt;label class="sheet-small-label2 sheet-entry-8p-shrink"&gt;&lt;input type="text" name="attr_damType" title="@{repeating_weapon_$X_damType} Damage Type" data-i18n-placeholder="pierce-blunt-slash-abbrv" placeholder="P B S" /&gt;&lt;span data-i18n="type"&gt;Type&lt;/span&gt;&lt;/label&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers sheet-sect2"&gt;&lt;input type="number" name="attr_range" title="@{repeating_weapon_$X_range}" value="0" min="0" /&gt;&lt;span data-i18n="range"&gt;Range&lt;/span&gt;&lt;/label&gt; &lt;label class="sheet-small-label2 sheet-narrow-numbers sheet-sect"&gt;&lt;input type="number" name="attr_ammo" title="@{repeating_weapon_$X_ammo}" value="0" style="width:2.8em;" /&gt;&lt;span data-i18n="ammo"&gt;Ammo&lt;/span&gt;&lt;/label&gt; &lt;div class="sheet-small-label2 sheet-sect" style="width:99%;height:auto;clear:both;margin-bottom:0;"&gt; &lt;textarea class="sheet-inline-textarea" name="attr_notes" title="@{repeating_weapon_$X_notes}" placeholder="Weapon Notes"&gt;&lt;/textarea&gt; &lt;span data-i18n="notes"&gt;Notes&lt;/span&gt; &lt;/div&gt; &lt;input type="hidden" name="attr_attack-type_macro_insert" value="@{toggle_global_melee_macro_insert}" /&gt; &lt;input type="hidden" name="attr_damage-type_macro_insert" value="@{toggle_global_melee_damage_macro_insert}" /&gt; &lt;input type="hidden" name="attr_macro_options" value="" /&gt; &lt;input type="hidden" name="attr_iterative_attacks" value="@{var_iterative_attack1_macro} @{toggle_iterative_attack2} @{toggle_iterative_attack3} @{toggle_iterative_attack4} @{toggle_iterative_attack5} @{toggle_iterative_attack6} @{toggle_iterative_attack7} @{toggle_iterative_attack8}" /&gt; &lt;input type="hidden" name="attr_attack_macro" value="[[ @{total-attack} ]] [Total] + @{proficiency}[Prof] + @{toggle_attack_macro_insert}" /&gt; &lt;input type="hidden" name="attr_damage_macro" value="[[ @{total-damage} ]] [Total] + @{toggle_damage_macro_insert}" /&gt; &lt;div class="sheet-sect sheet-expand"&gt; &lt;input type="checkbox" class="sheet-showarrow sheet-extra-damage-show" name="attr_add-damage-show" value="1" title="Add additional, precision, or extra critical damage" data-i18n-title="additional-damage-title" aria-label="Show Additional Damage" data-i18n-aria-label="additional-damage" aria-i18n-describedby="Add additional, precision, or extra critical damage" checked="checked"/&gt; &lt;label class="sheet-showsect sheet-extra-damage-showlabel" data-i18n="additional-damage"&gt;Additional Damage&lt;/label&gt; &lt;input type="checkbox" class="sheet-showarrow sheet-iterations-show" title="iterative-attacks-title" data-i18n-title="iterative-attacks-title" aria-label="Show Iterative Attacks" aria-describedby="Add additional attacks for this weapon."&nbsp; name="attr_iterative-attacks-show" value="1" checked="checked"/&gt; &lt;label class="sheet-showsect sheet-iterations-showlabel" data-i18n="iterative-attacks"&gt;Iterative Attacks&lt;/label&gt; &lt;input type="checkbox" class="sheet-showarrow sheet-macro-text-show" title="Click to expand" data-i18n-title="showsect-cmd" aria-label="Show Macro Text" name="attr_macro-text-show" value="1" checked="checked"/&gt; &lt;label class="sheet-showsect sheet-macro-text-showlabel" data-i18n="macro-text"&gt;Macro Text&lt;/label&gt; &lt;input type="checkbox" class="sheet-showarrow sheet-misc-attack-show" name="attr_misc-attack-show" value="1" title="Misc Weapon & attack details" checked="checked"/&gt; &lt;label class="sheet-showsect sheet-misc-attack-showlabel" data-i18n="miscellaneous-abbrv"&gt;Misc Details&lt;/label&gt; &lt;input type="checkbox" class="sheet-showarrow sheet-id-show" title="Click to expand" data-i18n-title="showsect-cmd" aria-label="Show Row ID" name="attr_ids-show" value="1" checked="checked"/&gt; &lt;label class="sheet-showsect sheet-id-showlabel" data-i18n="identification-abbrv"&gt;ID&lt;/label&gt; &lt;div class="sheet-cheat"&gt;&lt;/div&gt; &lt;div class="sheet-extra-damage sheet-center"&gt; &lt;label class="sheet-small-label2" style="width:23.85%;"&gt; &lt;span data-i18n-title="precision-damage-title" title="Extra or Precision Damage (not added to critical damage)" data-i18n="extra-damage"&gt;Extra Non-Crit Dmg&lt;/span&gt; &lt;textarea class="sheet-inline-textarea-both" type="text" name="attr_precision_dmg_macro" title="@{repeating_weapon_$X_precision_dmg_macro}" placeholder="+[[1d6]] or Macro/Query" data-i18n-placeholder="full-macro-place"&gt;&lt;/textarea&gt; &lt;/label&gt; &lt;label class="sheet-small-label2" style="width:23.85%;"&gt; &lt;span data-i18n-title="precision-damage-type" title="Extra Damage type" data-i18n="type"&gt;Type&lt;/span&gt; &lt;input style="height:2.15em;" type="text" name="attr_precision_dmg_type" title="@{repeating_weapon_$X_precision_dmg_type}" value="" placeholder="[B/P/S] or [F/A/C/E/N/Pos] Limited Room Only" data-i18n-placeholder="damage-type-or-description" /&gt; &lt;/label&gt; &lt;label class="sheet-small-label2" style="width:23.85%;"&gt; &lt;span data-i18n-title="extra-critical-damage-title" title="Extra Critical Damage" data-i18n="extra-critical-damage"&gt;Extra Crit Dmg&lt;/span&gt; &lt;textarea class="sheet-inline-textarea-both" type="text" name="attr_critical_dmg_macro" title="@{repeating_weapon_$X_critical_dmg_macro}" placeholder="+[[2d10]] or Macro/Query" data-i18n-placeholder="full-macro-place"&gt;&lt;/textarea&gt; &lt;/label&gt; &lt;label class="sheet-small-label2" style="width:23.85%;"&gt; &lt;span data-i18n-title="precision-damage-type" title="Extra Damage type" data-i18n="type"&gt;Type&lt;/span&gt; &lt;input style="height:2.15em;" type="text" name="attr_critical_dmg_type" title="@{repeating_weapon_$X_critical_dmg_type}" value="" placeholder="[B/P/S] or [F/A/C/E/N/Pos] Limited Room Only" data-i18n-placeholder="damage-type-or-description" /&gt; &lt;/label&gt; &lt;/div&gt; &lt;div class="sheet-table sheet-iterative_attack_section"&gt; &lt;span class="sheet-table-name" data-i18n="iterative-attacks"&gt;Iterative Attacks&lt;/span&gt; &lt;div class="sheet-table-row"&gt; &lt;span class="sheet-table-header" style="width: 14em;" data-i18n="include-attacks-?"&gt;Include Attack?&lt;/span&gt; &lt;span class="sheet-table-header" style="width: 20%;" data-i18n="custom-name"&gt;Custom Name&lt;/span&gt; &lt;span class="sheet-table-header" style="width: 7em;" data-i18n="attack-modifier-abbrv"&gt;Attack Mod&lt;/span&gt; &lt;span class="sheet-table-header" data-i18n="macro-text"&gt;Macro&lt;/span&gt; &lt;/div&gt; &lt;div class="sheet-table-row"&gt; &lt;span class="sheet-table-cell"&gt; &lt;label&gt;&nbsp;&lt;/label&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="text" name="attr_iterative_attack1_name" title="@{repeating_weapon_$X_iterative_attack1_name}" value="Atk1" data-i18n-placeholder="attack"&gt;&lt;/input&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &nbsp; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;textarea class="sheet-inline-textarea" data-i18n-placeholder="full-macro-place" name="attr_var_iterative_attack1_macro" title="@{repeating_weapon_$X_var_iterative_attack1_macro}"&gt;{{atk1-name=@{iterative_attack1_name} }} {{atk1=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}]]}} {{dmg1=[[ @{damage-dice-num}d@{damage-die} + @{damage_macro} ]]@{precision_dmg_macro}@{precision_dmg_type} }} {{cAt1=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{crit_conf_mod}[CritBon] ]] }} {{cDm1=[[ [[ @{damage-dice-num} * [[ @{crit-multiplier} - 1 ]] ]]d@{damage-die} + ((@{damage_macro}) * [[ @{crit-multiplier} - 1 ]]) ]]@{critical_dmg_macro} @{critical_dmg_type} }}&lt;/textarea&gt; &lt;/span&gt; &lt;/div&gt; &lt;div class="sheet-table-row"&gt; &lt;span class="sheet-table-cell"&gt; &lt;label&gt; &lt;input type="checkbox" class="sheet-boldlabel-check" name="attr_toggle_iterative_attack2" title="@{repeating_weapon_$X_toggle_iterative_attack2}" value="{{show-atk-2=[[1d1]]}} @{var_iterative_attack2_macro}" /&gt; &lt;b title="Include a second attack to your weapon?" data-i18n="include-second-attack"&gt;Include a 2nd attack?&lt;/b&gt; &lt;/label&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="text" name="attr_iterative_attack2_name" title="@{repeating_weapon_$X_iterative_attack2_name}" value="Atk2" data-i18n-placeholder="attack-2"&gt;&lt;/input&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="number" name="attr_iterative_attack2_value" title="@{repeating_weapon_$X_iterative_attack2_value}" value="-5" max="0" /&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;textarea class="sheet-inline-textarea" data-i18n-placeholder="full-macro-place" name="attr_var_iterative_attack2_macro" title="@{repeating_weapon_$X_var_iterative_attack2_macro}"&gt;{{atk2-name=@{iterative_attack2_name} }} {{atk2=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack2_value}[Iterative] ]]}} {{dmg2=[[ @{damage-dice-num}d@{damage-die} + @{damage_macro} ]]@{precision_dmg_macro}@{precision_dmg_type} }} {{cAt2=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack2_value}[Iterative]+@{crit_conf_mod}[CritBon] ]] }} {{cDm2=[[ [[ @{damage-dice-num} * [[ @{crit-multiplier} - 1 ]] ]]d@{damage-die} + ((@{damage_macro}) * [[ @{crit-multiplier} - 1 ]]) ]]@{critical_dmg_macro} @{critical_dmg_type} }}&lt;/textarea&gt; &lt;/span&gt; &lt;/div&gt; &lt;div class="sheet-table-row"&gt; &lt;span class="sheet-table-cell"&gt; &lt;label&gt; &lt;input type="checkbox" class="sheet-boldlabel-check" name="attr_toggle_iterative_attack3" title="@{repeating_weapon_$X_toggle_iterative_attack3}" value="{{show-atk-3=[[1d1]]}} @{var_iterative_attack3_macro}" /&gt; &lt;b title="Include a third attack to your weapon?" data-i18n="include-third-attack"&gt;Include a 3rd attack?&lt;/b&gt; &lt;/label&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="text" name="attr_iterative_attack3_name" title="@{repeating_weapon_$X_iterative_attack3_name}" value="Atk3" data-i18n-placeholder="attack-3"&gt;&lt;/input&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="number" name="attr_iterative_attack3_value" title="@{repeating_weapon_$X_iterative_attack3_value}" value="-10" max="0" /&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;textarea class="sheet-inline-textarea" data-i18n-placeholder="full-macro-place" name="attr_var_iterative_attack3_macro" title="@{repeating_weapon_$X_var_iterative_attack3_macro}"&gt;{{atk3-name=@{iterative_attack3_name} }} {{atk3=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack3_value}[Iterative] ]]}} {{dmg3=[[ @{damage-dice-num}d@{damage-die} + @{damage_macro} ]]@{precision_dmg_macro}@{precision_dmg_type} }} {{cAt3=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack3_value}[Iterative]+@{crit_conf_mod}[CritBon] ]] }} {{cDm3=[[ [[ @{damage-dice-num} * [[ @{crit-multiplier} - 1 ]] ]]d@{damage-die} + ((@{damage_macro}) * [[ @{crit-multiplier} - 1 ]]) ]]@{critical_dmg_macro} @{critical_dmg_type} }}&lt;/textarea&gt; &lt;/span&gt; &lt;/div&gt; &lt;div class="sheet-table-row"&gt; &lt;span class="sheet-table-cell"&gt; &lt;label&gt; &lt;input type="checkbox" class="sheet-boldlabel-check" name="attr_toggle_iterative_attack4" title="@{repeating_weapon_$X_toggle_iterative_attack4}" value="{{show-atk-4=[[1d1]]}} @{var_iterative_attack4_macro}" /&gt; &lt;b title="Include a fourth attack to your weapon?" data-i18n="include-fourth-attack"&gt;Include a 4th attack?&lt;/b&gt; &lt;/label&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="text" name="attr_iterative_attack4_name" title="@{repeating_weapon_$X_iterative_attack4_name}" value="Atk4" data-i18n-placeholder="attack-4"&gt;&lt;/input&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="number" name="attr_iterative_attack4_value" title="@{repeating_weapon_$X_iterative_attack4_value}" value="-15" max="0" /&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;textarea class="sheet-inline-textarea" data-i18n-placeholder="full-macro-place" name="attr_var_iterative_attack4_macro" title="@{repeating_weapon_$X_var_iterative_attack4_macro}"&gt;{{atk4-name=@{iterative_attack4_name} }} {{atk4=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack4_value}[Iterative] ]]}} {{dmg4=[[ @{damage-dice-num}d@{damage-die} + @{damage_macro} ]]@{precision_dmg_macro}@{precision_dmg_type} }} {{cAt4=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack4_value}[Iterative]+@{crit_conf_mod}[CritBon] ]] }} {{cDm4=[[ [[ @{damage-dice-num} * [[ @{crit-multiplier} - 1 ]] ]]d@{damage-die} + ((@{damage_macro}) * [[ @{crit-multiplier} - 1 ]]) ]]@{critical_dmg_macro} @{critical_dmg_type} }}&lt;/textarea&gt; &lt;/span&gt; &lt;/div&gt; &lt;div class="sheet-table-row"&gt; &lt;span class="sheet-table-cell"&gt; &lt;label&gt; &lt;input type="checkbox" class="sheet-boldlabel-check" name="attr_toggle_iterative_attack5" title="@{repeating_weapon_$X_toggle_iterative_attack5}" value="{{show-atk-5=[[1d1]]}} @{var_iterative_attack5_macro}" /&gt; &lt;b title="Include a fifth attack to your weapon?" data-i18n="include-fifth-attack"&gt;Include a 5th attack?&lt;/b&gt; &lt;/label&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="text" name="attr_iterative_attack5_name" title="@{repeating_weapon_$X_iterative_attack5_name}" value="Atk5" data-i18n-placeholder="attack-5"&gt;&lt;/input&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="number" name="attr_iterative_attack5_value" title="@{repeating_weapon_$X_iterative_attack5_value}" value="-20" max="0" /&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;textarea class="sheet-inline-textarea" data-i18n-placeholder="full-macro-place" name="attr_var_iterative_attack5_macro" title="@{repeating_weapon_$X_var_iterative_attack5_macro}"&gt;{{atk5-name=@{iterative_attack5_name} }} {{atk5=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack5_value}[Iterative] ]]}} {{dmg5=[[ @{damage-dice-num}d@{damage-die} + @{damage_macro} ]]@{precision_dmg_macro}@{precision_dmg_type} }} {{cAt5=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack5_value}[Iterative]+@{crit_conf_mod}[CritBon] ]] }} {{cDm5=[[ [[ @{damage-dice-num} * [[ @{crit-multiplier} - 1 ]] ]]d@{damage-die} + ((@{damage_macro}) * [[ @{crit-multiplier} - 1 ]]) ]]@{critical_dmg_macro} @{critical_dmg_type} }}&lt;/textarea&gt; &lt;/span&gt; &lt;/div&gt; &lt;div class="sheet-table-row"&gt; &lt;span class="sheet-table-cell"&gt; &lt;label&gt; &lt;input type="checkbox" class="sheet-boldlabel-check" name="attr_toggle_iterative_attack6" title="@{repeating_weapon_$X_toggle_iterative_attack6}" value="{{show-atk-6=[[1d1]]}} @{var_iterative_attack6_macro}" /&gt; &lt;b title="Include a sixth attack to your weapon?" data-i18n="include-sixth-attack"&gt;Include a 6th attack?&lt;/b&gt; &lt;/label&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="text" name="attr_iterative_attack6_name" title="@{repeating_weapon_$X_iterative_attack6_name}" value="Atk6" data-i18n-placeholder="attack-6"&gt;&lt;/input&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="number" name="attr_iterative_attack6_value" title="@{repeating_weapon_$X_iterative_attack6_value}" value="-25" max="0" /&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;textarea class="sheet-inline-textarea" data-i18n-placeholder="full-macro-place" name="attr_var_iterative_attack6_macro" title="@{repeating_weapon_$X_var_iterative_attack6_macro}"&gt;{{atk6-name=@{iterative_attack6_name} }} {{atk6=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack6_value}[Iterative] ]]}} {{dmg6=[[ @{damage-dice-num}d@{damage-die} + @{damage_macro} ]]@{precision_dmg_macro}@{precision_dmg_type} }} {{cAt6=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack6_value}[Iterative]+@{crit_conf_mod}[CritBon] ]] }} {{cDm6=[[ [[ @{damage-dice-num} * [[ @{crit-multiplier} - 1 ]] ]]d@{damage-die} + ((@{damage_macro}) * [[ @{crit-multiplier} - 1 ]]) ]]@{critical_dmg_macro} @{critical_dmg_type} }}&lt;/textarea&gt; &lt;/span&gt; &lt;/div&gt; &lt;div class="sheet-table-row"&gt; &lt;span class="sheet-table-cell"&gt; &lt;label&gt; &lt;input type="checkbox" class="sheet-boldlabel-check" name="attr_toggle_iterative_attack7" title="@{repeating_weapon_$X_toggle_iterative_attack7}" value="{{show-atk-7=[[1d1]]}} @{var_iterative_attack7_macro}" /&gt; &lt;b title="Include a seventh attack to your weapon?" data-i18n="include-seventh-attack"&gt;Include a 7th attack?&lt;/b&gt; &lt;/label&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="text" name="attr_iterative_attack7_name" title="@{repeating_weapon_$X_iterative_attack7_name}" value="Atk7" data-i18n-placeholder="attack-7"&gt;&lt;/input&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="number" name="attr_iterative_attack7_value" title="@{repeating_weapon_$X_iterative_attack7_value}" value="-30" max="0" /&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;textarea class="sheet-inline-textarea" data-i18n-placeholder="full-macro-place" name="attr_var_iterative_attack7_macro" title="@{repeating_weapon_$X_var_iterative_attack7_macro}"&gt;{{atk7-name=@{iterative_attack7_name} }} {{atk7=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack7_value}[Iterative] ]]}} {{dmg7=[[ @{damage-dice-num}d@{damage-die} + @{damage_macro} ]]@{precision_dmg_macro}@{precision_dmg_type} }} {{cAt7=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack7_value}[Iterative]+@{crit_conf_mod}[CritBon] ]] }} {{cDm7=[[ [[ @{damage-dice-num} * [[ @{crit-multiplier} - 1 ]] ]]d@{damage-die} + ((@{damage_macro}) * [[ @{crit-multiplier} - 1 ]]) ]]@{critical_dmg_macro} @{critical_dmg_type} }}&lt;/textarea&gt; &lt;/span&gt; &lt;/div&gt; &lt;div class="sheet-table-row"&gt; &lt;span class="sheet-table-cell"&gt; &lt;label&gt; &lt;input type="checkbox" class="sheet-boldlabel-check" name="attr_toggle_iterative_attack8" title="@{repeating_weapon_$X_toggle_iterative_attack8}" value="{{show-atk-8=[[1d1]]}} @{var_iterative_attack8_macro}" /&gt; &lt;b title="Include an eighth attack to your weapon?" data-i18n="include-eighth-attack"&gt;Include an 8th attack?&lt;/b&gt; &lt;/label&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="text" name="attr_iterative_attack8_name" title="@{repeating_weapon_$X_iterative_attack8_name}" value="Atk8" data-i18n-placeholder="attack-8"&gt;&lt;/input&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;input type="number" name="attr_iterative_attack8_value" title="@{repeating_weapon_$X_iterative_attack8_value}" value="-35" max="0" /&gt; &lt;/span&gt; &lt;span class="sheet-table-cell"&gt; &lt;textarea class="sheet-inline-textarea" data-i18n-placeholder="full-macro-place" name="attr_var_iterative_attack8_macro" title="@{repeating_weapon_$X_var_iterative_attack8_macro}"&gt;{{atk8-name=@{iterative_attack8_name} }} {{atk8=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack8_value}[Iterative] ]]}} {{dmg8=[[ @{damage-dice-num}d@{damage-die} + @{damage_macro} ]]@{precision_dmg_macro}@{precision_dmg_type} }} {{cAt8=[[1d20cf&lt;@{fail-target}cs&gt;@{crit-target}+@{attack_macro}+@{iterative_attack8_value}[Iterative]+@{crit_conf_mod}[CritBon] ]] }} {{cDm8=[[ [[ @{damage-dice-num} * [[ @{crit-multiplier} - 1 ]] ]]d@{damage-die} + ((@{damage_macro}) * [[ @{crit-multiplier} - 1 ]]) ]]@{critical_dmg_macro} @{critical_dmg_type} }}&lt;/textarea&gt; &lt;/span&gt; &lt;/div&gt; &lt;/div&gt; &lt;div class="sheet-macro-text" style="width:100%;height:auto;clear:both;"&gt; &lt;div class="sheet-center"&gt; &lt;div class="sheet-insertmacrocell" style="width:48.5%"&gt; &lt;input class="sheet-textarea-gray" type="checkbox" name="attr_toggle_attack_macro_insert" value="@{attack_macro_insert}" title="@{toggle_attack_macro_insert}" checked="checked"/&gt; &lt;label class="sheet-small-label2"&gt; &lt;span data-i18n="insert-macro-attack" data-i18n-title="additional-attack-macro/query(included-with-crits)" title="Additional Attack Macro/Query(included with crits)"&gt;Attack Insert Macro:&lt;/span&gt; &lt;input type="hidden" name="attr_var_attack_macro_insert" value="[[ @{attack_macro_insert} ]] [Macro]" /&gt; &lt;textarea class="sheet-inline-textarea-both" name="attr_attack_macro_insert" data-i18n-placeholder="full-macro-place" placeholder="Macro/Query" title="@{repeating_weapon_$X_attack_macro_insert}"&gt;0&lt;/textarea&gt; &lt;/label&gt; &lt;/div&gt; &lt;div class="sheet-insertmacrocell" style="width:48.5%"&gt; &lt;input class="sheet-textarea-gray" type="checkbox" name="attr_toggle_damage_macro_insert" value="@{damage_macro_insert}" title="@{toggle_damage_macro_insert}" checked="checked"/&gt; &lt;label class="sheet-small-label2"&gt; &lt;span data-i18n="insert-macro-damage" data-i18n-title="additional-damage-macro/query(included-with-crits)" title="Additional Damage Macro/Query(included with crits)"&gt;Damage Insert Macro:&lt;/span&gt; &lt;input type="hidden" name="attr_var_damage_macro_insert" value="[[ @{damage_macro_insert} ]] [Macro]" /&gt; &lt;textarea class="sheet-inline-textarea-both" name="attr_damage_macro_insert" data-i18n-placeholder="full-macro-place" placeholder="Macro/Query" title="@{repeating_weapon_$X_damage_macro_insert}"&gt;0&lt;/textarea&gt; &lt;/label&gt; &lt;/div&gt; &lt;/div&gt; &lt;label class="sheet-small-label2" style="width:100%;height:auto;margin-left:0;margin-right:0;padding-left:2px;padding-right:2px;"&gt; &lt;span data-i18n="full-macro"&gt;Full Macro:&lt;/span&gt; &lt;textarea&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;class="sheet-macro-text" title="@{repeating_weapon_$X_macro-text}"&nbsp; &nbsp; &nbsp;name="attr_macro-text"&nbsp; &nbsp; &gt;&{template:35AdvAtk2} @{iterative_attacks} {{prefix=@{wepEnh}}} {{name=@{name} [@{damType}] }} {{subtags=@{notes}}} @{wep-showatk}&lt;/textarea&gt; &lt;textarea style="display:none;" class="sheet-macro-text" title="@{repeating_weapon_$X_NPC-macro-text}" name="attr_NPC-macro-text"&gt;@{NPC-whisper} &{template:pf_attack} @{toggle_attack_accessible} @{toggle_rounded_flag}{{color=@{rolltemplate_color}}} {{character_name=@{character_name}}} {{character_id=@{character_id}}} {{subtitle}} {{name=@{name}}} {{attack=[[ 1d20cs&gt;[[ @{crit-target} ]] + @{attack_macro} ]]}} {{damage=[[@{damage-dice-num}d@{damage-die} + @{damage_macro}]]}} {{crit_confirm=[[ 1d20 + @{attack_macro} + [[ @{crit_conf_mod} ]] ]]}} {{crit_damage=[[ [[ @{damage-dice-num} * (@{crit-multiplier} - 1) ]]d@{damage-die} + ((@{damage_macro}) * [[ @{crit-multiplier} - 1 ]]) ]]}} {{type=@{damType}}} {{weapon_notes=@{notes}}} @{iterative_attacks} @{macro_options} {{vs=@{vs}}} {{vs@{vs}=@{vs}}} {{precision_dmg1=@{precision_dmg_macro}}} {{precision_dmg1_type=@{precision_dmg_type}}} {{precision_dmg2=@{global_precision_dmg_macro}}} {{precision_dmg2_type=@{global_precision_dmg_type}}} {{critical_dmg1=@{critical_dmg_macro}}} {{critical_dmg1_type=@{critical_dmg_type}}} {{critical_dmg2=@{global_critical_dmg_macro}}} {{critical_dmg2_type=@{global_critical_dmg_type}}}&lt;/textarea&gt; &lt;/label&gt; &lt;/div&gt; &lt;div class="sheet-misc-attack"&gt; &lt;label class="sheet-small-label2 sheet-entry-small sheet-sect" &gt; &lt;select title="@{repeating_weapon_$X_proficiency}" name="attr_proficiency" style="width:4.3em;"&gt;&lt;!-- Style Override --&gt; &lt;option value="0" data-i18n="yes-default" selected&gt;&#8226;Yes&lt;/option&gt; &lt;option value="-4" data-i18n="no"&gt;No&lt;/option&gt; &lt;/select&gt; &lt;span data-i18n-title="proficiency-title" data-i18n="proficiency"&gt;Prof&lt;/span&gt; &lt;/label&gt; &lt;/div&gt; &lt;div class="sheet-repeating-id"&gt; &lt;span data-i18n="identification-abbrv"&gt;ID&lt;/span&gt;: &lt;span class="sheet-selectable" name="attr_row_id" /&gt; &lt;/div&gt; &lt;/div&gt; &lt;/div&gt; &lt;/fieldset&gt; There is the HTML, as you requested, I am sorry it is so long. I could also send you a link to the testing game if you like.
1511685393
Jakob
Sheet Author
API Scripter
Re: your problems with removing the row, I suspect it may be connected to the change:repeating_weapons event string. I dimly remember having run into this problem before... Try using all the relevant attributes in that row instead of the blanket change:repeating_weapons: on('change:repeating_weapons:enhance change:repeating_weapons:attack-type ...', ...); (ellipsis because I'm lazy, of course you should fill in all the other attribute that affect the damage).
partial fix, I think... but it breaks other stuff.&nbsp; Too tired to continue, been working this for about 18 hours.&nbsp; Sleepy time. I think it would be a complete fix if I found Every single attribute in the repeating section in and added a change:xx for it... which is why I wanted the blanket version, cause a lot of them affect the damage and attack even if only in a side-along way.&nbsp; This will take me being alert to follow the overcooked limp spaghetti that is my code. G'night .. or G'morning.. and thanks for your assistance.
Well, I think I have it working.&nbsp; All of the NaN errors go away, all of the removing rows error go away, all of the conflicts go away and the rolls run rather quickly (perhaps a little faster than before). /* Repeating Weapons Parsing -- Both Global and Local (Excluding ROW ID OUTPUT Display) */ const calcWeaponDamage = function (prefix) { const sourceAttrs = [ "DMG-mod", "DMG2-mod", "DMG_ranged-mod", "DMG_ranged2-mod", 'PwrAtkDam', "APP-mod", "STR-mod", "DEX-mod", "CON-mod", "INT-mod", "WIS-mod", "CHA-mod", prefix+"_enhance", prefix+"_attack-type", prefix+"_damage", prefix+"_damage-ability", prefix+"_damage_ability_mult", prefix+"_damage-ability-max", prefix+"_masterwork", ]; getAttrs(sourceAttrs, function (v) { var atkType = v[prefix+"_attack-type"]; // Compare //console.log("===== " +prefix+"_attack-type: " +atkType+ "."); var damAbil = v[prefix+"_damage-ability"]; // Compare //console.log("====== " +prefix+"_damage-ability: " +damAbil+ "."); var attackType = " ", buff_DMG_mod = 0, damageAbil = " ", damAbilMod = 0; // Unset variables, yet. //console.log("buff_DMG_mod PRE: " +buff_DMG_mod+ "."); //console.log("damAbilMod PRE: " +damAbilMod+ "."); if (atkType === "0") {attackType="None", buff_DMG_mod=0;} else if (atkType === "@{attk-melee}") {attackType="Melee", buff_DMG_mod=parseFloat(v["DMG-mod"],10) || 0;} else if (atkType === "@{attk-melee2}") {attackType="Melee2", buff_DMG_mod=parseFloat(v["DMG2-mod"],10) || 0;} else if (atkType === "@{attk-ranged}") {attackType="Ranged", buff_DMG_mod=parseFloat(v["DMG_ranged-mod"],10) || 0;} //else if (atkType === "@{attk-ranged2}"){attackType="Ranged2", buff_DMG_mod=parseFloat(v["DMG_ranged2-mod"],10) || 0;}&nbsp; NOT USED, Yet. else if (atkType === "@{attk-CMB}") {attackType="CMB";} else if (atkType === "@{attk-CMB2}") {attackType="CMB2";} console.log("Attack Type: " +attackType+ " || Bonus Damage:" +buff_DMG_mod+ "."); if (damAbil === "0") {attackType="None";damAbilMod=0} else if (damAbil === "@{APP-mod}") {damageAbil="APP Mod";damAbilMod=parseInt(v["APP-mod"])||0;}&nbsp; // Appearance Score, kinda like comelyness from AD&D, Houserule. else if (damAbil === "@{STR-mod}") {damageAbil="STR Mod";damAbilMod=parseInt(v["STR-mod"])||0;} else if (damAbil === "@{DEX-mod}") {damageAbil="DEX Mod";damAbilMod=parseInt(v["DEX-mod"])||0;} else if (damAbil === "@{CON-mod}") {damageAbil="CON Mod";damAbilMod=parseInt(v["CON-mod"])||0;} else if (damAbil === "@{INT-mod}") {damageAbil="INT Mod";damAbilMod=parseInt(v["INT-mod"])||0;} else if (damAbil === "@{WIS-mod}") {damageAbil="WIS Mod";damAbilMod=parseInt(v["WIS-mod"])||0;} else if (damAbil === "@{CHA-mod}") {damageAbil="CHA Mod";damAbilMod=parseInt(v["CHA-mod"])||0;} console.log("Damage Ability: " +damageAbil+ "+" +damAbilMod+ "."); var wepEnh = parseInt(v[prefix+"_enhance"],10) || 0; //console.log("wepEnh: " +wepEnh+ "."); var wepDmgMisc = parseInt(v[prefix+"_damage"],10) || 0; //console.log("wepDmgMisc: " +wepDmgMisc+ "."); var abilDam = Math.max(damAbilMod * parseFloat(v[prefix+"_damage_ability_mult"]), parseInt(v[prefix+"_damage-ability-max"]))||0; // I've never really understood abilty max... but okay.. //console.log("abilDam: " +abilDam+ "."); var PwrAtk = parseInt(v["PwrAtkDam"])||0 * Math.max(parseFloat(v[prefix+"_damage_ability_mult"]),2)||0;&nbsp; // Set Power Attack Based Abil Multiplier, with a maximum of x2 var Damage = wepEnh + wepDmgMisc + abilDam + PwrAtk + buff_DMG_mod; console.log("Damage Calculation: "+Damage+"= Enh: "+wepEnh+"+Mod: "+wepDmgMisc+"+Abil: "+abilDam+"PwrAtk: "+PwrAtk+"+Buffs: "+buff_DMG_mod); /* From SWUtil.js || Parses an text or input field with @{xxx} or [[ xx ]] arithmatic into readable fields for SheetWorkers */ /* <a href="https://github.com/plutosdad/SheetWorkerParsing/b" rel="nofollow">https://github.com/plutosdad/SheetWorkerParsing/b</a>... ... IS REQUIRED. */ evaluateAndSetNumber("repeating_weapon_attack","repeating_weapon_attack-mod"); evaluateAndSetNumber("repeating_weapon_crit_confirm","repeating_weapon_crit_conf_mod"); evaluateAndSetNumber("repeating_weapon_damage","repeating_weapon_damage-mod"); setAttrs({ [prefix+"_wepEnh"]: Math.max(parseInt(v["repeating_weapon_enhance"]),parseInt(v["repeating_weapon_masterwork"])), [prefix+"_total-damage"]: Damage, }); }); }; on('change:APP-mod change:STR-mod change:DEX-mod change:CON-mod change:INT-mod change:WIS-mod change:CHA-mod change:DMG-mod change:DMG2-mod change:DMG_ranged-mod change:DMG_ranged2-mod change:toggle-PwrAtk', function () {&nbsp; // Make sure all of the attributes are properly checked, the fewer the better for efficiency for weapon rolls. getSectionIDs('repeating_weapon', function (ids) { ids.forEach(id =&gt; calcWeaponDamage('repeating_weapon_'+id)); }); }); on('change:repeating_weapon', function () { calcWeaponDamage('repeating_weapon'); // this is what the prefix param of the calcWeapDamage() make sure it is properly named!! }); The last onChange function was calling the calcWeaponDamage() incorrectly.&nbsp; It had an underscore at the end, which was causing the prefix parameter to have a second underscore when trying to parse local variables. Garbage in, Garbage Out...&nbsp; Gah.&nbsp; Anyways, now, I can make forward progress.
1511735228

Edited 1511735493
GiGs
Pro
Sheet Author
API Scripter
That's good news. Well done, on finding the problem. I'm a bit confused though. Isn't that exactly as Jacob posted originally, and how it was in your previous posts where you mentioned having problems?&nbsp;
1511766844

Edited 1511767182
Toby
Pro
Honestly, I don't really know what happened. But, yes you are correct, perhaps in my attempts to 'fix' things and try everything to get it to work I changed it and didnt change it back.. which would be odd, since normally if something doesnt correct something I change it back. Regardless, yes the NaN issue vanished for a little while, then... it reappeared.... Spent the entire day looking for it because none of my console.logs were showing any variables as unset or undefined or NaN. Then I checked, attributes i was setting directly without creating variables... and bingo, the NaN, seems to have once again vanished... Although, I once again still cant delete weapon rows... But thats a project for tomorrow. Just once, I'd like something to be easy :P Edit: I've been seeing this on and off last two days and I've never seen this error before: SHEET WORKER ERROR: You attempted to set an attribute beginning with 'repeating_' but did not include a Row ID or Attribute Name in repeating_weapon_total-attack_wepEnh app.js?1509374274:47 SHEET WORKER ERROR: You attempted to set an attribute beginning with 'repeating_' but did not include a Row ID or Attribute Name in repeating_weapon_total-attack_total-damage app.js?1509374274:47 SHEET WORKER ERROR: You attempted to set an attribute beginning with 'repeating_' but did not include a Row ID or Attribute Name in repeating_weapon_total-attack_attack-mod app.js?1509374274:47 SHEET WORKER ERROR: You attempted to set an attribute beginning with 'repeating_' but did not include a Row ID or Attribute Name in repeating_weapon_total-attack_crit_conf_mod app.js?1509374274:47 SHEET WORKER ERROR: You attempted to set an attribute beginning with 'repeating_' but did not include a Row ID or Attribute Name in repeating_weapon_total-attack_damage-mod It doesn't seem to be negatively impacting my sheet, and only occurs when changing attributes outside the repeating section.
1511770716

Edited 1511772391
Jakob
Sheet Author
API Scripter
I'm pretty sure that at least some of these last errors you are seeing have to do with these lines: evaluateAndSetNumber("repeating_weapon_attack","repeating_weapon_attack-mod"); evaluateAndSetNumber("repeating_weapon_crit_confirm","repeating_weapon_crit_conf_mod"); evaluateAndSetNumber("repeating_weapon_damage","repeating_weapon_damage-mod"); You should definitely use prefix instead of just repeating_weapon here. There's another place where you do not correctly use prefix in the function, namely this one [prefix+"_wepEnh"]: Math.max(parseInt(v["repeating_weapon_enhance"]),parseInt(v["repeating_weapon_masterwork"])), which WILL give you NaN when the event originates outside a repeating section. You need to use prefix here as well. As a more general question, why do you still have all these attributes lying around whose value is a formula or an inline roll? It seems that they serve no purpose when the totals are calculated by workers anyway, and they will lead to some serious attribute bloat, and it looks like the sheet is not exactly lightweight in the first place.
1511786714

Edited 1511787047
Toby
Pro
These are both text fields which are both evaluated into numeric fields using that function, its kinda the point. evaluateAndSetNumber("repeating_weapon_attack","repeating_weapon_attack-mod"); evaluateAndSetNumber("repeating_weapon_damage","repeating_weapon_damage-mod"); evaluateAndSetNumber(); converts [[ whatever ]] into disabled fields that sheet workers can read (at least thats how its supposed to work, its a script by Chris, and I'm still learning how to use it fully :P).&nbsp; I have tried using prefix+ with them.. it gives errors.&nbsp; Because, the fields are only relevant&nbsp;INSIDE each row, I moved the function down. and ignored.&nbsp; I don't care if these are only evaluated inside of the row, but it doesn't look like that made any difference. The first parameter sets the source attribute the second parameter sets the destination, the destination is used in formula all over the repeating section, and in a display field to the users.&nbsp; The crit mod, field is a purely numeric field, and isnt being used by me yet, but I intend to use it at a later time if I ever get all these errors cleared up. As for the, wepEnh one... that's the one I removed and replaced with. var wepEnh = Math.max(parseInt(v[prefix+"_enhance"]),parseInt(v[prefix+"_masterwork"])); console.log("wepEnh: " +wepEnh+ "."); .... Although, I'm not entirely happy with it, something just seems wrong with how it works, don't know why, I cant point my finger on it.
I am still having issues with repeating sections not being able to be deleted.&nbsp; I have exhausted all possible solutions that I can think of, anyone else have thoughts? on('change:repeating_weapon', function () {&nbsp; /* &lt;--- This onChange has cause me nothing but problems why couldnt this be easy... why is nothing easy! */ calcWeaponDamage('repeating_weapon'); // this is what the prefix param of the calcWeapDamage() make sure it is properly named!! /* From SWUtil.js || Parses an text or input field with @{xxx} or [[ xx ]] arithmatic into readable fields for SheetWorkers */ /* This is moved into this so it will only function while changes are made inside the repeating section and nowhere else . */ /* <a href="https://github.com/plutosdad/SheetWorkerParsing/blob/master/SWParser.js" rel="nofollow">https://github.com/plutosdad/SheetWorkerParsing/blob/master/SWParser.js</a> ... IS REQUIRED. */ evaluateAndSetNumber("repeating_weapon_attack","repeating_weapon_attack-mod"); evaluateAndSetNumber("repeating_weapon_crit_confirm","repeating_weapon_crit_conf_mod"); evaluateAndSetNumber("repeating_weapon_damage","repeating_weapon_damage-mod"); }); I know the above function is the offending function, specifically the on('change:repeating_weapon', function ()&nbsp; { .....&nbsp; I have tried replacing the contents with the actual repeating attribute names in full but when I do it no longer seems to register any events, however, it will allow repeating rows to be deleted, and global variables will trigger changes, just nothing in rows. I do not know where to go from here.&nbsp; Tried just about everything, so I've reached the end of what I can do with trial and error.
1511841771
GiGs
Pro
Sheet Author
API Scripter
Toby said: I have tried replacing the contents with the actual repeating attribute names in full but when I do it no longer seems to register any events, however, it will allow repeating rows to be deleted, and global variables will trigger changes, just nothing in rows. Post the code you used for this. There might be a mistake in the syntax. Also, Jacob pointed out earlier there may be a conflict with the&nbsp;evaluateAndSetNumber function. Maybe try writing the code without it. I'm not sure what it's doing, but you should be able to duplicate it in sheetworkers.
The code I have used is : on('change:repeating_weapon_row-show change:repeating_weapon_enhance change:repeating_weapon_masterwork change:repeating_weapon_name change:repeating_weapon_attack change:repeating_weapon_attack-type change:repeating_weapon_vs change:repeating_weapon_fail-target change:repeating_weapon_crit-target change:repeating_weapon_crit-multiplier change:repeating_weapon_crit_confirm change:repeating_weapon_damage-dice-num change:repeating_weapon_damage-die change:repeating_weapon_damage change:repeating_weapon_damage-ability change:repeating_weapon_damage_ability_mult change:repeating_weapon_damage-ability-max change:repeating_weapon_damType change:repeating_weapon_range change:repeating_weapon_ammo', function () {&nbsp; /* &lt;--- This onChange has cause me nothing but problems why couldnt this be easy... why is nothing easy! */ calcWeaponDamage('repeating_weapon'); // this is what the prefix param of the calcWeapDamage() make sure it is properly named!! /* From SWUtil.js || Parses an text or input field with @{xxx} or [[ xx ]] arithmatic into readable fields for SheetWorkers */ /* This is moved into this so it will only function while changes are made inside the repeating section and nowhere else . */ /* <a href="https://github.com/plutosdad/SheetWorkerParsing/b" rel="nofollow">https://github.com/plutosdad/SheetWorkerParsing/b</a>... ... IS REQUIRED. */ evaluateAndSetNumber("repeating_weapon_attack","repeating_weapon_attack-mod"); evaluateAndSetNumber("repeating_weapon_crit_confirm","repeating_weapon_crit_conf_mod"); evaluateAndSetNumber("repeating_weapon_damage","repeating_weapon_damage-mod"); }); I've tried adding each one at a time, I've tried adding only the ones required by the getAttrs... I've tried a bunch of different stuff.. As for the evaluateAndSetNumber();&nbsp; I'm not really sure what to say except, its needed.&nbsp; Its one of many functions that can be used in a similar way, its the only one I understand. from the SWUtils.js..&nbsp; There is another one that might be useful and more versitile:&nbsp; evaluateExpression(exprStr, callback), &nbsp;but I've not gotten it to work.
1511847691

Edited 1511847989
GiGs
Pro
Sheet Author
API Scripter
The syntax isn't quite right on the change line, it's an easy mistake to make. The correct way is: on('change:repeating_weapon:row-show change:repeating_weapon:enhance change:repeating_weapon:masterwork .... Yes, irritatingly, it's a different syntax to when calling getAttrs, which does work the way you wrote it above, eg: getAttrs(["repeating_weapon_enhance","repeating_weapon_masterwork", In a change event you have to use a colon as a separator, instead of the underscore you use in getAttrs. This tripped me up too when i first started fiddling with repeating sets.
*mutters* That ... fixed it.. Now, I'm going to find the strongest drink I have, and go to bed, and pray that when I wake up, a new error wont have arisen. Thank you again, I am very sorry for being such a pain in the... hind-quarters.