Use of if… elseif conditions
If (condition)
Elseif (condition)
Else
Endif
Much of TES scripting relies on the use of if… elseif conditions and variations thereof. It is very important to fully understand these, and the conditions that can be used in them to test conditions of the game world to trigger events.
In general a condition is "true" when it has the value of 1 (or simply "not 0" (e.g. -1 is "true" in TES Script too) and "false" when the value is 0. There are thus certain functions in the game that return "true" under certain conditions. For example see the GetAIPackageDone function further down. It returns "true" (= 1) for one frame when an AIPackage has finished. All lines of code between the if-statement and endif (which concludes a so-called "if block") will be executed only when the condition is true.
Thus:
If ( GetAIPackageDone )
;[do something here]
endif
will be only executed when the GetAIPackageDone function currently returns the value 1.
In addition to just a value, a condition can also be a more explicit test of conditions. The conditions, such as "A equals B" or "A is greater than B" will be evaluated, and the whole expression will be true (equals 1) when the condition is fulfilled. E.g.:
if ( GetAIPackageDone == 1 )
;[do something here]
endif
Is equivalent to the example above. This second syntax tests a condition and returns "true" if the condition is met. You can check for the following conditions:
Verbose Conditional operator
"Equal to":
==
"not equal to"
!=
"Greater than"
>
"Smaller than"
<
"Greater than or equal to"
>=
"Smaller than or equal to"
<=
If you have several independent if blocks each will be evaluated separately. If, e.g. the following if blocks are in your script:
if ( timer >= 2 )
;[Block A,do something here]
endif
if ( timer <= 3 )
;[Block B, do something else here]
endif
Both will be true and the code in the blocks will be executed when timer is between 2 and 3.
You can nest if-blocks if you want to make sure that two conditions are fulfilled simultaneously:
if ( timer >= 2 )
if ( controlvar == 0
;[do something here]
endif
endif
The code in the inner if block will only be executed when both conditions (timer >= 2 and controlvar == 0 ) are fulfilled at the same time.
For more elaborate constructions you can use Else and Elseif. Elseif tests for a separate condition if the preceding condition has failed (but not if the previous condition was fulfilled)
if ( timer >= 2 )
;[Block A,do something here]
elseif ( timer <= 3 )
; [Block B, do something else here]
endif
unlike the example above, both blocks can not be true at the same time now. Either timer is >= 2, then block A gets executed, or timer is not >= 2 but <= 3, meaning effectively timer is < 2, then block B gets executed. In all other cases, neither block will be executed. You can have several elseifs behind each other:
if ( counter == 1 )
;[Block A,do something here]
elseif ( counter == 2 )
; [Block B, do something else here]
elseif ( counter == 3 )
; [Block C, do something else here]
endif
An else creates a "default condition". The code following else will be executed if all previously tested conditions are false:
If ( foo_var == 1 )
[Block A: do something]
elseif ( foo_var == 2 )
[Block B: do something else]
else
[Block C: do something completely different]
endif
In this example Block C will be executed it foo_var is neither 1 nor 2.
Notes and cautions:
In my experience it is safest to use elseif instead of multiple separate if statements if you test different states of one variable.
Be careful using a function in a conditional ('If' statement); simple functions seem to be OK, but ones with numeric parameters don't seem to be reliable.
For example:
"If ( NewType != OldType )" worked correctly, but "If ( ( Player->GetArmorType 0 ) != OldType )" always registered as 'Not equal', even if the variable 'OldType' had the same value as the armor type that should have been returned by 'Get ArmorType 0' function.
So use "Set NewType to ( Player->GetArmorType 0 )", followed by a separate 'If' statement to compare 'NewType' to 'OldType'. -(DinkumThinkum)