diff options
Diffstat (limited to 'doc/script_commands.txt')
-rw-r--r-- | doc/script_commands.txt | 10471 |
1 files changed, 0 insertions, 10471 deletions
diff --git a/doc/script_commands.txt b/doc/script_commands.txt deleted file mode 100644 index 516454365..000000000 --- a/doc/script_commands.txt +++ /dev/null @@ -1,10471 +0,0 @@ -//===== Hercules Documentation =============================== -//= Hercules Script Commands -//===== By: ================================================== -//= Hercules Dev Team -//===== Description: ========================================= -//= A reference manual for the Hercules scripting language. -//= Commands are sorted depending on their functionality. -//============================================================ - -This document is a reference manual for all the scripting commands and -functions available in current Hercules GIT. It is not a simple tutorial. -When people tell you to "Read The F***ing Manual", they mean this. - -The information was mostly acquired through looking up how things actually -work in the source code of the server, which was written by many people -over time, and lots of them don't speak English and never left any notes - -or are otherwise not available for comments. As such, anything written in -here might not be correct, it is only correct to the best of our -knowledge, which is limited. - -This is not a place to teach you basic programming. This document will not -teach you basic programming by itself. It's more of a reference for those -who have at least a vague idea of what they want to do and want to know -what tools they have available to do it. We've tried to keep it as simple -as feasible, but if you don't understand it, getting a clear book on -programming in general will help better than yelling around the forum for -help. - -A little learning never caused anyone's head to explode. - -Structure ---------- - -The commands and functions are listed in no particular order: - -*Name of the command and how to call it. - -Descriptive text - - Small example if possible. Will usually be incomplete, it's there just - to give you an idea of how it works in practice. - -To find a specific command, use Ctrl+F, (or whatever keys call up a search -function in whatever you're reading this with) put an * followed by the -command name, and it should find the command description for you. - -If you find anything omitted, please tell us. :) - -Syntax ------- - -Throughout this document, wherever a command wants an argument, it is -given in <angle brackets>. This doesn't mean you should type the angle -brackets. :) If an argument of a command is optional, it is given in -{curly brackets}. You've doubtlessly seen this convention somewhere, if -you didn't, get used to it, that's how big boys do it. If a command can -optionally take an unspecified number of arguments, you'll see a list like -this: - -command(<argument>{, <argument>...<argument>}) - -This still means they will want to be separated by commas. - -Where a command wants a string, it will be given in "quotes", if it's a -number, it will be given without them. Normally, you can put an -expression, like a bunch of functions or operators returning a value, in -(round brackets) instead of most numbers. Round brackets will not always -be required, but they're often a good idea. - -Wherever you refer to a map, use 'mapname' instead of 'mapname.gat'. - - -Script loading structure ------------------------- - -Scripts are loaded by the map server as referenced in the -'npc/(pre-)re/scripts_main.conf' configuration file. - -The file contains a list of scripts to be loaded (or other configuration files -to be parsed, through the @include directive), in the following format: - -npc_global_list: ( - "npc/path/to/the/script/to/load.txt", - "npc/other/file.txt", -@include "npc/other_configuration_file.conf" -) - -Any script will only get loaded once even if specified twice, to prevent -possible errors. - -It's possible to specify scripts to exclude from loading, by inserting them -(using the same syntax) in the list available in npc/scripts_removed.conf: - -npc_removed_list: ( - "npc/path/to/the/file/to/skip.txt", -) - -Script file format ------------------- - -Whenever '//' is encountered in a line upon reading, everything beyond -this on that line is considered to be a comment and is ignored. This works -wherever you place it. - -// This line will be ignored when processing the script. - -Block comments can also be used, where you can place /* and */ between any -text you wish Hercules to ignore. - -Example: -/* This text, - * no matter which new line you start - * is ignored, until the following - * symbol is encountered: */ - -The asterisks (*) in front of each line is a personal preference, and is -not required. - -Upon loading all the files, the server will execute all the top-level -commands in them. No variables exist yet at this point, no commands can be -called other than those given in this section. These commands set up the -basic server script structure - create NPC objects, spawn monster objects, -set map flags, etc. No code is actually executed at this point except -them. The top-level commands the scripting are pretty confusing, since -they aren't structured like you would expect commands, command name first, -but rather, normally start with a map name. - -What's more confusing about the top-level commands is that most of them -use a tab symbol to divide their arguments. - -To prevent problems and confusion, the tab symbols are written as '%TAB%' -or '<TAB>' throughout this document, even though this makes the text a bit -less readable. Using an invisible symbol to denote arguments is one of the -bad things about this language, but we're stuck with it for now. :) - -Here is a list of valid top-level commands: - -** Set a map flag: - -<map name>%TAB%mapflag%TAB%<flag> - -This will, upon loading, set a specified map flag on a map you like. These -are normally in files inside 'npc/mapflag' and are loaded first, so by the -time the server's up, all the maps have the flags they should have. Map -flags determine the behavior of the map regarding various common problems, -for a better explanation, see 'setmapflag'. - -** Create a permanent monster spawn: - -<map name>,<x>,<y>,<xs>,<ys>%TAB%monster%TAB%<monster name>%TAB%<mob id>,<amount>,<delay1>,<delay2>,<event>{,<mob size>,<mob ai>} - -Map name is the name of the map the monsters will spawn on. X,Y are the -coordinates where the mob should spawn. If X's and Y's are non-zero, they -specify the 'radius' of a spawn-rectangle area centered at x,y. Putting -zeros instead of these coordinates will spawn the monsters randomly. Note -this is only the initial spawn zone, as mobs random-walk, they are free to -move away from their specified spawn region. - -Monster name is the name the monsters will have on screen, and has no -relation whatsoever to their names anywhere else. It's the mob id that -counts, which identifies monster record in 'mob_db.txt' database of -monsters. If the mob name is given as "--ja--", the 'japanese name' field -from the monster database is used, (which, in Hercules, actually contains -an English name) if it's "--en--", it's the 'english name' from the -monster database (which contains an uppercase name used to summon the -monster with a GM command). - -Amount is the amount of monsters that will be spawned when this command is -executed, it is affected by spawn rates in 'conf/map/battle.conf'. - -Delay1 and delay2 control monster respawn delays - the first one is the -fixed base respawn time, and the second is random variance on top of the -base time. Both values are given in milliseconds (1000 = 1 second). Note -that the server also enforces a minimum respawn delay of 5 seconds. - -You can specify a custom level to use for the mob different from the one -of the database by adjoining the level after the name with a comma. eg: -"Poring,50" for a name will spawn a monster with name Poring and level 50. - -Event is a script event to be executed when the mob is killed. The event -must be in the form "NPCName::OnEventName" to execute, and the event name -label should start with "On". As with all events, if the NPC is an -on-touch NPC, the player who triggers the script must be within 'trigger' -range for the event to work. - -There are two optional fields for monster size and AI. Size can be 0 -(medium), 1 (small), or 2 (big). AI can be 0 (default), 1 -(attack/friendly), 2 (sphere), 3 (flora), or 4 (zanzou). - -Alternately, a monster spawned using 'boss_monster' instead of 'monster' is able to be -detected on the map with the SC_CASH_BOSS_ALARM status (used by Convex Mirror, item ID# 12214). -A monster spawned using 'miniboss_monster' is spawn monster as mini boss view. - -** NPC names - -/!\ WARNING: this applies to warps, NPCs, duplicates and shops /!\ - -NPC names are kinda special and are formatted this way: - -<Display name>{::<Unique name>} - -All NPCs need to have a unique name that is used for identification -purposes. When you have to identify a NPC by it's name, you should use -<Unique name>. If <Unique name> is not provided, use <Display name> -instead. - -The client has a special feature when displaying names: if the display -name contains a '#' character, it hides that part of the name. -Ex: if your NPC is named 'Hunter#hunter1', it will be displayed as 'Hunter' - -<Display name> must be at most 24 characters in length. -<Unique name> must be at most 24 characters in length. - -** Define a warp point - -<from map name>,<fromX>,<fromY>{,<facing>}%TAB%warp%TAB%<warp name>%TAB%<spanx>,<spany>,<to map name>,<toX>,<toY> - -This will define a warp NPC that will warp a player between maps, and -while most arguments of that are obvious, some deserve special mention. - -SpanX and SpanY will make the warp sensitive to a character who didn't -step directly on it, but walked into a zone which is centered on the warp -from coordinates and is SpanX in each direction across the X axis and -SpanY in each direction across the Y axis. - -Warp NPC objects also have a name, because you can use it to refer to them -later with 'enablenpc'/'disablenpc'. - -Facing of a warp object is irrelevant, it is not used in the code and all -current scripts have a zero in there. - -** Define an NPC object. - -<map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite>,{<code>} -<map name>,<x>,<y>,<facing>%TAB%script%TAB%<NPC Name>%TAB%<sprite>,<triggerX>,<triggerY>,{<code>} - -This will place an NPC object on a specified map at the specified -location, and is a top-level command you will use the most in your custom -scripting. The NPCs are triggered by clicking on them, and/or by walking -in their trigger area, if defined. See that below. - -Facing is a direction the NPC sprite will face in. Not all NPC sprites -have different images depending on the direction you look from, so for -some facing will be meaningless. Facings are counted counterclockwise in -increments of 45 degrees, where 0 means facing towards the top of the map. -(So to turn the sprite towards the bottom of the map, you use facing 4, -and to make it look southeast it's facing 5.) - -Sprite is the sprite identifier used to display this particular NPC. For a -full list of sprite numbers see http://nn.ai4rei.net/dev/npclist/ as -well as doc/constants.md. -You may also use a monster's ID constant instead to display a monster sprite -for this NPC, in npcs that have view ids of mobs it's encouraged to use -OnTouch events with a 2,2 range and with an 'end' after the header to avoid -bugs (for more info on why see npc_click@map/npc.c). It is possible to use a job -sprite as well, but you must first define it as a monster sprite in 'mob_avail.txt', -a full description on how to do this is not in the scope of this manual. -A 'FAKE_NPC' sprite will make the NPC invisible (and unclickable). -A 'HIDDEN_NPC' sprite will make an NPC which does not have a sprite, but is -still clickable, which is useful if you want to make a clickable object of -the 3D terrain. - -TriggerX and triggerY, if given, will define an area, centered on NPC and -spanning triggerX cells in every direction across X and triggerY in every -direction across Y. Walking into that area will trigger the NPC. If no -'OnTouch:' special label is present in the NPC code, the execution will -start from the beginning of the script, otherwise, it will start from the -'OnTouch:' label. Monsters can also trigger the NPC, though the label -'OnTouchNPC:' is used in this case, and using mobattached() will return -monster GID. If player left the area will trigger the label 'OnUnTouch'. - -The code part is the script code that will execute whenever the NPC is -triggered. It may contain commands and function calls, descriptions of -which compose most of this document. It has to be in curly brackets, -unlike elsewhere where we use curly brackets, these do NOT signify an -optional parameter. - -** Define a 'floating' NPC object. - --%TAB%script%TAB%<NPC Name>%TAB%FAKE_NPC,{<code>} - -This will define an NPC object not triggerable by normal means. This would -normally mean it's pointless since it can't do anything, but there are -exceptions, mostly related to running scripts at specified time, which is -what these floating NPC objects are for. More on that below. - -** Define a shop/cashshop NPC. - --%TAB%shop%TAB%<NPC Name>%TAB%<sprite>,<itemid>:<price>{,<itemid>:<price>...} -<map name>,<x>,<y>,<facing>%TAB%shop%TAB%<NPC Name>%TAB%<sprite>,<itemid>:<price>{,<itemid>:<price>...} - -This will define a shop NPC, which, when triggered (which can only be done -by clicking) will cause a shop window to come up. No code whatsoever runs -in shop NPCs and you can't change the prices otherwise than by editing the -script itself (no variables even exist at this point of scripting, so -don't even bother trying to use them). - -The item id is the number of item in the 'item_db.txt' database. If Price -is set to -1, the 'buy price' given in the item database will be used. -Otherwise, the price you gave will be used for this item, which is how you -create differing prices for items in different shops. - -You can alternatively use "cashshop" in place of "shop" to use the Cash -Shop interface, allowing you to buy items with special points (Currently -stored as account vars in #CASHPOINTS and #KAFRAPOINTS). This -type of shop will not allow you to sell items at it, you may only purchase -items here. The layout used to define sale items still count, and -"<price>" refers to how many points will be spent purchasing the them. - -** Define a trader NPC -<map name>,<x>,<y>,<facing>%TAB%trader%TAB%<NPC Name>%TAB%<sprite>,{<code>} --%TAB%trader%TAB%<NPC Name>%TAB%FAKE_NPC,{<code>} - -All the standards that are valid to script objects are also valid for trader objects -(see ** Define an NPC object for more information). -This will define a trader NPC, which can cause a shop, cashshop or market window -to come up when clicked or called by other means. Unlike shop/cashshop NPCs this -type will run a code and can change the items that are being sold over time without -other NPC objects. -The types that a trader object can have are the following: -- NST_ZENY (0) Normal Zeny Shop (shop) -- NST_CASH (1) Normal Cash Shop (cashshop) -- NST_MARKET (2) Normal NPC Market Shop (where items have limited availability - and need to be refurbished) -- NST_CUSTOM (3) Custom Shop (any currency, item/var/etca, check sample) -- NST_BARTER (4) Barter Shop (each item with own item currency) -Unless otherwise specified via *tradertype an trader object will be defined as -NST_ZENY. - -Note: NST_MARKET is only available with PACKETVER 20131223 or newer. -Note: NST_BARTER is only available with PACKETVER 20181226 zero or newer. -See '12 - NPC Trader-Related Commands' and /doc/sample/npc_trader_sample.txt for -more information regarding how to use this NPC type. - -** Define an warp/shop/cashshop/NPC duplicate. - -warp: <map name>,<x>,<y>{,<facing>}%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<spanx>,<spany> -shop/cashshop/npc: -%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite> -shop/cashshop/npc: <map name>,<x>,<y>,<facing>%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite> -npc: -%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite>,<triggerX>,<triggerY> -npc: <map name>,<x>,<y>,<facing>%TAB%duplicate(<label>)%TAB%<NPC Name>%TAB%<sprite>,<triggerX>,<triggerY> - -This will duplicate an warp/shop/cashshop/NPC referred to by 'label'. -Warp duplicates inherit the target location. -Shop/cashshop duplicates inherit the item list. -NPC duplicates inherit the script code. -The rest (name, location, facing, sprite, span/trigger area) is -obtained from the definition of the duplicate (not inherited). - -** Define a function object - -function%TAB%script%TAB%<function name>%TAB%{<code>} - -This will define a function object, callable with the 'callfunc' command -(see below). This object will load on every map server separately, so you -can get at it from anywhere. It's not possible to call the code in this -object by anything other than the 'callfunc' script command. - -The code part is the script code that will execute whenever the function -is called with 'callfunc'. It has to be in curly brackets, unlike -elsewhere where we use curly brackets, these do NOT signify an optional -parameter. - -Once an object is defined which has a 'code' field to it's definition, it -contains script commands which can actually be triggered and executed. - -~ RID? GID? ~ - -What a RID is and why do you need to know ------------------------------------------ - -Most scripting commands and functions will want to request data about a -character, store variables referenced to that character, send stuff to the -client connected to that specific character. Whenever a script is invoked -by a character, it is passed a so-called RID - this is the account ID -number of a character that caused the code to execute by clicking on it, -walking into it's OnTouch zone, or otherwise. - -If you are only writing common NPCs, you don't need to bother with it. -However, if you use functions, if you use timers, if you use clock-based -script activation, you need to be aware of all cases when a script -execution can be triggered without a RID attached. This will make a lot of -commands and functions unusable, since they want data from a specific -character, want to send stuff to a specific client, want to store -variables specific to that character, and they would not know what -character to work on if there's no RID. - -Unless you use 'attachrid' to explicitly attach a character to the script -first (see player-related commands). - -Whenever we say 'invoking character', we mean 'the character who's RID is -attached to the running script. The script function playerattached() can -be used to check which is the currently attached player to the script (it -will return 0 if the there is no player attached or the attached player no -longer is logged on to the map-server). - -But what about GID? ---- ---- ----- ---- - -GID stands for the Game ID of something, this can either be the GID of a -mob obtained through the monster() script command (if only summoned one), -the GID of a NPC obtained through the getnpcid() script command or the -account ID of a character (same as its RID). Another way would be to right -click on a mob, NPC or char as GM sprited char to view its GID. - -Item and pet scripts --------------------- - -Each item in the item database has three special fields - Script, -OnEquip_Script and OnUnequip_Script. The first is script code run every -time a character equips the item, with the RID of the equipping character. -Every time they unequip an item, all temporary bonuses given by the script -commands are cleared, and all the scripts are executed once again to -rebuild them. This also happens in several other situations (like upon -login) but the full list is currently unknown. - -OnEquip_Script is a piece of script code run whenever the item is used by -a character by double-clicking on it. OnUnequip_Script runs whenever the -equipment is unequipped by a character. - -Not all script commands work properly in the item scripts. Where commands -and functions are known to be meant specifically for use in item scripts, -they are described as such. - -Every pet in the pet database has a PetScript field, which determines pet -behavior. It is invoked wherever a pet of the specified type is spawned -(hatched from an egg, or loaded from the char server when a character who -had that pet following them connects). This may occur in some other -situations as well. Don't expect anything other than commands definitely -marked as usable in pet scripts to work in there reliably. - -Numbers -------- - -Beside the common decimal numbers, which are nothing special whatsoever -(though do not expect to use fractions, since ALL numbers are integer in -this language), the script engine also handles hexadecimal numbers, which -are otherwise identical. Writing a number like '0x<hex digits>' will make -it recognized as a hexadecimal value. Notice that 0x10 is equal to 16. -Also notice that if you try to 'mes 0x10' it will print '16'. - -Number values can't exceed the limits of an integer variable: Any number -greater than INT_MAX (2147483647) or smaller than INT_MIN (-2147483648) will -be capped to those values and will cause a warning to be reported. - -Variables ---------- - -The meat of every programming language is variables - places where you -store data. - -In Hercules scripting language, variable names are case sensitive. Even though -at the current time the script engine accepts them even with the incorrect -case, it is not advised to rely on this behavior, as it may change at any -time. - -Variables are divided into and uniquely identified by the combination of: -prefix - determines the scope and extent (or lifetime) of the variable -name - an identifier consisting of '_' and alphanumeric characters -postfix - determines the type of the variable: integer or string - -Scope can be: -global - global to all servers -local - local to the server -account - attached to the account of the character identified by RID -character - attached to the character identified by RID -npc - attached to the NPC -scope - attached to the scope of the instance - -Extent can be: -permanent - They still exist when the server resets. -temporary - They cease to exist when the server resets. - -Prefix: scope and extent -nothing - A permanent variable attached to the character, the default - variable type. -"@" - A temporary variable attached to the character. - They disappear when the character logs out. -"$" - A global permanent variable. - They are stored in database table `mapreg`. -"$@" - A global temporary variable. - They are important for scripts which are called with no RID - attached, that is, not triggered by a specific character object. -"." - A NPC variable. - They exist in the NPC and disappear when the server restarts or - the NPC is reloaded. Can be accessed from inside the NPC or by - calling 'getvariableofnpc'. Function objects can also have - .variables which are accessible from inside the function, - however 'getvariableofnpc' does NOT work on function objects. -".@" - A scope variable. - They are unique to the character, script and scope. Each script - execution has its own scope that ends when the script ends. - Calling a function with callsub()/callfunc() starts a new scope, - returning from the function ends it. When a scope ends, its - variables are converted to values ('return .@var;' returns a - value, not a reference). -"'" - An instance variable. - These are used with the instancing system, and are unique to - each instance. -"#" - A permanent local account variable. -"##" - A permanent global account variable stored by the login server. - The only difference you will note from normal # variables is - when you have multiple char-servers connected to the same - login-server. The # variables are unique to each char-server, - while the ## variables are shared by all these char-servers. - -Postfix: integer or string -nothing - integer variable, can store positive and negative numbers, but - only whole numbers (so don't expect to do any fractional math). -'$' - string variable, can store text. - -Examples: - 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 - instance integer variable - 'name$ - instance 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 - -If a variable was never set, it is considered to equal zero for integer -variables or an empty string ("", nothing between the quotes) for string -variables. Once you set it to that, the variable is as good as forgotten -forever, and no trace remains of it even if it was stored with character -or account data. The maximum length of variable name including prefix and -suffix is 32. - -Some variables are special, that is, they are already defined for you by -the scripting engine. You can see the full list somewhere in -'doc/constants.md', which is a file you should read, since it also -allows you to replace lots of numbered arguments for many commands with -easier to read text. The special variables most commonly used are all -permanent character-based variables: - -Zeny - Amount of Zeny in the inventory. -BankVault - Amount of Zeny in the bank. -Hp - Current amount of hit points. -MaxHp - Maximum amount of hit points. -Sp - Current spell points. -MaxSp - Maximum amount of spell points. -StatusPoint - Amount of status points remaining. -SkillPoint - Amount of skill points remaining. -BaseLevel - Character's base level. -JobLevel - Character's job level. -BaseExp - Amount of base experience points. -JobExp - Amount of job experience points. -NextBaseExp - Amount of base experience points needed to reach next level. -NextJobExp - Amount of job experience points needed to reach next level. -Weight - Amount of weight the character currently carries. - Display as in Weight/10. -MaxWeight - Maximum weight the character can carry. - Display as in MaxWeight/10. -Sex - Character's gender (SEX_MALE or SEX_FEMALE). -Class - Character's job. -Upper - 0 if the character is normal class, 1 if advanced, 2 if baby. -BaseClass - The character's 1-1 'normal' job, regardless of Upper value. - For example, this will return Job_Acolyte for Acolyte, - Priest/Monk, High Priest/Champion, and Arch Bishop/Sura. - If the character has not reached a 1-1 class, it will return - Job_Novice. -BaseJob - The character's 'normal' job, regardless of Upper value. - For example, this will return Job_Acolyte for Acolyte, - Baby Acolyte, and High Acolyte. -Karma - The character's karma. Karma system is not fully functional, - but this doesn't mean this doesn't work at all. Not tested. -Manner - The character's manner rating. Becomes negative if the - player utters words forbidden through the use of - 'manner.txt' client-side file. - -While these behave as variables, do not always expect to just set them - -it is not certain whether this will work for all of them. Whenever there -is a command or a function to set something, it's usually preferable to -use that instead. The notable exception is Zeny, which you can and often -will address directly - setting it will make the character own this number -of Zeny. If you try to set Zeny to a negative number, the script will be -terminated with an error. - -Assigning variables ---------- --------- - -Variables can be accessed and assigned values directly without the use of -the built-in 'set' function. This means that variables can be accessed and -modified much like other programming languages. - - .@x = 100; - .@x = .@y = 100; - -Support for modifying variable values using 'set' is still supported (and -required to exist for this method to work) so previous scripts will -continue working. Its usage, though, is deprecated, and it should never be -used in new scripts unless there are special reasons to do so. - -When assigning values, all operator methods are supported which exist in -the below 'Operators' section. For instance: - - .@x += 100; - .@x -= 100; - .@x *= 2; - .@x /= 2; - .@x %= 5; - .@x >>= 2; - .@x <<= 2; - -Will all work. For more information on available operators, see the -Operators section described below. All operators listed there may be -placed in-front of the '=' sign when modifying variables to perform the -action as required. - -Increment and decrement operators are also provided, for your convenience. -Pre-increment and pre-decrement operators: - - ++.@x; // same as .@x = .@x + 1 - --.@x; // same as .@x = .@x - 1 - -Post-increment and post-decrement operators: - - .@x++; // similar to .@x = .@x + 1 - .@x--; // similar to .@x = .@x - 1 - -The difference between pre- and post- increment/decrement operators is that, -when used in an expression, the pre- ones will be executed before evaluating -the expression, while the post- ones will be executed after. For example: - - .@x = 1; - .@y = ++.@x; // After this line is executed, both .@y and .@x will be 2 - .@x = 1; - .@y = .@x++; // After this line is executed, .@y will be 1, .@x will be 2 - -Note: The pre-increment/pre-decrement operators are, by design, faster (or at -least not slower) than their respective post- equivalent. - -Note: - - !! Currently the scripting engine does not support directly copying array - !! variables. In order to copy arrays between variables the use of - !! 'copyarray' function is still required. - -Strings -------- - -Strings are enclosed in "double quotes". To include the literal double -quote symbol (") in a string you need to escape it with a blackslash: - - .@string$ = "This string contains some \"double quote\" symbols"; - -Arrays ------- - -Arrays (in Hercules at least) are essentially a set of variables going -under the same name. You can tell between the specific variables of an -array with an 'array index', a number of a variable in that array: - -<variable name>[<array index>] - -All variable types can be used as arrays. - -Variables stored in this way, inside an array, are also called 'array -elements'. Arrays are specifically useful for storing a set of similar -data (like several item IDs for example) and then looping through it. You -can address any array variable as if it was a normal variable: - - .@arrayofnumbers[0] = 1; - -You can use a variable (or an expression, or even a value from an another -array) as array index: - - .@x = 100; - .@arrayofnumbers[.@x] = 10; - -This will make .@arrayofnumbers[100] equal to 10. - -Index numbering always starts with 0 and arrays can hold over 2 billion -variables. As such, the (guaranteed) allowed values for indices are in the -range 0 ~ 2147483647. - -If the array index is omitted, it defaults to zero. Writing -.@arrayofnumbers is perfectly equivalent to writing .@arrayofnumbers[0]. - -Arrays can naturally store strings: - -.@menulines$[0] is the 0th element of the .@menulines$ array of strings. -Notice the '$', normally denoting a string variable, before the square -brackets that denotes an array index. - -Variable References -------------------- - -//##TODO - -Hard-coded constants --------------------- -Most of the constants defined by the scripting engine can be found in -'doc/constants.md' and have the same value independently of settings -that are core related, but there are constants that can be used to -retrieve core information that's set when the server is compiled. - -PACKETVER - Server packet version -MAX_LEVEL - Maximum level -MAX_STORAGE - Maximum storage items -MAX_GUILD_STORAGE - Maximum guild storage items -MAX_CART - Maximum cart items -MAX_INVENTORY - Maximum inventory items -MAX_ZENY - Maximum Zeny in the inventory -MAX_BANK_ZENY - Maximum Zeny in the bank -MAX_BG_MEMBERS - Maximum BattleGround members -MAX_CHAT_USERS - Maximum Chat users -MAX_REFINE - Maximum Refine level -MAX_ITEM_ID - Maximum Item ID -MAX_MENU_OPTIONS - Maximum NPC menu options -MAX_MENU_LENGTH - Maximum NPC menu string length -MOB_CLONE_START - Clone ID start from this range -MOB_CLONE_END - Clone ID end with this range - -Send targets and status options are also hard-coded and can be found -in 'doc/constants.md'. - -Operators ---------- - -Operators are things you can do to variables and numbers. They are either -the common mathematical operations or conditional operators: - -+ - will add two numbers. If you try to add two strings, the result will - be a string glued together at the +. You can add a number to a string, - and the result will be a string. No other math operators work with - strings. -- - will subtract two numbers. -* - will multiply two numbers. -** - will raise the first number to the power of the second number. -/ - will divide two numbers. Note that this is an integer division, i.e. - 7/2 is not equal 3.5, it's equal 3. -% - will give you the remainder of the division. 7%2 is equal to 1. - -There are also conditional operators. This has to do with the conditional -command 'if' and they are meant to return either 1 if the condition is -satisfied and 0 if it isn't. That's what they call 'boolean' variables. 0 -means 'False'. Anything except the zero is 'True'. Odd as it is, -1 and -5 -and anything below zero will also be True.) - -You can compare numbers to each other and you compare strings to each -other, but you can not compare numbers to strings. - - == - Is true if both sides are equal. For strings, it means they contain - the same value. - >= - True if the first value is equal to, or greater than, the second - value. - <= - True if the first value is equal to, or less than, the second value. - > - True if the first value greater than the second value. - < - True if the first value is less than the second value. - != - True if the first value IS NOT equal to the second one. - ~= - True if the second value (as regular expression) matches the first - value. Both values must be strings. See the script function pcre_match() - for more details and advanced features. - ~! - True if the second value (as regular expression) DOES NOT match the - first value. Both values must be strings. See script function pcre_match() - for more details and advanced features. - -Examples: - - 1==1 is True. - 1<2 is True while 1>2 is False. - .@x>2 is True if .@x is equal to 3. But it isn't true if .@x is 2. - -Only '==', '!=', '~=' and '~!' have been tested for comparing strings. Since -there's no way to code a seriously complex data structure in this language, -trying to sort strings by alphabet would be pointless anyway. - -Comparisons can be stacked in the same condition: - - && - Is True if and only if BOTH sides are true. - ('1==1 && 2==2' is true. '2==1 && 1==1' is false.) - || - Is True if either side of this expression is True. - - 1==1 && 2==2 is True. - 1==1 && 2==1 is False. - 1==1 || 2==1 is True. - -Logical bitwise operators work only on numbers, and they are the following: - - << - Left shift. - >> - Right shift. - Left shift moves the binary 1(s) of a number n positions to the left, - which is the same as multiplying by 2, n times. - In the other hand, Right shift moves the binary 1(s) of a number n - positions to the right, which is the same as dividing by 2, n times. - Example: - b = 2; - a = b << 3; - mes(a); - a = a >> 2; - mes(a); - The first mes() command would display 16, which is the same as: - 2 x (2 x 2 x 2) = 16. - The second mes() command would display 4, which is the same as: - 16 / 2 = 8; 8 / 2 = 4. - & - And. - | - Or. - The bitwise operator AND (&) is used to test two values against each - other, and results in setting bits which are active in both arguments. - This can be used for a few things, but in Hercules this operator is - usually used to create bit-masks in scripts. - - The bitwise operator OR (|) sets to 1 a binary position if the binary - position of one of the numbers is 1. This way a variable can hold - several values we can check, known as bit-mask. A variable currently - can hold up to 32 bit-masks (from position 0 to position 1). This is a - cheap(skate) and easy way to avoid using arrays to store several - checks that a player can have. - - A bit-mask basically is (ab)using the variables bits to set various - options in one variable. With the current limit in variables it is - possible to store 32 different options in one variable (by using the - bits on position 0 to 31). - - Example(s): - - Basic example of the & operator, bit example: - 10 & 2 = 2 - Why? : - 10 = 2^1 + 2^3 (2 + 8), so in bits, it would be 1010 - 2 = 2^1 (2), so in bits (same size) it would be 0010 - The & (AND) operator sets bits which are active (1) in both - arguments, so in the example 1010 & 0010, only the 2^1 bit is - active (1) in both. Resulting in the bit 0010, which is 2. - - Basic example of creating and using a bit-mask: - .@options = 2|4|16; // (note: this is the same as 2+4+16, or 22) - if (.@options & 1) - mes("Option 1 is activated"); - if (.@options & 2) - mes("Option 2 is activated"); - if (.@options & 4) - mes("Option 3 is activated"); - if (.@options & 8) - mes("Option 4 is activated"); - if (.@options & 16) - mes("Option 5 is activated"); - This would print the messages about option 2, 3 and 5 (since we've set - the 2,4 and 16 bit to 1). - ^ - Xor. - The bitwise operator XOR (eXclusive OR) sets a binary position to 0 if - both numbers have the same value in the said position. On the other - hand, it sets to 1 if they have different values in the said binary - position. This is another way of setting and unsetting bits in - bit-masks. - - Example: - - First let's set the quests that are currently in progress: - inProgress = 1|8|16; // quest 1,8 and 16 are in progress - - After playing for a bit, the player starts another quest: - if (inProgress&2 == 0) { - // this will set the bit for quest 2 (inProgress has that bit set to 0) - inProgress = inProgress^2; - mes("Quest 2: find a newbie and be helpful to him for an hour."); - close(); - } - - After spending some time reading info on Xor's, the player finally - completes quest 1: - if (inProgress&1 && isComplete) { - // this will unset the bit for quest 1 (inProgress has that bit set to 1) - inProgress = inProgress^1; - mes("Quest 1 complete!! You unlocked the secrets of the Xor dynasty, use them wisely."); - close(); - } - -Unary operators with only with a single number, which follows the -operator, and are the following: - - - - Negation. - The sign of the number will be reversed. If the number was positive, - it will become negative and vice versa. - - Example: - .@myvar = 10; - mes("Negative 10 is "+(-.@myvar)); - - ! - Logical Not. - Reverses the boolean result of an expression. True will become false - and false will become true. - - Example: - if (!callfunc("F_dosomething")) { - mes("Doing something failed."); - close(); - } - - ~ - Bitwise Not. - Reverses each bit in a number, also known as one's complement. Cleared - bits are set, and set bits are cleared. - - Example: - - Ensure, that quest 2 is disabled, while keeping all other active, if - they are. - inProgress = inProgress&(~2); - // same as set inProgress, inProgress&0xfffffffd - -Ternary operators take three expressions (numbers, strings or boolean), -and are the following: - - ?: - Conditional operator - Very useful e.g. to replace - - if (Sex == SEX_MALE) - mes("You're Male."); - else - mes("You're Female."); - - clauses with simple - - mes("Welcome, " + (Sex == SEX_MALE ? "Mr." : "Mrs.") + " " + strcharinfo(PC_NAME)); - - or to replace any other simple if-else clauses. It might be worth - mentioning that ?: has low priority and has to be enclosed with - parenthesis in most (if not all) cases. - -Operator Precedence and Associativity - -Operator precedence and associativity work more or less like they do in -mathematics. The rules can be summarized with the following table: - -Precedence | Description | Associativity ---------------------------------------------------------------------------- -1 (highest) | [] Array subscripting | None ---------------------------------------------------------------------------- -2 | ++ Increment | None - | -- Decrement | ---------------------------------------------------------------------------- -2 | - Unary minus | Right to left - | ! Logical NOT | - | ~ Bitwise NOT (One's Complement) | ---------------------------------------------------------------------------- -3 | ** Exponentiation | Left to right ---------------------------------------------------------------------------- -4 | * Multiplication | Left to right - | / Division | - | % Modulo (remainder) | ---------------------------------------------------------------------------- -5 | + Addition | Left to right - | - Subtraction | ---------------------------------------------------------------------------- -6 | << Bitwise left shift | Left to right - | >> Bitwise right shift | ---------------------------------------------------------------------------- -7 | < Less than | Left to right - | <= Less than or equal to | - | > Greater than | - | >= Greater than or equal to | ---------------------------------------------------------------------------- -8 | == Equal to | Left to right - | != Not equal to | - | ~= Regexp match | - | ~! Regexp non-match | ---------------------------------------------------------------------------- -9 | & Bitwise AND | Left to right ---------------------------------------------------------------------------- -10 | ^ Bitwise XOR (exclusive or) | Left to right ---------------------------------------------------------------------------- -11 | | Bitwise OR (inclusive or) | Left to right ---------------------------------------------------------------------------- -12 | && Logical AND | Left to right ---------------------------------------------------------------------------- -13 | || Logical OR | Left to right ---------------------------------------------------------------------------- -14 | ?: Ternary conditional | Right to left ---------------------------------------------------------------------------- -15 | = Direct assignment | Right to left -(lowest) | += Assignment by sum | - | -= Assignment by difference | - | *= Assignment by product | - | **= Assignment by power | - | /= Assignment by quotient | - | %= Assignment by remainder | - | <<= Assignment by bitwise left shift | - | >>= Assignment by bitwise right shift | - | &= Assignment by bitwise AND | - | ^= Assignment by bitwise XOR | - | |= Assignment by bitwise OR | - -Operator precedence means some operators are evaluated before others. For -example, in 2 + 4 * 5 , the multiplication has higher precedence so 4 * 5 is -evaluated first yielding 2 + 20 == 22 and not 6 * 5 == 30 . - -Operator associativity defines what happens if a sequence of the same -operators is used one after another: whether the evaluator will evaluate the -left operations first or the right. For example, in 8 - 4 - 2 , subtraction is -left associative so the expression is evaluated left to right. 8 - 4 is -evaluated first making the expression 4 - 2 == 2 and not 8 - 2 == 6 . - -Labels ------- - -Within executable script code, some lines can be labels: - -<label name>: - -Labels are points of reference in your script, which can be used to route -execution with 'goto' and 'menu' commands, invoked with 'doevent', 'donpcevent' -and 'callsub' commands and are otherwise essential. A label's name may not be -longer than 23 characters. (24th is the ':'.) It may only contain alphanumeric -characters and underscore. In addition to labels you name yourself, there are -also some special labels which the script engine will start execution from if -a special event happens: - -OnClock<hour><minute>: -OnMinute<minute>: -OnHour<hour>: -On<weekday><hour><minute>: -OnDay<month><day>: - -This will execute when the server clock hits the specified date or time. -Hours and minutes are given in military time. ('0105' will mean 01:05 AM). -Weekdays are Sun, Mon, Tue, Wed, Thu, Fri, Sat. Months are 01 to 12, days are -01 to 31. Remember the zero. :) - -OnInit: -OnInterIfInit: -OnInterIfInitOnce: - -OnInit will execute every time the scripts loading is complete, including -when they are reloaded with @reloadscript command. OnInterIfInit will -execute when the map server connects to a char server, OnInterIfInitOnce -will only execute once and will not execute if the map server reconnects -to the char server later. Note that all those events will be executed upon -scripts reloading. - -OnAgitStart: -OnAgitEnd: -OnAgitInit: -OnAgitStart2: -OnAgitEnd2: -OnAgitInit2: - -OnAgitStart will run whenever the server shifts into WoE mode, whether it -is done with @agitstart GM command or with 'AgitStart' script command. -OnAgitEnd will do likewise for the end of WoE. - -OnAgitInit will run when data for all castles and all guilds that hold a -castle is received by map-server from the char-server after initial -connect. - -No RID will be attached while any of the above mentioned labels are -triggered, so no character or account-based variables will be accessible, -until you attach a RID with 'attachrid' (see below). - -The above also applies to, the last three labels, the only difference is -that these labels are used exclusively for WoE SE, and are called -independently. - -OnInstanceInit: - -This label will be executed when an instance is created and initialized through -the 'instance_init' command. It will run again if @reloadscript is used while -an instance is in progress. - -OnTouch: - -This label will be executed if a trigger area is defined for the NPC -object it's in. If it isn't present, the execution will start from the -beginning of the NPC code. The RID of the triggering character object will -be attached. - -OnTouch_: - -Similar to OnTouch, but will only run one instance. Another character is -chosen once the triggering character leaves the area. - -OnUnTouch: - -This label will be executed if plater leave trigger area is defined for the NPC -object it's in. If it isn't present, nothing will happend. -The RID of the triggering character object will be attached. - -OnPCLoginEvent: -OnPCLogoutEvent: -OnPCBaseLvUpEvent: -OnPCJobLvUpEvent: - -It's pretty obvious when these four special labels will be invoked. - -OnPCDieEvent: - -This special label triggers when a player dies. The variable 'killerrid' -is set to the ID of the killer. - -OnPCKillEvent: - -This special label triggers when a player kills another player. The -variable 'killedrid' is set to the ID of the player killed. - -OnNPCKillEvent: - -This special label triggers when a player kills a monster. The variable -'killedrid' is set to the Class of the monster killed. - -OnPCLoadMapEvent: - -This special label will trigger once a player steps in a map marked with -the 'loadevent' mapflag and attach its RID. The fact that this label -requires a mapflag for it to work is because, otherwise, it'd be -server-wide and trigger every time a player would change maps. Imagine the -server load with 1,000 players (oh the pain...) - -Only the special labels which are not associated with any script command -are listed here. There are other kinds of labels which may be triggered in -a similar manner, but they are described with their associated commands. - -OnCountFunds: - -This special label is triggered when a player opens a trader NPC object that -is NST_CUSTOM. It is used to define different currency types to the trader via -setcurrency(). Should be used along with OnPayFunds, see -doc/sample/npc_trader_sample.txt for more information. - -OnPayFunds: - -This special label is triggered when a purchase is made on a trader NPC object -that is NST_CUSTOM. Receives @price, total cost and @points, secondary input -field for cash windows. It is used to remove items that are set as currency. -Should be used along with OnCountFunds, see /doc/sample/npc_trader_sample.txt -for more information. - -On<label name>: - -These special labels are used with Mob scripts mostly, and script commands -that requires you to point/link a command to a mob or another NPC, giving -a label name to start from. The label name can be any of your liking, but -must be started with "On". - -Example: - -monster("prontera", 123, 42, "Poringz0rd", 2341, 23, "Master::OnThisMobDeath"); - -amatsu,13,152,4 script Master 767,{ - mes("Hi there"); - close(); - -OnThisMobDeath: - announce("Hey, "+strcharinfo(PC_NAME)+" just killed a Poringz0rd!", bc_blue|bc_all); - end; -} - -Each time you kill one, that announce will appear in blue to everyone. - -"Global" labels - -There's a catch with labels and doevent(). If you call a label (using -doevent()) and called label is in NPC that has trigger area, that label must -end with "Global" to work globally (i.e. if RID is outside of the trigger area, -which usually happens since otherwise there would be no point calling the label -with doevent(), because OnTouch would do the job). For further reference look -for npc_event in npc.c. - -Scripting commands and functions --------------------------------- - -The commands and functions are listed here in no particular order. There's -a difference between commands and functions - commands leave no 'return -value' which might be used in a conditional statement, as a command -argument, or stored in a variable. - -All instructions must end with a ';'. Actually, you may expect to have multiple -instructions on one line if you properly terminate them with a ';', but it's -consider ill practice, since it impairs legibility of the script. - -Please note that command and function names are case sensitive. - -------------------------- - - -From here on, we will have the commands sorted as followed: - -1 - Basic Commands -2 - Information-Retrieving Commands - -- 2.1 - Item-Related Commands - -- 2.2 - Guild-Related Commands -3 - Checking Commands - -- 3.1 - Checking Item-Related Commands -4 - Player-Related Commands - -- 4.1 - Player Item-Related Commands - -- 4.2 - Guild-Related Commands - -- 4.3 - Marriage-Related Commands -5 - Mob / NPC Related commands - -- 5.1 - Time-Related Commands - -- 5.2 - Guild-Related Commands -6 - Other Commands -7 - Instance-Related Commands -8 - Quest Log Commands -9 - Battleground Commands -10 - Mercenary Commands -11 - Queue Commands -12 - NPC Trader Commands - - ---------------------------------------- -//===================================== -1 - Basic Commands -//===================================== ---------------------------------------- - -*mes("<string>") - -This command will displays a box on the screen for the invoking character, -if no such box is displayed already, and will print the string specified -into that box. There is normally no 'close' or 'next' button on this box, -unless you create one with 'close' or 'next', and while it's open the -player can't do much else, so it's important to create a button later. If -the string is empty, it will show up as an empty line. - - mes("Text that will appear in the box"); - -Inside the string you may put color codes, which will alter the color of -the text printed after them. The color codes are all '^<R><G><B>' and -contain three hexadecimal numbers representing colors as if they were -HTML colors - ^FF0000 is bright red, ^00FF00 is bright green, ^0000FF is -bright blue, ^000000 is black. ^FF00FF is a pure magenta, but it's also -a color that is considered transparent whenever the client is drawing -windows on screen, so printing text in that color will have kind of a -weird effect. You may also use C_ constants accompany with "F_MesColor" -function for the color effect, see the full list of the available ones -in 'db/constants.conf' under 'C_'. Once you've set a text's color to something, -you have to set it back to black unless you want all the rest of the text be in -that color: - - mes("This is ^FF0000 red ^000000 and this is ^00FF00 green, ^000000 so."); - mesf("%sThis message is now in BLUE.", F_MesColor(C_BLUE)); - -Notice that the text coloring is handled purely by the client. If you use -non-English characters, the color codes might get screwed if they stick to -letters with no intervening space. Separating them with spaces from the -letters on either side solves the problem. - -If you're using a client from 2011-10-10aRagexe.exe onwards, you can also -use automatic navigation and open URLs in browser by using some HTML-like -labels. For example: - - mes("go to <NAVI>[Hat Maker]<INFO>izlude,131,148,</INFO></NAVI> to make hats"); - -Will make the [Hat Maker] text clickable in the client and start a navigation -to that point. - - mes("You can <URL>Google<INFO>http://www.google.com/</INFO></URL> anything"); - -This will allow you to visit 'Google' with the in-game browser using default dimensions. - - mes("You can <URL>Bing!<INFO>http://www.bing.com/,800,600</INFO></URL> anything"); - -Clicking 'Bing!' will open the in-game browser using the specified dimensions. (800x600) - -If you're using client from 2013-01-30 onwards, you can also use <ITEMLINK> to show -the item's description. Gravity changed this into <ITEM> since 2015-07-29 onwards. - - mes("Bring me an <ITEM>Apple<INFO>512</INFO></ITEM>."); - mesf("Bring me an %s.", F_MesItemInfo(Apple)); - -This will show the item name and a clickable link for the item description. - ---------------------------------------- - -*mesf("<format>"{, <param>{, <param>{, ...}}}) - -This command will display a box on the screen for the invoking character, -if no such box is displayed already, and will print the string specified -into that box, after applying the same format-string replacements as sprintf(). - -Example: - - mesf("Hello, I'm %s, a level %d %s", strcharinfo(PC_NAME), BaseLevel, jobname(Class)); - // is equivalent to: - mes(sprintf("Hello, I'm %s, a level %d %s", strcharinfo(PC_NAME), BaseLevel, jobname(Class))); - -This command is a combination of mes() and sprintf(). See their documentation -for more details. - ---------------------------------------- - -*next() - -This command will display a 'next' button in the message window for the -invoking character. Clicking on it will cause the window to clear and -display a new one. Used to segment NPC-talking, next() is often used in -combination with mes() and close(). - -If no window is currently on screen, one will be created, but once the -invoking character clicks on it, a warning is thrown on the server console -and the script will terminate. - - mes("[Woman]"); - mes("This would appear on the page"); - next(); - mes("[Woman]"); // This is needed since it is a new page and the top will now be blank - mes("This would appear on the 2nd page"); - ---------------------------------------- - -*close() - -This command will create a 'close' button in the message window for the -invoking character. If no window is currently on screen, the script -command 'end;' must be used. This is one of the ways to end a speech from -an NPC. Once the button is clicked, the NPC script execution will end, and -the message box will disappear. - - mes("[Woman]"); - mes("I am finished talking to you, click the close button."); - close(); - mes("This command will not run at all, since the script has ended."); - ---------------------------------------- - -*close2() - -This command will create a 'close' button in the message window for the -invoking character. WARNING: If no window is currently on screen, the -script execution will halt indefinitely! See 'close'. There is one -important difference, though - even though the message box will have -closed, the script execution will not stop, and commands after 'close2' -will still run, meaning an 'end' has to be used to stop the script, unless -you make it stop in some other manner. - - mes("[Woman]"); - mes("I will warp you now."); - close2(); - warp("place", 50, 50); - end; - -Don't expect things to run smoothly if you don't make your scripts 'end'. - ---------------------------------------- - -*end - -This instruction will stop the execution for this particular script. -Note that this is to be considered a special instruction (not a regular -command or function), and as such doesn't require parentheses. - - if (BaseLevel <= 10) { - npctalk("Look at that you are still a n00b"); - end; - } - if (BaseLevel <= 20) { - npctalk("Look at that you are getting better, but still a n00b"); - end; - } - if (BaseLevel <= 30) { - npctalk("Look at that you are getting there, you are almost 2nd profession now right???"); - end; - } - if (BaseLevel <= 40) { - npctalk("Look at that you are almost 2nd profession"); - end; - } - -Without the use of 'end' it would travel through the ifs until the end -of the script. If you were lvl 10 or less, you would see all the speech -lines, the use of 'end' stops this, and ends the script. - ---------------------------------------- - -*set(<variable>, <expression>) - -This command will set a variable to the value that the expression results -in. This isn't the only way to set a variable directly: you can set them -much like any other programming language as stated before (refer to the -'Assigning variables' section). - -This command is deprecated and it shouldn't be used in new scripts, except -some special cases (mostly, set(getvariableofnpc(), <value>)). Use direct value -assignment instead. - ---------------------------------------- - -*setd("<variable name>", <value>) - -Works almost identically as set(), except the variable name is -identified as a string and can thus be constructed dynamically. - -This command is equivalent to: - set(getd("variable name"), <value>); - -Examples: - - setd(".@var$", "Poporing"); - mes(.@var$); // Displays "Poporing". - - setd(".@" + .@var$ + "123$", "Poporing is cool"); - mes(.@Poporing123$); // Displays "Poporing is cool". - ---------------------------------------- - -*getd("<variable name>") - -Returns a reference to a variable, the name can be constructed dynamically. -Refer to setd() for usage. - -This can also be used to set an array dynamically: - setarray(getd(".array[0]"), 1, 2, 3, 4, 5); - -Examples: - - mes("The value of $varReference is: " + getd("$varRefence")); - set(.@i, getd("$" + "pikachu")); - ---------------------------------------- - -*getvariableofnpc(<variable>, "<npc name>") - -Returns a reference to a NPC variable (. prefix) from the target NPC. -This can only be used to get . variables. - -Examples: - -//This will return the value of .var, note that this can't be used, since -//the value isn't caught. - getvariableofnpc(.var, "TargetNPC"); - -//This will set the .@v variable to the value of the TargetNPC's .var -//variable. - .@v = getvariableofnpc(.var, "TargetNPC"); - -//This will set the .var variable of TargetNPC to 1. - set(getvariableofnpc(.var, "TargetNPC"), 1); - -Note: even though function objects can have .variables, -getvariableofnpc() should not be used on them. - ---------------------------------------- - -*getvariableofpc(<variable>, <account id>{, <default value>}) - -Returns a reference to a PC variable from the target player. -If <default value> is passed, it will return this value if the player is -not found. - -Examples: - -//This will return the value of @var, note that this can't be used, since -//the value isn't caught. - getvariableofpc(@var, getcharid(CHAR_ID_ACCOUNT, "player")); - -//This will set the .@v variable to the value of the player's @var -//variable. - .@v = getvariableofpc(@var, getcharid(CHAR_ID_ACCOUNT, "player")); - -//This will set the @var variable of the player to 1. - set(getvariableofpc(@var, getcharid(CHAR_ID_ACCOUNT, "player")), 1); - ---------------------------------------- - -*goto(<label>) - -This command will make the script jump to a label, usually used in -conjunction with other instructions, such as "if", but often used on its own. - - ... - goto(Label); - mes("This will not be seen"); -Label: - mes("This will be seen"); - -Gotos are considered to be harmful and should be avoided whenever possible. - ---------------------------------------- - -*menu("<option_text>", <target_label>{, "<option_text>", <target_label>, ...}) - -This command will create a selectable menu for the invoking character. -Only one menu can be on screen at the same time. - -Depending on what the player picks from the menu, the script execution -will continue from the corresponding label. It's string-label pairs, not -label-string. - -This command is deprecated and it should not be used in new scripts, as it -is likely to be removed at a later time. Please consider using select() or -prompt() instead. - -Options can be grouped together, separated by the character ':'. - - menu("A:B", L_Wrong, "C", L_Right); - -It also sets a special temporary character variable @menu, which contains -the number of option the player picked. Numbering of options starts at 1. -This number is consistent with empty options and grouped options. - - menu("A::B", L_Wrong, "", L_Impossible, "C", L_Right); - L_Wrong: - // If they click "A" or "B" they will end up here - // @menu == 1 if "A" - // @menu == 2 will never happen because the option is empty - // @menu == 3 if "B" - L_Impossible: - // Empty options are not displayed and therefore can't be selected - // this label will never be reached from the menu command - L_Right: - // If they click "C" they will end up here - // @menu == 5 - -If a label is '-', the script execution will continue right after the menu -command if that option is selected, this can be used to save you time, and -optimize big scripts. - - menu("A::B:", -, "C", L_Right); - // If they click "A" or "B" they will end up here - // @menu == 1 if "A" - // @menu == 3 if "B" - L_Right: - // If they click "C" they will end up here - // @menu == 5 - -Both these examples will perform the exact same task. - -If you give an empty string as a menu item, the item will not display. -This can effectively be used to script dynamic menus by using empty string -for entries that should be unavailable at that time. - -You can do it by using arrays, but watch carefully - this trick isn't high -wizardry, but minor magic at least. You can't expect to easily duplicate -it until you understand how it works. - -Create a temporary array of strings to contain your menu items, and -populate it with the strings that should go into the menu at this -execution, making sure not to leave any gaps. Normally, you do it with a -loop and an extra counter, like this: - - setarray(.@possiblemenuitems$[0], <list of potential menu items>); - .@j = 0; // That's the menu lines counter. - - // We loop through the list of possible menu items. - // .@i is our loop counter. - for (.@i = 0; .@i < getarraysize(.@possiblemenuitems$); ++.@i) { - // That 'condition' is whatever condition that determines whether - // a menu item number .@i actually goes into the menu or not. - - if (<condition>) { - // We record the option into the list of options actually - // available. - .@menulist$[.@j] = .@possiblemenuitems$[.@i]; - - // We just copied the string, we do need it's number for later - // though, so we record it as well. - .@menureference[.@j] = .@i; - - // Since we've just added a menu item into the list, we - // increment the menu lines counter. - ++.@j; - } - - // We go on to the next possible menu item. - } - -This will create you an array .@menulist$ which contains the text of all -items that should actually go into the menu based on your condition, and -an array .@menureference, which contains their numbers in the list of -possible menu items. Remember, arrays start with 0. There's less of them -than the possible menu items you've defined, but the menu() command can -handle the empty lines - only if they are last in the list, and if it's -made this way, they are. Now comes a dirty trick: - - // X is whatever the most menu items you expect to handle. - menu(.@menulist$[0], -, .@menulist$[1], -, ..., .@menulist$[<X>], -); - -This calls up a menu of all your items. Since you didn't copy some of the -possible menu items into the list, it's end is empty and so no menu items -will show up past the end. But this menu() call doesn't jump anywhere, it -just continues execution right after the menu() command. (And it's a good -thing it doesn't, cause you can only explicitly define labels to jump to, -and how do you know which ones to define if you don't know beforehand -which options will end up where in your menu?) -But how do you figure out which option the user picked? Enter the @menu. - -@menu contains the number of option that the user selected from the list, -starting with 1 for the first option. You know now which option the user -picked and which number in your real list of possible menu items it -translated to: - - mes("You selected "+.@possiblemenuitems$[.@menureference[@menu-1]]+"!"); - -@menu is the number of option the user picked. -@menu-1 is the array index for the list of actually used menu items that -we made. -.@menureference[@menu-1] is the number of the item in the array of possible -menu items that we've saved just for this purpose. - -And .@possiblemenuitems$[.@menureference[@menu-1]] is the string that we -used to display the menu line the user picked. (Yes, it's a handful, but -it works.) - -You can set up a bunch of 'if (.@menureference[@menu-1]==X) goto(Y)' -statements to route your execution based on the line selected and still -generate a different menu every time, which is handy when you want to, for -example, make users select items in any specific order before proceeding, -or make a randomly shuffled menu. - -Kafra code bundled with the standard distribution uses a similar -array-based menu technique for teleport lists, but it's much simpler and -doesn't use @menu, probably since that wasn't documented anywhere. - -See also 'select', which is probably better in this particular case. -Instead of menu(), you could use select() like this: - - .@dummy = select(.@menulist$[0], .@menulist$[1], ..., .@menulist$[<X>]); - -For the purposes of the technique described above these two statements are -perfectly equivalent. - ---------------------------------------- - -*select("<option>"{, "<option>", ...}) - -This function is a handy replacement for 'menu' that doesn't use a complex -label structure. It will return the number of the menu option picked, -starting with 1. If the player presses cancel, the script is terminated. - - if (select("Yes", "No") == 1) - mes("You said yes, I know."); - -And like 'menu', the selected option is consistent with grouped options -and empty options. - ---------------------------------------- - -*prompt("<option>"{, "<option>", ...}) - -This function behaves exactly like select(), but when a player presses cancel -it returns MAX_MENU_OPTIONS and the script is not terminated. You almost always -want to use select() rather than prompt(). - ---------------------------------------- - -*input(<variable>{, <min>{, <max>}}) - -This command will make an input box pop up on the client connected to the -invoking character, to allow entering of a number or a string. This has -many uses, one example would be a guessing game, also making use of the -'rand' function: - - mes("[Woman]"); - mes("Try and guess the number I am thinking of."); - mes("The number will be between 1 and 10."); - next(); - .@number = rand(1, 10); - input(.@guess); - if (.@guess == .@number) { - mes("[Woman]"); - mes("Well done that was the number I was thinking of"); - close(); - } else { - mes("[Woman]"); - mes("Sorry, that wasn't the number I was thinking of."); - close(); - } - -If you give the input() command a string variable to put the input in, it -will allow the player to enter text. Otherwise, only numbers will be -allowed. - - mes("[Woman]"); - mes("Please say HELLO"); - next(); - input(.@var$); - if (.@var$ == "HELLO") { - mes("[Woman]"); - mes("Well done you typed it correctly"); - close(); - } else { - mes("[Woman]"); - mes("Sorry you got it wrong"); - close(); - } - -Normally you may not input a negative number with this command. -This is done to prevent exploits in badly written scripts, which would let -people, for example, put negative amounts of Zeny into a bank script and -receive free Zeny as a result. - -The command has two optional arguments and a return value. -The default value of 'min' and 'max' can be set with 'input_min_value' and -'input_max_value' in conf/map/script.conf. -For numeric inputs the value is capped to the range [min, max]. Returns 1 -if the value was higher than 'max', -1 if lower than 'min' and 0 otherwise. -For string inputs it returns 1 if the string was longer than 'max', -1 is -shorter than 'min' and 0 otherwise. - ---------------------------------------- - -*callfunc("<function>"{, <argument>, ...<argument>}) - -This command lets you call up a function NPC. A function NPC can be called -from any script on any map server. Using the 'return' instruction it -will come back to the place that called it. - - place,50,50,6%TAB%script%TAB%Woman%TAB%115,{ - mes("[Woman]"); - mes("Lets see if you win"); - callfunc("funcNPC"); - mes("Well done you have won"); - close(); - } - function%TAB%script%TAB%funcNPC%TAB%{ - .@win = rand(2); - if (.@win == 0) - return; - mes("Sorry you lost"); - end; - } - -You can pass arguments to your function - values telling it what exactly -to do - which will be available there with getarg() (see 'getarg'). -Notice that returning is not mandatory, you can end execution right there. - -If you want to return a real value from inside your function NPC, you -may do so: - - place,50,50,6%TAB%script%TAB%Man%TAB%115,{ - mes("[Man]"); - mes("Gimme a number!"); - next(); - input(.@number); - if (callfunc("OddFunc", .@number)) - mes("It's Odd!"); - close(); - } - function%TAB%script%TAB%OddFunc%TAB%{ - if (getarg(0)%2==0) - return 0;// it's even - return 1;// it's odd - } - -Alternately, user-defined functions may be called directly without the use -of the callfunc() script command. - - function<TAB>script<TAB>SayHello<TAB>{ - mes("Hello " + getarg(0)); - return 0; - } - - place,50,50,6<TAB>script<TAB>Man<TAB>115,{ - mes("[Man]"); - SayHello(strcharinfo(PC_NAME)); - close(); - } - -Note: - - !! A user-defined function must be declared /before/ a script attempts to - !! call it. That is to say, any functions should be placed above scripts - !! or NPCs (or loaded in a separate file first) before attempting to call - !! them directly. - ---------------------------------------- - -*callsub(<label>{, <argument>, ...<argument>}) - -This command will go to a specified label within the current script (do -NOT use quotes around it) coming in as if it were a 'callfunc' call, and -pass it arguments given, if any, which can be recovered there with -'getarg'. When done there, you should use the 'return' command to go back -to the point from where this label was called. This is used when there is -a specific thing the script will do over and over, this lets you use the -same bit of code as many times as you like, to save space and time, -without creating extra NPC objects which are needed with 'callfunc'. A -label is not callable in this manner from another script. - -Example 1: callsub for checking (if checks pass, return to script) - callsub(S_CheckFull, "guild_vs2", 50); - switch (rand(4)) { - case 0: - warp("guild_vs2", 9, 50); - end; - case 1: - warp("guild_vs2", 49, 90); - end; - case 2: - warp("guild_vs2", 90, 50); - end; - case 3: - warp("guild_vs2", 49, 9); - end; - } - end; - -S_CheckFull: - if (getmapusers(getarg(0)) >= getarg(1)) { - mes("I'm sorry, this arena is full. Please try again later."); - close(); - } - return; - -Example 2: callsub used repeatedly, with different arguments -// notice how the Zeny check/delete is reused, instead of copy-pasting for -// every warp. - switch (select("Abyss Lake", "Amatsu Dungeon", "Anthell", "Ayothaya Dungeon", "Beacon Island, Pharos")) { - case 1: - callsub(S_DunWarp, "hu_fild05", 192, 207); - break; - case 2: - callsub(S_DunWarp, "ama_in02", 119, 181); - break; - case 3: - callsub(S_DunWarp, "moc_fild20", 164, 145); - break; - case 4: - callsub(S_DunWarp, "ayo_fild02", 279, 150); - break; - case 5: - callsub(S_DunWarp, "cmd_fild07", 132, 125); - break; - // etc - } - -// ... - -S_DunWarp: -// getarg(0) = "mapname" -// getarg(1) = x -// getarg(2) = y - if (Zeny >= 100) { - Zeny -= 100; - warp(getarg(0), getarg(1), getarg(2)); - } else { - mes("Dungeon warp costs 100 Zeny."); - } - close(); - ---------------------------------------- - -*getarg(<index>{, <default_value>}) - -This function is used when you use the 'callsub' or 'callfunc' commands. -In the call you can specify variables that will make that call different -from another one. This function will return an argument the function or -subroutine was called with, and is the normal way to get them. -This is another thing that can let you use the same code more than once. - -Argument numbering starts with 0, i.e. the first argument you gave is -number 0. If no such argument was given, a zero is returned. - - place,50,50,6%TAB%script%TAB%Woman1%TAB%115,{ - mes("[Woman]"); - mes("Lets see if you win"); - callfunc("funcNPC", 2); - mes("Well done you have won"); - // ... - } - - place,52,50,6%TAB%script%TAB%Woman2%TAB%115,{ - mes("[Woman]"); - mes("Lets see if you win"); - callfunc("funcNPC", 5); - mes("Well done you have won"); - // ... - } - - function%TAB%script%TAB%funcNPC%TAB%{ - .@win = rand(getarg(0)); - if (.@win == 0) - return; - mes("Sorry you lost"); - close(); - } - -"woman1" NPC object calls the funcNPC. The argument it gives in this call -is stated as 2, so when the random number is generated by the 'rand' -function, it can only be 0 or 1. Whereas "woman2" gives 5 as the argument -number 0 when calling the function, so the random number could be 0, 1, 2, -3 or 4, this makes "woman2" less likely to say the player won. - -You can pass multiple arguments in a function call: - - callfunc("funcNPC", 5, 4, 3); - -getarg(0) would be 5, getarg(1) would be 4 and getarg(2) would be 3. - -Getarg also has an optional argument: -If the target argument exists, it is returned. -Otherwise, if <default_value> is present it is returned instead, if not -the script terminates immediately. - -In previous example getarg(2, -1) would be 3 and getarg(3, -1) would be -1. - ---------------------------------------- - -*getargcount() - -This function is used when you use the 'callsub' or 'callfunc' commands. -In the call you can specify arguments. This function will return the -number of arguments provided. - -Example: - callfunc("funcNPC", 5, 4, 3); - // ... - function%TAB%script%TAB%funcNPC%TAB%{ - .@count = getargcount(); // 3 - //... - } - ---------------------------------------- - -*return {<value>} - -This instruction causes the script execution to leave previously called -function with callfunc() or script with callsub() and return to the -location, where the call originated from. Optionally a return value can -be supplied. - -Using this command outside of functions or scripts referenced by callsub -will result in error and termination of the script. - - callfunc("<your function>"); // when nothing is returned - <variable> = callfunc("<your function>"); // when a value is being returned - ---------------------------------------- - -*function <function name>; -*<function name>{(<argument>, ...<argument>)}; -*function <function name> { -<code> -} - -This works like callfunc(), and is used for cleaner and faster scripting. -The function must be defined and used within a script, and works like a -label with arguments. -Note that the name may only contain alphanumeric characters and underscore. - -Usage: - - 1. Declare the function. - function <function name>; - 2. Call the function anywhere within the script. - It can also return a value when used with parentheses. - <function name>; - 3. Define the function within the script. - <function name> {<code>} - -Example: - -prontera,154,189,4 script Item Seller 767,{ - /* Function declaration */ - function SF_Selling; - - if (Zeny > 50) { - mes("Welcome!"); - /* Function call */ - SF_Selling(); - } else { - mes("You need 50z, sorry!"); - } - close(); - - /* Function definition */ - function SF_Selling { - mes("Would you like to buy a phracon for 50z?"); - next(); - if (select("Yes", "No, thanks") == 1) { - Zeny -= 50; - getitem(Phracon, 1); - mes("Thank you!"); - } - return; - } -} - -Example with parameters and return value: - -prontera,150,150,0 script TestNPC 123,{ - /* Function declaration */ - function MyAdd; - - mes("Enter two numbers."); - next(); - input(.@a); - input(.@b); - /* Function call */ - mes(.@a+" + "+.@b+" = "+MyAdd(.@a, .@b)); - close(); - - /* Function definition */ - function MyAdd { - return(getarg(0)+getarg(1)); - } -} - - ---------------------------------------- - -*is_function("<function name>") - -This command checks whether or not a function exists and returns its type. -Returns false if it cannot be found. - -return values: - - FUNCTION_IS_COMMAND - built-in script command (eg: mes, select, ...) - FUNCTION_IS_GLOBAL - user-defined global function (callable with callfunc) - FUNCTION_IS_LOCAL - user-defined local function - FUNCTION_IS_LABEL - user-defined label function (callable with callsub) - -Example: - - function script func1 { - dothat(); - } - - - script test FAKE_NPC,{ - function func2 { - do_something(); - } - - func3: - end; - - is_function("func1"); // FUNCTION_IS_GLOBAL - is_function("func2"); // FUNCTION_IS_LOCAL - is_function("func3"); // FUNCTION_IS_LABEL - is_function("select"); // FUNCTION_IS_COMMAND - is_function("invalid"); // false - } - ---------------------------------------- - -*if (<condition>) <statement or block> - -This is the basic conditional command. - -The condition can be any expression. All expressions resulting in a -non-zero value will be considered True, including negative values. All -expressions resulting in a zero are false. - -If the expression results in True, the statement will be executed. If it -isn't true, nothing happens and we move on to the next line of the script. - - if (true) - mes("This will always print."); - if (0) - mes("And this will never print."); - if (5) - mes("This will also always print."); - if (-1) - mes("Funny as it is, this will also print just fine."); - -For more information on conditional operators see the operators section -above. -Anything that is returned by a function can be used in a condition check -without bothering to store it in a specific variable: - - if (strcharinfo(PC_NAME) == "Daniel Jackson") - mes("It is true, you are Daniel!"); - -More examples of using the 'if' command in the real world: - -Example 1: - - .@var1 = 1; - input(.@var2); - if (.@var1 == .@var2) - close(); - mes("Sorry that is wrong"); - close(); - -Example 2: - - .@var1 = 1; - input(.@var2); - if (.@var1 != .@var2) - mes("Sorry that is wrong"); - close(); - -(Notice examples 1 and 2 have the same effect.) - -Example 3: - - ++@var1; - mes("[Forgetfull Man]"); - if (@var == 1) - mes("This is the first time you have talked to me"); - if (@var == 2) - mes("This is the second time you have talked to me"); - if (@var == 3) - mes("This is the third time you have talked to me"); - if (@var == 4) - mes("This is the forth time you have talked to me, but I think I am getting amnesia, I have forgotten about you"); - if (@var == 4) - @var = 0; - close(); - -Example 4: - - mes("[Quest Person]"); - // The (AegisName) constant Apple comes from item_db, it is the item number 512. - if (countitem(Apple) >= 1) { - mes("Oh an apple, I didn't want it, I just wanted to see one"); - close(); - } - mes("Can you please bring me an apple?"); - close(); - -Example 5: Using complex conditions. - - mes("[Multi Checker]"); - if ((queststarted == 1) && (countitem(Apple) >= 5)) { - // Executed only if the quest has been started AND You have 5 apples - mes("[Multi Checker]"); - mes("Well done you have started the quest of got me 5 apples"); - mes("Thank you"); - queststarted = 0; - delitem(Apple, 5); - close(); - } - mes("Please get me 5 apples"); - queststarted = 1; - close(); - -If the condition doesn't meet, it'll do the action following the else. -We can also group several actions depending on a condition, this way: - -if (<condition>) { - dothis1(); - dothis2(); -} else { - dothat1(); - dothat2(); - dothat3(); -} - -Example 6: - - mes("[Person Checker]"); - if ($name$ == "") { - mes("Please tell me someone's name"); - next(); - input($name$); - $name2$ = strcharinfo(PC_NAME); - mes("[Person Checker]"); - mes("Thank you"); - close(); - } - if ($name$ == strcharinfo(PC_NAME)) { - mes("You are the person that " +$name2$+ " just mentioned"); - mes("nice to meet you"); - } else { - mes("You are not the person that " +$name2$+ " mentioned"); - } - $name$ = ""; - $name2$ = ""; - close(); - -See strcharinfo() for explanation of what this function does. - -Remember that if you plan to do several actions upon the condition being -false, and you forget to use the curly braces (the { } ), the second -action will be executed regardless the output of the condition, unless of -course, you stop the execution of the script if the condition is true -(that is, in the first grouping using a return, and end or a close()). - -Also, you can have multiple conditions nested or chained, and don't worry -about limits as to how many nested if you can have, there is no spoon ;). - -... -if (<condition 1>) { - dothis(); -} else if (<condition 2>) { - dotheother(); - do_that(); - end; -} else { - do_this(); -} -... - ---------------------------------------- - -*while (<condition>) <statement or block> - -This is probably the simplest and most frequently used loop structure. The -'while' statement can be interpreted as "while <condition> is true, -perform <statement>". It is a pretest loop, meaning the conditional -expression is tested before any of the statements in the body of the loop -are performed. If the condition evaluates to false, the statement(s) in -the body of the loop is/are never executed. If the condition evaluates to -true, the statement(s) are executed, then control transfers back to the -conditional expression, which is reevaluated and the cycle continues. - -Multiple statements can be grouped with { }, curly braces, just like with -the 'if' statement. - -Example 1: - while (switch(select("Yes", "No") == 2)) - mes("You picked no."); - -Example 2: multiple statements - while (switch(select("Yes", "No") == 2 )) { - mes("Why did you pick no?"); - mes("You should pick yes instead!"); - } - -Example 3: counter-controlled loop - .@i = 1; - while (.@i <= 5) { - mes("This line will print 5 times."); - ++.@i; - } - -Example 4: sentinel-controlled loop - mes("Input 0 to stop"); - input(.@num); - while (.@num != 0) { - mes("You entered " + .@num); - input(.@num); - } - close(); - ---------------------------------------- - -*for (<variable initialization>; <condition>; <variable update>) <statement or block> - -Another pretest looping structure is the 'for' statement. It is considered -a specialized form of the 'while' statement, and is usually associated -with counter-controlled loops. Here are the steps of the 'for' statement: -the initialize statement is executed first and only once. The condition -test is performed. When the condition evaluates to false, the rest of the -for statement is skipped. When the condition evaluates to true, the body -of the loop is executed, then the update statement is executed (this -usually involves incrementing a variable). Then the condition is -reevaluated and the cycle continues. - -Example 1: - for (.@i = 0; .@i < 5; ++.@i) - mes("This line will print 5 times."); - -Example 2: - mes("This will print the numbers 1 - 5."); - for (.@i = 1; .@i <= 5; ++.@i) - mes(.@i); - ---------------------------------------- - -*do { <statements>; } while (<condition>) - -The 'do...while' is the only post-test loop structure available in this -script language. With a post-test, the statements are executed once before -the condition is tested. When the condition is true, the statement(s) are -repeated. When the condition is false, control is transferred to the -statement following the 'do...while' loop expression. - -Example 1: sentinel-controlled loop - mes("This menu will keep appearing until you pick Cancel"); - do { - .@choice = select("One:Two:Three:Cancel"); - } while (.@choice != 4); - -Example 2: counter-controlled loop - mes("This will countdown from 10 to 1."); - .@i = 10; - do { - mes(.@i--); - } while (.@i > 0); - ---------------------------------------- - -*freeloop(<toggle>) - -Toggling this to enabled (true) allows the script instance to bypass the -infinite loop protection, allowing your script to loop as much as it may -need. Disabling (false) may warn you if an infinite loop is detected if your -script is looping too many times. - -Please note, once again, that this isn't a solution to all problems, and by -disabling this protection your Hercules server may become laggy or -unresponsive if the script it is used in is performing lenghty loop -operations. - -Example: - freeloop(true); // enable script to loop freely - - //Be aware with what you do here. - for (.@i = 0; .@i < .@bigloop; ++.@i) { - dothis(); - // will sleep the script for 1ms when detect an infinity loop to - // let Hercules do what it need to do (socket, timer, process, - // etc.) - } - - freeloop(false); // disable - - for (.@i = 0; .@i < .@bigloop; ++.@i) { - dothis(); - // throw an infinity loop error - } - ---------------------------------------- - -*setarray(<array name>[<first value>], <value>{, <value>...<value>}) - -This command will allow you to quickly fill up an array in one go. Check -the Kafra scripts in the distribution to see this used a lot. - - setarray(.@array[0], 100, 200, 300, 400, 500, 600); - -The index of the first element of the array to alter can be omitted if -zero. For example: - - setarray(.@array, 200, 200, 200); - setarray(.@array[1], 300, 150); - -will produce: - - .@array[0] = 200 - .@array[1] = 300 - .@array[2] = 150 - ---------------------------------------- - -*cleararray(<array name>[<first value to alter>], <value>, <number of values to set>) - -This command will change many array values at the same time to the same -value. - - setarray(.@array, 100, 200, 300, 400, 500, 600); - // This will make all 6 values 0 - cleararray(.@array[0], 0, 6); - // This will make array element 0 change to 245 - cleararray(.@array[0], 245, 1); - // This is equivalent to the above - cleararray(.@array, 245, 1); - // This will make elements 1 and 2 change to 345 - cleararray(.@array[1], 345, 2); - -See 'setarray'. - ---------------------------------------- - -*copyarray(<destination array>[<first value>], <source array>[<first value>], <amount of data to copy>) - -This command lets you quickly shuffle a lot of data between arrays, which -is in some cases invaluable. - - setarray(.@array, 100, 200, 300, 400, 500, 600); - // So we have made .@array[] - copyarray(.@array2[0], .@array[2], 2); - - // Now, .@array2[0] will be equal to .@array[2] (300) and - // .@array2[1] will be equal to .@array[3]. - -So using the examples above: - .@array[0] = 100 - .@array[1] = 200 - .@array[2] = 300 - .@array[3] = 400 - .@array[4] = 500 - .@array[5] = 600 - -New Array: - .@array2[0] = 300 - .@array2[1] = 400 - .@array2[2] = 0 - .@array2[3] = 0 - -Notice that .@array[4] and .@array[5] won't be copied to the second array, -and it will return a 0. - ---------------------------------------- - -*deletearray(<array name>[<first value>], <how much to delete>) - -This command will delete a specified number of array elements totally from -an array, shifting all the elements beyond this towards the beginning. - - // This will delete array element 0, and move all the other array - // elements up one place. - deletearray(.@array[0], 1); - - // This would delete array elements numbered 1, 2 and 3, leave element 0 - // in its place, and move the other elements ups, so there are no gaps. - deletearray(.@array[1], 3); - -If the amount of items to delete is not specified, all elements of the -array starting from the specified one to the end, are deleted. If no -starting element is specified either, the the entire array will be -deleted. - - // This would delete all elements of the array starting from 2, leaving - // element 0 and 1 - deletearray(.@array[2]); - - // This would delete all elements of the array - deletearray(.@array); - ---------------------------------------- -//===================================== -1 - End of Basic-Related Commands -//===================================== ---------------------------------------- - - ---------------------------------------- -//===================================== -2 - Information-retrieving Related Commands -//===================================== ---------------------------------------- - -*strcharinfo(<type>{, <default value>{, <GID>}}) - -This function will return either the name, party name or guild name for -the invoking character. Whatever it returns is determined by type. -(0) PC_NAME - Character's name. -(1) PC_PARTY - The name of the party they're in if any. -(2) PC_GUILD - The name of the guild they're in if any. -(3) PC_MAP - The name of the map the character is in. -(4) PC_CLAN - The name of the clan they're in if any. - -If <GID> is passed, it will return the value of the specified player instead -the attached player. If the player is not found, it will return -<default value>, if any, or else return an empty string. - -If a character is not a member of any party or guild, an empty string will -be returned when requesting that information. - -Note: Numbers can also be used in <type>, but their usage is disncouraged as -using only numbers reduces script readability - ---------------------------------------- - -*strnpcinfo(<type>{, <default value>{, <GID>}}) - -This function will return the various parts of the name of the calling NPC. -Whatever it returns is determined by type. - -(0) NPC_NAME - The NPC's display name (visible#hidden) -(1) NPC_NAME_VISIBLE - The visible part of the NPC's display name -(2) NPC_NAME_HIDDEN - The hidden part of the NPC's display name -(3) NPC_NAME_UNIQUE - The NPC's unique name (::name) -(4) NPC_MAP - The name of the map the NPC is in. - -If <GID> is passed, it will return the value of the specified NPC instead of -the attached NPC. If the NPC is not found, it will return <default value>, -if any, or else return an empty string. - ---------------------------------------- - -*charid2rid(<char id>) - -This function returns the RID of the character with the given character ID. - -If the character is offline or doesn't exist, 0 is returned. - ---------------------------------------- - -*getarraysize(<array name>) - -This function returns highest index of the array that is filled. -Notice that zeros and empty strings at the end of this array are not -counted towards this number. - -For example: - - setarray(.@array, 100, 200, 300, 400, 500, 600); - .@arraysize = getarraysize(.@array); - -This will make .@arraysize == 6. But if you try this: - - setarray(.@array, 100, 200, 300, 400, 500, 600, 0); - .@arraysize = getarraysize(.@array); - -.@arraysize will still equal 6, even though you've set 7 values. - -If you do this: - - .@array[1000] = 1; - .@arraysize = getarraysize(.@array); - -.@arraysize will be 1000, even though only one element has been set. - ---------------------------------------- - -*getarrayindex(<array name>) - -This command returns the index of the passed array. This is useful when -used in combination with getarg() - -Example: - - getarrayindex(.@foo[42]) // 42 - ---------------------------------------- - -*getelementofarray(<array name>, <index>) - -This command retrieves the value of the element of given array at given -index. This is equivalent to using: - - <array name>[<index>] - -Also useful when passing arrays to functions or accessing another npc's -arrays: - getelementofarray(getarg(0), <index>) - getelementofarray(getvariableofnpc(.var, "testNPC"), <index>) - ---------------------------------------- - -*readparam(<parameter number>{, "<player name>"}) -*readparam(<parameter number>{, <account id>}) - -This function will return the basic stats of an invoking character, -referred to by the parameter number. Instead of a number, you can use a -parameter name if it is defined in 'doc/constants.md'. - -Example parameters: - -StatusPoint, BaseLevel, SkillPoint, Class, Upper, Zeny, Sex, Weight, -MaxWeight, JobLevel, BaseExp, JobExp, NextBaseExp, NextJobExp, Hp, MaxHp, -Sp, MaxSp, BaseJob, Karma, Manner, bVit, bDex, bAgi, bStr, bInt, bLuk - -All of these also behave as variables, but don't expect to be able to just -'set' them - some will not work for various internal reasons. - -Example 1: - - // Returns how many status points you haven't spent yet. - mes("Unused status points: "+readparam(9)); // [!] - -Using this particular information as a function call is not required. -Typing this will return the same result: - - mes("Unused status points: "+StatusPoint); - -Example 2: - -You can also use this command to get stat values. - - if (readparam(bVit) > 77) - mes("Only people with over 77 Vit are reading this!"); - -Example 3: - - // Display your current weight - mes("Your current weight is "+ (Weight/10) + "/" + (MaxWeight/10)); - ---------------------------------------- - -*setparam(<parameter number>, <value>{, "<player name>"}) -*setparam(<parameter number>, <value>{, <account id>}) - -Sets a parameter on the given player. See readparam() for more info about -parameters. Keep in mind that not all read-able parameters are also set-able. - -Parameters that can be modified include: - -StatusPoint, BaseLevel, SkillPoint, Zeny, Sex, Weight, MaxWeight, JobLevel, -BaseExp, JobExp, Hp, MaxHp, Sp, MaxSp, Karma, Manner, Fame, bVit, bDex, bAgi, -bStr, bInt, bLuk - - ---------------------------------------- - -*getcharid(<type>{, "<character name>"}) - -This function will return a unique ID number of the invoking character, -or, if a character name is specified, of that player. - -Type is the kind of associated ID number required: - -(0) CHAR_ID_CHAR - Character ID number. -(1) CHAR_ID_PARTY - Party ID number. -(2) CHAR_ID_GUILD - Guild ID number. -(3) CHAR_ID_ACCOUNT - Account ID number. -(4) CHAR_ID_BG - Battle ground ID -(5) CHAR_ID_CLAN - Clan ID number. - -For most purposes other than printing it, a number is better to have than -a name (people do horrifying things to their character names). - -If the character is not in a party or not in a guild, the function will -return 0 if guild or party number is requested. If a name is specified and -the character is not found, 0 is returned. - -If getcharid(CHAR_ID_CHAR) returns a zero, the script got called not by a character -and doesn't have an attached RID. Note that this will cause the map server -to print "player not attached!" error messages, so it is preferred to use -playerattached() to check for the character attached to the script. - - if (getcharid(CHAR_ID_GUILD) == 0) - mes("Only members of a guild are allowed here!"); - ---------------------------------------- - -*getnpcid({"<npc name>"}) - -Retrieves IDs of the currently invoked NPC. If a unique npc name is given, -IDs of that NPC are retrieved instead. - -If the NPC does not exist, 0 is returned. - ---------------------------------------- - -*getchildid() -*getmotherid() -*getfatherid() - -These functions return the character ID of the attached player's child, -mother, mother, or father, respectively. It returns 0 if no ID is found. - - if (getmotherid() != 0) - mes("Your mother's ID is: "+getmotherid()); - ---------------------------------------- - -*ispartneron() - -This function returns true if the invoking character's marriage partner -is currently online and false if they are not or if the character has no -partner. - ---------------------------------------- - -*getpartnerid() - -This function returns the character ID of the invoking character's -marriage partner, if any. If the invoking character is not married, it -will return 0, which is a quick way to see if they are married: - - if (getpartnerid() == 0) - mes("I'm not going to be your girlfriend!"); - else - mes("You're married already!"); - ---------------------------------------- - -*getpartyname(<party id>) - -This function will return the name of a party that has the specified ID -number. If there is no such party ID, "null" will be returned. - -Lets say the ID of a party was saved as a global variable: - - // This would return the name of the party from the ID stored in a - // variable - mes("You're in the '"+getpartyname($@var)+"' party, I know!"); - ---------------------------------------- - -*getpartymember(<party id>{, <type>}) - -This command will find all members of a specified party and returns their -names (or character id or account id depending on the value of "type") -into an array of temporary global variables. There's actually quite a few -commands like this which will fill a special variable with data upon -execution and not do anything else. - -Upon executing this, - -$@partymembername$[] is a global temporary string array which contains all - the names of these party members. - (only set when type is 0 or not specified) - -$@partymembercid[] is a global temporary number array which contains the - character id of these party members. - (only set when type is 1) - -$@partymemberaid[] is a global temporary number array which contains the - account id of these party members. - (only set when type is 2) - -$@partymembercount is the number of party members that were found. - -The party members will (apparently) be found regardless of whether they -are online or offline. Note that the names come in no particular order. - -Be sure to use $@partymembercount to go through this array, and not -'getarraysize', because it is not cleared between runs of 'getpartymember'. -If someone with 7 party members invokes this script, the array would have -7 elements. But if another person calls up the NPC, and he has a party of -5, the server will not clear the array for you, overwriting the values -instead. So in addition to returning the 5 member names, the 6th and 7th -elements from the last call remain, and you will get 5+2 members, of which -the last 2 don't belong to the new guy's party. $@partymembercount will -always contain the correct number, (5) unlike 'getarraysize()' which will -return 7 in this case. - -Example 1: list party member names - - // get the party member names - getpartymember(getcharid(CHAR_ID_PARTY), 0); - - // It's a good idea to copy the global temporary $@partymember***** - // variables to your own scope variables because if you have pauses in - // this script (sleep, sleep2, next, close2, input, menu, select, or - // prompt), another player could click this NPC, trigger - // 'getpartymember', and overwrite the $@partymember***** variables. - .@count = $@partymembercount; - copyarray(.@name$[0], $@partymembername$[0], $@partymembercount); - - // list the party member names - for (.@i = 0; .@i < .@count; ++.@i) { - mes((.@i +1) + ". ^0000FF" + .@name$[.@i] + "^000000"); - } - close(); - - -Example 2: check party count (with a next() pause), before warping to event - - .register_num = 5; // How many party members are required? - - // get the charID and accountID of character's party members - getpartymember(getcharid(CHAR_ID_PARTY), 1); - getpartymember(getcharid(CHAR_ID_PARTY), 2); - - if ($@partymembercount != .register_num) { - mes("Please form a party of "+ .register_num +" to continue"); - close(); - } - - // loop through both and use 'isloggedin' to count online party members - for (.@i = 0; .@i < $@partymembercount; ++.@i) - if (isloggedin($@partymemberaid[.@i], $@partymembercid[.@i])) - .@count_online++; - // We search accountID & charID because a single party can have - // multiple characters from the same account. Without searching - // through the charID, if a player has 2 characters from the same - // account inside the party but only 1 char online, it would count - // their online char twice. - - if (.@count_online != .register_num) { - mes("All your party members must be online to continue"); - close(); - } - - // copy the array to prevent players cheating the system - copyarray(.@partymembercid, $@partymembercid, .register_num); - - mes("Are you ready?"); - next(); // careful here - select("Yes"); - - // When a script hits a next, menu, sleep or input that pauses the - // script, players can invite or /leave and make changes in their - // party. To prevent this, we call getpartymember again and compare - // with the original values. - - getpartymember(getcharid(CHAR_ID_PARTY), 1); - if ($@partymembercount != .register_num) { - mes("You've made changes to your party !"); - close(); - } - for (.@i = 0; .@i < $@partymembercount; ++.@i) { - if (.@partymembercid[.@i] != $@partymembercid[.@i]) { - mes("You've made changes to your party !"); - close(); - } - } - - // Finally, it's safe to start the event! - warpparty("event_map", 0, 0, getcharid(CHAR_ID_PARTY), true); - ---------------------------------------- - -*getpartyleader(<party id>{, <type>}) - -This function returns some information about the given party-id's leader. -When type is omitted, the default information retrieved is the leader's -name. Possible types are: - - 1: Leader account id - 2: Leader character id - 3: Leader's class - 4: Leader's current map name - 5: Leader's current level as stored on the party structure (may not be - current level if leader leveled up recently). - -If retrieval fails (leader not found or party does not exist), this -function returns "null" instead of the character name, and -1 for the -other types. - ---------------------------------------- - -*getlook(<type>) - -This function will return the number for the current character look value -specified by type. See 'setlook' for valid look types. - -This can be used to make a certain script behave differently for -characters dressed in black. :) - ---------------------------------------- - -*getsavepoint(<information type>) - -This function will return information about the invoking character's save -point. You can use it to let a character swap between several recorded -save points. Available information types are: - - 0 - Map name (a string) - 1 - X coordinate - 2 - Y coordinate - ---------------------------------------- - -*getcharip({"<character name>"}) -*getcharip({<account id>}) -*getcharip({<character id>}) - -This function will return the IP address of the invoking character, or, if -a player is specified, of that character. A blank string is returned if no -player is attached. - -Examples: - -// Outputs IP address of attached player. - mes("Your IP: " + getcharip()); - -// Outputs IP address of character "Silver". - mes("Silver's IP: " + getcharip("Silver")); - ---------------------------------------- - -*sit({"<character name>"}) -*stand({"<character name>"}) - -This function will force a character to sit/stand if it is standing/sitting. -If no player is specified, the attached player will be used. - ---------------------------------------- - -*issit({"<character name>"}) - -This function will return a number depending on the character's sitting state. -If the character is sitting, it will return true, otherwise (standing) it will return false. -In case no player is specified, the function will return the state of the attached player. - ---------------------------------------- -//===================================== -2.1 - Item-Related Commands -//===================================== ---------------------------------------- - -*getequipid(<equipment slot>) - -This function returns the item ID of the item equipped in the equipment -slot specified on the invoking character. If nothing is equipped there, it -returns -1. Valid equipment slots are: - -EQI_HEAD_TOP (1) - Upper head gear -EQI_ARMOR (2) - Armor (Where you keep your Jackets and Robes) -EQI_HAND_L (3) - What is in your Left hand. -EQI_HAND_R (4) - What is in your Right hand. -EQI_GARMENT (5) - The garment slot (Mufflers, Hoods, Manteaus) -EQI_SHOES (6) - What foot gear the player has on. -EQI_ACC_L (7) - Accessory 1. -EQI_ACC_R (8) - Accessory 2. -EQI_HEAD_MID (9) - Middle Headgear (masks and glasses) -EQI_HEAD_LOW (10) - Lower Headgear (beards, some masks) -EQI_COSTUME_HEAD_LOW (11) - Lower Costume Headgear -EQI_COSTUME_HEAD_MID (12) - Middle Costume Headgear -EQI_COSTUME_HEAD_TOP (13) - Upper Costume Headgear -EQI_COSTUME_GARMENT (14) - Costume Garment -EQI_SHADOW_ARMOR (15) - Shadow Armor -EQI_SHADOW_WEAPON (16) - Shadow Weapon -EQI_SHADOW_SHIELD (17) - Shadow Shield -EQI_SHADOW_SHOES (18) - Shadow Shoes -EQI_SHADOW_ACC_R (19) - Shadow Accessory 2 -EQI_SHADOW_ACC_L (20) - Shadow Accessory 1 - -Notice that a few items occupy several equipment slots, and if the -character is wearing such an item, 'getequipid' will return it's ID number -for either slot. - -Can be used to check if you have something equipped, or if you haven't got -something equipped: - - if (getequipid(EQI_HEAD_TOP) == Tiara) { - mes("What a lovely Tiara you have on"); - close(); - } - mes("Come back when you have a Tiara on"); - close(); - -You can also use it to make sure people don't pass a point before removing -an item totally from them. Let's say you don't want people to wear Legion -Plate armor, but also don't want them to equip if after the check, you -would do this: - - if (getequipid(EQI_ARMOR) == Full_Plate_Armor || getequipid(EQI_ARMOR) == Full_Plate_Armor_) { - mes("You are wearing some Legion Plate Armor, please drop that in your stash before continuing"); - close(); - } - if (countitem(Full_Plate_Armor) > 0 || countitem(Full_Plate_Armor_) > 0) { - mes("You have some Legion Plate Armor in your inventory, please drop that in your stash before continuing"); - close(); - } - mes("I will lets you pass"); - close2(); - warp("place", 50, 50); - end; - ---------------------------------------- - -*getequipname(<equipment slot>) - -Returns the jname of the item equipped in the specified equipment slot on -the invoking character, or an empty string if nothing is equipped in that -position. -Does the same thing as getitemname(getequipid()). Useful for an NPC to -state what your are wearing, or maybe saving as a string variable. -See getequipid() for a full list of valid equipment slots. - - if (getequipid(EQI_HEAD_TOP) != 0) - mes("So you are wearing a "+getequipname(EQI_HEAD_TOP)+" on your head"); - else - mes("You are not wearing a head gear"); - ---------------------------------------- - -*getitemname(<item id>) - -Given the database ID number of an item, this function will return the -text stored in the 'japanese name' field (which, in Hercules, stores an -English name the players would normally see on screen). -Return "null" if no such item exist. - ---------------------------------------- - -*getbrokenid(<number>) - -This function will search the invoking character's inventory for any -broken items, and will return their item ID numbers. Since the character -may have several broken items, 1 given as an argument will return the -first one found, 2 will return the second one, etc. Will return 0 if no -such item is found. - - // Let's see if they have anything broken: - if (getbrokenid(1) == 0) - mes("You don't have anything broken, quit bothering me."); - else // They do, so let's print the name of the first broken item: - mes("Oh, I see you have a broken "+getitemname(getbrokenid(1))+" here!"); - ---------------------------------------- - -*getbrokencount() - -This function will return the total amount of broken equipment on the -invoking character. - ---------------------------------------- - -*getequipisequiped(<equipment slot>) - -This functions will return 1 if there is an equipment placed on the -specified equipment slot and 0 otherwise. For a list of equipment slots -see 'getequipid'. Function originally used by the refining NPCs: - - if (getequipisequiped(EQI_HEAD_TOP)) { - mes("[Refiner]"); - mes("That's a fine hat you are wearing there..."); - close(); - } - mes("[Refiner]"); - mes("Do you want me to refine your dumb head?"); - close(); - ---------------------------------------- - -*getequipisenableref(<equipment slot>) - -Will return true if the item equipped on the invoking character in the -specified equipment slot is refinable, and false if it isn't. For a list -of equipment slots see getequipid(). - - if (getequipisenableref(EQI_HEAD_TOP)) { - mes("[Refiner]"); - mes("Ok I can refine this"); - close(); - } - mes("[Refiner]"); - mes("I can't refine this hat!..."); - close(); - ---------------------------------------- - -*getequiprefinerycnt(<equipment slot>) - -Returns the current number of pluses for the item in the specified -equipment slot. For a list of equipment slots see 'getequipid'. - -Can be used to check if you have reached a maximum refine value, default -for this is +10: - - if (getequiprefinerycnt(EQI_HEAD_TOP) < 10) - mes("I will now upgrade your "+getequipname(EQI_HEAD_TOP)); - else - mes("Sorry, it's not possible to refine hats better than +10"); - ---------------------------------------- - -*getequipweaponlv(<equipment slot>) - -This function returns the weapon level for the weapon equipped in the -specified equipment slot on the invoking character. For a list of -equipment slots see 'getequipid'. - -Only EQI_HAND_L and EQI_HAND_R normally make sense, since only weapons -have a weapon level. You can, however, probably, use this field for other -equippable custom items as a flag or something. - -If no item is equipped in this slot, or if it doesn't have a weapon level -according to the database, 0 will be returned. - -Examples: - -// Right hand can only contain a weapon. - switch (getequipweaponlv(EQI_HAND_R)) { - case 1: - mes("You are holding a lvl 1 weapon."); - break; - case 2: - mes("You are holding a lvl 2 weapon."); - break; - case 3: - mes("You are holding a lvl 3 weapon."); - break; - case 4: - mes("You are holding a lvl 4 weapon."); - break; - case 5: - mes("You are holding a lvl 5 weapon, hm, must be a custom design..."); - break; - default: - mes("Seems you don't have a weapon on."); - break; - } - -// Left hand can hold either a weapon or shield. - if (getequipid(EQI_HAND_R) == 0) { - mes("Seems you have nothing equipped here."); - close(); - } - switch (getequipweaponlv(EQI_HAND_L)) { - case 0: - mes("You are holding a shield, so it doesn't have a level."); - break; - case 1: - mes("You are holding a lvl 1 weapon."); - break; - case 2: - mes("You are holding a lvl 2 weapon."); - break; - case 3: - mes("You are holding a lvl 3 weapon."); - break; - case 4: - mes("You are holding a lvl 4 weapon."); - break; - case 5: - mes("You are holding a lvl 5 weapon, hm, must be a custom design..."); - break; - } - ---------------------------------------- - -*getequippercentrefinery(<equipment slot>{, <type>}) - -This function calculates and returns the percent value chance to -successfully refine the item found in the specified equipment slot of the -invoking character by +1. Refine rates are defined in the db/<re/pre-re>/refine_db.conf -files. For a list of equipment slots see getequipid(). - -These values can be displayed for the player to see, or used to calculate -the random change of a refine succeeding or failing and then going through -with it (which is what the official NPC refinery scripts use it for). - -Refine Chance Type Constants - -REFINE_CHANCE_TYPE_NORMAL: 0 (Normal Ores) -REFINE_CHANCE_TYPE_ENRICHED: 1 (Enriched Ores) -REFINE_CHANCE_TYPE_E_NORMAL: 2 (Event Normal Ores) -REFINE_CHANCE_TYPE_E_ENRICHED: 3 (Event Enriched Ores) - -Refine rate information - -Normal Ores: http://ro.gnjoy.com/news/probability/View.asp?category=4&seq=1941553&curpage=1 -Enriched Ores: http://ro.gnjoy.com/news/probability/View.asp?category=4&seq=1941565&curpage=1 -Event Normal Ores: http://ro.gnjoy.com/news/probability/View.asp?category=4&seq=1941558&curpage=1 -Event Enriched Ores: http://ro.gnjoy.com/news/probability/View.asp?category=4&seq=1941567&curpage=1 - -// This will find a random number from 0 - 99 and if that is equal to or -// more than the value recovered by this command it will show a message - if (getequippercentrefinery(EQI_HAND_L, REFINE_CHANCE_TYPE_NORMAL) <= rand(100)) - mes("Aww"); - ---------------------------------------- - -*getareadropitem("<map name>", <x1>, <y1>, <x2>, <y2>, <item>) - -This function will count all the items with the specified ID number lying -on the ground on the specified map within the x1/y1-x2/y2 square on it and -return that number. - -This is the only function around where a parameter may be either a string -or a number! If it's a number, it means that only the items with that item -ID number will be counted. If it is a string, it is assumed to mean the -'english name' field from the item database. If you give it an empty -string, or something that isn't found from the item database, it will -count items number 512 (Apple). - ---------------------------------------- - -*getequipcardcnt(<equipment slot>) - -This function will return the number of cards that have been compounded -onto a specific equipped item for the invoking character. See 'getequipid' -for a list of possible equipment slots. - ---------------------------------------- - -*getinventorylist() - -This command sets a bunch of arrays with a complete list of whatever the -invoking character has in its inventory, including all the data needed to -recreate these items perfectly if they are destroyed. Here's what you get: - -@inventorylist_id[] - array of item ids. -@inventorylist_idx[] - array of item inventory index. -@inventorylist_amount[] - their corresponding item amounts. -@inventorylist_equip[] - will return the slot the item is equipped on, if at all. -@inventorylist_refine[] - for how much it is refined. -@inventorylist_identify[] - whether it is identified. -@inventorylist_attribute[] - whether it is broken. -@inventorylist_card1[] - These four arrays contain card data for the -@inventorylist_card2[] items. These data slots are also used to store -@inventorylist_card3[] names inscribed on the items, so you can -@inventorylist_card4[] explicitly check if the character owns an item - made by a specific craftsman. -@inventorylist_expire[] - expire time (Unix time stamp). 0 means never - expires. -@inventorylist_bound[] - whether it is an account bounded item or not. -@inventorylist_favorite[] - whether it is favorite (inside favorite tab) or not. -@inventorylist_count - the number of items in these lists. - -This could be handy to save/restore a character's inventory, since no -other command returns such a complete set of data, and could also be the -only way to correctly handle an NPC trader for carded and named items who -could resell them - since NPC objects cannot own items, so they have to -store item data in variables and recreate the items. - -Notice that the variables this command generates are all temporary, -attached to the character, and integer. - -Be sure to use @inventorylist_count to go through these arrays, and not -getarraysize(), because the arrays are not automatically cleared between -runs of getinventorylist(). - ---------------------------------------- - -*getcartinventorylist() - -This command sets a bunch of arrays with a complete list of whatever the -invoking character has in its cart_inventory, including all the data needed to -recreate these items perfectly if they are destroyed. Here's what you get: - -@cartinventorylist_id[] - array of item ids. -@cartinventorylist_amount[] - their corresponding item amounts. -@cartinventorylist_refine[] - for how much it is refined. -@cartinventorylist_identify[] - whether it is identified. -@cartinventorylist_attribute[] - whether it is broken. -@cartinventorylist_card1[] - These four arrays contain card data for the -@cartinventorylist_card2[] items. These data slots are also used to store -@cartinventorylist_card3[] names inscribed on the items, so you can -@cartinventorylist_card4[] explicitly check if the character owns an item - made by a specific craftsman. -@cartinventorylist_expire[] - expire time (Unix time stamp). 0 means never - expires. -@cartinventorylist_bound - whether it is an account bound item or not. -@cartinventorylist_count - the number of items in these lists. - -This could be handy to save/restore a character's cart_inventory, since no -other command returns such a complete set of data, and could also be the -only way to correctly handle an NPC trader for carded and named items who -could resell them - since NPC objects cannot own items, so they have to -store item data in variables and recreate the items. - -Notice that the variables this command generates are all temporary, -attached to the character, and integer. - -Be sure to use @cartinventorylist_count to go through these arrays, and not -getarraysize(), because the arrays are not automatically cleared between -runs of getcartinventorylist(). - ---------------------------------------- - -*cardscnt() - -This function will return the number of cards inserted into the weapon -currently equipped on the invoking character. -While this function was meant for item scripts, it will work outside them: - - if (cardscnt() == 4) - mes("So you've stuck four cards into that weapon, think you're cool now?"); - ---------------------------------------- - -*getrefine() - -This function will return the refine count of the equipment from which -the function is called. This function is intended for use in item scripts. - - if (getrefine() == 10) - mes("Wow. That's a murder weapon."); - ---------------------------------------- - -*getitemslots(<item ID>) - -This function will look up the item with the specified ID number in the -database and return the number of slots this kind of items has - 0 if they -are not slotted. It will also be 0 for all non-equippable items, -naturally, unless someone messed up the item database. It will return -1 -if there is no such item. - -Example: - -//.@slots now has the amount of slots of the item with ID 1205. - .@slots = getitemslots(1205); - ---------------------------------------- - -*getiteminfo(<item ID>, <type>) -*setiteminfo(<item ID>, <type>, <value>) - -This function will look up the item with the specified ID number in the -database and return the info set by TYPE argument. -It will return -1 if there is no such item. - -Valid types are: - - ITEMINFO_BUYPRICE - Buy Price - ITEMINFO_SELLPRICE - Sell Price - ITEMINFO_TYPE - Item Type - ITEMINFO_MAXCHANCE - Max drop chance of this item e.g. 1 = 0.01% , etc.. - if = 0, then monsters don't drop it at all (rare or a quest item) - if = 10000, then this item is sold in NPC shops only - ITEMINFO_SEX - Sex - ITEMINFO_LOC - Equip location - ITEMINFO_WEIGHT - Weight (note: 1/10 of unit) - ITEMINFO_ATK - Attack - ITEMINFO_DEF - Defense - ITEMINFO_RANGE - Range - ITEMINFO_SLOTS - Slots - ITEMINFO_SUBTYPE - Item subtype - ITEMINFO_ELV - Equip min. level - ITEMINFO_WLV - Weapon level - ITEMINFO_VIEWID - View ID ("Sprite" field in the Item DB) - ITEMINFO_MATK - MATK (only relevant if RENEWAL is set) - ITEMINFO_VIEWSPRITE - View Sprite ("ViewSprite" field in the Item DB) - ITEMINFO_TRADE - Trade Restriction (see "doc/constant.md": item trade restriction) - -Check sample in doc/sample/getiteminfo.txt - -The setiteminfo function will, instead, set the item's parameters. It returns -the new value on success, or -1 on failure (item_id not found). - -Example: - - setiteminfo(Stone, ITEMINFO_WEIGHT, 9990); // Stone now weighs 999.0 - ---------------------------------------- - -*getequipisenableopt(<equipment slot>) - -This function checks if the equipped item allows the use of bonus options. - -Returns 1 if allowed, 0 if not. - ---------------------------------------- - -*getequippedoptioninfo(<info_type>); - -This function is to be used with the scripts of contents listed in -db/item_options.conf only. - -Returns the value of the current equipment being parsed. -If the equip was not found or the type is invalid, -1 is returned. - ---------------------------------------- - -*getequipoption(<equip_index>,<slot>,<type>); - -Gets the option information of an equipment. - -<equipment_index> For a list of equipment indexes see getequipid(). -<option_slot> can range from 1 to MAX_ITEM_OPTIONS -<type> can be IT_OPT_INDEX (the ID of the option bonus, @see "Id" or "Name" in db/item_options.conf) - or IT_OPT_VALUE (the value of the bonus script of the equipment, @see "Script" in db_item_options.conf). - -returns the value of the slot if exists or -1 for invalid slot, type or slots. - ---------------------------------------- - -*setequipoption(<equip_index>,<slot>,<opt_index>,<value>); - -Set an equipment's option index or value for the specified option slot. - -<equipment_index> For a list of equipment indexes see getequipid(). -<option_slot> can range from 1 to MAX_ITEM_OPTIONS -<type> can be IT_OPT_INDEX (the ID of the option bonus, @see "Id" or "Name" in db/item_options.conf) - removes the equip option if type is 0. -<value> The value of the type to be set. - -returns 0 if value couldn't be set, 1 on success. - ---------------------------------------- - -*getequipcardid(<equipment slot>, <card slot>) - -Returns value for equipped item slot in the indicated slot (0, 1, 2, or 3). - -This function returns CARD ID, 255, 254, -255 (for card 0, if the item is -produced). It's useful for when you want to check whether an item contains -cards or if it's signed. - ---------------------------------------- - -*hateffect(<Hat Effect ID>, <State>) - -This will set a Hat Effect onto the player. The state field allows you to -enable (true) or disable (false) the effect on the player. - ---------------------------------------- -//===================================== -2.1 - End of Item-Related Commands -//===================================== ---------------------------------------- - -*getmapxy("<variable for map name>", <variable for x>, <variable for y>, <type>{, "<search parameter>"}) - -This function will locate a character object, NPC object or pet's -coordinates and place their coordinates into the variables specified when -calling it. It will return 0 if the search was successful, and -1 if the -parameters given were not variables or the search was not successful. - -Type is the type of object to search for: - - UNITTYPE_PC - Character object - UNITTYPE_NPC - NPC object - UNITTYPE_PET - Pet object - UNITTYPE_MOB - Monster object - UNITTYPE_HOM - Homunculus object - UNITTYPE_MER - Mercenary object - UNITTYPE_ELEM - Elemental object - -To look for a monster object, monster GID is required. The function will -always return -1 when search using string. - -The search parameter is optional. If it is not specified, the location of the -invoking character will always be returned for UNITTYPE_PC, the location of the -NPC running this function for UNITTYPE_NPC. If a search parameter is specified, -for UNITTYPE_PC and UNITTYPE_NPC, the character or NPC with the specified name -or GID will be located. - -If type is UNITTYPE_PET, UNITTYPE_HOM, UNITTYPE_MER or UNITTYPE_ELEM the search -will locate the owner's pet/homun/mercenary/elementals if the search parameter -is not provided. It will NOT locate these object by name, but can be done if GID -is provided. - -What a mess. Example, a working and tested one now: - - prontera,164,301,3%TAB%script%TAB%Meh%TAB%730,{ - mes("My name is Meh. I'm here so that Nyah can find me."); - close(); - } - - prontera,164,299,3%TAB%script%TAB%Nyah%TAB%730,{ - mes("My name is Nyah."); - mes("I will now search for Meh all across the world!"); - if (getmapxy(.@mapname$, .@mapx, .@mapy, UNITTYPE_NPC, "Meh") != 0) { - mes("I can't seem to find Meh anywhere!"); - close(); - } - mes("And I found him on map "+.@mapname$+" at X:"+.@mapx+" Y:"+.@mapy+" !"); - close(); - } - -Notice that NPC objects disabled with disablenpc() will still be located. - ---------------------------------------- - -*getmapinfo(<info>{, "<map name>"}) -*getmapinfo(<info>{, <map id>}) - -This command returns various information about a specific map. If the second -argument is omitted, it will try to use the map of the attached NPC, or the -map of the attached player if the NPC can't be found. - -Valid <info> are: - MAPINFO_NAME name of the map - MAPINFO_ID numeric ID of the map - MAPINFO_ZONE name of the zone used by the map - MAPINFO_SIZE_X width of the map (cells on the x axis) - MAPINFO_SIZE_Y height of the map (cells on the y axis) - -Examples: - getmapinfo(MAPINFO_ID, "map name"); // ID from name - getmapinfo(MAPINFO_NAME, 3); // name from ID - getmapinfo(MAPINFO_ZONE); // zone, ie Normal, PvP, Jail, ... - ---------------------------------------- - -*getunits(<type>, <variable>, <limit>{, "<map>"{, <x1>, <y1>, <x2>, <y2>}}) - -This function searches a whole map or area for units and adds their GID to -the provided <variable> array. It filters units by <type> and stops searching -after <limit> units have been found. Set <limit> to false (0) if you wish to -disable the limit altogether. If <map> is omitted, this command will search -on the whole server (slow). Returns the number of units added to the array. - -Type is the type of unit to search for: - - BL_PC - Character object - BL_MOB - Monster object - BL_PET - Pet object - BL_HOM - Homunculus object - BL_MER - Mercenary object - BL_ITEM - Item object (item drops) - BL_SKILL - Skill object (skill fx & sfx) - BL_NPC - NPC object - BL_CHAT - Chat object - BL_ELEM - Elemental object - BL_CHAR - Shorthand for (BL_PC|BL_MOB|BL_HOM|BL_MER|BL_ELEM) - BL_ALL - Any kind of object - -** Do NOT use UNITTYPE_ constants here, they have different values. - -** If battle_config.dynamic_mobs is enabled and no player has entered the map - yet, the mobs will not have spawned in the map yet, so getunits() will be - unable to find them when searching for BL_MOB. - -Example: - - .@count = getunits((BL_PC | BL_NPC), .@units, false, "prontera"); - -The above example would search the map "prontera" for all PC and NPC units and -add them to the .@units array, while setting .@count to the amount of units -added to the array (useful in for() loops). - ---------------------------------------- - -*getgmlevel() - -This function will return the (GM) level of player group the account to -which the invoking character belongs. If this is somehow executed from a -console command, 99 will be returned, and 0 will be returned if the -account has no GM level. - -This allows you to make NPC's only accessible for certain GM levels, or -behave specially when talked to by GMs. - - if (getgmlevel() > 0) - mes("What is your command, your godhood?"); - if (getgmlevel() < 99) - end; - ---------------------------------------- - -*setgroupid(<new group id>{, "<character name>"}) -*setgroupid(<new group id>{, <account id>}) - -This function will temporary adjust the id of player group the account to which the -player specified if the new group id is available. -Return true if successful, otherwise it will return false. - ---------------------------------------- - -*getgroupid({<account id>}) - -This command returns the id of the group of the attached or specified player. -If the player is not found, returns -1. - ---------------------------------------- - -*gettimetick(<type>) - -Valid types are : - 0 - server's tick (milleseconds), unsigned int, loops every ~50 days - 1 - time since the start of the current day in seconds - 2 - UNIX epoch time (number of seconds elapsed since 1st of January 1970) - ---------------------------------------- - -*gettime(<type>) - -This function returns specified information about the current system time. - -Valid types: - 1 - GETTIME_SECOND - Seconds (of a minute) - 2 - GETTIME_MINUTE - Minutes (of an hour) - 3 - GETTIME_HOUR - Hour (of a day) - 4 - GETTIME_WEEKDAY - Week day (0 for Sunday, 6 is Saturday) - - Additional: SUNDAY, MONDAY, TUESDAY, WEDNESDAY, THURSDAY, FRIDAY, SATURDAY - 5 - GETTIME_DAYOFMONTH - Day of the month. - 6 - GETTIME_MONTH - Number of the month. - - Additional: JANUARY, FEBRUARY, MARCH, APRIL, MAY, JUNE, JULY, AUGUST, SEPTEMBER, OCTOBER, NOVEMBER, DECEMBER - 7 - GETTIME_YEAR - Year - 8 - GETTIME_DAYOFYEAR - Day of the year. - -It will only return numbers based on types. -Example : - if (gettime(GETTIME_WEEKDAY) == SATURDAY) { - mes("It's a Saturday. I don't work on Saturdays."); - } else if (gettime(GETTIME_MONTH) == JANUARY) { - mes("It's January. I don't work on January."); - } else if (gettime(GETTIME_MONTH) == OCTOBER && gettime(GETTIME_DAYOFMONTH) == 31) { - mes("It's Halloween."); - } - ---------------------------------------- - -*getcalendartime(<hour>, <minute>{, <day of month>{, <day of week>}}) - -This function returns the timestamp of the next ocurrence of given time. - -Day of Month specifies a day between 1 and 31 in the future, by default its value is -1 (don't use). -Day of Week specifies a day in the week and its valid values are: - 0 - SUNDAY - 1 - MONDAY - 2 - TUESDAY - 3 - WEDNESDAY - 4 - THURSDAY - 5 - FRIDAY - 6 - SATURDAY - -In order to use Day of Week, you must use Day of Month as -1. -If for some reason the command fails, it'll return -1. - -Examples : - getcalendartime(19, 00); // Next 7 pm - getcalendartime(19, 00, 6); // Next day 6 of the month, at 7pm - getcalendartime(19, 10, -1, 1); // Next Monday, at 7:10pm - ---------------------------------------- - -*gettimestr(<format string>, <max length>{, <timestamp>}) - -This function will return a string containing time data as specified by -the format string. - -This uses the C function 'strftime', which obeys special format -characters. For a full description see, for example, the description of -'strftime' at http://www.delorie.com/gnu/docs/glibc/libc_437.html -All the format characters given in there should properly work. -Max length is the maximum length of a time string to generate. - -The example given in Hercules sample scripts works like this: - - mes(gettimestr("%Y-%m/%d %H:%M:%S", 21)); - mes(gettimestr("%Y-%m/%d %H:%M:%S", 21, getcalendartime(0, 0))); - -This will print a full date and time like 'YYYY-MM/DD HH:MM:SS'. - ---------------------------------------- - -*getusers(<type>) - -This function will return a number of users on a map or the whole server. -What it returns is specified by Type. - -Type can be one of the following values, which control what is returned: - - 0 - Count of all characters on the map of the invoking character. - 1 - Count of all characters in the entire server. - 8 - Count of all characters on the map of the NPC the script is - running in. - ---------------------------------------- - -*getmapusers("<map name>") - -This function will return the number of users currently located on the -specified map. - -Currently being used in the PVP scripts to check if a PVP room is full of -not, if the number returned it equal to the maximum allowed it will not -let you enter. - -Return -1 if the map name is invalid. - ---------------------------------------- - -*getareausers({"<map name>", }{<x1>, <y1>, <x2>, <y2>}) -*getareausers({"<map name>", }{<radius>}) - -This function will return the count of connected characters which are -located within the specified area. Area can be x1/y1-x2/y2 square, -or radius from npc position. If map name missing, used attached player map. - -This is useful for maps that are split into many buildings, such as all -the "*_in" maps, due to all the shops and houses. - -Examples: - // return players in area npc area on current map. - .@num = getareausers(); - // return players in square (1, 1) - (10, 10) - .@num = "players: " + getareausers(1, 1, 10, 10); - ---------------------------------------- - -*getusersname(); - -This command will give the invoking character a list of names of the -connected characters (including themselves) into an NPC script message -window (see 'mes') paging it by 10 names as if with the next() command. - -You need to put a 'close' after that yourself. - ---------------------------------------- -//===================================== -2.2 - Guild-Related Commands -//===================================== ---------------------------------------- - -*getguildname(<guild id>) - -This function returns a guild's name given an ID number. If there is no -such guild, "null" will be returned; - - // Would print whatever guild 10007 name is. - mes("The guild "+getguildname(10007)+" are all nice people."); - - // This will do the same as above: - .@var = 10007; - mes("We have some friends in "+getguildname(.@var)+", you know."); - -This is used all over the WoE controlling scripts. You could also use it -for a guild-based event. - ---------------------------------------- - -*getguildmaster(<guild id>) - -This function return the name of the master of the guild which has the -specified ID number. If there is no such guild, "null" will be returned. - -// Would return the guild master of guild 10007, whatever that might be. - mes(getguildmaster(10007)+" runs "+getguildname(10007)); - -Can be used to check if the character is the guild master of the specified -guild. - -Maybe you want to make a room only guild masters can enter: - - .@GID = getcharid(CHAR_ID_GUILD); - if (.@GID == 0) { - mes("Sorry you are not in a guild"); - close(); - } - if (strcharinfo(PC_NAME) == getguildmaster(.@GID)) { - mes("Welcome guild master of "+getguildname(.@GID)); - close(); - } - mes("Sorry you don't own the guild you are in"); - close(); - ---------------------------------------- - -*getguildmasterid(<guild id>) - -This function will return the character ID number of the guild master of -the guild specified by the ID. 0 if the character is not a guild master of -any guild. - ---------------------------------------- - -*getcastlename("<map name>") - -This function returns the name of the castle when given the map name for -that castle. The data is read from 'db/castle_db.txt'. - ---------------------------------------- - -*getcastledata("<map name>", <type of data>) -*setcastledata("<map name>", <type of data>, <value>); - -This function returns the castle ownership information for the castle -referred to by its map name. Castle information is stored in -`guild_castle` SQL table. - -Types of data correspond to `guild_castle` table columns: - - 1 - `guild_id` - Guild ID. - 2 - `economy` - Castle Economy score. - 3 - `defense` - Castle Defense score. - 4 - `triggerE` - Number of times the economy was invested in today. - 5 - `triggerD` - Number of times the defense was invested in today. - 6 - `nextTime` - unused - 7 - `payTime` - unused - 8 - `createTime` - unused - 9 - `visibleC` - Is 1 if a Kafra was hired for this castle, 0 otherwise. -10 - `visibleG0` - Is 1 if the 1st guardian is present (Soldier Guardian) -11 - `visibleG1` - Is 1 if the 2nd guardian is present (Soldier Guardian) -12 - `visibleG2` - Is 1 if the 3rd guardian is present (Soldier Guardian) -13 - `visibleG3` - Is 1 if the 4th guardian is present (Archer Guardian) -14 - `visibleG4` - Is 1 if the 5th guardian is present (Archer Guardian) -15 - `visibleG5` - Is 1 if the 6th guardian is present (Knight Guardian) -16 - `visibleG6` - Is 1 if the 7th guardian is present (Knight Guardian) -17 - `visibleG7` - Is 1 if the 8th guardian is present (Knight Guardian) - -All types of data have their meaning determined by War of Emperium -scripts, with exception of: - - `guild_id` that is always the ID of the guild that owns the castle, - - `defense` that is used in Guardians & Emperium HP calculations, - - `visibleG` that is always considered to hold guardian presence bits. - -The setcastledata() command will behave identically, but instead of -returning values for the specified types of accessible data, it will alter -them and cause them to be sent to the char-server for storage. - -Changing Guild ID or Castle Defense will trigger additional actions, like -recalculating guardians' HP. - ---------------------------------------- - -*getgdskilllv(<guild id>, <skill id>) -*getgdskilllv(<guild id>, "<skill name>") - -This function returns the level of the skill <skill id> of the guild -<guild id>. -If the guild does not have that skill, 0 is returned. -If the guild does not exist, -1 is returned. -Refer to 'db/(pre-)re/skill_db.txt' for the full list of skills. -GD_* are guild skills - ---------------------------------------- - -*requestguildinfo(<guild id>{, "<event label>"}); - -This command requests the guild data from the char server and merrily -continues with the execution. Whenever the guild information becomes -available (which happens instantly if the guild information is already in -memory, or later, if it isn't and the map server has to wait for the char -server to reply) it will run the specified event as in a 'doevent' call. - ---------------------------------------- - -*getmapguildusers(<mapname>, <guild id>) - -Returns the amount of characters from the specified guild on the given map. - -Example: - - mes("You have "+getmapguildusers("prontera", getcharid(CHAR_ID_GUILD))+" guild members in Prontera."); - ---------------------------------------- - -*getguildmember(<guild id>{, <type>}); - -This command will find all members of a specified guild and returns their names -(or character id or account id depending on the value of "type") into an array -of temporary global variables. - -Upon executing this, - -$@guildmembername$[] is a global temporary string array which contains all the - names of these guild members. - (only set when type is 0 or not specified) - -$@guildmembercid[] is a global temporary number array which contains the - character id of these guild members. - (only set when type is 1) - -$@guildmemberaid[] is a global temporary number array which contains the - account id of these guild members. - (only set when type is 2) - -$@guildmembercount is the number of guild members that were found. - -The guild members will be found regardless of whether they are online or offline. -Note that the names come in no particular order. - -Be sure to use $@guildmembercount to go through this array, and not -getarraysize(), because it is not cleared between runs of getguildmember(). - -For usage examples, see getpartymember(). - ---------------------------------------- -//===================================== -2.2 - End of Guild-Related Commands -//===================================== ---------------------------------------- - -*getskilllv(<skill id>) -*getskilllv("<skill name>") - -This function returns the level of the specified skill that the invoking -character has. If they don't have the skill, 0 will be returned. The full -list of character skills is available in 'db/(pre-)re/skill_db.txt'. - -There are two main uses for this function, it can check whether the -character has a skill or not, and it can tell you if the level is high -enough. - -Example 1: - - if (getskilllv(TF_THROWSTONE)) { - // TF_THROWSTONE is defined in skill_db.txt and its value is 152 - mes("You have got the skill Throw Stone"); - close(); - } - mes("You don't have Throw Stone"); - close(); - -Example 2: - - if (getskilllv(AL_HEAL) == 10) { - mes("Your heal lvl has been maxed"); - close(); - } - if (getskilllv(AL_HEAL) >= 5) { - mes("Your heal lvl is 5 or more"); - close(); - } - mes("You heal skill is below lvl 5"); - close(); - ---------------------------------------- - -*getskilllist(); - -This command sets a bunch of arrays with a complete list of skills the -invoking character has. Here's what you get: - -@skilllist_id[] - skill ids. -@skilllist_lv[] - skill levels. -@skilllist_flag[] - see 'skill' for the meaning of skill flags. -@skilllist_count - number of skills in the above arrays. - -While getskilllv() is probably more useful for most situations, this is the -easiest way to store all the skills and make the character something else -for a while. Advanced job for a day? :) This could also be useful to see -how many skills a character has. - ---------------------------------------- - -*getpetinfo(<type>) - -This command will return the currently active pet information of the invoking character. -These fields are associate in 'db/(pre-)re/pet_db.conf'. Valid types are: - - PETINFO_ID - Pet Database ID, stored in `pet` table to distinguish from other pets. - PETINFO_CLASS - Pet class ID. (Id field) - PETINFO_NAME - Pet Name, return "null" if there's no active pet. - PETINFO_INTIMACY - Pet Intimacy level. 1000 is full loyalty. - PETINFO_HUNGRY - Pet hungry level. 100 is completely full. - PETINFO_RENAME - Pet rename flag. 0 means this pet has not been named yet. - PETINFO_GID - Pet Game ID - PETINFO_EGGITEM - Pet EggItem - PETINFO_FOODITEM - Pet FoodItem - PETINFO_ACCESSORYITEM - Pet AccessoryItem - PETINFO_ACCESSORYFLAG - return 1 if the pet currently equipping accessory, return 0 otherwise. - PETINFO_EVO_EGGID - Pet Evolve EggID - PETINFO_AUTOFEED - Pet AutoFeed flag. - -If the invoking player doesn't own a pet, this command will -return "null" for type PETINFO_NAME, and return 0 for other types. - ---------------------------------------- - -*petstat(<flag>) - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ /!\ This command is deprecated @ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -Returns current pet status, all are integers except name. -Returns 0 or "" if the player doesn't have pets. - -Flags usable: -PET_CLASS -PET_NAME -PET_LEVEL -PET_HUNGRY -PET_INTIMATE - -Example: - .@i = petstat(PET_CLASS); - -This command is deprecated and it should not be used in new scripts, as it is -likely to be removed at a later time. Please use 'getpetinfo' instead. - ---------------------------------------- - -*getmonsterinfo(<mob ID>, <type>) - -This function will look up the monster with the specified ID number in the -mob database and return the info set by TYPE argument. -It will return -1 if there is no such monster (or the type value is -invalid), or "null" if you requested the monster's name. - -Valid types are listed in doc/constants.md: - MOB_NAME 0 - MOB_LV 1 - MOB_MAXHP 2 - MOB_BASEEXP 3 - MOB_JOBEXP 4 - MOB_ATK1 5 - MOB_ATK2 6 - MOB_DEF 7 - MOB_MDEF 8 - MOB_STR 9 - MOB_AGI 10 - MOB_VIT 11 - MOB_INT 12 - MOB_DEX 13 - MOB_LUK 14 - MOB_RANGE 15 - MOB_RANGE2 16 - MOB_RANGE3 17 - MOB_SIZE 18 - MOB_RACE 19 - MOB_ELEMENT 20 - MOB_MODE 21 - MOB_MVPEXP 22 - -Check sample in doc/sample/getmonsterinfo.txt - ---------------------------------------- - -*addmonsterdrop(<mob id or name>, <item id>, <rate>) - -This command will temporarily add a drop to an existing monster. If the -monster already drops the specified item, its drop rate will be updated to the -given value. - -Both the monster and the item must be valid. Acceptable values for the drop -rate are in the range [1:10000]. - -Return value will be 1 in case of success (the item was added or its drop rate -was updated), and 0 otherwise (there were no free item drop slots). - -Example: - // Add Poring Doll (741) to the Poring's (1002) drops, with 1% (100) rate - addmonsterdrop(PORING, Poring_Doll, 100); - ---------------------------------------- - -*delmonsterdrop(<mob id or name>, <item id>) - -This command will temporarily remove a drop from an existing monster. - -Both the monster and the item must be valid. - -Return value will be true in case of success (the item was removed), and -false otherwise (the monster didn't have the specified item in its drop -list). - -Example: - // Remove Jellopy (909) from the Poring's (1002) drops - delmonsterdrop(PORING, Jellopy); - ---------------------------------------- - -*getmobdrops(<mob id>) - -This command will find all drops of the specified mob and return the item -IDs and drop percentages into arrays of temporary global variables. -getmobdrops() returns true if successful and false if the mob ID doesn't -exist. - -Upon executing this, - -$@MobDrop_item[] is a global temporary number array which contains the - item IDs of the monster's drops. - -$@MobDrop_rate[] is a global temporary number array which contains the - drop percentages of each item. (1 = .01%) - -$@MobDrop_count is the number of item drops found. - -Be sure to use $@MobDrop_count to go through the arrays, and not -'getarraysize', because the temporary global arrays are not cleared -between runs of 'getmobdrops'. If a mob with 7 item drops is looked up, -the arrays would have 7 elements. But if another mob is looked up and it -only has 5 item drops, the server will not clear the arrays for you, -overwriting the values instead. So in addition to returning the 5 item -drops, the 6th and 7th elements from the last call remain, and you will -get 5+2 item drops, of which the last 2 don't belong to the new mob. -$@MobDrop_count will always contain the correct number (5), unlike -getarraysize() which would return 7 in this case. - -Example: - - // get a Mob ID from the user - input(.@mob_id); - - if (getmobdrops(.@mob_id)) { // getmobdrops() returns true on success - // immediately copy global temporary variables into scope - // variables, since we don't know when getmobdrops() will get - // called again for another mob, overwriting your global temporary - // variables. - .@count = $@MobDrop_count; - copyarray(.@item[0], $@MobDrop_item[0], .@count); - copyarray(.@rate[0], $@MobDrop_rate[0], .@count); - - mes(getmonsterinfo(.@mob_id, MOB_NAME) + " - " + .@count + " drops found:"); - for (.@i = 0; .@i < .@count; ++.@i) { - mes(.@item[.@i] + " (" + getitemname(.@item[.@i]) + ") " + .@rate[.@i]/100 + ((.@rate[.@i]%100 < 10) ? ".0":".") + .@rate[.@i]%100 + "%"); - } - } else { - mes("Unknown monster ID."); - } - close(); - ---------------------------------------- - -*skillpointcount() - -Returns the total amount of skill points a character possesses -(SkillPoint + skill points used in skills) This command can be used to -check the currently attached characters total amount of skill points. -This means the skill points used in skill are counted, and added to -SkillPoints (number of skill points not used). - -Example: - -//This will set the temp character variable @skill_points to the amount of -//skill points, and then tell the player the value. - @skill_points = skillpointcount(); - mes("You have "+@skill_points+" skill points in total!"); - -//Self-explanatory... :P - if (skillpointcount() > 20) - mes("Wow, you have more then 20 Skill Points in total!"); - -This command does not count skills which are set as flag 3 (permamently -granted) (e.g. ALL_BUYING_STORE/ALL_INCCARRY). ---------------------------------------- - -*getscrate(<effect type>, <base rate>{, <GID>}) - -This function will return the chance of a status effect affecting the -invoking character, in percent, modified by the their current defense -against said status. The 'base rate' is the base chance of the status -effect being inflicted, in percent. - - if (rand(100) > getscrate(Eff_Blind, 50)) { - // do something - } - -You can see the full list of available effect types you can possibly -inflict in 'doc/constants.md' under 'Status effects'. - ---------------------------------------- -//===================================== -3 - Checking-Related Commands -//===================================== ---------------------------------------- - -*playerattached() - -Returns the ID of the player currently attached to the script. It will -return 0 if no one is attached, or if the attached player no longer exists -on the map server. It is wise to check for the attached player in script -functions that deal with timers as there's no guarantee the player will -still be logged on when the timer triggers. Note that the ID of a player -is actually their account ID. - ---------------------------------------- - -*isloggedin(<account id>{, <char id>}) - -This function returns true if the specified account is logged in and -false if they aren't. You can also pass the char_id to check for both -account and char id. - ---------------------------------------- - -*checkweight(<item id>, <amount>{, <item id>, <amount>, <item id>, <amount>, ...}) -*checkweight("<item name>", <amount>{, "<item name>", <amount>, "<item name>", <amount>, ...}) -*checkweight2(<id_array>, <amount_array>) - -These functions will compute and return true if the total weight of the -specified number of specific items does not exceed the invoking -character's carrying capacity, and false otherwise. It is important to -see if a player can carry the items you expect to give them, failing to -do that may open your script up to abuse or create some very unfair -errors. - -The second function will check an array of items and amounts, and also -returns true on success and false on failure. - -The functions, in addition to checking to see if the player is capable of -holding a set amount of items, also ensure the player has room in their -inventory for the item(s) they will be receiving. - -Like getitem(), this function will also accept an 'english name' from -the database as an argument. - -Example 1: - - if (checkweight(Apple, 10)) { - getitem(Apple, 10); - } else { - mes("Sorry, you cannot hold this amount of apples!"); - } - -Example 2: - - setarray(.@item[0], 512, 513, 514); - setarray(.@amount[0], 10, 5, 5); - if (!checkweight(.@item, .@amount)) { - mes("Sorry, you cannot hold this amount of fruit!"); - } - ---------------------------------------- - -*basicskillcheck() - -This function will return the state of the configuration option -'basic_skill_check' in 'conf/map/battle.conf'. Returns true if the -option is enabled and false if it isn't. If the 'basic_skill_check' -option is enabled, which it is by default, characters must have a -certain number of basic skill levels to sit, request a trade, use -emotions, etc. Making your script behave differently depending on -whether the characters must actually have the skill to do all these -things might in some cases be required. - ---------------------------------------- - -*checkoption(<option number>{, <account id>}) -*checkoption1(<option number>{, <account id>}) -*checkoption2(<option number>{, <account id>}) -*setoption(<option number>{, <flag>{, <account id>}}); - -The setoption() series of functions check for a so-called option that is -set on the invoking character. 'Options' are used to store status -conditions and a lot of other non-permanent character data of the yes-no -kind. For most common cases, it is better to use checkcart(), -checkfalcon(), checkmount() and other similar functions, but there are -some options which you cannot get at this way. If <account id> is given, -this player will be used instead of the invoking character. - -Option numbers valid for the first (option) version of this command are: - -0x000000 Option_Nothing - No options -0x000001 Option_Sight - Sight in effect. -0x000002 Option_Hide - Hide in effect. -0x000004 Option_Cloak - Cloaking in effect. -0x000008 - Cart number 1 present. -0x000010 Option_Falcon - Falcon present. -0x000020 Option_Riding - Peco Peco present. -0x000040 Option_Invisible - GM Perfect Hide in effect. -0x000080 - Cart number 2 present. -0x000100 - Cart number 3 present. -0x000200 - Cart number 4 present. -0x000400 - Cart number 5 present. -0x000800 Option_Orcish - Orc head present. -0x001000 Option_Wedding - The character is wearing a wedding sprite. -0x002000 - Ruwach is in effect. -0x004000 Option_Chasewalk - Chasewalk in effect. -0x008000 Option_Flying - Flying or Xmas suit. -0x010000 - Sighttrasher. -0x100000 Option_Wug - Warg present. -0x200000 Option_Wugrider - The character is riding a warg. - -Option numbers valid for the second version (opt1) of this command are: - -1 - Petrified. -2 - Frozen. -3 - Stunned. -4 - Sleeping. -6 - Petrifying (the state where you can still walk) - -Option numbers valid for the third version (opt2) of this command are: - -0x01 - Poisoned. -0x02 - Cursed. -0x04 - Silenced. -0x08 - Signum Crucis (plays a howl-like sound effect, but otherwise no - visible effects are displayed) -0x10 - Blinded. -0x80 - Deadly poisoned. - -Option numbers (except for opt1) are bit-masks - you can add them up to -check for several states, but the functions will return true if at least -one of them is in effect. - -setoption() will set options on the invoking character. There are no -second and third versions of this command, so you can only change the -values in the first list (cloak, cart, ruwach, etc). If flag is 1 (default -when omitted), the option will be added to what the character currently -has; if 0, the option is removed. - -This is definitely not a complete list of available option flag numbers. -Ask a core developer (or read the source: src/map/status.h) for the full -list. - ---------------------------------------- - -*setcart({<type>}) -*checkcart() - -If <type> is 0 this command will remove the cart from the character. -Otherwise it gives the invoking character a cart. The cart given will be -cart number <type> and will work regardless of whether the character is a -merchant class or not. -Note: the character needs to have the skill MC_PUSHCART to gain a cart. - -The accompanying function will return true if the invoking character has a -cart (any kind of cart) and false if they don't. - - if (checkcart()) - mes("But you already have a cart!"); - ---------------------------------------- - -*setfalcon({<flag>}) -*checkfalcon() - -If <flag> is 0 this command will remove the falcon from the character. -Otherwise it gives the invoking character a falcon. The falcon will be -there regardless of whether the character is a hunter or not. It will -(probably) not have any useful effects for non-hunters though. -Note: the character needs to have the skill HT_FALCON to gain a falcon. - -The accompanying function will return true if the invoking character has a -falcon and false if they don't. - - if (checkfalcon()) - mes("But you already have a falcon!"); - ---------------------------------------- - -*setmount({<flag>}) -*checkmount() - -If <flag> is MOUNT_NONE this command will remove the mount from the -character. - -Otherwise it gives the invoking character the desired combat mount, where -allowed by their class and skills. - -If no flag is specified, the mount is automatically chosen according to the -character's class and skills. - -The following flag values are accepted: - - MOUNT_NONE: - - Dismount - MOUNT_PECO: - - PecoPeco (Knight series class) - - GrandPeco (Crusader series class) - - Gryphon (Royal Guard) - MOUNT_WUG: - - Warg (Ranger) - MOUNT_MADO: - - Mado Gear (Mechanic) - MOUNT_DRAGON: - MOUNT_DRAGON_GREEN: - MOUNT_DRAGON_BROWN: - MOUNT_DRAGON_GRAY: - MOUNT_DRAGON_BLUE: - MOUNT_DRAGON_RED: - - Dragon (Rune Knight) - if MOUNT_DRAGON is specified, a the default (green) dragon will be used. - -Unlike 'setfalcon' and 'setcart' this will not work at all if they aren't of a -class which can ride a mount. - -The accompanying function will return MOUNT_NONE if the invoking -character is not on a mount, and a non-zero value (according to the -above constants) if they are. -Note: in case of dragons, the returned value will always be MOUNT_DRAGON, -regardless of color. - - if (checkmount()) - mes("Leave your mount outside! No riding mounts on the floor here!"); - - if (checkmount() == MOUNT_DRAGON) - mes("Wow, your dragon is cool! Can I pet it?"); - ---------------------------------------- - -*setcashmount() -*hascashmount() - -The 'setcashmount' function toggles cash mount for the invoking character. -It will return true if successful, false otherwise. - -Note: Character must not be mounting a non-cash mount (eg. dragon, peco, - wug, etc.) - -The accompanying function will return true if the invoking character has a -cash mount and false if they don't. - ---------------------------------------- - -*checkwug() - -This function will return true if the invoking character has a warg and false if -they don't. - ---------------------------------------- - -*checkvending({"<Player Name>"}) -*checkchatting({"<Player Name>"}) - -Checks if the player is vending or in a chatroom. -Name is optional, and defaults to the attached player if omitted. - -Return values for 'checkvending' are - 0 = not vending - 1 = normal vending - 2 = vending using @autotrade - -checkchatting() returns true if they are in a chat room, false if they are not. - -Examples: - //This will check if Aaron is vending, and if so, put a message in - //front of the attached player saying Aaron is vending. - if (checkvending("Aaron")) - mes("Aaron is currently vending!"); - - //This will check if the attached player in a chat room or not. - if (checkchatting()) - mes("You are currently in a chat room!"); - ---------------------------------------- - -*checkidle({"<Player Name>"}) - -Returns the time, in seconds, that the specified player has been idle. -Name is optional, and defaults to the attached player if omitted. - ---------------------------------------- - -*agitcheck() -*agitcheck2() - -These function will let you check whether the server is currently in WoE -mode (or WoE SE mode if the second function is called) and will return true -if War of Emperium is on and false if it isn't. - ---------------------------------------- - -*isnight() - -This functions will return true or false depending on whether the server is in -night mode or day mode: - - if (!isnight()) - mes("I only prowl in the night."); - ---------------------------------------- -//===================================== -3.1 - Checking Item-Related Commands -//===================================== ---------------------------------------- - -*isequipped(<item id>{, <item id>{, <item id>{, <item id>}}}) - -This function will return true if the invoking character has all of the item -IDs given equipped (if card IDs are passed, then it checks if the cards -are inserted into slots in the equipment they are currently wearing). -Theoretically there is no limit to the number of items that may be tested -for at the same time. -If even one of the items given is not equipped, false will be returned. - - // (Poring, Santa Poring, Poporing, Marin) - if (isequipped(Poring_Card, Poring__Card, Poporing_Card, Marin_Card)) - mes("Wow! You're wearing a full complement of possible poring cards!"); - // (Poring) - if (isequipped(Poring_Card)) - mes("A poring card is useful, don't you think?"); - // (Earring) - if (isequipped(Earring_)) - mes("You got a pair of nice Earring."); - -The function was meant for item scripts to support the cards released by -Gravity in February 2005, but it will work just fine in normal NPC scripts. - ---------------------------------------- - -*isequippedcnt(<item id>{, <item id>{, <item id>{, <item id>}}}) - -This function is similar to isequipped(), but instead of true or false, it will -return the number of equipped items/cards in the list given that were found on the -invoking character. - - if (isequippedcnt(Poring_Card, Poring__Card, Poporing_Card, Marin_Card) == 4) - mes("Finally got all four poring cards?"); - if (isequippedcnt(Helm_Of_Sun_, Earring_) == 2) - mes("You equipped both Helm of Sun and Earring."); - ---------------------------------------- - -*checkequipedcard(<card id>) - -This function will return true if the card specified by it's item ID number -is inserted into any equipment they have in their inventory, currently -equipped or not. - ---------------------------------------- - -*getequipisidentify(<equipment slot>) - -This function will return true if an item in the specified equipment slot is -identified and false if it isn't. Since you can't even equip unidentified -equipment, there's a question of whether it can actually end up there, and -it will normally return true all the time if there is an item in this -equipment slot, which makes this script command kinda pointless. -For a list of equipment slots see getequipid(). - ---------------------------------------- -//===================================== -3.0 & 3.1 - End of Checking/Item-Related Commands -//===================================== ---------------------------------------- - ---------------------------------------- -//===================================== -4 - Player-Related Commands -//===================================== ---------------------------------------- - -*attachrid(<account ID>) -*detachrid() - -These commands allow the manipulation of the script's currently attached -player. While attachrid() allows attaching of a different player by using -its account id for the parameter rid, detachrid() makes the following -commands run as if the script was never invoked by a player. - -In case, that the player cannot be attached, such as, when the player went -offline in the mean time, attachrid() returns false, otherwise true. - ---------------------------------------- - -*rid2name(<account id>) - -Converts rid to name. Note: The player/monster/NPC must be online/enabled. -Good for PCKillEvent where you can convert 'killedrid' to the name of the -player. - -Note: rid2name() may not produce correct character names since RID means - account id. - It will return the current online character of the account only. - ---------------------------------------- - -*message(<account ID>, "<message>") -*message("<character name>", "<message>") - -That command will send a message to the chat window of the character -specified by account ID or name. The text will also appear above the head -of that character. It will not be seen by anyone else. - ---------------------------------------- - -*dispbottom("<message>"{, <color>}) - -This command will send the given message into the invoking character's -chat window. The color format is in RGB (0xRRGGBB), and default to green -if <color> field is left out. - ---------------------------------------- - -*showscript("<message>"{, <GID>{, <send_target>}}) - -Makes the attached player or GID, display a message similiar to a chat, -this will be seen by everyone near the invoking character but will not -be displayed in the chat window. -send_target: (optional) - AREA: show the message to everyone within the view range (default) - SELF: show the message to the given unit GID only - ---------------------------------------- - -*warp("<map name>", <x>, <y>{, <flag>}) - -This command will take the invoking character to the specified map, and if -wanted, specified coordinates too, but these can be random. - - warp("place", 50, 55); - -This would take them to X 50 Y 55 on the map called "place". If your X and -Y coordinates land on an unwalkable map square, it will send the warped -character to a random place. Same will happen if they are both zero: - - warp("place", 0, 0); - -Notice that while warping people to coordinates 0,0 will normally get them -into a random place, it's not certain to always be so. Darned if I know -where this is actually coded, it might be that this happens because square -0,0 is unwalkable on all official maps. Beware if you're using custom maps. - -There are also three special 'map names' you can use: - -"Random" will warp the player randomly on the current map. -"Save" and "SavePoint" will warp the player back to their save point. - -If flag parameter is set to 0, after player warped will be not stopped -currend running npc script. Running script after warp can be issue for -Gravity client if warp to other maps. - ---------------------------------------- - -*areawarp("<from map name>", <x1>, <y1>, <x2>, <y2>, "<to map name>", <x3>, <y3>{, <x4>, <y4>}) - -This command is similar to 'warp', however, it will not refer to the -invoking character, but instead, all characters within a specified area, -defined by the x1/y1-x2/y2 square, will be warped. Nobody outside the area -will be affected, including the activating character, if they are outside -the area. - - areawarp("place", 10, 10, 120, 120, "place2", 150, 150); - -Everyone that is in the area between X 10 Y 10 and X 120 Y 120, in a -square shape, on the map called "place", will be affected, and warped to -"place2" X 150 Y 150. - - areawarp("place", 10, 10, 120, 120, "place2", 0, 0); - -By using 0,0; as the destination coordinates it will take all the -characters in the affected area to a random set of co-ordinates on the -"place2" map. - - areawarp("place", 10, 10, 120, 120, "place2", 150, 150, 200, 200); - -By using the optional x4 and y4 parameters, the destination coordinates -will be a random place within the defined x3/y3-x4/y4 square. - -Like warp(), areawarp() will also explicitly warp characters randomly into -the current map if you give the 'to map name' as "Random". - -See also warp(). - ---------------------------------------- - -*warpparty("<to_mapname>", <x>, <y>, <party_id>, "<from_mapname>", <include_leader>) - -Warps a party to specified map and coordinate given the party ID, which -you can get with getcharid(CHAR_ID_PARTY). You can also request another party id given -a member's name with getcharid(CHAR_ID_PARTY, <player_name>). - -You can use the following "map names" for special warping behavior: -Random: All party members are randomly warped in their current map - (as if they all used a fly wing). -SavePointAll: All party members are warped to their respective save point. -SavePoint: All party members are warped to the save point of the - currently attached player (will fail if there's no player - attached). -Leader: All party members are warped to the leader's position. The - leader must be online and in the current map-server for - this to work. - -If you specify a from_mapname, warpparty() will only affect those on -that map. - -You can exclude Party leader from warping, by keeping include_leader option as false. - -Example: - - mes("[Party Warper]"); - mes("Here you go!"); - close2(); - .@id = getcharid(CHAR_ID_PARTY); - warpparty("prontera", 150, 100, .@id, true); - close(); - ---------------------------------------- - -*warpchar("<mapname>", <x>, <y>, <char_id>) - -Warps another player to specified map and coordinate given the char id, -which you can get with getcharid(CHAR_ID_CHAR, <player_name>). Obviously this is -useless if you want to warp the same player that is executing this script, -unless it's some kind of "chosen" script. - -Example: - - warpchar("prontera", 150, 100, 150001); - ---------------------------------------- - -*warpguild("<mapname>", <x>, <y>, <guild_id>, {"<from_mapname>"}) - -Warps a guild to specified map and coordinate given the guild id, which -you can get with getcharid(CHAR_ID_GUILD). You can also request another guild id given -the member's name with getcharid(CHAR_ID_GUILD, <player_name>). - -You can use the following "map names" for special warping behavior: -Random: All guild members are randomly warped in their current map - (as if they all used a fly wing) -SavePointAll: All guild members are warped to their respective save point. -SavePoint: All guild members are warped to the save point of the - currently attached player (will fail if there's no player - attached). - -If you specify a from_mapname, warpguild() will only affect those on that map. - -Example: - - warpguild("prontera", x, y, Guild_ID); - warpguild("prontera", x, y, Guild_ID, "payon"); // warp member from Payon map only. - ---------------------------------------- - -*warppartner("<map name>", <x>, <y>) - -This function will find the invoking character's marriage partner, if any, -and warp them to the map and coordinates given. Go kidnap that spouse. :) -It will return true upon success and false if the partner is not online, -the character is not married, or if there's no invoking character (no -RID). -0,0 will, as usual, normally translate to random coordinates. - ---------------------------------------- - -*savepoint("<map name>", <x>, <y>) - -This command saves where the invoking character will return to upon -'return to save point', if dead or in some other cases. The two versions -are equivalent. Map name, X coordinate and Y coordinate should be -perfectly obvious. This ignores any and all map flags, and can make a -character respawn where no teleportation is otherwise possible. - - savepoint("place", 350, 75); - ---------------------------------------- - -*heal(<hp>, <sp>) - -This command will heal a set amount of HP and/or SP on the invoking -character. - - heal(30000, 0) // This will heal 30,000 HP - heal(0, 30000) // This will heal 30,000 SP - heal(300, 300) // This will heal 300 HP and 300 SP - -This command just alters the hit points and spell points of the invoking -character and produces no other output whatsoever. - ---------------------------------------- - -*itemheal(<hp>, <sp>) - -This command heals given relative amounts of HP and/or SP on the invoking -character. Unlike heal, this command is intended for use in item scripts. -It applies potion-related bonuses, such as alchemist ranking, cards, -status changes. -It also applies a sp/vit-related bonus that is calculated by: - heal = heal*[(100+STATUS*2)/100] -So if a player has 99 vit and the script is 'itemheal 5, 0': - heal(hp) = 5*[(100+99*2)/100] - heal(hp) = 14.9 - heal(hp) = 14 - heal(sp) = 0 - -When used inside an NPC script, potion-related bonuses are omitted. - -There is also a nice example on using this with the rand() function, to -give you a random amount of healing. - - // If the player has 50 vit and no bonuses this will heal - // anything from 200 to 300 HP and 5 SP - itemheal(rand(100, 150), 5); - ---------------------------------------- - -*percentheal(<hp>, <sp>) - -This command will heal the invoking character. It heals the character, but -not by a set value - it adds percent of their maximum HP/SP. - - percentheal(100, 0); // This will heal 100% HP - percentheal(0, 100); // This will heal 100% SP - percentheal(50, 50); // This will heal 50% HP and 50% SP - -So the amount that this will heal will depend on the total amount of HP or -SP you have maximum. Like heal(), this will not call up any animations or -effects. - ---------------------------------------- - -*recovery({<account id>}) -*recovery("<map name>"{, <x1>, <y1>, <x2>, <y2>}) - -This command will revive and restore full HP and SP to all characters currently -connected to the server. If an account id is supplied, it will instead only -affect this character. If a map is supplied it will affect a whole map or area. - ---------------------------------------- - -*jobchange(<job number>{, <upper flag>}) - -This command will change the job class of the invoking character. - - jobchange(Job_Swordman); // This would change your player into a Swordman - jobchange(Job_Swordman_High); // This would change your player into a Swordman High - -This command does work with numbers, but you can also use job names. The -full list of job names and the numbers they correspond to can be found in -'doc/constants.md'. - -'upper flag' can alternatively be used to specify the type of job one -changes to. For example, jobchange(Job_Swordman, 1); will change the -character to a high swordsman. The upper values are: --1 (or when omitted): preserves the current job type. -0: Normal/standard classes -1: High/Advanced classes -2: Baby classes - -This command will also set a permanent character-based variable -'jobchange_level' which will contain the job level at the time right -before changing jobs, which can be checked for later in scripts. - ---------------------------------------- - -*jobname(<job number>) - -This command retrieves the name of the given job using the names defined -in messages.conf. - - mes("[Kid]"); - mes("I never thought I'd met a "+jobname(Class)+" here of all places."); - close(); - ---------------------------------------- - -*eaclass({<job number>}) - -This commands returns the "eA job-number" corresponding to the given -class, and uses the invoking player's class if none is given. The eA -job-number is also a class number system, but it's one that comes with -constants which make it easy to convert among classes. The command will -return -1 if you pass it a job number which doesn't have an eA job-number -equivalent. - - .@eac = eaclass(); - if ((.@eac&EAJ_BASEMASK) == EAJ_SWORDMAN) - mes("Your base job is Swordman."); - if (.@eac&EAJL_UPPER) - mes("You are a rebirth job."); - if ((.@eac&EAJ_UPPERMASK) == EAJ_SWORDMAN) - mes("You must be a Swordman, Baby Swordman or High Swordman."); - -For more information on the eA Job System, see the docs/ea_job_system.txt -file. - ---------------------------------------- -*roclass(<job number> {, <gender>}) - -Does the opposite of eaclass(). That is, given an eA job-number, it returns -the corresponding RO class number. A gender is required because both Bard -and Dancers share the same eA job-number (EAJ_BARDDANCER), and uses the -invoking player's gender if none is given (if no player is attached, -male will be used by default). The command will return -1 if there is no -valid class to represent the specified job (for example, if you try to get -the baby version of a Taekwon class). - - .@eac = eaclass(); - //Check if class is already rebirth - if (.@eac&EAJL_UPPER) { - mes("You look strong."); - close(); - } - .@eac = roclass(.@eac|EAJL_UPPER); - //Check if class has a rebirth version - if (.@eac != -1) { - mes("Bet you can't wait to become a "+jobname(.@eac)+"!"); - close(); - } - ---------------------------------------- - -*changebase(<job ID number>) - -This command will change the appearance of the invoking character to that -of a specified job class. Nothing but appearance will change. - -Examples: - - /* This example is an item script in the item db */ - { - Id: 2338 - AegisName: "Wedding_Dress" - Name: "Wedding Dress" - Type: 5 - Buy: 43000 - Weight: 500 - Job: 0xFFFFFFFE - Loc: 16 - Script: <" - bonus(bMdef, 15); - changebase(Job_Wedding); - "> - }, - -changebase(Job_Novice); // Changes player to Novice sprite. - -changebase(Class); // Changes player back to default sprite. - ---------------------------------------- - -*classchange(<view id>, <type> {, <char id>}) - -This command is very ancient, it's origins are clouded in mystery. -It will send a 'display id change' packet to player with given char ID -or to everyone in the immediate area of the NPC object if char ID is 0 or -not passed, which will make the NPC look like a different sprite, an NPC -sprite ID, or a monster ID. This effect is not stored anywhere and will -not persist. -Note that you can't send a Job sprite ID - -type is not used and should always be 0. - ---------------------------------------- - -*changesex() - -This command will change the gender for the attached character's account. -If it was male, it will become female, if it was female, it will become -male. The change will be written to the character server, the player will -receive the message: "Need disconnection to perform change-sex request..." -and the player will be immediately kicked to the login screen. When they -log back in, they will be the opposite sex. - -If there are any Dancer/Gypsy or Bard/Clown characters on the account, -they will also have their skills reset upon 'changesex'. - ---------------------------------------- - -*changecharsex() - -This command is exactly same as changesex(), with an exception that, -character sex will be changed instead of account sex. -Requires client 2014-10-22 or greater. - ---------------------------------------- - -*getexp(<base xp>, <job xp>) - -This command will give the invoking character a specified number of base -and job experience points. Should be used as a quest reward. Negative values -won't work. -Is subject to EXP bonuses and to the `quest_exp_rate` config option. - - getexp(10000, 5000); - -You can also assign directly to the parameters defined in -'doc/constants.md': - - BaseExp += 10000; - JobExp += 5000; - -You can also reduce the amount of experience points: - - BaseExp -= 10000; - -When setting the parameters directly no bonuses or config options are applied. - ---------------------------------------- - -*setlook(<look type>, <look value>) -*changelook(<look type>, <look value>) - -'setlook' will alter the look data for the invoking character. It is used -mainly for changing the palette used on hair and clothes: you specify -which look type you want to change, then the palette you want to use. Make -sure you specify a palette number that exists/is usable by the client you -use. 'changelook' works the same, but is only client side (it doesn't save -the look value). - - // This will change your hair(6), so that it uses palette 8, what ever - // your palette 8 is, your hair will use that color. - - setlook(LOOK_HAIR_COLOR, 8); - - // This will change your clothes(7), so they are using palette 1, - // whatever your palette 1 is, your clothes will then use that set of - // colors. - - setlook(LOOK_CLOTHES_COLOR, 1); - -Here are the possible look types: - - 0 - LOOK_BASE Base sprite - 1 - LOOK_HAIR Hairstyle - 2 - LOOK_WEAPON Weapon - 3 - LOOK_HEAD_BOTTOM Head bottom - 4 - LOOK_HEAD_TOP Head top - 5 - LOOK_HEAD_MID Head mid - 6 - LOOK_HAIR_COLOR Hair color - 7 - LOOK_CLOTHES_COLOR Clothes color - 8 - LOOK_SHIELD Shield - 9 - LOOK_SHOES Shoes - 10 - LOOK_BODY Body(N/A) - 11 - LOOK_FLOOR FLOOR(N/A) - 12 - LOOK_ROBE Robe - 13 - LOOK_BODY2 Body style - -Whatever 'shoes' means is anyone's guess, ask Gravity - the client does -nothing with this value. It still wants it from the server though, so it -is kept, but normally doesn't do a thing. - -Only the look data for hairstyle, hair color and clothes color are saved -to the char server's database and will persist. The rest freely change as -the character puts on and removes equipment, changes maps, logs in and out -and otherwise you should not expect to set them. In fact, messing with -them is generally hazardous, do it at your own risk, it is not tested -what will this actually do - it won't cause database corruption and -probably won't cause a server crash, but it's easy to crash the client -with just about anything unusual. - -However, it might be an easy way to quickly check for empty view IDs for -sprites, which is essential for making custom headgear. - -Since a lot of people have different palettes for hair and clothes, it's -impossible to tell you what all the color numbers are. If you want a -serious example, there is a Stylist script inside the default Hercules -installation that you can look at: 'npc/custom/stylist.txt' - ---------------------------------------- - -*pushpc(<direction>, <cells>) - -This command will push the currently attached player to given direction by -given amount of square cells. Direction is the same as used when declaring -NPCs, and can be specified by using one of the DIR_* constants -(doc/constants.md). - -The knock-back is not restricted by items or map flags, only obstacles are -taken into account. If there is not enough space to perform the push (e.g. -due to a wall), the character is pushed only up to the obstacle. - - // pushes the character 5 cells in 3 o'clock direction from it's - // current position. - pushpc(DIR_EAST, 5); - ---------------------------------------- - -*montransform(<monster id>, <duration>{, <sc_type>{, <val1>{, <val2>{, <val3>{, <val4>}}}}}) -*montransform("<monster name>", <duration>{, <sc_type>{, <val1>{, <val2>{, <val3>{, <val4>}}}}}) - -This command can transform your character into monster and you can still -use all your skills like a normal character. -Can only be removed when your killed or if you die or if duration is over. - -for sc_type, val1, val2, val3, val4, see sc_start(), sc_start2(), sc_start4() commands. - ---------------------------------------- -//===================================== -4.1 - Player Item-Related Commands -//===================================== ---------------------------------------- - -*getitem(<item id>, <amount>{, <account ID>}) -*getitem("<item name>", <amount>{, <account ID>}) - -This command will give a specific amount of specified items to the target -character. If the character is not online, nothing will happen. -If <account ID> is not specified, items will be created in the invoking -character inventory instead. - -In the first and most commonly used version of this command, items are -referred to by their database ID number found in 'db/(pre-)re/item_db.txt'. - - getitem(Apple, 10); // The person will receive 10 apples - getitem(Old_Violet_Box, 1); // The person will receive 1 Old Violet Box - -Giving an item ID of -1 will give a specified number of random items from -the list of those that fall out of Old Blue Box. Unlike in all other -cases, these will be unidentified, if they turn out to be equipment. This -is exactly what's written in the Old Blue Box's item script. - -Other negative IDs also correspond to other random item generating item -tables: - -Giving an item ID of -2 will produce the effects of Old Violet Box. -Giving an item ID of -3 will produce the effects of Old Card Album. -Giving an item ID of -4 will produce the effects of Gift Box. -Giving an item ID of -5 will produce the effects of Worn Out Scroll, -which, in current Git, drops only Jellopies anyway. - -This transaction is logged if the log script generated transactions option -is enabled. - -You may also create an item by it's name in the 'english name' field in -the item database: - - getitem("Red_Potion", 10); // Not recommended, use Red_Potion instead of "Red_Potion" - -Which will do what you'd expect. If it can't find that name in the -database, apples will be created anyway. - -This is used in pretty much all NPC scripts that have to do with items and -quite a few item scripts. For more examples check just about any official -script. - ---------------------------------------- - -*getitem2(<item id>, <amount>, <identify>, <refine>, <attribute>, <card1>, <card2>, <card3>, <card4>{, <account ID>}) -*getitem2("<item name>", <amount>, <identify>, <refine>, <attribute>, <card1>, <card2>, <card3>, <card4>{, <account ID>}) - -This command will give an amount of specified items to the invoking -character. If an optional account ID is specified, and the target -character is currently online, items will be created in their inventory -instead. If they are not online, nothing will happen. It works essentially -the same as 'getitem' (it even works for negative ID numbers the same way) -but is a lot more flexible. - -Those parameters that are different from getitem() are: - -identify - Whether you want the item to be identified (1) or not (0). -refine - For how many pluses will it be refined. It will not let you - refine an item higher than the max refine. -attribute - Whether the item is broken (1) or not (0). -card1,2,3,4 - If you want a card compound to it, place the card ID number - into the specific card slot. - -Card1-card4 values are also used to store name information for named -items, as well as the elemental property of weapons and armor. You can -create a named item in this manner, however, if you just need a named -piece of standard equipment, it is much easier to the 'getnameditem' -function instead. - -You will need to keep these values if you want to destroy and then -perfectly recreate a named item, for this see getinventorylist(). - -If you still want to try creating a named item with this command because -'getnameditem' won't do it for you cause it's too limited, you can do it -like this. Careful, minor magic ahead. - - // First, let's get an ID of a character who's name will be on the - // item. Only an existing character's name may be there. - // Let's assume our character is 'Adam' and find his ID. - - .@charid = getcharid(CHAR_ID_CHAR, "Adam"); - - // Now we split the character ID number into two portions with a - // binary shift operation. If you don't understand what this does, - // just copy it. - - .@card3 = .@charid & 65535; - .@card4 = .@charid >> 16; - - // If you're inscribing non-equipment, .@card1 must be 254. - // Arrows are also not equipment. :) - .@card1 = 254; - - // For named equipment, card2 means the Star Crumbs and elemental - // crystals used to make this equipment. For everything else, it's 0. - - .@card2 = 0; - - // Now, let's give the character who invoked the script some - // Adam's Apples: - - getitem2(Apple, 1, 1, 0, 0, .@card1, .@card2, .@card3, .@card4); - -This wasn't tested with all possible items, so I can't give any promises, -experiment first before relying on it. - -To create equipment, continue this example it like this: - - // We've already have card3 and card4 loaded with correct - // values so we'll just set up card1 and card2 with data - // for an Ice Stiletto. - - // If you're inscribing equipment, .@card1 must be 255. - .@card1 = 255; - - // That's the number of star crumbs in a weapon. - .@sc = 2; - - // That's the number of elemental property of the weapon. - .@ele = 1; - - // And that's the wacky formula that makes them into - // a single number. - .@card2 = .@ele+((.@sc*5)<<8); - - // That will make us an Adam's +2 VVS Ice Stiletto: - - getitem2(Stiletto, 1, 1, 2, 0, .@card1, .@card2, .@card3, .@card4); - -Experiment with the number of star crumbs - I'm not certain just how much -will work most and what it depends on. The valid element numbers are: - - 1 - Ice, 2 - Earth 3 - Fire 4 - Wind. - -You can, apparently, even create duplicates of the same pet egg with this -command, creating a pet which is the same, but simultaneously exists in -two eggs, and may hatch from either, although, I'm not sure what kind of a -mess will this really cause. - ---------------------------------------- -*getitembound(<item id>, <amount>, <bound type>{, <account ID>}) -*getitembound("<item name>", <amount>, <bound type>{, <account ID>}) - -This command behaves identically to getitem(), but the items created will be -bound to the target character as specified by the bound type. All items created -in this manner cannot be dropped, sold, vended, auctioned, or mailed, and in -some cases cannot be traded or stored. - -Valid bound types are: - 1 - Account Bound - 2 - Guild Bound - 3 - Party Bound - 4 - Character Bound - ---------------------------------------- - -*getitembound2(<item id>, <amount>, <identify>, <refine>, <attribute>, <card1>, <card2>, <card3>, <card4>, <bound type>) -*getitembound2("<item name>", <amount>, <identify>, <refine>, <attribute>, <card1>, <card2>, <card3>, <card4>, <bound type>) - -This command behaves identically to getitem2(), but the items created will be -bound to the target character as specified by the bound type. All items created -in this manner cannot be dropped, sold, vended, auctioned, or mailed, and in -some cases cannot be traded or stored. - -For a list of bound types see getitembound(). - ---------------------------------------- - -*countbound({<bound type>}) - -This function will return the number of bounded items in the character's -inventory, and sets an array @bound_items[] containing all item IDs of the -counted items. If a bound type is specified, only those items will be counted. - -For a list of bound types see 'getitembound'. - -Example: - mes("You currently have "+countbound()+" bound items."); - next(); - mes("The list of bounded items include:"); - for (.@i = 0; .@i < getarraysize(@bound_items); ++.@i) - mes(getitemname(@bound_items[.@i])); - close(); - ---------------------------------------- - -*checkbound(<item_id>{, <bound_type>{, <refine>{, <attribute>{, <card_1>{, <card_2>{, <card_3>{, <card_4>}}}}}}}) - -This command allows you to check whether or not the attached player has the specified bound item in their inventory. -If a bound type is not specified or a bound type of 0 is used, it will search the player's inventory for a bound item -of any type, so long as the other parameters match. In all cases, this command will return the bound type of the -item found, or 0 if the specified item was not found. - -Valid bound types are: - 0 - All Bound types. - 1 - Account Bound - 2 - Guild Bound - 3 - Party Bound - 4 - Character Bound - -Optional Parameters: - bound_type - checks to see if the item has the specified bound type. - refine - checks to see if the item is refined to the given number. - attribute - whether the item is broken (1) or not (0). - card 1,2,3,4 - checks to see if the specified cards are compounded on the item as well. - -Example: - // This will check if you have a bound (any type) 1205 (Cutter). - if (checkbound(Cutter)) { - mes("You have a bound Cutter"); - } else { - mes("You do not have a bound Cutter"); - } - close(); - - // This will also check if you have a bound (any type) 1205 (Cutter). - if (checkbound(Cutter, 0)) { - mes("You have a bound Cutter"); - } else { - mes("You do not have a bound Cutter"); - } - close(); - - // This will check if the player doesn't have a bound 1205 (Cutter). - if (!checkbound(Cutter)) { - mes("You do not have a bound Cutter"); - } else { - mes("You do have a bound Cutter"); - } - close(); - - // This will check if the item found, has a bound type of 2 (guild_bound) - if (checkbound(Cutter) == 2) { - mes("You have a guild_bound Cutter"); - } else { - mes("You do not have a guild_bound Cutter."); - } - close(); - - // This will check if you have a 'guild_bound' +7 1205 (Cutter). - if (checkbound(Cutter, 2, 7)) { - mes("You have a +7 guild_bound Cutter."); - } else { - mes("You don't have the required item."); - } - close(); ---------------------------------------- - -*getnameditem(<item id>, "<character name>") -*getnameditem(<item id>, <character ID>) -*getnameditem("<item name>", "<character name>") -*getnameditem("<item name>", <character ID>) - -Create an item signed with the given character's name. - -The command returns true when the item is created successfully, or false -if it fails. Failure occurs when: -- There is no player attached. -- Item name or ID is not valid. -- The given character ID/name is offline. - -Example: - -//This will give the currently attached player a Aaron's Apple (if Aaron -//is online). - getnameditem(Apple, "Aaron"); - -//Self-explanatory (I hope). - if (getnameditem(Apple, "Aaron")) { - mes("You now have a Aaron's Apple!"); - } - ---------------------------------------- - -*rentitem(<item id>, <time>) -*rentitem("<item name>", <time>) - -Creates a rental item in the attached character's inventory. The item will -expire in <time> seconds and be automatically deleted. When receiving a -rental item, the character will receive a message in their chat window. -The character will also receive warning messages in their chat window -before the item disappears. - -This command can not be used to rent stackable items. Rental items cannot -be dropped, traded, sold to NPCs, or placed in guild storage (i.e. trade -mask 75). -Note: delitem() in an NPC script can still remove rental items. - ---------------------------------------- - -*makeitem(<item id>, <amount>, "<map name>", <X>, <Y>) -*makeitem("<item name>", <amount>, "<map name>", <X>, <Y>) - -This command will create an item lying around on a specified map in the -specified location. - - itemid - Found in 'db/(pre-)re/item_db.txt' - amount - Amount you want produced - map name - The map name - X - The X coordinate - Y - The Y coordinate. - -This item will still disappear just like any other dropped item. Like -getitem(), it also accepts an 'english name' field from the database and -creates apples if the name isn't found. -If the map name is given as "this", the map the invoking character is on -will be used. - ---------------------------------------- - -*makeitem2(<item id>,<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,{"<map name>",<X>,<Y>,<range>}) -*makeitem2("<item name>",<amount>,<identify>,<refine>,<attribute>,<card1>,<card2>,<card3>,<card4>,{"<map name>",<X>,<Y>,<range>}) - -This script command work like 'makeitem', but it has additional parameters -to expand the usage of the scritp command. - -Parameter List: - itemid - ID / Name of an item - amount - Amount you want produced (Value: 1~MAX_AMOUNT) - - if item type is Armor/Wepaon/PetEgg/PetArmor, amount will be limit to 1 - identify - Item to be identified (1) or not (0) - refine - Refine count of item. (Value: 0 ~ MAX_REFINE) - attribute - Item is broken (1) or not (0) - card1,2,3,4 - Card IDs that compound on each slot - -Optional Parameter List: - map name - Map name (Default to attached player map) - X,Y - The coordinate of item will be dropped - If value = 0, it's drop random across the map - If value = -1, its drop around player - range - Range of item drop around player. (Value: 1 ~ battle_config.area_size, Default: 3) - Default value will be used if no player are attached to the script. - ---------------------------------------- - -*cleanarea("<map name>",<x1>,<y1>,<x2>,<y2>) -*cleanmap("<map name>") - -These commands will clear all items lying on the ground on the specified -map, either within the x1/y1-x2/y2 rectangle or across the entire map. - ---------------------------------------- - -*searchitem(<array name>, "<item name>") - -This command will fill the given array with the ID of items whose name -matches the given one. It returns the number of items found. For -performance reasons, the results array is limited to 10 items. - - mes("What item are you looking for?"); - input(.@name$); - .@qty = searchitem(.@matches[0], .@name$); - mes("I found "+.@qty+" items:"); - for (.@i = 0; .@i < .@qty; ++.@i) - //Display name (eg: "Apple[0]") - mes(getitemname(.@matches[.@i])+"["+getitemslots(.@matches[.@i])+"]"); - ---------------------------------------- - -*delitem(<item id>, <amount>{, <account ID>}) -*delitem("<item name>", <amount>{, <account ID>}) - -This command will remove a specified amount of items from the invoking or -target character. Like all the item commands, it uses the item ID found -inside 'db/(pre-)re/item_db.txt'. - - delitem(Apple, 10); // The person will lose 10 apples - delitem(Old_Violet_Box, 1); // The person will lose 1 Old Violet Box - -It is always a good idea to check if the player actually has the items -before you delete them. If you try to delete more items that the player -has, the player will lose the ones he/she has and the script will be -terminated with an error. - -Like getitem() this command will also accept an 'english name' field from -the database. If the name is not found, nothing will be deleted. - ---------------------------------------- - -*delitem2(<item id>, <amount>, <identify>, <refine>, <attribute>, <card1>, <card2>, <card3>, <card4>{, <account ID>}) -*delitem2("<item name>", <amount>, <identify>, <refine>, <attribute>, <card1>, <card2>, <card3>, <card4>{, <account ID>}) - -This command will remove a specified amount of items from the invoking or -target character. -Check getitem2() to understand its expanded parameters. - ---------------------------------------- - -*countitem(<item id>) -*countitem("<item name>") - -This function will return the number of items for the specified item ID -that the invoking character has in the inventory. - - mes("[Item Checker]"); - mes("Hmmm, it seems you have "+countitem(Apple)+" apples"); - close; - -Like getitem(), this function will also accept an 'english name' from the -database as an argument. - ---------------------------------------- - -*countitem2(<item id>, <identify>, <refine>, <attribute>, <card1>, <card2>, <card3>, <card4>) -*countitem2("<item name>", <identify>, <refine>, <attribute>, <card1>, <card2>, <card3>, <card4>) - -Expanded version of countitem() function, used for created/carded/forged -items. - -This function will return the number of items for the specified item ID -and other parameters that the invoking character has in the inventory. -Check getitem2() to understand the arguments of the function. - ---------------------------------------- - -*countnameditem(<item id>, "<character name>") -*countnameditem(<item id>, <character ID>) -*countnameditem("<item name>", "<character name>") -*countnameditem("<item name>", <character ID>) - -This function will return the number of signed items for the specified item ID -that the invoking character has in their inventory. - - mes("[Item Checker]"); - if (countnameditem(Apple) > 0) { - mes("You have an apple with your name on it!"); - } else { - mes("You do not have an apple with your name on it."); - } - next(); - mes("[Item Checker]"); - mesf("You have %d apples with John's name on it!", countnameditem(Apple, "John")); - close(); - -Like getnameditem(), this function will also accept an 'english name' from the -database as an argument. - ---------------------------------------- - -*groupranditem(<item id>) - -Returns the item_id of a random item picked from the item container specified. There -are different item containers and they are specified in 'db/(pre-)re/item_group.conf'. - -Example: - getitem(groupranditem(Old_Blue_Box), 1); - ---------------------------------------- - -*getrandgroupitem(<item id>, <quantity>) - -Similar to the above example, this command allows players to obtain the specified -quantity of a random item from the container. The different containers -are specified in 'db/(pre-)re/item_group.conf'. - -Example: - getrandgroupitem(Old_Blue_Box, 1); - ---------------------------------------- - -*packageitem({item_id}) - -This command has only 1 param which is optional. If the package item_id is not provided, it -will try to use the item id from the item it is being used from (if called from an item script). -It runs a item package and grants the items accordingly to the attached player. - -Example: - -/* This example is an item script from the item db */ - { - Id: 12477 - AegisName: "Gift_Bundle" - Name: "Gift Bundle" - Type: 2 - Buy: 0 - Script: <" packageitem(); "> - }, - ---------------------------------------- - -*enable_items() -*disable_items() - -These commands enable/disable changing of equipments while an NPC is -running. When disable_items() is run, equipments cannot be changed -during scripts until enable_items() is called or the script has -terminated. To avoid possible exploits, when disable_items() is invoked, -it will only disable changing equips while running that script in -particular. Note that if a different script also calls disable_items(), -it will override the last call (so you may want to call this command at -the start of your script without assuming the effect is still in -effect). -If 'item_enabled_npc' option is set to true in 'conf/map/battle/items.conf' all -NPC are allowing changing of equipment by default except for those have been -set with 'disable_items'. - ---------------------------------------- - -*itemskill(<skill id>, <skill level>, {flag}) -*itemskill("<skill name>", <skill level>, {flag}) - -This command meant for item scripts to replicate single-use skills in -usable items. It will not work properly if there is a visible dialog -window or menu. -If the skill is self or auto-targeting, it will be used immediately. -Otherwise, a target cursor is shown. -Flag is a optional param and, when present, the command will not check for -skill requirements. - -// When Anodyne is used, it will cast Endure, Level 1, as if the actual skill -// has been used from skill tree. - itemskill(SM_ENDURE, 1); - ---------------------------------------- - -*itemeffect(<item id>) -*itemeffect("<item name>") -*consumeitem is an alias of itemeffect (added for compatibility) - -This command will run the item script of the specified item on the -invoking character. The character does not need to posess the item, and -the item will not be deleted. While this command is intended for usable -items, it will run for any item type. - ---------------------------------------- - -*produce(<item level>) - -This command will open a crafting window on the client connected to the -invoking character. The 'item level' is a number which determines what -kind of a crafting window will pop-up. - -You can see the full list of such item levels in 'db/produce_db.txt' which -determines what can actually be produced. The window will not be empty -only if the invoking character can actually produce the items of that type -and has the appropriate raw materials in their inventory. - -The success rate to produce the item is the same as the success rate of -the skill associated with the item level. If there is no skill id, the -success rate will be 50%. - -Valid item levels are: - - 1 - Level 1 Weapons - 2 - Level 2 Weapons - 3 - Level 3 Weapons - 21 - Blacksmith's Stones and Metals - 22 - Alchemist's Potions, Holy Water, Assassin Cross's Deadly Poison - 23 - Elemental Converters - ---------------------------------------- - -*cooking(<dish level>) - -This command will open a produce window on the client connected to the -invoking character. The 'dish level' is the number which determines what -kind of dish level you can produce. You can see the full list of dishes -that can be produced in 'db/produce_db.txt'. - -The window will be shown empty if the invoking character does not have -enough of the required incredients to cook a dish. - -Valid dish levels are: - -11 - Level 1 Dish -12 - Level 2 Dish -13 - Level 3 Dish -14 - Level 4 Dish -15 - Level 5 Dish -16 - Level 6 Dish -17 - Level 7 Dish -18 - Level 8 Dish -19 - Level 9 Dish -20 - Level 10 Dish - -Although it's required to set a dish level, it doesn't matter if you set -it to 1 and you want to cook a level 10 dish, as long as you got the -required ingredients to cook the dish the command works. - ---------------------------------------- - -*makerune(<% success bonus>) - -This command will open a rune crafting window on the client connected to -the invoking character. Since this command is officially used in rune -ores, a bonus success rate must be specified (which adds to the base -formula). - -You can see the full list of runes that can be produced in -'db/produce_db.txt'. The window will not be empty only if the invoking -character can actually produce a rune and has the appropriate raw -materials in their inventory. - ---------------------------------------- - -*successremovecards(<equipment slot>) - -This command will remove all cards from the item found in the specified -equipment slot of the invoking character, create new card items and give -them to the character. If any cards were removed in this manner, it will -also show a success effect. - ---------------------------------------- - -*failedremovecards(<equipment slot>, <type>) - -This command will remove all cards from the item found in the specified -equipment slot of the invoking character. 'type' determines what happens -to the item and the cards: - - 0 - will destroy both the item and the cards. - 1 - will keep the item, but destroy the cards. - 2 - will keep the cards, but destroy the item. - -Whatever the type is, it will also show a failure effect on screen. - ---------------------------------------- - -*repair(<broken item number>) - -This command repairs a broken piece of equipment, using the same list of -broken items as available through 'getbrokenid'. - -The official scripts seem to use the repair command as a function instead: -'repair(<number>)' but it returns nothing on the stack. Probably only -Valaris, who made it, can answer why is it so. - ---------------------------------------- - -*repairall() - -This command repairs all broken equipment in the attached player's -inventory. A repair effect will be shown if any items are repaired, else -the command will end silently. - ---------------------------------------- - -*successrefitem(<equipment slot>{, <upgrade_count>}) - -This command will refine an item in the specified equipment slot of the -invoking character by +1 (unless <upgrade_count> is specified). -For a list of equipment slots see 'getequipid'. -This command will also display a 'refine success' -effect on the character and put appropriate messages into their chat -window. It will also give the character fame points if a weapon reached -+10 this way, even though these will only take effect for blacksmith who -will later forge a weapon. - ---------------------------------------- - -*failedrefitem(<equipment slot>) - -This command will fail to refine an item in the specified equipment slot -of the invoking character. The item will be destroyed. This will also -display a 'refine failure' effect on the character and put appropriate -messages into their chat window. - ---------------------------------------- - -*downrefitem(<equipment slot>{, <downgrade_count>}) - -This command will downgrade an item by - 1 (unless optional <downgrade_count> is provided) -in the specified equipment slot of the invoking character. -So the item will not be destroyed unlike in the failedrefitem() script -command. This will also display a 'refine failure' effect on the -character and put appropriate messages into their chat window. - ---------------------------------------- - -*unequip(<equipment slot>) - -This command will unequip whatever is currently equipped in the invoking -character's specified equipment slot. For a full list of possible -equipment slots see 'getequipid'. - -If an item occupies several equipment slots, it will get unequipped from -all of them. - ---------------------------------------- - -*clearitem() - -This command will destroy all items the invoking character has in their -inventory (including equipped items). It will not affect anything else, -like storage or cart. - ---------------------------------------- - -*equip(<item id>) -*equip2(<item id>, <refine>, <attribute>, <card1>, <card2>, <card3>, <card4>) -*autoequip(<item id>, <option>) - -These commands are to equip a equipment on the attached character. -The equip function will equip the item ID given when the player has this -item in his/her inventory, while the autoequip function will equip the -given item ID when this is looted. The option parameter of the autoequip -is 1 or 0, 1 to turn it on, and 0 to turn it off. - -Examples: - -//This will equip a 1104 (falchion) on the character if this is in the -//inventory. - equip(Falchion); - -//This will equip a +10 1104 (falchion) on the character if this is in the -//inventory. - equip2(Falchion, 10, 0, 0, 0, 0, 0); - -//The invoked character will now automatically equip a falchion when it's -//looted. - autoequip(Falchion, 1); - -//The invoked character will no longer automatically equip a falchion. - autoequip(Falchion, 0); - ---------------------------------------- - -*buyingstore(<slots>) - -Invokes buying store preparation window like the skill 'Open Buying -Store', without the item requirement. Amount of slots is limited by the -server to a maximum of 5 slots by default. - -Example: - - // Gives the player opportunity to buy 4 different kinds of items. - buyingstore(4); - ---------------------------------------- - -*searchstores(<uses>, <effect>); - -Invokes the store search window, which allows to search for both vending -and buying stores. Parameter uses indicates, how many searches can be -started, before the window has to be reopened. Effect value affects what -happens when a result item is double-clicked and can be one of the -following: - - 0 = Shows the store's position on the mini-map and highlights the shop - sign with yellow color, when the store is on same map as the - invoking player. - 1 = Directly opens the shop, regardless of distance. - -Example: - - // Item Universal_Catalog_Gold (10 uses, effect: open shop) - searchstores(10, 1); - ---------------------------------------- - -*mergeitem(); - -mergeitem() opens the item merge window, -The Item merge window shows all stackable item(same ItemID) with different -serial, that can be merged into one stack. -Check sample: npc/other/item_merge.txt - ---------------------------------------- - -*delequip(<equipment slot>) - -This command will destroy whatever is currently equipped in the invoking -character's specified equipment slot. For a full list of possible equipment -slots see getequipid(). - -It is always a good idea to check if the player actually has the item you want -before you use this command. If you try to delete in a position that the player -has no gear, script will be terminated with an error. - ---------------------------------------- -//===================================== -4.1 - End of Player Item-Related Commands -//===================================== ---------------------------------------- - -*openstorage() - -This will open character's Kafra storage window on the client connected to -the invoking character. It can be used from any kind of NPC or item -script, not just limited to Kafra Staff. - -The storage window opens regardless of whether there are open NPC dialogs -or not, but it is preferred to close the dialog before displaying the -storage window, to avoid any disruption when both windows overlap. - - mes("I will now open your stash for you"); - close2(); - openstorage(); - end; - ---------------------------------------- - -*openmail() - -This will open a character's Mail window on the client connected to the -invoking character. - - mes("Close this window to open your mail inbox."); - close2(); - openmail(); - end; - ---------------------------------------- - -*openauction() - -This will open the Auction window on the client connected to the invoking -character. - - mes("Close this window to open the Auction window."); - close2(); - openauction(); - end; - ---------------------------------------- - -*dressroom({<mode>}) - -This command controls the dressing room for the attached player. If no <mode> -is passed, DRESSROOM_OPEN is used by default. - -Valid <mode> for dressroom() are: - DRESSROOM_OPEN opens the dressing room window - DRESSROOM_CLOSE closes the dressing room window - -Example: - mes("Close this window to open the Dress Room window."); - close2(); - dressroom(DRESSROOM_OPEN); - end; - ---------------------------------------- -//===================================== -4.2 - Guild-Related Commands -//===================================== ---------------------------------------- - -*guildopenstorage() - -This function works the same as openstorage() but will open a guild -storage window instead for the guild storage of the guild the invoking -character belongs to. This is a function because it returns a value - 0 if -the guild storage was opened successfully and 1 if it wasn't. (Notice, -it's a ZERO upon success.) -Since guild storage is only accessible to one character at one time, it -may fail if another character is accessing the guild storage at the same -time. - -This will also fail and return 2 if the attached character does not belong -to any guild. - ---------------------------------------- - -*guildchangegm(<guild id>, <new master's name>) - -This function will change the Guild Master of a guild. The ID is the -guild's id, and the new guild master's name must be passed. - -Returns true on success, false otherwise. - ---------------------------------------- - -*guildgetexp(<amount>) - -This will give the specified amount of guild experience points to the -guild the invoking character belongs to. It will silently fail if they do -not belong to any guild. - ---------------------------------------- - -*guildskill(<skill id>, <level>) -*guildskill("<skill name>", <level>) - -This command will bump up the specified guild skill by the specified -number of levels. This refers to the invoking character and will only work -if the invoking character is a member of a guild AND it's guild master, -otherwise no failure message will be given and no error will occur, but -nothing will happen. The full list of guild skills is available in -'db/(pre-)re/skill_db.txt', these are all the GD_ skills at the end. -If a level higher than the maximum is given as parameter the skill will be -leveled to the maximum and not above. - -// This would give your character's guild one level of Approval -// (GD_APPROVAL ID 10000). Notice that if you try to add two levels of -// Approval, or add Approval when the guild already has it, it will only -// have one level of Approval afterwards. - guildskill(GD_APPROVAL, 1); - -You might want to make a quest for getting a certain guild skill, make it -hard enough that all the guild needs to help or something. Doing this for -the Glory of the Guild skill, which allows your guild to use an emblem, is -a good idea for a fun quest. (Wasting a level point on that is really -annoying :D) - ---------------------------------------- -//===================================== -4.2 - End of Guild-Related Commands -//===================================== ---------------------------------------- - -*resetlvl(<action type>) - -This is a character reset command, meant mostly for rebirth script -supporting Advanced jobs, which will reset the invoking character's stats -and level depending on the action type given. Valid action types are: - - 1 - Base level 1, Job level 1, 0 skill points, 0 base exp, 0 job exp, - wipes the status effects (only the ones settable by 'setoption'), - sets all stats to 1. If the new job is 'Novice High', give 100 status - points, give First Aid and Play Dead skills. - 2 - Base level 1, Job level 1, 0 skill points, 0 base exp, 0 job exp. - Skills and attribute values are not altered. - 3 - Base level 1, base exp 0. Nothing else is changed. - 4 - Job level 1, job exp 0. Nothing else is changed. - -In all cases everything the character has on will be unequipped. - ---------------------------------------- - -*resetstatus() - -This is a character reset command, which will reset the stats on the -invoking character and give back all the stat points used to raise them -previously. Nothing will happen to any other numbers about the character. - -Used in reset NPC's (duh!). - ---------------------------------------- - -*resetskill() - -This command takes off all the skill points on the invoking character, so -they only have Basic Skill blanked out (lvl 0) left, and returns the -points for them to spend again. Nothing else will change but the skills. -Quest skills will also reset if 'quest_skill_reset' option is set to true in -'conf/map/battle.conf'. If the 'quest_skill_learn' option is set in there, the -points in the quest skills will also count towards the total. - -Used in reset NPC's (duh!). - ---------------------------------------- - -*sc_start(<effect type>, <ticks>, <value 1>{, <rate>, <flag>{, <GID>}}) -*sc_start2(<effect type>, <ticks>, <value 1>, <value 2>{, <rate>, <flag>{, <GID>}}) -*sc_start4(<effect type>, <ticks>, <value 1>, <value 2>, <value 3>, <value 4>{, <rate>, <flag>{, <GID>}}) -*sc_end(<effect type>{, <GID>}) - -These commands will bestow a status effect on a character. - -The <effect type> determines which status is invoked. This can be either a number -or constant, with the common statuses (mostly negative) found in -'doc/constants.md' under 'Status Changes'. A full list is located in -'src/map/status.h', though they are not currently documented. - -The duration of the status is given in <ticks>, or milleseconds. - -Certain status changes take an additional parameter <value 1>, which typically -modifies player stats by the given number or percentage. This differs for each -status, and is sometimes zero. - -Optional value <rate> is the chance that the status will be invoked (10000 = 1%). -This is used primarily in item scripts. When used in an NPC script, a flag MUST -be defined for the rate to work. - -Optional value <flag> is how the status change start will be handled (a bitmask). - SCFLAG_NONE = 0x00: No special behavior. - SCFLAG_NOAVOID = 0x01: Status change cannot be avoided. - SCFLAG_FIXEDTICK = 0x02: Tick cannot be reduced by stats (default). - SCFLAG_LOADED = 0x04: sc_data was loaded, no value will be altered. - SCFLAG_FIXEDRATE = 0x08: Rate cannot be reduced. - SCFLAG_NOICON = 0x10: Status icon (SI) won't be shown. - -If a <GID> is given, the status change will be invoked on the specified character -instead of the one attached to the script. This can only be defined after setting -a rate and flag. - -sc_start2() and sc_start4() allow extra parameters to be passed, and are used only -for effects that require them. The meaning of the extra values vary depending on the -effect type. - -sc_end() will remove a specified status effect. If SC_ALL (-1) is given, it will -perform a complete removal of all statuses (although permanent ones will re-apply). - -Examples: - // This will poison the invoking character for 10 minutes at 50% chance. - sc_start(SC_POISON, 600000, 0, 5000); - - // This will bestow the effect of Level 10 Blessing. - sc_start(SC_BLESSING, 240000, 10); - - // This will end the Freezing status for the invoking character. - sc_end(SC_FREEZE); - -Note: to use SC_NOCHAT you should alter Manner - Manner = -5; // Will mute a user for 5 minutes - Manner = 0; // Will unmute a user - Manner = 5; // Will unmute a user and prevent the next use of 'Manner' - ---------------------------------------- - -*getstatus(<effect type>{, <type>}) - -Retrieve information about a specific status effect when called. Depending -on <type> specified the function will return different information. - -Possible <type> values: - - 0 or undefined: whether the status is active - - 1: the val1 of the status - - 2: the val2 of the status - - 3: the val3 of the status - - 4: the val4 of the status - - 5: the amount of time in milliseconds that the status has remaining - -If <type> is not defined or is set to 0, then the script function will -either return 1 if the status is active, or 0 if the status is not active. -If the status is not active when any of the <type> fields are provided, -this script function will always return 0. - ---------------------------------------- - -*skilleffect(<skill id>, <number>) -*skilleffect("<skill name>", <number>) - -This command displays visual and aural effects of given skill on currently -attached character. The number parameter is for skill whose visual effect -involves displaying of a number (healing or damaging). Note that this -command will not actually use the skill: it is intended for scripts which -simulate skill usage by the NPC, such as buffs, by setting appropriate -status and displaying the skill's effect. - - mes("Be blessed!"); - // Heal of 2000 HP - heal(2000, 0); - skilleffect(AL_HEAL, 2000); - // Blessing Level 10 - sc_start(SC_BLESSING, 240000, 10); - skilleffect(AL_BLESSING, 0); - // Increase AGI Level 5 - sc_start(SC_INC_AGI, 140000, 5); - skilleffect(AL_INCAGI, 0); - -This will heal the character with 2000 HP, buff it with Blessing Lv 10 and -Increase AGI Lv 5, and display appropriate effects. - ---------------------------------------- - -*npcskilleffect(<skill id>, <number>, <x>, <y>) -*npcskilleffect("<skill name>", <number>, <x>, <y>) - -This command behaves identically to skilleffect(), however, the effect -will not be centered on the invoking character's sprite, nor on the NPC -sprite, if any, but will be centered at map coordinates given on the same -map as the invoking character. - ---------------------------------------- - -*specialeffect(<effect number>{, <send_target>{, <unit id>{, <account id>}}}) -*specialeffect(<effect number>{, <send_target>{, "<NPC Name>"{, <account id>}}}) - -This command will display special effect with the given number, centered -on the specified NPCs coordinates, if any. For a full list of special -effect numbers known see 'doc/effect_list.txt'. Some effect numbers are -known not to work in some client releases. (Notably, rain is absent from -any client executables released after April 2005.) - -<NPC name> parameter will display <effect number> on another NPC. If the -NPC specified does not exist, the command will do nothing. When specifying -an NPC, <send_target> must be specified when specifying an <NPC Name>, -specifying AREA will retain the default behavior of the command. - -<unit id> behaves like <NPC Name> except it can display the effect on -any kind of unit, not just NPC, by specifying its GID. - -When <send_target> is SELF you can specify which player to send the effect -to by passing <account id>. - -Example usage: - - // To make a NPC do an effect and show it to everyone: - specialeffect(EF_HIT1, AREA, "John Doe#1"); - - // To make a player do an effect and show it to everyone: - specialeffect(EF_HIT1, AREA, getcharid(CHAR_ID_ACCOUNT, "player")); - - // To make a NPC do an effect and show it only to the attached player: - specialeffect(EF_HIT1, SELF, "John Doe#1"); - - // To make a NPC do an effect and show it only to another player: - specialeffect(EF_HIT1, SELF, "John Doe#1", getcharid(CHAR_ID_ACCOUNT, "player")); - ---------------------------------------- - -*removespecialeffect(<effect number>{, <send_target>{, <unit id>{, <account id>}}}) -*removespecialeffect(<effect number>{, <send_target>{, "<NPC Name>"{, <account id>}}}) - -Works for: - main client from version 2018-10-02 - re client from version 2018-10-02 -This command will remove special effect. All parameters same with specialeffect. -Examples and detailed explanation about parameters see in specialeffect. - ---------------------------------------- - -*specialeffect2(<effect number>{, <send_target>{, "<Player Name>"}}) - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ /!\ This command is deprecated @ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -This command behaves identically to the specialeffect(), but the effect -will be centered on the invoking character's sprite. - -This command is deprecated and it should not be used in new scripts, as it is -likely to be removed at a later time. Please use specialeffect instead, -ie: specialeffect(<effect number>, <send_target>, playerattached()) - ---------------------------------------- - -*statusup(<stat>) - -This command will bump a specified stat of the invoking character up by -one permanently using status points to do so, if there aren't enough to perform -the change nothing will happen. -Stats are to be given as number, but you can use these constants to replace them: - -bStr - Strength -bVit - Vitality -bInt - Intelligence -bAgi - Agility -bDex - Dexterity -bLuk - Luck - ---------------------------------------- - -*statusup2(<stat>, <amount>) - -This command will bump a specified stat of the invoking character up by -the specified amount permanently without using status points. -Amount can be negative. See statusup(). - -// This will decrease a character's Vit forever. - statusup(bVit, -1); - ---------------------------------------- - -*needed_status_point(<type>, <val>); - -Returns the number of stat points needed to change the specified stat <type> by <val>. -If <val> is negative, returns the number of stat points that would be needed to -raise the specified stat from (current value - <val>) to current value. - -List of <type>: -bStr - Strength -bVit - Vitality -bInt - Intelligence -bAgi - Agility -bDex - Dexterity -bLuk - Luck - ---------------------------------------- - -*bonus(<bonus type>, <val1>) -*bonus2(<bonus type>, <val1>, <val2>) -*bonus3(<bonus type>, <val1>, <val2>, <val3>) -*bonus4(<bonus type>, <val1>, <val2>, <val3>, <val4>) -*bonus5(<bonus type>, <val1>, <val2>, <val3>, <val4>, <val5>) - -These commands are meant to be used in item scripts. They will probably -work outside item scripts, but the bonus will not persist for long. They, -as expected, refer only to an invoking character. - -You can find the full list of possible bonuses and which command to use -for each kind in 'doc/item_bonus.txt'. - ---------------------------------------- - -*autobonus(<bonus script>, <rate>, <duration>{, <flag>, {<other script>}}) -*autobonus2(<bonus script>, <rate>, <duration>{, <flag>, {<other script>}}) -*autobonus3(<bonus script>, <rate>, <duration>, <skill id>, {<other script>}) -*autobonus3(<bonus script>, <rate>, <duration>, "<skill name>", {<other script>}) - -These commands are meant to be used in item scripts. They will probably -work outside item scripts, but the bonus will not persist for long. They, -as expected, refer only to an invoking character. - -What these commands do is 'attach' a script to the player which will get -executed on attack (or when attacked in the case of autobonus2()). - -Rate is the trigger rate of the script (1000 = 100%). - -Duration is the time that the bonus will last for since the script has -triggered. - -Skill ID/skill name the skill which will be used as trigger to start the -bonus (for autobonus3()). - -The optional argument 'flag' is used to classify the type of attack where -the script can trigger (it shares the same flags as the bAutoSpell bonus -script): - -Range criteria: - BF_SHORT: Trigger on melee attack - BF_LONG: Trigger on ranged attack - Default: BF_SHORT+BF_LONG -Attack type criteria: - BF_WEAPON: Trigger on weapon skills - BF_MAGIC: Trigger on magic skills - BF_MISC: Trigger on misc skills - Default: BF_WEAPON -Skill criteria: - BF_NORMAL: Trigger on normal attacks - BF_SKILL: Trigger on skills - default: If the attack type is BF_WEAPON (only) BF_NORMAL is used, - otherwise BF_SKILL+BF_NORMAL is used. - -The difference between the optional argument 'other script' and the 'bonus -script' is that, the former one triggers only when attacking (or attacked) -and the latter one runs on status calculation as well, which makes sure, -within the duration, the "bonus" that get lost on status calculation is -restored. So, 'bonus script' is technically supposed to accept "bonus" -command only. And we usually use 'other script' to show visual effects. - -In all cases, when the script triggers, the attached player will be the -one who holds the bonus. There is currently no way of knowing within this -script who was the other character (the attacker in autobonus2(), or the -target in autobonus() and autobonus3()). - -//Grants a 1% chance of starting the state "all stats +10" for 10 seconds -//when using weapon or misc attacks (both melee and ranged skills) and -//shows a special effect when the bonus is active. - autobonus("{ bonus(bAllStats, 10); }", 10, 10000, BF_WEAPON|BF_MISC, "{ specialeffect(EF_FIRESPLASHHIT, AREA, playerattached()); }"); - ---------------------------------------- - -*skill(<skill id>, <level>{, <flag>}) -*skill("<skill name>", <level>{, <flag>}) -*addtoskill(<skill id>, <level>{, <flag>}) -*addtoskill("<skill name>", <level>{, <flag>}) - -These commands will give the invoking character a specified skill. This is -also used for item scripts. - -Level is obvious. Skill id is the ID number of the skill in question as -per 'db/(pre-)re/skill_db.txt'. It is not known for certain whether this -can be used to give a character a monster's skill, but you're welcome to -try with the numbers given in 'db/(pre-)re/mob_skill_db.txt'. - -Flag is 0 if the skill is given permanently (will get written with the -character data) or 1 if it is temporary (will be lost eventually, this is -meant for card item scripts usage.). The flag parameter is optional, and -defaults to 1 in 'skill' and to 2 in 'addtoskill'. - -Flag 2 means that the level parameter is to be interpreted as a stackable -additional bonus to the skill level. If the character did not have that -skill previously, they will now at 0+the level given. - -// This will permanently give the character Stone Throw -// (TF_THROWSTONE, 152), at level 1. - skill(TF_THROWSTONE, 1, 0); - -Flag 3 is the same as flag 0 in that it saves to the database. However, -these skills are ignored when any action is taken that adjusts the skill -tree (reset/job change). - ---------------------------------------- - -*nude() - -This command will unequip anything equipped on the invoking character. - -It is not required to do this when changing jobs since jobchange() will -unequip everything not equippable by the new job class anyway. - ---------------------------------------- - -*disguise(<Monster ID>) -*undisguise() - -This command disguises the current player with a monster sprite. -The disguise lasts until undisguise() is issued or the player logs out. - -Example: - -disguise(PORING); // Disguise character as a Poring. -next(); -undisguise(); // Return to normal character sprite. - ---------------------------------------- -//===================================== -4.3 - Marriage-Related Commands -//===================================== ---------------------------------------- - -*marriage("<spouse name>") - -This function will marry two characters, the invoking character and the -one referred to by name given, together, setting them up as each other's -marriage partner. No second function call has to be issued (in current Git -at least) to make sure the marriage works both ways. The function returns -true upon success, or false if the marriage could not be completed, either -because the other character wasn't found or because one of the two -characters is already married. - -This will do nothing else for the marriage except setting up the spouse ID -for both of these characters. No rings will be given and no effects will -be shown. - ---------------------------------------- - -*wedding() - -This command will call up wedding effects - the music and confetti - -centered on the invoking character. Example can be found in the wedding -script. - ---------------------------------------- - -*divorce() - -This function will "un-marry" the invoking character from whoever they -were married to. Both will no longer be each other's marriage partner, -(at least in current Git, which prevents the cases of multi-spouse -problems). It will return true upon success or false if the character -was not married at all. - -This function will also destroy both wedding rings and send a message to -both players, telling them they are now divorced. - ---------------------------------------- -//===================================== -4.3 - End of Marriage-Related Commands -//===================================== ---------------------------------------- - -*pcfollow(<id>, <target id>) -*pcstopfollow(<id>) - -Makes a character follow or stop following someone. This command does the -same as the @follow command. The main difference is that @follow can use -character names, and this commands needs the Account ID for the target. - -Examples: - -// This will make Aaron follow Bullah, when both of these characters are -// online. - pcfollow(getcharid(CHAR_ID_ACCOUNT, "Aaron"), getcharid(CHAR_ID_ACCOUNT, "Bullah")); - -// Makes Aaron stop following whoever he is following. - pcstopfollow(getcharid(CHAR_ID_ACCOUNT, "Aaron")); - ---------------------------------------- - -*pcblockmove(<account id>, <option>) - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ /!\ This command is deprecated @ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -Prevents the player from moving when the option != 0, and 0 enables the -player to move again. The player has to be the account ID of a character, -and will run for the attached player if zero is supplied. - -Examples: - -// Prevents the current char from moving away. - pcblockmove(getcharid(CHAR_ID_ACCOUNT), true); - -// Enables the current char to move again. - pcblockmove(getcharid(CHAR_ID_ACCOUNT), false); - ---------------------------------------- - -*setpcblock(<type>,<option>) -*checkpcblock() - -Prevents the player from doing the following action. - -For setpcblock, when the <option> is true(1) will block them, and false(0) -will allow those actions again. - -The checkpcblock command returned value is a bit mask of the currently -enabled block flags (or PCBLOCK_NONE when none is set). - -The <type> listed are a bit mask of the following: - PCBLOCK_NONE (only used by checkpcblock) - PCBLOCK_MOVE - PCBLOCK_ATTACK - PCBLOCK_SKILL - PCBLOCK_USEITEM - PCBLOCK_CHAT - PCBLOCK_IMMUNE - PCBLOCK_SITSTAND - PCBLOCK_COMMANDS - -Examples: - -// Make the current attached player invulnerable, same as @monsterignore - setpcblock(PCBLOCK_IMMUNE, true); - -// Prevents the current char from attacking or using skills - setpcblock(PCBLOCK_ATTACK|PCBLOCK_SKILL, true); - -// Re-enables attack, skills and item use - setpcblock(PCBLOCK_ATTACK|PCBLOCK_SKILL|PCBLOCK_USEITEM, false); - -// checkpcblock related checks - if ((checkpcblock() & PCBLOCK_IMMUNE) != 0) - mes "You are invulnerable!"; - - if ((checkpcblock() & (PCBLOCK_MOVE|PCBLOCK_SITSTAND)) == (PCBLOCK_MOVE|PCBLOCK_SITSTAND)) - mes "You can't walk or sit"; - - if ((checkpcblock() & (PCBLOCK_ATTACK|PCBLOCK_SKILL)) == PCBLOCK_NONE) - mes "You can attack and use skills"; - - if ((checkpcblock() & PCBLOCK_CHAT) == PCBLOCK_NONE) - mes "You can't chat"; - ---------------------------------------- -//===================================== -4 - End of Player-Related Commands -//===================================== ---------------------------------------- - ---------------------------------------- -//===================================== -5 - Mob / NPC Related Commands -//===================================== ---------------------------------------- - -*monster("<map name>", <x>, <y>, "<name to show>", <mob id>, <amount>{, "<event label>"{, <size>{, <ai>}}}) -*areamonster("<map name>", <x1>, <y1>, <x2>, <y2>, "<name to show>", <mob id>, <amount>{, "<event label>"{, <size>{, <ai>}}}) - -This command will spawn a monster on the specified coordinates on the -specified map. If the script is invoked by a character, a special map -name, "this", will be recognized to mean the name of the map the invoking -character is located at. This command works fine in the item scripts. - -The same command arguments mean the same things as described above in the -beginning of this document when talking about permanent monster spawns. -Monsters spawned in this manner will not respawn upon being killed. - -Unlike the permanent monster spawns, if the mob id is -1, a random monster -will be picked from the entire database according to the rules configured -in the server for dead branches. This will work for all other kinds of -non-permanent monster spawns. - -The only very special thing about this command is an event label, which is -an optional parameter. This label is written like -'<NPC object name>::<label name>' and upon the monster being killed, it -will execute the script inside of the specified NPC object starting from -the label given. The RID of the player attached at this execution will be -the RID of the killing character. - -<size> can be: - Size_Medium = medium (default) - Size_Small = small - Size_Large = big - -<ai> can be: - 0 = none (default) - 1 = attack/friendly - 2 = sphere (Alchemist skill) - 3 = flora (Alchemist skill) - 4 = zanzou (Kagerou/Oboro skill) - - monster("place", 60, 100, "Poring", PORING, 1, "NPCNAME::OnLabel"); - -The coordinates of 0,0 will spawn the monster on a random place on the -map. Both 'monster' and 'areamonster' return the GID of the monster -spawned if there was ONLY ONE monster to be spawned. This is useful for -controlling each of the spawned mobs with the unit* commands shown below. -For example: - - // We'll make a poring which will automatically attack invoking player: - .@mobGID = monster("prontera", 150, 150, "Poring", PORING, 1); // PORING is defined in the mob db and its value is 1002 - unitattack(.@mobGID, getcharid(CHAR_ID_ACCOUNT)); // Attacker GID, attacked GID - -The way you can get the GID of more than only one monster is looping -through all the summons to get their individual GIDs and do whatever you -want with them. For example: - - // We want to summon .mobnumber porings which will give us a kiss - for (.@i = 0; .@i < .mobnumber; ++.@i) { - .@mobGID = monster("map", .x, .y, "Kisser Poring", PORING, 1); - unitemote(.@mobGID, e_kis); - } - -Refer to the unit* commands below. - -The areamonster() command works much like the monster() command and is not -significantly different, but spawns the monsters within a square defined -by x1/y1-x2/y2. - -Simple monster killing script: - - <NPC object definition. Let's assume you called him NPCNAME.> - mes("[Summon Man]"); - mes("Want to start the kill?"); - next(); - if (select("Yes", "No") != 1) { - mes("[Summon Man]"); - mes("Come back later"); - close(); - } - monster("prontera", 0, 0, "Quest Poring", PORING, 10, "NPCNAME::OnPoringKilled"); - // By using 0,0 it will spawn them in a random place. - mes("[Summon Man]"); - mes("Now go and kill all the Poring I summoned"); - // He summoned ten. - close(); - OnPoringKilled: - ++$poring_killed; - if ($poring_killed == 10) { - announce("Summon Man: Well done all the poring are dead", bc_self); - $poring_killed = 0; - } - end; - -For more examples see just about any official 2-1 or 2-2 job quest script. - ---------------------------------------- - -*areamobuseskill("<map name>", <x>, <y>, <range>, <mob id>, <skill id>, <skill level>, <cast time>, <cancelable>, <emotion>, <target type>) -*areamobuseskill("<map name>", <x>, <y>, <range>, <mob id>, "<skill name>", <skill level>, <cast time>, <cancelable>, <emotion>, <target type>) - -This command will make all monsters of the specified mob ID in the -specified area use the specified skill. Map name, x, and y define the -center of the area, which extending <range> cells in each direction (ex: a -range of 3 would create a 7x7 square). The skill can be specified by skill -ID or name. <cast time> is in milliseconds (1000 = 1 second), and the rest -should be self-explanatory. - -<target type> can be: - 0 = self - 1 = the mob's current target - 2 = the mob's master - 3 = random target - -Example: - - // spawn 1 Shining Plant in the 5x5 area centered on (155,188) - areamonster("prontera", 153, 186, 157, 190, "Shining Plant", SHINING_PLANT, 1); - // make the plant cast level 10 Cold Bolt on a random target - areamobuseskill("prontera", 155, 188, 2, SHINING_PLANT, MG_COLDBOLT, 10, 3000, 1, e_gg, 3) - ---------------------------------------- - -*killmonster("<map name>", "<event label>"{, <type>}) - -This command will kill all monsters that were spawned with monster() or -areamonster() and have a specified event label attached to them. Commonly -used to get rid of remaining quest monsters once the quest is complete. - -If the label is given as "All", all monsters which have their respawn -times set to -1 (like all the monsters summoned with 'monster' or -'areamonster' script command, and all monsters summoned with GM commands, -but no other ones - that is, all non-permanent monsters) on the specified -map will be killed regardless of the event label value. - -killmonster() supports an optional argument type. Using 1 for type will make -the command fire "OnMyMobDead" events from any monsters that do die as a -result of this command. - ---------------------------------------- - -*killmonsterall("<map name>"{, <type>}) - -This command will kill all monsters on a specified map name, regardless of -how they were spawned or what they are without triggering any event label -attached to them, unless you specify 1 for type parameter. In this case, -mob death labels will be allowed totrigger when there is no player. Any -other number for this parameter won't be recognized. - ---------------------------------------- - -*killmonstergid(<GID>); - -This command will kill the specific monster GID. The difference between -this command and 'unitkill', is this command does not trigger monster's -event label. - ---------------------------------------- - -*strmobinfo(<type>, <monster id>) - -This function will return information about a monster record in the -database, as per 'db/(pre-)re/mob_db.txt'. Type is the kind of information -returned. Valid types are: - - 1 - 'english name' field in the database, a string. - 2 - 'japanese name' field in the database, a string. - All other returned values are numbers: - 3 - Level. - 4 - Maximum HP. - 5 - Maximum SP. - 6 - Experience reward. - 7 - Job experience reward. - ---------------------------------------- - -*mobcount("<map name>", "<event label>") - -This function will count all the monsters on the specified map that have a -given event label and return the number or 0 if it can't find any. -Naturally, only monsters spawned with 'monster' and 'areamonster' script -commands can have non-empty event label. -If you pass this function an empty string for the event label, it will -return the total count of monster without event label, including -permanently spawning monsters. - -With the dynamic mobs system enabled, where mobs are not kept in memory -for maps with no actual people playing on them, this will return a 0 for -any such map. - -If the event label is given as "all", all monsters will be counted, -regardless of having any event label attached. - -If the map name is given as "this", the map the invoking character is on -will be used. If the map is not found, or the invoker is not a character -while the map is "this", it will return -1. - ---------------------------------------- - -*clone("<map name>", <x>, <y>, "<event>", <char id>{, <master_id>{, <mode>{, <flag>, <duration>}}}) - -This command creates a monster which is a copy of another player. The -first four arguments serve the same purpose as in the monster script -command, The <char id> is the character id of the player to clone (player -must be online). -If <master id> is given, the clone will be a 'slave/minion' of it. -Master_id must be a character id of another online player. - -The mode can be specified to determine the behavior of the clone, its -values are the same as the ones used for the mode field in the mob_db. The -default mode is aggressive, assists, can move, can attack. - -Flag can be either zero or one currently. If zero, the clone is a normal -monster that'll target players, if one, it is considered a summoned -monster, and as such, it'll target other monsters. Defaults to zero. - -The duration specifies how long the clone will live before it is -auto-removed. Specified in seconds, defaults to no limit (zero). - -Returned value is the monster ID of the spawned clone. If command fails, -returned value is zero. - ---------------------------------------- - -*summon("Monster name", <monster id>{, <Time Out>{, "event label"}}) - -This command will summon a monster. (see also monster()) Unlike monsters -spawned with other commands, this one will set up the monster to fight to -protect the invoking character. Monster name and mob id obey the same -rules as the one given at the beginning of this document for permanent -monster spawns with the exceptions mentioned when describing 'monster' -command. - -The effect for the skill 'Call Homunculus' will be displayed centered on -the invoking character. - -Timeout is the time in milliseconds the summon lives, and is set default -to 60000 (1 minute). Note that also the value 0 will set the timer to -default, and it is not possible to create a spawn that lasts forever. -If an event label is given, upon the monster being killed, the event label -will run as if by donpcevent(). - -// Will summon a poring to fight for the character. - summon("--ja--", PORING); - ---------------------------------------- - -*mobattached() - -This command will return RID of the monster running from 'OnTouchNPC:' label. - - -// Kill any monster entering npc's trigger area -OnTouchNPC: - killmonstergid mobattached(); - ---------------------------------------- - -*homevolution() - -This command will try to evolve the current player's homunculus. -If it doesn't work, the /swt emotion is shown. - -To evolve a homunculus, the invoking player must have a homunculus, the -homunculus must not be the last evolution and the homunculus must have -above 91000 intimacy with its owner. - ---------------------------------------- - -*gethominfo(<type>) - -This function works as a direct counterpart of 'getpetinfo': - 0 - Homunculus unique ID - 1 - Homunculus Class - 2 - Name - 3 - Friendly level (intimacy score). 100000 is full loyalty. - 4 - Hungry level. 100 is completely full. - 5 - Rename flag. 0 means this homunculus has not been named yet. - 6 - Homunculus level - -If the attached player doesn't own a homunculus, this command will return -"null" for type 2, and return 0 for other types. - ---------------------------------------- - -*morphembryo() - -This command will try to put the invoking player's Homunculus in an -uncallable state, required for mutation into a Homunculus S. The player -will also receive a Strange Embryo (ID 6415) in their inventory if -successful, which is deleted upon mutation. - -The command will fail if the invoking player does not have an evolved -Homunculus at level 99 or above. The /swt emotion is shown upon failure. - -Returns 1 upon success and 0 for all failures. - ---------------------------------------- - -*hommutate({<ID>}) - -This command will try to mutate the invoking player's Homunculus into a -Homunculus S. The Strange Embryo (Strange_Embryo, ID 6415) is deleted -upon success. - -The command will fail if the invoking player does not have an evolved -Homunculus at level 99 or above, if it is not in the embryo state -(from the morphembryo() command), or if the invoking player does not -possess a Strange Embryo. The /swt emotion is shown upon failure. - -If the optional parameter <ID> is set, the invoking player's Homunculus -will change into the specified Homunculus ID. Otherwise, a random Homunculus S -will be chosen. See 'db/homunculus_db.txt' for a full list of IDs. - -Returns true upon success and false for all failures. - ---------------------------------------- - -*checkhomcall() - -This function checks if the attached player's Homunculus is active, -and will return the following values: - -1: The player has no Homunculus. - 0: The player's Homunculus is active. - 1: The player's Homunculus is vaporized. - 2: The player's Homunculus is in morph state. - ---------------------------------------- - -*getunittype(<GID>) - -Returns the type of object from the given Game ID. Returns -1 if the given GID -does not exist. The return values are :- - - UNITTYPE_PC 0 - UNITTYPE_NPC 1 - UNITTYPE_PET 2 - UNITTYPE_MOB 3 - UNITTYPE_HOM 4 - UNITTYPE_MER 5 - UNITTYPE_ELEM 6 - ---------------------------------------- - -*unitwalk(<GID>, <x>, <y>) -*unitwalk(<GID>, <target_GID>) - -This is one command, but can be used in two ways. If only the first -argument is given, the unit whose GID is given will start walking towards -the target whose GID is given. - -When 2 arguments are passed, the given unit will walk to the given x,y -coordinates on the map where the unit currently is. - -Examples: - -//Will move/walk the poring we made to the coordinates 150,150 - unitwalk(.GID, 150, 150); - -//NPC will move towards the attached player. - unitwalk(.GID, getcharid(CHAR_ID_ACCOUNT));//a player's GID is their account ID - ---------------------------------------- - -*unitkill(<GID>) -*unitwarp(<GID>, <Mapname>, <x>, <y>) -*unitattack(<GID>, <Target ID>) -*unitstop(<GID>) -*unittalk(<GID>, <Text>{, show_name{, <send_target>{, <target_id>}}}) -*unitemote(<GID>, <Emote>) - -Okay, these commands should be fairly self explaining. -For the emotions, you can look in 'doc/constants.md' under 'Emotes' -PS: unitwarp() supports a <GID> of zero, which causes the executor of the -PS: unittalk() can receive 3 extra parameters: - show_name: - true: Shows Unit name like "UnitName : Message" (default) - false: Hides Unit name - send_target: - AREA_CHAT_WOC: sends the message to everyone in view range including the attached unit (default) - SELF: sends the message to the given unit gid only - target_id: - if send_target is set to SELF, the message will be shown by the given gid, - target_id allows changing the unit that will see the message. -script to be affected. This can be used with OnTouchNPC to warp -monsters: - -OnTouchNPC: - unitwarp(0, "this", -1, -1); - - // hide the npc name from the text - unittalk(getnpcid(0), "foobar", false); - - // display by npc to everyone - unittalk(getnpcid(0), "foobar", true); - - // display by npc to npc - unittalk(getnpcid(0), "foobar", true, SELF); - - // display the text by the npc to the attached player only - unittalk(getnpcid(0), "foobar", true, SELF, playerattached()); - - // display by player to everyone - unittalk(playerattached(), "foobar", true); - - // display by player to himself only - unittalk(playerattached(), "foobar", true, SELF); - - // display the text by the 1st player to the attached player only - unittalk(getcharid(CHAR_ID_ACCOUNT, "Name"), "foobar", true, SELF, playerattached()); - ---------------------------------------- - -*disablenpc("<NPC object name>") -*enablenpc("<NPC object name>") - -These two commands will disable and enable, respectively, an NPC object -specified by name. The disabled NPC will disappear from sight and will no -longer be triggerable in the normal way. It is not clear whether it will -still be accessible through donpcevent() and other triggering commands, -but it probably will be. You can disable even warp NPCs if you know their -object names, which is an easy way to make a map only accessible through -walking half the time. Then you 'enablenpc' them back. - -You can also use these commands to create the illusion of an NPC switching -between several locations, which is often better than actually moving the -NPC - create one NPC object with a visible and a hidden part to their -name, make a few copies, and then disable all except one. - ---------------------------------------- - -*hideonnpc("<NPC object name>") -*hideoffnpc("<NPC object name>") - -These commands will make the NPC object specified display as hidden or -visible, even though not actually disabled per se. Hidden as in thief Hide -skill, but unfortunately, not detectable by Ruwach or Sight. - -As they are now, these commands are pointless, it is suggested to use -'disablenpc'/'enablenpc', because these two commands actually unload the -NPC sprite location and other accompanying data from memory when it is not -used. However, you can use these for some quest ideas (such as cloaking -NPCs talking while hidden then revealing... you can wonder around =P). - ---------------------------------------- - -*doevent("<NPC object name>::<event label>") - -This command will start a new execution thread in a specified NPC object -at the specified label. The execution of the script running this command -will not stop, and the event called by the doevent() command will not run -until the invoking script has terminated. No parameters may be passed with -a doevent() call. - -The script of the NPC object invoked in this manner will run as if it's -been invoked by the RID that was active in the script that issued a -'doevent'. As such, the command will not work if an RID is not attached. - - place,100,100,1%TAB%script%TAB%NPC%TAB%53,{ - mes("This is what you will see when you click me"); - close(); - OnLabel: - mes("This is what you will see if the doevent is activated"); - close(); - } - - // ... - - doevent("NPC::OnLabel"); - ---------------------------------------- - -*donpcevent("<NPC object name>::<event label>") - -This command invokes the event label code within an another NPC or NPCs. -It starts a separate instance of execution, and the invoking NPC will -resume execution its immediately. - -If the supplied event label has the form "NpcName::OnLabel", then only -given NPC's event label will be invoked (much like goto() into another -NPC). If the form is "::OnLabel" (NPC name omitted), the event code of all -NPCs with given label will be invoked, one after another. In both cases -the invoked script will run without an attached RID, whether or not the -invoking script was attached to a player. The event label name is required -to start with "On". - -This command can be used to make other NPCs act, as if they were -responding to the invoking NPC's actions, such as using an emotion or -talking. - - place,100,100,1%TAB%script%TAB%NPC%TAB%53,{ - mes("Hey NPC2 copy what I do"); - close2(); - @emote = rand(1, 30); - donpcevent("NPC2::OnEmote"); - OnEmote: - emotion(@emote); - end; - } - - place,102,100,1%TAB%script%TAB%NPC2%TAB%53,{ - mes("Hey NPC copy what I do"); - close2(); - @emote = rand(1, 30); - donpcevent("NPC::OnEmote"); - OnEmote: - emotion(@emote); - end; - } - -Whichever of the both NPCs is talked to, both will show a random emotion -at the same time. - -Command returns true or false on success and failure. -A debug message also shows on the console when no events are triggered. - ---------------------------------------- - -*npctalk("<message>"{, "<npc name>"{, <show_name>}}) - -show_npcname values: - true: shows npc name (default) - false: hide npc name - -This command will display a message to the surrounding area as if the NPC -object running it was a player talking - that is, above their head and in -the chat window. If show_npcname is true the name of the NPC will get appended in front of -the message, otherwise the npc name will not be shown. - - // This will make everyone in the area see the NPC greet the character - // who just invoked it. - npctalk("Hello "+strcharinfo(PC_NAME)+", how are you?"); - npctalk("Hello "+strcharinfo(PC_NAME)+", how are you?", "Another_NPC_Name"); - ---------------------------------------- - -*setnpcdisplay("<npc name>", "<display name>", <class id>, <size>) -*setnpcdisplay("<npc name>", "<display name>", <class id>) -*setnpcdisplay("<npc name>", "<display name>") -*setnpcdisplay("<npc name>", <class id>) - -Changes the display name and/or display class of the target NPC. -Returns 0 is successful, 1 if the NPC does not exist. -Size is 0 = normal 1 = small 2 = big. - ---------------------------------------- -//===================================== -5.1 - Time-Related Commands -//===================================== ---------------------------------------- - -*addtimer(<ticks>, "NPC::OnLabel"{, <account id>}) - -This command will create a countdown timer. -The event label given is the identifier of that timer. -The timer runs on the character object that is attached to the script, -and can have multiple instances. If <acccount id> is passed, this player -will be used instead. When the label is run, it is run as if the player -that the timer runs on has clicked the NPC. - -When this timer runs out, a new execution thread will start in the -specified NPC object at the specified label. - -The ticks are given in 1/1000ths of a second. - -One more thing. These timers are stored as part of player data. If the -player logs out, all of these get immediately deleted, without executing -the script. If this behavior is undesirable, use some other timer -mechanism (like sleep()). - -Example: -<NPC Header> { - dispbottom("Starting a 5 second timer..."); - addtimer(5000, strnpcinfo(NPC_NAME_UNIQUE)+"::On5secs"); - end; -On5secs: - dispbottom("5 seconds have passed!"); - end; -} - ---------------------------------------- - -*deltimer("NPC::OnLabel"{, <account id>}) - -Deletes timers created by addtimer() that matches the given event -label. Refer to addtimer() for additional information. - ---------------------------------------- - -*addtimercount("NPC::OnLabel", <ticks>{, <account id>}) - -Delays a timer that was created with addtimer() by <ticks> ticks -if it matches the given event label. Refer to addtimer() for additional -information. - ---------------------------------------- - -*gettimer(<type>{, <account id>{, "<event>"}}) - -Returns informations on timers that were created by addtimer(). - -valid <type> for gettimer() are: - -(0) TIMER_COUNT - Will return the total number of timers for the specified or - attached player. Can be filtered by <event>. -(1) TIMER_TICK_NEXT - Will return the number of ticks until the next timer runs - for the specified or attached player. Can be filtered by <event>. -(2) TIMER_TICK_LAST - Will return the number of ticks until the last timer runs - for the specified or attached player. Can be filtered by <event>. - ---------------------------------------- - -*initnpctimer({"<NPC name>"{, <Attach Flag>}}) -*initnpctimer({<Attach Flag>}) -*stopnpctimer({"<NPC name>"{, <Detach Flag>}}) -*stopnpctimer({<Detach Flag>}}) -*startnpctimer({"<NPC name>"{, <Attach Flag>}}) -*startnpctimer({<Attach Flag>}) -*setnpctimer(<tick>{, "<NPC name>"}) -*getnpctimer(<type of information>{, "<NPC name>"}) -*attachnpctimer({"<character name>"}) -*detachnpctimer({"<NPC name>"}) - -This set of commands and functions will create and manage an NPC-based -timer. The NPC name may be omitted, in which case the calling NPC is used -as target. - -Contrary to addtimer()/deltimer() commands which let you have many different -timers referencing different labels in the same NPC, each with their own -countdown, initnpctimer() can only have one per NPC object. But it can -trigger many labels and let you know how many were triggered already and -how many still remain. - -This timer is counting up from 0 in ticks of 1/1000ths of a second each. -Upon creating this timer, the execution will not stop, but will happily -continue onward. The timer will then invoke new execution threads at -labels "OnTimer<time>:" in the NPC object it is attached to. - -To create the timer, use the initnpctimer(), which will start it running. -stopnpctimer() will pause the timer, without clearing the current tick, -while startnpctimer() will let the paused timer continue. - -By default timers do not have a RID attached, which lets them continue -even if the player that started them logs off. To attach a RID to a timer, -you can either use the optional "attach flag" when using -initnpctimer()/startnpctimer(), or do it manually by using attachnpctimer(). -Likewise, the optional flag of stopnpctimer() lets you detach any RID after -stopping the timer, and by using detachnpctimer() you can detach a RID at -any time. - -Normally there is only a single timer per NPC, but as an exception, as -long as you attach a player to the timer, you can have multiple timers -running at once, because these will get stored on the players instead of -the NPC. -NOTE: You need to attach the RID before the timer _before_ you start it to -get a player-attached timer. Otherwise it'll stay a NPC timer (no effect). - -If the player that is attached to the npctimer logs out, the -"OnTimerQuit:" event label of that NPC will be triggered, so you can do -the appropriate cleanup (the player is still attached when this event is -triggered). - -The setnpctimer() command will explicitly set the timer to a given tick. -getnpctimer() provides timer information. Its parameter defines what type: - - 0 - Will return the current tick count of the timer. - 1 - Will return 1 if there are remaining "OnTimer<ticks>:" labels in the - specified NPC waiting for execution. - 2 - Will return the number of times the timer has triggered and will - trigger an "OnTimer<tick>:" label in the specified NPC. - -Example 1: - - <NPC Header> { - // We need to use attachnpctimer() because the mes command below - // needs RID attach - attachnpctimer(); - initnpctimer(); - npctalk("I cant talk right now, give me 10 seconds"); - end; - OnTimer5000: - npctalk("Ok 5 seconds more"); - end; - OnTimer6000: - npctalk("4"); - end; - OnTimer7000: - npctalk("3"); - end; - OnTimer8000: - npctalk("2"); - end; - OnTimer9000: - npctalk("1"); - end; - OnTimer10000: - stopnpctimer(); - mes("[Man]"); - mes("Ok we can talk now"); - detachnpctimer(); - // and remember attachnpctimer() and detachnpctimer() can only be used - // while the NPC timer is not running! - } - -Example 2: - - OnTimer15000: - npctalk("Another 15 seconds have passed."); - - // You have to use initnpctimer() instead of setnpctimer(0). - // This is equal to setnpctimer(0); startnpctimer();. - // Alternatively, you can also insert another 'OnTimer15001:' label - // so that the timer won't stop. - initnpctimer(); - end; - - // This OnInit label will run when the script is loaded, so that the - // timer is initialized immediately as the server starts. It is - // dropped back to 0 every time the NPC says something, so it will - // cycle continuously. - OnInit: - initnpctimer(); - end; - -Example 3: - - mes("[Man]"); - mes("I have been waiting "+(getnpctimer(0)/1000)+" seconds for you."); - // We divide the timer returned by 1000 to convert milliseconds to - // seconds. - close(); - -Example 4: - - mes("[Man]"); - mes("Ok, I will let you have 30 more seconds..."); - close2(); - setnpctimer(getnpctimer(0)-30000); - // Notice the close2(). If there were a next() there the timer would - // be changed only after the player pressed the next() button. - end; - ---------------------------------------- - -*sleep(<milliseconds>) -*sleep2(<milliseconds>) -*awake("<NPC name>") - -These commands are used to control the pause of a NPC. -sleep() and sleep2() will pause the script for the given amount of -milliseconds. -awake() is used to cancel a sleep(). When awake() is called on a NPC it will run -as if the sleep timer ran out, and thus making the script continue. sleep() -and sleep2() basically do the same, but the main difference is that sleep() -will not keep the rid, while sleep2() does. - -Examples: - // This will pause the script for 10 seconds and ditch the RID - // (so no player is attached anymore) - sleep(10000); - // Pauses the script for 5 seconds, and continue with the RID attached. - sleep2(5000); - //Cancels any running sleep timers on the NPC 'NPC'. - awake("NPC"); - ---------------------------------------- - -*progressbar("<color>", <seconds>) -*progressbar_unit("<color>", <seconds>{, <GID>}) - -This command works almost like sleep2(), but displays a progress bar above -the head of the currently attached character (like cast bar). Once the -given amount of seconds passes, the script resumes. If the character moves -while the progress bar progresses, it is aborted and the script ends. The -color format is in RGB (0xRRGGBB). The color is currently ignored by the -client and appears always green. - -progressbar_unit works only for PACKETVER >= 20130821 -The progressbar will show on the given unit id but it will not -put the unit in timeout (the progressbar would be just an animation). -if GID is not given use the attached player. - ---------------------------------------- -//===================================== -5.1 - End of Time-related commands -//===================================== ---------------------------------------- - -*announce("<text>", <flag>{, <fontColor>{, <fontType>{, <fontSize>{, <fontAlign>{, <fontY>}}}}}) - -This command will broadcast a message to all or most players, similar to -@kami/@kamib GM commands. - - announce("This will be shown to everyone at all in yellow.", bc_all); - -The region the broadcast is heard in (target), source of the broadcast and -the color the message will come up as is determined by the flags. - -The flag values are coded as constants in doc/constants.md to make them -easier to use. - -Target flags: -- bc_all: Broadcast message is sent server-wide (default). -- bc_map: Message is sent to everyone in the same map as the source of - the broadcast (see below). -- bc_area: Message is sent to players in the vicinity of the source. -- bc_self: Message is sent only to current player. -You cannot use more than one target flag. - -Source flags: -- bc_pc: Broadcast source is the attached player (default). -- bc_npc: Broadcast source is the NPC, not the player attached to the - script (useful when a player is not attached or the message - should be sent to those nearby the NPC). -You cannot use more than one source flag. - -Special flags: -- bc_yellow:Broadcast will be displayed in yellow color (default). -- bc_blue: Broadcast will be displayed in blue color. -- bc_woe: Indicates that this broadcast is 'WoE Information' that can - be disabled client-side. -Due to the way client handles broadcasts, it is impossible to set both -bc_blue and bc_woe. - -The optional parameters allow usage of broadcasts in custom colors, -font-weights, sizes etc. If any of the optional parameters is used, -special flag is ignored. Optional parameters may not work well (or at all) -depending on a game client used. - -The color parameter is a single number which can be in hexadecimal -notation. C_ constant can also be used for color effects, see the full list -of the available ones in 'db/constants.conf' under 'C_'. - -For example: - announce("This announcement will be shown to everyone in green.", bc_all, 0x00FF00); -Will display a global announce in green. The color format is in RGB -(0xRRGGBB). - -Another example: - announce("This announcement will shown to everyone in purple.", bc_all, C_PURPLE); - -In official scripts only two font-weights (types) are used: - - normal (FW_NORMAL = 400, default), - - bold (FW_BOLD = 700). - -Default font size is 12. - -Using this for private messages to players is probably not that good an -idea, but it can be used instead in NPCs to "preview" an announce. - - // This will be a private message to the player using the NPC that - // made the announcement - announce("This is my message just for you", bc_blue|bc_self); - - // This will be shown on everyones screen that is in sight of the NPC. - announce("This is my message just for you people here", bc_npc|bc_area); - ---------------------------------------- - -*mapannounce("<map name>", "<text>", <flag>{, <fontColor>{, <fontType>{, <fontSize>{, <fontAlign>{, <fontY>}}}}}}) - -This command will work like announce() but will only broadcast to -characters currently residing on the specified map. The flag and optional -parameters parameters are the same as in announce(), but target and source -flags are ignored. - ---------------------------------------- - -*areaannounce("<map name>", <x1>, <y1>, <x2>, <y2>, "<text>", <flag>{, <fontColor>{, <fontType>{, <fontSize>{, <fontAlign>{, <fontY>}}}}}}) - -This command works like 'announce' but will only broadcast to characters -residing in the specified x1/y1-x2/y2 rectangle on the map given. The -flags and optional parameters are the same as in announce(), but target -and source flags are ignored. - - areaannounce("prt_church", 0, 0, 350, 350, "God's in his heaven, all right with the world", 0); - ---------------------------------------- - -*callshop("<name>", <option>) - -These are a series of commands used to create dynamic shops. -The callshop() function calls an invisible shop (FAKE_NPC) as if the player -clicked on it. - -For the options on callShop: - 0 = The normal window (buy, sell and cancel) - 1 = The buy window - 2 = The sell window - -Example: - -//Will call the shop named DaShop and opens the buy menu. -callshop("DaShop", 1); - - -The shop which is called by callshop() (as long as an npcshop* command is -executed from that NPC (see note 1)) will trigger the labels OnBuyItem and -OnSellitem. These labels can take over handling for relatively the buying -of items from the shop and selling the items to a shop. Via these labels -you can customize the way an item is bought or sold by a player. - -In the OnBuyItem, two arrays are filled (@bought_nameid and -@bought_quantity) with information about the name id (item id) sold -and the amount sold of it. Same goes for the OnSellItem label, only the -variables are named different (@sold_nameid, @sold_quantity, @sold_refine, -@sold_attribute, @sold_identify, @sold_card1, @sold_card2, @sold_card3, -@sold_card4). An example on a shop comes with Hercules, and can be found -in the doc/sample/npc_dynamic_shop.txt file. - -This example shows how to use the labels and their set variables to create -a dynamic shop. - -Note 1: These labels will only be triggered if a npcshop* command is -executed, this is because these commands set a special data on the shop -NPC, named master_nd in the source. -The OnSellItem and OnBuyItem are triggered in the NPC whose master_nd is -given in the shop. - ---------------------------------------- - -*npcshopitem("<name>", <item id>, <price>{, <item id>, <price>{, <item id>, <price>{, ...}}}) - -This command lets you override the contents of an existing NPC shop or -cashshop. The current sell list will be wiped, and only the items -specified with the price specified will be for sale. - -The function returns true if shop was updated successfully, or false if not found. - -Note that you cannot use -1 to specify default selling price! - ---------------------------------------- - -*npcshopadditem("<name>", <item id>, <price>{, <item id>, <price>{, <item id>, <price>{, ...}}}) - -This command will add more items at the end of the selling list for the -specified NPC shop or cashshop. If you specify an item already for sell, -that item will appear twice on the sell list. - -The function returns true if shop was updated successfully, or false if not found. - -Note that you cannot use -1 to specify default selling price! - ---------------------------------------- - -*npcshopdelitem("<name>", <item id>{, <item id>{, <item id>{, ...}}}) - -This command will remove items from the specified NPC shop or cashshop. -If the item to remove exists more than once on the shop, all instances -will be removed. - -Note that the function returns true even if no items were removed. The return -value is only to confirm that the shop was indeed found. - ---------------------------------------- - -*npcshopattach("<name>"{, <flag>}) - -This command will attach the current script to the given NPC shop. -When a script is attached to a shop, the events "OnBuyItem" and -"OnSellItem" of your script will be executed whenever a player buys/sells -from the shop. Additionally, the arrays @bought_nameid[], -@bought_quantity[] or @sold_nameid[] and @sold_quantity[] will be filled -up with the items and quantities bought/sold. - -The optional parameter specifies whether to attach (true) or detach (false) -from the shop (the default is to attach). Note that detaching will detach -any NPC attached to the shop, even if it's from another script, while -attaching will override any other script that may be already attached. - -The function returns false if the shop was not found, true otherwise. - ---------------------------------------- - -*waitingroom("<chatroom name>", <limit>{, <event label>, <trigger>, <required zeny>, <min lvl>, <max lvl>}) - -This command will create a chat room, owned by the NPC object running this -script and displayed above the NPC sprite. -The maximum length of a chat room name is 60 letters. - -The limit is the maximum number of people allowed to enter the chat room. -The attached NPC is included in this count. If the optional event and -trigger parameters are given, the event label -("<NPC object name>::<label name>") will be invoked as if with a donpcevent() -upon the number of people in the chat room reaching the given triggering -amount. - -// The NPC will just show a box above its head that says "Hello World", -// clicking it will do nothing, since the limit is zero. - waitingroom("Hello World", 0); - -// The NPC will have a box above its head, with "Disco - Waiting Room" -// written on it, and will have 8 waiting slots. Clicking this will enter -// the chat room, where the player will be able to wait until 7 players -// accumulate. Once this happens, it will cause the NPC "Bouncer" run the -// label "OnStart". - - waitingroom("Disco - Waiting Room", 8, "Bouncer::OnStart", 7); - -// The NPC will have a box above its head, with "Party - Waiting Room" -// written on it, and will have 8 waiting slots. Clicking this will allow -// a player who has 5000 zeny and lvl 50~99 to enter the chat room, where -// the player will be able to wait until 7 players accumulate. Once this -// happens, it will cause the NPC "Bouncer" run the label "OnStart". - - waitingroom("Party - Waiting Room", 8, "Bouncer::OnStart", 7, 5000, 50, 99); - -Creating a waiting room does not stop the execution of the script and it -will continue to the next line. - -For more examples see the 2-1 and 2-2 job quest scripts which make -extensive use of waiting rooms. - ---------------------------------------- - -*delwaitingroom({"<NPC object name"}) - -This command will delete a waiting room. If no parameter is given, it will -delete a waiting room attached to the NPC object running this command, if -it is, it will delete a waiting room owned by another NPC object. This is -the only way to get rid of a waiting room, nothing else will cause it to -disappear. - -It's not clear what happens to a waiting room if the NPC is disabled with -disablenpc(), by the way. - ---------------------------------------- - -*enablewaitingroomevent({"<NPC object name>"}) -*disablewaitingroomevent({"<NPC object name>"}) - -This will enable and disable triggering the waiting room event (see -waitingroom()) respectively. Optionally giving an NPC object name will do -that for a specified NPC object. The chat room will not disappear when -triggering is disabled and enabled in this manner and players will not be -kicked out of it. Enabling a chat room event will also cause it to -immediately check whether the number of users in it exceeded the trigger -amount and trigger the event accordingly. - -Normally, whenever a waiting room was created to make sure that only one -character is, for example, trying to pass a job quest trial, and no other -characters are present in the room to mess up the script. - ---------------------------------------- - -*getwaitingroomstate(<information type>{, "<NPC object name>"}) - -This function will return information about the waiting room state for the -attached waiting room or for a waiting room attached to the specified NPC -if any. - -The valid information types are: - - 0 - Number of users currently in the waiting room - $@chatmembers[] - list of user account_id - 1 - Maximum number of users allowed. - 2 - Will return 1 if the waiting room has a trigger set. - 0 otherwise. - 3 - Will return 1 if the waiting room is currently disabled. - 0 otherwise. - 4 - The Title of the waiting room (string) - 5 - Password of the waiting room, if any. Pointless, since there is no - way to set a password on a waiting room right now. - 16 - Event name of the waiting room (string) - 32 - Whether or not the waiting room is full. - 33 - Whether the amount of users in the waiting room is higher than the - trigger number. - 34 - Minimum Base Level to enter waiting room. - 35 - Maximum Base Level to enter waiting room. - 36 - Minimum Zeny to enter waiting room. - ---------------------------------------- - -*warpwaitingpc("<map name>", <x>, <y>{, <number of people>}) - -This command will warp the amount of characters equal to the trigger -number of the waiting room chat attached to the NPC object running this -command to the specified map and coordinates, kicking them out of the -chat. Those waiting the longest will get warped first. It can also do a -random warp on the same map ("Random" instead of map name) and warp to the -save point ("SavePoint"). - -The list of characters to warp is taken from the list of the chat room -members. Those not in the chat room will not be considered even if they -are talking to the NPC in question. If the number of people is given, -exactly this much people will be warped. - -This command can also keep track of who just got warped. It does this by -setting special variables: - -$@warpwaitingpc[] is an array containing the account_id numbers of the - characters who were just warped. -$@warpwaitingpcnum contains the number of the character it just warped. - -See also 'getpartymember' for advice on what to do with those variables. - -The obvious way of using this effectively would be to set up a waiting -room for two characters to be warped onto a random PVP map for a -one-on-one duel, for example. - ---------------------------------------- - -*kickwaitingroomall({"<NPC object name>"}) - -This command kicks everybody out of a specified waiting room chat. - ---------------------------------------- - -*setmapflagnosave("<map name>", "<alternate map name>", <x>, <y>) - -This command sets the 'nosave' flag for the specified map and also gives -an alternate respawn-upon-relogin point. - -It does not make a map impossible to make a save point on as you would -normally think, savepoint() will still work. It will, however, make the -specified map kick the reconnecting players off to the alternate map given -to the coordinates specified. - ---------------------------------------- - -*setmapflag("<map name>", <flag>{, <val>}) - -This command marks a specified map with a map flag given. Map flags alter -the behavior of the map, you can see the list of the available ones in -'doc/constants.md' under 'Mapflags'. - -The map flags alter the behavior of the map regarding teleporting -(mf_nomemo, mf_noteleport, mf_nowarp), storing location when -disconnected (mf_nosave), dead branch usage (mf_nobranch), penalties -upon death (mf_nopenalty, mf_nozenypenalty), PVP behavior (mf_pvp, -mf_pvp_noparty, mf_pvp_noguild), WoE behavior (mf_gvg, mf_gvg_noparty), -ability to use skills or open up trade deals (mf_notrade, mf_novending, -mf_noskill, mf_noicewall), current weather effects (mf_snow, mf_fog, -mf_sakura, mf_leaves, mf_clouds, mf_clouds2, mf_fireworks), whether -night will be in effect on this map (mf_nightenabled) and so on. - -The val optional parameter is as the mapflags variable when one exists, it -may be a number or a string depending on the mapflag in question. - ---------------------------------------- - -*removemapflag("<map name>", <flag>) - -This command removes a mapflag from a specified map. -See setmapflag() for examples of mapflags. - ---------------------------------------- - -*getmapflag("<map name>", <flag>) - -This command checks the status of a given mapflag and returns the -mapflag's state. -false means OFF, and true means ON. See setmapflag() for examples of mapflags. - ---------------------------------------- - -*setbattleflag("<battle flag>", <value>) -*getbattleflag("<battle flag>") - -Sets or gets the value of the given battle flag. -Battle flags are the flags found in the conf/map/battle/*.conf files and is -also used in Lupus' variable rates script. - -Examples: - -// Will set the base experience rate to 20x (2000%) - setbattleflag("base_exp_rate", 2000); - -// Will return the value of the base experience rate (when used after the -// above example, it would print 2000). - mes(getbattleflag("base_exp_rate")); - ---------------------------------------- - -*warpportal(<x>, <y>, "<mapname>", <x>, <y>) - -Creates a warp Portal as if a acolyte class character did it. -The first x and y is the place of the warp portal on the map where the NPC -is on the mapname and second x and y is the target area of the warp portal. - -Examples: - -// Will create a warp portal on the NPC's map at 150,150 -// leading to prontera, coords 150,180. - warpportal(150, 150, "prontera", 150, 180); - ---------------------------------------- - -*mapwarp("<from map>", "<to map>", <x>, <y>{, <type>, <ID>}) - -This command will collect all characters located on the From map and warp -them wholesale to the same point on the To map, or randomly distribute -them there if the coordinates are zero. "Random" is understood as a -special To map name and will mean randomly shuffling everyone on the same -map. - -Optionally, a type and ID can be specified. Available types are: - - 0 - Everyone - 1 - Guild - 2 - Party - -Example: - -// Will warp all members of guild with ID 63 on map prontera to alberta. - mapwarp("prontera", "alberta", 150, 150, 1, 63); - ---------------------------------------- -//===================================== -5.2 - Guild-Related Commands -//===================================== ---------------------------------------- - -*maprespawnguildid("<map name>", <guild id>, <flag>) - -This command goes through the specified map and for each player and -monster found there does stuff. - -Flag is a bit-mask (add up numbers to get effects you want) - 1 - warp all guild members to their save points. - 2 - warp all non-guild members to their save points. - 4 - remove all monsters which are not guardian or Emperium. - -Flag 7 will, therefore, mean 'wipe all mobs but guardians and the Emperium -and kick all characters out', which is what the official scripts do upon -castle surrender. Upon start of WoE, the scripts do 2 (warp out all people -not in the guild that owns the castle). - -Characters not belonging to any guild will be warped out regardless of the -flag setting. - -For examples, check the WoE scripts in the distribution. - ---------------------------------------- - -*agitstart() -*agitend() -*agitstart2() -*agitend2() - -These four commands will start/end War of Emperium or War of Emperium SE. - -This is a bit more complex than it sounds, since the commands themselves -won't actually do anything interesting, except causing all 'OnAgitStart:' -and 'OnAgitEnd:', or 'OnAgitStart2:' and 'OnAgitEnd2:' in the case of -latter two commands, events to run everywhere, respectively. They are used -as simple triggers to run a lot of complex scripts all across the server, -and they, in turn, are triggered by clock with an 'OnClock<time>:' -time-triggering label. - ---------------------------------------- - -*gvgon("<map name>") -*gvgoff("<map name>") - -These commands will turn GVG mode for the specified maps on and off, -setting up appropriate map flags. In GVG mode, maps behave as if during -the time of WoE, even though WoE itself may or may not actually be in -effect. - ---------------------------------------- - -*flagemblem(<guild id>) - -This command only works when run by the NPC objects which have sprite id -GUILD_FLAG (722), which is a 3D guild flag sprite. If it isn't, the data -will change, but nothing will be seen by anyone. If it is invoked in -that manner, the emblem of the specified guild will appear on the flag, -though, if any players are watching it at this moment, they will not see -the emblem change until they move out of sight of the flag and return. - -This is commonly used in official guildwar scripts with a function call -which returns a guild id: - -// This will change the emblem on the flag to that of the guild that owns -// "guildcastle" - - flagemblem(getcastledata("guildcastle", 1)); - ---------------------------------------- - -*guardian("<map name>", <x>, <y>, "<name to show>", <mob id>{, "<event label>"{, <guardian index>}}) - -This command is roughly equivalent to monster(), but is meant to be used -with castle guardian monsters and will only work with them. It will set -the guardian characteristics up according to the castle's investment -values and otherwise set the things up that only castle guardians need. - -Returns the id of the mob or 0 if an error occurred. -When 'guardian index' isn't supplied it produces a temporary guardian. -Temporary guardians are not saved with the castle and can't be accessed by -guardianinfo. - ---------------------------------------- - -*guardianinfo("<map name>", <guardian number>, <type>) - -This function will return various info about the specified guardian, or -1 -if it fails for some reason. It is primarily used in the castle manager -NPC. - -Map name and guardian number (value between 0 and 7) define the target. -Type indicates what information to return: - 0 - visibility (whether the guardian is installed or not) - 1 - max. hp - 2 - current hp - ---------------------------------------- -//===================================== -5.2 - End of Guild-Related Commands -//===================================== ---------------------------------------- - -*npcspeed(<speed value>) -*npcwalkto(<x>, <y>) -*npcstop() - -These commands will make the NPC object in question move around the map. -As they currently are, they are a bit buggy and are not useful for much -more than making an NPC move randomly around the map. - -npcspeed() will set the NPCs walking speed to a specified value. As in the -@speed GM command, 200 is the slowest possible speed while 0 is the -fastest possible (instant motion). 100 is the default character walking -speed. -npcwalkto() will start the NPC sprite moving towards the specified -coordinates on the same map as it is currently on. The script proceeds -immediately after the NPC begins moving. -npcstop() will stop the motion. - -While in transit, the NPC will be clickable, but invoking it will cause it -to stop moving, which will make it's coordinates different from what the -client computed based on the speed and motion coordinates. The effect is -rather unnerving. - -Only a few NPC sprites have walking animations, and those that do, do not -get the animation invoked when moving the NPC, due to the problem in the -NPC walking code, which looks a bit silly. You might have better success -by defining a job-sprite based sprite id in 'db/mob_avail.txt' with this. - ---------------------------------------- - -*movenpc("<NPC name>", <x>, <y>{, <dir>}) - -This command looks like the npcwalktoxy function, but is a little different. - -While npcwalktoxy just makes the NPC 'walk' to the coordinates given -(which sometimes gives problems if the path isn't a straight line without -objects), this command just moves the NPC. It basically warps out and in -on the current and given spot. Direction can be used to change the NPC's -facing direction. - -Example: - -// This will move Bugga from to the coordinates 100,20 (if those -// coordinates are legit). - movenpc("Bugga", 100, 20); - ---------------------------------------- - -*navigateto("<map>"{,<x>,<y>,<flag>,<hide_window>,<monster_id>,<char_id>}); - -Generates a navigation for attached or specified character. Requires client -2011-10-10aRagEXE or newer. - -The flag specifies how the client will calculate the specific route. - -Valid flags are: - NAV_NONE - No services - NAV_AIRSHIP_ONLY - Airship only - NAV_SCROLL_ONLY - Scroll only - NAV_AIRSHIP_AND_SCROLL - Airship and Scroll - NAV_KAFRA_ONLY - Kafra only - NAV_KAFRA_AND_AIRSHIP - Kafra and Airship - NAV_KAFRA_AND_SCROLL - Kafra and Scroll - NAV_ALL - All services - -When flag is not specified, the default value is NAV_KAFRA_AND_AIRSHIP. - -The hide_window specifies whether to display (0) or hide (1) the navigation window. -By default the window is hidden. - -You can specify the monster_id in combination with a mapname to make the -navigation system tell you, that you have reached the desired mob. - -Note: -The client requires custom monster spawns be in the navigation file -for using the embedded client Navigation feature to work properly. In this -instance sending the player to the map where the monster spawns is a simpler -solution rather than sending the map and the monster_id. - ---------------------------------------- -//===================================== -6 - Other Commands -//===================================== ---------------------------------------- - -*debugmes("<format string>"{, <param>{, ...}}) - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ /!\ This command is deprecated @ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -This command will print a message in the server console (map-server window), -after applying the same format-string replacements as sprintf(). It will not be -displayed anywhere else. Returns true on success. - -Example: - - // Displays "NAME has clicked me!" in the map-server window. - debugmes("%s has clicked me!", strcharinfo(PC_NAME)); - - debugmes("\033[0;32mHello World"); // supports ANSI escape sequences - ---------------------------------------- - -*consolemes("<type>", "<format string>"{,<param>{, ...}}) - -This command will print a message in the server console (map-server window), -after applying the same format-string replacements as sprintf(). It will not be -displayed anywhere else. Returns true on success. - -List of available <type> are: - CONSOLEMES_DEBUG = 0 - CONSOLEMES_ERROR = 1 - CONSOLEMES_WARNING = 2 - CONSOLEMES_INFO = 3 - CONSOLEMES_STATUS = 4 - CONSOLEMES_NOTICE = 5 - -Example: - - // Displays "NAME has clicked me!" in the map-server window. - consolemes(CONSOLEMES_DEBUG, "%s has clicked me!", strcharinfo(PC_NAME)); - - consolemes(CONSOLEMES_DEBUG, "\033[0;32mHello World"); // supports ANSI escape sequences - ---------------------------------------- - -*logmes("<message>"{, <log type>}) - -This command will write the message given to the map server log files, as -specified in 'conf/map/logs.conf'. If SQL logging is enabled, the message will -go to the specified log table. If logs are not enabled, nothing will happen. - -Log types are: - -LOGMES_NPC - log to the 'npclog' table (Default) -LOGMES_ATCOMMAND - log to the 'atcommandlog' table - -Example: - - logmes("foobar"); - logmes("foobar", LOGMES_ATCOMMAND); - ---------------------------------------- - -*globalmes("<message>"{, "<NPC name>"}) - -This command will send a message to the chat window of all currently -connected characters. - -If NPC name is specified, the message will be sent as if the sender would -be the NPC with the said name. - ---------------------------------------- - -*channelmes("<#channel>", "<message>") - -This command will send a message to the specified chat channel. - -The sent message will not include any character's names. - -For special channels, such as #map and #ally, the attached RID's map or guild -will be used. - -If the channel doesn't exist (or, in the case of a character-specific channel, -no RID is attached), false will be returned. In case of success, true is -returned. - ---------------------------------------- - -*addchannelhandler("<#channel>", "<NPC::OnEvent>") - -This command will trigger the specified event every time a player -talks in the specified channel, with said player as attached rid. -It assigns the message to @channelmes$ - -OnChannelMessage: - channelmes("#chan", "Echo: " + @channelmes$); - end; - -OnInit: - addchannelhandler("#chan", "NPC::OnChannelMessage"); - ---------------------------------------- - -*removechannelhandler("<#channel>", "<NPC::OnEvent>") - -Removes a channel handler added by addchannelhandler() - ---------------------------------------- -*rand(<number>{, <number>}) - -This function returns a number ... -(if you specify one) ... randomly positioned between 0 and the number you - specify -1. -(if you specify two) ... randomly positioned between the two numbers you - specify. - -rand(10) would result in 0, 1, 2, 3, 4, 5, 6, 7, 8 or 9 -rand(0, 9) would result in 0, 1, 2, 3, 4, 5, 6, 7, 8 or 9 -rand(2, 5) would result in 2, 3, 4 or 5 - ---------------------------------------- - -*viewpoint(<action>, <x>, <y>, <point number>, <color>) - -This command will mark places on the mini map in the client connected to -the invoking character. It uses the normal X and Y coordinates from the -main map. The colors of the marks are defined using a hexadecimal number, -same as the ones used to color text in mes() output, but are written as -hexadecimal numbers in C. (They look like 0x<six numbers>.) - -Action is what you want to do with a point, 1 will set it, while 2 will -clear it. 0 will also set it, but automatically removes the point after 15 -seconds. -Point number is the number of the point - you can have several. If more -than one point is drawn at the same coordinates, they will cycle, which -can be used to create flashing marks. - - // This command will show a mark at coordinates X 30 Y 40, is mark - // number 1, and will be red. - - viewpoint(1, 30, 40, 1, 0xFF0000); - -This will create three points: - - viewpoint(1, 30, 40, 1, 0xFF0000); - viewpoint(1, 35, 45, 2, 0xFF0000); - viewpoint(1, 40, 50, 3, 0xFF0000); - -And this is how you remove them: - - viewpoint(2, 30, 40, 1, 0xFF0000); - viewpoint(2, 35, 45, 2, 0xFF0000); - viewpoint(2, 40, 50, 3, 0xFF0000); - -The client determines what it does with the points entirely, the server -keeps no memory of where the points are set whatsoever. - ---------------------------------------- - -*cutin("<filename>", <position>) - -This command will display a picture, usually an NPC illustration, also -called cutin, for the currently attached client. The position parameter -determines the placement of the illustration and takes following values: - - 0 - bottom left corner - 1 - bottom middle - 2 - bottom right corner - 3 - middle of screen in a movable window with an empty title bar - 4 - middle of screen without the window header, but still movable - -The picture is read from data\texture\유저인터페이스\illust, from both the -GRF archive and data folder, and is required to be a bitmap. The file -extension .bmp can be omitted. Magenta color (#ff00ff) is considered -transparent. There is no limit placed on the size of the illustrations -by the client, although loading of large pictures (about 700x700 and -larger) causes the client to freeze shortly (lag). Typically the size is -about 320x480. New illustrations can be added by just putting the new file -into the location above. - -The client is able to display only one cutin at the same time and each new -one will cause the old one to disappear. To delete the currently displayed -illustration without displaying a new one, an empty file name and position -255 must be used. - - // Displays the Comodo Kafra illustration in lower right corner. - cutin("kafra_07", 2); - - // Typical way to end a script, which displayed an illustration during a - // dialog with a player. - mes("See you."); - close2(); - cutin("", 255); - end; - ---------------------------------------- - -*pet(<pet id>) - -This command is used in all the item scripts for taming items. Running -this command will make the pet catching cursor appear on the client -connected to the invoking character, usable on the monsters with the -specified pet ID number. It will still work outside an item script. - -A full list of pet IDs can be found inside 'db/pet_db.txt' - ---------------------------------------- - -*emotion(<emotion number>{, <target>{, "<target name>"}}) - -This command makes an object display an emotion sprite above their own as -if they were doing that emotion. For a full list of emotion numbers, see -'doc/constants.md' under 'Emotes'. The not so obvious ones are 'e_what' (a -question mark) and 'e_gasp' (the exclamation mark). - -The optional target parameter specifies who will get the emotion on top of -their head. If false (default if omitted), the NPC in current use will show -the emotion, if true, the player that is running the script will display it. - -Target name parameter allows to display emotion on top of other NPC/PC -without event labels. If specified name is not found, command does nothing. - ---------------------------------------- - -*misceffect(<effect number>) - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ /!\ This command is deprecated @ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -This command, if run from an NPC object that has a sprite, will call up a -specified effect number, centered on the NPC sprite. If the running code -does not have an object ID (a 'floating' NPC) or is not running from an -NPC object at all (an item script) the effect will be centered on the -character who's RID got attached to the script, if any. For usable item -scripts, this command will create an effect centered on the player using -the item. - -This command is deprecated and it should not be used in new scripts, as it is -likely to be removed at a later time. Please use specialeffect instead, -ie: specialeffect(<effect number>, <send target>, <unit id>) - ---------------------------------------- - -*soundeffect("<effect filename>", <type>) -*soundeffectall("<effect filename>", <type>{, "<map name>"}{, <x0>, <y0>, <x1>, <y1>}) - -These two commands will play a sound effect to either the invoking -character only (soundeffect()) or multiple characters (soundeffectall()). -If the running code does not have an object ID (a 'floating' NPC) or is -not running from an NPC object at all (an item script) the sound will be -centered on the character who's RID got attached to the script, if any. -If it does, it will be centered on that object. (an NPC sprite) - -Effect filename is the filename in a GRF. It must have the .wav extension. - -It's not quite certain what the 'type' actually does, it is sent to the -client directly. It probably determines which directory to play the effect -from. It's certain that giving 0 for the number will play sound files from -'\data\wav\', but where the other numbers will read from is unclear. - -The sound files themselves must be in the PCM format, and file names -should also have a maximum length of 23 characters including the .wav -extension: - -soundeffect("1234567890123456789.wav", 0); // will play the soundeffect -soundeffect("12345678901234567890.wav", 0); // throws gravity error - -You can add your own effects this way, naturally. - ---------------------------------------- - -*playbgm("<BGM filename>") -*playbgmall("<BGM filename>"{, "<map name>"{, <x0>, <y0>, <x1>, <y1>}}) - -These two commands will play a Background Music to either the invoking -character only (playbgm()) or multiple characters (playbgmall()). - -BGM filename is the filename in /BGM/ folder. It has to be in .mp3 -extension, but it's not required to specify the extension in the script. - -If coordinates are omitted, BGM will be broadcasted on the entire map. If -the map name is also omitted the BGM will be played for the entire server. - -You can add your own BGMs this way, naturally. - ---------------------------------------- - -*pvpon("<map name>") -*pvpoff("<map name>") - -These commands will turn PVP mode for the specified maps on and off. -Beside setting the flags referred to in setmapflag(), pvpon() will also -create a PVP timer and ranking as will @pvpon GM command do. - ---------------------------------------- - -*atcommand("<command>") - -This command will run the given command line exactly as if it was typed in -from the keyboard by the player connected to the invoking character, and -that character belonged to an account which had GM level 99. - - // This will ask the invoker for a character name and then use the - // '@nuke' GM command on them, killing them mercilessly. - input(.@player$); - atcommand("@nuke "+.@player$); - -Use of this command is not recommended unless you know what you're -doing, since not all atcommands are intended to be used by the script -engine. - ---------------------------------------- - -*charcommand("<command>") - -This command will run the given command line exactly as if it was typed in -from the keyboard from a character that belonged to an account which had -GM level 99. - -The commands can also run without an attached rid. - - // This would do the same as above, but now - // it doesn't need a player attached by default. - charcommand("#option 0 0 0 Roy"); - -Use of this command is not recommended unless you know what you're -doing, since not all atcommands are intended to be used by the script -engine. - ---------------------------------------- - -*bindatcmd("command", "<NPC object name>::<event label>"{, <group level>, <group level char>, <log>}) - -This command will bind a NPC event label to an atcommand. Upon execution -of the atcommand, the user will invoke the NPC event label. Each atcommand -is only allowed one binding. If you rebind, it will override the original -binding. If group level is provided, only users of that group level or -above will be able to access the command, if not provided, everyone will -be able to access the command. -"group level char" is the minimum group level required for the label to be -used on others like a char command would, e.g. "#command "target" params", -when not provided, "group level char" defaults to 99. -"log" whether to log the usages of this command with the atcommand log -(true = log, false = no log), default is to not log. - -The following variables are set upon execution: - .@atcmd_command$ = The name of the @command used. - .@atcmd_parameters$[] = Array containing the given parameters, - starting from an index of 0. - .@atcmd_numparameters = The number of parameters defined. - -Parameters are split on spaces. Multiple spaces aren't grouped together, and -will create multiple (empty) arguments. -Any leading spaces before the first parameter will be omitted. - -Usage example: - -When a user types the command "@test", an angel effect will be shown. - -- script atcmd_example FAKE_NPC,{ -OnInit: - bindatcmd("test", strnpcinfo(NPC_NAME_UNIQUE)+"::OnAtcommand"); - end; -OnAtcommand: - specialeffect(EF_ANGEL2, AREA, playerattached()); - end; -} - -Parameter splitting example: - @mycommand - .@atcmd_numparameters -> 0 - .@atcmd_parameters$ -> { } - @mycommand<space><space> - .@atcmd_numparameters -> 0 - .@atcmd_parameters$ -> { } - @mycommand<space>foo - .@atcmd_numparameters -> 1 - .@atcmd_parameters$ -> { "foo" } - @mycommand<space><space>foo - .@atcmd_numparameters -> 1 - .@atcmd_parameters$ -> { "foo" } - @mycommand<space>foo<space>bar - .@atcmd_numparameters -> 2 - .@atcmd_parameters$ -> { "foo", "bar" } - @mycommand<space>foo<space><space>bar - .@atcmd_numparameters -> 3 - .@atcmd_parameters$ -> { "foo", "", "bar" } - @mycommand<space>foo<space> - .@atcmd_numparameters -> 2 - .@atcmd_parameters$ -> { "foo", "" } - @mycommand<space>foo<space><space> - .@atcmd_numparameters -> 3 - .@atcmd_parameters$ -> { "foo", "", "" } - -The called event label needs to take care of joining arguments together, in -case it expects spaces. For example: - -- script atcmd_example FAKE_NPC,{ -OnInit: - bindatcmd("test", strnpcinfo(NPC_NAME_UNIQUE)+"::OnAtcommand"); - end; -OnAtcommand: - // This command expects a character name (that may contain spaces) as - // the only parameter. - .@name$ = ""; - for (.@i = 0; .@i < .@atcmd_numparameters; ++.@i) { - .@name$ += (.@i > 0 ? " " : "") + .@atcmd_parameters$[.@i]; - } - dispbottom("The specified name is: '" + .@name$ + "'"); - end; -} - ---------------------------------------- - -*add_group_command("<command>", <group id>, <use on self>, <use on other>) - -Allows to explicitly change the command permissions for a specific group. - -This command bypasses group inheritance, which means groups inheriting from -the specified <group id> will NOT inherit the specified permission. You should -use add_group_command() for every group you want to give permission to. - -Example: - bindatcmd("foobar", "NPC::OnUseCommand", 99, 99, 0); // define the command - add_group_command("foobar", 2, true, false); // allow group 2 to use @foobar - add_group_command("foobar", 5, true, true); // allow group 5 to use @foobar and #foobar - ---------------------------------------- - -*unbindatcmd("command") - -This command will unbind a NPC event label from an atcommand. - ---------------------------------------- - -*useatcmd("command") - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ /!\ This command is deprecated @ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -This command will execute an atcommand binding on the attached RID from a -script. The three .@atcmd_***** variables will NOT be set when invoking -scripts-atcommands this way. - -This command is deprecated and it should not be used in new scripts, as it is -likely to be removed at a later time. Instead, you should directly call to the -event label of the binding using timers or doevent(). For built-in commands, -atcommand() should be used instead. - ---------------------------------------- - -*can_use_command("<command>"{, <account id>}) - -Checks if the attached or specified player can use the specified -atcommand and returns true or false accordingly. Works for both -built-in atcommands and custom atcommands. - ---------------------------------------- - -*has_permission(<permission>{, <account id>}) -*has_permission("<permission>"{, <account id>}) - -Check if the attached or specified player has the specified permission -and returns true or false accordingly. See doc/permissions.md for -details about permissions. - -Valid <permission> are: - - PERM_TRADE - PERM_PARTY - PERM_ALL_SKILL - PERM_USE_ALL_EQUIPMENT - PERM_SKILL_UNCONDITIONAL - PERM_JOIN_ALL_CHAT - PERM_NO_CHAT_KICK - PERM_HIDE_SESSION - PERM_WHO_DISPLAY_AID - PERM_RECEIVE_HACK_INFO - PERM_WARP_ANYWHERE - PERM_VIEW_HPMETER - PERM_VIEW_EQUIPMENT - PERM_USE_CHECK - PERM_USE_CHANGEMAPTYPE - PERM_USE_ALL_COMMANDS - PERM_RECEIVE_REQUESTS - PERM_SHOW_BOSS - PERM_DISABLE_PVM - PERM_DISABLE_PVP - PERM_DISABLE_CMD_DEAD - PERM_HCHSYS_ADMIN - PERM_TRADE_BOUND - PERM_DISABLE_PICK_UP - PERM_DISABLE_STORE - PERM_DISABLE_EXP - PERM_DISABLE_SKILL_USAGE - -Example: - - if (has_permission(PERM_WARP_ANYWHERE)) { - //do something - } - -It is also possible to pass a string for plugin permissions: - - if (has_permission("show_version")) { - //do something - } - -** Passing a string is slower than passing a constant because - the engine has to loop through the array to find the permission. - In most cases you should use the PERM_ constants. - ---------------------------------------- - -*unitskilluseid(<GID>, <skill id>, <skill lvl>{, <target id>}) -*unitskilluseid(<GID>, "<skill name>", <skill lvl>{, <target id>}) -*unitskillusepos(<GID>, <skill id>, <skill lvl>, <x>, <y>) -*unitskillusepos(<GID>, "<skill name>", <skill lvl>, <x>, <y>) - -This is the replacement of the older commands, these use the same values -for GID as the other unit* commands (See 'GID'). - -Skill ID is the ID of the skill, skill level is the level of the skill. -For the position, the x and y are given in the unitskillusepos. - ---------------------------------------- - -*npcskill(<skill id>, <skill lvl>, <stat point>, <NPC level>) -*npcskill("<skill name>", <skill lvl>, <stat point>, <NPC level>) - -This command causes the attached NPC object to cast a skill on the -attached player. The skill will have no cast time or cooldown. The player -must be within the default skill range or the command will fail silently. - -The "stat point" parameter temporarily sets all NPC stats to the given -value, and "NPC level" is the temporary level of the NPC (used in some -skills). Neither value can be greater than the max level defined in -config, and will not work properly if the NPC has a mob sprite. - - // Casts Level 10 Heal on the attached player, calculated with - // all stats 99 and base level 60. - npcskill(AL_HEAL, 10, 99, 60); - ---------------------------------------- - -*setnpcdistance(<distance>) - -This command can reduce distance from where npc can be clicked. -Usefull to use from OnInit event. - - // Set distance to one tile on server load - OnInit: - setnpcdistance(1); - ---------------------------------------- - -*getnpcdir({<name>}) - -Return current npc direction for parameter "name" or for attached npc -if it missing. If name missing and not attached npc, return -1. - -Example: - .@dir = getnpcdir(); - ---------------------------------------- - -*setnpcdir({<name>, }<direction>) - -Set npc direction. If npc name missing, will be used attached npc. - -Example: - setnpcdir(DIR_WEST); - ---------------------------------------- - -*getnpcclass({<name>}) - -Return npc class/sprite id for npc with given name or for attached npc. -If name missing and no attached npc, return -1. - -Example: - .@class = getnpcclass(); - ---------------------------------------- - -*day(); -*night(); - -These two commands will switch the entire server between day and night -mode respectively. If your server is set to cycle between day and night by -configuration, it will eventually return to that cycle. - -Example: - -- script DayNight FAKE_NPC,{ -OnClock0600: - day(); - end; -OnInit: - // setting correct mode upon server start-up - if (gettime(GETTIME_HOUR) >= 6 && gettime(GETTIME_HOUR) < 18) - end; -OnClock1800: - night(); - end; -} - -This script allows to emulate the day/night cycle as the server does, but -also allows triggering additional effects upon change, like announces, -gifts, etc. -The day/night cycle set by configuration should be disabled when this -script is used. - ---------------------------------------- - -*pcre_match("<string>", "<regex>") - -The string <string> will be searched for a match to the regular expression -<regex>, and the number of matches will be returned. - -An alternative way to invoke this command is to use the operators '~=' or '~!'. -The operator '~=' is exactly the same as pcre_match, while the operator '~!' -will return true if no matches were found, or false if at least a match was found. - - if (pcre_match("string", "regex")) - mes("There was a match."); - if ("string" ~= "regex") - mes("There was a match."); - if ("string" ~! "regex") - mes("There were no matches."); - -You can find more usage examples in the test script npc/custom/test.txt. - -Using regular expressions is high wizardry. But with this high wizardry -comes unparalleled power of text manipulation. For an explanation of what -a regular expression pattern is, see a few web pages: - -http://www.regular-expressions.info/ -http://www.weitz.de/regex-coach/ - -Additionally, the following temporary variables will be filled (unless the -command is invoked as '~!'): - -- $@regexmatchcount: The number of matches detected, including any - parenthesized capture-groups. -- $@regexmatch$[0]: The part of <string> That matched the full <regex> pattern. -- $@regexmatch$[1 .. $@regexmatchcount]: The parts of <string> that matched - each of the parenthesized capture-groups in <pattern>. - -A capture group is a part of a regex enclosed in (parentheses) in order to -store in a variable the part of the expression that was matched by that part of -the regex. For more details, see the links above, as this is not intended to be -a regex tutorial. - ---------------------------------------- - -*defpattern(<set number>, "<regular expression pattern>", "<event label>") -*activatepset(<set number>) -*deactivatepset(<set number>) -*deletepset(<set number>) - -They will make the NPC object listen for text spoken publicly by players -and match it against regular expression patterns, then trigger labels -associated with these regular expression patterns. - -Patterns are organized into sets, which are referred to by a set number. -You can have multiple sets patterns, and multiple patterns may be active -at once. Numbers for pattern sets start at 1. - -defpattern() will associate a given regular expression pattern with an -event label. This event will be triggered whenever something a player says -is matched by this regular expression pattern, if the pattern is currently -active. - -activatepset() will make the pattern set specified active. An active -pattern will enable triggering labels defined with defpattern(), which -will not happen by default. -deactivatepset() will deactivate a specified pattern set. Giving -1 as a -pattern set number in this case will deactivate all pattern sets defined. - -deletepset() will delete a pattern set from memory, so you can create a -new pattern set in its place. - -For an example of this in use, see doc/sample/npc_test_pcre.txt - -With this you could, for example, automatically punish players for asking -for Zeny in public places, or alternatively, automatically give them Zeny -instead if they want it so much. - ---------------------------------------- - -*pow(<number>, <power>) - - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - @ /!\ This command is deprecated @ - @@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@@ - -Returns the result of the calculation. - -Example: - .@i = pow(2, 3); // .@i will be 8 - -This command is deprecated and it should not be used in new scripts, as it is -likely to be removed at a later time. Please use the exponentiation operator, -ie: (2 ** 3) instead of pow(2, 3) - ---------------------------------------- - -*log10(<number>) - -Returns log base 10 of the number. - -Note: The value is truncated to integer. - -Example: - .@i = log10(100); // .@i will be 2 - ---------------------------------------- - -*sqrt(<number>) - -Returns square-root of number. - -Note: The value is truncated to integer. - -Example: - .@i = sqrt(25); // .@i will be 5 - ---------------------------------------- - -*distance(<x0>, <y0>, <x1>, <y1>) - -Returns distance between 2 points. - -Note: When Hercules is configured to use circular areas, the Euclidean distance -is returned, otherwise the Chebyshev distance. The value is truncated to -integer. - -Example: - .@i = distance(100, 200, 101, 202); - ---------------------------------------- - -*min(<number>{, <number>...<number>}) -*max(<number>{, <number>...<number>}) - -Returns the smallest (or biggest) from the set of given numbers. - -Example: - .@minimum = min(1, -6, -2, 8, 2); // .@minimum will be equal to -6 - .@maximum = max(0, 5, 10, 4); // .@maximum will be equal to 10 - .@level = min(BaseLevel, 70); // .@level will be the character's base level, capped to 70 - ---------------------------------------- - -*md5("<string>") - -Returns the md5 checksum of a number or string. - -Example: - mes md5(12345); - mes md5("12345"); // Will both display 827ccb0eea8a706c4c34a16891f84e7b - mes md5("qwerty");// Will display d8578edf8458ce06fbc5bb76a58c5ca4 - ---------------------------------------- - -*swap(<variable>, <variable>) - -Swap the value of 2 variables. Both sides must be same integer or string type. - -Example: - .@var1 = 111; - .@var2 = 222; - swap(.@var1, .@var2); - mes("var1 = "+ .@var1); // return 222 - mes("var2 = "+ .@var2); // return 111 - ---------------------------------------- - -*query_sql("your MySQL query"{, <array variable>{, <array variable>{, ...}}}) -*query_logsql("your MySQL query"{, <array variable>{, <array variable>{, ...}}}) - -Executes an SQL query. A 'select' query can fill array variables with up -to 128 rows of values, and will return the number of rows (the array size). - -Note that query_sql() runs on the main database while query_logsql() runs -on the log database. - -Example: - .@nb = query_sql("select name, fame from `char` ORDER BY fame DESC LIMIT 5", .@name$, .@fame); - mes("Hall Of Fame: TOP5"); - mes("1."+.@name$[0]+"("+.@fame[0]+")"); // Will return a person with the biggest fame value. - mes("2."+.@name$[1]+"("+.@fame[1]+")"); - mes("3."+.@name$[2]+"("+.@fame[2]+")"); - mes("4."+.@name$[3]+"("+.@fame[3]+")"); - mes("5."+.@name$[4]+"("+.@fame[4]+")"); - ---------------------------------------- - -*escape_sql(<value>) - -Converts the value to a string and escapes special characters so that it's -safe to use in query_sql(). Returns the escaped form of the given value. - -Example: - .@str$ = "John's Laptop"; - .@esc_str$ = escape_sql(.@name$); // Escaped string: John\'s Laptop - ---------------------------------------- - -*setitemscript(<item id>, <"{ new item script }">{, <type>}) - -Set a new script bonus to the Item. Very useful for game events. -You can remove an item's itemscript by leaving the itemscript argument -empty. Returns 1 on success, or 0 on fail (item_id not found or new item -script is invalid). -Type can optionally be used indicates which script to set (default is 0): - 0 - Script - 1 - OnEquip_Script - 2 - OnUnequip_Script - -Example: - -setitemscript(Silver_Ring_, "{ if (isequipped(Santa's_Hat) == 0) end; if (getskilllv(AL_TELEPORT)) { skill(MC_IDENTIFY, 1); } else { skill(AL_TELEPORT, 1+isequipped(Santa's_Hat)); } }"); -setitemscript(Silver_Ring_, ""); - ---------------------------------------- - -*atoi("<string>") -*axtoi("<string>") -*strtol("string", base) - -These commands are used to convert strings to numbers. atoi() will -interpret given string as a decimal number (base 10), while axtoi() -interprets strings as hexadecimal numbers (base 16). strtol() lets -the user specify a base (valid range is between 2 and 36 inclusive, -or the special value0, which means auto-detection). - -The atoi() and strtol() functions conform to the C functions with the same -names, and axtoi() is the same as strtol(), with a base of 16. Results are -clamped to signed 32 bit int range (INT_MIN ~ INT_MAX) - -Example: - -.@var = atoi("11"); // Sets .@var to 11 -.@var = axtoi("FF"); // Sets .@var to 255 -mes(axtoi("11")); // Displays 17 (1 = 1, 10 = 16) -.@var = strtol("11", 10); // Sets .@var to 11 (11 base 10) -.@var = strtol("11", 16); // Sets .@var to 17 (11 base 16) -.@var = strtol("11", 0); // Sets .@var to 11 (11 base 10, auto-detected) -.@var = strtol("0x11", 0); // Sets .@var to 17 (11 base 16, auto-detected because of the "0x" prefix) -.@var = strtol("011", 0); // Sets .@var to 9 (11 base 8, auto-detected because of the "0" prefix) -.@var = strtol("11", 2); // Sets .@var to 3 (binary 11) - ---------------------------------------- - -*compare("<string>", "<substring>") - -This command returns true when the substring is in the main string or -false otherwise. This command is not case sensitive. - -Examples: - -//dothis(); will be executed ('Bloody Murderer' contains 'Blood'). - if (compare("Bloody Murderer", "Blood")) - dothis(); -//dothat(); will not be executed ('Blood butterfly' does not contain 'Bloody'). - if (compare("Blood Butterfly", "Bloody")) - dothat(); - ---------------------------------------- - -*strcmp("<string>", "<string>") - -This command compares two strings and is similar to strcmp in C. - -Return Values: - >0 : String 1 > String 2 - 0 : Strings are equal - <0 : String 1 < String 2 - -Examples: - .@a = strcmp("abcdef", "ABCDEF"); - if (.@a > 0){ - mes(".@a is greater than 0."); //Output is this. - } else { - mes(".@a is less or equal to 0"); - } - ---------------------------------------- - -*getstrlen("<string>") - -This function will return the length of the string given as an argument. -It is useful to check if anything input by the player exceeds name length -limits and other length limits and asking them to try to input something -else. - ---------------------------------------- - -*isstr(<argument>) - -This command checks if the given <argument> is a string (1), -an integer (0) or something else (2). - -Example: - - isstr(69); // outputs 0 - isstr("69"); // outputs 1 - ---------------------------------------- - -*getdatatype(<argument>) - -This command returns the raw type of the given <argument>. Unlike -isstr, this command does not evaluate the argument. The returned type -is bitmasked. - -types include: - - DATATYPE_NIL - DATATYPE_STR - DATATYPE_INT - DATATYPE_CONST - DATATYPE_PARAM - DATATYPE_VAR - DATATYPE_LABEL - -Example: - - getdatatype() // DATATYPE_NIL - getdatatype("foo") // DATATYPE_STR - getdatatype(@foo$) // (DATATYPE_VAR | DATATYPE_STR) - ---------------------------------------- - -*data_to_string(<data>) - -Returns a string representation of the given data, similar to the .toString() -method in JavaScript. - -Example: - - data_to_string(DATATYPE_VAR) // "DATATYPE_VAR" - data_to_string(.@foo) // ".@foo" - ---------------------------------------- - -*charisalpha("<string>", <position>) - -This function will return true if the character number Position in the given -string is a letter, false if it isn't a letter but a digit or a space. -The first letter is position 0. - ---------------------------------------- - -*charat(<string>, <index>) - -Returns char at specified index. If index is out of range, returns an -empty string. - -Example: - - charat("This is a string", 10); //returns "s" - ---------------------------------------- - -*chr(<int>) - -Returns a char from its ASCII value. - -Example: - - chr(99); //returns "c" - ---------------------------------------- - -*ord(<chr>) - -Returns the ASCII value of char <chr>. - -Example: - - ord("c"); //returns 99 - ---------------------------------------- - -*setchar(<string>, <char>, <index>) - -Returns the original string with the char at the specified index set to -the specified char. If index is out of range, the original string will be -returned. Only the 1st char in the <char> parameter will be used. - -Example: - - setchar("Cat", "B", 0); //returns "Bat" - ---------------------------------------- - -*insertchar(<string>, <char>, <index>) - -Returns the original string with the specified char inserted at the -specified index. If index is out of range, the char will be inserted on -the end of the string that it is closest. Only the 1st char in the <char> -parameter will be used. - -Example: - - insertchar("laughter", "s", 0); //returns "slaughter" - ---------------------------------------- - -*delchar(<string>, <index>) - -Returns the original string with the char at the specified index removed. -If index is out of range, original string will be returned. - -Example: - - delchar("Diet", 3); //returns "Die" - ---------------------------------------- - -*strtoupper(<string>) -*strtolower(<string>) - -Returns the specified string in it's uppercase/lowercase form. -All non-alpha characters will be preserved. - -Example: - - strtoupper("The duck is blue!!"); //returns "THE DUCK IS BLUE!!" - ---------------------------------------- - -*charisupper(<string>, <index>) -*charislower(<string>, <index>) - -Returns true if character at specified index of specified string is -uppercase for charisupper() or lowercase for charislower(). Otherwise, false. -Characters not of the alphabelt will return false. - -Example: - - charisupper("Hercules", 0); //returns 1 - ---------------------------------------- - -*substr(<string>, <start_index>, <end_index>) - -Returns the sub-string of the specified string inclusively between the set -indexes. If indexes are out of range, or the start index is after the end -index, an empty string will be returned. - -Example: - - substr("foobar", 3, 5); //returns "bar" - ---------------------------------------- - -*explode(<dest_array>, <string>, <delimiter>) - -Breaks a string up into substrings based on the specified delimiter. -Substrings will be stored within the specified string array. Only the 1st -char of the delimiter parameter will be used. If an empty string is passed -as a delimiter, the string will be placed in the array in its original -form, without any changes. Return the number of elements written to -<dest_array>. - -Example: - - .@num_elements = explode(.@my_array$, "Explode:Test:1965:red:PIE", ":"); - //.@my_array$ contents will be... - //.@my_array$[0]: "Explode" - //.@my_array$[1]: "Test" - //.@my_array$[2]: "1965" - //.@my_array$[3]: "red" - //.@my_array$[4]: "PIE" - //.@num_elements: 5 - ---------------------------------------- - -*implode(<string_array>{, <glue>}) - -Combines all substrings within the specified string array into a single -string. If the glue parameter is specified, it will be inserted inbetween -each substring. - -Example: - setarray(.@my_array$[0], "This", "is", "a", "test"); - implode(.@my_array$, " "); //returns "This is a test" - ---------------------------------------- - -*sprintf(<format>{, param{, param{, ...}}}) - -C style sprintf. The resulting string is returned. - -The format string can contain placeholders (format specifiers) using the -following structure: - - %[parameter][flags][width]type - -The following format specifier types are supported: - -%%: Prints a literal '%' (special case, doesn't support parameter, flag, width) -%d, %i: Formats the specified value as a decimal signed number -%u: Formats the specified value as a decimal unsigned number -%x: Formats the specified value as a hexadecimal (lowercase) unsigned number -%X: Formats the specified value as a hexadecimal (uppercase) unsigned number -%o: Formats the specified value as an octal unsigned number -%s: Formats the specified value as a string -%c: Formats the specified value as a character (only uses the first character - of strings) - -The following format specifier types are not supported: - -%n (not implemented due to safety concerns) -%f, %F, %e, %E, %g, %G (the script engine doesn't use floating point values) -%p (the script engine doesn't use pointers) -%a, %A (not supported, use 0x%x and 0x%X respectively instead) - -An ordinal parameter can be specified in the form 'x$' (where x is a number), -to reorder the output (this may be useful in translated strings, where the -sentence order may be different from the original order). Example: - - // Name, level, job name - mes(sprintf("Hello, I'm %s, a level %d %s", strcharinfo(PC_NAME), BaseLevel, jobname(Class))); - -When translating the sentence to other languages (for example Italian), -swapping some arguments may be appropriate, and it may be desirable to keep the -actual arguments in the same order (i.e. when translating through the HULD): - - // Job name is printed before the level, although they're specified in the opposite order. - // Name, job name, level - mes(sprintf("Ciao, io sono %1$s, un %3$s di livello %2$d", strcharinfo(PC_NAME), BaseLevel, jobname(Class))); - -The supported format specifier flags are: - -- (minus): Left-align the output of this format specifier. (the default is to - right-align the output). -+ (plus): Prepends a plus for positive signed-numeric types. positive = '+', - negative = '-'. -(space): Prepends a space for positive signed-numeric types. positive = ' ', - negative = '-'. This flag is ignored if the '+' flag exists. -0 (zero): When a field width option is specified, prepends zeros for numeric - types. (the default prepends spaces). -A field width can be specified. - - mes(sprintf("The temperature is %+d degrees Celsius", .@temperature)); // Keeps the '+' sign in front of positive values - .@map_name$ = sprintf("quiz_%02d", .@i); // Keeps the leading 0 in "quiz_00", etc - -A field width may be specified, to ensure that 'at least' that many characters -are printed. If a star ('*') is specified as width, then the width is read as -argument to the sprintf() function. This also supports positional arguments. - - sprintf("%04d", 10) // Returns "0010" - sprintf("%0*d", 5, 10) // Returns "00010" - sprintf("%5d", 10) // Returns " 10" - sprintf("%-5d", 10) // Returns "10 " - sprintf("%10s", "Hello") // Returns " Hello"; - sprintf("%-10s", "Hello") // Returns "Hello "; - -Precision ('.X') and length ('hh', 'h', 'l', 'll', 'L', 'z', 'j', 't') -specifiers are not implemented (not necessary for the script engine purposes) - -Example: - .@format$ = "The %s contains %d monkeys"; - dispbottom(sprintf(.@format$, "zoo", 5)); - //prints "The zoo contains 5 monkeys" - - dispbottom(sprintf(.@format$, "barrel", 82)); - //prints "The barrel contains 82 monkeys" - ---------------------------------------- - -*sscanf(<string>, <format>{, param{, param{, ...}}}) - -C style sscanf. All C format specifiers are supported. -More info: sscanf @ www.cplusplus.com. The number of params is only -limited by Hercules' script engine. - -Example: - sscanf("This is a test: 42 foobar", "This is a test: %d %s", .@num, .@str$); - dispbottom(.@num + " " + .@str$); //prints "42 foobar" - ---------------------------------------- - -*strpos(<haystack>, <needle>{, <offset>}) - -PHP style strpos. Finds a substring (needle) within a string (haystack). -The offset parameter indicates the index of the string to start searching. -Returns index of substring on successful search, else -1. -Comparison is case sensitive. - -Example: - strpos("foobar", "bar", 0); //returns 3 - strpos("foobarfoo", "foo", 0); //returns 0 - strpos("foobarfoo", "foo", 1); //returns 6 - ---------------------------------------- - -*replacestr(<input>, <search>, <replace>{, <usecase>{, <count>}}) - -Replaces all instances of a search string in the input with the specified -replacement string. By default is case sensitive unless <usecase> is set -to false. If specified it will only replace as many instances as specified -in the count parameter. - -Example: - replacestr("testing tester", "test", "dash"); //returns "dashing dasher" - replacestr("Donkey", "don", "mon", false); //returns "monkey" - replacestr("test test test test test", "test", "yay", false, 3); //returns "yay yay yay test test" - ---------------------------------------- - -*countstr(<input>, <search>{, <usecase>}) - -Counts all instances of a search string in the input. By default is case -sensitive unless <usecase> is set to false. - -Example: - countstr("test test test Test", "test"); //returns 3 - countstr("cake Cake", "Cake", false); //returns 2 - ---------------------------------------- - -*setfont(<font>) - -This command sets the current RO client interface font to one of the fonts -stored in data\*.eot by using an ID of the font. When the ID of the -currently used font is used, default interface font is used again. - - 0 - Default - 1 - RixLoveangel - 2 - RixSquirrel - 3 - NHCgogo - 4 - RixDiary - 5 - RixMiniHeart - 6 - RixFreshman - 7 - RixKid - 8 - RixMagic - 9 - RixJJangu - ---------------------------------------- - -*showdigit(<value>{, <type>}) - -Displays given numeric 'value' in large digital clock font on top of the -screen. The optional parameter 'type' specifies visual aspects of the -"clock" and can be one of the following values: - - 0 - Displays the value for 5 seconds (default). - 1 - Incremental counter (1 tick/second). - 2 - Decremental counter (1 tick/second). Does not stop at zero, but - overflows. - 3 - Decremental counter (1 tick/second). Two digits only, stops at - zero. - -For type 1 and 2 the start value is set by using negative number of the -one intended to set (ex. -10 starts the counter at 10 seconds). Except for -type 3 the value is interpreted as seconds and formatted as time in days, -hours, minutes and seconds. Note, that the official script command does -not have the optional parameter. - - // displays 23:59:59 for 5 seconds - showdigit(86399); - - // counter that starts at 60 and runs for 60 seconds - showdigit(60, 3); - ---------------------------------------- - -* The Pet AI commands - -These commands will only work if the invoking character has a pet, and are -meant to be executed from pet scripts. They will modify the pet AI -decision-making for the current pet of the invoking character, and will -NOT have any independent effect by themselves, which is why only one of -them each may be in effect at any time for a specific pet. A pet may -have petloot(), petskillbonus(), petskillattack() and petskillsupport() at the -same time. - -*petskillbonus(<bonus type>, <value>, <duration>, <delay>) - -This command will make the pet give a bonus to the owner's stat (bonus -type - bInt, bVit, bDex, bAgi, bLuk, bStr, bSpeedRate - for a full list, see the -'doc/constants.md' under 'Bonuses / Parameter IDs'). - -*petrecovery(<status type>, <delay>) - -This command will make the pet cure a specified status condition. The -curing actions will occur once every <delay> seconds. For a full list of -status conditions that can be cured, see the list of 'Status Changes' status -condition constants in 'doc/constants.md' - -*petloot(<max items>) - -This command will turn on pet looting, with a maximum number of items to -loot specified. Pet will store items and return them when the maximum is -reached or when pet performance is activated. - -*petskillsupport(<skill id>, <skill level>, <delay>, <percent hp>, <percent sp>) -*petskillsupport("<skill name>", <skill level>, <delay>, <percent hp>, <percent sp>) - -This will make the pet use a specified support skill on the owner whenever -the HP and SP are below the given percent values, with a specified delay -time between activations. The skill numbers are as per -'db/(pre-)re/skill_db.txt'. -It's not quite certain who's stats will be used for the skills cast, the -character's or the pets. Probably, Skotlex can answer that question. - -*petskillattack(<skill id>, <damage>, <number of attacks>, <rate>, <bonusrate>) -*petskillattack("<skill name>", <damage>, <number of attacks>, <rate>, <bonusrate>) - -This command will make the pet cast an attack skill on the enemy the pet's -owner is currently fighting. Skill IDs and levels are as per petskillsupport(). -If <number of attacks> is specified different than 0, it will make the pet cast -the skill with a fixed amount of damage inflicted and the specified number of -attacks. A value of zero uses the skill's defaults. - -All commands with delays and durations will only make the behavior active -for the specified duration of seconds, with a delay of the specified -number of seconds between activations. Rates are a chance of the effect -occurring and are given in percent. 'bonusrate' is added to the normal -rate if the pet intimacy is at the maximum possible. - -The behavior modified with the above mentioned commands will only be -exhibited if the pet is loyal and appropriate configuration options are -set in 'conf/map/battle.conf'. - -Pet scripts in the database normally run whenever a pet of that type -hatches from the egg. Other commands usable in item scripts (see bonus()) -will also happily run from pet scripts. Apparently, the pet-specific -commands will also work in NPC scripts and modify the behavior of the -current pet up until the pet is hatched again. (Which will also occur when -the character is logged in again with the pet still out of the egg.) It is -not certain for how long the effect of such command running from an NPC -script will eventually persist, but apparently, it is possible to usefully -employ them in usable item scripts to create pet buffing items. - -Nobody tried this before, so you're essentially on your own here. - ---------------------------------------- - -*bpet() - -This command opens up a pet hatching window on the client connected to the -invoking character. It is used in item script for the pet incubators and -will let the player hatch an owned egg. If the character has no eggs, it -will just open up an empty incubator window. -This is still usable outside item scripts. - ---------------------------------------- - -*makepet(<pet id>) - -This command will create a pet egg and put it in the invoking character's -inventory. The kind of pet is specified by pet ID numbers listed in -'db/pet_db.txt'. The egg is created exactly as if the character just -successfully caught a pet in the normal way. - - // This will make you a poring: - makepet(PORING); - -Notice that you absolutely have to create pet eggs with this command. If -you try to give a pet egg with getitem(), pet data will not be created by -the char server and the egg will disappear when anyone tries to hatch it. - ---------------------------------------- - -*homshuffle() - -This will recalculate the homunculus stats according to its level, of the -current invoking character. - ---------------------------------------- - -*setcell("<map name>", <x1>, <y1>, <x2>, <y2>, <type>, <flag>) - -Each map cell has several 'flags' that specify the properties of that cell. -These include terrain properties (walkability, shootability, presence of -water), skills (basilica, land protector, ...) and other (NPC nearby, no -vending, ...). -Each of these can be 'on' or 'off'. Together they define a cell's behavior. - -This command lets you alter these flags for all map cells in the specified -(x1,y1)-(x2,y2) rectangle. -'type' defines which flag to modify. Possible options include cell_walkable, -cell_shootable, cell_basilica. For a full list, see 'doc/constants.md'. -'flag' can be false (clear flat) or true (set flag). - -Example: - - setcell("arena", 0, 0, 300, 300, cell_basilica, true); - setcell("arena", 140, 140, 160, 160, cell_basilica, false); - setcell("arena", 135, 135, 165, 165, cell_walkable, false); - setcell("arena", 140, 140, 160, 160, cell_walkable, true); - -This will add a makeshift ring into the center of the map. The ring will -be surrounded by a 5-cell wide 'gap' to prevent interference from outside, -and the rest of the map will be marked as 'basilica', preventing observers -from casting any offensive skills or fighting among themselves. Note that -the wall will not be shown nor known client-side, which may cause movement -problems. - -Another example: - -OnBarricadeDeploy: - setcell("schg_cas05", 114, 51, 125, 51, cell_walkable, false); - end; -OnBarricadeBreak: - setcell("schg_cas05", 114, 51, 125, 51, cell_walkable, true); - end; - -This could be a part of the WoE:SE script, where attackers are not allowed -to proceed until all barricades are destroyed. This script would place and -remove a nonwalkable row of cells after the barricade mobs. - ---------------------------------------- - -*checkcell("<map name>", <x>, <y>, <type>) - -This command will return true or false, depending on whether the specified cell -has the 'type' flag set or not. There are various types to check, all -mimicking the server's cell_chk enumeration. The types can be found in -'doc/constants.md' under 'Cell checks'. - -The meaning of the individual types can be confusing, so here's an -overview: - - cell_chkwall/water/cliff - these check directly for the 'terrain component' of the specified cell - - cell_chkpass/reach/nopass/noreach - passable = not wall & not cliff, reachable = passable - wrt. no-stacking mod - - cell_chknpc/basilica/landprotector/novending/nochat - these check for specific dynamic flags (name indicates what they do) - -Example: - - mes("Pick a destination map."); - input(.@map$); - mes("Alright, now give me the coordinates."); - input(.@x); - input(.@y); - if (!checkcell(.@map$, .@x, .@y, cell_chkpass)) { - mes("Can't warp you there, sorry!"); - close(); - } else { - mes("Ok, get ready..."); - close2(); - warp(.@map$, .@x, .@y); - end; - } - ---------------------------------------- - -*setwall("<map name>", <x>, <y>, <size>, <dir>, <shootable>, "<name>") -*delwall("<name>") - -Creates an invisible wall, an array of setcell() starting from x,y and -doing a line of the given size in the given direction. The difference with -setcell is this one update client part too to avoid the glitch problem. -Directions are the same as NPC sprite facing directions: (DIR_ constants). - ---------------------------------------- - -*readbook(<book id>, <page>) - -This will open a book item at the specified page. - ---------------------------------------- - -*rodex_sendmail(<char id>, "<sender name>", "<title>", "<body>"{, <zeny>{, <item1>, <amount1>{, <item2>, <amount2>{, <item3>, <amount3>{, <item4>, <amount4>{, <item5>, <amount5>}}}}}}) -*rodex_sendmail_acc(<account id>, "<sender name>", "<title>", "<body>"{, <zeny>{, <item1>, <amount1>{, <item2>, <amount2>{, <item3>, <amount3>{, <item4>, <amount4>{, <item5>, <amount5>}}}}}}) - -This will send a mail using the RoDEX mail system, in newer clients the message will be marked as a NPC mail (that you can't reply). -If items and zeny are specified, they will be added as attachments to the message. - -For examples of usage, see /doc/sample/npc_rodex.txt - ---------------------------------------- - -*rodex_sendmail2(<char id>, "<sender name>", "<title>", "<body>"{, <zeny>{, <item1>, <amount1>, <refine1>, <attribute1>, <card0_1>, <card1_1>, <card2_1>, <card3_1>{,<item2>, <amount2>, <refine2>, <attribute2>, <card0_2>, <card1_2>, <card2_2>, <card3_2>{,<item3>, <amount3>, <refine3>, <attribute3>, <card0_3>, <card1_3>, <card2_3>, <card3_3>{,<item4>, <amount4>, <refine4>, <attribute4>, <card0_4>, <card1_4>, <card2_4>, <card3_4>{,<item5>, <amount5>, <refine5>, <attribute5>, <card0_5>, <card1_5>, <card2_5>, <card3_5>}}}}}}) -*rodex_sendmail_acc2(<account id>, "<sender name>", "<title>", "<body>"{, <zeny>{, <item1>, <amount1>, <refine1>, <attribute1>, <card0_1>, <card1_1>, <card2_1>, <card3_1>{,<item2>, <amount2>, <refine2>, <attribute2>, <card0_2>, <card1_2>, <card2_2>, <card3_2>{,<item3>, <amount3>, <refine3>, <attribute3>, <card0_3>, <card1_3>, <card2_3>, <card3_3>{,<item4>, <amount4>, <refine4>, <attribute4>, <card0_4>, <card1_4>, <card2_4>, <card3_4>{,<item5>, <amount5>, <refine5>, <attribute5>, <card0_5>, <card1_5>, <card2_5>, <card3_5>}}}}}}) - -These are more flexible versions of rodex_sendmail and rodex_sendmail_acc. - -This will send a mail using the RoDEX mail system, in newer clients the message will be marked as a NPC mail (that you can't reply). -If items and zeny are specified, they will be added as attachments to the message. -Check getitem2 command for more information of the extra parameters. - -For examples of usage, see /doc/sample/npc_rodex.txt - ---------------------------------------- -//===================================== -7 - Instance-Related Commands -//===================================== ---------------------------------------- - -*instance_create("<instance name>", <owner id>{, <optional owner_type>}) - -Create an instance using the name "<instance name>" for the <owner_id> of -owner_type (when not provided, defaults to IOT_PARTY). Most instance_* -commands are used in conjunction with this command and depend on the -ID this command returns. - -Example: - // Store the Party ID of the invoking character. - .@party_id = getcharid(CHAR_ID_PARTY); - - // Attempt to create an instance using that party ID. - .@id = instance_create("Endless Tower", .@party_id); - if (.@id == -1) { // Invalid type - not used anymore - // ... - } else if (.@id == -2) { // Invalid Party ID - // ... - } else if (.@id == -3) { // No free instances (MAX_INSTANCE exceeded) - // ... - } else if (.@id == -4) { // Already exists - // ... - } else (.@id < 0) { // Unspecified error while queuing instance. - // ... - } - ---------------------------------------- - -*instance_destroy({<instance id>}) - -Destroys instance with the ID <instance id>. If no ID is specified, the -instance the script is attached to is used. If in the end no instance_id, -is found the command halts the script execution. - ---------------------------------------- - -*instance_attachmap("<map name>", <instance id>{, <use base name>{, "<new map name>"}}) - -Attaches the map "<map name>" to the instance specified with -<instance id>. The optional parameter specifies, whether a map requires -emulation for instancing (true) or not (false = default). if use base name is specified, -and "<new map name>" too the server will instance the map under the "<new map name>", -name. - -Returns the resulting map name on success or an empty string on failure. - -Example: - instance_attachmap("prontera", .@instance_id, true, "via"); -^ the above creates a instance (or clone) of prontera, on a map called "via" - ---------------------------------------- - -*instance_detachmap("<map name>"{, <instance id>}) - -Detach the map "<map name>" to the instance with the <instance id>. If no -ID is specified, the instance the script is attached to is used. If in the -end no instance_id is found the command halts the script execution. - ---------------------------------------- - -*instance_init(<instance id>) - -Initializes the instance given by <instance id>. This copies all NPCs from -the source maps to the instanced maps. - ---------------------------------------- - -*instance_announce(<instance id>, "<text>", <flag>{, <fontColor>{, <fontType>{, <fontSize>{, <fontAlign>{, <fontY>}}}}}) - -Works like announce, but has the <instance id> parameter. If instance id -is -1, the instance the script is attached to is used. If in the -end no instance_id is found the command halts the script execution. - ---------------------------------------- - -*instance_attach(<instance id>) - -Attaches the current script to the instance given by <instance id>. - ---------------------------------------- - -*instance_npcname("<npc name>"{, <instance id>}) - -Retrieves the unique name given to a copy of an NPC given by "<npc name>" -in an instance specified <instance id>. If no ID is specified, the -instance the script is attached to is used. If in the end no instance_id, -is found the command halts the script execution. - ---------------------------------------- - -*has_instance("<map name>"{, <instance id>}) - -Checks whether or not the given map belongs to specified instance. If no -ID is specified, the instance the script is attached to is used. If the -script is not attached to an instance, it'll try to check whether the, -player attached to the script possesses an instance with a map matching -"<map name>". If in the end no instance_id is found the command halts the, -script execution. - -Returns name of the instanced map on success, otherwise an empty string. - ---------------------------------------- - -*has_instance2("<map name>") - -Same as has_instance, with exception it returns the instance id of the map, -as long as the user is assigned to a instance containing that map. -It will return -1 upon failure, valid instance ids are >= 0. - ---------------------------------------- - -*instance_id() - -Retrieves the instance id of the script it is being run on. - ---------------------------------------- - -*instance_warpall("<map name>", <x>, <y>{, <instance id>}) - -Warps all players in the instance <instance id> to <map name> at given -coordinates. If no ID is specified, the instance the script is attached to -is used. If in the end no instance_id is found the command halts the, -script execution. - ---------------------------------------- - -*instance_set_timeout(<alive timeout>, <idle timeout>{, <instance id>}) - -Sets the timeout values for an instance given by <instance id>. If no ID -is specified, the instance the script is attached to is used. If in the end, -no instance_id is found the command halts the script execution. - -Parameter <alive timeout> specifies the total amount of time the instance -will exist. Parameter <idle timeout> specifies how long players have, when -they are outside of the instance, until it is destroyed. - -Both timeout values are in seconds. - ---------------------------------------- - -*instance_check_party(<party id>{, <amount>{, <min>{, <max>}}}) - -This function checks if a party meets certain requirements, returning true if -all conditions are met and false otherwise. It will only check online -characters. - -amount - number of online party members (default is 1). -min - minimum level of all characters in the party (default is 1). -max - maximum level of all characters in the party (default is max - level in conf). - -Example: - -if (instance_check_party(getcharid(CHAR_ID_PARTY), 2, 2, 149)) { - mes("Your party meets the Memorial Dungeon requirements."); - mes("All online members are between levels 1-150 and at least two are online."); - close(); -} else { - mes("Sorry, your party does not meet the requirements."); - close(); -} - ---------------------------------------- - -*instance_check_guild(<guild_id>{, <amount>{, <min>{, <max>}}}) - -This function checks if a guild meets certain requirements, returning true if -all conditions are met and false otherwise. it will only check online characters. - -amount - number of online guild members (default is 1). -min - minimum level of all characters in the guild (default is 1). -max - maximum level of all characters in the guild (default is max level in conf). - -Example: - if (instance_check_guild(getcharid(CHAR_ID_GUILD), 2, 1, 150)) { - mes("Your guild meets the Memorial Dungeon requirements."); - mes("All online members are between levels 1-150 and at least two are online."); - close(); - } else { - mes("Sorry, your guild does not meet the requirements."); - close(); - } - ---------------------------------------- -*instance_set_respawn(<map_name>, <x>, <y>{, <instance_id>}) - -Updates the 'reload spawn' position of a instance, -that is where players in the instance are sent to upon @reloadscript, -uses the npc instance (if any) when instance_id is not provided, -handy to update a instance's progress so that when/if @reloadscript happens -the damage to the players progress is reduced. -It is most effective when used with instance variables (which are @reloadscript persistent) - -If a player warps into a instance before this command has been used, -it will use the player's warp destination as the initial respawn point, -it can of course be modified by using this script command at any point. - ---------------------------------------- -*instance_mapname("<map name>"{, <instance id>}) - -Returns the unique name of the instanced map. If no instance ID is specified, -the instance the script is attached to is used. If the script is not attached to -an instance, the instance of the currently attached player's party is used. If -that fails, the command returns an empty string instead. - - ---------------------------------------- -//===================================== -7 - End of Instance-Related Commands -//===================================== ---------------------------------------- - - ---------------------------------------- -//===================================== -8 - Quest Log-Related Commands -//===================================== ---------------------------------------- - -*questinfo(<Icon> {, <Map Mark Color>}) - -This is esentially a showevent() that supports different conditions that can be set using setquestinfo(). -Use this only in an OnInit label. -For Icon, use one of the following: - -No Icon : QTYPE_NONE -! Quest Icon : QTYPE_QUEST -? Quest Icon : QTYPE_QUEST2 -! Job Icon : QTYPE_JOB -? Job Icon : QTYPE_JOB2 -! Event Icon : QTYPE_EVENT -? Event Icon : QTYPE_EVENT2 -Warg : QTYPE_WARG -Warg Face : QTYPE_WARG2 (Only for packetver >= 20120410 && packetver < 20170315) - -- Only for packetver >= 20170315 -Click Me Icon : QTYPE_CLICKME -! Daily Quest Icon : QTYPE_DAILYQUEST -! Green Event Icon : QTYPE_EVENT3 -! Job Quest Icon : QTYPE_JOBQUEST -Jumping Poring : QTYPE_JUMPING_PORING - -Map Mark Color, when used, creates a mark in the user's mini map on the position of the NPC, -the available color values are: - -0 - No Marker -1 - Yellow Marker -2 - Green Marker -3 - Purple Marker - -When a user shows up on a map, each NPC is checked for questinfo that has been set. -If questinfo is present, it will check if the quest has been started, if it has not, the bubble will appear. - -Example - izlude,100,100,4 script Test 844,{ - mes("[Test]"); - mes("Hello World."); - close(); - - OnInit: - questinfo(QTYPE_QUEST); - end; - } - ---------------------------------------- - -*setquestinfo(<Type> {, <Values...>}) - -Use this command ONLY after a questinfo() -it allows you to set multiple required conditions for the quest bubble to show up. - -supported types: values - QINFO_JOB: job_id - QINFO_SEX: sex - QINFO_BASE_LEVEL: min, max - QINFO_JOB_LEVEL: min, max - QINFO_ITEM: item_id, min amount, max amount // append to the items list on each use - QINFO_HOMUN_LEVEL: min - QINFO_HOMUN_TYPE: homunculus_type (0 - regular, 1 - evolved, 2 - S) - QINFO_QUEST: quest_id, state // append to the quests list on each use - QINFO_MERCENARY_CLASS: mercenary_class - ---------------------------------------- - -*setquest(<ID>{, <Time Limit>}) - -Place quest of <ID> in the users quest log, the state of which is "active". -If Time Limit is given, this quest will have its expire time set to <Time Limit>, an UNIX epoch time, -ignoring quest_db setting. - -If questinfo() is set, and the same ID is specified here, the icon will be cleared when the quest is set. - ---------------------------------------- - -*completequest(<ID>{, <ID2>}) - -Change the state for the given quest <ID> to "complete" and remove from -the users quest log. - -If a second quest id of greater value is specified, all quests between the two -will be completed. - ---------------------------------------- - -*erasequest(<ID>{, <ID2>}) - -Remove the quest of the given <ID> from the user's quest log. - -If a second quest id of greater value is specified, all quests between the two -will be erased. - ---------------------------------------- - -*changequest(<ID>, <ID2>) - -Remove quest of the given <ID> from the user's quest log. -Add quest of the <ID2> to the the quest log, and the state is "active". - ---------------------------------------- - -*questprogress(<ID>{, <type>}) - -If no additional argument supplied, return the state of the quest: - 0 = Quest not started (not in quest log) - 1 = Quest has been given - 2 = Quest completed - -If <type> PLAYTIME is supplied: - 0 = Quest not started (not in quest log) - 1 = The time limit has not yet been reached - 2 = The time limit has been reached - -If <type> HUNTING is supplied: - 0 = Quest not started (not in quest log) - 1 = Player hasn't killed all of the target monsters - 2 = Player has killed all of the target monsters - ---------------------------------------- - -*questactive(<ID>) - -Check whether the given quest is in its active state. - -Returns true if the quest is active, false otherwise (quest not started, -inactive or completed) - ---------------------------------------- - -*showevent(<icon>{, <mark color>}) - -Show an emotion on top of a NPC, and optionally, -a colored mark in the mini-map like viewpoint(). -This is used to indicate that a NPC has a quest or an event to -a certain player. - -Available Icons: - -Remove Icon : QTYPE_NONE -! Quest Icon : QTYPE_QUEST -? Quest Icon : QTYPE_QUEST2 -! Job Icon : QTYPE_JOB -? Job Icon : QTYPE_JOB2 -! Event Icon : QTYPE_EVENT -? Event Icon : QTYPE_EVENT2 -Warg : QTYPE_WARG -Warg Face : QTYPE_WARG2 (Only for packetver >= 20120410 && packetver < 20170315) - -- Only for packetver >= 20170315 -Click Me Icon : QTYPE_CLICKME -! Daily Quest Icon : QTYPE_DAILYQUEST -! Green Event Icon : QTYPE_EVENT3 -! Job Quest Icon : QTYPE_JOBQUEST -Jumping Poring : QTYPE_JUMPING_PORING - -Mark Color: -0 - No Mark -1 - Yellow Mark -2 - Green Mark -3 - Purple Mark - ---------------------------------------- -//===================================== -8 - End of Quest Log-Related Commands -//===================================== ---------------------------------------- - - ---------------------------------------- -//===================================== -9 - Battlegrounds-Related Commands -//===================================== ---------------------------------------- - -*waitingroom2bg_single(<battle group>, "<mapname>", <x>, <y>, "<npc name>") - -Adds the first waiting player from the chat room of given NPC to an -existing battleground group and warps it to specified coordinates on given -map. - ---------------------------------------- - -*waitingroom2bg("<mapname>", <x>, <y>, "<On Quit Event>", "<On Death Event>"{, "<npc name>"}) - -<Mapname> and X Y coordinates refer to where the "respawn" base is, where -the player group will respawn when they die. -<On Quit Event> refers to an NPC label that attaches to the character and -is run when they relog. -<On Death Event> refers to an NPC label that attaches to the character and -is run when they die. Can be "" for empty. - -If "-" is supplied for <mapname>, this will remove the 1 second automatic -respawn on the battleground map. This allows for better manipulation of -<On Death Event>. The player will have to be warped to desired location -at the end of <On Death Event>. - -Unlike the prior command, the latter will attach a GROUP in a waiting room -to the battleground, and sets the array $@arenamembers[0] where 0 holds -the IDs of the first group, and 1 holds the IDs of the second. - -If the option parameter is left out, the waiting room of the current NPC -is used. - -Example: - // Battle Group will be referred to as $@KvM01BG_id1, and when they - // die, respawn at bat_c01,52,129. - $@KvM01BG_id1 = waitingroom2bg("bat_c01", 52, 129, "KvM01_BG::OnGuillaumeQuit", "KvM01_BG::OnGuillaumeDie"); - end; - ----------------------------------------- - -*bg_team_setxy(<Battle Group ID>, <x>, <y>) - -Update the respawn point of the given battle group to x, y on the same -map. The <Battle Group ID> can be retrieved using getcharid(CHAR_ID_BG). - -Example: - bg_team_setxy(getcharid(CHAR_ID_BG), 56, 212); - mapannounce("bat_a01", "Group [1] has taken the work shop, and will now respawn there.", bc_map, 0xFFCE00); - end; - ----------------------------------------- - -*bg_warp(<Battle Group>, "<Mapname>", <x>, <y>) - -Similar to warp command. -Place all members of <Battle Group> at <mapname> at x y. - -Example: - //place the battle group one for Tierra Gorge at starting position. - bg_warp($@TierraBG1_id1, "bat_a01", 352, 342); - end; - ----------------------------------------- - -*bg_monster(<Battle Group>, "<map name>", <x>, <y>, "<name to show>", <mob id>, "<event label>") - -Similar to monster() script command. -Spawn a monster with allegiance to the given battle group. -Does not allow for the summoning of multiple monsters. -Monsters are similar to that in War of Emperium, in that the specified -Battle group is considered friendly. - -Example: - // It can be used in two different ways. - bg_monster($@TierraBG1_id2, "bat_a01", 167, 50, "Food Depot", OBJ_B, "Feed Depot#1::OnMyMobDead"); - end; - - // Alternatively, you can set an ID for the monster using "set". - // This becomes useful when used with the command below. - $@Guardian_3 = bg_monster($@TierraBG1_id2, "bat_a01", 268, 204, "Guardian", B_S_GUARDIAN, "NPCNAME::OnMyMobDead"); - end; - ----------------------------------------- - -*bg_monster_set_team(<GID>, <Battle Group>) - -This command will change the allegiance if a monster in a battle ground. -GID can be set when spawning the monster via the bg_monster() command. - -Example: - -OnEnable: - mapannounce("bat_b01", "A guardian has been summoned for Battle Group 2!", bc_map, 0xFFCE00); - $@Guardian = bg_monster($@BG_2, "bat_a01", 268, 204, "Guardian", B_S_GUARDIAN, "NPCNAME::OnMyMobDead"); - initnpctimer(); - end; - -OnTimer1000: - stopnpctimer(); - mapannounce("bat_b01", "Erm, sorry about that! This monster was meant for Battle Group 1.", bc_map, 0xFFCE00); - bg_monster_set_team($@Guardian, $@BG_1); - end; - ----------------------------------------- - -*bg_leave() - -Removes attached player from their Battle Group. - ----------------------------------------- - -*bg_destroy(<Batte Group>) - -As the name says, destroys the battle group created for that battle ground. - ----------------------------------------- - -*areapercentheal("<mapname>", <x1>, <y1>, <x2>, <y2>, <hp>, <sp>) - -Not exactly limited to battleground use, this will restore HP/SP in a -defined area at a percentage. - -Example: - areapercentheal("bat_a01", 52, 208, 61, 217, 100, 100); - end; - ----------------------------------------- - -*bg_get_data(<Battle Group>, <type>) - -Retrieves data related to given battle group. Type can be one of the -following: - - 0 - Amount of players currently belonging to the group. - ----------------------------------------- - -*bg_getareausers(<battle group>, "<map_name>", <x0>, <y0>, <x1>, <y1>) - -Retrieves amount of players belonging to given battle group on given map -within an specified rectangular area. - ----------------------------------------- - -*bg_updatescore("<map_name>", <Guillaume Score>, <Croix Score>) - -This command will force the update of the displayed scoreboard. -It is only usable when the map is defined as a Type 2 Battleground: -mapflag%TAB%<map_name>%TAB%battleground%TAB%2 - ----------------------------------------- - -*bg_create_team("<map_name>", <Respawn X>, <Respawn Y>) - -This command will create a new BG Team. -When player dies, they will be respawned map_name,X,Y as mentioned. -If "-" is supplied for the map name, this will remove the 1 second automatic -respawn on the battleground map. - -Command will return -1 if BG Creation is failed, -else it will return the BG ID(Also known as TeamID). - ----------------------------------------- - -*bg_join_team(<Team_ID>{, <account_id>}) - -This command will make the attached player join to Team with ID as mentioned. -If account_id is provided, command will look for that player, instead of the attached player. - -Command will return -1 if Player is not found, 0 if join is failed, 1 upon successful. - ----------------------------------------- - -*bg_match_over("<Arena Name>"{, <Cancelled>}) - -This command will end the battleground Arena -(Arena Name as referred to, in conf/battlegrounds.conf) -If Cancelled is not provided, it will set the join delay, as mentioned in conf/battlegrounds.conf -else, it will just destroy the Teams and queue's. - -Command will return 0 when successful, else it will return 1. - ---------------------------------------- -//===================================== -9 - End of Battlegrounds-Related Commands -//===================================== ---------------------------------------- - - ---------------------------------------- -//===================================== -10 - Mercenary Commands -//===================================== ---------------------------------------- - -*mercenary_create(<class>, <contract time>) - -This command summons a mercenary of given class, for given amount of time -in milliseconds. Typically used in item scripts of mercenary scrolls. - ----------------------------------------- - -*mercenary_heal(<hp>, <sp>) - -This command works like heal(), but affects the mercenary of the currently -attached character. - ----------------------------------------- - -*mercenary_sc_start(<type>, <tick>, <val1>) - -This command works like sc_start(), but affects the mercenary of the -currently attached character. - ----------------------------------------- - -*mercenary_get_calls(<guild>) -*mercenary_set_calls(<guild>, <value>) - -Sets or gets the mercenary calls value for given guild for currently -attached character. Guild can be one or the following constants: - - ARCH_MERC_GUILD - SPEAR_MERC_GUILD - SWORD_MERC_GUILD - ----------------------------------------- - -*mercenary_get_faith(<guild>) -*mercenary_set_faith(<guild>, <value>) - -Sets or gets the mercenary faith value for given guild for currently -attached character. Guild can be one or the following constants: - - ARCH_MERC_GUILD - SPEAR_MERC_GUILD - SWORD_MERC_GUILD - ---------------------------------------- - -*getmercinfo(<type>{, <char id>}) - -Retrieves information about mercenary of the currently attached character. -If char id is given, the information of that character is retrieved -instead. Type specifies what information to retrieve and can be one of the -following: - - MERCINFO_ID - Mercenary Database ID - MERCINFO_CLASS - Mercenary Class - MERCINFO_NAME - Mercenary Name - MERCINFO_FAITH - Mercenary faith value for this mercenary's guild, if any - MERCINFO_CALLS - Mercenary calls value for this mercenary's guild, if any - MERCINFO_KILLCOUNT - Mercenary kill count - MERCINFO_LIFETIME - Mercenary remaining life time in mili-second - MERCINFO_LEVEL - Mercenary Level - MERCINFO_GID - Mercenary Game ID - -If the character does not have a mercenary, the command returns "" for MERCINFO_NAME -and 0 for all other types. - ---------------------------------------- -//===================================== -10 - End of Mercenary-Related Commands -//===================================== ---------------------------------------- - - ---------------------------------------- -//===================================== -11 - Queue-Related Commands -//===================================== ---------------------------------------- - -*queue() - -Creates a new queue instance and returns the created queue id. - ---------------------------------------- - -*queuesize(<queue_id>) - -Returns the amount of entries in the queue instance of <queue_id>. - ---------------------------------------- - -*queueadd(<queue_id>, <var_id>) - -Adds <var_id> to queue of <queue_id>. - -Returns false if <var_id> couldn't be added (was already present in the queue), -true otherwise. - ---------------------------------------- - -*queueremove(<queue_id>, <var_id>) - -Removes <var_id> from queue of <queue_id>. - -Returns false if <var_id> couldn't be removed (wasn't present in the queue), -true otherwise. - ---------------------------------------- - -*queueopt(<queue_id>, <optionType>{, <event label}) - -Modifies <queue_id>'s <optionType>. When <event label> is not present -<optionType> is removed from <queue_id>. When present it will execute the -<event label> when the <queue_id>'s <optionType> condition is met. - -Returns true on success, false on failure. - -Currently 3 options are available: -- QUEUEOPT_DEATH (1) -- QUEUEOPT_LOGOUT (2) -- QUEUEOPT_MAPCHANGE (3) - -When the QUEUEOPT_MAPCHANGE event is triggered, it sets a temp char var -@Queue_Destination_Map$ with the destination map name. - -Example: - queueopt(.@queue_id, QUEUEOPT_DEATH, "MyNPC::OnQueueMemberDeathEvent"); - ---------------------------------------- - -*queuedel(<queue_id>) - -Deletes the queue <queue_id>. - -Returns false if the queue wasn't found, true otherwise. - ---------------------------------------- - -*queueiterator(<queue_id>) - -Creates a new queue iterator instance. -A queue iterator is not a reference to a queue's actual members, it copies -the queues members when initialized, this way you can loop through them -even if you remove them from the queue. - ---------------------------------------- - -*qicheck(<queue_iterator_id>) - -Checks whether the current member in the iterator's queue exists. - -Returns true when it does, false otherwise. - ---------------------------------------- - -*qiget(<queue_iterator_id>) - -obtains the next member in the iterator's queue, returns the next member's -id or 0 when it doesnt exist. - -Example: - for (.@elem = qiget(.@queue_iterator_id); qicheck(.@queue_iterator_id); .@elem = qiget(.@queue_iterator_id)) { - //Do something - } - ---------------------------------------- - -*qiclear(<queue_iterator_id>) - -Deletes a queue iterator from memory. - -Returns false when it fails, otherwise true is returned. - ---------------------------------------- -//===================================== -11 - End of Queue-Related Commands -//===================================== ---------------------------------------- - ---------------------------------------- -//===================================== -12 - NPC Trader-Related Commands -//===================================== -Commands that control NPC Trader Shops -See /doc/sample/npc_trader_sample.txt ---------------------------------------- - -*openshop({NPC_Name}) - -opens the trader shop from the currently-attached npc unless, -when the optional NPC_Name param is used. - ---------------------------------------- - -*sellitem(<Item_ID>{, <price>{, <qty>}}) -*sellitem(<Item_ID>, <qty>, <currency_id>, <currency_amount>) - -adds (or modifies) <Item_ID> data to the shop, -when <price> is not provided (or when it is -1) itemdb default is used. -qty is only necessary for NST_MARKET trader types. - -when <Item_ID> is already in the shop, -the previous data (price/qty), is overwritten with the new. - -currency_id and currency_amount can be used only with shop type NST_BARTER - ---------------------------------------- - -*stopselling(<Item_ID>) -*stopselling(<Item_ID>{, <currency_id>, <currency_amount>}) - -attempts to remove <Item_ID> from the current shop list. -currency_id and currency_amount can be used only with shop type NST_BARTER - ---------------------------------------- - -*setcurrency(<Val1>{, <Val2>}) - -updates the currently attached player shop funds, -to be used within a "OnCountFunds" event of a NST_CUSTOM trader type. - -<Val1> is the value used in the *Cash* Points field -<Val2> is the value used in the Kafra Points field - ---------------------------------------- - -*tradertype(<Type>) - -Modifies the npc trader type, item list is cleared upon modifiying the value. -By default, all npcs staart with tradertype(NST_ZENY); - -- NST_ZENY (0) Normal Zeny Shop -- NST_CASH (1) Normal Cash Shop -- NST_MARKET (2) Normal NPC Market Shop (where items have limited availability and need to be refurbished) -- NST_CUSTOM (3) Custom Shop (any currency, item/var/etca, check sample) - ---------------------------------------- - -*purchaseok() - -Signs that the transaction (on a NST_CUSTOM trader) has been successful, -to be used within a "OnPayFunds" event of a NST_CUSTOM trader. - ---------------------------------------- - -*shopcount(<Item_ID>) - -Returns the amount of still-available <Item_ID> in the shop (on a NST_MARKET trader). - ---------------------------------------- - -*setunitdata(<GID>, <DataType>, <Val>) - -Sets or alters the data in real-time for game objects of the following types - -NPCs, Pets, Monsters, Homunuculus', Mercenaries, Elementals. - -Applicable Data Types (available as constants) - - Data Types Description (parameter type) - UDT_SIZE: Unit Size - UDT_LEVEL: Level - UDT_HP: Current HP - UDT_MAXHP: Max HP - UDT_SP: SP - UDT_MAXSP: MAX SP - UDT_MASTERAID: Master Account ID (for Summons) - UDT_MASTERCID: Master Char ID (for Summons) - UDT_SPEED: Unit Speed. - UDT_MODE: Mode (Mobs only) - UDT_AI: Unit AI Type (see doc/constants.md for Unit AI Types) - UDT_SCOPTION: Status Options. (see doc/constants.md for Unit Option Types) - UDT_SEX: Gender of the unit. (see doc/constants.md for Genders) - UDT_CLASS: Class of the unit. (Monster ID) - UDT_HAIRSTYLE: Hair Style ID. - UDT_HAIRCOLOR: Hair Color ID. - UDT_HEADBOTTOM: Headgear Bottom Sprite ID. - UDT_HEADMIDDLE: Headgear Middle Sprite ID. - UDT_HEADTOP: Headgear Top Sprite ID. - UDT_CLOTHCOLOR: Cloth Color ID. - UDT_SHIELD: Shield Sprite ID. - UDT_WEAPON: Weapon Sprite ID. - UDT_LOOKDIR: Face direction. - UDT_CANMOVETICK: Stop a unit from move for n seconds. - UDT_STR: Unit STR. - UDT_AGI: Unit AGI. - UDT_VIT: Unit VIT. - UDT_INT: Unit INT. - UDT_DEX: Unit DEX. - UDT_LUK: Unit LUK. - UDT_ATKRANGE: Attack range of a unit. - UDT_ATKMIN: Min Atk of a unit. - UDT_ATKMAX: Max Atk of a unit. - UDT_MATKMIN: Min MATK of a unit. - UDT_MATKMAX: Max MATK of a unit. - UDT_DEF: DEF. - UDT_MDEF: MDEF. - UDT_HIT: HIT. - UDT_FLEE: FLEE. - UDT_PDODGE: Perfect Dodge. - UDT_CRIT: Critical Rate. - UDT_RACE: Race. (Eg. constants RC_DemiHuman or Integer 7). - UDT_ELETYPE: Element. (Eg. constants Ele_Neutral or Integer 0). - UDT_ELELEVEL: Element Level. - UDT_AMOTION: AMotion Rate. - UDT_ADELAY: ADelay Rate. - UDT_DMOTION: DMotion Rate. - UDT_HUNGER: Hunger Rate - for summons. - UDT_INTIMACY: Intimacy Rate - for summons. - UDT_LIFETIME: LifeTime - for summons. - UDT_MERC_KILLCOUNT: Kill count for mercenaries - UDT_STATADD: Status Points - for NPCs. - UDT_GROUP: group id - -returns 0 if value could not be set, 1 if successful. - ---------------------------------------- - -*getunitdata (<GID>,<DataType>) - -Retrieves real-time data of a game object. - -Applicable Data types (available as constants) - - Data Types Description (return type) - UDT_SIZE: Unit Size - UDT_LEVEL: Level - UDT_HP: Current HP - UDT_MAXHP: Max HP - UDT_SP: SP - UDT_MAXSP: MAX SP - UDT_MASTERAID: Master Account ID (for Summons) - UDT_MASTERCID: Master Char ID (for Summons) - UDT_SPEED: Unit Speed. - UDT_MODE: Mode (Mobs only) - UDT_AI: Unit AI Type (see doc/constants.md for Unit AI Types) - UDT_SCOPTION: Status Options. (see doc/constants.md for Unit Option Types) - UDT_SEX: Gender of the unit. (see doc/constants.md for Genders) - UDT_CLASS: Class of the unit. (Monster ID) - UDT_HAIRSTYLE: Hair Style ID. - UDT_HAIRCOLOR: Hair Color ID. - UDT_HEADBOTTOM: Headgear Bottom Sprite ID. - UDT_HEADMIDDLE: Headgear Middle Sprite ID. - UDT_HEADTOP: Headgear Top Sprite ID. - UDT_CLOTHCOLOR: Cloth Color ID. - UDT_SHIELD: Shield Sprite ID. - UDT_WEAPON: Weapon Sprite ID. - UDT_LOOKDIR: Face direction. - UDT_CANMOVETICK: Stop a unit from move for n seconds. - UDT_STR: Unit STR. - UDT_AGI: Unit AGI. - UDT_VIT: Unit VIT. - UDT_INT: Unit INT. - UDT_DEX: Unit DEX. - UDT_LUK: Unit LUK. - UDT_ATKRANGE: Attack range of a unit. - UDT_ATKMIN: Min Atk of a unit. - UDT_ATKMAX: Max Atk of a unit. - UDT_MATKMIN: Min MATK of a unit. - UDT_MATKMAX: Max MATK of a unit. - UDT_DEF: DEF. - UDT_MDEF: MDEF. - UDT_HIT: HIT. - UDT_FLEE: FLEE. - UDT_PDODGE: Perfect Dodge. - UDT_CRIT: Critical Rate. - UDT_RACE: Race. (Eg. constants RC_DemiHuman or Integer 7). - UDT_ELETYPE: Element. (Eg. constants Ele_Neutral or Integer 0). - UDT_ELELEVEL: Element Level. - UDT_AMOTION: AMotion Rate. - UDT_ADELAY: ADelay Rate. - UDT_DMOTION: DMotion Rate. - UDT_HUNGER: Hunger Rate - for summons. - UDT_INTIMACY: Intimacy Rate - for summons. - UDT_LIFETIME: LifeTime - for summons. - UDT_MERC_KILLCOUNT: Kill count for mercenaries. - UDT_GROUP: group id - -returns -1 if value could not be retrieved. - ---------------------------------------- - -*getunitname(<GID>) - -Retrieve the name of a unit. - -returns "Unknown" if the value could not be retrieved. - ---------------------------------------- - -*setunitname(<GID>, <Name>) - -Changes the name of a unit. - -Supported Types - [ MOB | HOM | PET ]. - -returns 1 on success, 0 on failure. - ---------------------------------------- -//===================================== -13 - Clan System Related Commands -//===================================== ---------------------------------------- - -*join_clan(<ClanID>{, <account id>}) - -Joins a player into the given clan. -If no RID is given, will run with the current attached player. - -returns true on success, false on failure. - ---------------------------------------- - -*clan_leave({<account id>}) - -Removes a player from its clan. -If no RID is given, will run with the current attached player. - -returns true on success, false on failure. - ---------------------------------------- - -*clan_master(<ClanID>) - -Enables the Emblem of the given Clan to the current NPC - ---------------------------------------- -//===================================== -13 - End of Clan System Related Commands -//===================================== ---------------------------------------- - -*airship_respond(<flag>) - -Send client respond to different private airship status. -the available flags are: - P_AIRSHIP_NONE - P_AIRSHIP_RETRY - P_AIRSHIP_INVALID_START_MAP - P_AIRSHIP_INVALID_END_MAP - P_AIRSHIP_ITEM_NOT_ENOUGH - P_AIRSHIP_ITEM_INVALID - ---------------------------------------- - -*openstylist() - -Opens the styling shop on client - ---------------------------------------- - -*msgtable(<message_id>{, <color>}) - -Show in client message by <message_id> from msg string table -with optional <color>. - ---------------------------------------- - -*msgtable2(<message_id>, <param>{, <color>}) - -Show in client message by <message_id> from msg string table. -<param> is parameter for this message. Can be string or int. -Optional <color> can be used for set color for whole message. - ---------------------------------------- - -*camerainfo() - -Show or hide camera info window. -Works for 20160525 clients or newer. - ---------------------------------------- - -*changecamera(<range>, <rotation>, <latitude>{, <target>}) - -Change camera range, rotation, latitude. -The optional target parameter specifies who will get changed -camera. -Works for 20160525 clients or newer. - ---------------------------------------- - -*achievement_progress(<ach_id>, <obj_idx>, <progress>, <incremental>{, <account_id>}); - -Make the player progress in the specified achievement. -aid - achievement ID -obj_idx - achievement objective index. -progress - objective progress towards goal. -incremental - (boolean) true to add the progress towards the goal, - false to use the progress only as a comparand. -account_id - (optional) AID to perform on (default to attached player). - -returns progress on success and false on failure - ---------------------------------------- - -*itempreview(<index>) - -Update already opened preview window with item from - inventory with given index. -Works for 20181017 RE and main clients or newer. - ---------------------------------------- - -*enchantitem(<equip_pos>, <card_slot>, <card_id>); - -Insert card into equipped item in EQI_* slot. -card_slot - can be 0 to 3. -card_id - any card item id. - -returns true if all parameters correct -false in other case. -Works for 20160831 main, 20151118 RE, any zero version - ---------------------------------------- - -*servicemessage("<message>", <color>{, <account_id>}) -*servicemessage("<message>", <color>{, <player_name>}) - -That command will send a service message to the chat window of the character -specified by account ID or name, or to connected to npc player. -It will not be seen by anyone else. - -Works for 20170830 RE and main and for any zero clients - ---------------------------------------- - -*expandInventoryAck(<result>{, <itemId>}) - -Send initial inventory expansion result. -Normally this function should be called from script label -inventory_expansion::OnInventoryExpandRequest. - -Valid result statuses: - EXPAND_INVENTORY_ASK_CONFIRMATION - force client to ask player about inventory expansion - EXPAND_INVENTORY_FAILED - other failed reason - EXPAND_INVENTORY_OTHER_WORK - failed because player busy with other work - EXPAND_INVENTORY_MISSING_ITEM - failed because missing item - EXPAND_INVENTORY_MAX_SIZE - failed because inventory size already maximum - -ItemId make sense only if result is EXPAND_INVENTORY_ASK_CONFIRMATION -Works for 20181212 zero clients - ---------------------------------------- - -*expandInventoryResult(<result>) - -Send final inventory expansion result. -Normally this function should be called from script label -inventory_expansion::OnInventoryExpandConfirmed. - -Valid result values: - EXPAND_INVENTORY_RESULT_SUCCESS - success message - EXPAND_INVENTORY_RESULT_FAILED - other failed reason - EXPAND_INVENTORY_RESULT_OTHER_WORK - failed because player busy with other work - EXPAND_INVENTORY_RESULT_MISSING_ITEM - failed because missing item - EXPAND_INVENTORY_RESULT_MAX_SIZE - failed because inventory size already maximum - -Works for 20181212 zero clients - ---------------------------------------- - -*expandInventory(<value>) - -Adjust player inventory to given value. -Maximum inventory size is MAX_INVENTORY. -Minimum inventory size is FIXED_INVENTORY_SIZE. -For supported clients it send inventory change packet. For old clients, -this change is silent. -Current max inventory size can be read by function getInventorySize(). - ---------------------------------------- - -*getInventorySize() - -Return current player max inventory size. -This value always smaller or equal to MAX_INVENTORY. -Size can be changed by group of functions expandInventory* - ---------------------------------------- - -*getunittitle(<GID>) - -Return unit title string. -Works for 20180207 main clients, 20171129 re clients, 20171130 zero clients - ---------------------------------------- - -*setunittitle(<GID>, <title>) - -Set unit title string. -Invisible for players, because current implimentation using title id only. -Works for 20180207 main clients, 20171129 re clients, 20171130 zero clients - ---------------------------------------- - -*closeroulette() - -Force close roulette window. -Works for 20141008 main clients, 20140903 re, any zero. - ---------------------------------------- -*openrefineryui() - -Opens refinery user interface for the player -returns true on success and false on failure - ---------------------------------------- |