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

ChatSetAttr sometimes only executes one line of code and then stops

I have a two macros to distribute wealth among my players. First Macro accepts my input of cp, sp and gp, calculates how much gold each player gains and the remainder of copper and silver is stores in a "Bank" Character using these commands: !setattr --name Bank --mod --CP|[[ floor(floor(?{Copper}/100)/100)%?{Players}  ]] !setattr --name Bank --mod --SP|[[ floor(floor(floor((([[?{Copper}]] + ([[?{Silver}]] * 10) + ([[?{Gold}]] * 100))%100)/10) + ((floor(([[?{Copper}]] + ([[?{Silver}]] * 10) + ([[?{Gold}]] * 100))/100)%?{Players})*10))) ]] I created a second macro to, at any point, distribute the wealth the bank has ammased between my players. I calculate how much gold accrued in silver and copper, this is then announced in chat and the remainder of cp and sp is to be written back into the bank char using these commands: !setattr --name Bank --set --CP|[[ floor(floor(@{Bank|cp}%100)%10) ]] !setattr --name Bank --set --SP|[[ floor(floor(floor((([[@{Bank|cp}]] + ([[@{Bank|sp}]] * 10) + ([[@{Bank|gp}]] * 100))%100)/10) + ((floor(([[@{Bank|cp}]] + ([[@{Bank|sp}]] * 10) + ([[@{Bank|gp}]] * 100))/100)%?{Players})*10))) ]] These commands do exactly what they are supposed to do, but about each 5th use, only the first command, writing cp into the bank character sheet, is executed. If I reset the bank character sheet and execute the macro again, it works fine. I get no error in either the Chat nor the mod output console. Since the macro works fine most of the time and I get no errors, I'm at a loss at what to do. Anyone else having issues of commands not being executed? Thanks
1661741641
timmaugh
Forum Champion
API Scripter
Hey, Scorch... you're running into this bug: Dropped Commands from Multi-Command Chat Messages You can get around this using Plugger with/without ZeroFrame (metascripts that will work in the ChatSetAttr command lines). Plugger will let you "embed" one command in the other, so Roll20 effectively sees one command until the mods get involved. There are some considerations with your inline rolls, so post back if the threads aren't clear enough or you want more specific guidance on the workaround.
1661745467

Edited 1661745637
Oosh
Sheet Author
API Scripter
If you're running those two macros separately, you can also just combine each one onto one line like this: !setattr --name Bank --mod --CP|[[ floor(floor(?{Copper}/100)/100)%?{Players} ]] --SP|[[ floor(floor(floor((([[?{Copper}]] + ([[?{Silver}]] * 10) + ([[?{Gold}]] * 100))%100)/10) + ((floor(([[?{Copper}]] + ([[?{Silver}]] * 10) + ([[?{Gold}]] * 100))/100)%?{Players})*10))) ]] You can put as many attributes as you like in the same command, as long as they're on the same sheet, and using the same --mod / --set command. If you need to run both of those (all 4 lines) from within one macro, you'll need to Timmaughfy it, as above, since you can't mix --mod and --set in the same CSA line.
Thank you for the answers. Adjusting my commands seemed to do the trick, so far the macros now modified both fields in the character. I also tried around with Plugger a bit, but couldn't get it to run properly. It only gives me $[[0]] as result, regardless of my input. !{& eval}setattr --name Bank --set --CP|[[ floor(floor(?{Copper}%100)%10)  ]]{& /eval} I read in the Roll20 Wiki about HTML Entities, that there was an update to no longer require character codes. It was brought to dev servers over a year ago, but in the article I couldn't see any confirmation that is was also done subsequently to live servers. Do I need to replace characters in my query for it to work?
1661823243

