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

How do I remove the current row from a repeating section?

II have a repeating wounds section that allows the player to select the severity of each wound. If the severity is 0, i want it to delete the row. The sheetw roker I have so far is: <script type="text/worker"> on("change:repeating_wounds:severity", function(eventInfo) {    getAttrs(["repeating_wounds_severity"], function(values) {        const sev= parseInt(values["repeating_wounds_severity"]) || 0;        if(sev<1){            (remove row)        }    }); }); </script> The (remove row) is where I need it to delete the current row. 
1612035780

Edited 1612035811
Andreas J.
Forum Champion
Sheet Author
Translator
Check the documentation: <a href="https://wiki.roll20.net/Sheet_Worker_Scripts#removeRepeatingRow.28_RowID_.29" rel="nofollow">https://wiki.roll20.net/Sheet_Worker_Scripts#removeRepeatingRow.28_RowID_.29</a> on ( "change:repeating_inventory" , function () { getSectionIDs ( "repeating_inventorysummary" , function (idarray) { for ( var i = 0 ; i &lt; idarray. length ; i + + ) { removeRepeatingRow ( "repeating_inventorysummary_" + idarray[i]); } }); });
1612037133

Edited 1612039106
GiGs
Pro
Sheet Author
API Scripter
To build on Andreas's suggestion, to use the removeRepeatingRow function, you need the row id. There are two ways to get it - using the eventInfo object and extracting it from the event.sourceAttribute property, or using the getSectionIDs function, both of which are covered in the wiki. Here's one way to do it with the first method: on ( 'change:repeating_wounds:severity' ,&nbsp; function ( eventInfo )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;get&nbsp;the&nbsp;row&nbsp;id&nbsp;from&nbsp;the&nbsp;attribute&nbsp;that&nbsp;was&nbsp;just&nbsp;changed. &nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; rowid &nbsp;=&nbsp; eventInfo . sourceAttribute . split ( '_' )[ 2 ]; &nbsp;&nbsp;&nbsp;&nbsp; getAttrs ([ 'repeating_wounds_severity' ],&nbsp; function ( values )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; sev &nbsp;=&nbsp; parseInt ( values . repeating_wounds_severity )&nbsp;||&nbsp; 0 ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( sev &lt; 1 ){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; removeRepeatingRow ( 'repeating_wounds_' &nbsp;+&nbsp; rowid ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;}); }); Technically you can do this with eventInfo.newValue instead of getAttrrs, but there was a bug with newValue for a long time (and might still exist) so I don't trust it and never use it if I can avoid it. But if you prefer to use it, it's a little shorter: on ( 'change:repeating_wounds:severity' ,&nbsp; function ( eventInfo )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;get&nbsp;the&nbsp;row&nbsp;id&nbsp;from&nbsp;the&nbsp;attribute&nbsp;that&nbsp;was&nbsp;just&nbsp;changed. &nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; rowid &nbsp;=&nbsp; eventInfo . sourceAttribute . split ( '_' )[ 2 ]; &nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; sev &nbsp;=&nbsp; parseInt ( eventInfo . newValue )&nbsp;||&nbsp; 0 ; &nbsp;&nbsp;&nbsp;&nbsp; if ( sev &nbsp;&lt;&nbsp; 1 ){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; removeRepeatingRow ( 'repeating_wounds_' &nbsp;+&nbsp; rowid ); &nbsp;&nbsp;&nbsp;&nbsp;} }); The getSectionIDs method activates whenever the severity attribute changes, and scans every row in the repeating section, and deletes every row where theres a zero or less value. on ( 'change:repeating_wounds:severity' ,&nbsp; function ( eventInfo )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;get&nbsp;the&nbsp;row&nbsp;id&nbsp;from&nbsp;the&nbsp;attribute&nbsp;that&nbsp;was&nbsp;just&nbsp;changed. &nbsp;&nbsp;&nbsp;&nbsp; getSectionIDs ( 'repeating_wounds' ,&nbsp; idarray &nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; fields &nbsp;=&nbsp;[]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; idarray . forEach ( id &nbsp; =&gt; &nbsp; fields . push ( `repeating_wounds_ ${ id } _severity` )); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getAttrs ( fields ,&nbsp; values &nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; idarray . forEach ( id &nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; sev &nbsp;=&nbsp; parseInt ( values [ `repeating_wounds_ ${ id } _severity` ])&nbsp;||&nbsp; 0 ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( sev &lt; 1 ){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; removeRepeatingRow ( 'repeating_wounds_' &nbsp;+&nbsp; id ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;}); });
I tried this previously, but I don't know how to get it to delete just the current row. If I cut and paste the above, I can delete all rows in the section. on("change:repeating_wounds:severity", function(eventInfo) { &nbsp; &nbsp;getAttrs(["repeating_wounds_severity"], function(values) { &nbsp; &nbsp; &nbsp; &nbsp;const sev= parseInt(values["repeating_wounds_severity"]) || 0; &nbsp; &nbsp; &nbsp; &nbsp;if(sev&lt;1){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;getSectionIDs("repeating_wounds", function(idarray) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; for(var i=0; i &lt; idarray.length; i++) { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; removeRepeatingRow("repeating_wounds_" + idarray[i]); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}); &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp;}); }); I tried removing the part that loops through the section and gets all the rows, and replaced it with the specific row id like this: on("change:repeating_wounds:severity", function(eventInfo) { &nbsp; &nbsp; let RID = eventInfo.sourceAttribute.slice(18,38); &nbsp; &nbsp;getAttrs(["repeating_wounds_severity"], function(values) { &nbsp; &nbsp; &nbsp; &nbsp;const sev= parseInt(values["repeating_wounds_severity"]) || 0; &nbsp; &nbsp; &nbsp; &nbsp;if(sev&lt;1){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;removeRepeatingRow("repeating_wounds_"+RID); &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp;}); }); but that does not work at all.
Thanks! I figured it was something with getting the row id, but had no idea how to do that correctly.
1612040184
Andreas J.
Forum Champion
Sheet Author
Translator
gigs can you throw that example on the wiki somewhere, so it's findable in the future?
1612043062
GiGs
Pro
Sheet Author
API Scripter
It's not a very general example - its specifically for Randall's "if wound = 0" case. Do you think that would be generally useful?
So I tried to to use this to search the section and check off the appropriate boxes based on the severity of each wound. I did the following: &lt;script type="text/worker"&gt; on('change:repeating_wounds:severity', function(eventInfo) { &nbsp; &nbsp; const stats = ['health1','health2','health3','health4','health5','health6','health7','health8','health9','health10','health11','health12']; &nbsp; &nbsp; stats.forEach(function (stat){ &nbsp; &nbsp; &nbsp; &nbsp; setAttrs({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; [stat]:0 &nbsp; &nbsp; &nbsp; &nbsp; }) &nbsp; &nbsp; }); &nbsp; &nbsp; // get the row id from the attribute that was just changed. &nbsp; &nbsp; getSectionIDs('repeating_wounds', idarray =&gt; { &nbsp; &nbsp; &nbsp; &nbsp; const fields = []; &nbsp; &nbsp; &nbsp; &nbsp; idarray.forEach(id =&gt; fields.push(`repeating_wounds_${id}_severity`)); &nbsp; &nbsp; &nbsp; &nbsp; getAttrs(fields, values =&gt; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; idarray.forEach(id =&gt; { &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const sev = parseInt(values[`repeating_wounds_${id}_severity`]) || 0; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; if(sev==0){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; removeRepeatingRow('repeating_wounds_' + id); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; } &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; const num=['1','2','3','4','5','6','7','8','9','10','11','12'] &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var completed=0 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; num.forEach(function(n){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; var flag=`health${n}` &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; getAttrs([flag],function(val){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;var flagVal= parseInt(val[flag]) &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(sev==1){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(flagVal==0){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;if(completed==0){ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;completed=1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;setAttrs({ &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;[flag]:1 &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;}); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;} &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;})&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; &nbsp; &nbsp; }); &nbsp; &nbsp; }); }); &lt;/script&gt; The first wound that is severity should check the first box, the next one the second box, and so on, but it only checks the first box no matter what. What am I doing wrong?
1612234604

Edited 1612235467
GiGs
Pro
Sheet Author
API Scripter
First, you should never have a getAttrs or setAttrs statement inside a loop. I dont follow exactly what you're trying to do there, so I cant rewrite it completely. But here's a more efficiently structured sheet&nbsp; worker that sets health1-12 to 0, and removesthe sev=0 repeating rows. on ( 'change:repeating_wounds:severity' ,&nbsp; function ( eventInfo )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; stats &nbsp;=&nbsp;[ 'health1' , 'health2' , 'health3' , 'health4' , 'health5' , 'health6' , 'health7' , 'health8' , 'health9' , 'health10' , 'health11' , 'health12' ]; &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;create&nbsp;a&nbsp;holding&nbsp;object&nbsp;to&nbsp;save&nbsp;attributes &nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; output &nbsp;=&nbsp;{}; &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;set&nbsp;the&nbsp;stats&nbsp;to&nbsp;default&nbsp;value&nbsp;of&nbsp;zero &nbsp;&nbsp;&nbsp;&nbsp; stats . forEach ( stat &nbsp; =&gt; &nbsp; output [ stat ]&nbsp;=&nbsp; 0 ); &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;initialise&nbsp;an&nbsp;array&nbsp;to&nbsp;track&nbsp;the&nbsp;severity&nbsp;values.&nbsp;This&nbsp;assumes&nbsp;severities&nbsp;have&nbsp;values&nbsp;of&nbsp;1-5 &nbsp;&nbsp;&nbsp;&nbsp; let &nbsp; severities &nbsp;=&nbsp; Array ( 6 ). fill ( 0 ); &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;get&nbsp;the&nbsp;row&nbsp;id&nbsp;from&nbsp;the&nbsp;attribute&nbsp;that&nbsp;was&nbsp;just&nbsp;changed. &nbsp;&nbsp;&nbsp;&nbsp; getSectionIDs ( 'repeating_wounds' ,&nbsp; idarray &nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; fields &nbsp;=&nbsp;[]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; idarray . forEach ( id &nbsp; =&gt; &nbsp; fields . push ( `repeating_wounds_ ${ id } _severity` )); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getAttrs ([... fields ,&nbsp;... stats ],&nbsp; values &nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; idarray . forEach ( id &nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; sev &nbsp;=&nbsp; parseInt ( values [ `repeating_wounds_ ${ id } _severity` ])&nbsp;||&nbsp; 0 ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( sev === 0 ){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; removeRepeatingRow ( 'repeating_wounds_' &nbsp;+&nbsp; id ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; else &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if &nbsp;([ 1 , 2 ,&nbsp; 3 ,&nbsp; 4, 5 ]. includes ( sev ))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; severities [ sev ]&nbsp;=&nbsp; severities [ sev ]&nbsp;+ 1 ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; else &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;if&nbsp;a&nbsp;severity&nbsp;is&nbsp;outside&nbsp;the&nbsp;valid&nbsp;range&nbsp;of&nbsp;1-5,&nbsp;add to severities[0], so can report number invalid entries &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; severities [ 0 ]&nbsp;=&nbsp; severities [ 0 ]&nbsp;+ 1 ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;would&nbsp;have&nbsp;a&nbsp;routine&nbsp;here&nbsp;to&nbsp;convert&nbsp;severities&nbsp;into&nbsp;health1-12&nbsp;values,&nbsp;but&nbsp;I&nbsp;don't&nbsp;know the&nbsp;details. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; console . log ( severities ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setAttrs ( output ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;}); }); Since you already have an array that has the health1-12 attributes, you can include them in the getAttrs statement like this: getAttrs([...fields,&nbsp;...stats],&nbsp;values&nbsp;=&gt;&nbsp;{ The ... is the spread operator, it expands an array into its elements - this allows us to combine two separate arrays into another array. The output object in the above holds saved key:value &nbsp;pairs, like health1:0, &nbsp;and since these are in the same format that setAttrs expects, we can just include that in the setAttrs statement to save a bunch of attributes at once. The sheet worker above doesnt set any of the helath1-12 attributes to a value of 1, because IIRC from your other thread that is quite a complex calculation, and I dont know how the html for the repeating section is structured. How do you record the size of a wound, and how many of each can you have? in the second idarray loop, you likely need to build an array of severity values, so you can examine how many of each there are. Then after the idarray loop is finished, you analyse this data, and determine which of health1-12 need to be given a value of 1, and save them to output. Thats what the severities array is for.&nbsp; It assumes severity is a number from 1-5. For instance, you set the wound severity with a select, and the option values re numeric. If the values are strings, it's possible to rewrite the script to handle that, but it looks like they are numeric. Note that this sheet worker in its current form will zero out the health1-12 track. To finish it and calculate those values, what are the wound severity value names on the attribute, and how many of each can you have? (I remember if you have more they wrap upwards.) With that information I can finish the worker. For now, there's a console.log statement that will print out the values of each severity to the browser console.&nbsp;
The severity goes from 0 to 5 and is selected from a dropdown, so values should never fall out of the range. A severity of 0 should delete the row. A severity 1 can fill any slot of 1or higher, a severity 2 can fill any slot oh 5 or higher, a severity 3 can fill any slot of 8 or higher, a severity 4 can fill any slot of 10 or higher, and a severity 5 can only go in th 12 slot. The slots in question are named health1, health2, health3, etc. up to health12.&nbsp; The repeating section that the severity value is drawn from is &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;fieldset class="repeating_wounds"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="wound-row"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;select name="attr_severity" class="severity-select"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;option value="0"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;None&lt;/option&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;option value="1"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Trivial&lt;/option&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;option value="2"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Light&lt;/option&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;option value="3"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;Moderate&lt;/option&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;option value="4"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Severe&lt;/option&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;option value="5"&gt;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;&amp;nbsp;Fatal&lt;/option&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/select&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="text" name="attr_wound-desc" class="wound-desc" value="New wound"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;div class="wound-cap"&gt;&lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/div&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/fieldset&gt; The section it is changing is this: &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;table class="healthbox us"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;caption&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; WOUNDS &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="white drop align-right"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="red align-right"&gt;.&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="poison align-right"&gt;l&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/caption&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;tr&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td rowspan="3" style="width:4px;"&gt;&lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td colspan="11" style="text-align:right;vertical-align:middle;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; Modifier:&amp;nbsp;&amp;nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td colspan="2"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" name="attr_wound-mod" class="wound-mod" value="0"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span name="wound-mod" class="wmodbox"&gt;0&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td rowspan="3" style="width:4px;"&gt;&lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/tr&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;tr class="health-row"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td style="padding:0;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health1-show" name="attr_health1" value="2"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h1 left-cap"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td style="padding:0;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health2-show" name="attr_health2" value="3"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h2"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td style="padding:0;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health3-show" name="attr_health3" value="4"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h3"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td class="bar-divider" style="padding:0;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health4-show" name="attr_health4" value="5"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h4"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td style="padding:0;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health5-show" name="attr_health5" value="6"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h5"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td style="padding:0;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health6-show" name="attr_health6" value="7"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h6"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td class="bar-divider"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health7-show" name="attr_health7" value="8"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h7"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td style="padding:0;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health8-show" name="attr_health8" value="9"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h8"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td class="bar-divider" style="padding:0;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health9-show" name="attr_health9" value="10"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h9"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td style="padding:0;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health10-show" name="attr_health10" value="11"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h10"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td class="bar-divider" style="padding:0;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health11-show" name="attr_health11" value="12"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h11"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td style="padding:0;"&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;input type="hidden" class="health12-show" name="attr_health12" value="13"/&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;span class="health-dot h12 right-cap"&gt;k&lt;/span&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp;&nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/tr&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;tr&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td colspan="4" class="bar-label"&gt;Trivial&lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td colspan="3" class="bar-label"&gt;Light&lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td colspan="2" class="bar-label"&gt;Moderate&lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td colspan="2" class="bar-label"&gt;Severe&lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;td class="bar-label" style="border-right:none;"&gt;Fatal&lt;/td&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/tr&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;tr&gt;&lt;td&gt;&lt;/td&gt;&lt;/tr&gt; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &nbsp; &lt;/table&gt;
I don't know if this helps, but it should produce results that look like this:
1612236381
GiGs
Pro
Sheet Author
API Scripter
Obligatory friendly warning: if you're planning on publishing your sheet for community use on the roll20 github, you'll need to remove the table, and use a different layout method. Roll20 wont accept sheets that use html tables for layout. If this affects you, start a new thread asking for help on how to replace that table and post the above html.
The sheet is for my own homebrewed system, so I probably won't be publishing it. I probably will want to rewrite the parts with tables. I was just frustrated with getting the layout correct. I'm trying to learn most of this as I go, so there is a fair bit of banging my head against the keyboard, but I'm slowly getting there.
1612238589

Edited 1613513555
GiGs
Pro
Sheet Author
API Scripter
I sympathize, I don't like working with CSS :) Here's a sheet worker to calculate the healthtrack values, and handle the way wounds can wrap upwards, and marks the correct number of wounds. This assumes that if the last wound (severity 5) is marked, any that would wrap up beyond that are discarded (since the character is dead, probably). on ( 'change:repeating_wounds:severity' ,&nbsp; function ( eventInfo )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;create&nbsp;a&nbsp;holding&nbsp;object&nbsp;to&nbsp;save&nbsp;attributes &nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; output &nbsp;=&nbsp;{}; &nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;initialise&nbsp;an&nbsp;array&nbsp;to&nbsp;track&nbsp;the&nbsp;severity&nbsp;values.&nbsp;This&nbsp;assumes&nbsp;severities&nbsp;have&nbsp;values&nbsp;of&nbsp;1-5 &nbsp;&nbsp;&nbsp;&nbsp; let &nbsp; severities &nbsp;=&nbsp; Array ( 6 ). fill ( 0 ); &nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;an&nbsp;array&nbsp;for&nbsp;the&nbsp;minumum&nbsp;pont&nbsp;on&nbsp;the&nbsp;wound&nbsp;track&nbsp;each&nbsp;wound&nbsp;size&nbsp;must&nbsp;mark. &nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; sevmins &nbsp;=&nbsp;[ 0 ,&nbsp; 1 ,&nbsp; 5 ,&nbsp; 8 ,&nbsp; 10 ,&nbsp; 12 ]; &nbsp;&nbsp;&nbsp;&nbsp; getSectionIDs ( 'repeating_wounds' ,&nbsp; idarray &nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; fields &nbsp;=&nbsp;[]; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; idarray . forEach ( id &nbsp; =&gt; &nbsp; fields . push ( `repeating_wounds_ ${ id } _severity` )); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; getAttrs ( fields ,&nbsp; values &nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; idarray . forEach ( id &nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; sev &nbsp;=&nbsp; parseInt ( values [ `repeating_wounds_ ${ id } _severity` ])&nbsp;||&nbsp; 0 ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( sev == 0 ){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; removeRepeatingRow ( 'repeating_wounds_' &nbsp;+&nbsp; id ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; else &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if &nbsp;([ 1 ,&nbsp; 2 ,&nbsp; 3 ,&nbsp; 4 ,&nbsp; 5 ]. includes ( sev ))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; severities [ sev ]&nbsp;=&nbsp; severities [ sev ]&nbsp;+ 1 ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp; else &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;if&nbsp;a&nbsp;severity&nbsp;is&nbsp;outside&nbsp;the&nbsp;valid&nbsp;range&nbsp;of&nbsp;1-5,&nbsp;add&nbsp;it&nbsp;to&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; severities [ 0 ]&nbsp;=&nbsp; severities [ 0 ]&nbsp;+ 1 ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;a&nbsp;function&nbsp;to&nbsp;find&nbsp;the&nbsp;first&nbsp;eligible&nbsp;0&nbsp;value&nbsp;in&nbsp;the&nbsp;health&nbsp;track &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; findNextEmptyWound &nbsp;=&nbsp;( arr ,&nbsp; start )&nbsp; =&gt; &nbsp; arr . indexOf ( '0' ,&nbsp; start ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;a&nbsp;complex&nbsp;function&nbsp;to&nbsp;build&nbsp;a&nbsp;healthtrack&nbsp;of&nbsp;0-12&nbsp;with&nbsp;values&nbsp;0&nbsp;or&nbsp;1. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;I&nbsp;would&nbsp;normally&nbsp;explain&nbsp;how&nbsp;this&nbsp;function&nbsp;works,&nbsp;but&nbsp;lets&nbsp;just&nbsp;say&nbsp;its&nbsp;magic. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;reduce&nbsp;is&nbsp;an&nbsp;extremely&nbsp;powerful&nbsp;function,&nbsp;but&nbsp;not&nbsp;easy&nbsp;to&nbsp;explain. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; healthtrack &nbsp;=&nbsp; severities . reduce (( arr ,&nbsp; size ,&nbsp; index )&nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if &nbsp;( index &nbsp;===&nbsp; 0 )&nbsp; return &nbsp; arr ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; for ( let &nbsp; i &nbsp;=&nbsp; 0 ;&nbsp; i &nbsp;&lt;&nbsp; size ;&nbsp; i ++)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; nextEmpty &nbsp;=&nbsp; findNextEmptyWound ( arr ,&nbsp; sevmins [ index ]); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( nextEmpty &nbsp;&gt;&nbsp; 0 )&nbsp; arr [ nextEmpty ]&nbsp;=&nbsp; '1' ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return &nbsp; arr ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;},&nbsp; Array ( 13 ). fill ( '0' )); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;now&nbsp;that&nbsp;we&nbsp;know&nbsp;which&nbsp;points&nbsp;on&nbsp;healthtrack&nbsp;are&nbsp;1&nbsp;and&nbsp;which&nbsp;0,&nbsp;save&nbsp;them&nbsp;to&nbsp;output. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; healthtrack . forEach (( check ,&nbsp; index )&nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; if ( index &nbsp;&gt;&nbsp; 0 )&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;set&nbsp;the&nbsp;health&nbsp;track&nbsp;value&nbsp;to&nbsp;0&nbsp;or&nbsp;1. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output [ `health ${ index } ` ]&nbsp;=&nbsp; check ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; getWoundMod &nbsp;=&nbsp;( wounds ,&nbsp; woundBands )&nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;this&nbsp;will&nbsp;give&nbsp;the&nbsp;largest&nbsp;entry&nbsp;that&nbsp;has&nbsp;a&nbsp;marked&nbsp;wound,&nbsp;and&nbsp;0&nbsp;if&nbsp;no&nbsp;wounds. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; biggestWound &nbsp;=&nbsp; wounds . lastIndexOf ( '1' )&nbsp;===&nbsp;- 1 &nbsp;?&nbsp; 0 &nbsp;:&nbsp; wounds . lastIndexOf ( '1' ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;this&nbsp;will&nbsp;find&nbsp;which&nbsp;wound&nbsp;band&nbsp;that&nbsp;wound&nbsp;falls&nbsp;into &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; whichBand &nbsp;=&nbsp; 5 - woundBands . reverse (). findIndex ( index &nbsp; =&gt; &nbsp; biggestWound &nbsp;&gt;=&nbsp; index ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return &nbsp;- whichBand ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output [ 'wound-mod' ]&nbsp;=&nbsp; getWoundMod ( healthtrack ,&nbsp; sevmins ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; setAttrs ( output ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;}); }); If there glitches with the worker, I wont be able to test them till tomorrow.
1612238988

Edited 1612239006
GiGs
Pro
Sheet Author
API Scripter
Looking over the code again, I realised we can drop the stats array (containing&nbsp;'health1','health2','health3', etc) since there's never a reason to read their values. The wound values are read entirely from the repeating section, and the entire track of health1-12 values are updated each time. I updated the code.
1612239107
GiGs
Pro
Sheet Author
API Scripter
You should probably change the first line to on ( 'change:repeating_wounds:severity&nbsp;remove:repeating_wounds' ,&nbsp; function ( eventInfo )&nbsp;{ to account for situations when players delete a row manually, instead of changing the severity. It will happen!
Thanks again! It works perfectly. Now I just have to figure out how you did it.
1612240573

Edited 1612240997
GiGs
Pro
Sheet Author
API Scripter
I'll give some hints. Severities is an array that has 6 elements [0, 0, 0, 0, 0, 0] to hold how many wounds of each severity there are. In JS all arrays start at index = 0, so i created an extra element and ignored 0. This made some of the later work easier. So if you have 3 wound of severity 1, and 1 of severity 3, this will have value [0, 3, 0, 1, 0, 0] sevmins &nbsp;holds the minimum point on the threshold track for each of the wound types. again I had to include an element 0, but its ignored. This code populates the severities array: if &nbsp;([ 1 ,&nbsp; 2 ,&nbsp; 3 ,&nbsp; 4 ,&nbsp; 5 ]. includes ( sev ))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; severities [ sev ]&nbsp;=&nbsp; severities [ sev ]&nbsp;+ 1 ; The first line is probably unnecessary but it does no harm. It checks that the severity of this wound is a valid value. If so it adds 1 to the value at the the index matching the current wound size. So if its a light wound, sev = 1. And therefore severities[1] gets increased by 1, since severities[1] holds the number of light wounds you've found. This line is a compact function: const &nbsp; findNextEmptyWound &nbsp;=&nbsp;( arr ,&nbsp; start )&nbsp; =&gt; &nbsp; arr . indexOf ( '0' ,&nbsp; start ); It is called from within the reduce function that follows, which will pass the current value of the health track, which starts like this ['0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0', '0'], and a starting value to search from (this is based on wound size). It will return the first 0 value it finds from that starting point. So if you take a light wound, it will return 1, since it starts searching from position 1, and there's a zero value right there. But if you already have 3 light wounds, the health track will look like ['0', '1', '1', '1', '0', '0', '0', '0', '0', '0', '0', '0', '0'], and so the function will start looking from index 1, and find the first '0' value at index 4. That allows the reduce function to mark the correct position on the wound track. So the reduce function basically takes the severities array (which you'll recall with look something like [0, 3, 0, 1, 0, 0]) and steps through each index. Then at that index, it will see how many wounds there are and for each of them, will use the findNextEmptyWound function to&nbsp; mark the positions on the health track that need wounds. It then returns an array which might look like ['0', '1', '1', '1', '0', '0', '0', '0', '1', '0', '0', '0', '0']. then moving down to healthtrack.foreach, that steps through the above array, and assigns a value of 0 or 1 to each of the attributes health1, health2, etc. these are saved in the output function, so we dont have to call setAttrs multiple times. Finally setAttrs saves all the updated attribute values to the character sheet in one move. Hope this helps your understanding.
Thank you. That clarifies a lot and hopefully gives me some new tools to work with. I greatly appreciate the patience.
So, as I'm understanding it, severities is an array listing how many wounds of each severity there are. Is there a way to find the highest severity value in that array and output it to attr_wound-mod?
1613511067

Edited 1613511185
GiGs
Pro
Sheet Author
API Scripter
Yes, you could do that. IIRC, You'd need to find the position in the array, then convert it into a wound penalty, is that right? What is the sequence and modifiers again?
positions 1,2,3 and 4 would generate a 1, 5,6 and7 would be 2, positions 8 and 9 would generate&nbsp;a 3, 10 or 11 would generate&nbsp;a 4, and position 12 would generate&nbsp;a 5.
So I guess it would have to be pulled from the wounds array.
I was looking at how you pulled the first zero value and trying to figure out how to pull the last non zero value, but I don't understand the magic.
1613513491

Edited 1613513573
GiGs
Pro
Sheet Author
API Scripter
Try this at the end of the worker just before setAttrs: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; getWoundMod &nbsp;=&nbsp;( wounds ,&nbsp; woundBands )&nbsp; =&gt; &nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;this&nbsp;will&nbsp;give&nbsp;the&nbsp;largest&nbsp;entry&nbsp;that&nbsp;has&nbsp;a&nbsp;marked&nbsp;wound,&nbsp;and&nbsp;0&nbsp;if&nbsp;no&nbsp;wounds. &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; biggestWound &nbsp;=&nbsp; wounds . lastIndexOf ( '1' )&nbsp;===&nbsp;- 1 &nbsp;?&nbsp; 0 &nbsp;:&nbsp; wounds . lastIndexOf ( '1' ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; //&nbsp;this&nbsp;will&nbsp;find&nbsp;which&nbsp;wound&nbsp;band&nbsp;that&nbsp;wound&nbsp;falls&nbsp;into &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; const &nbsp; whichBand &nbsp;=&nbsp; 5 - woundBands . reverse (). findIndex ( index &nbsp; =&gt; &nbsp; biggestWound &nbsp;&gt;=&nbsp; index ); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; return &nbsp;- whichBand ; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp; output [ 'wound-mod' ]&nbsp;=&nbsp; getWoundMod ( healthtrack ,&nbsp; sevmins ); I'll add it to the earlier code.
1613514059
GiGs
Pro
Sheet Author
API Scripter
If its not meant to return a negative number, just change this line &nbsp;return&nbsp;-whichBand; to &nbsp;return&nbsp;whichBand;
1613514221
GiGs
Pro
Sheet Author
API Scripter
Randall S. said: I was looking at how you pulled the first zero value and trying to figure out how to pull the last non zero value, but I don't understand the magic. Javascript has a lastIndexOf function which you can see I used.
I can't seem to get it to work. I tried changing&nbsp; output [ 'wound-mod' ]&nbsp;=&nbsp; getWoundMod ( healthtrack ,&nbsp; sevmins ); &nbsp;to set it to a fixed value just to see if it was the calculation that wasn't working. It still didn't update wound-mod.
1613521584
GiGs
Pro
Sheet Author
API Scripter
Two questions: Have you removed the other sheet worker that updated wound-mod?&nbsp; is wound-mod the correct attribute name? (Just to be sure) If a line like this output [ 'wound-mod' ]&nbsp;=&nbsp;3; if failing, then there's a problem before that line. Are any of the values set by that worker being set properly?
I'm using the code exactly as shown above. Everything else is being set correctly. The input is&nbsp; &lt;input type="hidden" name="attr_wound-mod" value="0"/&gt; and I tried changing output['wound-mod'] = 99; which did not output to wound-mod. I don't have any other workers addressing wound-mod.
1613522565
GiGs
Pro
Sheet Author
API Scripter
Can you post the entire sheet html and css (link to pastebin or somewhere) so I can test it?
1613522620
GiGs
Pro
Sheet Author
API Scripter
also change this &lt;input type="hidden" name="attr_wound-mod" value="0"/&gt; to&nbsp; &lt;input type="number" name="attr_wound-mod" value="0"/&gt; while testing, so you can see the actual value.
I apologise in advance for the Frankenstein nature of the sheet. HTML &nbsp;&nbsp; CSS
I have a span&nbsp; &lt;span name="attr_wound-mod"&gt;&lt;/span&gt; To see what is happening
1613527752
GiGs
Pro
Sheet Author
API Scripter
Weird, its working for me. The only change to the code I made was to remove all the script blocks. You have every sheet worker inside its own script block. This has caused problems before. So you should have only one script block and all workers should be inside that. Instead of something like &lt;script type="text/worker"&gt; on('change:vitality sheet:opened',function(){ getAttrs(['vitality'],function(value){ const b= parseInt(value["vitality"]) || 0; base=b+1 minor=Math.ceil(base/2) major=Math.ceil(base*1.5) harrowing=base*2 dire=Math.ceil(base*2.5) setAttrs({'minor':minor}); setAttrs({'major':major}); setAttrs({'harrowing':harrowing}); setAttrs({'dire':dire}); }); }); &lt;/script&gt; &lt;script type="text/worker"&gt; on('change:will sheet:opened',function(){ getAttrs(['will'],function(value){ const b= parseInt(value["will"]) || 0; base=b+1 agitated=Math.ceil(base/2) addled=Math.ceil(base*1.5) disturbed=base*2 psychotic=Math.ceil(base*2.5) setAttrs({'agitated':agitated}); setAttrs({'addled':addled}); setAttrs({'disturbed':disturbed}); setAttrs({'psychotic':psychotic}); }); }); &lt;/script&gt; You instead want &lt;script type="text/worker"&gt; on('change:vitality sheet:opened',function(){ getAttrs(['vitality'],function(value){ const b= parseInt(value["vitality"]) || 0; base=b+1 minor=Math.ceil(base/2) major=Math.ceil(base*1.5) harrowing=base*2 dire=Math.ceil(base*2.5) setAttrs({'minor':minor}); setAttrs({'major':major}); setAttrs({'harrowing':harrowing}); setAttrs({'dire':dire}); }); }); on('change:will sheet:opened',function(){ getAttrs(['will'],function(value){ const b= parseInt(value["will"]) || 0; base=b+1 agitated=Math.ceil(base/2) addled=Math.ceil(base*1.5) disturbed=base*2 psychotic=Math.ceil(base*2.5) setAttrs({'agitated':agitated}); setAttrs({'addled':addled}); setAttrs({'disturbed':disturbed}); setAttrs({'psychotic':psychotic}); }); }); &lt;/script&gt; Remove all the lines like&nbsp; &lt;/script&gt; &lt;script type="text/worker"&gt; so all the workers are in the same script block. Also the above two workers have a couple of problems. Variables arent declared, lines lack semi-colon endings, and the most important - you should only have one setAttrs, like so on('change:vitality&nbsp;sheet:opened',&nbsp;function&nbsp;()&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;getAttrs(['vitality'],&nbsp;function&nbsp;(value)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;b&nbsp;=&nbsp;parseInt(value['vitality'])&nbsp;||&nbsp;0; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;base&nbsp;=&nbsp;b&nbsp;+&nbsp;1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;minor&nbsp;=&nbsp;Math.ceil(base&nbsp;/&nbsp;2); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;major&nbsp;=&nbsp;Math.ceil(base&nbsp;*&nbsp;1.5); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;harrowing&nbsp;=&nbsp;base&nbsp;*&nbsp;2; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;const&nbsp;dire&nbsp;=&nbsp;Math.ceil(base&nbsp;*&nbsp;2.5); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;setAttrs({ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'minor':&nbsp;minor, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'major':&nbsp;major, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'harrowing':&nbsp;harrowing, &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;'dire':&nbsp;dire &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}); &nbsp;&nbsp;&nbsp;&nbsp;}); These wont cause your code to fail, but do make it run less optimally.
I had tried removing the extra script tags previously, and found I could remove some safely, but removing some of them made it stop working, so I was planning to go back and test which ones I could remove later. As for the setAttrs, I did not know you could place them together with the commas like that. that actually cleans up a lot of things for me. I have kind of a horrible habit of messing with snippets until I end up with something that works, but looks awful and then rewriting it once I know what I'm doing (sort of). I've already rewritten the entire sheet from the ground up about six times so far. That's why all the buttons are empty and don't do anything currently.
So the script tags were giving me trouble because I was reusing variables. I changed the names and it fixed that issue.
1613534797
GiGs
Pro
Sheet Author
API Scripter
Randall S. said: So the script tags were giving me trouble because I was reusing variables. I changed the names and it fixed that issue. Oh yes, I forgot about that - there was one variable name I had to change.
I tried a few things and got some erratic behavior, so, on a hunch, I created a new game and cut and pasted the code into that and now everything works fine. I can only guess that something must have gotten corrupted in the original game.
1613537483
GiGs
Pro
Sheet Author
API Scripter
Did you try creating a new character in the same game? I've often had individual characters getting corrupted when designing a sheet, but creating a new character fixes things up.
I did, but it didn't work. I also had a problem with the ChatSetAttrs not triggering sheet workers until I unchecked and rechecked that function, so I suspect that something got corrupted in the API.
I'm definitely getting unstable behavior from this. When I set the damage to zero it does not always delete the row. Sometimes it sets the field to as null value and repositions elements on the page, and adds a border to the row.&nbsp; to this
1613575323
GiGs
Pro
Sheet Author
API Scripter
checking for zero can sometimes be tricky in javascript. Try changing this: &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(sev==0){ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;removeRepeatingRow('repeating_wounds_'&nbsp;+&nbsp;id); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;([1,&nbsp;2,&nbsp;3,&nbsp;4,&nbsp;5].includes(sev))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;severities[sev]&nbsp;=&nbsp;severities[sev]&nbsp;+1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;a&nbsp;severity&nbsp;is&nbsp;outside&nbsp;the&nbsp;valid&nbsp;range&nbsp;of&nbsp;1-5,&nbsp;add&nbsp;it&nbsp;to&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;severities[0]&nbsp;=&nbsp;severities[0]&nbsp;+1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} to &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if(sev)&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;if&nbsp;([1,&nbsp;2,&nbsp;3,&nbsp;4,&nbsp;5].includes(sev))&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;severities[sev]&nbsp;=&nbsp;severities[sev]&nbsp;+1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;}&nbsp;else&nbsp;{ &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;//&nbsp;if&nbsp;a&nbsp;severity&nbsp;is&nbsp;outside&nbsp;the&nbsp;valid&nbsp;range&nbsp;of&nbsp;1-5,&nbsp;add&nbsp;it&nbsp;to&nbsp; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;severities[0]&nbsp;=&nbsp;severities[0]&nbsp;+1; &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} else { &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;removeRepeatingRow('repeating_wounds_'&nbsp;+&nbsp;id); &nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;&nbsp;} If that doesnt work, we'll move on to something else :)
Unfortunately that did not do the trick. I notice the offending row always changes the wound-desc for that row to "a" and that it is always the first row that is broken. Is it possible that&nbsp;removeRepeatingRow is deleting the row id, but retaining the contents of the individual items in the row?
1613585842

Edited 1613585866
GiGs
Pro
Sheet Author
API Scripter
If its working properly it should remove all the attributes in the row then delete the row, as documented on the wiki: <a href="https://wiki.roll20.net/Sheet_Worker_Scripts#removeRepeatingRow.28_RowID_.29" rel="nofollow">https://wiki.roll20.net/Sheet_Worker_Scripts#removeRepeatingRow.28_RowID_.29</a> But if a worker is creating an attribute value in that row, it could be interrupting the process. where is that "a" coming from?
Not sure where it is coming from, but it is always the same.
1613590388
GiGs
Pro
Sheet Author
API Scripter
I'm fairly sure it's something your chatSetAttr commands are doing, which is beyond what I can help with. I deleted all the sheet workers in the sheet, and set the damage of a wound to 0 to see what happened, and saw the "a" appear in the description.
1613592713

Edited 1613592785
GiGs
Pro
Sheet Author
API Scripter
To confirm things, I restored the sheet workers and then found the attr_damage input, and changed it from type="hidden" to type="number". I then created 10 wounds, and dropped them all to 0 manually without using the chatsetAttr button, and all worked perfectly.
I've tried this every which way, and it works perfectly if the value is adjusted manually, but setting it through ChatSetAttr doesn't delete the row and adds that border. There's no way to put a conditional in the macro and use the API to delete the row if the value is zero, so I'm stumped.
This is weird, but I found a solution. It seems to be a problem with updating the section. If I update a different row afterwards, it deletes the zero row. So I added "&nbsp;--repeating_wounds_-CREATE_damage|0" to the button value. This creates a new row which automatically deletes, but also causes the sheet worker to trigger correctly and delete the row that was zeroed out. Klugey, but it works.
1614019226
GiGs
Pro
Sheet Author
API Scripter
If it works, it works :)