Creation/Dev/Using Classes Effectively: Difference between revisions

From Graal Bible
No edit summary
No edit summary
 
(6 intermediate revisions by 5 users not shown)
Line 1: Line 1:
[[Category:Scripting Reference]][[Category:Scripting Tutorials]]
Note: Code examples in this article use new engine scripting.
Note: Code examples in this article use new engine scripting.
= Why classes? =
= Why classes? =
== The idea ==
Classes are a very useful concept in Gscript. They allow many instances of the same code to be run and even dynamically placed. They are also an effective means of sharing functions between scripts. You can attach them to the player, too, where the player is treated as the current object.
Classes are a very useful concept in Gscript. They allow many instances of the same code to be run and even dynamically placed. They are also an effective means of sharing functions between other scripts. You can attach them to the player, too, where the player is treated as the current object.
== What this means ==
Increased efficiency and productivity!


= Using classes as standalone NPCs =
= Using classes as standalone NPCs =
== What this means ==
Objects, including NPCs from levels or database NPCs, can join a class. That class is then controlling the behaviour of the object. The class can so act either as level NPC, when being joined from a level NPC, or as database NPC, when joined from a database NPC. Many objects can join the same class, which is useful e.g. for ATMs.
Classes are capable of being "standalone", i.e. being treated like a level or database NPC. This makes it possible to create many copies of a single script. This could be useful for, say, ATM scripts.


When joined from a level, the class script is being included into the script of the level NPC that it is being joined from, therefore it acts as a level NPC. When joined
=== Joining from a level ===
from, say, a putnpc2 NPC, then it acts like a database NPC.
To let a level NPC join a class, simply create an NPC and put:
== Joining from a level ==
<pre>this.join("classname");</pre>
To join a class to a level NPC, simply create an NPC and put:
The NPC will then join the class once created. When updating a class with RC that is joined by level NPCs, you may have to update the level in order to see the update.
<pre>join("classname");</pre>
=== Joining using putnpc2 ===
== Joining using putnpc2 ==
To create a databased NPC, you can use the function putnpc2() on serverside:
To create a databased copy, you can use putnpc2 serverside:
<pre>putnpc2(x, y, "join(\"classname\");");</pre>
<pre>putnpc2(x, y, "join(\"classname\");");</pre>
... replacing x and y with coordinate values, or variable names containing these values.
... replacing x and y with coordinate values, or variable names containing these values. A putnpc2() NPC is called a "database NPC", being that it is databased in the NPC-Server, and does not belong to a specific level. Database NPCs usually receive updates when the script is updated with RC immediately. They can also warp to other levels.
== About database NPCs (putnpc2) ==
=== About database NPCs (including putnpc2 NPCs) ===
When you are finished with a DB NPC and want to destroy it, you should use destroy(); serverside.
When you are finished with a DB NPC and want to destroy it, you should use this.destroy(); serverside. The NPC will then be totally removed from memory. Note that the class will of course still remain on the server.


DB NPCs have unique identifiers, which can be read using this.name. This identifier can be used to locate the NPC on the serverside, like shown:
DB NPCs have unique identifiers, which can be read using this.name. This identifier can be used to locate the NPC on the serverside, like shown:
Line 28: Line 24:
}</pre>
}</pre>
<pre>findnpc(identifier).foo();</pre>
<pre>findnpc(identifier).foo();</pre>
This allows other scripts to interact with the database NPCs that you have placed. With the new scripting engine you can also access those npcs directly by using identifier.foo.
Like mentioned previously, database NPCs are not specific to one level, and such you can use the warpto() command to move the NPC into a new level:
<pre>this.warpto("levelname", x, y);</pre>
This enables great portability.
= Using classes to share functions =
= Using classes to share functions =
== What this means ==
If you write a set of functions that you wish to use in more than one NPC, then you can define them in a class, and let each npc join the class instead of copying the functions into each. It also means that you can update your functions across all your scripts, too.
If you write a set of functions that you wish to use in more than one NPC, then you can define them in a class, and join the class to each NPC instead of copying the functions into each. It also means that you can update your functions across all your scripts, too.
=== Define your functions ===
== Define your functions ==
Open up your class, and define your functions like you normally would!
Open up your class, and define your functions like you normally would!
<pre>function funcName(parameters)
<pre>function funcName(parameters)
Line 37: Line 38:
   // code
   // code
}</pre>
}</pre>
Then save your class.
Then save your class. This will provide these functions to any NPC that joins the class, and will allow you to easily update functions between several NPCs.
== Use your functions ==
=== Using your functions ===
Next, join the class to your NPCs:
Now, before you can use the functions in your other scripts, you must let the current NPC join the class. Like a level NPC, you use the following command:
<pre>join("classname");</pre>
<pre>this.join("classname");</pre>
... and use your functions!
Then, you can use your functions.
<pre>classname::funcName();</pre>
 
