18,700
edits
m (→Returning: using strong syntax for "return"; wording) |
(→Conditional: adding "else if"; mentioning optional braces for one-line conditional blocks) |
||
Line 136: | Line 136: | ||
if (7 - 8) # evaluates to true because it is non-zero | if (7 - 8) # evaluates to true because it is non-zero | ||
Braces are optional when you only have one line of code under the "if" (this is also true for "else" and "else if", discussed below): | |||
The logical operators "and" and "or" | if (a > 0) | ||
spawn_enemy_at_flag(a); | |||
spawn_considered = true; | |||
Here, "spawn_considered" will be set to true regardless of whether the "if" condition was true and spawn_enemy_at_flag() was run. Though it's nice to save the vertical space, the danger in omitting braces is writing something like this: | |||
if (a > 0) | |||
spawn_enemy_at_flag(a); | |||
spawn_considered = true; | |||
That indentation on "spawn_considered" is misleading; when glancing at this code, you might expect that "spawn_considered" only is changed if "a" is greater than zero. It could be that you even intended to add that line to the "if" statement but forgot to add braces. Always using braces around an "if" statement's body will prevent that mistake. | |||
Be aware that, even ''with'' braces, BSL does not always respect scope for blocks of code under "if" statements; for instance, a "return" statement will fire even if the surrounding "if" condition is false (see [[#Flow interrupt|Flow interrupt]] for an example). According to a note in neuro_level_logic.bsl, this may happen for variable assignments too. The workaround Bungie West used in that script for setting a variable conditionally was to make the variable global, and under the "if" statement call a function that modified that variable, since function calls will not fire unless the "if" condition is true. | |||
One very handy feature that you also won't see being used in Oni's game scripts is that you can use the logical operators "and" and "or" to string together multiple conditions: | |||
if ((a < b) and (c > d)) | if ((a < b) and (c > d)) | ||
Line 160: | Line 174: | ||
Though "else" is not used in Oni's existing BSL scripts, it seems to work fine. | Though "else" is not used in Oni's existing BSL scripts, it seems to work fine. | ||
====else if==== | |||
As is common in other programming languages, you can also specify an "if" condition that should only be evaluated if the previous condition was false, by writing "else if": | |||
if (error eq 0) | |||
dprint("Everything is fine."); | |||
else if (error eq 1) | |||
dprint("There are too many enemies to add one more."); | |||
else # handle all other possibilities | |||
dprint("Unknown error code!"); | |||
Often, programmers only use "else if" statements to save some CPU cycles. For instance, if you had a long string of "if" statements to handle different possible values for a variable, why should they all be evaluated once you have already found the one that is true? Imagine the above example, but with 30 possible values for "error". In reality, you won't find much benefit in trying to save cycles with BSL. However, "else if" can also simplify logic: | |||
if (d eq 0) | |||
... | |||
if (d eq 1) | |||
... | |||
if ((n eq d) and (n > 0) and (d > 1)) | |||
... | |||
if ((n eq 0) and (d > 1)) | |||
... | |||
In checking the condition of "n" and "d" in this example, we have to keep checking after the second statement whether "d" is greater than 1; otherwise, multiple "if" statements could evaluate to true and execute their code, but we only want to act on one of these possible situations. Using "else if" allows us to be confident that only one statement can run: | |||
if (d eq 0) | |||
... | |||
else if (d eq 1) | |||
... | |||
else if (n eq d) | |||
... | |||
else if (n eq 0) | |||
... | |||
Notice how we can shorten the logical tests without losing anything. "d" is still implicitly required to be above zero in statements 2-4, or else they will not even be evaluated. | |||
===Flow interrupt=== | ===Flow interrupt=== |