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 would I...

How would I - only once on API startup - loop through the list of every Pathfinder Community Sheet character sheet that has been made and change the value of one of the attributes? Can someone give me an example? I'm not new to programming or new to using existing API scripts but I'm new to writing them from scratch myself and could use some help - I'm not familiar with all the API functions yet and how to manipulate sheets/handouts/objects. Thanks in advance!
1524246155
The Aaron
Pro
API Scripter
Assuming the attribute was named "counter", it would look like this: on('ready',()=>{ findObjs({type:'attribute',name:'counter'}).forEach((a)=>a.set('current', parseInt(a.get('current'))+1)); }); The 'ready' event occurs only once, at startup when the API has loaded all objects. findObjs() takes an object and returns an array of all Roll20 objects which match it's properties.  In this case, all attributes named counter. .forEach() takes a function which will be called with each entry in an array. the rest is just setting the new value on the attribute.
1524251404

Edited 1524251460
Ada L.
Marketplace Creator
Sheet Author
API Scripter
You can't loop through the list of character sheets using the API. You can however, query for attributes that might be present in whatever character sheet the campaign is using. In Aaron's example, we assume that the character sheet the campaign is using (whichever sheet it may be of the many sheets available), has an attribute called "counter". 
1524537750

Edited 1524539054
MyRoll20Stuffs
API Scripter
Thanks for the responses guys. So to achieve what I wanted can I basically do the following? on('ready',()=>{ findObjs({type:'attribute',name:'movement-speed'}).forEach((a)=>a.set('current', '@{speed-modified}/5')); }); Am I doing it right? Or is there another way to achieve that? I want to recalculate how many squares a character can move each time the game starts up in case they changed armor or other factors changed their speed and I don't want to have to manually change each sheet any time their "speed-modified" value gets updated.  Setting the value of "movement-speed" to "@{speed-modified}/5" only works once it doesn't save the variable / calculation it updated the field with the value that @{speed-modified}/5 would return. EDIT: Another possible solution to my problem. Can you make an attribute field on a sheet read-only? If you can than it wouldn't overwrite the formula and I would never have to update the field.
I tried this: on('ready',()=>{ findObjs({type:'attribute',name:'movement-speed'}).forEach((a)=>a.set('current', '@{speed-modified}/5')); }); But that actually puts the text into the bar that uses movement-speed so in bar 2 for example it will say "@{speed-modified}/5" instead of the value the formula should produce. I tried something like this: on('ready',()=>{   findObjs({type:'attribute',name:'movement-speed'}).forEach((a)=>a.set('current', (a.get('current', 'speed-modified') / 5) )); }); And it just keeps dividing the movement-speed and getting into floating point numbers. How can I fix this to get speed-modified divided by 5?
1524554612
Jakob
Sheet Author
API Scripter
You need to get the value of speed-modified for each character separately. Since a  is the movement-speed attribute here, no method of a is going to get you the speed-modified attribute. You can do something like this: on('ready', () => {   findObjs({type:'attribute',name:'movement-speed'}).forEach((a) => {     const speed = parseInt(getAttrByName(a.get('characterid'), 'speed-modified')) || 0;     a.set('current', speed / 5);   }); });
Thanks so much Jakob. I'm a little confused about how this works though maybe you can explain it to me so I understand. I'm new to OOP a = the attribute movement-speed and nothing else? If that is the case how come you can run  a.get('characterid') Is characterid a special variable you have access to on the object if you get an attribute object?
1524556161
Jakob
Sheet Author
API Scripter
a   is the attribute object  which contains the movement speed, so it knows more than just the value of the movement speed. In the  wiki , you can see the properties that an object of type attribute has; in particular, it has the characterid property (underscored, but that's not so important right now) to know which character it belongs to. Hence, you can retrieve the id of the corresponding character via  a.get('characterid') . And next, we feed that into getAttrByName to gain the value of the "speed-modified" attribute for the character which a  belongs to. (Aside: getAttrByName is preferable to some findObjs-based solution here, since it works even for sheet default values, when no attribute object for "speed-modified" may exist yet).
Thanks for the info Jakob - it's basically what I had assumed - the attribute object carries additional properties - I just didn't know which ones. I'm going to have to spend a lot of time on the wiki over the next couple of days to familiarize myself with the API.