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

[Script] ChatSetAttr - set character attributes via chat messages

1469622106

Edited 1516806019
Jakob
Sheet Author
API Scripter
This is a utility script with a singular purpose: you can supply a list of characters (in multiple ways) and a list of attributes and values, and for all characters in the list the attributes will be set to the values (and created if they did not exist before). The syntax is !setattr [--options] --attribute1|value1|max1 --attribute2|value2|max2 ... Alternatively, you can use the following syntax to spread the command out over multiple lines (in this case, you cannot use closing curly braces('}}') anywhere in the values): !setattr {{ [--options] [--all|--allgm|--allplayers|--sel|--charid id1, id2, ...|--name name1, name2, ...] --attribute1|value1|max1 --attribute2|value2|max2 ... }} You can also just use --attribute1|value1  to leave the maximum unchanged. You can also use '#' in place of '|'. More in-depth documentation can be found in the README . Find the script at Github or via the One-Click library (both v1.7.1).
1469643838
The Aaron
Pro
API Scripter
Neat! =D
1469685611
Lithl
Pro
Sheet Author
API Scripter
It appears this script will only set the current value on an attribute. Would be nice if there was some means to set the maximum as well.
1469686824

Edited 1469694160
Jakob
Sheet Author
API Scripter
Brian said: It appears this script will only set the current value on an attribute. Would be nice if there was some means to set the maximum as well. I've been thinking about a good syntax for that. Easiest would be just --max applying to all attributes, but I would like something individual.  EDIT: I would like --Strength|12|14 to set maximum Strength to 14 and current Strength to 12, and --Strength||14 to only set maximum Strength to 14, but then there is no way of clearing current while setting maximum in the same command (repeating one attribute works badly due to the way I've set up parsing). If anyone has any good ideas, I'd be happy to hear them.
1469701793
Jakob
Sheet Author
API Scripter
Okay, I think I have figured out a way. Updated the OP with new information. One potentially breaking change I made: the option --sel  is now required to affect selected tokens. If no option is given at all, the script will simply spit out an error message.
OK, I am going to kick myself because I am sure that I am missing something so obvious that it is right in front of me, but I have been banging my head on the desk trying to get this to work so I am going to ask my stupid question. First let me say that the script is working great! I can select some tokens and run the script using chat and it will set the value in the Attribute exactly as expected. In this case I am attempting to set an Attribute named "zINIT_ROLL" using a roll query. So I enter this in the chat: !setattr --sel --zINIT_ROLL|?{Initiative Roll} And I get this back: (From John C. (GM)): C. (GM) Setting zINIT_ROLL to 3 for characters Oleanne, Garyld. Perfect. But what I want to do is setup a macro so that I can click on a button in the Macro Bar and run this for all of the selected tokens. So I created my macro ("Initiative Roll_v1") and used the exact same command in the macro that I entered in the char window. When I use the Test Macro button in the Edit Macro window it works fine! But when I Save the changes and click the button in the Macro Bar I get this in the chat window: John C. (GM): #Initiative Roll_v1 Now, I realize that the name of this script is Chat SetAttr, but does that mean it ONLY works from chat? If not, then what the heck am I doing wrong?! Thanks in advance far any help that anyone can provide!
Macros that have spaces within their names are not possible to call. You'll want to rename your Macro, maybe to "Initiative_Roll_v1".
See, I knew there was something very simple that I was missing! Thank you for the quick response Silvyre, that fixed it.
This looks really neat. I haven't tried it out yet because I'm in the midst of other prep, but is it be possible to have this affecting repeating section attributes with the list order syntax? A.K.A select an attribute as 'repeating_buff_$2_buff-enable_toggle' instead of ' repeating_buff_-KNoPmPxTXYSfbwuUjKm_buff-enable_toggle' ? I imagine that it would take a little leg-work to get running, but it'd be great for turning on mass buffs like Inspire Courage on the Pathfinder sheet once API+SheetWorker synergy is in place. As I said, I haven't tested it - maybe you thought ahead and already did this, but it seemed a question worth asking anyway. :-)
1469867609
Jakob
Sheet Author
API Scripter
Bennett S. said: This looks really neat. I haven't tried it out yet because I'm in the midst of other prep, but is it be possible to have this affecting repeating section attributes with the list order syntax? A.K.A select an attribute as 'repeating_buff_$2_buff-enable_toggle' instead of ' repeating_buff_-KNoPmPxTXYSfbwuUjKm_buff-enable_toggle' ? I imagine that it would take a little leg-work to get running, but it'd be great for turning on mass buffs like Inspire Courage on the Pathfinder sheet once API+SheetWorker synergy is in place. As I said, I haven't tested it - maybe you thought ahead and already did this, but it seemed a question worth asking anyway. :-) That would be a great feature! Unfortunately, I just tested it and it doesn't work just by chance. In the end, it comes down to the question: does findObj return the right attribute when you search the name by the row number instead of row id. Apparently it does not. I don't know if/how the API has access to the row number. If it does, I'll certainly try to make it work.
1470131023

