The Mana server uses the scripting language LUA for scripting. This is a list of the script commands currently implemented in addition to the standard lua statements and functions.
create_npc(string name, int spriteID, int x, int y, function talkfunct, function updatefunct)
Return value: A handle to the created NPC.
Creates a new NPC with the name name at the coordinates x:y which appears to the players with the appearence listed in their npcs.xml under spriteID. Every game tick the function updatefunct is called with the handle of the NPC. When a character talks to the NPC the function talkfunct is called with the NPC handle and the character handle.
mana.monster_create(int monsterID, int x, int y)
Return value: A handle to the created monster.
Spawns a new monster of type monsterID on the current map on the pixel coordinates x:y.
mana.trigger_create(int x, int y, int width, int height, string functionname, int arg, bool once)
Creates a new trigger area with the given height and width in pixels at the map position x:y in pixels. When a being steps into this area the function with the name functionname is called with the being handle and arg as arguments. When once is false the function is called every game tick the being is inside the area. When once is true it is only called again when the being leaves and reenters the area.
mana.effect_create(int id, int x, int y) mana.effect_create(int id, being b)
Triggers the effect id from the clients effects.xml (particle and/or sound) at map location x:y or on being b. This has no effect on gameplay.
Warning: Remember that clients might switch off particle effects for performance reasons. Thus you should not use this for important visual input.
do_message(handle npc, handle character, string message)
Warning: May only be called from an NPC talk function.
Shows an NPC dialog box on the screen of character ch displaying the string msg.
Idles the current thread until the user click “OK”.
do_choice(handle npc, handle character, item1, item2, ... itemN)
Return value: Number of the option the player selected (starting with 1).
Warning: May only be called from an NPC talk function.
Shows an NPC dialog box on the users screen with a number of dialog options to choose from. Idles the current thread until the user selects one or aborts the current thread when the user clicks “cancel”.
Items are either strings or tables of strings (indices are ignored, but presumed to be taken in order). So, do_choice(npc, ch, “A”, {“B”, “C”, “D”}, “E”) is the same as do_choice(npc, ch, “A”, “B”, “C”, “D”, “E”).
mana.being_say(handle being, string message)
Makes being, which can be a character, monster or NPC, speak the string message as if it was entered by a player in the chat bar.
mana.chatmessage(handle character, string message)
Outputs the string message in the chatlog of character which will appear as a private message from “Server”.
mana.npc_trade(handle npc, handle character, bool mode, {int item1id, int item1cost, int item1amount}, ..., {int itemNid, int itemNcost, int itemNamount})
Opens a trade window for character while talking with npc. mode is true for selling and false for buying. You have to set each items the NPC is buying/selling, the cost and the maximum amount in {}.
Note: If the fourth parameters (table type) is omitted or invalid, and the mode set to sell (true), the whole player inventory is then sellable.
N.B.: Be sure to put a value (item cost) parameter in your items.xml to permit the player to sell it when using this option.
Return values:
Examples:
-- "A buy sample." local buycase = mana.npc_trade(npc, ch, false, { {533, 10, 20}, {535, 10, 30}, {537, 10, 50} }) if buycase == 0 then do_message(npc, ch, "What do you want to buy?") elseif buycase == 1 then do_message(npc, ch, "I've got no items to sell.") else do_message(npc, ch, "Hmm, something went wrong... Ask a scripter to fix the buying mode!") end -- ... -- "Example: Let the player sell only pre-determined items." local sellcase = mana.npc_trade(npc, ch, true, { {533, 10, 20}, {535, 10, 30}, {511, 10, 200}, {524, 10, 300}, {508, 10, 500}, {537, 10, 25} }) if sellcase == 0 then do_message(npc, ch, "Here we go:") elseif sellcase == 1 then do_message(npc, ch, "I'm not interested by your items.") else do_message(npc, ch, "Hmm, something went wrong... Ask a scripter to fix me!") end -- ... -- "Example: Let the player sell every item with a 'value' parameter in the server's items.xml file local sellcase = mana.npc_trade(npc, ch, true) if sellcase == 0 then do_message(npc, ch, "Ok, what do you want to sell:") elseif sellcase == 1 then do_message(npc, ch, "I'm not interested by any of your items.") else do_message(npc, ch, "Hmm, something went wrong... Ask a scripter to fix this!") end
mana.chr_inv_count(handle character, int id1, ..., int idN)
Return values: A number of integers with the amount of items id carried by character.
mana.chr_inv_change(handle character, int id1, int number1, ..., int idN, numberN)
Return value: Boolean true on success, boelean false on failure.
Changes the number of items with the item ID id owned by character by number. You can change any number of items with this function by passing multiple id and number pairs. A failure can be caused by trying to take items the character doesn't possess.
Warning: When one of the operations fails the following operations are ignored but these before are executed. For that reason you should always check if the character possesses items you are taking away using mana.chr_inv_count.
mana.chr_money(handle character)
Return value: The money currently owned by character
mana.chr_money_change(handle character, int amount)
Changes the money currently owned by character by amount.
Warning: Before reducing the money make sure to check if the character owns enough money using mana.chr_money.
mana.get_quest_var(handle character, string name)
Return value: The quest variable named name for the given character.
mana.chr_set_quest(handle character, string name, string value)
Sets the quest variable named name for the given character to the value value.
mana.being_walk(handle character, int pixelX, int pixelY, int walkSpeed)
Set the desired destination in pixels for the 'character'.
The 'WalkSpeed' is to be given in tiles per second. The average speed is 6.0 tiles per second.
mana.being_get_speed(handle character)
Get the current walk speed for the given 'character'.
mana.being_get_speed(handle character, float speed)
Set the walk speed for the given 'character'.
The 'speed' is to be given in tiles per second. The average speed is 6.0 tiles per second.
mana.being_damage(handle being, int damage, int delta, int accuracy, int type, int element)
Inflicts damage to being. The severity of the attack is between damage and (damage + delta) and is calculated using the normal damage calculation rules. The being has a chance to dodge the attack with its agility attribute. The accuracy decides how hard this is.
type affects which kind of armor and character attributes reduce the damage. It can be one of the following values:
| 0 | DAMAGE_PHYSICAL |
| 1 | DAMAGE_MAGICAL |
| 2 | DAMAGE_OTHER |
element decides how the element system changes the damage. The following values are possible:
| 0 | ELEMENT_NEUTRAL |
| 1 | ELEMENT_FIRE |
| 2 | ELEMENT_WATER |
| 3 | ELEMENT_EARTH |
| 4 | ELEMENT_AIR |
| 5 | ELEMENT_LIGHTNING |
| 6 | ELEMENT_METAL |
| 7 | ELEMENT_WOOD |
| 8 | ELEMENT_ICE |
Return Value: Actual HP reduction resulting from the attack.
mana.being_heal(handle being[, int value])
Restores value lost hit points to being. Value can be omitted to restore the being to full hit points.
While you can (ab)use this function to hurt a being by using a negative value you should rather use mana.being_damage for this purpose.
mana.get_beings_in_circle(int x, int y, int radius)
Return value: This function returns a lua table of all beings in a circle of radius radius centered at the pixel at (x, y).
mana.being_get_name(handle being)
Return value: Name of the being.
mana.being_type(handle being)
Return value: Type of the given being. These type constants are defined in libmana-constants.lua:
| 0 | TYPE_ITEM |
| 1 | TYPE_ACTOR |
| 2 | TYPE_NPC |
| 3 | TYPE_MONSTER |
| 4 | TYPE_CHARACTER |
| 5 | TYPE_EFFECT |
| 6 | TYPE_OTHER |
mana.being_get_action(handle being)
Return value: Current action of the given being. These action constants are defined in libmana-constants.lua:
| 0 | ACTION_STAND |
| 1 | ACTION_WALK |
| 2 | ACTION_ATTACK |
| 3 | ACTION_SIT |
| 4 | ACTION_DEAD |
| 5 | ACTION_HURT |
mana.being_set_action(handle being, int action)
mana.being_get_direction(handle being)
Return value: Current direction of the given being. These direction constants are defined in libmana-constants.lua:
| 0 | DIRECTION_DEFAULT |
| 1 | DIRECTION_UP |
| 2 | DIRECTION_DOWN |
| 3 | DIRECTION_LEFT |
| 4 | DIRECTION_RIGHT |
| 5 | DIRECTION_INVALID |
mana.being_set_direction(handle being, int direction)
Sets the current direction of the given being. Directions are same as in mana.being_get_direction.
mana.chr_warp(handle character, int mapID, int posX, int posY)
Teleports the character to the position posX:posY on the map with the ID number mapID. The mapID can be substituted by nil to warp the character to a new position on the current map.
mana.posx(handle being)
Return value: The horizontal position of the being in pixels measured from the left border of the map it is currently on.
mana.posy(handle being)
Return value: The vertical position of the being in pixels measured from the upper border of the map it is currently on.
mana.being_get_attribute(handle being, int attribute)
Return value: Returns the score in attribute of being. Can also be used to query the skill levels of player characters.
mana.chr_get_exp(handle character, int attribute)
Return value: The total experience collected by character in skill attribute.
mana.chr_give_exp(handle character, int attribute, int amount [, int optimalLevel])
Gives character amount experience in skill attribute. When an optimal level is set (over 0), the experience is reduced when the characters skill level is beyond this.
mana.exp_for_level(int level)
Return value: Returns the total experience necessary (counted from level 0) for reaching level in any skill.
mana.chr_get_hair_color(handle character)
Return value: The hair color ID of character
mana.chr_set_hair_color(handle character, int color)
Sets the hair color ID of character to color
mana.chr_get_hair_style(handle character)
Return value: The hair style ID of character
mana.chr_set_hair_style(handle character, int style)
Sets the hair style ID of character to style
mana.chr_get_kill_count(handle character, int monsterType)
Return value: The total number of monsters of type monsterType the character has killed during its career.
mana.chr_get_rights(handle character)
Return value: The access level of the account of character.
mana.being_apply_status(handle Being, int status_id, int time)
Gives a being a status effect status_id, status effects don't work on NPCs. time is in game ticks.
mana.being_remove_status(handle Being, int status_id)
Removes a given status effect from a being.
mana.being_has_status(handle Being, int status_id)
Return value: Bool if the being has a given status effect.
mana.being_get_status_time(handle Being, int status_id)
Return Value: Number of ticks remaining on a status effect.
mana.being_set_status_time(handle Being, int status_id, int time)
Sets the time on a status effect a target being already has.
atinit(function() [function body] end)
Adds a function which is executed when the gameserver loads the map this script belongs to. Usually used for placing NPCs or trigger areas and for setting up cronjobs with schedule_every. Any number of functions can be added this way.
schedule_in(seconds, function() [function body] end)
Executes the function body in seconds seconds.
schedule_every(seconds, function() [function body] end)
Executes the function body every seconds seconds from now on.
on_death(handle being, function() [function body] end)
Executes the function body when being is killed. Note that this doesn't happen anymore after the being left the map.
on_remove(handle being, function() [function body] end)
Executes the function body when being is no longer on the map for some reason (leaves the map voluntarily, is warped away, logs out, cleaned up after getting killed or whatever).
mana.get_map_id()
Return value: The ID number of the map the script runs on.
With the introduction of the scripted Special System some new script bindings are needed which makes it easier for server administrators to define damage inflicting specials.
we already have get_beings_in_circle, but we could also need:
Most servers will likely want a lot of special attacks which inflict damage based on the attributes of the attacker in the same way as a normal attack, just that they are stronger. To make this easier we need a function which makes being A attack being B with the normal combat rules, except that the damage and accuracy can be made stronger or weaker and that the element can be changed.
* perform_modified_attack(handle attacker, handle defender, float damage_factor, float damage_delta_factor, float accuracy_factor, int type, int element)
The float factors will be multipliers to the damage values created by a normal attack. Element can be nil to use the element of the currently equipped weapon.
IMO, we should have a separate article for each function, with code samples and all.
I Agree. Scripting really lacks some useful snippets. (If the per function article is too much, maybe per-section pages, then?)