Welcome!

Join our community of MMO enthusiasts and game developers! By registering, you'll gain access to discussions on the latest developments in MMO server files and collaborate with like-minded individuals. Join us today and unlock the potential of MMO server development!

Join Today!

[Add-On]Learning NPCs, Start to Finish

Status
Not open for further replies.
bleh....
Loyal Member
Joined
Oct 15, 2008
Messages
2,898
Reaction score
1,129
Learning NPCs, From Start To Finish

Hello, and welcome to my attempt to teach everyone NPC scripts better. Regardless of the countless tutorials, and countless Help threads that have been posted and solved, people still seem to have issues with NPCs. Hopefully, with this tutorial, people will learn something. Before we start, let me tell you a bit about myself. I joined RageZone in October of 2008. I started just like most of you guys, not knowing a god damn thing. I've had my share of nub questions asked, but I've also learned from the help others have given me. I read tutorial after tutorial to learn more, so I didn't have to rely on others to answer my questions. Sure, there are still quite a few things I don't know, no one knows everything. Anyone who says otherwise is a damn fool. The main point I'm trying to make is, if you truly want to be good at something, it takes work. You can't sit back, have others do the work, and expect to become a pro at whatever it is you wish to do. You have to show initiative, and want to learn. I hope my tutorial teaches you something, even if it's just one thing.

Class 1: Beginning Level

Lesson 1: Useful programs for scripting

There are many programs that can assist with creating codes/scripts. Some allow key features like language changing, so you can have the proper vocabulary, and highlighting of brackets, so you can see where they open and close. It also helps when trying to organize a script. Here are some programs I recommend.




Lesson 2: Types of NPCs

There are two main types of NPCs. One that deals with status, and one that doesn't. The easiest way to tell them apart is obviously... the status. When creating an NPC, always think to yourself. "Will my NPC be opening more than 2 windows when I talk to it before it's over?" If your answer is yes, you will most likely need to use status. If you answered no, then status probably won't be needed. Here are some examples in the spoiler.

NPC not requiring status
PHP:
function start() {
	cm.sendOk("I am an NPC without a status.");
	cm.dispose();
}
Another NPC not requiring status
PHP:
function start() {
	cm.sendOk("Here is another example of an NPC without status.");
}

function action(mode, type, selection) {
	cm.warp(100000000, 0);
	cm.gainItem(4001126, 1);
	cm.sendOk("See? Here, I warped you and gave you an item without using status.");
	cm.dispose();
}

NPC requiring status
PHP:
var status;

function start() {
	status = -1;
	action(1, 0, 0);
}

function action(mode, type, selection) {
	if (mode == 1) {
		status++;
	}else{
		status--;
	}
	if (status == 0) {
		cm.sendNext("Go ahead and press Next so I can proceed to the next status.");
	} else if (status == 1) {
		cm.sendSimple("Would you like to see how I use status again? \r\n #L0# Yes. #l \r\n #L1# No. #l");
	} else if (status == 2) {
		if (selection == 0) {
			cm.sendOk("Here I am, in another status. As you can see from the script, this window is in status 2.");
			cm.dispose();
		} else if (selection == 1) {
			cm.sendOk("Well, sucks to be you, don't it? This window is also in status 2 :) ");
			cm.dispose();
		}
	}
}

Lesson 3: Communicating with yourself and other scripters

One of the key things when scripting is being able to understand what exactly you are doing or being able to understand what the author was doing. What better way to understand than to make notes while scripting? Have you ever looked at a script, and seen two // at the end of a line? Those are called comments. There are a few types of comments, and I will brush up on them.

PHP:
// This is one form of a comment
// When using this type of comment, it is typically used for single lines, hence why it is called a Single-Lined Comment.

/**
 This is a Multi-Lined Comment
 Anything in between the *s will not be read by whatever program is reading the script.
 **/

Comments are ignored by programs when being read. This means whatever you put as a comment, is strictly for the person reading the script. They are very useful if you are writing a long script and need to keep track of what you are doing. They also help by allowing you to tell other people what it is you were intending to do, in case they can't understand just by reading the code.

Lesson 4: Learning the Terminology

Let's face it. You can't code an NPC if you have no idea what the proper terminology is. Here are some quick notes.

NPC Color codes/Item pictures/etc
Code:
#b = Blue text.
#c[itemid]# Shows how many [itemid] the player has in their inventory.
#d = Purple text.
#e = Bold text.
#f[imagelocation]# - Shows an image inside the .wz files.
#g = Green text.
#h # - Shows the name of the player.
#i[itemid]# - Shows a picture of the item.
#k = Black text.
#l - Selection close.
#m[mapid]# - Shows the name of the map.
#n = Normal text (removes bold).
#o[mobid]# - Shows the name of the mob.
#p[npcid]# - Shows the name of the NPC.
#q[skillid]# - Shows the name of the skill.
#r = Red text.
#s[skillid]# - Shows the image of the skill.
#t[itemid]# - Shows the name of the item.
#v[itemid]# - Shows a picture of the item.
#x - Returns "0%" (need more information on this).
#z[itemid]# - Shows the name of the item.
#B[%]# - Shows a 'progress' bar.
#F[imagelocation]# - Shows an image inside the .wz files.
#L[number]# Selection open.
\r\n - Moves down a line.
\r = Return Carriage
\n = New Line
\t = Tab (4 spaces)
\b = Backwards