Edited 1470167003
Jakob
Sheet Author
API Scripter
I just pushed 0.7 to Github, which now handles repeating sections better, with the following changes ( only affects repeating sections). Repeating section attributes will never be created if they do not exist yet. The reason for this is that creating repeating section attributes with invalid row ids messes up the sheet and creates ghost repeating rows. Bad news. The downside to this is that you can no longer overwrite defaults for row id items; the attribute must have been created first (e.g. by clicking into the corresponding field once and clicking somewhere else again). I think this is an acceptable compromise for now- maybe in the future I will add some check to see if the row exists, even if the particular attribute for this row does not. The script will fail silently if it doesn't find an existing attribute (i.e. it will still claim to have changed it, but nothing will happen for characters where the attribute does not exist). You can  adress repeating sections by row index ($5). However, this only works if the rows have not  been reordered. I.e., this will target rows in order of creation, not in the order they are displayed in. It will also ONLY target the correct attribute if the attribute exists for ALL rows of this type (well, created before the one we are trying to target). There does not currently seem to be a way to find out the real row number of an attribute, so I think this is the best I can do. This uses a bit of fiddling around with regexps, I hope I didn't create too many errors here. As before, this will just do nothing if the corresponding attribute does not exist (for example because the row does not exist). Phew.  This would be so much easier and less prone to user-error if I had some way of getting the id from the row number, but it doesn't seem possible (outside of the sheet author supporting it by explicitly providing the id via sheetworkers). EDIT: Okay, I've rethought my way of dealing with this and played around a bit to make it work better (0.7.1). It is now possible to create repeating section attributes if they happen to be created in repeating sections that already exist. Also, adressing repeating sections by row index (e.g. $5) will now work as expected even if the attributes don't exist yet. The only problem that seems unsolvable is the fact this method does not care about reordering of repeating rows, so it will find the attributes in order of creation, not in display order. But this should cover most use cases. Now to wait for api/sheetworker integration (and perhaps upgrade the parser at some point, to allow more complicated inputs).
1470305830

Edited 1470306082
Jakob
Sheet Author
API Scripter
v 0.7.2  adds the option --replace. It allows you to set the values of attributes to be inline rolls, or other attributes (instead of the values of these attributes or inline rolls). When --replace is supplied, the characters <,>,#,~ will be replaced by [,],|,@ when the attributes are set. This allows you to run, for example !setattr --sel --replace --strength_total | ~{strength} + ~{strength_bonus} This will set strength_total to "@{strength} + @{strength_bonus}".
Ahh dude! Awesome! Crossing my fingers that reordered rows can be tracked properly soon but even this makes it so much easier! And the new features are sweet too. I'll consider it a birthday present come one day early. :-D
1470921885
Jakob
Sheet Author
API Scripter
Update 0.8 Added new command !delattr , with essentially the same syntax (with attribute values ignored, obviously), that will delete attributes it finds. Added option --nocreate  to not create missing attributes, will display an error message instead.
1472085056

