MapTool macros: Improved tracking of encounter/daily powers

I’ve been having fun playing with my MapTool campaign file recently.  One of my latest improvements is to add actual tracking for encounter powers and daily powers so that the players can know which powers they’ve used and which are still available.

In an earlier post I described my addition of code to the encounter and daily power macros that would give the player an error message if they tried to use a power that had already been used.  The code is basically as follows:

[h, if(E1==0), CODE:
{[assert(1==0,add(“This power has already been expended.”),0)]
};{[h: E1=0]}
]

Each macro will need its own E1, E2, E3, Daily1, Daily2, Daily3, etc. property to modify and check.  This is nice, but the player only figures out that they can’t use the power again if they try to do so.  What would be even better? A visual cue to show the player that the power is gone.

Enter the MetaMacro!  I didn’t learn until recently that MapTool macros can change the macro button itself.  One of the simplest things to change is the background color of the button.  I want the button to turn dark gray after a power is used up, so:

[h: setMacroProps(getMacroButtonIndex(), “color=darkgray”) ]

This piece of code uses the setMacroProps function to set the color property to “darkgray”.  The setMacroProps function takes two arguments: the index number of the macro whose button you want to change, and then a string that says what property you want to change and what you want the new value to be.

I didn’t know that each macro on a token has an index number, but it’s true.  I’m not sure how they’re assigned (perhaps the order in which you create them).  Fortunately, there’s a function you can use to get MapTool to tell you the index number of the macro you’re currently running.  That’s the getMacroButtonIndex() function that you see above.  It takes no arguments, and it just gives you the index number of the button.  Perfect!

Witchfire has been expended; Otherwind Stride is still available

Next, I had to write some code to turn the buttons back to their original color when the character takes a short rest (encounter powers only) or an extended rest (both encounter and daily powers).  This ended up being quite a bit trickier, but I finally figured it out.

[h, foreach(currentMacroName, getMacros()), CODE:
{
[h, foreach(currentMacroIndex, getMacroIndexes(currentMacroName)), CODE:
{
[h: myProps=getMacroProps(currentMacroIndex)]
[h: currentButtonColor=getStrProp(myProps, “color”)]
[h: currentFontColor=getStrProp(myProps, “fontColor”)]
[h: encounterPower=if(currentFontColor==”red” || currentFontColor==”purple”, 1, 0)]
[h: changeThisButton=if(currentButtonColor==”darkgray” && encounterPower==1, 1, 0)]
[h, if(changeThisButton==1): setMacroProps(currentMacroIndex, “color=default”) ]
}]
}]

Okay, what’s going on here? This piece of code loops through every macro on the token (that’s the first line), gets the index number for that macro (that’s the third line, counting the curly bracket as line 2), then checks to see if that macro needs to have its color changed.  That involves getting a string containing all of the properties for the macro (getMacroProps(currentMacroIndex)) and extracting the button color and font color for that macro.

In my campaign, the buttons for attack macros and special abilities use the default color for their background and a color-coded system for the text (green for at-will powers, red for encounter powers, purple for twice-per-encounter powers and blue for daily powers).  The short rest macro only resets encounter and twice-per-encounter powers, so it checks to see if the button is currently dark gray (expended) and the font is red or purple.  If so, it changes the color back to the default.  Otherwise, such as with a daily power, it leaves the button alone.

The same piece of code for extended rests looks like this:

[h, foreach(currentMacroName, getMacros()), CODE:
{
[h, foreach(currentMacroIndex, getMacroIndexes(currentMacroName)), CODE:
{
[h: myProps=getMacroProps(currentMacroIndex)]
[h: currentButtonColor=getStrProp(myProps, “color”)]
[h: currentFontColor=getStrProp(myProps, “fontColor”)]
[h: encounterOrDaily=if(currentFontColor==”red” || currentFontColor==”blue” || currentFontColor==”purple”, 1, 0)]
[h: changeThisButton=if(currentButtonColor==”darkgray” && encounterOrDaily==1, 1, 0)]
[h, if(changeThisButton==1): setMacroProps(currentMacroIndex, “color=default”) ]
}]
}]

Pretty much the same thing, except now it looks for fonts that are red, purple OR blue.

By the way, I’m aware that there are complete campaign frameworks out there, such as Rumble’s, and I’ve talked about them in an earlier post.  They’re great and very cool and they do everything that my code does and more.  But I write macros for the joy of it, and I love to learn about the language of MapTool.  My posts are intended to help other do-it-yourselfers out there who want to write their own code because they enjoy it.  If this isn’t for you, I highly recommend using a pre-packaged campaign framework – they’re quite slick!

In future posts I’ll talk more about my Short Rest and Extended Rest macros, and the concurrent improvements I’ve made to the healing macro.  Please let me know if there are particular macros that you’d like to hear about!

Leave a Reply