Difference between revisions of "Basic Scripting"
Mysterious (Talk | contribs) (Created page with "==The Basics== Scripts control all NPCs, warps, mob spawns, shops, and quests you will find in the game--and nearly everything else! Clearly they play a large part in custom...") |
(Removed any references to NPC ID's. These are no longer recommended and may lose support.) |
||
(9 intermediate revisions by 5 users not shown) | |||
Line 1: | Line 1: | ||
+ | {{outdated}} | ||
+ | |||
==The Basics== | ==The Basics== | ||
Scripts control all NPCs, warps, mob spawns, shops, and quests you will find in the game--and nearly everything else! Clearly they play a large part in customizing a server, but learning isn't very hard. | Scripts control all NPCs, warps, mob spawns, shops, and quests you will find in the game--and nearly everything else! Clearly they play a large part in customizing a server, but learning isn't very hard. | ||
− | Scripts are built up of predefined script commands, all of which can be found in {{ | + | Scripts are built up of predefined script commands, all of which can be found in {{git|doc/script_commands.txt}} (for explanations, see [[:Category:Script_Command|Script Commands]]). Every line should begin with a command and the argument it takes, and must end in a semicolon (or you'll get mapserver errors!). Arguments are usually separated by commas, and are sometimes contained in parentheses () or curly brackets {}. Tabs and proper indentation are standard scripting measures. |
Scripts are saved as text (*.txt) files, so all code can be written in Notepad. There are also a lot of scripting programs to use: the most recent and comprehensive one is [http://rathena.org/board/topic/56484-enpc-script-editor/ Vince's eNPC]. All defined functions are highlighted, with an autocomplete feature included, and pressing "F1" will display the corresponding explanation for any command. | Scripts are saved as text (*.txt) files, so all code can be written in Notepad. There are also a lot of scripting programs to use: the most recent and comprehensive one is [http://rathena.org/board/topic/56484-enpc-script-editor/ Vince's eNPC]. All defined functions are highlighted, with an autocomplete feature included, and pressing "F1" will display the corresponding explanation for any command. | ||
Line 11: | Line 13: | ||
===NPC=== | ===NPC=== | ||
A '''Script NPC''' will look something like the following: | A '''Script NPC''' will look something like the following: | ||
− | prontera,156,145,4 <tab> script <tab> Test NPC <tab> | + | prontera,156,145,4 <tab> script <tab> Test NPC <tab> 1_M_MERCHANT,{ |
The first section is the map location of the NPC, followed by its coordinates in x,y and the direction the NPC will face. Direction numbers are counted counterclockwise in 45º increments, with 0 being the center: <br> | The first section is the map location of the NPC, followed by its coordinates in x,y and the direction the NPC will face. Direction numbers are counted counterclockwise in 45º increments, with 0 being the center: <br> | ||
− | [1][ | + | [1][0][7] <br> |
− | [2][ | + | [2][ ][6] <br> |
[3][4][5] <br> | [3][4][5] <br> | ||
After the first tab, the type of script is defined. For our purposes, it'll stay "script" for now, but can also be function, shop, or cashshop, for starters. <br> | After the first tab, the type of script is defined. For our purposes, it'll stay "script" for now, but can also be function, shop, or cashshop, for starters. <br> | ||
The name of the NPC is next. You can use up to 24 characters, so make it unique! Any duplicates will cause warnings or errors, and the NPC will just be automatically renamed anyway. <br> | The name of the NPC is next. You can use up to 24 characters, so make it unique! Any duplicates will cause warnings or errors, and the NPC will just be automatically renamed anyway. <br> | ||
− | The last number is for the sprite (Ai4rei's sprite list can be found [http://nn. | + | The last number is for the sprite (Ai4rei's sprite list can be found [http://nn.ai4rei.net/dev/npclist/ here]). It's followed by a comma and open curly bracket, marking the beginning of the script contents. Of course, the script must also end in a curly bracket.<br> |
===Function=== | ===Function=== | ||
Line 31: | Line 33: | ||
===Shop=== | ===Shop=== | ||
A '''Shop''' starts like a normal script: | A '''Shop''' starts like a normal script: | ||
− | prontera,156,145,4 <tab> shop <tab> Fruit Store <tab> | + | prontera,156,145,4 <tab> shop <tab> Fruit Store <tab> 1_M_MERCHANT,512:-1,513:1000 |
The first section defines the map, coordinates, and direction. The word "shop" replaces "script" (alternately, "cashshop" will use Cashpoints instead of Zeny). The name and sprite ID follow, then a comma. <br> | The first section defines the map, coordinates, and direction. The word "shop" replaces "script" (alternately, "cashshop" will use Cashpoints instead of Zeny). The name and sprite ID follow, then a comma. <br> | ||
Line 141: | Line 143: | ||
Take a look at our old Test NPC: | Take a look at our old Test NPC: | ||
− | prontera,156,145,4 <tab> script <tab> Test NPC <tab> | + | prontera,156,145,4 <tab> script <tab> Test NPC <tab> 1_M_MERCHANT,{ |
To be able to duplicate this, we will change the heading to this: | To be able to duplicate this, we will change the heading to this: | ||
− | - <tab> script <tab> Test NPC#01::testnpc <tab> | + | - <tab> script <tab> Test NPC#01::testnpc <tab> 1_M_MERCHANT,{ |
The location doesn't need to be defined in the NPC, since it will be in the duplicates. <br> | The location doesn't need to be defined in the NPC, since it will be in the duplicates. <br> | ||
The displayed name remains "Test NPC". But since NPC names must be unique, adding #01 separates this one from the rest, which will be #02, #03, etc. Lastly, ::testnpc is the reference name used for duplicating NPCs; this part is not displayed on the screen. <br> | The displayed name remains "Test NPC". But since NPC names must be unique, adding #01 separates this one from the rest, which will be #02, #03, etc. Lastly, ::testnpc is the reference name used for duplicating NPCs; this part is not displayed on the screen. <br> | ||
After creating the base NPC, duplicates can be added anywhere to any file, so long as you use the same NPC name: | After creating the base NPC, duplicates can be added anywhere to any file, so long as you use the same NPC name: | ||
− | spl_fild03,150,150,7 <tab> duplicate(testnpc) <tab> Test NPC <tab> | + | spl_fild03,150,150,7 <tab> duplicate(testnpc) <tab> Test NPC <tab> 1_M_MERCHANT |
− | niflheim,50,50,2 <tab> duplicate(testnpc) <tab> Test NPC <tab> | + | niflheim,50,50,2 <tab> duplicate(testnpc) <tab> Test NPC <tab> 1_M_MERCHANT |
− | tha_scene01,140,190,4 <tab> duplicate(testnpc) <tab> Test NPC <tab> | + | tha_scene01,140,190,4 <tab> duplicate(testnpc) <tab> Test NPC <tab> 1_M_MERCHANT |
The first part is ''map,x,y,direction'', as you're probably used to by now. <br> | The first part is ''map,x,y,direction'', as you're probably used to by now. <br> | ||
− | To define a duplicate, the word "duplicate" followed by the NPC, in parentheses, is needed. The last two parameters are the display name and | + | To define a duplicate, the word "duplicate" followed by the NPC, in parentheses, is needed. The last two parameters are the display name and NPC view constant (actual name of the npc sprite, yes, you can change these, too!). |
==Finished Product== | ==Finished Product== | ||
Line 158: | Line 160: | ||
Here is an example using the features explained above: | Here is an example using the features explained above: | ||
− | prontera,156,145,4 script Test NPC::test | + | prontera,156,145,4 script Test NPC::test 4_WHIKEBAIN,{ |
mes "Hello, how are you?"; | mes "Hello, how are you?"; | ||
mes "I am fine, how are you?"; | mes "I am fine, how are you?"; | ||
Line 187: | Line 189: | ||
} | } | ||
− | lhz_dun01,157,285,4 duplicate(test) Test NPC | + | lhz_dun01,157,285,4 duplicate(test) Test NPC 4_F_AGENTKAFRA |
− | hu_fild05,186,210,4 duplicate(test) Test NPC | + | hu_fild05,186,210,4 duplicate(test) Test NPC 4_F_AGENTKAFRA |
− | yuno_fild07,221,179,4 duplicate(test) Test NPC | + | yuno_fild07,221,179,4 duplicate(test) Test NPC 4_F_AGENTKAFRA |
− | tha_scene01,139,194,1 duplicate(test) Test NPC | + | tha_scene01,139,194,1 duplicate(test) Test NPC 4_F_AGENTKAFRA |
==Adding Scripts== | ==Adding Scripts== | ||
Line 201: | Line 203: | ||
==External Links== | ==External Links== | ||
'''Reference Manuals for scriping commands''' | '''Reference Manuals for scriping commands''' | ||
− | * {{ | + | * {{git|/doc/script_commands.txt}} Original documentation |
'''Sprite lists''' | '''Sprite lists''' | ||
− | * http://nn. | + | * http://nn.ai4rei.net/dev/npclist/ |
'''Color Charts''' | '''Color Charts''' | ||
Line 213: | Line 215: | ||
'''Support, Request and Release''' | '''Support, Request and Release''' | ||
− | * [http:// | + | * [http://herc.ws/board/forum/22-script-support/ Scripting support on Hercules Boards] |
− | * # | + | * #Hercules on irc.rizon.net : Main Hercules channel. |
− | + | ||
[[Category:Scripting]] | [[Category:Scripting]] |
Latest revision as of 22:17, 17 September 2016
Contents |
The Basics
Scripts control all NPCs, warps, mob spawns, shops, and quests you will find in the game--and nearly everything else! Clearly they play a large part in customizing a server, but learning isn't very hard.
Scripts are built up of predefined script commands, all of which can be found in doc/script_commands.txt (for explanations, see Script Commands). Every line should begin with a command and the argument it takes, and must end in a semicolon (or you'll get mapserver errors!). Arguments are usually separated by commas, and are sometimes contained in parentheses () or curly brackets {}. Tabs and proper indentation are standard scripting measures.
Scripts are saved as text (*.txt) files, so all code can be written in Notepad. There are also a lot of scripting programs to use: the most recent and comprehensive one is Vince's eNPC. All defined functions are highlighted, with an autocomplete feature included, and pressing "F1" will display the corresponding explanation for any command.
Structure
NPC
A Script NPC will look something like the following:
prontera,156,145,4 <tab> script <tab> Test NPC <tab> 1_M_MERCHANT,{
The first section is the map location of the NPC, followed by its coordinates in x,y and the direction the NPC will face. Direction numbers are counted counterclockwise in 45º increments, with 0 being the center:
[1][0][7]
[2][ ][6]
[3][4][5]
After the first tab, the type of script is defined. For our purposes, it'll stay "script" for now, but can also be function, shop, or cashshop, for starters.
The name of the NPC is next. You can use up to 24 characters, so make it unique! Any duplicates will cause warnings or errors, and the NPC will just be automatically renamed anyway.
The last number is for the sprite (Ai4rei's sprite list can be found here). It's followed by a comma and open curly bracket, marking the beginning of the script contents. Of course, the script must also end in a curly bracket.
Function
A Function script will look almost identical to:
function <tab> script <tab> Function Name <tab> {
The words "function" and "script" won't change; the name must also be unique. All functions can be called using the "callfunc" command.
Shop
A Shop starts like a normal script:
prontera,156,145,4 <tab> shop <tab> Fruit Store <tab> 1_M_MERCHANT,512:-1,513:1000
The first section defines the map, coordinates, and direction. The word "shop" replaces "script" (alternately, "cashshop" will use Cashpoints instead of Zeny). The name and sprite ID follow, then a comma.
Items in the shop are defined in an ID:Price format. A price of -1 uses the default price in item_db.txt. Be sure the price is not too low, or a you will open a Zeny exploit in your server!
Fundamentals
You can always look up commands that you need--even the best scripters don't have everything memorized. There are a few fundamentals that you should know by heart, though, since they are so commonly used.
Message
*mes "<string>";
This is the most basic command. Start the line with the word mes, then enter the message in quotes (don't forget the semicolon at the end!).
To add color, simply add ^ and the hex code anywhere in the message. A list can be found here.
As an example:
mes "[^FF0000Test NPC^000000]"; mes "Hello!";
Will display:
[Test NPC]
Hello!
Labels, Goto, and End
To create a label, type a label name and a colon at the start of a line. If the label does not end with an "end;" command, everything following the label will be read, so don't forget it between labels!
To go to a label, use the simple "goto" command:
*goto <label>;
Note that there are "special" labels that trigger whenever a specific event occurs. The name usually makes it obvious, but you can find explanations in script_commands.txt. Here is a brief sampling:
OnClock<hour><minute>: OnInit: OnAgitStart: OnAgitEnd: OnTouch: OnPCLoginEvent: OnPCLogoutEvent: OnPCBaseLvUpEvent: OnPCJobLvUpEvent: OnPCDieEvent: OnPCKillEvent: OnNPCKillEvent: OnPCLoadMapEvent:
Menus, Close, and Next
For the entire article, see Menus.
*menu "<option_text>",<target_label>{,"<option_text>",<target_label>,...}; *close; *next;
Menus create a set of options, which trigger labels when selected. The text in quotes is what will be displayed, followed by its respective label. Enter as many choices as you want, and end the last one with a semicolon instead of a comma.
"Close" will close any message window that is open (from "mes" commands).
"Next" will clear the message window, bringing up a fresh screen.
For example:
mes "[Test NPC]"; mes "How are you doing today?"; menu "I am doing okay!",doingokay,"Not doing too well",bad; doingokay: mes "Glad to hear it!"; close; end; bad: mes "Aww, I'm sorry about that."; close; end;
Conditions, Variables, and Set
For the entire article, see Variables.
*if(condition) {<script>;} *else {<script>;}
Conditional statements "if" and "else" are the same as anywhere else. Multiple conditions can be specified: || means or, while && means and. == is equal, != is not equal. Inequalities can be used as well (<, >, <=, >=).
The "else" can be omitted, and the brackets aren't necessary unless multiple commands follow a conditional statement.
The type of variable used is defined in the name. There are permanent and temporary variables, as well as scope (temporary NPC), character, global, and global account. The default type is an integer, and adding $ as a suffix creates a string.
Here are some example types, taken from script_commands.txt:
name - permanent character integer variable name$ - permanent character string variable @name - temporary character integer variable @name$ - temporary character string variable $name - permanent global integer variable $name$ - permanent global string variable $@name - temporary global integer variable $@name$ - temporary global string variable .name - NPC integer variable .name$ - NPC string variable .@name - scope integer variable .@name$ - scope string variable #name - permanent local account integer variable #name$ - permanent local account string variable ##name - permanent global account integer variable ##name$ - permanent global account string variable
The "set" command is used to give a value (or string) to a variable:
*set <variable>,<expression>;
The following script will pick a random number, store it as the temporary scope variable .@random, and display two different messages depending on the result:
set .@random, rand(1,2); if (.@random == 1) { mes "I like you! :D"; } else { mes "I don't like you. Get out of here!"; } close;
Duplicating
It would be a huge waste of time and space to code the same NPC over and over again. By duplication, an NPC can be created in multiple locations.
Take a look at our old Test NPC:
prontera,156,145,4 <tab> script <tab> Test NPC <tab> 1_M_MERCHANT,{
To be able to duplicate this, we will change the heading to this:
- <tab> script <tab> Test NPC#01::testnpc <tab> 1_M_MERCHANT,{
The location doesn't need to be defined in the NPC, since it will be in the duplicates.
The displayed name remains "Test NPC". But since NPC names must be unique, adding #01 separates this one from the rest, which will be #02, #03, etc. Lastly, ::testnpc is the reference name used for duplicating NPCs; this part is not displayed on the screen.
After creating the base NPC, duplicates can be added anywhere to any file, so long as you use the same NPC name:
spl_fild03,150,150,7 <tab> duplicate(testnpc) <tab> Test NPC <tab> 1_M_MERCHANT niflheim,50,50,2 <tab> duplicate(testnpc) <tab> Test NPC <tab> 1_M_MERCHANT tha_scene01,140,190,4 <tab> duplicate(testnpc) <tab> Test NPC <tab> 1_M_MERCHANT
The first part is map,x,y,direction, as you're probably used to by now.
To define a duplicate, the word "duplicate" followed by the NPC, in parentheses, is needed. The last two parameters are the display name and NPC view constant (actual name of the npc sprite, yes, you can change these, too!).
Finished Product
Here is an example using the features explained above:
prontera,156,145,4 script Test NPC::test 4_WHIKEBAIN,{ mes "Hello, how are you?"; mes "I am fine, how are you?"; menu "I am doing okay!",-,"Not doing too good",bad; mes "That's good, I'm glad to hear that"; close; bad: mes "Awww, that makes me a bit ^FF0000sad^000000. Sorry to hear that."; next; mes "Would you like some zeny to help yourself feel better?"; next; menu "Sure, give it to me!",L_zeny,"Naw, No zeny for me",-; close; L_Zeny: mes "I can only give you zeny if you have 10,000 or less."; if (Zeny > 10000) goto toomuch; mes "You have 10,000 zeny or less, I see."; set Zeny,Zeny+10000; next; mes "Hope you feel better!"; close; toomuch: mes "You have over 10,000 zeny, you must feel really good about yourself!"; close; } lhz_dun01,157,285,4 duplicate(test) Test NPC 4_F_AGENTKAFRA hu_fild05,186,210,4 duplicate(test) Test NPC 4_F_AGENTKAFRA yuno_fild07,221,179,4 duplicate(test) Test NPC 4_F_AGENTKAFRA tha_scene01,139,194,1 duplicate(test) Test NPC 4_F_AGENTKAFRA
Adding Scripts
For the entire article, see Adding a Script.
For an NPC to be loaded, it needs to be added to a .conf file. This is typically npc/scripts_custom.conf.
Add a line, and enter your NPC file in the following format:
npc: npc/path/to/script.txt
That's it! You're finished!
External Links
Reference Manuals for scriping commands
- /doc/script_commands.txt Original documentation
Sprite lists
Color Charts
- http://www.immigration-usa.com/html_colors.html
- http://www.december.com/html/spec/colorcodes.html
- Hex triplet
- http://www.colorschemer.com/online.html
Support, Request and Release
- Scripting support on Hercules Boards
- #Hercules on irc.rizon.net : Main Hercules channel.