Edited 1472099748
This looks amazing.  Any chance it will get added to the Roll20 API Script Library so people can get updates automatically? Also, is there a way to add abilities via this script?  I've got a lot of  standard power cards  I'd like to add to every character sheet via something like this.... :) Thank you again for this amazing script.
1472096427
Tetsuo
Forum Champion
Jakob said: Brian said: It appears this script will only set the current value on an attribute. Would be nice if there was some means to set the maximum as well. I've been thinking about a good syntax for that. Easiest would be just --max applying to all attributes, but I would like something individual.  EDIT: I would like --Strength|12|14 to set maximum Strength to 14 and current Strength to 12, and --Strength||14 to only set maximum Strength to 14, but then there is no way of clearing current while setting maximum in the same command (repeating one attribute works badly due to the way I've set up parsing). If anyone has any good ideas, I'd be happy to hear them. Maybe try  --Strength|@{selected|strength}|14 would set max to 14 while keeping current at whatever it already is?
1472111202

Edited 1472111251
Jakob
Sheet Author
API Scripter
Sudain said: This looks amazing.  Any chance it will get added to the Roll20 API Script Library so people can get updates automatically? Also, is there a way to add abilities via this script?  I've got a lot of  standard power cards  I'd like to add to every character sheet via something like this.... :) Thank you again for this amazing script. I've been thinking about adding it to the library. Eventually, I'll get around to it... This script doesn't touch abilities, they are a different type of object than attributes are. One could hack this script to affect abilities instead of attributes pretty easily, but you would need to do a bit more to implement your plan, because the current syntax does not allow for double dashes inside attribute values (and I think PowerCards needs plenty of those). @ Franky: I solved this problem quite a while ago. As written in the introductory post, the correct syntax is --Strength||14.
1472112572
Tetsuo
Forum Champion
Oh. My mistake. I missed that. I thought you were asking for ways it my work. My mistake. 
1472126729

Edited 1472128689
Jakob
Sheet Author
API Scripter
Franky H. said: Oh. My mistake. I missed that. I thought you were asking for ways it my work. My mistake.  No problem, I just wanted to correct so that no one reads your post and thinks there's not yet a solution for this :).
1472147553

Edited 1472147582
:D  I used this last night with the below macro and this is speeding up my monster character creation time GREATLY.  Thank you again.  I'll try to find a different mod to add abilities; I don't want to hack your working script of time-saving. !setattr --sel --Init|?{Init}|, AC|?{AC}|, touch|?{touch}|, flat-footed|?{flat-footed}|, hp|?{hp}|, Fort|?{Fort}|, Ref|?{Ref}|, Will|?{Will}|, Speed|?{Land Speed}|, bab|@?{bab}|, CMB|?{CMB}|, CMD|?{CMD}|, Acrobatics|?{Acrobatics}|, Bluff|?{Bluff}|, Climb|?{Climb}|, Diplomacy|?{Diplomacy}|, Disguise|?{Disguise}|, Escape Artist|?{Escape Artist}|, Fly|?{Fly}|, Intimidate|?{Intimidate}|, Perception|?{Perception}|, Ride|?{Ride}|, Sense Motive|?{Sense Motive}|, Stealth|?{Steath}|, Survival|?{Survival}|, Swim|?{Swim}|, Languages|?{Languages}|
1472228595

