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

Referencing button name in setAttrs

I have a dice-rolling sheetworker that I'd like to generalise across multiple buttons rather than have 12 slightly different copies of it (I also have a lot of other sheetworkers that will benefit to the same extent). I have it all working except that I need the setAttrs to set an attribute that corresponds to the specific button clicked and I don't know the syntax. Here's the whole sheetworker: const NPC1talking = [     'NPC1talking' ]; NPC1talking.forEach(button => {     on(`clicked:${button}`, () => {     getAttrs(['NPC1talking'], v=> {             startRoll(`&{template:default} {{name=${button}}} {{Roll=[[[[@{${button}}]]d6]]}}`, (NPC1talking) => {                 const dice = NPC1talking.results.Roll.dice //This will be an array of the values rolled on all the dice                 const total1s = dice.filter(d => d === 1).length;                 const total2s = dice.filter(d => d === 2).length;                 const total3s = dice.filter(d => d === 3).length;                 const total4s = dice.filter(d => d === 4).length;                 const total5s = dice.filter(d => d === 5).length;                 const total6s = dice.filter(d => d === 6).length;                 const total7s = dice.filter(d => d === 7).length;                 const total8s = dice.filter(d => d === 8).length;                 const total9s = dice.filter(d => d === 9).length;                 const total10s = dice.filter(d => d === 10).length;                 finishRoll(                     NPC1talking.rollId, // this is where you save the computed values into something that can be passed to rolltemplates.                     {                     }                 );                 setAttrs({                     NPC1talkingused: 1,             dummy1: total1s,             dummy2: total2s,             dummy3: total3s,             dummy4: total4s,             dummy5: total5s,             dummy6: total6s,             dummy7: total7s,             dummy8: total8s,             dummy9: total9s,             dummy10: total10s,                 });             });         });     }); }); This works exactly as I need it to for the NPC1talking button, but I want to generalise it for all 12 NPCs. I've done this within the roller itself (see name= and roll=), but I also need to do it for NPC1talkingused in the setAttrs. That is, once the sheetworker has been set up for all 12 buttons ( NPC1talking , NPC2talking , etc) I need setAttrs to set a specific attribute to 1 and that attribute has the same name as the button clicked but with 'used' added on the end. I.e. If the NPC7talking button is clicked, then after the roll is computed the NPC7talkingused attribute needs to be set to 1 with all the other NPC#talkingused attributes being left alone. What would the syntax for that be? Or is it not doable?
1662660312

Edited 1662660564
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
You want the object literal syntax  bracket notation: setAttrs({ [`${button}used`]: 1, dummy1: total1s, dummy2: total2s, dummy3: total3s, dummy4: total4s, dummy5: total5s, dummy6: total6s, dummy7: total7s, dummy8: total8s, dummy9: total9s, dummy10: total10s, }); I'd also recommend using an object accumulator to store your changes in before calling setAttrs. This lets you write fewer lines of code and have something to log if things suddenly stop working right. I'd do this like so: const NPC1talking = [ 'NPC1talking' ]; NPC1talking.forEach(button => { on(`clicked:${button}`, () => { getAttrs(['NPC1talking'], v => { startRoll(`&{template:default} {{name=${button}}} {{Roll=[[[[@{${button}}]]d6]]}}`, (NPC1talking) => { const dice = NPC1talking.results.Roll.dice //This will be an array of the values rolled on all the dice const setObj = {[`${button}used`]: 1}; setObj.dummy1 = dice.filter(d => d === 1).length; setObj.dummy2 = dice.filter(d => d === 2).length; setObj.dummy3 = dice.filter(d => d === 3).length; setObj.dummy4 = dice.filter(d => d === 4).length; setObj.dummy5 = dice.filter(d => d === 5).length; setObj.dummy6 = dice.filter(d => d === 6).length; setObj.dummy7 = dice.filter(d => d === 7).length; setObj.dummy8 = dice.filter(d => d === 8).length; setObj.dummy9 = dice.filter(d => d === 9).length; setObj.dummy10 = dice.filter(d => d === 10).length; finishRoll( NPC1talking.rollId, // this is where you save the computed values into something that can be passed to rolltemplates. { } ); setAttrs(setObj); }); }); }); }); Edit: Also, if you aren't passing any computed properties, you don't need to pass a second argument to finishRoll . E.g. you can just do finishRoll(NPC1talking.rollId) .
Perfect, thank you!!
I have follow-up if you wouldn't mind indulging me... Here's a copy of the same sheet worker for a different set of buttons: const NPCrollt = [   'NPC1t1' ]; NPCrollt.forEach(button => {   on(`clicked:${button}`, () => {     getAttrs(['[`${button}used`]'], v => {       startRoll(`&{template:default} {{name=${button}}} {{Roll=[[[[@{NPC1t1number}]]d[[@{NPC1t1size}]]]]}}`, (NPCrollt) => {         const dice = NPCrollt.results.Roll.dice //This will be an array of the values rolled on all the dice         const setObj = {[`${button}used`]: 1};         setObj.dummy1 = dice.filter(d => d === 1).length;         setObj.dummy2 = dice.filter(d => d === 2).length;         setObj.dummy3 = dice.filter(d => d === 3).length;         setObj.dummy4 = dice.filter(d => d === 4).length;         setObj.dummy5 = dice.filter(d => d === 5).length;         setObj.dummy6 = dice.filter(d => d === 6).length;         setObj.dummy7 = dice.filter(d => d === 7).length;         setObj.dummy8 = dice.filter(d => d === 8).length;         setObj.dummy9 = dice.filter(d => d === 9).length;         setObj.dummy10 = dice.filter(d => d === 10).length;         finishRoll(           NPCrollt.rollId, // this is where you save the computed values into something that can be passed to rolltemplates.           {           }         );         setAttrs(setObj);       });     });   }); }); It's just set up for one button right now ( NPC1t1 ) and works as required, but I want to use it for t1, t2, t3 and t4 for each of the 12 NPCs. In the startRoll line I need to replace NPC1t1  with the button name for both attributes used in the roll: NPC1t1number and NPC1t1size . I just can't seem to hit the right formation. E.g. `${button}size` doesn't work. What should it be?
1662684981

Edited 1662731294
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
That should work. I'd guess that you have some syntax error in it, maybe a malformed macro. It should be this: startRoll(`&{template:default} {{name=${button}}} {{Roll=[[[[@{${button}number}]]d[[@{${button}size}]]]]}}`, (NPCrollt) => { // Do your startroll reactions });
Weird, thought I'd tried that, but no it works. Thanks again!
1662731271
Scott C.
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Heh, and I actually screwed up that macro. Forgot the ending curly brace on the number attribute call. (Fixed now)