cm.[Commands]
Code:
dispose
Ends the conversation with an NPC, allows you to talk to NPCs again.
How to use: cm.dispose();

sendNext
Shows a conversation window with a 'Next' button.
How to use: cm.sendNext("[text]");

sendPrev
Shows a conversation window with a 'Prev' (previous) button.
How to use: cm.sendPrev("[text]");

sendNextPrev
Shows a conversation window with a 'Next' and 'Prev' button (see above).
How to use: cm.sendNextPrev("[text]");

sendOk
Shows a conversation window with an 'Ok' button.
How to use: cm.sendOk("[text]");

sendYesNo
Shows a conversation window with a 'Yes' and 'No' button, 'No' ends the conversation unless otherwise stated.
How to use: cm.sendYesNo("[text]");

sendAcceptDecline
Shows a conversation window with an 'Accept' and 'Decline' button. 'Decline' ends the conversation unless otherwise stated.
How to use: cm.sendAcceptDecline("[text]");

sendSimple
Shows a conversation window with no buttons.
How to use: cm.sendSimple("[text]");

sendStyle
Shows a style-select window.
How to use: cm.sendStyle("[Text]", [variable]); // You'll need to declare the variable in a Var statement.

warp
Warps the player to a map.
How to use: cm.warp([mapid], [portal]); // Set [portal] as 0 if you want default.

openShop
Opens a shop window.
How to use: cm.openShop([shopid]);

haveItem
Checks if the player has an item (in their inventories or equipped).
How to use: cm.haveItem([itemid]);

gainItem
Gives the player an item/takes an item from a player.
How to use: cm.gainItem([itemid],[ammount]); // Change [ammount] to -[ammount] to take an item.

changeJob
Changes the job of the player.
How to use: cm.changeJob([jobid]);

getJob
Finds out what job the player has.
How to use: cm.getJob();

startQuest
Starts a quest.
How to use: cm.startQuest([questid]);

completeQuest
Finishes a quest.
How to use: cm.completeQuest([questid]);

forfeitQuest
Forfeits a quest.
How to use: cm.forfeitQuest([questid]);

getMeso
Finds out how many mesos a player has.
How to use: cm.getMeso();

gainMeso
Gives a player mesos/takes mesos from a player.
How to use: cm.gainMeso([ammount]); // use -[ammount] to take mesos.

gainExp
Gives a player exp/takes exp from a player.
How to use: cm.gainExp([ammount]); // use -[ammount] to take exp.

getLevel
Finds out the level of the player.
How to use: cm.getLevel();

teachSkill
Teaches a player a skill.
How to use: cm.teachSkill([skillid],[skilllevel],[maxskilllevel]);

get[Stat]
Finds out the [Stat] of the player. [Stat] being: HP, MP, STR, DEX, INT, LUK.
How to use: cm.get[Stat]();

modifyNX
Gives/Takes the player nx
How to use: cm.gainNX([amount]);
Make it negative to make it take away.

