More MapTool macro fun! Yes, I’m a nerd and proud of it.
In a game like Dungeons and Dragons 4th Edition, it’s pretty common to get temporary bonuses to attack rolls or defenses. When you’re playing with pen and paper, you have to keep track of these yourself. When you’re using MapTool, the program can help.
Now, I’m sure that some of the snazzier MapTool frameworks out there will handle temporary modifiers in super-fancy ways that actually change the calculation of attacks based on these modifiers and so on. I’m not looking for any of that. I’m simply looking for a visible reminder on a token that it has a temporary bonus or penalty.
I started creating +2 attack and-5 attack and +2 defense states in a piecemeal manner months ago. As PCs and monsters in my games started getting powers that could apply these bonuses or penalties, I created states that would remind me of them. I would then turn these states on and off very manually – right click on the token, find the right state, click on it. Repeat to turn it off.
Well, I’m sick of that, so I decided to automate the process.
First, I created a set of 20 token states: +1 to +5 attack, -1 to -5 attack, +1 to +5 defense and -1 to -5 defense. They look something like this:
Depending on whether I’m using MapTool online or with my projector setup, I either display these states as 3×3 grid images (online) or 2×2 grid images (projector – the larger images show up better). The red boxes are for attack (or damage) and the blue boxes are for defenses. I use 80% opacity, so you can still make out a little of the token art behind the states.
For a while, I was creating individual toggle buttons for my states. Click a token, then click the “+2 Attack” button, and the +2 Attack state will toggle on or off. Now that I have 20 of these states, I decided to streamline. Rather than 20 buttons, I have two: One to set attack modifiers and one to set defense modifiers.
Attack bonus macro (download the macro)
[h: x=input("NewMod|0|What is the token's new attack modifier?")] [h: abort(x)]
I start by asking for the new attack modifier in a pop-up; if the user clicks the Cancel button, the macro ends. Note that the user can specify a +2 bonus as either “2” or “+2”; the macro works either way.
[h: SelectedTokens=getSelected()] [FOREACH(TokenID, SelectedTokens, " "), CODE:
I create a list of token IDs called SelectedTokens for however many tokens are currently selected, and then I loop through each of these tokens to perform the same code on them. This lets me apply (or remove) a bonus or penalty to a bunch of tokens at once.
{[if(NewMod>5 || NewMod<-5), CODE: {[assert(1==0,add("<b>Error</b>: Attack modifier must be between -5 and +5"),0)]}; {}]
I throw off an error message if the user tries to enter a number over 5 or under -5, since that’s the range of states I’ve created.
[h: OldMod=getProperty("AttackState",TokenID)] [h: OldState=if(OldMod>=0, add("+", OldMod, " Attack"), add(OldMod, " Attack"))] [h: NewState=if(NewMod>=0, add("+", NewMod, " Attack"), add(NewMod, " Attack"))]
I figure out what the current value of the token’s AttackState property is (a number from -5 to 5), and then convert this to a string like “+2 Attack” or “-3 Attack”. This corresponds to the names of the states in my campaign file. I do the same for the new attack modifier, getting the appropriate state name.
[h, if(OldMod==0), CODE:{}; {[h: setState(OldState,0,TokenID)]} ] [h, if(NewMod==0), CODE:{}; {[h: setState(NewState,1,TokenID)]} ]
If the new or old modifier is zero, I don’t try to change it (since no state is displayed on the token for a zero bonus). Otherwise, I turn off the old state (setting it to false, or 0) and turn on the new state (setting it to true, or 1).
[h: setProperty("AttackState", NewMod, TokenID)] } ]
I set the value of the AttackState property to whatever the user entered, so that the macro can reference that property the next time it’s run. I then close the CODE block and the FOREACH loop that I started at the top. Voila!
The whole macro is as follows:
[h: x=input("NewMod|0|What is the token's new attack modifier?")] [h: abort(x)] [h: SelectedTokens=getSelected()] [FOREACH(TokenID, SelectedTokens, " "), CODE: {[if(NewMod>5 || NewMod<-5), CODE: {[assert(1==0,add("<b>Error</b>: Attack modifier must be between -5 and +5"),0)]}; {}] [h: OldMod=getProperty("AttackState",TokenID)] [h: OldState=if(OldMod>=0, add("+", OldMod, " Attack"), add(OldMod, " Attack"))] [h: NewState=if(NewMod>=0, add("+", NewMod, " Attack"), add(NewMod, " Attack"))] [h, if(OldMod==0), CODE:{}; {[h: setState(OldState,0,TokenID)]} ] [h, if(NewMod==0), CODE:{}; {[h: setState(NewState,1,TokenID)]} ] [h: setProperty("AttackState", NewMod, TokenID)] } ]
Defense bonus macro (download the macro)
The defense macro is exactly the same as the attack macro – just replace “Attack” with “Defense”.
[h: x=input("NewMod|0|What is the token's new defense modifier?")] [h: abort(x)] [h: SelectedTokens=getSelected()] [FOREACH(TokenID, SelectedTokens, " "), CODE: {[if(NewMod>5 || NewMod<-5), CODE: {[assert(1==0,add("<b>Error</b>: Defense modifier must be between -5 and +5"),0)]}; {}] [h: OldMod=getProperty("DefenseState",TokenID)] [h: OldState=if(OldMod>=0, add("+", OldMod, " Defense"), add(OldMod, " Defense"))] [h: NewState=if(NewMod>=0, add("+", NewMod, " Defense"), add(NewMod, " Defense"))] [h, if(OldMod==0), CODE:{}; {[h: setState(OldState,0,TokenID)]} ] [h, if(NewMod==0), CODE:{}; {[h: setState(NewState,1,TokenID)]} ] [h: setProperty("DefenseState", NewMod, TokenID)] } ]
I hope this type of macro is useful for folks out there. As always, let me know if you have questions about my macros or requests for new macros. I love this kind of thing, as you can no doubt tell!
Note: All macros were generated with version 1.3.b66 of MapTool, but they work with 1.2.b86 as well.
Download the properties for online games with these states
Download the properties for projector games with these states