A suggestion from Benoit (who, based on this blog post, seems to be the person behind Roving Band of Misfits) prompted me to start a mailbag series. Welcome to issue #1! I’d love to get more mailbag questions, so if you have an issue you’d like to see me address, please drop me a line at onlinedungeonmaster@gmail.com.
Question from Benoit:
I have a lot of trouble with simple “If” statements. I found a few examples in the forums, but I can’t seem to write my own.
Answer from OnlineDM:
Thanks for the question, Benoit! IF statements are an important part of most programming languages, including MapTool. Let’s do some examples
Concept #1: There are two different IF statements in MapTool
MapTool is a bit of an odd language in that you can have two different structures for the same thing. An IF statement, for instance, can either be a roll option or a function.
IF statement roll option
A roll option comes “before the colon” in MapTool macros. One common roll option is h: which causes the result of the line of code to be hidden (useful for assigning a value of a variable without printing anything to the chat window).
The syntax for an IF statement roll option is:
- [if(Foo>Bar): Thing you do if Foo is greater than Bar; Thing you do if Foo is not greater than Bar]
For instance, here’s a very simple two-line macro
[h: Variable=InputVariable] [if(Variable>10): "The variable is greater than ten"; "The variable is not greater than ten"]
The first line brings up an input box that asks the user to type in a number, which is assigned to Variable. The second line uses the IF roll option to see if Variable > 10 and then displays the appropriate message.
Note that you don’t have to specify the “if not” part of this second line if you don’t want to. If I want to display a message if Variable>10 but do nothing otherwise:
[h: Variable=InputVariable] [if(Variable>10): "The variable is greater than ten"]
In this particular case, I’d output a blank line to the chat window if Variable is less than or equal to ten. This is more useful in cases where I’m doing things behind the scenes that are hidden rather than outputting them to the chat window.
Note that if you have another roll option you want to use at the same time as the IF roll option (such as the h: roll option to make the output hidden), you’ll put that other roll option before the IF statement, separated by a comma:
[h: Variable=InputVariable] [h, if(Variable>10): "The chat window won't actually display this because I used the h roll option, too!"]
If you want to do just one thing in the case where a particular condition is true, the simple IF roll option is a good way to do it.
The IF roll option with the CODE roll option
What if you want to do multiple things if a particular condition is true? Then you want to use the CODE roll option alongside the IF roll option.
[h: Variable=InputVariable] [if(Variable>10), CODE: { Can you believe the variable is greater than 10? [h: DoubleVariable=Variable*2] And if you double the variable, you get [DoubleVariable]! }; { What do you know? The variable is not greater than 10. [h: HalfVariable=Variable/2] And if you cut the variable in half, you get [HalfVariable]. } ]
Now instead of just doing one thing when a particular condition is true, I can do several. I accomplish this by sticking the CODE statement after the IF statement (separated by a comma) and then the colon. Then I have the code to execute for the “true” case of the IF statement enclosed in curly braces, followed by a semicolon and then the code to execute for the “false” case of the IF statement inside another set of curly braces.
I can do as much stuff as I like within those curly braces. Note that once I’m in curly braces, it’s just like being outside of square brackets. Text typed normally will be printed straight to the chat window, and any code I want to execute (such as assigning variables or printing their values) is enclosed in square brackets. I can even do more IF statements and CODE blocks inside these curly braces if I need to (though you can only go two layers of curly braces deep in MapTool).
The IF function
The other way to test a condition using an IF statement is to use the IF function. Functions in MapTool come “after the colon”.
[h: Variable=InputVariable] [h: NewVariable=if(Variable>10, Variable*2, Variable/2)] The new variable is [NewVariable].
In this example, the IF statement comes after the colon. I’m specifically using the IF function here to assign the value of a new variable, conditional on an existing variable. The syntax is completely different:
- [NewFoo = IF(Foo>Bar, Value of NewFoo if Foo is greater than Bar, Value of NewFoo if Foo is not greater than Bar)]
You’ll note that now the “what to do” part for both the true and false cases are within the parentheses of the IF statement instead of outside the parentheses as they were for the IF roll option. They’re separated from the condition being tested by a comma (instead of a closed parenthesis and colon as in the roll option), and the “true” and “false” options are separated from one another by a comma as well (instead of a semicolon as in the roll option).
There’s no way to use CODE blocks here. So far in my own MapTool programming, I’ve only used the IF function for the particular purpose of assigning the value of a variable or other very simple tasks. I use the IF roll option much more frequently.
Concept #2: How to test conditions
I’ll wrap up with some notes on syntax. The syntax to check whether Foo is greater than Bar, Foo is less than Bar, Foo is greater than or equal to Bar and Foo is less than or equal to Bar is all exactly what you would expect:
[If(Foo>Bar): ... ] [If(Foo<Bar): ... ] [If(Foo>=Bar): ... ] [If(Foo<=Bar): ... ]
Less obvious is how to check whether Foo is not equal to Bar – you use an exclamation point followed by an equals sign:
[If(Foo!=Bar): ... ]
The worst of all comes on the check you’ll likely use most often: Seeing whether Foo is equal to Bar. For this, you need to use a double equals sign:
[If(Foo==Bar): ... ]
If you try what you’ll no doubt try at some point [if(Foo=Bar):…], you’ll get an error message from MapTool.
I’ll also note that you might want to check to see whether a variable is equal to a particular string (some text rather than a number). In that case, you need to make sure the value you’re checking for is enclosed in quotes.
[h: Variable=FavoriteColor] [if(Variable=="Blue"): "My favorite color is blue, too!"; "I see. Well, I prefer blue."]
Note the syntax. First, I’m using the IF roll option (before the colon), not the function. Second, I’m using the double equals sign to check for equality. Third, I’m enclosing “Blue” in quotes to see if that’s what’s been entered for Variable. If I enter Red or Nothing or 75 into the input box, I’ll get a message in the chat window saying “I see. Well, I prefer blue.” But if I enter Blue into the input box, I’ll get a message in the chat window saying “My favorite color is blue, too!”
If I forget the quotes around the word Blue in parentheses, I’ll get a second input box asking me for the value of Blue. MapTool will think that Blue is a variable that I haven’t assigned a value to, instead of a string that I want to check Variable against.
Wrap-up
Well Benoit, I hope you found this to be helpful! MapTool is a bit of a wonky language, but it can get you where you need to go most of the time. Understanding the ins and outs of the IF roll option and the IF function will take you a long way.
Remember everyone, send me your future mailbag questions at onlinedungeonmaster@gmail.com.
-Michael the OnlineDM
Pingback: Links of the Week: November 28, 2011 | KJD-IMC - KJDavies "In My Campaign" Articles