Edited 1472231028
Anyone familiar with how the D&D 5E OGL sheet handles the Whisper Rolls to GM setting?  I'm looking for a way to set all my npc's to the option "Query Whisper" but i'm not finding the right attribute to manipulate to make this happen. Edit:  Looks like it is the wtype attribute and the value is "?{Whisper?|Public Roll,|Whisper Roll,/w gm }" Edit2:  Looks like there's not a replace option to replace the ? character so i'm not able to add the roll query to the attribute value. Edit3:  It also doesn't seem to be too happy about commas within the attribute either.   Anywho, this may be something that gets updated by sheet workers  or something as well, so it may be a moot point (Not 100% sure i'm understanding how all this works so take that comment with a grain of salt) Last Edit (I hope):  I got it to work using the following: Edited the script a bit by changing line number 157  From  returnstr.replace(//g,']').replace(/#/g,'|').replace(/\~/g,'@'); To return str.replace(//g,']').replace(/#/g,'|').replace(/\~/g,'@').replace(/\=/g,'?').replace(/\^/g,','); This allowed me to use = in place of ? and ^ in place of ,  at least for the time being.  May want to change those back after this so as not to mess up any future commands. I then ran the command: !setattr --allgm --replace --wtype|={Whisper?#Public Roll^#WhisperRoll^/w gm} And that worked setting the wtype attribute to the ?{Whisper?|Public Roll,|Whisper Roll,/w gm } value.
1472240686
Jakob
Sheet Author
API Scripter
Hmm, it seems you solved all your problems yourself :) ! Some thoughts: It's true that there's no replacement for ?. I just forgot about that! I'll build something into the script, though I will not use =, since that is also pretty likely to be used by some commands. The commas don't work because the script expects to split multiple attributes by comma. That's unnecessary in theory - one could delete lines 147 and 148 to get rid of that behaviour, and still change multiple attributes at once via --attribute1|value1 --attribute2|value2 et cetera. On the other hand, I don't want to delete it at this point since it looks and will make everyone's macros invalid. (I could put in some sort of replacement instead, like you did, but I feel like I'm running out of characters here.)
1472542384
Jakob
Sheet Author
API Scripter
FYI, I have submitted a pull request for version 0.9 to the roll20 API repository. I've decided to bite the bullet and make 2 potentially breaking changes for this version (better get it done before I add it to the script library): It's no longer possible to separate attributes by commas. Instead, they must be separated by double dashes (--). The replacer list is changed to: < , > , # , ~ , ; ,  ` being replaced by [,],|,-,?, and @. (In particular, the tilde is no longer replaced by @). I've added an extra variable replacers  at the start of the script. If you know a bit what you are doing and do not like my choices, you can change the replacement rules there instead of having to muck about in the script and parse my undocumented code :). The script is not in the normal place for the moment until I also get to update the documentation above. But one can get it under  Link .
1472574215

Edited 1472574351
Thanks, Jakob! Really enjoying these features!
Awesome!  Thanks for making the updates!
1473260950
Jakob
Sheet Author
API Scripter
The pull request has been accepted, so in a couple of days(?) the script will be available for One-Click installation. I hope more people will become aware of its existence this way, "I want to make a macro to mod character attributes" seems to be a rather common request.
1473603940

Edited 1473604164
So, looks like an awesome script, can see using it quite a bit. One question though, is there a way to pull the value of an attribute in order to set another attribute?  For example, lets say I have an attribute called Temp.  I would like: !setattr --Strength|@{selected|Temp}|@selected|Temp|max} NEVERMIND!  Figured out that I needed to use the --sel option! !setattr --sel --Strength|@{selected|Temp}|@selected|Temp|max}
1473699559
Jakob
Sheet Author
API Scripter
Yep, that works Kevin. Downside is that everyone's strength will be set to the same value if you have several tokens selected.
1474031520
Jakob
Sheet Author
API Scripter
v0.9.1 adds (among some small cosmetic fixes) the option --mod to adjust (integer-valued) attributes instead of replacing the current value.
1474165729

