[Script] ChatSetAttr - set character attributes via chat messages

1492386273

Edited 1492386426
I know this is probably asked a lot but how do I round with this? The following is not working (of course): !setattr --allplayers --evaluate --mod --hit_dice|floor(%hit_dice_max%/2) I tried to find the answer my self but couldn't. All help appreciated.
1492389161
Im assuming your building a Long rest macro that adds the players hit dice back based on 1/2 their level? I use this macro !setattr --sel --modb --hit_dice|[[floor(@{selected|level}/2)]]
1492390179
Just so! However, with that system I would have to individually select each character and run the macro, which is what I am trying to avoid. :/
1492390456
If I cannot round without using @selected, could I perhaps set a separate attribute beforehand? eg: !setattr --sel --replace --hit_dice_add|floor(`{selected|level}/2) !setattr --modb --allplayers --hit_dice|%hit_dice_add% However the above example simply results in "nothing to do for character".
1492394281

Edited 1492394392
Well without the selected I dont know how the macro would determine each players level (assuming they were diff levels). I use the one I mentioned as a Token macro for each PC, I also add other stuff based on class. Works great for me. I make it a Token Macro bc then, they are all ready selected :)
1492394478
Try this (after taking the necessary precautions): !setattr --allplayers --evaluate --modb --hit_dice|Math.floor(%hit_dice_max%/2)
1492486887
I am try to get !setattr to work with resource name instead of @{repeating_resource_$0_resource_left} So something like !setattr --name @{selected|character_name} --mod --Potion of Healing|-1 --silent
1492487394

Edited 1492487496
You could do this: Add an Attribute to your Character named Potion of Healing Give that Attribute a Current value of repeating_resource_$0_resource_left (or repeating_resource_ RowID _resource_left) Then, you could use this: !modbattr --silent --name @{character_name} --@{Potion of Healing}|-1
1492643612

Edited 1492643799
Silvyre said: Try this (after taking the necessary precautions): !setattr --allplayers --evaluate --modb --hit_dice|Math.floor(%hit_dice_max%/2) This works perfectly, though I elected to use Math.round() instead of Math.floor() so as to avoid level 1 characters regenerating no Hit Die. Thank you for replying. :)
1497734595

Edited 1497735098
Hello, first i have to say this script is great! It broils my brain while thinking what i can do with it and how :) At the moment, i'm trying to set up a coin loot macro, which automatically rolls the amount of coins and put them on the players sheet (DnD 5OGL). So far i have this for example: !setattr --silent --sel --mod --gp|+[[1d6]] It rolls me 1d6 goldp(whatever the p is for) and kick it right in the selected players face. So far so good. My questions/thoughts to improve this are three points: Can i use a roll-table in there? Like !setattr --silent --sel --mod --gp|+[[table_name]] so that, i can make a loot table and link it directly (edit: found the answer on site 2 of this thread, works great) Is there a way to prompt the result in the chat, so that the players can see it? (use the macro, roll XX and the chat output uses the result: you loot XX gold(penny's?) How can i do this with other loot? I didn't get it to work, that it would put me automatically a short sword, for example, in the players item list after smashing the macro button Thanks and have a nice evening
1497742114
Ziechael
Pro
Sheet Author
API Scripter
pale81 said: It rolls me 1d6 goldp(whatever the p is for) and kick it right in the selected players face. So far so good. Gold Pieces traditionally but go with what works for you ;)
1497759524
Ziechael said: pale81 said: It rolls me 1d6 goldp(whatever the p is for) and kick it right in the selected players face. So far so good. Gold Pieces traditionally but go with what works for you ;) Thank you, sounds obvious. One question resolved : )
1497863167
Jakob
Pro
Sheet Author
API Scripter
pale81 said: Is there a way to prompt the result in the chat, so that the players can see it? (use the macro, roll XX and the chat output uses the result: you loot XX gold(penny's?) So, there's no way for ChatSetAttr itself to output the result to chat, you could however write a listener similar to the one I wrote in  this post to react to your CSA commands and output stuff to chat. How can i do this with other loot? I didn't get it to work, that it would put me automatically a short sword, for example, in the players item list after smashing the macro button Now, this is a bit more complicated, and I don't know how exactly the result of a rollable table with a non-number entry interacts with this this script trying to convert an inline roll to its result. I can offer the following: if you have a repeating section repeating_equipment, and the name of an item in that section is described by the "name" attribute in a given row, the following command will add a short sword to the repeating_equipment section of the selected token/character: !setattr --sel --repeating_equipment_create_name|Short Sword This will add just the name, no stats whatsoever. Look for  this example on page 2 for a command that generates a complete weapon (on the PF sheet, but the general strategy is always the same). This is probably too complicated to work as the result of a rollable table, so while you can make an "add short sword" button, I doubt you can make a "roll random weapon and add it in one go" button without further work. Although I could think of a script that takes a rolled weapon from a table, and creates a matching ChatSetAttr API command button for you to add it to a character.
1497868349

Edited 1497869033
Ziechael
Pro
Sheet Author
API Scripter
I have to admit that this idea intrigued me somewhat so I played a bit... since your players aren't always going to want to use the stuff they loot I would suggest having an area (notes or in my 3.5e hacked version the Stored Items section) where you can build up a list of things collected over time, the players can then distribute or put things into use as needed. They'd still need to add the full info for equipment but players have to do something sometimes right??? The gif below is pretty quick (click to view) but the command is pretty simple (beware, I copy and pasted this and it put a false space before it, if it doesn't work try to delete a space that might not look to be at the beginning lol): !setattr --sel --storeditems|@{selected|storeditems} [[ 1t[loot] ]], I prefix it with the stored item section itself to keep the initial info (since --mod doesn't like NAN fields) and then add the results of a rollable table to it (any number of rolls can be done at once), I then added a ',' at the end so that future additions to the list will retain some kind of order... and now, gif time!
1497883575
Jakob
Pro
Sheet Author
API Scripter
Interesting Ziechael. Just wanted to add that you might want to make it  !setattr --sel --storeditems|%storeditems% [[ 1t[loot] ]], instead such that it works correctly when multiple tokens are selected.
1497884446
Ziechael
Pro
Sheet Author
API Scripter
True, it was more a proof of concept really, I'd also add --silent in there too to avoid chat clutter, although a listener might be handy for outputting the loot to chat for all to see?
1498153395
Thank you again, i have to try this as soon as i can. 
1498663249
Dougansf
Pro
Sheet Author
I recently added GroupInitiative to my game.  I was hoping that a ChatSetAttr macro could help me set up character sheets with the formula needed for initiative.  I figure it would be something like this: !setattr {{ --sel --GroupInitiative|[[ [[{1e3, 8}<[[{@{InitTotal}-@{Wounds} - 11, 0}kh1 % 11]] + floor([[{@{InitTotal}-@{Wounds} - 11, 0}kh1]] / 11)]]d20! + [[{2, 4, 5, 6, 7}=[[{@{InitTotal}-@{Wounds}, 0}kh1 % 11]] + {1, 3}=[[{@{InitTotal}-@{Wounds}, 0}kh1]] + {1e3, 3}=[[{@{InitTotal}-@{Wounds} - 11, 0}kh1 % 11]] * 2]]d[[{{(@{InitTotal}-@{Wounds} - 1) * 2, 4}kh1, {12} }kl1]]! + [[{1e3, 8}<[[{@{InitTotal}-@{Wounds}, 0}kh1]] * (1 - {3, 6, 10}=[[{@{InitTotal}-@{Wounds}, 0}kh1 % 11]] + {1, 4, 8}=[[{@{InitTotal}-@{Wounds}, 0}kh1 % 11]])]]d[[10 - {4, 5, 8, 9}=[[{@{InitTotal}-@{Wounds}, 0}kh1 % 11]] * 4]]! + [[{1e3, 8}<[[{@{InitTotal}-@{Wounds}, 0}kh1]] * ({0, 5, 7, 9}=[[{@{InitTotal}-@{Wounds}, 1}kh1 % 11]] + 2 * {6, 10}=[[{@{InitTotal}-@{Wounds}, 0}kh1 % 11]])]]d8! - [[{1, 2}=[[{@{InitTotal}-@{Wounds}, 0}kh1]] * (3 - [[{@{InitTotal}-@{Wounds}, 0}kh1]])]] ]] }} But it doesn't seem to be working.  I get this error: TypeError: Cannot read property 'substring' of undefined.
1498664956
Jakob
Pro
Sheet Author
API Scripter
Yes, so the problem is that Roll20 wants to evaluate your attributes and inline rolls before they ever arrive for ChatSetAttr to handle them! Solution: add the --replace option, and 1) replace all instances of "[" in your message by "<", and (optionally, I think) "]" by ">" 2) replace all instances of "@" in your message by "`" (backtick). That should do the trick.
1500212568
This is an amazingly powerful script!! Much appreciated!  Now I could use some assistance in with something I am attempting to do. what I'm needing to do is to have it modify one attribute if it is lower than another.
1500281390
Jakob
Pro
Sheet Author
API Scripter
Adras said: This is an amazingly powerful script!! Much appreciated!  Now I could use some assistance in with something I am attempting to do. what I'm needing to do is to have it modify one attribute if it is lower than another. So, in pseudocode, you want to do something like this ? if (attr1 < attr2) { attr1 = SOME_FUNCTION(attr1) } That can be done, the easiest way would probably be using --evaluate. Something like this (if both attr1 and attr2 are numbers): !setattr {{ --evaluate --attr1|(%attr1% < %attr2%) ? ( %attr1% + 2 ) : %attr1% }} This will increase attr1 by 2 (bold part) if it is smaller than attr2. You can stick any kind of valid Javascript formula in there instead. Naturally, this will probably give an error of some kind if either attr1 or attr2 are not numbers. Or maybe crash your sandbox, I'm not sure :).
1500294990
awesome! thanks, I will work with this and see what I can create!
1500298631
you wouldn't happen to know if there is a way to have this go into the script inside the HTML of a character sheet would you?
1500299572
Jakob
Pro
Sheet Author
API Scripter
Adras said: you wouldn't happen to know if there is a way to have this go into the script inside the HTML of a character sheet would you? Not directly. I mean, you could write a sheet worker to do something similar depending on your particular use case, but you can't put an API script into a sheet, and the sheet worker code would look completely different from this.
1500301723
mind if I PM you Jakob?
1500622591
Jakob
Pro
Sheet Author
API Scripter
Adras said: mind if I PM you Jakob? Just do it, I always have the liberty of not replying ;) (I'll probably reply though).
1500982492
Jakob
Pro
Sheet Author
API Scripter
1.4 It is now possible to delete repeating rows, using !delattr [--target] --repeating_sectionName_ID or !delattr [--target] --repeating_sectionName_$rowNumber.
1500989757
Vince
Pro
Sheet Author
"It appears someone has lifted your coin purse..."
1500992266
Jakob- If you can delete repeating rows it must be possible to create them. Is it possible to use your script to set up new modifiers on the shaped sheet? And traits? I have certain buffs and abilities that should be on every character and monster, but it is a real pain to set them up. Could your script help automate that?
1500993248

Edited 1500993324
Jakob
Pro
Sheet Author
API Scripter
Gary W. said: Jakob- If you can delete repeating rows it must be possible to create them. Is it possible to use your script to set up new modifiers on the shaped sheet? And traits? I have certain buffs and abilities that should be on every character and monster, but it is a real pain to set them up. Could your script help automate that? Yes! For example, this is how you create a Bless modifier on a character {{ --repeating_modifier_-create_name|Bless --repeating_modifier_-create_attack_toggle|1 --repeating_modifier_-create_attack_modifier|1d4cs0cf0 --repeating_modifier_-create_saving_throw_toggle|1 --repeating_modifier_-create_saving_throw_modifier|1d4cs0cf0 }} (Add !setattr and target as normal - !setattr --allgm is possible!). It will be active by default (because that's the sheet default). Add --repeating_modifier_-create_active|0 if you want it to be inactive to start with. So, essentially: figure out the fields you have to set in that section with the dev tools, and set them all in one !setattr command per buff or ability. If you use -create for the same repeating section several times in one command, they will all go into the same row; if you put them into several commands, every command will get its own row.
1501526954
That solution is working very well for me, thanks again Jakob. I thought I had asked a follow up question, but maybe never actually posted it. Can your script also create Abilities? The macros on the third tab? If so, how would I go about it?
1501582025
Jakob
Pro
Sheet Author
API Scripter
Gary W. said: That solution is working very well for me, thanks again Jakob. I thought I had asked a follow up question, but maybe never actually posted it. Can your script also create Abilities? The macros on the third tab? If so, how would I go about it? Alas, it cannot.
1501591883
I am surprised! Actually, I knew that was a stretch. But I figured  you and Aaron had split the writing. Token Mod for all things on the token, and yours for everything on the sheet. And this was on the sheet. Your slacking :)
1501593989
Ziechael
Pro
Sheet Author
API Scripter
The Aaron does have something that can write abilities to characters, not sure it is on general release or not though... sure he'll be along soon enough to promote it if so ;)
1501594190
The Aaron
Pro
API Scripter
(That's not really ready for general release... =D )
1501594689
That will be a nice utility tool!
1501597422
Ziechael
Pro
Sheet Author
API Scripter
The Aaron said: (That's not really ready for general release... =D ) Hence the gentle prodding towards completion ;)
1501614005
Jakob
Pro
Sheet Author
API Scripter
@Gary: You inspired me for a quick & dirty hack. See  here .
1502994040
All right- raising the white flag and asking for help. Trying to make a setchatattr macro to create an attacher for Shaped Sheets. The only thing working is to create the attacher and the name. Anybody able to fix my field names for me?  !setattr --sel {{ --repeating_attacher_-create_name|Dice Modifiers --repeating_attacher_-create_attr_strength_check_attacher|1 --repeating_attacher_-create_attr_dexterity_check_attacher|1 --repeating_attacher_-create_attr_constitution_check_attacher|1 --repeating_attacher_-create_attr_intelligence_check_attacher|1 --repeating_attacher_-create_attr_wisdom_check_attacher|1 --repeating_attacher_-create_attr_charisma_check_attacher|1 --repeating_attacher_-create_attr_initiative_check_attacher|1 --repeating_attacher_-create_attr_strength_saving_throw_attacher|1 --repeating_attacher_-create_attr_dexterity_saving_throw_attacher|1 --repeating_attacher_-create_attr_constitution_saving_throw_attacher|1 --repeating_attacher_-create_attr_intelligence_saving_throw_attacher|1 --repeating_attacher_-create_attr_wisdom_saving_throw_attacher|1 --repeating_attacher_-create_attr_charisma_saving_throw_attacher|1 --repeating_attacher_-create_attr_spell_attacher|1 --repeating_attacher_-create_attr_offense_attacher|1 --repeating_attacher_-create_attr_utility_attacher|1 --repeating_attacher_-create_attr_skill_attacher|1 --repeating_attacher_-create_attr_freetext| [Use A Hero Point](~selected|Use-Hero-Point) [Use Bardic Inspiration](~Macro Sheet|Use-Bardic-Inspration) [Use GM Inspiration](~Macro Sheet|Use-GM-Inspration) }}
1502994316
Jakob
Pro
Sheet Author
API Scripter
Get rid of all the "attr_" (e.g. --repeating_attacher_-create_strength_check_attacher|1) , then it should work.
1502994980
Just tried that- no joy. (Believe that is what I started out at even) !setattr --sel {{ --repeating_attacher_-create_name|Dice Modifiers --repeating_attacher_-create_strength_check_attacher|1 --repeating_attacher_-create_dexterity_check_attacher|1 --repeating_attacher_-create_constitution_check_attacher|1 --repeating_attacher_-create_intelligence_check_attacher|1 --repeating_attacher_-create_wisdom_check_attacher|1 --repeating_attacher_-create_charisma_check_attacher|1 --repeating_attacher_-create_initiative_check_attacher|1 --repeating_attacher_-create_strength_saving_throw_attacher|1 --repeating_attacher_-create_dexterity_saving_throw_attacher|1 --repeating_attacher_-create_constitution_saving_throw_attacher|1 --repeating_attacher_-create_intelligence_saving_throw_attacher|1 --repeating_attacher_-create_wisdom_saving_throw_attacher|1 --repeating_attacher_-create_charisma_saving_throw_attacher|1 --repeating_attacher_-create_spell_attacher|1 --repeating_attacher_-create_offense_attacher|1 --repeating_attacher_-create_utility_attacher|1 --repeating_attacher_-create_skill_attacher|1 --repeating_attacher_-create_freetext| [Use A Hero Point](~selected|Use-Hero-Point) [Use Bardic Inspiration](~Macro Sheet|Use-Bardic-Inspration) [Use GM Inspiration](~Macro Sheet|Use-GM-Inspration) }} results in  Setting attributes Setting repeating_attacher_-create_name to Dice Modifiers, repeating_attacher_-create_strength_check_attacher to 1, repeating_attacher_-create_dexterity_check_attacher to 1, repeating_attacher_-create_constitution_check_attacher to 1, repeating_attacher_-create_intelligence_check_attacher to 1, repeating_attacher_-create_wisdom_check_attacher to 1, repeating_attacher_-create_charisma_check_attacher to 1, repeating_attacher_-create_initiative_check_attacher to 1, repeating_attacher_-create_strength_saving_throw_attacher to 1, repeating_attacher_-create_dexterity_saving_throw_attacher to 1, repeating_attacher_-create_constitution_saving_throw_attacher to 1, repeating_attacher_-create_intelligence_saving_throw_attacher to 1, repeating_attacher_-create_wisdom_saving_throw_attacher to 1, repeating_attacher_-create_charisma_saving_throw_attacher to 1, repeating_attacher_-create_spell_attacher to 1, repeating_attacher_-create_offense_attacher to 1, repeating_attacher_-create_utility_attacher to 1, repeating_attacher_-create_skill_attacher to 1, repeating_attacher_-create_freetext to [Use A Hero Point](~selected / Use-Hero-Point) [Use Bardic Inspiration](~Macro Sheet for character Pheobi Stormtower. But the result in the character sheet is 
1502995554

Edited 1502995609
Jakob
Pro
Sheet Author
API Scripter
Ah! It seems that these checkboxes are not set to value=1 on the sheet, so you'lll need to use "on" in place of "1" everywhere. Moreover, the freetext doesn't work since you haven't escaped the vertical bars, so replace "|" by "\|" in the value of the freetext.
1502996971
Thanks Jakob. I had tried most of those things individually, but the Lord only knows what combination I used them in!  Worked perfectly. 
1503000937
Would it be possible to add a limiter to the --allgm command? Maybe something along the lines of limiting the command to all sheets with names that start with the letter A, B, C, etc? (--allgm A) That allgm command is incredibly useful setting up characters in my campaign, but my monster warehouse is already too big for the command to be processed. The API times out. Not sure if it is related to that max size issue. 
1503007790
Jakob
Pro
Sheet Author
API Scripter
Gary W. said: Would it be possible to add a limiter to the --allgm command? Maybe something along the lines of limiting the command to all sheets with names that start with the letter A, B, C, etc? (--allgm A) That allgm command is incredibly useful setting up characters in my campaign, but my monster warehouse is already too big for the command to be processed. The API times out. Not sure if it is related to that max size issue. It's possible, but that's really odd, I thought I had eliminated the problem via a deferred queue. *sigh*. How many character sheets are in your campaign, roughly? I had tested it with ~300 sheets in a campaign, I think, but I didn't test it with 300 sheets and  complicated operations like creating rows...
1503008460
Think it is about 600 and growing.
1503008571
This isn't the campaign we at in, it is where I warehouse fully functional monsters with macros and tokens. 
1503067793
Jakob
Pro
Sheet Author
API Scripter
600 is tough: I'm not exactly sure where the script fails; depending on where it is, it's easy or hard to fix. I guess you're creating an attacher for every character in the campaign? That's going to be tough on the API, for sure.... Anyway, take a look at this  Gist . I've changed the delay from 50ms to 200ms. Maybe you could first try --all again. See if it works (probably not). If it doesn't work, see if it still manages to print 'ChatSetAttr: got all the attributes.' to the API log. That will tell me where it's stalling. Anyway, since this will probably fail, I've also added a --startswith option, so you can do e.g. --startswith A to catch all characters whose names start with A (case-insensitively).
1503072266
Awesome- I try not to mess with anything on game day so will give it a spin tomorrow and let you know. Your script has become an essential piece in my toolbox for my actual campaign. It ran into troubles with both creating the attachers and traits as well as simply setting the defaults in the monster warehouse. The exact message was something about a possible infinite loop. Will try and be more specific tomorrow.