-
Notifications
You must be signed in to change notification settings - Fork 5
Tutorial 2.1. If and else
Checking for certain conditions is fundamental for any programming language. So far we can do this with the command block modifiers conditional and invert. For more convenience MPL also supports if- and else-expressions. The syntax looks like this:
if: /testfor ...
then {
/say then part
/multiple commands are allowed here
} else {
/say else part
/multiple commands are allowed here
}
You can invert the condition like this:
if not: /testfor ...
then {
// ...
}
The then and else parts may contain any expressions like start, stop and while. Nested if statements are allowed too.
The main advantage of if over the conditional and invert modifiers is that several commands can savely depend on one condition. If you use a series of conditional commands you are at the risk of failing due to side effects. To better understand this risk look at the following program:
install {
/scoreboard objectives add ZombieKills stat.killEntity.Zombie
}
uninstall {
/scoreboard objectives remove ZombieKills
}
// start: /execute @e[name=startZombieGame] ~ ~ ~ setblock ~ ~ ~ redstone_block
impulse process startZombieGame {
/say starting new zombie challenge
/execute @a ~ ~ ~ summon Zombie
/scoreboard players reset @a ZombieKills
testForWinner()
/say the winner is @p[score_ZombieKills_min=1]
}
repeat process testForWinner {
/testfor @p[score_ZombieKills_min=1]
conditional: /kill @e[type=Zombie]
// if no zombies were killed by the previous command, this process will not stop
conditional: notify testForWinner
conditional: stop
}
This program will start a game with the goal to kill a zombie. After printing out a start message the program summons a zombie at every player. The player that kills its zombie the fastest wins. This program works fine in multiplayer, but it does not work in singleplayer. The problem is, that the command /kill @e[type=Zombie]
, which is supposed to clean up the zombies of the loosing players, fails if there is no zombie left. In singleplayer only one zombie is summoned, so once the player kills it to win the game the kill command will fail and the two following conditional commands will not be executed.
When using an if expression this does not happen, because every command in the then part only depends on the condition, not on the previous command. You can still make the commands in the then part conditional or invert if you want that behaviour.
The correct way to implement the testForWinner
process looks like this:
repeat process testForWinner {
if: /testfor @p[score_ZombieKills_min=1]
then {
/kill @e[type=Zombie]
notify testForWinner
stop
}
}
By the way, the following implementation behaves exactly like the original incorrect one:
repeat process testForWinner {
if: /testfor @p[score_ZombieKills_min=1]
then {
/kill @e[type=Zombie]
conditional: notify testForWinner
conditional: stop
}
}
Now that we know all about if expressions it's time to look at another fundamental language feature. Continue with Tutorial 2.2. Loops.