macro (roll option): Difference between revisions

From RPTools Wiki
Jump to navigation Jump to search
m (variable1 should be variable2)
(What happens if multiple macros have the same name)
 
(7 intermediate revisions by 5 users not shown)
Line 6: Line 6:


|usage=
|usage=
<source lang="mtmacro" line>
<syntaxhighlight lang="mtmacro" line>
[macro("macro_name@location"): macro_arguments]
[macro("macro_name@location"): macro_arguments]
</source>
</syntaxhighlight>
'''Parameters'''
'''Parameters'''
{{param|macro_name|The name of the macro button that is run.}}
{{param|macro_name|The name of the macro button that is run.}}
Line 17: Line 17:
The {{code|location}} can be one of the following:
The {{code|location}} can be one of the following:
* {{code|TOKEN}} - The currently impersonated token (use the word {{code|TOKEN}}, not the token's name).
* {{code|TOKEN}} - The currently impersonated token (use the word {{code|TOKEN}}, not the token's name).
* Library Token - A [[Library Token]] in the current campaign.
* {{code|campaign}}
* {{code|global}}
* {{code|Lib:*}} Library Token - A [[Library Token]] in the current campaign.
* {{code|this}} - If the macro is calling another macro on the same [[Library Token]], {{code|this}} may be used instead of retyping the full [[Library Token]] name.
* {{code|this}} - If the macro is calling another macro on the same [[Library Token]], {{code|this}} may be used instead of retyping the full [[Library Token]] name.
'''Notes'''
'''Notes'''
Line 26: Line 28:


This roll option may not interact with other roll options the way you expect.  For example:
This roll option may not interact with other roll options the way you expect.  For example:
<source lang="mtmacro" line>
<syntaxhighlight lang="mtmacro" line>
[if(Condition),MACRO("getDamage@Lib:combat"): damageRoll]
[if(Condition),MACRO("getDamage@Lib:combat"): damageRoll]
</source>
</syntaxhighlight>


{{code|getDamage}} gets executed regardless of the value of {{code|Condition}}.  However, if {{code|Condition}} is not true, the arguments to the macro will be empty instead of containing {{code|damageRoll}}.  You probably want:
{{code|getDamage}} gets executed regardless of the value of {{code|Condition}}.  However, if {{code|Condition}} is not true, the arguments to the macro will be empty instead of containing {{code|damageRoll}}.  You probably want:
<source lang="mtmacro" line>
<syntaxhighlight lang="mtmacro" line>
[if(Condition): evalMacro('[MACRO("getDamage@Lib:combat"): damageRoll]')]
[if(Condition): evalMacro('[MACRO("getDamage@Lib:combat"): damageRoll]')]
</source>
</syntaxhighlight>
 
If multiple macros with the exact same name exist in the same location, this roll option will call the ''first created'' macro, regardless of its group location on the Token.  Renaming the macro will not change its creation order, but moving it to a different token and moving it back, or deleting and recreating it, will.


|example=
|example=
<source lang="mtmacro" line>
<syntaxhighlight lang="mtmacro" line>
[MACRO("getDamage@Lib:combat"): damageRoll]
[MACRO("getDamage@Lib:combat"): damageRoll]
</source>
</syntaxhighlight>
Calls the macro {{code|getDamage}} which resides on a [[Library Token]] called {{code|Lib:combat}}, and passes the variable {{code|damageRoll}} as an argument to the called macro.  
Calls the macro {{code|getDamage}} which resides on a [[Library Token]] called {{code|Lib:combat}}, and passes the variable {{code|damageRoll}} as an argument to the called macro.  


Line 46: Line 50:


'''Using a [[JSON Array]] to pass multiple values (order matters, names do not)'''
'''Using a [[JSON Array]] to pass multiple values (order matters, names do not)'''
<source lang="mtmacro" line>
<syntaxhighlight lang="mtmacro" line>
[ variable1 = "hello" ]
[ variable1 = "hello" ]
[ variable2 = "world" ]
[ variable2 = "world" ]
Line 52: Line 56:
[MACRO("calledMacro@this"): passedVars ] <!-- macro call, with values being passed -->
[MACRO("calledMacro@this"): passedVars ] <!-- macro call, with values being passed -->
[ resultVar = macro.return ]  <!-- this is what you get back from the called macro -->
[ resultVar = macro.return ]  <!-- this is what you get back from the called macro -->
</source>
</syntaxhighlight>
Within the "called macro", the [[macro.args]] (macro arguments) must be unpackaged to recover the values stored in the array:
Within the "called macro", the [[macro.args]] (macro arguments) must be unpackaged to recover the values stored in the array:
<source lang="mtmacro" line>
<syntaxhighlight lang="mtmacro" line>
[ var1 = json.get( macro.args, 0 )]
[ var1 = json.get( macro.args, 0 )]
[ var2 = json.get( macro.args, 1 )]
[ var2 = json.get( macro.args, 1 )]
<!-- do stuff with your new variables -->
<!-- do stuff with your new variables -->
[ macro.return = var1 +" "+ var2 ] <!-- this is what you can send back to the calling macro (can also be another JSON Object or array -->
[ macro.return = var1 +" "+ var2 ] <!-- this is what you can send back to the calling macro (can also be another JSON Object or array -->
</source>
</syntaxhighlight>
Note that using a [[JSON Array]] to pass & unpack values, rather than a [[JSON Object]], has the added advantage that if the called macro is also a [[user defined function]] (see [[defineFunction]]), the exact same commands given in the example above can be used to separate individual arguments passed in the calling "function", since function arguments are automatically bundled into a [[JSON Array]] and passed to the [[macro.args]] special variable.
Note that using a [[JSON Array]] to pass & unpack values, rather than a [[JSON Object]], has the added advantage that if the called macro is also a user defined function (see [[defineFunction]]), the exact same commands given in the example above can be used to separate individual arguments passed in the calling "function", since function arguments are automatically bundled into a [[JSON Array]] and passed to the [[macro.args]] special variable.


'''Using a [[JSON Object]] to pass multiple values (names matter, order does not)'''
'''Using a [[JSON Object]] to pass multiple values (names matter, order does not)'''
<source lang="mtmacro" line>
<syntaxhighlight lang="mtmacro" line>
[ variable1 = "hello" ]
[ variable1 = "hello" ]
[ variable1 = "world" ]
[ variable2 = "world" ]
[ passedVars = json.set( "{}", "variable2", variable2, "variable1", variable1 )] <!-- package up variables into a json array to be passed to called macro.  Note that the order here does not matter, but the labels in quotes are needed to be able to retrieve the correct values in the called macro -->
[ passedVars = json.set( "{}", "variable2", variable2, "variable1", variable1 )] <!-- package up variables into a json array to be passed to called macro.  Note that the order here does not matter, but the labels in quotes are needed to be able to retrieve the correct values in the called macro -->
[MACRO("calledMacro@this"): passedVars ] <!-- macro call, with values being passed -->
[MACRO("calledMacro@this"): passedVars ] <!-- macro call, with values being passed -->
[ resultVar = macro.return ]  <!-- this is what you get back from the called macro -->
[ resultVar = macro.return ]  <!-- this is what you get back from the called macro -->
</source>
</syntaxhighlight>
Within the "called macro", the [[macro.args]] (macro arguments) must be unpackaged to recover the values stored in the array:
Within the "called macro", the [[macro.args]] (macro arguments) must be unpackaged to recover the values stored in the array:
<source lang="mtmacro" line>
<syntaxhighlight lang="mtmacro" line>
[ var1 = json.get( macro.args, "variable1" )]<!-- actually the second label / value pair in the object -->  
[ var1 = json.get( macro.args, "variable1" )]<!-- actually the second label / value pair in the object -->  
[ var2 = json.get( macro.args, "variable2" )]<!-- the order does not matter, but the label must be accurate to retrieve the correct value -->
[ var2 = json.get( macro.args, "variable2" )]<!-- the order does not matter, but the label must be accurate to retrieve the correct value -->
<!-- do stuff with your new variables -->
<!-- do stuff with your new variables -->
[ macro.return = var1 +" "+ var2 ] <!-- this is what you can send back to the calling macro (can also be another JSON Object or array -->
[ macro.return = var1 +" "+ var2 ] <!-- this is what you can send back to the calling macro (can also be another JSON Object or array -->
</source>
</syntaxhighlight>





Latest revision as of 23:59, 20 September 2024

[macro():] Roll Option

* Introduced in version 1.3b46

Runs the named macro, returning its output in the form of the macro.return special variable.

Usage

[macro("macro_name@location"): macro_arguments]

Parameters

  • macro_name - The name of the macro button that is run.
  • location - The location of the macro button that is run.
  • macro_arguments - Sent to the called macro in the form of the macro.args special variable.

Location Requirements

The location can be one of the following:

  • TOKEN - The currently impersonated token (use the word TOKEN, not the token's name).
  • campaign
  • global
  • Lib:* Library Token - A Library Token in the current campaign.
  • this - If the macro is calling another macro on the same Library Token, this may be used instead of retyping the full Library Token name.

Notes

When a token macro calls another macro, the macro instructions in the called macro are executed against the calling token (in other words, the macro uses properties available on the calling token and applies all results to that token), unless the focus is explicitly changed to another token via either a roll option, or the switchToken() function, or the getLibProperty() function within the called macro. This applies even if the Current Token was explicitly changed prior to using the [macro():] roll option.

Also- as of at least 1.3.b50- a variable must be given for macro_arguments, or the "Could not execute the command: Undefined function: MACRO" error will result. However, the variable given as macro_arguments doesn't have to be used, and can be set to an empty string ("").

This roll option may not interact with other roll options the way you expect. For example:

[if(Condition),MACRO("getDamage@Lib:combat"): damageRoll]

getDamage gets executed regardless of the value of Condition. However, if Condition is not true, the arguments to the macro will be empty instead of containing damageRoll. You probably want:

[if(Condition): evalMacro('[MACRO("getDamage@Lib:combat"): damageRoll]')]

If multiple macros with the exact same name exist in the same location, this roll option will call the first created macro, regardless of its group location on the Token. Renaming the macro will not change its creation order, but moving it to a different token and moving it back, or deleting and recreating it, will.

Example

[MACRO("getDamage@Lib:combat"): damageRoll]

Calls the macro getDamage which resides on a Library Token called Lib:combat, and passes the variable damageRoll as an argument to the called macro.

Passing multiple arguments to a called macro

Note that only one variable can be passed to the called macro. To pass multiple values, you must "package" them into a format that can be stored in a single variable to be passed to the called macro, and then unpackaged appropriately to recover local variables used in the called macro. JSON Objects and JSON Arrays work very well for this purpose (although string lists and StrProps can also serve this purpose, they have more limitations and are less recommended). For example, multiple values can be stored into a json array, which becomes the argument passed in the macro call:

Using a JSON Array to pass multiple values (order matters, names do not)

[ variable1 = "hello" ]
[ variable2 = "world" ]
[ passedVars = json.append( "", variable1, variable2 )] <!-- package up variables into a json array to be passed to called macro -->
[MACRO("calledMacro@this"): passedVars ] <!-- macro call, with values being passed -->
[ resultVar = macro.return ]  <!-- this is what you get back from the called macro -->

Within the "called macro", the macro.args (macro arguments) must be unpackaged to recover the values stored in the array:

[ var1 = json.get( macro.args, 0 )]
[ var2 = json.get( macro.args, 1 )]
<!-- do stuff with your new variables -->
[ macro.return = var1 +" "+ var2 ] <!-- this is what you can send back to the calling macro (can also be another JSON Object or array -->

Note that using a JSON Array to pass & unpack values, rather than a JSON Object, has the added advantage that if the called macro is also a user defined function (see defineFunction), the exact same commands given in the example above can be used to separate individual arguments passed in the calling "function", since function arguments are automatically bundled into a JSON Array and passed to the macro.args special variable.

Using a JSON Object to pass multiple values (names matter, order does not)

[ variable1 = "hello" ]
[ variable2 = "world" ]
[ passedVars = json.set( "{}", "variable2", variable2, "variable1", variable1 )] <!-- package up variables into a json array to be passed to called macro.  Note that the order here does not matter, but the labels in quotes are needed to be able to retrieve the correct values in the called macro -->
[MACRO("calledMacro@this"): passedVars ] <!-- macro call, with values being passed -->
[ resultVar = macro.return ]  <!-- this is what you get back from the called macro -->

Within the "called macro", the macro.args (macro arguments) must be unpackaged to recover the values stored in the array:

[ var1 = json.get( macro.args, "variable1" )]<!-- actually the second label / value pair in the object --> 
[ var2 = json.get( macro.args, "variable2" )]<!-- the order does not matter, but the label must be accurate to retrieve the correct value -->
<!-- do stuff with your new variables -->
[ macro.return = var1 +" "+ var2 ] <!-- this is what you can send back to the calling macro (can also be another JSON Object or array -->

See Also

macro.args, macro.return, defineFunction, More Branching Options