You can easily let an NPC join more than one class, for example:
<pre>this.join("classone");
this.join("classtwo");</pre>
However, this can cause problems where there is more than one function with the same name. You can specify which class you want to use the function from by using the :: operator. The :: tells the scripting engine to look in that specific class, like so:
<pre>classtwo::myFunction();</pre>
This means that you do not have to worry about using the same function name more than once. If function names are colliding, then the first function found will be used, which means either from the script of the npc itself or of the class joined first.
 
= Using "player classes" =
= Using "player classes" =
== What this means ==
Player classes are classes joined by players. A player-joined class treats the player as the current object (this.). Also, you can create functions available to other scripts through the player object, for example, creating a function that damages the player called doDamage() and then calling it from any script using:
Player classes are classes joined to the player. A player-joined class treats the player as the current object (this.). Also, you can create functions available to other scripts through the player object.
<pre>player.doDamage();</pre>
== Join the class ==
This allows the player to be treated easier using different functions.
You can join the class to the player on the serverside like this:
 
=== Join the class ===
You can let the player join the class on serverside like this:
<pre>player.join("classname");</pre>
<pre>player.join("classname");</pre>
== Define your functions ==
You could do this in your Control-NPC to, say, join the classes whenever the player logs onto the game server.
 
Player classes are no different to ordinary classes - you should edit them in RC the same way as you do with normal classes.
 
=== Define your functions ===
For functions to be useable by other NPCs, they must be public:
For functions to be useable by other NPCs, they must be public:
<pre>public function funcName(parameters)
<pre>public function funcName(parameters)
Line 55: Line 69:
   // code
   // code
}</pre>
}</pre>
== Use your functions ==
This means that other NPCs can run the function, for example:
Other NPCs can use your player joined functions through the player object like shown here:
<pre>player.funcName(1, "Hello!");</pre>
Non-public functions will not be useable from outside the current script, so you can define normal functions to create a function that you don't want to be called externally, for example:
<pre>function funcName()
{
  // code
}</pre>
 
=== Using your functions ===
If your functions are public, then other scripts can easily call the functions that you have defined in your class, for example:
<pre>player.funcName();</pre>
<pre>player.funcName();</pre>
== Using this. ==
this. is the player's object in a player joined class, i.e.
<pre>this.chat = "foo";</pre>
... would set the player's chat text to "foo".