Checking for mesos, items, donator, gm, and gender
PHP:
if (cm.getPlayer().isGM()) { // checks for GM

if (cm.getChar().isDonator() == true) { // checks for donator

if (cm.getJob().equals(net.sf.odinms.client.MapleJob.BOWMAN)) { // checks for Bowman job (list of jobs in below spoiler)

if (cm.getLevel() >= 30) { // checks if level is more than or equal to 30.

if (cm.getChar().getGender() == 0) { // 0 = male, 1 = female
if (cm.getPlayer().getGender() == 0) { // 0 = male, 1 = female

if (cm.getMeso() >= amount) { // >= greater than or equal to, <= less than or equal to,  == is equal to

if (cm.haveItem(itemid, amount)) { // checks if the player has a certain amount of an item

if (cm.getPlayer().getitemQuantity(itemid)); // gets a count of how much a player has of an item

Job Terms and Ids
Code:
BEGINNER - 0
WARRIOR - 100
FIGHTER - 110
CRUSADER - 111
HERO - 112
PAGE - 120
WHITEKNIGHT - 121
PALADIN - 122
SPEARMAN - 130
DRAGONKNIGHT - 131
DARKKNIGHT - 132
MAGICIAN - 200
FP_WIZARD - 210
FP_MAGE - 211
FP_ARCHMAGE - 212
IL_WIZARD - 220
IL_MAGE - 221
IL_ARCHMAGE - 222
CLERIC - 230
PRIEST - 231
BISHOP - 232
BOWMAN - 300
HUNTER - 310
RANGER - 311
BOWMASTER - 312
CROSSBOWMAN - 320
SNIPER - 321
CROSSBOWMASTER - 322
THIEF - 400
ASSASSIN - 410
HERMIT - 411
NIGHTLORD - 412
BANDIT - 420
CHIEFBANDIT - 421
SHADOWER - 422
PIRATE - 500
BRAWLER - 510
MARAUDER - 511
BUCCANEER - 512
GUNSLINGER - 520
OUTLAW - 521
CORSAIR - 522
MAPLELEAF_BRIGADIER - 800
GM - 500(v55) / 900(v62+)
SUPERGM 510(v55) / 910(v62+)
DAWNWARRIOR1 - 1000
DAWNWARRIOR2 - 1010
DAWNWARRIOR3 - 1011
DAWNWARRIOR4 - 1012
BLAZEWIZARD1 - 1100
BLAZEWIZARD2 - 1110
BLAZEWIZARD3 - 1111
BLAZEWIZARD4 - 1112
WINDARCHER1 - 1200
WINDARCHER2 - 1210
WINDARCHER3 - 1211
WINDARCHER4 - 1212
NIGHTWALKER1 - 1300
NIGHTWALKER2 - 1310
NIGHTWALKER3 - 1311
NIGHTWALKER4 - 1312
THUNDERBREAKER1 - 1400
THUNDERBREAKER2 - 1410
THUNDERBREAKER3 - 1411
THUNDERBREAKER4 - 1412
ARAN1 - 2100
ARAN2 - 2110
ARAN3 - 2111
ARAN4 - 2112

Keep in mind that some repacks use a different Terminology than this, so it's best to browse your repack/source folder to get familiar with yours.

Partial Credits: Here for easy copy/pasting and editing.

Class 2: Intermediate Level

Lesson 1: Learning to code an NPC

When creating an NPC, it's always best to have a general idea of what you are doing. A quick way to do this is to open a Notepad file, with little notes of what you want it to do. Example:

Code:
Item Exchanger
Window 1 - Shows different options
Window 2 - Shows different options after picking from Window 1

Window 1 choices - ores for a maple coin, ores for a maple leaf
Window 2 choices - if picked maple coin = 10 ores for 1 coin, 20 ores for 3 coins
				if picked maple leaf = 5 ores for 1 leaf, 10 ores for 3 leafs

That was just an example, but by making little notes like that, you can think of the best layout beforehand. It also helps having something to look back on to remind you, in case you don't have the time to do your script in one sitting.

Now, before you begin, you need to think of what type of NPC you are going to do. If you need reference, revert to Class 1, Lesson 2. In this example, I will be using an NPC that uses status. Please read the comments (Class 1, Lesson 3) in the script, to understand what I am doing.

PHP:
var status;

function start() { // starts the NPC
	status = -1; // sets the status of the NPC to -1
	action(1, 0, 0); // sets the mode to 1, type to 0, and selection to 0 for the NPC
} // closes off the start function

function action(mode, type, selection) { // calls what you set above in function start, almost all actions are done here
	if (mode == 1) { // the mode is set to 1 because of the function start, as shown above
		status++; // advances the NPC to the next status, in this case, status 0
	}else{ // if mode does not equal 1
		status--; // does not advance the NPC to the next status.
	}
	
	if (status == 0) { // if mode was 1, status would move from -1 to 0. If status is 0, these actions will happen
		cm.sendSimple("Hello. I am going to show you how to use #belse#k and #bif#k. Are you ready? \r\n #L0# Yes, I am. #l \r\n #L1# No, I'm not. #l"); // Opens a window with 2 choices (selections)
	} else if (status == 1) { // NPC advances to next status if a selection is chosen.
		if (selection == 0) { // selection 0 is #L0#, "Yes, I am."
			if (cm.haveItem(4001129, 10)) { // checks for an item
				cm.sendOk("IF you chose selection 0, or in easier terms, the first choice, I will say this."); // IF you have the item, this will show
				cm.dispose();
			}else{
				cm.sendOk("I'm sorry, you don't have the item."); // ELSE, you don't have the item.
				cm.dispose();
			}
		} else if (selection == 1) { // "No, I'm not."
			cm.sendOk("ELSE IF you chose selection 1, I will say this.");
			cm.dispose();
		}
	}
}

Here's a little something to help you with NPCs as well.

Code:
----------- 
sendNext(); & sendOk(); 
----------- 
Type = 0 
If end chat    -    mode = -1 
If next/ok    -    mode = 1 

----------- 
sendNextPrev(); 
----------- 
Type = 0 
If end chat    -    mode = -1 
If next        -    mode = 1 
if back        -    mode = 0 

----------- 
sendYesNo(); 
----------- 
Type = 1 
If end chat    -    mode = -1 
If yes        -    mode = 1 
If no        -    mode = 0 

----------- 
sendAcceptDecline(); 
----------- 
Type = 12 
If end chat    -    mode = -1 
If accept    -    mode = 1 
If decline    -    mode = 0 

----------- 
sendGetText(); 
----------- 
Nothing o____o its something special <3 

----------- 
sendGetNumber(); 
----------- 
Type = 3 
If end chat     -     mode = 0 
if ok         -    mode = 1 

----------- 
sendSimple(); 
----------- 
Type = 4 
If end chat     -     mode = 0 
if select     -    mode = 1

Credits: BENG


Brackets can be a key factor between a working NPC and a non working NPC. Let's take a look at a part of the above NPC.
Code:
if (cm.haveItem(4001129, 10)) { // checks for an item
				cm.sendOk("IF you chose selection 0, or in easier terms, the first choice, I will say this."); // IF you have the item, this will show
				cm.dispose();
			}

If you look at the first line...
Code:
if (cm.haveItem(4001129, 10)) {
There is an opening bracket at the end of the line. This means, in an easier understanding, if the condition is true, anything after will happen. So, for that line, if you have 10 of 4001129, the following line will happen. Look at the end of the snippet of code. Notice the other bracket?
Code:
}
That is a closing bracket. It closes the condition. So, anything between the opening and closing bracket is for that specific condition. The closing bracket will usually be followed by an else, which means if you don't have the item, the actions under else will happen.

Lesson 2: Using Operators

In this lesson, you will learn the different types of Operators and how to use them. There are a few types of Operators. They can help you determine if something is bigger or smaller, and even if it's equal to. Below is a list of Operators you will most likely be using.
Code:
Operator	Name			Type		Description
!		Not			Unary 		Returns true if the operand to the right evaluates
to false. Returns false If the
operand to the right is true.

&& 		Conditional And 	Binary 		If the operand on the left
returns false, returns false without evaluating
the operand on the right.

|| 		Conditional Or 		Binary 		If the operand on the left
returns true, returns true without evaluating
the operand on the right.

The above Operators are commonly used in between conditions. What is a condition? Things you see quite often in NPC scripts.
PHP:
if (cm.haveItem(itemid, amount)) {
if (cm.getMeso() >= amount) {
if (cm.getPlayer().getLevel() >= amount) {


These are all conditions. So, when used in between, you can further specify certain requirements for players. Examples:
PHP:
if (cm.haveItem(4001129, 50) && cm.getMeso() >= 1000) { // This requires the player to have both 50 Maple Coins and 1000 Mesos
if (cm.haveItem(4001129, 50) || cm.getMeso() >= 1000) { // This checks if the player has either 50 Maple coins [b]or[/b] 1000 Mesos
if (!cm.haveItem(4001129, 50)) { // This will check to see if they don't have at 50 Maple Coins
Using this is a good way to limit players from saving up loads of an item to cash in at once. Next, we have Relational Operators. These are commonly used inside conditions. Here is a list of a few.
Code:
Operator	Description
== 		Returns true if the expression on the left evaluates to the
same value as the expression on the right.

<  		Returns true if the expression on the left evaluates to a value
that is less than the value of the expression on the right.

<= 		Returns true if the expression on the left evaluates to a value
that is less than or equal to the expression on the right.

>  		Returns true if the expression on the left evaluates to a value
that is greater than the value of the expression on the right.

>= 		Returns true if the expression on the left evaluates to a value
that is greater than or equal to the expression on the right.

I've already given you a few examples of these, if you haven't noticed, but let me run a few more by you.
PHP:
if (cm.getMeso() >= 1000) { // if player has GREATER THAN OR EQUAL TO 1000 Mesos
if (cm.getPlayer().getLevel() == 120) { // if player IS level 120
if (cm.getJobById() <= 112) { // if players' job id is LESS THAN OR EQUAL TO 112 (Hero, Crusader, Fighter, Warrior, Beginner)

Lesson 3: Learning how to use Variables

As you progress in your learning experiences, you'll begin to notice and wonder why there are things at the top of a script that start with "var". This is called a variable. Variables, in short, are used to "replace" something. They basically take a number, or a sentence, and "replace it" with whatever you name the variable. Typically, you would want the variable to shorten the script, even if by a few characters. Here is an example.
PHP:
var gl = 4000313;

function start() {
	cm.sendOk("Hello, do you have any #v"+gl+"#?"); // Calls the variable gl, and the information it is replacing
	cm.dispose();
}

As you can see from the example, the item id 4000313 is being replaced with the variable "gl". Even though it's only a minor difference, I shortend the script by 1 character. Now imagine having hundreds of places on a script where 4000313 was replaced by "gl". It adds up on how much space you save by using variables. That was an example on how to use a variable for a number. Here is one on how to use a variable for a string, or text sentence.
PHP:
var yes = "Good Job! You have enough Golden Maple Leafs!";
var no = "I'm sorry, you don't have enough Golden Maple Leafs.";
var status;

function start() {
	status = -1;
	action(1, 0, 0);
}

function action(mode, type, selection) {
	if (mode == 1) {
		status++;
	}else{
		status--;
	}
	if (status == 0) {
		cm.sendSimple("#L0# I have 10 Golden Maple Leafs #l \r\n #L1# I have 20 Golden Maple Leafs #l");
	}else if (status == 1) {
		if (selection == 0) {
			if (cm.haveItem(4000313, 10)) {
				cm.sendOk(yes); // Calls the variable "yes", and displays what you have set for it
				cm.dispose();
			}else{
				cm.sendOk(no); // Calls the variable "no", and displays what you have set for it
				cm.dispose();
			}
		} else if (selection == 1) {
			if (cm.haveItem(4000313, 20)) {
				cm.sendOk(yes); // Calls the variable "yes", and displays what you have set for it
				cm.dispose();
			}else{
				cm.sendOk(no); // Calls the variable "no", and displays what you have set for it
				cm.dispose();
			}
		}
	}
}

As you can clearly see, using these variables saved me a great deal of space. Instead of using 202 characters by typing in those long lines, I used 111 characters, and that's including the top variables! Using variables also makes it easier to edit scripts in the future.

Class 3: Advanced Level

Lesson 1: Learning Arrays

Now we get to the fun part. Arrays are what all the "pros" stress about. If Arrays can be used, they want to see it. It not only makes the script cleaner, but helps with the overall performance of the script. Arrays can be easily edited, and once you learn how to use them, can help you understand what the creator of the script is doing. Here are some examples of Arrays.

PHP:
item = [4000313, 4001129, 4001126];

function start() {
	cm.sendSimple("Which would you like? \r\n #L0# Golden Maple Leaf #l \r\n #L1# Maple Coin #l \r\n #L2# Maple Leaf #l");
}

function action(mode, type, selection) {
    if (mode == 1) {
        cm.gainItem(item[selection], 1);
    }
    cm.dispose();
}

As you can see, the item ids are placed in the order they are shown in the sendSimple. The [selection] in the cm.gainItem method, calls the Array to determine which item to give the player. If they chose the second selection, it would call the second number in the Array. By placing the items in an Array, it shortens the script by a lot. Here is what the script would look like without an Array.
PHP:
function start() {
	cm.sendSimple("Which would you like? \r\n #L0# Golden Maple Leaf #l \r\n #L1# Maple Coin #l \r\n #L2# Maple Leaf #l");
}

function action(mode, type, selection) {
	if (mode == 1) {
		if (selection == 0)
			cm.gainItem(4000313, 1);
		else if (selection == 1)
			cm.gainItem(4001129, 1);
		else if (selection == 2)
			cm.gainItem(4001126, 1);
	}
	cm.dispose();
}

There is a clear difference between the two in which is longer. One of the most common ways to use Arrays, is with the infamous for loop, which I will explain in a later lesson.

Lesson 2: Learning Multi-Dimentional Arrays and Randoms

In this section, I will teach you about Multi-Dimentional Arrays and Randoms. Now, I'm not an expert at this, so I'll only be able to show you what I know. So what is a Multi-Dimentional Array? A Multi-Dimentional array is an array made up of separate arrays. Basically, you can have more than one array, and simplify them further by making them into a multi-dimentional array. Unfortunately, I only know how to use them with randoms, so that is what I'll be teaching you. First, lets' set up a simple multi-dimentional array NPC.
PHP:
var status;
var item = [[4001129, 4001129], [1082025, 1102023], [4000313, 1002085]];
var rand = Math.floor(Math.random()*100);

function start() {
	status -1;
	action(1, 0, 0);
}

function action(mode, type, selection) {
	if (mode == -1) {
        cm.dispose();
    }else{
    if (status >= 2 && mode == 0) {
        cm.sendOk("See you next time!.");
        cm.dispose();
        return;                    
    }
    
    if (mode == 1) {
        status++;
    }else{
        status--;
    }
	
	if (status == 0) {
		cm.sendYesNo("Are you sure you want to take a chance?");
	} else if (status == 1) {
		var rand2;
        if ((rand >= 1) && (rand <= 50)) {
            rand2 = Math.floor(Math.random() * item[0].length);
        } else if ((rand >= 51) && (rand <= 90)) {
            rand2 = Math.floor(Math.random() * item[1].length);
        }else{
            rand2 = Math.floor(Math.random() * item[2].length);
            }
            cm.gainItem([rand >= 1 && rand <= 50 ? item[0][rand2] : rand >= 51 && rand <= 90 ? item[1][rand2] : item[2][rand2]]);
			cm.sendOk("Congrats on your item.");
			cm.dispose();
		}
	}
}

Alright, time to explain. This is the multi-dimentional array.
Code:
var item = [[color=red][4001129, 4001129][/color], [color=blue][1082025, 1102023][/color], [color=green][4000313, 1002085][/color]];
Each separete array is colored, so you can see the 3 different arrays within the multi-dimentional array. Next is the random part, or this little snippet.
PHP:
var rand2;
        if ((rand >= 1) && (rand <= 50)) {
            rand2 = Math.floor(Math.random() * item[0].length);
        } else if ((rand >= 51) && (rand <= 90)) {
            rand2 = Math.floor(Math.random() * item[1].length);
        }else{
            rand2 = Math.floor(Math.random() * item[2].length);
        }

Ok, at the top of the script, you see this line.
Code:
var rand = Math.floor(Math.random()*100);
Think of this as if it were a dice. The number symbolizes the sides of a dice. So on this dice, there are 100 sides. Continue reading the random part as you read this. If the dice lands on side 1 - 50, give an item in the first array. If the dice lands on side 51 - 90, give an item in the second array. If it lands on any other side, give an item in the third array. This line here...
Code:
cm.gainItem([[color=red]rand >= 1 && rand <= 50 ? item[0][rand2][/color] : [color=blue]rand >= 51 && rand <= 90 ? item[1][rand2][/color] : [color=green]item[2][rand2][/color]]);
Basically follows through with the action. That is all I know about these types of arrays.

Lesson 3: Learning the Infamous For Loop

Have you ever looked at a script, and seen something like this?
PHP:
for (var i = 0; i < options.length; i++)
            text += "\r\n#L"+i+"#"+options[i]+"#l";

This is the infamous for loop. It simplifies almost anything it is used with. It was created to specifically deal with Arrays. Here is the entire part of the code, so I can explain what it means.
PHP:
var text = "#e#k What region have you trained in?#b";
        var options = new Array("Aqua Road Region = 1 #v4001010#", "Ariant Region = 1 #v4001011#", "El Nath Region = 1 #v4001013#", "Ludas Lake Region = 1 #v4001012#", "Minar Forest Region = 1 #v4001009#", "Victoria Island Region = 5 #v4001126#", "World Tour = 5 #v4001129#", "Ores/Crystals = 1 #v4001014#");
        for (var i = 0; i < options.length; i++)
            text += "\r\n#L"+i+"#"+options[i]+"#l";
        cm.sendSimple(text);

Ok so, i = 0. While 0 is less than the options array, do the code. After executing the code, do i++. i++ basically tells the program running the script to increase i until it reaches the length of the array. So since the options array has a length of 8, it will keep increasing until it displays all 8 options.

Contributions from other members

Insert In NpcConversatonManager:

Code:
 public void changeKeyBinding (int key, int type, int action) {
        getPlayer().changeKeybinding(key, new MapleKeyBinding(type, action));
        getPlayer().sendKeymap();
    }

How to use
Code:
var status = 0;

function start() {
    status = -1;
    action(1, 0, 0);
}

function action(mode, type, selection) {
    if (mode == -1) {
        cm.dispose();
    } else {
        if (mode == 0 && status == 1) {
            cm.dispose();
            return;
        }
        if (mode == 1)
            status++;
        else
            status--;
            if (status == 0) {
                cm.sendYesNo("Hello there! Do you want to learn flash jump?");
            } else if (status == 1) {
                cm.sendSimple("Which key do you want #fSkill/411.img/skill/4111006/icon# on? #b\r\n#L59#F1#L60#F2#L61#F3#L62#F4#L63#F5#L64#F6#L65#F7#L66#F8#L67#F9 \r\n #L68#F10#L87#F11#L88#F12 \r\n#L2#1#L3#2#L4#3#L5#4#L6#5#L7#6#L8#7#L9#8#L10#9#L11#0#L12#-#L13#= \r\n#L16#Q#L17#W#L18#E#L19#R#L20#T#L21#Y#L22#U#L23#I#L24#O#L25#P#L26#[#L27#] \r\n#L30#A#L31#S#L32#D#L33#F#L34#G#L35#H#L36#J#L37#K#L38#L#L39#;#L40#' \r\n#L42#Shift#L44#Z#L45#X#L46#C#L47#V#L48#B#L49#N#L50#M#L51#,#L52#.#L42#Shift \r\n#L29#Ctrl#L56#Alt#L57#SPACE#L56#Alt#L29#Ctrl \r\n#L82#Ins#L71#Hm#L73#Pup#L83#Del#L79#End#L81#Pdn");
            } else if (status == 2) {2
                    cm.sendOk("There you go!");
		    cm.changeKeyBinding(selection, 1, 4111006);
		    cm.dispose();
	    } else {
		cm.sendOk("See you next time then.");
                cm.dispose();
                
            }
    } 
}

CM command:
Code:
changeKeyBinding
allows you to place a skill anywhere in your key config.
How to use: cm.changeKeyBinding(selection, 1, SKILLID);
(THINKS THATS HOW TO USE?)

ALL CREDITS GOES TO "made4forum" FROM HIS RELEASE
LINK:http://forum.ragezone.com/f427/skill-teaching-npc-619108/

....​

Further Explanation of the For Loop
Rice said:
Shawn - [Add-On]Learning NPCs, Start to Finish - RaGEZONE Forums

Final Words

This concludes the tutorial. There is still quite a bit I don't know, even with NPCs. If anyone has something they wish to add/contribute, feel free to post it and I'll include it with credits. I hope you enjoyed my wall of text and learned something valuable. Please leave credits if this is posted anywhere else. Lastly, if you need help with an NPC script or have trouble understanding something, feel free to ask HERE. Do not quote the entire tutorial. If you do, I will ask a Mod to remove your post, because it's an inconvenience for others.

Credits:
Shawn aka bboy242 aka DevonsDaddy

Special Thanks:
Moogra and Osiris
.:LastBreath:.
made4forum
Alcohol
Rice

 
Last edited:
Initiate Mage
Joined
Sep 30, 2009
Messages
2
Reaction score
0
Re: Learning NPCs, Start to Finish

Great guide
 
Initiate Mage
Joined
Jan 11, 2009
Messages
2
Reaction score
0
Re: Learning NPCs, Start to Finish

Awesome guide, I'm going to be reading through this thoroughly. ;]
 
Newbie Spellweaver
Joined
Aug 14, 2008
Messages
23
Reaction score
0
Re: Learning NPCs, Start to Finish

Bboy, you really should be stickyed for this. I mean, it's just so clear. I've scimmed through it, and it's really good. Really specific too. I'll read it more later, to see if you made any grammmar mistakes :). This page just got bookmarked. I just hope there will be less help threads about npc script errors.
 
Last edited:
Junior Spellweaver
Joined
Jan 17, 2010
Messages
152
Reaction score
58
Re: Learning NPCs, Start to Finish

Great Tutorial thanks,this is going to help so much people with there servers.
Great Job!
 
bleh....
Loyal Member
Joined
Oct 15, 2008
Messages
2,898
Reaction score
1,129
Re: Learning NPCs, Start to Finish

Thanks guys. If anyone has something to contribute, feel free to. Hopefully this thread can be a one-stop thread, to answer anyones' problems with NPCs.
 
Custom Title Activated
Loyal Member
Joined
Aug 21, 2009
Messages
1,149
Reaction score
598
Re: Learning NPCs, Start to Finish

Nice tutorial Shawn <3
 
Joined
Nov 27, 2009
Messages
442
Reaction score
230
Re: Learning NPCs, Start to Finish

Ohh thanks i diddn't know about these commands
Code:
\r = Return Carriage
\n = New Line
\t = Tab (4 spaces)
\b = Backwards
 
Supreme Arcanarch
Loyal Member
Joined
Oct 18, 2009
Messages
914
Reaction score
335
Re: Learning NPCs, Start to Finish

Awesome, just awesome! You put alot of work to this, it really shows, oh ah well I use cm.changeKeyBinding(spelling?), which allows to give you and set a skill on to you keyboard from any NPC... heres the script for people who dont know how to add....

Instert In NpcConversatonManager:

Code:
 public void changeKeyBinding (int key, int type, int action) {
        getPlayer().changeKeybinding(key, new MapleKeyBinding(type, action));
        getPlayer().sendKeymap();
    }

and heres script...
Code:
var status = 0;

function start() {
    status = -1;
    action(1, 0, 0);
}

function action(mode, type, selection) {
    if (mode == -1) {
        cm.dispose();
    } else {
        if (mode == 0 && status == 1) {
            cm.dispose();
            return;
        }
        if (mode == 1)
            status++;
        else
            status--;
            if (status == 0) {
                cm.sendYesNo("Hello there! Do you want to learn flash jump?");
            } else if (status == 1) {
                cm.sendSimple("Which key do you want #fSkill/411.img/skill/4111006/icon# on? #b\r\n#L59#F1#L60#F2#L61#F3#L62#F4#L63#F5#L64#F6#L65#F7#L66#F8#L67#F9 \r\n #L68#F10#L87#F11#L88#F12 \r\n#L2#1#L3#2#L4#3#L5#4#L6#5#L7#6#L8#7#L9#8#L10#9#L11#0#L12#-#L13#= \r\n#L16#Q#L17#W#L18#E#L19#R#L20#T#L21#Y#L22#U#L23#I#L24#O#L25#P#L26#[#L27#] \r\n#L30#A#L31#S#L32#D#L33#F#L34#G#L35#H#L36#J#L37#K#L38#L#L39#;#L40#' \r\n#L42#Shift#L44#Z#L45#X#L46#C#L47#V#L48#B#L49#N#L50#M#L51#,#L52#.#L42#Shift \r\n#L29#Ctrl#L56#Alt#L57#SPACE#L56#Alt#L29#Ctrl \r\n#L82#Ins#L71#Hm#L73#Pup#L83#Del#L79#End#L81#Pdn");
            } else if (status == 2) {2
                    cm.sendOk("There you go!");
		    cm.changeKeyBinding(selection, 1, 4111006);
		    cm.dispose();
	    } else {
		cm.sendOk("See you next time then.");
                cm.dispose();
                
            }
    } 
}

CM command:
Code:
changeKeyBinding
allows you to place a skill anywhere in your key config.
How to use: cm.changeKeyBinding(selection, 1, SKILLID);
(THINKS THATS HOW TO USE?)

ALL CREDITS GOES TO "made4forum" FROM HIS RELEASE
LINK:http://forum.ragezone.com/f427/skill-teaching-npc-619108/

....​
 
Last edited:
bleh....
Loyal Member
Joined
Oct 15, 2008
Messages
2,898
Reaction score
1,129
Re: Learning NPCs, Start to Finish

Awesome, just awesome! You put alot of work to this, it really shows, oh ah well I use cm.changeKeyBinding(spelling?), which allows to give you and set a skill on to you keyboard from any NPC..

Nice. I actually didn't know about that. You taught me something. Good job. I'll include it. Thanks again.
 
Last edited:
Banned
Banned
Joined
Nov 17, 2009
Messages
104
Reaction score
30
Re: Learning NPCs, Start to Finish

getChar doesn't work with shootsource just saying it'd be getPlayer
 
bleh....
Loyal Member
Joined
Oct 15, 2008
Messages
2,898
Reaction score
1,129
Re: Learning NPCs, Start to Finish

getChar doesn't work with shootsource just saying it'd be getPlayer

lol I thought we already went through this? I put that the people should go through their repack/source to find out which other methods are in there. Thank you though.
 
Junior Spellweaver
Joined
Jan 23, 2010
Messages
126
Reaction score
1
Re: Learning NPCs, Start to Finish

Great Guide, this will help alot of people.
 
Joined
Jun 19, 2008
Messages
4,135
Reaction score
2,179
Re: Learning NPCs, Start to Finish

Read through all of this just now, and I have to say, it's quite marvelous. This is how a guide should be typed up; I'm sure this guide will cut down on the overwhelming help threads concerning NPC codes. Nice to see there is still some quality being put into guides! I'd motion this for a sticky.
 
bleh....
Loyal Member
Joined
Oct 15, 2008
Messages
2,898
Reaction score
1,129
Re: Learning NPCs, Start to Finish

Read through all of this just now, and I have to say, it's quite marvelous. This is how a guide should be typed up; I'm sure this guide will cut down on the overwhelming help threads concerning NPC codes. Nice to see there is still some quality being put into guides! I'd motion this for a sticky.

Thank you. This actually took me about a week to do, because I had to research a few things first. I knew how to do the for loop in an NPC, but didn't know how to explain it, so had to research that, as well as other things. Thank you for the kind words. As for the sticky part, I'll be very surprised if it does get stickied.
 
Supreme Arcanarch
Loyal Member
Joined
Oct 18, 2009
Messages
914
Reaction score
335
Re: Learning NPCs, Start to Finish

Hmm I think you forgot cm.gainFame ? ill let you know if I find another NPC command that is useful. Keep the good work up :)

Oh I also think but I am not sure but cm.gainPoints? or ahh... well because I know most people have this if not then... well make a guide how to.. or?
 
Last edited:
Newbie Spellweaver
Joined
Dec 15, 2009
Messages
44
Reaction score
12
Re: Learning NPCs, Start to Finish

You can use pretty much any method in MapleMap in any map by using cm.getChannelServer().getMapFactory().getMap(mapid).
You can use any method in MapleCharacter by doing cm.getPlayer() or cm.getClient().getPlayer() and any method in MapleClient by doing cm.getClient().
You can access any method in MapleMonster by getting the map, and using one of the getMonsterByOid or getMonsterById if you check if it isn't null. You can use any method in maplereactor and other map objects this way as well.

Basically the cm commands aren't that important. Only the getClient seems to be mandatory. The rest can be done by looking at the source, with a possible exception of referencing other players.

The reason I say this is because too many people memorize the methods in NPCConversationManager/PlayerInteraction and don't look at the bigger picture. Many of the methods there are for simplicity sake, but not needed. For example, gainExp(int amount) could just be cm.getPlayer().gainExp(amount, true, true, true); (i think the syntax is like this).
 
Last edited:
Junior Spellweaver
Joined
Jun 12, 2009
Messages
116
Reaction score
1
Re: Learning NPCs, Start to Finish

nice guide xD easy to understand and noob friendly
 
Status
Not open for further replies.
Back
Top