Logical Operators/Truth Tests
Logical operators perform Boolean (TRUE/FALSE) comparisons on an expression. Since NWNScript does not support a strict Boolean data type, the result of a logical operation will be an int value of either FALSE (0) or TRUE (1).
Logical Operators
Symbol | Conditional |
---|---|
== | Equality test ("is equal to"). |
!= | Inequality test ("is not equal to"). |
< | Less than equality test. |
> | Greater than equality test. |
<= | Less than or equal to equality test. |
>= | Greater than or equal to equality test. |
&& | Short circuit logical AND. |
& | Bitwise AND. |
|| | Short circuit logical OR. |
| | Bitwise OR. |
! | Logical NOT. |
The following expressions all equate to TRUE or 1:
// data int nValue1 = 3; int nValue2 = 3; // expressions int bTest = nValue1 == nValue2; int bTest = nValue1 != 0; int bTest = (nValue1 == 3) && (nValue2 != 0); int bTest = (nValue1 == 3) || (nValue2 == 0);
The following examples all equate to FALSE or 0:
// data int nValue1 = 3; int nValue2 = 3; // expressions int bTest = nValue1 != nValue2; int bTest = nValue1 == 0; int bTest = (nValue1 == 3) && (nValue2 == 0); int bTest = (nValue1 != 3) || (nValue2 == 0);
One good use for logical operators is to test multiple expressions in a single if statement. This will prevent unnecessary nested if statements which make code difficult to follow, and in some cases slower.
The Logical NOT operator is an exception because it's a unary operator (only operates on a single expression):
int bRunning = TRUE; int bRunTest = !bRunning;
In this example bRunTest will equate to 0 or FALSE.
It should be noted that && and || are considered short-circuit operators: that is, in an && conditional the first condition to evaluate as FALSE from left-to-right stops evaluation of the remaining statements, and in an || conditional the first condition to evaluate as TRUE from left-to-right stops evaluation of the remaining statements. What does this mean? Suppose you had two functions and either function returns TRUE or FALSE:
int bFunction1() { // check to see if a specific item is in the player's inventory int bRet = FALSE; bRet = GetItemPossessedBy(OBJECT_SELF, "some_item"); PrintInteger(bRet); // out to the log file return bRet; } int bFunction2() { // moves the camera around SetCameraFacing(270.0f, CAMERA_TRANSITION_TYPE_SLOW); // returns TRUE for absolutely no reason return TRUE; }
bFunction2, above, has what is known as a side effect. That means that although it is a function, it also causes something else to happen as well. When we use a short circuit AND operator (&&)...
void main() { if (bFunction1() && bFunction2()) { // do something here } }
If OBJECT_SELF does not have the item "some_item" then bFunction2() will never be called, thus the camera angle will never change. Contrast that to the following:
void main() { if (bFunction1() & bFunction2()) { // do something } }
In this second example, the camera angle will be changed because we are not using a short circuit operator; the entire statement will be evaluated.
Don't get "==" confused with the assignment operator "="! Assigning a statement to a value always returns TRUE and is a common source of bugs in code.
int nNumber = 4; if (nNumber = 5) // assignment; assigns value and returns TRUE! { PrintInt(nNumber); } // this will print "5" to the log file because nNumber is assigned // the value of 5 during the "if" test // if (nNumber == 5) is what should really appear above
Finally because "==", "!=", "<", ">", "<=", and ">=" return TRUE or FALSE, you can use them for shortcuts when assigning values to boolean (TRUE/FALSE) integers. For example, the following code:
int nNumber = 3; int bCondition = FALSE; if (nNumber == 3) bCondition = TRUE; else bCondition = FALSE;
can become a single line of code:
int nNumber = 3; int bCondition = nNumber == 3;
author: Ryan Hunt, editors: Charles Feduke, Mistress, additional contributors: Bradley Beacham, ccaswell, Ken Cotterill