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

Can ChatSetAttr Be Called from Within an API Script?

Currently, I'm able to call PowerCards from within an API script.  It is awesome!  Is there a hook exposed in ChatSetAttr that would allow something similar?
1564279814
The Aaron
Roll20 Production Team
API Scripter
Worst case, you can issue a sendChat() with the command, you just can't count on any features requiring selected tokens. 
Thanks Aaron.  I was thinking that might be the case.  I'm already capturing the characterID, tokenID and other things in the master script so passing that along shouldn't be a problem.  
1564288771

Edited 1564288822
GiGs
Pro
Sheet Author
API Scripter
That said, if are making your own script, you can likely replicate what chatsetattr does within your own script. The API allows you to update attribute values relatively easily, making chatsetattr unnecessary in most cases. You have the character id, so you can use findobjs to get the attribute, and if the attribute exists, directly modify its value, and if it doesnt exist, create it.
Thanks, GiGs!  I was having a heck of a time getting "other_resource" pulled in and modified.  Aaron's suggestion worked beautifully, but it still bugs me that I couldn't get it to work in a more elegant way.  I'm still going to see if I can implement it in the way you suggest.  I'm sure its something I wasn't wrapping my brain around. :-)
1564325504
The Aaron
Roll20 Production Team
API Scripter
A construct like this works: let c = [ SOME CHARACTER FROM findObjs() OR getObj() ]; let attr = (findObjs({ type: 'attribute', characterid: c.id, name: 'someattr' })[0] || createObj('attribute', { characterid: c.id, name: 'someattr' })); attr.set({ current: 5, max: 23 }); Since everything in Javascript can be evaluated as true (truthy) or false (falsy), the boolean operators actually return the values they acted on, so that || (or) in the middle means if findObjs() found something, you return it's first element; if it didn't, you return a newly created object.  The short circuiting property of || (or) means that the createObj() is never called if findObjs() returned something truthy.
1564330819

Edited 1564330953
What's odd is when I perform a getAttrByName(characterID*, "other_resource") , it returns the "current" and "max" values with no issue.  However, when I try to execute a findObjs({type: 'attribute', characterid: characterID*, name: "other_resource"})[0] , I get "undefined" when I try to print out "current" or "max". As you can see below, the "other_resource" is there and has values (obviously, since I"m able to pull "current" and "max" with getAttrByName). One thing to note is that "other_resource" is not listed on the "Attributes & Abilities" tab.  Is that the issue here? *"characterID" is a variable that resolves to the selected character.
1564334875
GiGs
Pro
Sheet Author
API Scripter
Can you show the code you are using in context, to get the current or max value? Attributes on the character sheet dont always show up on the attributes & abilities tab, that's not likely to be the issue. 
1564335547
The Aaron
Roll20 Production Team
API Scripter
Some clarification on when attributes do not show up on the Attributes tab: Repeating section attributes never show up there. Attributes from character sheets that only have their default value do not show up there. Probably what is happening is the attribute you're using has a default value.  In that case, you'll have to grab it with getAttrByName() (Which should really be called "GetAttrVALUEbyNameOrDefaultValueOrZero()" =D).  You could do that as part of the create: let attr = (findObjs({ type: 'attribute', characterid: c.id, name: 'someattr' })[0] || createObj('attribute', { characterid: c.id, name: 'someattr', current: getAttrByName(c.id, 'someattr'), max: getAttrByName(c.id, 'someattr', 'max') })); log(`Attr ${attr.get('name')} fetched with value ${attr.get('current')}/${attr.get('max')}`); attr.set({ current: 5, max: 23 });