Edited 1474169780
This is such a great tool Jakob.  Major kudos to you for making it happen! I am running into a minor problem while attempting to make a specific case scenario work though.  I am attempting to use this script to toggle a boolean attribute by using a macro button.  Here is the syntax I am attempting to use which is not functioning correctly: !setattr --sel --replace --repeating_buff_$0_buff-enable_toggle|((`{selected#repeating_buff_$0_buff~enable_toggle} ~ 1) * (`{selected#repeating_buff_$0_buff~enable_toggle} ~ 1)) When I activate this text command it gives the following: Setting repeating_buff_$0_buff-enable_toggle to ((`{selected>repeating_buff_$0_buff~enable_toggle} ~ 1) * (`{selected>repeating_buff_$0_buff~enable_toggle} ~ 1)) for characters (character name here) (replacing <,>,#,~,;,` by [,],|,-,?,@). However, the attribute in question is not changing.  Any chance I'm missing something?  Basically I want to set a boolean attribute to the value (b-1)*(b-1) where b=the current value of the attribute. EDIT:  So I found my first problem.  I needed to be parsing the math before passing it into the script.  So I have adjusted the text command as follows: !setattr --sel --nocreate --repeating_buff_$0_buff-enable_toggle|(@{selected|repeating_buff_$0_buff-enable_toggle} - 1) * (@{selected|repeating_buff_$0_buff-enable_toggle} - 1) This still doesn't quite work as when the attribute is set to 0 the returned message is: Setting repeating_buff_$0_buff-enable_toggle to (0 - 1) * (0 - 1) for characters (character name here). How can I get the (0-1)*(0-1) to parse before sending to the script? EDIT2: SUCCESS!  I found that this script apparently functions with inline rolls!  Here was the final text command used to achieve the desired effect: !setattr --sel --nocreate --repeating_buff_$0_buff-enable_toggle|[[(@{selected|repeating_buff_$0_buff-enable_toggle} - 1) * (@{selected|repeating_buff_$0_buff-enable_toggle} - 1)]]
1474372485

Edited 1474372530
Jakob
Sheet Author
API Scripter
v 1.0  (now on Github) features a (possibly very large) performance gain as well as handling of large campaigns (e.g. Storm King's Thunder). If you use --all  on many characters at once, it will take some time for the changes to be applied to all characters, but the script will finish and not crash the sandbox due to taking too long (it handles 20 characters per second, because The Aaron said he always uses a delay of 50 ms :)). Many thanks to The Aaron, who made this version possible. This version is a rewrite of some parts of the script, so it's possible some new errors may have crept in.
1475006133
Caden
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Love this script! Just wanted to throw this out for Shadowrun people. New players have a habit typing 1d6 into macros instead of just the 1. We noticed typing 1d6 crashes the script. Easy restart but I wanted to let you know. :) Thanks again!
1475011315

Edited 1475011368
Necoya said: We noticed typing 1d6 [into macros] crashes the script. What do you mean? Could you provide an example of a macro that crashes the script?
1475011906
Jakob
Sheet Author
API Scripter
Necoya said: Love this script! Just wanted to throw this out for Shadowrun people. New players have a habit typing 1d6 into macros instead of just the 1. We noticed typing 1d6 crashes the script. Easy restart but I wanted to let you know. :) Thanks again! What Silvyre said, I'd love a reproduction path so I can fix this crash.
1475012085
Caden
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Of course! How rude of me not to leave you the steps reproduce. :) Due to how wonky Shadowrun's initiative is I use this Macro !setattr --sel --silent --initiativedice|?{Initiative Dice|1} If players leave the 1 alone its fine. If they enter 1d6 it results in this: Could not determine result type of: [{"type":"M","expr":"(5)"},{"type":"C","text":" + ((1d6)d6)"}] undefined
1475014342

Edited 1475014434
!setattr --sel --silent --initiativedice|?{Initiative Dice|1} There's no issues with setting an Attribute to have a Current value of '1d6'. However, there is an issue with rolling '(1d6)d6' within a macro, which is evidently what one of your macros is attempting to do via (@{initiativedice})d6. I recommend using ?{Initiative Dice|1|2|3|4|5} within your CSA macro to prevent this from happening.
1475016092
Caden
Forum Champion
Sheet Author
API Scripter
Compendium Curator
Ah you are complete right. Serves me for multitasking. :)
1475065208
Jakob
Sheet Author
API Scripter
To be 100% sure: the script is not actually crashing over this, is it?
1475071071
Caden
Forum Champion
Sheet Author
API Scripter
Compendium Curator
@Jakob. Nope. The crash is coming from the second half of my macro. Silyre was right. Sorry about that. Thanks for looking into it. :) Love the script.
1475653036
Jakob
Sheet Author
API Scripter
Update: The newest version (also part of 1.0) features some quality-of-life improvements in the parsing: it will automatically get rid of trailing spaces in the input, and it supports input in multiple lines to help make macros more beautiful.
Is there a way to copy the current _Max value to the _value value?
1476779568
Jakob
Sheet Author
API Scripter
Kevin Flynn said: Is there a way to copy the current _Max value to the _value value? Hmm, no. You can do it for a single character by just writing it in manually (e.g. --attrname|@{charname|attribute|max}, but not for multiple characters. Perhaps I should add this as an option.
Jakob said: Kevin Flynn said: Is there a way to copy the current _Max value to the _value value? Hmm, no. You can do it for a single character by just writing it in manually (e.g. --attrname|@{charname|attribute|max}, but not for multiple characters. Perhaps I should add this as an option. Seems like a function Token-Mod might cover?
1476781546
Jakob
Sheet Author
API Scripter
Saevar L. "Liquid-Sonic" said: Jakob said: Kevin Flynn said: Is there a way to copy the current _Max value to the _value value? Hmm, no. You can do it for a single character by just writing it in manually (e.g. --attrname|@{charname|attribute|max}, but not for multiple characters. Perhaps I should add this as an option. Seems like a function Token-Mod might cover? Only if it's a linked attribute on a token... (which will cover the most common use cases like hit points).
1476787707

Edited 1476788342
I want to use it to reset ammo loads, so create a gun then track its ammo, then use the Max score to reload.... so I need to prompt for Gun name (attr), then copy the Max value over to the Value.
1476791017
Jakob
Sheet Author
API Scripter
If you check out the latest Github (now 1.0.2), I've added a command !resetattr  (same syntax as setattr  and  delattr ) that resets all specified attributes to their maximum (value and max are ignored).
Awesome, thanks :)
1476813734
Jakob
Sheet Author
API Scripter
Oops, forgot to sync. Anyway, it'll be there some time tomorrow.
Am I looking in the right place, from first post, still says 1.0.1
1476854582

Edited 1476861721
Jakob
Sheet Author
API Scripter
Kevin Flynn said: Am I looking in the right place, from first post, still says 1.0.1 Jakob said: Oops, forgot to sync. Anyway, it'll be there some time tomorrow. OK, online now, sorry for the confusion :).
1477910440

Edited 1478010703
Jakob
Sheet Author
API Scripter
I just pushed CSA 1.1 to GitHub. This one is a bit experimental, and I'm not putting it into one-click just yet. Changes are as follows: The !resetattr command has been removed . Its functionality is still available, but only through !setattr ... --attribute|%attribute_max% (this is to avoid a bloat of options to maintain). New option --modb , which works just like --mod  with one change: if it's changing the current  value of an attribute, it will keep the attribute between 0 and the maximum (if there is a maximum). The script can now fill in values of other attributes into your attribute values. More precisely, any expression of the form %attr% or %attr_max% will be parsed to corresponding character's attribute value or maximum, respectively. Example: !setattr --mod --sel --attr1|%attr2% !setattr --sel --attr1|%attr2%|%attr2_max% The first line will add the value of attr2 to the value of attr1. The second line will copy attr2 into attr1. New, dangerous, nasty option --evaluate . This will try to evaluate math expressions that you put into attribute values. Because this works through Javascript's eval(), this can execute arbitrary code in your API sandbox. So don't put anything crazy in here. Should I limit this to GM use only? Probably! (not yet the case though). I have tried to catch errors resulting from this, but this is impossible to debug. On the other hand, this allows neat stuff like !setattr --sel --evaluate --attr3|2*%attr1% + 7 - %attr2%