Ok, so you made your first script. Only 3 lines long nice and sweet. However - there are some issues with this script. Most notably, ANY creature wondering in to the trigger is going to get jumped to the inside of your chest. This is ok if that is what you want, but we want it to only work if a Player enters the trigger. This is were conditions come into play. By definition Condition is nothing more that a specific decision made by the script based on specific information that your as a scripted give it. A condition is nothing more than "IF" this, then do that. For example, If it rains, take an umbrella.
Conditionals, part 1:
if/else, while, switch/case, for, do, continue, and break statements are all forms of conditionals. I will cover the rest later, for now I will only talk about the if/else statement.
The if/else syntax is as follows;
if(condition)
{
// do this scope
}
else
{
// do that scope
}
The workings of an if condition is simple. Basically it reads "if( this condition is TRUE), do this scope, else do that scope. Note: the "scope" referred to is the lines between the curly brackets - remember those open and close a "scope". Note that there is not a semi- colon after a if statement. This is because it is not the end of a function call. The end of a function depends on if the statement results in TRUE or FALSE so the script must first equate the condition before executing a function.
A lot of times you will see just an if statement with no else statement. This is perfectly OK. The only reason you would need an else is if you want to do one thing if a condition is TRUE and another if the condition is FALSE, and a third (or nothing at all) if it is neither TRUE or FALSE. Mostly, the else is used in conjunction with another if statement or "else if". This allows you to string a bunch of if statements together. More on that in an advanced topic later on in these tutorials. For now, lets concentrate on just the if statement.
The if statement simply tells the script if a condition is TRUE or FALSE, this result is called Boolean logic. In the Boolean world, FALSE equals 0 and TRUE equals anything NOT FALSE. A boolean condition is generally used with only integer values. For example, lest say that the variable iN equals 3. If we build a condition like this;
if(iN)
{
// do this
}
The result will be TRUE because the boolean condition doesn't care what value iN holds - just as long as it's not FALSE. If the variable iN was 0 or INVALID, the result would have been FALSE. But what if we want to check the value of a string, or even an object? This is where an if statement becomes a comparison condition. A comparison condition checks to see if the value of one variable matches, or is equal to (greater than, less than or not equal) the value of another variable or given value. For example, lets say we want to know if the string variable nB is equal to "HELLO".
if(nB == "HELLO")
{
// do this scope
}
Notice the double equal sign. A single equal sign means "equals" a double equal sign means "is equal to".
int A = 2; // A "equals" 2
if(A == 2) // if A "is equal to" 2
See the difference? This is a Logical Comparison, where 2 values are compared with each other. Note: anytime a single equal sign is used in a condition the result will always be TRUE. So when making comparisons we must use the following;
== "is equal to"
!= "is NOT equal to"
>= "greater than or equal to"
<= "less than or equal to"
> "greater than"
> "less than"
The one thing I want to bring your attention to here is the "!", This means NOT. I call it a "flipper" because it "flips" the outcome of the condition. For example, lets say the variable iN equals 1.
if(iN == 1)
{
// The result is TRUE
}
if(iN != 1)
{
// The result is FALSE
}
There is a small difference between the boolean if condition and the comparison if condition - otherwise the operation is the same but I feel it is worth mentioning. In the boolean condition above, I stated that the value of the variable iN is 3. So in boolean condition,
if(iN)
{
// do this
}
The result is TRUE. however in a comparison condition,
if(iN == TRUE)
{
// do this
}
The result is FALSE. This is because in NWN script, the constant value of FALSE is defined as 0 and the constant value of TRUE is defined as 1. Because the variable iN equals 3, the comparison of iN == TRUE is FALSE because iN is 3 and TRUE is 1. We are comparing the value of iN to the value of TRUE. This is not the same as the boolean TRUE and FALSE mentioned above. Very seldom will this be a problem, but it is something to be aware of.
When an if condition results in TRUE, the very next single line of code will be executed. If the condition results in FALSE, the very next single line is skipped. So this;
if(iN)
{
// do this
}
and this;
if(iN)
// do this
are identical. A lot of times we will want more than one line of code, this is when we must open a new scope. If the condition is TRUE everything inside the new scope will be executed, if it results in FALSE, everything inside the new scope will be skipped. Until you become a better scripter, I suggest always opening a new scope after a if condition. Not only will it help you keep your script organized for better debugging, it will prevent you from pulling your hair out wondering why something keeps happening when you think it shouldn't. This goes for the else statement as well.
The else statement is pretty much the same as an if statement except that it executes only if the preceding if statement is FALSE.
if(iN)
{
// do this if TRUE
}
else
{
// do that if FALSE
}
That's the basics of it, I'll cover more on the if/else later as we advance through the tutorial. Now it's time to get back into our script. Open the toolset and load your tutorial_1 mod. Before doing anything else, go to "File > Save As" and save the mod as "tutorial_2". This way if anything goes wrong you can simply back up to the previous tutorial instead of starting from scratch.
Go to the scripts palette and double click the script we made previously, "t_ent_chestgrabber". It should open up into the script editor. We want to add a line to make sure oEnter is a Player. Again, to find a function suited for this we can click in the script filter and enter the word "PC". You will have a few options, but by looking at the notes for each, we can see that the "GetIsPC" function is the one we want. We want to place it after the variable definitions. Lets also add a comment, so enter a blank line after your variables and add the comment "// Check for a Player". Also notice that in the notes for this function, it returns a "int" data type, FALSE if the specified object is not a Player Character and TRUE if the specified object is a Player Character.
Looking back at the syntax for the if statement, we need "if" (obviously) and then a condition between two parenthesis. so type in "if" then open "(" then close ")" and now enter GetIsPC between those parenthesis. For this function we also need a object. In this case the oEnter object, so again after you enter "GetIsPC" open "(" then close ")" and then type "oEnter" between them. Your line should look like this;
if(GetIsPC(oEnter))
After you hit the Enter key, hit the TAB key to indent and then open a new scope with a "{" curly bracket. This is where we will place what we want to happen if the if statement results in TRUE. We already have what we want to happen, that's the "JumpToObject" part so we just need to close our new scope after that section with a "}" curly bracket. Your whole script should look like this;
void main()
{
// Declare Variables
object oEnter = GetEnteringObject();
object oWP = GetObjectByTag("WP_INSIDE_CHEST");
// Check for Player
if(GetIsPC(oEnter))
{
//AssignCommand oEnter to Jump
AssignCommand(oEnter,JumpToObject(oWP));
}
}
There are 2 ways you can use the if statement here, by boolean - check for TRUE or FALSE, or by comparison - Check the value of the function to the value of TRUE. The script above is a boolean condition. The function GetIsPC returns a TRUE or FALSE to the statement (As described in it's notes for that function), which results in either TRUE or FALSE. A Comparison condition would look like this;
if(GetIsPC(oEnter) == TRUE)
Here we actually compare the result of the function GetIsPC to the value of TRUE. If the function returns TRUE then they are equal and the if statement results to TRUE. If the comparison is not equal the result is FALSE. Either way is correct, use which ever way makes most sense to you. Personally, I prefer the boolean check myself.
Note really a big change here, but test out your script in game, it should work the same. As an exercise, place a NPC down and add some waypoints for the NPC to walk, making sure that the NPC must walk into the trigger of the chest. You should be able to watch the NPC walk around and not get ported in to the chest. In the next section we will add some animations to liven up our jumping PC.