Edited 1661823286
timmaugh
Forum Champion
API Scripter
You know... I'd written a much longer answer last night, but then I went to get a link to one of the threads I mentioned and instead of hitting "Copy" on the bookmark, I clicked it... and the page moved on and I lost all I'd written. So I gave you the short version. Sorry.  Let's try again. OK, so you've got inline rolls to manage. Let's say you send a message of: !runThis [[1d10]]{&eval}!runThat [[2d10]]{&/eval} Here's what's happening... YOU SEND ROLL20 RECEIVES =================================================================== | MESSAGE1 | | content: !runThis [[1d10]]{&eval}!runThat [[2d20]]{&/eval} | =================================================================== | | _| |_ \ / ROLL20 PARSES ROLLS V MOD SCRIPTS RECEIVE =================================================================== | MESSAGE1 | | content: !runThis $[[0]]{&eval}!runThat $[[1]]{&/eval} | | inlinerolls: data for $[[0]], data for $[[1]] | =================================================================== | | _| |_ \ / PLUGGER EXTRACTS SYNTAX V AND SPAWNS 2ND MESSAGE ROLL20 RECEIVES =================================================================== ================================= | MESSAGE1 | | MESSAGE2 | | content: !runThis $[[0]] |~~~~~~>| content: !runThat $[[1]] | | inlinerolls: data for $[[0]], data for $[[1]] | ================================= =================================================================== /\ /\ || || || MOD "runThis" RECEIVES THE ABOVE / MOD "runThat" RECEIVES THE ABOVE / You can see that the roll data is created the first time Roll20 catches the message, and then it's left behind when Plugger dispatches the second message. There is no data for Roll20 to use to replace the $[[1]] roll index, and nothing there when the recipient script ( rollThat ) processes the message. The Fix The quickest fix is to use Pluggers ability to declare a deferral character. To do that, declare the character you will use between parentheses attached to the opening {&eval} tag. Pick something that doesn't otherwise appear in your command line, because Plugger will remove all instances of that character before dispatching the second message. I like to use a caret. That might look like this: {&eval(^)}!runThat [^[2d20]^]{&eval} The deferral character breaks up the inline roll syntax so that it isn't detected by Roll20 at the first pass. Then when Plugger removes the characters and dispatches the second message, the inline roll syntax is "restored". Roll20 detects and parses it, and gives the message (Message2) the inline roll data. The Alternative Fix If you use ZeroFrame (think of it like a metascript manager), you can use the .value syntax in combination with a roll to immediately extract the roll value into the command line. That might look like: {&eval}!runThat [[2d20]].value{&eval} There are times/places/situations where you might need one solution, and others where you might need the second solution. It really comes down to the timing of the metascript events and when the data is available that you need/use in a roll.
Thank you very much for this explanation. I went for the Fix first, but I somehow only managed to crash the API Sandbox when using a deferral character in my macro. I have multiple instances of [[...]] in my macros, I tried setting the deferral to all or only the first, but to no avail I then tried the Alternative Fix, adding ZeroFrame as well, and using this method everything works fine. I chained multiple ChatSetAttr scripts together and they all went through a100% of the time.
1661877579

Edited 1661877741
timmaugh
Forum Champion
API Scripter
Great! If it comes to needing to do the "Fix" style of deferral, you can post the question with your macro syntax and I'll try to help sort out what the syntax should be. Like I said, some of the interactions get a little deep in the meta. But I'm glad you got it working! EDIT: One thing I should add is that when you do this, you are having the mod script generate the second (embedded) message. That can break other things, like selected tokens. (The API "player" doesn't have a VTT interface, so there are never any tokens for that "player".) To fix this, just install one more metascript: SelectManager.
1661936317
Oosh
Sheet Author
API Scripter
timmaugh said: To fix this, just install one more metascript: SelectManager. And this is how the Metamancer reels in his prey....
1661947697
timmaugh
Forum Champion
API Scripter
It's really less... "reeling"... and more just... I don't know. Good beer?
EDIT: One thing I should add is that when you do this, you are having the mod script generate the second (embedded) message. That can break other things, like selected tokens. (The API "player" doesn't have a VTT interface, so there are never any tokens for that "player".) To fix this, just install one more metascript: SelectManager. I will keep that in mind. Thanks to your fix I can implement loads of macros I had in mind that never really worked due to dropping commands.