You are here

Function Junction (Includes & Functions Tutorial)

Author: 
Genisys / Guile
Old Vault Category: 
other

What's your major mal function private!?!  Um... Include sir, INCLUDES!  Like what in the 9 hells is an include?  Well, it's quite simply a script that doesn't have a void main, where functions & prototypes are stored to referrence in other scripts (Or even other includes) by including them in a script that has a void main() {}, Let's look at an example.

// ScriptName

#include "gen_inv_inc"

// Goes in the OnOpen event of a placeable / chest

void main(){

 object oPC = GetLastOpenedBy();

 object oMe = OBJECT_SELF; // The chest they just opened.

 if(GetHasInventory(oMe)){

  int nInvCount = GetMyDamnTotalInventnoryCount(oMe);

  SendMessageToPC(oPC, IntToString(nInvCount) + " Items are in your chest.");

 }

}

 

Of course #include "gen_inv_inc" is referrencing an include script that has functions in it, and the function GetMyDamnTotalInventnoryCount (Which is totally made up by the way), is a function that would be found in "gen_inv_inc" script...,  Let's look at the real "gen_inv_inc" include script for a moment and see what's in it.  Notice how it has #include "gen_colors_inc" in it as well, this is important, because everything in "gen_colors_inc" is now also accessible by the script above, because any time an include is put in any include, you must remember that functions inside of any include cannot be found in other includes, otherwise it will throw errors out in the compiler.

There is another important thing to remember about includes, if you are including an include script inside of an include script, the include script you include can NOT include the script you put the include in, for example if "gen_colors_inc" included "gen_inv_inc" the compiler would kick out a circular dependency error.  Also, constants in includes cannot be found in other includes that are included in your include, & generally speaking I don't think you should make constants of the same name in different scripts, it might cause issues later on.

Often you will see people name includes with suffixes of "_inc" or "include", but they also may use "_func" (Functions) or "_config" (Configuration Include) or "_const" (Constants), which are often used by multiple include scripts, for example "gen_const_colors" is included in "gen_colors_inc", this means it holds constants that will likely be used in combination with scripts that use "gen_colors_inc".

The first part of includes generally have declarations of prototypes / functions (Same thing), as you can see in "gen_inv_inc" it immediately starts listing the functions that are part of the include by declaring them outright. (See example immediately below)  Also, after all declarations, you'll find the defined functions for the declared functions below them...

// Counts all of the items the PC has equipped (Except the Skin/Hide)
 
int CountItemsWorn(object oPC);
 
Notice the // Comments above the declared prototype, which when the PC goes to type the function name in the list box of the functions tab to the right in the compiler, you will see the custom functions / prototypes Bolded, if they were declared in the included put in your main script, if not, then you won't see the function at all, and if the comments are directly above the declared function, then you will see the comments as well when you click on the function in the function list....

A function is anything that produces data, performs a scripted action, or returns a variable (Data), so then take a look at the int CountItemsWorn(object oPC); function and let's analyze it in depth...

Here we are simply inspecting each slot and ensuring that the item in that slot is valid, and if so, we are adding to the total items worn, this function may be handy to use in a script that needs to quickly loop through worn items multiple different times, or is needed to be known for some other function. This is not the most efficient way to code this, a for loop would have been better, but that's not the subject of this tutorial, it's about functions & includes...

int <<< Tells us what the function returns (In this case it gives us an integer of how many items are worn).  The Function name gave it away yeah?  Well, functions need to be named after what they do, e.g. object GetEquippedWeapon() would return the weapon in their right hand.  If a function uses variables e.g.  Function(Var1, Var2, Var3 = 12); remember that you can only assign data to a variable by default AFTER the varaiables that are NOT assigned data by default.  Furthermore, it's imperative to explain what those Variables MUST be...

If you look at the Bioware Function ItempropertyDamageBonus(....), you'll notice how it requires you to supply constant variables for varaible data input needed to run the function.

// Returns Item property damage bonus.  You must specify the damage type constant
// (IP_CONST_DAMAGETYPE_*) and the amount of damage constant(IP_CONST_DAMAGEBONUS_*).
// NOTE: not all the damage types will work, use only the following: Acid, Bludgeoning,
//       Cold, Electrical, Fire, Piercing, Slashing, Sonic.
 

itemproperty ItemPropertyDamageBonus(int nDamageType, int nDamage)

This function tells us what the itemproperty is exactly and what type of properties it gets, e.g. nDamageType & nDamage (Bonus), but we must supply the constants for those variables, e.g.,  ItemPropertyDamageBonus(IP_CONST_DAMAGETYPE_ACID, IP_CONST_DAMAGEBONUS_2D12) would be a solid example of usage, we supplied the data for the variables, no need to enter nDamageType = XXXXX at all, we just supply the data to the function so that it can work with said data.

As I explained in my Basic Scripting Tutorial, all varaibles are data types, whether an int, float, string, object, and those variables need to be defined with data.  A function returns data or performs an action generally, though it can do both, it's generally not recommended because function that gets the data may be used multiple times in a script, therefore causing the function to fire multiple times, and that could present a problem for you (the scripter) in testing.

One rock solid thing to remember aobut functions is, they can be declare before void main(), and then defined after void main() {  } ends, and what this does is tidy your script so that the person reading it can see that custom functions exist, but they want to get to the meat (the main script) and not the poatatoes (Functions) of the meal first.  If we put 4 functions above void main(), then they will have to scroll past all of the functions.

//----------------------------------------------------------------------------------

Also it's important to learn to separate functions with commented block lines... (See above), this way you can scroll faster to find functions, because reading 1,000+ line includes can get quite tedious if it horribly conjoined together with no separating lines spaces, or proper coding standards.  You dont' look like a smarter coder with horribly conjoined code blocks, you look like someone who wants to give people a headache (Jerk!). :D

I'll tell you first hand, I'm not a real programmer, but having had to learn NWScript from the ground up using the Lexicon & the old Lilac Soul's Script Generator, it took me a while before I got the hang of it and started making my own code.  Yes, writing code is the fastest way to learn, don't be afraid, but do learn how to make functions, for ultimately these things are DA BOMB!  What they can do for you is save you LOADS of time, imagine having to code something 2,000 times, when you could have simply made a short function MyFunction(object oObject, int nInt); to save your self having to write that long code 2,000 times!!!

Do you get the picture now?  Well, I hope this tutorial was helpful in some way, though it wasn't terribly in depth, you did at least get to examine a very high quality include script, and learn more about functions (somewhat) & some about includes as well, if you have any comments on this tutorial please post them below.  (I'm always willing to entertain constructive criticism)

Thanks for reading...

Genisys / Guile

 

Don't forget to Read NWScript Basics as well!

Migrate Wizard: 
First Release: 
  • up
    100%
  • down
    0%
NearEthereal

Thank you, this is exactly what I was looking for :)

  • up
    100%
  • down
    0%