Because of this, this. variables (when not writing to a built-in variable) are stored in the client strings, unlike weapons, etc.
=== this. object ===
Player classes work in a different focus, where the current object (that's the '''this.''' object) becomes the player. So, if you wanted to change the player's chat text in a player joined class, you would use the following:
<pre>this.chat = "Chat text!";</pre>
Calling functions using this. will also call functions from player joined classes, for example:
<pre>player.join("classname");</pre>
<pre>this.playerFunction();
this.anotherFunction();</pre>

Latest revision as of 14:49, 16 February 2010

Note: Code examples in this article use new engine scripting.

Why classes?

Classes are a very useful concept in Gscript. They allow many instances of the same code to be run and even dynamically placed. They are also an effective means of sharing functions between scripts. You can attach them to the player, too, where the player is treated as the current object.

Using classes as standalone NPCs

Objects, including NPCs from levels or database NPCs, can join a class. That class is then controlling the behaviour of the object. The class can so act either as level NPC, when being joined from a level NPC, or as database NPC, when joined from a database NPC. Many objects can join the same class, which is useful e.g. for ATMs.

Joining from a level

To let a level NPC join a class, simply create an NPC and put:

this.join("classname");

The NPC will then join the class once created. When updating a class with RC that is joined by level NPCs, you may have to update the level in order to see the update.

Joining using putnpc2

To create a databased NPC, you can use the function putnpc2() on serverside:

putnpc2(x, y, "join(\"classname\");");

... replacing x and y with coordinate values, or variable names containing these values. A putnpc2() NPC is called a "database NPC", being that it is databased in the NPC-Server, and does not belong to a specific level. Database NPCs usually receive updates when the script is updated with RC immediately. They can also warp to other levels.

About database NPCs (including putnpc2 NPCs)

When you are finished with a DB NPC and want to destroy it, you should use this.destroy(); serverside. The NPC will then be totally removed from memory. Note that the class will of course still remain on the server.

DB NPCs have unique identifiers, which can be read using this.name. This identifier can be used to locate the NPC on the serverside, like shown:

with (findnpc(identifier))
{
  // foo
}
findnpc(identifier).foo();

This allows other scripts to interact with the database NPCs that you have placed. With the new scripting engine you can also access those npcs directly by using identifier.foo.

Like mentioned previously, database NPCs are not specific to one level, and such you can use the warpto() command to move the NPC into a new level:

this.warpto("levelname", x, y);

This enables great portability.

Using classes to share functions

If you write a set of functions that you wish to use in more than one NPC, then you can define them in a class, and let each npc join the class instead of copying the functions into each. It also means that you can update your functions across all your scripts, too.

Define your functions

Open up your class, and define your functions like you normally would!

function funcName(parameters)
{
  // code
}

Then save your class. This will provide these functions to any NPC that joins the class, and will allow you to easily update functions between several NPCs.

Using your functions

Now, before you can use the functions in your other scripts, you must let the current NPC join the class. Like a level NPC, you use the following command:

this.join("classname");

Then, you can use your functions.

You can easily let an NPC join more than one class, for example:

this.join("classone");
this.join("classtwo");

However, this can cause problems where there is more than one function with the same name. You can specify which class you want to use the function from by using the :: operator. The :: tells the scripting engine to look in that specific class, like so:

classtwo::myFunction();

This means that you do not have to worry about using the same function name more than once. If function names are colliding, then the first function found will be used, which means either from the script of the npc itself or of the class joined first.

Using "player classes"

Player classes are classes joined by players. A player-joined class treats the player as the current object (this.). Also, you can create functions available to other scripts through the player object, for example, creating a function that damages the player called doDamage() and then calling it from any script using:

player.doDamage();

This allows the player to be treated easier using different functions.

Join the class

You can let the player join the class on serverside like this:

player.join("classname");

You could do this in your Control-NPC to, say, join the classes whenever the player logs onto the game server.

Player classes are no different to ordinary classes - you should edit them in RC the same way as you do with normal classes.

Define your functions

For functions to be useable by other NPCs, they must be public:

public function funcName(parameters)
{
  // code
}

This means that other NPCs can run the function, for example:

player.funcName(1, "Hello!");

Non-public functions will not be useable from outside the current script, so you can define normal functions to create a function that you don't want to be called externally, for example:

function funcName()
{
  // code
}

Using your functions

If your functions are public, then other scripts can easily call the functions that you have defined in your class, for example:

player.funcName();

this. object

Player classes work in a different focus, where the current object (that's the this. object) becomes the player. So, if you wanted to change the player's chat text in a player joined class, you would use the following:

this.chat = "Chat text!";

Calling functions using this. will also call functions from player joined classes, for example:

player.join("classname");
this.playerFunction();
this.anotherFunction();