Advertisement
Guest User

Untitled

a guest
Aug 26th, 2017
514
0
Never
Not a member of Pastebin yet? Sign Up, it unlocks many cool features!
C++ 315.44 KB | None | 0 0
  1. /**
  2.  * The Forgotten Server - a free and open-source MMORPG server emulator
  3.  * Copyright (C) 2016  Mark Samman <mark.samman@gmail.com>
  4.  *
  5.  * This program is free software; you can redistribute it and/or modify
  6.  * it under the terms of the GNU General Public License as published by
  7.  * the Free Software Foundation; either version 2 of the License, or
  8.  * (at your option) any later version.
  9.  *
  10.  * This program is distributed in the hope that it will be useful,
  11.  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  12.  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
  13.  * GNU General Public License for more details.
  14.  *
  15.  * You should have received a copy of the GNU General Public License along
  16.  * with this program; if not, write to the Free Software Foundation, Inc.,
  17.  * 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301 USA.
  18.  */
  19.  
  20. #include "otpch.h"
  21.  
  22. #include <boost/range/adaptor/reversed.hpp>
  23.  
  24. #include "luascript.h"
  25. #include "chat.h"
  26. #include "player.h"
  27. #include "game.h"
  28. #include "protocolstatus.h"
  29. #include "spells.h"
  30. #include "iologindata.h"
  31. #include "configmanager.h"
  32. #include "teleport.h"
  33. #include "databasemanager.h"
  34. #include "bed.h"
  35. #include "monster.h"
  36. #include "scheduler.h"
  37. #include "databasetasks.h"
  38.  
  39. extern Chat* g_chat;
  40. extern Game g_game;
  41. extern Monsters g_monsters;
  42. extern ConfigManager g_config;
  43. extern Vocations g_vocations;
  44. extern Spells* g_spells;
  45.  
  46. enum {
  47.     EVENT_ID_LOADING = 1,
  48.     EVENT_ID_USER = 1000,
  49. };
  50.  
  51. ScriptEnvironment::DBResultMap ScriptEnvironment::tempResults;
  52. uint32_t ScriptEnvironment::lastResultId = 0;
  53.  
  54. std::multimap<ScriptEnvironment*, Item*> ScriptEnvironment::tempItems;
  55.  
  56. LuaEnvironment g_luaEnvironment;
  57.  
  58. ScriptEnvironment::ScriptEnvironment()
  59. {
  60.     curNpc = nullptr;
  61.     resetEnv();
  62.     lastUID = std::numeric_limits<uint16_t>::max();
  63. }
  64.  
  65. ScriptEnvironment::~ScriptEnvironment()
  66. {
  67.     resetEnv();
  68. }
  69.  
  70. void ScriptEnvironment::resetEnv()
  71. {
  72.     scriptId = 0;
  73.     callbackId = 0;
  74.     timerEvent = false;
  75.     interface = nullptr;
  76.     localMap.clear();
  77.     tempResults.clear();
  78.  
  79.     auto pair = tempItems.equal_range(this);
  80.     auto it = pair.first;
  81.     while (it != pair.second) {
  82.         Item* item = it->second;
  83.         if (item->getParent() == VirtualCylinder::virtualCylinder) {
  84.             g_game.ReleaseItem(item);
  85.         }
  86.         it = tempItems.erase(it);
  87.     }
  88. }
  89.  
  90. bool ScriptEnvironment::setCallbackId(int32_t callbackId, LuaScriptInterface* scriptInterface)
  91. {
  92.     if (this->callbackId != 0) {
  93.         //nested callbacks are not allowed
  94.         if (interface) {
  95.             interface->reportErrorFunc("Nested callbacks!");
  96.         }
  97.         return false;
  98.     }
  99.  
  100.     this->callbackId = callbackId;
  101.     interface = scriptInterface;
  102.     return true;
  103. }
  104.  
  105. void ScriptEnvironment::getEventInfo(int32_t& scriptId, LuaScriptInterface*& scriptInterface, int32_t& callbackId, bool& timerEvent) const
  106. {
  107.     scriptId = this->scriptId;
  108.     scriptInterface = interface;
  109.     callbackId = this->callbackId;
  110.     timerEvent = this->timerEvent;
  111. }
  112.  
  113. uint32_t ScriptEnvironment::addThing(Thing* thing)
  114. {
  115.     if (!thing || thing->isRemoved()) {
  116.         return 0;
  117.     }
  118.  
  119.     Creature* creature = thing->getCreature();
  120.     if (creature) {
  121.         return creature->getID();
  122.     }
  123.  
  124.     Item* item = thing->getItem();
  125.     if (item && item->hasAttribute(ITEM_ATTRIBUTE_UNIQUEID)) {
  126.         return item->getUniqueId();
  127.     }
  128.  
  129.     for (const auto& it : localMap) {
  130.         if (it.second == item) {
  131.             return it.first;
  132.         }
  133.     }
  134.  
  135.     localMap[++lastUID] = item;
  136.     return lastUID;
  137. }
  138.  
  139. void ScriptEnvironment::insertItem(uint32_t uid, Item* item)
  140. {
  141.     auto result = localMap.emplace(uid, item);
  142.     if (!result.second) {
  143.         std::cout << std::endl << "Lua Script Error: Thing uid already taken.";
  144.     }
  145. }
  146.  
  147. Thing* ScriptEnvironment::getThingByUID(uint32_t uid)
  148. {
  149.     if (uid >= 0x10000000) {
  150.         return g_game.getCreatureByID(uid);
  151.     }
  152.  
  153.     if (uid <= std::numeric_limits<uint16_t>::max()) {
  154.         Item* item = g_game.getUniqueItem(uid);
  155.         if (item && !item->isRemoved()) {
  156.             return item;
  157.         }
  158.         return nullptr;
  159.     }
  160.  
  161.     auto it = localMap.find(uid);
  162.     if (it != localMap.end()) {
  163.         Item* item = it->second;
  164.         if (!item->isRemoved()) {
  165.             return item;
  166.         }
  167.     }
  168.     return nullptr;
  169. }
  170.  
  171. Item* ScriptEnvironment::getItemByUID(uint32_t uid)
  172. {
  173.     Thing* thing = getThingByUID(uid);
  174.     if (!thing) {
  175.         return nullptr;
  176.     }
  177.     return thing->getItem();
  178. }
  179.  
  180. Container* ScriptEnvironment::getContainerByUID(uint32_t uid)
  181. {
  182.     Item* item = getItemByUID(uid);
  183.     if (!item) {
  184.         return nullptr;
  185.     }
  186.     return item->getContainer();
  187. }
  188.  
  189. void ScriptEnvironment::removeItemByUID(uint32_t uid)
  190. {
  191.     if (uid <= std::numeric_limits<uint16_t>::max()) {
  192.         g_game.removeUniqueItem(uid);
  193.         return;
  194.     }
  195.  
  196.     auto it = localMap.find(uid);
  197.     if (it != localMap.end()) {
  198.         localMap.erase(it);
  199.     }
  200. }
  201.  
  202. void ScriptEnvironment::addTempItem(Item* item)
  203. {
  204.     tempItems.emplace(this, item);
  205. }
  206.  
  207. void ScriptEnvironment::removeTempItem(Item* item)
  208. {
  209.     for (auto it = tempItems.begin(), end = tempItems.end(); it != end; ++it) {
  210.         if (it->second == item) {
  211.             tempItems.erase(it);
  212.             break;
  213.         }
  214.     }
  215. }
  216.  
  217. uint32_t ScriptEnvironment::addResult(DBResult_ptr res)
  218. {
  219.     tempResults[++lastResultId] = res;
  220.     return lastResultId;
  221. }
  222.  
  223. bool ScriptEnvironment::removeResult(uint32_t id)
  224. {
  225.     auto it = tempResults.find(id);
  226.     if (it == tempResults.end()) {
  227.         return false;
  228.     }
  229.  
  230.     tempResults.erase(it);
  231.     return true;
  232. }
  233.  
  234. DBResult_ptr ScriptEnvironment::getResultByID(uint32_t id)
  235. {
  236.     auto it = tempResults.find(id);
  237.     if (it == tempResults.end()) {
  238.         return nullptr;
  239.     }
  240.     return it->second;
  241. }
  242.  
  243. std::string LuaScriptInterface::getErrorDesc(ErrorCode_t code)
  244. {
  245.     switch (code) {
  246.         case LUA_ERROR_PLAYER_NOT_FOUND: return "Player not found";
  247.         case LUA_ERROR_CREATURE_NOT_FOUND: return "Creature not found";
  248.         case LUA_ERROR_ITEM_NOT_FOUND: return "Item not found";
  249.         case LUA_ERROR_THING_NOT_FOUND: return "Thing not found";
  250.         case LUA_ERROR_TILE_NOT_FOUND: return "Tile not found";
  251.         case LUA_ERROR_HOUSE_NOT_FOUND: return "House not found";
  252.         case LUA_ERROR_COMBAT_NOT_FOUND: return "Combat not found";
  253.         case LUA_ERROR_CONDITION_NOT_FOUND: return "Condition not found";
  254.         case LUA_ERROR_AREA_NOT_FOUND: return "Area not found";
  255.         case LUA_ERROR_CONTAINER_NOT_FOUND: return "Container not found";
  256.         case LUA_ERROR_VARIANT_NOT_FOUND: return "Variant not found";
  257.         case LUA_ERROR_VARIANT_UNKNOWN: return "Unknown variant type";
  258.         case LUA_ERROR_SPELL_NOT_FOUND: return "Spell not found";
  259.         default: return "Bad error code";
  260.     }
  261. }
  262.  
  263. ScriptEnvironment LuaScriptInterface::scriptEnv[16];
  264. int32_t LuaScriptInterface::scriptEnvIndex = -1;
  265.  
  266. LuaScriptInterface::LuaScriptInterface(std::string interfaceName)
  267.     : luaState(nullptr), interfaceName(interfaceName), eventTableRef(-1), runningEventId(EVENT_ID_USER)
  268. {
  269.     if (!g_luaEnvironment.getLuaState()) {
  270.         g_luaEnvironment.initState();
  271.     }
  272. }
  273.  
  274. LuaScriptInterface::~LuaScriptInterface()
  275. {
  276.     closeState();
  277. }
  278.  
  279. bool LuaScriptInterface::reInitState()
  280. {
  281.     g_luaEnvironment.clearCombatObjects(this);
  282.     g_luaEnvironment.clearAreaObjects(this);
  283.  
  284.     closeState();
  285.     return initState();
  286. }
  287.  
  288. /// Same as lua_pcall, but adds stack trace to error strings in called function.
  289. int LuaScriptInterface::protectedCall(lua_State* L, int nargs, int nresults)
  290. {
  291.     int error_index = lua_gettop(L) - nargs;
  292.     lua_pushcfunction(L, luaErrorHandler);
  293.     lua_insert(L, error_index);
  294.  
  295.     int ret = lua_pcall(L, nargs, nresults, error_index);
  296.     lua_remove(L, error_index);
  297.     return ret;
  298. }
  299.  
  300. int32_t LuaScriptInterface::loadFile(const std::string& file, Npc* npc /* = nullptr*/)
  301. {
  302.     //loads file as a chunk at stack top
  303.     int ret = luaL_loadfile(luaState, file.c_str());
  304.     if (ret != 0) {
  305.         lastLuaError = popString(luaState);
  306.         return -1;
  307.     }
  308.  
  309.     //check that it is loaded as a function
  310.     if (!isFunction(luaState, -1)) {
  311.         return -1;
  312.     }
  313.  
  314.     loadingFile = file;
  315.  
  316.     if (!reserveScriptEnv()) {
  317.         return -1;
  318.     }
  319.  
  320.     ScriptEnvironment* env = getScriptEnv();
  321.     env->setScriptId(EVENT_ID_LOADING, this);
  322.     env->setNpc(npc);
  323.  
  324.     //execute it
  325.     ret = protectedCall(luaState, 0, 0);
  326.     if (ret != 0) {
  327.         reportError(nullptr, popString(luaState));
  328.         resetScriptEnv();
  329.         return -1;
  330.     }
  331.  
  332.     resetScriptEnv();
  333.     return 0;
  334. }
  335.  
  336. int32_t LuaScriptInterface::getEvent(const std::string& eventName)
  337. {
  338.     //get our events table
  339.     lua_rawgeti(luaState, LUA_REGISTRYINDEX, eventTableRef);
  340.     if (!isTable(luaState, -1)) {
  341.         lua_pop(luaState, 1);
  342.         return -1;
  343.     }
  344.  
  345.     //get current event function pointer
  346.     lua_getglobal(luaState, eventName.c_str());
  347.     if (!isFunction(luaState, -1)) {
  348.         lua_pop(luaState, 2);
  349.         return -1;
  350.     }
  351.  
  352.     //save in our events table
  353.     lua_pushvalue(luaState, -1);
  354.     lua_rawseti(luaState, -3, runningEventId);
  355.     lua_pop(luaState, 2);
  356.  
  357.     //reset global value of this event
  358.     lua_pushnil(luaState);
  359.     lua_setglobal(luaState, eventName.c_str());
  360.  
  361.     cacheFiles[runningEventId] = loadingFile + ":" + eventName;
  362.     return runningEventId++;
  363. }
  364.  
  365. int32_t LuaScriptInterface::getMetaEvent(const std::string& globalName, const std::string& eventName)
  366. {
  367.     //get our events table
  368.     lua_rawgeti(luaState, LUA_REGISTRYINDEX, eventTableRef);
  369.     if (!isTable(luaState, -1)) {
  370.         lua_pop(luaState, 1);
  371.         return -1;
  372.     }
  373.  
  374.     //get current event function pointer
  375.     lua_getglobal(luaState, globalName.c_str());
  376.     lua_getfield(luaState, -1, eventName.c_str());
  377.     if (!isFunction(luaState, -1)) {
  378.         lua_pop(luaState, 3);
  379.         return -1;
  380.     }
  381.  
  382.     //save in our events table
  383.     lua_pushvalue(luaState, -1);
  384.     lua_rawseti(luaState, -4, runningEventId);
  385.     lua_pop(luaState, 1);
  386.  
  387.     //reset global value of this event
  388.     lua_pushnil(luaState);
  389.     lua_setfield(luaState, -2, eventName.c_str());
  390.     lua_pop(luaState, 2);
  391.  
  392.     cacheFiles[runningEventId] = loadingFile + ":" + globalName + "@" + eventName;
  393.     return runningEventId++;
  394. }
  395.  
  396. const std::string& LuaScriptInterface::getFileById(int32_t scriptId)
  397. {
  398.     if (scriptId == EVENT_ID_LOADING) {
  399.         return loadingFile;
  400.     }
  401.  
  402.     auto it = cacheFiles.find(scriptId);
  403.     if (it == cacheFiles.end()) {
  404.         static const std::string& unk = "(Unknown scriptfile)";
  405.         return unk;
  406.     }
  407.     return it->second;
  408. }
  409.  
  410. std::string LuaScriptInterface::getStackTrace(const std::string& error_desc)
  411. {
  412.     lua_getglobal(luaState, "debug");
  413.     if (!isTable(luaState, -1)) {
  414.         lua_pop(luaState, 1);
  415.         return error_desc;
  416.     }
  417.  
  418.     lua_getfield(luaState, -1, "traceback");
  419.     if (!isFunction(luaState, -1)) {
  420.         lua_pop(luaState, 2);
  421.         return error_desc;
  422.     }
  423.  
  424.     lua_replace(luaState, -2);
  425.     pushString(luaState, error_desc);
  426.     lua_call(luaState, 1, 1);
  427.     return popString(luaState);
  428. }
  429.  
  430. void LuaScriptInterface::reportError(const char* function, const std::string& error_desc, bool stack_trace/* = false*/)
  431. {
  432.     int32_t scriptId;
  433.     int32_t callbackId;
  434.     bool timerEvent;
  435.     LuaScriptInterface* scriptInterface;
  436.     getScriptEnv()->getEventInfo(scriptId, scriptInterface, callbackId, timerEvent);
  437.  
  438.     std::cout << std::endl << "Lua Script Error: ";
  439.  
  440.     if (scriptInterface) {
  441.         std::cout << '[' << scriptInterface->getInterfaceName() << "] " << std::endl;
  442.  
  443.         if (timerEvent) {
  444.             std::cout << "in a timer event called from: " << std::endl;
  445.         }
  446.  
  447.         if (callbackId) {
  448.             std::cout << "in callback: " << scriptInterface->getFileById(callbackId) << std::endl;
  449.         }
  450.  
  451.         std::cout << scriptInterface->getFileById(scriptId) << std::endl;
  452.     }
  453.  
  454.     if (function) {
  455.         std::cout << function << "(). ";
  456.     }
  457.  
  458.     if (stack_trace && scriptInterface) {
  459.         std::cout << scriptInterface->getStackTrace(error_desc) << std::endl;
  460.     } else {
  461.         std::cout << error_desc << std::endl;
  462.     }
  463. }
  464.  
  465. bool LuaScriptInterface::pushFunction(int32_t functionId)
  466. {
  467.     lua_rawgeti(luaState, LUA_REGISTRYINDEX, eventTableRef);
  468.     if (!isTable(luaState, -1)) {
  469.         return false;
  470.     }
  471.  
  472.     lua_rawgeti(luaState, -1, functionId);
  473.     lua_replace(luaState, -2);
  474.     return isFunction(luaState, -1);
  475. }
  476.  
  477. bool LuaScriptInterface::initState()
  478. {
  479.     luaState = g_luaEnvironment.getLuaState();
  480.     if (!luaState) {
  481.         return false;
  482.     }
  483.  
  484.     lua_newtable(luaState);
  485.     eventTableRef = luaL_ref(luaState, LUA_REGISTRYINDEX);
  486.     runningEventId = EVENT_ID_USER;
  487.     return true;
  488. }
  489.  
  490. bool LuaScriptInterface::closeState()
  491. {
  492.     if (!g_luaEnvironment.getLuaState() || !luaState) {
  493.         return false;
  494.     }
  495.  
  496.     cacheFiles.clear();
  497.     if (eventTableRef != -1) {
  498.         luaL_unref(luaState, LUA_REGISTRYINDEX, eventTableRef);
  499.         eventTableRef = -1;
  500.     }
  501.  
  502.     luaState = nullptr;
  503.     return true;
  504. }
  505.  
  506. int LuaScriptInterface::luaErrorHandler(lua_State* L)
  507. {
  508.     const std::string& errorMessage = popString(L);
  509.     auto interface = getScriptEnv()->getScriptInterface();
  510.     assert(interface); //This fires if the ScriptEnvironment hasn't been setup
  511.     pushString(L, interface->getStackTrace(errorMessage));
  512.     return 1;
  513. }
  514.  
  515. bool LuaScriptInterface::callFunction(int params)
  516. {
  517.     bool result = false;
  518.     int size = lua_gettop(luaState);
  519.     if (protectedCall(luaState, params, 1) != 0) {
  520.         LuaScriptInterface::reportError(nullptr, LuaScriptInterface::getString(luaState, -1));
  521.     } else {
  522.         result = LuaScriptInterface::getBoolean(luaState, -1);
  523.     }
  524.  
  525.     lua_pop(luaState, 1);
  526.     if ((lua_gettop(luaState) + params + 1) != size) {
  527.         LuaScriptInterface::reportError(nullptr, "Stack size changed!");
  528.     }
  529.  
  530.     resetScriptEnv();
  531.     return result;
  532. }
  533.  
  534. void LuaScriptInterface::callVoidFunction(int params)
  535. {
  536.     int size = lua_gettop(luaState);
  537.     if (protectedCall(luaState, params, 0) != 0) {
  538.         LuaScriptInterface::reportError(nullptr, LuaScriptInterface::popString(luaState));
  539.     }
  540.  
  541.     if ((lua_gettop(luaState) + params + 1) != size) {
  542.         LuaScriptInterface::reportError(nullptr, "Stack size changed!");
  543.     }
  544.  
  545.     resetScriptEnv();
  546. }
  547.  
  548. void LuaScriptInterface::pushVariant(lua_State* L, const LuaVariant& var)
  549. {
  550.     lua_createtable(L, 0, 2);
  551.     setField(L, "type", var.type);
  552.     switch (var.type) {
  553.         case VARIANT_NUMBER:
  554.             setField(L, "number", var.number);
  555.             break;
  556.         case VARIANT_STRING:
  557.             setField(L, "string", var.text);
  558.             break;
  559.         case VARIANT_TARGETPOSITION:
  560.         case VARIANT_POSITION: {
  561.             pushPosition(L, var.pos);
  562.             lua_setfield(L, -2, "pos");
  563.             break;
  564.         }
  565.         default:
  566.             break;
  567.     }
  568.     setMetatable(L, -1, "Variant");
  569. }
  570.  
  571. void LuaScriptInterface::pushThing(lua_State* L, Thing* thing)
  572. {
  573.     if (!thing) {
  574.         lua_createtable(L, 0, 4);
  575.         setField(L, "uid", 0);
  576.         setField(L, "itemid", 0);
  577.         setField(L, "actionid", 0);
  578.         setField(L, "type", 0);
  579.         return;
  580.     }
  581.  
  582.     if (Item* item = thing->getItem()) {
  583.         pushUserdata<Item>(L, item);
  584.         setItemMetatable(L, -1, item);
  585.     } else if (Creature* creature = thing->getCreature()) {
  586.         pushUserdata<Creature>(L, creature);
  587.         setCreatureMetatable(L, -1, creature);
  588.     } else {
  589.         lua_pushnil(L);
  590.     }
  591. }
  592.  
  593. void LuaScriptInterface::pushCylinder(lua_State* L, Cylinder* cylinder)
  594. {
  595.     if (Creature* creature = cylinder->getCreature()) {
  596.         pushUserdata<Creature>(L, creature);
  597.         setCreatureMetatable(L, -1, creature);
  598.     } else if (Item* parentItem = cylinder->getItem()) {
  599.         pushUserdata<Item>(L, parentItem);
  600.         setItemMetatable(L, -1, parentItem);
  601.     } else if (Tile* tile = cylinder->getTile()) {
  602.         pushUserdata<Tile>(L, tile);
  603.         setMetatable(L, -1, "Tile");
  604.     } else if (cylinder == VirtualCylinder::virtualCylinder) {
  605.         pushBoolean(L, true);
  606.     } else {
  607.         lua_pushnil(L);
  608.     }
  609. }
  610.  
  611. void LuaScriptInterface::pushString(lua_State* L, const std::string& value)
  612. {
  613.     lua_pushlstring(L, value.c_str(), value.length());
  614. }
  615.  
  616. void LuaScriptInterface::pushCallback(lua_State* L, int32_t callback)
  617. {
  618.     lua_rawgeti(L, LUA_REGISTRYINDEX, callback);
  619. }
  620.  
  621. std::string LuaScriptInterface::popString(lua_State* L)
  622. {
  623.     if (lua_gettop(L) == 0) {
  624.         return std::string();
  625.     }
  626.  
  627.     std::string str(getString(L, -1));
  628.     lua_pop(L, 1);
  629.     return str;
  630. }
  631.  
  632. int32_t LuaScriptInterface::popCallback(lua_State* L)
  633. {
  634.     return luaL_ref(L, LUA_REGISTRYINDEX);
  635. }
  636.  
  637. // Metatables
  638. void LuaScriptInterface::setMetatable(lua_State* L, int32_t index, const std::string& name)
  639. {
  640.     luaL_getmetatable(L, name.c_str());
  641.     lua_setmetatable(L, index - 1);
  642. }
  643.  
  644. void LuaScriptInterface::setWeakMetatable(lua_State* L, int32_t index, const std::string& name)
  645. {
  646.     static std::set<std::string> weakObjectTypes;
  647.     const std::string& weakName = name + "_weak";
  648.  
  649.     auto result = weakObjectTypes.emplace(name);
  650.     if (result.second) {
  651.         luaL_getmetatable(L, name.c_str());
  652.         int childMetatable = lua_gettop(L);
  653.  
  654.         luaL_newmetatable(L, weakName.c_str());
  655.         int metatable = lua_gettop(L);
  656.  
  657.         static const std::vector<std::string> methodKeys = {"__index", "__metatable", "__eq"};
  658.         for (const std::string& metaKey : methodKeys) {
  659.             lua_getfield(L, childMetatable, metaKey.c_str());
  660.             lua_setfield(L, metatable, metaKey.c_str());
  661.         }
  662.  
  663.         static const std::vector<int> methodIndexes = {'h', 'p', 't'};
  664.         for (int metaIndex : methodIndexes) {
  665.             lua_rawgeti(L, childMetatable, metaIndex);
  666.             lua_rawseti(L, metatable, metaIndex);
  667.         }
  668.  
  669.         lua_pushnil(L);
  670.         lua_setfield(L, metatable, "__gc");
  671.  
  672.         lua_remove(L, childMetatable);
  673.     } else {
  674.         luaL_getmetatable(L, weakName.c_str());
  675.     }
  676.     lua_setmetatable(L, index - 1);
  677. }
  678.  
  679. void LuaScriptInterface::setItemMetatable(lua_State* L, int32_t index, const Item* item)
  680. {
  681.     if (item->getContainer()) {
  682.         luaL_getmetatable(L, "Container");
  683.     } else if (item->getTeleport()) {
  684.         luaL_getmetatable(L, "Teleport");
  685.     } else {
  686.         luaL_getmetatable(L, "Item");
  687.     }
  688.     lua_setmetatable(L, index - 1);
  689. }
  690.  
  691. void LuaScriptInterface::setCreatureMetatable(lua_State* L, int32_t index, const Creature* creature)
  692. {
  693.     if (creature->getPlayer()) {
  694.         luaL_getmetatable(L, "Player");
  695.     } else if (creature->getMonster()) {
  696.         luaL_getmetatable(L, "Monster");
  697.     } else {
  698.         luaL_getmetatable(L, "Npc");
  699.     }
  700.     lua_setmetatable(L, index - 1);
  701. }
  702.  
  703. // Get
  704. std::string LuaScriptInterface::getString(lua_State* L, int32_t arg)
  705. {
  706.     size_t len;
  707.     const char* c_str = lua_tolstring(L, arg, &len);
  708.     if (!c_str || len == 0) {
  709.         return std::string();
  710.     }
  711.     return std::string(c_str, len);
  712. }
  713.  
  714. Position LuaScriptInterface::getPosition(lua_State* L, int32_t arg, int32_t& stackpos)
  715. {
  716.     Position position;
  717.     position.x = getField<uint16_t>(L, arg, "x");
  718.     position.y = getField<uint16_t>(L, arg, "y");
  719.     position.z = getField<uint8_t>(L, arg, "z");
  720.  
  721.     lua_getfield(L, arg, "stackpos");
  722.     if (lua_isnil(L, -1) == 1) {
  723.         stackpos = 0;
  724.     } else {
  725.         stackpos = getNumber<int32_t>(L, -1);
  726.     }
  727.  
  728.     lua_pop(L, 4);
  729.     return position;
  730. }
  731.  
  732. Position LuaScriptInterface::getPosition(lua_State* L, int32_t arg)
  733. {
  734.     Position position;
  735.     position.x = getField<uint16_t>(L, arg, "x");
  736.     position.y = getField<uint16_t>(L, arg, "y");
  737.     position.z = getField<uint8_t>(L, arg, "z");
  738.  
  739.     lua_pop(L, 3);
  740.     return position;
  741. }
  742.  
  743. Outfit_t LuaScriptInterface::getOutfit(lua_State* L, int32_t arg)
  744. {
  745.     Outfit_t outfit;
  746.     outfit.lookAddons = getField<uint8_t>(L, arg, "lookAddons");
  747.  
  748.     outfit.lookFeet = getField<uint8_t>(L, arg, "lookFeet");
  749.     outfit.lookLegs = getField<uint8_t>(L, arg, "lookLegs");
  750.     outfit.lookBody = getField<uint8_t>(L, arg, "lookBody");
  751.     outfit.lookHead = getField<uint8_t>(L, arg, "lookHead");
  752.  
  753.     outfit.lookTypeEx = getField<uint16_t>(L, arg, "lookTypeEx");
  754.     outfit.lookType = getField<uint16_t>(L, arg, "lookType");
  755.  
  756.     lua_pop(L, 7);
  757.     return outfit;
  758. }
  759.  
  760. LuaVariant LuaScriptInterface::getVariant(lua_State* L, int32_t arg)
  761. {
  762.     LuaVariant var;
  763.     switch (var.type = getField<LuaVariantType_t>(L, arg, "type")) {
  764.         case VARIANT_NUMBER: {
  765.             var.number = getField<uint32_t>(L, arg, "number");
  766.             lua_pop(L, 2);
  767.             break;
  768.         }
  769.  
  770.         case VARIANT_STRING: {
  771.             var.text = getFieldString(L, arg, "string");
  772.             lua_pop(L, 2);
  773.             break;
  774.         }
  775.  
  776.         case VARIANT_POSITION:
  777.         case VARIANT_TARGETPOSITION: {
  778.             lua_getfield(L, arg, "pos");
  779.             var.pos = getPosition(L, lua_gettop(L));
  780.             lua_pop(L, 2);
  781.             break;
  782.         }
  783.  
  784.         default: {
  785.             var.type = VARIANT_NONE;
  786.             lua_pop(L, 1);
  787.             break;
  788.         }
  789.     }
  790.     return var;
  791. }
  792.  
  793. Thing* LuaScriptInterface::getThing(lua_State* L, int32_t arg)
  794. {
  795.     Thing* thing;
  796.     if (lua_getmetatable(L, arg) != 0) {
  797.         lua_rawgeti(L, -1, 't');
  798.         switch(getNumber<uint32_t>(L, -1)) {
  799.             case LuaData_Item:
  800.                 thing = getUserdata<Item>(L, arg);
  801.                 break;
  802.             case LuaData_Container:
  803.                 thing = getUserdata<Container>(L, arg);
  804.                 break;
  805.             case LuaData_Teleport:
  806.                 thing = getUserdata<Teleport>(L, arg);
  807.                 break;
  808.             case LuaData_Player:
  809.                 thing = getUserdata<Player>(L, arg);
  810.                 break;
  811.             case LuaData_Monster:
  812.                 thing = getUserdata<Monster>(L, arg);
  813.                 break;
  814.             case LuaData_Npc:
  815.                 thing = getUserdata<Npc>(L, arg);
  816.                 break;
  817.             default:
  818.                 thing = nullptr;
  819.                 break;
  820.         }
  821.         lua_pop(L, 2);
  822.     } else {
  823.         thing = getScriptEnv()->getThingByUID(getNumber<uint32_t>(L, arg));
  824.     }
  825.     return thing;
  826. }
  827.  
  828. Creature* LuaScriptInterface::getCreature(lua_State* L, int32_t arg)
  829. {
  830.     if (isUserdata(L, arg)) {
  831.         return getUserdata<Creature>(L, arg);
  832.     }
  833.     return g_game.getCreatureByID(getNumber<uint32_t>(L, arg));
  834. }
  835.  
  836. Player* LuaScriptInterface::getPlayer(lua_State* L, int32_t arg)
  837. {
  838.     if (isUserdata(L, arg)) {
  839.         return getUserdata<Player>(L, arg);
  840.     }
  841.     return g_game.getPlayerByID(getNumber<uint32_t>(L, arg));
  842. }
  843.  
  844. std::string LuaScriptInterface::getFieldString(lua_State* L, int32_t arg, const std::string& key)
  845. {
  846.     lua_getfield(L, arg, key.c_str());
  847.     return getString(L, -1);
  848. }
  849.  
  850. LuaDataType LuaScriptInterface::getUserdataType(lua_State* L, int32_t arg)
  851. {
  852.     if (lua_getmetatable(L, arg) == 0) {
  853.         return LuaData_Unknown;
  854.     }
  855.     lua_rawgeti(L, -1, 't');
  856.  
  857.     LuaDataType type = getNumber<LuaDataType>(L, -1);
  858.     lua_pop(L, 2);
  859.  
  860.     return type;
  861. }
  862.  
  863. // Push
  864. void LuaScriptInterface::pushBoolean(lua_State* L, bool value)
  865. {
  866.     lua_pushboolean(L, value ? 1 : 0);
  867. }
  868.  
  869. void LuaScriptInterface::pushPosition(lua_State* L, const Position& position, int32_t stackpos/* = 0*/)
  870. {
  871.     lua_createtable(L, 0, 4);
  872.  
  873.     setField(L, "x", position.x);
  874.     setField(L, "y", position.y);
  875.     setField(L, "z", position.z);
  876.     setField(L, "stackpos", stackpos);
  877.  
  878.     setMetatable(L, -1, "Position");
  879. }
  880.  
  881. void LuaScriptInterface::pushOutfit(lua_State* L, const Outfit_t& outfit)
  882. {
  883.     lua_createtable(L, 0, 7);
  884.     setField(L, "lookType", outfit.lookType);
  885.     setField(L, "lookTypeEx", outfit.lookTypeEx);
  886.     setField(L, "lookHead", outfit.lookHead);
  887.     setField(L, "lookBody", outfit.lookBody);
  888.     setField(L, "lookLegs", outfit.lookLegs);
  889.     setField(L, "lookFeet", outfit.lookFeet);
  890.     setField(L, "lookAddons", outfit.lookAddons);
  891. }
  892.  
  893. #define registerEnum(value) { std::string enumName = #value; registerGlobalVariable(enumName.substr(enumName.find_last_of(':') + 1), value); }
  894. #define registerEnumIn(tableName, value) { std::string enumName = #value; registerVariable(tableName, enumName.substr(enumName.find_last_of(':') + 1), value); }
  895.  
  896. void LuaScriptInterface::registerFunctions()
  897. {
  898.     //getPlayerFlagValue(cid, flag)
  899.     lua_register(luaState, "getPlayerFlagValue", LuaScriptInterface::luaGetPlayerFlagValue);
  900.  
  901.     //getPlayerInstantSpellCount(cid)
  902.     lua_register(luaState, "getPlayerInstantSpellCount", LuaScriptInterface::luaGetPlayerInstantSpellCount);
  903.  
  904.     //getPlayerInstantSpellInfo(cid, index)
  905.     lua_register(luaState, "getPlayerInstantSpellInfo", LuaScriptInterface::luaGetPlayerInstantSpellInfo);
  906.  
  907.     //doPlayerAddItem(uid, itemid, <optional: default: 1> count/subtype)
  908.     //doPlayerAddItem(cid, itemid, <optional: default: 1> count, <optional: default: 1> canDropOnMap, <optional: default: 1>subtype)
  909.     //Returns uid of the created item
  910.     lua_register(luaState, "doPlayerAddItem", LuaScriptInterface::luaDoPlayerAddItem);
  911.  
  912.     //doCreateItem(itemid, type/count, pos)
  913.     //Returns uid of the created item, only works on tiles.
  914.     lua_register(luaState, "doCreateItem", LuaScriptInterface::luaDoCreateItem);
  915.  
  916.     //doCreateItemEx(itemid, <optional> count/subtype)
  917.     lua_register(luaState, "doCreateItemEx", LuaScriptInterface::luaDoCreateItemEx);
  918.  
  919.     //doTileAddItemEx(pos, uid)
  920.     lua_register(luaState, "doTileAddItemEx", LuaScriptInterface::luaDoTileAddItemEx);
  921.  
  922.     //doMoveCreature(cid, direction)
  923.     lua_register(luaState, "doMoveCreature", LuaScriptInterface::luaDoMoveCreature);
  924.  
  925.     //doSetCreatureLight(cid, lightLevel, lightColor, time)
  926.     lua_register(luaState, "doSetCreatureLight", LuaScriptInterface::luaDoSetCreatureLight);
  927.  
  928.     //getCreatureCondition(cid, condition[, subId])
  929.     lua_register(luaState, "getCreatureCondition", LuaScriptInterface::luaGetCreatureCondition);
  930.  
  931.     //isValidUID(uid)
  932.     lua_register(luaState, "isValidUID", LuaScriptInterface::luaIsValidUID);
  933.  
  934.     //isDepot(uid)
  935.     lua_register(luaState, "isDepot", LuaScriptInterface::luaIsDepot);
  936.  
  937.     //isMovable(uid)
  938.     lua_register(luaState, "isMovable", LuaScriptInterface::luaIsMoveable);
  939.  
  940.     //doAddContainerItem(uid, itemid, <optional> count/subtype)
  941.     lua_register(luaState, "doAddContainerItem", LuaScriptInterface::luaDoAddContainerItem);
  942.  
  943.     //getDepotId(uid)
  944.     lua_register(luaState, "getDepotId", LuaScriptInterface::luaGetDepotId);
  945.  
  946.     //getWorldTime()
  947.     lua_register(luaState, "getWorldTime", LuaScriptInterface::luaGetWorldTime);
  948.  
  949.     //getWorldLight()
  950.     lua_register(luaState, "getWorldLight", LuaScriptInterface::luaGetWorldLight);
  951.  
  952.     //getWorldUpTime()
  953.     lua_register(luaState, "getWorldUpTime", LuaScriptInterface::luaGetWorldUpTime);
  954.  
  955.     //createCombatArea( {area}, <optional> {extArea} )
  956.     lua_register(luaState, "createCombatArea", LuaScriptInterface::luaCreateCombatArea);
  957.  
  958.     //doAreaCombatHealth(cid, type, pos, area, min, max, effect)
  959.     lua_register(luaState, "doAreaCombatHealth", LuaScriptInterface::luaDoAreaCombatHealth);
  960.  
  961.     //doTargetCombatHealth(cid, target, type, min, max, effect)
  962.     lua_register(luaState, "doTargetCombatHealth", LuaScriptInterface::luaDoTargetCombatHealth);
  963.  
  964.     //doAreaCombatMana(cid, pos, area, min, max, effect)
  965.     lua_register(luaState, "doAreaCombatMana", LuaScriptInterface::luaDoAreaCombatMana);
  966.  
  967.     //doTargetCombatMana(cid, target, min, max, effect)
  968.     lua_register(luaState, "doTargetCombatMana", LuaScriptInterface::luaDoTargetCombatMana);
  969.  
  970.     //doAreaCombatCondition(cid, pos, area, condition, effect)
  971.     lua_register(luaState, "doAreaCombatCondition", LuaScriptInterface::luaDoAreaCombatCondition);
  972.  
  973.     //doTargetCombatCondition(cid, target, condition, effect)
  974.     lua_register(luaState, "doTargetCombatCondition", LuaScriptInterface::luaDoTargetCombatCondition);
  975.  
  976.     //doAreaCombatDispel(cid, pos, area, type, effect)
  977.     lua_register(luaState, "doAreaCombatDispel", LuaScriptInterface::luaDoAreaCombatDispel);
  978.  
  979.     //doTargetCombatDispel(cid, target, type, effect)
  980.     lua_register(luaState, "doTargetCombatDispel", LuaScriptInterface::luaDoTargetCombatDispel);
  981.  
  982.     //doChallengeCreature(cid, target)
  983.     lua_register(luaState, "doChallengeCreature", LuaScriptInterface::luaDoChallengeCreature);
  984.  
  985.     //doSetMonsterOutfit(cid, name, time)
  986.     lua_register(luaState, "doSetMonsterOutfit", LuaScriptInterface::luaSetMonsterOutfit);
  987.  
  988.     //doSetItemOutfit(cid, item, time)
  989.     lua_register(luaState, "doSetItemOutfit", LuaScriptInterface::luaSetItemOutfit);
  990.  
  991.     //doSetCreatureOutfit(cid, outfit, time)
  992.     lua_register(luaState, "doSetCreatureOutfit", LuaScriptInterface::luaSetCreatureOutfit);
  993.  
  994.     //isInArray(array, value)
  995.     lua_register(luaState, "isInArray", LuaScriptInterface::luaIsInArray);
  996.  
  997.     //addEvent(callback, delay, ...)
  998.     lua_register(luaState, "addEvent", LuaScriptInterface::luaAddEvent);
  999.  
  1000.     //stopEvent(eventid)
  1001.     lua_register(luaState, "stopEvent", LuaScriptInterface::luaStopEvent);
  1002.  
  1003.     //saveServer()
  1004.     lua_register(luaState, "saveServer", LuaScriptInterface::luaSaveServer);
  1005.  
  1006.     //cleanMap()
  1007.     lua_register(luaState, "cleanMap", LuaScriptInterface::luaCleanMap);
  1008.  
  1009.     //debugPrint(text)
  1010.     lua_register(luaState, "debugPrint", LuaScriptInterface::luaDebugPrint);
  1011.  
  1012.     //isInWar(cid, target)
  1013.     lua_register(luaState, "isInWar", LuaScriptInterface::luaIsInWar);
  1014.  
  1015.     //getWaypointPosition(name)
  1016.     lua_register(luaState, "getWaypointPositionByName", LuaScriptInterface::luaGetWaypointPositionByName);
  1017.  
  1018.     //sendChannelMessage(channelId, type, message)
  1019.     lua_register(luaState, "sendChannelMessage", LuaScriptInterface::luaSendChannelMessage);
  1020.  
  1021.     //sendGuildChannelMessage(guildId, type, message)
  1022.     lua_register(luaState, "sendGuildChannelMessage", LuaScriptInterface::luaSendGuildChannelMessage);
  1023.  
  1024. #ifndef LUAJIT_VERSION
  1025.     //bit operations for Lua, based on bitlib project release 24
  1026.     //bit.bnot, bit.band, bit.bor, bit.bxor, bit.lshift, bit.rshift
  1027.     luaL_register(luaState, "bit", LuaScriptInterface::luaBitReg);
  1028. #endif
  1029.  
  1030.     //configManager table
  1031.     luaL_register(luaState, "configManager", LuaScriptInterface::luaConfigManagerTable);
  1032.  
  1033.     //db table
  1034.     luaL_register(luaState, "db", LuaScriptInterface::luaDatabaseTable);
  1035.  
  1036.     //result table
  1037.     luaL_register(luaState, "result", LuaScriptInterface::luaResultTable);
  1038.  
  1039.     /* New functions */
  1040.     //registerClass(className, baseClass, newFunction)
  1041.     //registerTable(tableName)
  1042.     //registerMethod(className, functionName, function)
  1043.     //registerMetaMethod(className, functionName, function)
  1044.     //registerGlobalMethod(functionName, function)
  1045.     //registerVariable(tableName, name, value)
  1046.     //registerGlobalVariable(name, value)
  1047.     //registerEnum(value)
  1048.     //registerEnumIn(tableName, value)
  1049.  
  1050.     // Enums
  1051.     registerEnum(ACCOUNT_TYPE_NORMAL)
  1052.     registerEnum(ACCOUNT_TYPE_TUTOR)
  1053.     registerEnum(ACCOUNT_TYPE_SENIORTUTOR)
  1054.     registerEnum(ACCOUNT_TYPE_GAMEMASTER)
  1055.     registerEnum(ACCOUNT_TYPE_GOD)
  1056.  
  1057.     registerEnum(CALLBACK_PARAM_LEVELMAGICVALUE)
  1058.     registerEnum(CALLBACK_PARAM_SKILLVALUE)
  1059.     registerEnum(CALLBACK_PARAM_TARGETTILE)
  1060.     registerEnum(CALLBACK_PARAM_TARGETCREATURE)
  1061.  
  1062.     registerEnum(COMBAT_FORMULA_UNDEFINED)
  1063.     registerEnum(COMBAT_FORMULA_LEVELMAGIC)
  1064.     registerEnum(COMBAT_FORMULA_SKILL)
  1065.     registerEnum(COMBAT_FORMULA_DAMAGE)
  1066.  
  1067.     registerEnum(DIRECTION_NORTH)
  1068.     registerEnum(DIRECTION_EAST)
  1069.     registerEnum(DIRECTION_SOUTH)
  1070.     registerEnum(DIRECTION_WEST)
  1071.     registerEnum(DIRECTION_SOUTHWEST)
  1072.     registerEnum(DIRECTION_SOUTHEAST)
  1073.     registerEnum(DIRECTION_NORTHWEST)
  1074.     registerEnum(DIRECTION_NORTHEAST)
  1075.  
  1076.     registerEnum(COMBAT_NONE)
  1077.     registerEnum(COMBAT_PHYSICALDAMAGE)
  1078.     registerEnum(COMBAT_ENERGYDAMAGE)
  1079.     registerEnum(COMBAT_EARTHDAMAGE)
  1080.     registerEnum(COMBAT_FIREDAMAGE)
  1081.     registerEnum(COMBAT_UNDEFINEDDAMAGE)
  1082.     registerEnum(COMBAT_LIFEDRAIN)
  1083.     registerEnum(COMBAT_MANADRAIN)
  1084.     registerEnum(COMBAT_HEALING)
  1085.     registerEnum(COMBAT_DROWNDAMAGE)
  1086.     registerEnum(COMBAT_ICEDAMAGE)
  1087.     registerEnum(COMBAT_HOLYDAMAGE)
  1088.     registerEnum(COMBAT_DEATHDAMAGE)
  1089.  
  1090.     registerEnum(COMBAT_PARAM_TYPE)
  1091.     registerEnum(COMBAT_PARAM_EFFECT)
  1092.     registerEnum(COMBAT_PARAM_DISTANCEEFFECT)
  1093.     registerEnum(COMBAT_PARAM_BLOCKSHIELD)
  1094.     registerEnum(COMBAT_PARAM_BLOCKARMOR)
  1095.     registerEnum(COMBAT_PARAM_TARGETCASTERORTOPMOST)
  1096.     registerEnum(COMBAT_PARAM_CREATEITEM)
  1097.     registerEnum(COMBAT_PARAM_AGGRESSIVE)
  1098.     registerEnum(COMBAT_PARAM_DISPEL)
  1099.     registerEnum(COMBAT_PARAM_USECHARGES)
  1100.  
  1101.     registerEnum(CONDITION_NONE)
  1102.     registerEnum(CONDITION_POISON)
  1103.     registerEnum(CONDITION_FIRE)
  1104.     registerEnum(CONDITION_ENERGY)
  1105.     registerEnum(CONDITION_BLEEDING)
  1106.     registerEnum(CONDITION_HASTE)
  1107.     registerEnum(CONDITION_PARALYZE)
  1108.     registerEnum(CONDITION_OUTFIT)
  1109.     registerEnum(CONDITION_INVISIBLE)
  1110.     registerEnum(CONDITION_LIGHT)
  1111.     registerEnum(CONDITION_MANASHIELD)
  1112.     registerEnum(CONDITION_INFIGHT)
  1113.     registerEnum(CONDITION_DRUNK)
  1114.     registerEnum(CONDITION_EXHAUST_WEAPON)
  1115.     registerEnum(CONDITION_REGENERATION)
  1116.     registerEnum(CONDITION_SOUL)
  1117.     registerEnum(CONDITION_DROWN)
  1118.     registerEnum(CONDITION_MUTED)
  1119.     registerEnum(CONDITION_CHANNELMUTEDTICKS)
  1120.     registerEnum(CONDITION_YELLTICKS)
  1121.     registerEnum(CONDITION_ATTRIBUTES)
  1122.     registerEnum(CONDITION_FREEZING)
  1123.     registerEnum(CONDITION_DAZZLED)
  1124.     registerEnum(CONDITION_CURSED)
  1125.     registerEnum(CONDITION_EXHAUST_COMBAT)
  1126.     registerEnum(CONDITION_EXHAUST_HEAL)
  1127.     registerEnum(CONDITION_PACIFIED)
  1128.  
  1129.     registerEnum(CONDITIONID_DEFAULT)
  1130.     registerEnum(CONDITIONID_COMBAT)
  1131.     registerEnum(CONDITIONID_HEAD)
  1132.     registerEnum(CONDITIONID_NECKLACE)
  1133.     registerEnum(CONDITIONID_BACKPACK)
  1134.     registerEnum(CONDITIONID_ARMOR)
  1135.     registerEnum(CONDITIONID_RIGHT)
  1136.     registerEnum(CONDITIONID_LEFT)
  1137.     registerEnum(CONDITIONID_LEGS)
  1138.     registerEnum(CONDITIONID_FEET)
  1139.     registerEnum(CONDITIONID_RING)
  1140.     registerEnum(CONDITIONID_AMMO)
  1141.  
  1142.     registerEnum(CONDITION_PARAM_OWNER)
  1143.     registerEnum(CONDITION_PARAM_TICKS)
  1144.     registerEnum(CONDITION_PARAM_HEALTHGAIN)
  1145.     registerEnum(CONDITION_PARAM_HEALTHTICKS)
  1146.     registerEnum(CONDITION_PARAM_MANAGAIN)
  1147.     registerEnum(CONDITION_PARAM_MANATICKS)
  1148.     registerEnum(CONDITION_PARAM_DELAYED)
  1149.     registerEnum(CONDITION_PARAM_SPEED)
  1150.     registerEnum(CONDITION_PARAM_LIGHT_LEVEL)
  1151.     registerEnum(CONDITION_PARAM_LIGHT_COLOR)
  1152.     registerEnum(CONDITION_PARAM_SOULGAIN)
  1153.     registerEnum(CONDITION_PARAM_SOULTICKS)
  1154.     registerEnum(CONDITION_PARAM_MINVALUE)
  1155.     registerEnum(CONDITION_PARAM_MAXVALUE)
  1156.     registerEnum(CONDITION_PARAM_STARTVALUE)
  1157.     registerEnum(CONDITION_PARAM_TICKINTERVAL)
  1158.     registerEnum(CONDITION_PARAM_FORCEUPDATE)
  1159.     registerEnum(CONDITION_PARAM_SKILL_MELEE)
  1160.     registerEnum(CONDITION_PARAM_SKILL_FIST)
  1161.     registerEnum(CONDITION_PARAM_SKILL_CLUB)
  1162.     registerEnum(CONDITION_PARAM_SKILL_SWORD)
  1163.     registerEnum(CONDITION_PARAM_SKILL_AXE)
  1164.     registerEnum(CONDITION_PARAM_SKILL_DISTANCE)
  1165.     registerEnum(CONDITION_PARAM_SKILL_SHIELD)
  1166.     registerEnum(CONDITION_PARAM_SKILL_FISHING)
  1167.     registerEnum(CONDITION_PARAM_STAT_MAXHITPOINTS)
  1168.     registerEnum(CONDITION_PARAM_STAT_MAXMANAPOINTS)
  1169.     registerEnum(CONDITION_PARAM_STAT_MAGICPOINTS)
  1170.     registerEnum(CONDITION_PARAM_STAT_MAXHITPOINTSPERCENT)
  1171.     registerEnum(CONDITION_PARAM_STAT_MAXMANAPOINTSPERCENT)
  1172.     registerEnum(CONDITION_PARAM_STAT_MAGICPOINTSPERCENT)
  1173.     registerEnum(CONDITION_PARAM_PERIODICDAMAGE)
  1174.     registerEnum(CONDITION_PARAM_SKILL_MELEEPERCENT)
  1175.     registerEnum(CONDITION_PARAM_SKILL_FISTPERCENT)
  1176.     registerEnum(CONDITION_PARAM_SKILL_CLUBPERCENT)
  1177.     registerEnum(CONDITION_PARAM_SKILL_SWORDPERCENT)
  1178.     registerEnum(CONDITION_PARAM_SKILL_AXEPERCENT)
  1179.     registerEnum(CONDITION_PARAM_SKILL_DISTANCEPERCENT)
  1180.     registerEnum(CONDITION_PARAM_SKILL_SHIELDPERCENT)
  1181.     registerEnum(CONDITION_PARAM_SKILL_FISHINGPERCENT)
  1182.     registerEnum(CONDITION_PARAM_BUFF_SPELL)
  1183.     registerEnum(CONDITION_PARAM_SUBID)
  1184.     registerEnum(CONDITION_PARAM_FIELD)
  1185.  
  1186.     registerEnum(CONST_ME_NONE)
  1187.     registerEnum(CONST_ME_DRAWBLOOD)
  1188.     registerEnum(CONST_ME_LOSEENERGY)
  1189.     registerEnum(CONST_ME_POFF)
  1190.     registerEnum(CONST_ME_BLOCKHIT)
  1191.     registerEnum(CONST_ME_EXPLOSIONAREA)
  1192.     registerEnum(CONST_ME_EXPLOSIONHIT)
  1193.     registerEnum(CONST_ME_FIREAREA)
  1194.     registerEnum(CONST_ME_YELLOW_RINGS)
  1195.     registerEnum(CONST_ME_GREEN_RINGS)
  1196.     registerEnum(CONST_ME_HITAREA)
  1197.     registerEnum(CONST_ME_TELEPORT)
  1198.     registerEnum(CONST_ME_ENERGYHIT)
  1199.     registerEnum(CONST_ME_MAGIC_BLUE)
  1200.     registerEnum(CONST_ME_MAGIC_RED)
  1201.     registerEnum(CONST_ME_MAGIC_GREEN)
  1202.     registerEnum(CONST_ME_HITBYFIRE)
  1203.     registerEnum(CONST_ME_HITBYPOISON)
  1204.     registerEnum(CONST_ME_MORTAREA)
  1205.     registerEnum(CONST_ME_SOUND_GREEN)
  1206.     registerEnum(CONST_ME_SOUND_RED)
  1207.     registerEnum(CONST_ME_POISONAREA)
  1208.     registerEnum(CONST_ME_SOUND_YELLOW)
  1209.     registerEnum(CONST_ME_SOUND_PURPLE)
  1210.     registerEnum(CONST_ME_SOUND_BLUE)
  1211.     registerEnum(CONST_ME_SOUND_WHITE)
  1212.     registerEnum(CONST_ME_BUBBLES)
  1213.     registerEnum(CONST_ME_CRAPS)
  1214.     registerEnum(CONST_ME_GIFT_WRAPS)
  1215.     registerEnum(CONST_ME_FIREWORK_YELLOW)
  1216.     registerEnum(CONST_ME_FIREWORK_RED)
  1217.     registerEnum(CONST_ME_FIREWORK_BLUE)
  1218.     registerEnum(CONST_ME_STUN)
  1219.     registerEnum(CONST_ME_SLEEP)
  1220.     registerEnum(CONST_ME_WATERCREATURE)
  1221.     registerEnum(CONST_ME_GROUNDSHAKER)
  1222.     registerEnum(CONST_ME_HEARTS)
  1223.     registerEnum(CONST_ME_FIREATTACK)
  1224.     registerEnum(CONST_ME_ENERGYAREA)
  1225.     registerEnum(CONST_ME_SMALLCLOUDS)
  1226.     registerEnum(CONST_ME_HOLYDAMAGE)
  1227.     registerEnum(CONST_ME_BIGCLOUDS)
  1228.     registerEnum(CONST_ME_ICEAREA)
  1229.     registerEnum(CONST_ME_ICETORNADO)
  1230.     registerEnum(CONST_ME_ICEATTACK)
  1231.     registerEnum(CONST_ME_STONES)
  1232.     registerEnum(CONST_ME_SMALLPLANTS)
  1233.     registerEnum(CONST_ME_CARNIPHILA)
  1234.     registerEnum(CONST_ME_PURPLEENERGY)
  1235.     registerEnum(CONST_ME_YELLOWENERGY)
  1236.     registerEnum(CONST_ME_HOLYAREA)
  1237.     registerEnum(CONST_ME_BIGPLANTS)
  1238.     registerEnum(CONST_ME_CAKE)
  1239.     registerEnum(CONST_ME_GIANTICE)
  1240.     registerEnum(CONST_ME_WATERSPLASH)
  1241.     registerEnum(CONST_ME_PLANTATTACK)
  1242.     registerEnum(CONST_ME_TUTORIALARROW)
  1243.     registerEnum(CONST_ME_TUTORIALSQUARE)
  1244.     registerEnum(CONST_ME_MIRRORHORIZONTAL)
  1245.     registerEnum(CONST_ME_MIRRORVERTICAL)
  1246.     registerEnum(CONST_ME_SKULLHORIZONTAL)
  1247.     registerEnum(CONST_ME_SKULLVERTICAL)
  1248.     registerEnum(CONST_ME_ASSASSIN)
  1249.     registerEnum(CONST_ME_STEPSHORIZONTAL)
  1250.     registerEnum(CONST_ME_BLOODYSTEPS)
  1251.     registerEnum(CONST_ME_STEPSVERTICAL)
  1252.     registerEnum(CONST_ME_YALAHARIGHOST)
  1253.     registerEnum(CONST_ME_BATS)
  1254.     registerEnum(CONST_ME_SMOKE)
  1255.     registerEnum(CONST_ME_INSECTS)
  1256.     registerEnum(CONST_ME_DRAGONHEAD)
  1257.  
  1258.     registerEnum(CONST_ANI_NONE)
  1259.     registerEnum(CONST_ANI_SPEAR)
  1260.     registerEnum(CONST_ANI_BOLT)
  1261.     registerEnum(CONST_ANI_ARROW)
  1262.     registerEnum(CONST_ANI_FIRE)
  1263.     registerEnum(CONST_ANI_ENERGY)
  1264.     registerEnum(CONST_ANI_POISONARROW)
  1265.     registerEnum(CONST_ANI_BURSTARROW)
  1266.     registerEnum(CONST_ANI_THROWINGSTAR)
  1267.     registerEnum(CONST_ANI_THROWINGKNIFE)
  1268.     registerEnum(CONST_ANI_SMALLSTONE)
  1269.     registerEnum(CONST_ANI_DEATH)
  1270.     registerEnum(CONST_ANI_LARGEROCK)
  1271.     registerEnum(CONST_ANI_SNOWBALL)
  1272.     registerEnum(CONST_ANI_POWERBOLT)
  1273.     registerEnum(CONST_ANI_POISON)
  1274.     registerEnum(CONST_ANI_INFERNALBOLT)
  1275.     registerEnum(CONST_ANI_HUNTINGSPEAR)
  1276.     registerEnum(CONST_ANI_ENCHANTEDSPEAR)
  1277.     registerEnum(CONST_ANI_REDSTAR)
  1278.     registerEnum(CONST_ANI_GREENSTAR)
  1279.     registerEnum(CONST_ANI_ROYALSPEAR)
  1280.     registerEnum(CONST_ANI_SNIPERARROW)
  1281.     registerEnum(CONST_ANI_ONYXARROW)
  1282.     registerEnum(CONST_ANI_PIERCINGBOLT)
  1283.     registerEnum(CONST_ANI_WHIRLWINDSWORD)
  1284.     registerEnum(CONST_ANI_WHIRLWINDAXE)
  1285.     registerEnum(CONST_ANI_WHIRLWINDCLUB)
  1286.     registerEnum(CONST_ANI_ETHEREALSPEAR)
  1287.     registerEnum(CONST_ANI_ICE)
  1288.     registerEnum(CONST_ANI_EARTH)
  1289.     registerEnum(CONST_ANI_HOLY)
  1290.     registerEnum(CONST_ANI_SUDDENDEATH)
  1291.     registerEnum(CONST_ANI_FLASHARROW)
  1292.     registerEnum(CONST_ANI_FLAMMINGARROW)
  1293.     registerEnum(CONST_ANI_SHIVERARROW)
  1294.     registerEnum(CONST_ANI_ENERGYBALL)
  1295.     registerEnum(CONST_ANI_SMALLICE)
  1296.     registerEnum(CONST_ANI_SMALLHOLY)
  1297.     registerEnum(CONST_ANI_SMALLEARTH)
  1298.     registerEnum(CONST_ANI_EARTHARROW)
  1299.     registerEnum(CONST_ANI_EXPLOSION)
  1300.     registerEnum(CONST_ANI_CAKE)
  1301.     registerEnum(CONST_ANI_WEAPONTYPE)
  1302.  
  1303.     registerEnum(CONST_PROP_BLOCKSOLID)
  1304.     registerEnum(CONST_PROP_HASHEIGHT)
  1305.     registerEnum(CONST_PROP_BLOCKPROJECTILE)
  1306.     registerEnum(CONST_PROP_BLOCKPATH)
  1307.     registerEnum(CONST_PROP_ISVERTICAL)
  1308.     registerEnum(CONST_PROP_ISHORIZONTAL)
  1309.     registerEnum(CONST_PROP_MOVEABLE)
  1310.     registerEnum(CONST_PROP_IMMOVABLEBLOCKSOLID)
  1311.     registerEnum(CONST_PROP_IMMOVABLEBLOCKPATH)
  1312.     registerEnum(CONST_PROP_IMMOVABLENOFIELDBLOCKPATH)
  1313.     registerEnum(CONST_PROP_NOFIELDBLOCKPATH)
  1314.     registerEnum(CONST_PROP_SUPPORTHANGABLE)
  1315.  
  1316.     registerEnum(CONST_SLOT_HEAD)
  1317.     registerEnum(CONST_SLOT_NECKLACE)
  1318.     registerEnum(CONST_SLOT_BACKPACK)
  1319.     registerEnum(CONST_SLOT_ARMOR)
  1320.     registerEnum(CONST_SLOT_RIGHT)
  1321.     registerEnum(CONST_SLOT_LEFT)
  1322.     registerEnum(CONST_SLOT_LEGS)
  1323.     registerEnum(CONST_SLOT_FEET)
  1324.     registerEnum(CONST_SLOT_RING)
  1325.     registerEnum(CONST_SLOT_AMMO)
  1326.  
  1327.     registerEnum(GAME_STATE_STARTUP)
  1328.     registerEnum(GAME_STATE_INIT)
  1329.     registerEnum(GAME_STATE_NORMAL)
  1330.     registerEnum(GAME_STATE_CLOSED)
  1331.     registerEnum(GAME_STATE_SHUTDOWN)
  1332.     registerEnum(GAME_STATE_CLOSING)
  1333.     registerEnum(GAME_STATE_MAINTAIN)
  1334.  
  1335.     registerEnum(MESSAGE_STATUS_CONSOLE_BLUE)
  1336.     registerEnum(MESSAGE_STATUS_CONSOLE_RED)
  1337.     registerEnum(MESSAGE_STATUS_DEFAULT)
  1338.     registerEnum(MESSAGE_STATUS_WARNING)
  1339.     registerEnum(MESSAGE_EVENT_ADVANCE)
  1340.     registerEnum(MESSAGE_STATUS_SMALL)
  1341.     registerEnum(MESSAGE_INFO_DESCR)
  1342.     registerEnum(MESSAGE_EVENT_DEFAULT)
  1343.     registerEnum(MESSAGE_EVENT_ORANGE)
  1344.     registerEnum(MESSAGE_STATUS_CONSOLE_ORANGE)
  1345.  
  1346.     registerEnum(CREATURETYPE_PLAYER)
  1347.     registerEnum(CREATURETYPE_MONSTER)
  1348.     registerEnum(CREATURETYPE_NPC)
  1349.  
  1350.     registerEnum(CLIENTOS_LINUX)
  1351.     registerEnum(CLIENTOS_WINDOWS)
  1352.     registerEnum(CLIENTOS_FLASH)
  1353.     registerEnum(CLIENTOS_OTCLIENT_LINUX)
  1354.     registerEnum(CLIENTOS_OTCLIENT_WINDOWS)
  1355.     registerEnum(CLIENTOS_OTCLIENT_MAC)
  1356.  
  1357.     registerEnum(ITEM_ATTRIBUTE_NONE)
  1358.     registerEnum(ITEM_ATTRIBUTE_ACTIONID)
  1359.     registerEnum(ITEM_ATTRIBUTE_UNIQUEID)
  1360.     registerEnum(ITEM_ATTRIBUTE_DESCRIPTION)
  1361.     registerEnum(ITEM_ATTRIBUTE_TEXT)
  1362.     registerEnum(ITEM_ATTRIBUTE_DATE)
  1363.     registerEnum(ITEM_ATTRIBUTE_WRITER)
  1364.     registerEnum(ITEM_ATTRIBUTE_NAME)
  1365.     registerEnum(ITEM_ATTRIBUTE_ARTICLE)
  1366.     registerEnum(ITEM_ATTRIBUTE_PLURALNAME)
  1367.     registerEnum(ITEM_ATTRIBUTE_WEIGHT)
  1368.     registerEnum(ITEM_ATTRIBUTE_ATTACK)
  1369.     registerEnum(ITEM_ATTRIBUTE_DEFENSE)
  1370.     registerEnum(ITEM_ATTRIBUTE_EXTRADEFENSE)
  1371.     registerEnum(ITEM_ATTRIBUTE_ARMOR)
  1372.     registerEnum(ITEM_ATTRIBUTE_HITCHANCE)
  1373.     registerEnum(ITEM_ATTRIBUTE_SHOOTRANGE)
  1374.     registerEnum(ITEM_ATTRIBUTE_OWNER)
  1375.     registerEnum(ITEM_ATTRIBUTE_DURATION)
  1376.     registerEnum(ITEM_ATTRIBUTE_DECAYSTATE)
  1377.     registerEnum(ITEM_ATTRIBUTE_CORPSEOWNER)
  1378.     registerEnum(ITEM_ATTRIBUTE_CHARGES)
  1379.     registerEnum(ITEM_ATTRIBUTE_FLUIDTYPE)
  1380.     registerEnum(ITEM_ATTRIBUTE_DOORID)
  1381.  
  1382.     registerEnum(ITEM_TYPE_DEPOT)
  1383.     registerEnum(ITEM_TYPE_MAILBOX)
  1384.     registerEnum(ITEM_TYPE_TRASHHOLDER)
  1385.     registerEnum(ITEM_TYPE_CONTAINER)
  1386.     registerEnum(ITEM_TYPE_DOOR)
  1387.     registerEnum(ITEM_TYPE_MAGICFIELD)
  1388.     registerEnum(ITEM_TYPE_TELEPORT)
  1389.     registerEnum(ITEM_TYPE_BED)
  1390.     registerEnum(ITEM_TYPE_KEY)
  1391.     registerEnum(ITEM_TYPE_RUNE)
  1392.  
  1393.     registerEnum(ITEM_BAG)
  1394.     registerEnum(ITEM_GOLD_COIN)
  1395.     registerEnum(ITEM_PLATINUM_COIN)
  1396.     registerEnum(ITEM_CRYSTAL_COIN)
  1397.     registerEnum(ITEM_AMULETOFLOSS)
  1398.     registerEnum(ITEM_PARCEL)
  1399.     registerEnum(ITEM_LABEL)
  1400.     registerEnum(ITEM_FIREFIELD_PVP_FULL)
  1401.     registerEnum(ITEM_FIREFIELD_PVP_MEDIUM)
  1402.     registerEnum(ITEM_FIREFIELD_PVP_SMALL)
  1403.     registerEnum(ITEM_FIREFIELD_PERSISTENT_FULL)
  1404.     registerEnum(ITEM_FIREFIELD_PERSISTENT_MEDIUM)
  1405.     registerEnum(ITEM_FIREFIELD_PERSISTENT_SMALL)
  1406.     registerEnum(ITEM_FIREFIELD_NOPVP)
  1407.     registerEnum(ITEM_POISONFIELD_PVP)
  1408.     registerEnum(ITEM_POISONFIELD_PERSISTENT)
  1409.     registerEnum(ITEM_POISONFIELD_NOPVP)
  1410.     registerEnum(ITEM_ENERGYFIELD_PVP)
  1411.     registerEnum(ITEM_ENERGYFIELD_PERSISTENT)
  1412.     registerEnum(ITEM_ENERGYFIELD_NOPVP)
  1413.     registerEnum(ITEM_MAGICWALL)
  1414.     registerEnum(ITEM_MAGICWALL_PERSISTENT)
  1415.     registerEnum(ITEM_MAGICWALL_SAFE)
  1416.     registerEnum(ITEM_WILDGROWTH)
  1417.     registerEnum(ITEM_WILDGROWTH_PERSISTENT)
  1418.     registerEnum(ITEM_WILDGROWTH_SAFE)
  1419.  
  1420.     registerEnum(PlayerFlag_CannotUseCombat)
  1421.     registerEnum(PlayerFlag_CannotAttackPlayer)
  1422.     registerEnum(PlayerFlag_CannotAttackMonster)
  1423.     registerEnum(PlayerFlag_CannotBeAttacked)
  1424.     registerEnum(PlayerFlag_CanConvinceAll)
  1425.     registerEnum(PlayerFlag_CanSummonAll)
  1426.     registerEnum(PlayerFlag_CanIllusionAll)
  1427.     registerEnum(PlayerFlag_CanSenseInvisibility)
  1428.     registerEnum(PlayerFlag_IgnoredByMonsters)
  1429.     registerEnum(PlayerFlag_NotGainInFight)
  1430.     registerEnum(PlayerFlag_HasInfiniteMana)
  1431.     registerEnum(PlayerFlag_HasInfiniteSoul)
  1432.     registerEnum(PlayerFlag_HasNoExhaustion)
  1433.     registerEnum(PlayerFlag_CannotUseSpells)
  1434.     registerEnum(PlayerFlag_CannotPickupItem)
  1435.     registerEnum(PlayerFlag_CanAlwaysLogin)
  1436.     registerEnum(PlayerFlag_CanBroadcast)
  1437.     registerEnum(PlayerFlag_CanEditHouses)
  1438.     registerEnum(PlayerFlag_CannotBeBanned)
  1439.     registerEnum(PlayerFlag_CannotBePushed)
  1440.     registerEnum(PlayerFlag_HasInfiniteCapacity)
  1441.     registerEnum(PlayerFlag_CanPushAllCreatures)
  1442.     registerEnum(PlayerFlag_CanTalkRedPrivate)
  1443.     registerEnum(PlayerFlag_CanTalkRedChannel)
  1444.     registerEnum(PlayerFlag_TalkOrangeHelpChannel)
  1445.     registerEnum(PlayerFlag_NotGainExperience)
  1446.     registerEnum(PlayerFlag_NotGainMana)
  1447.     registerEnum(PlayerFlag_NotGainHealth)
  1448.     registerEnum(PlayerFlag_NotGainSkill)
  1449.     registerEnum(PlayerFlag_SetMaxSpeed)
  1450.     registerEnum(PlayerFlag_SpecialVIP)
  1451.     registerEnum(PlayerFlag_NotGenerateLoot)
  1452.     registerEnum(PlayerFlag_CanTalkRedChannelAnonymous)
  1453.     registerEnum(PlayerFlag_IgnoreProtectionZone)
  1454.     registerEnum(PlayerFlag_IgnoreSpellCheck)
  1455.     registerEnum(PlayerFlag_IgnoreWeaponCheck)
  1456.     registerEnum(PlayerFlag_CannotBeMuted)
  1457.     registerEnum(PlayerFlag_IsAlwaysPremium)
  1458.  
  1459.     registerEnum(PLAYERSEX_FEMALE)
  1460.     registerEnum(PLAYERSEX_MALE)
  1461.  
  1462.     registerEnum(VOCATION_NONE)
  1463.  
  1464.     registerEnum(SKILL_FIST)
  1465.     registerEnum(SKILL_CLUB)
  1466.     registerEnum(SKILL_SWORD)
  1467.     registerEnum(SKILL_AXE)
  1468.     registerEnum(SKILL_DISTANCE)
  1469.     registerEnum(SKILL_SHIELD)
  1470.     registerEnum(SKILL_FISHING)
  1471.     registerEnum(SKILL_MAGLEVEL)
  1472.     registerEnum(SKILL_LEVEL)
  1473.  
  1474.     registerEnum(SKULL_NONE)
  1475.     registerEnum(SKULL_YELLOW)
  1476.     registerEnum(SKULL_GREEN)
  1477.     registerEnum(SKULL_WHITE)
  1478.     registerEnum(SKULL_RED)
  1479.     registerEnum(SKULL_BLACK)
  1480.  
  1481.     registerEnum(TALKTYPE_SAY)
  1482.     registerEnum(TALKTYPE_WHISPER)
  1483.     registerEnum(TALKTYPE_YELL)
  1484.     registerEnum(TALKTYPE_PRIVATE_PN)
  1485.     registerEnum(TALKTYPE_PRIVATE_NP)
  1486.     registerEnum(TALKTYPE_PRIVATE)
  1487.     registerEnum(TALKTYPE_CHANNEL_Y)
  1488.     registerEnum(TALKTYPE_CHANNEL_W)
  1489.     registerEnum(TALKTYPE_BROADCAST)
  1490.     registerEnum(TALKTYPE_CHANNEL_R1)
  1491.     registerEnum(TALKTYPE_PRIVATE_RED)
  1492.     registerEnum(TALKTYPE_CHANNEL_O)
  1493.     registerEnum(TALKTYPE_MONSTER_SAY)
  1494.     registerEnum(TALKTYPE_MONSTER_YELL)
  1495.     registerEnum(TALKTYPE_CHANNEL_R2)
  1496.  
  1497.     registerEnum(TEXTCOLOR_BLUE)
  1498.     registerEnum(TEXTCOLOR_LIGHTGREEN)
  1499.     registerEnum(TEXTCOLOR_LIGHTBLUE)
  1500.     registerEnum(TEXTCOLOR_MAYABLUE)
  1501.     registerEnum(TEXTCOLOR_DARKRED)
  1502.     registerEnum(TEXTCOLOR_LIGHTGREY)
  1503.     registerEnum(TEXTCOLOR_SKYBLUE)
  1504.     registerEnum(TEXTCOLOR_PURPLE)
  1505.     registerEnum(TEXTCOLOR_RED)
  1506.     registerEnum(TEXTCOLOR_ORANGE)
  1507.     registerEnum(TEXTCOLOR_YELLOW)
  1508.     registerEnum(TEXTCOLOR_WHITE_EXP)
  1509.     registerEnum(TEXTCOLOR_NONE)
  1510.  
  1511.     registerEnum(TILESTATE_NONE)
  1512.     registerEnum(TILESTATE_PROTECTIONZONE)
  1513.     registerEnum(TILESTATE_NOPVPZONE)
  1514.     registerEnum(TILESTATE_NOLOGOUT)
  1515.     registerEnum(TILESTATE_PVPZONE)
  1516.     registerEnum(TILESTATE_FLOORCHANGE)
  1517.     registerEnum(TILESTATE_FLOORCHANGE_DOWN)
  1518.     registerEnum(TILESTATE_FLOORCHANGE_NORTH)
  1519.     registerEnum(TILESTATE_FLOORCHANGE_SOUTH)
  1520.     registerEnum(TILESTATE_FLOORCHANGE_EAST)
  1521.     registerEnum(TILESTATE_FLOORCHANGE_WEST)
  1522.     registerEnum(TILESTATE_TELEPORT)
  1523.     registerEnum(TILESTATE_MAGICFIELD)
  1524.     registerEnum(TILESTATE_MAILBOX)
  1525.     registerEnum(TILESTATE_TRASHHOLDER)
  1526.     registerEnum(TILESTATE_BED)
  1527.     registerEnum(TILESTATE_DEPOT)
  1528.     registerEnum(TILESTATE_BLOCKSOLID)
  1529.     registerEnum(TILESTATE_BLOCKPATH)
  1530.     registerEnum(TILESTATE_IMMOVABLEBLOCKSOLID)
  1531.     registerEnum(TILESTATE_IMMOVABLEBLOCKPATH)
  1532.     registerEnum(TILESTATE_IMMOVABLENOFIELDBLOCKPATH)
  1533.     registerEnum(TILESTATE_NOFIELDBLOCKPATH)
  1534.     registerEnum(TILESTATE_FLOORCHANGE_SOUTH_ALT)
  1535.     registerEnum(TILESTATE_FLOORCHANGE_EAST_ALT)
  1536.     registerEnum(TILESTATE_SUPPORTS_HANGABLE)
  1537.  
  1538.     registerEnum(WEAPON_NONE)
  1539.     registerEnum(WEAPON_SWORD)
  1540.     registerEnum(WEAPON_CLUB)
  1541.     registerEnum(WEAPON_AXE)
  1542.     registerEnum(WEAPON_SHIELD)
  1543.     registerEnum(WEAPON_DISTANCE)
  1544.     registerEnum(WEAPON_WAND)
  1545.     registerEnum(WEAPON_AMMO)
  1546.  
  1547.     registerEnum(WORLD_TYPE_NO_PVP)
  1548.     registerEnum(WORLD_TYPE_PVP)
  1549.     registerEnum(WORLD_TYPE_PVP_ENFORCED)
  1550.  
  1551.     // Use with container:addItem, container:addItemEx and possibly other functions.
  1552.     registerEnum(FLAG_NOLIMIT)
  1553.     registerEnum(FLAG_IGNOREBLOCKITEM)
  1554.     registerEnum(FLAG_IGNOREBLOCKCREATURE)
  1555.     registerEnum(FLAG_CHILDISOWNER)
  1556.     registerEnum(FLAG_PATHFINDING)
  1557.     registerEnum(FLAG_IGNOREFIELDDAMAGE)
  1558.     registerEnum(FLAG_IGNORENOTMOVEABLE)
  1559.     registerEnum(FLAG_IGNOREAUTOSTACK)
  1560.  
  1561.     // Use with itemType:getSlotPosition
  1562.     registerEnum(SLOTP_WHEREEVER)
  1563.     registerEnum(SLOTP_HEAD)
  1564.     registerEnum(SLOTP_NECKLACE)
  1565.     registerEnum(SLOTP_BACKPACK)
  1566.     registerEnum(SLOTP_ARMOR)
  1567.     registerEnum(SLOTP_RIGHT)
  1568.     registerEnum(SLOTP_LEFT)
  1569.     registerEnum(SLOTP_LEGS)
  1570.     registerEnum(SLOTP_FEET)
  1571.     registerEnum(SLOTP_RING)
  1572.     registerEnum(SLOTP_AMMO)
  1573.     registerEnum(SLOTP_DEPOT)
  1574.     registerEnum(SLOTP_TWO_HAND)
  1575.  
  1576.     // Use with combat functions
  1577.     registerEnum(ORIGIN_NONE)
  1578.     registerEnum(ORIGIN_CONDITION)
  1579.     registerEnum(ORIGIN_SPELL)
  1580.     registerEnum(ORIGIN_MELEE)
  1581.     registerEnum(ORIGIN_RANGED)
  1582.  
  1583.     // Use with house:getAccessList, house:setAccessList
  1584.     registerEnum(GUEST_LIST)
  1585.     registerEnum(SUBOWNER_LIST)
  1586.  
  1587.     // Use with player:addMapMark
  1588.     registerEnum(MAPMARK_TICK)
  1589.     registerEnum(MAPMARK_QUESTION)
  1590.     registerEnum(MAPMARK_EXCLAMATION)
  1591.     registerEnum(MAPMARK_STAR)
  1592.     registerEnum(MAPMARK_CROSS)
  1593.     registerEnum(MAPMARK_TEMPLE)
  1594.     registerEnum(MAPMARK_KISS)
  1595.     registerEnum(MAPMARK_SHOVEL)
  1596.     registerEnum(MAPMARK_SWORD)
  1597.     registerEnum(MAPMARK_FLAG)
  1598.     registerEnum(MAPMARK_LOCK)
  1599.     registerEnum(MAPMARK_BAG)
  1600.     registerEnum(MAPMARK_SKULL)
  1601.     registerEnum(MAPMARK_DOLLAR)
  1602.     registerEnum(MAPMARK_REDNORTH)
  1603.     registerEnum(MAPMARK_REDSOUTH)
  1604.     registerEnum(MAPMARK_REDEAST)
  1605.     registerEnum(MAPMARK_REDWEST)
  1606.     registerEnum(MAPMARK_GREENNORTH)
  1607.     registerEnum(MAPMARK_GREENSOUTH)
  1608.  
  1609.     // Use with Game.getReturnMessage
  1610.     registerEnum(RETURNVALUE_NOERROR)
  1611.     registerEnum(RETURNVALUE_NOTPOSSIBLE)
  1612.     registerEnum(RETURNVALUE_NOTENOUGHROOM)
  1613.     registerEnum(RETURNVALUE_PLAYERISPZLOCKED)
  1614.     registerEnum(RETURNVALUE_PLAYERISNOTINVITED)
  1615.     registerEnum(RETURNVALUE_CANNOTTHROW)
  1616.     registerEnum(RETURNVALUE_THEREISNOWAY)
  1617.     registerEnum(RETURNVALUE_DESTINATIONOUTOFREACH)
  1618.     registerEnum(RETURNVALUE_CREATUREBLOCK)
  1619.     registerEnum(RETURNVALUE_NOTMOVEABLE)
  1620.     registerEnum(RETURNVALUE_DROPTWOHANDEDITEM)
  1621.     registerEnum(RETURNVALUE_BOTHHANDSNEEDTOBEFREE)
  1622.     registerEnum(RETURNVALUE_CANONLYUSEONEWEAPON)
  1623.     registerEnum(RETURNVALUE_NEEDEXCHANGE)
  1624.     registerEnum(RETURNVALUE_CANNOTBEDRESSED)
  1625.     registerEnum(RETURNVALUE_PUTTHISOBJECTINYOURHAND)
  1626.     registerEnum(RETURNVALUE_PUTTHISOBJECTINBOTHHANDS)
  1627.     registerEnum(RETURNVALUE_TOOFARAWAY)
  1628.     registerEnum(RETURNVALUE_FIRSTGODOWNSTAIRS)
  1629.     registerEnum(RETURNVALUE_FIRSTGOUPSTAIRS)
  1630.     registerEnum(RETURNVALUE_CONTAINERNOTENOUGHROOM)
  1631.     registerEnum(RETURNVALUE_NOTENOUGHCAPACITY)
  1632.     registerEnum(RETURNVALUE_CANNOTPICKUP)
  1633.     registerEnum(RETURNVALUE_THISISIMPOSSIBLE)
  1634.     registerEnum(RETURNVALUE_DEPOTISFULL)
  1635.     registerEnum(RETURNVALUE_CREATUREDOESNOTEXIST)
  1636.     registerEnum(RETURNVALUE_CANNOTUSETHISOBJECT)
  1637.     registerEnum(RETURNVALUE_PLAYERWITHTHISNAMEISNOTONLINE)
  1638.     registerEnum(RETURNVALUE_NOTREQUIREDLEVELTOUSERUNE)
  1639.     registerEnum(RETURNVALUE_YOUAREALREADYTRADING)
  1640.     registerEnum(RETURNVALUE_THISPLAYERISALREADYTRADING)
  1641.     registerEnum(RETURNVALUE_YOUMAYNOTLOGOUTDURINGAFIGHT)
  1642.     registerEnum(RETURNVALUE_DIRECTPLAYERSHOOT)
  1643.     registerEnum(RETURNVALUE_NOTENOUGHLEVEL)
  1644.     registerEnum(RETURNVALUE_NOTENOUGHMAGICLEVEL)
  1645.     registerEnum(RETURNVALUE_NOTENOUGHMANA)
  1646.     registerEnum(RETURNVALUE_NOTENOUGHSOUL)
  1647.     registerEnum(RETURNVALUE_YOUAREEXHAUSTED)
  1648.     registerEnum(RETURNVALUE_PLAYERISNOTREACHABLE)
  1649.     registerEnum(RETURNVALUE_CANONLYUSETHISRUNEONCREATURES)
  1650.     registerEnum(RETURNVALUE_ACTIONNOTPERMITTEDINPROTECTIONZONE)
  1651.     registerEnum(RETURNVALUE_YOUMAYNOTATTACKTHISPLAYER)
  1652.     registerEnum(RETURNVALUE_YOUMAYNOTATTACKAPERSONINPROTECTIONZONE)
  1653.     registerEnum(RETURNVALUE_YOUMAYNOTATTACKAPERSONWHILEINPROTECTIONZONE)
  1654.     registerEnum(RETURNVALUE_YOUMAYNOTATTACKTHISCREATURE)
  1655.     registerEnum(RETURNVALUE_YOUCANONLYUSEITONCREATURES)
  1656.     registerEnum(RETURNVALUE_CREATUREISNOTREACHABLE)
  1657.     registerEnum(RETURNVALUE_TURNSECUREMODETOATTACKUNMARKEDPLAYERS)
  1658.     registerEnum(RETURNVALUE_YOUNEEDPREMIUMACCOUNT)
  1659.     registerEnum(RETURNVALUE_YOUNEEDTOLEARNTHISSPELL)
  1660.     registerEnum(RETURNVALUE_YOURVOCATIONCANNOTUSETHISSPELL)
  1661.     registerEnum(RETURNVALUE_YOUNEEDAWEAPONTOUSETHISSPELL)
  1662.     registerEnum(RETURNVALUE_PLAYERISPZLOCKEDLEAVEPVPZONE)
  1663.     registerEnum(RETURNVALUE_PLAYERISPZLOCKEDENTERPVPZONE)
  1664.     registerEnum(RETURNVALUE_ACTIONNOTPERMITTEDINANOPVPZONE)
  1665.     registerEnum(RETURNVALUE_YOUCANNOTLOGOUTHERE)
  1666.     registerEnum(RETURNVALUE_YOUNEEDAMAGICITEMTOCASTSPELL)
  1667.     registerEnum(RETURNVALUE_CANNOTCONJUREITEMHERE)
  1668.     registerEnum(RETURNVALUE_YOUNEEDTOSPLITYOURSPEARS)
  1669.     registerEnum(RETURNVALUE_NAMEISTOOAMBIGIOUS)
  1670.     registerEnum(RETURNVALUE_CANONLYUSEONESHIELD)
  1671.     registerEnum(RETURNVALUE_NOPARTYMEMBERSINRANGE)
  1672.     registerEnum(RETURNVALUE_YOUARENOTTHEOWNER)
  1673.  
  1674.     // _G
  1675.     registerGlobalVariable("INDEX_WHEREEVER", INDEX_WHEREEVER);
  1676.     registerGlobalBoolean("VIRTUAL_PARENT", true);
  1677.  
  1678.     registerGlobalMethod("isType", LuaScriptInterface::luaIsType);
  1679.     registerGlobalMethod("rawgetmetatable", LuaScriptInterface::luaRawGetMetatable);
  1680.  
  1681.     // configKeys
  1682.     registerTable("configKeys");
  1683.  
  1684.     registerEnumIn("configKeys", ConfigManager::ALLOW_CHANGEOUTFIT)
  1685.     registerEnumIn("configKeys", ConfigManager::ONE_PLAYER_ON_ACCOUNT)
  1686.     registerEnumIn("configKeys", ConfigManager::AIMBOT_HOTKEY_ENABLED)
  1687.     registerEnumIn("configKeys", ConfigManager::REMOVE_RUNE_CHARGES)
  1688.     registerEnumIn("configKeys", ConfigManager::EXPERIENCE_FROM_PLAYERS)
  1689.     registerEnumIn("configKeys", ConfigManager::FREE_PREMIUM)
  1690.     registerEnumIn("configKeys", ConfigManager::REPLACE_KICK_ON_LOGIN)
  1691.     registerEnumIn("configKeys", ConfigManager::ALLOW_CLONES)
  1692.     registerEnumIn("configKeys", ConfigManager::BIND_ONLY_GLOBAL_ADDRESS)
  1693.     registerEnumIn("configKeys", ConfigManager::OPTIMIZE_DATABASE)
  1694.     registerEnumIn("configKeys", ConfigManager::EMOTE_SPELLS)
  1695.     registerEnumIn("configKeys", ConfigManager::STAMINA_SYSTEM)
  1696.     registerEnumIn("configKeys", ConfigManager::WARN_UNSAFE_SCRIPTS)
  1697.     registerEnumIn("configKeys", ConfigManager::CONVERT_UNSAFE_SCRIPTS)
  1698.     registerEnumIn("configKeys", ConfigManager::CLASSIC_EQUIPMENT_SLOTS)
  1699.  
  1700.     registerEnumIn("configKeys", ConfigManager::MAP_NAME)
  1701.     registerEnumIn("configKeys", ConfigManager::HOUSE_RENT_PERIOD)
  1702.     registerEnumIn("configKeys", ConfigManager::SERVER_NAME)
  1703.     registerEnumIn("configKeys", ConfigManager::OWNER_NAME)
  1704.     registerEnumIn("configKeys", ConfigManager::OWNER_EMAIL)
  1705.     registerEnumIn("configKeys", ConfigManager::URL)
  1706.     registerEnumIn("configKeys", ConfigManager::LOCATION)
  1707.     registerEnumIn("configKeys", ConfigManager::IP)
  1708.     registerEnumIn("configKeys", ConfigManager::MOTD)
  1709.     registerEnumIn("configKeys", ConfigManager::WORLD_TYPE)
  1710.     registerEnumIn("configKeys", ConfigManager::MYSQL_HOST)
  1711.     registerEnumIn("configKeys", ConfigManager::MYSQL_USER)
  1712.     registerEnumIn("configKeys", ConfigManager::MYSQL_PASS)
  1713.     registerEnumIn("configKeys", ConfigManager::MYSQL_DB)
  1714.     registerEnumIn("configKeys", ConfigManager::MYSQL_SOCK)
  1715.     registerEnumIn("configKeys", ConfigManager::DEFAULT_PRIORITY)
  1716.     registerEnumIn("configKeys", ConfigManager::MAP_AUTHOR)
  1717.  
  1718.     registerEnumIn("configKeys", ConfigManager::SQL_PORT)
  1719.     registerEnumIn("configKeys", ConfigManager::MAX_PLAYERS)
  1720.     registerEnumIn("configKeys", ConfigManager::PZ_LOCKED)
  1721.     registerEnumIn("configKeys", ConfigManager::DEFAULT_DESPAWNRANGE)
  1722.     registerEnumIn("configKeys", ConfigManager::DEFAULT_DESPAWNRADIUS)
  1723.     registerEnumIn("configKeys", ConfigManager::RATE_EXPERIENCE)
  1724.     registerEnumIn("configKeys", ConfigManager::RATE_SKILL)
  1725.     registerEnumIn("configKeys", ConfigManager::RATE_LOOT)
  1726.     registerEnumIn("configKeys", ConfigManager::RATE_MAGIC)
  1727.     registerEnumIn("configKeys", ConfigManager::RATE_SPAWN)
  1728.     registerEnumIn("configKeys", ConfigManager::HOUSE_PRICE)
  1729.     registerEnumIn("configKeys", ConfigManager::KILLS_TO_RED)
  1730.     registerEnumIn("configKeys", ConfigManager::KILLS_TO_BLACK)
  1731.     registerEnumIn("configKeys", ConfigManager::MAX_MESSAGEBUFFER)
  1732.     registerEnumIn("configKeys", ConfigManager::ACTIONS_DELAY_INTERVAL)
  1733.     registerEnumIn("configKeys", ConfigManager::EX_ACTIONS_DELAY_INTERVAL)
  1734.     registerEnumIn("configKeys", ConfigManager::KICK_AFTER_MINUTES)
  1735.     registerEnumIn("configKeys", ConfigManager::PROTECTION_LEVEL)
  1736.     registerEnumIn("configKeys", ConfigManager::DEATH_LOSE_PERCENT)
  1737.     registerEnumIn("configKeys", ConfigManager::STATUSQUERY_TIMEOUT)
  1738.     registerEnumIn("configKeys", ConfigManager::FRAG_TIME)
  1739.     registerEnumIn("configKeys", ConfigManager::WHITE_SKULL_TIME)
  1740.     registerEnumIn("configKeys", ConfigManager::GAME_PORT)
  1741.     registerEnumIn("configKeys", ConfigManager::LOGIN_PORT)
  1742.     registerEnumIn("configKeys", ConfigManager::STATUS_PORT)
  1743.     registerEnumIn("configKeys", ConfigManager::STAIRHOP_DELAY)
  1744.     registerEnumIn("configKeys", ConfigManager::EXP_FROM_PLAYERS_LEVEL_RANGE)
  1745.     registerEnumIn("configKeys", ConfigManager::MAX_PACKETS_PER_SECOND)
  1746.  
  1747.     // os
  1748.     registerMethod("os", "mtime", LuaScriptInterface::luaSystemTime);
  1749.  
  1750.     // table
  1751.     registerMethod("table", "create", LuaScriptInterface::luaTableCreate);
  1752.  
  1753.     // Game
  1754.     registerTable("Game");
  1755.  
  1756.     registerMethod("Game", "getSpectators", LuaScriptInterface::luaGameGetSpectators);
  1757.     registerMethod("Game", "getPlayers", LuaScriptInterface::luaGameGetPlayers);
  1758.     registerMethod("Game", "loadMap", LuaScriptInterface::luaGameLoadMap);
  1759.  
  1760.     registerMethod("Game", "getExperienceStage", LuaScriptInterface::luaGameGetExperienceStage);
  1761.     registerMethod("Game", "getMonsterCount", LuaScriptInterface::luaGameGetMonsterCount);
  1762.     registerMethod("Game", "getPlayerCount", LuaScriptInterface::luaGameGetPlayerCount);
  1763.     registerMethod("Game", "getNpcCount", LuaScriptInterface::luaGameGetNpcCount);
  1764.  
  1765.     registerMethod("Game", "getTowns", LuaScriptInterface::luaGameGetTowns);
  1766.     registerMethod("Game", "getHouses", LuaScriptInterface::luaGameGetHouses);
  1767.  
  1768.     registerMethod("Game", "getGameState", LuaScriptInterface::luaGameGetGameState);
  1769.     registerMethod("Game", "setGameState", LuaScriptInterface::luaGameSetGameState);
  1770.  
  1771.     registerMethod("Game", "getWorldType", LuaScriptInterface::luaGameGetWorldType);
  1772.     registerMethod("Game", "setWorldType", LuaScriptInterface::luaGameSetWorldType);
  1773.  
  1774.     registerMethod("Game", "getReturnMessage", LuaScriptInterface::luaGameGetReturnMessage);
  1775.  
  1776.     registerMethod("Game", "createItem", LuaScriptInterface::luaGameCreateItem);
  1777.     registerMethod("Game", "createContainer", LuaScriptInterface::luaGameCreateContainer);
  1778.     registerMethod("Game", "createMonster", LuaScriptInterface::luaGameCreateMonster);
  1779.     registerMethod("Game", "createNpc", LuaScriptInterface::luaGameCreateNpc);
  1780.     registerMethod("Game", "createTile", LuaScriptInterface::luaGameCreateTile);
  1781.  
  1782.     registerMethod("Game", "startRaid", LuaScriptInterface::luaGameStartRaid);
  1783.  
  1784.     registerMethod("Game", "sendAnimatedText", LuaScriptInterface::luaGameSendAnimatedText);
  1785.  
  1786.     // Variant
  1787.     registerClass("Variant", "", LuaScriptInterface::luaVariantCreate);
  1788.  
  1789.     registerMethod("Variant", "getNumber", LuaScriptInterface::luaVariantGetNumber);
  1790.     registerMethod("Variant", "getString", LuaScriptInterface::luaVariantGetString);
  1791.     registerMethod("Variant", "getPosition", LuaScriptInterface::luaVariantGetPosition);
  1792.  
  1793.     // Position
  1794.     registerClass("Position", "", LuaScriptInterface::luaPositionCreate);
  1795.     registerMetaMethod("Position", "__add", LuaScriptInterface::luaPositionAdd);
  1796.     registerMetaMethod("Position", "__sub", LuaScriptInterface::luaPositionSub);
  1797.     registerMetaMethod("Position", "__eq", LuaScriptInterface::luaPositionCompare);
  1798.  
  1799.     registerMethod("Position", "getDistance", LuaScriptInterface::luaPositionGetDistance);
  1800.     registerMethod("Position", "isSightClear", LuaScriptInterface::luaPositionIsSightClear);
  1801.  
  1802.     registerMethod("Position", "sendMagicEffect", LuaScriptInterface::luaPositionSendMagicEffect);
  1803.     registerMethod("Position", "sendDistanceEffect", LuaScriptInterface::luaPositionSendDistanceEffect);
  1804.  
  1805.     // Tile
  1806.     registerClass("Tile", "", LuaScriptInterface::luaTileCreate);
  1807.     registerMetaMethod("Tile", "__eq", LuaScriptInterface::luaUserdataCompare);
  1808.  
  1809.     registerMethod("Tile", "getPosition", LuaScriptInterface::luaTileGetPosition);
  1810.     registerMethod("Tile", "getGround", LuaScriptInterface::luaTileGetGround);
  1811.     registerMethod("Tile", "getThing", LuaScriptInterface::luaTileGetThing);
  1812.     registerMethod("Tile", "getThingCount", LuaScriptInterface::luaTileGetThingCount);
  1813.     registerMethod("Tile", "getTopVisibleThing", LuaScriptInterface::luaTileGetTopVisibleThing);
  1814.  
  1815.     registerMethod("Tile", "getTopTopItem", LuaScriptInterface::luaTileGetTopTopItem);
  1816.     registerMethod("Tile", "getTopDownItem", LuaScriptInterface::luaTileGetTopDownItem);
  1817.     registerMethod("Tile", "getFieldItem", LuaScriptInterface::luaTileGetFieldItem);
  1818.  
  1819.     registerMethod("Tile", "getItemById", LuaScriptInterface::luaTileGetItemById);
  1820.     registerMethod("Tile", "getItemByType", LuaScriptInterface::luaTileGetItemByType);
  1821.     registerMethod("Tile", "getItemByTopOrder", LuaScriptInterface::luaTileGetItemByTopOrder);
  1822.     registerMethod("Tile", "getItemCountById", LuaScriptInterface::luaTileGetItemCountById);
  1823.  
  1824.     registerMethod("Tile", "getBottomCreature", LuaScriptInterface::luaTileGetBottomCreature);
  1825.     registerMethod("Tile", "getTopCreature", LuaScriptInterface::luaTileGetTopCreature);
  1826.     registerMethod("Tile", "getBottomVisibleCreature", LuaScriptInterface::luaTileGetBottomVisibleCreature);
  1827.     registerMethod("Tile", "getTopVisibleCreature", LuaScriptInterface::luaTileGetTopVisibleCreature);
  1828.  
  1829.     registerMethod("Tile", "getItems", LuaScriptInterface::luaTileGetItems);
  1830.     registerMethod("Tile", "getItemCount", LuaScriptInterface::luaTileGetItemCount);
  1831.     registerMethod("Tile", "getDownItemCount", LuaScriptInterface::luaTileGetDownItemCount);
  1832.     registerMethod("Tile", "getTopItemCount", LuaScriptInterface::luaTileGetTopItemCount);
  1833.  
  1834.     registerMethod("Tile", "getCreatures", LuaScriptInterface::luaTileGetCreatures);
  1835.     registerMethod("Tile", "getCreatureCount", LuaScriptInterface::luaTileGetCreatureCount);
  1836.  
  1837.     registerMethod("Tile", "getThingIndex", LuaScriptInterface::luaTileGetThingIndex);
  1838.  
  1839.     registerMethod("Tile", "hasProperty", LuaScriptInterface::luaTileHasProperty);
  1840.     registerMethod("Tile", "hasFlag", LuaScriptInterface::luaTileHasFlag);
  1841.  
  1842.     registerMethod("Tile", "queryAdd", LuaScriptInterface::luaTileQueryAdd);
  1843.  
  1844.     registerMethod("Tile", "getHouse", LuaScriptInterface::luaTileGetHouse);
  1845.  
  1846.     // NetworkMessage
  1847.     registerClass("NetworkMessage", "", LuaScriptInterface::luaNetworkMessageCreate);
  1848.     registerMetaMethod("NetworkMessage", "__eq", LuaScriptInterface::luaUserdataCompare);
  1849.     registerMetaMethod("NetworkMessage", "__gc", LuaScriptInterface::luaNetworkMessageDelete);
  1850.     registerMethod("NetworkMessage", "delete", LuaScriptInterface::luaNetworkMessageDelete);
  1851.  
  1852.     registerMethod("NetworkMessage", "getByte", LuaScriptInterface::luaNetworkMessageGetByte);
  1853.     registerMethod("NetworkMessage", "getU16", LuaScriptInterface::luaNetworkMessageGetU16);
  1854.     registerMethod("NetworkMessage", "getU32", LuaScriptInterface::luaNetworkMessageGetU32);
  1855.     registerMethod("NetworkMessage", "getU64", LuaScriptInterface::luaNetworkMessageGetU64);
  1856.     registerMethod("NetworkMessage", "getString", LuaScriptInterface::luaNetworkMessageGetString);
  1857.     registerMethod("NetworkMessage", "getPosition", LuaScriptInterface::luaNetworkMessageGetPosition);
  1858.  
  1859.     registerMethod("NetworkMessage", "addByte", LuaScriptInterface::luaNetworkMessageAddByte);
  1860.     registerMethod("NetworkMessage", "addU16", LuaScriptInterface::luaNetworkMessageAddU16);
  1861.     registerMethod("NetworkMessage", "addU32", LuaScriptInterface::luaNetworkMessageAddU32);
  1862.     registerMethod("NetworkMessage", "addU64", LuaScriptInterface::luaNetworkMessageAddU64);
  1863.     registerMethod("NetworkMessage", "addString", LuaScriptInterface::luaNetworkMessageAddString);
  1864.     registerMethod("NetworkMessage", "addPosition", LuaScriptInterface::luaNetworkMessageAddPosition);
  1865.     registerMethod("NetworkMessage", "addDouble", LuaScriptInterface::luaNetworkMessageAddDouble);
  1866.     registerMethod("NetworkMessage", "addItem", LuaScriptInterface::luaNetworkMessageAddItem);
  1867.     registerMethod("NetworkMessage", "addItemId", LuaScriptInterface::luaNetworkMessageAddItemId);
  1868.  
  1869.     registerMethod("NetworkMessage", "reset", LuaScriptInterface::luaNetworkMessageReset);
  1870.     registerMethod("NetworkMessage", "skipBytes", LuaScriptInterface::luaNetworkMessageSkipBytes);
  1871.     registerMethod("NetworkMessage", "sendToPlayer", LuaScriptInterface::luaNetworkMessageSendToPlayer);
  1872.  
  1873.     // Item
  1874.     registerClass("Item", "", LuaScriptInterface::luaItemCreate);
  1875.     registerMetaMethod("Item", "__eq", LuaScriptInterface::luaUserdataCompare);
  1876.  
  1877.     registerMethod("Item", "isItem", LuaScriptInterface::luaItemIsItem);
  1878.  
  1879.     registerMethod("Item", "getParent", LuaScriptInterface::luaItemGetParent);
  1880.     registerMethod("Item", "getTopParent", LuaScriptInterface::luaItemGetTopParent);
  1881.  
  1882.     registerMethod("Item", "getId", LuaScriptInterface::luaItemGetId);
  1883.  
  1884.     registerMethod("Item", "clone", LuaScriptInterface::luaItemClone);
  1885.     registerMethod("Item", "split", LuaScriptInterface::luaItemSplit);
  1886.     registerMethod("Item", "remove", LuaScriptInterface::luaItemRemove);
  1887.  
  1888.     registerMethod("Item", "getUniqueId", LuaScriptInterface::luaItemGetUniqueId);
  1889.     registerMethod("Item", "getActionId", LuaScriptInterface::luaItemGetActionId);
  1890.     registerMethod("Item", "setActionId", LuaScriptInterface::luaItemSetActionId);
  1891.  
  1892.     registerMethod("Item", "getCount", LuaScriptInterface::luaItemGetCount);
  1893.     registerMethod("Item", "getCharges", LuaScriptInterface::luaItemGetCharges);
  1894.     registerMethod("Item", "getFluidType", LuaScriptInterface::luaItemGetFluidType);
  1895.     registerMethod("Item", "getWeight", LuaScriptInterface::luaItemGetWeight);
  1896.  
  1897.     registerMethod("Item", "getSubType", LuaScriptInterface::luaItemGetSubType);
  1898.  
  1899.     registerMethod("Item", "getName", LuaScriptInterface::luaItemGetName);
  1900.     registerMethod("Item", "getPluralName", LuaScriptInterface::luaItemGetPluralName);
  1901.     registerMethod("Item", "getArticle", LuaScriptInterface::luaItemGetArticle);
  1902.  
  1903.     registerMethod("Item", "getPosition", LuaScriptInterface::luaItemGetPosition);
  1904.     registerMethod("Item", "getTile", LuaScriptInterface::luaItemGetTile);
  1905.  
  1906.     registerMethod("Item", "hasAttribute", LuaScriptInterface::luaItemHasAttribute);
  1907.     registerMethod("Item", "getAttribute", LuaScriptInterface::luaItemGetAttribute);
  1908.     registerMethod("Item", "setAttribute", LuaScriptInterface::luaItemSetAttribute);
  1909.     registerMethod("Item", "removeAttribute", LuaScriptInterface::luaItemRemoveAttribute);
  1910.  
  1911.     registerMethod("Item", "moveTo", LuaScriptInterface::luaItemMoveTo);
  1912.     registerMethod("Item", "transform", LuaScriptInterface::luaItemTransform);
  1913.     registerMethod("Item", "decay", LuaScriptInterface::luaItemDecay);
  1914.  
  1915.     registerMethod("Item", "getDescription", LuaScriptInterface::luaItemGetDescription);
  1916.  
  1917.     registerMethod("Item", "hasProperty", LuaScriptInterface::luaItemHasProperty);
  1918.  
  1919.     // Container
  1920.     registerClass("Container", "Item", LuaScriptInterface::luaContainerCreate);
  1921.     registerMetaMethod("Container", "__eq", LuaScriptInterface::luaUserdataCompare);
  1922.  
  1923.     registerMethod("Container", "getSize", LuaScriptInterface::luaContainerGetSize);
  1924.     registerMethod("Container", "getCapacity", LuaScriptInterface::luaContainerGetCapacity);
  1925.     registerMethod("Container", "getEmptySlots", LuaScriptInterface::luaContainerGetEmptySlots);
  1926.  
  1927.     registerMethod("Container", "getItemHoldingCount", LuaScriptInterface::luaContainerGetItemHoldingCount);
  1928.     registerMethod("Container", "getItemCountById", LuaScriptInterface::luaContainerGetItemCountById);
  1929.  
  1930.     registerMethod("Container", "getItem", LuaScriptInterface::luaContainerGetItem);
  1931.     registerMethod("Container", "hasItem", LuaScriptInterface::luaContainerHasItem);
  1932.     registerMethod("Container", "addItem", LuaScriptInterface::luaContainerAddItem);
  1933.     registerMethod("Container", "addItemEx", LuaScriptInterface::luaContainerAddItemEx);
  1934.  
  1935.     // Teleport
  1936.     registerClass("Teleport", "Item", LuaScriptInterface::luaTeleportCreate);
  1937.     registerMetaMethod("Teleport", "__eq", LuaScriptInterface::luaUserdataCompare);
  1938.  
  1939.     registerMethod("Teleport", "getDestination", LuaScriptInterface::luaTeleportGetDestination);
  1940.     registerMethod("Teleport", "setDestination", LuaScriptInterface::luaTeleportSetDestination);
  1941.  
  1942.     // Creature
  1943.     registerClass("Creature", "", LuaScriptInterface::luaCreatureCreate);
  1944.     registerMetaMethod("Creature", "__eq", LuaScriptInterface::luaUserdataCompare);
  1945.  
  1946.     registerMethod("Creature", "registerEvent", LuaScriptInterface::luaCreatureRegisterEvent);
  1947.     registerMethod("Creature", "unregisterEvent", LuaScriptInterface::luaCreatureUnregisterEvent);
  1948.  
  1949.     registerMethod("Creature", "isRemoved", LuaScriptInterface::luaCreatureIsRemoved);
  1950.     registerMethod("Creature", "isCreature", LuaScriptInterface::luaCreatureIsCreature);
  1951.     registerMethod("Creature", "isInGhostMode", LuaScriptInterface::luaCreatureIsInGhostMode);
  1952.     registerMethod("Creature", "isHealthHidden", LuaScriptInterface::luaCreatureIsHealthHidden);
  1953.  
  1954.     registerMethod("Creature", "canSee", LuaScriptInterface::luaCreatureCanSee);
  1955.     registerMethod("Creature", "canSeeCreature", LuaScriptInterface::luaCreatureCanSeeCreature);
  1956.  
  1957.     registerMethod("Creature", "getParent", LuaScriptInterface::luaCreatureGetParent);
  1958.  
  1959.     registerMethod("Creature", "getId", LuaScriptInterface::luaCreatureGetId);
  1960.     registerMethod("Creature", "getName", LuaScriptInterface::luaCreatureGetName);
  1961.  
  1962.     registerMethod("Creature", "getTarget", LuaScriptInterface::luaCreatureGetTarget);
  1963.     registerMethod("Creature", "setTarget", LuaScriptInterface::luaCreatureSetTarget);
  1964.  
  1965.     registerMethod("Creature", "getFollowCreature", LuaScriptInterface::luaCreatureGetFollowCreature);
  1966.     registerMethod("Creature", "setFollowCreature", LuaScriptInterface::luaCreatureSetFollowCreature);
  1967.  
  1968.     registerMethod("Creature", "getMaster", LuaScriptInterface::luaCreatureGetMaster);
  1969.     registerMethod("Creature", "setMaster", LuaScriptInterface::luaCreatureSetMaster);
  1970.  
  1971.     registerMethod("Creature", "getLight", LuaScriptInterface::luaCreatureGetLight);
  1972.     registerMethod("Creature", "setLight", LuaScriptInterface::luaCreatureSetLight);
  1973.  
  1974.     registerMethod("Creature", "getSpeed", LuaScriptInterface::luaCreatureGetSpeed);
  1975.     registerMethod("Creature", "getBaseSpeed", LuaScriptInterface::luaCreatureGetBaseSpeed);
  1976.     registerMethod("Creature", "changeSpeed", LuaScriptInterface::luaCreatureChangeSpeed);
  1977.  
  1978.     registerMethod("Creature", "setDropLoot", LuaScriptInterface::luaCreatureSetDropLoot);
  1979.  
  1980.     registerMethod("Creature", "getPosition", LuaScriptInterface::luaCreatureGetPosition);
  1981.     registerMethod("Creature", "getTile", LuaScriptInterface::luaCreatureGetTile);
  1982.     registerMethod("Creature", "getDirection", LuaScriptInterface::luaCreatureGetDirection);
  1983.     registerMethod("Creature", "setDirection", LuaScriptInterface::luaCreatureSetDirection);
  1984.  
  1985.     registerMethod("Creature", "getHealth", LuaScriptInterface::luaCreatureGetHealth);
  1986.     registerMethod("Creature", "addHealth", LuaScriptInterface::luaCreatureAddHealth);
  1987.     registerMethod("Creature", "getMaxHealth", LuaScriptInterface::luaCreatureGetMaxHealth);
  1988.     registerMethod("Creature", "setMaxHealth", LuaScriptInterface::luaCreatureSetMaxHealth);
  1989.     registerMethod("Creature", "setHiddenHealth", LuaScriptInterface::luaCreatureSetHiddenHealth);
  1990.  
  1991.     registerMethod("Creature", "getMana", LuaScriptInterface::luaCreatureGetMana);
  1992.     registerMethod("Creature", "addMana", LuaScriptInterface::luaCreatureAddMana);
  1993.     registerMethod("Creature", "getMaxMana", LuaScriptInterface::luaCreatureGetMaxMana);
  1994.  
  1995.     registerMethod("Creature", "getSkull", LuaScriptInterface::luaCreatureGetSkull);
  1996.     registerMethod("Creature", "setSkull", LuaScriptInterface::luaCreatureSetSkull);
  1997.  
  1998.     registerMethod("Creature", "getOutfit", LuaScriptInterface::luaCreatureGetOutfit);
  1999.     registerMethod("Creature", "setOutfit", LuaScriptInterface::luaCreatureSetOutfit);
  2000.  
  2001.     registerMethod("Creature", "getCondition", LuaScriptInterface::luaCreatureGetCondition);
  2002.     registerMethod("Creature", "addCondition", LuaScriptInterface::luaCreatureAddCondition);
  2003.     registerMethod("Creature", "removeCondition", LuaScriptInterface::luaCreatureRemoveCondition);
  2004.  
  2005.     registerMethod("Creature", "remove", LuaScriptInterface::luaCreatureRemove);
  2006.     registerMethod("Creature", "teleportTo", LuaScriptInterface::luaCreatureTeleportTo);
  2007.     registerMethod("Creature", "say", LuaScriptInterface::luaCreatureSay);
  2008.  
  2009.     registerMethod("Creature", "getDamageMap", LuaScriptInterface::luaCreatureGetDamageMap);
  2010.  
  2011.     registerMethod("Creature", "getSummons", LuaScriptInterface::luaCreatureGetSummons);
  2012.  
  2013.     registerMethod("Creature", "getDescription", LuaScriptInterface::luaCreatureGetDescription);
  2014.  
  2015.     registerMethod("Creature", "getPathTo", LuaScriptInterface::luaCreatureGetPathTo);
  2016.  
  2017.     // Player
  2018.     registerClass("Player", "Creature", LuaScriptInterface::luaPlayerCreate);
  2019.     registerMetaMethod("Player", "__eq", LuaScriptInterface::luaUserdataCompare);
  2020.  
  2021.     registerMethod("Player", "isPlayer", LuaScriptInterface::luaPlayerIsPlayer);
  2022.  
  2023.     registerMethod("Player", "getGuid", LuaScriptInterface::luaPlayerGetGuid);
  2024.     registerMethod("Player", "getIp", LuaScriptInterface::luaPlayerGetIp);
  2025.     registerMethod("Player", "getAccountId", LuaScriptInterface::luaPlayerGetAccountId);
  2026.     registerMethod("Player", "getLastLoginSaved", LuaScriptInterface::luaPlayerGetLastLoginSaved);
  2027.     registerMethod("Player", "getLastLogout", LuaScriptInterface::luaPlayerGetLastLogout);
  2028.  
  2029.     registerMethod("Player", "getAccountType", LuaScriptInterface::luaPlayerGetAccountType);
  2030.     registerMethod("Player", "setAccountType", LuaScriptInterface::luaPlayerSetAccountType);
  2031.  
  2032.     registerMethod("Player", "getCapacity", LuaScriptInterface::luaPlayerGetCapacity);
  2033.     registerMethod("Player", "setCapacity", LuaScriptInterface::luaPlayerSetCapacity);
  2034.  
  2035.     registerMethod("Player", "getFreeCapacity", LuaScriptInterface::luaPlayerGetFreeCapacity);
  2036.  
  2037.     registerMethod("Player", "getDepotChest", LuaScriptInterface::luaPlayerGetDepotChest);
  2038.  
  2039.     registerMethod("Player", "getSkullTime", LuaScriptInterface::luaPlayerGetSkullTime);
  2040.     registerMethod("Player", "setSkullTime", LuaScriptInterface::luaPlayerSetSkullTime);
  2041.     registerMethod("Player", "getDeathPenalty", LuaScriptInterface::luaPlayerGetDeathPenalty);
  2042.  
  2043.     registerMethod("Player", "getExperience", LuaScriptInterface::luaPlayerGetExperience);
  2044.     registerMethod("Player", "addExperience", LuaScriptInterface::luaPlayerAddExperience);
  2045.     registerMethod("Player", "removeExperience", LuaScriptInterface::luaPlayerRemoveExperience);
  2046.     registerMethod("Player", "getLevel", LuaScriptInterface::luaPlayerGetLevel);
  2047.  
  2048.     registerMethod("Player", "getMagicLevel", LuaScriptInterface::luaPlayerGetMagicLevel);
  2049.     registerMethod("Player", "getBaseMagicLevel", LuaScriptInterface::luaPlayerGetBaseMagicLevel);
  2050.     registerMethod("Player", "setMaxMana", LuaScriptInterface::luaPlayerSetMaxMana);
  2051.     registerMethod("Player", "getManaSpent", LuaScriptInterface::luaPlayerGetManaSpent);
  2052.     registerMethod("Player", "addManaSpent", LuaScriptInterface::luaPlayerAddManaSpent);
  2053.  
  2054.     registerMethod("Player", "getSkillLevel", LuaScriptInterface::luaPlayerGetSkillLevel);
  2055.     registerMethod("Player", "getEffectiveSkillLevel", LuaScriptInterface::luaPlayerGetEffectiveSkillLevel);
  2056.     registerMethod("Player", "getSkillPercent", LuaScriptInterface::luaPlayerGetSkillPercent);
  2057.     registerMethod("Player", "getSkillTries", LuaScriptInterface::luaPlayerGetSkillTries);
  2058.     registerMethod("Player", "addSkillTries", LuaScriptInterface::luaPlayerAddSkillTries);
  2059.  
  2060.     registerMethod("Player", "addOfflineTrainingTime", LuaScriptInterface::luaPlayerAddOfflineTrainingTime);
  2061.     registerMethod("Player", "getOfflineTrainingTime", LuaScriptInterface::luaPlayerGetOfflineTrainingTime);
  2062.     registerMethod("Player", "removeOfflineTrainingTime", LuaScriptInterface::luaPlayerRemoveOfflineTrainingTime);
  2063.  
  2064.     registerMethod("Player", "addOfflineTrainingTries", LuaScriptInterface::luaPlayerAddOfflineTrainingTries);
  2065.  
  2066.     registerMethod("Player", "getOfflineTrainingSkill", LuaScriptInterface::luaPlayerGetOfflineTrainingSkill);
  2067.     registerMethod("Player", "setOfflineTrainingSkill", LuaScriptInterface::luaPlayerSetOfflineTrainingSkill);
  2068.  
  2069.     registerMethod("Player", "getItemCount", LuaScriptInterface::luaPlayerGetItemCount);
  2070.     registerMethod("Player", "getItemById", LuaScriptInterface::luaPlayerGetItemById);
  2071.  
  2072.     registerMethod("Player", "getVocation", LuaScriptInterface::luaPlayerGetVocation);
  2073.     registerMethod("Player", "setVocation", LuaScriptInterface::luaPlayerSetVocation);
  2074.  
  2075.     registerMethod("Player", "getSex", LuaScriptInterface::luaPlayerGetSex);
  2076.     registerMethod("Player", "setSex", LuaScriptInterface::luaPlayerSetSex);
  2077.  
  2078.     registerMethod("Player", "getTown", LuaScriptInterface::luaPlayerGetTown);
  2079.     registerMethod("Player", "setTown", LuaScriptInterface::luaPlayerSetTown);
  2080.  
  2081.     registerMethod("Player", "getGuild", LuaScriptInterface::luaPlayerGetGuild);
  2082.     registerMethod("Player", "setGuild", LuaScriptInterface::luaPlayerSetGuild);
  2083.  
  2084.     registerMethod("Player", "getGuildLevel", LuaScriptInterface::luaPlayerGetGuildLevel);
  2085.     registerMethod("Player", "setGuildLevel", LuaScriptInterface::luaPlayerSetGuildLevel);
  2086.  
  2087.     registerMethod("Player", "getGuildNick", LuaScriptInterface::luaPlayerGetGuildNick);
  2088.     registerMethod("Player", "setGuildNick", LuaScriptInterface::luaPlayerSetGuildNick);
  2089.  
  2090.     registerMethod("Player", "getGroup", LuaScriptInterface::luaPlayerGetGroup);
  2091.     registerMethod("Player", "setGroup", LuaScriptInterface::luaPlayerSetGroup);
  2092.  
  2093.     registerMethod("Player", "getStamina", LuaScriptInterface::luaPlayerGetStamina);
  2094.     registerMethod("Player", "setStamina", LuaScriptInterface::luaPlayerSetStamina);
  2095.  
  2096.     registerMethod("Player", "getSoul", LuaScriptInterface::luaPlayerGetSoul);
  2097.     registerMethod("Player", "addSoul", LuaScriptInterface::luaPlayerAddSoul);
  2098.     registerMethod("Player", "getMaxSoul", LuaScriptInterface::luaPlayerGetMaxSoul);
  2099.  
  2100.     registerMethod("Player", "getBankBalance", LuaScriptInterface::luaPlayerGetBankBalance);
  2101.     registerMethod("Player", "setBankBalance", LuaScriptInterface::luaPlayerSetBankBalance);
  2102.  
  2103.     registerMethod("Player", "getStorageValue", LuaScriptInterface::luaPlayerGetStorageValue);
  2104.     registerMethod("Player", "setStorageValue", LuaScriptInterface::luaPlayerSetStorageValue);
  2105.  
  2106.     registerMethod("Player", "addItem", LuaScriptInterface::luaPlayerAddItem);
  2107.     registerMethod("Player", "addItemEx", LuaScriptInterface::luaPlayerAddItemEx);
  2108.     registerMethod("Player", "removeItem", LuaScriptInterface::luaPlayerRemoveItem);
  2109.  
  2110.     registerMethod("Player", "getMoney", LuaScriptInterface::luaPlayerGetMoney);
  2111.     registerMethod("Player", "addMoney", LuaScriptInterface::luaPlayerAddMoney);
  2112.     registerMethod("Player", "removeMoney", LuaScriptInterface::luaPlayerRemoveMoney);
  2113.  
  2114.     registerMethod("Player", "showTextDialog", LuaScriptInterface::luaPlayerShowTextDialog);
  2115.  
  2116.     registerMethod("Player", "sendTextMessage", LuaScriptInterface::luaPlayerSendTextMessage);
  2117.     registerMethod("Player", "sendChannelMessage", LuaScriptInterface::luaPlayerSendChannelMessage);
  2118.     registerMethod("Player", "sendPrivateMessage", LuaScriptInterface::luaPlayerSendPrivateMessage);
  2119.     registerMethod("Player", "channelSay", LuaScriptInterface::luaPlayerChannelSay);
  2120.     registerMethod("Player", "openChannel", LuaScriptInterface::luaPlayerOpenChannel);
  2121.  
  2122.     registerMethod("Player", "getSlotItem", LuaScriptInterface::luaPlayerGetSlotItem);
  2123.  
  2124.     registerMethod("Player", "getParty", LuaScriptInterface::luaPlayerGetParty);
  2125.  
  2126.     registerMethod("Player", "addOutfit", LuaScriptInterface::luaPlayerAddOutfit);
  2127.     registerMethod("Player", "addOutfitAddon", LuaScriptInterface::luaPlayerAddOutfitAddon);
  2128.     registerMethod("Player", "removeOutfit", LuaScriptInterface::luaPlayerRemoveOutfit);
  2129.     registerMethod("Player", "removeOutfitAddon", LuaScriptInterface::luaPlayerRemoveOutfitAddon);
  2130.     registerMethod("Player", "hasOutfit", LuaScriptInterface::luaPlayerHasOutfit);
  2131.     registerMethod("Player", "sendOutfitWindow", LuaScriptInterface::luaPlayerSendOutfitWindow);
  2132.  
  2133.     registerMethod("Player", "getPremiumDays", LuaScriptInterface::luaPlayerGetPremiumDays);
  2134.     registerMethod("Player", "addPremiumDays", LuaScriptInterface::luaPlayerAddPremiumDays);
  2135.     registerMethod("Player", "removePremiumDays", LuaScriptInterface::luaPlayerRemovePremiumDays);
  2136.  
  2137.     registerMethod("Player", "hasBlessing", LuaScriptInterface::luaPlayerHasBlessing);
  2138.     registerMethod("Player", "addBlessing", LuaScriptInterface::luaPlayerAddBlessing);
  2139.     registerMethod("Player", "removeBlessing", LuaScriptInterface::luaPlayerRemoveBlessing);
  2140.  
  2141.     registerMethod("Player", "canLearnSpell", LuaScriptInterface::luaPlayerCanLearnSpell);
  2142.     registerMethod("Player", "learnSpell", LuaScriptInterface::luaPlayerLearnSpell);
  2143.     registerMethod("Player", "forgetSpell", LuaScriptInterface::luaPlayerForgetSpell);
  2144.     registerMethod("Player", "hasLearnedSpell", LuaScriptInterface::luaPlayerHasLearnedSpell);
  2145.  
  2146.     registerMethod("Player", "sendTutorial", LuaScriptInterface::luaPlayerSendTutorial);
  2147.     registerMethod("Player", "addMapMark", LuaScriptInterface::luaPlayerAddMapMark);
  2148.  
  2149.     registerMethod("Player", "save", LuaScriptInterface::luaPlayerSave);
  2150.     registerMethod("Player", "popupFYI", LuaScriptInterface::luaPlayerPopupFYI);
  2151.  
  2152.     registerMethod("Player", "isPzLocked", LuaScriptInterface::luaPlayerIsPzLocked);
  2153.  
  2154.     registerMethod("Player", "getClient", LuaScriptInterface::luaPlayerGetClient);
  2155.     registerMethod("Player", "getHouse", LuaScriptInterface::luaPlayerGetHouse);
  2156.  
  2157.     registerMethod("Player", "setGhostMode", LuaScriptInterface::luaPlayerSetGhostMode);
  2158.  
  2159.     registerMethod("Player", "getContainerId", LuaScriptInterface::luaPlayerGetContainerId);
  2160.     registerMethod("Player", "getContainerById", LuaScriptInterface::luaPlayerGetContainerById);
  2161.     registerMethod("Player", "getContainerIndex", LuaScriptInterface::luaPlayerGetContainerIndex);
  2162.  
  2163.     // Monster
  2164.     registerClass("Monster", "Creature", LuaScriptInterface::luaMonsterCreate);
  2165.     registerMetaMethod("Monster", "__eq", LuaScriptInterface::luaUserdataCompare);
  2166.  
  2167.     registerMethod("Monster", "isMonster", LuaScriptInterface::luaMonsterIsMonster);
  2168.  
  2169.     registerMethod("Monster", "getType", LuaScriptInterface::luaMonsterGetType);
  2170.  
  2171.     registerMethod("Monster", "getSpawnPosition", LuaScriptInterface::luaMonsterGetSpawnPosition);
  2172.     registerMethod("Monster", "isInSpawnRange", LuaScriptInterface::luaMonsterIsInSpawnRange);
  2173.  
  2174.     registerMethod("Monster", "isIdle", LuaScriptInterface::luaMonsterIsIdle);
  2175.     registerMethod("Monster", "setIdle", LuaScriptInterface::luaMonsterSetIdle);
  2176.  
  2177.     registerMethod("Monster", "isTarget", LuaScriptInterface::luaMonsterIsTarget);
  2178.     registerMethod("Monster", "isOpponent", LuaScriptInterface::luaMonsterIsOpponent);
  2179.     registerMethod("Monster", "isFriend", LuaScriptInterface::luaMonsterIsFriend);
  2180.  
  2181.     registerMethod("Monster", "addFriend", LuaScriptInterface::luaMonsterAddFriend);
  2182.     registerMethod("Monster", "removeFriend", LuaScriptInterface::luaMonsterRemoveFriend);
  2183.     registerMethod("Monster", "getFriendList", LuaScriptInterface::luaMonsterGetFriendList);
  2184.     registerMethod("Monster", "getFriendCount", LuaScriptInterface::luaMonsterGetFriendCount);
  2185.  
  2186.     registerMethod("Monster", "addTarget", LuaScriptInterface::luaMonsterAddTarget);
  2187.     registerMethod("Monster", "removeTarget", LuaScriptInterface::luaMonsterRemoveTarget);
  2188.     registerMethod("Monster", "getTargetList", LuaScriptInterface::luaMonsterGetTargetList);
  2189.     registerMethod("Monster", "getTargetCount", LuaScriptInterface::luaMonsterGetTargetCount);
  2190.  
  2191.     registerMethod("Monster", "selectTarget", LuaScriptInterface::luaMonsterSelectTarget);
  2192.     registerMethod("Monster", "searchTarget", LuaScriptInterface::luaMonsterSearchTarget);
  2193.  
  2194.     // Npc
  2195.     registerClass("Npc", "Creature", LuaScriptInterface::luaNpcCreate);
  2196.     registerMetaMethod("Npc", "__eq", LuaScriptInterface::luaUserdataCompare);
  2197.  
  2198.     registerMethod("Npc", "isNpc", LuaScriptInterface::luaNpcIsNpc);
  2199.  
  2200.     registerMethod("Npc", "setMasterPos", LuaScriptInterface::luaNpcSetMasterPos);
  2201.  
  2202.     // Guild
  2203.     registerClass("Guild", "", LuaScriptInterface::luaGuildCreate);
  2204.     registerMetaMethod("Guild", "__eq", LuaScriptInterface::luaUserdataCompare);
  2205.  
  2206.     registerMethod("Guild", "getId", LuaScriptInterface::luaGuildGetId);
  2207.     registerMethod("Guild", "getName", LuaScriptInterface::luaGuildGetName);
  2208.     registerMethod("Guild", "getMembersOnline", LuaScriptInterface::luaGuildGetMembersOnline);
  2209.  
  2210.     registerMethod("Guild", "addRank", LuaScriptInterface::luaGuildAddRank);
  2211.     registerMethod("Guild", "getRankById", LuaScriptInterface::luaGuildGetRankById);
  2212.     registerMethod("Guild", "getRankByLevel", LuaScriptInterface::luaGuildGetRankByLevel);
  2213.  
  2214.     registerMethod("Guild", "getMotd", LuaScriptInterface::luaGuildGetMotd);
  2215.     registerMethod("Guild", "setMotd", LuaScriptInterface::luaGuildSetMotd);
  2216.  
  2217.     // Group
  2218.     registerClass("Group", "", LuaScriptInterface::luaGroupCreate);
  2219.     registerMetaMethod("Group", "__eq", LuaScriptInterface::luaUserdataCompare);
  2220.  
  2221.     registerMethod("Group", "getId", LuaScriptInterface::luaGroupGetId);
  2222.     registerMethod("Group", "getName", LuaScriptInterface::luaGroupGetName);
  2223.     registerMethod("Group", "getFlags", LuaScriptInterface::luaGroupGetFlags);
  2224.     registerMethod("Group", "getAccess", LuaScriptInterface::luaGroupGetAccess);
  2225.     registerMethod("Group", "getMaxDepotItems", LuaScriptInterface::luaGroupGetMaxDepotItems);
  2226.     registerMethod("Group", "getMaxVipEntries", LuaScriptInterface::luaGroupGetMaxVipEntries);
  2227.  
  2228.     // Vocation
  2229.     registerClass("Vocation", "", LuaScriptInterface::luaVocationCreate);
  2230.     registerMetaMethod("Vocation", "__eq", LuaScriptInterface::luaUserdataCompare);
  2231.  
  2232.     registerMethod("Vocation", "getId", LuaScriptInterface::luaVocationGetId);
  2233.     registerMethod("Vocation", "getClientId", LuaScriptInterface::luaVocationGetClientId);
  2234.     registerMethod("Vocation", "getName", LuaScriptInterface::luaVocationGetName);
  2235.     registerMethod("Vocation", "getDescription", LuaScriptInterface::luaVocationGetDescription);
  2236.  
  2237.     registerMethod("Vocation", "getRequiredSkillTries", LuaScriptInterface::luaVocationGetRequiredSkillTries);
  2238.     registerMethod("Vocation", "getRequiredManaSpent", LuaScriptInterface::luaVocationGetRequiredManaSpent);
  2239.  
  2240.     registerMethod("Vocation", "getCapacityGain", LuaScriptInterface::luaVocationGetCapacityGain);
  2241.  
  2242.     registerMethod("Vocation", "getHealthGain", LuaScriptInterface::luaVocationGetHealthGain);
  2243.     registerMethod("Vocation", "getHealthGainTicks", LuaScriptInterface::luaVocationGetHealthGainTicks);
  2244.     registerMethod("Vocation", "getHealthGainAmount", LuaScriptInterface::luaVocationGetHealthGainAmount);
  2245.  
  2246.     registerMethod("Vocation", "getManaGain", LuaScriptInterface::luaVocationGetManaGain);
  2247.     registerMethod("Vocation", "getManaGainTicks", LuaScriptInterface::luaVocationGetManaGainTicks);
  2248.     registerMethod("Vocation", "getManaGainAmount", LuaScriptInterface::luaVocationGetManaGainAmount);
  2249.  
  2250.     registerMethod("Vocation", "getMaxSoul", LuaScriptInterface::luaVocationGetMaxSoul);
  2251.     registerMethod("Vocation", "getSoulGainTicks", LuaScriptInterface::luaVocationGetSoulGainTicks);
  2252.  
  2253.     registerMethod("Vocation", "getAttackSpeed", LuaScriptInterface::luaVocationGetAttackSpeed);
  2254.     registerMethod("Vocation", "getBaseSpeed", LuaScriptInterface::luaVocationGetBaseSpeed);
  2255.  
  2256.     registerMethod("Vocation", "getDemotion", LuaScriptInterface::luaVocationGetDemotion);
  2257.     registerMethod("Vocation", "getPromotion", LuaScriptInterface::luaVocationGetPromotion);
  2258.  
  2259.     // Town
  2260.     registerClass("Town", "", LuaScriptInterface::luaTownCreate);
  2261.     registerMetaMethod("Town", "__eq", LuaScriptInterface::luaUserdataCompare);
  2262.  
  2263.     registerMethod("Town", "getId", LuaScriptInterface::luaTownGetId);
  2264.     registerMethod("Town", "getName", LuaScriptInterface::luaTownGetName);
  2265.     registerMethod("Town", "getTemplePosition", LuaScriptInterface::luaTownGetTemplePosition);
  2266.  
  2267.     // House
  2268.     registerClass("House", "", LuaScriptInterface::luaHouseCreate);
  2269.     registerMetaMethod("House", "__eq", LuaScriptInterface::luaUserdataCompare);
  2270.  
  2271.     registerMethod("House", "getId", LuaScriptInterface::luaHouseGetId);
  2272.     registerMethod("House", "getName", LuaScriptInterface::luaHouseGetName);
  2273.     registerMethod("House", "getTown", LuaScriptInterface::luaHouseGetTown);
  2274.     registerMethod("House", "getExitPosition", LuaScriptInterface::luaHouseGetExitPosition);
  2275.     registerMethod("House", "getRent", LuaScriptInterface::luaHouseGetRent);
  2276.  
  2277.     registerMethod("House", "getOwnerGuid", LuaScriptInterface::luaHouseGetOwnerGuid);
  2278.     registerMethod("House", "setOwnerGuid", LuaScriptInterface::luaHouseSetOwnerGuid);
  2279.  
  2280.     registerMethod("House", "getBeds", LuaScriptInterface::luaHouseGetBeds);
  2281.     registerMethod("House", "getBedCount", LuaScriptInterface::luaHouseGetBedCount);
  2282.  
  2283.     registerMethod("House", "getDoors", LuaScriptInterface::luaHouseGetDoors);
  2284.     registerMethod("House", "getDoorCount", LuaScriptInterface::luaHouseGetDoorCount);
  2285.  
  2286.     registerMethod("House", "getTiles", LuaScriptInterface::luaHouseGetTiles);
  2287.     registerMethod("House", "getTileCount", LuaScriptInterface::luaHouseGetTileCount);
  2288.  
  2289.     registerMethod("House", "getAccessList", LuaScriptInterface::luaHouseGetAccessList);
  2290.     registerMethod("House", "setAccessList", LuaScriptInterface::luaHouseSetAccessList);
  2291.  
  2292.     // ItemType
  2293.     registerClass("ItemType", "", LuaScriptInterface::luaItemTypeCreate);
  2294.     registerMetaMethod("ItemType", "__eq", LuaScriptInterface::luaUserdataCompare);
  2295.  
  2296.     registerMethod("ItemType", "isCorpse", LuaScriptInterface::luaItemTypeIsCorpse);
  2297.     registerMethod("ItemType", "isDoor", LuaScriptInterface::luaItemTypeIsDoor);
  2298.     registerMethod("ItemType", "isContainer", LuaScriptInterface::luaItemTypeIsContainer);
  2299.     registerMethod("ItemType", "isFluidContainer", LuaScriptInterface::luaItemTypeIsFluidContainer);
  2300.     registerMethod("ItemType", "isMovable", LuaScriptInterface::luaItemTypeIsMovable);
  2301.     registerMethod("ItemType", "isRune", LuaScriptInterface::luaItemTypeIsRune);
  2302.     registerMethod("ItemType", "isStackable", LuaScriptInterface::luaItemTypeIsStackable);
  2303.     registerMethod("ItemType", "isReadable", LuaScriptInterface::luaItemTypeIsReadable);
  2304.     registerMethod("ItemType", "isWritable", LuaScriptInterface::luaItemTypeIsWritable);
  2305.  
  2306.     registerMethod("ItemType", "getType", LuaScriptInterface::luaItemTypeGetType);
  2307.     registerMethod("ItemType", "getId", LuaScriptInterface::luaItemTypeGetId);
  2308.     registerMethod("ItemType", "getClientId", LuaScriptInterface::luaItemTypeGetClientId);
  2309.     registerMethod("ItemType", "getName", LuaScriptInterface::luaItemTypeGetName);
  2310.     registerMethod("ItemType", "getPluralName", LuaScriptInterface::luaItemTypeGetPluralName);
  2311.     registerMethod("ItemType", "getArticle", LuaScriptInterface::luaItemTypeGetArticle);
  2312.     registerMethod("ItemType", "getDescription", LuaScriptInterface::luaItemTypeGetDescription);
  2313.     registerMethod("ItemType", "getSlotPosition", LuaScriptInterface::luaItemTypeGetSlotPosition);
  2314.  
  2315.     registerMethod("ItemType", "getCharges", LuaScriptInterface::luaItemTypeGetCharges);
  2316.     registerMethod("ItemType", "getFluidSource", LuaScriptInterface::luaItemTypeGetFluidSource);
  2317.     registerMethod("ItemType", "getCapacity", LuaScriptInterface::luaItemTypeGetCapacity);
  2318.     registerMethod("ItemType", "getWeight", LuaScriptInterface::luaItemTypeGetWeight);
  2319.  
  2320.     registerMethod("ItemType", "getHitChance", LuaScriptInterface::luaItemTypeGetHitChance);
  2321.     registerMethod("ItemType", "getShootRange", LuaScriptInterface::luaItemTypeGetShootRange);
  2322.  
  2323.     registerMethod("ItemType", "getAttack", LuaScriptInterface::luaItemTypeGetAttack);
  2324.     registerMethod("ItemType", "getDefense", LuaScriptInterface::luaItemTypeGetDefense);
  2325.     registerMethod("ItemType", "getExtraDefense", LuaScriptInterface::luaItemTypeGetExtraDefense);
  2326.     registerMethod("ItemType", "getArmor", LuaScriptInterface::luaItemTypeGetArmor);
  2327.     registerMethod("ItemType", "getWeaponType", LuaScriptInterface::luaItemTypeGetWeaponType);
  2328.  
  2329.     registerMethod("ItemType", "getElementType", LuaScriptInterface::luaItemTypeGetElementType);
  2330.     registerMethod("ItemType", "getElementDamage", LuaScriptInterface::luaItemTypeGetElementDamage);
  2331.  
  2332.     registerMethod("ItemType", "getTransformEquipId", LuaScriptInterface::luaItemTypeGetTransformEquipId);
  2333.     registerMethod("ItemType", "getTransformDeEquipId", LuaScriptInterface::luaItemTypeGetTransformDeEquipId);
  2334.     registerMethod("ItemType", "getDestroyId", LuaScriptInterface::luaItemTypeGetDestroyId);
  2335.     registerMethod("ItemType", "getDecayId", LuaScriptInterface::luaItemTypeGetDecayId);
  2336.     registerMethod("ItemType", "getRequiredLevel", LuaScriptInterface::luaItemTypeGetRequiredLevel);
  2337.  
  2338.     registerMethod("ItemType", "hasSubType", LuaScriptInterface::luaItemTypeHasSubType);
  2339.  
  2340.     // Combat
  2341.     registerClass("Combat", "", LuaScriptInterface::luaCombatCreate);
  2342.     registerMetaMethod("Combat", "__eq", LuaScriptInterface::luaUserdataCompare);
  2343.  
  2344.     registerMethod("Combat", "setParameter", LuaScriptInterface::luaCombatSetParameter);
  2345.     registerMethod("Combat", "setFormula", LuaScriptInterface::luaCombatSetFormula);
  2346.  
  2347.     registerMethod("Combat", "setArea", LuaScriptInterface::luaCombatSetArea);
  2348.     registerMethod("Combat", "setCondition", LuaScriptInterface::luaCombatSetCondition);
  2349.     registerMethod("Combat", "setCallback", LuaScriptInterface::luaCombatSetCallback);
  2350.     registerMethod("Combat", "setOrigin", LuaScriptInterface::luaCombatSetOrigin);
  2351.  
  2352.     registerMethod("Combat", "execute", LuaScriptInterface::luaCombatExecute);
  2353.  
  2354.     // Condition
  2355.     registerClass("Condition", "", LuaScriptInterface::luaConditionCreate);
  2356.     registerMetaMethod("Condition", "__eq", LuaScriptInterface::luaUserdataCompare);
  2357.     registerMetaMethod("Condition", "__gc", LuaScriptInterface::luaConditionDelete);
  2358.     registerMethod("Condition", "delete", LuaScriptInterface::luaConditionDelete);
  2359.  
  2360.     registerMethod("Condition", "getId", LuaScriptInterface::luaConditionGetId);
  2361.     registerMethod("Condition", "getSubId", LuaScriptInterface::luaConditionGetSubId);
  2362.     registerMethod("Condition", "getType", LuaScriptInterface::luaConditionGetType);
  2363.     registerMethod("Condition", "getIcons", LuaScriptInterface::luaConditionGetIcons);
  2364.     registerMethod("Condition", "getEndTime", LuaScriptInterface::luaConditionGetEndTime);
  2365.  
  2366.     registerMethod("Condition", "clone", LuaScriptInterface::luaConditionClone);
  2367.  
  2368.     registerMethod("Condition", "getTicks", LuaScriptInterface::luaConditionGetTicks);
  2369.     registerMethod("Condition", "setTicks", LuaScriptInterface::luaConditionSetTicks);
  2370.  
  2371.     registerMethod("Condition", "setParameter", LuaScriptInterface::luaConditionSetParameter);
  2372.     registerMethod("Condition", "setFormula", LuaScriptInterface::luaConditionSetFormula);
  2373.     registerMethod("Condition", "setOutfit", LuaScriptInterface::luaConditionSetOutfit);
  2374.  
  2375.     registerMethod("Condition", "addDamage", LuaScriptInterface::luaConditionAddDamage);
  2376.  
  2377.     // MonsterType
  2378.     registerClass("MonsterType", "", LuaScriptInterface::luaMonsterTypeCreate);
  2379.     registerMetaMethod("MonsterType", "__eq", LuaScriptInterface::luaUserdataCompare);
  2380.  
  2381.     registerMethod("MonsterType", "isAttackable", LuaScriptInterface::luaMonsterTypeIsAttackable);
  2382.     registerMethod("MonsterType", "isConvinceable", LuaScriptInterface::luaMonsterTypeIsConvinceable);
  2383.     registerMethod("MonsterType", "isSummonable", LuaScriptInterface::luaMonsterTypeIsSummonable);
  2384.     registerMethod("MonsterType", "isIllusionable", LuaScriptInterface::luaMonsterTypeIsIllusionable);
  2385.     registerMethod("MonsterType", "isHostile", LuaScriptInterface::luaMonsterTypeIsHostile);
  2386.     registerMethod("MonsterType", "isPushable", LuaScriptInterface::luaMonsterTypeIsPushable);
  2387.     registerMethod("MonsterType", "isHealthShown", LuaScriptInterface::luaMonsterTypeIsHealthShown);
  2388.  
  2389.     registerMethod("MonsterType", "canPushItems", LuaScriptInterface::luaMonsterTypeCanPushItems);
  2390.     registerMethod("MonsterType", "canPushCreatures", LuaScriptInterface::luaMonsterTypeCanPushCreatures);
  2391.  
  2392.     registerMethod("MonsterType", "getName", LuaScriptInterface::luaMonsterTypeGetName);
  2393.     registerMethod("MonsterType", "getNameDescription", LuaScriptInterface::luaMonsterTypeGetNameDescription);
  2394.  
  2395.     registerMethod("MonsterType", "getHealth", LuaScriptInterface::luaMonsterTypeGetHealth);
  2396.     registerMethod("MonsterType", "getMaxHealth", LuaScriptInterface::luaMonsterTypeGetMaxHealth);
  2397.     registerMethod("MonsterType", "getRunHealth", LuaScriptInterface::luaMonsterTypeGetRunHealth);
  2398.     registerMethod("MonsterType", "getExperience", LuaScriptInterface::luaMonsterTypeGetExperience);
  2399.  
  2400.     registerMethod("MonsterType", "getCombatImmunities", LuaScriptInterface::luaMonsterTypeGetCombatImmunities);
  2401.     registerMethod("MonsterType", "getConditionImmunities", LuaScriptInterface::luaMonsterTypeGetConditionImmunities);
  2402.  
  2403.     registerMethod("MonsterType", "getAttackList", LuaScriptInterface::luaMonsterTypeGetAttackList);
  2404.     registerMethod("MonsterType", "getDefenseList", LuaScriptInterface::luaMonsterTypeGetDefenseList);
  2405.     registerMethod("MonsterType", "getElementList", LuaScriptInterface::luaMonsterTypeGetElementList);
  2406.  
  2407.     registerMethod("MonsterType", "getVoices", LuaScriptInterface::luaMonsterTypeGetVoices);
  2408.     registerMethod("MonsterType", "getLoot", LuaScriptInterface::luaMonsterTypeGetLoot);
  2409.     registerMethod("MonsterType", "getCreatureEvents", LuaScriptInterface::luaMonsterTypeGetCreatureEvents);
  2410.  
  2411.     registerMethod("MonsterType", "getSummonList", LuaScriptInterface::luaMonsterTypeGetSummonList);
  2412.     registerMethod("MonsterType", "getMaxSummons", LuaScriptInterface::luaMonsterTypeGetMaxSummons);
  2413.  
  2414.     registerMethod("MonsterType", "getArmor", LuaScriptInterface::luaMonsterTypeGetArmor);
  2415.     registerMethod("MonsterType", "getDefense", LuaScriptInterface::luaMonsterTypeGetDefense);
  2416.     registerMethod("MonsterType", "getOutfit", LuaScriptInterface::luaMonsterTypeGetOutfit);
  2417.     registerMethod("MonsterType", "getRace", LuaScriptInterface::luaMonsterTypeGetRace);
  2418.     registerMethod("MonsterType", "getCorpseId", LuaScriptInterface::luaMonsterTypeGetCorpseId);
  2419.     registerMethod("MonsterType", "getManaCost", LuaScriptInterface::luaMonsterTypeGetManaCost);
  2420.     registerMethod("MonsterType", "getBaseSpeed", LuaScriptInterface::luaMonsterTypeGetBaseSpeed);
  2421.     registerMethod("MonsterType", "getLight", LuaScriptInterface::luaMonsterTypeGetLight);
  2422.  
  2423.     registerMethod("MonsterType", "getStaticAttackChance", LuaScriptInterface::luaMonsterTypeGetStaticAttackChance);
  2424.     registerMethod("MonsterType", "getTargetDistance", LuaScriptInterface::luaMonsterTypeGetTargetDistance);
  2425.     registerMethod("MonsterType", "getYellChance", LuaScriptInterface::luaMonsterTypeGetYellChance);
  2426.     registerMethod("MonsterType", "getYellSpeedTicks", LuaScriptInterface::luaMonsterTypeGetYellSpeedTicks);
  2427.     registerMethod("MonsterType", "getChangeTargetChance", LuaScriptInterface::luaMonsterTypeGetChangeTargetChance);
  2428.     registerMethod("MonsterType", "getChangeTargetSpeed", LuaScriptInterface::luaMonsterTypeGetChangeTargetSpeed);
  2429.  
  2430.     // Party
  2431.     registerClass("Party", "", nullptr);
  2432.     registerMetaMethod("Party", "__eq", LuaScriptInterface::luaUserdataCompare);
  2433.  
  2434.     registerMethod("Party", "disband", LuaScriptInterface::luaPartyDisband);
  2435.  
  2436.     registerMethod("Party", "getLeader", LuaScriptInterface::luaPartyGetLeader);
  2437.     registerMethod("Party", "setLeader", LuaScriptInterface::luaPartySetLeader);
  2438.  
  2439.     registerMethod("Party", "getMembers", LuaScriptInterface::luaPartyGetMembers);
  2440.     registerMethod("Party", "getMemberCount", LuaScriptInterface::luaPartyGetMemberCount);
  2441.  
  2442.     registerMethod("Party", "getInvitees", LuaScriptInterface::luaPartyGetInvitees);
  2443.     registerMethod("Party", "getInviteeCount", LuaScriptInterface::luaPartyGetInviteeCount);
  2444.  
  2445.     registerMethod("Party", "addInvite", LuaScriptInterface::luaPartyAddInvite);
  2446.     registerMethod("Party", "removeInvite", LuaScriptInterface::luaPartyRemoveInvite);
  2447.  
  2448.     registerMethod("Party", "addMember", LuaScriptInterface::luaPartyAddMember);
  2449.     registerMethod("Party", "removeMember", LuaScriptInterface::luaPartyRemoveMember);
  2450.  
  2451.     registerMethod("Party", "isSharedExperienceActive", LuaScriptInterface::luaPartyIsSharedExperienceActive);
  2452.     registerMethod("Party", "isSharedExperienceEnabled", LuaScriptInterface::luaPartyIsSharedExperienceEnabled);
  2453.     registerMethod("Party", "shareExperience", LuaScriptInterface::luaPartyShareExperience);
  2454.     registerMethod("Party", "setSharedExperience", LuaScriptInterface::luaPartySetSharedExperience);
  2455. }
  2456.  
  2457. #undef registerEnum
  2458. #undef registerEnumIn
  2459.  
  2460. void LuaScriptInterface::registerClass(const std::string& className, const std::string& baseClass, lua_CFunction newFunction/* = nullptr*/)
  2461. {
  2462.     // className = {}
  2463.     lua_newtable(luaState);
  2464.     lua_pushvalue(luaState, -1);
  2465.     lua_setglobal(luaState, className.c_str());
  2466.     int methods = lua_gettop(luaState);
  2467.  
  2468.     // methodsTable = {}
  2469.     lua_newtable(luaState);
  2470.     int methodsTable = lua_gettop(luaState);
  2471.  
  2472.     if (newFunction) {
  2473.         // className.__call = newFunction
  2474.         lua_pushcfunction(luaState, newFunction);
  2475.         lua_setfield(luaState, methodsTable, "__call");
  2476.     }
  2477.  
  2478.     uint32_t parents = 0;
  2479.     if (!baseClass.empty()) {
  2480.         lua_getglobal(luaState, baseClass.c_str());
  2481.         lua_rawgeti(luaState, -1, 'p');
  2482.         parents = getNumber<uint32_t>(luaState, -1) + 1;
  2483.         lua_pop(luaState, 1);
  2484.         lua_setfield(luaState, methodsTable, "__index");
  2485.     }
  2486.  
  2487.     // setmetatable(className, methodsTable)
  2488.     lua_setmetatable(luaState, methods);
  2489.  
  2490.     // className.metatable = {}
  2491.     luaL_newmetatable(luaState, className.c_str());
  2492.     int metatable = lua_gettop(luaState);
  2493.  
  2494.     // className.metatable.__metatable = className
  2495.     lua_pushvalue(luaState, methods);
  2496.     lua_setfield(luaState, metatable, "__metatable");
  2497.  
  2498.     // className.metatable.__index = className
  2499.     lua_pushvalue(luaState, methods);
  2500.     lua_setfield(luaState, metatable, "__index");
  2501.  
  2502.     // className.metatable['h'] = hash
  2503.     lua_pushnumber(luaState, std::hash<std::string>()(className));
  2504.     lua_rawseti(luaState, metatable, 'h');
  2505.  
  2506.     // className.metatable['p'] = parents
  2507.     lua_pushnumber(luaState, parents);
  2508.     lua_rawseti(luaState, metatable, 'p');
  2509.  
  2510.     // className.metatable['t'] = type
  2511.     if (className == "Item") {
  2512.         lua_pushnumber(luaState, LuaData_Item);
  2513.     } else if (className == "Container") {
  2514.         lua_pushnumber(luaState, LuaData_Container);
  2515.     } else if (className == "Teleport") {
  2516.         lua_pushnumber(luaState, LuaData_Teleport);
  2517.     } else if (className == "Player") {
  2518.         lua_pushnumber(luaState, LuaData_Player);
  2519.     } else if (className == "Monster") {
  2520.         lua_pushnumber(luaState, LuaData_Monster);
  2521.     } else if (className == "Npc") {
  2522.         lua_pushnumber(luaState, LuaData_Npc);
  2523.     } else if (className == "Tile") {
  2524.         lua_pushnumber(luaState, LuaData_Tile);
  2525.     } else {
  2526.         lua_pushnumber(luaState, LuaData_Unknown);
  2527.     }
  2528.     lua_rawseti(luaState, metatable, 't');
  2529.  
  2530.     // pop className, className.metatable
  2531.     lua_pop(luaState, 2);
  2532. }
  2533.  
  2534. void LuaScriptInterface::registerTable(const std::string& tableName)
  2535. {
  2536.     // _G[tableName] = {}
  2537.     lua_newtable(luaState);
  2538.     lua_setglobal(luaState, tableName.c_str());
  2539. }
  2540.  
  2541. void LuaScriptInterface::registerMethod(const std::string& globalName, const std::string& methodName, lua_CFunction func)
  2542. {
  2543.     // globalName.methodName = func
  2544.     lua_getglobal(luaState, globalName.c_str());
  2545.     lua_pushcfunction(luaState, func);
  2546.     lua_setfield(luaState, -2, methodName.c_str());
  2547.  
  2548.     // pop globalName
  2549.     lua_pop(luaState, 1);
  2550. }
  2551.  
  2552. void LuaScriptInterface::registerMetaMethod(const std::string& className, const std::string& methodName, lua_CFunction func)
  2553. {
  2554.     // className.metatable.methodName = func
  2555.     luaL_getmetatable(luaState, className.c_str());
  2556.     lua_pushcfunction(luaState, func);
  2557.     lua_setfield(luaState, -2, methodName.c_str());
  2558.  
  2559.     // pop className.metatable
  2560.     lua_pop(luaState, 1);
  2561. }
  2562.  
  2563. void LuaScriptInterface::registerGlobalMethod(const std::string& functionName, lua_CFunction func)
  2564. {
  2565.     // _G[functionName] = func
  2566.     lua_pushcfunction(luaState, func);
  2567.     lua_setglobal(luaState, functionName.c_str());
  2568. }
  2569.  
  2570. void LuaScriptInterface::registerVariable(const std::string& tableName, const std::string& name, lua_Number value)
  2571. {
  2572.     // tableName.name = value
  2573.     lua_getglobal(luaState, tableName.c_str());
  2574.     setField(luaState, name.c_str(), value);
  2575.  
  2576.     // pop tableName
  2577.     lua_pop(luaState, 1);
  2578. }
  2579.  
  2580. void LuaScriptInterface::registerGlobalVariable(const std::string& name, lua_Number value)
  2581. {
  2582.     // _G[name] = value
  2583.     lua_pushnumber(luaState, value);
  2584.     lua_setglobal(luaState, name.c_str());
  2585. }
  2586.  
  2587. void LuaScriptInterface::registerGlobalBoolean(const std::string& name, bool value)
  2588. {
  2589.     // _G[name] = value
  2590.     pushBoolean(luaState, value);
  2591.     lua_setglobal(luaState, name.c_str());
  2592. }
  2593.  
  2594. int LuaScriptInterface::luaGetPlayerFlagValue(lua_State* L)
  2595. {
  2596.     //getPlayerFlagValue(cid, flag)
  2597.     Player* player = getPlayer(L, 1);
  2598.     if (player) {
  2599.         PlayerFlags flag = getNumber<PlayerFlags>(L, 2);
  2600.         pushBoolean(L, player->hasFlag(flag));
  2601.     } else {
  2602.         reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  2603.         pushBoolean(L, false);
  2604.     }
  2605.     return 1;
  2606. }
  2607.  
  2608. int LuaScriptInterface::luaGetPlayerInstantSpellCount(lua_State* L)
  2609. {
  2610.     //getPlayerInstantSpellCount(cid)
  2611.     Player* player = getPlayer(L, 1);
  2612.     if (player) {
  2613.         lua_pushnumber(L, g_spells->getInstantSpellCount(player));
  2614.     } else {
  2615.         reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  2616.         pushBoolean(L, false);
  2617.     }
  2618.     return 1;
  2619. }
  2620.  
  2621. int LuaScriptInterface::luaGetPlayerInstantSpellInfo(lua_State* L)
  2622. {
  2623.     //getPlayerInstantSpellInfo(cid, index)
  2624.     Player* player = getPlayer(L, 1);
  2625.     if (!player) {
  2626.         reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  2627.         pushBoolean(L, false);
  2628.         return 1;
  2629.     }
  2630.  
  2631.     uint32_t index = getNumber<uint32_t>(L, 2);
  2632.     InstantSpell* spell = g_spells->getInstantSpellByIndex(player, index);
  2633.     if (!spell) {
  2634.         reportErrorFunc(getErrorDesc(LUA_ERROR_SPELL_NOT_FOUND));
  2635.         pushBoolean(L, false);
  2636.         return 1;
  2637.     }
  2638.  
  2639.     lua_createtable(L, 0, 6);
  2640.     setField(L, "name", spell->getName());
  2641.     setField(L, "words", spell->getWords());
  2642.     setField(L, "level", spell->getLevel());
  2643.     setField(L, "mlevel", spell->getMagicLevel());
  2644.     setField(L, "mana", spell->getManaCost(player));
  2645.     setField(L, "manapercent", spell->getManaPercent());
  2646.     return 1;
  2647. }
  2648.  
  2649. int LuaScriptInterface::luaDoPlayerAddItem(lua_State* L)
  2650. {
  2651.     //doPlayerAddItem(cid, itemid, <optional: default: 1> count/subtype, <optional: default: 1> canDropOnMap)
  2652.     //doPlayerAddItem(cid, itemid, <optional: default: 1> count, <optional: default: 1> canDropOnMap, <optional: default: 1>subtype)
  2653.     Player* player = getPlayer(L, 1);
  2654.     if (!player) {
  2655.         reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  2656.         pushBoolean(L, false);
  2657.         return 1;
  2658.     }
  2659.  
  2660.     uint16_t itemId = getNumber<uint16_t>(L, 2);
  2661.     int32_t count = getNumber<int32_t>(L, 3, 1);
  2662.     bool canDropOnMap = getBoolean(L, 4, true);
  2663.     uint16_t subType = getNumber<uint16_t>(L, 5, 1);
  2664.  
  2665.     const ItemType& it = Item::items[itemId];
  2666.     int32_t itemCount;
  2667.  
  2668.     auto parameters = lua_gettop(L);
  2669.     if (parameters > 4) {
  2670.         //subtype already supplied, count then is the amount
  2671.         itemCount = std::max<int32_t>(1, count);
  2672.     } else if (it.hasSubType()) {
  2673.         if (it.stackable) {
  2674.             itemCount = static_cast<int32_t>(std::ceil(static_cast<float>(count) / 100));
  2675.         } else {
  2676.             itemCount = 1;
  2677.         }
  2678.         subType = count;
  2679.     } else {
  2680.         itemCount = std::max<int32_t>(1, count);
  2681.     }
  2682.  
  2683.     while (itemCount > 0) {
  2684.         uint16_t stackCount = subType;
  2685.         if (it.stackable && stackCount > 100) {
  2686.             stackCount = 100;
  2687.         }
  2688.  
  2689.         Item* newItem = Item::CreateItem(itemId, stackCount);
  2690.         if (!newItem) {
  2691.             reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  2692.             pushBoolean(L, false);
  2693.             return 1;
  2694.         }
  2695.  
  2696.         if (it.stackable) {
  2697.             subType -= stackCount;
  2698.         }
  2699.  
  2700.         ReturnValue ret = g_game.internalPlayerAddItem(player, newItem, canDropOnMap);
  2701.         if (ret != RETURNVALUE_NOERROR) {
  2702.             delete newItem;
  2703.             pushBoolean(L, false);
  2704.             return 1;
  2705.         }
  2706.  
  2707.         if (--itemCount == 0) {
  2708.             if (newItem->getParent()) {
  2709.                 uint32_t uid = getScriptEnv()->addThing(newItem);
  2710.                 lua_pushnumber(L, uid);
  2711.                 return 1;
  2712.             } else {
  2713.                 //stackable item stacked with existing object, newItem will be released
  2714.                 pushBoolean(L, false);
  2715.                 return 1;
  2716.             }
  2717.         }
  2718.     }
  2719.  
  2720.     pushBoolean(L, false);
  2721.     return 1;
  2722. }
  2723.  
  2724. int LuaScriptInterface::luaDoTileAddItemEx(lua_State* L)
  2725. {
  2726.     //doTileAddItemEx(pos, uid)
  2727.     const Position& pos = getPosition(L, 1);
  2728.  
  2729.     Tile* tile = g_game.map.getTile(pos);
  2730.     if (!tile) {
  2731.         std::ostringstream ss;
  2732.         ss << pos << ' ' << getErrorDesc(LUA_ERROR_TILE_NOT_FOUND);
  2733.         reportErrorFunc(ss.str());
  2734.         pushBoolean(L, false);
  2735.         return 1;
  2736.     }
  2737.  
  2738.     uint32_t uid = getNumber<uint32_t>(L, 2);
  2739.     Item* item = getScriptEnv()->getItemByUID(uid);
  2740.     if (!item) {
  2741.         reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  2742.         pushBoolean(L, false);
  2743.         return 1;
  2744.     }
  2745.  
  2746.     if (item->getParent() != VirtualCylinder::virtualCylinder) {
  2747.         reportErrorFunc("Item already has a parent");
  2748.         pushBoolean(L, false);
  2749.         return 1;
  2750.     }
  2751.  
  2752.     lua_pushnumber(L, g_game.internalAddItem(tile, item));
  2753.     return 1;
  2754. }
  2755.  
  2756. int LuaScriptInterface::luaDoCreateItem(lua_State* L)
  2757. {
  2758.     //doCreateItem(itemid, <optional> type/count, pos)
  2759.     //Returns uid of the created item, only works on tiles.
  2760.     const Position& pos = getPosition(L, 3);
  2761.     Tile* tile = g_game.map.getTile(pos);
  2762.     if (!tile) {
  2763.         std::ostringstream ss;
  2764.         ss << pos << ' ' << getErrorDesc(LUA_ERROR_TILE_NOT_FOUND);
  2765.         reportErrorFunc(ss.str());
  2766.         pushBoolean(L, false);
  2767.         return 1;
  2768.     }
  2769.  
  2770.     ScriptEnvironment* env = getScriptEnv();
  2771.  
  2772.     int32_t itemCount = 1;
  2773.     int32_t subType = 1;
  2774.  
  2775.     uint16_t itemId = getNumber<uint16_t>(L, 1);
  2776.     uint32_t count = getNumber<uint32_t>(L, 2, 1);
  2777.  
  2778.     const ItemType& it = Item::items[itemId];
  2779.     if (it.hasSubType()) {
  2780.         if (it.stackable) {
  2781.             itemCount = static_cast<int32_t>(std::ceil(static_cast<float>(count) / 100));
  2782.         }
  2783.  
  2784.         subType = count;
  2785.     } else {
  2786.         itemCount = std::max<int32_t>(1, count);
  2787.     }
  2788.  
  2789.     while (itemCount > 0) {
  2790.         int32_t stackCount = std::min<int32_t>(100, subType);
  2791.         Item* newItem = Item::CreateItem(itemId, stackCount);
  2792.         if (!newItem) {
  2793.             reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  2794.             pushBoolean(L, false);
  2795.             return 1;
  2796.         }
  2797.  
  2798.         if (it.stackable) {
  2799.             subType -= stackCount;
  2800.         }
  2801.  
  2802.         ReturnValue ret = g_game.internalAddItem(tile, newItem, INDEX_WHEREEVER, FLAG_NOLIMIT);
  2803.         if (ret != RETURNVALUE_NOERROR) {
  2804.             delete newItem;
  2805.             pushBoolean(L, false);
  2806.             return 1;
  2807.         }
  2808.  
  2809.         if (--itemCount == 0) {
  2810.             if (newItem->getParent()) {
  2811.                 uint32_t uid = env->addThing(newItem);
  2812.                 lua_pushnumber(L, uid);
  2813.                 return 1;
  2814.             } else {
  2815.                 //stackable item stacked with existing object, newItem will be released
  2816.                 pushBoolean(L, false);
  2817.                 return 1;
  2818.             }
  2819.         }
  2820.     }
  2821.  
  2822.     pushBoolean(L, false);
  2823.     return 1;
  2824. }
  2825.  
  2826. int LuaScriptInterface::luaDoCreateItemEx(lua_State* L)
  2827. {
  2828.     //doCreateItemEx(itemid, <optional> count/subtype)
  2829.     //Returns uid of the created item
  2830.     uint16_t itemId = getNumber<uint16_t>(L, 1);
  2831.     uint32_t count = getNumber<uint32_t>(L, 2, 1);
  2832.  
  2833.     const ItemType& it = Item::items[itemId];
  2834.     if (it.stackable && count > 100) {
  2835.         reportErrorFunc("Stack count cannot be higher than 100.");
  2836.         count = 100;
  2837.     }
  2838.  
  2839.     Item* newItem = Item::CreateItem(itemId, count);
  2840.     if (!newItem) {
  2841.         reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  2842.         pushBoolean(L, false);
  2843.         return 1;
  2844.     }
  2845.  
  2846.     newItem->setParent(VirtualCylinder::virtualCylinder);
  2847.  
  2848.     ScriptEnvironment* env = getScriptEnv();
  2849.     env->addTempItem(newItem);
  2850.  
  2851.     uint32_t uid = env->addThing(newItem);
  2852.     lua_pushnumber(L, uid);
  2853.     return 1;
  2854. }
  2855.  
  2856. int LuaScriptInterface::luaDebugPrint(lua_State* L)
  2857. {
  2858.     //debugPrint(text)
  2859.     reportErrorFunc(getString(L, -1));
  2860.     return 0;
  2861. }
  2862.  
  2863. int LuaScriptInterface::luaGetWorldTime(lua_State* L)
  2864. {
  2865.     //getWorldTime()
  2866.     uint32_t time = g_game.getLightHour();
  2867.     lua_pushnumber(L, time);
  2868.     return 1;
  2869. }
  2870.  
  2871. int LuaScriptInterface::luaGetWorldLight(lua_State* L)
  2872. {
  2873.     //getWorldLight()
  2874.     LightInfo lightInfo;
  2875.     g_game.getWorldLightInfo(lightInfo);
  2876.     lua_pushnumber(L, lightInfo.level);
  2877.     lua_pushnumber(L, lightInfo.color);
  2878.     return 2;
  2879. }
  2880.  
  2881. int LuaScriptInterface::luaGetWorldUpTime(lua_State* L)
  2882. {
  2883.     //getWorldUpTime()
  2884.     uint64_t uptime = (OTSYS_TIME() - ProtocolStatus::start) / 1000;
  2885.     lua_pushnumber(L, uptime);
  2886.     return 1;
  2887. }
  2888.  
  2889. bool LuaScriptInterface::getArea(lua_State* L, std::list<uint32_t>& list, uint32_t& rows)
  2890. {
  2891.     lua_pushnil(L);
  2892.     for (rows = 0; lua_next(L, -2) != 0; ++rows) {
  2893.         if (!isTable(L, -1)) {
  2894.             return false;
  2895.         }
  2896.  
  2897.         lua_pushnil(L);
  2898.         while (lua_next(L, -2) != 0) {
  2899.             if (!isNumber(L, -1)) {
  2900.                 return false;
  2901.             }
  2902.             list.push_back(getNumber<uint32_t>(L, -1));
  2903.             lua_pop(L, 1);
  2904.         }
  2905.  
  2906.         lua_pop(L, 1);
  2907.     }
  2908.  
  2909.     lua_pop(L, 1);
  2910.     return (rows != 0);
  2911. }
  2912.  
  2913. int LuaScriptInterface::luaCreateCombatArea(lua_State* L)
  2914. {
  2915.     //createCombatArea( {area}, <optional> {extArea} )
  2916.     ScriptEnvironment* env = getScriptEnv();
  2917.     if (env->getScriptId() != EVENT_ID_LOADING) {
  2918.         reportErrorFunc("This function can only be used while loading the script.");
  2919.         pushBoolean(L, false);
  2920.         return 1;
  2921.     }
  2922.  
  2923.     uint32_t areaId = g_luaEnvironment.createAreaObject(env->getScriptInterface());
  2924.     AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
  2925.  
  2926.     int parameters = lua_gettop(L);
  2927.     if (parameters >= 2) {
  2928.         uint32_t rowsExtArea;
  2929.         std::list<uint32_t> listExtArea;
  2930.         if (!getArea(L, listExtArea, rowsExtArea)) {
  2931.             reportErrorFunc("Invalid extended area table.");
  2932.             pushBoolean(L, false);
  2933.             return 1;
  2934.         }
  2935.         area->setupExtArea(listExtArea, rowsExtArea);
  2936.     }
  2937.  
  2938.     uint32_t rowsArea = 0;
  2939.     std::list<uint32_t> listArea;
  2940.     if (!getArea(L, listArea, rowsArea)) {
  2941.         reportErrorFunc("Invalid area table.");
  2942.         pushBoolean(L, false);
  2943.         return 1;
  2944.     }
  2945.  
  2946.     area->setupArea(listArea, rowsArea);
  2947.     lua_pushnumber(L, areaId);
  2948.     return 1;
  2949. }
  2950.  
  2951. int LuaScriptInterface::luaDoAreaCombatHealth(lua_State* L)
  2952. {
  2953.     //doAreaCombatHealth(cid, type, pos, area, min, max, effect[, origin = ORIGIN_SPELL])
  2954.     Creature* creature = getCreature(L, 1);
  2955.     if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  2956.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  2957.         pushBoolean(L, false);
  2958.         return 1;
  2959.     }
  2960.  
  2961.     uint32_t areaId = getNumber<uint32_t>(L, 4);
  2962.     const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
  2963.     if (area || areaId == 0) {
  2964.         CombatType_t combatType = getNumber<CombatType_t>(L, 2);
  2965.  
  2966.         CombatParams params;
  2967.         params.combatType = combatType;
  2968.         params.impactEffect = getNumber<uint8_t>(L, 7);
  2969.  
  2970.         CombatDamage damage;
  2971.         damage.origin = getNumber<CombatOrigin>(L, 8, ORIGIN_SPELL);
  2972.         damage.primary.type = combatType;
  2973.         damage.primary.value = normal_random(getNumber<int32_t>(L, 6), getNumber<int32_t>(L, 5));
  2974.  
  2975.         Combat::doCombatHealth(creature, getPosition(L, 3), area, damage, params);
  2976.         pushBoolean(L, true);
  2977.     } else {
  2978.         reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
  2979.         pushBoolean(L, false);
  2980.     }
  2981.     return 1;
  2982. }
  2983.  
  2984. int LuaScriptInterface::luaDoTargetCombatHealth(lua_State* L)
  2985. {
  2986.     //doTargetCombatHealth(cid, target, type, min, max, effect[, origin = ORIGIN_SPELL])
  2987.     Creature* creature = getCreature(L, 1);
  2988.     if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  2989.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  2990.         pushBoolean(L, false);
  2991.         return 1;
  2992.     }
  2993.  
  2994.     Creature* target = getCreature(L, 2);
  2995.     if (!target) {
  2996.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  2997.         pushBoolean(L, false);
  2998.         return 1;
  2999.     }
  3000.  
  3001.     CombatType_t combatType = getNumber<CombatType_t>(L, 3);
  3002.  
  3003.     CombatParams params;
  3004.     params.combatType = combatType;
  3005.     params.impactEffect = getNumber<uint8_t>(L, 6);
  3006.  
  3007.     CombatDamage damage;
  3008.     damage.origin = getNumber<CombatOrigin>(L, 7, ORIGIN_SPELL);
  3009.     damage.primary.type = combatType;
  3010.     damage.primary.value = normal_random(getNumber<int32_t>(L, 4), getNumber<int32_t>(L, 5));
  3011.  
  3012.     Combat::doCombatHealth(creature, target, damage, params);
  3013.     pushBoolean(L, true);
  3014.     return 1;
  3015. }
  3016.  
  3017. int LuaScriptInterface::luaDoAreaCombatMana(lua_State* L)
  3018. {
  3019.     //doAreaCombatMana(cid, pos, area, min, max, effect[, origin = ORIGIN_SPELL])
  3020.     Creature* creature = getCreature(L, 1);
  3021.     if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3022.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3023.         pushBoolean(L, false);
  3024.         return 1;
  3025.     }
  3026.  
  3027.     uint32_t areaId = getNumber<uint32_t>(L, 3);
  3028.     const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
  3029.     if (area || areaId == 0) {
  3030.         CombatParams params;
  3031.         params.impactEffect = getNumber<uint8_t>(L, 6);
  3032.  
  3033.         CombatDamage damage;
  3034.         damage.origin = getNumber<CombatOrigin>(L, 7, ORIGIN_SPELL);
  3035.         damage.primary.type = COMBAT_MANADRAIN;
  3036.         damage.primary.value = normal_random(getNumber<int32_t>(L, 4), getNumber<int32_t>(L, 5));
  3037.  
  3038.         Position pos = getPosition(L, 2);
  3039.         Combat::doCombatMana(creature, pos, area, damage, params);
  3040.         pushBoolean(L, true);
  3041.     } else {
  3042.         reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
  3043.         pushBoolean(L, false);
  3044.     }
  3045.     return 1;
  3046. }
  3047.  
  3048. int LuaScriptInterface::luaDoTargetCombatMana(lua_State* L)
  3049. {
  3050.     //doTargetCombatMana(cid, target, min, max, effect[, origin = ORIGIN_SPELL)
  3051.     Creature* creature = getCreature(L, 1);
  3052.     if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3053.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3054.         pushBoolean(L, false);
  3055.         return 1;
  3056.     }
  3057.  
  3058.     Creature* target = getCreature(L, 2);
  3059.     if (!target) {
  3060.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3061.         pushBoolean(L, false);
  3062.         return 1;
  3063.     }
  3064.  
  3065.     CombatParams params;
  3066.     params.impactEffect = getNumber<uint8_t>(L, 5);
  3067.  
  3068.     CombatDamage damage;
  3069.     damage.origin = getNumber<CombatOrigin>(L, 6, ORIGIN_SPELL);
  3070.     damage.primary.type = COMBAT_MANADRAIN;
  3071.     damage.primary.value = normal_random(getNumber<int32_t>(L, 3), getNumber<int32_t>(L, 4));
  3072.  
  3073.     Combat::doCombatMana(creature, target, damage, params);
  3074.     pushBoolean(L, true);
  3075.     return 1;
  3076. }
  3077.  
  3078. int LuaScriptInterface::luaDoAreaCombatCondition(lua_State* L)
  3079. {
  3080.     //doAreaCombatCondition(cid, pos, area, condition, effect)
  3081.     Creature* creature = getCreature(L, 1);
  3082.     if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3083.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3084.         pushBoolean(L, false);
  3085.         return 1;
  3086.     }
  3087.  
  3088.     const Condition* condition = getUserdata<Condition>(L, 4);
  3089.     if (!condition) {
  3090.         reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
  3091.         pushBoolean(L, false);
  3092.         return 1;
  3093.     }
  3094.  
  3095.     uint32_t areaId = getNumber<uint32_t>(L, 3);
  3096.     const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
  3097.     if (area || areaId == 0) {
  3098.         CombatParams params;
  3099.         params.impactEffect = getNumber<uint8_t>(L, 5);
  3100.         params.conditionList.emplace_front(condition);
  3101.         Combat::doCombatCondition(creature, getPosition(L, 2), area, params);
  3102.         pushBoolean(L, true);
  3103.     } else {
  3104.         reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
  3105.         pushBoolean(L, false);
  3106.     }
  3107.     return 1;
  3108. }
  3109.  
  3110. int LuaScriptInterface::luaDoTargetCombatCondition(lua_State* L)
  3111. {
  3112.     //doTargetCombatCondition(cid, target, condition, effect)
  3113.     Creature* creature = getCreature(L, 1);
  3114.     if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3115.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3116.         pushBoolean(L, false);
  3117.         return 1;
  3118.     }
  3119.  
  3120.     Creature* target = getCreature(L, 2);
  3121.     if (!target) {
  3122.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3123.         pushBoolean(L, false);
  3124.         return 1;
  3125.     }
  3126.  
  3127.     const Condition* condition = getUserdata<Condition>(L, 3);
  3128.     if (!condition) {
  3129.         reportErrorFunc(getErrorDesc(LUA_ERROR_CONDITION_NOT_FOUND));
  3130.         pushBoolean(L, false);
  3131.         return 1;
  3132.     }
  3133.  
  3134.     CombatParams params;
  3135.     params.impactEffect = getNumber<uint8_t>(L, 4);
  3136.     params.conditionList.emplace_front(condition);
  3137.     Combat::doCombatCondition(creature, target, params);
  3138.     pushBoolean(L, true);
  3139.     return 1;
  3140. }
  3141.  
  3142. int LuaScriptInterface::luaDoAreaCombatDispel(lua_State* L)
  3143. {
  3144.     //doAreaCombatDispel(cid, pos, area, type, effect)
  3145.     Creature* creature = getCreature(L, 1);
  3146.     if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3147.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3148.         pushBoolean(L, false);
  3149.         return 1;
  3150.     }
  3151.  
  3152.     uint32_t areaId = getNumber<uint32_t>(L, 3);
  3153.     const AreaCombat* area = g_luaEnvironment.getAreaObject(areaId);
  3154.     if (area || areaId == 0) {
  3155.         CombatParams params;
  3156.         params.impactEffect = getNumber<uint8_t>(L, 5);
  3157.         params.dispelType = getNumber<ConditionType_t>(L, 4);
  3158.         Combat::doCombatDispel(creature, getPosition(L, 2), area, params);
  3159.  
  3160.         pushBoolean(L, true);
  3161.     } else {
  3162.         reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
  3163.         pushBoolean(L, false);
  3164.     }
  3165.     return 1;
  3166. }
  3167.  
  3168. int LuaScriptInterface::luaDoTargetCombatDispel(lua_State* L)
  3169. {
  3170.     //doTargetCombatDispel(cid, target, type, effect)
  3171.     Creature* creature = getCreature(L, 1);
  3172.     if (!creature && (!isNumber(L, 1) || getNumber<uint32_t>(L, 1) != 0)) {
  3173.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3174.         pushBoolean(L, false);
  3175.         return 1;
  3176.     }
  3177.  
  3178.     Creature* target = getCreature(L, 2);
  3179.     if (!target) {
  3180.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3181.         pushBoolean(L, false);
  3182.         return 1;
  3183.     }
  3184.  
  3185.     CombatParams params;
  3186.     params.dispelType = getNumber<ConditionType_t>(L, 3);
  3187.     params.impactEffect = getNumber<uint8_t>(L, 4);
  3188.     Combat::doCombatDispel(creature, target, params);
  3189.     pushBoolean(L, true);
  3190.     return 1;
  3191. }
  3192.  
  3193. int LuaScriptInterface::luaDoChallengeCreature(lua_State* L)
  3194. {
  3195.     //doChallengeCreature(cid, target)
  3196.     Creature* creature = getCreature(L, 1);
  3197.     if (!creature) {
  3198.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3199.         pushBoolean(L, false);
  3200.         return 1;
  3201.     }
  3202.  
  3203.     Creature* target = getCreature(L, 2);
  3204.     if (!target) {
  3205.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3206.         pushBoolean(L, false);
  3207.         return 1;
  3208.     }
  3209.  
  3210.     target->challengeCreature(creature);
  3211.     pushBoolean(L, true);
  3212.     return 1;
  3213. }
  3214.  
  3215. int LuaScriptInterface::luaSetCreatureOutfit(lua_State* L)
  3216. {
  3217.     //doSetCreatureOutfit(cid, outfit, time)
  3218.     Creature* creature = getCreature(L, 1);
  3219.     if (!creature) {
  3220.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3221.         pushBoolean(L, false);
  3222.         return 1;
  3223.     }
  3224.  
  3225.     Outfit_t outfit = getOutfit(L, 2);
  3226.     int32_t time = getNumber<int32_t>(L, 3);
  3227.     pushBoolean(L, Spell::CreateIllusion(creature, outfit, time) == RETURNVALUE_NOERROR);
  3228.     return 1;
  3229. }
  3230.  
  3231. int LuaScriptInterface::luaSetMonsterOutfit(lua_State* L)
  3232. {
  3233.     //doSetMonsterOutfit(cid, name, time)
  3234.     Creature* creature = getCreature(L, 1);
  3235.     if (!creature) {
  3236.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3237.         pushBoolean(L, false);
  3238.         return 1;
  3239.     }
  3240.  
  3241.     std::string name = getString(L, 2);
  3242.     int32_t time = getNumber<int32_t>(L, 3);
  3243.     pushBoolean(L, Spell::CreateIllusion(creature, name, time) == RETURNVALUE_NOERROR);
  3244.     return 1;
  3245. }
  3246.  
  3247. int LuaScriptInterface::luaSetItemOutfit(lua_State* L)
  3248. {
  3249.     //doSetItemOutfit(cid, item, time)
  3250.     Creature* creature = getCreature(L, 1);
  3251.     if (!creature) {
  3252.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3253.         pushBoolean(L, false);
  3254.         return 1;
  3255.     }
  3256.  
  3257.     uint32_t item = getNumber<uint32_t>(L, 2);
  3258.     int32_t time = getNumber<int32_t>(L, 3);
  3259.     pushBoolean(L, Spell::CreateIllusion(creature, item, time) == RETURNVALUE_NOERROR);
  3260.     return 1;
  3261. }
  3262.  
  3263. int LuaScriptInterface::luaDoMoveCreature(lua_State* L)
  3264. {
  3265.     //doMoveCreature(cid, direction)
  3266.     Creature* creature = getCreature(L, 1);
  3267.     if (!creature) {
  3268.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3269.         pushBoolean(L, false);
  3270.         return 1;
  3271.     }
  3272.  
  3273.     Direction direction = getNumber<Direction>(L, 2);
  3274.     if (direction > DIRECTION_LAST) {
  3275.         reportErrorFunc("No valid direction");
  3276.         pushBoolean(L, false);
  3277.         return 1;
  3278.     }
  3279.  
  3280.     ReturnValue ret = g_game.internalMoveCreature(creature, direction, FLAG_NOLIMIT);
  3281.     lua_pushnumber(L, ret);
  3282.     return 1;
  3283. }
  3284.  
  3285. int LuaScriptInterface::luaIsValidUID(lua_State* L)
  3286. {
  3287.     //isValidUID(uid)
  3288.     pushBoolean(L, getScriptEnv()->getThingByUID(getNumber<uint32_t>(L, -1)) != nullptr);
  3289.     return 1;
  3290. }
  3291.  
  3292. int LuaScriptInterface::luaIsDepot(lua_State* L)
  3293. {
  3294.     //isDepot(uid)
  3295.     Container* container = getScriptEnv()->getContainerByUID(getNumber<uint32_t>(L, -1));
  3296.     pushBoolean(L, container && container->getDepotLocker());
  3297.     return 1;
  3298. }
  3299.  
  3300. int LuaScriptInterface::luaIsMoveable(lua_State* L)
  3301. {
  3302.     //isMoveable(uid)
  3303.     //isMovable(uid)
  3304.     Thing* thing = getScriptEnv()->getThingByUID(getNumber<uint32_t>(L, -1));
  3305.     pushBoolean(L, thing && thing->isPushable());
  3306.     return 1;
  3307. }
  3308.  
  3309. int LuaScriptInterface::luaDoAddContainerItem(lua_State* L)
  3310. {
  3311.     //doAddContainerItem(uid, itemid, <optional> count/subtype)
  3312.     uint32_t uid = getNumber<uint32_t>(L, 1);
  3313.  
  3314.     ScriptEnvironment* env = getScriptEnv();
  3315.     Container* container = env->getContainerByUID(uid);
  3316.     if (!container) {
  3317.         reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND));
  3318.         pushBoolean(L, false);
  3319.         return 1;
  3320.     }
  3321.  
  3322.     uint16_t itemId = getNumber<uint16_t>(L, 2);
  3323.     const ItemType& it = Item::items[itemId];
  3324.  
  3325.     int32_t itemCount = 1;
  3326.     int32_t subType = 1;
  3327.     uint32_t count = getNumber<uint32_t>(L, 3, 1);
  3328.  
  3329.     if (it.hasSubType()) {
  3330.         if (it.stackable) {
  3331.             itemCount = static_cast<int32_t>(std::ceil(static_cast<float>(count) / 100));
  3332.         }
  3333.  
  3334.         subType = count;
  3335.     } else {
  3336.         itemCount = std::max<int32_t>(1, count);
  3337.     }
  3338.  
  3339.     while (itemCount > 0) {
  3340.         int32_t stackCount = std::min<int32_t>(100, subType);
  3341.         Item* newItem = Item::CreateItem(itemId, stackCount);
  3342.         if (!newItem) {
  3343.             reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  3344.             pushBoolean(L, false);
  3345.             return 1;
  3346.         }
  3347.  
  3348.         if (it.stackable) {
  3349.             subType -= stackCount;
  3350.         }
  3351.  
  3352.         ReturnValue ret = g_game.internalAddItem(container, newItem);
  3353.         if (ret != RETURNVALUE_NOERROR) {
  3354.             delete newItem;
  3355.             pushBoolean(L, false);
  3356.             return 1;
  3357.         }
  3358.  
  3359.         if (--itemCount == 0) {
  3360.             if (newItem->getParent()) {
  3361.                 lua_pushnumber(L, env->addThing(newItem));
  3362.             } else {
  3363.                 //stackable item stacked with existing object, newItem will be released
  3364.                 pushBoolean(L, false);
  3365.             }
  3366.             return 1;
  3367.         }
  3368.     }
  3369.  
  3370.     pushBoolean(L, false);
  3371.     return 1;
  3372. }
  3373.  
  3374. int LuaScriptInterface::luaGetDepotId(lua_State* L)
  3375. {
  3376.     //getDepotId(uid)
  3377.     uint32_t uid = getNumber<uint32_t>(L, -1);
  3378.  
  3379.     Container* container = getScriptEnv()->getContainerByUID(uid);
  3380.     if (!container) {
  3381.         reportErrorFunc(getErrorDesc(LUA_ERROR_CONTAINER_NOT_FOUND));
  3382.         pushBoolean(L, false);
  3383.         return 1;
  3384.     }
  3385.  
  3386.     DepotLocker* depotLocker = container->getDepotLocker();
  3387.     if (!depotLocker) {
  3388.         reportErrorFunc("Depot not found");
  3389.         pushBoolean(L, false);
  3390.         return 1;
  3391.     }
  3392.  
  3393.     lua_pushnumber(L, depotLocker->getDepotId());
  3394.     return 1;
  3395. }
  3396.  
  3397. int LuaScriptInterface::luaIsInArray(lua_State* L)
  3398. {
  3399.     //isInArray(array, value)
  3400.     if (!isTable(L, 1)) {
  3401.         pushBoolean(L, false);
  3402.         return 1;
  3403.     }
  3404.  
  3405.     lua_pushnil(L);
  3406.     while (lua_next(L, 1)) {
  3407.         if (lua_equal(L, 2, -1) != 0) {
  3408.             pushBoolean(L, true);
  3409.             return 1;
  3410.         }
  3411.         lua_pop(L, 1);
  3412.     }
  3413.  
  3414.     pushBoolean(L, false);
  3415.     return 1;
  3416. }
  3417.  
  3418. int LuaScriptInterface::luaDoSetCreatureLight(lua_State* L)
  3419. {
  3420.     //doSetCreatureLight(cid, lightLevel, lightColor, time)
  3421.     Creature* creature = getCreature(L, 1);
  3422.     if (!creature) {
  3423.         reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  3424.         pushBoolean(L, false);
  3425.         return 1;
  3426.     }
  3427.  
  3428.     uint16_t level = getNumber<uint16_t>(L, 2);
  3429.     uint16_t color = getNumber<uint16_t>(L, 3);
  3430.     uint32_t time = getNumber<uint32_t>(L, 4);
  3431.     Condition* condition = Condition::createCondition(CONDITIONID_COMBAT, CONDITION_LIGHT, time, level | (color << 8));
  3432.     creature->addCondition(condition);
  3433.     pushBoolean(L, true);
  3434.     return 1;
  3435. }
  3436.  
  3437. int LuaScriptInterface::luaAddEvent(lua_State* L)
  3438. {
  3439.     //addEvent(callback, delay, ...)
  3440.     lua_State* globalState = g_luaEnvironment.getLuaState();
  3441.     if (!globalState) {
  3442.         reportErrorFunc("No valid script interface!");
  3443.         pushBoolean(L, false);
  3444.         return 1;
  3445.     } else if (globalState != L) {
  3446.         lua_xmove(L, globalState, lua_gettop(L));
  3447.     }
  3448.  
  3449.     int parameters = lua_gettop(globalState);
  3450.     if (!isFunction(globalState, -parameters)) { //-parameters means the first parameter from left to right
  3451.         reportErrorFunc("callback parameter should be a function.");
  3452.         pushBoolean(L, false);
  3453.         return 1;
  3454.     }
  3455.  
  3456.     if (g_config.getBoolean(ConfigManager::WARN_UNSAFE_SCRIPTS) || g_config.getBoolean(ConfigManager::CONVERT_UNSAFE_SCRIPTS)) {
  3457.         std::vector<std::pair<int32_t, LuaDataType>> indexes;
  3458.         for (int i = 3; i <= parameters; ++i) {
  3459.             if (lua_getmetatable(globalState, i) == 0) {
  3460.                 continue;
  3461.             }
  3462.             lua_rawgeti(L, -1, 't');
  3463.  
  3464.             LuaDataType type = getNumber<LuaDataType>(L, -1);
  3465.             if (type != LuaData_Unknown && type != LuaData_Tile) {
  3466.                 indexes.push_back({i, type});
  3467.             }
  3468.             lua_pop(globalState, 2);
  3469.         }
  3470.  
  3471.         if (!indexes.empty()) {
  3472.             if (g_config.getBoolean(ConfigManager::WARN_UNSAFE_SCRIPTS)) {
  3473.                 bool plural = indexes.size() > 1;
  3474.  
  3475.                 std::string warningString = "Argument";
  3476.                 if (plural) {
  3477.                     warningString += 's';
  3478.                 }
  3479.  
  3480.                 for (const auto& entry : indexes) {
  3481.                     if (entry == indexes.front()) {
  3482.                         warningString += ' ';
  3483.                     } else if (entry == indexes.back()) {
  3484.                         warningString += " and ";
  3485.                     } else {
  3486.                         warningString += ", ";
  3487.                     }
  3488.                     warningString += '#';
  3489.                     warningString += std::to_string(entry.first);
  3490.                 }
  3491.  
  3492.                 if (plural) {
  3493.                     warningString += " are unsafe";
  3494.                 } else {
  3495.                     warningString += " is unsafe";
  3496.                 }
  3497.  
  3498.                 reportErrorFunc(warningString);
  3499.             }
  3500.  
  3501.             if (g_config.getBoolean(ConfigManager::CONVERT_UNSAFE_SCRIPTS)) {
  3502.                 for (const auto& entry : indexes) {
  3503.                     switch (entry.second) {
  3504.                         case LuaData_Item:
  3505.                         case LuaData_Container:
  3506.                         case LuaData_Teleport: {
  3507.                             lua_getglobal(globalState, "Item");
  3508.                             lua_getfield(globalState, -1, "getUniqueId");
  3509.                             break;
  3510.                         }
  3511.                         case LuaData_Player:
  3512.                         case LuaData_Monster:
  3513.                         case LuaData_Npc: {
  3514.                             lua_getglobal(globalState, "Creature");
  3515.                             lua_getfield(globalState, -1, "getId");
  3516.                             break;
  3517.                         }
  3518.                         default:
  3519.                             break;
  3520.                     }
  3521.                     lua_replace(globalState, -2);
  3522.                     lua_pushvalue(globalState, entry.first);
  3523.                     lua_call(globalState, 1, 1);
  3524.                     lua_replace(globalState, entry.first);
  3525.                 }
  3526.             }
  3527.         }
  3528.     }
  3529.  
  3530.     LuaTimerEventDesc eventDesc;
  3531.     for (int i = 0; i < parameters - 2; ++i) { //-2 because addEvent needs at least two parameters
  3532.         eventDesc.parameters.push_back(luaL_ref(globalState, LUA_REGISTRYINDEX));
  3533.     }
  3534.  
  3535.     uint32_t delay = std::max<uint32_t>(100, getNumber<uint32_t>(globalState, 2));
  3536.     lua_pop(globalState, 1);
  3537.  
  3538.     eventDesc.function = luaL_ref(globalState, LUA_REGISTRYINDEX);
  3539.     eventDesc.scriptId = getScriptEnv()->getScriptId();
  3540.  
  3541.     auto& lastTimerEventId = g_luaEnvironment.lastEventTimerId;
  3542.     eventDesc.eventId = g_scheduler.addEvent(createSchedulerTask(
  3543.         delay, std::bind(&LuaEnvironment::executeTimerEvent, &g_luaEnvironment, lastTimerEventId)
  3544.     ));
  3545.  
  3546.     g_luaEnvironment.timerEvents.emplace(lastTimerEventId, std::move(eventDesc));
  3547.     lua_pushnumber(L, lastTimerEventId++);
  3548.     return 1;
  3549. }
  3550.  
  3551. int LuaScriptInterface::luaStopEvent(lua_State* L)
  3552. {
  3553.     //stopEvent(eventid)
  3554.     lua_State* globalState = g_luaEnvironment.getLuaState();
  3555.     if (!globalState) {
  3556.         reportErrorFunc("No valid script interface!");
  3557.         pushBoolean(L, false);
  3558.         return 1;
  3559.     }
  3560.  
  3561.     uint32_t eventId = getNumber<uint32_t>(L, 1);
  3562.  
  3563.     auto& timerEvents = g_luaEnvironment.timerEvents;
  3564.     auto it = timerEvents.find(eventId);
  3565.     if (it == timerEvents.end()) {
  3566.         pushBoolean(L, false);
  3567.         return 1;
  3568.     }
  3569.  
  3570.     LuaTimerEventDesc timerEventDesc = std::move(it->second);
  3571.     timerEvents.erase(it);
  3572.  
  3573.     g_scheduler.stopEvent(timerEventDesc.eventId);
  3574.     luaL_unref(globalState, LUA_REGISTRYINDEX, timerEventDesc.function);
  3575.  
  3576.     for (auto parameter : timerEventDesc.parameters) {
  3577.         luaL_unref(globalState, LUA_REGISTRYINDEX, parameter);
  3578.     }
  3579.  
  3580.     pushBoolean(L, true);
  3581.     return 1;
  3582. }
  3583.  
  3584. int LuaScriptInterface::luaGetCreatureCondition(lua_State* L)
  3585. {
  3586.     Creature* creature = getCreature(L, 1);
  3587.     if (!creature) {
  3588.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  3589.         pushBoolean(L, false);
  3590.         return 1;
  3591.     }
  3592.  
  3593.     ConditionType_t condition = getNumber<ConditionType_t>(L, 2);
  3594.     uint32_t subId = getNumber<uint32_t>(L, 3, 0);
  3595.     pushBoolean(L, creature->hasCondition(condition, subId));
  3596.     return 1;
  3597. }
  3598.  
  3599. int LuaScriptInterface::luaSaveServer(lua_State* L)
  3600. {
  3601.     g_game.saveGameState();
  3602.     pushBoolean(L, true);
  3603.     return 1;
  3604. }
  3605.  
  3606. int LuaScriptInterface::luaCleanMap(lua_State* L)
  3607. {
  3608.     lua_pushnumber(L, g_game.map.clean());
  3609.     return 1;
  3610. }
  3611.  
  3612. int LuaScriptInterface::luaIsInWar(lua_State* L)
  3613. {
  3614.     //isInWar(cid, target)
  3615.     Player* player = getPlayer(L, 1);
  3616.     if (!player) {
  3617.         reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  3618.         pushBoolean(L, false);
  3619.         return 1;
  3620.     }
  3621.  
  3622.     Player* targetPlayer = getPlayer(L, 2);
  3623.     if (!targetPlayer) {
  3624.         reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  3625.         pushBoolean(L, false);
  3626.         return 1;
  3627.     }
  3628.  
  3629.     pushBoolean(L, player->isInWar(targetPlayer));
  3630.     return 1;
  3631. }
  3632.  
  3633. int LuaScriptInterface::luaGetWaypointPositionByName(lua_State* L)
  3634. {
  3635.     //getWaypointPositionByName(name)
  3636.     auto& waypoints = g_game.map.waypoints;
  3637.  
  3638.     auto it = waypoints.find(getString(L, -1));
  3639.     if (it != waypoints.end()) {
  3640.         pushPosition(L, it->second);
  3641.     } else {
  3642.         pushBoolean(L, false);
  3643.     }
  3644.     return 1;
  3645. }
  3646.  
  3647. int LuaScriptInterface::luaSendChannelMessage(lua_State* L)
  3648. {
  3649.     //sendChannelMessage(channelId, type, message)
  3650.     uint32_t channelId = getNumber<uint32_t>(L, 1);
  3651.     ChatChannel* channel = g_chat->getChannelById(channelId);
  3652.     if (!channel) {
  3653.         pushBoolean(L, false);
  3654.         return 1;
  3655.     }
  3656.  
  3657.     SpeakClasses type = getNumber<SpeakClasses>(L, 2);
  3658.     std::string message = getString(L, 3);
  3659.     channel->sendToAll(message, type);
  3660.     pushBoolean(L, true);
  3661.     return 1;
  3662. }
  3663.  
  3664. int LuaScriptInterface::luaSendGuildChannelMessage(lua_State* L)
  3665. {
  3666.     //sendGuildChannelMessage(guildId, type, message)
  3667.     uint32_t guildId = getNumber<uint32_t>(L, 1);
  3668.     ChatChannel* channel = g_chat->getGuildChannelById(guildId);
  3669.     if (!channel) {
  3670.         pushBoolean(L, false);
  3671.         return 1;
  3672.     }
  3673.  
  3674.     SpeakClasses type = getNumber<SpeakClasses>(L, 2);
  3675.     std::string message = getString(L, 3);
  3676.     channel->sendToAll(message, type);
  3677.     pushBoolean(L, true);
  3678.     return 1;
  3679. }
  3680.  
  3681. std::string LuaScriptInterface::escapeString(const std::string& string)
  3682. {
  3683.     std::string s = string;
  3684.     replaceString(s, "\\", "\\\\");
  3685.     replaceString(s, "\"", "\\\"");
  3686.     replaceString(s, "'", "\\'");
  3687.     replaceString(s, "[[", "\\[[");
  3688.     return s;
  3689. }
  3690.  
  3691. #ifndef LUAJIT_VERSION
  3692. const luaL_Reg LuaScriptInterface::luaBitReg[] = {
  3693.     //{"tobit", LuaScriptInterface::luaBitToBit},
  3694.     {"bnot", LuaScriptInterface::luaBitNot},
  3695.     {"band", LuaScriptInterface::luaBitAnd},
  3696.     {"bor", LuaScriptInterface::luaBitOr},
  3697.     {"bxor", LuaScriptInterface::luaBitXor},
  3698.     {"lshift", LuaScriptInterface::luaBitLeftShift},
  3699.     {"rshift", LuaScriptInterface::luaBitRightShift},
  3700.     //{"arshift", LuaScriptInterface::luaBitArithmeticalRightShift},
  3701.     //{"rol", LuaScriptInterface::luaBitRotateLeft},
  3702.     //{"ror", LuaScriptInterface::luaBitRotateRight},
  3703.     //{"bswap", LuaScriptInterface::luaBitSwapEndian},
  3704.     //{"tohex", LuaScriptInterface::luaBitToHex},
  3705.     {nullptr, nullptr}
  3706. };
  3707.  
  3708. int LuaScriptInterface::luaBitNot(lua_State* L)
  3709. {
  3710.     lua_pushnumber(L, ~getNumber<uint32_t>(L, -1));
  3711.     return 1;
  3712. }
  3713.  
  3714. #define MULTIOP(name, op) \
  3715. int LuaScriptInterface::luaBit##name(lua_State* L) \
  3716. { \
  3717.     int n = lua_gettop(L); \
  3718.     uint32_t w = getNumber<uint32_t>(L, -1); \
  3719.     for (int i = 1; i < n; ++i) \
  3720.         w op getNumber<uint32_t>(L, i); \
  3721.     lua_pushnumber(L, w); \
  3722.     return 1; \
  3723. }
  3724.  
  3725. MULTIOP(And, &= )
  3726. MULTIOP(Or, |= )
  3727. MULTIOP(Xor, ^= )
  3728.  
  3729. #define SHIFTOP(name, op) \
  3730. int LuaScriptInterface::luaBit##name(lua_State* L) \
  3731. { \
  3732.     uint32_t n1 = getNumber<uint32_t>(L, 1), n2 = getNumber<uint32_t>(L, 2); \
  3733.     lua_pushnumber(L, (n1 op n2)); \
  3734.     return 1; \
  3735. }
  3736.  
  3737. SHIFTOP(LeftShift, << )
  3738. SHIFTOP(RightShift, >> )
  3739. #endif
  3740.  
  3741. const luaL_Reg LuaScriptInterface::luaConfigManagerTable[] = {
  3742.     {"getString", LuaScriptInterface::luaConfigManagerGetString},
  3743.     {"getNumber", LuaScriptInterface::luaConfigManagerGetNumber},
  3744.     {"getBoolean", LuaScriptInterface::luaConfigManagerGetBoolean},
  3745.     {nullptr, nullptr}
  3746. };
  3747.  
  3748. int LuaScriptInterface::luaConfigManagerGetString(lua_State* L)
  3749. {
  3750.     pushString(L, g_config.getString(getNumber<ConfigManager::string_config_t>(L, -1)));
  3751.     return 1;
  3752. }
  3753.  
  3754. int LuaScriptInterface::luaConfigManagerGetNumber(lua_State* L)
  3755. {
  3756.     lua_pushnumber(L, g_config.getNumber(getNumber<ConfigManager::integer_config_t>(L, -1)));
  3757.     return 1;
  3758. }
  3759.  
  3760. int LuaScriptInterface::luaConfigManagerGetBoolean(lua_State* L)
  3761. {
  3762.     pushBoolean(L, g_config.getBoolean(getNumber<ConfigManager::boolean_config_t>(L, -1)));
  3763.     return 1;
  3764. }
  3765.  
  3766. const luaL_Reg LuaScriptInterface::luaDatabaseTable[] = {
  3767.     {"query", LuaScriptInterface::luaDatabaseExecute},
  3768.     {"asyncQuery", LuaScriptInterface::luaDatabaseAsyncExecute},
  3769.     {"storeQuery", LuaScriptInterface::luaDatabaseStoreQuery},
  3770.     {"asyncStoreQuery", LuaScriptInterface::luaDatabaseAsyncStoreQuery},
  3771.     {"escapeString", LuaScriptInterface::luaDatabaseEscapeString},
  3772.     {"escapeBlob", LuaScriptInterface::luaDatabaseEscapeBlob},
  3773.     {"lastInsertId", LuaScriptInterface::luaDatabaseLastInsertId},
  3774.     {"tableExists", LuaScriptInterface::luaDatabaseTableExists},
  3775.     {nullptr, nullptr}
  3776. };
  3777.  
  3778. int LuaScriptInterface::luaDatabaseExecute(lua_State* L)
  3779. {
  3780.     pushBoolean(L, Database::getInstance()->executeQuery(getString(L, -1)));
  3781.     return 1;
  3782. }
  3783.  
  3784. int LuaScriptInterface::luaDatabaseAsyncExecute(lua_State* L)
  3785. {
  3786.     std::function<void(DBResult_ptr, bool)> callback;
  3787.     if (lua_gettop(L) > 1) {
  3788.         int32_t ref = luaL_ref(L, LUA_REGISTRYINDEX);
  3789.         auto scriptId = getScriptEnv()->getScriptId();
  3790.         callback = [ref, scriptId](DBResult_ptr, bool success) {
  3791.             lua_State* luaState = g_luaEnvironment.getLuaState();
  3792.             if (!luaState) {
  3793.                 return;
  3794.             }
  3795.  
  3796.             if (!LuaScriptInterface::reserveScriptEnv()) {
  3797.                 luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
  3798.                 return;
  3799.             }
  3800.  
  3801.             lua_rawgeti(luaState, LUA_REGISTRYINDEX, ref);
  3802.             pushBoolean(luaState, success);
  3803.             auto env = getScriptEnv();
  3804.             env->setScriptId(scriptId, &g_luaEnvironment);
  3805.             g_luaEnvironment.callFunction(1);
  3806.  
  3807.             luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
  3808.         };
  3809.     }
  3810.     g_databaseTasks.addTask(getString(L, -1), callback);
  3811.     return 0;
  3812. }
  3813.  
  3814. int LuaScriptInterface::luaDatabaseStoreQuery(lua_State* L)
  3815. {
  3816.     if (DBResult_ptr res = Database::getInstance()->storeQuery(getString(L, -1))) {
  3817.         lua_pushnumber(L, ScriptEnvironment::addResult(res));
  3818.     } else {
  3819.         pushBoolean(L, false);
  3820.     }
  3821.     return 1;
  3822. }
  3823.  
  3824. int LuaScriptInterface::luaDatabaseAsyncStoreQuery(lua_State* L)
  3825. {
  3826.     std::function<void(DBResult_ptr, bool)> callback;
  3827.     if (lua_gettop(L) > 1) {
  3828.         int32_t ref = luaL_ref(L, LUA_REGISTRYINDEX);
  3829.         auto scriptId = getScriptEnv()->getScriptId();
  3830.         callback = [ref, scriptId](DBResult_ptr result, bool) {
  3831.             lua_State* luaState = g_luaEnvironment.getLuaState();
  3832.             if (!luaState) {
  3833.                 return;
  3834.             }
  3835.  
  3836.             if (!LuaScriptInterface::reserveScriptEnv()) {
  3837.                 luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
  3838.                 return;
  3839.             }
  3840.  
  3841.             lua_rawgeti(luaState, LUA_REGISTRYINDEX, ref);
  3842.             if (result) {
  3843.                 lua_pushnumber(luaState, ScriptEnvironment::addResult(result));
  3844.             } else {
  3845.                 pushBoolean(luaState, false);
  3846.             }
  3847.             auto env = getScriptEnv();
  3848.             env->setScriptId(scriptId, &g_luaEnvironment);
  3849.             g_luaEnvironment.callFunction(1);
  3850.  
  3851.             luaL_unref(luaState, LUA_REGISTRYINDEX, ref);
  3852.         };
  3853.     }
  3854.     g_databaseTasks.addTask(getString(L, -1), callback, true);
  3855.     return 0;
  3856. }
  3857.  
  3858. int LuaScriptInterface::luaDatabaseEscapeString(lua_State* L)
  3859. {
  3860.     pushString(L, Database::getInstance()->escapeString(getString(L, -1)));
  3861.     return 1;
  3862. }
  3863.  
  3864. int LuaScriptInterface::luaDatabaseEscapeBlob(lua_State* L)
  3865. {
  3866.     uint32_t length = getNumber<uint32_t>(L, 2);
  3867.     pushString(L, Database::getInstance()->escapeBlob(getString(L, 1).c_str(), length));
  3868.     return 1;
  3869. }
  3870.  
  3871. int LuaScriptInterface::luaDatabaseLastInsertId(lua_State* L)
  3872. {
  3873.     lua_pushnumber(L, Database::getInstance()->getLastInsertId());
  3874.     return 1;
  3875. }
  3876.  
  3877. int LuaScriptInterface::luaDatabaseTableExists(lua_State* L)
  3878. {
  3879.     pushBoolean(L, DatabaseManager::tableExists(getString(L, -1)));
  3880.     return 1;
  3881. }
  3882.  
  3883. const luaL_Reg LuaScriptInterface::luaResultTable[] = {
  3884.     {"getNumber", LuaScriptInterface::luaResultGetNumber},
  3885.     {"getString", LuaScriptInterface::luaResultGetString},
  3886.     {"getStream", LuaScriptInterface::luaResultGetStream},
  3887.     {"next", LuaScriptInterface::luaResultNext},
  3888.     {"free", LuaScriptInterface::luaResultFree},
  3889.     {nullptr, nullptr}
  3890. };
  3891.  
  3892. int LuaScriptInterface::luaResultGetNumber(lua_State* L)
  3893. {
  3894.     DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, 1));
  3895.     if (!res) {
  3896.         pushBoolean(L, false);
  3897.         return 1;
  3898.     }
  3899.  
  3900.     const std::string& s = getString(L, 2);
  3901.     lua_pushnumber(L, res->getNumber<int64_t>(s));
  3902.     return 1;
  3903. }
  3904.  
  3905. int LuaScriptInterface::luaResultGetString(lua_State* L)
  3906. {
  3907.     DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, 1));
  3908.     if (!res) {
  3909.         pushBoolean(L, false);
  3910.         return 1;
  3911.     }
  3912.  
  3913.     const std::string& s = getString(L, 2);
  3914.     pushString(L, res->getString(s));
  3915.     return 1;
  3916. }
  3917.  
  3918. int LuaScriptInterface::luaResultGetStream(lua_State* L)
  3919. {
  3920.     DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, 1));
  3921.     if (!res) {
  3922.         pushBoolean(L, false);
  3923.         return 1;
  3924.     }
  3925.  
  3926.     unsigned long length;
  3927.     const char* stream = res->getStream(getString(L, 2), length);
  3928.     lua_pushlstring(L, stream, length);
  3929.     lua_pushnumber(L, length);
  3930.     return 2;
  3931. }
  3932.  
  3933. int LuaScriptInterface::luaResultNext(lua_State* L)
  3934. {
  3935.     DBResult_ptr res = ScriptEnvironment::getResultByID(getNumber<uint32_t>(L, -1));
  3936.     if (!res) {
  3937.         pushBoolean(L, false);
  3938.         return 1;
  3939.     }
  3940.  
  3941.     pushBoolean(L, res->next());
  3942.     return 1;
  3943. }
  3944.  
  3945. int LuaScriptInterface::luaResultFree(lua_State* L)
  3946. {
  3947.     pushBoolean(L, ScriptEnvironment::removeResult(getNumber<uint32_t>(L, -1)));
  3948.     return 1;
  3949. }
  3950.  
  3951. // Userdata
  3952. int LuaScriptInterface::luaUserdataCompare(lua_State* L)
  3953. {
  3954.     // userdataA == userdataB
  3955.     pushBoolean(L, getUserdata<void>(L, 1) == getUserdata<void>(L, 2));
  3956.     return 1;
  3957. }
  3958.  
  3959. // _G
  3960. int LuaScriptInterface::luaIsType(lua_State* L)
  3961. {
  3962.     // isType(derived, base)
  3963.     lua_getmetatable(L, -2);
  3964.     lua_getmetatable(L, -2);
  3965.  
  3966.     lua_rawgeti(L, -2, 'p');
  3967.     uint_fast8_t parentsB = getNumber<uint_fast8_t>(L, 1);
  3968.  
  3969.     lua_rawgeti(L, -3, 'h');
  3970.     size_t hashB = getNumber<size_t>(L, 1);
  3971.  
  3972.     lua_rawgeti(L, -3, 'p');
  3973.     uint_fast8_t parentsA = getNumber<uint_fast8_t>(L, 1);
  3974.     for (uint_fast8_t i = parentsA; i < parentsB; ++i) {
  3975.         lua_getfield(L, -3, "__index");
  3976.         lua_replace(L, -4);
  3977.     }
  3978.  
  3979.     lua_rawgeti(L, -4, 'h');
  3980.     size_t hashA = getNumber<size_t>(L, 1);
  3981.  
  3982.     pushBoolean(L, hashA == hashB);
  3983.     return 1;
  3984. }
  3985.  
  3986. int LuaScriptInterface::luaRawGetMetatable(lua_State* L)
  3987. {
  3988.     // rawgetmetatable(metatableName)
  3989.     luaL_getmetatable(L, getString(L, 1).c_str());
  3990.     return 1;
  3991. }
  3992.  
  3993. // os
  3994. int LuaScriptInterface::luaSystemTime(lua_State* L)
  3995. {
  3996.     // os.mtime()
  3997.     lua_pushnumber(L, OTSYS_TIME());
  3998.     return 1;
  3999. }
  4000.  
  4001. // table
  4002. int LuaScriptInterface::luaTableCreate(lua_State* L)
  4003. {
  4004.     // table.create(arrayLength, keyLength)
  4005.     lua_createtable(L, getNumber<int32_t>(L, 1), getNumber<int32_t>(L, 2));
  4006.     return 1;
  4007. }
  4008.  
  4009. // Game
  4010. int LuaScriptInterface::luaGameGetSpectators(lua_State* L)
  4011. {
  4012.     // Game.getSpectators(position[, multifloor = false[, onlyPlayer = false[, minRangeX = 0[, maxRangeX = 0[, minRangeY = 0[, maxRangeY = 0]]]]]])
  4013.     const Position& position = getPosition(L, 1);
  4014.     bool multifloor = getBoolean(L, 2, false);
  4015.     bool onlyPlayers = getBoolean(L, 3, false);
  4016.     int32_t minRangeX = getNumber<int32_t>(L, 4, 0);
  4017.     int32_t maxRangeX = getNumber<int32_t>(L, 5, 0);
  4018.     int32_t minRangeY = getNumber<int32_t>(L, 6, 0);
  4019.     int32_t maxRangeY = getNumber<int32_t>(L, 7, 0);
  4020.  
  4021.     SpectatorVec spectators;
  4022.     g_game.map.getSpectators(spectators, position, multifloor, onlyPlayers, minRangeX, maxRangeX, minRangeY, maxRangeY);
  4023.  
  4024.     lua_createtable(L, spectators.size(), 0);
  4025.  
  4026.     int index = 0;
  4027.     for (Creature* creature : spectators) {
  4028.         pushUserdata<Creature>(L, creature);
  4029.         setCreatureMetatable(L, -1, creature);
  4030.         lua_rawseti(L, -2, ++index);
  4031.     }
  4032.     return 1;
  4033. }
  4034.  
  4035. int LuaScriptInterface::luaGameGetPlayers(lua_State* L)
  4036. {
  4037.     // Game.getPlayers()
  4038.     lua_createtable(L, g_game.getPlayersOnline(), 0);
  4039.  
  4040.     int index = 0;
  4041.     for (const auto& playerEntry : g_game.getPlayers()) {
  4042.         pushUserdata<Player>(L, playerEntry.second);
  4043.         setMetatable(L, -1, "Player");
  4044.         lua_rawseti(L, -2, ++index);
  4045.     }
  4046.     return 1;
  4047. }
  4048.  
  4049. int LuaScriptInterface::luaGameLoadMap(lua_State* L)
  4050. {
  4051.     // Game.loadMap(path)
  4052.     const std::string& path = getString(L, 1);
  4053.     g_dispatcher.addTask(createTask(std::bind(&Game::loadMap, &g_game, path)));
  4054.     return 0;
  4055. }
  4056.  
  4057. int LuaScriptInterface::luaGameGetExperienceStage(lua_State* L)
  4058. {
  4059.     // Game.getExperienceStage(level)
  4060.     uint32_t level = getNumber<uint32_t>(L, 1);
  4061.     lua_pushnumber(L, g_game.getExperienceStage(level));
  4062.     return 1;
  4063. }
  4064.  
  4065. int LuaScriptInterface::luaGameGetMonsterCount(lua_State* L)
  4066. {
  4067.     // Game.getMonsterCount()
  4068.     lua_pushnumber(L, g_game.getMonstersOnline());
  4069.     return 1;
  4070. }
  4071.  
  4072. int LuaScriptInterface::luaGameGetPlayerCount(lua_State* L)
  4073. {
  4074.     // Game.getPlayerCount()
  4075.     lua_pushnumber(L, g_game.getPlayersOnline());
  4076.     return 1;
  4077. }
  4078.  
  4079. int LuaScriptInterface::luaGameGetNpcCount(lua_State* L)
  4080. {
  4081.     // Game.getNpcCount()
  4082.     lua_pushnumber(L, g_game.getNpcsOnline());
  4083.     return 1;
  4084. }
  4085.  
  4086. int LuaScriptInterface::luaGameGetTowns(lua_State* L)
  4087. {
  4088.     // Game.getTowns()
  4089.     const auto& towns = g_game.map.towns.getTowns();
  4090.     lua_createtable(L, towns.size(), 0);
  4091.  
  4092.     int index = 0;
  4093.     for (auto townEntry : towns) {
  4094.         pushUserdata<Town>(L, townEntry.second);
  4095.         setMetatable(L, -1, "Town");
  4096.         lua_rawseti(L, -2, ++index);
  4097.     }
  4098.     return 1;
  4099. }
  4100.  
  4101. int LuaScriptInterface::luaGameGetHouses(lua_State* L)
  4102. {
  4103.     // Game.getHouses()
  4104.     const auto& houses = g_game.map.houses.getHouses();
  4105.     lua_createtable(L, houses.size(), 0);
  4106.  
  4107.     int index = 0;
  4108.     for (auto houseEntry : houses) {
  4109.         pushUserdata<House>(L, houseEntry.second);
  4110.         setMetatable(L, -1, "House");
  4111.         lua_rawseti(L, -2, ++index);
  4112.     }
  4113.     return 1;
  4114. }
  4115.  
  4116. int LuaScriptInterface::luaGameGetGameState(lua_State* L)
  4117. {
  4118.     // Game.getGameState()
  4119.     lua_pushnumber(L, g_game.getGameState());
  4120.     return 1;
  4121. }
  4122.  
  4123. int LuaScriptInterface::luaGameSetGameState(lua_State* L)
  4124. {
  4125.     // Game.setGameState(state)
  4126.     GameState_t state = getNumber<GameState_t>(L, 1);
  4127.     g_game.setGameState(state);
  4128.     pushBoolean(L, true);
  4129.     return 1;
  4130. }
  4131.  
  4132. int LuaScriptInterface::luaGameGetWorldType(lua_State* L)
  4133. {
  4134.     // Game.getWorldType()
  4135.     lua_pushnumber(L, g_game.getWorldType());
  4136.     return 1;
  4137. }
  4138.  
  4139. int LuaScriptInterface::luaGameSetWorldType(lua_State* L)
  4140. {
  4141.     // Game.setWorldType(type)
  4142.     WorldType_t type = getNumber<WorldType_t>(L, 1);
  4143.     g_game.setWorldType(type);
  4144.     pushBoolean(L, true);
  4145.     return 1;
  4146. }
  4147.  
  4148. int LuaScriptInterface::luaGameGetReturnMessage(lua_State* L)
  4149. {
  4150.     // Game.getReturnMessage(value)
  4151.     ReturnValue value = getNumber<ReturnValue>(L, 1);
  4152.     pushString(L, getReturnMessage(value));
  4153.     return 1;
  4154. }
  4155.  
  4156. int LuaScriptInterface::luaGameCreateItem(lua_State* L)
  4157. {
  4158.     // Game.createItem(itemId[, count[, position]])
  4159.     uint16_t count = getNumber<uint16_t>(L, 2, 1);
  4160.     uint16_t id;
  4161.     if (isNumber(L, 1)) {
  4162.         id = getNumber<uint16_t>(L, 1);
  4163.     } else {
  4164.         id = Item::items.getItemIdByName(getString(L, 1));
  4165.         if (id == 0) {
  4166.             lua_pushnil(L);
  4167.             return 1;
  4168.         }
  4169.     }
  4170.  
  4171.     const ItemType& it = Item::items[id];
  4172.     if (it.stackable) {
  4173.         count = std::min<uint16_t>(count, 100);
  4174.     }
  4175.  
  4176.     Item* item = Item::CreateItem(id, count);
  4177.     if (!item) {
  4178.         lua_pushnil(L);
  4179.         return 1;
  4180.     }
  4181.  
  4182.     if (lua_gettop(L) >= 3) {
  4183.         const Position& position = getPosition(L, 3);
  4184.         Tile* tile = g_game.map.getTile(position);
  4185.         if (!tile) {
  4186.             delete item;
  4187.             lua_pushnil(L);
  4188.             return 1;
  4189.         }
  4190.  
  4191.         g_game.internalAddItem(tile, item, INDEX_WHEREEVER, FLAG_NOLIMIT);
  4192.     } else {
  4193.         getScriptEnv()->addTempItem(item);
  4194.         item->setParent(VirtualCylinder::virtualCylinder);
  4195.     }
  4196.  
  4197.     pushUserdata<Item>(L, item);
  4198.     setItemMetatable(L, -1, item);
  4199.     return 1;
  4200. }
  4201.  
  4202. int LuaScriptInterface::luaGameCreateContainer(lua_State* L)
  4203. {
  4204.     // Game.createContainer(itemId, size[, position])
  4205.     uint16_t size = getNumber<uint16_t>(L, 2);
  4206.     uint16_t id;
  4207.     if (isNumber(L, 1)) {
  4208.         id = getNumber<uint16_t>(L, 1);
  4209.     } else {
  4210.         id = Item::items.getItemIdByName(getString(L, 1));
  4211.         if (id == 0) {
  4212.             lua_pushnil(L);
  4213.             return 1;
  4214.         }
  4215.     }
  4216.  
  4217.     Container* container = Item::CreateItemAsContainer(id, size);
  4218.     if (!container) {
  4219.         lua_pushnil(L);
  4220.         return 1;
  4221.     }
  4222.  
  4223.     if (lua_gettop(L) >= 3) {
  4224.         const Position& position = getPosition(L, 3);
  4225.         Tile* tile = g_game.map.getTile(position);
  4226.         if (!tile) {
  4227.             delete container;
  4228.             lua_pushnil(L);
  4229.             return 1;
  4230.         }
  4231.  
  4232.         g_game.internalAddItem(tile, container, INDEX_WHEREEVER, FLAG_NOLIMIT);
  4233.     } else {
  4234.         getScriptEnv()->addTempItem(container);
  4235.         container->setParent(VirtualCylinder::virtualCylinder);
  4236.     }
  4237.  
  4238.     pushUserdata<Container>(L, container);
  4239.     setMetatable(L, -1, "Container");
  4240.     return 1;
  4241. }
  4242.  
  4243. int LuaScriptInterface::luaGameCreateMonster(lua_State* L)
  4244. {
  4245.     // Game.createMonster(monsterName, position[, extended = false[, force = false]])
  4246.     Monster* monster = Monster::createMonster(getString(L, 1));
  4247.     if (!monster) {
  4248.         lua_pushnil(L);
  4249.         return 1;
  4250.     }
  4251.  
  4252.     const Position& position = getPosition(L, 2);
  4253.     bool extended = getBoolean(L, 3, false);
  4254.     bool force = getBoolean(L, 4, false);
  4255.     if (g_game.placeCreature(monster, position, extended, force)) {
  4256.         pushUserdata<Monster>(L, monster);
  4257.         setMetatable(L, -1, "Monster");
  4258.     } else {
  4259.         delete monster;
  4260.         lua_pushnil(L);
  4261.     }
  4262.     return 1;
  4263. }
  4264.  
  4265. int LuaScriptInterface::luaGameCreateNpc(lua_State* L)
  4266. {
  4267.     // Game.createNpc(npcName, position[, extended = false[, force = false]])
  4268.     Npc* npc = Npc::createNpc(getString(L, 1));
  4269.     if (!npc) {
  4270.         lua_pushnil(L);
  4271.         return 1;
  4272.     }
  4273.  
  4274.     const Position& position = getPosition(L, 2);
  4275.     bool extended = getBoolean(L, 3, false);
  4276.     bool force = getBoolean(L, 4, false);
  4277.     if (g_game.placeCreature(npc, position, extended, force)) {
  4278.         pushUserdata<Npc>(L, npc);
  4279.         setMetatable(L, -1, "Npc");
  4280.     } else {
  4281.         delete npc;
  4282.         lua_pushnil(L);
  4283.     }
  4284.     return 1;
  4285. }
  4286.  
  4287. int LuaScriptInterface::luaGameCreateTile(lua_State* L)
  4288. {
  4289.     // Game.createTile(x, y, z[, isDynamic = false])
  4290.     // Game.createTile(position[, isDynamic = false])
  4291.     Position position;
  4292.     bool isDynamic;
  4293.     if (isTable(L, 1)) {
  4294.         position = getPosition(L, 1);
  4295.         isDynamic = getBoolean(L, 2, false);
  4296.     } else {
  4297.         position.x = getNumber<uint16_t>(L, 1);
  4298.         position.y = getNumber<uint16_t>(L, 2);
  4299.         position.z = getNumber<uint16_t>(L, 3);
  4300.         isDynamic = getBoolean(L, 4, false);
  4301.     }
  4302.  
  4303.     Tile* tile = g_game.map.getTile(position);
  4304.     if (!tile) {
  4305.         if (isDynamic) {
  4306.             tile = new DynamicTile(position.x, position.y, position.z);
  4307.         } else {
  4308.             tile = new StaticTile(position.x, position.y, position.z);
  4309.         }
  4310.  
  4311.         g_game.map.setTile(position, tile);
  4312.     }
  4313.  
  4314.     pushUserdata(L, tile);
  4315.     setMetatable(L, -1, "Tile");
  4316.     return 1;
  4317. }
  4318.  
  4319. int LuaScriptInterface::luaGameStartRaid(lua_State* L)
  4320. {
  4321.     // Game.startRaid(raidName)
  4322.     const std::string& raidName = getString(L, 1);
  4323.  
  4324.     Raid* raid = g_game.raids.getRaidByName(raidName);
  4325.     if (raid) {
  4326.         raid->startRaid();
  4327.         pushBoolean(L, true);
  4328.     } else {
  4329.         lua_pushnil(L);
  4330.     }
  4331.     return 1;
  4332. }
  4333.  
  4334. int LuaScriptInterface::luaGameSendAnimatedText(lua_State* L)
  4335. {
  4336.     // Game.sendAnimatedText(message, position, color)
  4337.     int parameters = lua_gettop(L);
  4338.     if (parameters < 3) {
  4339.         pushBoolean(L, false);
  4340.         return 1;
  4341.     }
  4342.  
  4343.     TextColor_t color = getNumber<TextColor_t>(L, 3);
  4344.     const Position& position = getPosition(L, 2);
  4345.     const std::string& message = getString(L, 1);
  4346.  
  4347.     if (!position.x || !position.y) {
  4348.         pushBoolean(L, false);
  4349.         return 1;
  4350.     }
  4351.  
  4352.     g_game.addAnimatedText(message, position, color);
  4353.     pushBoolean(L, true);
  4354.     return 1;
  4355. }
  4356.  
  4357. // Variant
  4358. int LuaScriptInterface::luaVariantCreate(lua_State* L)
  4359. {
  4360.     // Variant(number or string or position or thing)
  4361.     LuaVariant variant;
  4362.     if (isUserdata(L, 2)) {
  4363.         if (Thing* thing = getThing(L, 2)) {
  4364.             variant.type = VARIANT_TARGETPOSITION;
  4365.             variant.pos = thing->getPosition();
  4366.         }
  4367.     } else if (isTable(L, 2)) {
  4368.         variant.type = VARIANT_POSITION;
  4369.         variant.pos = getPosition(L, 2);
  4370.     } else if (isNumber(L, 2)) {
  4371.         variant.type = VARIANT_NUMBER;
  4372.         variant.number = getNumber<uint32_t>(L, 2);
  4373.     } else if (isString(L, 2)) {
  4374.         variant.type = VARIANT_STRING;
  4375.         variant.text = getString(L, 2);
  4376.     }
  4377.     pushVariant(L, variant);
  4378.     return 1;
  4379. }
  4380.  
  4381. int LuaScriptInterface::luaVariantGetNumber(lua_State* L)
  4382. {
  4383.     // Variant:getNumber()
  4384.     const LuaVariant& variant = getVariant(L, 1);
  4385.     if (variant.type == VARIANT_NUMBER) {
  4386.         lua_pushnumber(L, variant.number);
  4387.     } else {
  4388.         lua_pushnumber(L, 0);
  4389.     }
  4390.     return 1;
  4391. }
  4392.  
  4393. int LuaScriptInterface::luaVariantGetString(lua_State* L)
  4394. {
  4395.     // Variant:getString()
  4396.     const LuaVariant& variant = getVariant(L, 1);
  4397.     if (variant.type == VARIANT_STRING) {
  4398.         pushString(L, variant.text);
  4399.     } else {
  4400.         pushString(L, std::string());
  4401.     }
  4402.     return 1;
  4403. }
  4404.  
  4405. int LuaScriptInterface::luaVariantGetPosition(lua_State* L)
  4406. {
  4407.     // Variant:getPosition()
  4408.     const LuaVariant& variant = getVariant(L, 1);
  4409.     if (variant.type == VARIANT_POSITION || variant.type == VARIANT_TARGETPOSITION) {
  4410.         pushPosition(L, variant.pos);
  4411.     } else {
  4412.         pushPosition(L, Position());
  4413.     }
  4414.     return 1;
  4415. }
  4416.  
  4417. // Position
  4418. int LuaScriptInterface::luaPositionCreate(lua_State* L)
  4419. {
  4420.     // Position([x = 0[, y = 0[, z = 0[, stackpos = 0]]]])
  4421.     // Position([position])
  4422.     if (lua_gettop(L) <= 1) {
  4423.         pushPosition(L, Position());
  4424.         return 1;
  4425.     }
  4426.  
  4427.     int32_t stackpos;
  4428.     if (isTable(L, 2)) {
  4429.         const Position& position = getPosition(L, 2, stackpos);
  4430.         pushPosition(L, position, stackpos);
  4431.     } else {
  4432.         uint16_t x = getNumber<uint16_t>(L, 2, 0);
  4433.         uint16_t y = getNumber<uint16_t>(L, 3, 0);
  4434.         uint8_t z = getNumber<uint8_t>(L, 4, 0);
  4435.         stackpos = getNumber<int32_t>(L, 5, 0);
  4436.  
  4437.         pushPosition(L, Position(x, y, z), stackpos);
  4438.     }
  4439.     return 1;
  4440. }
  4441.  
  4442. int LuaScriptInterface::luaPositionAdd(lua_State* L)
  4443. {
  4444.     // positionValue = position + positionEx
  4445.     int32_t stackpos;
  4446.     const Position& position = getPosition(L, 1, stackpos);
  4447.  
  4448.     Position positionEx;
  4449.     if (stackpos == 0) {
  4450.         positionEx = getPosition(L, 2, stackpos);
  4451.     } else {
  4452.         positionEx = getPosition(L, 2);
  4453.     }
  4454.  
  4455.     pushPosition(L, position + positionEx, stackpos);
  4456.     return 1;
  4457. }
  4458.  
  4459. int LuaScriptInterface::luaPositionSub(lua_State* L)
  4460. {
  4461.     // positionValue = position - positionEx
  4462.     int32_t stackpos;
  4463.     const Position& position = getPosition(L, 1, stackpos);
  4464.  
  4465.     Position positionEx;
  4466.     if (stackpos == 0) {
  4467.         positionEx = getPosition(L, 2, stackpos);
  4468.     } else {
  4469.         positionEx = getPosition(L, 2);
  4470.     }
  4471.  
  4472.     pushPosition(L, position - positionEx, stackpos);
  4473.     return 1;
  4474. }
  4475.  
  4476. int LuaScriptInterface::luaPositionCompare(lua_State* L)
  4477. {
  4478.     // position == positionEx
  4479.     const Position& positionEx = getPosition(L, 2);
  4480.     const Position& position = getPosition(L, 1);
  4481.     pushBoolean(L, position == positionEx);
  4482.     return 1;
  4483. }
  4484.  
  4485. int LuaScriptInterface::luaPositionGetDistance(lua_State* L)
  4486. {
  4487.     // position:getDistance(positionEx)
  4488.     const Position& positionEx = getPosition(L, 2);
  4489.     const Position& position = getPosition(L, 1);
  4490.     lua_pushnumber(L, std::max<int32_t>(
  4491.         std::max<int32_t>(
  4492.             std::abs(Position::getDistanceX(position, positionEx)),
  4493.             std::abs(Position::getDistanceY(position, positionEx))
  4494.         ),
  4495.         std::abs(Position::getDistanceZ(position, positionEx))
  4496.     ));
  4497.     return 1;
  4498. }
  4499.  
  4500. int LuaScriptInterface::luaPositionIsSightClear(lua_State* L)
  4501. {
  4502.     // position:isSightClear(positionEx[, sameFloor = true])
  4503.     bool sameFloor = getBoolean(L, 3, true);
  4504.     const Position& positionEx = getPosition(L, 2);
  4505.     const Position& position = getPosition(L, 1);
  4506.     pushBoolean(L, g_game.isSightClear(position, positionEx, sameFloor));
  4507.     return 1;
  4508. }
  4509.  
  4510. int LuaScriptInterface::luaPositionSendMagicEffect(lua_State* L)
  4511. {
  4512.     // position:sendMagicEffect(magicEffect[, player = nullptr])
  4513.     SpectatorVec list;
  4514.     if (lua_gettop(L) >= 3) {
  4515.         Player* player = getPlayer(L, 3);
  4516.         if (player) {
  4517.             list.insert(player);
  4518.         }
  4519.     }
  4520.  
  4521.     MagicEffectClasses magicEffect = getNumber<MagicEffectClasses>(L, 2);
  4522.     const Position& position = getPosition(L, 1);
  4523.     if (!list.empty()) {
  4524.         Game::addMagicEffect(list, position, magicEffect);
  4525.     } else {
  4526.         g_game.addMagicEffect(position, magicEffect);
  4527.     }
  4528.  
  4529.     pushBoolean(L, true);
  4530.     return 1;
  4531. }
  4532.  
  4533. int LuaScriptInterface::luaPositionSendDistanceEffect(lua_State* L)
  4534. {
  4535.     // position:sendDistanceEffect(positionEx, distanceEffect[, player = nullptr])
  4536.     SpectatorVec list;
  4537.     if (lua_gettop(L) >= 4) {
  4538.         Player* player = getPlayer(L, 4);
  4539.         if (player) {
  4540.             list.insert(player);
  4541.         }
  4542.     }
  4543.  
  4544.     ShootType_t distanceEffect = getNumber<ShootType_t>(L, 3);
  4545.     const Position& positionEx = getPosition(L, 2);
  4546.     const Position& position = getPosition(L, 1);
  4547.     if (!list.empty()) {
  4548.         Game::addDistanceEffect(list, position, positionEx, distanceEffect);
  4549.     } else {
  4550.         g_game.addDistanceEffect(position, positionEx, distanceEffect);
  4551.     }
  4552.  
  4553.     pushBoolean(L, true);
  4554.     return 1;
  4555. }
  4556.  
  4557. // Tile
  4558. int LuaScriptInterface::luaTileCreate(lua_State* L)
  4559. {
  4560.     // Tile(x, y, z)
  4561.     // Tile(position)
  4562.     Tile* tile;
  4563.     if (isTable(L, 2)) {
  4564.         tile = g_game.map.getTile(getPosition(L, 2));
  4565.     } else {
  4566.         uint8_t z = getNumber<uint8_t>(L, 4);
  4567.         uint16_t y = getNumber<uint16_t>(L, 3);
  4568.         uint16_t x = getNumber<uint16_t>(L, 2);
  4569.         tile = g_game.map.getTile(x, y, z);
  4570.     }
  4571.  
  4572.     if (tile) {
  4573.         pushUserdata<Tile>(L, tile);
  4574.         setMetatable(L, -1, "Tile");
  4575.     } else {
  4576.         lua_pushnil(L);
  4577.     }
  4578.     return 1;
  4579. }
  4580.  
  4581. int LuaScriptInterface::luaTileGetPosition(lua_State* L)
  4582. {
  4583.     // tile:getPosition()
  4584.     Tile* tile = getUserdata<Tile>(L, 1);
  4585.     if (tile) {
  4586.         pushPosition(L, tile->getPosition());
  4587.     } else {
  4588.         lua_pushnil(L);
  4589.     }
  4590.     return 1;
  4591. }
  4592.  
  4593. int LuaScriptInterface::luaTileGetGround(lua_State* L)
  4594. {
  4595.     // tile:getGround()
  4596.     Tile* tile = getUserdata<Tile>(L, 1);
  4597.     if (tile && tile->getGround()) {
  4598.         pushUserdata<Item>(L, tile->getGround());
  4599.         setItemMetatable(L, -1, tile->getGround());
  4600.     } else {
  4601.         lua_pushnil(L);
  4602.     }
  4603.     return 1;
  4604. }
  4605.  
  4606. int LuaScriptInterface::luaTileGetThing(lua_State* L)
  4607. {
  4608.     // tile:getThing(index)
  4609.     int32_t index = getNumber<int32_t>(L, 2);
  4610.     Tile* tile = getUserdata<Tile>(L, 1);
  4611.     if (!tile) {
  4612.         lua_pushnil(L);
  4613.         return 1;
  4614.     }
  4615.  
  4616.     Thing* thing = tile->getThing(index);
  4617.     if (!thing) {
  4618.         lua_pushnil(L);
  4619.         return 1;
  4620.     }
  4621.  
  4622.     if (Creature* creature = thing->getCreature()) {
  4623.         pushUserdata<Creature>(L, creature);
  4624.         setCreatureMetatable(L, -1, creature);
  4625.     } else if (Item* item = thing->getItem()) {
  4626.         pushUserdata<Item>(L, item);
  4627.         setItemMetatable(L, -1, item);
  4628.     } else {
  4629.         lua_pushnil(L);
  4630.     }
  4631.     return 1;
  4632. }
  4633.  
  4634. int LuaScriptInterface::luaTileGetThingCount(lua_State* L)
  4635. {
  4636.     // tile:getThingCount()
  4637.     Tile* tile = getUserdata<Tile>(L, 1);
  4638.     if (tile) {
  4639.         lua_pushnumber(L, tile->getThingCount());
  4640.     } else {
  4641.         lua_pushnil(L);
  4642.     }
  4643.     return 1;
  4644. }
  4645.  
  4646. int LuaScriptInterface::luaTileGetTopVisibleThing(lua_State* L)
  4647. {
  4648.     // tile:getTopVisibleThing(creature)
  4649.     Creature* creature = getCreature(L, 2);
  4650.     Tile* tile = getUserdata<Tile>(L, 1);
  4651.     if (!tile) {
  4652.         lua_pushnil(L);
  4653.         return 1;
  4654.     }
  4655.  
  4656.     Thing* thing = tile->getTopVisibleThing(creature);
  4657.     if (!thing) {
  4658.         lua_pushnil(L);
  4659.         return 1;
  4660.     }
  4661.  
  4662.     if (Creature* visibleCreature = thing->getCreature()) {
  4663.         pushUserdata<Creature>(L, visibleCreature);
  4664.         setCreatureMetatable(L, -1, visibleCreature);
  4665.     } else if (Item* visibleItem = thing->getItem()) {
  4666.         pushUserdata<Item>(L, visibleItem);
  4667.         setItemMetatable(L, -1, visibleItem);
  4668.     } else {
  4669.         lua_pushnil(L);
  4670.     }
  4671.     return 1;
  4672. }
  4673.  
  4674. int LuaScriptInterface::luaTileGetTopTopItem(lua_State* L)
  4675. {
  4676.     // tile:getTopTopItem()
  4677.     Tile* tile = getUserdata<Tile>(L, 1);
  4678.     if (!tile) {
  4679.         lua_pushnil(L);
  4680.         return 1;
  4681.     }
  4682.  
  4683.     Item* item = tile->getTopTopItem();
  4684.     if (item) {
  4685.         pushUserdata<Item>(L, item);
  4686.         setItemMetatable(L, -1, item);
  4687.     } else {
  4688.         lua_pushnil(L);
  4689.     }
  4690.     return 1;
  4691. }
  4692.  
  4693. int LuaScriptInterface::luaTileGetTopDownItem(lua_State* L)
  4694. {
  4695.     // tile:getTopDownItem()
  4696.     Tile* tile = getUserdata<Tile>(L, 1);
  4697.     if (!tile) {
  4698.         lua_pushnil(L);
  4699.         return 1;
  4700.     }
  4701.  
  4702.     Item* item = tile->getTopDownItem();
  4703.     if (item) {
  4704.         pushUserdata<Item>(L, item);
  4705.         setItemMetatable(L, -1, item);
  4706.     } else {
  4707.         lua_pushnil(L);
  4708.     }
  4709.     return 1;
  4710. }
  4711.  
  4712. int LuaScriptInterface::luaTileGetFieldItem(lua_State* L)
  4713. {
  4714.     // tile:getFieldItem()
  4715.     Tile* tile = getUserdata<Tile>(L, 1);
  4716.     if (!tile) {
  4717.         lua_pushnil(L);
  4718.         return 1;
  4719.     }
  4720.  
  4721.     Item* item = tile->getFieldItem();
  4722.     if (item) {
  4723.         pushUserdata<Item>(L, item);
  4724.         setItemMetatable(L, -1, item);
  4725.     } else {
  4726.         lua_pushnil(L);
  4727.     }
  4728.     return 1;
  4729. }
  4730.  
  4731. int LuaScriptInterface::luaTileGetItemById(lua_State* L)
  4732. {
  4733.     // tile:getItemById(itemId[, subType = -1])
  4734.     Tile* tile = getUserdata<Tile>(L, 1);
  4735.     if (!tile) {
  4736.         lua_pushnil(L);
  4737.         return 1;
  4738.     }
  4739.  
  4740.     uint16_t itemId;
  4741.     if (isNumber(L, 2)) {
  4742.         itemId = getNumber<uint16_t>(L, 2);
  4743.     } else {
  4744.         itemId = Item::items.getItemIdByName(getString(L, 2));
  4745.         if (itemId == 0) {
  4746.             lua_pushnil(L);
  4747.             return 1;
  4748.         }
  4749.     }
  4750.     int32_t subType = getNumber<int32_t>(L, 3, -1);
  4751.  
  4752.     Item* item = g_game.findItemOfType(tile, itemId, false, subType);
  4753.     if (item) {
  4754.         pushUserdata<Item>(L, item);
  4755.         setItemMetatable(L, -1, item);
  4756.     } else {
  4757.         lua_pushnil(L);
  4758.     }
  4759.     return 1;
  4760. }
  4761.  
  4762. int LuaScriptInterface::luaTileGetItemByType(lua_State* L)
  4763. {
  4764.     // tile:getItemByType(itemType)
  4765.     Tile* tile = getUserdata<Tile>(L, 1);
  4766.     if (!tile) {
  4767.         lua_pushnil(L);
  4768.         return 1;
  4769.     }
  4770.  
  4771.     bool found;
  4772.  
  4773.     ItemTypes_t itemType = getNumber<ItemTypes_t>(L, 2);
  4774.     switch (itemType) {
  4775.         case ITEM_TYPE_TELEPORT:
  4776.             found = tile->hasFlag(TILESTATE_TELEPORT);
  4777.             break;
  4778.         case ITEM_TYPE_MAGICFIELD:
  4779.             found = tile->hasFlag(TILESTATE_MAGICFIELD);
  4780.             break;
  4781.         case ITEM_TYPE_MAILBOX:
  4782.             found = tile->hasFlag(TILESTATE_MAILBOX);
  4783.             break;
  4784.         case ITEM_TYPE_TRASHHOLDER:
  4785.             found = tile->hasFlag(TILESTATE_TRASHHOLDER);
  4786.             break;
  4787.         case ITEM_TYPE_BED:
  4788.             found = tile->hasFlag(TILESTATE_BED);
  4789.             break;
  4790.         case ITEM_TYPE_DEPOT:
  4791.             found = tile->hasFlag(TILESTATE_DEPOT);
  4792.             break;
  4793.         default:
  4794.             found = true;
  4795.             break;
  4796.     }
  4797.  
  4798.     if (!found) {
  4799.         lua_pushnil(L);
  4800.         return 1;
  4801.     }
  4802.  
  4803.     if (Item* item = tile->getGround()) {
  4804.         const ItemType& it = Item::items[item->getID()];
  4805.         if (it.type == itemType) {
  4806.             pushUserdata<Item>(L, item);
  4807.             setItemMetatable(L, -1, item);
  4808.             return 1;
  4809.         }
  4810.     }
  4811.  
  4812.     if (const TileItemVector* items = tile->getItemList()) {
  4813.         for (Item* item : *items) {
  4814.             const ItemType& it = Item::items[item->getID()];
  4815.             if (it.type == itemType) {
  4816.                 pushUserdata<Item>(L, item);
  4817.                 setItemMetatable(L, -1, item);
  4818.                 return 1;
  4819.             }
  4820.         }
  4821.     }
  4822.  
  4823.     lua_pushnil(L);
  4824.     return 1;
  4825. }
  4826.  
  4827. int LuaScriptInterface::luaTileGetItemByTopOrder(lua_State* L)
  4828. {
  4829.     // tile:getItemByTopOrder(topOrder)
  4830.     Tile* tile = getUserdata<Tile>(L, 1);
  4831.     if (!tile) {
  4832.         lua_pushnil(L);
  4833.         return 1;
  4834.     }
  4835.  
  4836.     int32_t topOrder = getNumber<int32_t>(L, 2);
  4837.  
  4838.     Item* item = tile->getItemByTopOrder(topOrder);
  4839.     if (!item) {
  4840.         lua_pushnil(L);
  4841.         return 1;
  4842.     }
  4843.  
  4844.     pushUserdata<Item>(L, item);
  4845.     setItemMetatable(L, -1, item);
  4846.     return 1;
  4847. }
  4848.  
  4849. int LuaScriptInterface::luaTileGetItemCountById(lua_State* L)
  4850. {
  4851.     // tile:getItemCountById(itemId[, subType = -1])
  4852.     Tile* tile = getUserdata<Tile>(L, 1);
  4853.     if (!tile) {
  4854.         lua_pushnil(L);
  4855.         return 1;
  4856.     }
  4857.  
  4858.     int32_t subType = getNumber<int32_t>(L, 3, -1);
  4859.  
  4860.     uint16_t itemId;
  4861.     if (isNumber(L, 2)) {
  4862.         itemId = getNumber<uint16_t>(L, 2);
  4863.     } else {
  4864.         itemId = Item::items.getItemIdByName(getString(L, 2));
  4865.         if (itemId == 0) {
  4866.             lua_pushnil(L);
  4867.             return 1;
  4868.         }
  4869.     }
  4870.  
  4871.     lua_pushnumber(L, tile->getItemTypeCount(itemId, subType));
  4872.     return 1;
  4873. }
  4874.  
  4875. int LuaScriptInterface::luaTileGetBottomCreature(lua_State* L)
  4876. {
  4877.     // tile:getBottomCreature()
  4878.     Tile* tile = getUserdata<Tile>(L, 1);
  4879.     if (!tile) {
  4880.         lua_pushnil(L);
  4881.         return 1;
  4882.     }
  4883.  
  4884.     const Creature* creature = tile->getBottomCreature();
  4885.     if (!creature) {
  4886.         lua_pushnil(L);
  4887.         return 1;
  4888.     }
  4889.  
  4890.     pushUserdata<const Creature>(L, creature);
  4891.     setCreatureMetatable(L, -1, creature);
  4892.     return 1;
  4893. }
  4894.  
  4895. int LuaScriptInterface::luaTileGetTopCreature(lua_State* L)
  4896. {
  4897.     // tile:getTopCreature()
  4898.     Tile* tile = getUserdata<Tile>(L, 1);
  4899.     if (!tile) {
  4900.         lua_pushnil(L);
  4901.         return 1;
  4902.     }
  4903.  
  4904.     Creature* creature = tile->getTopCreature();
  4905.     if (!creature) {
  4906.         lua_pushnil(L);
  4907.         return 1;
  4908.     }
  4909.  
  4910.     pushUserdata<Creature>(L, creature);
  4911.     setCreatureMetatable(L, -1, creature);
  4912.     return 1;
  4913. }
  4914.  
  4915. int LuaScriptInterface::luaTileGetBottomVisibleCreature(lua_State* L)
  4916. {
  4917.     // tile:getBottomVisibleCreature(creature)
  4918.     Tile* tile = getUserdata<Tile>(L, 1);
  4919.     if (!tile) {
  4920.         lua_pushnil(L);
  4921.         return 1;
  4922.     }
  4923.  
  4924.     Creature* creature = getCreature(L, 2);
  4925.     if (!creature) {
  4926.         lua_pushnil(L);
  4927.         return 1;
  4928.     }
  4929.  
  4930.     const Creature* visibleCreature = tile->getBottomVisibleCreature(creature);
  4931.     if (visibleCreature) {
  4932.         pushUserdata<const Creature>(L, visibleCreature);
  4933.         setCreatureMetatable(L, -1, visibleCreature);
  4934.     } else {
  4935.         lua_pushnil(L);
  4936.     }
  4937.     return 1;
  4938. }
  4939.  
  4940. int LuaScriptInterface::luaTileGetTopVisibleCreature(lua_State* L)
  4941. {
  4942.     // tile:getTopVisibleCreature(creature)
  4943.     Tile* tile = getUserdata<Tile>(L, 1);
  4944.     if (!tile) {
  4945.         lua_pushnil(L);
  4946.         return 1;
  4947.     }
  4948.  
  4949.     Creature* creature = getCreature(L, 2);
  4950.     if (!creature) {
  4951.         lua_pushnil(L);
  4952.         return 1;
  4953.     }
  4954.  
  4955.     Creature* visibleCreature = tile->getTopVisibleCreature(creature);
  4956.     if (visibleCreature) {
  4957.         pushUserdata<Creature>(L, visibleCreature);
  4958.         setCreatureMetatable(L, -1, visibleCreature);
  4959.     } else {
  4960.         lua_pushnil(L);
  4961.     }
  4962.     return 1;
  4963. }
  4964.  
  4965. int LuaScriptInterface::luaTileGetItems(lua_State* L)
  4966. {
  4967.     // tile:getItems()
  4968.     Tile* tile = getUserdata<Tile>(L, 1);
  4969.     if (!tile) {
  4970.         lua_pushnil(L);
  4971.         return 1;
  4972.     }
  4973.  
  4974.     TileItemVector* itemVector = tile->getItemList();
  4975.     if (!itemVector) {
  4976.         lua_pushnil(L);
  4977.         return 1;
  4978.     }
  4979.  
  4980.     lua_createtable(L, itemVector->size(), 0);
  4981.  
  4982.     int index = 0;
  4983.     for (Item* item : *itemVector) {
  4984.         pushUserdata<Item>(L, item);
  4985.         setItemMetatable(L, -1, item);
  4986.         lua_rawseti(L, -2, ++index);
  4987.     }
  4988.     return 1;
  4989. }
  4990.  
  4991. int LuaScriptInterface::luaTileGetItemCount(lua_State* L)
  4992. {
  4993.     // tile:getItemCount()
  4994.     Tile* tile = getUserdata<Tile>(L, 1);
  4995.     if (!tile) {
  4996.         lua_pushnil(L);
  4997.         return 1;
  4998.     }
  4999.  
  5000.     lua_pushnumber(L, tile->getItemCount());
  5001.     return 1;
  5002. }
  5003.  
  5004. int LuaScriptInterface::luaTileGetDownItemCount(lua_State* L)
  5005. {
  5006.     // tile:getDownItemCount()
  5007.     Tile* tile = getUserdata<Tile>(L, 1);
  5008.     if (tile) {
  5009.         lua_pushnumber(L, tile->getDownItemCount());
  5010.     } else {
  5011.         lua_pushnil(L);
  5012.     }
  5013.     return 1;
  5014. }
  5015.  
  5016. int LuaScriptInterface::luaTileGetTopItemCount(lua_State* L)
  5017. {
  5018.     // tile:getTopItemCount()
  5019.     Tile* tile = getUserdata<Tile>(L, 1);
  5020.     if (!tile) {
  5021.         lua_pushnil(L);
  5022.         return 1;
  5023.     }
  5024.  
  5025.     lua_pushnumber(L, tile->getTopItemCount());
  5026.     return 1;
  5027. }
  5028.  
  5029. int LuaScriptInterface::luaTileGetCreatures(lua_State* L)
  5030. {
  5031.     // tile:getCreatures()
  5032.     Tile* tile = getUserdata<Tile>(L, 1);
  5033.     if (!tile) {
  5034.         lua_pushnil(L);
  5035.         return 1;
  5036.     }
  5037.  
  5038.     CreatureVector* creatureVector = tile->getCreatures();
  5039.     if (!creatureVector) {
  5040.         lua_pushnil(L);
  5041.         return 1;
  5042.     }
  5043.  
  5044.     lua_createtable(L, creatureVector->size(), 0);
  5045.  
  5046.     int index = 0;
  5047.     for (Creature* creature : *creatureVector) {
  5048.         pushUserdata<Creature>(L, creature);
  5049.         setCreatureMetatable(L, -1, creature);
  5050.         lua_rawseti(L, -2, ++index);
  5051.     }
  5052.     return 1;
  5053. }
  5054.  
  5055. int LuaScriptInterface::luaTileGetCreatureCount(lua_State* L)
  5056. {
  5057.     // tile:getCreatureCount()
  5058.     Tile* tile = getUserdata<Tile>(L, 1);
  5059.     if (!tile) {
  5060.         lua_pushnil(L);
  5061.         return 1;
  5062.     }
  5063.  
  5064.     lua_pushnumber(L, tile->getCreatureCount());
  5065.     return 1;
  5066. }
  5067.  
  5068. int LuaScriptInterface::luaTileHasProperty(lua_State* L)
  5069. {
  5070.     // tile:hasProperty(property[, item])
  5071.     Tile* tile = getUserdata<Tile>(L, 1);
  5072.     if (!tile) {
  5073.         lua_pushnil(L);
  5074.         return 1;
  5075.     }
  5076.  
  5077.     Item* item;
  5078.     if (lua_gettop(L) >= 3) {
  5079.         item = getUserdata<Item>(L, 3);
  5080.     } else {
  5081.         item = nullptr;
  5082.     }
  5083.  
  5084.     ITEMPROPERTY property = getNumber<ITEMPROPERTY>(L, 2);
  5085.     if (item) {
  5086.         pushBoolean(L, tile->hasProperty(item, property));
  5087.     } else {
  5088.         pushBoolean(L, tile->hasProperty(property));
  5089.     }
  5090.     return 1;
  5091. }
  5092.  
  5093. int LuaScriptInterface::luaTileGetThingIndex(lua_State* L)
  5094. {
  5095.     // tile:getThingIndex(thing)
  5096.     Tile* tile = getUserdata<Tile>(L, 1);
  5097.     if (!tile) {
  5098.         lua_pushnil(L);
  5099.         return 1;
  5100.     }
  5101.  
  5102.     Thing* thing = getThing(L, 2);
  5103.     if (thing) {
  5104.         lua_pushnumber(L, tile->getThingIndex(thing));
  5105.     } else {
  5106.         lua_pushnil(L);
  5107.     }
  5108.     return 1;
  5109. }
  5110.  
  5111. int LuaScriptInterface::luaTileHasFlag(lua_State* L)
  5112. {
  5113.     // tile:hasFlag(flag)
  5114.     Tile* tile = getUserdata<Tile>(L, 1);
  5115.     if (tile) {
  5116.         tileflags_t flag = getNumber<tileflags_t>(L, 2);
  5117.         pushBoolean(L, tile->hasFlag(flag));
  5118.     } else {
  5119.         lua_pushnil(L);
  5120.     }
  5121.     return 1;
  5122. }
  5123.  
  5124. int LuaScriptInterface::luaTileQueryAdd(lua_State* L)
  5125. {
  5126.     // tile:queryAdd(thing[, flags])
  5127.     Tile* tile = getUserdata<Tile>(L, 1);
  5128.     if (!tile) {
  5129.         lua_pushnil(L);
  5130.         return 1;
  5131.     }
  5132.  
  5133.     Thing* thing = getThing(L, 2);
  5134.     if (thing) {
  5135.         uint32_t flags = getNumber<uint32_t>(L, 3, 0);
  5136.         lua_pushnumber(L, tile->queryAdd(0, *thing, 1, flags));
  5137.     } else {
  5138.         lua_pushnil(L);
  5139.     }
  5140.     return 1;
  5141. }
  5142.  
  5143. int LuaScriptInterface::luaTileGetHouse(lua_State* L)
  5144. {
  5145.     // tile:getHouse()
  5146.     Tile* tile = getUserdata<Tile>(L, 1);
  5147.     if (!tile) {
  5148.         lua_pushnil(L);
  5149.         return 1;
  5150.     }
  5151.  
  5152.     if (HouseTile* houseTile = dynamic_cast<HouseTile*>(tile)) {
  5153.         pushUserdata<House>(L, houseTile->getHouse());
  5154.         setMetatable(L, -1, "House");
  5155.     } else {
  5156.         lua_pushnil(L);
  5157.     }
  5158.     return 1;
  5159. }
  5160.  
  5161. // NetworkMessage
  5162. int LuaScriptInterface::luaNetworkMessageCreate(lua_State* L)
  5163. {
  5164.     // NetworkMessage()
  5165.     pushUserdata<NetworkMessage>(L, new NetworkMessage);
  5166.     setMetatable(L, -1, "NetworkMessage");
  5167.     return 1;
  5168. }
  5169.  
  5170. int LuaScriptInterface::luaNetworkMessageDelete(lua_State* L)
  5171. {
  5172.     NetworkMessage** messagePtr = getRawUserdata<NetworkMessage>(L, 1);
  5173.     if (messagePtr && *messagePtr) {
  5174.         delete *messagePtr;
  5175.         *messagePtr = nullptr;
  5176.     }
  5177.     return 0;
  5178. }
  5179.  
  5180. int LuaScriptInterface::luaNetworkMessageGetByte(lua_State* L)
  5181. {
  5182.     // networkMessage:getByte()
  5183.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5184.     if (message) {
  5185.         lua_pushnumber(L, message->getByte());
  5186.     } else {
  5187.         lua_pushnil(L);
  5188.     }
  5189.     return 1;
  5190. }
  5191.  
  5192. int LuaScriptInterface::luaNetworkMessageGetU16(lua_State* L)
  5193. {
  5194.     // networkMessage:getU16()
  5195.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5196.     if (message) {
  5197.         lua_pushnumber(L, message->get<uint16_t>());
  5198.     } else {
  5199.         lua_pushnil(L);
  5200.     }
  5201.     return 1;
  5202. }
  5203.  
  5204. int LuaScriptInterface::luaNetworkMessageGetU32(lua_State* L)
  5205. {
  5206.     // networkMessage:getU32()
  5207.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5208.     if (message) {
  5209.         lua_pushnumber(L, message->get<uint32_t>());
  5210.     } else {
  5211.         lua_pushnil(L);
  5212.     }
  5213.     return 1;
  5214. }
  5215.  
  5216. int LuaScriptInterface::luaNetworkMessageGetU64(lua_State* L)
  5217. {
  5218.     // networkMessage:getU64()
  5219.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5220.     if (message) {
  5221.         lua_pushnumber(L, message->get<uint64_t>());
  5222.     } else {
  5223.         lua_pushnil(L);
  5224.     }
  5225.     return 1;
  5226. }
  5227.  
  5228. int LuaScriptInterface::luaNetworkMessageGetString(lua_State* L)
  5229. {
  5230.     // networkMessage:getString()
  5231.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5232.     if (message) {
  5233.         pushString(L, message->getString());
  5234.     } else {
  5235.         lua_pushnil(L);
  5236.     }
  5237.     return 1;
  5238. }
  5239.  
  5240. int LuaScriptInterface::luaNetworkMessageGetPosition(lua_State* L)
  5241. {
  5242.     // networkMessage:getPosition()
  5243.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5244.     if (message) {
  5245.         pushPosition(L, message->getPosition());
  5246.     } else {
  5247.         lua_pushnil(L);
  5248.     }
  5249.     return 1;
  5250. }
  5251.  
  5252. int LuaScriptInterface::luaNetworkMessageAddByte(lua_State* L)
  5253. {
  5254.     // networkMessage:addByte(number)
  5255.     uint8_t number = getNumber<uint8_t>(L, 2);
  5256.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5257.     if (message) {
  5258.         message->addByte(number);
  5259.         pushBoolean(L, true);
  5260.     } else {
  5261.         lua_pushnil(L);
  5262.     }
  5263.     return 1;
  5264. }
  5265.  
  5266. int LuaScriptInterface::luaNetworkMessageAddU16(lua_State* L)
  5267. {
  5268.     // networkMessage:addU16(number)
  5269.     uint16_t number = getNumber<uint16_t>(L, 2);
  5270.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5271.     if (message) {
  5272.         message->add<uint16_t>(number);
  5273.         pushBoolean(L, true);
  5274.     } else {
  5275.         lua_pushnil(L);
  5276.     }
  5277.     return 1;
  5278. }
  5279.  
  5280. int LuaScriptInterface::luaNetworkMessageAddU32(lua_State* L)
  5281. {
  5282.     // networkMessage:addU32(number)
  5283.     uint32_t number = getNumber<uint32_t>(L, 2);
  5284.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5285.     if (message) {
  5286.         message->add<uint32_t>(number);
  5287.         pushBoolean(L, true);
  5288.     } else {
  5289.         lua_pushnil(L);
  5290.     }
  5291.     return 1;
  5292. }
  5293.  
  5294. int LuaScriptInterface::luaNetworkMessageAddU64(lua_State* L)
  5295. {
  5296.     // networkMessage:addU64(number)
  5297.     uint64_t number = getNumber<uint64_t>(L, 2);
  5298.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5299.     if (message) {
  5300.         message->add<uint64_t>(number);
  5301.         pushBoolean(L, true);
  5302.     } else {
  5303.         lua_pushnil(L);
  5304.     }
  5305.     return 1;
  5306. }
  5307.  
  5308. int LuaScriptInterface::luaNetworkMessageAddString(lua_State* L)
  5309. {
  5310.     // networkMessage:addString(string)
  5311.     const std::string& string = getString(L, 2);
  5312.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5313.     if (message) {
  5314.         message->addString(string);
  5315.         pushBoolean(L, true);
  5316.     } else {
  5317.         lua_pushnil(L);
  5318.     }
  5319.     return 1;
  5320. }
  5321.  
  5322. int LuaScriptInterface::luaNetworkMessageAddPosition(lua_State* L)
  5323. {
  5324.     // networkMessage:addPosition(position)
  5325.     const Position& position = getPosition(L, 2);
  5326.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5327.     if (message) {
  5328.         message->addPosition(position);
  5329.         pushBoolean(L, true);
  5330.     } else {
  5331.         lua_pushnil(L);
  5332.     }
  5333.     return 1;
  5334. }
  5335.  
  5336. int LuaScriptInterface::luaNetworkMessageAddDouble(lua_State* L)
  5337. {
  5338.     // networkMessage:addDouble(number)
  5339.     double number = getNumber<double>(L, 2);
  5340.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5341.     if (message) {
  5342.         message->addDouble(number);
  5343.         pushBoolean(L, true);
  5344.     } else {
  5345.         lua_pushnil(L);
  5346.     }
  5347.     return 1;
  5348. }
  5349.  
  5350. int LuaScriptInterface::luaNetworkMessageAddItem(lua_State* L)
  5351. {
  5352.     // networkMessage:addItem(item)
  5353.     Item* item = getUserdata<Item>(L, 2);
  5354.     if (!item) {
  5355.         reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  5356.         lua_pushnil(L);
  5357.         return 1;
  5358.     }
  5359.  
  5360.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5361.     if (message) {
  5362.         message->addItem(item);
  5363.         pushBoolean(L, true);
  5364.     } else {
  5365.         lua_pushnil(L);
  5366.     }
  5367.     return 1;
  5368. }
  5369.  
  5370. int LuaScriptInterface::luaNetworkMessageAddItemId(lua_State* L)
  5371. {
  5372.     // networkMessage:addItemId(itemId)
  5373.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5374.     if (!message) {
  5375.         lua_pushnil(L);
  5376.         return 1;
  5377.     }
  5378.  
  5379.     uint16_t itemId;
  5380.     if (isNumber(L, 2)) {
  5381.         itemId = getNumber<uint16_t>(L, 2);
  5382.     } else {
  5383.         itemId = Item::items.getItemIdByName(getString(L, 2));
  5384.         if (itemId == 0) {
  5385.             lua_pushnil(L);
  5386.             return 1;
  5387.         }
  5388.     }
  5389.  
  5390.     message->addItemId(itemId);
  5391.     pushBoolean(L, true);
  5392.     return 1;
  5393. }
  5394.  
  5395. int LuaScriptInterface::luaNetworkMessageReset(lua_State* L)
  5396. {
  5397.     // networkMessage:reset()
  5398.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5399.     if (message) {
  5400.         message->reset();
  5401.         pushBoolean(L, true);
  5402.     } else {
  5403.         lua_pushnil(L);
  5404.     }
  5405.     return 1;
  5406. }
  5407.  
  5408. int LuaScriptInterface::luaNetworkMessageSkipBytes(lua_State* L)
  5409. {
  5410.     // networkMessage:skipBytes(number)
  5411.     int16_t number = getNumber<int16_t>(L, 2);
  5412.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5413.     if (message) {
  5414.         message->skipBytes(number);
  5415.         pushBoolean(L, true);
  5416.     } else {
  5417.         lua_pushnil(L);
  5418.     }
  5419.     return 1;
  5420. }
  5421.  
  5422. int LuaScriptInterface::luaNetworkMessageSendToPlayer(lua_State* L)
  5423. {
  5424.     // networkMessage:sendToPlayer(player)
  5425.     NetworkMessage* message = getUserdata<NetworkMessage>(L, 1);
  5426.     if (!message) {
  5427.         lua_pushnil(L);
  5428.         return 1;
  5429.     }
  5430.  
  5431.     Player* player = getPlayer(L, 2);
  5432.     if (player) {
  5433.         player->sendNetworkMessage(*message);
  5434.         pushBoolean(L, true);
  5435.     } else {
  5436.         reportErrorFunc(getErrorDesc(LUA_ERROR_PLAYER_NOT_FOUND));
  5437.         lua_pushnil(L);
  5438.     }
  5439.     return 1;
  5440. }
  5441.  
  5442. // Item
  5443. int LuaScriptInterface::luaItemCreate(lua_State* L)
  5444. {
  5445.     // Item(uid)
  5446.     uint32_t id = getNumber<uint32_t>(L, 2);
  5447.  
  5448.     Item* item = getScriptEnv()->getItemByUID(id);
  5449.     if (item) {
  5450.         pushUserdata<Item>(L, item);
  5451.         setItemMetatable(L, -1, item);
  5452.     } else {
  5453.         lua_pushnil(L);
  5454.     }
  5455.     return 1;
  5456. }
  5457.  
  5458. int LuaScriptInterface::luaItemIsItem(lua_State* L)
  5459. {
  5460.     // item:isItem()
  5461.     pushBoolean(L, getUserdata<const Item>(L, 1) != nullptr);
  5462.     return 1;
  5463. }
  5464.  
  5465. int LuaScriptInterface::luaItemGetParent(lua_State* L)
  5466. {
  5467.     // item:getParent()
  5468.     Item* item = getUserdata<Item>(L, 1);
  5469.     if (!item) {
  5470.         lua_pushnil(L);
  5471.         return 1;
  5472.     }
  5473.  
  5474.     Cylinder* parent = item->getParent();
  5475.     if (!parent) {
  5476.         lua_pushnil(L);
  5477.         return 1;
  5478.     }
  5479.  
  5480.     pushCylinder(L, parent);
  5481.     return 1;
  5482. }
  5483.  
  5484. int LuaScriptInterface::luaItemGetTopParent(lua_State* L)
  5485. {
  5486.     // item:getTopParent()
  5487.     Item* item = getUserdata<Item>(L, 1);
  5488.     if (!item) {
  5489.         lua_pushnil(L);
  5490.         return 1;
  5491.     }
  5492.  
  5493.     Cylinder* topParent = item->getTopParent();
  5494.     if (!topParent) {
  5495.         lua_pushnil(L);
  5496.         return 1;
  5497.     }
  5498.  
  5499.     pushCylinder(L, topParent);
  5500.     return 1;
  5501. }
  5502.  
  5503. int LuaScriptInterface::luaItemGetId(lua_State* L)
  5504. {
  5505.     // item:getId()
  5506.     Item* item = getUserdata<Item>(L, 1);
  5507.     if (item) {
  5508.         lua_pushnumber(L, item->getID());
  5509.     } else {
  5510.         lua_pushnil(L);
  5511.     }
  5512.     return 1;
  5513. }
  5514.  
  5515. int LuaScriptInterface::luaItemClone(lua_State* L)
  5516. {
  5517.     // item:clone()
  5518.     Item* item = getUserdata<Item>(L, 1);
  5519.     if (!item) {
  5520.         lua_pushnil(L);
  5521.         return 1;
  5522.     }
  5523.  
  5524.     Item* clone = item->clone();
  5525.     if (!clone) {
  5526.         lua_pushnil(L);
  5527.         return 1;
  5528.     }
  5529.  
  5530.     getScriptEnv()->addTempItem(clone);
  5531.     clone->setParent(VirtualCylinder::virtualCylinder);
  5532.  
  5533.     pushUserdata<Item>(L, clone);
  5534.     setItemMetatable(L, -1, clone);
  5535.     return 1;
  5536. }
  5537.  
  5538. int LuaScriptInterface::luaItemSplit(lua_State* L)
  5539. {
  5540.     // item:split([count = 1])
  5541.     Item** itemPtr = getRawUserdata<Item>(L, 1);
  5542.     if (!itemPtr) {
  5543.         lua_pushnil(L);
  5544.         return 1;
  5545.     }
  5546.  
  5547.     Item* item = *itemPtr;
  5548.     if (!item || !item->isStackable()) {
  5549.         lua_pushnil(L);
  5550.         return 1;
  5551.     }
  5552.  
  5553.     uint16_t count = std::min<uint16_t>(getNumber<uint16_t>(L, 2, 1), item->getItemCount());
  5554.     uint16_t diff = item->getItemCount() - count;
  5555.  
  5556.     Item* splitItem = item->clone();
  5557.     if (!splitItem) {
  5558.         lua_pushnil(L);
  5559.         return 1;
  5560.     }
  5561.  
  5562.     ScriptEnvironment* env = getScriptEnv();
  5563.     uint32_t uid = env->addThing(item);
  5564.  
  5565.     Item* newItem = g_game.transformItem(item, item->getID(), diff);
  5566.     if (item->isRemoved()) {
  5567.         env->removeItemByUID(uid);
  5568.     }
  5569.  
  5570.     if (newItem && newItem != item) {
  5571.         env->insertItem(uid, newItem);
  5572.     }
  5573.  
  5574.     *itemPtr = newItem;
  5575.  
  5576.     splitItem->setParent(VirtualCylinder::virtualCylinder);
  5577.     env->addTempItem(splitItem);
  5578.  
  5579.     pushUserdata<Item>(L, splitItem);
  5580.     setItemMetatable(L, -1, splitItem);
  5581.     return 1;
  5582. }
  5583.  
  5584. int LuaScriptInterface::luaItemRemove(lua_State* L)
  5585. {
  5586.     // item:remove([count = -1])
  5587.     Item* item = getUserdata<Item>(L, 1);
  5588.     if (item) {
  5589.         int32_t count = getNumber<int32_t>(L, 2, -1);
  5590.         pushBoolean(L, g_game.internalRemoveItem(item, count) == RETURNVALUE_NOERROR);
  5591.     } else {
  5592.         lua_pushnil(L);
  5593.     }
  5594.     return 1;
  5595. }
  5596.  
  5597. int LuaScriptInterface::luaItemGetUniqueId(lua_State* L)
  5598. {
  5599.     // item:getUniqueId()
  5600.     Item* item = getUserdata<Item>(L, 1);
  5601.     if (item) {
  5602.         uint32_t uniqueId = item->getUniqueId();
  5603.         if (uniqueId == 0) {
  5604.             uniqueId = getScriptEnv()->addThing(item);
  5605.         }
  5606.         lua_pushnumber(L, uniqueId);
  5607.     } else {
  5608.         lua_pushnil(L);
  5609.     }
  5610.     return 1;
  5611. }
  5612.  
  5613. int LuaScriptInterface::luaItemGetActionId(lua_State* L)
  5614. {
  5615.     // item:getActionId()
  5616.     Item* item = getUserdata<Item>(L, 1);
  5617.     if (item) {
  5618.         lua_pushnumber(L, item->getActionId());
  5619.     } else {
  5620.         lua_pushnil(L);
  5621.     }
  5622.     return 1;
  5623. }
  5624.  
  5625. int LuaScriptInterface::luaItemSetActionId(lua_State* L)
  5626. {
  5627.     // item:setActionId(actionId)
  5628.     uint16_t actionId = getNumber<uint16_t>(L, 2);
  5629.     Item* item = getUserdata<Item>(L, 1);
  5630.     if (item) {
  5631.         item->setActionId(actionId);
  5632.         pushBoolean(L, true);
  5633.     } else {
  5634.         lua_pushnil(L);
  5635.     }
  5636.     return 1;
  5637. }
  5638.  
  5639. int LuaScriptInterface::luaItemGetCount(lua_State* L)
  5640. {
  5641.     // item:getCount()
  5642.     Item* item = getUserdata<Item>(L, 1);
  5643.     if (item) {
  5644.         lua_pushnumber(L, item->getItemCount());
  5645.     } else {
  5646.         lua_pushnil(L);
  5647.     }
  5648.     return 1;
  5649. }
  5650.  
  5651. int LuaScriptInterface::luaItemGetCharges(lua_State* L)
  5652. {
  5653.     // item:getCharges()
  5654.     Item* item = getUserdata<Item>(L, 1);
  5655.     if (item) {
  5656.         lua_pushnumber(L, item->getCharges());
  5657.     } else {
  5658.         lua_pushnil(L);
  5659.     }
  5660.     return 1;
  5661. }
  5662.  
  5663. int LuaScriptInterface::luaItemGetFluidType(lua_State* L)
  5664. {
  5665.     // item:getFluidType()
  5666.     Item* item = getUserdata<Item>(L, 1);
  5667.     if (item) {
  5668.         lua_pushnumber(L, item->getFluidType());
  5669.     } else {
  5670.         lua_pushnil(L);
  5671.     }
  5672.     return 1;
  5673. }
  5674.  
  5675. int LuaScriptInterface::luaItemGetWeight(lua_State* L)
  5676. {
  5677.     // item:getWeight()
  5678.     Item* item = getUserdata<Item>(L, 1);
  5679.     if (item) {
  5680.         lua_pushnumber(L, item->getWeight());
  5681.     } else {
  5682.         lua_pushnil(L);
  5683.     }
  5684.     return 1;
  5685. }
  5686.  
  5687. int LuaScriptInterface::luaItemGetSubType(lua_State* L)
  5688. {
  5689.     // item:getSubType()
  5690.     Item* item = getUserdata<Item>(L, 1);
  5691.     if (item) {
  5692.         lua_pushnumber(L, item->getSubType());
  5693.     } else {
  5694.         lua_pushnil(L);
  5695.     }
  5696.     return 1;
  5697. }
  5698.  
  5699. int LuaScriptInterface::luaItemGetName(lua_State* L)
  5700. {
  5701.     // item:getName()
  5702.     Item* item = getUserdata<Item>(L, 1);
  5703.     if (item) {
  5704.         pushString(L, item->getName());
  5705.     } else {
  5706.         lua_pushnil(L);
  5707.     }
  5708.     return 1;
  5709. }
  5710.  
  5711. int LuaScriptInterface::luaItemGetPluralName(lua_State* L)
  5712. {
  5713.     // item:getPluralName()
  5714.     Item* item = getUserdata<Item>(L, 1);
  5715.     if (item) {
  5716.         pushString(L, item->getPluralName());
  5717.     } else {
  5718.         lua_pushnil(L);
  5719.     }
  5720.     return 1;
  5721. }
  5722.  
  5723. int LuaScriptInterface::luaItemGetArticle(lua_State* L)
  5724. {
  5725.     // item:getArticle()
  5726.     Item* item = getUserdata<Item>(L, 1);
  5727.     if (item) {
  5728.         pushString(L, item->getArticle());
  5729.     } else {
  5730.         lua_pushnil(L);
  5731.     }
  5732.     return 1;
  5733. }
  5734.  
  5735. int LuaScriptInterface::luaItemGetPosition(lua_State* L)
  5736. {
  5737.     // item:getPosition()
  5738.     Item* item = getUserdata<Item>(L, 1);
  5739.     if (item) {
  5740.         pushPosition(L, item->getPosition());
  5741.     } else {
  5742.         lua_pushnil(L);
  5743.     }
  5744.     return 1;
  5745. }
  5746.  
  5747. int LuaScriptInterface::luaItemGetTile(lua_State* L)
  5748. {
  5749.     // item:getTile()
  5750.     Item* item = getUserdata<Item>(L, 1);
  5751.     if (!item) {
  5752.         lua_pushnil(L);
  5753.         return 1;
  5754.     }
  5755.  
  5756.     Tile* tile = item->getTile();
  5757.     if (tile) {
  5758.         pushUserdata<Tile>(L, tile);
  5759.         setMetatable(L, -1, "Tile");
  5760.     } else {
  5761.         lua_pushnil(L);
  5762.     }
  5763.     return 1;
  5764. }
  5765.  
  5766. int LuaScriptInterface::luaItemHasAttribute(lua_State* L)
  5767. {
  5768.     // item:hasAttribute(key)
  5769.     Item* item = getUserdata<Item>(L, 1);
  5770.     if (!item) {
  5771.         lua_pushnil(L);
  5772.         return 1;
  5773.     }
  5774.  
  5775.     itemAttrTypes attribute;
  5776.     if (isNumber(L, 2)) {
  5777.         attribute = getNumber<itemAttrTypes>(L, 2);
  5778.     } else if (isString(L, 2)) {
  5779.         attribute = stringToItemAttribute(getString(L, 2));
  5780.     } else {
  5781.         attribute = ITEM_ATTRIBUTE_NONE;
  5782.     }
  5783.  
  5784.     pushBoolean(L, item->hasAttribute(attribute));
  5785.     return 1;
  5786. }
  5787.  
  5788. int LuaScriptInterface::luaItemGetAttribute(lua_State* L)
  5789. {
  5790.     // item:getAttribute(key)
  5791.     Item* item = getUserdata<Item>(L, 1);
  5792.     if (!item) {
  5793.         lua_pushnil(L);
  5794.         return 1;
  5795.     }
  5796.  
  5797.     itemAttrTypes attribute;
  5798.     if (isNumber(L, 2)) {
  5799.         attribute = getNumber<itemAttrTypes>(L, 2);
  5800.     } else if (isString(L, 2)) {
  5801.         attribute = stringToItemAttribute(getString(L, 2));
  5802.     } else {
  5803.         attribute = ITEM_ATTRIBUTE_NONE;
  5804.     }
  5805.  
  5806.     if (ItemAttributes::isIntAttrType(attribute)) {
  5807.         lua_pushnumber(L, item->getIntAttr(attribute));
  5808.     } else if (ItemAttributes::isStrAttrType(attribute)) {
  5809.         pushString(L, item->getStrAttr(attribute));
  5810.     } else {
  5811.         lua_pushnil(L);
  5812.     }
  5813.     return 1;
  5814. }
  5815.  
  5816. int LuaScriptInterface::luaItemSetAttribute(lua_State* L)
  5817. {
  5818.     // item:setAttribute(key, value)
  5819.     Item* item = getUserdata<Item>(L, 1);
  5820.     if (!item) {
  5821.         lua_pushnil(L);
  5822.         return 1;
  5823.     }
  5824.  
  5825.     itemAttrTypes attribute;
  5826.     if (isNumber(L, 2)) {
  5827.         attribute = getNumber<itemAttrTypes>(L, 2);
  5828.     } else if (isString(L, 2)) {
  5829.         attribute = stringToItemAttribute(getString(L, 2));
  5830.     } else {
  5831.         attribute = ITEM_ATTRIBUTE_NONE;
  5832.     }
  5833.  
  5834.     if (ItemAttributes::isIntAttrType(attribute)) {
  5835.         if (attribute == ITEM_ATTRIBUTE_UNIQUEID) {
  5836.             reportErrorFunc("Attempt to set protected key \"uid\"");
  5837.             pushBoolean(L, false);
  5838.             return 1;
  5839.         }
  5840.  
  5841.         item->setIntAttr(attribute, getNumber<int32_t>(L, 3));
  5842.         pushBoolean(L, true);
  5843.     } else if (ItemAttributes::isStrAttrType(attribute)) {
  5844.         item->setStrAttr(attribute, getString(L, 3));
  5845.         pushBoolean(L, true);
  5846.     } else {
  5847.         lua_pushnil(L);
  5848.     }
  5849.     return 1;
  5850. }
  5851.  
  5852. int LuaScriptInterface::luaItemRemoveAttribute(lua_State* L)
  5853. {
  5854.     // item:removeAttribute(key)
  5855.     Item* item = getUserdata<Item>(L, 1);
  5856.     if (!item) {
  5857.         lua_pushnil(L);
  5858.         return 1;
  5859.     }
  5860.  
  5861.     itemAttrTypes attribute;
  5862.     if (isNumber(L, 2)) {
  5863.         attribute = getNumber<itemAttrTypes>(L, 2);
  5864.     } else if (isString(L, 2)) {
  5865.         attribute = stringToItemAttribute(getString(L, 2));
  5866.     } else {
  5867.         attribute = ITEM_ATTRIBUTE_NONE;
  5868.     }
  5869.  
  5870.     bool ret = attribute != ITEM_ATTRIBUTE_UNIQUEID;
  5871.     if (ret) {
  5872.         item->removeAttribute(attribute);
  5873.     } else {
  5874.         reportErrorFunc("Attempt to erase protected key \"uid\"");
  5875.     }
  5876.     pushBoolean(L, ret);
  5877.     return 1;
  5878. }
  5879.  
  5880. int LuaScriptInterface::luaItemMoveTo(lua_State* L)
  5881. {
  5882.     // item:moveTo(position or cylinder)
  5883.     Item** itemPtr = getRawUserdata<Item>(L, 1);
  5884.     if (!itemPtr) {
  5885.         lua_pushnil(L);
  5886.         return 1;
  5887.     }
  5888.  
  5889.     Item* item = *itemPtr;
  5890.     if (!item || item->isRemoved()) {
  5891.         lua_pushnil(L);
  5892.         return 1;
  5893.     }
  5894.  
  5895.     Cylinder* toCylinder;
  5896.     if (isUserdata(L, 2)) {
  5897.         const LuaDataType type = getUserdataType(L, 2);
  5898.         switch (type) {
  5899.             case LuaData_Container:
  5900.                 toCylinder = getUserdata<Container>(L, 2);
  5901.                 break;
  5902.             case LuaData_Player:
  5903.                 toCylinder = getUserdata<Player>(L, 2);
  5904.                 break;
  5905.             case LuaData_Tile:
  5906.                 toCylinder = getUserdata<Tile>(L, 2);
  5907.                 break;
  5908.             default:
  5909.                 toCylinder = nullptr;
  5910.                 break;
  5911.         }
  5912.     } else {
  5913.         toCylinder = g_game.map.getTile(getPosition(L, 2));
  5914.     }
  5915.  
  5916.     if (!toCylinder) {
  5917.         lua_pushnil(L);
  5918.         return 1;
  5919.     }
  5920.  
  5921.     if (item->getParent() == toCylinder) {
  5922.         pushBoolean(L, true);
  5923.         return 1;
  5924.     }
  5925.  
  5926.     if (item->getParent() == VirtualCylinder::virtualCylinder) {
  5927.         pushBoolean(L, g_game.internalAddItem(toCylinder, item) == RETURNVALUE_NOERROR);
  5928.     } else {
  5929.         Item* moveItem = nullptr;
  5930.         ReturnValue ret = g_game.internalMoveItem(item->getParent(), toCylinder, INDEX_WHEREEVER, item, item->getItemCount(), &moveItem, FLAG_NOLIMIT | FLAG_IGNOREBLOCKITEM | FLAG_IGNOREBLOCKCREATURE | FLAG_IGNORENOTMOVEABLE);
  5931.         if (moveItem) {
  5932.             *itemPtr = moveItem;
  5933.         }
  5934.         pushBoolean(L, ret == RETURNVALUE_NOERROR);
  5935.     }
  5936.     return 1;
  5937. }
  5938.  
  5939. int LuaScriptInterface::luaItemTransform(lua_State* L)
  5940. {
  5941.     // item:transform(itemId[, count/subType = -1])
  5942.     Item** itemPtr = getRawUserdata<Item>(L, 1);
  5943.     if (!itemPtr) {
  5944.         lua_pushnil(L);
  5945.         return 1;
  5946.     }
  5947.  
  5948.     Item*& item = *itemPtr;
  5949.     if (!item) {
  5950.         lua_pushnil(L);
  5951.         return 1;
  5952.     }
  5953.  
  5954.     uint16_t itemId;
  5955.     if (isNumber(L, 2)) {
  5956.         itemId = getNumber<uint16_t>(L, 2);
  5957.     } else {
  5958.         itemId = Item::items.getItemIdByName(getString(L, 2));
  5959.         if (itemId == 0) {
  5960.             lua_pushnil(L);
  5961.             return 1;
  5962.         }
  5963.     }
  5964.  
  5965.     int32_t subType = getNumber<int32_t>(L, 3, -1);
  5966.     if (item->getID() == itemId && (subType == -1 || subType == item->getSubType())) {
  5967.         pushBoolean(L, true);
  5968.         return 1;
  5969.     }
  5970.  
  5971.     const ItemType& it = Item::items[itemId];
  5972.     if (it.stackable) {
  5973.         subType = std::min<int32_t>(subType, 100);
  5974.     }
  5975.  
  5976.     ScriptEnvironment* env = getScriptEnv();
  5977.     uint32_t uid = env->addThing(item);
  5978.  
  5979.     Item* newItem = g_game.transformItem(item, itemId, subType);
  5980.     if (item->isRemoved()) {
  5981.         env->removeItemByUID(uid);
  5982.     }
  5983.  
  5984.     if (newItem && newItem != item) {
  5985.         env->insertItem(uid, newItem);
  5986.     }
  5987.  
  5988.     item = newItem;
  5989.     pushBoolean(L, true);
  5990.     return 1;
  5991. }
  5992.  
  5993. int LuaScriptInterface::luaItemDecay(lua_State* L)
  5994. {
  5995.     // item:decay()
  5996.     Item* item = getUserdata<Item>(L, 1);
  5997.     if (item) {
  5998.         g_game.startDecay(item);
  5999.         pushBoolean(L, true);
  6000.     } else {
  6001.         lua_pushnil(L);
  6002.     }
  6003.     return 1;
  6004. }
  6005.  
  6006. int LuaScriptInterface::luaItemGetDescription(lua_State* L)
  6007. {
  6008.     // item:getDescription(distance)
  6009.     Item* item = getUserdata<Item>(L, 1);
  6010.     if (item) {
  6011.         int32_t distance = getNumber<int32_t>(L, 2);
  6012.         pushString(L, item->getDescription(distance));
  6013.     } else {
  6014.         lua_pushnil(L);
  6015.     }
  6016.     return 1;
  6017. }
  6018.  
  6019. int LuaScriptInterface::luaItemHasProperty(lua_State* L)
  6020. {
  6021.     // item:hasProperty(property)
  6022.     Item* item = getUserdata<Item>(L, 1);
  6023.     if (item) {
  6024.         ITEMPROPERTY property = getNumber<ITEMPROPERTY>(L, 2);
  6025.         pushBoolean(L, item->hasProperty(property));
  6026.     } else {
  6027.         lua_pushnil(L);
  6028.     }
  6029.     return 1;
  6030. }
  6031.  
  6032. // Container
  6033. int LuaScriptInterface::luaContainerCreate(lua_State* L)
  6034. {
  6035.     // Container(uid)
  6036.     uint32_t id = getNumber<uint32_t>(L, 2);
  6037.  
  6038.     Container* container = getScriptEnv()->getContainerByUID(id);
  6039.     if (container) {
  6040.         pushUserdata(L, container);
  6041.         setMetatable(L, -1, "Container");
  6042.     } else {
  6043.         lua_pushnil(L);
  6044.     }
  6045.     return 1;
  6046. }
  6047.  
  6048. int LuaScriptInterface::luaContainerGetSize(lua_State* L)
  6049. {
  6050.     // container:getSize()
  6051.     Container* container = getUserdata<Container>(L, 1);
  6052.     if (container) {
  6053.         lua_pushnumber(L, container->size());
  6054.     } else {
  6055.         lua_pushnil(L);
  6056.     }
  6057.     return 1;
  6058. }
  6059.  
  6060. int LuaScriptInterface::luaContainerGetCapacity(lua_State* L)
  6061. {
  6062.     // container:getCapacity()
  6063.     Container* container = getUserdata<Container>(L, 1);
  6064.     if (container) {
  6065.         lua_pushnumber(L, container->capacity());
  6066.     } else {
  6067.         lua_pushnil(L);
  6068.     }
  6069.     return 1;
  6070. }
  6071.  
  6072. int LuaScriptInterface::luaContainerGetEmptySlots(lua_State* L)
  6073. {
  6074.     // container:getEmptySlots([recursive = false])
  6075.     Container* container = getUserdata<Container>(L, 1);
  6076.     if (!container) {
  6077.         lua_pushnil(L);
  6078.         return 1;
  6079.     }
  6080.  
  6081.     uint32_t slots = container->capacity() - container->size();
  6082.     bool recursive = getBoolean(L, 2, false);
  6083.     if (recursive) {
  6084.         for (ContainerIterator it = container->iterator(); it.hasNext(); it.advance()) {
  6085.             if (Container* tmpContainer = (*it)->getContainer()) {
  6086.                 slots += tmpContainer->capacity() - tmpContainer->size();
  6087.             }
  6088.         }
  6089.     }
  6090.     lua_pushnumber(L, slots);
  6091.     return 1;
  6092. }
  6093.  
  6094. int LuaScriptInterface::luaContainerGetItemHoldingCount(lua_State* L)
  6095. {
  6096.     // container:getItemHoldingCount()
  6097.     Container* container = getUserdata<Container>(L, 1);
  6098.     if (container) {
  6099.         lua_pushnumber(L, container->getItemHoldingCount());
  6100.     } else {
  6101.         lua_pushnil(L);
  6102.     }
  6103.     return 1;
  6104. }
  6105.  
  6106. int LuaScriptInterface::luaContainerGetItem(lua_State* L)
  6107. {
  6108.     // container:getItem(index)
  6109.     Container* container = getUserdata<Container>(L, 1);
  6110.     if (!container) {
  6111.         lua_pushnil(L);
  6112.         return 1;
  6113.     }
  6114.  
  6115.     uint32_t index = getNumber<uint32_t>(L, 2);
  6116.     Item* item = container->getItemByIndex(index);
  6117.     if (item) {
  6118.         pushUserdata<Item>(L, item);
  6119.         setItemMetatable(L, -1, item);
  6120.     } else {
  6121.         lua_pushnil(L);
  6122.     }
  6123.     return 1;
  6124. }
  6125.  
  6126. int LuaScriptInterface::luaContainerHasItem(lua_State* L)
  6127. {
  6128.     // container:hasItem(item)
  6129.     Item* item = getUserdata<Item>(L, 2);
  6130.     Container* container = getUserdata<Container>(L, 1);
  6131.     if (container) {
  6132.         pushBoolean(L, container->isHoldingItem(item));
  6133.     } else {
  6134.         lua_pushnil(L);
  6135.     }
  6136.     return 1;
  6137. }
  6138.  
  6139. int LuaScriptInterface::luaContainerAddItem(lua_State* L)
  6140. {
  6141.     // container:addItem(itemId[, count/subType = 1[, index = INDEX_WHEREEVER[, flags = 0]]])
  6142.     Container* container = getUserdata<Container>(L, 1);
  6143.     if (!container) {
  6144.         lua_pushnil(L);
  6145.         return 1;
  6146.     }
  6147.  
  6148.     uint16_t itemId;
  6149.     if (isNumber(L, 2)) {
  6150.         itemId = getNumber<uint16_t>(L, 2);
  6151.     } else {
  6152.         itemId = Item::items.getItemIdByName(getString(L, 2));
  6153.         if (itemId == 0) {
  6154.             lua_pushnil(L);
  6155.             return 1;
  6156.         }
  6157.     }
  6158.  
  6159.     uint32_t subType = getNumber<uint32_t>(L, 3, 1);
  6160.  
  6161.     Item* item = Item::CreateItem(itemId, std::min<uint32_t>(subType, 100));
  6162.     if (!item) {
  6163.         lua_pushnil(L);
  6164.         return 1;
  6165.     }
  6166.  
  6167.     int32_t index = getNumber<int32_t>(L, 4, INDEX_WHEREEVER);
  6168.     uint32_t flags = getNumber<uint32_t>(L, 5, 0);
  6169.  
  6170.     ReturnValue ret = g_game.internalAddItem(container, item, index, flags);
  6171.     if (ret == RETURNVALUE_NOERROR) {
  6172.         pushUserdata<Item>(L, item);
  6173.         setItemMetatable(L, -1, item);
  6174.     } else {
  6175.         delete item;
  6176.         lua_pushnil(L);
  6177.     }
  6178.     return 1;
  6179. }
  6180.  
  6181. int LuaScriptInterface::luaContainerAddItemEx(lua_State* L)
  6182. {
  6183.     // container:addItemEx(item[, index = INDEX_WHEREEVER[, flags = 0]])
  6184.     Item* item = getUserdata<Item>(L, 2);
  6185.     if (!item) {
  6186.         lua_pushnil(L);
  6187.         return 1;
  6188.     }
  6189.  
  6190.     Container* container = getUserdata<Container>(L, 1);
  6191.     if (!container) {
  6192.         lua_pushnil(L);
  6193.         return 1;
  6194.     }
  6195.  
  6196.     if (item->getParent() != VirtualCylinder::virtualCylinder) {
  6197.         reportErrorFunc("Item already has a parent");
  6198.         lua_pushnil(L);
  6199.         return 1;
  6200.     }
  6201.  
  6202.     int32_t index = getNumber<int32_t>(L, 3, INDEX_WHEREEVER);
  6203.     uint32_t flags = getNumber<uint32_t>(L, 4, 0);
  6204.     ReturnValue ret = g_game.internalAddItem(container, item, index, flags);
  6205.     if (ret == RETURNVALUE_NOERROR) {
  6206.         ScriptEnvironment::removeTempItem(item);
  6207.     }
  6208.     lua_pushnumber(L, ret);
  6209.     return 1;
  6210. }
  6211.  
  6212. int LuaScriptInterface::luaContainerGetItemCountById(lua_State* L)
  6213. {
  6214.     // container:getItemCountById(itemId[, subType = -1])
  6215.     Container* container = getUserdata<Container>(L, 1);
  6216.     if (!container) {
  6217.         lua_pushnil(L);
  6218.         return 1;
  6219.     }
  6220.  
  6221.     uint16_t itemId;
  6222.     if (isNumber(L, 2)) {
  6223.         itemId = getNumber<uint16_t>(L, 2);
  6224.     } else {
  6225.         itemId = Item::items.getItemIdByName(getString(L, 2));
  6226.         if (itemId == 0) {
  6227.             lua_pushnil(L);
  6228.             return 1;
  6229.         }
  6230.     }
  6231.  
  6232.     int32_t subType = getNumber<int32_t>(L, 3, -1);
  6233.     lua_pushnumber(L, container->getItemTypeCount(itemId, subType));
  6234.     return 1;
  6235. }
  6236.  
  6237. // Teleport
  6238. int LuaScriptInterface::luaTeleportCreate(lua_State* L)
  6239. {
  6240.     // Teleport(uid)
  6241.     uint32_t id = getNumber<uint32_t>(L, 2);
  6242.  
  6243.     Item* item = getScriptEnv()->getItemByUID(id);
  6244.     if (item && item->getTeleport()) {
  6245.         pushUserdata(L, item);
  6246.         setMetatable(L, -1, "Teleport");
  6247.     } else {
  6248.         lua_pushnil(L);
  6249.     }
  6250.     return 1;
  6251. }
  6252.  
  6253. int LuaScriptInterface::luaTeleportGetDestination(lua_State* L)
  6254. {
  6255.     // teleport:getDestination()
  6256.     Teleport* teleport = getUserdata<Teleport>(L, 1);
  6257.     if (teleport) {
  6258.         pushPosition(L, teleport->getDestPos());
  6259.     } else {
  6260.         lua_pushnil(L);
  6261.     }
  6262.     return 1;
  6263. }
  6264.  
  6265. int LuaScriptInterface::luaTeleportSetDestination(lua_State* L)
  6266. {
  6267.     // teleport:setDestination(position)
  6268.     Teleport* teleport = getUserdata<Teleport>(L, 1);
  6269.     if (teleport) {
  6270.         teleport->setDestPos(getPosition(L, 2));
  6271.         pushBoolean(L, true);
  6272.     } else {
  6273.         lua_pushnil(L);
  6274.     }
  6275.     return 1;
  6276. }
  6277.  
  6278. // Creature
  6279. int LuaScriptInterface::luaCreatureCreate(lua_State* L)
  6280. {
  6281.     // Creature(id or name or userdata)
  6282.     Creature* creature;
  6283.     if (isNumber(L, 2)) {
  6284.         creature = g_game.getCreatureByID(getNumber<uint32_t>(L, 2));
  6285.     } else if (isString(L, 2)) {
  6286.         creature = g_game.getCreatureByName(getString(L, 2));
  6287.     } else if (isUserdata(L, 2)) {
  6288.         LuaDataType type = getUserdataType(L, 2);
  6289.         if (type != LuaData_Player && type != LuaData_Monster && type != LuaData_Npc) {
  6290.             lua_pushnil(L);
  6291.             return 1;
  6292.         }
  6293.         creature = getUserdata<Creature>(L, 2);
  6294.     } else {
  6295.         creature = nullptr;
  6296.     }
  6297.  
  6298.     if (creature) {
  6299.         pushUserdata<Creature>(L, creature);
  6300.         setCreatureMetatable(L, -1, creature);
  6301.     } else {
  6302.         lua_pushnil(L);
  6303.     }
  6304.     return 1;
  6305. }
  6306.  
  6307. int LuaScriptInterface::luaCreatureRegisterEvent(lua_State* L)
  6308. {
  6309.     // creature:registerEvent(name)
  6310.     Creature* creature = getUserdata<Creature>(L, 1);
  6311.     if (creature) {
  6312.         const std::string& name = getString(L, 2);
  6313.         pushBoolean(L, creature->registerCreatureEvent(name));
  6314.     } else {
  6315.         lua_pushnil(L);
  6316.     }
  6317.     return 1;
  6318. }
  6319.  
  6320. int LuaScriptInterface::luaCreatureUnregisterEvent(lua_State* L)
  6321. {
  6322.     // creature:unregisterEvent(name)
  6323.     const std::string& name = getString(L, 2);
  6324.     Creature* creature = getUserdata<Creature>(L, 1);
  6325.     if (creature) {
  6326.         pushBoolean(L, creature->unregisterCreatureEvent(name));
  6327.     } else {
  6328.         lua_pushnil(L);
  6329.     }
  6330.     return 1;
  6331. }
  6332.  
  6333. int LuaScriptInterface::luaCreatureIsRemoved(lua_State* L)
  6334. {
  6335.     // creature:isRemoved()
  6336.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6337.     if (creature) {
  6338.         pushBoolean(L, creature->isRemoved());
  6339.     } else {
  6340.         lua_pushnil(L);
  6341.     }
  6342.     return 1;
  6343. }
  6344.  
  6345. int LuaScriptInterface::luaCreatureIsCreature(lua_State* L)
  6346. {
  6347.     // creature:isCreature()
  6348.     pushBoolean(L, getUserdata<const Creature>(L, 1) != nullptr);
  6349.     return 1;
  6350. }
  6351.  
  6352. int LuaScriptInterface::luaCreatureIsInGhostMode(lua_State* L)
  6353. {
  6354.     // creature:isInGhostMode()
  6355.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6356.     if (creature) {
  6357.         pushBoolean(L, creature->isInGhostMode());
  6358.     } else {
  6359.         lua_pushnil(L);
  6360.     }
  6361.     return 1;
  6362. }
  6363.  
  6364. int LuaScriptInterface::luaCreatureIsHealthHidden(lua_State* L)
  6365. {
  6366.     // creature:isHealthHidden()
  6367.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6368.     if (creature) {
  6369.         pushBoolean(L, creature->isHealthHidden());
  6370.     } else {
  6371.         lua_pushnil(L);
  6372.     }
  6373.     return 1;
  6374. }
  6375.  
  6376. int LuaScriptInterface::luaCreatureCanSee(lua_State* L)
  6377. {
  6378.     // creature:canSee(position)
  6379.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6380.     if (creature) {
  6381.         const Position& position = getPosition(L, 2);
  6382.         pushBoolean(L, creature->canSee(position));
  6383.     } else {
  6384.         lua_pushnil(L);
  6385.     }
  6386.     return 1;
  6387. }
  6388.  
  6389. int LuaScriptInterface::luaCreatureCanSeeCreature(lua_State* L)
  6390. {
  6391.     // creature:canSeeCreature(creature)
  6392.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6393.     if (creature) {
  6394.         const Creature* otherCreature = getCreature(L, 2);
  6395.         pushBoolean(L, creature->canSeeCreature(otherCreature));
  6396.     } else {
  6397.         lua_pushnil(L);
  6398.     }
  6399.     return 1;
  6400. }
  6401.  
  6402. int LuaScriptInterface::luaCreatureGetParent(lua_State* L)
  6403. {
  6404.     // creature:getParent()
  6405.     Creature* creature = getUserdata<Creature>(L, 1);
  6406.     if (!creature) {
  6407.         lua_pushnil(L);
  6408.         return 1;
  6409.     }
  6410.  
  6411.     Cylinder* parent = creature->getParent();
  6412.     if (!parent) {
  6413.         lua_pushnil(L);
  6414.         return 1;
  6415.     }
  6416.  
  6417.     pushCylinder(L, parent);
  6418.     return 1;
  6419. }
  6420.  
  6421. int LuaScriptInterface::luaCreatureGetId(lua_State* L)
  6422. {
  6423.     // creature:getId()
  6424.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6425.     if (creature) {
  6426.         lua_pushnumber(L, creature->getID());
  6427.     } else {
  6428.         lua_pushnil(L);
  6429.     }
  6430.     return 1;
  6431. }
  6432.  
  6433. int LuaScriptInterface::luaCreatureGetName(lua_State* L)
  6434. {
  6435.     // creature:getName()
  6436.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6437.     if (creature) {
  6438.         pushString(L, creature->getName());
  6439.     } else {
  6440.         lua_pushnil(L);
  6441.     }
  6442.     return 1;
  6443. }
  6444.  
  6445. int LuaScriptInterface::luaCreatureGetTarget(lua_State* L)
  6446. {
  6447.     // creature:getTarget()
  6448.     Creature* creature = getUserdata<Creature>(L, 1);
  6449.     if (!creature) {
  6450.         lua_pushnil(L);
  6451.         return 1;
  6452.     }
  6453.  
  6454.     Creature* target = creature->getAttackedCreature();
  6455.     if (target) {
  6456.         pushUserdata<Creature>(L, target);
  6457.         setCreatureMetatable(L, -1, target);
  6458.     } else {
  6459.         lua_pushnil(L);
  6460.     }
  6461.     return 1;
  6462. }
  6463.  
  6464. int LuaScriptInterface::luaCreatureSetTarget(lua_State* L)
  6465. {
  6466.     // creature:setTarget(target)
  6467.     Creature* creature = getUserdata<Creature>(L, 1);
  6468.     if (creature) {
  6469.         Creature* target = getCreature(L, 2);
  6470.         pushBoolean(L, creature->setAttackedCreature(target));
  6471.     } else {
  6472.         lua_pushnil(L);
  6473.     }
  6474.     return 1;
  6475. }
  6476.  
  6477. int LuaScriptInterface::luaCreatureGetFollowCreature(lua_State* L)
  6478. {
  6479.     // creature:getFollowCreature()
  6480.     Creature* creature = getUserdata<Creature>(L, 1);
  6481.     if (!creature) {
  6482.         lua_pushnil(L);
  6483.         return 1;
  6484.     }
  6485.  
  6486.     Creature* followCreature = creature->getFollowCreature();
  6487.     if (followCreature) {
  6488.         pushUserdata<Creature>(L, followCreature);
  6489.         setCreatureMetatable(L, -1, followCreature);
  6490.     } else {
  6491.         lua_pushnil(L);
  6492.     }
  6493.     return 1;
  6494. }
  6495.  
  6496. int LuaScriptInterface::luaCreatureSetFollowCreature(lua_State* L)
  6497. {
  6498.     // creature:setFollowCreature(followedCreature)
  6499.     Creature* creature = getUserdata<Creature>(L, 1);
  6500.     if (creature) {
  6501.         Creature* followCreature = getCreature(L, 2);
  6502.         pushBoolean(L, creature->setFollowCreature(followCreature));
  6503.     } else {
  6504.         lua_pushnil(L);
  6505.     }
  6506.     return 1;
  6507. }
  6508.  
  6509. int LuaScriptInterface::luaCreatureGetMaster(lua_State* L)
  6510. {
  6511.     // creature:getMaster()
  6512.     Creature* creature = getUserdata<Creature>(L, 1);
  6513.     if (!creature) {
  6514.         lua_pushnil(L);
  6515.         return 1;
  6516.     }
  6517.  
  6518.     Creature* master = creature->getMaster();
  6519.     if (!master) {
  6520.         lua_pushnil(L);
  6521.         return 1;
  6522.     }
  6523.  
  6524.     pushUserdata<Creature>(L, master);
  6525.     setCreatureMetatable(L, -1, master);
  6526.     return 1;
  6527. }
  6528.  
  6529. int LuaScriptInterface::luaCreatureSetMaster(lua_State* L)
  6530. {
  6531.     // creature:setMaster(master)
  6532.     Creature* creature = getUserdata<Creature>(L, 1);
  6533.     if (!creature) {
  6534.         lua_pushnil(L);
  6535.         return 1;
  6536.     }
  6537.  
  6538.     Creature* master = getCreature(L, 2);
  6539.     if (master) {
  6540.         pushBoolean(L, creature->convinceCreature(master));
  6541.     } else {
  6542.         master = creature->getMaster();
  6543.         if (master) {
  6544.             master->removeSummon(creature);
  6545.             creature->incrementReferenceCounter();
  6546.             creature->setDropLoot(true);
  6547.         }
  6548.         pushBoolean(L, true);
  6549.     }
  6550.     return 1;
  6551. }
  6552.  
  6553. int LuaScriptInterface::luaCreatureGetLight(lua_State* L)
  6554. {
  6555.     // creature:getLight()
  6556.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6557.     if (!creature) {
  6558.         lua_pushnil(L);
  6559.         return 1;
  6560.     }
  6561.  
  6562.     LightInfo light;
  6563.     creature->getCreatureLight(light);
  6564.     lua_pushnumber(L, light.level);
  6565.     lua_pushnumber(L, light.color);
  6566.     return 2;
  6567. }
  6568.  
  6569. int LuaScriptInterface::luaCreatureSetLight(lua_State* L)
  6570. {
  6571.     // creature:setLight(color, level)
  6572.     Creature* creature = getUserdata<Creature>(L, 1);
  6573.     if (!creature) {
  6574.         lua_pushnil(L);
  6575.         return 1;
  6576.     }
  6577.  
  6578.     LightInfo light;
  6579.     light.color = getNumber<uint8_t>(L, 2);
  6580.     light.level = getNumber<uint8_t>(L, 3);
  6581.     creature->setCreatureLight(light);
  6582.     g_game.changeLight(creature);
  6583.     pushBoolean(L, true);
  6584.     return 1;
  6585. }
  6586.  
  6587. int LuaScriptInterface::luaCreatureGetSpeed(lua_State* L)
  6588. {
  6589.     // creature:getSpeed()
  6590.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6591.     if (creature) {
  6592.         lua_pushnumber(L, creature->getSpeed());
  6593.     } else {
  6594.         lua_pushnil(L);
  6595.     }
  6596.     return 1;
  6597. }
  6598.  
  6599. int LuaScriptInterface::luaCreatureGetBaseSpeed(lua_State* L)
  6600. {
  6601.     // creature:getBaseSpeed()
  6602.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6603.     if (creature) {
  6604.         lua_pushnumber(L, creature->getBaseSpeed());
  6605.     } else {
  6606.         lua_pushnil(L);
  6607.     }
  6608.     return 1;
  6609. }
  6610.  
  6611. int LuaScriptInterface::luaCreatureChangeSpeed(lua_State* L)
  6612. {
  6613.     // creature:changeSpeed(delta)
  6614.     Creature* creature = getCreature(L, 1);
  6615.     if (!creature) {
  6616.         reportErrorFunc(getErrorDesc(LUA_ERROR_CREATURE_NOT_FOUND));
  6617.         pushBoolean(L, false);
  6618.         return 1;
  6619.     }
  6620.  
  6621.     int32_t delta = getNumber<int32_t>(L, 2);
  6622.     g_game.changeSpeed(creature, delta);
  6623.     pushBoolean(L, true);
  6624.     return 1;
  6625. }
  6626.  
  6627. int LuaScriptInterface::luaCreatureSetDropLoot(lua_State* L)
  6628. {
  6629.     // creature:setDropLoot(doDrop)
  6630.     Creature* creature = getUserdata<Creature>(L, 1);
  6631.     if (creature) {
  6632.         creature->setDropLoot(getBoolean(L, 2));
  6633.         pushBoolean(L, true);
  6634.     } else {
  6635.         lua_pushnil(L);
  6636.     }
  6637.     return 1;
  6638. }
  6639.  
  6640. int LuaScriptInterface::luaCreatureGetPosition(lua_State* L)
  6641. {
  6642.     // creature:getPosition()
  6643.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6644.     if (creature) {
  6645.         pushPosition(L, creature->getPosition());
  6646.     } else {
  6647.         lua_pushnil(L);
  6648.     }
  6649.     return 1;
  6650. }
  6651.  
  6652. int LuaScriptInterface::luaCreatureGetTile(lua_State* L)
  6653. {
  6654.     // creature:getTile()
  6655.     Creature* creature = getUserdata<Creature>(L, 1);
  6656.     if (!creature) {
  6657.         lua_pushnil(L);
  6658.         return 1;
  6659.     }
  6660.  
  6661.     Tile* tile = creature->getTile();
  6662.     if (tile) {
  6663.         pushUserdata<Tile>(L, tile);
  6664.         setMetatable(L, -1, "Tile");
  6665.     } else {
  6666.         lua_pushnil(L);
  6667.     }
  6668.     return 1;
  6669. }
  6670.  
  6671. int LuaScriptInterface::luaCreatureGetDirection(lua_State* L)
  6672. {
  6673.     // creature:getDirection()
  6674.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6675.     if (creature) {
  6676.         lua_pushnumber(L, creature->getDirection());
  6677.     } else {
  6678.         lua_pushnil(L);
  6679.     }
  6680.     return 1;
  6681. }
  6682.  
  6683. int LuaScriptInterface::luaCreatureSetDirection(lua_State* L)
  6684. {
  6685.     // creature:setDirection(direction)
  6686.     Creature* creature = getUserdata<Creature>(L, 1);
  6687.     if (creature) {
  6688.         pushBoolean(L, g_game.internalCreatureTurn(creature, getNumber<Direction>(L, 2)));
  6689.     } else {
  6690.         lua_pushnil(L);
  6691.     }
  6692.     return 1;
  6693. }
  6694.  
  6695. int LuaScriptInterface::luaCreatureGetHealth(lua_State* L)
  6696. {
  6697.     // creature:getHealth()
  6698.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6699.     if (creature) {
  6700.         lua_pushnumber(L, creature->getHealth());
  6701.     } else {
  6702.         lua_pushnil(L);
  6703.     }
  6704.     return 1;
  6705. }
  6706.  
  6707. int LuaScriptInterface::luaCreatureAddHealth(lua_State* L)
  6708. {
  6709.     // creature:addHealth(healthChange)
  6710.     Creature* creature = getUserdata<Creature>(L, 1);
  6711.     if (!creature) {
  6712.         lua_pushnil(L);
  6713.         return 1;
  6714.     }
  6715.  
  6716.     CombatDamage damage;
  6717.     damage.primary.value = getNumber<int32_t>(L, 2);
  6718.     if (damage.primary.value >= 0) {
  6719.         damage.primary.type = COMBAT_HEALING;
  6720.     } else {
  6721.         damage.primary.type = COMBAT_UNDEFINEDDAMAGE;
  6722.     }
  6723.     pushBoolean(L, g_game.combatChangeHealth(nullptr, creature, damage));
  6724.     return 1;
  6725. }
  6726.  
  6727. int LuaScriptInterface::luaCreatureGetMaxHealth(lua_State* L)
  6728. {
  6729.     // creature:getMaxHealth()
  6730.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6731.     if (creature) {
  6732.         lua_pushnumber(L, creature->getMaxHealth());
  6733.     } else {
  6734.         lua_pushnil(L);
  6735.     }
  6736.     return 1;
  6737. }
  6738.  
  6739. int LuaScriptInterface::luaCreatureSetMaxHealth(lua_State* L)
  6740. {
  6741.     // creature:setMaxHealth(maxHealth)
  6742.     Creature* creature = getUserdata<Creature>(L, 1);
  6743.     if (!creature) {
  6744.         lua_pushnil(L);
  6745.         return 1;
  6746.     }
  6747.  
  6748.     creature->healthMax = getNumber<uint32_t>(L, 2);
  6749.     creature->health = std::min<int32_t>(creature->health, creature->healthMax);
  6750.     g_game.addCreatureHealth(creature);
  6751.  
  6752.     Player* player = creature->getPlayer();
  6753.     if (player) {
  6754.         player->sendStats();
  6755.     }
  6756.     pushBoolean(L, true);
  6757.     return 1;
  6758. }
  6759.  
  6760. int LuaScriptInterface::luaCreatureSetHiddenHealth(lua_State* L)
  6761. {
  6762.     // creature:setHiddenHealth(hide)
  6763.     Creature* creature = getUserdata<Creature>(L, 1);
  6764.     if (creature) {
  6765.         creature->setHiddenHealth(getBoolean(L, 2));
  6766.         g_game.addCreatureHealth(creature);
  6767.         pushBoolean(L, true);
  6768.     } else {
  6769.         lua_pushnil(L);
  6770.     }
  6771.     return 1;
  6772. }
  6773.  
  6774. int LuaScriptInterface::luaCreatureGetMana(lua_State* L)
  6775. {
  6776.     // creature:getMana()
  6777.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6778.     if (creature) {
  6779.         lua_pushnumber(L, creature->getMana());
  6780.     } else {
  6781.         lua_pushnil(L);
  6782.     }
  6783.     return 1;
  6784. }
  6785.  
  6786. int LuaScriptInterface::luaCreatureAddMana(lua_State* L)
  6787. {
  6788.     // creature:addMana(manaChange[, animationOnLoss = false])
  6789.     Creature* creature = getUserdata<Creature>(L, 1);
  6790.     if (!creature) {
  6791.         lua_pushnil(L);
  6792.         return 1;
  6793.     }
  6794.  
  6795.     int32_t manaChange = getNumber<int32_t>(L, 2);
  6796.     bool animationOnLoss = getBoolean(L, 3, false);
  6797.     if (!animationOnLoss && manaChange < 0) {
  6798.         creature->changeMana(manaChange);
  6799.     } else {
  6800.         g_game.combatChangeMana(nullptr, creature, manaChange, ORIGIN_NONE);
  6801.     }
  6802.     pushBoolean(L, true);
  6803.     return 1;
  6804. }
  6805.  
  6806. int LuaScriptInterface::luaCreatureGetMaxMana(lua_State* L)
  6807. {
  6808.     // creature:getMaxMana()
  6809.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6810.     if (creature) {
  6811.         lua_pushnumber(L, creature->getMaxMana());
  6812.     } else {
  6813.         lua_pushnil(L);
  6814.     }
  6815.     return 1;
  6816. }
  6817.  
  6818. int LuaScriptInterface::luaCreatureGetSkull(lua_State* L)
  6819. {
  6820.     // creature:getSkull()
  6821.     Creature* creature = getUserdata<Creature>(L, 1);
  6822.     if (creature) {
  6823.         lua_pushnumber(L, creature->getSkull());
  6824.     } else {
  6825.         lua_pushnil(L);
  6826.     }
  6827.     return 1;
  6828. }
  6829.  
  6830. int LuaScriptInterface::luaCreatureSetSkull(lua_State* L)
  6831. {
  6832.     // creature:setSkull(skull)
  6833.     Creature* creature = getUserdata<Creature>(L, 1);
  6834.     if (creature) {
  6835.         creature->setSkull(getNumber<Skulls_t>(L, 2));
  6836.         pushBoolean(L, true);
  6837.     } else {
  6838.         lua_pushnil(L);
  6839.     }
  6840.     return 1;
  6841. }
  6842.  
  6843. int LuaScriptInterface::luaCreatureGetOutfit(lua_State* L)
  6844. {
  6845.     // creature:getOutfit()
  6846.     const Creature* creature = getUserdata<const Creature>(L, 1);
  6847.     if (creature) {
  6848.         pushOutfit(L, creature->getCurrentOutfit());
  6849.     } else {
  6850.         lua_pushnil(L);
  6851.     }
  6852.     return 1;
  6853. }
  6854.  
  6855. int LuaScriptInterface::luaCreatureSetOutfit(lua_State* L)
  6856. {
  6857.     // creature:setOutfit(outfit)
  6858.     Creature* creature = getUserdata<Creature>(L, 1);
  6859.     if (creature) {
  6860.         creature->defaultOutfit = getOutfit(L, 2);
  6861.         g_game.internalCreatureChangeOutfit(creature, creature->defaultOutfit);
  6862.         pushBoolean(L, true);
  6863.     } else {
  6864.         lua_pushnil(L);
  6865.     }
  6866.     return 1;
  6867. }
  6868.  
  6869. int LuaScriptInterface::luaCreatureGetCondition(lua_State* L)
  6870. {
  6871.     // creature:getCondition(conditionType[, conditionId = CONDITIONID_COMBAT[, subId = 0]])
  6872.     Creature* creature = getUserdata<Creature>(L, 1);
  6873.     if (!creature) {
  6874.         lua_pushnil(L);
  6875.         return 1;
  6876.     }
  6877.  
  6878.     ConditionType_t conditionType = getNumber<ConditionType_t>(L, 2);
  6879.     ConditionId_t conditionId = getNumber<ConditionId_t>(L, 3, CONDITIONID_COMBAT);
  6880.     uint32_t subId = getNumber<uint32_t>(L, 4, 0);
  6881.  
  6882.     Condition* condition = creature->getCondition(conditionType, conditionId, subId);
  6883.     if (condition) {
  6884.         pushUserdata<Condition>(L, condition);
  6885.         setWeakMetatable(L, -1, "Condition");
  6886.     } else {
  6887.         lua_pushnil(L);
  6888.     }
  6889.     return 1;
  6890. }
  6891.  
  6892. int LuaScriptInterface::luaCreatureAddCondition(lua_State* L)
  6893. {
  6894.     // creature:addCondition(condition[, force = false])
  6895.     Creature* creature = getUserdata<Creature>(L, 1);
  6896.     Condition* condition = getUserdata<Condition>(L, 2);
  6897.     if (creature && condition) {
  6898.         bool force = getBoolean(L, 3, false);
  6899.         pushBoolean(L, creature->addCondition(condition->clone(), force));
  6900.     } else {
  6901.         lua_pushnil(L);
  6902.     }
  6903.     return 1;
  6904. }
  6905.  
  6906. int LuaScriptInterface::luaCreatureRemoveCondition(lua_State* L)
  6907. {
  6908.     // creature:removeCondition(conditionType[, conditionId = CONDITIONID_COMBAT[, subId = 0[, force = false]]])
  6909.     Creature* creature = getUserdata<Creature>(L, 1);
  6910.     if (!creature) {
  6911.         lua_pushnil(L);
  6912.         return 1;
  6913.     }
  6914.  
  6915.     ConditionType_t conditionType = getNumber<ConditionType_t>(L, 2);
  6916.     ConditionId_t conditionId = getNumber<ConditionId_t>(L, 3, CONDITIONID_COMBAT);
  6917.     uint32_t subId = getNumber<uint32_t>(L, 4, 0);
  6918.     Condition* condition = creature->getCondition(conditionType, conditionId, subId);
  6919.     if (condition) {
  6920.         bool force = getBoolean(L, 5, false);
  6921.         creature->removeCondition(condition, force);
  6922.         pushBoolean(L, true);
  6923.     } else {
  6924.         lua_pushnil(L);
  6925.     }
  6926.     return 1;
  6927. }
  6928.  
  6929. int LuaScriptInterface::luaCreatureRemove(lua_State* L)
  6930. {
  6931.     // creature:remove()
  6932.     Creature** creaturePtr = getRawUserdata<Creature>(L, 1);
  6933.     if (!creaturePtr) {
  6934.         lua_pushnil(L);
  6935.         return 1;
  6936.     }
  6937.  
  6938.     Creature* creature = *creaturePtr;
  6939.     if (!creature) {
  6940.         lua_pushnil(L);
  6941.         return 1;
  6942.     }
  6943.  
  6944.     Player* player = creature->getPlayer();
  6945.     if (player) {
  6946.         player->kickPlayer(true);
  6947.     } else {
  6948.         g_game.removeCreature(creature);
  6949.     }
  6950.  
  6951.     *creaturePtr = nullptr;
  6952.     pushBoolean(L, true);
  6953.     return 1;
  6954. }
  6955.  
  6956. int LuaScriptInterface::luaCreatureTeleportTo(lua_State* L)
  6957. {
  6958.     // creature:teleportTo(position[, pushMovement = false])
  6959.     bool pushMovement = getBoolean(L, 3, false);
  6960.  
  6961.     const Position& position = getPosition(L, 2);
  6962.     Creature* creature = getUserdata<Creature>(L, 1);
  6963.     if (!creature) {
  6964.         lua_pushnil(L);
  6965.         return 1;
  6966.     }
  6967.  
  6968.     const Position oldPosition = creature->getPosition();
  6969.     if (g_game.internalTeleport(creature, position, pushMovement) != RETURNVALUE_NOERROR) {
  6970.         pushBoolean(L, false);
  6971.         return 1;
  6972.     }
  6973.  
  6974.     if (!pushMovement) {
  6975.         if (oldPosition.x == position.x) {
  6976.             if (oldPosition.y < position.y) {
  6977.                 g_game.internalCreatureTurn(creature, DIRECTION_SOUTH);
  6978.             } else {
  6979.                 g_game.internalCreatureTurn(creature, DIRECTION_NORTH);
  6980.             }
  6981.         } else if (oldPosition.x > position.x) {
  6982.             g_game.internalCreatureTurn(creature, DIRECTION_WEST);
  6983.         } else if (oldPosition.x < position.x) {
  6984.             g_game.internalCreatureTurn(creature, DIRECTION_EAST);
  6985.         }
  6986.     }
  6987.     pushBoolean(L, true);
  6988.     return 1;
  6989. }
  6990.  
  6991. int LuaScriptInterface::luaCreatureSay(lua_State* L)
  6992. {
  6993.     // creature:say(text, type[, ghost = false[, target = nullptr[, position]]])
  6994.     int parameters = lua_gettop(L);
  6995.  
  6996.     Position position;
  6997.     if (parameters >= 6) {
  6998.         position = getPosition(L, 6);
  6999.         if (!position.x || !position.y) {
  7000.             reportErrorFunc("Invalid position specified.");
  7001.             pushBoolean(L, false);
  7002.             return 1;
  7003.         }
  7004.     }
  7005.  
  7006.     Creature* target = nullptr;
  7007.     if (parameters >= 5) {
  7008.         target = getCreature(L, 5);
  7009.     }
  7010.  
  7011.     bool ghost = getBoolean(L, 4, false);
  7012.  
  7013.     SpeakClasses type = getNumber<SpeakClasses>(L, 3);
  7014.     const std::string& text = getString(L, 2);
  7015.     Creature* creature = getUserdata<Creature>(L, 1);
  7016.     if (!creature) {
  7017.         lua_pushnil(L);
  7018.         return 1;
  7019.     }
  7020.  
  7021.     SpectatorVec list;
  7022.     if (target) {
  7023.         list.insert(target);
  7024.     }
  7025.  
  7026.     if (position.x != 0) {
  7027.         pushBoolean(L, g_game.internalCreatureSay(creature, type, text, ghost, &list, &position));
  7028.     } else {
  7029.         pushBoolean(L, g_game.internalCreatureSay(creature, type, text, ghost, &list));
  7030.     }
  7031.     return 1;
  7032. }
  7033.  
  7034. int LuaScriptInterface::luaCreatureGetDamageMap(lua_State* L)
  7035. {
  7036.     // creature:getDamageMap()
  7037.     Creature* creature = getUserdata<Creature>(L, 1);
  7038.     if (!creature) {
  7039.         lua_pushnil(L);
  7040.         return 1;
  7041.     }
  7042.  
  7043.     lua_createtable(L, creature->damageMap.size(), 0);
  7044.     for (auto damageEntry : creature->damageMap) {
  7045.         lua_createtable(L, 0, 2);
  7046.         setField(L, "total", damageEntry.second.total);
  7047.         setField(L, "ticks", damageEntry.second.ticks);
  7048.         lua_rawseti(L, -2, damageEntry.first);
  7049.     }
  7050.     return 1;
  7051. }
  7052.  
  7053. int LuaScriptInterface::luaCreatureGetSummons(lua_State* L)
  7054. {
  7055.     // creature:getSummons()
  7056.     Creature* creature = getUserdata<Creature>(L, 1);
  7057.     if (!creature) {
  7058.         lua_pushnil(L);
  7059.         return 1;
  7060.     }
  7061.  
  7062.     lua_createtable(L, creature->getSummonCount(), 0);
  7063.  
  7064.     int index = 0;
  7065.     for (Creature* summon : creature->getSummons()) {
  7066.         pushUserdata<Creature>(L, summon);
  7067.         setCreatureMetatable(L, -1, summon);
  7068.         lua_rawseti(L, -2, ++index);
  7069.     }
  7070.     return 1;
  7071. }
  7072.  
  7073. int LuaScriptInterface::luaCreatureGetDescription(lua_State* L)
  7074. {
  7075.     // creature:getDescription(distance)
  7076.     int32_t distance = getNumber<int32_t>(L, 2);
  7077.     Creature* creature = getUserdata<Creature>(L, 1);
  7078.     if (creature) {
  7079.         pushString(L, creature->getDescription(distance));
  7080.     } else {
  7081.         lua_pushnil(L);
  7082.     }
  7083.     return 1;
  7084. }
  7085.  
  7086. int LuaScriptInterface::luaCreatureGetPathTo(lua_State* L)
  7087. {
  7088.     // creature:getPathTo(pos[, minTargetDist = 0[, maxTargetDist = 1[, fullPathSearch = true[, clearSight = true[, maxSearchDist = 0]]]]])
  7089.     Creature* creature = getUserdata<Creature>(L, 1);
  7090.     if (!creature) {
  7091.         lua_pushnil(L);
  7092.         return 1;
  7093.     }
  7094.  
  7095.     const Position& position = getPosition(L, 2);
  7096.  
  7097.     FindPathParams fpp;
  7098.     fpp.minTargetDist = getNumber<int32_t>(L, 3, 0);
  7099.     fpp.maxTargetDist = getNumber<int32_t>(L, 4, 1);
  7100.     fpp.fullPathSearch = getBoolean(L, 5, fpp.fullPathSearch);
  7101.     fpp.clearSight = getBoolean(L, 6, fpp.clearSight);
  7102.     fpp.maxSearchDist = getNumber<int32_t>(L, 7, fpp.maxSearchDist);
  7103.  
  7104.     std::forward_list<Direction> dirList;
  7105.     if (creature->getPathTo(position, dirList, fpp)) {
  7106.         lua_newtable(L);
  7107.  
  7108.         int index = 0;
  7109.         for (Direction dir : dirList) {
  7110.             lua_pushnumber(L, dir);
  7111.             lua_rawseti(L, -2, ++index);
  7112.         }
  7113.     } else {
  7114.         pushBoolean(L, false);
  7115.     }
  7116.     return 1;
  7117. }
  7118.  
  7119. // Player
  7120. int LuaScriptInterface::luaPlayerCreate(lua_State* L)
  7121. {
  7122.     // Player(id or name or userdata)
  7123.     Player* player;
  7124.     if (isNumber(L, 2)) {
  7125.         player = g_game.getPlayerByID(getNumber<uint32_t>(L, 2));
  7126.     } else if (isString(L, 2)) {
  7127.         ReturnValue ret = g_game.getPlayerByNameWildcard(getString(L, 2), player);
  7128.         if (ret != RETURNVALUE_NOERROR) {
  7129.             lua_pushnil(L);
  7130.             lua_pushnumber(L, ret);
  7131.             return 2;
  7132.         }
  7133.     } else if (isUserdata(L, 2)) {
  7134.         if (getUserdataType(L, 2) != LuaData_Player) {
  7135.             lua_pushnil(L);
  7136.             return 1;
  7137.         }
  7138.         player = getUserdata<Player>(L, 2);
  7139.     } else {
  7140.         player = nullptr;
  7141.     }
  7142.  
  7143.     if (player) {
  7144.         pushUserdata<Player>(L, player);
  7145.         setMetatable(L, -1, "Player");
  7146.     } else {
  7147.         lua_pushnil(L);
  7148.     }
  7149.     return 1;
  7150. }
  7151.  
  7152. int LuaScriptInterface::luaPlayerIsPlayer(lua_State* L)
  7153. {
  7154.     // player:isPlayer()
  7155.     pushBoolean(L, getUserdata<const Player>(L, 1) != nullptr);
  7156.     return 1;
  7157. }
  7158.  
  7159. int LuaScriptInterface::luaPlayerGetGuid(lua_State* L)
  7160. {
  7161.     // player:getGuid()
  7162.     Player* player = getUserdata<Player>(L, 1);
  7163.     if (player) {
  7164.         lua_pushnumber(L, player->getGUID());
  7165.     } else {
  7166.         lua_pushnil(L);
  7167.     }
  7168.     return 1;
  7169. }
  7170.  
  7171. int LuaScriptInterface::luaPlayerGetIp(lua_State* L)
  7172. {
  7173.     // player:getIp()
  7174.     Player* player = getUserdata<Player>(L, 1);
  7175.     if (player) {
  7176.         lua_pushnumber(L, player->getIP());
  7177.     } else {
  7178.         lua_pushnil(L);
  7179.     }
  7180.     return 1;
  7181. }
  7182.  
  7183. int LuaScriptInterface::luaPlayerGetAccountId(lua_State* L)
  7184. {
  7185.     // player:getAccountId()
  7186.     Player* player = getUserdata<Player>(L, 1);
  7187.     if (player) {
  7188.         lua_pushnumber(L, player->getAccount());
  7189.     } else {
  7190.         lua_pushnil(L);
  7191.     }
  7192.     return 1;
  7193. }
  7194.  
  7195. int LuaScriptInterface::luaPlayerGetLastLoginSaved(lua_State* L)
  7196. {
  7197.     // player:getLastLoginSaved()
  7198.     Player* player = getUserdata<Player>(L, 1);
  7199.     if (player) {
  7200.         lua_pushnumber(L, player->getLastLoginSaved());
  7201.     } else {
  7202.         lua_pushnil(L);
  7203.     }
  7204.     return 1;
  7205. }
  7206.  
  7207. int LuaScriptInterface::luaPlayerGetLastLogout(lua_State* L)
  7208. {
  7209.     // player:getLastLogout()
  7210.     Player* player = getUserdata<Player>(L, 1);
  7211.     if (player) {
  7212.         lua_pushnumber(L, player->getLastLogout());
  7213.     } else {
  7214.         lua_pushnil(L);
  7215.     }
  7216.     return 1;
  7217. }
  7218.  
  7219. int LuaScriptInterface::luaPlayerGetAccountType(lua_State* L)
  7220. {
  7221.     // player:getAccountType()
  7222.     Player* player = getUserdata<Player>(L, 1);
  7223.     if (player) {
  7224.         lua_pushnumber(L, player->getAccountType());
  7225.     } else {
  7226.         lua_pushnil(L);
  7227.     }
  7228.     return 1;
  7229. }
  7230.  
  7231. int LuaScriptInterface::luaPlayerSetAccountType(lua_State* L)
  7232. {
  7233.     // player:setAccountType(accountType)
  7234.     Player* player = getUserdata<Player>(L, 1);
  7235.     if (player) {
  7236.         player->accountType = getNumber<AccountType_t>(L, 2);
  7237.         IOLoginData::setAccountType(player->getAccount(), player->accountType);
  7238.         pushBoolean(L, true);
  7239.     } else {
  7240.         lua_pushnil(L);
  7241.     }
  7242.     return 1;
  7243. }
  7244.  
  7245. int LuaScriptInterface::luaPlayerGetCapacity(lua_State* L)
  7246. {
  7247.     // player:getCapacity()
  7248.     Player* player = getUserdata<Player>(L, 1);
  7249.     if (player) {
  7250.         lua_pushnumber(L, player->getCapacity());
  7251.     } else {
  7252.         lua_pushnil(L);
  7253.     }
  7254.     return 1;
  7255. }
  7256.  
  7257. int LuaScriptInterface::luaPlayerSetCapacity(lua_State* L)
  7258. {
  7259.     // player:setCapacity(capacity)
  7260.     Player* player = getUserdata<Player>(L, 1);
  7261.     if (player) {
  7262.         player->capacity = getNumber<uint32_t>(L, 2);
  7263.         player->sendStats();
  7264.         pushBoolean(L, true);
  7265.     } else {
  7266.         lua_pushnil(L);
  7267.     }
  7268.     return 1;
  7269. }
  7270.  
  7271. int LuaScriptInterface::luaPlayerGetFreeCapacity(lua_State* L)
  7272. {
  7273.     // player:getFreeCapacity()
  7274.     Player* player = getUserdata<Player>(L, 1);
  7275.     if (player) {
  7276.         lua_pushnumber(L, player->getFreeCapacity());
  7277.     } else {
  7278.         lua_pushnil(L);
  7279.     }
  7280.     return 1;
  7281. }
  7282.  
  7283. int LuaScriptInterface::luaPlayerGetDepotChest(lua_State* L)
  7284. {
  7285.     // player:getDepotChest(depotId[, autoCreate = false])
  7286.     Player* player = getUserdata<Player>(L, 1);
  7287.     if (!player) {
  7288.         lua_pushnil(L);
  7289.         return 1;
  7290.     }
  7291.  
  7292.     uint32_t depotId = getNumber<uint32_t>(L, 2);
  7293.     bool autoCreate = getBoolean(L, 3, false);
  7294.     DepotChest* depotChest = player->getDepotChest(depotId, autoCreate);
  7295.     if (depotChest) {
  7296.         pushUserdata<Item>(L, depotChest);
  7297.         setItemMetatable(L, -1, depotChest);
  7298.     } else {
  7299.         pushBoolean(L, false);
  7300.     }
  7301.     return 1;
  7302. }
  7303.  
  7304. int LuaScriptInterface::luaPlayerGetSkullTime(lua_State* L)
  7305. {
  7306.     // player:getSkullTime()
  7307.     Player* player = getUserdata<Player>(L, 1);
  7308.     if (player) {
  7309.         lua_pushnumber(L, player->getSkullTicks());
  7310.     } else {
  7311.         lua_pushnil(L);
  7312.     }
  7313.     return 1;
  7314. }
  7315.  
  7316. int LuaScriptInterface::luaPlayerSetSkullTime(lua_State* L)
  7317. {
  7318.     // player:setSkullTime(skullTime)
  7319.     Player* player = getUserdata<Player>(L, 1);
  7320.     if (player) {
  7321.         player->setSkullTicks(getNumber<int64_t>(L, 2));
  7322.         pushBoolean(L, true);
  7323.     } else {
  7324.         lua_pushnil(L);
  7325.     }
  7326.     return 1;
  7327. }
  7328.  
  7329. int LuaScriptInterface::luaPlayerGetDeathPenalty(lua_State* L)
  7330. {
  7331.     // player:getDeathPenalty()
  7332.     Player* player = getUserdata<Player>(L, 1);
  7333.     if (player) {
  7334.         lua_pushnumber(L, static_cast<uint32_t>(player->getLostPercent() * 100));
  7335.     } else {
  7336.         lua_pushnil(L);
  7337.     }
  7338.     return 1;
  7339. }
  7340.  
  7341. int LuaScriptInterface::luaPlayerGetExperience(lua_State* L)
  7342. {
  7343.     // player:getExperience()
  7344.     Player* player = getUserdata<Player>(L, 1);
  7345.     if (player) {
  7346.         lua_pushnumber(L, player->getExperience());
  7347.     } else {
  7348.         lua_pushnil(L);
  7349.     }
  7350.     return 1;
  7351. }
  7352.  
  7353. int LuaScriptInterface::luaPlayerAddExperience(lua_State* L)
  7354. {
  7355.     // player:addExperience(experience[, sendText = false])
  7356.     Player* player = getUserdata<Player>(L, 1);
  7357.     if (player) {
  7358.         int64_t experience = getNumber<int64_t>(L, 2);
  7359.         bool sendText = getBoolean(L, 3, false);
  7360.         player->addExperience(nullptr, experience, sendText);
  7361.         pushBoolean(L, true);
  7362.     } else {
  7363.         lua_pushnil(L);
  7364.     }
  7365.     return 1;
  7366. }
  7367.  
  7368. int LuaScriptInterface::luaPlayerRemoveExperience(lua_State* L)
  7369. {
  7370.     // player:removeExperience(experience[, sendText = false])
  7371.     Player* player = getUserdata<Player>(L, 1);
  7372.     if (player) {
  7373.         int64_t experience = getNumber<int64_t>(L, 2);
  7374.         bool sendText = getBoolean(L, 3, false);
  7375.         player->removeExperience(experience, sendText);
  7376.         pushBoolean(L, true);
  7377.     } else {
  7378.         lua_pushnil(L);
  7379.     }
  7380.     return 1;
  7381. }
  7382.  
  7383. int LuaScriptInterface::luaPlayerGetLevel(lua_State* L)
  7384. {
  7385.     // player:getLevel()
  7386.     Player* player = getUserdata<Player>(L, 1);
  7387.     if (player) {
  7388.         lua_pushnumber(L, player->getLevel());
  7389.     } else {
  7390.         lua_pushnil(L);
  7391.     }
  7392.     return 1;
  7393. }
  7394.  
  7395. int LuaScriptInterface::luaPlayerGetMagicLevel(lua_State* L)
  7396. {
  7397.     // player:getMagicLevel()
  7398.     Player* player = getUserdata<Player>(L, 1);
  7399.     if (player) {
  7400.         lua_pushnumber(L, player->getMagicLevel());
  7401.     } else {
  7402.         lua_pushnil(L);
  7403.     }
  7404.     return 1;
  7405. }
  7406.  
  7407. int LuaScriptInterface::luaPlayerGetBaseMagicLevel(lua_State* L)
  7408. {
  7409.     // player:getBaseMagicLevel()
  7410.     Player* player = getUserdata<Player>(L, 1);
  7411.     if (player) {
  7412.         lua_pushnumber(L, player->getBaseMagicLevel());
  7413.     } else {
  7414.         lua_pushnil(L);
  7415.     }
  7416.     return 1;
  7417. }
  7418.  
  7419. int LuaScriptInterface::luaPlayerSetMaxMana(lua_State* L)
  7420. {
  7421.     // player:setMaxMana(maxMana)
  7422.     Player* player = getPlayer(L, 1);
  7423.     if (player) {
  7424.         player->manaMax = getNumber<int32_t>(L, 2);
  7425.         player->mana = std::min<int32_t>(player->mana, player->manaMax);
  7426.         player->sendStats();
  7427.         pushBoolean(L, true);
  7428.     } else {
  7429.         lua_pushnil(L);
  7430.     }
  7431.     return 1;
  7432. }
  7433.  
  7434. int LuaScriptInterface::luaPlayerGetManaSpent(lua_State* L)
  7435. {
  7436.     // player:getManaSpent()
  7437.     Player* player = getUserdata<Player>(L, 1);
  7438.     if (player) {
  7439.         lua_pushnumber(L, player->getSpentMana());
  7440.     } else {
  7441.         lua_pushnil(L);
  7442.     }
  7443.     return 1;
  7444. }
  7445.  
  7446. int LuaScriptInterface::luaPlayerAddManaSpent(lua_State* L)
  7447. {
  7448.     // player:addManaSpent(amount)
  7449.     Player* player = getUserdata<Player>(L, 1);
  7450.     if (player) {
  7451.         player->addManaSpent(getNumber<uint64_t>(L, 2));
  7452.         pushBoolean(L, true);
  7453.     } else {
  7454.         lua_pushnil(L);
  7455.     }
  7456.     return 1;
  7457. }
  7458.  
  7459. int LuaScriptInterface::luaPlayerGetSkillLevel(lua_State* L)
  7460. {
  7461.     // player:getSkillLevel(skillType)
  7462.     skills_t skillType = getNumber<skills_t>(L, 2);
  7463.     Player* player = getUserdata<Player>(L, 1);
  7464.     if (player && skillType <= SKILL_LAST) {
  7465.         lua_pushnumber(L, player->skills[skillType].level);
  7466.     } else {
  7467.         lua_pushnil(L);
  7468.     }
  7469.     return 1;
  7470. }
  7471.  
  7472. int LuaScriptInterface::luaPlayerGetEffectiveSkillLevel(lua_State* L)
  7473. {
  7474.     // player:getEffectiveSkillLevel(skillType)
  7475.     skills_t skillType = getNumber<skills_t>(L, 2);
  7476.     Player* player = getUserdata<Player>(L, 1);
  7477.     if (player && skillType <= SKILL_LAST) {
  7478.         lua_pushnumber(L, player->getSkillLevel(skillType));
  7479.     } else {
  7480.         lua_pushnil(L);
  7481.     }
  7482.     return 1;
  7483. }
  7484.  
  7485. int LuaScriptInterface::luaPlayerGetSkillPercent(lua_State* L)
  7486. {
  7487.     // player:getSkillPercent(skillType)
  7488.     skills_t skillType = getNumber<skills_t>(L, 2);
  7489.     Player* player = getUserdata<Player>(L, 1);
  7490.     if (player && skillType <= SKILL_LAST) {
  7491.         lua_pushnumber(L, player->skills[skillType].percent);
  7492.     } else {
  7493.         lua_pushnil(L);
  7494.     }
  7495.     return 1;
  7496. }
  7497.  
  7498. int LuaScriptInterface::luaPlayerGetSkillTries(lua_State* L)
  7499. {
  7500.     // player:getSkillTries(skillType)
  7501.     skills_t skillType = getNumber<skills_t>(L, 2);
  7502.     Player* player = getUserdata<Player>(L, 1);
  7503.     if (player && skillType <= SKILL_LAST) {
  7504.         lua_pushnumber(L, player->skills[skillType].tries);
  7505.     } else {
  7506.         lua_pushnil(L);
  7507.     }
  7508.     return 1;
  7509. }
  7510.  
  7511. int LuaScriptInterface::luaPlayerAddSkillTries(lua_State* L)
  7512. {
  7513.     // player:addSkillTries(skillType, tries)
  7514.     Player* player = getUserdata<Player>(L, 1);
  7515.     if (player) {
  7516.         skills_t skillType = getNumber<skills_t>(L, 2);
  7517.         uint64_t tries = getNumber<uint64_t>(L, 3);
  7518.         player->addSkillAdvance(skillType, tries);
  7519.         pushBoolean(L, true);
  7520.     } else {
  7521.         lua_pushnil(L);
  7522.     }
  7523.     return 1;
  7524. }
  7525.  
  7526. int LuaScriptInterface::luaPlayerAddOfflineTrainingTime(lua_State* L)
  7527. {
  7528.     // player:addOfflineTrainingTime(time)
  7529.     Player* player = getUserdata<Player>(L, 1);
  7530.     if (player) {
  7531.         int32_t time = getNumber<int32_t>(L, 2);
  7532.         player->addOfflineTrainingTime(time);
  7533.         player->sendStats();
  7534.         pushBoolean(L, true);
  7535.     } else {
  7536.         lua_pushnil(L);
  7537.     }
  7538.     return 1;
  7539. }
  7540.  
  7541.  
  7542. int LuaScriptInterface::luaPlayerGetOfflineTrainingTime(lua_State* L)
  7543. {
  7544.     // player:getOfflineTrainingTime()
  7545.     Player* player = getUserdata<Player>(L, 1);
  7546.     if (player) {
  7547.         lua_pushnumber(L, player->getOfflineTrainingTime());
  7548.     } else {
  7549.         lua_pushnil(L);
  7550.     }
  7551.     return 1;
  7552. }
  7553.  
  7554. int LuaScriptInterface::luaPlayerRemoveOfflineTrainingTime(lua_State* L)
  7555. {
  7556.     // player:removeOfflineTrainingTime(time)
  7557.     Player* player = getUserdata<Player>(L, 1);
  7558.     if (player) {
  7559.         int32_t time = getNumber<int32_t>(L, 2);
  7560.         player->removeOfflineTrainingTime(time);
  7561.         player->sendStats();
  7562.         pushBoolean(L, true);
  7563.     } else {
  7564.         lua_pushnil(L);
  7565.     }
  7566.     return 1;
  7567. }
  7568.  
  7569. int LuaScriptInterface::luaPlayerAddOfflineTrainingTries(lua_State* L)
  7570. {
  7571.     // player:addOfflineTrainingTries(skillType, tries)
  7572.     Player* player = getUserdata<Player>(L, 1);
  7573.     if (player) {
  7574.         skills_t skillType = getNumber<skills_t>(L, 2);
  7575.         uint64_t tries = getNumber<uint64_t>(L, 3);
  7576.         pushBoolean(L, player->addOfflineTrainingTries(skillType, tries));
  7577.     } else {
  7578.         lua_pushnil(L);
  7579.     }
  7580.     return 1;
  7581. }
  7582.  
  7583. int LuaScriptInterface::luaPlayerGetOfflineTrainingSkill(lua_State* L)
  7584. {
  7585.     // player:getOfflineTrainingSkill()
  7586.     Player* player = getUserdata<Player>(L, 1);
  7587.     if (player) {
  7588.         lua_pushnumber(L, player->getOfflineTrainingSkill());
  7589.     } else {
  7590.         lua_pushnil(L);
  7591.     }
  7592.     return 1;
  7593. }
  7594.  
  7595. int LuaScriptInterface::luaPlayerSetOfflineTrainingSkill(lua_State* L)
  7596. {
  7597.     // player:setOfflineTrainingSkill(skillId)
  7598.     Player* player = getUserdata<Player>(L, 1);
  7599.     if (player) {
  7600.         uint32_t skillId = getNumber<uint32_t>(L, 2);
  7601.         player->setOfflineTrainingSkill(skillId);
  7602.         pushBoolean(L, true);
  7603.     } else {
  7604.         lua_pushnil(L);
  7605.     }
  7606.     return 1;
  7607. }
  7608.  
  7609. int LuaScriptInterface::luaPlayerGetItemCount(lua_State* L)
  7610. {
  7611.     // player:getItemCount(itemId[, subType = -1])
  7612.     Player* player = getUserdata<Player>(L, 1);
  7613.     if (!player) {
  7614.         lua_pushnil(L);
  7615.         return 1;
  7616.     }
  7617.  
  7618.     uint16_t itemId;
  7619.     if (isNumber(L, 2)) {
  7620.         itemId = getNumber<uint16_t>(L, 2);
  7621.     } else {
  7622.         itemId = Item::items.getItemIdByName(getString(L, 2));
  7623.         if (itemId == 0) {
  7624.             lua_pushnil(L);
  7625.             return 1;
  7626.         }
  7627.     }
  7628.  
  7629.     int32_t subType = getNumber<int32_t>(L, 3, -1);
  7630.     lua_pushnumber(L, player->getItemTypeCount(itemId, subType));
  7631.     return 1;
  7632. }
  7633.  
  7634. int LuaScriptInterface::luaPlayerGetItemById(lua_State* L)
  7635. {
  7636.     // player:getItemById(itemId, deepSearch[, subType = -1])
  7637.     Player* player = getUserdata<Player>(L, 1);
  7638.     if (!player) {
  7639.         lua_pushnil(L);
  7640.         return 1;
  7641.     }
  7642.  
  7643.     uint16_t itemId;
  7644.     if (isNumber(L, 2)) {
  7645.         itemId = getNumber<uint16_t>(L, 2);
  7646.     } else {
  7647.         itemId = Item::items.getItemIdByName(getString(L, 2));
  7648.         if (itemId == 0) {
  7649.             lua_pushnil(L);
  7650.             return 1;
  7651.         }
  7652.     }
  7653.     bool deepSearch = getBoolean(L, 3);
  7654.     int32_t subType = getNumber<int32_t>(L, 4, -1);
  7655.  
  7656.     Item* item = g_game.findItemOfType(player, itemId, deepSearch, subType);
  7657.     if (item) {
  7658.         pushUserdata<Item>(L, item);
  7659.         setItemMetatable(L, -1, item);
  7660.     } else {
  7661.         lua_pushnil(L);
  7662.     }
  7663.     return 1;
  7664. }
  7665.  
  7666. int LuaScriptInterface::luaPlayerGetVocation(lua_State* L)
  7667. {
  7668.     // player:getVocation()
  7669.     Player* player = getUserdata<Player>(L, 1);
  7670.     if (player) {
  7671.         pushUserdata<Vocation>(L, player->getVocation());
  7672.         setMetatable(L, -1, "Vocation");
  7673.     } else {
  7674.         lua_pushnil(L);
  7675.     }
  7676.     return 1;
  7677. }
  7678.  
  7679. int LuaScriptInterface::luaPlayerSetVocation(lua_State* L)
  7680. {
  7681.     // player:setVocation(id or name or userdata)
  7682.     Player* player = getUserdata<Player>(L, 1);
  7683.     if (!player) {
  7684.         lua_pushnil(L);
  7685.         return 1;
  7686.     }
  7687.  
  7688.     Vocation* vocation;
  7689.     if (isNumber(L, 2)) {
  7690.         vocation = g_vocations.getVocation(getNumber<uint16_t>(L, 2));
  7691.     } else if (isString(L, 2)) {
  7692.         vocation = g_vocations.getVocation(g_vocations.getVocationId(getString(L, 2)));
  7693.     } else if (isUserdata(L, 2)) {
  7694.         vocation = getUserdata<Vocation>(L, 2);
  7695.     } else {
  7696.         vocation = nullptr;
  7697.     }
  7698.  
  7699.     if (!vocation) {
  7700.         pushBoolean(L, false);
  7701.         return 1;
  7702.     }
  7703.  
  7704.     player->setVocation(vocation->getId());
  7705.     pushBoolean(L, true);
  7706.     return 1;
  7707. }
  7708.  
  7709. int LuaScriptInterface::luaPlayerGetSex(lua_State* L)
  7710. {
  7711.     // player:getSex()
  7712.     Player* player = getUserdata<Player>(L, 1);
  7713.     if (player) {
  7714.         lua_pushnumber(L, player->getSex());
  7715.     } else {
  7716.         lua_pushnil(L);
  7717.     }
  7718.     return 1;
  7719. }
  7720.  
  7721. int LuaScriptInterface::luaPlayerSetSex(lua_State* L)
  7722. {
  7723.     // player:setSex(newSex)
  7724.     Player* player = getUserdata<Player>(L, 1);
  7725.     if (player) {
  7726.         PlayerSex_t newSex = getNumber<PlayerSex_t>(L, 2);
  7727.         player->setSex(newSex);
  7728.         pushBoolean(L, true);
  7729.     } else {
  7730.         lua_pushnil(L);
  7731.     }
  7732.     return 1;
  7733. }
  7734.  
  7735. int LuaScriptInterface::luaPlayerGetTown(lua_State* L)
  7736. {
  7737.     // player:getTown()
  7738.     Player* player = getUserdata<Player>(L, 1);
  7739.     if (player) {
  7740.         pushUserdata<Town>(L, player->getTown());
  7741.         setMetatable(L, -1, "Town");
  7742.     } else {
  7743.         lua_pushnil(L);
  7744.     }
  7745.     return 1;
  7746. }
  7747.  
  7748. int LuaScriptInterface::luaPlayerSetTown(lua_State* L)
  7749. {
  7750.     // player:setTown(town)
  7751.     Town* town = getUserdata<Town>(L, 2);
  7752.     if (!town) {
  7753.         pushBoolean(L, false);
  7754.         return 1;
  7755.     }
  7756.  
  7757.     Player* player = getUserdata<Player>(L, 1);
  7758.     if (player) {
  7759.         player->setTown(town);
  7760.         pushBoolean(L, true);
  7761.     } else {
  7762.         lua_pushnil(L);
  7763.     }
  7764.     return 1;
  7765. }
  7766.  
  7767. int LuaScriptInterface::luaPlayerGetGuild(lua_State* L)
  7768. {
  7769.     // player:getGuild()
  7770.     Player* player = getUserdata<Player>(L, 1);
  7771.     if (!player) {
  7772.         lua_pushnil(L);
  7773.         return 1;
  7774.     }
  7775.  
  7776.     Guild* guild = player->getGuild();
  7777.     if (!guild) {
  7778.         lua_pushnil(L);
  7779.         return 1;
  7780.     }
  7781.  
  7782.     pushUserdata<Guild>(L, guild);
  7783.     setMetatable(L, -1, "Guild");
  7784.     return 1;
  7785. }
  7786.  
  7787. int LuaScriptInterface::luaPlayerSetGuild(lua_State* L)
  7788. {
  7789.     // player:setGuild(guild)
  7790.     Player* player = getUserdata<Player>(L, 1);
  7791.     if (!player) {
  7792.         lua_pushnil(L);
  7793.         return 1;
  7794.     }
  7795.  
  7796.     player->setGuild(getUserdata<Guild>(L, 2));
  7797.     pushBoolean(L, true);
  7798.     return 1;
  7799. }
  7800.  
  7801. int LuaScriptInterface::luaPlayerGetGuildLevel(lua_State* L)
  7802. {
  7803.     // player:getGuildLevel()
  7804.     Player* player = getUserdata<Player>(L, 1);
  7805.     if (player) {
  7806.         lua_pushnumber(L, player->getGuildLevel());
  7807.     } else {
  7808.         lua_pushnil(L);
  7809.     }
  7810.     return 1;
  7811. }
  7812.  
  7813. int LuaScriptInterface::luaPlayerSetGuildLevel(lua_State* L)
  7814. {
  7815.     // player:setGuildLevel(level)
  7816.     uint8_t level = getNumber<uint8_t>(L, 2);
  7817.     Player* player = getUserdata<Player>(L, 1);
  7818.     if (player) {
  7819.         player->setGuildLevel(level);
  7820.         pushBoolean(L, true);
  7821.     } else {
  7822.         lua_pushnil(L);
  7823.     }
  7824.     return 1;
  7825. }
  7826.  
  7827. int LuaScriptInterface::luaPlayerGetGuildNick(lua_State* L)
  7828. {
  7829.     // player:getGuildNick()
  7830.     Player* player = getUserdata<Player>(L, 1);
  7831.     if (player) {
  7832.         pushString(L, player->getGuildNick());
  7833.     } else {
  7834.         lua_pushnil(L);
  7835.     }
  7836.     return 1;
  7837. }
  7838.  
  7839. int LuaScriptInterface::luaPlayerSetGuildNick(lua_State* L)
  7840. {
  7841.     // player:setGuildNick(nick)
  7842.     const std::string& nick = getString(L, 2);
  7843.     Player* player = getUserdata<Player>(L, 1);
  7844.     if (player) {
  7845.         player->setGuildNick(nick);
  7846.         pushBoolean(L, true);
  7847.     } else {
  7848.         lua_pushnil(L);
  7849.     }
  7850.     return 1;
  7851. }
  7852.  
  7853. int LuaScriptInterface::luaPlayerGetGroup(lua_State* L)
  7854. {
  7855.     // player:getGroup()
  7856.     Player* player = getUserdata<Player>(L, 1);
  7857.     if (player) {
  7858.         pushUserdata<Group>(L, player->getGroup());
  7859.         setMetatable(L, -1, "Group");
  7860.     } else {
  7861.         lua_pushnil(L);
  7862.     }
  7863.     return 1;
  7864. }
  7865.  
  7866. int LuaScriptInterface::luaPlayerSetGroup(lua_State* L)
  7867. {
  7868.     // player:setGroup(group)
  7869.     Group* group = getUserdata<Group>(L, 2);
  7870.     if (!group) {
  7871.         pushBoolean(L, false);
  7872.         return 1;
  7873.     }
  7874.  
  7875.     Player* player = getUserdata<Player>(L, 1);
  7876.     if (player) {
  7877.         player->setGroup(group);
  7878.         pushBoolean(L, true);
  7879.     } else {
  7880.         lua_pushnil(L);
  7881.     }
  7882.     return 1;
  7883. }
  7884.  
  7885. int LuaScriptInterface::luaPlayerGetStamina(lua_State* L)
  7886. {
  7887.     // player:getStamina()
  7888.     Player* player = getUserdata<Player>(L, 1);
  7889.     if (player) {
  7890.         lua_pushnumber(L, player->getStaminaMinutes());
  7891.     } else {
  7892.         lua_pushnil(L);
  7893.     }
  7894.     return 1;
  7895. }
  7896.  
  7897. int LuaScriptInterface::luaPlayerSetStamina(lua_State* L)
  7898. {
  7899.     // player:setStamina(stamina)
  7900.     uint16_t stamina = getNumber<uint16_t>(L, 2);
  7901.     Player* player = getUserdata<Player>(L, 1);
  7902.     if (player) {
  7903.         player->staminaMinutes = std::min<uint16_t>(2520, stamina);
  7904.         player->sendStats();
  7905.     } else {
  7906.         lua_pushnil(L);
  7907.     }
  7908.     return 1;
  7909. }
  7910.  
  7911. int LuaScriptInterface::luaPlayerGetSoul(lua_State* L)
  7912. {
  7913.     // player:getSoul()
  7914.     Player* player = getUserdata<Player>(L, 1);
  7915.     if (player) {
  7916.         lua_pushnumber(L, player->getSoul());
  7917.     } else {
  7918.         lua_pushnil(L);
  7919.     }
  7920.     return 1;
  7921. }
  7922.  
  7923. int LuaScriptInterface::luaPlayerAddSoul(lua_State* L)
  7924. {
  7925.     // player:addSoul(soulChange)
  7926.     int32_t soulChange = getNumber<int32_t>(L, 2);
  7927.     Player* player = getUserdata<Player>(L, 1);
  7928.     if (player) {
  7929.         player->changeSoul(soulChange);
  7930.         pushBoolean(L, true);
  7931.     } else {
  7932.         lua_pushnil(L);
  7933.     }
  7934.     return 1;
  7935. }
  7936.  
  7937. int LuaScriptInterface::luaPlayerGetMaxSoul(lua_State* L)
  7938. {
  7939.     // player:getMaxSoul()
  7940.     Player* player = getUserdata<Player>(L, 1);
  7941.     if (player && player->vocation) {
  7942.         lua_pushnumber(L, player->vocation->getSoulMax());
  7943.     } else {
  7944.         lua_pushnil(L);
  7945.     }
  7946.     return 1;
  7947. }
  7948.  
  7949. int LuaScriptInterface::luaPlayerGetBankBalance(lua_State* L)
  7950. {
  7951.     // player:getBankBalance()
  7952.     Player* player = getUserdata<Player>(L, 1);
  7953.     if (player) {
  7954.         lua_pushnumber(L, player->getBankBalance());
  7955.     } else {
  7956.         lua_pushnil(L);
  7957.     }
  7958.     return 1;
  7959. }
  7960.  
  7961. int LuaScriptInterface::luaPlayerSetBankBalance(lua_State* L)
  7962. {
  7963.     // player:setBankBalance(bankBalance)
  7964.     Player* player = getUserdata<Player>(L, 1);
  7965.     if (player) {
  7966.         player->setBankBalance(getNumber<uint64_t>(L, 2));
  7967.         pushBoolean(L, true);
  7968.     } else {
  7969.         lua_pushnil(L);
  7970.     }
  7971.     return 1;
  7972. }
  7973.  
  7974. int LuaScriptInterface::luaPlayerGetStorageValue(lua_State* L)
  7975. {
  7976.     // player:getStorageValue(key)
  7977.     Player* player = getUserdata<Player>(L, 1);
  7978.     if (!player) {
  7979.         lua_pushnil(L);
  7980.         return 1;
  7981.     }
  7982.  
  7983.     uint32_t key = getNumber<uint32_t>(L, 2);
  7984.     int32_t value;
  7985.     if (player->getStorageValue(key, value)) {
  7986.         lua_pushnumber(L, value);
  7987.     } else {
  7988.         lua_pushnumber(L, -1);
  7989.     }
  7990.     return 1;
  7991. }
  7992.  
  7993. int LuaScriptInterface::luaPlayerSetStorageValue(lua_State* L)
  7994. {
  7995.     // player:setStorageValue(key, value)
  7996.     int32_t value = getNumber<int32_t>(L, 3);
  7997.     uint32_t key = getNumber<uint32_t>(L, 2);
  7998.     Player* player = getUserdata<Player>(L, 1);
  7999.     if (IS_IN_KEYRANGE(key, RESERVED_RANGE)) {
  8000.         std::ostringstream ss;
  8001.         ss << "Accessing reserved range: " << key;
  8002.         reportErrorFunc(ss.str());
  8003.         pushBoolean(L, false);
  8004.         return 1;
  8005.     }
  8006.  
  8007.     if (player) {
  8008.         player->addStorageValue(key, value);
  8009.         pushBoolean(L, true);
  8010.     } else {
  8011.         lua_pushnil(L);
  8012.     }
  8013.     return 1;
  8014. }
  8015.  
  8016. int LuaScriptInterface::luaPlayerAddItem(lua_State* L)
  8017. {
  8018.     // player:addItem(itemId[, count = 1[, canDropOnMap = true[, subType = 1[, slot = CONST_SLOT_WHEREEVER]]]])
  8019.     Player* player = getUserdata<Player>(L, 1);
  8020.     if (!player) {
  8021.         pushBoolean(L, false);
  8022.         return 1;
  8023.     }
  8024.  
  8025.     uint16_t itemId;
  8026.     if (isNumber(L, 2)) {
  8027.         itemId = getNumber<uint16_t>(L, 2);
  8028.     } else {
  8029.         itemId = Item::items.getItemIdByName(getString(L, 2));
  8030.         if (itemId == 0) {
  8031.             lua_pushnil(L);
  8032.             return 1;
  8033.         }
  8034.     }
  8035.  
  8036.     int32_t count = getNumber<int32_t>(L, 3, 1);
  8037.     int32_t subType = getNumber<int32_t>(L, 5, 1);
  8038.  
  8039.     const ItemType& it = Item::items[itemId];
  8040.  
  8041.     int32_t itemCount = 1;
  8042.     int parameters = lua_gettop(L);
  8043.     if (parameters >= 4) {
  8044.         itemCount = std::max<int32_t>(1, count);
  8045.     } else if (it.hasSubType()) {
  8046.         if (it.stackable) {
  8047.             itemCount = std::ceil(count / 100.f);
  8048.         }
  8049.  
  8050.         subType = count;
  8051.     } else {
  8052.         itemCount = std::max<int32_t>(1, count);
  8053.     }
  8054.  
  8055.     bool hasTable = itemCount > 1;
  8056.     if (hasTable) {
  8057.         lua_newtable(L);
  8058.     } else if (itemCount == 0) {
  8059.         lua_pushnil(L);
  8060.         return 1;
  8061.     }
  8062.  
  8063.     bool canDropOnMap = getBoolean(L, 4, true);
  8064.     slots_t slot = getNumber<slots_t>(L, 6, CONST_SLOT_WHEREEVER);
  8065.     for (int32_t i = 1; i <= itemCount; ++i) {
  8066.         int32_t stackCount = subType;
  8067.         if (it.stackable) {
  8068.             stackCount = std::min<int32_t>(stackCount, 100);
  8069.             subType -= stackCount;
  8070.         }
  8071.  
  8072.         Item* item = Item::CreateItem(itemId, stackCount);
  8073.         if (!item) {
  8074.             if (!hasTable) {
  8075.                 lua_pushnil(L);
  8076.             }
  8077.             return 1;
  8078.         }
  8079.  
  8080.         ReturnValue ret = g_game.internalPlayerAddItem(player, item, canDropOnMap, slot);
  8081.         if (ret != RETURNVALUE_NOERROR) {
  8082.             delete item;
  8083.             if (!hasTable) {
  8084.                 lua_pushnil(L);
  8085.             }
  8086.             return 1;
  8087.         }
  8088.  
  8089.         if (hasTable) {
  8090.             lua_pushnumber(L, i);
  8091.             pushUserdata<Item>(L, item);
  8092.             setItemMetatable(L, -1, item);
  8093.             lua_settable(L, -3);
  8094.         } else {
  8095.             pushUserdata<Item>(L, item);
  8096.             setItemMetatable(L, -1, item);
  8097.         }
  8098.     }
  8099.     return 1;
  8100. }
  8101.  
  8102. int LuaScriptInterface::luaPlayerAddItemEx(lua_State* L)
  8103. {
  8104.     // player:addItemEx(item[, canDropOnMap = false[, index = INDEX_WHEREEVER[, flags = 0]]])
  8105.     // player:addItemEx(item[, canDropOnMap = true[, slot = CONST_SLOT_WHEREEVER]])
  8106.     Item* item = getUserdata<Item>(L, 2);
  8107.     if (!item) {
  8108.         reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  8109.         pushBoolean(L, false);
  8110.         return 1;
  8111.     }
  8112.  
  8113.     Player* player = getUserdata<Player>(L, 1);
  8114.     if (!player) {
  8115.         lua_pushnil(L);
  8116.         return 1;
  8117.     }
  8118.  
  8119.     if (item->getParent() != VirtualCylinder::virtualCylinder) {
  8120.         reportErrorFunc("Item already has a parent");
  8121.         pushBoolean(L, false);
  8122.         return 1;
  8123.     }
  8124.  
  8125.     bool canDropOnMap = getBoolean(L, 3, false);
  8126.     ReturnValue returnValue;
  8127.     if (canDropOnMap) {
  8128.         slots_t slot = getNumber<slots_t>(L, 4, CONST_SLOT_WHEREEVER);
  8129.         returnValue = g_game.internalPlayerAddItem(player, item, true, slot);
  8130.     } else {
  8131.         int32_t index = getNumber<int32_t>(L, 4, INDEX_WHEREEVER);
  8132.         uint32_t flags = getNumber<uint32_t>(L, 5, 0);
  8133.         returnValue = g_game.internalAddItem(player, item, index, flags);
  8134.     }
  8135.  
  8136.     if (returnValue == RETURNVALUE_NOERROR) {
  8137.         ScriptEnvironment::removeTempItem(item);
  8138.     }
  8139.     lua_pushnumber(L, returnValue);
  8140.     return 1;
  8141. }
  8142.  
  8143. int LuaScriptInterface::luaPlayerRemoveItem(lua_State* L)
  8144. {
  8145.     // player:removeItem(itemId, count[, subType = -1[, ignoreEquipped = false]])
  8146.     Player* player = getUserdata<Player>(L, 1);
  8147.     if (!player) {
  8148.         lua_pushnil(L);
  8149.         return 1;
  8150.     }
  8151.  
  8152.     uint16_t itemId;
  8153.     if (isNumber(L, 2)) {
  8154.         itemId = getNumber<uint16_t>(L, 2);
  8155.     } else {
  8156.         itemId = Item::items.getItemIdByName(getString(L, 2));
  8157.         if (itemId == 0) {
  8158.             lua_pushnil(L);
  8159.             return 1;
  8160.         }
  8161.     }
  8162.  
  8163.     uint32_t count = getNumber<uint32_t>(L, 3);
  8164.     int32_t subType = getNumber<int32_t>(L, 4, -1);
  8165.     bool ignoreEquipped = getBoolean(L, 5, false);
  8166.     pushBoolean(L, player->removeItemOfType(itemId, count, subType, ignoreEquipped));
  8167.     return 1;
  8168. }
  8169.  
  8170. int LuaScriptInterface::luaPlayerGetMoney(lua_State* L)
  8171. {
  8172.     // player:getMoney()
  8173.     Player* player = getUserdata<Player>(L, 1);
  8174.     if (player) {
  8175.         lua_pushnumber(L, player->getMoney());
  8176.     } else {
  8177.         lua_pushnil(L);
  8178.     }
  8179.     return 1;
  8180. }
  8181.  
  8182. int LuaScriptInterface::luaPlayerAddMoney(lua_State* L)
  8183. {
  8184.     // player:addMoney(money)
  8185.     uint64_t money = getNumber<uint64_t>(L, 2);
  8186.     Player* player = getUserdata<Player>(L, 1);
  8187.     if (player) {
  8188.         g_game.addMoney(player, money);
  8189.         pushBoolean(L, true);
  8190.     } else {
  8191.         lua_pushnil(L);
  8192.     }
  8193.     return 1;
  8194. }
  8195.  
  8196. int LuaScriptInterface::luaPlayerRemoveMoney(lua_State* L)
  8197. {
  8198.     // player:removeMoney(money)
  8199.     Player* player = getUserdata<Player>(L, 1);
  8200.     if (player) {
  8201.         uint64_t money = getNumber<uint64_t>(L, 2);
  8202.         pushBoolean(L, g_game.removeMoney(player, money));
  8203.     } else {
  8204.         lua_pushnil(L);
  8205.     }
  8206.     return 1;
  8207. }
  8208.  
  8209. int LuaScriptInterface::luaPlayerShowTextDialog(lua_State* L)
  8210. {
  8211.     // player:showTextDialog(itemId[, text[, canWrite[, length]]])
  8212.     Player* player = getUserdata<Player>(L, 1);
  8213.     if (!player) {
  8214.         lua_pushnil(L);
  8215.         return 1;
  8216.     }
  8217.  
  8218.     int32_t length = getNumber<int32_t>(L, 5, -1);
  8219.     bool canWrite = getBoolean(L, 4, false);
  8220.     std::string text;
  8221.  
  8222.     int parameters = lua_gettop(L);
  8223.     if (parameters >= 3) {
  8224.         text = getString(L, 3);
  8225.     }
  8226.  
  8227.     uint16_t itemId;
  8228.     if (isNumber(L, 2)) {
  8229.         itemId = getNumber<uint16_t>(L, 2);
  8230.     } else {
  8231.         itemId = Item::items.getItemIdByName(getString(L, 2));
  8232.         if (itemId == 0) {
  8233.             lua_pushnil(L);
  8234.             return 1;
  8235.         }
  8236.     }
  8237.  
  8238.     Item* item = Item::CreateItem(itemId);
  8239.     if (!item) {
  8240.         reportErrorFunc(getErrorDesc(LUA_ERROR_ITEM_NOT_FOUND));
  8241.         pushBoolean(L, false);
  8242.         return 1;
  8243.     }
  8244.  
  8245.     if (length < 0) {
  8246.         length = Item::items[item->getID()].maxTextLen;
  8247.     }
  8248.  
  8249.     if (!text.empty()) {
  8250.         item->setText(text);
  8251.         length = std::max<int32_t>(text.size(), length);
  8252.     }
  8253.  
  8254.     item->setParent(player);
  8255.     player->setWriteItem(item, length);
  8256.     player->sendTextWindow(item, length, canWrite);
  8257.     pushBoolean(L, true);
  8258.     return 1;
  8259. }
  8260.  
  8261. int LuaScriptInterface::luaPlayerSendTextMessage(lua_State* L)
  8262. {
  8263.     // player:sendTextMessage(type, text)
  8264.     TextMessage message(getNumber<MessageClasses>(L, 2), getString(L, 3));
  8265.     Player* player = getUserdata<Player>(L, 1);
  8266.     if (player) {
  8267.         player->sendTextMessage(message);
  8268.         pushBoolean(L, true);
  8269.     } else {
  8270.         lua_pushnil(L);
  8271.     }
  8272.     return 1;
  8273. }
  8274.  
  8275. int LuaScriptInterface::luaPlayerSendChannelMessage(lua_State* L)
  8276. {
  8277.     // player:sendChannelMessage(author, text, type, channelId)
  8278.     uint16_t channelId = getNumber<uint16_t>(L, 5);
  8279.     SpeakClasses type = getNumber<SpeakClasses>(L, 4);
  8280.     const std::string& text = getString(L, 3);
  8281.     const std::string& author = getString(L, 2);
  8282.     Player* player = getUserdata<Player>(L, 1);
  8283.     if (player) {
  8284.         player->sendChannelMessage(author, text, type, channelId);
  8285.         pushBoolean(L, true);
  8286.     } else {
  8287.         lua_pushnil(L);
  8288.     }
  8289.     return 1;
  8290. }
  8291.  
  8292. int LuaScriptInterface::luaPlayerSendPrivateMessage(lua_State* L)
  8293. {
  8294.     // player:sendPrivateMessage(speaker, text[, type])
  8295.     Player* player = getUserdata<Player>(L, 1);
  8296.     if (!player) {
  8297.         lua_pushnil(L);
  8298.         return 1;
  8299.     }
  8300.  
  8301.     const Player* speaker = getUserdata<const Player>(L, 2);
  8302.     const std::string& text = getString(L, 3);
  8303.     SpeakClasses type = getNumber<SpeakClasses>(L, 4, TALKTYPE_PRIVATE);
  8304.     player->sendPrivateMessage(speaker, type, text);
  8305.     pushBoolean(L, true);
  8306.     return 1;
  8307. }
  8308.  
  8309. int LuaScriptInterface::luaPlayerChannelSay(lua_State* L)
  8310. {
  8311.     // player:channelSay(speaker, type, text, channelId)
  8312.     Player* player = getUserdata<Player>(L, 1);
  8313.     if (!player) {
  8314.         lua_pushnil(L);
  8315.         return 1;
  8316.     }
  8317.  
  8318.     Creature* speaker = getCreature(L, 2);
  8319.     SpeakClasses type = getNumber<SpeakClasses>(L, 3);
  8320.     const std::string& text = getString(L, 4);
  8321.     uint16_t channelId = getNumber<uint16_t>(L, 5);
  8322.     player->sendToChannel(speaker, type, text, channelId);
  8323.     pushBoolean(L, true);
  8324.     return 1;
  8325. }
  8326.  
  8327. int LuaScriptInterface::luaPlayerOpenChannel(lua_State* L)
  8328. {
  8329.     // player:openChannel(channelId)
  8330.     uint16_t channelId = getNumber<uint16_t>(L, 2);
  8331.     Player* player = getUserdata<Player>(L, 1);
  8332.     if (player) {
  8333.         g_game.playerOpenChannel(player->getID(), channelId);
  8334.         pushBoolean(L, true);
  8335.     } else {
  8336.         lua_pushnil(L);
  8337.     }
  8338.     return 1;
  8339. }
  8340.  
  8341. int LuaScriptInterface::luaPlayerGetSlotItem(lua_State* L)
  8342. {
  8343.     // player:getSlotItem(slot)
  8344.     const Player* player = getUserdata<const Player>(L, 1);
  8345.     if (!player) {
  8346.         lua_pushnil(L);
  8347.         return 1;
  8348.     }
  8349.  
  8350.     uint32_t slot = getNumber<uint32_t>(L, 2);
  8351.     Thing* thing = player->getThing(slot);
  8352.     if (!thing) {
  8353.         lua_pushnil(L);
  8354.         return 1;
  8355.     }
  8356.  
  8357.     Item* item = thing->getItem();
  8358.     if (item) {
  8359.         pushUserdata<Item>(L, item);
  8360.         setItemMetatable(L, -1, item);
  8361.     } else {
  8362.         lua_pushnil(L);
  8363.     }
  8364.     return 1;
  8365. }
  8366.  
  8367. int LuaScriptInterface::luaPlayerGetParty(lua_State* L)
  8368. {
  8369.     // player:getParty()
  8370.     const Player* player = getUserdata<const Player>(L, 1);
  8371.     if (!player) {
  8372.         lua_pushnil(L);
  8373.         return 1;
  8374.     }
  8375.  
  8376.     Party* party = player->getParty();
  8377.     if (party) {
  8378.         pushUserdata<Party>(L, party);
  8379.         setMetatable(L, -1, "Party");
  8380.     } else {
  8381.         lua_pushnil(L);
  8382.     }
  8383.     return 1;
  8384. }
  8385.  
  8386. int LuaScriptInterface::luaPlayerAddOutfit(lua_State* L)
  8387. {
  8388.     // player:addOutfit(lookType)
  8389.     Player* player = getUserdata<Player>(L, 1);
  8390.     if (player) {
  8391.         player->addOutfit(getNumber<uint16_t>(L, 2), 0);
  8392.         pushBoolean(L, true);
  8393.     } else {
  8394.         lua_pushnil(L);
  8395.     }
  8396.     return 1;
  8397. }
  8398.  
  8399. int LuaScriptInterface::luaPlayerAddOutfitAddon(lua_State* L)
  8400. {
  8401.     // player:addOutfitAddon(lookType, addon)
  8402.     Player* player = getUserdata<Player>(L, 1);
  8403.     if (player) {
  8404.         uint16_t lookType = getNumber<uint16_t>(L, 2);
  8405.         uint8_t addon = getNumber<uint8_t>(L, 3);
  8406.         player->addOutfit(lookType, addon);
  8407.         pushBoolean(L, true);
  8408.     } else {
  8409.         lua_pushnil(L);
  8410.     }
  8411.     return 1;
  8412. }
  8413.  
  8414. int LuaScriptInterface::luaPlayerRemoveOutfit(lua_State* L)
  8415. {
  8416.     // player:removeOutfit(lookType)
  8417.     Player* player = getUserdata<Player>(L, 1);
  8418.     if (player) {
  8419.         uint16_t lookType = getNumber<uint16_t>(L, 2);
  8420.         pushBoolean(L, player->removeOutfit(lookType));
  8421.     } else {
  8422.         lua_pushnil(L);
  8423.     }
  8424.     return 1;
  8425. }
  8426.  
  8427. int LuaScriptInterface::luaPlayerRemoveOutfitAddon(lua_State* L)
  8428. {
  8429.     // player:removeOutfitAddon(lookType, addon)
  8430.     Player* player = getUserdata<Player>(L, 1);
  8431.     if (player) {
  8432.         uint16_t lookType = getNumber<uint16_t>(L, 2);
  8433.         uint8_t addon = getNumber<uint8_t>(L, 3);
  8434.         pushBoolean(L, player->removeOutfitAddon(lookType, addon));
  8435.     } else {
  8436.         lua_pushnil(L);
  8437.     }
  8438.     return 1;
  8439. }
  8440.  
  8441. int LuaScriptInterface::luaPlayerHasOutfit(lua_State* L)
  8442. {
  8443.     // player:hasOutfit(lookType[, addon = 0])
  8444.     Player* player = getUserdata<Player>(L, 1);
  8445.     if (player) {
  8446.         uint16_t lookType = getNumber<uint16_t>(L, 2);
  8447.         uint8_t addon = getNumber<uint8_t>(L, 3, 0);
  8448.         pushBoolean(L, player->canWear(lookType, addon));
  8449.     } else {
  8450.         lua_pushnil(L);
  8451.     }
  8452.     return 1;
  8453. }
  8454.  
  8455. int LuaScriptInterface::luaPlayerSendOutfitWindow(lua_State* L)
  8456. {
  8457.     // player:sendOutfitWindow()
  8458.     Player* player = getUserdata<Player>(L, 1);
  8459.     if (player) {
  8460.         player->sendOutfitWindow();
  8461.         pushBoolean(L, true);
  8462.     } else {
  8463.         lua_pushnil(L);
  8464.     }
  8465.     return 1;
  8466. }
  8467.  
  8468. int LuaScriptInterface::luaPlayerGetPremiumDays(lua_State* L)
  8469. {
  8470.     // player:getPremiumDays()
  8471.     Player* player = getUserdata<Player>(L, 1);
  8472.     if (player) {
  8473.         lua_pushnumber(L, player->premiumDays);
  8474.     } else {
  8475.         lua_pushnil(L);
  8476.     }
  8477.     return 1;
  8478. }
  8479.  
  8480. int LuaScriptInterface::luaPlayerAddPremiumDays(lua_State* L)
  8481. {
  8482.     // player:addPremiumDays(days)
  8483.     Player* player = getUserdata<Player>(L, 1);
  8484.     if (!player) {
  8485.         lua_pushnil(L);
  8486.         return 1;
  8487.     }
  8488.  
  8489.     if (player->premiumDays != std::numeric_limits<uint16_t>::max()) {
  8490.         uint16_t days = getNumber<uint16_t>(L, 2);
  8491.         int32_t addDays = std::min<int32_t>(0xFFFE - player->premiumDays, days);
  8492.         if (addDays > 0) {
  8493.             player->setPremiumDays(player->premiumDays + addDays);
  8494.             IOLoginData::addPremiumDays(player->getAccount(), addDays);
  8495.         }
  8496.     }
  8497.     pushBoolean(L, true);
  8498.     return 1;
  8499. }
  8500.  
  8501. int LuaScriptInterface::luaPlayerRemovePremiumDays(lua_State* L)
  8502. {
  8503.     // player:removePremiumDays(days)
  8504.     Player* player = getUserdata<Player>(L, 1);
  8505.     if (!player) {
  8506.         lua_pushnil(L);
  8507.         return 1;
  8508.     }
  8509.  
  8510.     if (player->premiumDays != std::numeric_limits<uint16_t>::max()) {
  8511.         uint16_t days = getNumber<uint16_t>(L, 2);
  8512.         int32_t removeDays = std::min<int32_t>(player->premiumDays, days);
  8513.         if (removeDays > 0) {
  8514.             player->setPremiumDays(player->premiumDays - removeDays);
  8515.             IOLoginData::removePremiumDays(player->getAccount(), removeDays);
  8516.         }
  8517.     }
  8518.     pushBoolean(L, true);
  8519.     return 1;
  8520. }
  8521.  
  8522. int LuaScriptInterface::luaPlayerHasBlessing(lua_State* L)
  8523. {
  8524.     // player:hasBlessing(blessing)
  8525.     uint8_t blessing = getNumber<uint8_t>(L, 2) - 1;
  8526.     Player* player = getUserdata<Player>(L, 1);
  8527.     if (player) {
  8528.         pushBoolean(L, player->hasBlessing(blessing));
  8529.     } else {
  8530.         lua_pushnil(L);
  8531.     }
  8532.     return 1;
  8533. }
  8534.  
  8535. int LuaScriptInterface::luaPlayerAddBlessing(lua_State* L)
  8536. {
  8537.     // player:addBlessing(blessing)
  8538.     Player* player = getUserdata<Player>(L, 1);
  8539.     if (!player) {
  8540.         lua_pushnil(L);
  8541.         return 1;
  8542.     }
  8543.  
  8544.     uint8_t blessing = getNumber<uint8_t>(L, 2) - 1;
  8545.     if (player->hasBlessing(blessing)) {
  8546.         pushBoolean(L, false);
  8547.         return 1;
  8548.     }
  8549.  
  8550.     player->addBlessing(1 << blessing);
  8551.     pushBoolean(L, true);
  8552.     return 1;
  8553. }
  8554.  
  8555. int LuaScriptInterface::luaPlayerRemoveBlessing(lua_State* L)
  8556. {
  8557.     // player:removeBlessing(blessing)
  8558.     Player* player = getUserdata<Player>(L, 1);
  8559.     if (!player) {
  8560.         lua_pushnil(L);
  8561.         return 1;
  8562.     }
  8563.  
  8564.     uint8_t blessing = getNumber<uint8_t>(L, 2) - 1;
  8565.     if (!player->hasBlessing(blessing)) {
  8566.         pushBoolean(L, false);
  8567.         return 1;
  8568.     }
  8569.  
  8570.     player->removeBlessing(1 << blessing);
  8571.     pushBoolean(L, true);
  8572.     return 1;
  8573. }
  8574.  
  8575. int LuaScriptInterface::luaPlayerCanLearnSpell(lua_State* L)
  8576. {
  8577.     // player:canLearnSpell(spellName)
  8578.     const Player* player = getUserdata<const Player>(L, 1);
  8579.     if (!player) {
  8580.         lua_pushnil(L);
  8581.         return 1;
  8582.     }
  8583.  
  8584.     const std::string& spellName = getString(L, 2);
  8585.     InstantSpell* spell = g_spells->getInstantSpellByName(spellName);
  8586.     if (!spell) {
  8587.         reportErrorFunc("Spell \"" + spellName + "\" not found");
  8588.         pushBoolean(L, false);
  8589.         return 1;
  8590.     }
  8591.  
  8592.     if (player->hasFlag(PlayerFlag_IgnoreSpellCheck)) {
  8593.         pushBoolean(L, true);
  8594.         return 1;
  8595.     }
  8596.  
  8597.     const auto& vocMap = spell->getVocMap();
  8598.     if (vocMap.count(player->getVocationId()) == 0) {
  8599.         pushBoolean(L, false);
  8600.     } else if (player->getLevel() < spell->getLevel()) {
  8601.         pushBoolean(L, false);
  8602.     } else if (player->getMagicLevel() < spell->getMagicLevel()) {
  8603.         pushBoolean(L, false);
  8604.     } else {
  8605.         pushBoolean(L, true);
  8606.     }
  8607.     return 1;
  8608. }
  8609.  
  8610. int LuaScriptInterface::luaPlayerLearnSpell(lua_State* L)
  8611. {
  8612.     // player:learnSpell(spellName)
  8613.     Player* player = getUserdata<Player>(L, 1);
  8614.     if (player) {
  8615.         const std::string& spellName = getString(L, 2);
  8616.         player->learnInstantSpell(spellName);
  8617.         pushBoolean(L, true);
  8618.     } else {
  8619.         lua_pushnil(L);
  8620.     }
  8621.     return 1;
  8622. }
  8623.  
  8624. int LuaScriptInterface::luaPlayerForgetSpell(lua_State* L)
  8625. {
  8626.     // player:forgetSpell(spellName)
  8627.     Player* player = getUserdata<Player>(L, 1);
  8628.     if (player) {
  8629.         const std::string& spellName = getString(L, 2);
  8630.         player->forgetInstantSpell(spellName);
  8631.         pushBoolean(L, true);
  8632.     } else {
  8633.         lua_pushnil(L);
  8634.     }
  8635.     return 1;
  8636. }
  8637.  
  8638. int LuaScriptInterface::luaPlayerHasLearnedSpell(lua_State* L)
  8639. {
  8640.     // player:hasLearnedSpell(spellName)
  8641.     Player* player = getUserdata<Player>(L, 1);
  8642.     if (player) {
  8643.         const std::string& spellName = getString(L, 2);
  8644.         pushBoolean(L, player->hasLearnedInstantSpell(spellName));
  8645.     } else {
  8646.         lua_pushnil(L);
  8647.     }
  8648.     return 1;
  8649. }
  8650.  
  8651. int LuaScriptInterface::luaPlayerSendTutorial(lua_State* L)
  8652. {
  8653.     // player:sendTutorial(tutorialId)
  8654.     Player* player = getUserdata<Player>(L, 1);
  8655.     if (player) {
  8656.         uint8_t tutorialId = getNumber<uint8_t>(L, 2);
  8657.         player->sendTutorial(tutorialId);
  8658.         pushBoolean(L, true);
  8659.     } else {
  8660.         lua_pushnil(L);
  8661.     }
  8662.     return 1;
  8663. }
  8664.  
  8665. int LuaScriptInterface::luaPlayerAddMapMark(lua_State* L)
  8666. {
  8667.     // player:addMapMark(position, type, description)
  8668.     Player* player = getUserdata<Player>(L, 1);
  8669.     if (player) {
  8670.         const Position& position = getPosition(L, 2);
  8671.         uint8_t type = getNumber<uint8_t>(L, 3);
  8672.         const std::string& description = getString(L, 4);
  8673.         player->sendAddMarker(position, type, description);
  8674.         pushBoolean(L, true);
  8675.     } else {
  8676.         lua_pushnil(L);
  8677.     }
  8678.     return 1;
  8679. }
  8680.  
  8681. int LuaScriptInterface::luaPlayerSave(lua_State* L)
  8682. {
  8683.     // player:save()
  8684.     Player* player = getUserdata<Player>(L, 1);
  8685.     if (player) {
  8686.         player->loginPosition = player->getPosition();
  8687.         pushBoolean(L, IOLoginData::savePlayer(player));
  8688.     } else {
  8689.         lua_pushnil(L);
  8690.     }
  8691.     return 1;
  8692. }
  8693.  
  8694. int LuaScriptInterface::luaPlayerPopupFYI(lua_State* L)
  8695. {
  8696.     // player:popupFYI(message)
  8697.     Player* player = getUserdata<Player>(L, 1);
  8698.     if (player) {
  8699.         const std::string& message = getString(L, 2);
  8700.         player->sendFYIBox(message);
  8701.         pushBoolean(L, true);
  8702.     } else {
  8703.         lua_pushnil(L);
  8704.     }
  8705.     return 1;
  8706. }
  8707.  
  8708. int LuaScriptInterface::luaPlayerIsPzLocked(lua_State* L)
  8709. {
  8710.     // player:isPzLocked()
  8711.     Player* player = getUserdata<Player>(L, 1);
  8712.     if (player) {
  8713.         pushBoolean(L, player->isPzLocked());
  8714.     } else {
  8715.         lua_pushnil(L);
  8716.     }
  8717.     return 1;
  8718. }
  8719.  
  8720. int LuaScriptInterface::luaPlayerGetClient(lua_State* L)
  8721. {
  8722.     // player:getClient()
  8723.     Player* player = getUserdata<Player>(L, 1);
  8724.     if (player) {
  8725.         lua_createtable(L, 0, 2);
  8726.         setField(L, "version", player->getProtocolVersion());
  8727.         setField(L, "os", player->getOperatingSystem());
  8728.     } else {
  8729.         lua_pushnil(L);
  8730.     }
  8731.     return 1;
  8732. }
  8733.  
  8734. int LuaScriptInterface::luaPlayerGetHouse(lua_State* L)
  8735. {
  8736.     // player:getHouse()
  8737.     Player* player = getUserdata<Player>(L, 1);
  8738.     if (!player) {
  8739.         lua_pushnil(L);
  8740.         return 1;
  8741.     }
  8742.  
  8743.     House* house = g_game.map.houses.getHouseByPlayerId(player->getGUID());
  8744.     if (house) {
  8745.         pushUserdata<House>(L, house);
  8746.         setMetatable(L, -1, "House");
  8747.     } else {
  8748.         lua_pushnil(L);
  8749.     }
  8750.     return 1;
  8751. }
  8752.  
  8753. int LuaScriptInterface::luaPlayerSetGhostMode(lua_State* L)
  8754. {
  8755.     // player:setGhostMode(enabled)
  8756.     Player* player = getUserdata<Player>(L, 1);
  8757.     if (!player) {
  8758.         lua_pushnil(L);
  8759.         return 1;
  8760.     }
  8761.  
  8762.     bool enabled = getBoolean(L, 2);
  8763.     if (player->isInGhostMode() == enabled) {
  8764.         pushBoolean(L, true);
  8765.         return 1;
  8766.     }
  8767.  
  8768.     player->switchGhostMode();
  8769.  
  8770.     Tile* tile = player->getTile();
  8771.     const Position& position = player->getPosition();
  8772.  
  8773.     SpectatorVec list;
  8774.     g_game.map.getSpectators(list, position, true, true);
  8775.     for (Creature* spectator : list) {
  8776.         Player* tmpPlayer = spectator->getPlayer();
  8777.         if (tmpPlayer != player && !tmpPlayer->isAccessPlayer()) {
  8778.             if (enabled) {
  8779.                 tmpPlayer->sendRemoveTileThing(position, tile->getStackposOfCreature(tmpPlayer, player));
  8780.             } else {
  8781.                 tmpPlayer->sendCreatureAppear(player, position, true);
  8782.             }
  8783.         } else {
  8784.             tmpPlayer->sendCreatureChangeVisible(player, !enabled);
  8785.         }
  8786.     }
  8787.  
  8788.     if (player->isInGhostMode()) {
  8789.         for (const auto& it : g_game.getPlayers()) {
  8790.             if (!it.second->isAccessPlayer()) {
  8791.                 it.second->notifyStatusChange(player, false);
  8792.             }
  8793.         }
  8794.         IOLoginData::updateOnlineStatus(player->getGUID(), false);
  8795.     } else {
  8796.         for (const auto& it : g_game.getPlayers()) {
  8797.             if (!it.second->isAccessPlayer()) {
  8798.                 it.second->notifyStatusChange(player, true);
  8799.             }
  8800.         }
  8801.         IOLoginData::updateOnlineStatus(player->getGUID(), true);
  8802.     }
  8803.     pushBoolean(L, true);
  8804.     return 1;
  8805. }
  8806.  
  8807. int LuaScriptInterface::luaPlayerGetContainerId(lua_State* L)
  8808. {
  8809.     // player:getContainerId(container)
  8810.     Player* player = getUserdata<Player>(L, 1);
  8811.     if (!player) {
  8812.         lua_pushnil(L);
  8813.         return 1;
  8814.     }
  8815.  
  8816.     Container* container = getUserdata<Container>(L, 2);
  8817.     if (container) {
  8818.         lua_pushnumber(L, player->getContainerID(container));
  8819.     } else {
  8820.         lua_pushnil(L);
  8821.     }
  8822.     return 1;
  8823. }
  8824.  
  8825. int LuaScriptInterface::luaPlayerGetContainerById(lua_State* L)
  8826. {
  8827.     // player:getContainerById(id)
  8828.     Player* player = getUserdata<Player>(L, 1);
  8829.     if (!player) {
  8830.         lua_pushnil(L);
  8831.         return 1;
  8832.     }
  8833.  
  8834.     Container* container = player->getContainerByID(getNumber<uint8_t>(L, 2));
  8835.     if (container) {
  8836.         pushUserdata<Container>(L, container);
  8837.         setMetatable(L, -1, "Container");
  8838.     } else {
  8839.         lua_pushnil(L);
  8840.     }
  8841.     return 1;
  8842. }
  8843.  
  8844. int LuaScriptInterface::luaPlayerGetContainerIndex(lua_State* L)
  8845. {
  8846.     // player:getContainerIndex(id)
  8847.     Player* player = getUserdata<Player>(L, 1);
  8848.     if (player) {
  8849.         lua_pushnumber(L, player->getContainerIndex(getNumber<uint8_t>(L, 2)));
  8850.     } else {
  8851.         lua_pushnil(L);
  8852.     }
  8853.     return 1;
  8854. }
  8855.  
  8856. // Monster
  8857. int LuaScriptInterface::luaMonsterCreate(lua_State* L)
  8858. {
  8859.     // Monster(id or userdata)
  8860.     Monster* monster;
  8861.     if (isNumber(L, 2)) {
  8862.         monster = g_game.getMonsterByID(getNumber<uint32_t>(L, 2));
  8863.     } else if (isUserdata(L, 2)) {
  8864.         if (getUserdataType(L, 2) != LuaData_Monster) {
  8865.             lua_pushnil(L);
  8866.             return 1;
  8867.         }
  8868.         monster = getUserdata<Monster>(L, 2);
  8869.     } else {
  8870.         monster = nullptr;
  8871.     }
  8872.  
  8873.     if (monster) {
  8874.         pushUserdata<Monster>(L, monster);
  8875.         setMetatable(L, -1, "Monster");
  8876.     } else {
  8877.         lua_pushnil(L);
  8878.     }
  8879.     return 1;
  8880. }
  8881.  
  8882. int LuaScriptInterface::luaMonsterIsMonster(lua_State* L)
  8883. {
  8884.     // monster:isMonster()
  8885.     pushBoolean(L, getUserdata<const Monster>(L, 1) != nullptr);
  8886.     return 1;
  8887. }
  8888.  
  8889. int LuaScriptInterface::luaMonsterGetType(lua_State* L)
  8890. {
  8891.     // monster:getType()
  8892.     const Monster* monster = getUserdata<const Monster>(L, 1);
  8893.     if (monster) {
  8894.         pushUserdata<MonsterType>(L, monster->mType);
  8895.         setMetatable(L, -1, "MonsterType");
  8896.     } else {
  8897.         lua_pushnil(L);
  8898.     }
  8899.     return 1;
  8900. }
  8901.  
  8902. int LuaScriptInterface::luaMonsterGetSpawnPosition(lua_State* L)
  8903. {
  8904.     // monster:getSpawnPosition()
  8905.     const Monster* monster = getUserdata<const Monster>(L, 1);
  8906.     if (monster) {
  8907.         pushPosition(L, monster->getMasterPos());
  8908.     } else {
  8909.         lua_pushnil(L);
  8910.     }
  8911.     return 1;
  8912. }
  8913.  
  8914. int LuaScriptInterface::luaMonsterIsInSpawnRange(lua_State* L)
  8915. {
  8916.     // monster:isInSpawnRange([position])
  8917.     Monster* monster = getUserdata<Monster>(L, 1);
  8918.     if (monster) {
  8919.         pushBoolean(L, monster->isInSpawnRange(lua_gettop(L) >= 2 ? getPosition(L, 2) : monster->getPosition()));
  8920.     } else {
  8921.         lua_pushnil(L);
  8922.     }
  8923.     return 1;
  8924. }
  8925.  
  8926. int LuaScriptInterface::luaMonsterIsIdle(lua_State* L)
  8927. {
  8928.     // monster:isIdle()
  8929.     Monster* monster = getUserdata<Monster>(L, 1);
  8930.     if (monster) {
  8931.         pushBoolean(L, monster->getIdleStatus());
  8932.     } else {
  8933.         lua_pushnil(L);
  8934.     }
  8935.     return 1;
  8936. }
  8937.  
  8938. int LuaScriptInterface::luaMonsterSetIdle(lua_State* L)
  8939. {
  8940.     // monster:setIdle(idle)
  8941.     Monster* monster = getUserdata<Monster>(L, 1);
  8942.     if (!monster) {
  8943.         lua_pushnil(L);
  8944.         return 1;
  8945.     }
  8946.  
  8947.     monster->setIdle(getBoolean(L, 2));
  8948.     pushBoolean(L, true);
  8949.     return 1;
  8950. }
  8951.  
  8952. int LuaScriptInterface::luaMonsterIsTarget(lua_State* L)
  8953. {
  8954.     // monster:isTarget(creature)
  8955.     Monster* monster = getUserdata<Monster>(L, 1);
  8956.     if (monster) {
  8957.         const Creature* creature = getCreature(L, 2);
  8958.         pushBoolean(L, monster->isTarget(creature));
  8959.     } else {
  8960.         lua_pushnil(L);
  8961.     }
  8962.     return 1;
  8963. }
  8964.  
  8965. int LuaScriptInterface::luaMonsterIsOpponent(lua_State* L)
  8966. {
  8967.     // monster:isOpponent(creature)
  8968.     Monster* monster = getUserdata<Monster>(L, 1);
  8969.     if (monster) {
  8970.         const Creature* creature = getCreature(L, 2);
  8971.         pushBoolean(L, monster->isOpponent(creature));
  8972.     } else {
  8973.         lua_pushnil(L);
  8974.     }
  8975.     return 1;
  8976. }
  8977.  
  8978. int LuaScriptInterface::luaMonsterIsFriend(lua_State* L)
  8979. {
  8980.     // monster:isFriend(creature)
  8981.     Monster* monster = getUserdata<Monster>(L, 1);
  8982.     if (monster) {
  8983.         const Creature* creature = getCreature(L, 2);
  8984.         pushBoolean(L, monster->isFriend(creature));
  8985.     } else {
  8986.         lua_pushnil(L);
  8987.     }
  8988.     return 1;
  8989. }
  8990.  
  8991. int LuaScriptInterface::luaMonsterAddFriend(lua_State* L)
  8992. {
  8993.     // monster:addFriend(creature)
  8994.     Monster* monster = getUserdata<Monster>(L, 1);
  8995.     if (monster) {
  8996.         Creature* creature = getCreature(L, 2);
  8997.         monster->addFriend(creature);
  8998.         pushBoolean(L, true);
  8999.     } else {
  9000.         lua_pushnil(L);
  9001.     }
  9002.     return 1;
  9003. }
  9004.  
  9005. int LuaScriptInterface::luaMonsterRemoveFriend(lua_State* L)
  9006. {
  9007.     // monster:removeFriend(creature)
  9008.     Monster* monster = getUserdata<Monster>(L, 1);
  9009.     if (monster) {
  9010.         Creature* creature = getCreature(L, 2);
  9011.         monster->removeFriend(creature);
  9012.         pushBoolean(L, true);
  9013.     } else {
  9014.         lua_pushnil(L);
  9015.     }
  9016.     return 1;
  9017. }
  9018.  
  9019. int LuaScriptInterface::luaMonsterGetFriendList(lua_State* L)
  9020. {
  9021.     // monster:getFriendList()
  9022.     Monster* monster = getUserdata<Monster>(L, 1);
  9023.     if (!monster) {
  9024.         lua_pushnil(L);
  9025.         return 1;
  9026.     }
  9027.  
  9028.     const auto& friendList = monster->getFriendList();
  9029.     lua_createtable(L, friendList.size(), 0);
  9030.  
  9031.     int index = 0;
  9032.     for (Creature* creature : friendList) {
  9033.         pushUserdata<Creature>(L, creature);
  9034.         setCreatureMetatable(L, -1, creature);
  9035.         lua_rawseti(L, -2, ++index);
  9036.     }
  9037.     return 1;
  9038. }
  9039.  
  9040. int LuaScriptInterface::luaMonsterGetFriendCount(lua_State* L)
  9041. {
  9042.     // monster:getFriendCount()
  9043.     Monster* monster = getUserdata<Monster>(L, 1);
  9044.     if (monster) {
  9045.         lua_pushnumber(L, monster->getFriendList().size());
  9046.     } else {
  9047.         lua_pushnil(L);
  9048.     }
  9049.     return 1;
  9050. }
  9051.  
  9052. int LuaScriptInterface::luaMonsterAddTarget(lua_State* L)
  9053. {
  9054.     // monster:addTarget(creature[, pushFront = false])
  9055.     Monster* monster = getUserdata<Monster>(L, 1);
  9056.     if (!monster) {
  9057.         lua_pushnil(L);
  9058.         return 1;
  9059.     }
  9060.  
  9061.     Creature* creature = getCreature(L, 2);
  9062.     bool pushFront = getBoolean(L, 3, false);
  9063.     monster->addTarget(creature, pushFront);
  9064.     pushBoolean(L, true);
  9065.     return 1;
  9066. }
  9067.  
  9068. int LuaScriptInterface::luaMonsterRemoveTarget(lua_State* L)
  9069. {
  9070.     // monster:removeTarget(creature)
  9071.     Monster* monster = getUserdata<Monster>(L, 1);
  9072.     if (!monster) {
  9073.         lua_pushnil(L);
  9074.         return 1;
  9075.     }
  9076.  
  9077.     monster->removeTarget(getCreature(L, 2));
  9078.     pushBoolean(L, true);
  9079.     return 1;
  9080. }
  9081.  
  9082. int LuaScriptInterface::luaMonsterGetTargetList(lua_State* L)
  9083. {
  9084.     // monster:getTargetList()
  9085.     Monster* monster = getUserdata<Monster>(L, 1);
  9086.     if (!monster) {
  9087.         lua_pushnil(L);
  9088.         return 1;
  9089.     }
  9090.  
  9091.     const auto& targetList = monster->getTargetList();
  9092.     lua_createtable(L, targetList.size(), 0);
  9093.  
  9094.     int index = 0;
  9095.     for (Creature* creature : targetList) {
  9096.         pushUserdata<Creature>(L, creature);
  9097.         setCreatureMetatable(L, -1, creature);
  9098.         lua_rawseti(L, -2, ++index);
  9099.     }
  9100.     return 1;
  9101. }
  9102.  
  9103. int LuaScriptInterface::luaMonsterGetTargetCount(lua_State* L)
  9104. {
  9105.     // monster:getTargetCount()
  9106.     Monster* monster = getUserdata<Monster>(L, 1);
  9107.     if (monster) {
  9108.         lua_pushnumber(L, monster->getTargetList().size());
  9109.     } else {
  9110.         lua_pushnil(L);
  9111.     }
  9112.     return 1;
  9113. }
  9114.  
  9115. int LuaScriptInterface::luaMonsterSelectTarget(lua_State* L)
  9116. {
  9117.     // monster:selectTarget(creature)
  9118.     Monster* monster = getUserdata<Monster>(L, 1);
  9119.     if (monster) {
  9120.         Creature* creature = getCreature(L, 2);
  9121.         pushBoolean(L, monster->selectTarget(creature));
  9122.     } else {
  9123.         lua_pushnil(L);
  9124.     }
  9125.     return 1;
  9126. }
  9127.  
  9128. int LuaScriptInterface::luaMonsterSearchTarget(lua_State* L)
  9129. {
  9130.     // monster:searchTarget([searchType = TARGETSEARCH_DEFAULT])
  9131.     Monster* monster = getUserdata<Monster>(L, 1);
  9132.     if (monster) {
  9133.         TargetSearchType_t searchType = getNumber<TargetSearchType_t>(L, 2, TARGETSEARCH_DEFAULT);
  9134.         pushBoolean(L, monster->searchTarget(searchType));
  9135.     } else {
  9136.         lua_pushnil(L);
  9137.     }
  9138.     return 1;
  9139. }
  9140.  
  9141. // Npc
  9142. int LuaScriptInterface::luaNpcCreate(lua_State* L)
  9143. {
  9144.     // Npc([id or name or userdata])
  9145.     Npc* npc;
  9146.     if (lua_gettop(L) >= 2) {
  9147.         if (isNumber(L, 2)) {
  9148.             npc = g_game.getNpcByID(getNumber<uint32_t>(L, 2));
  9149.         } else if (isString(L, 2)) {
  9150.             npc = g_game.getNpcByName(getString(L, 2));
  9151.         } else if (isUserdata(L, 2)) {
  9152.             if (getUserdataType(L, 2) != LuaData_Npc) {
  9153.                 lua_pushnil(L);
  9154.                 return 1;
  9155.             }
  9156.             npc = getUserdata<Npc>(L, 2);
  9157.         } else {
  9158.             npc = nullptr;
  9159.         }
  9160.     } else {
  9161.         npc = getScriptEnv()->getNpc();
  9162.     }
  9163.  
  9164.     if (npc) {
  9165.         pushUserdata<Npc>(L, npc);
  9166.         setMetatable(L, -1, "Npc");
  9167.     } else {
  9168.         lua_pushnil(L);
  9169.     }
  9170.     return 1;
  9171. }
  9172.  
  9173. int LuaScriptInterface::luaNpcIsNpc(lua_State* L)
  9174. {
  9175.     // npc:isNpc()
  9176.     pushBoolean(L, getUserdata<const Npc>(L, 1) != nullptr);
  9177.     return 1;
  9178. }
  9179.  
  9180. int LuaScriptInterface::luaNpcSetMasterPos(lua_State* L)
  9181. {
  9182.     // npc:setMasterPos(pos[, radius])
  9183.     Npc* npc = getUserdata<Npc>(L, 1);
  9184.     if (!npc) {
  9185.         lua_pushnil(L);
  9186.         return 1;
  9187.     }
  9188.  
  9189.     const Position& pos = getPosition(L, 2);
  9190.     int32_t radius = getNumber<int32_t>(L, 3, 1);
  9191.     npc->setMasterPos(pos, radius);
  9192.     pushBoolean(L, true);
  9193.     return 1;
  9194. }
  9195.  
  9196. // Guild
  9197. int LuaScriptInterface::luaGuildCreate(lua_State* L)
  9198. {
  9199.     // Guild(id)
  9200.     uint32_t id = getNumber<uint32_t>(L, 2);
  9201.  
  9202.     Guild* guild = g_game.getGuild(id);
  9203.     if (guild) {
  9204.         pushUserdata<Guild>(L, guild);
  9205.         setMetatable(L, -1, "Guild");
  9206.     } else {
  9207.         lua_pushnil(L);
  9208.     }
  9209.     return 1;
  9210. }
  9211.  
  9212. int LuaScriptInterface::luaGuildGetId(lua_State* L)
  9213. {
  9214.     // guild:getId()
  9215.     Guild* guild = getUserdata<Guild>(L, 1);
  9216.     if (guild) {
  9217.         lua_pushnumber(L, guild->getId());
  9218.     } else {
  9219.         lua_pushnil(L);
  9220.     }
  9221.     return 1;
  9222. }
  9223.  
  9224. int LuaScriptInterface::luaGuildGetName(lua_State* L)
  9225. {
  9226.     // guild:getName()
  9227.     Guild* guild = getUserdata<Guild>(L, 1);
  9228.     if (guild) {
  9229.         pushString(L, guild->getName());
  9230.     } else {
  9231.         lua_pushnil(L);
  9232.     }
  9233.     return 1;
  9234. }
  9235.  
  9236. int LuaScriptInterface::luaGuildGetMembersOnline(lua_State* L)
  9237. {
  9238.     // guild:getMembersOnline()
  9239.     const Guild* guild = getUserdata<const Guild>(L, 1);
  9240.     if (!guild) {
  9241.         lua_pushnil(L);
  9242.         return 1;
  9243.     }
  9244.  
  9245.     const auto& members = guild->getMembersOnline();
  9246.     lua_createtable(L, members.size(), 0);
  9247.  
  9248.     int index = 0;
  9249.     for (Player* player : members) {
  9250.         pushUserdata<Player>(L, player);
  9251.         setMetatable(L, -1, "Player");
  9252.         lua_rawseti(L, -2, ++index);
  9253.     }
  9254.     return 1;
  9255. }
  9256.  
  9257. int LuaScriptInterface::luaGuildAddRank(lua_State* L)
  9258. {
  9259.     // guild:addRank(id, name, level)
  9260.     Guild* guild = getUserdata<Guild>(L, 1);
  9261.     if (guild) {
  9262.         uint32_t id = getNumber<uint32_t>(L, 2);
  9263.         const std::string& name = getString(L, 3);
  9264.         uint8_t level = getNumber<uint8_t>(L, 4);
  9265.         guild->addRank(id, name, level);
  9266.         pushBoolean(L, true);
  9267.     } else {
  9268.         lua_pushnil(L);
  9269.     }
  9270.     return 1;
  9271. }
  9272.  
  9273. int LuaScriptInterface::luaGuildGetRankById(lua_State* L)
  9274. {
  9275.     // guild:getRankById(id)
  9276.     Guild* guild = getUserdata<Guild>(L, 1);
  9277.     if (!guild) {
  9278.         lua_pushnil(L);
  9279.         return 1;
  9280.     }
  9281.  
  9282.     uint32_t id = getNumber<uint32_t>(L, 2);
  9283.     GuildRank* rank = guild->getRankById(id);
  9284.     if (rank) {
  9285.         lua_createtable(L, 0, 3);
  9286.         setField(L, "id", rank->id);
  9287.         setField(L, "name", rank->name);
  9288.         setField(L, "level", rank->level);
  9289.     } else {
  9290.         lua_pushnil(L);
  9291.     }
  9292.     return 1;
  9293. }
  9294.  
  9295. int LuaScriptInterface::luaGuildGetRankByLevel(lua_State* L)
  9296. {
  9297.     // guild:getRankByLevel(level)
  9298.     const Guild* guild = getUserdata<const Guild>(L, 1);
  9299.     if (!guild) {
  9300.         lua_pushnil(L);
  9301.         return 1;
  9302.     }
  9303.  
  9304.     uint8_t level = getNumber<uint8_t>(L, 2);
  9305.     const GuildRank* rank = guild->getRankByLevel(level);
  9306.     if (rank) {
  9307.         lua_createtable(L, 0, 3);
  9308.         setField(L, "id", rank->id);
  9309.         setField(L, "name", rank->name);
  9310.         setField(L, "level", rank->level);
  9311.     } else {
  9312.         lua_pushnil(L);
  9313.     }
  9314.     return 1;
  9315. }
  9316.  
  9317. int LuaScriptInterface::luaGuildGetMotd(lua_State* L)
  9318. {
  9319.     // guild:getMotd()
  9320.     Guild* guild = getUserdata<Guild>(L, 1);
  9321.     if (guild) {
  9322.         pushString(L, guild->getMotd());
  9323.     } else {
  9324.         lua_pushnil(L);
  9325.     }
  9326.     return 1;
  9327. }
  9328.  
  9329. int LuaScriptInterface::luaGuildSetMotd(lua_State* L)
  9330. {
  9331.     // guild:setMotd(motd)
  9332.     const std::string& motd = getString(L, 2);
  9333.     Guild* guild = getUserdata<Guild>(L, 1);
  9334.     if (guild) {
  9335.         guild->setMotd(motd);
  9336.         pushBoolean(L, true);
  9337.     } else {
  9338.         lua_pushnil(L);
  9339.     }
  9340.     return 1;
  9341. }
  9342.  
  9343. // Group
  9344. int LuaScriptInterface::luaGroupCreate(lua_State* L)
  9345. {
  9346.     // Group(id)
  9347.     uint32_t id = getNumber<uint32_t>(L, 2);
  9348.  
  9349.     Group* group = g_game.groups.getGroup(id);
  9350.     if (group) {
  9351.         pushUserdata<Group>(L, group);
  9352.         setMetatable(L, -1, "Group");
  9353.     } else {
  9354.         lua_pushnil(L);
  9355.     }
  9356.     return 1;
  9357. }
  9358.  
  9359. int LuaScriptInterface::luaGroupGetId(lua_State* L)
  9360. {
  9361.     // group:getId()
  9362.     Group* group = getUserdata<Group>(L, 1);
  9363.     if (group) {
  9364.         lua_pushnumber(L, group->id);
  9365.     } else {
  9366.         lua_pushnil(L);
  9367.     }
  9368.     return 1;
  9369. }
  9370.  
  9371. int LuaScriptInterface::luaGroupGetName(lua_State* L)
  9372. {
  9373.     // group:getName()
  9374.     Group* group = getUserdata<Group>(L, 1);
  9375.     if (group) {
  9376.         pushString(L, group->name);
  9377.     } else {
  9378.         lua_pushnil(L);
  9379.     }
  9380.     return 1;
  9381. }
  9382.  
  9383. int LuaScriptInterface::luaGroupGetFlags(lua_State* L)
  9384. {
  9385.     // group:getFlags()
  9386.     Group* group = getUserdata<Group>(L, 1);
  9387.     if (group) {
  9388.         lua_pushnumber(L, group->flags);
  9389.     } else {
  9390.         lua_pushnil(L);
  9391.     }
  9392.     return 1;
  9393. }
  9394.  
  9395. int LuaScriptInterface::luaGroupGetAccess(lua_State* L)
  9396. {
  9397.     // group:getAccess()
  9398.     Group* group = getUserdata<Group>(L, 1);
  9399.     if (group) {
  9400.         pushBoolean(L, group->access);
  9401.     } else {
  9402.         lua_pushnil(L);
  9403.     }
  9404.     return 1;
  9405. }
  9406.  
  9407. int LuaScriptInterface::luaGroupGetMaxDepotItems(lua_State* L)
  9408. {
  9409.     // group:getMaxDepotItems()
  9410.     Group* group = getUserdata<Group>(L, 1);
  9411.     if (group) {
  9412.         lua_pushnumber(L, group->maxDepotItems);
  9413.     } else {
  9414.         lua_pushnil(L);
  9415.     }
  9416.     return 1;
  9417. }
  9418.  
  9419. int LuaScriptInterface::luaGroupGetMaxVipEntries(lua_State* L)
  9420. {
  9421.     // group:getMaxVipEntries()
  9422.     Group* group = getUserdata<Group>(L, 1);
  9423.     if (group) {
  9424.         lua_pushnumber(L, group->maxVipEntries);
  9425.     } else {
  9426.         lua_pushnil(L);
  9427.     }
  9428.     return 1;
  9429. }
  9430.  
  9431. // Vocation
  9432. int LuaScriptInterface::luaVocationCreate(lua_State* L)
  9433. {
  9434.     // Vocation(id or name)
  9435.     uint32_t id;
  9436.     if (isNumber(L, 2)) {
  9437.         id = getNumber<uint32_t>(L, 2);
  9438.     } else {
  9439.         id = g_vocations.getVocationId(getString(L, 2));
  9440.     }
  9441.  
  9442.     Vocation* vocation = g_vocations.getVocation(id);
  9443.     if (vocation) {
  9444.         pushUserdata<Vocation>(L, vocation);
  9445.         setMetatable(L, -1, "Vocation");
  9446.     } else {
  9447.         lua_pushnil(L);
  9448.     }
  9449.     return 1;
  9450. }
  9451.  
  9452. int LuaScriptInterface::luaVocationGetId(lua_State* L)
  9453. {
  9454.     // vocation:getId()
  9455.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9456.     if (vocation) {
  9457.         lua_pushnumber(L, vocation->getId());
  9458.     } else {
  9459.         lua_pushnil(L);
  9460.     }
  9461.     return 1;
  9462. }
  9463.  
  9464. int LuaScriptInterface::luaVocationGetClientId(lua_State* L)
  9465. {
  9466.     // vocation:getClientId()
  9467.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9468.     if (vocation) {
  9469.         lua_pushnumber(L, vocation->getClientId());
  9470.     } else {
  9471.         lua_pushnil(L);
  9472.     }
  9473.     return 1;
  9474. }
  9475.  
  9476. int LuaScriptInterface::luaVocationGetName(lua_State* L)
  9477. {
  9478.     // vocation:getName()
  9479.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9480.     if (vocation) {
  9481.         pushString(L, vocation->getVocName());
  9482.     } else {
  9483.         lua_pushnil(L);
  9484.     }
  9485.     return 1;
  9486. }
  9487.  
  9488. int LuaScriptInterface::luaVocationGetDescription(lua_State* L)
  9489. {
  9490.     // vocation:getDescription()
  9491.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9492.     if (vocation) {
  9493.         pushString(L, vocation->getVocDescription());
  9494.     } else {
  9495.         lua_pushnil(L);
  9496.     }
  9497.     return 1;
  9498. }
  9499.  
  9500. int LuaScriptInterface::luaVocationGetRequiredSkillTries(lua_State* L)
  9501. {
  9502.     // vocation:getRequiredSkillTries(skillType, skillLevel)
  9503.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9504.     if (vocation) {
  9505.         skills_t skillType = getNumber<skills_t>(L, 2);
  9506.         uint16_t skillLevel = getNumber<uint16_t>(L, 3);
  9507.         lua_pushnumber(L, vocation->getReqSkillTries(skillType, skillLevel));
  9508.     } else {
  9509.         lua_pushnil(L);
  9510.     }
  9511.     return 1;
  9512. }
  9513.  
  9514. int LuaScriptInterface::luaVocationGetRequiredManaSpent(lua_State* L)
  9515. {
  9516.     // vocation:getRequiredManaSpent(magicLevel)
  9517.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9518.     if (vocation) {
  9519.         uint32_t magicLevel = getNumber<uint32_t>(L, 2);
  9520.         lua_pushnumber(L, vocation->getReqMana(magicLevel));
  9521.     } else {
  9522.         lua_pushnil(L);
  9523.     }
  9524.     return 1;
  9525. }
  9526.  
  9527. int LuaScriptInterface::luaVocationGetCapacityGain(lua_State* L)
  9528. {
  9529.     // vocation:getCapacityGain()
  9530.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9531.     if (vocation) {
  9532.         lua_pushnumber(L, vocation->getCapGain());
  9533.     } else {
  9534.         lua_pushnil(L);
  9535.     }
  9536.     return 1;
  9537. }
  9538.  
  9539. int LuaScriptInterface::luaVocationGetHealthGain(lua_State* L)
  9540. {
  9541.     // vocation:getHealthGain()
  9542.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9543.     if (vocation) {
  9544.         lua_pushnumber(L, vocation->getHPGain());
  9545.     } else {
  9546.         lua_pushnil(L);
  9547.     }
  9548.     return 1;
  9549. }
  9550.  
  9551. int LuaScriptInterface::luaVocationGetHealthGainTicks(lua_State* L)
  9552. {
  9553.     // vocation:getHealthGainTicks()
  9554.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9555.     if (vocation) {
  9556.         lua_pushnumber(L, vocation->getHealthGainTicks());
  9557.     } else {
  9558.         lua_pushnil(L);
  9559.     }
  9560.     return 1;
  9561. }
  9562.  
  9563. int LuaScriptInterface::luaVocationGetHealthGainAmount(lua_State* L)
  9564. {
  9565.     // vocation:getHealthGainAmount()
  9566.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9567.     if (vocation) {
  9568.         lua_pushnumber(L, vocation->getHealthGainAmount());
  9569.     } else {
  9570.         lua_pushnil(L);
  9571.     }
  9572.     return 1;
  9573. }
  9574.  
  9575. int LuaScriptInterface::luaVocationGetManaGain(lua_State* L)
  9576. {
  9577.     // vocation:getManaGain()
  9578.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9579.     if (vocation) {
  9580.         lua_pushnumber(L, vocation->getManaGain());
  9581.     } else {
  9582.         lua_pushnil(L);
  9583.     }
  9584.     return 1;
  9585. }
  9586.  
  9587. int LuaScriptInterface::luaVocationGetManaGainTicks(lua_State* L)
  9588. {
  9589.     // vocation:getManaGainTicks()
  9590.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9591.     if (vocation) {
  9592.         lua_pushnumber(L, vocation->getManaGainTicks());
  9593.     } else {
  9594.         lua_pushnil(L);
  9595.     }
  9596.     return 1;
  9597. }
  9598.  
  9599. int LuaScriptInterface::luaVocationGetManaGainAmount(lua_State* L)
  9600. {
  9601.     // vocation:getManaGainAmount()
  9602.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9603.     if (vocation) {
  9604.         lua_pushnumber(L, vocation->getManaGainAmount());
  9605.     } else {
  9606.         lua_pushnil(L);
  9607.     }
  9608.     return 1;
  9609. }
  9610.  
  9611. int LuaScriptInterface::luaVocationGetMaxSoul(lua_State* L)
  9612. {
  9613.     // vocation:getMaxSoul()
  9614.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9615.     if (vocation) {
  9616.         lua_pushnumber(L, vocation->getSoulMax());
  9617.     } else {
  9618.         lua_pushnil(L);
  9619.     }
  9620.     return 1;
  9621. }
  9622.  
  9623. int LuaScriptInterface::luaVocationGetSoulGainTicks(lua_State* L)
  9624. {
  9625.     // vocation:getSoulGainTicks()
  9626.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9627.     if (vocation) {
  9628.         lua_pushnumber(L, vocation->getSoulGainTicks());
  9629.     } else {
  9630.         lua_pushnil(L);
  9631.     }
  9632.     return 1;
  9633. }
  9634.  
  9635. int LuaScriptInterface::luaVocationGetAttackSpeed(lua_State* L)
  9636. {
  9637.     // vocation:getAttackSpeed()
  9638.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9639.     if (vocation) {
  9640.         lua_pushnumber(L, vocation->getAttackSpeed());
  9641.     } else {
  9642.         lua_pushnil(L);
  9643.     }
  9644.     return 1;
  9645. }
  9646.  
  9647. int LuaScriptInterface::luaVocationGetBaseSpeed(lua_State* L)
  9648. {
  9649.     // vocation:getBaseSpeed()
  9650.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9651.     if (vocation) {
  9652.         lua_pushnumber(L, vocation->getBaseSpeed());
  9653.     } else {
  9654.         lua_pushnil(L);
  9655.     }
  9656.     return 1;
  9657. }
  9658.  
  9659. int LuaScriptInterface::luaVocationGetDemotion(lua_State* L)
  9660. {
  9661.     // vocation:getDemotion()
  9662.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9663.     if (!vocation) {
  9664.         lua_pushnil(L);
  9665.         return 1;
  9666.     }
  9667.  
  9668.     uint16_t fromId = vocation->getFromVocation();
  9669.     if (fromId == VOCATION_NONE) {
  9670.         lua_pushnil(L);
  9671.         return 1;
  9672.     }
  9673.  
  9674.     Vocation* demotedVocation = g_vocations.getVocation(fromId);
  9675.     if (demotedVocation && demotedVocation != vocation) {
  9676.         pushUserdata<Vocation>(L, demotedVocation);
  9677.         setMetatable(L, -1, "Vocation");
  9678.     } else {
  9679.         lua_pushnil(L);
  9680.     }
  9681.     return 1;
  9682. }
  9683.  
  9684. int LuaScriptInterface::luaVocationGetPromotion(lua_State* L)
  9685. {
  9686.     // vocation:getPromotion()
  9687.     Vocation* vocation = getUserdata<Vocation>(L, 1);
  9688.     if (!vocation) {
  9689.         lua_pushnil(L);
  9690.         return 1;
  9691.     }
  9692.  
  9693.     uint16_t promotedId = g_vocations.getPromotedVocation(vocation->getId());
  9694.     if (promotedId == VOCATION_NONE) {
  9695.         lua_pushnil(L);
  9696.         return 1;
  9697.     }
  9698.  
  9699.     Vocation* promotedVocation = g_vocations.getVocation(promotedId);
  9700.     if (promotedVocation && promotedVocation != vocation) {
  9701.         pushUserdata<Vocation>(L, promotedVocation);
  9702.         setMetatable(L, -1, "Vocation");
  9703.     } else {
  9704.         lua_pushnil(L);
  9705.     }
  9706.     return 1;
  9707. }
  9708.  
  9709. // Town
  9710. int LuaScriptInterface::luaTownCreate(lua_State* L)
  9711. {
  9712.     // Town(id or name)
  9713.     Town* town;
  9714.     if (isNumber(L, 2)) {
  9715.         town = g_game.map.towns.getTown(getNumber<uint32_t>(L, 2));
  9716.     } else if (isString(L, 2)) {
  9717.         town = g_game.map.towns.getTown(getString(L, 2));
  9718.     } else {
  9719.         town = nullptr;
  9720.     }
  9721.  
  9722.     if (town) {
  9723.         pushUserdata<Town>(L, town);
  9724.         setMetatable(L, -1, "Town");
  9725.     } else {
  9726.         lua_pushnil(L);
  9727.     }
  9728.     return 1;
  9729. }
  9730.  
  9731. int LuaScriptInterface::luaTownGetId(lua_State* L)
  9732. {
  9733.     // town:getId()
  9734.     Town* town = getUserdata<Town>(L, 1);
  9735.     if (town) {
  9736.         lua_pushnumber(L, town->getID());
  9737.     } else {
  9738.         lua_pushnil(L);
  9739.     }
  9740.     return 1;
  9741. }
  9742.  
  9743. int LuaScriptInterface::luaTownGetName(lua_State* L)
  9744. {
  9745.     // town:getName()
  9746.     Town* town = getUserdata<Town>(L, 1);
  9747.     if (town) {
  9748.         pushString(L, town->getName());
  9749.     } else {
  9750.         lua_pushnil(L);
  9751.     }
  9752.     return 1;
  9753. }
  9754.  
  9755. int LuaScriptInterface::luaTownGetTemplePosition(lua_State* L)
  9756. {
  9757.     // town:getTemplePosition()
  9758.     Town* town = getUserdata<Town>(L, 1);
  9759.     if (town) {
  9760.         pushPosition(L, town->getTemplePosition());
  9761.     } else {
  9762.         lua_pushnil(L);
  9763.     }
  9764.     return 1;
  9765. }
  9766.  
  9767. // House
  9768. int LuaScriptInterface::luaHouseCreate(lua_State* L)
  9769. {
  9770.     // House(id)
  9771.     House* house = g_game.map.houses.getHouse(getNumber<uint32_t>(L, 2));
  9772.     if (house) {
  9773.         pushUserdata<House>(L, house);
  9774.         setMetatable(L, -1, "House");
  9775.     } else {
  9776.         lua_pushnil(L);
  9777.     }
  9778.     return 1;
  9779. }
  9780.  
  9781. int LuaScriptInterface::luaHouseGetId(lua_State* L)
  9782. {
  9783.     // house:getId()
  9784.     House* house = getUserdata<House>(L, 1);
  9785.     if (house) {
  9786.         lua_pushnumber(L, house->getId());
  9787.     } else {
  9788.         lua_pushnil(L);
  9789.     }
  9790.     return 1;
  9791. }
  9792.  
  9793. int LuaScriptInterface::luaHouseGetName(lua_State* L)
  9794. {
  9795.     // house:getName()
  9796.     House* house = getUserdata<House>(L, 1);
  9797.     if (house) {
  9798.         pushString(L, house->getName());
  9799.     } else {
  9800.         lua_pushnil(L);
  9801.     }
  9802.     return 1;
  9803. }
  9804.  
  9805. int LuaScriptInterface::luaHouseGetTown(lua_State* L)
  9806. {
  9807.     // house:getTown()
  9808.     House* house = getUserdata<House>(L, 1);
  9809.     if (!house) {
  9810.         lua_pushnil(L);
  9811.         return 1;
  9812.     }
  9813.  
  9814.     Town* town = g_game.map.towns.getTown(house->getTownId());
  9815.     if (town) {
  9816.         pushUserdata<Town>(L, town);
  9817.         setMetatable(L, -1, "Town");
  9818.     } else {
  9819.         lua_pushnil(L);
  9820.     }
  9821.     return 1;
  9822. }
  9823.  
  9824. int LuaScriptInterface::luaHouseGetExitPosition(lua_State* L)
  9825. {
  9826.     // house:getExitPosition()
  9827.     House* house = getUserdata<House>(L, 1);
  9828.     if (house) {
  9829.         pushPosition(L, house->getEntryPosition());
  9830.     } else {
  9831.         lua_pushnil(L);
  9832.     }
  9833.     return 1;
  9834. }
  9835.  
  9836. int LuaScriptInterface::luaHouseGetRent(lua_State* L)
  9837. {
  9838.     // house:getRent()
  9839.     House* house = getUserdata<House>(L, 1);
  9840.     if (house) {
  9841.         lua_pushnumber(L, house->getRent());
  9842.     } else {
  9843.         lua_pushnil(L);
  9844.     }
  9845.     return 1;
  9846. }
  9847.  
  9848. int LuaScriptInterface::luaHouseGetOwnerGuid(lua_State* L)
  9849. {
  9850.     // house:getOwnerGuid()
  9851.     House* house = getUserdata<House>(L, 1);
  9852.     if (house) {
  9853.         lua_pushnumber(L, house->getOwner());
  9854.     } else {
  9855.         lua_pushnil(L);
  9856.     }
  9857.     return 1;
  9858. }
  9859.  
  9860. int LuaScriptInterface::luaHouseSetOwnerGuid(lua_State* L)
  9861. {
  9862.     // house:setOwnerGuid(guid[, updateDatabase = true])
  9863.     House* house = getUserdata<House>(L, 1);
  9864.     if (house) {
  9865.         uint32_t guid = getNumber<uint32_t>(L, 2);
  9866.         bool updateDatabase = getBoolean(L, 3, true);
  9867.         house->setOwner(guid, updateDatabase);
  9868.         pushBoolean(L, true);
  9869.     } else {
  9870.         lua_pushnil(L);
  9871.     }
  9872.     return 1;
  9873. }
  9874.  
  9875. int LuaScriptInterface::luaHouseGetBeds(lua_State* L)
  9876. {
  9877.     // house:getBeds()
  9878.     House* house = getUserdata<House>(L, 1);
  9879.     if (!house) {
  9880.         lua_pushnil(L);
  9881.         return 1;
  9882.     }
  9883.  
  9884.     const auto& beds = house->getBeds();
  9885.     lua_createtable(L, beds.size(), 0);
  9886.  
  9887.     int index = 0;
  9888.     for (BedItem* bedItem : beds) {
  9889.         pushUserdata<Item>(L, bedItem);
  9890.         setItemMetatable(L, -1, bedItem);
  9891.         lua_rawseti(L, -2, ++index);
  9892.     }
  9893.     return 1;
  9894. }
  9895.  
  9896. int LuaScriptInterface::luaHouseGetBedCount(lua_State* L)
  9897. {
  9898.     // house:getBedCount()
  9899.     House* house = getUserdata<House>(L, 1);
  9900.     if (house) {
  9901.         lua_pushnumber(L, house->getBedCount());
  9902.     } else {
  9903.         lua_pushnil(L);
  9904.     }
  9905.     return 1;
  9906. }
  9907.  
  9908. int LuaScriptInterface::luaHouseGetDoors(lua_State* L)
  9909. {
  9910.     // house:getDoors()
  9911.     House* house = getUserdata<House>(L, 1);
  9912.     if (!house) {
  9913.         lua_pushnil(L);
  9914.         return 1;
  9915.     }
  9916.  
  9917.     const auto& doors = house->getDoors();
  9918.     lua_createtable(L, doors.size(), 0);
  9919.  
  9920.     int index = 0;
  9921.     for (Door* door : doors) {
  9922.         pushUserdata<Item>(L, door);
  9923.         setItemMetatable(L, -1, door);
  9924.         lua_rawseti(L, -2, ++index);
  9925.     }
  9926.     return 1;
  9927. }
  9928.  
  9929. int LuaScriptInterface::luaHouseGetDoorCount(lua_State* L)
  9930. {
  9931.     // house:getDoorCount()
  9932.     House* house = getUserdata<House>(L, 1);
  9933.     if (house) {
  9934.         lua_pushnumber(L, house->getDoors().size());
  9935.     } else {
  9936.         lua_pushnil(L);
  9937.     }
  9938.     return 1;
  9939. }
  9940.  
  9941. int LuaScriptInterface::luaHouseGetTiles(lua_State* L)
  9942. {
  9943.     // house:getTiles()
  9944.     House* house = getUserdata<House>(L, 1);
  9945.     if (!house) {
  9946.         lua_pushnil(L);
  9947.         return 1;
  9948.     }
  9949.  
  9950.     const auto& tiles = house->getTiles();
  9951.     lua_createtable(L, tiles.size(), 0);
  9952.  
  9953.     int index = 0;
  9954.     for (Tile* tile : tiles) {
  9955.         pushUserdata<Tile>(L, tile);
  9956.         setMetatable(L, -1, "Tile");
  9957.         lua_rawseti(L, -2, ++index);
  9958.     }
  9959.     return 1;
  9960. }
  9961.  
  9962. int LuaScriptInterface::luaHouseGetTileCount(lua_State* L)
  9963. {
  9964.     // house:getTileCount()
  9965.     House* house = getUserdata<House>(L, 1);
  9966.     if (house) {
  9967.         lua_pushnumber(L, house->getTiles().size());
  9968.     } else {
  9969.         lua_pushnil(L);
  9970.     }
  9971.     return 1;
  9972. }
  9973.  
  9974. int LuaScriptInterface::luaHouseGetAccessList(lua_State* L)
  9975. {
  9976.     // house:getAccessList(listId)
  9977.     House* house = getUserdata<House>(L, 1);
  9978.     if (!house) {
  9979.         lua_pushnil(L);
  9980.         return 1;
  9981.     }
  9982.  
  9983.     std::string list;
  9984.     uint32_t listId = getNumber<uint32_t>(L, 2);
  9985.     if (house->getAccessList(listId, list)) {
  9986.         pushString(L, list);
  9987.     } else {
  9988.         pushBoolean(L, false);
  9989.     }
  9990.     return 1;
  9991. }
  9992.  
  9993. int LuaScriptInterface::luaHouseSetAccessList(lua_State* L)
  9994. {
  9995.     // house:setAccessList(listId, list)
  9996.     House* house = getUserdata<House>(L, 1);
  9997.     if (!house) {
  9998.         lua_pushnil(L);
  9999.         return 1;
  10000.     }
  10001.  
  10002.     uint32_t listId = getNumber<uint32_t>(L, 2);
  10003.     const std::string& list = getString(L, 3);
  10004.     house->setAccessList(listId, list);
  10005.     pushBoolean(L, true);
  10006.     return 1;
  10007. }
  10008.  
  10009. // ItemType
  10010. int LuaScriptInterface::luaItemTypeCreate(lua_State* L)
  10011. {
  10012.     // ItemType(id or name)
  10013.     uint32_t id;
  10014.     if (isNumber(L, 2)) {
  10015.         id = getNumber<uint32_t>(L, 2);
  10016.     } else {
  10017.         id = Item::items.getItemIdByName(getString(L, 2));
  10018.     }
  10019.  
  10020.     const ItemType& itemType = Item::items[id];
  10021.     pushUserdata<const ItemType>(L, &itemType);
  10022.     setMetatable(L, -1, "ItemType");
  10023.     return 1;
  10024. }
  10025.  
  10026. int LuaScriptInterface::luaItemTypeIsCorpse(lua_State* L)
  10027. {
  10028.     // itemType:isCorpse()
  10029.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10030.     if (itemType) {
  10031.         pushBoolean(L, itemType->corpseType != RACE_NONE);
  10032.     } else {
  10033.         lua_pushnil(L);
  10034.     }
  10035.     return 1;
  10036. }
  10037.  
  10038. int LuaScriptInterface::luaItemTypeIsDoor(lua_State* L)
  10039. {
  10040.     // itemType:isDoor()
  10041.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10042.     if (itemType) {
  10043.         pushBoolean(L, itemType->isDoor());
  10044.     } else {
  10045.         lua_pushnil(L);
  10046.     }
  10047.     return 1;
  10048. }
  10049.  
  10050. int LuaScriptInterface::luaItemTypeIsContainer(lua_State* L)
  10051. {
  10052.     // itemType:isContainer()
  10053.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10054.     if (itemType) {
  10055.         pushBoolean(L, itemType->isContainer());
  10056.     } else {
  10057.         lua_pushnil(L);
  10058.     }
  10059.     return 1;
  10060. }
  10061.  
  10062. int LuaScriptInterface::luaItemTypeIsFluidContainer(lua_State* L)
  10063. {
  10064.     // itemType:isFluidContainer()
  10065.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10066.     if (itemType) {
  10067.         pushBoolean(L, itemType->isFluidContainer());
  10068.     } else {
  10069.         lua_pushnil(L);
  10070.     }
  10071.     return 1;
  10072. }
  10073.  
  10074. int LuaScriptInterface::luaItemTypeIsMovable(lua_State* L)
  10075. {
  10076.     // itemType:isMovable()
  10077.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10078.     if (itemType) {
  10079.         pushBoolean(L, itemType->moveable);
  10080.     } else {
  10081.         lua_pushnil(L);
  10082.     }
  10083.     return 1;
  10084. }
  10085.  
  10086. int LuaScriptInterface::luaItemTypeIsRune(lua_State* L)
  10087. {
  10088.     // itemType:isRune()
  10089.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10090.     if (itemType) {
  10091.         pushBoolean(L, itemType->isRune());
  10092.     } else {
  10093.         lua_pushnil(L);
  10094.     }
  10095.     return 1;
  10096. }
  10097.  
  10098. int LuaScriptInterface::luaItemTypeIsStackable(lua_State* L)
  10099. {
  10100.     // itemType:isStackable()
  10101.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10102.     if (itemType) {
  10103.         pushBoolean(L, itemType->stackable);
  10104.     } else {
  10105.         lua_pushnil(L);
  10106.     }
  10107.     return 1;
  10108. }
  10109.  
  10110. int LuaScriptInterface::luaItemTypeIsReadable(lua_State* L)
  10111. {
  10112.     // itemType:isReadable()
  10113.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10114.     if (itemType) {
  10115.         pushBoolean(L, itemType->canReadText);
  10116.     } else {
  10117.         lua_pushnil(L);
  10118.     }
  10119.     return 1;
  10120. }
  10121.  
  10122. int LuaScriptInterface::luaItemTypeIsWritable(lua_State* L)
  10123. {
  10124.     // itemType:isWritable()
  10125.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10126.     if (itemType) {
  10127.         pushBoolean(L, itemType->canWriteText);
  10128.     } else {
  10129.         lua_pushnil(L);
  10130.     }
  10131.     return 1;
  10132. }
  10133.  
  10134. int LuaScriptInterface::luaItemTypeGetType(lua_State* L)
  10135. {
  10136.     // itemType:getType()
  10137.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10138.     if (itemType) {
  10139.         lua_pushnumber(L, itemType->type);
  10140.     } else {
  10141.         lua_pushnil(L);
  10142.     }
  10143.     return 1;
  10144. }
  10145.  
  10146. int LuaScriptInterface::luaItemTypeGetId(lua_State* L)
  10147. {
  10148.     // itemType:getId()
  10149.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10150.     if (itemType) {
  10151.         lua_pushnumber(L, itemType->id);
  10152.     } else {
  10153.         lua_pushnil(L);
  10154.     }
  10155.     return 1;
  10156. }
  10157.  
  10158. int LuaScriptInterface::luaItemTypeGetClientId(lua_State* L)
  10159. {
  10160.     // itemType:getClientId()
  10161.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10162.     if (itemType) {
  10163.         lua_pushnumber(L, itemType->clientId);
  10164.     } else {
  10165.         lua_pushnil(L);
  10166.     }
  10167.     return 1;
  10168. }
  10169.  
  10170. int LuaScriptInterface::luaItemTypeGetName(lua_State* L)
  10171. {
  10172.     // itemType:getName()
  10173.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10174.     if (itemType) {
  10175.         pushString(L, itemType->name);
  10176.     } else {
  10177.         lua_pushnil(L);
  10178.     }
  10179.     return 1;
  10180. }
  10181.  
  10182. int LuaScriptInterface::luaItemTypeGetPluralName(lua_State* L)
  10183. {
  10184.     // itemType:getPluralName()
  10185.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10186.     if (itemType) {
  10187.         pushString(L, itemType->getPluralName());
  10188.     } else {
  10189.         lua_pushnil(L);
  10190.     }
  10191.     return 1;
  10192. }
  10193.  
  10194. int LuaScriptInterface::luaItemTypeGetArticle(lua_State* L)
  10195. {
  10196.     // itemType:getArticle()
  10197.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10198.     if (itemType) {
  10199.         pushString(L, itemType->article);
  10200.     } else {
  10201.         lua_pushnil(L);
  10202.     }
  10203.     return 1;
  10204. }
  10205.  
  10206. int LuaScriptInterface::luaItemTypeGetDescription(lua_State* L)
  10207. {
  10208.     // itemType:getDescription()
  10209.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10210.     if (itemType) {
  10211.         pushString(L, itemType->description);
  10212.     } else {
  10213.         lua_pushnil(L);
  10214.     }
  10215.     return 1;
  10216. }
  10217.  
  10218. int LuaScriptInterface::luaItemTypeGetSlotPosition(lua_State *L)
  10219. {
  10220.     // itemType:getSlotPosition()
  10221.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10222.     if (itemType) {
  10223.         lua_pushnumber(L, itemType->slotPosition);
  10224.     } else {
  10225.         lua_pushnil(L);
  10226.     }
  10227.     return 1;
  10228. }
  10229.  
  10230. int LuaScriptInterface::luaItemTypeGetCharges(lua_State* L)
  10231. {
  10232.     // itemType:getCharges()
  10233.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10234.     if (itemType) {
  10235.         lua_pushnumber(L, itemType->charges);
  10236.     } else {
  10237.         lua_pushnil(L);
  10238.     }
  10239.     return 1;
  10240. }
  10241.  
  10242. int LuaScriptInterface::luaItemTypeGetFluidSource(lua_State* L)
  10243. {
  10244.     // itemType:getFluidSource()
  10245.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10246.     if (itemType) {
  10247.         lua_pushnumber(L, itemType->fluidSource);
  10248.     } else {
  10249.         lua_pushnil(L);
  10250.     }
  10251.     return 1;
  10252. }
  10253.  
  10254. int LuaScriptInterface::luaItemTypeGetCapacity(lua_State* L)
  10255. {
  10256.     // itemType:getCapacity()
  10257.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10258.     if (itemType) {
  10259.         lua_pushnumber(L, itemType->maxItems);
  10260.     } else {
  10261.         lua_pushnil(L);
  10262.     }
  10263.     return 1;
  10264. }
  10265.  
  10266. int LuaScriptInterface::luaItemTypeGetWeight(lua_State* L)
  10267. {
  10268.     // itemType:getWeight([count = 1])
  10269.     uint16_t count = getNumber<uint16_t>(L, 2, 1);
  10270.  
  10271.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10272.     if (!itemType) {
  10273.         lua_pushnil(L);
  10274.         return 1;
  10275.     }
  10276.  
  10277.     uint64_t weight = static_cast<uint64_t>(itemType->weight) * std::max<int32_t>(1, count);
  10278.     lua_pushnumber(L, weight);
  10279.     return 1;
  10280. }
  10281.  
  10282. int LuaScriptInterface::luaItemTypeGetHitChance(lua_State* L)
  10283. {
  10284.     // itemType:getHitChance()
  10285.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10286.     if (itemType) {
  10287.         lua_pushnumber(L, itemType->hitChance);
  10288.     } else {
  10289.         lua_pushnil(L);
  10290.     }
  10291.     return 1;
  10292. }
  10293.  
  10294. int LuaScriptInterface::luaItemTypeGetShootRange(lua_State* L)
  10295. {
  10296.     // itemType:getShootRange()
  10297.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10298.     if (itemType) {
  10299.         lua_pushnumber(L, itemType->shootRange);
  10300.     } else {
  10301.         lua_pushnil(L);
  10302.     }
  10303.     return 1;
  10304. }
  10305.  
  10306. int LuaScriptInterface::luaItemTypeGetAttack(lua_State* L)
  10307. {
  10308.     // itemType:getAttack()
  10309.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10310.     if (itemType) {
  10311.         lua_pushnumber(L, itemType->attack);
  10312.     } else {
  10313.         lua_pushnil(L);
  10314.     }
  10315.     return 1;
  10316. }
  10317.  
  10318. int LuaScriptInterface::luaItemTypeGetDefense(lua_State* L)
  10319. {
  10320.     // itemType:getDefense()
  10321.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10322.     if (itemType) {
  10323.         lua_pushnumber(L, itemType->defense);
  10324.     } else {
  10325.         lua_pushnil(L);
  10326.     }
  10327.     return 1;
  10328. }
  10329.  
  10330. int LuaScriptInterface::luaItemTypeGetExtraDefense(lua_State* L)
  10331. {
  10332.     // itemType:getExtraDefense()
  10333.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10334.     if (itemType) {
  10335.         lua_pushnumber(L, itemType->extraDefense);
  10336.     } else {
  10337.         lua_pushnil(L);
  10338.     }
  10339.     return 1;
  10340. }
  10341.  
  10342. int LuaScriptInterface::luaItemTypeGetArmor(lua_State* L)
  10343. {
  10344.     // itemType:getArmor()
  10345.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10346.     if (itemType) {
  10347.         lua_pushnumber(L, itemType->armor);
  10348.     } else {
  10349.         lua_pushnil(L);
  10350.     }
  10351.     return 1;
  10352. }
  10353.  
  10354. int LuaScriptInterface::luaItemTypeGetWeaponType(lua_State* L)
  10355. {
  10356.     // itemType:getWeaponType()
  10357.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10358.     if (itemType) {
  10359.         lua_pushnumber(L, itemType->weaponType);
  10360.     } else {
  10361.         lua_pushnil(L);
  10362.     }
  10363.     return 1;
  10364. }
  10365.  
  10366. int LuaScriptInterface::luaItemTypeGetElementType(lua_State* L)
  10367. {
  10368.     // itemType:getElementType()
  10369.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10370.     if (!itemType) {
  10371.         lua_pushnil(L);
  10372.         return 1;
  10373.     }
  10374.  
  10375.     auto& abilities = itemType->abilities;
  10376.     if (abilities) {
  10377.         lua_pushnumber(L, abilities->elementType);
  10378.     } else {
  10379.         lua_pushnil(L);
  10380.     }
  10381.     return 1;
  10382. }
  10383.  
  10384. int LuaScriptInterface::luaItemTypeGetElementDamage(lua_State* L)
  10385. {
  10386.     // itemType:getElementDamage()
  10387.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10388.     if (!itemType) {
  10389.         lua_pushnil(L);
  10390.         return 1;
  10391.     }
  10392.  
  10393.     auto& abilities = itemType->abilities;
  10394.     if (abilities) {
  10395.         lua_pushnumber(L, abilities->elementDamage);
  10396.     } else {
  10397.         lua_pushnil(L);
  10398.     }
  10399.     return 1;
  10400. }
  10401.  
  10402. int LuaScriptInterface::luaItemTypeGetTransformEquipId(lua_State* L)
  10403. {
  10404.     // itemType:getTransformEquipId()
  10405.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10406.     if (itemType) {
  10407.         lua_pushnumber(L, itemType->transformEquipTo);
  10408.     } else {
  10409.         lua_pushnil(L);
  10410.     }
  10411.     return 1;
  10412. }
  10413.  
  10414. int LuaScriptInterface::luaItemTypeGetTransformDeEquipId(lua_State* L)
  10415. {
  10416.     // itemType:getTransformDeEquipId()
  10417.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10418.     if (itemType) {
  10419.         lua_pushnumber(L, itemType->transformDeEquipTo);
  10420.     } else {
  10421.         lua_pushnil(L);
  10422.     }
  10423.     return 1;
  10424. }
  10425.  
  10426. int LuaScriptInterface::luaItemTypeGetDestroyId(lua_State* L)
  10427. {
  10428.     // itemType:getDestroyId()
  10429.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10430.     if (itemType) {
  10431.         lua_pushnumber(L, itemType->destroyTo);
  10432.     } else {
  10433.         lua_pushnil(L);
  10434.     }
  10435.     return 1;
  10436. }
  10437.  
  10438. int LuaScriptInterface::luaItemTypeGetDecayId(lua_State* L)
  10439. {
  10440.     // itemType:getDecayId()
  10441.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10442.     if (itemType) {
  10443.         lua_pushnumber(L, itemType->decayTo);
  10444.     } else {
  10445.         lua_pushnil(L);
  10446.     }
  10447.     return 1;
  10448. }
  10449.  
  10450. int LuaScriptInterface::luaItemTypeGetRequiredLevel(lua_State* L)
  10451. {
  10452.     // itemType:getRequiredLevel()
  10453.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10454.     if (itemType) {
  10455.         lua_pushnumber(L, itemType->minReqLevel);
  10456.     } else {
  10457.         lua_pushnil(L);
  10458.     }
  10459.     return 1;
  10460. }
  10461.  
  10462. int LuaScriptInterface::luaItemTypeHasSubType(lua_State* L)
  10463. {
  10464.     // itemType:hasSubType()
  10465.     const ItemType* itemType = getUserdata<const ItemType>(L, 1);
  10466.     if (itemType) {
  10467.         pushBoolean(L, itemType->hasSubType());
  10468.     } else {
  10469.         lua_pushnil(L);
  10470.     }
  10471.     return 1;
  10472. }
  10473.  
  10474. // Combat
  10475. int LuaScriptInterface::luaCombatCreate(lua_State* L)
  10476. {
  10477.     // Combat()
  10478.     pushUserdata<Combat>(L, g_luaEnvironment.createCombatObject(getScriptEnv()->getScriptInterface()));
  10479.     setMetatable(L, -1, "Combat");
  10480.     return 1;
  10481. }
  10482.  
  10483. int LuaScriptInterface::luaCombatSetParameter(lua_State* L)
  10484. {
  10485.     // combat:setParameter(key, value)
  10486.     Combat* combat = getUserdata<Combat>(L, 1);
  10487.     if (!combat) {
  10488.         lua_pushnil(L);
  10489.         return 1;
  10490.     }
  10491.  
  10492.     CombatParam_t key = getNumber<CombatParam_t>(L, 2);
  10493.     uint32_t value;
  10494.     if (isBoolean(L, 3)) {
  10495.         value = getBoolean(L, 3) ? 1 : 0;
  10496.     } else {
  10497.         value = getNumber<uint32_t>(L, 3);
  10498.     }
  10499.     combat->setParam(key, value);
  10500.     pushBoolean(L, true);
  10501.     return 1;
  10502. }
  10503.  
  10504. int LuaScriptInterface::luaCombatSetFormula(lua_State* L)
  10505. {
  10506.     // combat:setFormula(type, mina, minb, maxa, maxb)
  10507.     Combat* combat = getUserdata<Combat>(L, 1);
  10508.     if (!combat) {
  10509.         lua_pushnil(L);
  10510.         return 1;
  10511.     }
  10512.  
  10513.     formulaType_t type = getNumber<formulaType_t>(L, 2);
  10514.     double mina = getNumber<double>(L, 3);
  10515.     double minb = getNumber<double>(L, 4);
  10516.     double maxa = getNumber<double>(L, 5);
  10517.     double maxb = getNumber<double>(L, 6);
  10518.     combat->setPlayerCombatValues(type, mina, minb, maxa, maxb);
  10519.     pushBoolean(L, true);
  10520.     return 1;
  10521. }
  10522.  
  10523. int LuaScriptInterface::luaCombatSetArea(lua_State* L)
  10524. {
  10525.     // combat:setArea(area)
  10526.     if (getScriptEnv()->getScriptId() != EVENT_ID_LOADING) {
  10527.         reportErrorFunc("This function can only be used while loading the script.");
  10528.         lua_pushnil(L);
  10529.         return 1;
  10530.     }
  10531.  
  10532.     const AreaCombat* area = g_luaEnvironment.getAreaObject(getNumber<uint32_t>(L, 2));
  10533.     if (!area) {
  10534.         reportErrorFunc(getErrorDesc(LUA_ERROR_AREA_NOT_FOUND));
  10535.         lua_pushnil(L);
  10536.         return 1;
  10537.     }
  10538.  
  10539.     Combat* combat = getUserdata<Combat>(L, 1);
  10540.     if (combat) {
  10541.         combat->setArea(new AreaCombat(*area));
  10542.         pushBoolean(L, true);
  10543.     } else {
  10544.         lua_pushnil(L);
  10545.     }
  10546.     return 1;
  10547. }
  10548.  
  10549. int LuaScriptInterface::luaCombatSetCondition(lua_State* L)
  10550. {
  10551.     // combat:setCondition(condition)
  10552.     Condition* condition = getUserdata<Condition>(L, 2);
  10553.     Combat* combat = getUserdata<Combat>(L, 1);
  10554.     if (combat && condition) {
  10555.         combat->setCondition(condition->clone());
  10556.         pushBoolean(L, true);
  10557.     } else {
  10558.         lua_pushnil(L);
  10559.     }
  10560.     return 1;
  10561. }
  10562.  
  10563. int LuaScriptInterface::luaCombatSetCallback(lua_State* L)
  10564. {
  10565.     // combat:setCallback(key, function)
  10566.     Combat* combat = getUserdata<Combat>(L, 1);
  10567.     if (!combat) {
  10568.         lua_pushnil(L);
  10569.         return 1;
  10570.     }
  10571.  
  10572.     CallBackParam_t key = getNumber<CallBackParam_t>(L, 2);
  10573.     if (!combat->setCallback(key)) {
  10574.         lua_pushnil(L);
  10575.         return 1;
  10576.     }
  10577.  
  10578.     CallBack* callback = combat->getCallback(key);
  10579.     if (!callback) {
  10580.         lua_pushnil(L);
  10581.         return 1;
  10582.     }
  10583.  
  10584.     const std::string& function = getString(L, 3);
  10585.     pushBoolean(L, callback->loadCallBack(getScriptEnv()->getScriptInterface(), function));
  10586.     return 1;
  10587. }
  10588.  
  10589. int LuaScriptInterface::luaCombatSetOrigin(lua_State* L)
  10590. {
  10591.     // combat:setOrigin(origin)
  10592.     Combat* combat = getUserdata<Combat>(L, 1);
  10593.     if (combat) {
  10594.         combat->setOrigin(getNumber<CombatOrigin>(L, 2));
  10595.         pushBoolean(L, true);
  10596.     } else {
  10597.         lua_pushnil(L);
  10598.     }
  10599.     return 1;
  10600. }
  10601.  
  10602. int LuaScriptInterface::luaCombatExecute(lua_State* L)
  10603. {
  10604.     // combat:execute(creature, variant)
  10605.     Combat* combat = getUserdata<Combat>(L, 1);
  10606.     if (!combat) {
  10607.         pushBoolean(L, false);
  10608.         return 1;
  10609.     }
  10610.  
  10611.     Creature* creature = getCreature(L, 2);
  10612.  
  10613.     const LuaVariant& variant = getVariant(L, 3);
  10614.     switch (variant.type) {
  10615.         case VARIANT_NUMBER: {
  10616.             Creature* target = g_game.getCreatureByID(variant.number);
  10617.             if (!target) {
  10618.                 pushBoolean(L, false);
  10619.                 return 1;
  10620.             }
  10621.  
  10622.             if (combat->hasArea()) {
  10623.                 combat->doCombat(creature, target->getPosition());
  10624.             } else {
  10625.                 combat->doCombat(creature, target);
  10626.             }
  10627.             break;
  10628.         }
  10629.  
  10630.         case VARIANT_POSITION: {
  10631.             combat->doCombat(creature, variant.pos);
  10632.             break;
  10633.         }
  10634.  
  10635.         case VARIANT_TARGETPOSITION: {
  10636.             if (combat->hasArea()) {
  10637.                 combat->doCombat(creature, variant.pos);
  10638.             } else {
  10639.                 combat->postCombatEffects(creature, variant.pos);
  10640.                 g_game.addMagicEffect(variant.pos, CONST_ME_POFF);
  10641.             }
  10642.             break;
  10643.         }
  10644.  
  10645.         case VARIANT_STRING: {
  10646.             Player* target = g_game.getPlayerByName(variant.text);
  10647.             if (!target) {
  10648.                 pushBoolean(L, false);
  10649.                 return 1;
  10650.             }
  10651.  
  10652.             combat->doCombat(creature, target);
  10653.             break;
  10654.         }
  10655.  
  10656.         case VARIANT_NONE: {
  10657.             reportErrorFunc(getErrorDesc(LUA_ERROR_VARIANT_NOT_FOUND));
  10658.             pushBoolean(L, false);
  10659.             return 1;
  10660.         }
  10661.  
  10662.         default: {
  10663.             break;
  10664.         }
  10665.     }
  10666.  
  10667.     pushBoolean(L, true);
  10668.     return 1;
  10669. }
  10670.  
  10671. // Condition
  10672. int LuaScriptInterface::luaConditionCreate(lua_State* L)
  10673. {
  10674.     // Condition(conditionType[, conditionId = CONDITIONID_COMBAT])
  10675.     ConditionType_t conditionType = getNumber<ConditionType_t>(L, 2);
  10676.     ConditionId_t conditionId = getNumber<ConditionId_t>(L, 3, CONDITIONID_COMBAT);
  10677.  
  10678.     Condition* condition = Condition::createCondition(conditionId, conditionType, 0, 0);
  10679.     if (condition) {
  10680.         pushUserdata<Condition>(L, condition);
  10681.         setMetatable(L, -1, "Condition");
  10682.     } else {
  10683.         lua_pushnil(L);
  10684.     }
  10685.     return 1;
  10686. }
  10687.  
  10688. int LuaScriptInterface::luaConditionDelete(lua_State* L)
  10689. {
  10690.     // condition:delete()
  10691.     Condition** conditionPtr = getRawUserdata<Condition>(L, 1);
  10692.     if (conditionPtr && *conditionPtr) {
  10693.         delete *conditionPtr;
  10694.         *conditionPtr = nullptr;
  10695.     }
  10696.     return 0;
  10697. }
  10698.  
  10699. int LuaScriptInterface::luaConditionGetId(lua_State* L)
  10700. {
  10701.     // condition:getId()
  10702.     Condition* condition = getUserdata<Condition>(L, 1);
  10703.     if (condition) {
  10704.         lua_pushnumber(L, condition->getId());
  10705.     } else {
  10706.         lua_pushnil(L);
  10707.     }
  10708.     return 1;
  10709. }
  10710.  
  10711. int LuaScriptInterface::luaConditionGetSubId(lua_State* L)
  10712. {
  10713.     // condition:getSubId()
  10714.     Condition* condition = getUserdata<Condition>(L, 1);
  10715.     if (condition) {
  10716.         lua_pushnumber(L, condition->getSubId());
  10717.     } else {
  10718.         lua_pushnil(L);
  10719.     }
  10720.     return 1;
  10721. }
  10722.  
  10723. int LuaScriptInterface::luaConditionGetType(lua_State* L)
  10724. {
  10725.     // condition:getType()
  10726.     Condition* condition = getUserdata<Condition>(L, 1);
  10727.     if (condition) {
  10728.         lua_pushnumber(L, condition->getType());
  10729.     } else {
  10730.         lua_pushnil(L);
  10731.     }
  10732.     return 1;
  10733. }
  10734.  
  10735. int LuaScriptInterface::luaConditionGetIcons(lua_State* L)
  10736. {
  10737.     // condition:getIcons()
  10738.     Condition* condition = getUserdata<Condition>(L, 1);
  10739.     if (condition) {
  10740.         lua_pushnumber(L, condition->getIcons());
  10741.     } else {
  10742.         lua_pushnil(L);
  10743.     }
  10744.     return 1;
  10745. }
  10746.  
  10747. int LuaScriptInterface::luaConditionGetEndTime(lua_State* L)
  10748. {
  10749.     // condition:getEndTime()
  10750.     Condition* condition = getUserdata<Condition>(L, 1);
  10751.     if (condition) {
  10752.         lua_pushnumber(L, condition->getEndTime());
  10753.     } else {
  10754.         lua_pushnil(L);
  10755.     }
  10756.     return 1;
  10757. }
  10758.  
  10759. int LuaScriptInterface::luaConditionClone(lua_State* L)
  10760. {
  10761.     // condition:clone()
  10762.     Condition* condition = getUserdata<Condition>(L, 1);
  10763.     if (condition) {
  10764.         pushUserdata<Condition>(L, condition->clone());
  10765.         setMetatable(L, -1, "Condition");
  10766.     } else {
  10767.         lua_pushnil(L);
  10768.     }
  10769.     return 1;
  10770. }
  10771.  
  10772. int LuaScriptInterface::luaConditionGetTicks(lua_State* L)
  10773. {
  10774.     // condition:getTicks()
  10775.     Condition* condition = getUserdata<Condition>(L, 1);
  10776.     if (condition) {
  10777.         lua_pushnumber(L, condition->getTicks());
  10778.     } else {
  10779.         lua_pushnil(L);
  10780.     }
  10781.     return 1;
  10782. }
  10783.  
  10784. int LuaScriptInterface::luaConditionSetTicks(lua_State* L)
  10785. {
  10786.     // condition:setTicks(ticks)
  10787.     int32_t ticks = getNumber<int32_t>(L, 2);
  10788.     Condition* condition = getUserdata<Condition>(L, 1);
  10789.     if (condition) {
  10790.         condition->setTicks(ticks);
  10791.         pushBoolean(L, true);
  10792.     } else {
  10793.         lua_pushnil(L);
  10794.     }
  10795.     return 1;
  10796. }
  10797.  
  10798. int LuaScriptInterface::luaConditionSetParameter(lua_State* L)
  10799. {
  10800.     // condition:setParameter(key, value)
  10801.     Condition* condition = getUserdata<Condition>(L, 1);
  10802.     if (!condition) {
  10803.         lua_pushnil(L);
  10804.         return 1;
  10805.     }
  10806.  
  10807.     ConditionParam_t key = getNumber<ConditionParam_t>(L, 2);
  10808.     int32_t value;
  10809.     if (isBoolean(L, 3)) {
  10810.         value = getBoolean(L, 3) ? 1 : 0;
  10811.     } else {
  10812.         value = getNumber<int32_t>(L, 3);
  10813.     }
  10814.     condition->setParam(key, value);
  10815.     pushBoolean(L, true);
  10816.     return 1;
  10817. }
  10818.  
  10819. int LuaScriptInterface::luaConditionSetFormula(lua_State* L)
  10820. {
  10821.     // condition:setFormula(mina, minb, maxa, maxb)
  10822.     double maxb = getNumber<double>(L, 5);
  10823.     double maxa = getNumber<double>(L, 4);
  10824.     double minb = getNumber<double>(L, 3);
  10825.     double mina = getNumber<double>(L, 2);
  10826.     ConditionSpeed* condition = dynamic_cast<ConditionSpeed*>(getUserdata<Condition>(L, 1));
  10827.     if (condition) {
  10828.         condition->setFormulaVars(mina, minb, maxa, maxb);
  10829.         pushBoolean(L, true);
  10830.     } else {
  10831.         lua_pushnil(L);
  10832.     }
  10833.     return 1;
  10834. }
  10835.  
  10836. int LuaScriptInterface::luaConditionSetOutfit(lua_State* L)
  10837. {
  10838.     // condition:setOutfit(outfit)
  10839.     // condition:setOutfit(lookTypeEx, lookType, lookHead, lookBody, lookLegs, lookFeet[, lookAddons])
  10840.     Outfit_t outfit;
  10841.     if (isTable(L, 2)) {
  10842.         outfit = getOutfit(L, 2);
  10843.     } else {
  10844.         outfit.lookAddons = getNumber<uint8_t>(L, 8, outfit.lookAddons);
  10845.         outfit.lookFeet = getNumber<uint8_t>(L, 7);
  10846.         outfit.lookLegs = getNumber<uint8_t>(L, 6);
  10847.         outfit.lookBody = getNumber<uint8_t>(L, 5);
  10848.         outfit.lookHead = getNumber<uint8_t>(L, 4);
  10849.         outfit.lookType = getNumber<uint16_t>(L, 3);
  10850.         outfit.lookTypeEx = getNumber<uint16_t>(L, 2);
  10851.     }
  10852.  
  10853.     ConditionOutfit* condition = dynamic_cast<ConditionOutfit*>(getUserdata<Condition>(L, 1));
  10854.     if (condition) {
  10855.         condition->setOutfit(outfit);
  10856.         pushBoolean(L, true);
  10857.     } else {
  10858.         lua_pushnil(L);
  10859.     }
  10860.     return 1;
  10861. }
  10862.  
  10863. int LuaScriptInterface::luaConditionAddDamage(lua_State* L)
  10864. {
  10865.     // condition:addDamage(rounds, time, value)
  10866.     int32_t value = getNumber<int32_t>(L, 4);
  10867.     int32_t time = getNumber<int32_t>(L, 3);
  10868.     int32_t rounds = getNumber<int32_t>(L, 2);
  10869.     ConditionDamage* condition = dynamic_cast<ConditionDamage*>(getUserdata<Condition>(L, 1));
  10870.     if (condition) {
  10871.         pushBoolean(L, condition->addDamage(rounds, time, value));
  10872.     } else {
  10873.         lua_pushnil(L);
  10874.     }
  10875.     return 1;
  10876. }
  10877.  
  10878. // MonsterType
  10879. int LuaScriptInterface::luaMonsterTypeCreate(lua_State* L)
  10880. {
  10881.     // MonsterType(name)
  10882.     MonsterType* monsterType = g_monsters.getMonsterType(getString(L, 2));
  10883.     if (monsterType) {
  10884.         pushUserdata<MonsterType>(L, monsterType);
  10885.         setMetatable(L, -1, "MonsterType");
  10886.     } else {
  10887.         lua_pushnil(L);
  10888.     }
  10889.     return 1;
  10890. }
  10891.  
  10892. int LuaScriptInterface::luaMonsterTypeIsAttackable(lua_State* L)
  10893. {
  10894.     // monsterType:isAttackable()
  10895.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  10896.     if (monsterType) {
  10897.         pushBoolean(L, monsterType->isAttackable);
  10898.     } else {
  10899.         lua_pushnil(L);
  10900.     }
  10901.     return 1;
  10902. }
  10903.  
  10904. int LuaScriptInterface::luaMonsterTypeIsConvinceable(lua_State* L)
  10905. {
  10906.     // monsterType:isConvinceable()
  10907.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  10908.     if (monsterType) {
  10909.         pushBoolean(L, monsterType->isConvinceable);
  10910.     } else {
  10911.         lua_pushnil(L);
  10912.     }
  10913.     return 1;
  10914. }
  10915.  
  10916. int LuaScriptInterface::luaMonsterTypeIsSummonable(lua_State* L)
  10917. {
  10918.     // monsterType:isSummonable()
  10919.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  10920.     if (monsterType) {
  10921.         pushBoolean(L, monsterType->isSummonable);
  10922.     } else {
  10923.         lua_pushnil(L);
  10924.     }
  10925.     return 1;
  10926. }
  10927.  
  10928. int LuaScriptInterface::luaMonsterTypeIsIllusionable(lua_State* L)
  10929. {
  10930.     // monsterType:isIllusionable()
  10931.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  10932.     if (monsterType) {
  10933.         pushBoolean(L, monsterType->isIllusionable);
  10934.     } else {
  10935.         lua_pushnil(L);
  10936.     }
  10937.     return 1;
  10938. }
  10939.  
  10940. int LuaScriptInterface::luaMonsterTypeIsHostile(lua_State* L)
  10941. {
  10942.     // monsterType:isHostile()
  10943.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  10944.     if (monsterType) {
  10945.         pushBoolean(L, monsterType->isHostile);
  10946.     } else {
  10947.         lua_pushnil(L);
  10948.     }
  10949.     return 1;
  10950. }
  10951.  
  10952. int LuaScriptInterface::luaMonsterTypeIsPushable(lua_State* L)
  10953. {
  10954.     // monsterType:isPushable()
  10955.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  10956.     if (monsterType) {
  10957.         pushBoolean(L, monsterType->pushable);
  10958.     } else {
  10959.         lua_pushnil(L);
  10960.     }
  10961.     return 1;
  10962. }
  10963.  
  10964. int LuaScriptInterface::luaMonsterTypeIsHealthShown(lua_State* L)
  10965. {
  10966.     // monsterType:isHealthShown()
  10967.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  10968.     if (monsterType) {
  10969.         pushBoolean(L, !monsterType->hiddenHealth);
  10970.     } else {
  10971.         lua_pushnil(L);
  10972.     }
  10973.     return 1;
  10974. }
  10975.  
  10976. int LuaScriptInterface::luaMonsterTypeCanPushItems(lua_State* L)
  10977. {
  10978.     // monsterType:canPushItems()
  10979.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  10980.     if (monsterType) {
  10981.         pushBoolean(L, monsterType->canPushItems);
  10982.     } else {
  10983.         lua_pushnil(L);
  10984.     }
  10985.     return 1;
  10986. }
  10987.  
  10988. int LuaScriptInterface::luaMonsterTypeCanPushCreatures(lua_State* L)
  10989. {
  10990.     // monsterType:canPushCreatures()
  10991.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  10992.     if (monsterType) {
  10993.         pushBoolean(L, monsterType->canPushCreatures);
  10994.     } else {
  10995.         lua_pushnil(L);
  10996.     }
  10997.     return 1;
  10998. }
  10999.  
  11000. int LuaScriptInterface::luaMonsterTypeGetName(lua_State* L)
  11001. {
  11002.     // monsterType:getName()
  11003.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11004.     if (monsterType) {
  11005.         pushString(L, monsterType->name);
  11006.     } else {
  11007.         lua_pushnil(L);
  11008.     }
  11009.     return 1;
  11010. }
  11011.  
  11012. int LuaScriptInterface::luaMonsterTypeGetNameDescription(lua_State* L)
  11013. {
  11014.     // monsterType:getNameDescription()
  11015.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11016.     if (monsterType) {
  11017.         pushString(L, monsterType->nameDescription);
  11018.     } else {
  11019.         lua_pushnil(L);
  11020.     }
  11021.     return 1;
  11022. }
  11023.  
  11024. int LuaScriptInterface::luaMonsterTypeGetHealth(lua_State* L)
  11025. {
  11026.     // monsterType:getHealth()
  11027.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11028.     if (monsterType) {
  11029.         lua_pushnumber(L, monsterType->health);
  11030.     } else {
  11031.         lua_pushnil(L);
  11032.     }
  11033.     return 1;
  11034. }
  11035.  
  11036. int LuaScriptInterface::luaMonsterTypeGetMaxHealth(lua_State* L)
  11037. {
  11038.     // monsterType:getMaxHealth()
  11039.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11040.     if (monsterType) {
  11041.         lua_pushnumber(L, monsterType->healthMax);
  11042.     } else {
  11043.         lua_pushnil(L);
  11044.     }
  11045.     return 1;
  11046. }
  11047.  
  11048. int LuaScriptInterface::luaMonsterTypeGetRunHealth(lua_State* L)
  11049. {
  11050.     // monsterType:getRunHealth()
  11051.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11052.     if (monsterType) {
  11053.         lua_pushnumber(L, monsterType->runAwayHealth);
  11054.     } else {
  11055.         lua_pushnil(L);
  11056.     }
  11057.     return 1;
  11058. }
  11059.  
  11060. int LuaScriptInterface::luaMonsterTypeGetExperience(lua_State* L)
  11061. {
  11062.     // monsterType:getExperience()
  11063.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11064.     if (monsterType) {
  11065.         lua_pushnumber(L, monsterType->experience);
  11066.     } else {
  11067.         lua_pushnil(L);
  11068.     }
  11069.     return 1;
  11070. }
  11071.  
  11072. int LuaScriptInterface::luaMonsterTypeGetCombatImmunities(lua_State* L)
  11073. {
  11074.     // monsterType:getCombatImmunities()
  11075.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11076.     if (monsterType) {
  11077.         lua_pushnumber(L, monsterType->damageImmunities);
  11078.     } else {
  11079.         lua_pushnil(L);
  11080.     }
  11081.     return 1;
  11082. }
  11083.  
  11084. int LuaScriptInterface::luaMonsterTypeGetConditionImmunities(lua_State* L)
  11085. {
  11086.     // monsterType:getConditionImmunities()
  11087.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11088.     if (monsterType) {
  11089.         lua_pushnumber(L, monsterType->conditionImmunities);
  11090.     } else {
  11091.         lua_pushnil(L);
  11092.     }
  11093.     return 1;
  11094. }
  11095.  
  11096. int LuaScriptInterface::luaMonsterTypeGetAttackList(lua_State* L)
  11097. {
  11098.     // monsterType:getAttackList()
  11099.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11100.     if (!monsterType) {
  11101.         lua_pushnil(L);
  11102.         return 1;
  11103.     }
  11104.  
  11105.     lua_createtable(L, monsterType->attackSpells.size(), 0);
  11106.  
  11107.     int index = 0;
  11108.     for (const auto& spellBlock : monsterType->attackSpells) {
  11109.         lua_createtable(L, 0, 8);
  11110.  
  11111.         setField(L, "chance", spellBlock.chance);
  11112.         setField(L, "isCombatSpell", spellBlock.combatSpell ? 1 : 0);
  11113.         setField(L, "isMelee", spellBlock.isMelee ? 1 : 0);
  11114.         setField(L, "minCombatValue", spellBlock.minCombatValue);
  11115.         setField(L, "maxCombatValue", spellBlock.maxCombatValue);
  11116.         setField(L, "range", spellBlock.range);
  11117.         setField(L, "speed", spellBlock.speed);
  11118.         pushUserdata<CombatSpell>(L, static_cast<CombatSpell*>(spellBlock.spell));
  11119.         lua_setfield(L, -2, "spell");
  11120.  
  11121.         lua_rawseti(L, -2, ++index);
  11122.     }
  11123.     return 1;
  11124. }
  11125.  
  11126. int LuaScriptInterface::luaMonsterTypeGetDefenseList(lua_State* L)
  11127. {
  11128.     // monsterType:getDefenseList()
  11129.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11130.     if (!monsterType) {
  11131.         lua_pushnil(L);
  11132.         return 1;
  11133.     }
  11134.  
  11135.     lua_createtable(L, monsterType->defenseSpells.size(), 0);
  11136.  
  11137.  
  11138.     int index = 0;
  11139.     for (const auto& spellBlock : monsterType->defenseSpells) {
  11140.         lua_createtable(L, 0, 8);
  11141.  
  11142.         setField(L, "chance", spellBlock.chance);
  11143.         setField(L, "isCombatSpell", spellBlock.combatSpell ? 1 : 0);
  11144.         setField(L, "isMelee", spellBlock.isMelee ? 1 : 0);
  11145.         setField(L, "minCombatValue", spellBlock.minCombatValue);
  11146.         setField(L, "maxCombatValue", spellBlock.maxCombatValue);
  11147.         setField(L, "range", spellBlock.range);
  11148.         setField(L, "speed", spellBlock.speed);
  11149.         pushUserdata<CombatSpell>(L, static_cast<CombatSpell*>(spellBlock.spell));
  11150.         lua_setfield(L, -2, "spell");
  11151.  
  11152.         lua_rawseti(L, -2, ++index);
  11153.     }
  11154.     return 1;
  11155. }
  11156.  
  11157. int LuaScriptInterface::luaMonsterTypeGetElementList(lua_State* L)
  11158. {
  11159.     // monsterType:getElementList()
  11160.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11161.     if (!monsterType) {
  11162.         lua_pushnil(L);
  11163.         return 1;
  11164.     }
  11165.  
  11166.     lua_createtable(L, monsterType->elementMap.size(), 0);
  11167.     for (const auto& elementEntry : monsterType->elementMap) {
  11168.         lua_pushnumber(L, elementEntry.second);
  11169.         lua_rawseti(L, -2, elementEntry.first);
  11170.     }
  11171.     return 1;
  11172. }
  11173.  
  11174. int LuaScriptInterface::luaMonsterTypeGetVoices(lua_State* L)
  11175. {
  11176.     // monsterType:getVoices()
  11177.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11178.     if (!monsterType) {
  11179.         lua_pushnil(L);
  11180.         return 1;
  11181.     }
  11182.  
  11183.     int index = 0;
  11184.     lua_createtable(L, monsterType->voiceVector.size(), 0);
  11185.     for (const auto& voiceBlock : monsterType->voiceVector) {
  11186.         lua_createtable(L, 0, 2);
  11187.         setField(L, "text", voiceBlock.text);
  11188.         setField(L, "yellText", voiceBlock.yellText);
  11189.         lua_rawseti(L, -2, ++index);
  11190.     }
  11191.     return 1;
  11192. }
  11193.  
  11194. int LuaScriptInterface::luaMonsterTypeGetLoot(lua_State* L)
  11195. {
  11196.     // monsterType:getLoot()
  11197.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11198.     if (!monsterType) {
  11199.         lua_pushnil(L);
  11200.         return 1;
  11201.     }
  11202.  
  11203.     static const std::function<void(const std::vector<LootBlock>&)> parseLoot = [&](const std::vector<LootBlock>& lootList) {
  11204.         lua_createtable(L, lootList.size(), 0);
  11205.  
  11206.         int index = 0;
  11207.         for (const auto& lootBlock : lootList) {
  11208.             lua_createtable(L, 0, 7);
  11209.  
  11210.             setField(L, "itemId", lootBlock.id);
  11211.             setField(L, "chance", lootBlock.chance);
  11212.             setField(L, "subType", lootBlock.subType);
  11213.             setField(L, "maxCount", lootBlock.countmax);
  11214.             setField(L, "actionId", lootBlock.actionId);
  11215.             setField(L, "text", lootBlock.text);
  11216.  
  11217.             parseLoot(lootBlock.childLoot);
  11218.             lua_setfield(L, -2, "childLoot");
  11219.  
  11220.             lua_rawseti(L, -2, ++index);
  11221.         }
  11222.     };
  11223.     parseLoot(monsterType->lootItems);
  11224.     return 1;
  11225. }
  11226.  
  11227. int LuaScriptInterface::luaMonsterTypeGetCreatureEvents(lua_State* L)
  11228. {
  11229.     // monsterType:getCreatureEvents()
  11230.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11231.     if (!monsterType) {
  11232.         lua_pushnil(L);
  11233.         return 1;
  11234.     }
  11235.  
  11236.     int index = 0;
  11237.     lua_createtable(L, monsterType->scripts.size(), 0);
  11238.     for (const std::string& creatureEvent : monsterType->scripts) {
  11239.         pushString(L, creatureEvent);
  11240.         lua_rawseti(L, -2, ++index);
  11241.     }
  11242.     return 1;
  11243. }
  11244.  
  11245. int LuaScriptInterface::luaMonsterTypeGetSummonList(lua_State* L)
  11246. {
  11247.     // monsterType:getSummonList()
  11248.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11249.     if (!monsterType) {
  11250.         lua_pushnil(L);
  11251.         return 1;
  11252.     }
  11253.  
  11254.     int index = 0;
  11255.     lua_createtable(L, monsterType->summons.size(), 0);
  11256.     for (const auto& summonBlock : monsterType->summons) {
  11257.         lua_createtable(L, 0, 3);
  11258.         setField(L, "name", summonBlock.name);
  11259.         setField(L, "speed", summonBlock.speed);
  11260.         setField(L, "chance", summonBlock.chance);
  11261.         lua_rawseti(L, -2, ++index);
  11262.     }
  11263.     return 1;
  11264. }
  11265.  
  11266. int LuaScriptInterface::luaMonsterTypeGetMaxSummons(lua_State* L)
  11267. {
  11268.     // monsterType:getMaxSummons()
  11269.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11270.     if (monsterType) {
  11271.         lua_pushnumber(L, monsterType->maxSummons);
  11272.     } else {
  11273.         lua_pushnil(L);
  11274.     }
  11275.     return 1;
  11276. }
  11277.  
  11278. int LuaScriptInterface::luaMonsterTypeGetArmor(lua_State* L)
  11279. {
  11280.     // monsterType:getArmor()
  11281.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11282.     if (monsterType) {
  11283.         lua_pushnumber(L, monsterType->armor);
  11284.     } else {
  11285.         lua_pushnil(L);
  11286.     }
  11287.     return 1;
  11288. }
  11289.  
  11290. int LuaScriptInterface::luaMonsterTypeGetDefense(lua_State* L)
  11291. {
  11292.     // monsterType:getDefense()
  11293.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11294.     if (monsterType) {
  11295.         lua_pushnumber(L, monsterType->defense);
  11296.     } else {
  11297.         lua_pushnil(L);
  11298.     }
  11299.     return 1;
  11300. }
  11301.  
  11302. int LuaScriptInterface::luaMonsterTypeGetOutfit(lua_State* L)
  11303. {
  11304.     // monsterType:getOutfit()
  11305.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11306.     if (monsterType) {
  11307.         pushOutfit(L, monsterType->outfit);
  11308.     } else {
  11309.         lua_pushnil(L);
  11310.     }
  11311.     return 1;
  11312. }
  11313.  
  11314. int LuaScriptInterface::luaMonsterTypeGetRace(lua_State* L)
  11315. {
  11316.     // monsterType:getRace()
  11317.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11318.     if (monsterType) {
  11319.         lua_pushnumber(L, monsterType->race);
  11320.     } else {
  11321.         lua_pushnil(L);
  11322.     }
  11323.     return 1;
  11324. }
  11325.  
  11326. int LuaScriptInterface::luaMonsterTypeGetCorpseId(lua_State* L)
  11327. {
  11328.     // monsterType:getCorpseId()
  11329.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11330.     if (monsterType) {
  11331.         lua_pushnumber(L, monsterType->lookcorpse);
  11332.     } else {
  11333.         lua_pushnil(L);
  11334.     }
  11335.     return 1;
  11336. }
  11337.  
  11338. int LuaScriptInterface::luaMonsterTypeGetManaCost(lua_State* L)
  11339. {
  11340.     // monsterType:getManaCost()
  11341.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11342.     if (monsterType) {
  11343.         lua_pushnumber(L, monsterType->manaCost);
  11344.     } else {
  11345.         lua_pushnil(L);
  11346.     }
  11347.     return 1;
  11348. }
  11349.  
  11350. int LuaScriptInterface::luaMonsterTypeGetBaseSpeed(lua_State* L)
  11351. {
  11352.     // monsterType:getBaseSpeed()
  11353.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11354.     if (monsterType) {
  11355.         lua_pushnumber(L, monsterType->baseSpeed);
  11356.     } else {
  11357.         lua_pushnil(L);
  11358.     }
  11359.     return 1;
  11360. }
  11361.  
  11362. int LuaScriptInterface::luaMonsterTypeGetLight(lua_State* L)
  11363. {
  11364.     // monsterType:getLight()
  11365.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11366.     if (!monsterType) {
  11367.         lua_pushnil(L);
  11368.         return 1;
  11369.     }
  11370.  
  11371.     lua_pushnumber(L, monsterType->lightLevel);
  11372.     lua_pushnumber(L, monsterType->lightColor);
  11373.     return 2;
  11374. }
  11375.  
  11376. int LuaScriptInterface::luaMonsterTypeGetStaticAttackChance(lua_State* L)
  11377. {
  11378.     // monsterType:getStaticAttackChance()
  11379.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11380.     if (monsterType) {
  11381.         lua_pushnumber(L, monsterType->staticAttackChance);
  11382.     } else {
  11383.         lua_pushnil(L);
  11384.     }
  11385.     return 1;
  11386. }
  11387.  
  11388. int LuaScriptInterface::luaMonsterTypeGetTargetDistance(lua_State* L)
  11389. {
  11390.     // monsterType:getTargetDistance()
  11391.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11392.     if (monsterType) {
  11393.         lua_pushnumber(L, monsterType->targetDistance);
  11394.     } else {
  11395.         lua_pushnil(L);
  11396.     }
  11397.     return 1;
  11398. }
  11399.  
  11400. int LuaScriptInterface::luaMonsterTypeGetYellChance(lua_State* L)
  11401. {
  11402.     // monsterType:getYellChance()
  11403.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11404.     if (monsterType) {
  11405.         lua_pushnumber(L, monsterType->yellChance);
  11406.     } else {
  11407.         lua_pushnil(L);
  11408.     }
  11409.     return 1;
  11410. }
  11411.  
  11412. int LuaScriptInterface::luaMonsterTypeGetYellSpeedTicks(lua_State* L)
  11413. {
  11414.     // monsterType:getYellSpeedTicks()
  11415.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11416.     if (monsterType) {
  11417.         lua_pushnumber(L, monsterType->yellSpeedTicks);
  11418.     } else {
  11419.         lua_pushnil(L);
  11420.     }
  11421.     return 1;
  11422. }
  11423.  
  11424. int LuaScriptInterface::luaMonsterTypeGetChangeTargetChance(lua_State* L)
  11425. {
  11426.     // monsterType:getChangeTargetChance()
  11427.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11428.     if (monsterType) {
  11429.         lua_pushnumber(L, monsterType->changeTargetChance);
  11430.     } else {
  11431.         lua_pushnil(L);
  11432.     }
  11433.     return 1;
  11434. }
  11435.  
  11436. int LuaScriptInterface::luaMonsterTypeGetChangeTargetSpeed(lua_State* L)
  11437. {
  11438.     // monsterType:getChangeTargetSpeed()
  11439.     MonsterType* monsterType = getUserdata<MonsterType>(L, 1);
  11440.     if (monsterType) {
  11441.         lua_pushnumber(L, monsterType->changeTargetSpeed);
  11442.     } else {
  11443.         lua_pushnil(L);
  11444.     }
  11445.     return 1;
  11446. }
  11447.  
  11448. // Party
  11449. int LuaScriptInterface::luaPartyDisband(lua_State* L)
  11450. {
  11451.     // party:disband()
  11452.     Party** partyPtr = getRawUserdata<Party>(L, 1);
  11453.     if (partyPtr && *partyPtr) {
  11454.         Party*& party = *partyPtr;
  11455.         party->disband();
  11456.         party = nullptr;
  11457.         pushBoolean(L, true);
  11458.     } else {
  11459.         lua_pushnil(L);
  11460.     }
  11461.     return 1;
  11462. }
  11463.  
  11464. int LuaScriptInterface::luaPartyGetLeader(lua_State* L)
  11465. {
  11466.     // party:getLeader()
  11467.     Party* party = getUserdata<Party>(L, 1);
  11468.     if (!party) {
  11469.         lua_pushnil(L);
  11470.         return 1;
  11471.     }
  11472.  
  11473.     Player* leader = party->getLeader();
  11474.     if (leader) {
  11475.         pushUserdata<Player>(L, leader);
  11476.         setMetatable(L, -1, "Player");
  11477.     } else {
  11478.         lua_pushnil(L);
  11479.     }
  11480.     return 1;
  11481. }
  11482.  
  11483. int LuaScriptInterface::luaPartySetLeader(lua_State* L)
  11484. {
  11485.     // party:setLeader(player)
  11486.     Player* player = getPlayer(L, 2);
  11487.     Party* party = getUserdata<Party>(L, 1);
  11488.     if (party && player) {
  11489.         pushBoolean(L, party->passPartyLeadership(player));
  11490.     } else {
  11491.         lua_pushnil(L);
  11492.     }
  11493.     return 1;
  11494. }
  11495.  
  11496. int LuaScriptInterface::luaPartyGetMembers(lua_State* L)
  11497. {
  11498.     // party:getMembers()
  11499.     Party* party = getUserdata<Party>(L, 1);
  11500.     if (!party) {
  11501.         lua_pushnil(L);
  11502.         return 1;
  11503.     }
  11504.  
  11505.     int index = 0;
  11506.     lua_createtable(L, party->getMemberCount(), 0);
  11507.     for (Player* player : party->getMembers()) {
  11508.         pushUserdata<Player>(L, player);
  11509.         setMetatable(L, -1, "Player");
  11510.         lua_rawseti(L, -2, ++index);
  11511.     }
  11512.     return 1;
  11513. }
  11514.  
  11515. int LuaScriptInterface::luaPartyGetMemberCount(lua_State* L)
  11516. {
  11517.     // party:getMemberCount()
  11518.     Party* party = getUserdata<Party>(L, 1);
  11519.     if (party) {
  11520.         lua_pushnumber(L, party->getMemberCount());
  11521.     } else {
  11522.         lua_pushnil(L);
  11523.     }
  11524.     return 1;
  11525. }
  11526.  
  11527. int LuaScriptInterface::luaPartyGetInvitees(lua_State* L)
  11528. {
  11529.     // party:getInvitees()
  11530.     Party* party = getUserdata<Party>(L, 1);
  11531.     if (party) {
  11532.         lua_createtable(L, party->getInvitationCount(), 0);
  11533.  
  11534.         int index = 0;
  11535.         for (Player* player : party->getInvitees()) {
  11536.             pushUserdata<Player>(L, player);
  11537.             setMetatable(L, -1, "Player");
  11538.             lua_rawseti(L, -2, ++index);
  11539.         }
  11540.     } else {
  11541.         lua_pushnil(L);
  11542.     }
  11543.     return 1;
  11544. }
  11545.  
  11546. int LuaScriptInterface::luaPartyGetInviteeCount(lua_State* L)
  11547. {
  11548.     // party:getInviteeCount()
  11549.     Party* party = getUserdata<Party>(L, 1);
  11550.     if (party) {
  11551.         lua_pushnumber(L, party->getInvitationCount());
  11552.     } else {
  11553.         lua_pushnil(L);
  11554.     }
  11555.     return 1;
  11556. }
  11557.  
  11558. int LuaScriptInterface::luaPartyAddInvite(lua_State* L)
  11559. {
  11560.     // party:addInvite(player)
  11561.     Player* player = getPlayer(L, 2);
  11562.     Party* party = getUserdata<Party>(L, 1);
  11563.     if (party && player) {
  11564.         pushBoolean(L, party->invitePlayer(*player));
  11565.     } else {
  11566.         lua_pushnil(L);
  11567.     }
  11568.     return 1;
  11569. }
  11570.  
  11571. int LuaScriptInterface::luaPartyRemoveInvite(lua_State* L)
  11572. {
  11573.     // party:removeInvite(player)
  11574.     Player* player = getPlayer(L, 2);
  11575.     Party* party = getUserdata<Party>(L, 1);
  11576.     if (party && player) {
  11577.         pushBoolean(L, party->removeInvite(*player));
  11578.     } else {
  11579.         lua_pushnil(L);
  11580.     }
  11581.     return 1;
  11582. }
  11583.  
  11584. int LuaScriptInterface::luaPartyAddMember(lua_State* L)
  11585. {
  11586.     // party:addMember(player)
  11587.     Player* player = getPlayer(L, 2);
  11588.     Party* party = getUserdata<Party>(L, 1);
  11589.     if (party && player) {
  11590.         pushBoolean(L, party->joinParty(*player));
  11591.     } else {
  11592.         lua_pushnil(L);
  11593.     }
  11594.     return 1;
  11595. }
  11596.  
  11597. int LuaScriptInterface::luaPartyRemoveMember(lua_State* L)
  11598. {
  11599.     // party:removeMember(player)
  11600.     Player* player = getPlayer(L, 2);
  11601.     Party* party = getUserdata<Party>(L, 1);
  11602.     if (party && player) {
  11603.         pushBoolean(L, party->leaveParty(player));
  11604.     } else {
  11605.         lua_pushnil(L);
  11606.     }
  11607.     return 1;
  11608. }
  11609.  
  11610. int LuaScriptInterface::luaPartyIsSharedExperienceActive(lua_State* L)
  11611. {
  11612.     // party:isSharedExperienceActive()
  11613.     Party* party = getUserdata<Party>(L, 1);
  11614.     if (party) {
  11615.         pushBoolean(L, party->isSharedExperienceActive());
  11616.     } else {
  11617.         lua_pushnil(L);
  11618.     }
  11619.     return 1;
  11620. }
  11621.  
  11622. int LuaScriptInterface::luaPartyIsSharedExperienceEnabled(lua_State* L)
  11623. {
  11624.     // party:isSharedExperienceEnabled()
  11625.     Party* party = getUserdata<Party>(L, 1);
  11626.     if (party) {
  11627.         pushBoolean(L, party->isSharedExperienceEnabled());
  11628.     } else {
  11629.         lua_pushnil(L);
  11630.     }
  11631.     return 1;
  11632. }
  11633.  
  11634. int LuaScriptInterface::luaPartyShareExperience(lua_State* L)
  11635. {
  11636.     // party:shareExperience(experience)
  11637.     uint64_t experience = getNumber<uint64_t>(L, 2);
  11638.     Party* party = getUserdata<Party>(L, 1);
  11639.     if (party) {
  11640.         party->shareExperience(experience);
  11641.         pushBoolean(L, true);
  11642.     } else {
  11643.         lua_pushnil(L);
  11644.     }
  11645.     return 1;
  11646. }
  11647.  
  11648. int LuaScriptInterface::luaPartySetSharedExperience(lua_State* L)
  11649. {
  11650.     // party:setSharedExperience(active)
  11651.     bool active = getBoolean(L, 2);
  11652.     Party* party = getUserdata<Party>(L, 1);
  11653.     if (party) {
  11654.         pushBoolean(L, party->setSharedExperience(party->getLeader(), active));
  11655.     } else {
  11656.         lua_pushnil(L);
  11657.     }
  11658.     return 1;
  11659. }
  11660.  
  11661. //
  11662. LuaEnvironment::LuaEnvironment() :
  11663.     LuaScriptInterface("Main Interface"), testInterface(nullptr),
  11664.     lastEventTimerId(1), lastCombatId(0), lastAreaId(0)
  11665. {
  11666.     //
  11667. }
  11668.  
  11669. LuaEnvironment::~LuaEnvironment()
  11670. {
  11671.     delete testInterface;
  11672.     closeState();
  11673. }
  11674.  
  11675. bool LuaEnvironment::initState()
  11676. {
  11677.     luaState = luaL_newstate();
  11678.     if (!luaState) {
  11679.         return false;
  11680.     }
  11681.  
  11682.     luaL_openlibs(luaState);
  11683.     registerFunctions();
  11684.  
  11685.     runningEventId = EVENT_ID_USER;
  11686.     return true;
  11687. }
  11688.  
  11689. bool LuaEnvironment::reInitState()
  11690. {
  11691.     // TODO: get children, reload children
  11692.     closeState();
  11693.     return initState();
  11694. }
  11695.  
  11696. bool LuaEnvironment::closeState()
  11697. {
  11698.     if (!luaState) {
  11699.         return false;
  11700.     }
  11701.  
  11702.     for (const auto& combatEntry : combatIdMap) {
  11703.         clearCombatObjects(combatEntry.first);
  11704.     }
  11705.  
  11706.     for (const auto& areaEntry : areaIdMap) {
  11707.         clearAreaObjects(areaEntry.first);
  11708.     }
  11709.  
  11710.     for (auto& timerEntry : timerEvents) {
  11711.         LuaTimerEventDesc timerEventDesc = std::move(timerEntry.second);
  11712.         for (int32_t parameter : timerEventDesc.parameters) {
  11713.             luaL_unref(luaState, LUA_REGISTRYINDEX, parameter);
  11714.         }
  11715.         luaL_unref(luaState, LUA_REGISTRYINDEX, timerEventDesc.function);
  11716.     }
  11717.  
  11718.     combatIdMap.clear();
  11719.     areaIdMap.clear();
  11720.     timerEvents.clear();
  11721.     cacheFiles.clear();
  11722.  
  11723.     lua_close(luaState);
  11724.     luaState = nullptr;
  11725.     return true;
  11726. }
  11727.  
  11728. LuaScriptInterface* LuaEnvironment::getTestInterface()
  11729. {
  11730.     if (!testInterface) {
  11731.         testInterface = new LuaScriptInterface("Test Interface");
  11732.         testInterface->initState();
  11733.     }
  11734.     return testInterface;
  11735. }
  11736.  
  11737. Combat* LuaEnvironment::getCombatObject(uint32_t id) const
  11738. {
  11739.     auto it = combatMap.find(id);
  11740.     if (it == combatMap.end()) {
  11741.         return nullptr;
  11742.     }
  11743.     return it->second;
  11744. }
  11745.  
  11746. Combat* LuaEnvironment::createCombatObject(LuaScriptInterface* interface)
  11747. {
  11748.     Combat* combat = new Combat;
  11749.     combatMap[++lastCombatId] = combat;
  11750.     combatIdMap[interface].push_back(lastCombatId);
  11751.     return combat;
  11752. }
  11753.  
  11754. void LuaEnvironment::clearCombatObjects(LuaScriptInterface* interface)
  11755. {
  11756.     auto it = combatIdMap.find(interface);
  11757.     if (it == combatIdMap.end()) {
  11758.         return;
  11759.     }
  11760.  
  11761.     for (uint32_t id : it->second) {
  11762.         auto itt = combatMap.find(id);
  11763.         if (itt != combatMap.end()) {
  11764.             delete itt->second;
  11765.             combatMap.erase(itt);
  11766.         }
  11767.     }
  11768.     it->second.clear();
  11769. }
  11770.  
  11771. AreaCombat* LuaEnvironment::getAreaObject(uint32_t id) const
  11772. {
  11773.     auto it = areaMap.find(id);
  11774.     if (it == areaMap.end()) {
  11775.         return nullptr;
  11776.     }
  11777.     return it->second;
  11778. }
  11779.  
  11780. uint32_t LuaEnvironment::createAreaObject(LuaScriptInterface* interface)
  11781. {
  11782.     areaMap[++lastAreaId] = new AreaCombat;
  11783.     areaIdMap[interface].push_back(lastAreaId);
  11784.     return lastAreaId;
  11785. }
  11786.  
  11787. void LuaEnvironment::clearAreaObjects(LuaScriptInterface* interface)
  11788. {
  11789.     auto it = areaIdMap.find(interface);
  11790.     if (it == areaIdMap.end()) {
  11791.         return;
  11792.     }
  11793.  
  11794.     for (uint32_t id : it->second) {
  11795.         auto itt = areaMap.find(id);
  11796.         if (itt != areaMap.end()) {
  11797.             delete itt->second;
  11798.             areaMap.erase(itt);
  11799.         }
  11800.     }
  11801.     it->second.clear();
  11802. }
  11803.  
  11804. void LuaEnvironment::executeTimerEvent(uint32_t eventIndex)
  11805. {
  11806.     auto it = timerEvents.find(eventIndex);
  11807.     if (it == timerEvents.end()) {
  11808.         return;
  11809.     }
  11810.  
  11811.     LuaTimerEventDesc timerEventDesc = std::move(it->second);
  11812.     timerEvents.erase(it);
  11813.  
  11814.     //push function
  11815.     lua_rawgeti(luaState, LUA_REGISTRYINDEX, timerEventDesc.function);
  11816.  
  11817.     //push parameters
  11818.     for (auto parameter : boost::adaptors::reverse(timerEventDesc.parameters)) {
  11819.         lua_rawgeti(luaState, LUA_REGISTRYINDEX, parameter);
  11820.     }
  11821.  
  11822.     //call the function
  11823.     if (reserveScriptEnv()) {
  11824.         ScriptEnvironment* env = getScriptEnv();
  11825.         env->setTimerEvent();
  11826.         env->setScriptId(timerEventDesc.scriptId, this);
  11827.         callFunction(timerEventDesc.parameters.size());
  11828.     } else {
  11829.         std::cout << "[Error - LuaScriptInterface::executeTimerEvent] Call stack overflow" << std::endl;
  11830.     }
  11831.  
  11832.     //free resources
  11833.     luaL_unref(luaState, LUA_REGISTRYINDEX, timerEventDesc.function);
  11834.     for (auto parameter : timerEventDesc.parameters) {
  11835.         luaL_unref(luaState, LUA_REGISTRYINDEX, parameter);
  11836.     }
  11837. }
Advertisement
Add Comment
Please, Sign In to add comment
Advertisement