Script reference Version 1.02

This section is for the reporting of bugs or any sort of issues found during testing. It is also used for the organisation of contributors in general.


Post Reply
quietlyquietly
Peon
Peon
Posts: 35
Joined: 07 Sep 2023, 09:40

Script reference Version 1.02

Post by quietlyquietly »

This is still a work in progress. However, it is mostly done, needs review.
The command guide at the end was done by spending several weeks reading the tmwAthena source code.
I am tied of reading the source code. It is not written in a style that is readable.
I have not figured out all the details of the function delcaration line yet, so that must be done.
Sorry that the indenting is not compatible with this forum.
It also is too long so will be broken up into part1 and part2.

Code: Select all

// Script reference for tmwAthena.

// Version: 1.02
// Author: quietlyquietly
// Date: 2025-04-15
// Update: 2025-04-30

//---- ---- Notes
// Integer Operators
The following operators are accepted.
  // Arith operators
     + add, - subtract, * multiply, / divide
  // Bit operators
     &   bit and
     |   bit or
     ~   bit complement
     >>  right shift by int
     <<  left shift by int
  // Logic operators
     &&  logic and
     ||  logic or
  <v1> + <v2>
  <v1> == <v2>  test equal
  <v1> != <v2>  test not equal

// String Operators
The following operators have been accepted.
  <s1> + <s2>   concatenate
  <s1> == <s2>  test equal
  <s1> != <s2>  test not equal


// Conditional expression 

The conditional ? is not recognized.
  set .@a, (( <expr> )? "was true" : "try again" );
  Gives an error of unexpected ")".
 
Use the if_then_else function to do the same thing.
   set .@a, if_then_else( <expr>, "was true", "try again" );
   
// IF-stmts These are accepted. if ( <cond> ) <stmt> if ( <cond> ) goto L_next;
Some stmts are rejected, because they have never worked properly in an IF-stmt. if ( <cond> ) return; // REJECTED if ( <cond> ) callfunc ... ; // REJECTED if ( <cond> ) callsub ... ; // REJECTED These are NOT accepted in tmwAthena, in spite of being in eAthena docs. if ( <cond> ) { } elsif ( <cond> ) { } else { } // Labels Most labels in the script start with L_ : L_thing: Labels that are events, start with "On". Otherwise, if a label does not start with "L_" or "S_", it will be an error "ugly label". // Label fall through The script compiler does not allow execution to fall through a label. Every code block with a label is a separate block, that can only goto other code blocks. Every such code block must be terminated by an end, return, goto, or menu. A menu, unless the menu explicitly uses "-" for a label, everything after the menu is unreachable, and will be an error as unreachable code. // Literal strings Must entirely be on one line, there is no continuation to next line. // Constructed strings Cannot calculate a character value, because there is no ability to use a calculated value as a char. Cannot encode into ASCII. Have not found any way to encode an integer into "A" to "Z". see chr see ord To decode decimal and hex numbers in strings. 1. Assign using set. Strings are converted to int using atoi(), using conv_num. Numeric are converted to string using print, using conv_str. 2. Just use the value as an arg. Most numeric args are run through conv_num. Most string args are run through conv_str. Have not found any way to encode a value into a hex string. // String functions These are NOT accepted in tmwAthena. getstrlen
Explode function does not use () explode .@b$, "|", .@buf; // Function syntax Do not use the same function name in multiple scripts as there is no expectation that such names will be local. Functions appear at the main level of a script file. There does not seem to be any order dependency, so you can call a function declared later, or even one from another file. This is the function syntax commonly used: function|script|<name> { <body of function> } Often there is a number, the purpose of which is not known. function|script|<name>|400 The call: set .@result, callfunc "<name>", arg1, arg2, arg3, etc. ; To use the parameters: function|script|func1 { set .@x, getarg(0); set .@y, getarg(1); set .@z, getarg(2); <body of function> } The parameters are by reference, so can also set them. function|script|func2 { set .@x, getarg(0); set .@y, getarg(1); <code>
set getarg(0), .@new_x; set getarg(1), .@new_y; return; }
A function needs to have an end, or return. It does not like implied end of function. // Init and Events Init and event labels appear inside of functions. function|script|<name> { <body of function> return; // Will be called starting at this label, at script load time. OnInit: <code> goto some_label; // or end }
Calling a built-in script command. See the command reference for Example. The command usually will have parameters. Some of the parameters are Optional. The parameter list may be enclosed in () for some commands, and may be optional for some commands. Where there are type, mode, or other enum parameters, it is preferred to use the predefined names. For some commands, the predefined names are missing, and the numeric value will have to be used. In such a case please put the name in a comment so these can be found later. //---- ---- From reading tmwAthena script code Much of this is from comments embedded in the script code. A chunk of code is a series of lines, with a terminator. The following scripts: npc, item, magic, functions (the function directory?) are allowed to have as code: chunk of code terminator. The following scripts: events are allowed to have as code: comment(s) label: chunk of code terminator. Terminators are: goto <label> return close menu <menu_selections> end mapexit shop destroy Prefix operators + - ! ~ Infix operators + - * / % ^ & | << == != < > <= >= && || Script body is delimited by: { <code> } Constructs that are allowed to have { } delimited script body: function // Data converstion The script execution often uses these functions when a var value is used, or assigned to another var. conv_str: Used as a string. Int value is printed as a string. Otherwise returns a reference to the string. conv_num: Used as a numeric value. Default is to abort. String is converted to integer using atoi(). Integer returns the integer value. Positive type returns the integer value. conv_script: Used as a script. Script returns a script reference.
quietlyquietly
Peon
Peon
Posts: 35
Joined: 07 Sep 2023, 09:40

Re: Script reference Version 1.02

Post by quietlyquietly »

Part 2

Code: Select all

//---- ---- Builtin functions identified from reading script code.

//---- Var assign support

get <var>, <npcid>
The <npcid> (not optional) can be a name or numeric id.
Return the <var> value read from the NPC, or player.
Return -1 when access fails.
Return 0, or empty string, when var does not exist.
If <var> has a "$" postfix then it is a str var, conv_str will be
applied, where integer will be printed to a string.

The possible <var> cases are handled as follows:
   If <var> is a ScriptDataParam then:
   {
       This form cannot access the player vars, the <npcid> is required.
       If <npcid> is a string then
       {
         The scope of the <var> (which NPC has values read) is
         determined by <npcid> used as name.
       }
       else
       {
         The <npcid> is converted to numeric.
         If it is greater than 2000000 then the scope is that of the id.
         If it is greater than 150000 it is used as an NPC id,
	 and the scope that of the NPC bl_id.
         Else it returns and does nothing.
       }
       return <var> from the scope.
   }
   else
   {
     // Normal case
     If <var> prefix is ".@" then error "illegal scope".
     If <var> prefix is "." then
     {
           If <npcid> is a string then
	     That <npcid> is used as a NPC name, and the var scope is that NPC.
	   else
	     That <npcid> is used as a numeric NPC id, and the var scope is that NPC.
     }
     else if <var> prefix is "$" then
     {
           The <var> scope is global.
	   Error "illegal scope".
     }
     else
     {
           // <var> prefix is "@" "#" "##"
           If <npcid> is a string then
	     That <npcid> is used as a map nick name which is the <var> scope.
	   else
	     That <npcid> is used as a numeric map id which is the <var> scope.
     }
   }
   
