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

Macros calling Scripts with variable combinations of arguments

1692988039

Edited 1692988092
Is there a way to write one macro that calls commands in one API script, where the prompts in the macro can be different based on user choice? Say, for example, I have an Intoxication API script that has three commands that it supports: "drink", "report", and  "set" . The "drink" command wants another parameter for the type of drink the character wants to consume ("diluted", "weak", "moderate", "strong", etc.) The "set" command wants an integer which is the arbitrary level of intoxication I want to set the character at. The "report" command needs no further script arguments because it will just use sendChat to report the chartacter's current intoxication level to the players. I can create a macro for this that says: !intoxication ?{Option|Drink|Report|Set} ?{Drink|Diluted|Weak|Moderate|Strong} ?{Level|0|1|2|3|4|5|6} But because macros don't support conditional logic, this macro will prompt for all these parameters even though not all of them are required for the option desired. I want the macro to prompt me for an Option and if I select "Report" it should not prompt for anything else, it should just run the intoxication script with the chosen command parameter. "Report". Is there a way to do this? If not, how do others do this? I hate the idea and it leads to macro proliferation, particularly when the Roll20 macro bar and token bar can't be nested, like a menu system, if you have to create three separate macros, "Drink", "Set_Intoxication", and "Report_Intoxication" to avoid having to go through unneccesary parameter input prompts when you just want to report the level of intoxication, have the character drink something, or arbitrarily set the intoxication level. It seems to me this would be a great justification to add conditional execution or branching logic in macros. Thanks --Andy
1692994907
timmaugh
Pro
API Scripter
If you want conditional branching in command lines, you can use APILogic. As a metascript, you can use it in addition to your primary script. You can get it separately, or as a part of the Metascript Toolbox (which is, and has been for 3 weeks now, pending in the 1-click merge queue... but will eventually become available). In the Toolbox you'd also get ZeroFrame (which you can also get separately, of course)... and using those two scripts you can do: !Let's test a value. The selected HP is {&if @{selected|hp} > 10}greater than{&elseif @{selected|hp}<10}less than{&else}equal to{&end} 10.{&simple} But... What you're running into is the need for conditionals in queries. Since those happen before scripts (even metascripts) get a hold of the message, the queries have all completed before we can apply conditional logic to them. There is no second chance to run queries. That means, if you don't want to have multiple commands/buttons cluttering your button bar, that you will have to nest the queries one in the other. To do that, your nested query will have to have every instance of the following control characters replaced by their HTML equivalent: CHAR  =>   HTML ------------------ |    =>   | ,    =>   , }    =>   } Making your command line something more like: !intoxication ?{Option|Drink  ?{Drink|Diluted | Weak | Moderate | Strong} |Report|Set  ?{Level|0 | 1 | 2 | 3 | 4 | 5 | 6&rbrace}
1692996278
GiGs
Pro
Sheet Author
API Scripter
You can probably get it down to two macros. The report macro simply reports intoxication level, and the set Intoxiaction and Drink might be same, like ?{drink or set intoxication| Diluted,0|Weak,1|Moderate,2|Strong,3} Set each level matching a text label, and in the macro you'll accept the number that corresponds to that level, and add to inftoxication level or whatever you do with intoxication.
1693006056

Edited 1693006083
timmaugh, Thanks. I'll look into APILogic and the Metascript Toolbox. Not sure I understand what nesting and replacing those characters with HTML equivalents does. Do those changes also require use of APILogic to have an impact? I tried to just copy and paste this and it resulted in jibberish. Are you implying that  this command line syntax alone...  ?{Option|Drink  ?{Drink|Diluted | Weak | Moderate | Strong} |Report|Set  ?{Level|0 | 1 | 2 | 3 | 4 | 5 | 6&rbrace} Will result in nested parsing and correspondingly informed conditional display of input prompt dialogs, or this syntax used with APILogic will do that? I guess I can see some kind of nested sendChat approach in my JS that parses the Option sent in from the macro as a command, and if the command is "drink", calls sendChat wiith "?{Strength|Diluted|Weak|etc.}". But if the command is "set" calls sendChat with "?{Level|0|1|2|etc.}. Is that what APILogic will do for me, parse my original nested "message" and call nested iterations of sendChat to get conditional inputs? Or it that yet another approach? timmaugh said: If you want conditional branching in command lines, you can use APILogic. As a metascript, you can use it in addition to your primary script. You can get it separately, or as a part of the Metascript Toolbox (which is, and has been for 3 weeks now, pending in the 1-click merge queue... but will eventually become available). In the Toolbox you'd also get ZeroFrame (which you can also get separately, of course)... and using those two scripts you can do: !Let's test a value. The selected HP is {&if @{selected|hp} > 10}greater than{&elseif @{selected|hp}<10}less than{&else}equal to{&end} 10.{&simple} But... What you're running into is the need for conditionals in queries. Since those happen before scripts (even metascripts) get a hold of the message, the queries have all completed before we can apply conditional logic to them. There is no second chance to run queries. That means, if you don't want to have multiple commands/buttons cluttering your button bar, that you will have to nest the queries one in the other. To do that, your nested query will have to have every instance of the following control characters replaced by their HTML equivalent: CHAR  =>   HTML ------------------ |    =>   | ,    =>   , }    =>   } Making your command line something more like: !intoxication ?{Option|Drink  ?{Drink|Diluted | Weak | Moderate | Strong} |Report|Set  ?{Level|0 | 1 | 2 | 3 | 4 | 5 | 6&rbrace}
1693020368
timmaugh
Pro
API Scripter
Sorry. I should have made that clearer. And I should have caught the error that I left in that bit of command line. Let me fix both now. APILogic gives you conditionals, and it gives them by using the tags: {&if} {&elseif} {&else} {&end} APILogic, as a metascript, gets the message first. (The same message object is handed off from script to script in the order they are installed; however, metascripts use a trick to get into the head of the queue, giving them early access to the message object and the command line. They make changes before the recipient script ever sees the message. APILogic conditionally includes (or excludes parts of the command line based on the evaluation of the conditionals.) I mentioned APILogic just as a way to fill the general need of conditionals in Roll20 commands. However, APILogic won't work for nested queries for the problems I mentioned. This (corrected version of what I posted before) is how you nest that set of queries: ?{Option|Drink,?{Drink|Diluted|Weak|Moderate|Strong}|Report|Set,?{Level|0|1|2|3|4|5|6&rbrace} You'll have to tweak what information is left behind based on what you need in the command line. For instance, the way it is written if you pick "Drink" then "Diluted"... you'll only get "Diluted" in the outcome. That's because the value of the "Drink" option from the outer query is the inner query... and the inner query is resolving to "Diluted" and ONLY diluted. If you needed "Drink" to be in there, too, you'd have to put that on the value side of that option. Now, about using this in a mod... you mentioned building a sendChat command line. These will not work from a mod script. Chat messages coming out of a mod script are sent via the Script Moderator. Imagine that the Script Moderator is another player at your game, except that they can't interact with the tabletop. So when the Script Moderator sends a chat message that has roll queries... there is no player who can answer the queries. *You* will never see them. The best you can do from a script is to output a chat button that has, as a part of the command line it will run when it is clicked, the query syntax you need. That way, when the player or GM clicks that button, they will be the player initiating the command line, and THEY are the ones who will be prompted to answer the questions. The alternative, if you are building a mod yourself, is to build around an expected command line template where you let the players place the queries themselves. If that's what you're intended to do, post back.
Thanks That corrected syntax worked and did what I wanted it to do, the first time I tried it, but then somehow the macro was edited by the system and all &verts got replaced by vertical pipes. Can you instruct Roll20 not to automatically replace the HTML with CHAR?
1693053853
timmaugh
Pro
API Scripter
That is a quirk of macros on the Collection tab. You can use HTML replacements in those, and if you save it and never look at the macro again, they will continue to work. But if you ever go into one of them as if to edit it, even if you don't actually make any changes, the system will revert the HTML substitutions back to their decoded characters. This is one of the main reasons why macro mules are suggested instead. Abilities on character sheets don't suffer from the same quirk.
Thanks for your help timmaugh. I'm coming back to this after a long break. The corrected syntax works for "Drink" but not for "Set". I'd expect choosing "Set" to then display 0 - 6 as new options but it doesn't. It just closes the prompt.