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

Auto-Populate Token Assignment

Hello to all! I am using Pathfinder 1ED for a game and because I use PRD compendium entries, the default settings for the game do not apply to tokens when they are dropped on the page/map. So... any chance someone out there has written an API script that automatically populates the assignment of AC and HP to different token bars when the token is dropped on the page. When I look at the details of the dropdown, the AC and the HP values appear to be some kind of an ID rather than a simple text value of "AC" or "HP", but most of the other options in the dropdown can be referenced by a simple text value (example below - see how the option value for "ac" is different than all the others) I have made a script to set the value for "sheetattr_ac_ability_mod" just fine (as an example). If I use the specific value for the "ac" works but only for the single token (as each monster/character seems to have it's own ID value for the "ac" option). I basically want to know how to get the ID for the "ac" option so I can set as the token is dropped on the page. Of course if there is much more elegant way to do this  Man, I hope this all makes sense... thanks in advance for any help on this!
1661893540
timmaugh
Forum Champion
API Scripter
TokenMod will do what you want: !token-mod --set bar1_link|npc_HP You just have to use the right bar and the right attribute name. You can do multiple things in one command, and TM will affect all selected tokens... something like: !token-mod --set bar1_link|hp bar2_link|ac bar3_link|cocktail_count Probably without the count of cocktails for bar3. Unless your game needs it. No judging, here.
1661911458
The Aaron
Roll20 Production Team
API Scripter
So, if you're looking at writing a script that assigns bar1_link, etc, there is a trick to it.  There are 2 types of attributes on a character sheet: Attributes -- these are attributes like you normally deal with, where there is an object with the type 'attribute' that represents the data in question. Autocalc Fields -- these are simply a formula that results in a value, with no object that represents them. In the case of an attribute, to link it up to the bar, you must do 3 things: set bar1_link to the id of the attribute object set bar1_value to the current property of the attribute object set bar1_max to the max property of the attribute object This is because setting the linked attribute does not cause the values to synchronize, so you must initialize them yourself manually. In the case of an autocalc field, you set the bar1_link to the special string `sheetattr_<NAME>`.  So, assuming you were setting an autocalc field for `ac`, you'd set the bar1_link to `sheetattr_ac`.  Then synchronization happens for you and everything works out.  The code in TokenMod that does this is on line 3440: cid=mods.represents || token.get('represents') || ''; if('' !== cid) { delta=findObjs({type: 'attribute', characterid: cid, name: f[0]}, {caseInsensitive: true})[0]; if(delta) { mods[k]=delta.id; mods[k.split(/_/)[0]+'_value']=delta.get('current'); mods[k.split(/_/)[0]+'_max']=delta.get('max'); } else { mods[k]=`sheetattr_${f[0]}`; } } delta in this case will be the attribute object.  If it doesn't exist, assume it was an autocalc field (BTW: you can only get the value of autocalc fields via the getattrbyname() function). Hope that helps.
1661912996
timmaugh
Forum Champion
API Scripter
The Aaron said: (BTW: you can only get the value of autocalc fields via the getattrbyname() function). I did not know this. Probably means there's a hole in Fetch, doesn't it? There's probably a hole in Fetch. ... There's a hole. *wanders of, wrench in hand*
1661965323

Edited 1661965478
OMG THANK YOU!! Seriously, this made it all possible. My tokens now auto-assign AC and HP as a linked value when I drop the token on the page. If anyone is interested, here is my code: on("ready", function() { on("add:token", function(obj) { log("new token dropped"); var cid = obj.get("represents"); var character = getObj("character", cid); charName = character.get('name'); try { //log("start try"); acObj = findObjs({type: 'attribute', characterid: cid, name: 'ac'}, {caseInsensitive: true})[0]; acID = acObj.id; hpObj = findObjs({type: 'attribute', characterid: cid, name: 'hp'}, {caseInsensitive: true})[0]; hpID = hpObj.id; obj.set({ bar1_link:acID, bar3_link:hpID }); log(charName + ' correctly setup') //log("end try"); } catch { //Do nothing, just not fail log(charName + ' failed to setup') } }); });
1661970099
The Aaron
Roll20 Production Team
API Scripter
Ah, nice! Did you find that the value synchronized without needing to set value and max?  They must have fixed that...
I did not need to set value and max - it just worked! So yes, they fixed that? 
Heya folks, found a flaw in my code when you would drop something that was not  a token! Now checking for only those items that are tokens. Because, you know, people are just looking for code here... :) log('loading newTokenSetup.js'); on("ready", function () { on("add:token", function (obj) { log("new token dropped"); if (obj.get("represents") != '') { cid = obj.get("represents"); character = getObj("character", cid); charName = character.get('name'); try { //log("start try"); acObj = findObjs({type: 'attribute', characterid: cid, name: 'ac'}, {caseInsensitive: true})[0]; acID = acObj.id; hpObj = findObjs({type: 'attribute', characterid: cid, name: 'hp'}, {caseInsensitive: true})[0]; hpID = hpObj.id; obj.set({ bar1_link: acID, bar3_link: hpID, showname: true, showplayers_name: true }); log(charName + ' correctly setup') //log("end try"); } catch { //Do nothing, just not fail log(charName + ' failed to setup') } } }); }); log('loaded newTokenSetup.js');
Hmm... looks like my fix brought back the issue where you have to assign the values directly. But... if you delete it and drop it a second  time, it works just fine! Weird... maybe I can fix that at some point! Is there a place to post these kind of script for others to use?
1661990097
The Aaron
Roll20 Production Team
API Scripter
There's an issue where the  add:token  event will fire before the token is 100% set up. If you look at TokenNameNumber, it handles that by storing the added token's ID, then checking if it's well formed when the change:token  event occurs afterward. I've got an example around somewhere that I'll try and find for you. 
1661990382
The Aaron
Roll20 Production Team
API Scripter
Here it is: on('ready',()=>{ const isAddChange = (()=>{ const THRESHOLD = 300; const createRegistry = {}; on('add:graphic',(obj)=>{ createRegistry[obj.id]= new Date() * 1; }); return (id) => ( (new Date()*1) - (createRegistry[id]||0) ) < THRESHOLD; })(); on('change:graphic',(obj)=>{ if( isAddChange(obj.id)) { log('Add Change'); } else { log('Real Change'); } }); });
1662041777

Edited 1662061403
So this isn't helping. The weird part with my code is that is does make the link properly, it just doesn't include the values (see screen shot below). So it seems like it fires off the event properly (as it was doing the exact same thing when I used your code), but doesn't actually assign the values. I added the code to specifically assign values (as per your code you quote way back at the top of this conversation) and it works fine. So... yay on us?