If <var> is string then { Return read as string. } else { If <var> prefix is "#" "##" and have scope then { If <var> prefix is "##" then read player ## account data. else read player # account data. } else { read player scope } Return as numeric. } Example: if (.@n == get(.rsize, "_N-Alchemy")) set <var>, <expr>, <npcid> set ( <var>, <expr>, <npcid> ) Optional <npcid>, which can be a name or numeric id. Set the <var> in the NPC, or player, with the value from <expr>. If <var> is an integer, conv_num will be applied, the value will be converted to an integer, where strings will converted to integer using atoi(); If <var> has a "$" postfix then it is a str var, conv_str will be applied, where integer will be printed to a string. Accessing player vars requires player RID. The possible <var> cases are handled as follows: If <var> is a ScriptDataParam then: { If <npcid> is present then { If <npcid> is a string then { The scope of the <var> (which NPC has values changed) is determined by <npcid> used as a nick name. } else { The <npcid> is converted to numeric. If it is greater than 2000000 then the scope is that of the id. If it is greater than 150000 it is used as an NPC id, and the scope that of the NPC bl_id. Else it does nothing and returns. } } else { The scope is that of the player. } The <expr> value is passed through conv_num, and assigned to <var> as a numeric. return } else { // Normal case If <var> prefix is "$" { The <var> scope is global (no scope). } else { // <var> prefix is "." "@" ".@" If <npcid> is present then { If <var> prefix is ".@" then error "illegal scope". If <var> prefix is "." then { If <npcid> is a string then That <npcid> is used as a NPC name, and the var scope is that NPC. else That <npcid> is used as a numeric NPC id, and the var scope is that NPC. } else { If <npcid> is a string then That <npcid> is used as a map nick name to determine the scope of <var>. else That <npcid> is used as a numeric map id to determine the scope of <var>. } } else { // <npcid> is not present // Normal <var> scope determinations are applied If <var> prefix is ".@" then assign to local scope, "." then assign to NPC scope, else assign to player scope. } } } Example: set .@area, (.@x2 - .@x1) * (.@y2 - .@y1) Example: set .master, BL_ID, .@puppet; set .lifetime, (@spellpower*9)+60000, .@puppet; //---- Array support setarray <dest>, <values> ... setarray <dest>[ <first_index> ], <values> ... setarray <dest>, <npc_name>, <values> ... setarray <dest>[ <first_index> ], <npc_name>, <values> ... Setup an array with values. Optional <npc_name>. When <dest> is an NPC type ("."), must specify which NPC using <npc_name>. When <npc_name> is "this" or "oid", then will use the script NPC (OID). Existing examples use NPC names like "_N-Alchemy", and "_N-Pumpkin". If <dest> first char is not "$", "@", "." then error "illegal scope". Thus allows <dest>: "$", "$@", "@", "." or ".@". Player <dest> requires player RID. If the <dest> is ".@" then the <values> will be copied as they are, otherwise the <values> will be converted to the <dest> type. The number of array values is limited to 256 in this function, even though arrays are supposedly limited to 128 elements. cleararray <dest>, <value>, <size> Clear an array to a set <value>. The <size> is the number of array elements that are set to <value>. The <size> should be limited to 128 If <dest> first char is not "$", "@", "." then error "illegal scope". Thus allows <dest>: "$", "$@", "@", "." or ".@". Player <dest> requires player RID. If the <dest> is ".@" then the <values> will be copied as they are, otherwise the <values> will be converted to the <dest> type. BUG: If the <dest> is ".@", then the "cleararray" will try to access a list of values, as if it was "setarray". The $AARG(i) should have been $AARG(1). This is not a feature, and will be fixed sometime. getarraysize <src> Returns the number of array elements, which is last index + 1; If <src> first char is not "$", "@", "." then error "illegal scope". Thus allows <dest>: "$", "$@", "@", "." or ".@". getelementofarray <src>, <index> Return the array element at [ <index> ]. The <index> is converted to numeric. If <index> is not in range 0 to 255 then error "param2 illegal number" and returns 0. if <src> is not a var then error "param1 not named". array_search <key>, <srcarray> The <srcarray> is the array to be searched for <key> value. Returns the index ( 0 to 255 ) where the <key> is found. If the <key> is not found, then returns -1. If <src> first char is not "$", "@", "." then error "illegal scope". Thus allows <src>: "$", "$@", "@", "." or ".@". //---- Math rand ( <num> ) Return random number, 0 to (<num> - 1). rand ( <min>, <max> ) Return random number, <min> to <max>. max <var>, <var> Any number of <var>. Return numeric max of all <var> max <varname> Return numeric max of all values in <varname>. This only makes sense if <varname> is an array. Only valid for <varname> prefix of ".", "@", and "$", otherwise "illegal scope". min <var>, <var> Any number of <var>. Return numeric min of all <var>. min <varname> Return numeric min of all values in <varname>. This only makes sense if <varname> is an array. Only valid for <varname> prefix of ".", "@", and "$", otherwise "illegal scope". average <var>, <var> Any number of <var>. Return numeric average of all <var>. sqrt <var> Return square-root of <var> (uses sqrt function). cbrt <var> Return cube-root of <var> (uses cbrt function). pow <var>, <var> Return power result, using pow( <var>, <var> ). //---- String chr <val> Convert <val> to ASCII char. Return string( conv_num( <val> ) ) ord <val> Convert <val> to Int value of ASCII char. Return numeric value of conv_str( first char of <val> )[0]. explode <dest>, <src>, <separator> Separate an encoded string into its parts, using a separator char. The <dest> must be an array, indexed [ 0 to 127 ]. If the <dest> is a string array, then the substr will be stored. If the <dest> is a numeric array, then atoi( substr ) will be stored. The <dest> cannot be permanent var "", "#", "##". If <dest> first char is not "$", "@", "." then error "illegal scope". Thus allows <dest>: "$", "$@", "@", "." or ".@". The <src> is the source string. The <separator> is the separator char, only the first char is used. The "implode" function is missing in tmwAthena. Must use <str1> + ":" + <str2> + ":" + <str3>, etc. l <str> Translatable string. Return conv_str <str>. The Translation is a TODO. //---- Messages mes <str> Display message. Defaults to "". Requires player RID. mesq <str> Display message with quotes around it Defaults to "". Requires player RID. mesn <str> Display message with [ ] around it. Must be NPC name. Defaults to the NPC name. Requires player RID, and NPC OID. message <player_name> <str> Display message <str> to player <player_name>.
smsg <str> smsg <type>, <str> smsg <type>, <str>, <player_name> Optional <player_name>. Will send the server message <str> to the <player_name>, or by default to the invoking player (RID). Optional <type>. The <type> must be 1 to 99, otherwise will default to 0. debugmes <str> Print "script debug: <rid> <oid>:" <str> wgm <str> Send message to GM, using tag "[GM]". gmlog <str> Send message to log, using tag "{SCRIPT}". Requires player RID. title <str> Sent to the invoking player client a title line. Requires player RID. Example: title "Alchemy Lab" Example: title "Game Rules" announce <str>, <to> Announcement from the server, GM, used to notify everyone. Only use this if you want everybody in the world to get the message. If <to> & 0x08 then From script NPC (OID). The <to> values: 0: Send as GM message using intif_GMmessage, on all map servers. 1: Send ALL_SAMEMAP 2: Send AREA 3: Send SELF else: Send ALL_CLIENT This is used in every setup battle to make announcements. Example: announce "Doomsday : The Final Showdown will start shortly! Make way to the Master Chamber at once!", 0; mapannounce <mapname>, <str>, <to> Announcement in setup battles, to everyone on the map <mapname>. Send message <str> to each player on the map <mapname>, using clif_GMmessage (..., (<to> & 0x10) | SELF ). The <to> is broken and ineffective, because mapannounce does ( <to> & 0x10 ) and clif_GMmessage does ( & 0x07), making <to> have no contribution. So it seems that the message will always be to SELF. However, all the scripts use <to>=0, and this sends the message to all on that map. This is used in every setup battle to make announcements. Example: mapannounce "027-4", "The battle is lost.", 0; Example: mapannounce "027-4", "General Razha is defeated.", 0; //---- Menu, input, dialog menu <menu entry> One or more <menu entry>, separated by comma. Where each <menu entry> is: <str>,<label> . Menu display of <str>. When <str> is empty, then that menu entry is not displayed. When a menu entry is selected then a GOTO <label> is performed. Sets menu value to index of selection, 1 to num of choices. If menu selection is cancelled, then state is END, and menu value is 0xFF. Requires player RID. next Display next button. Wait until button pressed. Requires player RID. close Display close button. Wait until button pressed, then close dialog. Sets state to END. If has no dialog then clif_npc_action( sd, st->oid, 5, 0, 0, 0 ) Requires player RID. close2 Does same as close, but does not check for callfunc and callsub, and sets state to STOP. Display close button. Wait until button pressed, then close dialog. If has no dialog then clif_npc_action( sd, st->oid, 5, 0, 0, 0 ) Requires player RID. clear Clear the dialog. Requires player RID. input <variable> Uses dialog box to input integer or string. Checks that integer is not < 0. Does not implement the min, max of eAthena. Requires player RID. requestitem <dest>, <amount> Optional <amount> The <amount> must be between 1 and 16, otherwise it will be defaulted to 1. The <dest> must be an array, indexed [ 0 to 127 ]. The <dest> cannot be permanent var "", "#", "##". If <dest> is first char is not "$", "@", "." then error "illegal scope". Thus allows <dest>: "$", "$@", "@", "." or ".@". Requires player RID. Uses clif_npc_action( id, 10, <amount>, 0, 0 ), query the client for list of items. For each item that is in inventory, put the item name in the array. requestlang <dest> Requires <dest> to be string. Requires player RID. Uses clif_npc_action( id, 0, 0, 0, 0 ), query the client for language. Set <var> with language str. //---- Conditional constructs void Does nothing, successfully. goto <label> Labels must start with "L_", or "S_". if_then_else <bool_expr>, <true_result>, <false_result> When <bool_expr> is TRUE, it returns the <true_result>, otherwise it returns the <false_result>. Does not have the "( )? : " construct of eAthena, must use if_then_else. if <bool_expr> Executes the statement following if the <bool_expr> is true. Does not recognize { } on IF-stmt.
else When the preceding IF-stmt was FALSE, it executes the statement following. elif <bool_expr> When the preceding IF-stmt was FALSE, it executes an IF using the <bool_expr> and the statement following. foreach <each_mode>, <mapname>,<x0>,<y0>, <x1>,<y1>, <event>, <player_mapid> Optional <player_mapid>. If <player_mapid> is present then will use that for player, otherwise will use the invoking player (RID), which requires player RID. For each item on the <mapname> within the area <x0>,<y0>, <x1>,<y1>, perform the <event>. The <event> is an event label, such as "npcname::OnNearbyPlayer", where the npcname is the npc function that the event label appears within; This can use any label that starts with "On". The <each_mode> values: 0: For each Player. 1: For each NPC. 2: For each monster. 3: Any, All ? //---- Functions callfunc "<name>", <args> Optional <args>. Call script function. Passes return value. The <arg> are passed by reference. callsub "<name>", <args> Optional <args>. The <arg> are passed by reference. Call script sub, no return value. call "<name>", <args> Call script function, or some other kind of function. Execution can do "callfunc", or "callsub" dynamically. BUG: The stack copy operations are not commented out as they are in both "callfunc" and "callsub". This function may crash the script due to call stack corruption. getarg( <num> ) Get the function arg indexed by <num>, where the first is (0). Can only be used in function. There must be a callfunc or callsub invoking the function. Cannot be used with event or init label. getarg( <num>, <default> ) Get the function arg indexed by <num>, where the first is (0). Can only be used in function. There must be a callfunc or callsub invoking the function. Cannot be used with event or init label. If cannot get the arg, then use the default value. return <value> Optional return value. Deprecated to have return outside of a callfunc or callsub invocation. end End the script. Error msg ("deprecated") if in callsub or callfunc execution. Should close any dialog before executing "end". //---- Map distance <id0>, <id1>, <dist_mode> Optional <dist_mode>, which defaults to 0. The <id0> and <id1> are map_id. Only mode==0 is implemented. The <dist_mode> values: 0: Return the distance between the <id0> and <id1>. Only works for map_id on a single map. Example: if (distance(BL_ID, @target_id) >= (@spellpower/30)+2) target <source>, <target>, <cond_flags> Optional <cond_flags>, which defaults to 0. The <source> and <target> are map_id. The <cond_flags> are bits that select condition operations, one or more may be present. The <cond_flags> bit values (these are OR'ed together using "|"): 0x01: when target is in visible range of source. 0x02: when target is in attack range of source. 0x04: when source has walkable path to target. 0x08: TODO. 0x10: when target can be attacked by source (killer, killable, etc.). 0x20: when target is in line-of-sight from source (battle_check_range). Returns the OR'd <cond_flag> values from each of the tests that are true. Example: if ( (target BL_ID, @target_id, 0x02|0x04) == 0x02|0x04 ) // when target is in attack range and there is a walkable path areawarp <from_mapname>,<x1>,<y1>,<x2>,<y2>, <to_mapname>,<x3>,<y3> Move all in the <from_mapname> area box, to the <to_mapname>,<x3>,<y3> location. Does not seem to have the eAthena enhancements, but not sure. mapwarp <src_mapname>, <dest_mapname>,<x1>,<y1> Foreach player on the <src_mapname>, warp them to the <dest_mapname>,<x1>,<y1>. getusers <mode> Return the count of users on the map. If <mode> & 0x08 then the script NPC map, else the invoking player map. The <mode> values: 0: Return the NPC map user count. 1: Return the world_user_count. 0x80 Return the player map user count. Example: getusers(1) getmapusers <mapname> Return the count of users on the map. Does not count players that HIDE. If <mapname> has an error then return -1. Example: if (getmapusers("035-1") < 3) ... getareausers <mapname>,<x0>,<y0>, <x1>,<y1>, <living> Return the count of players in a map area <mapname>,<x0>,<y0> to <x1>,<y1>. Optional <living>, default 0. If <living> == 1 then only count alive players. Does not count players that HIDE. If <mapname> has an error then return -1. Example: if (getareausers("025-4", 26, 63, 60, 97) < 1) getareadropitem <mapname>,<x0>,<y0>, <x1>,<y1>, <item_id>, <del_item> Return the count of drop items in a map area <mapname>,<x0>,<y0> to <x1>,<y1>. The <item_id>, can be by name or id number. Optional <del_item>, default do not delete. If <mapname> has an error then return -1. If <del_item> is true then remove the items after counting them. Example: // Syntax error if not setting a variable. set $@dummy_var, getareadropitem("052-1", 1, 1, 98, 78, 873, 1) + getareadropitem("052-1", 1, 1, 98, 78, 874, 1) + getareadropitem("052-1", 1, 1, 98, 78, 875, 1); set $@dummy_var, 0; sendcollision <mapname>, <value>, <x1>,<y1>, <x2>,<y2>, <player_id> sendcollision <mapname>, <value>, <x1>,<y1>, <player_id> Change the map collision to <value> for the area <mapname>,<x1>,<y1>, <x2>,<y2>, and player <player_id>. The <value> is 0: WALKABLE 1: UNWALKABLE. Optional <x2>,<y2>, <player_id>, Requires player RID. This can be used to block access to special areas for anyone except those who are allowed access. Example: sendcollision "009-8", 1, 62, 105, 77, 123; // not a party member iscollision <mapname>,<x>,<y> Return 1 if the <mapname>,<x>,<y> position is UNWALKABLE. getmapmaxx <mapname> Return the max x coord. of a map. getmapmaxy <mapname> Return the max x coord. of a map. getmaphash <mapname> Return the hash of a map. getmapnamefromhash <hash> Return the mapname corresponding to that hash. mapexit Set run flag off. Do not know what that does. setmapflag <mapname>, <index> Set the <mapname> map flag[ <index> ] to 1. removemapflag Set the <mapname> map flag[ <index> ] to 0. getmapflag Return the <mapname> map flag[ <index> ]. If map flag cannot be read, return -1. mapmask <mask>, <saveflag> The <mask> is numeric arg, limited to int (32 bit). Optional <saveflag>. If <saveflag> is present (actual value is not checked) { If player (RID) is present then Set map mask of the map the player is on to <mask>. else if script NPC (OID) is present then Set the mask of the map the NPC is on to <mask>. } Requires player RID. Will also send the mask to the player client. The mask is just set and read by some scripts, like a boolean array. Example from Celestias tea party: mapmask 1 | 2 | 8 getmask Return the map mask of the player map, or NPC map. { If player (RID) is present then Return the map mask of the map the player is on. else if script NPC (OID) is present then Return the mask of the map the NPC is on. else Return -1 } pvpon <mapname> Turn on PVP for map <mapname>. If ranking is enabled then update players (and their clients) on the map. pvpoff Turn off PVP for map <mapname>. If ranking is enabled then update players (and their clients) on the map. setpvpchannel <pvpchannel> Set the invoking player pvpchannel to <pvpchannel>. If <pvpchannel> < 0 then it is set to 0. Requires player RID. getpvpflag <mode>, <player_id> Return pvp information. Optional <player_id>. If <player_id> is not present then will access invoking player, which requires player RID. The <mode> values: 0: Return the pvpchannel of the player. 1: Return TRUE if the invoking player had HIDE set. //---- Item interactions makeitem <item>, <amount>, <mapname>,<x>,<y> The <item> can be id number, or name string. Make the <item> * <amount>, at the map location. getitemlink <item_name> Return the name_id for the item <item_name>. Return "Unknown Item" when it does not recognize the item. When printed in a message, this will give the item description. Example: mes "... to create a " + getitemlink("ConcentrationPotion") + " ..."; Example: mes " ["+ getitemlink(@alchlab_items$[0]) +"]"; Example: if(getitemlink($@DYE_items$[$@w]) == "Unknown Item") goto L_Fail; //---- Generic actor interactions injure <source>, <target>, <damage> Display damage. Applies battle_damage ( <source>, <target>, <damage> ). Example: injure .caster, @target_id, .@damage; // arrow hail isloggedin <map_id> Return true if the <map_id> is valid player. This checks if map_id2sd, which is only used for players, returns a value. Example: set .master, BL_ID, .@puppet; // save creator addnpctimer 4000-(@spellpower*9), .@puppet$+"::OnSummon"; .... OnSummon: if (!(isloggedin(.master))) destroy; // no longer valid Example: set @target_id, getcharid(3, @args$); if (@target_id < 1 || !(isloggedin(@target_id)) set @target_id, BL_ID; // fallback to self Example: // this is a dirty trick to check if the target is a player if(@target_id != BL_ID && isloggedin(@target_id)) emotion <emo_type>, <player_id> Display an emotion above the script NPC, or player. Optional <player_id>. If <player_id> is present then display the emotion only to that player (RID). else if <player_id> == "self" and RID is present then display the emotion over the invoking player else display the emotion above the script NPC for eveyone in the AREA. These are defined in serverdata/world/map/db/const.txt. The <emo_type> values (0 to 200): EMOTE_HAPPY EMOTE_GRIN EMOTE_TONGUE EMOTE_WINK EMOTE_SURPRISE EMOTE_SAD EMOTE_UPSET EMOTE_SUSPICIOUS EMOTE_PERTURBED EMOTE_AFRAID EMOTE_FACEPALM EMOTE_DISGUST EMOTE_EVIL EMOTE_VICIOUS EMOTE_DEAD EMOTE_MEOW //---- Player interactions getcharid <mode>, <player_name> Return the selected info of the player character <target>. Optional <player_name>, which is a player name. If <player_name> is not present, then the invoking player (RID) will be used, and then will require the invoking player (RID). If player error then return -1. The <mode> values: 0: // char_id 1: // party_id 2: // guild_id (deprecated, returns 0) 3: // account_id strcharinfo <mode>, <player_name> Optional <player_name>, which is a player name. If <player_name> is not present, then the invoking player (RID) will be used. and then will require the invoking player (RID). If player error then error "player not found", and return -1. The <mode> values: 0: $ // char_name 1: $ // party_name 2: $ // guild_name (deprecated, always returns "" ) getmap <map_id> Optional <map_id>. Return the player map, which requires player RID. If <map_id> is specified, return it's map instead. getx Return the player position x. Requires player RID. gety Return the player position y. Requires player RID. getdir Return the player direction facing. Requires player RID. isat <mapname>,<x>,<y> Return true if the player is at that location. Requires player RID. isin <mapname>,<x0>,<y0>, <x1>,<y1> Check if the player is in the map area. Return 1 if the player is in the area, otherwise 0. Requires player RID. warp <mapname>,<x>,<y> Move the player to that location. Does not seem to have the eAthena enhancements, but not sure. Requires player RID. isdead Return 1 if player is dead, otherwise 0. Requires player RID. heal <hit_points>, <spell_points>, <item> Optional <item>. Will apply heal <hit_points>, <spell_points> to invoking player (RID). If <item> is TRUE, then will apply itemheal to the player instead, which is intended for item scripts (like potions) that heal the player. Requires player RID. Example: heal 10000,10000 Example: heal -10,0 // lose health from pumpkin explosion Example: heal -Hp,0 // kill the player getexp <exp>,<job> Give the <exp>, <job> to the player. Increase only, if <exp> < 0 or <job> < 0 then does nothing. Requires player RID. getinventorylist Makes a list of the player inventory, in some predetermined arrays. Requires player RID. Because the arrays are not automatically cleared, it is not safe to get the array size from the output. Use the @inventorylist_count instead. @inventorylist_count : number of items put into the arrays. Arrays that are created: @inventorylist_id[] : item id. @inventorylist_amount[] : item amounts. @inventorylist_equip[] : item is equipped. countitem <item> The <item> can be id number, or name string. Returns the amount of <item> in the invoking player inventory. Requires player RID. getitem <item>, <amount>, <to_player> The <item> can be id number, or name string. Optional <to_player>. If <to_player> is present, then the <item> will be given to that player, otherwise it will be given to the invoking player (RID). Requires player RID. Gives the <item> * <amount> to the player inventory. If it fails to put it into the player inventory, then it is put on the map floor. delitem <item>, <amount> The <item> can be id number, or name string. Take the <item> * <amount> from the invoking player inventory. Requires player RID. checkweight <item>, <amount> Check that adding <item> * <amount> will not exceed the maximum weight. Return 0 for exceed, and 1 for OK. Requires player RID. getequipid <equip_slot>, <player_id> Return the item_id of the equiped item. Return 0 if there is no item. Optional <player_id> If <player_id> is not present then will access invoking player, which requires player RID. If there is a player_id error, return -1. This uses its own equip enum values, 1 to 11. The <equip_slot> values: 1: HAT 2: MISC1 3: SHIELD 4: WEAPON 5: GLOVES 6: SHOES 7: CAPE 8: MISC2 9: TORSO 10: LEGS 11: ARROW unequipbyid <equip_slot> Unequip the slot, on the invoking player. Requires player RID. This uses the EQUIP enum values, 0 to 11. The <equip_slot> values from EQUIP: 0: MISC2 1: CAPE 2: SHOES 3: GLOVES 4: LEGS // also called "head bottom" 5: TORSO // also called "head middle" 6: HAT // also called "head top" 7: MISC1 8: SHIELD 9: WEAPON 10: ARROW 11: COUNT // not allowed for unequipbyid nude Unequip all, on the invoking player. Requires player RID. getlook <look> Examine the player appearance (hair, etc.). Return numeric code. Return -1 on error. Requires player RID. The <look> values: 1: HAIR 2: WEAPON 3: HEAD_BOTTOM 4: HEAD_TOP 5: HEAD_MID 6: HAIR_COLOR 7: CLOTHES_COLOR 8: SHIELD 9: SHOES (not implemented) setlook <look>, <val> Set player <look> to the numeric <val>. See getlook for the <look> values. Requires player RID. sc_start <type>, <tick>, <val1>, <target> Start suffering from an abnormal condition. The <type> identifies the type of condition, or cooldown. The <val1> is passed as a parameter of the <type>, see the chart below. Optional <target>. The <target> specifies who the effect is applied to, otherwise apply effect to invoking player (RID). // These always have <ticks> in ms. // It would break the cooldown since many spells have cooldowns less than 1s. The <type> values: 199: SC_PHYS_SHIELD // `Protect' spell, reduce damage (val1: power) 197: SC_MBARRIER // Magical barrier, magic resistance (val1: power (%)) 133: SC_SLOWMOVE // slows down movement 134: SC_CANTMOVE // stops all movement 71: SC_COOLDOWN // Spell cooldown 72: SC_COOLDOWN_MG // Mana Guardian cooldown 73: SC_COOLDOWN_MT // Mana Tyrant cooldown 74: SC_COOLDOWN_R // Kaflosh cooldown 75: SC_COOLDOWN_AR // Frillyar cooldown 76: SC_COOLDOWN_ENCH // Enchanter cooldown 77: SC_COOLDOWN_KOY // Koyntety cooldown 78: SC_COOLDOWN_UPMARMU // Upmarmu cooldown 79: SC_COOLDOWN_SG // Stone Golem cooldown // For these types, if the <ticks> in ms are less than 1 second (1000 ms), // the <ticks> will be interpreted as in seconds. // This is for old script compatibility with speed potion, atk potion, and matk potion, // which used to use seconds. 105: SC_ATKPOT // item script 106: SC_MATKPOT // `Matk' spell from items (val1: power) 35: SC_WEIGHT50 // ? sort of used 36: SC_WEIGHT90 // definitely used 37: SC_SPEEDPOTION0 // item script 70: SC_HEALING // item script 132: SC_POISON // bad; actually used 14: SC_SLOWPOISON // item script 193: SC_PHYS_SHIELD_ITEM // `Protect' spell from items, reduce damage (val1: power) can't be cancelled with detsanc 194: SC_HIDE // Hide from `detect' magic (PCs only) 194: SC_SHEARED // Has been sheared (mobs only) 195: SC_HALT_REGENERATE // Suspend regeneration 196: SC_FLYING_BACKPACK // Flying backpack 198: SC_HASTE // `Haste' spell (val1: power) 200: MAX_STATUSCHANGE Example: sc_start SC_COOLDOWN, 500, 0, BL_ID; Example: sc_start SC_HALT_REGENERATE, if_then_else(.@dark, 5000, 10000), 0; sc_end <type>, <target> End suffering from an abnormal condition. The <type> identifies the type of condition, or cooldown (see sc_start). Optional <target>. The <target> specifies who is being applied to, otherwise apply to invoking player (RID). sc_check <type>, <target> Return 1 if specified abnormal condition is active, otherwise 0. The <type> identifies the type of condition, or cooldown (see sc_start). Optional <target>. The <target> specifies who is being checked for the effect, otherwise check the invoking player (RID). Example: if (sc_check(SC_HALT_REGENERATE,@target_id)) end; bonus <bonus_type>, <value> Apply ability bonus for equipment, for use in an item script. Requires player RID. Some of the bonus apply to the player, some apply to equipment uses. Those that apply to arrows (marked as (sword, arrow)) keep the arrow ability separate from the sword, and determine which by passing an arrow_flag. These <bonus_type> are conditional on NOT arrow_flag, execept where (sword, arrow) indicates separate abilities. It does not appear to be possible to pass the the arrow_flag from this command, so these will only directly affect the sword. The commands override_attack, setopt2, unequipbyid, and nude call pc_calcstatus, which when it encounters an arrow in the inventory, sets the arrow_flag and runs a special script. These are sent to the player client. Many of these fields are also accessible as special player predefined vars. The <bonus_type> values: 13: STR // + <value>, strength 14: AGI // + <value>, agility 15: VIT // + <value>, vitality 16: INT // + <value>, intelligence 17: DEX // + <value>, dexterity 18: LUK // + <value>, luck 1088: ALL_STATS // STR,AGI,VIT,INT,DEX,LUK + <value> 1089: AGI_VIT // AGI,VIT + <value> 1090: AGI_DEX_STR // AGI,DEX,STR + <value> 6: MAXHP // + <value>, player fully healed HP 8: MAXSP // + <value>, player fully charged mana 1004: MAXHPRATE // + <value>, ?? HP recover rate 1005: MAXSPRATE // + <value>, ?? mana recover rate 1016: HP_RECOV_RATE // + <value> 1017: SP_RECOV_RATE // + <value> 25: MAXWEIGHT // = <value> 26: MAXWEIGHT_ADD // + <value> 70: DEAF // = 1 1000: ATTACKRANGE // + <value>, distance that attack can reach (sword, arrow) 1014: BASE_ATK // + <value>, base attack that modifiers add to 41: ATK1 // + <value>, physical attack 1 42: ATK2 // + <value>, physical attack 2 43: MATK1 // + <value>, magic attack 1 44: MATK2 // + <value>, magic attack 2 45: DEF1 // + <value>, physical defense 1 46: DEF2 // + <value>, physical defense 2 47: MDEF1 // + <value>, magic defense 1 48: MDEF2 // + <value>, magic defense 2 49: HIT // + <value>, ability to hit (sword, arrow) 50: FLEE1 // + <value>, ability to flee 1 51: FLEE2 // + <value> * 10, ability to flee 2 52: CRITICAL // + <value> * 10, ability to deliver critical hit (sword, arrow) 1019: CRITICAL_DEF // + <value> 1050: ADD_SPEED // - interval( <value> ), speed boost 1018: SPEED_RATE // = min( speed_rate, 100 - <value> ), ?? 1029: SPEED_ADDRATE // = speed_add_rate * (100 - <value>) / 100, ?? 1087: SPEED_CAP // = max( speed_cap, interval(<value> ) highest value is slowest speed 53: ASPD // - interval( <value> ), ?? 1015: ASPD_RATE // aspd_rate = 100 - <value>, ?? 1030: ASPD_ADDRATE // = aspd_add_rate * (100 - <value>) / 100, ?? 1022: DOUBLE_RATE // = max( double_rate, <value> ) 1023: DOUBLE_ADD_RATE // + <value> 1025: MATK_RATE // + <value> 1028: ATK_RATE // + <value> 1038: PERFECT_HIT_RATE // = max( perfect_hit_rate, <value> ) 1039: PERFECT_HIT_ADD_RATE // + <value> 1040: CRITICAL_RATE // + <value> 1051: HIT_RATE // + <value> 1052: FLEE_RATE // + <value> 1053: FLEE2_RATE // + <value> 1054: DEF_RATE // + <value> 1055: DEF2_RATE // + <value> 1056: MDEF_RATE // + <value> 1057: MDEF2_RATE // + <value> 1091: DEADLY_STRIKE_RATE // = max( deadly_strike, <value> ) 1093: BASE_WEAPON_DELAY_ADJUST // + interval( <value> ) Example: bonus bStr, 10; bonus bAtkRange, 1; bonus2 <bonus_type>, <rate>, <per> Add to player ability for equipment, for use in an item script. Requires player RID. These bonus apply to the player. These <bonus_type> are conditional on NOT arrow_flag, which cannot be set from this command. These are sent to the player client. The <bonus_type> values: 1061: HP_DRAIN_RATE // + ( <rate> ), + ( <per> ) 1062: SP_DRAIN_RATE // + ( <rate> ), + ( <per> ) skill <skill_id>, <level>, <skill_flag> Modify a skill level of the invoking player. Requires player RID. Optional <skill_flag>, default 1 (increase only). The <level> values are (0 to 100). The <skill_flag> values: 0: set = <level> // can set skill level to 0 1: set = max( current_level, <level> ) // can only increase skill The <skill_id> values (1 to 398): // Basic skills. 1: NV_EMOTE 2: NV_TRADE 3: NV_PARTY 45: AC_OWL // Mallard's Eye 175: NPC_SELFDESTRUCTION 178: NPC_POISON 198: NPC_SUMMONSLAVE 199: NPC_EMOTION // magic skills 340: TMW_MAGIC 341: TMW_MAGIC_LIFE 342: TMW_MAGIC_WAR 343: TMW_MAGIC_TRANSMUTE 344: TMW_MAGIC_NATURE 345: TMW_MAGIC_ETHER 346: TMW_MAGIC_DARK 347: TMW_MAGIC_LIGHT // focusable skills 350: TMW_BRAWLING 351: TMW_LUCKY_COUNTER 352: TMW_SPEED 353: TMW_RESIST_POISON 354: TMW_ASTRAL_SOUL 355: TMW_RAGING setskill <skill_id>, <level> Set a skill level of the invoking player. Requires player RID. The <skill_id> values (1 to 398) are the same as the skill command. The <level> is limited to (0 to 100). The skill is set = <level>, unconditionally. getskilllvl <skill_id. Return the current level of the skill <skill_id>, for the invoking player. The <skill_id> values (1 to 398) are the same as the skill command. Requires player RID. poolskill <skill_id> Activate the poolable skill <skill_id> for the invoking player. Requires player RID. See the skill list in the skill command. unpoolskill <skill_id> Deactivate the poolable skill <skill_id> for the invoking player. Requires player RID. See the skill list in the skill command. getactivatedpoolskilllist Read the activated pool skills to predetermined arrays. Requires player RID. The arrays are not cleared, so always use skilllist_count. @skilllist_count : number of skills put into the arrays. Arrays that are created: @skilllist_id[] : skill id. @skilllist_level[] : skill level. @skilllist_flag[] : skill flags. @skilllist_name[] : skill name Example: getactivatedpoolskilllist; getunactivatedpoolskilllist Read the unactivated pool skills to predetermined arrays. Requires player RID. Same arrays as getactivatedpoolskilllist. Example: getunactivatedpoolskilllist; resetstatus Reset all the invoking player state. Only debug and stat_reset functions use this. This removes all the player accomplishments, resets their attributes to 1, so DO NOT DO THIS. Requires player RID. overrideattack overrideattack <attack_delay>, <attack_range>, <icon>, <look>, <event>, <charges> Setup a magic attack spell, for use in magic scripts. Optional <attack_delay> etc.. Optional <charges>, default to 1. The command without parameters will discharge the override, returning to normal. Sets the player state to use the <attack_delay>, <attack_range>, <icon>, <look>, and to use <event> for the magic attack. Requires player RID. Example: setarray @wandspell[0], .WandsAnim[.@wand_loop], // wand anim/id ((.@pwr * BaseLevel * 2 / 3) / 15 + 2), // wand cost (.@pwr * (@spellpower * (11-.@pwr) / 30)), // wand dmg (((200 - (Agi+Agi2)) * 1200) / 200), //delay (.@pwr + (@spellpower / 10)); // charges overrideattack @wandspell[3], 3, ATTACK_ICON_GENERIC, @wandspell[0], strnpcinfo(0)+"::OnAttack", @wandspell[4]; set @wandspell[4], @wandspell[4] - 1; marriage <partner> The invoking player and the player <partner>, each have their partner_id set to the other. Returns 1 if successful, otherwise returns 0. divorce The invoking player and their partner_id each have their partner_id set to NULL. Returns 1 if successful, otherwise returns 0. getpartnerid2 Return the partner_id for the invoking player. Requires player RID. getsavepoint <mode> Examine the player savepoint. Requires player RID. Mode 0: Mapname $ Mode 1: Position x Mode 2: Position y savepoint <mapname>,<x>,<y> Set the savepoint to <mapname>,<x>,<y>. Requires player RID. getgmlevel Return the GM level of the invoking player. Requires player RID. Example: if ( getgmlevel() > 60 ) ... Example: if ( getgmlevel() > G_DEV ) ... getopt2 Return the opt2 value of the invoking player. Requires player RID. This is not used in any existing scripts. It is likely obsolete and may be removed, do not use it. setopt2 <expr> Set the opt2 value of the invoking player. Requires player RID. This is not used in any existing scripts. It is likely obsolete and may be removed, do not use it. getversion Return the version of the client being used by the player. Requires player (RID). This is not used in any existing scripts. //---- NPC interactions getnpcid <npcname> Optional <npcname>. Get the ID (bl_id) of the NPC (OID), or the <npcname> if it is present. enablenpc <npcname> Enable the NPC given by the <npcname>. disablenpc <npcname> Enable the NPC given by the <npcname>. strnpcinfo <mode>, <npc> Optional <npc>. Uses the script NPC, unless <npc> is specified. A NPC display name is <visible_part>#<hidden_part>. Normally, only the <visible_part> is seen in the game. Return parts of the NPC name. Mode 0: display name whole Mode 1: visible part of the display name Mode 2: hidden part of the display name Mode 3: unique name (::name) getnpcx <npc> Optional <npc>. Uses the script NPC, unless <npc> is specified. Return the position x, of the NPC. getnpcy <npc> Optional <npc>. Uses the script NPC, unless <npc> is specified. Return the position y, of the NPC. fakenpcname Changes the npc name and sprite. destroy <target> Optional parameter <target>. If <target> is present then destroy that, otherwise default is invoking NPC (OID). Destroy the <target> NPC, or the NPC (OID) of this script. If there is a player (RID) attached, then dequeue their events. This is unsafe if there are other players accessing this NPC. puppet <mapname>, <x0>,<y0>, <npc_name>, <species>, <x1>,<y1> Optional <x1>,<y1>. Create <npc_name> at <mapname>, <x0>,<y0>, of species <species>. If <x1>,<y1> are present then set the scr.xs,scr.ys to this coord, whatever that is. Initialize the NPC timers, such as "OnTimer". Return the new npc id (bl_id); setnpcdirection <direction>, <sit>, <save>, <npcname> Set the NPC direction. Optional <npcname>. If <npcname> is present, then change that NPC, otherwise change the script NPC (OID). If <sit> then change the NPC to SIT, otherwise STAND. If <save> then save the new <direction> and action in the NPC. If there is a player attached (RID), then face that player. donpcevent <event> Signal the event. The <event> has format <scriptname>::<label> where <label> starts with "On". The <scriptname> can be the name of any script used by the NPC, even if it is triggered by map position too. Example: donpcevent "Luvia::OnCommandStart" Example: donpcevent "?::OnCommandTalk" // Luvia has a script named "?" Example: donpcevent "XmasSpawnManager::OnCommandSpawnStart" Example: donpcevent "#WarpBossCave::OnGetout" // Has script named "#WarpBossCave" Example: donpcevent "AniManOMat::OnCommandOverheat" npcwarp <x>,<y>, <npcname> Move NPC <npcname> to new position <x>,<y>, on the same map. This disables the NPC during the warp, and enables it afterwards. npcareawarp <x0>,<y0>, <x1>,<y1>, <walkableflag>, <npcname> Move NPC <npcname> to random position in area <x0>,<y0>, <x1>,<y1> on the same map. If <walkableflag> then { Will only warp to WALKABLE positions on the map. If the WALKABLE random search does not find a WALKABLE position it will return without moving the NPC. } This disables the NPC during the warp, and enables it afterwards. npctalk <npcname>, <str> Send message to surrounding area. Example: npctalk strnpcinfo(0), "Hurry up" Example: npctalk "Zax De'Kagen#0", "Don't make me laugh." //---- Monster interactions mobcount( <mapname>, <event> ) For each monster on the map <mapname>, trigger the <event>, and count the monsters. Return the count - 1, so it returns -1 when there a 0 monsters. If there is a <mapname> error, returns -1. Example: if( mobcount( "027-6", "General Krukan::OnPetDeath") < 0 ) Example: set $@KeshlamMc, mobcount("099-8", "Keshlam Maze::OnDeath1") + 1 Example: set .slimes_alive, mobcount("$@slime_mine_maps$[.map_nr], "Miner_Mania::OnSlimeSlain" + .map_nr) + 1 mobinfo <mob_id>, <mode> Return info from a large number of fields. Return int or str value, according to <mode>. Those marked with a $ return a string. Error return -1, bad <mode> or mob not found. Mode 0: // ID Mode 1: // ENG_NAME $ Mode 2: // JAP_NAME $ Mode 3: // LVL Mode 4: // HP Mode 5: // SP Mode 6: // BASE_EXP Mode 7: // JOB_EXP Mode 8: // RANGE1 Mode 9: // ATK1 Mode 10: // ATK2 Mode 11: // DEF11, (defence) Mode 12: // MDEF (magic defence) Mode 13: // CRITICAL_DEF (critical hit defence) Mode 14: // STR Mode 15: // AGI Mode 16: // VIT Mode 17: // INT Mode 18: // DEX Mode 19: // LUK Mode 20: // RANGE2 Mode 21: // RANGE3 Mode 22: // SCALE Mode 23: // RACE Mode 24: // ELEMENT Mode 25: // ELEMENT_LVL Mode 26: // MODE Mode 27: // SPEED Mode 28: // ADELAY Mode 29: // AMOTION Mode 30: // DMOTION Mode 31: // MUTATION_NUM Mode 32: // MUTATION_POWER Mode 33: // DROPID0 Mode 34: // DROPNAME0 $ Mode 35: // DROPPERCENT0 Mode 36: // DROPID1 Mode 37: // DROPNAME1 $ Mode 38: // DROPPERCENT1 Mode 39: // DROPID2 Mode 40: // DROPNAME2 $ Mode 41: // DROPPERCENT2 Mode 42: // DROPID3 Mode 43: // DROPNAME3 $ Mode 44: // DROPPERCENT3 Mode 45: // DROPID4 Mode 46: // DROPNAME4 $ Mode 47: // DROPPERCENT4 Mode 48: // DROPID5 Mode 49: // DROPNAME5 $ Mode 50: // DROPPERCENT5 Mode 51: // DROPID6 Mode 52: // DROPNAME6 $ Mode 53: // DROPPERCENT6 Mode 54: // DROPID7 Mode 55: // DROPNAME7 $ Mode 56: // DROPPERCENT7 Mode 57: // DROPID8 Mode 58: // DROPNAME8 $ Mode 59: // DROPPERCENT8 Mode 60: // DROPID9 Mode 61: // DROPNAME9 $ Mode 62: // DROPPERCENT9 mobinfo_droparrays <mob_id>, <request>, <dest> Queries the monster database for the <mob_id>, for its drops items. Return values: 0 = mob not found or error 1 = mob found and has drops 2 = mob found and has no drops Sets array <dest> with the selected drops information. If <dest> first char is not "$", "@", "." then error "illegal scope". Thus allows <dest>: "$", "$@", "@", "." or ".@". Player <dest> requires player RID. The <request> selects what is set in the array. The $ indicates a string result, otherwise numeric. REQUEST 0: IDS // nameid REQUEST 1: NAMES $ // item_name REQUEST 2: PERCENTS // drop percentage (integer) getmobdrops <mob_id> Queries the monster database for the <mob_id>, for its drops items. Return values: 0 = mob not found or error 1 = mob found and has drops 2 = mob found and has no drops Sets predetermined arrays with the drop information. The $ indicates a string result, otherwise numeric. Array $@MobDrop_item : IDS // nameid Array $@MobDrop_name : NAMES $ // item_name Array $@MobDrop_rate : PERCENTS // drop percentage (integer) $@MobDrop_count is the array count. The arrays are not cleared, so do not use arraysize, use $@MobDrop_count. summon <mapname>,<x0>,<y0>, <owner>, <mon_name>, <mon_id>, <mon_attitude>, <lifespan>, <event> Summon the monster <mon_name>, with the attributes, at <mapname>,<x0>,<y0>. Optional <event>. If <event> is present, then trigger the <event> for the monster. If <owner> not valid then error "bad owner". If <mon_name> is not present, then use MobName(). The <attitude> values -> mode: 0: HOSTILE -> & CAN_MOVE | (CAN_ATTACK | AGGRESSIVE) | SUMMONED 1: FRIENDLY -> & CAN_MOVE | (CAN_ATTACK) | SUMMONED 2: SERVANT -> & ALL | (AGGRESSIVE) | SUMMONED 3: FROZEN -> = ZERO | SUMMONED Set the lifetime of the monster to <lifespan>. Set the distance from the owner to 6. Example: set .master, BL_ID, .@puppet; set .lifetime, (@spellpower*9)+60000, .@puppet; summon .@map$, rand(.@x-2,.@x+2), rand(.@y-2,.@y+2), .master, "Mana Guardian Summon", ManaGuard, 2, .lifetime; issummon <mon_id> Return 1 if summoned (monster mode == SUMMONED), otherwise 0. Example: if( issummon( @targetid ) != 0 ) monster <mapname>, <x0>,<y0>, <mob_name>, <mob_class>, <num_mob>, <event> Monster outbreak. Optional <event>. Create the monster <mob_name>, with <mob_class>, number <num_mob>, at <mapname>,<x0>,<y0>. If the <event> is present, then invoke that <event> at spawn. Example <event> can be "npcname:OnCreate".
areamonster <mapname>, <x0>,<y0>, <x1>,<y1>, <mob_name>, <mob_class>, <num_mob>, <event> Monster outbreak. Optional <event>. Create the <mob_name>, with <mob_class>, number <num_mob>, in the area <mapname>, <x0>,<y0>, <x1>,<y1>. If the <event> is present, then invoke that <event> at spawn. Example <event> can be "npcname:OnCreate". killmonster <mapname>, <event> Kill every monster on the map <mapname>. The <event> is not optional, and may be "All". Invoke the <event> for each monster kill. Any items the monster may have will be deleted. Example: killmonster "052-1", "All"; // Kill all monsters Example: killmonster "051-1", "Door::OnB"; // Kill all remaining bandits aggravate <mon_id>, <target> Aggravate the monster <mon_id>, to the <target>. Optional <target>. If <target> is not present, then the invoking player is the target. That requires player RID, but it does not check for missing target. Example: aggravate @target_id
quietlyquietly
Peon
Peon
Posts: 35
Joined: 07 Sep 2023, 09:40

Re: Script reference Version 1.02

Post by quietlyquietly »

Part 3
Node that the commands are marked with ">>", and the forum is not displaying that correctly.

Code: Select all

//---- Timers and Events

gettimetick  <mode>
Return the time.

Mode 0: system tick.  (Default)
Mode 1: seconds elapsed today.
Mode 2: seconds since UNIX epoch.

gettime  <mode>
Return the time field.

Mode 1: second
Mode 2: minute
Mode 3: hour
Mode 4: weekday
Mode 5: monthday
Mode 6: month
Mode 7: year
else  : error (-1)


addtimer <tick>, <event>, <player_id>
Start a timer, for the delay <tick> in ms.
Optional <player_id>.
If <player_id> is not present then will use the invoking player,
which requires player RID.
After the delay the <event> will be triggered for this script NPC
and the selected player.
The <event> must be of the form "<script_name>::<label>", where
the label starts with "On".
The <script_name> is often the NPC name, or a spell name.
Every magic effect uses one of these.

Example:  addtimer 2000, "Magic Timer::OnClear"; // set the new debuff
Example:  addtimer 0, @upmarmu_spell_npc_name$ + "::OnResetTimer";
Example:  if (@upmarmuspell[1] > 0)  addtimer 0, strnpcinfo(0) + "::OnSetRecast";


addnpctimer <tick>, <event>
Add a delay <tick> and <event> to the script NPC timer, and start it.
After the delay the <event> will be triggered for this script NPC.
The <event> must be of the form "<script_name>::<label>", where
the label starts with "On".
The <script_name> is often the NPC name.
There is one NPC timer, but if can have multiple delays and events.
Many NPC script uses one or more of these.
These are useful where the player is not needed.

Example: addnpctimer 5000-(@spellpower*9), .@puppet$+"::OnSummon";
         addnpctimer 6000, .@puppet$+"::OnDestroy";
Example: addnpctimer .death_delay, strnpcinfo(0) + "::OnReallyDestroy"; // schedule a respawn


initnpctimer  <npc_id>
Reset the NPC timer to 0 and start it.  The delays are unchanged.
Optional <npc_id>.
If the <npc_id> is not present then the <npc_id> will be the script NPC.

startnpctimer  <npc_id>
Start the NPC timer without changing the time.  The delays are unchanged.
Optional <npc_id>.
If the <npc_id> is not present then the <npc_id> will be the script NPC.

stopnpctimer
Stop the NPC timer without changing the time.  The delays are unchanged.
Optional <npc_id>.
If the <npc_id> is not present then the <npc_id> will be the script NPC.

Example: stopnpctimer;
Example: stopnpctimer "Stone Board";

getnpctimer  <mode>, <npc_id>
Return the NPC timer.
Optional <npc_id>.
If the <npc_id> is not present then the <npc_id> will be the script NPC.

The <mode> values:
  0: Return the tick count.
  1: Return TRUE is the timer is active.
  2: Return the number of events set.

setnpctimer <tick>, <npc_id>
Set the NPC timer to time <tick>.
Optional <npc_id>.
If the <npc_id> is not present then the <npc_id> will be the script NPC.
This is often used to set it to 0.

Example: setnpctimer 0, "Stone Board";
Example: setnpctimer min(49000, getnpctimer(0)-rand(2500,5000));


npcaction  <npc_command>, <param>, <x>,<y>
Send <npc_command> and parameters to the player client.
Optional <param>, <x>,<y>.
If <param> is not present then set <param> to 0.
Requires player RID.

Most of these commands are already done by script commands
that check parameters and do it correctly.
It should not be necessary to use this in a normal script.

The <npc_command> values :
  0 : RequestLang
  1 : move camera to NPC (0,0)
  2 : <param>=0 : move camera to position (x,y)
      <param>!=0 : move camera to actor(<param>) (x,y)
  3 : return camera, does CameraRestore, camera off
  4 : move camera relative (x,y)
  5 : close dialog, restore camera
  6 : show avatar of actor(<param>)
  7 : set avatar direction of actor(<param>)
  8 : set avatar action of actor(<param>)
  9 : clear npc dialog
 10 : send selected item id, <param> is inventory size.
 11 : send selected item index, <param> is inventory size.
 12 : send complex items, <param> is inventory size.
 14 : close erase dialog of NPC.


areatimer <mode>,  <mapname>,<x0>,<y0>, <x1>,<y1>,  <tick>, <event>
For all in the map area,
execute "addeventtimer" with <tick> and <event>.

Mode 0: player
No other modes are supported at this time.

Example:  areatimer 0, "052-2", 19, 18, 48, 43, 2000, "#LuviaShadow::OnNN";


//---- Script commands

attachrid  <rid>
Attach the <rid> to this script giving it an invoking player.
Return true if this is a valid map_id.

Example:  if (!(attachrid($@ILLIA_HERO_ID)))  goto L_Clear;
Example:
    if (attachrid(@target_id) < 1) end;     // Switch context -> found player (to look up focused skills)
    if (call("is_magician")) misceffect FX_MAGIC_DETECT_HIT, BL_ID; // BL_ID because now attached to target
    if (attachrid(.caster) < 1) end;        // Try to reattach back -> caster

detachrid
Detatch the script RID so that it does not have an invoking player.

Example:
OnTimer25000:
    if (attachrid(.caster) < 1) end;
    set @num_upmarmu_hits, 0;
    detachrid;


freeloop  <value>
  Set script state freeloop to the <value> value, 0 or 1.


//---- Other

misceffect  <effect>, <target>
Effects generated by NPC.
Optional <target>.
The <target> can be player name, or player id.
If <target> is present (or not valid) then
  target is <target>
else if script NPC is valid then
  target will be the script NPC
else if invoking player is valid then
  target will be invoking player
else
  do nothing.

These are defined in serverdata/world/map/db/const.txt.
The source is in serverdata/client-data/effects.xml,
which is much harder to read.
FX range (0 to 555).
Emote range (10000 to 10041).
The <effect> values (partial list):
  FX_NONE
  FX_LEVELUP
  FX_SKILLUP
  FX_MAGIC_GENERIC
  FX_MAGIC_WHITE
  FX_MAGIC_BLACK
  FX_MAGIC_RED
  FX_MAGIC_GREEN
  FX_MAGIC_BLUE
  FX_MAGIC_DARKRED
  FX_MAGIC_DEFAULT
  FX_MAGIC_SHIELD
  FX_MAGIC_HIT
  FX_MAGIC_HIT_EVIL
  FX_FIRE_BURST
  FX_FIRE_EXPLOSION
  FX_LIGHTNING1
  FX_LIGHTNING2
  FX_LIGHTNING3
  FX_MAGIC_TELEPORT
  FX_PENTAGRAM_BUILDUP
  FX_PENTAGRAM_BURST
  FX_MAGIC_TELEPORT2
  FX_RAIN
  FX_HIT
  FX_ARROW_HAIL
  FX_CRITICAL
  FX_LARGE_EXPLOSION
  FX_MEDIUM_EXPLOSION
  FX_MEDIUM_SMOKE
  FX_MEDIUM_BLINDINGLIGHT
// Others found in scripts.
// Many of these are unique to that special magic.
  FX_PUMPKIN_EXPLOSION
  FX_MAGIC_DARK_EXPLOSION
  FX_MAGIC_WAND_CAST
  FX_MAGIC_DISCHARGE
  FX_ELECTRICITY_RED
  FX_RED_MAGIC_CAST
  FX_BLUE_MAGIC_CAST
  FX_MAGIC_BLUE_TELEPORT
  FX_MEDIUM_BLINDINGLIGHT
  FX_ENCHANTED_DOOR_BROKEN
  FX_CHANNELLING_RAISE
  FX_CHANNELLING_RAISE_RED
  FX_CHANNELLING_RAISE_BLUE
  FX_CHANNELLING_CAST
  FX_CHANNELLING_CAST_RED  
FX_CHANNELLING_CAST_BLUE FX_DARK_TELEPORT FX_MAGIC_SNAKE_CAST FX_EVIL_SUMMON FX_GROUND_SPAWN FX_MAGIC_MAGGOT_CAST FX_MAGIC_SPIKY_CAST
FX_MAGIC_AGGRAVATE_CAST FX_MAGIC_AGGRAVATE_HIT FX_MAGIC_DETECT_CAST FX_MAGIC_DETECT_HIT
FX_MAGIC_EXP_CAST FX_MAGIC_DART_CAST FX_MAGIC_DISCHARGE
FX_MAGIC_GROW_CAST FX_MAGIC_GROW_SPAWN FX_MAGIC_HEAL_HIT FX_MAGIC_BLADE_CAST FX_MAGIC_SULPHUR_CAST FX_MAGIC_WOOD_CAST FX_MAGIC_AHAIL_CAST FX_MAGIC_BARRIER_CAST FX_MAGIC_BARRIER_HIT FX_MAGIC_BARRIER_END FX_MAGIC_WHO_CAST FX_MAGIC_STONE_CAST FX_MAGIC_FLYING_CAST FX_MAGIC_FLYING_HIT FX_MAGIC_FLYING_END FX_MAGIC_JOY_CAST FX_MAGIC_HIDE_CAST FX_MAGIC_HIDE_HIT FX_MAGIC_HIDE_END FX_MAGIC_LAY_CAST FX_MAGIC_LAY_HIT FX_MAGIC_BOLT_CAST FX_MAGIC_KNUCKLE_CAST FX_MAGIC_ARROW_CAST FX_MAGIC_IRONP_CAST FX_MAGIC_SHIRT_CAST FX_MAGIC_SHIELD_CAST FX_MAGIC_SHIELD_ENDS FX_MAGIC_RAIN_CAST FX_RAIN FX_MAGIC_SHEAR_CAST FX_MAGIC_FLUFFY_CAST FX_MAGIC_MOUBOO_CAST FX_MAGIC_PINKY_CAST FX_MAGIC_SNAKE_CAST FX_MAGIC_SPIKY_CAST FX_MAGIC_WICKED_CAST FX_MAGIC_TDART_CAST FX_MAGIC_DARKRED FX_PENTAGRAM_BUILDUP FX_PENTAGRAM_BURST FX_HUG // Emotes, there are 40 more.
FX_EMOTE_SURPRISE FX_EMOTE_DISGUST Example: misceffect sfx_magic_nature; Example: misceffect FX_MAGIC_BLUE_TELEPORT, strcharinfo(0); Example: misceffect 11, strcharinfo(0); Example: misceffect FX_MAGIC_DARKRED, strcharinfo(0); // on caster specialeffect <effect> Special effect on the script NPC map, that do not have a target. Updates players in the AREA. These are defined in serverdata/world/map/db/const.txt. The source is in serverdata/client-data/effects.xml, which is much harder to read. The <effect> values (partial list): FX_MAGIC_FLUFFY_SPAWN FX_MAGIC_MOUBOO_SPAWN FX_MAGIC_SNAKE_SPAWN FX_MAGIC_SPIKY_SPAWN FX_MAGIC_WICKED_SPAWN Example: specialeffect FX_MAGIC_MAGGOT_SPAWN Example: specialeffect 22 // FX_PENTAGRAM_BURST specialeffect2 Special effect on the invoking player map, that do not have a target. Updates players in the AREA. These are defined in serverdata/world/map/db/const.txt. The source is in serverdata/client-data/effects.xml, which is much harder to read. The <effect> values (partial list): FX_MAGIC_FLUFFY_SPAWN FX_MAGIC_MOUBOO_SPAWN FX_MAGIC_SNAKE_SPAWN FX_MAGIC_SPIKY_SPAWN FX_MAGIC_WICKED_SPAWN Example: specialeffect 53 // particles and music, from illia quest Example: specialeffect 39 // FX_GROUND_SPAWN music <music_name> Play the music. Requires player RID. Example: music "goulish-fun.ogg" Example: music "Dramatic.ogg" shop <npc_name> Activate the shop dialog of a nearby NPC. Requires player RID. Example: shop "#FlowerShop" camera <x>, <y> camera <mapid>, <x>, <y> Move the camera view to specified map and position. Send camera NPC actions to the client. This is used in the game Introduction and Tutorial. Optional <mapid>, <x>, <y>. The <mapid> may be numeric, mapname, "relative", "rid", "oid", "player", or "npc". Requires player RID. If <x>,<y> present, but <mapid> not present then Move camera to position <x>,<y> on current camera map. clif_npc_action( player, npc, 2, 0, <x>, <y> ) else if <mapid> present then If <x>,<y> are not present then set position <x>,<y> to <0>,<0> if <mapid> == "relative" Move camera relative to current camera position. clif_npc_action( player, npc, 4, 0, <x>, <y> ) else if <mapid> is numeric then map is from <mapid> else if <mapid> is "rid" or "player" then map is invoking player map BUG: this does not work due to a bug, it will try to interpret "rid" as a mapname. else if <mapid> is "oid" or "npc" then map is script NPC map else map is from mapname <mapid> Move camera to specified map and position <x>,<y>. clif_npc_action( player, npc, 2, map, <x>, <y> ) else Return camera to player position. clif_npc_action( player, npc, 3, map, 0, 0 )
Example: camera ; // camera off Example: camera "Dresser#tutorial" registercmd <evoke>, <event> Register a command. When the <evoke> happens, the <event> is triggered. This is used in the OnInit code of command/ scripts to register their commands. Example: registercmd "@teleportadd", "TeleportManager::OnCmdAdd"; registercmd "@teleportdel", "TeleportManager::OnCmdDel"; registercmd "@teleportlist", "TeleportManager::OnCmdList"; registercmd "@teleporthelp", "TeleportManager::OnCmdHelp"; registercmd "@teleport", "TeleportManager::OnCmdHelp"; Example: registercmd "*hugs", strnpcinfo(0); // eq: /me hugs (target) registercmd "*hugs*", strnpcinfo(0); // eq: /me hugs Example: registercmd chr(ATCMD_SYMBOL) + "warp", strnpcinfo(0); registercmd chr(ATCMD_SYMBOL) + "charwarp", strnpcinfo(0); Example: registercmd .invocation$, strnpcinfo(0); // sense spouse magic remotecmd <player_id>, <command> Sends the <command> to the player client. Optional <player_id> If <player_id> is not present then will access invoking player, which requires player RID. You should probably should not be using this in anything but the command/remotecmd script. openstorage Open a coupler warehouse (??) for the Bank. Requires player RID. This allows the Bank to change Bank options. Do not be using this for any other kind of script. // Notes To understand the server code: conv_num : function used to ensure that the argument is a number. It converts string arguments to numeric using atoi(). conv_str : function used to ensure that the argument is a string. It converts numeric arguments to string by using PRINT. HARG(0) : test if ARG(0) is present AARG(0) : the value of command argument AARG(0).get_if<ScriptDataDataInt>() : If the argument is numeric, returns a ptr to a structure holding the value. The numeric value is ptr->numi. AARG(0).get_if<ScriptDataDataStr>() : If the argument is string, returns a ptr to a structure holding the value. The string value is ptr->str. st : ScriptState, the script execution state. It contains who invoked the script, and flags. RID : a player id Most scripts have the RID of the invoking player attached, but not all. It can be problem for scripts that are invoked without a RID. The invoking player is st->rid. OID : an NPC id, most scripts are invoked by a NPC action and are a NPC script. The script NPC st->oid. BL : enum { NUL, PC, // player NPC, MOB, // monster ITEM } Used to mark block_list, or any structure containing a block_list. Usually seen as BL::PC, BL::NPC, BL::MOB, BL::ITEM. bl : <block_list>, a type, map, and position. Most map operations require a bl ptr. The block_list id is bl->bl_id. The position is bl->x, bl->y. Beware as_player(), as_npc(), as_mob(), as_item(), because their use causes many crashes. Even though each of these contain a block_list, using a block_list as one is assuming too much. Beware is_player(), is_npc(), is_mob(), is_item(), because they only test the type value which does not ensure that it is actually that specific structure (it could be a block_list copy). Also, upon failure they return a NULL, which if used will also cause a SEGFAULT. Any use of these functions that do not test for the NULL is a BUG. map_id : BlockId field used for player, npc, mob, and item. Some differentiated by numeric range, but mostly looked up in database. bl_id : BlockId, a field or var that is a map_id. map_id2bl : convert a map_id to a block_list ptr This often is a database search. if map_id > MAX_FLOORITEM then is object[id._value] else lookup in database. map_id_is_npc : convert a st->oid to a npc ptr, which is needed by many npc functions. sd : <map_player_session>, a player session, contains a block_list, session, and a ton of player data Player operations require an sd ptr. script_rid2sd : convert player RID to session ptr This is a database search. script_nullpo_end : function that checks for player ptr being NULL, and if it is, issues an error message and ends the script. clif_ : client message functions pc_ : player functions mob_mode flags : ZERO = 0x0000, CAN_MOVE = 0x0001, LOOTER = 0x0002, AGGRESSIVE = 0x0004, ASSIST = 0x0008, CAST_SENSOR = 0x0010, BOSS = 0x0020, // sometimes also called "robust" PLANT = 0x0040, CAN_ATTACK = 0x0080, DETECTOR = 0x0100, CHANGE_TARGET = 0x0200, war = CAN_MOVE | AGGRESSIVE | CAN_ATTACK, SUMMONED = 0x1000, TURNS_AGAINST_BAD_MASTER = 0x2000, // mob mode flags that Fate actually understood SENSIBLE_MASK = 0xf000, npc_command : 0 : RequestLang 1 : move camera to actor (0,0) 2 : id=0 : move camera to position (x,y) id!=0 : move camera to actor (x,y) 3 : return camera 4 : move camera relative (x,y) 5 : close dialog, restore camera 6 : show avatar 7 : set avatar direction 8 : set avatar action 9 : clear npc dialog 10 : send selected item id 11 : send selected item index 12 : send complex items 14 : close erase dialog of NPC.
quietlyquietly
Peon
Peon
Posts: 35
Joined: 07 Sep 2023, 09:40

Re: Script reference Version 1.02

Post by quietlyquietly »

Is there any way I can upload this as a file.
The forum does not allow posting the entire thing because it is 3x too long.
I already have made changes, ver 1.03.

User avatar
WildX
Source of Mana
Source of Mana
Posts: 2141
Joined: 07 Aug 2010, 14:13
Location: United Kingdom
Contact:

Re: Script reference Version 1.02

Post by WildX »

Did you get git access in the end?

Mana Team member

quietlyquietly
Peon
Peon
Posts: 35
Joined: 07 Sep 2023, 09:40

Re: Script reference Version 1.02

Post by quietlyquietly »

Have a GIT account. Of course this means I am now fighting with GIT trying to get it to do something useful.

User avatar
WildX
Source of Mana
Source of Mana
Posts: 2141
Joined: 07 Aug 2010, 14:13
Location: United Kingdom
Contact:

Re: Script reference Version 1.02

Post by WildX »

quietlyquietly wrote: 10 Jun 2025, 03:54

Have a GIT account. Of course this means I am now fighting with GIT trying to get it to do something useful.

I really think that joining us on IRC/Discord would help you coordinate better with the relevant people. You can click here to find all the information.

Mana Team member

Post Reply